map

Attachment 'jquery-ubuntu-maps-0.2.js'

Download

   1 /*
   2  * jQuery Google Map Plugin 0.2
   3  * https://wiki.ubuntu.com/ubuntu-django-foundations/map
   4  * Requires jQuery 1.4.2
   5  *
   6  * Copyright 2011, Ronnie van den Crommenacker
   7  * Dual licensed under the MIT or GPL Version 2 licenses.
   8  * http://jquery.org/license
   9  */
  10 
  11 (function($){  
  12     $.fn.extend({   
  13         showLocations: function(options){
  14             var defaults = {
  15                     markers_url: null,          // http://link/to/json/markers or /link/to/json/markers
  16                     markers_list: null,         // [ {lat: 0.345, lng: 0.3456}, {lat: 44.345, lng: 34.3456} ]
  17                     position_name: {
  18                         lat: 'lat',             // { lat: 0.4567, lng: 0.2345 }
  19                         lng: 'lng'              // { lat: 0.4567, lng: 0.2345 }
  20                     },
  21                     marker_content_url: null,   // The url to load when clicked on a marker
  22                     marker_content_tmpl: null,  // The template to load when clicked on a marker
  23                     mapOptions: {
  24                         zoom: 2,
  25                         center: new google.maps.LatLng(22, 12),
  26                         mapTypeId: google.maps.MapTypeId.ROADMAP,
  27                         mapTypeControl: false
  28                     },
  29                     user_location_zoom: 7,      // use null to disable this feature
  30                     single_marker_zoom: 7,      // the zoomlevel. use null to disable
  31                     ajax_load_error: '<p>The page could not be loaded</p>',
  32                     ajax_load_icon: '/ubuntu-website/media/images/ajax-loader.gif',
  33                     marker_icon: null,
  34                     cluster_tmpl: null,
  35                     filter: null, //[ { element: $('...'), attrs: { attr: value }}, { element: $('...'), attrs: { attr: value }} ]
  36                     mcOptions: { gridSize: 40, maxZoom: 10, zoomOnClick: false//, styles: [
  37                             //{ url: 'images/supportCluster1.png', height: 48, width: 48, opt_anchor: [16, 0], opt_textColor: '#ffffff', opt_textSize: 10 }, /* 2-9 members */
  38                             //{ url: 'images/supportCluster2.png', height: 64, width: 64, opt_anchor: [24, 0], opt_textColor: '#ffffff', opt_textSize: 11 }, /* 10-99 members */
  39                             //{ url: 'images/supportCluster3.png', height: 96, width: 96, opt_anchor: [32, 0], opt_textColor: '#ffffff', opt_textSize: 12 }, /* 100-999 members */
  40                             //{ url: 'images/supportCluster4.png', height: 128, width: 128, opt_anchor: [32, 0], opt_textColor: '#ffffff', opt_textSize: 12 }  /* 1000+ members */
  41                         //]
  42                     }
  43                 },
  44                 // Add the window where the details are shown when clicked on a marker
  45 	            infowindow = new google.maps.InfoWindow();
  46 	            
  47             options =  $.extend( defaults, options );
  48 
  49             // TODO: rewrite this one
  50             function getAjaxLoader() {
  51 	            var ajaximg = $('<img src="' + options.ajax_load_icon + '" />')
  52 	                .attr({'style': 'display:inline-block;vertical-align:middle;margin-right:10px;'}),
  53 	                ajaxtxt = $('<p>')
  54 	                .attr({'style': 'display:inline-block;vertical-align:middle;'})
  55                     .html('Retrieving data<br />from server...'),
  56                     wrapper = $('<div>')
  57                     .attr({'style': 'margin:auto;width:130px;'});
  58 	            return wrapper.append(ajaximg).append(ajaxtxt)[0];
  59             }
  60 
  61             infowindow.show = function( html, pos ){
  62                 this.setContent( html );
  63                 this.setPosition( pos );
  64                 this.open( this.map );
  65             };
  66             infowindow.ajaxloader = null;
  67             infowindow.showLoader = function( pos ){
  68                 // Set a temporary loader while the data is retreved from the server 
  69                 if( this.ajaxloader === null ){
  70                     // TODO: allow user defined ajax loader
  71 	                this.ajaxloader = getAjaxLoader();
  72                 }
  73                 this.show( this.ajaxloader, pos );
  74             };
  75             infowindow.showTemplate = function( url, data, pos ){
  76                 var $data = data,
  77                     $pos = pos;
  78                     
  79                 if( !$.tmpl ){
  80                     alert( 'jQuery.tmpl is not installed\nYou can download here:\nhttp://github.com/jquery/jquery-tmpl' );
  81                     return false;
  82                 }
  83                 
  84                 this.showLoader( pos );
  85                 $.ajax({ url: url, 
  86                          dataType: 'html',
  87                          success: function( template ){
  88                             infowindow.show( $( template ).tmpl( $data )[0], $pos ); 
  89                          },
  90                          error: function(){
  91                             infowindow.show( options.ajax_load_error, $pos );
  92                          }
  93                 });
  94             };
  95             infowindow.showHTML = function( url, pos ){
  96                 var $pos = pos;
  97                 
  98                 this.showLoader( pos );
  99 	            $.ajax({ url: url, 
 100                          dataType: 'html',
 101                          success: function( template ){
 102                             infowindow.show( html, $pos );
 103                          },
 104                          error: function(){
 105                             infowindow.show( options.ajax_load_error, $pos );
 106                          }
 107                 });
 108             };
 109 
 110             // Constructs an url with ${...} together with data to a normal url
 111             function constructUrl( url, marker ){
 112                 var pattern = /\$\{[^}]+\}/g,           // match pattern for ${....}
 113 	                url_match = url.match( pattern ),   // Matches the url for ${...} and returns a list of matches
 114 	                param = null,                       // Used for getting a specific param from the marker
 115 	                tag = null;                         // The tags in the match pattern
 116             
 117 	            for( tag in url_match ){
 118 	                if( url_match.hasOwnProperty( tag ) ){
 119 	                    param = url_match[tag];
 120                         url = url.replace( param, marker[param.slice( 2, param.length-1 )] );
 121 	                }
 122 	            }
 123                 return url;
 124             }
 125     
 126             // Function executed when clicked on a cluster object
 127             function clusterClicked( cluster ) {
 128                 var marker_list = null;
 129 	            if( options.cluster_tmpl ){
 130                     infowindow.showTemplate( options.cluster_tmpl, { marker_list: cluster[0].markers_ }, cluster[0].getCenter() );
 131                 }
 132             }
 133 
 134             // Function that is executed when user clicks on a marker
 135             function markerClicked() {
 136                 var url = null;
 137                 
 138                 if( options.marker_content_url ){
 139                     url = constructUrl( options.marker_content_url, this );
 140                     infowindow.showHTML( url, this.position );
 141                 } else if( options.marker_content_tmpl ){
 142                     infowindow.showTemplate( options.marker_content_tmpl, { marker: this }, this.position );
 143                 }
 144             }
 145 
 146             // Create from json data the google.maps.Marker and add them to the markercluster (mc)
 147             // Then center the map if there is only one cluster and options.single_marker_zoom is true
 148             function createMarkers( map, mc, markers ){
 149                 var marker_list = [],           // A list of gmakers
 150                     marker = null,              // The json of a marker
 151                     gmarker = null,             // The actual google.maps.Marker() type
 152                     idx = null,                 // Index
 153                     lat = options.position_name.lat,  // The parameter that contains the latitude
 154                     lng = options.position_name.lng;  // The parameter that contains the longitude
 155                 
 156                 if( markers[0].fields ){
 157                     // Django model
 158                     // Use django pk and fields parameters
 159                     for( idx in markers ){
 160                         if ( markers.hasOwnProperty( idx ) ) {
 161                             marker = markers[idx].fields;
 162                             marker.pk = markers[idx].pk;
 163                             marker.position = new google.maps.LatLng( marker[lat], marker[lng] );
 164                             if( !marker.icon && options.marker_icon ){
 165                                 marker.icon = options.marker_icon;
 166                             }
 167                             gmarker = new google.maps.Marker( marker );
 168                             google.maps.event.addDomListener(gmarker, 'click', markerClicked);
 169                             marker_list.push( gmarker );
 170                         }
 171                     }
 172                     
 173                 } else {
 174                     // Use normal parameters
 175                     for( idx in markers ){
 176                         if ( markers.hasOwnProperty( idx ) ) {
 177                             marker = markers[idx];
 178                             marker.position = new google.maps.LatLng( marker[lat], marker[lng] );
 179                             if( !markers[idx].icon && options.marker_icon ){
 180                                 marker.icon = options.marker_icon;
 181                             }
 182                             gmarker = new google.maps.Marker( marker );
 183                             google.maps.event.addDomListener(gmarker, 'click', markerClicked);
 184                             marker_list.push( gmarker );
 185                         }
 186                     }
 187                 }
 188                 mc.addMarkers(marker_list);
 189                 
 190                 // If there is only one marker
 191                 if ( options.single_marker_zoom && marker_list.length === 1 ){
 192                     // Make sure the map is initialized
 193                     // FIXME: Look for an map.init event
 194                     setTimeout(function(){
 195                         map.setCenter( mc.getMarkers()[0].getPosition() );
 196                         map.setZoom( options.single_marker_zoom );
 197                     }, 100);
 198                 }
 199             }
 200             
 201             return $(this).each( function( i, html_element ){
 202                 var map = new google.maps.Map( html_element, options.mapOptions ),
 203                     markerCluster = new MarkerClusterer( map, [], options.mcOptions ),
 204                     filter = options.filter,
 205                     index = null;
 206 
 207                 // FIXME: Manually override the zoomOnClick because of this bug
 208                 // http://www.devcomments.com/V3-MarkerClusterer-zoomOnClick-issue-at255452.htm
 209                 markerCluster.zoomOnClick_ = false;
 210                 
 211                 // Attach the info window to the curernt map
 212                 infowindow.map = map;
 213                 
 214                 // When clicked on a cluster, call the event
 215                 google.maps.event.addListener( markerCluster, 'clusterclick', clusterClicked );
 216                 
 217                 // Try W3C Geolocation (Preferred)
 218                 // Ask the user for their location and set the map to it
 219                 if( options.user_location_zoom && navigator.geolocation ){
 220 	                navigator.geolocation.getCurrentPosition( function( position ) {
 221 		                var pos = new google.maps.LatLng( position.coords.latitude, position.coords.longitude ),
 222 		                    opt = options;
 223 		                map.setCenter( pos );
 224 		                map.setZoom( opt.user_location_zoom );
 225 	                });
 226                 }
 227                 
 228                 // Load the list of markers into the map
 229                 if( options.markers_url ){
 230                     $.get( options.markers_url, function( markers ){
 231                         createMarkers( map, markerCluster, markers );
 232                     }, 'json');
 233                 } else if( options.markers_list ){
 234                     createMarkers( map, markerCluster, options.markers_list );
 235                 }
 236                 
 237                 var filterer = (function(markerCluster){
 238                     var mc = markerCluster,
 239                         markers = mc.getMarkers();
 240                     return {
 241                         addFilter: function(filter){
 242                             filter.element.click(function(event){
 243                                 event.preventDefault();
 244                                 var attrs = filter.attrs,
 245                                     visible_markers = [],
 246                                     m = null,
 247                                     a = null;
 248 
 249                                 for( m in markers ){
 250                                     if( markers.hasOwnProperty(m) ){
 251                                         marker = markers[m];
 252                                         for( a in attrs ){
 253                                             if( attrs.hasOwnProperty(a) ){
 254                                                 if( marker[a] === attrs[a] ){
 255                                                     visible_markers.push(marker);
 256                                                 }
 257                                             }
 258                                         }
 259                                     }
 260                                 }
 261                                 // If there are no filter options, show all markers
 262                                 if( !a ){
 263                                     visible_markers = markers;
 264                                 }
 265                                 mc.clearMarkers();
 266                                 mc.addMarkers(visible_markers, false);
 267                             });
 268                         }
 269                     }
 270                 }(markerCluster));
 271                 
 272                 if( filter ){
 273                     for( index in filter ){
 274                         if( filter.hasOwnProperty(index) ){
 275                             filterer.addFilter(filter[index]);
 276                         }
 277                     }
 278                 }
 279             });
 280         },
 281         selectLocation: function(options){
 282             var defaults = {
 283                 html_lng: null,
 284                 html_lat: null,
 285                 marker_icon: null,
 286                 markers: [],
 287                 html_addr: null,
 288                 mapOptions: {
 289                     zoom: 4,
 290                     center: new google.maps.LatLng(51.8211, 5.591),
 291                     mapTypeId: google.maps.MapTypeId.ROADMAP,
 292                     mapTypeControl: false
 293                 }
 294             };
 295             options = $.extend(defaults, options);
 296             
 297             function showPositionHTML(location){
 298                 console.log('show', location);
 299                 if(options.html_lng && options.html_lat){
 300                     if( location.xa && location.za ){
 301                         options.html_lat.val(location.xa);
 302                         options.html_lng.val(location.za);
 303                     } else if( location.wa && location.ya ){
 304                         options.html_lat.val(location.wa);
 305                         options.html_lng.val(location.ya);
 306                     }
 307                 }
 308             }
 309             
 310             function setMarker(map, location){
 311                 var marker = null;
 312                 
 313                 if( options.markers.length ){
 314                     marker = options.markers[0];
 315                     marker.setPosition(location);
 316                     marker.setAnimation(google.maps.Animation.DROP);
 317                 } else {
 318                     marker = new google.maps.Marker({
 319                         map: map,
 320                         position: location,
 321                         draggable:true,
 322                         animation: google.maps.Animation.DROP
 323                     });
 324                     if (options.marker_icon){
 325                         marker.icon = options.marker_icon;
 326                     }
 327                     options.markers.push(marker);
 328                     google.maps.event.addListener(options.markers[0], 'mouseup', function(){
 329                         showPositionHTML(marker.getPosition());
 330                     });
 331                 }
 332                 
 333                 map.setCenter(location);
 334                 showPositionHTML(marker.getPosition());
 335             }
 336             
 337             return $(this).each(function(i, html_element){
 338                 var map = new google.maps.Map($(html_element)[0], options.mapOptions),
 339                     geoCoder = new google.maps.Geocoder();
 340 
 341                 if (options.html_addr) {
 342                     options.html_addr.change(function(){
 343                         var address = [];
 344                         options.html_addr.each(function(i, item){
 345                             address.push(item.value);
 346                         });
 347                         
 348                         geoCoder.geocode({address: address.join(' ')}, function(results, status) {
 349                             if (status === google.maps.GeocoderStatus.OK) {
 350                                 setMarker(map, results[0].geometry.location);
 351                             }
 352                         });
 353                     });
 354                 }
 355                 google.maps.event.addListener(map, 'click', function(event){
 356                     setMarker(map, event.latLng);
 357                 });
 358                 
 359                 if (options.html_lat.val() && options.html_lng.val()) {
 360                     var location = new google.maps.LatLng(options.html_lat.val(),options.html_lng.val());
 361                     setMarker(map, location);
 362                 }
 363             });
 364             
 365         }
 366     });
 367 }(jQuery));

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2011-02-20 02:23:19, 17.5 KB) [[attachment:_jquery-ubuntu-maps-0.2.4.js]]
  • [get | view] (2011-01-21 13:09:42, 17.5 KB) [[attachment:jquery-ubuntu-maps-0.2.1.js]]
  • [get | view] (2011-02-17 15:26:21, 17.5 KB) [[attachment:jquery-ubuntu-maps-0.2.3.js]]
  • [get | view] (2011-02-20 02:23:39, 17.5 KB) [[attachment:jquery-ubuntu-maps-0.2.4.js]]
  • [get | view] (2011-01-21 10:56:32, 17.3 KB) [[attachment:jquery-ubuntu-maps-0.2.js]]
  • [get | view] (2011-01-20 17:49:53, 15.2 KB) [[attachment:jquery-ubuntu-maps.js]]
 All files | Selected Files: delete move to page

You are not allowed to attach a file to this page.