PostGIS extention driver based on postgresql-simple package.
Please see the README on GitHub at https://github.com/igor720/postgis-trivial#README.md
postgis-trivial
Haskell Postgresql/PostGIS DB Driver
This library provides methods which allow direct use of user-defined Haskell data with Postgresql/PostGIS databases. It is based on postgresql-simple and can be used with other postgresql-simple capabilities.
The main interface module Database.PostGIS.Trivial allows PostGIS to work with geospatial (point) data enclosed in Traversable data structures. If the most inner data structures are Unboxed vectors, then use the functions and types defined in Database.PostGIS.Trivial.Unboxed. And, if the most inner data structures are Storable vectors then use Database.PostGIS.Trivial.Storable module.
Synopsis
Default types
P2D for 2D points
P3DZ, P3DM for 3D points
P4D for points with z and m coordinates
You can freely use them for your data. Unboxed and Storable types are in the corresponding modules (thay have appending 'U' and 'S' letters in names).
User-defined types
Ensure that user geometry data points is correctly translated into the internal default points data as in the example.
{-# LANGUAGE TypeFamilies #-}
data LatLon = -- example of 2D geospatial point data
LatLon !Double !Double
deriving (Show, Eq)
type instance Cast LatLon = P2D -- translation to inner 2D point
instance Castable LatLon where -- specify translation
toPointND (LatLon y x) = Point2D x y
fromPointND (Point2D x y) = LatLon y x
Then a structure of type Traversable t => t LatLon can be interpreted as LineString or MultiPoint. Any structure of type (Traversable t1, Traversable t2) => t2 (t1 LatLon) can be interpreted as Polygon or MultiLineString. And any structure of type (Traversable t1, Traversable t2, Traversable t3) => t3 (t2 (t1 LatLon)) can be interpreted as MultiPolygon. Currently, only following Traversables are supported: List, Data.Vector.Vector. Data.IntMap.IntMap and Data.Map.Map have partial support.
By this way you can use these structures in postgresql-simple functions as such:
ls = [LatLon 1 2, LatLon 1.5 2.5, LatLon 2.5 3, LatLon 1 2]
_ <- execute conn "INSERT INTO linestrings (geom) VALUES (?)"
(Only (Geo (LineString srid ls)))
[Only res] <- query_ conn "SELECT * FROM linestrings LIMIT 1"
let Geo (LineString srid' ls') = res
Or the same with suitable helper functions:
_ <- execute conn "INSERT INTO linestrings (geom) VALUES (?)"
(Only (putLS srid ls))
[Only res] <- query_ conn "SELECT * FROM linestrings LIMIT 1"
let (srid', ls') = getLS res