function OmekaMap(mapDivId, center, options) { this.mapDivId = mapDivId; this.center = center; this.options = options; } OmekaMap.prototype = { map: null, mapDivId: null, markers: [], options: {}, center: null, markerBounds: null, infoWindow: null, addMarker: function (lat, lng, options, bindHtml) { if (!options) { options = {}; } options.position = new google.maps.LatLng(lat, lng); options.map = this.map; options.icon = { url : "/custom/themes/default/logos_img/icones/mapPins/orange-map-pin.svg.hi.png", /*modification ne pas utiliser le pointeur orange-map-pin.svg.hi_2.png car pixelise*/ // size: new google.maps.Size(50, 50), origin: new google.maps.Point(0, 0), // anchor: new google.maps.Point(25, 25), scaledSize: new google.maps.Size(15, 25) } var marker = new google.maps.Marker(options); if (bindHtml) { var that = this; google.maps.event.addListener(marker, 'click', function () { // Prevent multiple windows from being open at once. that.infoWindow.setContent(bindHtml); that.infoWindow.open(this.map, marker); }); } this.markers.push(marker); this.markerBounds.extend(options.position); return marker; }, fitMarkers: function () { if (this.markers.length == 1) { this.map.setCenter(this.markers[0].getPosition()); } else { this.map.fitBounds(this.markerBounds); } }, initMap: function () { if (!this.center) { alert('Error: The center of the map has not been set!'); return; } // Build the map. var mapOptions = { zoom: this.center.zoomLevel, center: new google.maps.LatLng(this.center.latitude, this.center.longitude), }; switch (this.options.mapType) { case 'hybrid': mapOptions.mapTypeId = google.maps.MapTypeId.HYBRID; break; case 'satellite': mapOptions.mapTypeId = google.maps.MapTypeId.SATELLITE; break; case 'terrain': mapOptions.mapTypeId = google.maps.MapTypeId.TERRAIN; break; case 'roadmap': default: mapOptions.mapTypeId = google.maps.MapTypeId.ROADMAP; } jQuery.extend(mapOptions, this.options.mapOptions); this.map = new google.maps.Map(document.getElementById(this.mapDivId), mapOptions); this.markerBounds = new google.maps.LatLngBounds(); this.infoWindow = new google.maps.InfoWindow(); // Show the center marker if we have that enabled. if (this.center.show) { this.addMarker(this.center.latitude, this.center.longitude, {title: "(" + this.center.latitude + ',' + this.center.longitude + ")"}, this.center.markerHtml); } } }; function OmekaMapBrowse(mapDivId, center, options) { var omekaMap = new OmekaMap(mapDivId, center, options); jQuery.extend(true, this, omekaMap); this.initMap(); //XML loads asynchronously, so need to call for further config only after it has executed this.loadKmlIntoMap(this.options.uri, this.options.params); } OmekaMapBrowse.prototype = { afterLoadItems: function () { if (this.options.fitMarkers) { this.fitMarkers(); } if (!this.options.list) { return; } var listDiv = jQuery('#' + this.options.list); if (!listDiv.size()) { alert('Error: You have no map links div!'); } else { //Create HTML links for each of the markers this.buildListLinks(listDiv); } }, /* Need to parse KML manually b/c Google Maps API cannot access the KML behind the admin interface */ loadKmlIntoMap: function (kmlUrl, params) { var that = this; jQuery.ajax({ type: 'GET', dataType: 'xml', url: kmlUrl, data: params, success: function(data) { var xml = jQuery(data); /* KML can be parsed as: kml - root element Placemark namewithlink description Point - longitude,latitude */ var placeMarks = xml.find('Placemark'); // If we have some placemarks, load them if (placeMarks.size()) { // Retrieve the balloon styling from the KML file that.browseBalloon = that.getBalloonStyling(xml); // Build the markers from the placemarks jQuery.each(placeMarks, function (index, placeMark) { placeMark = jQuery(placeMark); that.buildMarkerFromPlacemark(placeMark); }); // We have successfully loaded some map points, so continue setting up the map object return that.afterLoadItems(); } else { // @todo Elaborate with an error message return false; } } }); }, getBalloonStyling: function (xml) { return xml.find('BalloonStyle text').text(); }, // Build a marker given the KML XML Placemark data // I wish we could use the KML file directly, but it's behind the admin interface so no go buildMarkerFromPlacemark: function (placeMark) { // Get the info for each location on the map var title = placeMark.find('name').text(); var titleWithLink = placeMark.find('namewithlink').text(); var body = placeMark.find('description').text(); var snippet = placeMark.find('Snippet').text(); // Extract the lat/long from the KML-formatted data var coordinates = placeMark.find('Point coordinates').text().split(','); var longitude = coordinates[0]; var latitude = coordinates[1]; // Use the KML formatting (do some string sub magic) var balloon = this.browseBalloon; balloon = balloon.replace('$[namewithlink]', titleWithLink).replace('$[description]', body).replace('$[Snippet]', snippet); // Build a marker, add HTML for it this.addMarker(latitude, longitude, {title: title}, balloon); }, // Calculate the zoom level given the 'range' value // Not currently used by this class, but possibly useful // http://throwless.wordpress.com/2008/02/23/gmap-geocoding-zoom-level-and-accuracy/ calculateZoom: function (range, width, height) { var zoom = 18 - Math.log(3.3 * range / Math.sqrt(width * width + height * height)) / Math.log(2); return zoom; }, buildListLinks: function (container) { var that = this; var list = jQuery('<ul></ul>'); list.appendTo(container); //tri de la liste (localeCompare prend en compte les caractètes accentuées et la différence minuscule/majuscule contrairement à juste (chaineA > chaineB) ) this.markers.sort(function(a,b){ if(a.title.localeCompare(b.title) > 0) return 1; else return -1; }); // Loop through all the markers jQuery.each(this.markers, function (index, marker) { var listElement = jQuery('<li></li>'); // Make an <a> tag, give it a class for styling var link = jQuery('<a></a>'); link.addClass('item-link'); // Links open up the markers on the map, clicking them doesn't actually go anywhere link.attr('href', 'javascript:void(0);'); // Each <li> starts with the title of the item link.html(marker.getTitle()); // Clicking the link should take us to the map link.bind('click', {}, function (event) { google.maps.event.trigger(marker, 'click'); that.map.panTo(marker.getPosition()); }); link.appendTo(listElement); listElement.appendTo(list); }); } }; function OmekaMapSingle(mapDivId, center, options) { var omekaMap = new OmekaMap(mapDivId, center, options); jQuery.extend(true, this, omekaMap); this.initMap(); } function OmekaMapForm(mapDivId, center, options) { var that = this; var omekaMap = new OmekaMap(mapDivId, center, options); jQuery.extend(true, this, omekaMap); this.initMap(); this.formDiv = jQuery('#' + this.options.form.id); // Make the map clickable to add a location point. google.maps.event.addListener(this.map, 'click', function (event) { // If we are clicking a new spot on the map if (!that.options.confirmLocationChange || that.markers.length === 0 || confirm('Are you sure you want to change the location of the item?')) { var point = event.latLng; var marker = that.setMarker(point); jQuery('#geolocation_address').val(''); } }); // Make the map update on zoom changes. google.maps.event.addListener(this.map, 'zoom_changed', function () { that.updateZoomForm(); }); // Make the Find By Address button lookup the geocode of an address and add a marker. jQuery('#geolocation_find_location_by_address').bind('click', function (event) { var address = jQuery('#geolocation_address').val(); that.findAddress(address); //Don't submit the form event.stopPropagation(); return false; }); // Make the return key in the geolocation address input box click the button to find the address. jQuery('#geolocation_address').bind('keydown', function (event) { if (event.which == 13) { jQuery('#geolocation_find_location_by_address').click(); event.stopPropagation(); return false; } }); // Add the existing map point. if (this.options.point) { this.map.setZoom(this.options.point.zoomLevel); var point = new google.maps.LatLng(this.options.point.latitude, this.options.point.longitude); var marker = this.setMarker(point); this.map.setCenter(marker.getPosition()); } } OmekaMapForm.prototype = { /* Get the geolocation of the address and add marker. */ findAddress: function (address) { var that = this; function setFoundAddress(point) { // If required, ask the user if they want to add a marker to the geolocation point of the address. // If so, add the marker, otherwise clear the address. if (!that.options.confirmLocationChange || that.markers.length === 0 || confirm('Are you sure you want to change the location of the item?')) { var marker = that.setMarker(point); } else { jQuery('#geolocation_address').val(''); jQuery('#geolocation_address').focus(); } } // Use lat/lng pair var latLngMatch = address.trim().match(/^(-?[\d]+(?:\.[\d]+)?)[\s]*[,;][\s]*(-?[\d]+(?:\.[\d]+)?)$/); if (latLngMatch && Math.abs(latLngMatch[1]) <= 90 && Math.abs(latLngMatch[2]) <= 180) { var point = new google.maps.LatLng(latLngMatch[1], latLngMatch[2]); setFoundAddress(point); return; } if (!this.geocoder) { this.geocoder = new google.maps.Geocoder(); } this.geocoder.geocode({'address': address}, function (results, status) { // If the point was found, then put the marker on that spot if (status == google.maps.GeocoderStatus.OK) { var point = results[0].geometry.location; setFoundAddress(point); } else { // If no point was found, give us an alert alert('Error: "' + address + '" was not found!'); return null; } }); }, /* Set the marker to the point. */ setMarker: function (point) { var that = this; // Get rid of existing markers. this.clearForm(); // Add the marker var marker = this.addMarker(point.lat(), point.lng()); marker.setAnimation(google.maps.Animation.DROP); // Pan the map to the marker that.map.panTo(point); // Make the marker clear the form if clicked. google.maps.event.addListener(marker, 'click', function (event) { if (!that.options.confirmLocationChange || confirm('Are you sure you want to remove the location of the item?')) { that.clearForm(); } }); this.updateForm(point); return marker; }, /* Update the latitude, longitude, and zoom of the form. */ updateForm: function (point) { var latElement = document.getElementsByName('geolocation[latitude]')[0]; var lngElement = document.getElementsByName('geolocation[longitude]')[0]; var zoomElement = document.getElementsByName('geolocation[zoom_level]')[0]; // If we passed a point, then set the form to that. If there is no point, clear the form if (point) { latElement.value = point.lat(); lngElement.value = point.lng(); zoomElement.value = this.map.getZoom(); } else { latElement.value = ''; lngElement.value = ''; zoomElement.value = this.map.getZoom(); } }, /* Update the zoom input of the form to be the current zoom on the map. */ updateZoomForm: function () { var zoomElement = document.getElementsByName('geolocation[zoom_level]')[0]; zoomElement.value = this.map.getZoom(); }, /* Clear the form of all markers. */ clearForm: function () { // Remove the markers from the map for (var i = 0; i < this.markers.length; i++) { this.markers[i].setMap(null); } // Clear the markers array this.markers = []; // Update the form this.updateForm(); }, /* Resize the map and center it on the first marker. */ resize: function () { google.maps.event.trigger(this.map, 'resize'); var point; if (this.markers.length) { var marker = this.markers[0]; point = marker.getPosition(); } else { point = new google.maps.LatLng(this.center.latitude, this.center.longitude); } this.map.setCenter(point); } };