How to Work With GeoJSON Data in Golang for HERE XYZ
Learn how to work with GeoJSON Data in Golang.
Join the DZone community and get the full member experience.
Join For FreeSince I’m personally becoming more familiar with HERE XYZ, I’ve been learning about all the bits and pieces that go with it, and that includes data formats such as GeoJSON. In a previous tutorial titled, Format Data into GeoJSON with JavaScript to be used with HERE XYZ, I demonstrated how to work with GeoJSON data in JavaScript. However, I’m a huge fan of the Go programming language, so I figured it would be awesome to try to replicate what I did with Golang.
We’re not going to work directly with HERE XYZ in this example. We’re just going to get our data ready to be sent to HERE XYZ or received from it. I have other tutorials where we make HTTP requests to the HERE XYZ APIs using Golang.
Before we create a project, execute the following from the command line:
go get github.com/paulmach/go.geojson
The above command will get the community supported go.geojson package for use in our project.
Within your $GOPATH
, create a new project with a main.go file. In that main.go file, include the following boilerplate code:
package main
import (
"fmt"
geojson "github.com/paulmach/go.geojson"
)
type Position struct {}
type XYZData struct {}
func NewGeoJSON(position Position, tags []string) ([]byte, error) {}
func main() {}
You’ll notice that we have two data structures and two functions, one of which is our main
function. Under normal circumstances, using the pure GeoJSON package would be sufficient, but we’re going to create our own helper function to work with HERE XYZ.
Essentially, HERE XYZ allows tagging, which is useful when issuing search queries. You could, for example, create a tag for a date and then return results that only match that tag. This doesn’t break the GeoJSON specification, but it does mean we need to include certain things.
Let’s first create our Position
data structure:
type Position struct {
Latitude float64 `json:"lat"`
Longitude float64 `json:"lng"`
}
As you guessed, we have a latitude and longitude property to work with instead of a plain floating point slice. The XYZData
data structure will look like the following:
type XYZData struct {
Tags []string `json:"tags"`
}
With those two data structures in place, we can start constructing our GeoJSON feature collection. We’re going to create our full feature collection in the NewGeoJSON
function and return a slice of bytes, which could later be sent to HERE XYZ.
func NewGeoJSON(position Position, tags []string) ([]byte, error) {
featureCollection := geojson.NewFeatureCollection()
feature := geojson.NewPointFeature([]float64{position.Longitude, position.Latitude})
feature.SetProperty("@ns:com:here:xyz", XYZData{Tags: tags})
featureCollection.AddFeature(feature)
return featureCollection.MarshalJSON()
}
In the above function, we are accepting a position of latitude and longitude coordinates as well as any number of tags to be stored.
After creating a new feature for the collection, we are adding a property to that feature. The property has a specific key and it is an object. We want our final output to look something like this:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-121,37]
},
"properties": {
"@ns:com:here:xyz": {
"tags": ["foo","bar"]
}
}
}
]
}
We can make use of this NewGeoJSON
function in the main
function. Take the following, for example, to reproduce the above output:
func main() {
g, _ := NewGeoJSON(Position{37, -121}, []string{"foo", "bar"})
fmt.Println(string(g))
}
Not so bad, right?
GeoJSON can be a lot more complex, but this is just a basic example, something that was valuable for one of my own projects. In my example, I was collecting latitude and longitude positions and needed to send it to HERE XYZ. So, I took the data I had and converted it to GeoJSON format.
Conclusion
You just saw how to work with GeoJSON data in Golang. While the go.geojson package for Golang makes it easy in general, we wanted to make some changes that better accommodate working with HERE XYZ.
To learn more about working with location data in Golang, check out my previous tutorial titled, Reverse Geocoding NEO 6M GPS Positions with Golang and a Serial UART Connection.
Published at DZone with permission of Nic Raboy, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments