diff --git a/pkg/controller/fence.go b/pkg/controller/fence.go index 9ed6c792..f671b6ab 100644 --- a/pkg/controller/fence.go +++ b/pkg/controller/fence.go @@ -364,12 +364,13 @@ func fenceMatchRoam( return } p := obj.CalculatedPoint() - var prevNearbys []roamMatch - if fence.roam.nearbys != nil { - prevNearbys = fence.roam.nearbys[tid] - } + prevNearbys := fence.roam.nearbys[tid] + var newNearbys map[string]bool col.Nearby(0, p.Y, p.X, fence.roam.meters, math.Inf(-1), math.Inf(+1), func(id string, obj geojson.Object, fields []float64) bool { + if c.hasExpired(fence.roam.key, id) { + return true + } var idMatch bool if id == tid { return true // skip self @@ -382,34 +383,38 @@ func fenceMatchRoam( if !idMatch { return true } + if newNearbys == nil { + newNearbys = make(map[string]bool) + } + newNearbys[id] = true + prev := prevNearbys[id] + if prev { + delete(prevNearbys, id) + } + match := roamMatch{ id: id, obj: obj, meters: obj.CalculatedPoint().DistanceTo(p), } - for i := 0; i < len(prevNearbys); i++ { - if prevNearbys[i].id == match.id { - prevNearbys[i] = prevNearbys[len(prevNearbys)-1] - prevNearbys = prevNearbys[:len(prevNearbys)-1] - i-- - break - } + if !prev || !fence.nodwell { + // brand new "nearby" + nearbys = append(nearbys, match) } - nearbys = append(nearbys, match) return true }, ) - for i := 0; i < len(prevNearbys); i++ { - obj, _, ok := col.Get(prevNearbys[i].id) - if ok { + for id := range prevNearbys { + obj, _, ok := col.Get(id) + if ok && !c.hasExpired(fence.roam.key, id) { faraways = append(faraways, roamMatch{ - id: prevNearbys[i].id, - obj: obj, + id: id, obj: obj, meters: obj.CalculatedPoint().DistanceTo(p), }) } } - if len(nearbys) == 0 { + + if len(newNearbys) == 0 { if fence.roam.nearbys != nil { delete(fence.roam.nearbys, tid) if len(fence.roam.nearbys) == 0 { @@ -418,9 +423,9 @@ func fenceMatchRoam( } } else { if fence.roam.nearbys == nil { - fence.roam.nearbys = make(map[string][]roamMatch) + fence.roam.nearbys = make(map[string]map[string]bool) } - fence.roam.nearbys[tid] = nearbys + fence.roam.nearbys[tid] = newNearbys } return } diff --git a/pkg/controller/search.go b/pkg/controller/search.go index 7f7e40b7..63c2aca7 100644 --- a/pkg/controller/search.go +++ b/pkg/controller/search.go @@ -35,7 +35,7 @@ type roamSwitches struct { pattern bool meters float64 scan string - nearbys map[string][]roamMatch + nearbys map[string]map[string]bool } type roamMatch struct { diff --git a/pkg/controller/token.go b/pkg/controller/token.go index 0549cfb3..6b691616 100644 --- a/pkg/controller/token.go +++ b/pkg/controller/token.go @@ -233,6 +233,7 @@ type searchScanBaseTokens struct { lineout string fence bool distance bool + nodwell bool detect map[string]bool accept map[string]bool glob string @@ -535,6 +536,14 @@ func (c *Controller) parseSearchScanBaseTokens( } } continue + case "nodwell": + vs = nvs + if t.desc || asc { + err = errDuplicateArgument(strings.ToUpper(wtok)) + return + } + t.nodwell = true + continue case "desc": vs = nvs if t.desc || asc {