Quick Demo - KML and CFMAP

This post is more than 2 years old.

A while ago I shared a few emails with a reader who wanted to know if it was possible to do KML operations with CFMAP. For those who don't know, KML is an XML format for geographical data. From what I've read, it allows for various types of overlays and data "skins" over map or Earth data. The reader, Richard Zawadzki, and I went back and forth a bit, but it was he who finally got it working and graciously allowed me to share his code.

To use KML with Google Maps, you simply need to follow the previous examples I've shared - get the map object. ColdFusion gives you the hooks to do so. Once you have it, you can then follow Google's KML docs to work with your data. Here is a quick example of the JavaScript here used. Only the first call is ColdFusion specific:


function AddKMLOverlay() {
	
	var map = ColdFusion.Map.getMapObject("mainMap");
	map.setCenter(new google.maps.LatLng(28.291889, -81.407793), 9);
	map.setZoom(9);
	
	var DRIKML = new GGeoXml("http://maps.google.com/maps/ms?ie=UTF8&hl=en&vps=4&jsv=201b&msa=0&output=nl&msid=101779661887239513456.000465f6105cf06ca4c63"); 
	map.addOverlay(DRIKML);
	
	var ParksKML = new GGeoXml("http://maps.google.com/maps/ms?ie=UTF8&hl=en&vps=5&jsv=201b&oe=UTF8&msa=0&output=nl&msid=101779661887239513456.000465f607e578d46cf83"); 
	map.addOverlay(ParksKML);
	
	var CountyKML = new GGeoXml("http://maps.google.com/maps/ms?ie=UTF8&hl=en&vps=5&jsv=201b&oe=UTF8&msa=0&output=nl&msid=101779661887239513456.00047e28dce659094bcb5"); 
	map.addOverlay(CountyKML);
 
}

You can see a demo of what he came up with here. (You can download the old code here: https://static.raymondcamden.com/enclosures/kmldemo.zip) I've included the complete code below. (And once again - I'm really impressed with everything that can be done with Google Maps!) (Note - I forgot to mention this when I first posted, but Richard asked that I also credit Steve Gongage, his coworker, for working on this as well.)


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Google Maps KML Overlays</title>

<script>
//<![CDATA[
function AddKMLOverlay() {
	
	var map = ColdFusion.Map.getMapObject("mainMap");
	map.setCenter(new google.maps.LatLng(28.291889, -81.407793), 9);
	map.setZoom(9);
	
	var DRIKML = new GGeoXml("http://maps.google.com/maps/ms?ie=UTF8&hl=en&vps=4&jsv=201b&msa=0&output=nl&msid=101779661887239513456.000465f6105cf06ca4c63"); 
	map.addOverlay(DRIKML);
	
	var ParksKML = new GGeoXml("http://maps.google.com/maps/ms?ie=UTF8&hl=en&vps=5&jsv=201b&oe=UTF8&msa=0&output=nl&msid=101779661887239513456.000465f607e578d46cf83"); 
	map.addOverlay(ParksKML);
	
	var CountyKML = new GGeoXml("http://maps.google.com/maps/ms?ie=UTF8&hl=en&vps=5&jsv=201b&oe=UTF8&msa=0&output=nl&msid=101779661887239513456.00047e28dce659094bcb5"); 
	map.addOverlay(CountyKML);

}

function init() {
	AddKMLOverlay();
}
//]]>
</script>


</head>

<body>

    <table width="100%" height="100%">
    <tr>
      <td align="center">
        <table>
          
          <tr align="left" valign="top">
            <td>
               <cfmap width="680" height="400" centeraddress="34741" zoomlevel="9" name="mainMap">    
                    <cfmapitem name="marker01"    
                        address="1 Courthouse Sq, Kissimmee, FL 34741 USA"    
                        tip="Osceola County Administration Building"/>    
                </cfmap>
            </td>
          </tr>

        </table>

      </td>
    </tr>
  </table>

</body>
</html>
<cfset ajaxOnLoad("init")>
Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by John Sieber posted on 3/4/2010 at 10:08 AM

Great to see this example as it is something I was hoping to do. I have some .kml files that I would like to display but I'm a still a little confused when trying to do this with my own files. In the countykml variable as an example, can the url point directly to a hosted kml file?

Comment 2 by Raymond Camden posted on 3/4/2010 at 5:13 PM

I think so. But you have to ensure your web server is set up to serve the KML file correctly.

Comment 3 by RickZ posted on 3/4/2010 at 7:08 PM

Hi John, yes, it can point directly to a hosted file. Like Ray said, you have to make sure that whatever webserver you're using is set-up with the correct mime-type for KML. For example, in Apache you'd add the following to your .htaccess file:

AddType application/vnd.google-earth.kml+xml kml

We use IIS and it's equally simple to add the correct mime-type.

You also need to make sure that your server is capable of back and forth communication with Google Maps. On our webstage server we were unable to map anything until we actually NAT'ed it out with a public domain.

Thanks Ray for your help and for posting this!

Comment 4 by Michael De Jonghe posted on 3/5/2010 at 3:23 AM

Very cool.

I've been trying to get cfmap to do "larger custom icons" and had some success... but the cfmap and my javascript LatLng don't match up because CF throws an error when it sees a CENTERLONGITUDE greater than -90.0. WHAT??

Try this bit...

<cfmap width="900" height="800" centerlatitude="34.0000" centerlongitude="-118.0000" zoomlevel="13" name="map" showcentermarker="no">
</cfmap>

That should be the center of Los Angeles California... it's a small town maybe CF hasn't heard about it yet.

Any ideas for the readers.

Comment 5 by Raymond Camden posted on 3/5/2010 at 3:26 AM

That's a known bug. I'd use an address for now, not a long/lat pair.

Comment 6 by Michael De Jonghe posted on 3/5/2010 at 3:50 AM

I figured out the Longitude error. CF seems to be using a 360 degree approach.

Simply add the negative Longitude from 360 and you'll get the positive number you need to make CFMap work.

<cfset lng = -118.0000>
<cfif lng lt 0>
<cfset lng = (360 + lng)>
</cfif>

<cfmap width="900" height="800" centerlatitude="34.0000" centerlongitude="#lng#" zoomlevel="8" name="map" showcentermarker="yes">
</cfmap>

Comment 7 by John Sieber posted on 3/5/2010 at 6:17 AM

Thanks Ray and Rick,
Adding the mime type to my server made it work. Thanks for sharing this!

Comment 8 by John Sieber posted on 3/5/2010 at 9:27 AM

One other item, if you need to show .gpx files as overlays you can add a mime type for gpx files and they will display as well. This will save me the step of converting my .gpx files to .kml.

Comment 9 by RickZ posted on 3/5/2010 at 7:24 PM

Michael- We bumped into that same issue and came up with an identical workaround. Unfortunate, but a small hiccup in an otherwise incredibly easy to use way of incorporating Google Maps.

John - I'm glad that we were able to help out. That's awesome that it works with other overlay types beyond KML. I searched all over for some reference to doing this and never really found anything. Ray pointed me in the right direction of experimenting with using the standard Google Maps API functions. It never even dawned on me that it would be that simple. The only caveat was that I had to declare the setCenter in the javascript. Leaving that out throws a an error in Firebug and prevents it from adding more than one map layer.

Comment 10 by theresa Valentine posted on 5/21/2011 at 12:55 AM

I've been trying to add a KML file to my application, and I can't see to get the KML file to draw using cold fusion tags. The kml file is ok, as I get it to draw in other apps.

<script>
//<![CDATA[
function AddKMLOverlay(){

var map = ColdFusion.Map.getMapObject("myMap");
map.setCenter(new google.maps.LatLng(44.212,-122.256), 13);
map.setZoom(13);

var boundKML = new GGeoXml("http://andrewsforest.oregon...");
map.addOverlay(boundKML);
}
function initialize() {
AddKMLOverlay();
}
//]]>
</script>

<table>
<cfoutput>
<h1>#dbcode#</h1>
</cfoutput>
<tr><td>
<cfmap width="680" height="400" centerlatitude="44.212" centerlongitude="-122.256" zoomlevel="9" typecontrol="advanced" name="myMap">
</cfmap>
</td></tr>
</table>
<cfset ajaxOnLoad("initialize")>

any ideas?

Comment 11 by Raymond Camden posted on 5/21/2011 at 12:56 AM

Is the URL to your KML file valid?

Comment 12 by theresa Valentine posted on 5/21/2011 at 1:16 AM

yes. I can get it to draw on when not using coldfusion tags.

Comment 13 by Raymond Camden posted on 5/21/2011 at 1:18 AM

Do you mean if you don't use CFMAP and just use Google maps by itself?

Comment 14 by theresa Valentine posted on 5/21/2011 at 2:06 AM

yes. I am trying to generate markers from a database query. I have one sample where I don't use cfmap and I can get the boundary and the markers, but the info windows all point to the same point (first record). I can get the info window to work if I use cfmap, but then I can't get the boundary kml to show. Sorry, my maps are behind firewall right now...
will see if I can get one working outside and post links.

Comment 15 by theresa Valentine posted on 5/21/2011 at 2:17 AM

here is one that works for one place and one the boundary

http://andrewsforest.oregon...

Comment 16 by theresa Valentine posted on 5/21/2011 at 2:42 AM

can't get it to work on our internet, as it's version 5 or so of CF.. and it doesn't like my tags..

Comment 17 by Raymond Camden posted on 5/21/2011 at 5:51 AM

Not sure what to tell you. You said you are on CF5 - CFMAP won't work there for sure. You can definitely do Google Maps via the JS api though.

Comment 18 by theresa Valentine posted on 5/23/2011 at 8:24 PM

figured out the problem. The script tag needed to be within the <head> tag for it to work.
Just to clarify, our development site is on version 9 of CF, but our production site (old site) is on version 5. I'll try and post a link when we go live with the new site. Thanks to Aimee Lesieutre for figuring this out for me.

Comment 19 by tdo posted on 11/2/2011 at 8:12 PM

any ideas on why this data won't work? it just pulls up the map but without the overlay.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1...">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Google Maps KML Overlays</title>

<cfajaximport params="#{googlemapkey='ABQIAAAAyBqdTNCO82gdyPcdR94xEBQLxw0Tb61Zhdk6a1DqnmRS3wNprhS8v8KU4__Dlq7yiLtBm5L1kZJSpQ'}#">

<script>
//<![CDATA[
function AddKMLOverlay() {

var map = ColdFusion.Map.getMapObject("mainMap");
map.setCenter(new google.maps.LatLng(33.710413, -117.951616), 9);
map.setZoom(9);

var NorthOC = new GGeoXml("http://maps.google.com/maps...");
map.addOverlay(NorthOC);

}

function init() {
AddKMLOverlay();
}
//]]>
</script>

</head>

<body>

<table width="100%" height="100%">
<tr>
<td align="center">
<table>

<tr align="left" valign="top">
<td>
<cfmap width="680" height="400" centeraddress="92708" zoomlevel="9" name="mainMap">
</cfmap>
</td>
</tr>

</table>

</td>
</tr>
</table>

</body>
</html>
<cfset ajaxOnLoad("init")>

Comment 20 by Raymond Camden posted on 11/2/2011 at 8:19 PM

Not sure. My old demo still seems to work fine.