Ejemplo n.º 1
0
func (p WOFPointInPolygon) LoadPolygons(wof *geojson.WOFSpatial) ([]*geojson.WOFPolygon, error) {

	id := wof.Id

	cache, ok := p.Cache.Get(id)

	if ok {

		var c metrics.Counter
		c = *p.Metrics.CountCacheHit
		go c.Inc(1)

		polygons := cache.([]*geojson.WOFPolygon)
		return polygons, nil
	}

	var c metrics.Counter
	c = *p.Metrics.CountCacheMiss
	go c.Inc(1)

	abs_path := utils.Id2AbsPath(p.Source, id)
	feature, err := p.LoadGeoJSON(abs_path)

	if err != nil {
		return nil, err
	}

	polygons, poly_err := p.LoadPolygonsForFeature(feature)

	if poly_err != nil {
		return nil, poly_err
	}

	return polygons, nil
}
Ejemplo n.º 2
0
func (idx *WOFIndex) LoadPolygons(wof *geojson.WOFSpatial) ([]*geojson.WOFPolygon, error) {

	id := wof.Id

	cache, ok := idx.Cache.Get(id)

	if ok {
		polygons := cache.([]*geojson.WOFPolygon)
		return polygons, nil
	}

	abs_path := utils.Id2AbsPath(idx.Source, id)
	feature, err := idx.LoadGeoJSON(abs_path)

	if err != nil {
		return nil, err
	}

	polygons, poly_err := idx.LoadPolygonsForFeature(feature)

	if poly_err != nil {
		return nil, poly_err
	}

	return polygons, nil
}
func main() {

	var data = flag.String("data", "", "The data directory where WOF data lives, required")
	var cache_size = flag.Int("cache_size", 1024, "The number of WOF records with large geometries to cache")
	var cache_trigger = flag.Int("cache_trigger", 2000, "The minimum number of coordinates in a WOF record that will trigger caching")
	var loglevel = flag.String("loglevel", "debug", "...")
	var subject_id = flag.Int("subject", 0, "...")
	var clipping_id = flag.Int("clipping", 0, "...")

	flag.Parse()

	logger := log.NewWOFLogger("[wof-breaches] ")
	logger.AddLogger(os.Stdout, *loglevel)

	idx, _ := breaches.NewIndex(*data, *cache_size, *cache_trigger, logger)

	subject_path := utils.Id2AbsPath(*data, *subject_id)
	clipping_path := utils.Id2AbsPath(*data, *clipping_id)

	idx.IndexGeoJSONFile(subject_path)

	subject, _ := idx.LoadGeoJSON(subject_path)
	clipping, _ := idx.LoadGeoJSON(clipping_path)

	logger.Info("does %s (clipping) breach %s (subject)", clipping.WOFName(), subject.WOFName())

	t1 := time.Now()

	results, _ := idx.Breaches(clipping)

	if len(results) == 0 {
		logger.Info("%s (clipping) DOES NOT breach %s (subject)", clipping.WOFName(), subject.WOFName())
	}

	for _, r := range results {

		subject_path := utils.Id2AbsPath(*data, r.Id)
		subject_feature, _ := idx.LoadGeoJSON(subject_path)

		logger.Info("%s (%d) breaches %s (%d)", clipping.WOFName(), clipping.WOFId(), subject_feature.WOFName(), subject_feature.WOFId())
	}

	t2 := time.Since(t1)
	logger.Info("time to search %v", t2)

}
func main() {

	/*
	   This still lacks metrics collection of strict placetype checking
	   (20151203/thisisaaronland)
	*/

	var port = flag.Int("port", 9988, "The port number to listen for requests on")
	var data = flag.String("data", "", "The data directory where WOF data lives, required")
	var cache_size = flag.Int("cache_size", 1024, "The number of WOF records with large geometries to cache")
	var cache_trigger = flag.Int("cache_trigger", 2000, "The minimum number of coordinates in a WOF record that will trigger caching")
	// var strict = flag.Bool("strict", false, "Enable strict placetype checking")
	var logs = flag.String("logs", "", "Where to write logs to disk")
	// var metrics = flag.String("metrics", "", "Where to write (@rcrowley go-metrics style) metrics to disk")
	// var format = flag.String("metrics-as", "plain", "Format metrics as... ? Valid options are \"json\" and \"plain\"")
	var cors = flag.Bool("cors", false, "Enable CORS headers")
	var loglevel = flag.String("loglevel", "info", "")

	flag.Parse()
	args := flag.Args()

	if *data == "" {
		panic("missing data")
	}

	_, err := os.Stat(*data)

	if os.IsNotExist(err) {
		panic("data does not exist")
	}

	l_writer := io.MultiWriter(os.Stdout)

	if *logs != "" {

		l_file, l_err := os.OpenFile(*logs, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0660)

		if l_err != nil {
			panic(l_err)
		}

		l_writer = io.MultiWriter(os.Stdout, l_file)
	}

	logger := log.NewWOFLogger("[wof-breach-server] ")
	logger.AddLogger(l_writer, *loglevel)

	idx, _ := breaches.NewIndex(*data, *cache_size, *cache_trigger, logger)

	for _, meta := range args {
		logger.Info("indexing %s", meta)
		idx.IndexMetaFile(meta)
	}

	logger.Info("indexing meta files complete")

	var lookups int64
	lookups = 0

	handler := func(rsp http.ResponseWriter, req *http.Request) {

		query := req.URL.Query()

		str_wofid := query.Get("wofid")

		if str_wofid == "" {
			http.Error(rsp, "Missing wofid parameter", http.StatusBadRequest)
			return
		}

		wofid, err := strconv.Atoi(str_wofid)

		if err != nil {
			http.Error(rsp, "Unable to parse WOF ID", http.StatusBadRequest)
			return
		}

		path := utils.Id2AbsPath(*data, wofid)
		feature, err := idx.LoadGeoJSON(path)

		if err != nil {
			http.Error(rsp, "Invalid WOF ID", http.StatusBadRequest)
			return
		}

		logger.Info("looking up %d (%d)", feature.WOFId(), lookups)

		t1 := time.Now()
		atomic.AddInt64(&lookups, 1)

		results, err := idx.Breaches(feature)

		atomic.AddInt64(&lookups, -1)
		t2 := time.Since(t1)

		logger.Info("time to lookup %d : %v", feature.WOFId(), t2)

		if err != nil {
			http.Error(rsp, err.Error(), http.StatusInternalServerError)
			return
		}

		logger.Info("%d results breach %d", len(results), feature.WOFId())

		js, err := json.Marshal(results)

		if err != nil {
			http.Error(rsp, err.Error(), http.StatusInternalServerError)
			return
		}

		if *cors {
			rsp.Header().Set("Access-Control-Allow-Origin", "*")
		}

		rsp.Header().Set("Content-Type", "application/json")
		rsp.Write(js)
	}

	str_port := fmt.Sprintf(":%d", *port)

	http.HandleFunc("/", handler)
	http.ListenAndServe(str_port, nil)
}
func main() {

	var data = flag.String("data", "", "The data directory where WOF data lives, required")
	var cache_size = flag.Int("cache_size", 1024, "The number of WOF records with large geometries to cache")
	var cache_trigger = flag.Int("cache_trigger", 2000, "The minimum number of coordinates in a WOF record that will trigger caching")
	var loglevel = flag.String("loglevel", "info", "...")

	flag.Parse()
	args := flag.Args()

	logger := log.NewWOFLogger("[wof-breaches] ")
	logger.AddLogger(os.Stdout, *loglevel)

	idx, _ := breaches.NewIndex(*data, *cache_size, *cache_trigger, logger)

	for _, meta := range args {
		logger.Info("indexing %s", meta)
		idx.IndexMetaFile(meta)
	}

	logger.Info("indexing meta files complete")

	scanner := bufio.NewScanner(os.Stdin)

	for scanner.Scan() {

		id := scanner.Text()

		if id == "" {
			continue
		}

		wofid, err := strconv.Atoi(id)

		if err != nil {
			logger.Error("failed to convert %s to a WOF ID, because %v", id, err)
			continue
		}

		path := utils.Id2AbsPath(*data, wofid)
		feature, err := idx.LoadGeoJSON(path)

		if err != nil {
			logger.Error("Failed to read %s, because %v", path, err)
			continue
		}

		// Note the WOFID-iness below - please to be waiting for this
		// to get pushed to get resolved (20151125/thisisaaronland)
		// https://github.com/whosonfirst/go-whosonfirst-geojson/issues/2

		logger.Info("what records does %s (%s) breach?", feature.WOFName(), path)

		t1 := time.Now()

		results, err := idx.Breaches(feature)

		if err != nil {
			logger.Error("Failed to determined breaches for %s (%d), because %v", feature.WOFName(), feature.WOFId(), err)
			continue
		}

		count := len(results)

		if count == 0 {
			logger.Status("%s does not breach any other records in the index", feature.WOFName())
		} else if count == 1 {
			logger.Status("%s breaches one other record in the index", feature.WOFName())
		} else {
			logger.Status("%s breaches %d other records in the index", feature.WOFName(), count)
		}

		for _, r := range results {

			other_path := utils.Id2AbsPath(*data, r.Id)
			other_feature, _ := idx.LoadGeoJSON(other_path)

			logger.Info("%s (%d) breaches %s (%d)", feature.WOFName(), feature.WOFId(), other_feature.WOFName(), other_feature.WOFId())
		}

		t2 := time.Since(t1)
		logger.Info("time to search %v", t2)
	}

}