Problems changing kmlLayer dynamically on view change

115 views
Skip to first unread message

James Morley

unread,
Dec 15, 2011, 4:42:56 PM12/15/11
to google-map...@googlegroups.com
Hi, I'm fairly new to the Maps API, but I developed a simple kml service for displaying images from Flickr Commons in Google Earth and I was looking to see if there was a quick way of displaying this on an embedded map.  The service is delivered via a NetworkLink in the kml file at http://www.whatsthatpicture.com/flickr/commons.kml which calls http://www.whatsthatpicture.com/flickr/commons-kml.php?BBOX=a,b,c,d

I can of course get a crude web visualisation of this at e.g. http://maps.google.com/maps?q=http:%2F%2Fwhatsthatpicture.com%2Fflickr%2Fcommons.kml but there are several limitations and I want to create my own custom map.

I have got tantalisingly close using API v3.  You can see the latest efforts at http://www.whatsthatpicture.com/flickr/commons-map-v1.php.  This is intended to work as follows:
- initially calls the dynamic kml http://www.whatsthatpicture.com/flickr/commons-kml.php with no BBOX (retrieves latest 100 images globally) and loads into into kmlLayer (works fine)
- when the user pans or zooms it refreshes the kmlLayer with data called using the current parameters from getBounds (works with manually set BBOX value, not with getBounds - see below)

Sorry, long winded introduction, now onto the problems and questions ...

- I have managed to add listeners to get the basic user events, although I think they're a bit clumsy - suggestions welcome

- I seem to be able to manually construct a url to pass to my kml service and then display the results (currently set as a region covering western Europe).  I can also capture the current view using getBounds().  But trying to shape this into a standard BBOX format (removing parentheses and spaces) seems to break it, no matter what I try, so my ultimate aim of constructing the url using this has so far failed.

- when it has changed the view and layer, the listener that handles the placemark click seems to be lost, I assume because I've emptied the original layer and reloaded it?

- This was only intended as a 'quick win' re-using the existing kml, but I'm now starting to think that the effort I am putting into this would be better spent re-engineering it all to deliver json.  Agreed?!

- I've also now got the 'bug' and want to try more things with this, like custom icons (including a clear indication of the 'current' icon), a 'loading' image when data is being fetched, user input queries (the kml service accepts a simple q= to run a text search), and enhanced navigation.  I'd also quite like to display more placemarks and cluster them.

But before I plunge headlong into anything I'd welcome any advice, whether it's quick fixes, or longer-term approaches.

Thanks, James



Chad Killingsworth

unread,
Dec 15, 2011, 5:47:17 PM12/15/11
to google-map...@googlegroups.com
- I have managed to add listeners to get the basic user events, although I think they're a bit clumsy - suggestions welcome

Rather than using the "idle" event, have you tried "bounds_changed"?
 
- I seem to be able to manually construct a url to pass to my kml service and then display the results (currently set as a region covering western Europe).  I can also capture the current view using getBounds().  But trying to shape this into a standard BBOX format (removing parentheses and spaces) seems to break it, no matter what I try, so my ultimate aim of constructing the url using this has so far failed.

Instead of depending on the toString() implementation of the LatLngBounds object, manually construct your string. Something like:

mybbox.getNorthEast().lat() + "," + mybbox.getNorthEast().lng() + "," + ...
 
- when it has changed the view and layer, the listener that handles the placemark click seems to be lost, I assume because I've emptied the original layer and reloaded it?

Yup. You'll need to re-attach that even listener every time you call "new google.maps.KmlLayer"
 
- This was only intended as a 'quick win' re-using the existing kml, but I'm now starting to think that the effort I am putting into this would be better spent re-engineering it all to deliver json.  Agreed?!

Up to you - but as you said you are close.
 
- I've also now got the 'bug' and want to try more things with this, like custom icons (including a clear indication of the 'current' icon), a 'loading' image when data is being fetched, user input queries (the kml service accepts a simple q= to run a text search), and enhanced navigation.  I'd also quite like to display more placemarks and cluster them.

But before I plunge headlong into anything I'd welcome any advice, whether it's quick fixes, or longer-term approaches.

Thanks, James

It's a cool maps project. Just have fun with it. 

James Morley

unread,
Dec 16, 2011, 6:30:31 PM12/16/11
to google-map...@googlegroups.com
Hi Chad

Thanks so much for your reply - I think seem to have cracked it thanks to your tips.

Overall I think I simply overcomplicated things, and stripping it back has solved many problems (isn't that always the way?!).  My problem with using bounds_changed was that it triggered as soon as the map loaded, which I had set up to initialise with a sample dataset of the latest 100 images.  But you saying that then prompted me to question why I was doing that when I could actually use that event to set the first dataset, not just when the user intercated.  That in turn solved the problem with having to re-attach the listener - I only had to do it once so there was no need.  One thing I did find was that when the user dragged bounds_changed was repeatedly triggering, so I swapped it for 'idle'  which appears to work well (though you don't get to specify a delay like you do with a kml NetworkLink onStop property, so if a user drags then stops and drags again, you get two triggers and two kml calls).

You can see my latest efforts at http://www.whatsthatpicture.com/flickr/commons-map-v2.php

Rather than annoying alerts I've now got any debugging info going into the left window, latest at top.

The problem now seems to be impatience on Google's part, and the slowness of my response.  This is mainly because when an event is triggered it calls my sevrer, which fetches data 'live' from the Flickr api, and then has to be converted into kml before being returned.  And the unique nature of every call due to the variation in bbox parameters means caching is tricky using this method. So I do think I'll end up creating a local database of all image data (currently c. 17,000) which just gets updated periodically, perhaps overnight.  This will take out the Flickr requests and responses.

Aside from that, some little niggles that remain though ...

I used to have it set so that on any change the existing cleared and then new data loaded - now it just seems to add extra points and I'm not sure

I'd love to set a custom icon based on the one specified in the kml style, and also to have a different style one for the placemark that has just been clicked.  Is this relatively straight forward?

I'd also really like to have some sort of 'loading' image to show the server is doing something. Actually, thinking about this, I wonder if the map could send a request to my server to a script that kicks off the generation of the kml, and then wait for a prescribed period whilst the data is generated and cached, and then request it?  A bit clumsy, but I could see this working.

Anyway, thanks again for your help.  As you say, it's a cool project and I've already had some positive response from some of the museums involved in the Commons.  This was in response to a blog post I wrote - http://www.whatsthatpicture.com/2011/12/mapping-flickr-commons

Regards, James

Chad Killingsworth

unread,
Dec 16, 2011, 7:09:42 PM12/16/11
to google-map...@googlegroups.com
Glad I could help - even a little.

- You are correct in that many maps implementations end up writing their own throttling methods for events like "bounds_changed".

- The timeout of Google's servers in regards to kml file fetching is a frustration many face and your local caching solution sounds plausible.

- Highlighting the kml feature just clicked may prove challenging. You'll probably have to just place a duplicate marker on top of the one they clicked. So no - not straightforward.

- Loading feedback should be straight forward. I believe there is an event that gets triggered when the KmlLayer loads, but I can't remember for sure off the top of my head. The hard part is there is no real way other than a setTimeout to determine that the layer failed to load.
Reply all
Reply to author
Forward
0 new messages