Well, I never thought it would happen, but it turns out one of those annoying chores of uni work actually paid off, in a non-too-trivial way. For project we’re expected to keep, and are marked on, a log book. Now, I’m all for taking notes of things; everything within reach of my desk has crap written all over it. But I have a pretty high turnover; once I’m done with something, I throw it out. At best it gets collected with dozens or even hundreds of other scraps in a folder somewhere to slowly compost.
But, since I intend to do well with this project, and because in this case collating all my scribbles wouldn’t be such a bad idea, I’ve relented and spent the last week pulling all my bits and pieces together into a single book. Well… more or less.. it’s already bulging with scrap paper and printouts and whatnot… but anyway. :)
So, while going through and writing stuff up in the book – most of which is copied verbatim from other places, like emails, this journal, MSN logs, etc – it was all very menial, and absolutely unproductive. It’s kept me from playing with Google Maps all weekend, for what little time I did have available for it, which wasn’t doing anything to rectify the log book’s position in my bad books.
[honestly, no pun intended… I didn’t even see that one until I was proof reading :) ]
Until, of course, I decided to write down a summary of the relevant parts of the Google Maps API. I expected this would be menial and useless as well, until I got almost all the way through, and realised something… some methods in the API (GProjection
‘s fromLatLngToPixel()
and fromPixelToLatLng()
) weren’t what I’d first read them as. I’d initially taken them as being an underlying implementation for GMap2
‘s similarly-named methods, fromLatLngToDivPixel()
and fromDivPixelToLatLng()
. Of course, when you actually read them carefully, and the associated documentation, you realise they are subtly different. While GMap2
works in screen co-ords (relative to the DIV containing the map), GProjection
‘s versions work in absolute pixel co-ords. As in, {0, 0} being the upper left-most pixel of the entire map layer, regardless of it’s position in (or out of) view. *bells and sirens and streamers*
So, a quick bit of JavaScriptery later, I’d confirmed that these methods do work as advertised, which gives a trivial three-step process for translating a latitude and longitude into an image URL. It is:
- Use the
GProjection
methodfromLatLngToPixel()
to determine the absolute pixel position of a given latitude/longitude, at a given zoom level (0 being furthest away). (AGProjection
instance can be retrieved from the relevantGMapType
using itsgetProjection()
method) - Get the tile size of the map in question, using
GMapType
‘sgetTileSize()
method, and divide the pixel co-ords from the previous step by these. Round down to yield the tile index of the relevant map. - Use the appropriate
GTileLayer
‘sgetTileUrl()
method to retrieve the exact URL desired.
It’s that easy! No need to worry about approximations and complex caching and querying and all that crap… just query for the exact point I want. And once I know the tile index of the main tile of interest, I can iterate over the surrounding tiles to expand the mapped area. Superb!
And this wouldn’t have been discovered if I hadn’t been writing it up in all it’s anal-retentive glory. So while I’m not quite at the point of screaming hallelujah and joining the logbook band, it has probably saved me as much work as I could have got done this last week anyway. So I guess it’s covered it’s own cost, thus far…
So the next stage will be to write a cache to work exclusively with a WebView hosting Google Maps, which will retain imagery and provide a nice ObjC interface for retrieving it (and caching associated data like lat/long bounds of each image, etc).
I guess now it’s time to actually drop in an OpenGL view and start doing the 3D world view.