Skip to content

Commit

Permalink
snapshot
Browse files Browse the repository at this point in the history
  • Loading branch information
twpayne committed Feb 5, 2023
1 parent 568fc71 commit 8bd4a66
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ geometries and use a geometric operation that is only available in `go-geos`.
| | To `geom.T` | To `*geos.Geom` | To `orb.Geometry` |
| ------------------- | ----------- | --------------- | ----------------- |
| From `geom.T` | n/a | no | yes |
| From `*geos.Geom` | no | n/a | yes |
| From `*geos.Geom` | yes | n/a | yes |
| From `orb.Geometry` | yes | yes | n/a |

## License
Expand Down
1 change: 1 addition & 0 deletions geobabel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ func TestAll(t *testing.T) {
require.True(t, tc.geos.IsValid())
require.Equal(t, "Valid Geometry", tc.geos.IsValidReason())

assert.Equal(t, tc.geom, geobabel.NewGeomTFromGEOSGeom(tc.geos))
assert.Equal(t, tc.geom, geobabel.NewGeomTFromOrbGeometry(tc.orb))

assert.True(t, tc.geos.Equals(geobabel.NewGEOSGeomFromOrbGeometry(geosContext, tc.orb)))
Expand Down
137 changes: 137 additions & 0 deletions geomfromgeos.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package geobabel

// FIXME add a geos.Geom.Flat method and use that instead
// FIXME test non-XY layouts

import (
"fmt"

"github.com/twpayne/go-geom"
"github.com/twpayne/go-geos"
)

func NewGeomTFromGEOSGeom(geosGeom *geos.Geom) geom.T {
switch geosGeom.TypeID() {
case geos.TypeIDPoint:
return NewGeomPointFromGEOSGeom(geosGeom)
case geos.TypeIDLineString:
return NewGeomLineStringFromGEOSGeom(geosGeom)
case geos.TypeIDLinearRing:
return NewGeomLinearRingFromGEOSGeom(geosGeom)
case geos.TypeIDPolygon:
return NewGeomPolygonFromGEOSGeom(geosGeom)
case geos.TypeIDMultiPoint:
return NewGeomMultiPointFromGEOSGeom(geosGeom)
case geos.TypeIDMultiLineString:
return NewGeomMultiLineStringFromGEOSGeom(geosGeom)
case geos.TypeIDMultiPolygon:
return NewGeomMultiPolygonFromGEOSGeom(geosGeom)
case geos.TypeIDGeometryCollection:
return NewGeomGeometryCollectionFromGEOSGeom(geosGeom)
default:
panic(fmt.Sprintf("%s: unsupported GEOS type", geosGeom.Type()))
}
}

func NewGeomPointFromGEOSGeom(geosGeom *geos.Geom) *geom.Point {
geosCoordSeq := geosGeom.CoordSeq()
geomLayout := GeomLayoutFromGEOSDimensions(geosCoordSeq.Dimensions())
return geom.NewPointFlat(geomLayout, geosCoordSeq.FlatCoords())
}

func NewGeomLineStringFromGEOSGeom(geosGeom *geos.Geom) *geom.LineString {
geosCoordSeq := geosGeom.CoordSeq()
geomLayout := GeomLayoutFromGEOSDimensions(geosCoordSeq.Dimensions())
return geom.NewLineStringFlat(geomLayout, geosCoordSeq.FlatCoords())
}

func NewGeomLinearRingFromGEOSGeom(geosGeom *geos.Geom) *geom.LinearRing {
geosCoordSeq := geosGeom.CoordSeq()
geomLayout := GeomLayoutFromGEOSDimensions(geosCoordSeq.Dimensions())
return geom.NewLinearRingFlat(geomLayout, geosCoordSeq.FlatCoords())
}

func NewGeomPolygonFromGEOSGeom(geosGeom *geos.Geom) *geom.Polygon {
geosExteriorRingCoordSeq := geosGeom.ExteriorRing().CoordSeq()
geomLayout := GeomLayoutFromGEOSDimensions(geosExteriorRingCoordSeq.Dimensions())
geomFlatCoords := geosExteriorRingCoordSeq.FlatCoords()
geomEnds := []int{len(geomFlatCoords)}
for i, n := 0, geosGeom.NumInteriorRings(); i < n; i++ {
geosInteriorRing := geosGeom.InteriorRing(i)
geomFlatCoords = append(geomFlatCoords, geosInteriorRing.CoordSeq().FlatCoords()...)
geomEnds = append(geomEnds, len(geomFlatCoords))
}
return geom.NewPolygonFlat(geomLayout, geomFlatCoords, geomEnds)
}

func NewGeomMultiPointFromGEOSGeom(geosGeom *geos.Geom) *geom.MultiPoint {
geosNumGeometries := geosGeom.NumGeometries()
geomLayout := geom.XY
var geomFlatCoords []float64
for i := 0; i < geosNumGeometries; i++ {
geosCoordSeq := geosGeom.Geometry(i).CoordSeq()
geomLayout = GeomLayoutFromGEOSDimensions(geosCoordSeq.Dimensions())
geomFlatCoords = append(geomFlatCoords, geosCoordSeq.FlatCoords()...)
}
return geom.NewMultiPointFlat(geomLayout, geomFlatCoords)
}

func NewGeomMultiLineStringFromGEOSGeom(geosGeom *geos.Geom) *geom.MultiLineString {
geosNumGeometries := geosGeom.NumGeometries()
geomLayout := geom.XY
var geomFlatCoords []float64
geomEnds := make([]int, 0, geosNumGeometries)
for i := 0; i < geosNumGeometries; i++ {
geosCoordSeq := geosGeom.Geometry(i).CoordSeq()
geomLayout = GeomLayoutFromGEOSDimensions(geosCoordSeq.Dimensions())
geomFlatCoords = append(geomFlatCoords, geosCoordSeq.FlatCoords()...)
geomEnds = append(geomEnds, len(geomFlatCoords))
}
return geom.NewMultiLineStringFlat(geomLayout, geomFlatCoords, geomEnds)
}

func NewGeomMultiPolygonFromGEOSGeom(geosGeom *geos.Geom) *geom.MultiPolygon {
geosNumGeometries := geosGeom.NumGeometries()
geomLayout := geom.XY
var geomFlatCoords []float64
geomEndss := make([][]int, 0, geosNumGeometries)
for i := 0; i < geosNumGeometries; i++ {
geosPolygon := geosGeom.Geometry(i)
geosExteriorRingCoordSeq := geosPolygon.ExteriorRing().CoordSeq()
geomLayout = GeomLayoutFromGEOSDimensions(geosExteriorRingCoordSeq.Dimensions())
geomFlatCoords = append(geomFlatCoords, geosExteriorRingCoordSeq.FlatCoords()...)
geomEnds := []int{len(geomFlatCoords)}
for i, n := 0, geosGeom.NumInteriorRings(); i < n; i++ {
geosInteriorRing := geosGeom.InteriorRing(i)
geomFlatCoords = append(geomFlatCoords, geosInteriorRing.CoordSeq().FlatCoords()...)
geomEnds = append(geomEnds, len(geomFlatCoords))
}
geomEndss = append(geomEndss, geomEnds)
}
return geom.NewMultiPolygonFlat(geomLayout, geomFlatCoords, geomEndss)
}

func NewGeomGeometryCollectionFromGEOSGeom(geosGeom *geos.Geom) *geom.GeometryCollection {
geosNumGeometries := geosGeom.NumGeometries()
geomGeomTs := make([]geom.T, 0, geosNumGeometries)
for i := 0; i < geosNumGeometries; i++ {
geosGeomT := NewGeomTFromGEOSGeom(geosGeom.Geometry(i))
geomGeomTs = append(geomGeomTs, geosGeomT)
}
return geom.NewGeometryCollection().MustPush(geomGeomTs...)
}

func GeomLayoutFromGEOSDimensions(geosDimensions int) geom.Layout {
switch {
case geosDimensions == 2:
return geom.XY
case geosDimensions == 3:
return geom.XYZ
case geosDimensions == 4:
return geom.XYZM
case geosDimensions > 4:
return geom.Layout(geosDimensions)
default:
panic(fmt.Sprintf("%d: unsupported GEOS dimensions", geosDimensions))
}
}
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

replace github.com/twpayne/go-geos => ../go-geos
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKs
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/twpayne/go-geom v1.5.0 h1:seB5SE58wtTDOljFXFnyz2UmKI2SU86tRb2l4yFWH6c=
github.com/twpayne/go-geom v1.5.0/go.mod h1:Kz4sX4LtdesDQgkhsMERazLlH/NiCg90s6FPaNr0KNI=
github.com/twpayne/go-geos v0.9.0 h1:Dcgmnqyj6EeaGlq6WH3yZ2uKGQ3e/VxdnxBhWu5mXe0=
github.com/twpayne/go-geos v0.9.0/go.mod h1:ghmhzeDJuLrFJFvOXUbn+sjPukdKYh11fxaGVq3e7Hk=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
Expand Down

0 comments on commit 8bd4a66

Please sign in to comment.