meyerweb.com

Skip to: site navigation/presentation
Skip to: Thoughts From Eric

Working With Google Maps

As I worked on HYDEsim, I discovered some interesting things about the Google Maps API.  Well, let’s call them what they are: limitations.

(And let me say right up front that if I missed ways to get around these limitations, then I’ll happily be corrected.  Either way, these are the impressions of someone whose first project in the API took about two days, and was in the end basically a success, which speaks volumes to the quality of the API.)

The first and most important limitation was that the Google Maps API permits the creation of two types of objects.  The first type is icons, the most obvious example of which are those little push-pin symbols in Google Maps that mark locations.  The second is polylines, which are how Google Maps draws the “get from here to there” routes on the maps.  You get both any time you ask for driving directions, like these from Norwalk, CT to New York City, NY.

Note that they’re polylines, not polygons.  You could certainly draw a polygonal shape using a polyline, but you couldn’t easily fill it with a color, let alone a translucent color.  And as for a circle… well, if you want to draw enough line segments so that you approximate the roundness of a circle, you certainly can.  It just doesn’t seem like a great idea.  Plus there’s no simple way to fill it in.

So in order to draw the overpressure rings, I created a 1000×1000 pixel 24-bit PNG of a circle.  To create a ring, I first used the Google Maps API to figure out the latitude and longitude boundaries of the map.  From that, I determined the number of miles per degree based on the latitude, and then calculated the number of miles per pixel (mpp) within the view.  From there, I determined how wide a ring needed to be to be the right size, created an icon at that size using the big PNG, and added it as an icon.

Whew.

Okay, so that solved the problem of putting the rings on the map.  What it didn’t solve was what happened if the zoom level changed, because icons (being raster images) don’t zoom with the map.  By default, you wouldn’t want them to: if the pushpin kept growing with the map as you zoomed in, eventually it would get huge and blocky and obscure half the view.

Therefore, the upshot was that every time the zoom level changed, I had to rip away the rings and rebuild them entirely, based on the new mpp value.  It was easy to trigger the process:

GEvent.addListener(map, "zoom", zoomLimit);

That’s the API at work for me.  I just tack a listener onto the zoom event, and I’m ready to go.  Cool.  Rebuilding the icons—well, not so cool, although it doesn’t seem to kill the tool’s performance.

All this zoom handling was necessary because icons, as you might expect, are given dimensions in pixels.  Polylines, on the other hand, have each point defined with longitude/latitude coordinates.  That’s why polylines do scale with change in zoom level—as, again, you’d want them to do by default.  If I could have defined my icons’ sizes using longitude/latitude measures instead of pixels, I could have avoided the whole “recalculate the ring sizes every time the zoom level changes” bit and shaved two or three hours off of my development time.  (Which was, in total, 12 hours or less.)

Of course, if the API provided polygonal primitives, I’d have avoided even more hackery.  If I could have just drawn the circles as circles, using longitudinal degrees as the unit of sizing, then there’d have been even less work and a shorter development time.  Something like this:

var base = new GShape();
base.type = circle;
base.anchor = new GPoint(-73.9971, 40.7223);  // longitude,latitude
base.radius = 0.0273548;  // degrees of latitude

…or something to that effect, with properties for the color and thickness of the outline, and also for the color and transparency of the interior.  And so on.

By doing it this way, the shapes (and there could easily be many other types) would be like filled polylines, and would scale in size along with the map.  That would have made HYDESim a whole lot easier to create.

You might say, “That’s all well and good, Eric, but how many reasons are there to draw circles on a map besides charting widespread destruction?”  I thought of a few possibilities:

  • Explicitly showing the scope of a “show me hotels within this many miles of the specified address” type of request
  • Someone looking to recreate the WIMPUR map in Google Maps
  • Plotting Iridium flare intensities

I’m sure there are countless more.  As well, allowing for actual filled polygons would add extra possibilities to applications like chicagocrime.org, which uses polylines to draw ZIP code boundaries.  With filled polygons, they could shade the ZIP code in question… or shade all other ZIP codes while leaving the current one unshaded, in order to give it some extra visual pop.

There was one other thing I encountered that’s either a limitation, or I just couldn’t figure out how to deal with it.  If you click on a detonation point in HYDESim, it pops up a “blowup” window (their term, not mine!) that shows a zoomed-in view of that point on the map.  The overpressure ring overlays are faithfully reproduced on that map, but they aren’t scaled to its zoom level.  They exactly match the overlays on the main map, and zooming in and out in that window has no scaling effects.

Ideally, I’d just remove the overlays from the zoom window while leaving them in place on the larger map.  I couldn’t find a way to do it.  Failing that, I wanted to have the overlays correctly scaled.  No dice there either.  If there is a way to do either of these and I missed it, hopefully someone will let me know.  If not, it’s something I hope the API adds in the future.

The final observation has to do with the icons and interactivity.  I wanted to set the overpressure rings to be event-transparent.  In other words, I wanted to make it so that the rings didn’t exist as far as the event model was concerned.  That way, you could click-and-drag the map even if there’s a ring underneath the mouse pointer.  This didn’t appear to be possible, although again, maybe I just couldn’t figure out how.  I did play around with the imageMap property, but it didn’t seem to have much effect.  Figuring that out would be nice, though.  I could leave the detonation point active for popping open the blowup window, and make the rest inert.

Other than that, things went as smoothly as you might expect they would for someone with limited JavaScript skills and no prior experience with the Google Maps API.  The examples provided by Google on the documentation page helped immensely, actually, especially the AJAX example.  That let me split the city list into a separate file, thus making it much easier to maintain, and get my first hands-on experience with AJAX programming.  (I’ve seen AJAX applications before—as long as three years ago, actually—but never written any code along those lines.)

Oh, and one more thing—the fact that the Google Maps API key only works for a specific directory, and not any of its subdirectories, drove me up the wall.  Instead of generating a key for meyerweb.com that would cover anything I might do on the site, I’ll have to generate a new key for every new directory.  This is why I set up the directory /eric/tools/gmap/, but that just seems so… confining.  Similarly, it was annoying that the key was completely bound to the full address.  I generated the key for meyerweb.com/eric/tools/gmap/, so if anyone types in www.meyerweb.com/eric/tools/gmap/ they’ll get a key error.  It would be nice if at some future time the keys were a little more flexible than they are now.

17 Responses»

    • #1
    • Comment
    • Fri 15 Jul 2005
    • 1953
    Daniel E. Renfer wrote in to say...

    The way Google does their keys based on directories is really annoying. My application has two ways to access a particular page.

    http://www.kronkltd.net/mycyclopedia/display.php?Id=173
    or
    http://www.kronkltd.net/mycyclopedia/display.php/173

    I prefer to use the latter for links, but I still allow the former. I should have no problem with that, but Google reads those as two different directories. Now, whenever anybody tries to view a page using the first url scheme, they get an error.

    • #2
    • Comment
    • Fri 15 Jul 2005
    • 2020
    Richard Wright wrote in to say...

    “That”s all well and good, Eric, but how many reasons are there to draw circles on a map besides charting widespread destruction?”

    Before you do start a campaign of widespread destruction you’ll write an article explaining how to plan your carnage in CSS!

    • #3
    • Comment
    • Mon 18 Jul 2005
    • 1120
    Dan Kohn wrote in to say...

    Fantastic project. This is a great demonstration of the Google Maps API, and I hope you’ll email their dev board, as the Google guy who spoke at Where 2.0 seemed genuinely interested in feedback and improvement.

    Restricting keys to a directory does seem annoying, but restricting them to meyerweb.com vs. http://www.meyerweb.com should really not be an issue. The reality is that you should be using Apache mod_rewrite to standardize the domain name of your URLs on the fly. This improves cacheing, and also can have a big impact on SEO (otherwise, your PageRank can be split in half between the two formulations). Admittedly, .htaccess files are black magic, but I dove into the syntax enough to make this blog post, which should be easily adaptable.

    Note that the previous commenter should also be rewriting URLs to fix his problem as well.

    One other small thing. It would be really nice to include a short descriptions below each psi rating: disintegration, light damage to residential structures, etc.

    Thanks again for a great project.

    • #4
    • Comment
    • Mon 18 Jul 2005
    • 1620
    Isaac Z. Schlueter wrote in to say...

    It seems like the app isn’t working at the moment (possibly a momentary hiccough, and we should all just realize it’s beta and chill?)

    I can see the circles, and move them around, but the actual map/satellite background image is blank gray.

    Seems like the same is going on over at chicagocrime.org, so maybe it’s Google and not just you. (Or maybe it’s me?) However, maps.google.com seems to be working just fine.

    Anyway, you have a great site, and this was an interesting post. I’m going to have to figure out something fun to do with the google maps API now!

    • #5
    • Comment
    • Mon 18 Jul 2005
    • 1638
    Isaac Z. Schlueter wrote in to say...

    Nevermind, Doof = me.

    I had Firefox set to only images for the originating site only.

    Works fine.

    • #6
    • Comment
    • Tue 16 Aug 2005
    • 1604
    Joe wrote in to say...

    Re: “In other words, I wanted to make it so that the rings didn”t exist as far as the event model was concerned. That way, you could click-and-drag the map even if there”s a ring underneath the mouse pointer.”

    Did you try making the concentric rings the “shadow” of the GIcon, and the center area (as much as you want clickable) the “image”? It appears on maps.google.com that the shadows (of markers and of infoWindows) do not trigger events, whereas the marker images always do. And you can choose how the shadow is attached to the image.

    • #7
    • Comment
    • Fri 19 Aug 2005
    • 1603
    Dipesh wrote in to say...

    Hi Eric,

    Thanks for writing such a nice article demostrating usage of GAPI.

    I would like to know one thing, how did ya got lat/lan ? I mean the source for getting lat/lan? I need to find lat/lng for all the zipcodes? How can i do this without buying some data ? One option which i can see as of now is sitting for the whole day or more than that and use some webiste which allows me to enter zipcode and get the lat/lgn.

    Your input will be of great help to me.

    Hope to hear from you soon.

    Cheers!
    Dipesh

    • #8
    • Comment
    • Sun 2 Oct 2005
    • 2044
    AxsDeny wrote in to say...

    Did your radial distances take the curvature of the earth into account? I’m trying to write something similar as I need a 50 mile circle drawn around a particular lat/lon. I’m trying to figure out how to create php that will create an array of coordinates that fall at every 1 degree at 50 miles out from the center. I’m using the great circle method to determine distance based on coords. The issue is create the array. Converting the trigonometry to php is the issue. Anyone have any ideas? This may scale decently up to 100 miles out, after that it may get a little choppy in the circumference.

    • #9
    • Comment
    • Wed 5 Oct 2005
    • 0920
    eduardo wrote in to say...

    If you are interested Google Maps and Ajax maybe you would like:

    Panoramio.com

    • #10
    • Comment
    • Tue 13 Dec 2005
    • 1837
    Didi wrote in to say...

    Great use for terrorist!

    You could make a biological version as well and more….

    It really depends on your own attitude….

    Nevertheless it’s done very well.

    I’m using the API since 2 hours and think that I will link the cruising range of our liveaboard diving boat named “Tidak Apapa” the same way.

    I think this is a bit more creative approach than yours!

    :-) Dirk

    http://www.tidakapapa.com

    • #11
    • Comment
    • Sat 7 Jan 2006
    • 1407
    Patrick Desmarais wrote in to say...

    Just a little question…

    Is it me or they changed how the key works since you wrote this post?

    I had a map set up at the root of my server. I moved it in a subdirectory and it still works.

    It also works with and without the www subdomain…

    Is that normal?

    Thanks!

    • #12
    • Comment
    • Sun 8 Jan 2006
    • 1756
    Erik wrote in to say...

    Interesting..

    http://www.novelviews.com

    • #13
    • Comment
    • Fri 13 Jan 2006
    • 1739
    Brandon Swift wrote in to say...

    Cool app, Eric! I was fishing around trying to find how google generates their polyline overlays and ran across this, which might be very helpful to you!

    Apparently, google builds transparent png’s for non-IE browsers, but this guy worked around it so that they are generated by SVG instead. You can easily make filled circles and all sorts of other shapes with SVG (here’s a tutorial.

    Let me know if you get it working!!
    -Brandon

    • #14
    • Pingback
    • Thu 22 Jun 2006
    • 0016
    Received from lectroid.net » Blog Archive » Google Maps and Kismet

    […] Using the XML output from Kismet we can plot APs. Ok, but why stop there? I took a look at a page covering circles on Google Maps and figured since Kismet records min and max power locations, it might be fun to assume a full circle with the max power in the center and the distance between the min and max points being the radius. It’s not really accurate, but it is very interesting as a visualation tool. […]

    • #15
    • Comment
    • Fri 15 Dec 2006
    • 1803
    Pablo Veliz wrote in to say...


    function mapCircle(lat,lng,radius)
    {
        var points = [];
        x = lat;
        y = lng;
        r = radius;
        for (var i = 0; i < 37; i++) {
            x1 = x+r*Math.cos(2*Math.PI*i/36);
            y1 = y+r*Math.sin(2*Math.PI*i/36);
            points.push(new GLatLng(x1,y1));
        }
        return points;
    }

    map.addOverlay(new GPolyline( mapCircle(18.30124,-73.65197,0.001) ));

    // The code tag doesn´t seems to work fine

    • #16
    • Comment
    • Wed 2 May 2007
    • 0638
    Nick wrote in to say...

    Pablo Veliz, if you want your circle to be round in all parts of the world your math is a bit wrong. Due to the conversion factor from angular coordinates to cartesian coordinates, it goes a bit elliptical. The below seems to work.

    function mapCircle(lat,lng,radius)
    {
    var points = [];
    x = lat;
    y = lng;
    r = radius;
    for (var i = 0; i

    • #17
    • Comment
    • Wed 6 Feb 2008
    • 1346
    Robert Allen wrote in to say...

    Cheers for the information man, this is quite handy. Circles are giving me grief as well as I need to display radii (er, hope that right) on the map as well.

Leave a Comment

Line and paragraph breaks automatic, e-mail address required but never displayed, HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>



Remember to encode character entities if you're posting markup examples! Management reserves the right to edit or remove any comment—especially those that are abusive, irrelevant to the topic at hand, or made by anonymous posters—although honestly, most edits are a matter of fixing mangled markup. Thus the note about encoding your entities. If you're satisfied with what you've written, then go ahead...


July 2005
SMTWTFS
June August
 12
3456789
10111213141516
17181920212223
24252627282930
31  

Sidestep

Feeds

Extras