Using Google Earth Borders as Google Maps Polygons

Today we are going to cover how to extract the polygonal data from Google Earth’s country borders and encode the data into a JavaScript array that we can use in Google maps. With the combination of both polygon borders and Google style wizard you can get some stunning map results.

[View Working Example Here]

To begin, download and install Google earth here. Once you have installed Google earth, open Google earth:

ss-1

Now download these two country borders KMZ files as you desire:

Once you have downloaded both files, double click each one to list the borders in Google earth. Once you see the optional overlays for low and high polygon borders in Google Earth, we can begin.

ss-3

Lets pick a single country; for our example sakes, I will choose Germany but you may choose any country you wish at this point. Also, I’m choosing to use the low details polygon borders over high detail border; depending on your fidelity of detail need, you may choose to use the higher detail over the lower detail polygon borders.

ss-4

Once you have picked a country, simply right click on it, and choose copy.

ss-5

This will copy the KMZ lat/lng data numbers for each point that makes up a polygon. Now open up a modern word processor (for sakes of speed, I will choose MS Word) and paste your copied data.

 

Once here, use the find and replace feature to search for all instances of this:

,0

and replace it with:

^p

(Please note there is a space after the 0 and it is important!!!) Now click replace all.

ss-6

This will separate all your coordinates by pairs into new lines allowing us to copy them in a format we can use to compress the data. So, once done replacing all instances, select everything and copy your results out of MS Word and into something more readable like notepad, or your favourite IDE.

Now, we are going to go through each XML group called and selecting their , like so (do the following one at a time for each polygon grouping):

ss-7

we are going to point our browser to a lovely online resources that will take our lng/lat data, and compress this selected data into a special algorithm to lower our polygon cache size.

Go here: http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/encodeForm.html

In the textarea at the top of the page titled “Input text”, paste our copied coordinates, then change the Lat/lng order to lng/lat, and finally press “Show Map” to confirm our polygon shape is rendering correctly. Once you have confirmed you see your polygon shape rendering correctly, click “Show Code” to open a window that will expose our encoded and compressed coordinates. From here, copy the string value in the “points” properties, like so:

ss-8

Now that we have our compressed polygon data, we need to build a JavaScript object array that we can store the data in and ultimately and draw the polygons on Google Maps for our visitors. Here is how I purpose you construct such an array, but you may alter it how ever you like, just as long as the polygon data is accessible and support multiply polygons per country you will be fine:

ss-9

Great, as you can see we have three objects in our “country_polys” object in the above array, and each object contains an encoded polygon group we encoded from the steps above.

Here is our Object array with a second country added:

ss-10

Again, this second country only has two “poly” objects because when we copied its KMZ data from Google earth, it only had two XML polygon groups that we had to encode.

Great, now we need to actually render the polygons into a Google Maps instance on a page, so save this Object array as country-borders.js on your web server for later use and open a new document.

Here is a basic document I’ve set-up already that includes the basics for setting up a Google Maps; the install portion of Google Maps is out side of the scope of this tutorial so I suggest you read more about this on the Google Maps Developer Documentation. I will point out however, that when working with polygons and Google maps, you must extend your api to include geometry functionality so we must include “libraries=geometry” to our Google Maps JavaScript API source url.

%MINIFYHTML2c4519e42c5402c433c270706962f02b4%%MINIFYHTML2c4519e42c5402c433c270706962f02b5%%MINIFYHTML2c4519e42c5402c433c270706962f02b6%

Great, notice in our document we have already included the country-border.js we just saved out in our last step? We need to include this JavaScript Object array before any attempts to use it, so the browser has time to cache and reference to it when we need it. If you save this html source out now, and point your browser it it, you should see a Google maps instance, but no polygon being rendered yet. We must now parse our country-borders.js Object array and plot each polygon coordinate on our map instance before the polygon will showup.

Here is what we will use to parse our encoded borders:

var bounds = new google.maps.LatLngBounds();
var countries = country_borders;
var i = countries.length;
var p = { paths: '0', fillColor: '#54cafe', strokeColor: '#b5e8ff', strokeWeight: 1, fillOpacity: 1};

while(i--){
    var country = countries[i];
    var polygon = country.country_poly;
    var v = polygon.length;

    while(v--){
        p.paths = google.maps.geometry.encoding.decodePath(polygon[v].poly);

        var shape = new google.maps.Polygon(p);
        shape.setMap(map); //set it

        //capture bounds
        var m = p.paths.length;
        while(m--){ bounds.extend(p.paths[m]); }
    }
}
map.fitBounds(bounds);

Ok, there is a lot to cover here, so I will do my best to break it down as needed.

First, we set-up a bounds variable and equal it to a Google LatLngBounds() function that we will use to auto zoom, and pan our map around the drawn polygons once we are finished. Next we want to gather all our country borders, so we set-up another variable called “countries” and equal it to our globally available Object array from our country-borders.js “country_borders”. Next we set-up a third variable called “i” and we equal it to the length of found objects in our “countries” variable. Finally we set-up a variable called “p” that will be used to contain our path, and polygon styles.

Now that we have gathered the necessaries in values to plot our polygons, we need to loop over our data. We use the while loop and the fastest proven method of looping, by looping in reverse (v–). Once we are in our loop, we must further drill down into each polygon, of each countrym and plot each vertex points that we encoded before. So we create a new variable called “country” (singular, cause we are a single country scope now) and equal it to “countries[i]” or rather, the current country in the looping procedure. Next we will create another variable called “polygon” and equal it to our current country’s found polygon objects; and finally we make a third variable and equal it to the found polygons length for our current county.

If you are starting to see the looping pattern of first country, then polygons, then you can understand why we need a second while loop to loop over all the found polygon instances of a single country. Again we will make use of the while loop, and do so in reverse looping order for performance sakes. Now that we have reached the “single polygon” scope of our looping (the second while loop), we need to now decode our encoded polygon coordinates. Google provides a function called decodePath that does this for us, so we set the value of “p.path” to equal a passed param value to decodePath of “polygon[v].poly”, or rather our currently looped polygon.

Once we have collected the current polygon in it’s decoded format, we must apply it to the map. We do so by creating a new variable called “shape” and equal it to a Google maps “Polygon()” overlay type, with our “p” variable as a passed parameter that also now contains our decoded coordinates. Once we have collected all the custom options, and coordinates of our currently looped polygon into a Polygon overlay declaration, we need to bind it to map. Using our new “shape” variable and the Google map’s “setMap(map)” function (note “map” param was defined when setting up the Google maps) our finally compiled polygon will be plotted on the map and rendered.

Lastly as promised is the auto fit/bounds. The final step is to take the paths of our current polygon, and apply them to our bounds functionality through an “extend” method in order to execute a map.fitBounds(bounds) once all our looping is completed. This will auto center the map around the drawn polygons by both zoom level and pan.

 

[View Working Example Here]

 

That’s it everyone, you have now successfully converted Google Earth KMZ data over to JavaScript in a very neat and compressed way that can be decoded and rendered in a Google Maps.

Thanks, and Enjoy!

Devin R. Olsen

Located in Portland Oregon. I like to teach, share and dabble deep into the digital dark arts of web and game development.

More Posts

Follow Me:
TwitterFacebookGoogle Plus