Requesting a HERE Map Image With HTTP and Golang
In this post, we cover how to use Golang and HTTP requests to the HERE API to integrate an interactive map into an application.
Join the DZone community and get the full member experience.
Join For FreeAt events, I often get asked about generating map images using server-side technologies, or basically any technology that isn't client facing like JavaScript, Android, and iOS. For example, a common request is around providing criteria for a map to be generated as part of a script, report, or similar. Let me show you how.
HERE does have a REST API known as the HERE Map Image API and it is consumed through HTTP requests. This API can generate standard map images or map images that include map objects such as polylines, polygons, or similar. Essentially, if you can produce it with the JavaScript SDK on an interactive map, you can produce it on a map image.
While REST APIs can be consumed in pretty much any technology, we're going to have a look at using the Go programming language to create map images. To get a better idea of what we hope to accomplish, take the following image:

We're going to request a map image that contains a polygon. We'll be able to specify the sizing information for this image as well.
Understanding the HERE Map Image API
Before we jump into the Go code, we should probably understand a little more about the HERE Map Image API. Since this is a REST API, there will be different endpoints for accomplishing different things. A list of those possible endpoints can be found here. For this example, we'll be focusing on the region
endpoint.
Try executing the following command with cURL after swapping out the app id and app code with your own:
curl https://image.maps.api.here.com/mia/1.6/region?a0=37.739700%2C-121.425200%2C37.797400%2C-121.216100%2C37.639100%2C-120.996900%2C37.739700%2C-121.425200&app_code=APP_CODE_HERE&app_id=APP_ID_HERE&h=720&ppi=320&w=1280&z=11
Generating an app id and app code is free and can be done in the HERE Developer Portal. After executing the command, you'll notice that it created exactly what we saw in the prior image at the top of this tutorial.
The request made use of a few parameters. The a0
parameter represents the area to draw the polygon. It represents each of the points in the shape. The w
parameter represents the output image width, along with h
being for height. The ppi
represents the resolution and z
represents the zoom on the map. The a0
is probably the most complicated part of this request.
So now we should probably make something useful out of this API.
Developing an Application With the Go Programming Language
We won't be doing anything fancy in our Golang application. We'll just be constructing a request and sending it. Most of the setup will be around the data model for our polygon, to make things a little easier on the developer.
Take the following data structures:
type Point struct {
Latitude float64
Longitude float64
}
type Polygon struct {
Points []Point
}
Instead of forcing someone to create that ugly a0
string by hand, we're going to create some cleaner looking data structures, as seen above. With the data structures in place, the following can be done in our main
function:
func main() {
polygon := Polygon{
Points: []Point{
Point{Latitude: 37.7397, Longitude: -121.4252},
Point{Latitude: 37.7974, Longitude: -121.2161},
Point{Latitude: 37.6391, Longitude: -120.9969},
Point{Latitude: 37.7397, Longitude: -121.4252},
},
}
}
Great, so we have the points for our polygon. The problem is that our a0
parameter still expects a string. We can create some classic toString
functions to take care of this.
func (point *Point) toString() string {
return fmt.Sprintf("%f,%f", point.Latitude, point.Longitude)
}
The above function will take a point and turn it into a string where the axis is delimited by a comma. With the point being converted into a string, the entire slice of points needs to be converted. The following toString
function can be created:
func (polygon *Polygon) toString() string {
var result string
var points []string
for _, point := range polygon.Points {
points = append(points, point.toString())
}
result = strings.Join(points, ",")
return result
}
In the above function, we are looping through each of our points, converting them into strings, and then joining the slice of strings into one string delimited by a comma.
If we wanted to, we could do the following:
func main() {
polygon := Polygon{
Points: []Point{
Point{Latitude: 37.7397, Longitude: -121.4252},
Point{Latitude: 37.7974, Longitude: -121.2161},
Point{Latitude: 37.6391, Longitude: -120.9969},
Point{Latitude: 37.7397, Longitude: -121.4252},
},
}
fmt.Println(polygon.toString())
}
Now that the data is properly formatted, it is time to create a request. It is best to create a separate function for this, maybe calling it a GetMapWithPolygon
function like the following:
func GetMapWithPolygon(output string, geometry string) {
endpoint, _ := url.Parse("https://image.maps.api.here.com/mia/1.6/region")
queryParams := endpoint.Query()
queryParams.Set("app_id", "APP-ID-HERE")
queryParams.Set("app_code", "APP-CODE-HERE")
queryParams.Set("ppi", "320")
queryParams.Set("w", "1280")
queryParams.Set("h", "720")
queryParams.Set("z", "11")
queryParams.Set("a0", geometry)
endpoint.RawQuery = queryParams.Encode()
response, err := http.Get(endpoint.String())
if err != nil {
fmt.Printf("The HTTP request failed with error %s\n", err)
} else {
f, _ := os.Create(output)
data, _ := ioutil.ReadAll(response.Body)
f.Write(data)
defer f.Close()
}
While long, the above function is just creating a URL string with query parameters. Each of the query parameters is what we've already seen in the raw request. For more information on consuming data from web services with Go, check out a tutorial I wrote titled, Consume RESTful API Endpoints within a Golang Application.
After executing the request, if it didn't fail, an output file is created and the response body is saved directly to the file. The response body should be image data.
func main() {
polygon := Polygon{
Points: []Point{
Point{Latitude: 37.7397, Longitude: -121.4252},
Point{Latitude: 37.7974, Longitude: -121.2161},
Point{Latitude: 37.6391, Longitude: -120.9969},
Point{Latitude: 37.7397, Longitude: -121.4252},
},
}
GetMapWithPolygon("map.jpg", polygon.toString())
}
The above main
function makes use of the new GetMapWithPolygon
polygon function.
Conclusion
You just saw how to use the HERE Map Image API with the Go programming language. This example was probably a bit overkill because it is only a single request to a REST API, but it is a common question that I receive at events. Knowing how to generate map images as needed can be a useful ability.
Published at DZone with permission of Nic Raboy, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments