2 * Description: display a query result in a googlemap
3 * Copyright (c) 2012 UPMC Sorbonne Universite - INRIA
7 // xxx TODO -- this one could use a bit of cleaning like what was done for the first plugins
8 // especially wrt using 'instance' and 'data' in such a confusing way
13 init : function( options ) {
15 return this.each(function(){
17 var $this = jQuery(this),
18 data = $this.data('GoogleMap'), GoogleMap = jQuery('<div />', {text : $this.attr('title')});
20 // If the plugin hasn't been initialized yet
23 /* Plugin initialization */
25 //google.load('maps', '3', { other_params: 'sensor=false' });
26 //google.setOnLoadCallback(initialize);
28 $this.data('map', null);
29 $this.data('markerCluster', null);
30 $this.data('markers', []);
32 console.log ("lat=" + options.latitude + " long=" + options.longitude + " and zoom=" + options.zoom);
33 var myLatlng = new google.maps.LatLng(options.latitude, options.longitude);
37 mapTypeId: google.maps.MapTypeId.ROADMAP
40 var map = new google.maps.Map(document.getElementById("map"), myOptions);
41 $this.data('map', map);
43 /* End of plugin initialization */
45 jQuery(this).data('GoogleMap', {
46 plugin_uuid: options.plugin_uuid,
47 query_uuid: options.query_uuid,
49 current_resources: Array(),
53 /* Subscribe to query updates */
54 jQuery.subscribe('/results/' + options.query_uuid + '/changed', {instance: $this}, update_map);
55 jQuery.subscribe('/update-set/' + options.query_uuid, {instance: $this}, on_resource_changed);
56 jQuery.subscribe('/query/' + options.query_uuid + '/changed', {instance: $this}, query_changed);
58 //data = jQuery(this).data();
60 // TODO: Change the status of a node based on the actions in GoogleMap plugin or in other plugins (e.g. DataTables)
61 // Can we publish a value in results row['sliver'] ???
62 // Today, the value is attached or undefined
63 // But can we think about a added/removed status ???
64 // This plugin would update the map based on the results published
69 destroy : function( ) {
71 return this.each(function(){
72 var $this = jQuery(this), data = $this.data('GoogleMap');
73 jQuery(window).unbind('GoogleMap');
74 data.GoogleMap.remove();
75 $this.removeData('GoogleMap');
80 reposition : function( ) { // ... },
81 update : function( ) { // ... },
82 hide : function( ) { // ... },
84 show : function( content ) {
85 google.maps.event.trigger(map, 'resize');
89 jQuery.fn.GoogleMap = function( method ) {
90 /* Method calling logic */
91 if ( methods[method] ) {
92 return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
93 } else if ( typeof method === 'object' || ! method ) {
94 return methods.init.apply( this, arguments );
96 jQuery.error( 'Method ' + method + ' does not exist on jQuery.GoogleMap' );
101 /* Private methods */
102 function query_changed(e,query){
103 var data = e.data.instance.data();
104 /* Compare current and advertised query to get added and removed fields */
105 previous_query=data.current_query;
106 /* Save the query as the current query */
107 data.current_query=query;
110 if(typeof(data.results)!="undefined" && data.results.length>0){
111 jQuery.each(data.results, function(i, row){
112 jQuery.each(query.filter, function (idx, filter){
113 if(get_value(row[filter[0]])==filter[2]){
118 data.markerCluster=[];
120 var myLatlng = new google.maps.LatLng(34.397, 150.644);
124 mapTypeId: google.maps.MapTypeId.ROADMAP
126 map = new google.maps.Map(jQuery('#map')[0],myOptions);
128 //map.clearMarkers();
132 function update_map(e, rows) {
133 var data = e.data.instance.data();
134 var instance_ = e.data.instance;
135 //$plugindiv.closest('.need-spin').spin(false);
136 instance_.closest('.need-spin').spin(false);
139 if (rows === undefined || !rows || rows.length==0) {
140 messages.warning ("Empty result in googlemap.update_map - nothing to show");
148 if(typeof(data.results)=="undefined" || data.results==null){
152 var markerCluster = data.markerCluster;
153 var markers = data.markers;
154 var coords = new Array();
155 var infowindow = new google.maps.InfoWindow();
157 if(typeof(markers)!="undefined" && markers.length>0){
161 data.current_resources = Array();
163 jQuery.each(data.results, function(i, result){
164 // get the coordinates
165 var latitude=get_value(result['latitude']);
166 var longitude=get_value(result['longitude']);
167 var hash = latitude + longitude;
169 // check to see if we've seen this hash before
170 if(coords[hash] == null) {
171 // get coordinate object
172 var myLatlng = new google.maps.LatLng(latitude, longitude);
173 // store an indicator that we've seen this point before
176 // add some randomness to this point 1500 = 100 meters, 15000 = 10 meters
177 var lat = latitude + (Math.random() -.5) / 1500;
178 var lng = longitude + (Math.random() -.5) / 1500;
180 // get the coordinate object
181 var myLatlng = new google.maps.LatLng(lat, lng);
183 // If the node is attached to the slice, action will be Remove; else action will be add to slice
184 if (typeof(result['sliver']) != 'undefined') {
185 data.current_resources.push(result['urn']);
187 action_class="ui-icon-circle-minus";
188 action_message="Remove from slice";
191 action_class="ui-icon-circle-plus";
192 action_message="Add to slice";
195 if (!(result['latitude'])) {
199 //jQuery(".map-button").click(button_click);
200 if(jQuery.inArray(result,rows)>-1){
201 var marker = new google.maps.Marker({
203 title: get_value(result['ip']),
204 // This should be done by the rendering
205 content: '<p>Agent: ' + get_value(result['ip']) + ' (' + get_value(result['urn']) + ')<br/>Platform: ' + get_value(result['platform'])+'</p>' +
206 '<div class="map-button" id="'+action+'/'+get_value(result['urn'])+'" style="cursor:pointer;">'+
207 '<span class="ui-icon '+action_class+'" style="clear:both;float:left;"></span>'+action_message+
211 google.maps.event.addListener(marker, 'click', function() {
212 infowindow.content = this.content;
213 infowindow.open(map, this);
214 // onload of the infowindow on the map, bind a click on a button
215 google.maps.event.addListener(infowindow, 'domready', function() {
216 jQuery('.map-button').unbind('click');
217 jQuery(".map-button").click({instance: instance_}, button_click);
220 markers.push(marker);
223 markerCluster = new MarkerClusterer(map, markers, {zoomOnClick: false});
224 google.maps.event.addListener(markerCluster, "clusterclick", function (cluster) {
225 var markers = cluster.getMarkers();
226 var bounds = new google.maps.LatLngBounds();
230 * Firefox JS Error - replaced $.each by JQuery.each
232 jQuery.each(markers, function(i, marker){
233 bounds.extend(marker.getPosition());
235 //map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
236 map.fitBounds(bounds);
238 data.markerCluster=markerCluster;
240 function button_click(e){
241 var data = e.data.instance.data().GoogleMap;
242 var op_value=this.id.split("/");
243 if(op_value.length>0){
244 jQuery.publish('selected', op_value[0]+'/'+op_value[1]);
245 var value = op_value[1];
247 if (op_value[0] == 'add') {
248 data.current_resources.push(value);
250 tmp = jQuery.grep(data.current_resources, function(x) { return x != value; });
251 data.current_resources = tmp;
254 /* inform slice that our selected resources have changed */
255 jQuery.publish('/update-set/' + data.query_uuid, [data.current_resources, true, e.data.instance]);
259 function on_resource_changed(e, resources, instance)
261 /* TODO OPENLAB : this query determines which checkboxes must be checked */
262 if (instance == e.data.instance)
264 data = e.data.instance.data().GoogleMap;
266 previous_resources = data.current_resources;
267 data.current_resources = resources;
269 /* TODO We uncheck all checkboxes ... */
270 //jQuery('datatables-checkbox-' + data.options.plugin_uuid).attr('checked', false);
271 /* ... and check the ones specified in the resource list */
272 //jQuery.each(data.current_resources, function(index, urn) {
273 // jQuery('#datatables-checkbox-' + data.options.plugin_uuid + "-" + urn).attr('checked', true)