From 951fc58e025c7f0206f18b36e094ac29b9ac15ec Mon Sep 17 00:00:00 2001 From: tidwall Date: Wed, 25 Mar 2020 15:35:31 -0700 Subject: [PATCH] Match geometry indexing to server config --- internal/clip/clip.go | 16 +++++++++------- internal/clip/clip_test.go | 4 ++-- internal/clip/collection.go | 8 ++++++-- internal/clip/feature.go | 8 ++++++-- internal/clip/linestring.go | 3 ++- internal/clip/point.go | 9 +++++++-- internal/clip/polygon.go | 3 ++- internal/clip/rect.go | 8 +++++--- internal/server/scanner.go | 2 +- internal/server/server.go | 6 ++++++ internal/server/test.go | 2 +- 11 files changed, 47 insertions(+), 22 deletions(-) diff --git a/internal/clip/clip.go b/internal/clip/clip.go index 92a88a46..88797266 100644 --- a/internal/clip/clip.go +++ b/internal/clip/clip.go @@ -6,20 +6,22 @@ import ( ) // Clip clips the contents of a geojson object and return -func Clip(obj geojson.Object, clipper geojson.Object) (clipped geojson.Object) { +func Clip( + obj geojson.Object, clipper geojson.Object, opts *geometry.IndexOptions, +) (clipped geojson.Object) { switch obj := obj.(type) { case *geojson.Point: - return clipPoint(obj, clipper) + return clipPoint(obj, clipper, opts) case *geojson.Rect: - return clipRect(obj, clipper) + return clipRect(obj, clipper, opts) case *geojson.LineString: - return clipLineString(obj, clipper) + return clipLineString(obj, clipper, opts) case *geojson.Polygon: - return clipPolygon(obj, clipper) + return clipPolygon(obj, clipper, opts) case *geojson.Feature: - return clipFeature(obj, clipper) + return clipFeature(obj, clipper, opts) case geojson.Collection: - return clipCollection(obj, clipper) + return clipCollection(obj, clipper, opts) } return obj } diff --git a/internal/clip/clip_test.go b/internal/clip/clip_test.go index a0bba35e..ef9953a9 100644 --- a/internal/clip/clip_test.go +++ b/internal/clip/clip_test.go @@ -27,7 +27,7 @@ func TestClipLineStringSimple(t *testing.T) { {X: 1, Y: 1}, {X: 2, Y: 2}, {X: 3, Y: 1}}) - clipped := Clip(ls, RO(1.5, 0.5, 2.5, 1.8)) + clipped := Clip(ls, RO(1.5, 0.5, 2.5, 1.8), nil) cl, ok := clipped.(*geojson.MultiLineString) if !ok { t.Fatal("wrong type") @@ -56,7 +56,7 @@ func TestClipPolygonSimple(t *testing.T) { }, } polygon := PPO(exterior, holes) - clipped := Clip(polygon, RO(1.3, 1.3, 1.4, 2.15)) + clipped := Clip(polygon, RO(1.3, 1.3, 1.4, 2.15), nil) cp, ok := clipped.(*geojson.Polygon) if !ok { t.Fatal("wrong type") diff --git a/internal/clip/collection.go b/internal/clip/collection.go index dc713a52..6758ff1f 100644 --- a/internal/clip/collection.go +++ b/internal/clip/collection.go @@ -1,13 +1,17 @@ package clip -import "github.com/tidwall/geojson" +import ( + "github.com/tidwall/geojson" + "github.com/tidwall/geojson/geometry" +) func clipCollection( collection geojson.Collection, clipper geojson.Object, + opts *geometry.IndexOptions, ) geojson.Object { var features []geojson.Object for _, feature := range collection.Children() { - feature = Clip(feature, clipper) + feature = Clip(feature, clipper, opts) if feature.Empty() { continue } diff --git a/internal/clip/feature.go b/internal/clip/feature.go index 2e50f506..59cf10a4 100644 --- a/internal/clip/feature.go +++ b/internal/clip/feature.go @@ -1,11 +1,15 @@ package clip -import "github.com/tidwall/geojson" +import ( + "github.com/tidwall/geojson" + "github.com/tidwall/geojson/geometry" +) func clipFeature( feature *geojson.Feature, clipper geojson.Object, + opts *geometry.IndexOptions, ) geojson.Object { - newFeature := Clip(feature.Base(), clipper) + newFeature := Clip(feature.Base(), clipper, opts) if _, ok := newFeature.(*geojson.Feature); !ok { newFeature = geojson.NewFeature(newFeature, feature.Members()) } diff --git a/internal/clip/linestring.go b/internal/clip/linestring.go index 5cc06964..b173da1f 100644 --- a/internal/clip/linestring.go +++ b/internal/clip/linestring.go @@ -7,6 +7,7 @@ import ( func clipLineString( lineString *geojson.LineString, clipper geojson.Object, + opts *geometry.IndexOptions, ) geojson.Object { bbox := clipper.Rect() var newPoints [][]geometry.Point @@ -34,7 +35,7 @@ func clipLineString( var children []*geometry.Line for _, points := range newPoints { children = append(children, - geometry.NewLine(points, nil)) + geometry.NewLine(points, opts)) } if len(children) == 1 { return geojson.NewLineString(children[0]) diff --git a/internal/clip/point.go b/internal/clip/point.go index cf6de5c0..b1c34be9 100644 --- a/internal/clip/point.go +++ b/internal/clip/point.go @@ -1,8 +1,13 @@ package clip -import "github.com/tidwall/geojson" +import ( + "github.com/tidwall/geojson" + "github.com/tidwall/geojson/geometry" +) -func clipPoint(point *geojson.Point, clipper geojson.Object) geojson.Object { +func clipPoint( + point *geojson.Point, clipper geojson.Object, opts *geometry.IndexOptions, +) geojson.Object { if point.IntersectsRect(clipper.Rect()) { return point } diff --git a/internal/clip/polygon.go b/internal/clip/polygon.go index a2bebe4d..a49687b4 100644 --- a/internal/clip/polygon.go +++ b/internal/clip/polygon.go @@ -7,6 +7,7 @@ import ( func clipPolygon( polygon *geojson.Polygon, clipper geojson.Object, + opts *geometry.IndexOptions, ) geojson.Object { rect := clipper.Rect() var newPoints [][]geometry.Point @@ -30,7 +31,7 @@ func clipPolygon( holes = newPoints[1:] } newPoly := geojson.NewPolygon( - geometry.NewPoly(exterior, holes, nil), + geometry.NewPoly(exterior, holes, opts), ) if newPoly.Empty() { return geojson.NewMultiPolygon(nil) diff --git a/internal/clip/rect.go b/internal/clip/rect.go index b3944824..917b615b 100644 --- a/internal/clip/rect.go +++ b/internal/clip/rect.go @@ -5,13 +5,15 @@ import ( "github.com/tidwall/geojson/geometry" ) -func clipRect(rect *geojson.Rect, clipper geojson.Object) geojson.Object { +func clipRect( + rect *geojson.Rect, clipper geojson.Object, opts *geometry.IndexOptions, +) geojson.Object { base := rect.Base() points := make([]geometry.Point, base.NumPoints()) for i := 0; i < len(points); i++ { points[i] = base.PointAt(i) } - poly := geometry.NewPoly(points, nil, nil) + poly := geometry.NewPoly(points, nil, opts) gPoly := geojson.NewPolygon(poly) - return Clip(gPoly, clipper) + return Clip(gPoly, clipper, opts) } diff --git a/internal/server/scanner.go b/internal/server/scanner.go index bfa6f176..46813750 100644 --- a/internal/server/scanner.go +++ b/internal/server/scanner.go @@ -368,7 +368,7 @@ func (sw *scanWriter) writeObject(opts ScanWriterParams) bool { return sw.count < sw.limit } if opts.clip != nil { - opts.o = clip.Clip(opts.o, opts.clip) + opts.o = clip.Clip(opts.o, opts.clip, &sw.s.geomIndexOpts) } switch sw.msg.OutputType { case JSON: diff --git a/internal/server/server.go b/internal/server/server.go index f3939e50..a68f9099 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -80,6 +80,7 @@ type Server struct { // env opts geomParseOpts geojson.ParseOptions + geomIndexOpts geometry.IndexOptions // atomics followc aint // counter increases when follow property changes @@ -178,9 +179,11 @@ func Serve(host string, port int, dir string, http bool) error { // T38IDXGEOM -- Min number of points in a geometry for indexing. // T38IDXMULTI -- Min number of object in a Multi/Collection for indexing. server.geomParseOpts = *geojson.DefaultParseOptions + server.geomIndexOpts = *geometry.DefaultIndexOptions n, err := strconv.ParseUint(os.Getenv("T38IDXGEOM"), 10, 32) if err == nil { server.geomParseOpts.IndexGeometry = int(n) + server.geomIndexOpts.MinPoints = int(n) } n, err = strconv.ParseUint(os.Getenv("T38IDXMULTI"), 10, 32) if err == nil { @@ -197,10 +200,13 @@ func Serve(host string, port int, dir string, http bool) error { case "": case "None": server.geomParseOpts.IndexGeometryKind = geometry.None + server.geomIndexOpts.Kind = geometry.None case "RTree": server.geomParseOpts.IndexGeometryKind = geometry.RTree + server.geomIndexOpts.Kind = geometry.RTree case "QuadTree": server.geomParseOpts.IndexGeometryKind = geometry.QuadTree + server.geomIndexOpts.Kind = geometry.QuadTree } if server.geomParseOpts.IndexGeometryKind == geometry.None { log.Debugf("Geom indexing: %s", diff --git a/internal/server/test.go b/internal/server/test.go index e276367c..b5f302ca 100644 --- a/internal/server/test.go +++ b/internal/server/test.go @@ -280,7 +280,7 @@ func (s *Server) cmdTest(msg *Message) (res resp.Value, err error) { if area1.IntersectsExpr(area2) { result = 1 if doClip { - clipped = clip.Clip(area1.obj, area2.obj) + clipped = clip.Clip(area1.obj, area2.obj, nil) } } }