From de59d23ac41ae5e6eeb87fa776b166de20880100 Mon Sep 17 00:00:00 2001 From: tidwall Date: Sun, 26 Sep 2021 06:09:43 -0700 Subject: [PATCH] Fixed Z not matching on where clause Feature points. This issues fixes an issue where a search command with a where clause using the "z" field would not match correctly for point that where contained inside a GeoJSON Feature type. Tile38 now extracts the Z coordinate from Point and Feature/Point types. fixes #622 --- internal/server/crud.go | 5 +---- internal/server/json.go | 5 +---- internal/server/scanner.go | 26 ++++++++++++++++---------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/internal/server/crud.go b/internal/server/crud.go index 08142c4f..4d90a700 100644 --- a/internal/server/crud.go +++ b/internal/server/crud.go @@ -183,10 +183,7 @@ func (server *Server) cmdGet(msg *Message) (resp.Value, error) { buf.Write(appendJSONSimplePoint(nil, o)) } else { point := o.Center() - var z float64 - if gPoint, ok := o.(*geojson.Point); ok { - z = gPoint.Z() - } + z := extractZCoordinate(o) if z != 0 { vals = append(vals, resp.ArrayValue([]resp.Value{ resp.StringValue(strconv.FormatFloat(point.Y, 'f', -1, 64)), diff --git a/internal/server/json.go b/internal/server/json.go index ab7fb1be..4dad895d 100644 --- a/internal/server/json.go +++ b/internal/server/json.go @@ -133,10 +133,7 @@ func appendJSONSimpleBounds(dst []byte, o geojson.Object) []byte { func appendJSONSimplePoint(dst []byte, o geojson.Object) []byte { point := o.Center() - var z float64 - if gPoint, ok := o.(*geojson.Point); ok { - z = gPoint.Z() - } + z := extractZCoordinate(o) dst = append(dst, `{"lat":`...) dst = strconv.AppendFloat(dst, point.Y, 'f', -1, 64) dst = append(dst, `,"lon":`...) diff --git a/internal/server/scanner.go b/internal/server/scanner.go index e11c14ad..d6b7955b 100644 --- a/internal/server/scanner.go +++ b/internal/server/scanner.go @@ -214,6 +214,19 @@ func (sw *scanWriter) writeFoot() { } } +func extractZCoordinate(o geojson.Object) float64 { + for { + switch g := o.(type) { + case *geojson.Point: + return g.Z() + case *geojson.Feature: + o = g.Base() + default: + return 0 + } + } +} + func (sw *scanWriter) fieldMatch(fields []float64, o geojson.Object) (fvals []float64, match bool) { var z float64 var gotz bool @@ -222,9 +235,7 @@ func (sw *scanWriter) fieldMatch(fields []float64, o geojson.Object) (fvals []fl for _, where := range sw.wheres { if where.field == "z" { if !gotz { - if point, ok := o.(*geojson.Point); ok { - z = point.Z() - } + z = extractZCoordinate(o) } if !where.match(z) { return @@ -270,9 +281,7 @@ func (sw *scanWriter) fieldMatch(fields []float64, o geojson.Object) (fvals []fl for _, where := range sw.wheres { if where.field == "z" { if !gotz { - if point, ok := o.(*geojson.Point); ok { - z = point.Z() - } + z = extractZCoordinate(o) } if !where.match(z) { return @@ -455,10 +464,7 @@ func (sw *scanWriter) writeObject(opts ScanWriterParams) bool { vals = append(vals, resp.StringValue(opts.o.String())) case outputPoints: point := opts.o.Center() - var z float64 - if point, ok := opts.o.(*geojson.Point); ok { - z = point.Z() - } + z := extractZCoordinate(opts.o) if z != 0 { vals = append(vals, resp.ArrayValue([]resp.Value{ resp.FloatValue(point.Y),