@hackage postgis-trivial0.0.1.0

PostGIS extention driver based on postgresql-simple package

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