Overview


What Is jKMLMap?


jKMLMap is a flexible, easy-to-use Javascript library for generating a Google Map from a KML file and embedding it in a webpage.

The main concept behind this script is that once you have it up and running, presenting user-friendly maps requires nothing more than making a KML file in Google Earth and dropping it on your server; the rest is handled automatically: paths, markers, pop-up marker descriptions, and default views are all taken directly from the KML.

The library can also generate a hierarchical sidebar menu based on the folder structure found in the KML, which visitors can use to show/hide individual markers or groups of markers in realtime. And because all the loading is done via AJAX, swapping maps does not require reloading the page - it can be done dynamically.

Features:
  • Automatically downloads a KML file and uses it to create an embedded Google Map.
  • Maps include clickable paths and markers (with pop-up descriptions).
  • Map views will automtically default to those set in the KML (and can be overridden).
  • Downloading is performed asynchronously; realtime progress can be displayed as a new map loads.
  • Collapsable sidebar menu allows users to dynamically add/remove/locate their markers.
  • Marker icons are customizable based on the text found in marker descriptions.
  • Doesn't depend on any third-party frameworks - just javascript.
  • No limit on the size of the KML file (beyond your browser's capabilities and desired download time).
  • Tested on IE6-9, Firefox 3-6, Opera 10, Safari 4, and Chrome 4-13.
    (Note that larger KMLs are likely to be slow on IE6, due to its outdated js engine.)

Live Demo


You can see the script in action on my Travellog page.


Basic Installation


Getting your first KMLMap up and running is simple:

1. Include the Google Maps and jKMLMap javascript in your page's <head> section, like this:
<head>
  <title>My KML Map</title>
  <script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false" ></script>
  <script type="text/javascript" src="/jKMLMap.js" ></script>
</head>
2. Setup the div where you'd like your map to be output, including its height and width. By default, maps will be outputted to "jKMLMap" (this can be customized later):
<body>
  <div id="jKMLMap" style="width:800px; height:600px;"></div>
</body>
3. Initialize jKMLMap and tell it to load a KML File:
<script type="text/javascript"> //<!--
  myKMLMap = new jKMLMap();                 //Create a new jKMLMap Object
  myKMLMap.LoadMap( '/maps/testMap.kml' );  //Load a map
// --></script>
4. That's it! The script will download the KML file, parse it, and generate an embedded Google Map in the "jKMLMap" div. Now let's move on to some of the real features...


Configuration


Once you've got a simple KMLMap up and running, you're ready to play with a bit of customization. There are three ways to customize your jKMLMap: by passing options to its constructor, by registering event callbacks, and by modifying the GMap object directly.

Options

To specify options to jKMLMap, we pass a single JSON object to its constructor, like so:
<script type="text/javascript"> //<!--
  myKMLMap = new jKMLMap({
                          mapDiv:    'kmlMapOut',
                          menuDiv:   'kmlMenuOut',
                          mkrBasic:   null,
                          mkrLinks:   CreateGIcon('/icons/book.png', 25, 20, true),
                          mkrSpecial: CreateGIcon('/icons/me.png', 39, 45, false),
                          mkrSpecialRegex: /Current Location/
                         });

  myKMLMap.LoadMap( '/maps/testMap.kml' );  //Once initialized, load as usual 
// --></script>
Here's what each of the options mean:
  • mapDiv - Specifies the ID of the div where the map will be output; defaults to "jKMLMap"
  • menuDiv - Specifies the ID of the div where the menu will be output; omit to skip menu generation.
  • mkrBasic - An icon to be used for the map's markers. If unspecified or null a default icon will be used.
    I've provided a global function CreateGIcon() to make it easier to create custom icons (described below).
  • mkrLinks - An icon that can differentiate markers whose pop-up descriptions contain a hyperlink.
  • mkrSpecial - An icon that can differentiate markers with user-defined text in their descriptions.
  • mkrSpecialRegex - A regular expression used to trigger a mkrSpecial. Default is "Current Location".
CreateGIcon()'s parameters are: ImageFilename, Width, Height, Centered. If Centered is true, the marker will be oriented relative to its center (like a target), otherwise it'll be relative to its bottom (like a pushpin).

Callbacks

In addition to specifying options to the constructor, you can register callbacks to be notified when a certain event occurs. This is useful if you want to hide the menu while it's loading, show the user a progressbar, etc. Events are registered by calling RegisterCallback(name, func), like this:
<script type="text/javascript"> //<!--
  myKMLMap = new jKMLMap();
  
  //Register a callback to hide the menu and show a status div when loading begins
  myKMLMap.RegisterCallback('onStart', function()
  {
      jQuery("#kmlStatusOut").toggle(true);
      jQuery("#kmlMenuOut").toggle(false);
  });

  //Register a callback to show progress updates while loading
  myKMLMap.RegisterCallback('onProgress', function(msg,percent)
  {
      document.getElementById('kmlStatusOut').innerHTML = msg + " ("+percent+"%)";
  });
  
  //Register a callback to hide the status div and reveal the menu when complete
  myKMLMap.RegisterCallback('onComplete', function()
  {
      jQuery("#kmlStatusOut").toggle(false);
      jQuery("#kmlMenuOut").toggle(true);
  });
  
  myKMLMap.LoadMap( '/maps/testMap.kml' );  //Load the map as usual 
// --></script>

Google Maps API

Another way you can customize your map is by modifying it directly with the Google Maps API. For example, if you want to manually override the view parsed from the KML:
<script type="text/javascript"> //<!--
  myKMLMap = new jKMLMap();

  myKMLMap.RegisterCallback('onComplete', function()
  {
      myKMLMap.map.setCenter(new google.maps.LatLng(-164, 9.5), 2);
  });
  
  myKMLMap.LoadMap( '/maps/testMap.kml' ); 
// --></script>
There are loads of advanced customizations you can achieve directly with the Google Maps API.

Map Switching

One handy feature is that it's easy to dynamically swap between maps without requiring the user to reload the page. You can see my Live Demo for an example of this:
<h3>Map Selection:</h3>
<form name="mapSelection" action="javascript:void(0);">
 <select onchange="myMap.LoadMap(this.options[this.selectedIndex].value)" name="k">
  <option value="/kml/map1.kml">Current Location</option>
  <option value="/kml/map2.kml">My Trip to Europe</option>
  <option value="/kml/map3.kml">RoadTrip 2010</option>
 </select>
</form>

Download


Latest Version: 1.1.3 (01/03/2013):
  • Production Version - YUI Compressed Javascript. Most users should download this version.
  • Development Version - Uncompressed Javascript. For coders wanting to modify the script themselves.
If you find this script useful, please consider making a donation to the author.

License & Usage


This script is released under the creative commons Attribution-ShareAlike 2.5 license for personal use, meaning you're free to use, modify, and redestribute it as you see fit - provided that you do not represent it as your own work, and that you attribute it to me as the author. By default the script will output a very small "Created by jKMLMap" link below the map itself; as long as you don't remove it, you're fine. If it is necessary to remove it for aesthetic reasons, you must replace it with something similarly visible that refers back to this page. Other than that, it's all yours.

If you're interested in using it commercially, please contact me directly.


Feedback/Support


If you have feedback or support requests, please use the comment form below and I'll reply as soon as I can.

  61 Responses to “jKMLMap”

  1. Beautiful plugin. I’d love to see it working with an event’s calendar !

  2. Thanks! 🙂 Haha with the nearly 500 comments on one of my other plugins I’d wondered if anyone even noticed this one – but I guess in general people like plug-and-play better than something that requires writing actual code 😉

    I’d be interested to see your use for it, if you do get one up-and-running!

  3. Great Job Justin. Thanks

  4. Looks great. Been looking for a wordpress plugin to visualize my travels for ages. Now before I start, do you know of a good and free KML editor? preferably a visual one? The only one I can find doesn’t seem to work with the latest Google Earth version…

  5. It definitely works with Google Earth – that’s exactly what I wrote it for (and what I used to make everything on the travellog)! 🙂

  6. *putting on my confused look* I thought one has to manually generate a KML file? I googled and all I found was Google’s explanations how to hand-code a kml file… which is kind of hard and takes forever!
    Are you saying I can use Google Earth to create a kml file? Any hints how to do that?
    I was asking for a graphical tool to create a kml file. Found one but not compatible with the latest Google Earth..

  7. Right click on any folder of placemarks/paths and save it as a kml file…

    Alternatively, you can export KML’s right from google maps in your web browser…

  8. well and how do I get those placemarks? Anyway, currently playing around with Google Earth, searching for places, then saving them into my places, then exporting my places as KML….
    so good so far but is there a way to connect them? I understand that Google Earth KML files support paths as well… reading the manual if you have a shortcut for me or a hint please speak up 🙂

  9. not sure about where to do step 4:

    `4. Initialize jKMLMap and tell it to load a KML File: `

    where do I insert that code? in the palce I want the output or Insert it into the header?

    sorry for these newbie questions I am a plugin user but I am getting slowly where I want to be with your script here…

  10. I think I figured things out, I mean where to position them. But now there is no error, nothing, the page just shows the basic Google maps controls and nothing else !?
    Here you can find my page template: http://pastebin.com/rctBuT1J here is the livepage: http://pacura.ru/travelmap/ and all I can supply is that there is nothing in the error log only firebug reports this on the page: `document.getElementById(“jKMLStatus”) is null
    Line 240`
    Besides this info, these scripts are loaded via a dynamic widget in my header: `
    `

    oh and in this tutorial you always refer to jKMLMap.js but I exchanged that with jKMLMaps-min.js I hope that is right… I am playing around with your demo KML file so far.
    I really hope you can give me a hint, please.

  11. As stated in the instructions and sample code above, you need to give the map div your desired dimensions. You haven’t.

  12. sorry I just thought I’d keep styling and content separate and added it in my cs file. its in the template now and your demo map is working just fine, check here: http://pacura.ru/travelmaps/ now onto creating my own.
    Thanks a lot for this wonderful script!

  13. Cool, glad you got it 🙂 There still seem to be a lot of bugs over there, but it’ll be nice to check it out once it’s finalized & up & running!

  14. yeah, I tried different methods of including the js, via widgets, via the template file, etc…
    I’ll let you know once I got a proper kml map. still reading up on that trying to figure out how to add a path 🙂 but I’ll figure it out!

  15. hi,

    Great work dud. I love it. 🙂

  16. Thanks! 🙂

  17. Hi, great library . Have you got this working with google api version 3 yet. Thanks

  18. are you looking to get this working with V3?

  19. Unless Google plans to depreciate the previous version, I didn’t really see any reason to

  20. Great plugin!!!

    I installed it on my site and I love it:

    http://saragiovanni.com/rtwt-path/

    Question, how do you create the sidebar widget that says: Current Location?

    I tried but failed …

    Thanks!

    Giovanni

  21. That’s a separate bit of code that I haven’t released, loosely based on jKMLMap but using the Static Maps API. It contains a lot of hard-coded stuff and isn’t really suitable for public consumption, but should be pretty easy to reproduce (as it only uses a small subset of jKMLMap itself, which of course is open-source :))

  22. Hey Justin. Do you know what happened to the API? Your demo is not working and neither is the one on my website that was based on your code. =(

    http://saragiovanni.com

    Thanks.

    Giovanni

  23. I noticed it too, but won’t have time to look into it for at least a few weeks

  24. Ukraine? Nice. Let me know when you take a look at it please!

    I’ll be in Europe Sept/Oct/Nov, maybe we can meet up?

  25. Love to if I’m still here! Plans are totally up in the air at the moment tho 🙂

  26. OK, so I had a few minutes and got to it sooner than expected 😛 You can grab the updated script from here for now, as I haven’t “officially” submitted it yet:

    http://www.justin-klein.com/travellog_/jKMLMap.js

  27. Hey Justin!

    I changed the file “jKMLMap.js” on my server but that did not work unfortunately.

    http://saragiovanni.com/the-route/

    Anything else I need to do?

    Thanks!

    Giovanni

  28. Hey Justin!

    That did it! Thanks!

    Do you know how to change the color of a path? On Google Earth I have each path set on different colors but when I create the KML file and put it on my server, all paths are red…

    Lastly, I’d like to show my map in MAP mode and not satellite mode for defaul. Thoughts?

    Thanks!

    Giovanni

  29. All of this is hardcoded atm; you’ll have to edit the source if you want it to look different

  30. Hi Justin.

    Thanks for the feedback! I’m finally getting the hang of it. There is still a few questions I can’t figure out:

    – How can I make it so that certain paths have one color and others have another? I looked into the docs for KML files and even though I make changes in my KML files, nothing happens.

    – Same as above, change the icon for “visited cities” and another icon for “future cities”

    – Lastly, I noticed that your script creates a default “center”. Can that be overridden by each KML? Or its the same center for all KML files?

    I’m OK with hard coding it, I just don’t know where exactly? The KML files or the JS script?

    Any advice would be appreciated!

    Take a look at our current location image: http://saragiovanni.com/the-route

  31. One more question, how can I make it so that the Lon and Lat of the center of the map be assigned in the backend?

    I assume I can create a wp_options variable and pass these values via php into the JS function when I call

    myKMLMap=new jKMLMap …

    However, I have no idea what the syntax would be. Any idea or do you have a better method?

    Thanks!

    Giovanni

  32. For all of these, please refer to the JS first which is pretty thoroughly commented – I’m sorry but I really don’t have the resources to personally provide such user-by-user customization/instruction for each of my free plugins (especially while traveling, as I sometimes get hundreds of requests a day when I already have far more work requests than I can take on :neutral:).

    Hard coding means the JS. View is automatically set by the KML, or can be changed by manipulating the map object directly, as documented above. Icons can be changed via the JSON object parameter, as documented above.

  33. Thank you very much for this! I’m using jKMLMap, along with a Python script that I wrote, to automatically build maps of my world travels using Foursquare checkins. (You can check out the map at the page linked to my name above.)

    I wanted to mention that I needed to add “_self.map.setZoom(zoom);” after Line 603 in jKMLMap.js to get the zoom working properly. I’m not sure if this problem is a result of migrating to V3 of Google Maps API, but adding that seems to have fixed the zoom for me.

    • That’s awesome! Care to share the code? I don’t have Python on my server at the moment, but considering how much I use FourSquare it sounds like it could be amazingly useful… 🙂

    • I learned as much Python as was needed to put the script together, so the code isn’t exactly beautiful, but it works! Here’s the project on GitHub: https://github.com/raamdev/kml-map-generator

      I also wrote a WordPress plugin that allows me use a shortcode to display my current location, linking the location to the Wikipedia page of the location. I wrote some Python scripts to update the WordPress plugin with my latest location (the actual City, State, Country, which is pulled using a reverse lookup of the coordinates), along with the URL to the corresponding Wikipedia page (which basically searches Google for “site:wikipedia.org city, state, country” and then returns the first result).

      It’s all hacked together rather messily, but you should be able to figure out what you don’t need or want and move stuff around. Let me know if you have any questions!

    • Wow, looks like you really put some work into it. And nice site! Seems like we’re doing more or less the same thing, I’m impressed that you managed to get so many fans in such a short time (since ’10) 😉

      I’ll definitely have a look at the code once I settle down a bit; been hopping from festival to festival for the past 3 months and am pretty behind on work at the moment, haha 😉

    • Thanks. 🙂 Yeah, I thought the same thing when I found your site. And I was a bit jealous of your extensive travels, which inspired me to work on getting the travel map on my site. 😀

  34. Hey Justin,

    Using Firefox 14.0.1, a dialog box pops up that says “jKMLMap Error: The KML file you requested could not be downloaded (Status: 0).”. The JavaScript console reports “NS_ERROR_NOT_INITIALIZED: Component not initialized” on line 213 of jKMLMap.js (“xmlDoc.send(null);”).

    A bit of research on Google didn’t turn up anything obvious, but I’m not a JavaScript programmer, so I’m a bit of a fish out of water. The same page (raamdev.com/travels/) loads fine in the latest versions of Safari and Chrome. Any ideas?

    Out of curiosity, I tested your travels page with Firefox and to my surprise, it loads fine….?

    • Sorry, couldn’t tell you without getting in and debugging. As you pointed out though, it does work here on my site – which means the error could only be modifications you’ve made to the script (if any), or i.e. something funny with your site’s DOM. Shouldn’t be too tough to create a duplicate of that page and start pruning things away until it works.

  35. I just re-downloaded the original jKMLMap files to make sure I wasn’t using a modified version and when I tried running the demo “out-of-the-box” using the latest version of Firefox on my Mac I received the same error. (Screenshot) When you get a chance, could you give the demo a shot with Firefox and see if you can at least reproduce this?

    • Please try to keep related replies in the same comment thread.

      Then as mentioned, it seems like it could only be coming from issues elsewhere on your site (I see that it doesn’t work there, but it does here). You’ll need to debug it by starting with the simplest case (i.e. the demo page) and then working up to what you’ve got until you find where it breaks…or the reverse.

    • I did try to keep my reply in the same thread, but when I failed the CAPTCHA on your comment and I had to press the back button the browser to fill it in again (as per the instructions I saw), your comment form lost the association with the comment thread I was replying to and started a new one.

      Regarding your suggestion: I already tried that. As I mentioned in my last comment, it’s the demo itself that is failing with Firefox. I don’t know how I can start with a more simple case… I’ve tested it on two different servers. I’m not changing anything in the demo and as shown in the screenshot linked in my previous comment, loading the demo.htm file is what’s throwing this particular error on the latest version of Firefox.

      If the demo is not working but your site is working, that would indicate you’ve fixed something on your site that’s not fixed in the demo, or there’s something different about the KML files you’re using on your site.

    • Ohh, sorry I guess I misunderstood.

      I won’t be at my computer till tomorrow so I can’t test the demo, but I haven’t modified anything on the version running on my site, so i guess the difference is the kml? You can try downloading one of my kml files and run it thru ur server – u should be able to find the filenames by viewing the page source.

    • Looks like it’s not the KML files. I just tried your 00_Current.kml on the demo and it’s still throwing that error when viewing the demo on the latest version of Firefox.

      I did a bit more research and found this answer on StackOverflow and the linked Mozilla Docs that indicate you’re not supposed to use onreadystatechange with synchronous requests.

      Still not knowing what I was doing, I looked at some more code samples about this problem and finally found this one that gave me the idea of trying to move xmlDoc.open(“GET”, kmlfile, true); and xmlDoc.send(null); above xmlDoc.onreadystatechange = function () { (i.e., outside of that function) and that seems to have fixed the problem!

      It would be great if you could take a look at this when you get back to your computer and let me know if that change would screw with anything else (again, this is unfamiliar territory for me).

    • And one last update to this: After getting it working with the latest Firefox, I noticed that several path lines were missing (on my travels page, there should be lots of path lines on Tasmania).

      Out of curiosity, I went to your Travellog page, selected “Current Location”, and noticed that all your paths to North Korea are missing as well. So, I guess your Travellog is somewhat broken with the latest Firefox as well.

    • I can confirm that it now seems to be broken in Firefox. Damn, yet another thing that needs to be fixed (Facebook recently broke two of my plugins in several ways each :P). I’ll add this to my todo list for once I get back home, hopefully I can take a closer look at it within a few weeks.

      Regarding the missing lines: I’ve run into problems before when you have maps with too many elements (i.e. a ton of markers, a ton of line segments, etc). I’m pretty sure this is just what’s happening – try deleting some of the earlier stuff, and you’ll probably notice the later stuff suddenly appear. This hasn’t been a problem for me previously, except that my current map is more than a year’s worth of travel so it’s gotten far bigger than any other single map. The limit is even lower with the static maps API – check out my current location thumbnail in the upper right, you’ll notice that the pins around Vietnam from earlier in the year don’t have lines either.

    • Ah 🙂 You gotta love how much extra work all these big services create. You received my PayPal donation, right?

      Thank you for confirming this is broken in Firefox… at least now I know you’re aware of it. 🙂 Also, thanks for explaining the missing lines. That makes sense. My current location map has quite a few of them and it’s only my most recent weeks of travel that are missing lines.

      I’ll wait on your fix. For now, the partial fix that I mentioned earlier is at least preventing Firefox from throwing an error and not loading the map at all.

      Bon voyage, traveler!

    • Yep, I got it, thanks!

      Just uploaded a new version that fixes this and several other little issues, which you can grab from the link above. It should work in the new version of FF (and Opera) now 🙂

    • Hey Raam Dev,

      Just wanted to let you know that I finally got around to looking at your code. Although I took a slightly different approach, I liked the idea SO much that I went a bit overboard and implemented another full-blown PHP solution myself. You can see my “Last Seen” postbox on the main homepage, idea shamefully stolen from your site 🙂

      What I actually did was rather than use FourSquare’s feed, I wrote a callback script and setup a FourSquare app to actively notify it when I checkin. The script decodes the checkin info, opens my KML, prepends a new placemark, extends the path, and re-saves it – but *only* if moved to a new city. I reformat the placemarks somewhat so it matches my KMLs from before – i.e. it doesn’t show my actual venue, but just the date & city/country. Same-city checkins are logged, but not publicly as placemarks. I also rewrote the “Current Location” widget to parse the KML and generate the staticmap URL on the server, then cache the image locally, to significantly reduce load on old crappy browsers like IE (previously it worked like jKMLMap – it would download the whole KML and parse it locally – which is fine for a dedicated travellog page, but inefficient for a sidebar widget shown on every pageload). So if you check the widget, you’ll now see a URL like http://www.justin-klein.com/…/cache/2013.01.06.00.28.55.png.

      There’s a tad more going on on the backend, but that’s the gist of it. Thanks for the idea! Finally, no more mucking about with Google Earth whenever I reach a new city 😀

    • That’s awesome! I hadn’t even considered using a FourSquare App to update the KML file. Any chance you can share the code? I’d love to implement that on my own site. 🙂

    • Sure, which part? It’s 2 totally separate scripts, one that builds KML from Foursquare (like yours), and one that goes KML->staticmap.

      Also, are you in a rush? I’d like to clean them up and post them here at some point, but don’t really have time to do it properly at the moment – and they’re still riddled with hacky- and private- stuff, like userIDs and API keys and whatnot

    • If you can share the code for both, including the FourSquare App code, that would be great.

      I’m in no rush. I just didn’t want to forget to ask you. 🙂 If you can leave me a comment in this thread when you post the code, that would be great. That way I’ll get notified via email and I can grab it.

    • Coo. And *if* it gets to be too long, feel free to ping me again – my list is like 10 pages deep so I wouldn’t be surprised if it got lost at the bottom eventually 😉

    • Will do! 🙂 (Sorry for the post outside the thread again; I failed the Captcha and the reply form unlinked from the main thread.)

    • Hey man, just pinging you to see if you got a chance to put that code together. 🙂

    • Haha sorry, not even close! Still in the midst of several enormous projects 😛

    • No worries. 🙂 I’ll ping you again in a month.

    • Hey bud, just checking in to see if you found some time to put that code together. 🙂 If not, when would you like me to ask you again? I don’t want to bug you too much.

    • It might still be awhile until I’m ready, so I just emailed it to you.

 Leave a Reply

(required)

(required)


(required)

Notify me of followup comments via e-mail. You can also subscribe without commenting.

jfb_p_buttontext

Contact | Terms & Privacy
©2004-2018 Justin Klein
whos online
Feedburner
HTML5 Valid
07-19-2018 13:34:09UTC 0.41s 68q 5.42MB