Google maps API v3 - KML Layer changes - google-maps-api-3

I use google.maps.KmlLayer('http://mywebsite.com/my.kml') to set objects from KML file. It is working, but when I change kml and try to refresh website...I still have the same state as before...without my changes. When I change file name to my2.kml - it is working... Are google caching my kml? What I need to do to update changes with the same kml file name?

The Google servers do in fact cache KML data. Because the Google servers are processing your KML and not your browser, clearing your cache will not help. This is why changing the file name works. In order to prevent caching, add a cache-buster to your KML URL that you create the KML layer with, such as a random number or the current timestamp. http://mywebsite.com/my.kml?rev=323626252346 where the value of rev changes every time you refresh the page would work. You could also write Javascript so that you can click a button that updates the URL on the KML Layer object, removing the need to refresh the page.

Yes, google servers cache the KML data. So avoid this caching, change the kml url to
"http://www.kmlsource.com/foo.kml?dummy=" + (new Date()).getTime();
This will always generate a new website and the caching problem will be solved.

I would like to add a strong caveat to the advice to add cache-busting to the KML URLs: please note that if you use a timestamp like (new Date()).getTime(), this means that Google will try to fetch the KML file from your server almost every time a user tries to display your KML layer.
Two consequences:
the bandwidth and CPU used by simultaneous file uploads can get very high if you have a peak of visitors on your website (this will of course also depend on the size of your KML);
this in turn can add big delays to show the KML on your map.
A better strategy would be to only add a cache-busting parameter when you know the KML has changed. Maybe the browser could receive a hash of your KML file from your server, or a version number of the KML, and add that as an extra parameter to the request. You'd need to recompute the hash, or generate a new version number, every time the KML file got updated.
A lazier, far less efficient idea, would be for the server to generate a new token at regular intervals (e.g. once every 10 minutes, make it a reasonable period for your use-case), and have the browser use that token when it needs to display the KML file.
A much worse idea, but still a little bit better than using a browser-side millisecond timestamp to do cache-busting, is to only change the parameter at most once every 10 minutes on the browser side.
For example, instead of (new Date()).getTime(), you could use something like: Math.floor((new Date()).getTime()/1000/(10*60))*(10*60)
Note that this is a pretty bad solution, because this will still be computed based on the end-user's computer clock. If the end-users have set up incorrect times on their machines, many different timestamps can still be generated within a short period of time.
One of the advantages of using KML layers in Google Maps JavaScript API is that they get cached on Google side: if you don't need that, you might be better served with layers built directly on the browser-side. E.g. use GeoJSON. There is even a doc for that for the Google JS API: https://developers.google.com/maps/documentation/javascript/datalayer#load_geojson

Related

Google Maps Pinpoint Display

My friend has a website named as http://jobifly.com .Now the issue is that when you enter the site you will see Google maps on the navigation panel and that shows the jobs which are available, but its Pin-pointing them one by one, can't it show all of them together?
Awaiting Response..
Regards,
Zain Sohail
The problem with the page is that all the locations will be gecoded when the page loads. To avoid the OVER_QUERY_LIMIT this will be done with a delay.
To show them together you must wait until all locations have been geocoded.
So your friend may either:
use the current geocoding-strategy and initialize the map when all addresses have been geocoded(I don't think that it is an option for your friend)
or store the LatLng's somewhere when they have been geocoded, so he can use them directly without a delay (Note: this is only permitted for up to 30 days)
It's also possible to use a FusionTable to store these data, the geocoding would be done automatically there.
Another option to be able to store the LatLng's permanent: give the users that offer a job a map where they can select the location manually by clicking on the map, the returned LatLng may be stored without restrictions.

Google Maps - Caching - Methods

Ok! So I have spoken to a google representative about this issue, however since I am not enterprise level, he can't push me to tech support and suggested that I use the SO for answers. Here is the question...
In Google Maps Terms it states the following:
(b) No Pre-Fetching, Caching, or Storage of Content. You must not pre-fetch, cache, or store
any Content, except that you may store: (i) limited amounts of Content for the purpose of
improving the performance of your Maps API Implementation if you do so temporarily (and in
no event for more than 30 calendar days), securely, and in a manner that does not permit
use of the Content outside of the Service; and (ii) any content identifier or key that
the Maps APIs Documentation specifically permits you to store. For example, you must not
use the Content to create an independent database of "places" or other local listings
information.
This led me to originally believe that google would not allow caching of any type of information. However, then I read the following:
When to Use Client-Side Geocoding
The basic answer is "almost always." As geocoding limits are per user session, there is no risk that your application will reach a global limit as your userbase grows. Client-side geocoding will not face a quota limit unless you perform a batch of geocoding requests within a user session. Therefore, running client-side geocoding, you generally don't have to worry about your quota.
Two basic architectures for client-side geocoding exist.
Run the geocoding and display entirely in the browser. For instance, the user enters an address on your page. Your application geocodes it. Then your page uses the geocode to create a marker on the map. Or your app does some simple analysis using the geocode. No data is sent to your server. This reduces load on your server, but doesn't give you any sense of what your users are doing.
Run the geocode in the browser and then send it to the server. For instance, the user enters an address. Your application geocodes it in the browser. The app then sends the data to your server. The server responds with some data, such as nearby points of interest. This allows you to customize a response based on your own data, and also to cache the geocode if you want. This cache allows you to optimize even more. You can even query the server with the address, see if you have a recently cached geocode for it, and if you do, use that. If you don't, then return no result to the browser, and let it geocode the result and send it back to the server to for caching.
So one side says you cannot cache, the other side tells you, you should. Another solution it states is to always use clientside when you can, but then this becomes a grey area as well, because both examples state that you must have a user input data. What if the jquery read data from a div or span and then geocoded the information? The user wouldn't have actually done the geocode,but it was still done client-side? I'm trying to create a site that has a bunch of events generated by users and this site could get pretty loaded, so I am trying to determine the best practice in being able to do this. Google suggested here, so before you go and say this is "off-topic" please note, this is where they stated me to post.
Any feedback would be greatly appreciated.
The first quote does not explicitly forbid caching data at all. It is ambiguous as to how much you can cache (what number explicitly is "limited amounts"?) but it does not forbid caching.
You are allowed to cache the data if it helps improve the performance of your site as long as you retain the data for no longer than 30 days and do not make it available in any way to any other service except the service that originally retrieved the data.
Regarding user interaction - if your user explicitly enters a page with the expectation that they will be shown geocoded information I would assume that this would fulfill "user interaction".
As an example from a project I worked on last year I had it set up to do the following:
- Show markers on the map
- If the user clicked a marker they were shown a popup with data from the cache if available, otherwise a geocode would be performed and the returned information would be cached along with the date/time of the cache.
Another page of the site showed a history of these markers at 5 minute intervals throughout the day. If cached data was present (from clicking the map marker as in the previous part) this would be shown, otherwise a geocode would be performed and the data cached as before. The user clicking to run the report was (in my opinion) enough "user interaction" to not count as pre-fetching as the user had to manually select a timeframe before the report would be displayed.
A cronjob then ran every day at midnight which would go through each record with cached data over 25 days old and remove it.
As it was I was caching much less than 10% of the marker positions being shown (20+ markers being updated every minute, but the report was being run on maybe 3-5 markers each day and only geocoding data for every 5th point).

Issues with KML Layers limit

I have loaded 6 kml layers via url to my website to be toggled off/on by checkboxes. I have recently notice though, that it will only allow me to show 4 kml's at a given time. When I select more than 4 the 5th and 6th does not show. It does not matter what ones I choose, it seems to limit me to only showing 4. Can someone direct me on what may be causing this or should I be coding this some other way? The kml's by themselves do work and are under 800kb. Is just seems very weird that I can only have 4 kml showing at a given time.
This is the site - www.gbnrtc.org/bikemap
If you check the KML Support page, which lists the level of KML support provided for Google Maps and Google Maps for mobile, it lists the following size and complexity restrictions:
Maximum fetched file size (raw KML, raw GeoRSS, or compressed KMZ): 3MB
Maximum uncompressed KML file size: 10MB
Maximum number of Network Links: 10
Maximum number of total document-wide features: 1,000
Given that you estimate your file size at ~800K, that would put you right around 3.2 MB for four of your files. Without knowing more about your KML content, it seems to make sense that the limit would gate you after loading four.
This answer is quite old. I have found a great library to load large KML/KMZ files (even if Google is throwing an error). Please note that the library is quite old and have not received any update.
Here are more details about it:
Using GeoXML, I was able to add all the required KMLs to the map successfully! https://github.com/geocodezip/geoxml3
Step 1: Download and include geoxml3.js script
<script src="geoxml3.js"></script> // include after google map api script
Stpe 2: Instantiate and initialize the object in JS:
var myParser = new geoXML3.parser({map: map});
myParser.parse('/path/to/data.kml');
And this will load the KMl file.

Hiding google maps raw data from user

I am trying to get into the google maps api v3 to display store locations.
All non-flash tutorials for google maps, which I have seen so far, create an array with the latitude and longitude in either java script part of the html or in a seperate js file.
However, then I list all coordinates in plain text in the requested html site.
Is there a way to hide the exact location in a seperate file or layer, which is not accessible to the user? I would like to display the locations with a broad view and would like to keep the exact locations hidden.
Thank you for any suggestions.
I do not know if it is possible to do, but you can try create external PHP script that will returns JSON output with all Google Maps data.
In the beggining of the script you can check referer and it is correct (equals to the site script) show that data - otherwise, print some error, etc.
In JavaScript load whole data with Ajax.
However there is no way to permanently hide data from user - it is always possible to write some script that will export them from Google Map (for example using FireBug/Chrome console).

Capturing a Map to embed in a Wordpress Blog post

I originally asked this question on Super User but was told that it might be better placed here...
I have a running blog and to help me track and write about my runs I've recently bought a Garmin GPS watch. The setup works a treat and I'm able to share links to my runs in my blog such as:
http://connect.garmin.com/activity/23842182
Is there an easy way for me to capture the map itself out of the Garmin Connect site (see the link) and display it in my blog posting? I can take a screenshot but an interactive map would be heaps better. It's obviously a Google Map with the run info overlayed so there must be a way... right?
To created an embedded interactive Google Map to render your run polylines, you will need to extract the data that the Garmin site is using to render the line.
From the Garmin site, there are two Javascript files that do the work:
http://connect.garmin.com/resource/garmin-js-lib/map/MapsUtil.js - Bunch of utility functions for rendering Google maps based on data in the Garmin system
http://connect.garmin.com/api/activity/component/mapLoader.js - Uses Garmin.service.ActivityClient to grab the JSON data describing the polyline. It feeds this data into Garmin.map.MapsUtil.addEncodedPolylineToMap to render the map.
So do do this on your blog, you will need to either request the JSON data from the Garmin site (and trust that the URI format doesn't change) or grab the data and store it on your own site. The URI format is currently:
http://connect.garmin.com/proxy/activity-service-1.0/gpolyline/activity/<activity id>?full=true
Where activity ID is the last number in your original URL. So:
http://connect.garmin.com/activity/23842182
http://connect.garmin.com/proxy/activity-service-1.0/gpolyline/activity/23842182?full=true
This data request will return some JSON that you can then use to render a Google Map.
Once you have decided how you want to store the JSON data, you will need to write some Javascript to request the JSON and, in the callback, feed it into the GPolyline.fromEncoded method. Once you have a GPolyline object (that is populated from the encoded JSON data), you can add it to a Google Maps GMap2 with the addOverlay method.
I realize that this answer is fairly technically involved and might be overwhelming if you haven't played with Google Maps before. If this is the case, I suggest heading over to the Google Maps API intro page for some hints on getting started.
Since this question was first posted, Garmin Connect has since added a quick code snippet to embed in your WordPress site to display your maps and course data. If you're having issues getting the code snippet to stay in the post after saving - check out these instructions for embedding Garmin Connect activities in WordPress.

Resources