func (p WOFPointInPolygon) LoadPolygonsForFeature(feature *geojson.WOFFeature) ([]*geojson.WOFPolygon, error) { id := feature.Id() polygons := feature.GeomToPolygons() var points int for _, pl := range polygons { points += pl.CountPoints() } p.Logger.Debug("%d has %d points", id, points) if points >= p.CacheTrigger { p.Logger.Debug("caching %d because it has E_EXCESSIVE_POINTS (%d)", id, points) var c metrics.Counter c = *p.Metrics.CountCacheSet evicted := p.Cache.Add(id, polygons) if evicted == true { cache_size := p.CacheSize cache_set := c.Count() p.Logger.Warning("starting to push thing out of the cache %d sets on a cache size of %d", cache_set, cache_size) } go c.Inc(1) } return polygons, nil }
func (idx *WOFIndex) LoadPolygonsForFeature(feature *geojson.WOFFeature) ([]*geojson.WOFPolygon, error) { id := feature.Id() polygons := feature.GeomToPolygons() var points int for _, pl := range polygons { points += pl.CountPoints() } idx.Logger.Debug("%d has %d points", id, points) if points >= idx.CacheTrigger { idx.Logger.Debug("caching %d because it has E_EXCESSIVE_POINTS (%d)", id, points) evicted := idx.Cache.Add(id, polygons) if evicted == true { idx.Logger.Warning("starting to push thing out of the cache") } } return polygons, nil }
func (idx *Index) Breaches(feature *geojson.WOFFeature) ([]*geojson.WOFSpatial, error) { clipping, err := feature.EnSpatialize() if err != nil { return nil, err } breaches := make([]*geojson.WOFSpatial, 0) bounds := clipping.Bounds() results := idx.GetIntersectsByRect(bounds) // idx.Logger.Info("possible results for %v : %d", bounds, len(results)) if len(results) > 0 { t1 := time.Now() clipping_polys := feature.GeomToPolygons() idx.Logger.Debug("compare %d polys from clipping against %d possible subjects", len(clipping_polys), len(results)) // See what's going on here? We are *not* relying on the standard Inflate method // but rather bucketing all the WOFSpatials by their WOF ID (this is because the // (WOF) rtree package indexes the bounding boxes of individual polygons on the // geom rather than the bounding box of the set of polygons) which we we will // loop over below (20151130/thisisaaronland) inflated := make(map[int][]*geojson.WOFSpatial) for _, r := range results { wof := r.(*geojson.WOFSpatial) wofid := wof.Id _, ok := inflated[wofid] possible := make([]*geojson.WOFSpatial, 0) if ok { possible = inflated[wofid] } possible = append(possible, wof) inflated[wofid] = possible } for wofid, possible := range inflated { if wofid == feature.WOFId() { idx.Logger.Debug("%d can not breach itself, skipping", wofid) continue } // Despite the notes about goroutines and yak-shaving below this is probably // a pretty good place to do things concurrently (21051130/thisisaaronland) subject_polys, err := idx.LoadPolygons(possible[0]) if err != nil { idx.Logger.Warning("Unable to load polygons for ID %d, because %v", wofid, err) continue } idx.Logger.Debug("testing %d with %d possible candidates", wofid, len(possible)) // Note to self: it turns out that goroutine-ing these operations is yak-shaving // and often slower (20151130/thisisaaronland) for i, subject := range possible { idx.Logger.Debug("testing %d (offset %d) with candidate %d", wofid, subject.Offset, i) test_polys := make([]*geojson.WOFPolygon, 0) if subject.Offset == -1 { test_polys = subject_polys } else { test_polys = append(test_polys, subject_polys[subject.Offset]) } intersects, err := idx.Intersects(clipping_polys, test_polys) if err != nil { idx.Logger.Error("Failed to determine intersection, because %v", err) continue } if intersects { breaches = append(breaches, subject) idx.Logger.Debug("determined that %d breaches after %d/%d iterations", wofid, i, len(possible)) break } } } t2 := time.Since(t1) idx.Logger.Debug("time to test %d possible results: %v", len(results), t2) } return breaches, nil }