Skip Navigation

[Resolved] Without OpenStreet Maps, how can we make Google Maps cheaper?

This thread is resolved. Here is a description of the problem and solution.

Problem:
The free OpenStreet Maps API is not available with Toolset Maps. When using the Google API, what can we do to keep the API costs down?

Solution:
Toolset Maps already caches addresses to reduce geocoding costs. One thing you can additionally do is to use Static Maps instead of the normal interactive JavaScript Maps when displaying addresses on maps.

The thread below describes the steps involved.

Relevant Documentation:
https://toolset.com/course-lesson/creating-a-maps-api-key/#creating-an-api-key-for-google-maps
https://developers.google.com/maps/documentation/maps-static/start

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
- 7:00 – 14:00 7:00 – 14:00 7:00 – 14:00 7:00 – 14:00 7:00 – 14:00 -
- 15:00 – 16:00 15:00 – 16:00 15:00 – 16:00 15:00 – 16:00 15:00 – 16:00 -

Supporter timezone: Europe/London (GMT+00:00)

This topic contains 1 reply, has 1 voice.

Last updated by Nigel 6 months, 1 week ago.

Assigned support staff: Nigel.

Author
Posts
#2365985

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+00:00)

Toolset Maps uses the Google or Azure APIs which can be expensive, and the free OpenStreet Maps alternative is not available.

How can we reduce the costs associated with the Google Maps APIs?

#2366001

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+00:00)

staticmap.png

The Problem
Part of the costs of using the Google Maps APIs occur when adding addresses to posts (geocoding, to convert addresses to coordinates) or providing addresses to search against (again, geocoding), and Toolset Maps already uses caching to mitigate such costs. Every time an address is added (or someone enters a location in a distance filter) the address is stored alongside the corresponding coordinates in a cache table so that the same addresses do not need to be converted to coordinates again.

Other costs arise when displaying maps, which are not amenable to caching.

However, you may be able to reduce the costs of displaying maps by using the Static Maps API instead of the JavaScript Maps API.

At the time of writing, the JavaScript Maps API costs $7 / 1000 impressions, while the Static Maps API costs $2 / 1000 impressions.

The JavaScript Maps API delivers interactive maps, with zoom and other controls, and markers that can display tooltips and pop-ups etc.

The Static Maps API delivers a map as a .png image. It can have a marker (or markers), but they are inert, embedded into the image. (See the screenshot staticmap.png for an example.)

Though lacking interactivity, the map image can link to the same location in maps.google.com, and there is significantly less overhead, which may be a consideration on lesser-powered mobile devices on slower connections.

Below are directions on how to add such a static map to the Content Template for a post type that has an address field.

Solution
First, you will need to update your Google API key to include the Static Maps API (see https://toolset.com/course-lesson/creating-a-maps-api-key/#creating-an-api-key-for-google-maps).

The map in the screenshot is generated via an img tag whose src points to the Google API with details of the map and marker provided via URL parameters, i.e. this is the kind of img tag we need to generate:

<img class="image-cover" src="https://maps.googleapis.com/maps/api/staticmap?center=51.50545,-0.090963&zoom=16&size=640x640&maptype=roadmap&markers=|51.50545,-0.090963&key=your-api-key">
.

See the Static Maps API documentation about the available parameters and how to use them: https://developers.google.com/maps/documentation/maps-static/start

To display such a static map, it's simply a question of adding the above markup for an img tag where parts of the src attribute are generated dynamically using Toolset shortcodes. Similarly, the img can be inside an anchor tag to create a link, where parts of the href attribute are similarly generated dynamically via shortcodes.

In the template where you want the static map to appear, you would add the markup and shortcodes as below (editing for the slug of the Types address field, and changing parameters as required):

<img class="image-cover" src="https://maps.googleapis.com/maps/api/staticmap?center=[types field='location-address' format='FIELD_LATITUDE,FIELD_LONGITUDE'][/types]&zoom=16&size=640x640&maptype=roadmap&markers=|[types field='location-address' format='FIELD_LATITUDE,FIELD_LONGITUDE'][/types]&key=your-api-key">
.

If we additionally want to wrap the img in an anchor tag that links to an interactive version of the map hosted by Google (no API costs implied), we need to generate an href attribute that corresponds to a format like this:

https://www.google.com/maps/place/51.5054533,-0.0931517/@51.5054533,-0.0931517,16z
.

We can achieve that via shortcodes like so:

<a href="https://www.google.com/maps/place/[types field='location-address' format='FIELD_LATITUDE,FIELD_LONGITUDE'][/types]/@[types field='location-address' format='FIELD_LATITUDE,FIELD_LONGITUDE'][/types],16z">Link</a>
.

Combining the link with the image we end up with the following:

<a href="https://www.google.com/maps/place/[types field='location-address' format='FIELD_LATITUDE,FIELD_LONGITUDE'][/types]/@[types field='location-address' format='FIELD_LATITUDE,FIELD_LONGITUDE'][/types],16z">
<img class="image-cover" src="https://maps.googleapis.com/maps/api/staticmap?center=[types field='location-address' format='FIELD_LATITUDE,FIELD_LONGITUDE'][/types]&zoom=16&size=640x640&maptype=roadmap&markers=|[types field='location-address' format='FIELD_LATITUDE,FIELD_LONGITUDE'][/types]&key=your-api-key">
</a>

If you are using the Block editor for your templates you can insert the above inside a Custom HTML block, or a Fields and Text block (switch to HTML mode first).