From 128d8d3a2f469927620f717a2f34d1aafdbbf4ab Mon Sep 17 00:00:00 2001 From: kuznetsovin Date: Tue, 24 Nov 2020 10:15:46 +0300 Subject: [PATCH] Append bounds method --- geos/geom.go | 50 +++++++++++++++++++++++++++++++++++++++++++++++ geos/geom_test.go | 18 +++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/geos/geom.go b/geos/geom.go index 964bcd3..416b8eb 100644 --- a/geos/geom.go +++ b/geos/geom.go @@ -846,6 +846,56 @@ func (g *Geometry) RelatePat(other *Geometry, pat string) (bool, error) { return boolFromC("RelatePat", cGEOSRelatePattern(g.g, other.g, cs)) } +type Bounds struct { + MinX float64 + MinY float64 + MaxX float64 + MaxY float64 +} + +var NilBounds = Bounds{1e20, 1e20, -1e20, -1e20} + +// Bounds returns (minx, miny, maxx, maxy) that bounds the object. +func (g *Geometry) Bounds() (Bounds, error) { + geom, err := g.Envelope() + if err != nil { + return NilBounds, Error() + } + + s, err := geom.Shell() + if err != nil { + return NilBounds, Error() + } + c, err := s.Coords() + if err != nil { + return NilBounds, Error() + } + + minx := 1.e+20 + maxx := -1e+20 + miny := 1.e+20 + maxy := -1e+20 + + for _, cd := range c { + if cd.X < minx { + minx = cd.X + } + if cd.X > maxx { + maxx = cd.X + } + + if cd.Y < miny { + miny = cd.Y + } + if cd.Y > maxy { + maxy = cd.Y + } + } + + return Bounds{minx, miny, maxx, maxy}, nil +} + + // various wrappers around C API type unaryTopo func(*C.GEOSGeometry) *C.GEOSGeometry diff --git a/geos/geom_test.go b/geos/geom_test.go index f6cc491..259b72c 100644 --- a/geos/geom_test.go +++ b/geos/geom_test.go @@ -1063,3 +1063,21 @@ func TestLineInterpolatePoint(t *testing.T) { } } } + +func TestBounds(t *testing.T) { + testPolygon := "POLYGON((17672.0337 9338.1706,17685.6852 9298.5111,17749.098 9319.1397,17742.66 9339.25,17738.74 9342.61,17735.94 9342.4,17732.42 9340.1,17731.2 9340.32,17729.03 9341.35,17720.35 9348.95,17716.3509 9352.6934,17672.0337 9338.1706))" + exampleBounds := Bounds{MinX: 17672.0337, MinY: 9298.5111, MaxX: 17749.098, MaxY: 9352.6934} + p, err := FromWKT(testPolygon) + if err != nil { + t.Fatal(err) + } + + bt, err := p.Bounds() + if err != nil { + t.Fatal(err) + } + + if bt != exampleBounds { + t.Errorf("Bounds are not equal %v != %v", bt, exampleBounds) + } +}