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
This commit is contained in:
tidwall 2021-09-26 06:09:43 -07:00
parent 4f4e168445
commit de59d23ac4
3 changed files with 18 additions and 18 deletions

View File

@ -183,10 +183,7 @@ func (server *Server) cmdGet(msg *Message) (resp.Value, error) {
buf.Write(appendJSONSimplePoint(nil, o)) buf.Write(appendJSONSimplePoint(nil, o))
} else { } else {
point := o.Center() point := o.Center()
var z float64 z := extractZCoordinate(o)
if gPoint, ok := o.(*geojson.Point); ok {
z = gPoint.Z()
}
if z != 0 { if z != 0 {
vals = append(vals, resp.ArrayValue([]resp.Value{ vals = append(vals, resp.ArrayValue([]resp.Value{
resp.StringValue(strconv.FormatFloat(point.Y, 'f', -1, 64)), resp.StringValue(strconv.FormatFloat(point.Y, 'f', -1, 64)),

View File

@ -133,10 +133,7 @@ func appendJSONSimpleBounds(dst []byte, o geojson.Object) []byte {
func appendJSONSimplePoint(dst []byte, o geojson.Object) []byte { func appendJSONSimplePoint(dst []byte, o geojson.Object) []byte {
point := o.Center() point := o.Center()
var z float64 z := extractZCoordinate(o)
if gPoint, ok := o.(*geojson.Point); ok {
z = gPoint.Z()
}
dst = append(dst, `{"lat":`...) dst = append(dst, `{"lat":`...)
dst = strconv.AppendFloat(dst, point.Y, 'f', -1, 64) dst = strconv.AppendFloat(dst, point.Y, 'f', -1, 64)
dst = append(dst, `,"lon":`...) dst = append(dst, `,"lon":`...)

View File

@ -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) { func (sw *scanWriter) fieldMatch(fields []float64, o geojson.Object) (fvals []float64, match bool) {
var z float64 var z float64
var gotz bool var gotz bool
@ -222,9 +235,7 @@ func (sw *scanWriter) fieldMatch(fields []float64, o geojson.Object) (fvals []fl
for _, where := range sw.wheres { for _, where := range sw.wheres {
if where.field == "z" { if where.field == "z" {
if !gotz { if !gotz {
if point, ok := o.(*geojson.Point); ok { z = extractZCoordinate(o)
z = point.Z()
}
} }
if !where.match(z) { if !where.match(z) {
return return
@ -270,9 +281,7 @@ func (sw *scanWriter) fieldMatch(fields []float64, o geojson.Object) (fvals []fl
for _, where := range sw.wheres { for _, where := range sw.wheres {
if where.field == "z" { if where.field == "z" {
if !gotz { if !gotz {
if point, ok := o.(*geojson.Point); ok { z = extractZCoordinate(o)
z = point.Z()
}
} }
if !where.match(z) { if !where.match(z) {
return return
@ -455,10 +464,7 @@ func (sw *scanWriter) writeObject(opts ScanWriterParams) bool {
vals = append(vals, resp.StringValue(opts.o.String())) vals = append(vals, resp.StringValue(opts.o.String()))
case outputPoints: case outputPoints:
point := opts.o.Center() point := opts.o.Center()
var z float64 z := extractZCoordinate(opts.o)
if point, ok := opts.o.(*geojson.Point); ok {
z = point.Z()
}
if z != 0 { if z != 0 {
vals = append(vals, resp.ArrayValue([]resp.Value{ vals = append(vals, resp.ArrayValue([]resp.Value{
resp.FloatValue(point.Y), resp.FloatValue(point.Y),