Rich's Adventures with Google Maps & Fusion Tables
Something came along the other day that caught my attention. The 'brief' was to create an interactive map that displayed countries based on a 'risk' level. That was it. (after all, it was just a prototype, to see a) what was possible and b) the best way to go about this.)Obviously, it was Google Maps that was the immediate front-runner for this.. I've tinkered with gmaps a little in the past, but not really delved into what you can actually achieve. A previous project I'd worked on called for an interactive map,with custom routes that didnt stick to any roads. (I'll cover that in a seperate post).
Initial steps
My first foray into coding this hinged on what I'd done in previous projects.. namely plotting the points using some very handy sites that let you plot your points, then gave you the javascript code for the latitude and longitude for each point.After mapping out two countries by hand, I realised that this was futile task. Not only would it take you aaages to map out each country that you wanted (depending on how 'close' to the actual country borders you wanted to go. Having fairly coarse points worked ok when zoomed right out, but as soon as you zoomed in closer, you could see that the points did not match the borders), it would also be a right pain to maintain, or add new 'countries'.
Plotting points by hand = off the cards. Time for a re-think.
KML files
A bit more research, and I discovered KML (Keyhole Markup Language) files. Now some of you may be thinking "err.. little late to the game, arn't you?". Well, yes. But hey-ho!So KML files are basically XML files, which can contain one or more <Placemark> elements. These, in turn can contain one or more <Geometry> elements.
A quick google around brought me a KML file of all the worlds country borders in one handy file. Bonus!
Half my work is done!
Quickly dropping the required code into a page resulted in.... nothing. Just a normal map. no borders or anything. Hmm.
A quick scan of the documentation resulted in the titbit of information I missed earlier. In order for Google Maps to successfully parse a KML file, it needs to be hosted on a public, internet-facing site. Doh!
It makes sense though, Google reads the information in the file, then geo-codes the locations on their servers, and sends back the map layers to you.
Ok, attempt no2. Upload the KML file to my Google Drive lcoation, and amend the source code accordingly. a quick Ctrl-F5 then resulted in the map appearing. Success! However, it had put a nice blue border around EVERY country on the map. Hmm, lets sort that out.
A scan of the KML file, and I spotted the <Style> sections.. perfect!
Quick amend to that, re-upload and re-test. Better now.
Now, I the brief was to have a 'risk' level associated with a country. So, quick read up of the documentation again, and it throws up a gotcha - you can only have up to 5 styles per KML layer.
Luckily, in my case, I only required 3, so it's all good.
Onto my next issue.. Maintainability. To be able to add new countries, you'd need to edit the KML, add all your new placemarkers in etc. For some reason, I can't see a client spending the time to do this. (It's not very easy, or a quick process). So, whilst it does what I wanted it to do.. there has to be a better way.
Enter Fusion Tables
I'd not come across Fusion Tables before.. I've seen a few posts on StackOverflow etc when researching KML files that mentioned them. Bit of reading up I think!
The premis of Fusion Tables is simple.. it's basically a (simple) database-in-the-cloud. Columns, Rows.. all that jazz.
The clever part of Fusion Tables, is the fact you can merge data from one table, with that of another to create a third table, which you use on your map.
You can search for publicly available tables that contain the information you want. In my case, a search for 'World Country Borders' threw up a result.. a public table that contains all the countries of the world, with the lat/lng of the borders. the special column for me was the 'geometry' column. This effectivley holds a KML file for each country (see KML above).
I downloaded the data, re-uploaded to my GDrive account, and added a new 'RiskLevel' column. There we go, there's all the countries of the world, with all the KML data needed in one fell swoop!
A few things to note about using Fusion Table data in your maps.
V3 of Google Maps no longer requires an API key. Fusion Tables, however do. no biggie - just go to the Google API Console, and create yourself an api key.Once you have an api key, click on 'Services' in the left menu, and pick and choose the services you require.
Once you have your table already set up and ready to go, adding that data to your map is remarkably easy:
1: <div id="googleMap" style="height: 500px;width:500px"></div>
2:
3: <script type="text/javascript">
4:
5: // the URL to Google's fusion table service
6: var queryurl = "https://www.googleapis.com/fusiontables/v1/query?key=xxxxxxxxxx&sql=";
7: var table = "1I7F5us4zbKrwOsPMsc8jUqBwkI9MwbIHNpRtEgM";
8:
9: /* map variables */
10: var mapCenter = new google.maps.LatLng(53.739358, -2.445720);
11: var mapStyles = [
12: { featureType: "water", stylers: [{ color: "#808080"}] }, { featureType: "administrative.country", stylers: [{ visibility: "on"}] }, { featureType: "landscape", elementType: "geometry.stroke", stylers: [{ visibility: "off"}] }, { featureType: "poi", stylers: [{ visibility: "off"}] }, { featureType: "administrative.province", stylers: [{ visibility: "off"}] }, { featureType: "administrative.country", stylers: [{ visibility: "on"}] }
13: ];
14:
15: var mapOptions = {
16: center: mapCenter,
17: zoom: 3,
18: mapTypeId: google.maps.MapTypeId.ROADMAP,
19: styles: mapStyles
20: };
21:
22: var map = new google.maps.Map(document.getElementById("googleMap"), mapOptions);
23:
24: var fusionLayer = new google.maps.FusionTablesLayer({
25: query: {
26: select: "'geometry'",
27: from: table
28: },
29: map: map,
30: });
31:
Mostly all normal Google maps stuffs, apart from the final variable. you create a new google.maps.FusionTablesLayer(), and select the column(s) that you want. In this case, the 'geometry' column held everything that I needed. And, to top it all off, clicking on a country will open the standard google InfoWindow with some data, without any extra code or effort.
Now I'd got the data loaded (and it's rapid.. quicker than using the KML files), it was time to differentiate my countries into their 'risks'. (You may remember the 'RiskLevel' column I added above.. this is where it comes into play).
Styling a FusionTable map is much easier, as with KML files, you cannot use javascript to style the maps.. therefore, that means no dynamic styling. :(
Adding a style to the layer is easy..
1: var fusionLayer = new google.maps.FusionTablesLayer({
2: query: {
3: select: "'geometry'",
4: from: tablename
5: },
6: styles: [
7: {
8: where : "RiskLevel = ''",
9: polygonOptions: {
10: fillColor: layerStyles.blank.color,
11: fillOpacity: layerStyles.blank.opacity
12: }
13: },
14: {
15: where: "RiskLevel = 'Low'",
16: polygonOptions: {
17: fillColor: layerStyles.low.color,
18: fillOpacity: layerStyles.low.opacity
19: }
20: }
21: ],
22: map: map,
23: });
As you can see, you can 'where' clauses in your style elements, which will only be applied if that clause matches.
This code resulted in a map of the world, with those countries that I'd filled in information in in my FusionTable, being output on the map, with the styles set above.
How cool is that? and (once you know how it all works, and have everything set up), remarkably easy to work with, and edit.
Oh yeah, about editing.. edit the data in your FusionTable, refresh your map, and bammo! instant update :)
No more having to compress large KML files, upload etc. It's all in the cloud, and it's all instant!
So there you go, hopefully I've given you some tips on how to use Fusion Tables, and the benefit they could bring. (I'm currently extending my initial test to be something more useful.. with multiple tables, and interactive-ness to it)
No comments:
Post a Comment