2 * Description: display a query result in a googlemap
3 * Copyright (c) 2012 UPMC Sorbonne Universite - INRIA
8 * It's a best practice to pass jQuery to an IIFE (Immediately Invoked Function
9 * Expression) that maps it to the dollar sign so it can't be overwritten by
10 * another library in the scope of its execution.
16 jQuery.fn.GoogleMap = function( method ) {
17 if ( methods[method] ) {
18 return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
19 } else if ( typeof method === 'object' || ! method ) {
20 return methods.init.apply( this, arguments );
22 jQuery.error( 'Method ' + method + ' does not exist on jQuery.GoogleMap' );
26 /***************************************************************************
28 ***************************************************************************/
33 * @brief Plugin initialization
34 * @param options : an associative array of setting values
35 * @return : a jQuery collection of objects on which the plugin is
36 * applied, which allows to maintain chainability of calls
38 init : function( options ) {
40 return this.each(function(){
44 /* An object that will hold private variables and methods */
45 var plugin = new GoogleMaps(options);
46 $this.data('Manifold', plugin);
51 $this.on('show.GoogleMaps', methods.show);
53 $this.set_query_handler(options.query_uuid, plugin.query_handler);
54 $this.set_record_handler(options.query_uuid, plugin.record_handler);
55 $this.set_record_handler(options.query_all_uuid, plugin.record_handler_all);
61 * @brief Plugin destruction
62 * @return : a jQuery collection of objects on which the plugin is
63 * applied, which allows to maintain chainability of calls
65 destroy : function( ) {
67 return this.each(function() {
69 var hazelnut = $this.data('Manifold');
71 // Unbind all events using namespacing
72 $(window).unbind('Manifold');
74 // Remove associated data
76 $this.removeData('Manifold');
82 google.maps.event.trigger(map, 'resize');
87 /***************************************************************************
89 ***************************************************************************/
91 function GoogleMaps(options)
93 /* member variables */
94 this.options = options;
97 this.received_all = false;
98 this.received_set = false;
99 this.in_set_buffer = Array();
105 this.initialize = function() {
107 this.markerCluster = null;
109 this.coords = new Array();
111 var myLatlng = new google.maps.LatLng(options.latitude, options.longitude);
115 mapTypeId: google.maps.MapTypeId.ROADMAP
118 this.map = new google.maps.Map(document.getElementById("map"), myOptions);
119 this.infowindow = new google.maps.InfoWindow();
124 this.new_record = function(record)
127 // get the coordinates
128 var latitude=get_value(record['latitude']);
129 var longitude=get_value(record['longitude']);
130 var hash = latitude + longitude;
132 // check to see if we've seen this hash before
133 if(this.coords[hash] == null) {
134 // get coordinate object
135 var myLatlng = new google.maps.LatLng(latitude, longitude);
136 // store an indicator that we've seen this point before
137 this.coords[hash] = 1;
139 // add some randomness to this point 1500 = 100 meters, 15000 = 10 meters
140 var lat = latitude + (Math.random() -.5) / 1500;
141 var lng = longitude + (Math.random() -.5) / 1500;
143 // get the coordinate object
144 var myLatlng = new google.maps.LatLng(lat, lng);
146 // If the node is attached to the slice, action will be Remove; else action will be add to slice
147 if (typeof(record['sliver']) != 'undefined') {
148 data.current_resources.push(record['urn']);
150 action_class="ui-icon-circle-minus";
151 action_message="Remove from slice";
154 action_class="ui-icon-circle-plus";
155 action_message="Add to slice";
158 if (!(record['latitude'])) {
162 //jQuery(".map-button").click(button_click);
163 //if(jQuery.inArray(record, rows)>-1){
164 var marker = new google.maps.Marker({
166 title: get_value(record['hostname']),
167 // This should be done by the rendering
168 content: '<p>Agent: ' + get_value(record['ip']) + ' (' + get_value(record['resource_hrn']) + ')<br/>Platform: ' + get_value(record['platform'])+'</p>' +
169 '<div class="map-button" id="'+action+'/'+get_value(record['resource_hrn'])+'" style="cursor:pointer;">'+
170 '<span class="ui-icon '+action_class+'" style="clear:both;float:left;"></span>'+action_message+
174 this.addInfoWindow(marker, object.map);
175 object.markers.push(marker);
180 this.addInfoWindow = function(marker, map) {
181 google.maps.event.addListener(marker, 'click', function () {
182 if(object.infowindow){
183 object.infowindow.close();
185 object.infowindow.setContent(marker.content);// = new google.maps.InfoWindow({ content: marker.content });
186 object.infowindow.open(map, marker);
187 // onload of the infowindow on the map, bind a click on a button
188 google.maps.event.addListener(object.infowindow, 'domready', function() {
189 jQuery('.map-button').unbind('click');
190 // jQuery(".map-button").click({instance: instance_, infoWindow: object.infowindow}, button_click);
196 this.set_checkbox = function(record)
198 // XXX urn should be replaced by the key
199 // XXX we should enforce that both queries have the same key !!
200 //checkbox_id = "#hazelnut-checkbox-" + object.options.plugin_uuid + "-" + unfold.escape_id(record[ELEMENT_KEY].replace(/\\/g, ''))
201 //$(checkbox_id, object.table.fnGetNodes()).attr('checked', true);
204 this.record_handler = function(e, event_type, record)
209 /* NOTE in fact we are doing a join here */
210 if (object.received_all)
211 // update checkbox for record
212 object.set_checkbox(record);
214 // store for later update of checkboxes
215 object.in_set_buffer.push(record);
218 // nothing to do here
221 manifold.spin($(this));
224 if (object.received_all)
225 manifold.spin($(this), false);
226 object.received_set = true;
231 this.record_handler_all = function(e, event_type, record)
236 // Add the record to the table
237 object.new_record(record);
240 // object.table.fnClearTable();
243 manifold.spin($(this));
248 object.markerCluster = new MarkerClusterer(object.map, object.markers, {zoomOnClick: false});
249 google.maps.event.addListener(object.markerCluster, "clusterclick", function (cluster) {
250 var markers = cluster.getMarkers();
251 var bounds = new google.maps.LatLngBounds();
255 * Firefox JS Error - replaced $.each by JQuery.each
257 jQuery.each(markers, function(i, marker){
258 bounds.extend(marker.getPosition());
261 //map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
262 object.map.fitBounds(bounds);
265 if (object.received_set) {
266 /* XXX needed ? XXX We uncheck all checkboxes ... */
267 $("[id^='datatables-checkbox-" + object.options.plugin_uuid +"']").attr('checked', false);
269 /* ... and check the ones specified in the resource list */
270 $.each(object.in_set_buffer, function(i, record) {
271 object.set_checkbox(record);
274 manifold.spin($(this), false);
276 object.received_all = true;
282 this.query_handler = function(e, event_type, query)
284 // This replaces the complex set_query function
285 // The plugin does not need to remember the query anymore
291 // XXX Here we might need to maintain the list of filters !
292 /* Process updates in filters / current_query must be updated before this call for filtering ! */
293 object.table.fnDraw();
297 /* Hide/unhide columns to match added/removed fields */
300 $.each(added_fields, function (index, field) {
301 var index = object.getColIndex(field,cols);
303 object.table.fnSetColumnVis(index, true);
308 $.each(removed_fields, function (index, field) {
309 var index = object.getColIndex(field,cols);
311 object.table.fnSetColumnVis(index, false);
315 alert('GoogleMaps::clear_fields() not implemented');
322 function button_click(e){
323 var op_value=this.id.split("/");
324 if(op_value.length>0){
325 var value = op_value[1];
326 manifold.raise_event(object.options.query_uuid, (op_value[0] == 'add')?SET_ADD:SET_REMOVED, value);
328 } // function button_click()
332 // jQuery.each(data.results, function(i, row){
333 // jQuery.each(query.filter, function (idx, filter){
334 // if(get_value(row[filter[0]])==filter[2]){
339 // data.markerCluster=[];
341 // var myLatlng = new google.maps.LatLng(34.397, 150.644);
345 // mapTypeId: google.maps.MapTypeId.ROADMAP
347 // map = new google.maps.Map(jQuery('#map')[0],myOptions);
349 // //map.clearMarkers();
350 // update_map(e, rows);