示例#1
0
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
}
示例#2
0
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
}
示例#3
0
func (p WOFPointInPolygon) IndexGeoJSONFeature(feature *geojson.WOFFeature) error {

	spatial, spatial_err := feature.EnSpatialize()

	if spatial_err != nil {

		body := feature.Body()
		geom_type, ok := body.Path("geometry.type").Data().(string)

		if ok && geom_type == "Point" {
			p.Logger.Warning("feature is a Point type so I am ignoring it...")
			return nil
		}

		p.Logger.Error("failed to enspatialize feature, because %s", spatial_err)
		return spatial_err
	}

	return p.IndexSpatialFeature(spatial)
}
示例#4
0
func (idx *WOFIndex) IndexGeoJSONFeature(feature *geojson.WOFFeature) error {

	spatial, spatial_err := feature.EnSpatializeGeom()

	if spatial_err != nil {
		idx.Logger.Error("failed to enspatialize feature, because %s", spatial_err)
		return spatial_err
	}

	for _, sf := range spatial {

		err := idx.IndexSpatialFeature(sf)

		if err != nil {
			return err
		}
	}

	return 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
}