mirror of https://github.com/tidwall/tile38.git
parent
0ce2dab945
commit
248ccfbe8a
|
@ -59,11 +59,12 @@ type scanWriter struct {
|
|||
}
|
||||
|
||||
type ScanWriterParams struct {
|
||||
id string
|
||||
o geojson.Object
|
||||
fields []float64
|
||||
distance float64
|
||||
noLock bool
|
||||
id string
|
||||
o geojson.Object
|
||||
fields []float64
|
||||
distance float64
|
||||
noLock bool
|
||||
ignoreGlobMatch bool
|
||||
}
|
||||
|
||||
func (c *Controller) newScanWriter(
|
||||
|
@ -294,6 +295,28 @@ func (sw *scanWriter) fieldMatch(fields []float64, o geojson.Object) (fvals []fl
|
|||
return
|
||||
}
|
||||
|
||||
func (sw *scanWriter) globMatch(id string, o geojson.Object) (ok, keepGoing bool) {
|
||||
if !sw.globEverything {
|
||||
if sw.globSingle {
|
||||
if sw.globPattern != id {
|
||||
return false, true
|
||||
}
|
||||
return true, false
|
||||
}
|
||||
var val string
|
||||
if sw.matchValues {
|
||||
val = o.String()
|
||||
} else {
|
||||
val = id
|
||||
}
|
||||
ok, _ := glob.Match(sw.globPattern, val)
|
||||
if !ok {
|
||||
return false, true
|
||||
}
|
||||
}
|
||||
return true, true
|
||||
}
|
||||
|
||||
//id string, o geojson.Object, fields []float64, noLock bool
|
||||
func (sw *scanWriter) writeObject(opts ScanWriterParams) bool {
|
||||
if !opts.noLock {
|
||||
|
@ -301,23 +324,11 @@ func (sw *scanWriter) writeObject(opts ScanWriterParams) bool {
|
|||
defer sw.mu.Unlock()
|
||||
}
|
||||
keepGoing := true
|
||||
if !sw.globEverything {
|
||||
if sw.globSingle {
|
||||
if sw.globPattern != opts.id {
|
||||
return true
|
||||
}
|
||||
keepGoing = false // return current object and stop iterating
|
||||
} else {
|
||||
var val string
|
||||
if sw.matchValues {
|
||||
val = opts.o.String()
|
||||
} else {
|
||||
val = opts.id
|
||||
}
|
||||
ok, _ := glob.Match(sw.globPattern, val)
|
||||
if !ok {
|
||||
return true
|
||||
}
|
||||
if !opts.ignoreGlobMatch {
|
||||
var match bool
|
||||
match, keepGoing = sw.globMatch(opts.id, opts.o)
|
||||
if !match {
|
||||
return true
|
||||
}
|
||||
}
|
||||
nfields, ok := sw.fieldMatch(opts.fields, opts.o)
|
||||
|
|
|
@ -328,6 +328,7 @@ func (c *Controller) cmdNearby(msg *server.Message) (res resp.Value, err error)
|
|||
}
|
||||
sw.writeHead()
|
||||
if sw.col != nil {
|
||||
var matched uint32
|
||||
iter := func(id string, o geojson.Object, fields []float64, dist *float64) bool {
|
||||
if c.hasExpired(s.key, id) {
|
||||
return true
|
||||
|
@ -342,15 +343,16 @@ func (c *Controller) cmdNearby(msg *server.Message) (res resp.Value, err error)
|
|||
}
|
||||
}
|
||||
return sw.writeObject(ScanWriterParams{
|
||||
id: id,
|
||||
o: o,
|
||||
fields: fields,
|
||||
distance: distance,
|
||||
noLock: true,
|
||||
id: id,
|
||||
o: o,
|
||||
fields: fields,
|
||||
distance: distance,
|
||||
noLock: true,
|
||||
ignoreGlobMatch: s.knn,
|
||||
})
|
||||
}
|
||||
if s.knn {
|
||||
nearestNeighbors(sw, s.lat, s.lon, iter)
|
||||
nearestNeighbors(sw, s.lat, s.lon, &matched, iter)
|
||||
} else {
|
||||
sw.col.Nearby(s.sparse, s.lat, s.lon, s.meters, minZ, maxZ,
|
||||
func(id string, o geojson.Object, fields []float64) bool {
|
||||
|
@ -374,13 +376,22 @@ type iterItem struct {
|
|||
dist float64
|
||||
}
|
||||
|
||||
func nearestNeighbors(sw *scanWriter, lat, lon float64, iter func(id string, o geojson.Object, fields []float64, dist *float64) bool) {
|
||||
func nearestNeighbors(sw *scanWriter, lat, lon float64, matched *uint32,
|
||||
iter func(id string, o geojson.Object, fields []float64, dist *float64) bool) {
|
||||
limit := int(sw.cursor + sw.limit)
|
||||
var items []iterItem
|
||||
sw.col.NearestNeighbors(lat, lon, func(id string, o geojson.Object, fields []float64) bool {
|
||||
if _, ok := sw.fieldMatch(fields, o); ok {
|
||||
dist := o.CalculatedPoint().DistanceTo(geojson.Position{X: lon, Y: lat, Z: 0})
|
||||
items = append(items, iterItem{id: id, o: o, fields: fields, dist: dist})
|
||||
if _, ok := sw.fieldMatch(fields, o); !ok {
|
||||
return true
|
||||
}
|
||||
match, keepGoing := sw.globMatch(id, o)
|
||||
if !match {
|
||||
return true
|
||||
}
|
||||
dist := o.CalculatedPoint().DistanceTo(geojson.Position{X: lon, Y: lat, Z: 0})
|
||||
items = append(items, iterItem{id: id, o: o, fields: fields, dist: dist})
|
||||
if !keepGoing {
|
||||
return false
|
||||
}
|
||||
return len(items) < limit
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue