Drawing arbitrary GIS data on Google Maps

Written by Adrian Holovaty on May 31, 2005

I just added ZIP-code browsing to chicagocrime.org. A novel thing about it, from a technical standpoint, is that the ZIP code maps (example) display a blue border around the relevant area, so you can tell where the ZIP code begins and ends.

I did this using free GIS data from the City of Chicago. That data defines each ZIP code in the city and its spatial boundaries.

The data comes in standard SHP (shapefile) format, which I imported into PostgreSQL using its excellent PostGIS spatial-database package. PostGIS handles the conversion of the shapefile data to longitude and latitude points in the projection that Google Maps uses.

Next, I fed that list of coordinates through a Python script that encodes latitude/longitude points into Google's proprietary line-generation format. That script is a port of Neil Kandalgaonkar's Perl version. Neil appears to be the guy who reverse-engineered the line-generation format -- an incredibly impressive feat.

With Google's line-generation format calculated, it was just a matter of inserting that chunk of characters in the appropriate place within the Google Maps XML file.

Interesting tidbit: I played with importing the City of Chicago's neighborhood-boundary data, too, but the neighborhood boundaries -- particularly those that touch Lake Michigan -- are made up of so many distinct longitude/latitude points that displaying them on a Google Map crashes the browser when viewed at a close zoom level. The lines generated in that case are simply too complex!

Comments

Posted by anonymous on May 31, 2005 at 4:03 a.m.:

This feature is pretty neat, but my address shows up in the wrong zip code. I'm on the 1200 block of W Bryn Mawr, which I believe is the boundary btw. 60640 and -60, but is actually entirely contained in 60660. It's the 40 map, though, where its incidents show up. I guess you can't help if your source data are wrong, but I thought it might be useful to know.

Thanks for all the hard work! This is a super service to Chicagoans.

Posted by Adrian on May 31, 2005 at 11:15 a.m.:

Thanks for the heads-up, anonymous. I've changed that strip of Bryn Mawr by hand so that it's 60660 where appropriate and will look into finding a second source of ZIP code information so that I can cross-check. If anybody has suggestions, let me know!

Posted by Jeremy Dunck on May 31, 2005 at 11:34 a.m.:

These might help:

USPS address info

2000 census TIGER data

Posted by Mike Pitman on June 1, 2005 at 6:03 p.m.:

Is there a way to download or create a pdf/jpg/gif/tif file on a google map?

mpitman@coxohio.com

Posted by Doug on June 8, 2005 at 12:31 p.m.:

Wanted to share the JavaScript version of the encodePolyline with everyone (I'm not a perl or python guy, so this is easier for me to understand) Basically, you just pass the coordinates to it, and it returns the string. Modify for your needs.

function encodePolyline(a) {

var p = a.split(',');

var d = '';

var xo=0;

var yo=0;

for(c=0;c<p.length;c+=2) {

x = p[c];

xd = x - xo;

xo = x;

f = (Math.abs(xd) << 1) - (xd<0);

do {

e = f & 31;

f>>=5;

if(f){e|=32};

d+=String.fromCharCode(e+63);

} while(f!=0);

y = p[c+1];

yd = y - yo;

yo = y;

f = (Math.abs(yd)<<1)-(yd<0);

do {

e = f & 31;

f>>=5;

if(f){e|=32};

d+=String.fromCharCode(e+63);

} while (f != 0);

}

return d;

}

Posted by Christy Little on June 8, 2005 at 4:54 p.m.:

You're on the national wire!

Posted by David Woods on June 9, 2005 at 1:43 p.m.:

Hey, nice CNN article! Congratulations!

Posted by Eric Meyer on June 9, 2005 at 2:21 p.m.:

To echo David's comment, congratulations!

Though I don't necessarily agree with you entirely that the world is better wherever there's more information. I'd say the world is better when there's better information-- and that's definitely what you've provided in this case.

Posted by Dan Bassill on June 9, 2005 at 5:30 p.m.:

Hi Adrian, great stuff.

I lead a non profit in Chicago (Tutor/Mentor Connection) that's been trying to use a GIS system to draw volunteers and donors to tutor/mentor programs located in high poverty neighborhoods and near poorly performing schools throughout the city. Visit the Program Locator at www.tutormentorexchange.net and you can see examples of this.

Visit the Tutor/Mentor Institute part of the same site and you can read a power point essay that shows how we think the President, CEOs and School leaders should be using maps to create a more even distribution of support services in places where they are most needed.

Finding volunteers who have time to work on a project like this, or finding donors to fund it, has been nearly impossible, so our GIS moves forward at a slow pace. If any of you reading this would like to get involved, I think you can apply the concept to any social service in the country.

Dan Bassill, tutormentor2@earthlink.net

Posted by Jason La on June 9, 2005 at 8:02 p.m.:

Congratulations on the Los Angeles Times article.

Posted by Brian on June 24, 2005 at 4:14 p.m.:

A great (and free) tool for extracting coordinate information out of shapefiles using VB/VBA without any GIS software was written by Ross Pickard.....

http://arcscripts.esri.com/details.asp?dbid=11810

Thanks for the crime site and hack info--consider me duly inspired.

Posted by lara on July 21, 2005 at 7:58 a.m.:

This java script code is working or it just fake .i will it.If it would work i am thankfull to u. It will help me alot.l

Posted by anonymous on July 27, 2005 at 2:01 p.m.:

Have you seen postalcoded.com? It's been doing this for a while.

Posted by chris on August 2, 2005 at 7:47 p.m.:

I am a GIS analyst, and what I recemmend is to simplify the the number of vectors (points) that create the line or polygon of zip code boundaries. You would edit the GIS shapefile

in a program such as ArcView by ESRI, and there are some public domain GIS programs

out there that also allow you to edit shapefiles. There are some arcscripts that can

do this for you, so you don't spend hours removing vertices by hand. See ESRI's ARSCRIPT website.

Chris (mapmedia@sbcglobal.net)

Posted by Kyle Mulka on August 11, 2005 at 8:44 p.m.:

Why worry about the hassle of exporting shapefiles to something else when you could just load them into mapserver and serve them as WFS right into Google Maps like I've done here?

http://blog.kylemulka.com/?p=289

Posted by Adrian on August 12, 2005 at 12:32 a.m.:

Kyle: Because I don't want to run MapServer, for performance reasons.

Posted by anonymous on September 12, 2005 at 6:21 p.m.:

Here is a link where you can directly upload a polyline shapefiles (WGS84) and see it displayed on a Googlemap :

http://www.wildsoft.org/surveyarea/map/map.aspx

Posted by flux on December 13, 2005 at 12:28 p.m.:

I imported the geometry for the zip codes but now I have a multipolygon. What kind of query are you using to get all of the lat/long points for the polygon for google maps? I'm new to this GIS stuff so I'm a bit confused.

Posted by sean on December 14, 2005 at 8:57 p.m.:

Ok, but tell me. Can anyone have a user draw / circle regions over a map and return the zip codes in the enclosed areas? That would be very useful. Perhaps with the new Flash Yahoo Maps api.

Posted by gp on January 16, 2006 at 11:25 a.m.:

Sean,

Try http://www.melissadata.com/Lookups/zipradius.asp

you put in a zip and radius and get back a list of all zips. Not exact but close.

Posted by Eric Pollitt on February 21, 2006 at 3:18 p.m.:

I would like to be able to plot all my customers zip codes (heck, even houses would be cool) to a national map, the way that old school salesmen used to use push-pins on wall maps. I'd appreciate any help.

Comments have been turned off for this entry.