// Feature returns the Node as a *geojson.Feature. func (n *Node) Feature() (f *geojson.Feature) { // Set the properties. properties := make(map[string]interface{}, 6) properties["OwnerName"] = n.OwnerName properties["Status"] = n.Status if len(n.Contact) != 0 { properties["Contact"] = n.Contact } if len(n.PGP) != 0 { properties["PGP"] = n.PGP.String() } if len(n.Details) != 0 { properties["Details"] = n.Details } if n.SourceID != 0 { properties["SourceID"] = n.SourceID } // Create and return the feature. return geojson.NewFeature( geojson.NewPoint(geojson.Coordinate{ geojson.CoordType(n.Longitude), geojson.CoordType(n.Latitude)}), properties, n.Addr) }
func SpaceToFeature(space Space) *geojson.Feature { infra := spaceToInfra(space) lng := geojson.CoordType(infra.Point_.Lng) lat := geojson.CoordType(infra.Point_.Lat) c := geojson.Coordinate{lng, lat} geom := geojson.NewPoint(c) prop := map[string]interface{}{spaceValueName: infra.Value_, "createAt": infra.CreateAt_.Unix()} return geojson.NewFeature(geom, prop, nil) }
func EncodeMultiPointsIntoLineString(points []*Point) *geojson.Feature { var coordinates = make(geojson.Coordinates, len(points)) for i := range points { var c geojson.Coordinate c[0] = geojson.CoordType(points[i].Lng) c[1] = geojson.CoordType(points[i].Lat) coordinates[i] = c } lineString := geojson.NewLineString(coordinates) return geojson.NewFeature(lineString, nil, nil) }
func EncodeMultiPointsIntoFeature(points []*Point) *geojson.Feature { var coordinates = make(geojson.Coordinates, len(points)) for i := range points { var c geojson.Coordinate c[0] = geojson.CoordType(points[i].Lng) c[1] = geojson.CoordType(points[i].Lat) coordinates[i] = c } multiPoint := geojson.NewMultiPoint(coordinates) return geojson.NewFeature(multiPoint, nil, nil) }
/** * or free docks, or an error if that was not possible. * @see getFreeDocksNear * @see getBikesNear */ func writeDockingStations(w http.ResponseWriter, r *http.Request, filter_type string) { lat, _ := strconv.ParseFloat(r.URL.Query().Get("lat"), 64) lon, _ := strconv.ParseFloat(r.URL.Query().Get("lon"), 64) x0, _ := strconv.ParseFloat(r.URL.Query().Get("x0"), 64) y0, _ := strconv.ParseFloat(r.URL.Query().Get("y0"), 64) x1, _ := strconv.ParseFloat(r.URL.Query().Get("x1"), 64) y1, _ := strconv.ParseFloat(r.URL.Query().Get("y1"), 64) var dockingStations DockingStations var err error var ret []byte if filter_type == "bikes" { err = dockingStations.GetBikesNear(lat, lon, 4) } if filter_type == "freedocks" { err = dockingStations.GetBikesNear(lat, lon, 4) } if filter_type == "stations" { err = dockingStations.GetStationsInside(x0, y0, x1, y1) } if err == nil { features := []*gj.Feature{} for _, dockingStationStatus := range dockingStations.DockingStationStatuses { properties := map[string]interface{}{"name": dockingStationStatus.Name, "i": dockingStationStatus.DockId, "bikes": dockingStationStatus.Bikes, "docks": dockingStationStatus.Docks, "updated": dockingStationStatus.Time} lat, _ := strconv.ParseFloat(dockingStationStatus.Lat, 64) lon, _ := strconv.ParseFloat(dockingStationStatus.Lon, 64) p := gj.NewPoint(gj.Coordinate{gj.CoordType(lon), gj.CoordType(lat)}) f := gj.NewFeature(p, properties, nil) features = append(features, f) } ret, err = json.Marshal(features) } if err != nil { //@todo set return code logger.Log("msg", "There was an error retrieving docking stations", "err", err) w.Header().Set("Content-Type", "application/json") w.Write([]byte("{msg: \"There was an error\"}")) return } w.Header().Set("Server", "bikefinder") w.Header().Set("Content-Type", "application/json") w.Write(ret) }
// isOtherGeo searches for non-standard geo data in the given json map. It looks for the presence // of lat/lng (and a few variations thereof) or x/y values in the object as well as a distance/radius/accuracy // field and creates a geojson point out of it and returns that, along with a boolean value // representing whether or not it found any geo data in the object. It will also look for // any keys that hold an array of two numbers with a key name that suggests that it might // be a lng/lat array. // // The following keys will be detected as Latitude: // "lat", "latitude" // "y" // // The following keys will be detected as Longitude: // "lng", "lon", "long", "longitude" // "x" // // The following keys will be used to fill the "radius" property of the resulting geojson: // "dist", "distance" // "rad", "radius" // "acc", "accuracy" // // The following keys will be searched for a long/lat pair: // "geo" // "loc" or "location" // "coord", "coords", "coordinate" or "coordinates" func isOtherGeo(o map[string]interface{}) (bool, *Geo) { var foundLat, foundLng, foundDst bool var lat, lng, dst float64 for k, v := range o { switch strings.ToLower(k) { case "lat", "latitude", "y": lat, foundLat = v.(float64) case "lng", "lon", "long", "longitude", "x": lng, foundLng = v.(float64) case "dst", "dist", "distance", "rad", "radius", "acc", "accuracy": dst, foundDst = v.(float64) case "geo", "loc", "location", "coord", "coordinate", "coords", "coordinates": g, ok := v.([]float64) if !ok || len(g) != 2 { break } lng, lat = g[0], g[1] foundLat, foundLng = true, true } } if foundLat && foundLng && latIsValid(lat) && lngIsValid(lng) { p := gj.NewPoint(gj.Coordinate{gj.CoordType(lng), gj.CoordType(lat)}) pstr, _ := gj.Marshal(p) var geo map[string]interface{} json.Unmarshal([]byte(pstr), &geo) debugLog("Found other geo:", geo) g := &Geo{ Geo: geo, } if foundDst { g.Radius = dst } return true, g } return false, nil }
func EncodePoint(point *Point) *geojson.Point { var c geojson.Coordinate c[0] = geojson.CoordType(point.Lng) c[1] = geojson.CoordType(point.Lat) return geojson.NewPoint(c) }
// @todo genericize this processor to be a general-purpose *.shp processor // and make it archive format-agnostic func MTTurkeyProcessor(ds DataSource) (geoCol *geojson.GeometryCollection, err error) { // download the source archive fmt.Printf("Downloading %s...", ds.URL) resp, err := http.Get(ds.URL) if err != nil { return nil, err } tmpZip, err := ioutil.TempFile(os.TempDir(), ds.Attribution+"_zip") if err != nil { return nil, err } n, err := io.Copy(tmpZip, resp.Body) if err != nil { return nil, err } resp.Body.Close() tmpZip.Close() fmt.Printf("done! (%d bytes)\n", n) // search the zip file fmt.Printf("Searching archive for %s files:\n", ds.Filetype) r, err := zip.OpenReader(tmpZip.Name()) if err != nil { return nil, err } defer r.Close() shpMatcher := regexp.MustCompile(".*[.]shp$") matched := false // iterate through the files in the archive and process any .shp files geoCol = geojson.NewGeometryCollection(nil) for _, f := range r.File { if !shpMatcher.MatchString(f.Name) { continue } matched = true fmt.Printf(">> Extracting %s...", f.Name) shpData, err := f.Open() if err != nil { return nil, err } tmpSHP, err := ioutil.TempFile(os.TempDir(), ds.Attribution+"_shp") if err != nil { return nil, err } n, err = io.Copy(tmpSHP, shpData) if err != nil { return nil, err } shpData.Close() tmpSHP.Close() fmt.Printf("done! (%d bytes)\n", n) // @todo remove this hack when the library authors remove theirs // the shp library currently replaces the last three filename // characters with "shp" for some reason... err = os.Rename(tmpSHP.Name(), tmpSHP.Name()[0:len(tmpSHP.Name())-3]+"shp") if err != nil { return nil, err } fmt.Printf(">> Processing %s...", f.Name) shape, err := shp.Open(tmpSHP.Name()) if err != nil { return nil, err } defer shape.Close() shapeCnt := 0 for shape.Next() { _, p := shape.Shape() bb := p.BBox() //fmt.Printf("Adding %s: %s", reflect.TypeOf(p).Elem(), bb) minX, maxX, minY, maxY := geojson.CoordType(bb.MinX), geojson.CoordType(bb.MaxX), geojson.CoordType(bb.MinY), geojson.CoordType(bb.MaxY) // @todo more correct and complete conversion from shp to geojson // right now we're just deriving a square polygon from the bounding box coords := []geojson.Coordinates{ // left line { {minX, minY}, {minX, maxY}, }, // top line { {minX, maxY}, {maxX, maxY}, }, // right line { {maxX, maxY}, {maxX, minY}, }, // bottom line { {maxX, minY}, {minX, minY}, }, } poly := geojson.NewPolygon(coords) geoCol.AddGeometry(*poly) shapeCnt++ } fmt.Printf("done! (loaded %d shapes)\n", shapeCnt) } if !matched { return nil, fmt.Errorf("Could not find any %s files", ds.Filetype) } return geoCol, nil }