Documentation ¶
Overview ¶
Package gogis is the SQL driver for PostGIS (https://postgis.net/). It implements some of the PostGIS geometry:
import ( "context" "database/sql" _ "github.com/lib/pq" "github.com/landru29/gogis" "github.com/landru29/gogis/ewkb" ) func main() { ctx := context.Background() db, err := sql.Open("postgres", "postgresql://tester:tester@localhost/test?sslmode=disable") if err != nil { panic(err) } rows, err := db.QueryContext(ctx, ` SELECT coordinate FROM geometries `) if err != nil { panic(err) } if err := rows.Err(); err != nil { panic(err) } defer func() { _ = rows.Close() }() output := []gogis.Point{} for rows.Next() { pnt := gogis.NullPoint{} err = rows.Scan(&pnt) if err != nil { panic(err) } if pnt.Valid { output = append(output, pnt.Point) } } fmt.Println(output) }
It also let users to implements their own types:
import ( "io" "github.com/landru29/gogis/ewkb" ) type Custom struct { databytes []byte } func (c *Custom) UnmarshalEWBK(ewkb.ExtendedWellKnownBytes) error { data, err := io.ReadAll() c.dataBytes = data return err } func (c Custom) MarshalEWBK(binary.ByteOrder) ([]byte, error) { return c.dataBytes, nil } func (c Custom) Layout() ewkb.Layout { return ewkb.Layout(0) } func (c Custom) Type() ewkb.GeometryType { return ewkb.GeometryType(42) } // CustomSQL is to used with "sql" package. type CustomSQL Custom func (c *CustomSQL) Scan(value interface{}) error { custo := Custom{} if err := ewkb.Unmarshal(&custo, value); err != nil { return err } *c = CustomSQL(custo) return nil } func (c CustomSQL) Value() (driver.Value, error) { return ewkb.Marshal(Custom(c)) }
Example (InsertLineString) ¶
package main import ( "context" "database/sql" "github.com/landru29/gogis" "github.com/landru29/gogis/ewkb" ) func main() { //nolint: wsl,nosnakecase,testableexamples // Launch database: // $> docker run --name db -p 5432:5432 -e POSTGRES_PASSWORD=tester -e POSTGRES_USER=tester -e POSTGRES_DB=test -d postgis/postgis:15-master // // Create the table: // $> docker exec -i db psql -h 0.0.0.0 -p 5432 -U tester -d test -c "CREATE TABLE IF NOT EXISTS geometries (coordinate GEOMETRY);" -t // // Do not forget the imports: // import ( // "context" // "database/sql" // _ "github.com/lib/pq" // "github.com/landru29/gogis" // "github.com/landru29/gogis/ewkb" // ) ctx := context.Background() // Connect to database. db, err := sql.Open("postgres", "postgresql://tester:tester@localhost/test?sslmode=disable") //nolint: varnamelen if err != nil { panic(err) } // Prepare the query. stmt, err := db.PrepareContext(ctx, ` INSERT INTO geometries( coordinate ) VALUES( $1 ) `) if err != nil { panic(err) } defer func() { _ = stmt.Close() }() // Execute the query. if _, err = stmt.ExecContext(ctx, gogis.LineString{ { Coordinate: ewkb.Coordinate{ 'x': 42.42, 'y': 24.24, }, SRID: ewkb.WithSRID(ewkb.SystemReferenceWGS84), }, { Coordinate: ewkb.Coordinate{ 'x': 10, 'y': 30, }, SRID: ewkb.WithSRID(ewkb.SystemReferenceWGS84), }, }, ); err != nil { panic(err) } }
Output:
Example (InsertPoint) ¶
package main import ( "context" "database/sql" "github.com/landru29/gogis" "github.com/landru29/gogis/ewkb" ) func main() { //nolint: wsl,nosnakecase,testableexamples // Launch database: // $> docker run --name db -p 5432:5432 -e POSTGRES_PASSWORD=tester -e POSTGRES_USER=tester -e POSTGRES_DB=test -d postgis/postgis:15-master // // Create the table: // $> docker exec -i db psql -h 0.0.0.0 -p 5432 -U tester -d test -c "CREATE TABLE IF NOT EXISTS geometries (coordinate GEOMETRY);" -t // // Do not forget the imports: // import ( // "context" // "database/sql" // _ "github.com/lib/pq" // "github.com/landru29/gogis" // "github.com/landru29/gogis/ewkb" // ) ctx := context.Background() // Connect to database. db, err := sql.Open("postgres", "postgresql://tester:tester@localhost/test?sslmode=disable") //nolint: varnamelen if err != nil { panic(err) } // Prepare the query. stmt, err := db.PrepareContext(ctx, ` INSERT INTO geometries( coordinate ) VALUES( $1 ) `) if err != nil { panic(err) } defer func() { _ = stmt.Close() }() // Execute the query. if _, err = stmt.ExecContext(ctx, gogis.Point{ Coordinate: ewkb.Coordinate{ 'x': 42.42, 'y': 24.24, }, SRID: ewkb.WithSRID(ewkb.SystemReferenceWGS84), }, ); err != nil { panic(err) } }
Output:
Example (ScanAny) ¶
This example shows how to read any geometry from database.
package main import ( "context" "database/sql" "fmt" "github.com/landru29/gogis" ) func main() { //nolint: wsl,nosnakecase,testableexamples // Launch database: // $> docker run --name db -p 5432:5432 -e POSTGRES_PASSWORD=tester -e POSTGRES_USER=tester -e POSTGRES_DB=test -d postgis/postgis:15-master // // Create the table: // $> docker exec -i db psql -h 0.0.0.0 -p 5432 -U tester -d test -c "CREATE TABLE IF NOT EXISTS geometries (coordinate GEOMETRY);" -t // // Insert data: // $> docker exec -i db psql -h 0.0.0.0 -p 5432 -U tester -d test -c "INSERT INTO geometries(coordinate) VALUES (ST_GeomFromText('POINT ZM(10 20 30 50)', 4326))" -t // $> docker exec -i db psql -h 0.0.0.0 -p 5432 -U tester -d test -c "INSERT INTO geometries(coordinate) VALUES (ST_GeomFromText('MULTIPOINT((-71.42 42.71),(-17.42 42.17),(-17.42 71.17),(-71.42 42.71))', 4326))" -t // $> docker exec -i db psql -h 0.0.0.0 -p 5432 -U tester -d test -c "INSERT INTO geometries(coordinate) VALUES (ST_GeomFromText('POLYGON Z((-71.42 42.71 4,-17.42 42.17 4,-17.42 71.17 4,-71.42 42.71 4),(1 2 3,4 5 6,7 8 9,1 2 3))', 4326))" -t // $> docker exec -i db psql -h 0.0.0.0 -p 5432 -U tester -d test -c "INSERT INTO geometries(coordinate) VALUES (ST_GeomFromText('LINESTRING (-71.060316 48.432044, 5 6, 42 24)', 4326))" -t // // Do not forget the imports: // import ( // "context" // "database/sql" // _ "github.com/lib/pq" // "github.com/landru29/gogis" // "github.com/landru29/gogis/ewkb" // ) ctx := context.Background() // Connect to database. db, err := sql.Open("postgres", "postgresql://tester:tester@localhost/test?sslmode=disable") //nolint: varnamelen if err != nil { panic(err) } // Prepare the query. rows, err := db.QueryContext(ctx, ` SELECT coordinate FROM geometries `) if err != nil { panic(err) } if err := rows.Err(); err != nil { panic(err) } defer func() { _ = rows.Close() }() // Read data. for rows.Next() { geometry := gogis.NewGeometry() err = rows.Scan(geometry) if err != nil { panic(err) } switch data := geometry.Geometry.(type) { case *gogis.Point: // process point fmt.Printf("* point %+v\n", data) case *gogis.LineString: // process linestring fmt.Printf("* linestring %+v\n", data) case *gogis.Polygon: // process polygon fmt.Printf("* polygon %+v\n", data) case *gogis.MultiPoint: // process multipoint fmt.Printf("* multipoint %+v\n", data) } } }
Output:
Example (ScanLineString) ¶
package main import ( "context" "database/sql" "fmt" "github.com/landru29/gogis" ) func main() { //nolint: wsl,nosnakecase,testableexamples // Launch database: // $> docker run --name db -p 5432:5432 -e POSTGRES_PASSWORD=tester -e POSTGRES_USER=tester -e POSTGRES_DB=test -d postgis/postgis:15-master // // Create the table: // $> docker exec -i db psql -h 0.0.0.0 -p 5432 -U tester -d test -c "CREATE TABLE IF NOT EXISTS geometries (coordinate GEOMETRY);" -t // // Insert data: // $> docker exec -i db psql -h 0.0.0.0 -p 5432 -U tester -d test -c "INSERT INTO geometries(coordinate) VALUES (ST_GeomFromText('LINESTRING (-71.060316 48.432044, 5 6, 42 24)', 4326))" -t // // Do not forget the imports: // import ( // "context" // "database/sql" // _ "github.com/lib/pq" // "github.com/landru29/gogis" // "github.com/landru29/gogis/ewkb" // ) ctx := context.Background() // Connect to database. db, err := sql.Open("postgres", "postgresql://tester:tester@localhost/test?sslmode=disable") //nolint: varnamelen if err != nil { panic(err) } // Prepare the query. rows, err := db.QueryContext(ctx, ` SELECT coordinate FROM geometries `) if err != nil { panic(err) } if err := rows.Err(); err != nil { panic(err) } defer func() { _ = rows.Close() }() output := []gogis.LineString{} // Read data. for rows.Next() { pnt := gogis.NullLineString{} err = rows.Scan(&pnt) if err != nil { panic(err) } if pnt.Valid { output = append(output, pnt.LineString) } } // Display the result. fmt.Println(output) }
Output:
Example (ScanPoint) ¶
package main import ( "context" "database/sql" "fmt" "github.com/landru29/gogis" ) func main() { //nolint: wsl,nosnakecase,testableexamples // Launch database: // $> docker run --name db -p 5432:5432 -e POSTGRES_PASSWORD=tester -e POSTGRES_USER=tester -e POSTGRES_DB=test -d postgis/postgis:15-master // // Create the table: // $> docker exec -i db psql -h 0.0.0.0 -p 5432 -U tester -d test -c "CREATE TABLE IF NOT EXISTS geometries (coordinate GEOMETRY);" -t // // Insert data: // $> docker exec -i db psql -h 0.0.0.0 -p 5432 -U tester -d test -c "INSERT INTO geometries(coordinate) VALUES (ST_GeomFromText('POINT ZM(10 20 30 50)', 4326))" -t // // Do not forget the imports: // import ( // "context" // "database/sql" // _ "github.com/lib/pq" // "github.com/landru29/gogis" // "github.com/landru29/gogis/ewkb" // ) ctx := context.Background() // Connect to database. db, err := sql.Open("postgres", "postgresql://tester:tester@localhost/test?sslmode=disable") //nolint: varnamelen if err != nil { panic(err) } // Prepare the query. rows, err := db.QueryContext(ctx, ` SELECT coordinate FROM geometries `) if err != nil { panic(err) } if err := rows.Err(); err != nil { panic(err) } defer func() { _ = rows.Close() }() output := []gogis.Point{} // Read data. for rows.Next() { pnt := gogis.NullPoint{} err = rows.Scan(&pnt) if err != nil { panic(err) } if pnt.Valid { output = append(output, pnt.Point) } } // Display the result. fmt.Println(output) }
Output:
Index ¶
- func AppendWellKnownBinding(binding Binding)
- func WithGeometry(geometry ...ModelConverter) func(interface{})
- func WithSystemReferenceID(srid ewkb.SystemReferenceID) func(interface{})
- func WithWellKnownGeometry(binding ...Binding) func(interface{})
- type BindSet
- type Binding
- type CircularString
- type Geometry
- type GeometryArray
- type GeometryCollection
- func (g *GeometryCollection) FromEWKB(from interface{}) error
- func (g GeometryCollection) Geometry(opts ...func(interface{})) Geometry
- func (g *GeometryCollection) Scan(value interface{}) error
- func (g GeometryCollection) ToEWKB() ewkb.Geometry
- func (g GeometryCollection) Value() (driver.Value, error)
- type LineString
- type ModelConverter
- type MultiLineString
- type MultiPoint
- type MultiPolygon
- type NullCircularString
- type NullLineString
- type NullMultiLineString
- type NullMultiPoint
- type NullMultiPolygon
- type NullPoint
- type NullPolygon
- type NullTriangle
- type Point
- type Polygon
- type Triangle
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AppendWellKnownBinding ¶ added in v1.2.0
func AppendWellKnownBinding(binding Binding)
AppendWellKnownBinding add new binding to the globazl list.
func WithGeometry ¶ added in v1.1.0
func WithGeometry(geometry ...ModelConverter) func(interface{})
WithGeometry adds geometry to the collection.
func WithSystemReferenceID ¶ added in v1.1.0
func WithSystemReferenceID(srid ewkb.SystemReferenceID) func(interface{})
WithSystemReferenceID specifies the system reference ID.
func WithWellKnownGeometry ¶ added in v0.0.1
func WithWellKnownGeometry(binding ...Binding) func(interface{})
WithWellKnownGeometry add custom Geometry to the wellknown.
Types ¶
type BindSet ¶ added in v1.1.0
type BindSet []Binding
BindSet is a set of bindings.
func DefaultWellKnownBinding ¶ added in v1.1.0
func DefaultWellKnownBinding() BindSet
DefaultWellKnownBinding is the default binding.
type Binding ¶ added in v1.1.0
type Binding struct {
// contains filtered or unexported fields
}
Binding is a type binding.
type CircularString ¶ added in v0.0.8
type CircularString []Point
CircularString is CIRCULARSTRING in database.
func (*CircularString) FromEWKB ¶ added in v1.1.0
func (c *CircularString) FromEWKB(from interface{}) error
FromEWKB implements the ModelConverter interface.
func (CircularString) Geometry ¶ added in v1.2.0
func (c CircularString) Geometry(opts ...func(interface{})) Geometry
Geometry converts to a generic geometry.
func (*CircularString) Scan ¶ added in v0.0.8
func (c *CircularString) Scan(value interface{}) error
Scan implements the SQL driver.Scanner interface.
func (CircularString) ToEWKB ¶ added in v1.1.0
func (c CircularString) ToEWKB() ewkb.Geometry
ToEWKB implements the ModelConverter interface.
type Geometry ¶ added in v0.0.1
type Geometry struct { Type ewkb.GeometryType Geometry interface{} Valid bool // contains filtered or unexported fields }
Geometry is any PostGIS geometry. This is used when user doesn't know which geometry to retrieve from database.
func NewGeometry ¶ added in v0.0.1
func NewGeometry(opts ...func(interface{})) *Geometry
NewGeometry creates a new Geometry.
type GeometryArray ¶ added in v1.2.0
type GeometryArray []Geometry
GeometryArray is an array of geometries.
func (*GeometryArray) Scan ¶ added in v1.2.0
func (g *GeometryArray) Scan(value interface{}) error
Scan implements the SQL driver.Scanner interface.
type GeometryCollection ¶ added in v1.1.0
type GeometryCollection struct { Collection []ModelConverter Valid bool SRID *ewkb.SystemReferenceID // contains filtered or unexported fields }
GeometryCollection is a lat lng position in database.
func NewGeometryCollection ¶ added in v1.1.0
func NewGeometryCollection(opts ...func(interface{})) *GeometryCollection
NewGeometryCollection creates a new empty collection.
func (*GeometryCollection) FromEWKB ¶ added in v1.1.0
func (g *GeometryCollection) FromEWKB(from interface{}) error
FromEWKB implements the ModelConverter interface.
func (GeometryCollection) Geometry ¶ added in v1.2.0
func (g GeometryCollection) Geometry(opts ...func(interface{})) Geometry
Geometry converts to a generic geometry.
func (*GeometryCollection) Scan ¶ added in v1.1.0
func (g *GeometryCollection) Scan(value interface{}) error
Scan implements the SQL driver.Scanner interface.
func (GeometryCollection) ToEWKB ¶ added in v1.1.0
func (g GeometryCollection) ToEWKB() ewkb.Geometry
ToEWKB implements the ModelConverter interface.
type LineString ¶ added in v0.0.5
type LineString []Point
LineString is LINESTRING in database.
func (*LineString) FromEWKB ¶ added in v1.1.0
func (l *LineString) FromEWKB(from interface{}) error
FromEWKB implements the ModelConverter interface.
func (LineString) Geometry ¶ added in v1.2.0
func (l LineString) Geometry(opts ...func(interface{})) Geometry
Geometry converts to a generic geometry.
func (*LineString) Scan ¶ added in v0.0.5
func (l *LineString) Scan(value interface{}) error
Scan implements the SQL driver.Scanner interface.
func (LineString) ToEWKB ¶ added in v1.1.0
func (l LineString) ToEWKB() ewkb.Geometry
ToEWKB implements the ModelConverter interface.
type ModelConverter ¶ added in v1.1.0
type ModelConverter interface { // FromEWKB converts EWKB data type to model. FromEWKB(geometry interface{}) error // ToEWKB converts model to EWKB. ToEWKB() ewkb.Geometry }
ModelConverter is the converter from EWKB to Model.
type MultiLineString ¶ added in v0.0.8
type MultiLineString []LineString
MultiLineString is MULTILINESTRING in database.
func (*MultiLineString) FromEWKB ¶ added in v1.1.0
func (m *MultiLineString) FromEWKB(from interface{}) error
FromEWKB implements the ModelConverter interface.
func (MultiLineString) Geometry ¶ added in v1.2.0
func (m MultiLineString) Geometry(opts ...func(interface{})) Geometry
Geometry converts to a generic geometry.
func (*MultiLineString) Scan ¶ added in v0.0.8
func (m *MultiLineString) Scan(value interface{}) error
Scan implements the SQL driver.Scanner interface.
func (MultiLineString) ToEWKB ¶ added in v1.1.0
func (m MultiLineString) ToEWKB() ewkb.Geometry
ToEWKB implements the ModelConverter interface.
type MultiPoint ¶ added in v0.0.8
type MultiPoint []Point
MultiPoint is MULTIPOINT in database.
func (*MultiPoint) FromEWKB ¶ added in v1.1.0
func (m *MultiPoint) FromEWKB(from interface{}) error
FromEWKB implements the ModelConverter interface.
func (MultiPoint) Geometry ¶ added in v1.2.0
func (m MultiPoint) Geometry(opts ...func(interface{})) Geometry
Geometry converts to a generic geometry.
func (*MultiPoint) Scan ¶ added in v0.0.8
func (m *MultiPoint) Scan(value interface{}) error
Scan implements the SQL driver.Scanner interface.
func (MultiPoint) ToEWKB ¶ added in v1.1.0
func (m MultiPoint) ToEWKB() ewkb.Geometry
ToEWKB implements the ModelConverter interface.
type MultiPolygon ¶ added in v0.0.8
type MultiPolygon []Polygon
MultiPolygon is MULTIPOLYGON in database.
func (*MultiPolygon) FromEWKB ¶ added in v1.1.0
func (p *MultiPolygon) FromEWKB(from interface{}) error
FromEWKB implements the ModelConverter interface.
func (MultiPolygon) Geometry ¶ added in v1.2.0
func (p MultiPolygon) Geometry(opts ...func(interface{})) Geometry
Geometry converts to a generic geometry.
func (*MultiPolygon) Scan ¶ added in v0.0.8
func (p *MultiPolygon) Scan(value interface{}) error
Scan implements the SQL driver.Scanner interface.
func (MultiPolygon) ToEWKB ¶ added in v1.1.0
func (p MultiPolygon) ToEWKB() ewkb.Geometry
ToEWKB implements the ModelConverter interface.
type NullCircularString ¶ added in v0.0.8
type NullCircularString struct { CircularString CircularString Valid bool }
NullCircularString represents a CircularString that may be null. NullCircularString implements the SQL driver.Scanner interface so it can be used as a scan destination:
var circle gogis.NullCircularString err := db.QueryRow("SELECT coordinate FROM foo WHERE id=?", id).Scan(&circle) ... if circle.Valid { // use circle.CircularString } else { // NULL value }
func (*NullCircularString) Scan ¶ added in v0.0.8
func (c *NullCircularString) Scan(value interface{}) error
Scan implements the SQL driver.Scanner interface.
type NullLineString ¶ added in v0.0.5
type NullLineString struct { LineString LineString Valid bool }
NullLineString represents a LineString that may be null. NullLineString implements the SQL driver.Scanner interface so it can be used as a scan destination:
var line gogis.NullLineString err := db.QueryRow("SELECT coordinate FROM foo WHERE id=?", id).Scan(&line) ... if line.Valid { // use line.LineString } else { // NULL value }
func (*NullLineString) Scan ¶ added in v0.0.5
func (l *NullLineString) Scan(value interface{}) error
Scan implements the SQL driver.Scanner interface.
type NullMultiLineString ¶ added in v0.0.8
type NullMultiLineString struct { MultiLineString MultiLineString Valid bool }
NullMultiLineString represents a MultiLineString that may be null. NullMultiLineString implements the SQL driver.Scanner interface so it can be used as a scan destination:
var multi gogis.NullMultiLineString err := db.QueryRow("SELECT coordinate FROM foo WHERE id=?", id).Scan(&multi) ... if multi.Valid { // use multi.MultiLineString } else { // NULL value }
func (*NullMultiLineString) Scan ¶ added in v0.0.8
func (m *NullMultiLineString) Scan(value interface{}) error
Scan implements the SQL driver.Scanner interface.
type NullMultiPoint ¶ added in v0.0.8
type NullMultiPoint struct { MultiPoint MultiPoint Valid bool }
NullMultiPoint represents a MultiPoint that may be null. NullMultiPoint implements the SQL driver.Scanner interface so it can be used as a scan destination:
var multi gogis.NullMultiPoint err := db.QueryRow("SELECT coordinate FROM foo WHERE id=?", id).Scan(&multi) ... if multi.Valid { // use multi.MultiPoint } else { // NULL value }
func (*NullMultiPoint) Scan ¶ added in v0.0.8
func (m *NullMultiPoint) Scan(value interface{}) error
Scan implements the SQL driver.Scanner interface.
type NullMultiPolygon ¶ added in v0.0.8
type NullMultiPolygon struct { MultiPolygon MultiPolygon Valid bool }
NullMultiPolygon represents a MultiPolygon that may be null. NullMultiPolygon implements the SQL driver.Scanner interface so it can be used as a scan destination:
var multi gogis.NullMultiPolygon err := db.QueryRow("SELECT coordinate FROM foo WHERE id=?", id).Scan(&multi) ... if multi.Valid { // use multi.MultiPolygon } else { // NULL value }
func (*NullMultiPolygon) Scan ¶ added in v0.0.8
func (p *NullMultiPolygon) Scan(value interface{}) error
Scan implements the SQL driver.Scanner interface.
type NullPoint ¶
NullPoint represents a Point that may be null. NullPoint implements the SQL driver.Scanner interface so it can be used as a scan destination:
var pt gogis.NullPoint err := db.QueryRow("SELECT coordinate FROM foo WHERE id=?", id).Scan(&pt) ... if pt.Valid { // use pt.Point } else { // NULL value }
type NullPolygon ¶ added in v0.0.1
NullPolygon represents a Polygon that may be null. NullPolygon implements the SQL driver.Scanner interface so it can be used as a scan destination:
var poly gogis.NullPolygon err := db.QueryRow("SELECT coordinate FROM foo WHERE id=?", id).Scan(&poly) ... if poly.Valid { // use poly.Polygon } else { // NULL value }
func (*NullPolygon) Scan ¶ added in v0.0.1
func (p *NullPolygon) Scan(value interface{}) error
Scan implements the SQL driver.Scanner interface.
type NullTriangle ¶ added in v0.0.8
NullTriangle represents a Triangle that may be null. NullTriangle implements the SQL driver.Scanner interface so it can be used as a scan destination:
var triangle gogis.NullTriangle err := db.QueryRow("SELECT coordinate FROM foo WHERE id=?", id).Scan(&triangle) ... if triangle.Valid { // use triangle.Triangle } else { // NULL value }
func (*NullTriangle) Scan ¶ added in v0.0.8
func (t *NullTriangle) Scan(value interface{}) error
Scan implements the SQL driver.Scanner interface.
type Point ¶
Point is a lat lng position in database.
type Polygon ¶ added in v0.0.1
type Polygon []LineString
Polygon is POLYGON in database.
type Triangle ¶ added in v0.0.8
type Triangle []Point
Triangle is TRIANGLE in database.