2 * MySlice GoogleMap plugin
3 * URL: http://trac.myslice.info
4 * Description: display a query result in a googlemap
5 * Author: The MySlice Team
6 * Copyright (c) 2012 UPMC Sorbonne Universite - INRIA
10 // xxx TODO -- this one could use a bit of cleaning like what was done for the first plugins
11 // especially wrt using 'instance' and 'data' in such a confusing way
16 init : function( options ) {
18 return this.each(function(){
20 var $this = jQuery(this),
21 data = $this.data('GoogleMap'), GoogleMap = jQuery('<div />', {text : $this.attr('title')});
23 // If the plugin hasn't been initialized yet
26 /* Plugin initialization */
28 //google.load('maps', '3', { other_params: 'sensor=false' });
29 //google.setOnLoadCallback(initialize);
31 $this.data('map', null);
32 $this.data('markerCluster', null);
33 $this.data('markers', []);
35 var myLatlng = new google.maps.LatLng(34.397, 150.644);
39 mapTypeId: google.maps.MapTypeId.ROADMAP
42 var map = new google.maps.Map(document.getElementById("map"), myOptions);
43 $this.data('map', map);
45 /* End of plugin initialization */
47 jQuery(this).data('GoogleMap', {
48 plugin_uuid: options.plugin_uuid,
49 query_uuid: options.query_uuid,
51 current_resources: Array(),
55 /* Subscribe to query updates */
56 jQuery.subscribe('/results/' + options.query_uuid + '/changed', {instance: $this}, update_map);
57 jQuery.subscribe('/update-set/' + options.query_uuid, {instance: $this}, on_resource_changed);
58 jQuery.subscribe('/query/' + options.query_uuid + '/changed', {instance: $this}, query_changed);
60 //data = jQuery(this).data();
62 // TODO: Change the status of a node based on the actions in GoogleMap plugin or in other plugins (e.g. DataTables)
63 // Can we publish a value in results row['sliver'] ???
64 // Today, the value is attached or undefined
65 // But can we think about a added/removed status ???
66 // This plugin would update the map based on the results published
71 destroy : function( ) {
73 return this.each(function(){
74 var $this = jQuery(this), data = $this.data('GoogleMap');
75 jQuery(window).unbind('GoogleMap');
76 data.GoogleMap.remove();
77 $this.removeData('GoogleMap');
82 reposition : function( ) { // ... },
83 update : function( ) { // ... },
84 hide : function( ) { // ... },
86 show : function( content ) {
87 google.maps.event.trigger(map, 'resize');
91 jQuery.fn.GoogleMap = function( method ) {
92 /* Method calling logic */
93 if ( methods[method] ) {
94 return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
95 } else if ( typeof method === 'object' || ! method ) {
96 return methods.init.apply( this, arguments );
98 jQuery.error( 'Method ' + method + ' does not exist on jQuery.GoogleMap' );
103 /* Private methods */
104 function query_changed(e,query){
105 var data = e.data.instance.data();
106 /* Compare current and advertised query to get added and removed fields */
107 previous_query=data.current_query;
108 /* Save the query as the current query */
109 data.current_query=query;
112 if(typeof(data.results)!="undefined" && data.results.length>0){
113 jQuery.each(data.results, function(i, row){
114 jQuery.each(query.filter, function (idx, filter){
115 if(get_value(row[filter[0]])==filter[2]){
120 data.markerCluster=[];
122 var myLatlng = new google.maps.LatLng(34.397, 150.644);
126 mapTypeId: google.maps.MapTypeId.ROADMAP
128 map = new google.maps.Map(jQuery('#map')[0],myOptions);
130 //map.clearMarkers();
134 function update_map(e, rows) {
135 var data = e.data.instance.data();
136 var instance_ = e.data.instance;
137 //$plugindiv.closest('.need-spin').spin(false);
138 instance_.closest('.need-spin').spin(false);
150 if(typeof(data.results)=="undefined" || data.results==null){
154 var markerCluster = data.markerCluster;
155 var markers = data.markers;
156 var coords = new Array();
157 var infowindow = new google.maps.InfoWindow();
159 if(typeof(markers)!="undefined" && markers.length>0){
163 data.current_resources = Array();
165 jQuery.each(data.results, function(i, result){
166 // get the coordinates
167 var latitude=get_value(result['latitude']);
168 var longitude=get_value(result['longitude']);
169 var hash = latitude + longitude;
171 // check to see if we've seen this hash before
172 if(coords[hash] == null) {
173 // get coordinate object
174 var myLatlng = new google.maps.LatLng(latitude, longitude);
175 // store an indicator that we've seen this point before
178 // add some randomness to this point 1500 = 100 meters, 15000 = 10 meters
179 var lat = latitude + (Math.random() -.5) / 1500;
180 var lng = longitude + (Math.random() -.5) / 1500;
182 // get the coordinate object
183 var myLatlng = new google.maps.LatLng(lat, lng);
185 // If the node is attached to the slice, action will be Remove; else action will be add to slice
186 if (typeof(result['sliver']) != 'undefined') {
187 data.current_resources.push(result['urn']);
189 action_class="ui-icon-circle-minus";
190 action_message="Remove from slice";
193 action_class="ui-icon-circle-plus";
194 action_message="Add to slice";
197 if (!(result['latitude'])) {
201 //jQuery(".map-button").click(button_click);
202 if(jQuery.inArray(result,rows)>-1){
203 var marker = new google.maps.Marker({
205 title: get_value(result['ip']),
206 // This should be done by the rendering
207 content: '<p>Agent: ' + get_value(result['ip']) + ' (' + get_value(result['urn']) + ')<br/>Platform: ' + get_value(result['platform'])+'</p>' +
208 '<div class="map-button" id="'+action+'/'+get_value(result['urn'])+'" style="cursor:pointer;">'+
209 '<span class="ui-icon '+action_class+'" style="clear:both;float:left;"></span>'+action_message+
213 google.maps.event.addListener(marker, 'click', function() {
214 infowindow.content = this.content;
215 infowindow.open(map, this);
216 // onload of the infowindow on the map, bind a click on a button
217 google.maps.event.addListener(infowindow, 'domready', function() {
218 jQuery('.map-button').unbind('click');
219 jQuery(".map-button").click({instance: instance_}, button_click);
222 markers.push(marker);
225 markerCluster = new MarkerClusterer(map, markers, {zoomOnClick: false});
226 google.maps.event.addListener(markerCluster, "clusterclick", function (cluster) {
227 var markers = cluster.getMarkers();
228 var bounds = new google.maps.LatLngBounds();
232 * Firefox JS Error - replaced $.each by JQuery.each
234 jQuery.each(markers, function(i, marker){
235 bounds.extend(marker.getPosition());
237 //map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
238 map.fitBounds(bounds);
240 data.markerCluster=markerCluster;
242 function button_click(e){
243 var data = e.data.instance.data().GoogleMap;
244 var op_value=this.id.split("/");
245 if(op_value.length>0){
246 jQuery.publish('selected', op_value[0]+'/'+op_value[1]);
247 var value = op_value[1];
249 if (op_value[0] == 'add') {
250 data.current_resources.push(value);
252 tmp = jQuery.grep(data.current_resources, function(x) { return x != value; });
253 data.current_resources = tmp;
256 /* inform slice that our selected resources have changed */
257 jQuery.publish('/update-set/' + data.query_uuid, [data.current_resources, true, e.data.instance]);
261 function on_resource_changed(e, resources, instance)
263 /* TODO OPENLAB : this query determines which checkboxes must be checked */
264 if (instance == e.data.instance)
266 data = e.data.instance.data().GoogleMap;
268 previous_resources = data.current_resources;
269 data.current_resources = resources;
271 /* TODO We uncheck all checkboxes ... */
272 //jQuery('datatables-checkbox-' + data.options.plugin_uuid).attr('checked', false);
273 /* ... and check the ones specified in the resource list */
274 //jQuery.each(data.current_resources, function(index, urn) {
275 // jQuery('#datatables-checkbox-' + data.options.plugin_uuid + "-" + urn).attr('checked', true)