Dirty Guide to Geohacking

Thanks to a side project, I had the chance to dip my toes into Google Maps API and some general geo hackery.

First up was a long dip in the Google Maps API developer documentation and API references. Mike William’s Google Maps API Tutorials were a god-send for getting up to speed on what’s possible with the API and a treasure trove of sample code for reference.

After a few days of intensive reading, I felt somewhat assured that my ideas were feasible and it was time to figure what I need. One of the first things I needed to get working was an overlay of the administrative districts and borders on GMaps.

Converting Shapefiles

I forget how, but I knew I needed shapefiles. Thanks to some references, we lucked out and managed to get the shapefiles needed. What was left was to figure out a way to convert them to a format I could use with Google Maps.

This was where the Finder! utility on GeoCommons.com came through for me. I was able to convert the shapefile into a usable javascript-friendly JSON format for use with GMaps.

Finder GeoCommons Formats

Finder GeoCommons Formats

Simply upload the shapefiles as instructed on Finder as a layer and in the layer details page, download the JSON format. To use the geo data in the json file, save it with a .js extension, e.g. japan_boundaries.js.

Open up the .js file with a text editor and prepend a javascript variable declaration (“var japan = ” like so to the json object:

var japan ={“features”: [{“PERIMETER”: 2.733, “ADMIN_NAME”: “Osaka”…

Include the .js file in your page, and you can access the “features” as an associative array in javascript.

// loop through each feature
for (var i = 0; i < japan.features.length; i++) {
	var feature = japan.features[i];
	if (feature.geometry.coordinates) {
		var xys = new Array(feature.geometry.coordinates.length);
		// loop through each pair of coordinates
		for (var x = 0; x < feature.geometry.coordinates.length; x++) {
			xys[x] = new GLatLng(
				// yes, the coords are "inverted"
				feature.geometry.coordinates[x][1]
				, feature.geometry.coordinates[x][0]);
		}
		// create a polygon from the coordinates
		var polygon = createMapPoly(i, xys);
		_map.addOverlay(polygon);
	}
}

With this, you should be pretty much on the way to rendering each area as a polygon on the map.

Test Overlay for Japan

Simplifying Shapefiles

A word of warning, depending on your shapefile source, you may end up with an extremely complex polygon (with many points). Multiply this by the number of the number of polygons you are rendering on a single map, the rendering can be painfully slow in the browser (particularly in IE, even IE8).

This was the case for me, and because we had such great shapefiles, each polygon had a few hundred points to render. To improve performance, the shapefiles had to be simplified to reduce the number of coordinate points.

I found a dead simple flash tool online called MapShaper which worked great for me. Just upload your original shapefile and select the level of simplification you need. I had to use a fairly aggressive setting of 80 to bring down the number of points but your mileage may vary.

Mapshaper Simplification Settings

Export the simplified shapefiles and upload them to Finder again. You should notice that the json file is much smaller after simplification.