Tag Archives: API

Static Maps API format size comparison

Sod’s Law, I realised after the deadline that the loading of the environment’s texture could have been sped up! So I’m fixing it now.

The Static Maps API request still has to go through a PHP proxy due to cross-origin issues, however instead of also using the PHP’s GD libary to convert the image from a PNG to a JPG, which is notoriously slow, we can just request the specific format straight from the API using the format parameter.

I have tested all the formats to check which is the smallest:


As expected, the progressive jpg provides the smallest file size.

Changing the format to jpg cut around 1 second off the request time.




It might not seem like much, but considering this request actually freezes the page, it is important that it is as quick as possible.

Generating more accurate 3D models

One of things that regularly surprised us was the quality of the models that we were able to produce.

There were two factors which contributed to this: the quality of the texture and the detail in the height map.

We had already found the highest quality texture that the Google Static Maps API would give us, so the next step was the height maps.

The main issue with the detail of the height maps was finding the perfect balance between clone time and detail.

First of all, I moved the blurring of the height maps from the PHP to the JS thanks to stackblur.js. The gaussian blur filter in PHP is extremely slow, and is lacking in options, which forced me to apply the filter 50 times over in a for-loop, greatly increasing the clone time. On our sandbox, this cut the clone time from several 10s of seconds down to under 3 seconds!

Now that the clone time was reduced, I attempted to increase the detail in the height maps.

The main issue here was the Google Elevation API. It would reject and requests if they were either too large (i.e. requesting too many elevation points in one request) or too frequent. If either were rejected, the request would have to be resent, adding more time to the cloning process.

The first thing I did was to refactor the request code to continuously request the data until it is complete in a self-invoking loop, rather than a set of fixed-size chained requests. This made it much easier to fiddle with the height map detail variables.

With the new request code in place, I was able to crank up the detail variables to much higher values. The original resolution was 20x20px; increasing this to 100x100px produced amazing results. All the crevices and valleys would show up on the model in amazing detail. The only problem being that the clone time shot up to over a minute. We felt that a short clone time greatly outweighed the quality of the models. An average user would not realise unless they had a comparison.

Agreeing upon anything less than 30 seconds of clone time, we settled on a resolution of 40x40px; not a great increase,but an increase nonetheless!

Clone a new environment

The clone a new environment page has gone through many iterations.

To begin with, it all boils down to allowing the user to select a predefined area of the map and to kick off the cloning process. We use the Google Maps API to allow the user to interact with the map and handle the selection of a point.

We’ve added several enhancements in order to make the process easier:

  • An overlay grid appears once the user has zoomed to the required zoom level, showing the user the boundaries of the tile that they will be cloning
  • When clicking the map, the overlay grid will update to show the selected tile
  • The maximum zoom is also the required zoom level for selection
  • Satellite, hybrid and terrain map display options are visible to aid the user in finding an area of interest
  • A search box is available if the user already knows where they want to clone

The CLONE button also required quite a bit of validation:

  • Check whether a tile has been selected
  • Check whether that tile has already been cloned before by another user
  • Ensure the environment name the user enters is present and not longer than 30 characters

New Environment Map

Generating 3D terrain models using Google Elevation API, Google Static Maps and ThreeJS

By combining Google Elevation API, Google Static Maps API and ThreeJS, we can automatically generate and display 3D topographical representations of real-world areas using only code.

The following lists out the step-by-step process we went through in order to produce the outcome.

Getting the elevation data:

  1. Split the world into tiles
  2. Work out which tile the user has selected
  3. Get the latlng (latitude and longitude) boundaries of that tile
  4. Divide the tile into another grid (30×30)
  5. Loop through the grid, row by row, and get the latlng of each of those divisions
  6. Request the elevation of each latlng from Google Elevation API and store in an array

Generating the height map:

A height map is a grey scale image where white means high and black means low.

In RGB, white = 255 and black = 0.

  1. Take the elevation array and find the maximum and minimum value
  2. Normalise all the data so that the minimum value = 0
  3. Calculate the ratio of all the values so that they lie between 0 and 255
  4. Convert the array into a string, with each column delimited by a comma and each new row signified by a dash, and pass the string into a PHP script
  5. The PHP parses and loops through the string to draw out the grey scale image pixel by pixel, which is then saved to disk

Getting the satellite image:

  1. From the selected tile boundaries, calculate the centre latlng of that tile
  2. Request the satellite image using Google Static Maps (proxying through a PHP script to bypass the Cross-Origin Policy)

Rendering the model:

  1. ThreeJS is used to generate a mesh and downloads the height map and the satellite image
  2. The height map is applied as a displacement map
  3. The satellite image is applied as a texture