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