A Google Maps Version 3 jQuery Plugin
As more and more devices become GPS capable or location aware, mapping will become more pervasive. This is already happening today. There are a number of mapping solutions that are available. This post will examine how to use a jQuery plug-in that encapsulates the Google Maps JavaScript API version 3. The Google Maps V3 API is already very simple to use. This jQuery plugin hides a bit of the ‘Google-centric’ knowledge.
You can download the plug-in above, and then following the steps below to get up and running.
There are a few other jQuery plug-ins that wrap the Google maps API. The purpose of me creating another plug-in is two-fold. First, I wanted to learn more about the API that Google is using. Second, none of the other plug-ins had the coding interface that I wanted.
HTML
The following is the HTML content for the demonstration page:
<html> <head> <title>Google Map Demo</title> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <link type="text/css" href="css/index.css" rel="stylesheet" /> <script type="text/javascript" src="scripts/jquery-1.4.1.js"></script> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> <script type="text/javascript" src="scripts/jquery.gmap3.js"></script> <script type="text/javascript" src="scripts/index.js"></script> </head> <body> <div id="wrapper"> <div class="demo"> <a href="http://blog.bobcravens.com/" class="demo">Bob <span>Cravens</span> Dotcom Demo Page</a> </div> <div id="content"> <div id="map_canvas" class="line"></div> <div id="latlng" class="line">click the map</div> <div id="address" class="line">click the map</div> <div> Enter an address: <input id="addressToAdd" type="text" value="Vilas Zoo, Madison, WI" /> <input id="addMarker" type="button" value="Add Marker" /> </div> </div> </div> </body> </html>
In the ‘head’ element, the required JavaScript libraries are referenced. The jQuery plug-in is called ‘jquery.gmap3.js’ and is referenced third. It depends on the jQuery library and the Google JavaScript API. We will see in a bit the contents of ‘index.js’.
CSS
Next we add some style to the page. Most of the CSS is to style up the demo page. Here are the relevant part for the map.
h1 { font-size: 16px; } #map_canvas { width: 800px; height: 500px; margin: 10px auto; } div#latlng-control { background: #ffc; border: 1px solid #676767; padding: 2px 4px; position: absolute; } .line { padding: 3px; }
The ‘h1’ style is used for the balloon tip that appear when the markers are clicked. The map div is sized and auto-centered with a top margin. The ‘latlng-control’ style is used by the mouse-over tool-tip that is helpful in debug mode (more later). The final style adds a bit of padding to the text elements below the map.
JavaScript
The following JavaScript is used in the demo. First, we define some arrays that hold latitude / longitude data that will be mapped.
var path = [ { "lat": 43.00678, "lng": -89.53743 }, { "lat": 43.00656, "lng": -89.53732 }, { "lat": 43.005878, "lng": -89.53797 }, { "lat": 43.005344, "lng": -89.53684 }, { "lat": 43.003834, "lng": -89.535400 }, { "lat": 43.003692, "lng": -89.533834 }, { "lat": 43.006384, "lng": -89.533796 }, { "lat": 43.0120328, "lng": -89.533667 }, { "lat": 43.015931, "lng": -89.533635 }, { "lat": 43.023030, "lng": -89.5335390 }, { "lat": 43.032010, "lng": -89.533249 }, { "lat": 43.040221, "lng": -89.5329596 }, { "lat": 43.04632176, "lng": -89.5318224 }, { "lat": 43.052562, "lng": -89.5277883 }, { "lat": 43.060300, "lng": -89.52759526 }, { "lat": 43.06401556, "lng": -89.5268978 }, { "lat": 43.06681381, "lng": -89.5241620 }, { "lat": 43.0714224, "lng": -89.52499888 }, { "lat": 43.07468269, "lng": -89.52698371 }, { "lat": 43.07490213, "lng": -89.53292749 }, { "lat": 43.076203059, "lng": -89.53269145 }, { "lat": 43.0765949, "lng": -89.5314576 }, { "lat": 43.0793377, "lng": -89.53323862 }, { "lat": 43.0803799, "lng": -89.53454754 }, { "lat": 43.0835927, "lng": -89.5340754 }, { "lat": 43.08458789, "lng": -89.5334853 }, { "lat": 43.0844468, "lng": -89.53403256 }, { "lat": 43.08445469, "lng": -89.5352985 }, { "lat": 43.084619242, "lng": -89.5358993791 } ]; var poly1 = [ { "lat": 43.0379081608, "lng": -89.451271661 }, { "lat": 43.060613611, "lng": -89.45127166 }, { "lat": 43.06086445, "lng": -89.4711843 }, { "lat": 43.0454357, "lng": -89.47118438 } ]; var poly2 = [ { "lat": 43.015194305, "lng": -89.455563195 }, { "lat": 43.0154453329, "lng": -89.4252649627 }, { "lat": 43.001197884, "lng": -89.42826903686 }, { "lat": 43.001197884, "lng": -89.459425576 } ];
Next a simple helper method that creates the HTML content for the balloon popups that occur when markers are clicked.
function createInfo(title, content) { return '<div id="popup"><h1 class="popup-title">' + title + '</h1><div id="popup-body"><p>' + content + '</p></div></div>'; }
Finally, the jQuery document ready event creates and configures the map.
$(document).ready(function () { // create the map var map = $("#map_canvas").gmap3( { lat: 43.0566, lng: -89.4511, zoom: 12 }); // turn on mouse hover debug helper map.toggleDebug(); // add markers by address map.addMarkerByAddress("Madison, WI", "Madison", createInfo("Madison", "This point was added by geo-coding an address.")); map.addMarkerByAddress("312 Monte Cristo Circle, Verona, WI", "Home2", createInfo("Madison", "This point was added by geo-coding an address.")); // add markers by lat / long map.addMarkerByLatLng(43.0747, -89.3845, "State Capital", createInfo("State Capital", "This is the capital of the State of Wisconsin.")); map.addMarkerByLatLng(43.0849, -89.5349, "Work", createInfo("TomoTherapy", "This is where I work.")); map.addMarkerByLatLng(43.0068, -89.5376, "Home", createInfo("Home", "This is where I live.")); // add click handlers map.onclickReverseGeocode($("#address")); map.onclickGetLatLng($("#latlng")); // add a path map.addPath(path); // add polygons map.addPolygon(poly1); map.addClickablePolygon(poly2, createInfo("Housing District", "Look at all the houses"), { fillColor: "#0000ff", strokeColor: "#0000ff" }); // set up the button $("#addMarker").click(function () { var address = $("#addressToAdd").val(); if (address != undefined && address != null && address != "") { $.fn.gmap3.geoCodeAddress(address, function (latlng) { $.fn.gmap3.geoCodeLatLng(latlng.lat(), latlng.lng(), function(foundAddress){ var str = "latitude = " + latlng.lat() + "nlongitude = " + latlng.lng() + "naddress = " + foundAddress; alert(str); map.addMarkerByLatLng(latlng.lat(), latlng.lng(), address, createInfo(address, str.replace(/n/gi, "<br />"))); }); }); } }); });
First the map is created using a jQuery selector to select the map element and then calling the ‘gmap3’ function. There are a few optional parameters that can be overridden when the map is created. The demo page sets the center of the map to a specified lat/long and the zoom level.
The following is a list of the available functions. This list follows the order in which they are used in the demo.
- toggleDemo – This function turns on the mouse tooltip that displays the lat/long as the mouse is moved over the map. This is useful in debugging and to record lat/long information. This function takes no parameters.
- addMarkerByAddress – This function adds a marker to the map. This function takes the following parameters.
- address – The address (ex. ‘Madison, WI’ ) for the marker.
- title – The title for the marker. This is displayed when the mouse is over the marker.
- html (optional) – The markup to be displayed when the marker is clicked.
- addMarkerByLatLng – This function adds a marker to the map. Nearly the same as the above function. This function takes the following parameters:
- lat – Latitude for the marker.
- lng – Longitude for the marker.
- title – Same as above.
- html (optional) – Same as above.
- onclickReverseGeocode – This wires up a click handler to the map. When the map is clicked the lat/long coordinates are converted into an address. This function uses a geo-coding service provided by Google. This is an AJAX call. This function takes the following parameter:
- elem – The jQuery element that will have its ‘html’ set to the address.
- onclickGetLatLng – This wires up a click handler to the map. When the map is clicked the lat/long coordinates are supplied to an HTML element. This function takes the following parameter:
- elemfunction converts an address to a lat/long
- addPath – This function adds a path (an array of JSON lat/long values) to the map. This function takes the following parameters:
- data – The data points. See the JavaScript above for example format.
- opts (optional) – An array of parameters that can be overridden to set properties.
- color (default: red) – The color of the stroke.
- opacity (default: 1.0) – The opacity of the stroke.
- strokeWeight (default: 2.0) – The stroke weight (line thickness).
- addPolygon – This function adds a shaded polygon to the map. This function takes the following parameters:
- data – The data points. See the JavaScript above for example format.
- opts (optional) – An array of parameters that can be overridden to set properties.
- strokeColor (default: red) – The border color.
- strokeOpacity (default: 0.8) – The border opacity.
- strokeWeight (default: 2.0) – The border thickness.
- fillColor (default: red) – The fill color.
- fillOpacity (default: 0.35) – The fill opacity.
- addClickablePolygon – This is nearly the same as ‘addPolygon’ except that a click event is wired up to the polygon. This function takes the following parameters:
- data – Same as addPolygon.
- html – The content that is displayed when the polygon is clicked.
- opts – Same as addPolygon.
- $.fn.gmap3.geoCodeLatLng – A global function that converts lat/long coordinates into an address using an AJAX call to a geo-coding service hosted by Google. This function takes the following parameters:
- lat – Latitude of the coordinate.
- lng – Longitude of the coordinate.
- callback – The callback to execute when the AJAX call completes. The callback function should accept one parameter. This will be a string representing the resulting address.
- $.fn.gmap3.geoCodeAddress – A global function that converts an address into lat/long coordinates. This is an AJAX call to the geo-coding service. This function takes the following parameters:
- address – The address to be converted.
- callback – The callback to execute when the AJAX call completes. The callback function should accept one parameter. This will be a string representing the resulting lat/long.
Summary
Mapping is not so hard when you can lean on the shoulders of giants. The map content that is available today is awesome. Hopefully, you will find this jQuery plug-in useful. As always, feedback is appreciated.
Just wanted to thank you as it has been a great help with my development. Just wanted to ask what kind of license you have over this code and if I can fork this over to github or something. I plan to modify it a bit (and maybe ask for your input as well).I see that there markers are separate objects in the API so I think your code could be improved if the markers were separate objects. That way, we can call/make methods that are specific to the markers like hide/delete them or something.
I use your code with a bdd sql , the addmarkerbyadress works with my table but the createinfo fonction doesn’t work
one frame displays :
"<div id="popup"><h1 class="popup-title">test</h1><div id="popup-body"><p>test</p></div></div>" but not an infobulle
if you have a solution , thanks and congratulations for this code , it’s very interisting 🙂
the code:
<html>
<head>
<title>Google Map Demo</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<link type="text/css" href="index.css" rel="stylesheet" />
<script type="text/javascript" src="jquery-1.4.1.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="jquery.gmap3.js"></script>
<script type="text/javascript" src="index.js"></script>
<script>
function createInfo(title, content) {
return ‘<div id="popup"><h1 class="popup-title">’ + title + ‘</h1><div id="popup-body"><p>’ + content + ‘</p></div></div>’;
}
$(document).ready(function () {
// create the map
var map = $("#map_canvas").gmap3(
{
lat: 43.0566,
lng: -89.4511,
zoom: 2
});
// turn on mouse hover debug helper
map.toggleDebug();
// add markers by address
map.addMarkerByAddress("Madison, WI", "Madison", createInfo("Madison", "This point was added by geo-coding an address."));
map.addMarkerByAddress("312 Monte Cristo Circle, Verona, WI", "Home2", createInfo("Madison", "This point was added by geo-coding an address."));
<?php
mysql_connect(‘localhost’, ‘florian’, ‘florian123’);
mysql_select_db("florian");
$req=mysql_query("SELECT * FROM partenaires");
while($result=mysql_fetch_array($req)) // on récupère la liste des membres
{
?>
// add markers by address
map.addMarkerByAddress("<?php echo($result[‘coordonnee’].”.$result[‘pays’]);?>", createInfo("<?php echo($result[‘nom’]);?>","<br />"));
<?php }?>
// add click handlers
map.onclickReverseGeocode($("#address"));
map.onclickGetLatLng($("#latlng"));
// add a path
map.addPath(path);
// set up the button
$("#addMarker").click(function () {
var address = $("#addressToAdd").val();
if (address != undefined && address != null && address != "") {
$.fn.gmap3.geoCodeAddress(address, function (latlng) {
$.fn.gmap3.geoCodeLatLng(latlng.lat(), latlng.lng(), function(foundAddress){
var str = "latitude = " + latlng.lat() + "nlongitude = " + latlng.lng() + "naddress = " + foundAddress;
alert(str);
map.addMarkerByLatLng(latlng.lat(), latlng.lng(), address, createInfo(address, str.replace(/n/gi, "<br />")));
});
});
}
});
});
</script>
</head>
<body>
<div id="wrapper">
<div class="demo">
Bob <span>Cravens</span> Dotcom Demo Page
</div>
<div id="content">
<div id="map_canvas" class="line"></div>
<div id="latlng" class="line">click the map</div>
<div id="address" class="line">click the map</div>
<div>
Enter an address:
<input id="addressToAdd" type="text" value="Vilas Zoo, Madison, WI" />
<input id="addMarker" type="button" value="Add Marker" />
</div>
</div>
</div>
</body>
</html>
Useful blog website, keep me personally through searching it, I am seriously interested to find out another recommendation of it.
Hi,
Here is another gmap3 implementation with a full demo on http://night-coder.com/jquery-plugin-gmap3-1202.html
Hi.
I know this post is pretty old now butI’ve had a look at your demo and when I click on the map, I can’t get the longitude and latitude to show in the latlng div.
You got this function in your library:
this.onclickGetLatLng = function (callback) {
geocode = google.maps.event.addListener(this.map, ‘click’, function (me) {
var result = [me.latLng.lat(), me.latLng.lng()];
if (callback != undefined) {
callback(result);
}
});
}
That’s called like this:
map.onclickGetLatLng($(“#latlng”));
The div will not display anything.
I’ve added an alert box in onClickGetLatLng to see if anything is happening and I do have coordinates there.
I’m not familiar with the way you call pass the value to #latlng. Does callback(result) assigns result to callback?
Hi Nico,
You caught my demo not keeping up with the latest plugin code. I have updated the demo to use the latest version. The two functions that have a callback as a parameter now look like this:
map.onclickReverseGeocode(function(address){
$(“#address”).html(address);
});
map.onclickGetLatLng(function(latlng){
$(“#latlng”).html(latlng[0] + ‘,’ + latlng[1]);
});
The callback functions are passed the data and you can format it how you want. Sorry for the confusion.
Bob
No problem at all.
I was getting there myself at my own pace. Just after I posted I realized you were passing the DOM to the function. I reached a point where it did modify from click here to nothingness. Which is much better.
Thanks a lot for the super click reply.
I will check the new version right away and let you know if I find something new. (I’m glad you keep maintaining it!)
I saw too much click so far. I meant quick.
Following your example, I’ve added a marker this way, but it allows for a lot of marker.
map.onclickGetLatLng(function(latlng){
map.clear;
map.addMarkerByLatLng(latlng[0],latlng[1]);
});
I want only one marker on the map at all time. But map.clear isn’t doing anything.
cheers and thanks again,
Nico
I love your script,
however it threw some errors at me.
by changing line 213:
from
overlays.push(marker);
to
if(overlays){overlays.push(marker);}
it solved those.
@Thijs…thanks for the bug report. I will integrate that fix in the next version.
Bob
Bob,
also a fun feature to add for the next release is the possiblity to change the icon.
It took me 5 mins to figure it out. If you like I can send you the code.
Many many thanks for sharing
Roy in Manchester UK
Hi,
great approach for a quick ‘n easy maps plugin.
It looks like the setType-stuff is not documented here?
Like: map.setTypeRoadMap();
Is there an easy way to style the buttons?
Cheers, Carl (Berlin)
Hi Carl,
Thanks for visiting. The latest version of the plugin has a few additional features. I am a bit behind keeping the documentation up to date. It is on my list of things to do. At this time, you cannot customize the marker images. That is not hard to do. Here is a jsFiddle to customize the marker. I don’t think it will be hard to incorporate this into the library.
Bob
Latest version of gmap3 has been released on http:://gmap3.net
As new features, it allow to create clusters, give custom data in each object event, use $(this) …
Exactly what I was looking for, thanks very much!
Hi, I am using addClickablePolygon to create multiple polygons which show an infowindow as in your demo… I cannot get the infowindows from previous polygons to close when a new one is opened… anyone got any ideas?
Thanks
Check out this stackoverflow question. I think it is probably the same issue. The root cause is the scoping of javascript variables. http://stackoverflow.com/questions/5479827/jquery-google-maps-v3-information-window-is-always-fixed-to-one-marker/5480063#5480063
Hope this helps.
Bob
Thanks, I’m looking into javascript debuggers to help me identify this issue … & no doubt future ones!
Hi,
I really appreciate your post! Could I have one question, I got a javascript error of
Error: callback is not a function
Source File: jquery.gmap3.js
Line: 161
Would you know why is callback an object but not a function? Thank you very much!
Terry
I have just figured out that I could instead use callback.html(address);
Hi Terry,
Thanks for using the gmap3. I suspect that you issue may be related to this stack overflow question:
http://stackoverflow.com/questions/533817/why-does-my-event-handler-cause-an-is-not-a-function-error-but-works-from-the
Hope that helps.
Bob
Thank you so much! This is very useful!
Many thanks for sharing the code. Much appreciated.
Hi, this is a great blog but i am looking for something different. I want to capture state and city providing only zip code. how can i do this stuff in php and javascript . I am new to all of this dont know how can i do this. Can you please help me to do this?
A quick google search found this: http://www.bizinfosys.com/php/php-get-city-state-from-zipcode.html
Bob
This is very interesting, You are a very skilled blogger.
I’ve joined your rss feed and look forward to seeking more of your magnificent post. Also, I have shared your web site in my social networks!
Hi Bob,
Thank you for the code, is there a way of saving the markers that have been added by people?
Thank you,
Richard
Hi Bob,
i would like my map to allow visitors to my website to add their own marker to the map. Is this possible?
Thanks,
Tom
Thanks mate !! you saved a lot of time – thanks a ton, job well done !!
Hi,
I’m planning to do new project gps tracking application in web asp.net but new to gps system. how many days will take to do complete project? Please give me useful code and you valuable suggestions.
Thanks
Kevin