map
Attachment 'jquery-ubuntu-maps-0.2.4.js'
Download 1 /*
2 * jQuery Google Map Plugin 0.2.4
3 * https://wiki.ubuntu.com/ubuntu-django-foundations/map
4 * Requires jQuery 1.3.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 ifw = this;
79
80 if (!$.tmpl) {
81 alert('jQuery.tmpl is not installed\nYou can download here:\nhttp://github.com/jquery/jquery-tmpl');
82 return false;
83 }
84
85 this.showLoader(pos);
86 $.ajax({
87 url: url,
88 dataType: 'html',
89 success: function (template) {
90 ifw.show($(template).tmpl($data)[0], $pos);
91 },
92 error: function () {
93 ifw.show(options.ajax_load_error, $pos);
94 }
95 });
96 };
97 infowindow.showHTML = function (url, pos) {
98 var $pos = pos,
99 ifw = this;
100
101 this.showLoader(pos);
102 //TODO: Check for better same-origin in url
103 if (url.slice(0, 4) == 'http'){
104 ifw.show($('<iframe>').attr('src', url)[0], $pos);
105 } else {
106 $.ajax({
107 url: url,
108 dataType: 'html',
109 success: function (html) {
110 ifw.show(html, $pos);
111 },
112 error: function () {
113 ifw.show(options.ajax_load_error, $pos);
114 }
115 });
116 }
117 };
118
119 // Constructs an url with ${...} together with data to a normal url
120 function constructUrl(url, marker) {
121 var pattern = /\$\{[\w\d]+\}/g, // match pattern for ${....}
122 url_match = url.match(pattern), // Matches the url for ${...} and returns a list of matches
123 param = null, // Used for getting a specific param from the marker
124 tag = null; // The tags in the match pattern
125
126 for (tag in url_match) {
127 if (url_match.hasOwnProperty(tag)) {
128 param = url_match[tag];
129 url = url.replace(param, marker[param.slice(2, param.length - 1)]);
130 }
131 }
132 return url;
133 }
134
135 // Function executed when clicked on a cluster object
136 function clusterClicked(cluster) {
137 if (options.cluster_tmpl) {
138 infowindow.showTemplate(options.cluster_tmpl, {marker_list: cluster[0].markers_}, cluster[0].getCenter());
139 }
140 }
141
142 // Function that is executed when user clicks on a marker
143 function markerClicked() {
144 var url = null;
145
146 if (options.marker_content_url) {
147 url = constructUrl(options.marker_content_url, this);
148 infowindow.showHTML(url, this.position);
149 } else if (options.marker_content_tmpl) {
150 infowindow.showTemplate(options.marker_content_tmpl, {marker: this}, this.position);
151 }
152 }
153
154 // Create from json data the google.maps.Marker and add them to the markercluster (mc)
155 // Then center the map if there is only one cluster and options.single_marker_zoom is true
156 function createMarkers(map, mc, markers) {
157 var marker_list = [], // A list of gmakers
158 marker = null, // The json of a marker
159 gmarker = null, // The actual google.maps.Marker() type
160 idx = null, // Index
161 lat = options.position_name.lat, // The parameter that contains the latitude
162 lng = options.position_name.lng; // The parameter that contains the longitude
163
164 if (markers[0].fields) {
165 // Django model
166 // Use django pk and fields parameters
167 for (idx in markers) {
168 if (markers.hasOwnProperty(idx)) {
169 marker = markers[idx].fields;
170 marker.pk = markers[idx].pk;
171 marker.position = new google.maps.LatLng(marker[lat], marker[lng]);
172 if (!marker.icon && options.marker_icon) {
173 marker.icon = options.marker_icon;
174 }
175 gmarker = new google.maps.Marker(marker);
176 google.maps.event.addDomListener(gmarker, 'click', markerClicked);
177 marker_list.push(gmarker);
178 }
179 }
180
181 } else {
182 // Use normal parameters
183 for (idx in markers) {
184 if (markers.hasOwnProperty(idx)) {
185 marker = markers[idx];
186 marker.position = new google.maps.LatLng(marker[lat], marker[lng]);
187 if (!markers[idx].icon && options.marker_icon) {
188 marker.icon = options.marker_icon;
189 }
190 gmarker = new google.maps.Marker(marker);
191 google.maps.event.addDomListener(gmarker, 'click', markerClicked);
192 marker_list.push(gmarker);
193 }
194 }
195 }
196 mc.addMarkers(marker_list);
197
198 // If there is only one marker
199 if (options.single_marker_zoom && marker_list.length === 1) {
200 // Make sure the map is initialized
201 // FIXME: Look for an map.init event
202 setTimeout(function () {
203 map.setCenter(mc.getMarkers()[0].getPosition());
204 map.setZoom(options.single_marker_zoom);
205 }, 100);
206 }
207 }
208
209 return $(this).each(function (i, html_element) {
210 var map = new google.maps.Map(html_element, options.mapOptions),
211 markerCluster = new MarkerClusterer(map, [], options.mcOptions),
212 filter = options.filter,
213 filterer = null,
214 index = null,
215 pos = null;
216
217 // FIXME: Manually override the zoomOnClick because of this bug
218 // http://www.devcomments.com/V3-MarkerClusterer-zoomOnClick-issue-at255452.htm
219 markerCluster.zoomOnClick_ = false;
220
221 // Attach the info window to the curernt map
222 infowindow.map = map;
223
224 // When clicked on a cluster, call the event
225 google.maps.event.addListener(markerCluster, 'clusterclick', clusterClicked);
226
227 // Try W3C Geolocation (Preferred)
228 // Ask the user for their location and set the map to it
229 if (options.user_location_zoom && navigator.geolocation) {
230 navigator.geolocation.getCurrentPosition(function (position) {
231 pos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
232 map.setCenter(pos);
233 map.setZoom(options.user_location_zoom);
234 });
235 }
236
237 // Load the list of markers into the map
238 if (options.markers_url) {
239 $.getJSON(options.markers_url, function (markers) {
240 createMarkers(map, markerCluster, markers);
241 }, 'json');
242 } else if (options.markers_list) {
243 createMarkers(map, markerCluster, options.markers_list);
244 }
245
246 if (filter) {
247 filterer = (function (markerCluster) {
248 var mc = markerCluster,
249 markers = mc.getMarkers();
250 return {
251 addFilter: function (filter) {
252 filter.element.click(function (event) {
253 var attrs = filter.attrs,
254 visible_markers = [],
255 m = null,
256 a = null;
257
258 event.preventDefault();
259
260 for (m in markers) {
261 if (markers.hasOwnProperty(m)) {
262 marker = markers[m];
263 for (a in attrs) {
264 if (attrs.hasOwnProperty(a)) {
265 if (marker[a] === attrs[a]) {
266 visible_markers.push(marker);
267 }
268 }
269 }
270 }
271 }
272 // If there are no filter options, show all markers
273 if (!a) {
274 visible_markers = markers;
275 }
276 mc.clearMarkers();
277 mc.addMarkers(visible_markers, false);
278 });
279 }
280 };
281 }(markerCluster));
282 for (index in filter) {
283 if (filter.hasOwnProperty(index)) {
284 filterer.addFilter(filter[index]);
285 }
286 }
287 }
288 });
289 },
290 selectLocation: function (options) {
291 var defaults = {
292 html_lng: null,
293 html_lat: null,
294 marker_icon: null,
295 markers: [],
296 html_addr: null,
297 mapOptions: {
298 zoom: 4,
299 center: new google.maps.LatLng(51.8211, 5.591),
300 mapTypeId: google.maps.MapTypeId.ROADMAP,
301 mapTypeControl: false
302 }
303 };
304 options = $.extend(defaults, options);
305
306 function showPositionHTML(location) {
307 if (options.html_lng && options.html_lat) {
308 if (location.lat() && location.lng()) {
309 options.html_lat.val(location.lat());
310 options.html_lng.val(location.lng());
311 }
312 }
313 }
314
315 function setMarker(map, location) {
316 var marker = null;
317
318 if (options.markers.length) {
319 marker = options.markers[0];
320 marker.setPosition(location);
321 marker.setAnimation(google.maps.Animation.DROP);
322 } else {
323 marker = new google.maps.Marker({
324 map: map,
325 position: location,
326 draggable: true,
327 animation: google.maps.Animation.DROP
328 });
329 if (options.marker_icon) {
330 marker.icon = options.marker_icon;
331 }
332 options.markers.push(marker);
333 google.maps.event.addListener(options.markers[0], 'mouseup', function () {
334 showPositionHTML(marker.getPosition());
335 });
336 }
337
338 map.setCenter(location);
339 showPositionHTML(marker.getPosition());
340 }
341
342 return $(this).each(function (i, html_element) {
343 var map = new google.maps.Map($(html_element)[0], options.mapOptions),
344 geoCoder = new google.maps.Geocoder(),
345 location = null;
346
347 if (options.html_addr) {
348 options.html_addr.change(function () {
349 var address = [];
350 options.html_addr.each(function (i, item) {
351 address.push(item.value);
352 });
353
354 geoCoder.geocode({address: address.join(' ')}, function (results, status) {
355 if (status === google.maps.GeocoderStatus.OK) {
356 setMarker(map, results[0].geometry.location);
357 }
358 });
359 });
360 }
361 google.maps.event.addListener(map, 'click', function (event) {
362 setMarker(map, event.latLng);
363 });
364
365 if (options.html_lat.val() && options.html_lng.val()) {
366 location = new google.maps.LatLng(options.html_lat.val(), options.html_lng.val());
367 setMarker(map, location);
368 }
369 });
370
371 }
372 });
373 }(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.You are not allowed to attach a file to this page.