summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/Maps/resources/leaflet/jquery.leaflet.js
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/extensions/Maps/resources/leaflet/jquery.leaflet.js')
-rw-r--r--www/wiki/extensions/Maps/resources/leaflet/jquery.leaflet.js567
1 files changed, 232 insertions, 335 deletions
diff --git a/www/wiki/extensions/Maps/resources/leaflet/jquery.leaflet.js b/www/wiki/extensions/Maps/resources/leaflet/jquery.leaflet.js
index 3483ec3a..5012c766 100644
--- a/www/wiki/extensions/Maps/resources/leaflet/jquery.leaflet.js
+++ b/www/wiki/extensions/Maps/resources/leaflet/jquery.leaflet.js
@@ -4,423 +4,321 @@
*
* @author Pavel Astakhov < pastakhov@yandex.ru >
* @author Peter Grassberger < petertheone@gmail.com >
+ * @author Jeroen De Dauw
*/
-(function ($, mw, L, MQ) {
- $.fn.leafletmaps = function ( options ) {
- var _this = this;
- this.map = null;
- this.options = options;
- this.markers = [];
- this.markercluster = null;
- var apikeys = mw.config.get('egMapsLeafletLayersApiKeys') ;
-
- /**
- * array point of all map elements (markers, lines, polygons, etc.)
- * for map fit
- */
- this.points = [];
-
- /**
- * Creates a new marker with the provided data and returns it.
- * @param {Object} properties Contains the fields lat, lon, title, text and icon
- * @return {L.Marker}
- */
- this.createMarker = function (properties) {
- this.points.push( new L.LatLng(properties.lat, properties.lon) );
-
- var markerOptions = {
- title:properties.title
+(function ($, mw, L, maps, sm) {
+
+ function getMapOptions(options) {
+ let mapOptions = {};
+ if (options.minzoom !== false) mapOptions.minZoom = options.minzoom;
+ if (options.maxzoom !== false) mapOptions.maxZoom = options.maxzoom;
+
+ if (options.fullscreen) {
+ mapOptions.fullscreenControl = true;
+ mapOptions.fullscreenControlOptions= {
+ position: 'topleft'
};
+ }
- var marker = L.marker( [properties.lat, properties.lon], markerOptions );
-
- if (properties.hasOwnProperty('icon') && properties.icon !== '') {
- marker.setOpacity(0);
-
- var img = new Image();
- img.onload = function() {
- var icon = new L.Icon({
- iconUrl: properties.icon,
- iconSize: [ img.width, img.height ],
- iconAnchor: [ img.width / 2, img.height ],
- popupAnchor: [ -img.width % 2, -img.height*2/3 ]
- });
-
- marker.setIcon(icon);
- marker.setOpacity(1);
- };
- img.src = properties.icon;
- }
+ mapOptions.scrollWheelZoom = options.scrollwheelzoom;
- if( properties.hasOwnProperty('text') && properties.text.length > 0 ) {
- marker.bindPopup( properties.text );
- }
+ if (options.static) {
+ mapOptions.scrollWheelZoom = false;
+ mapOptions.doubleClickZoom = false;
+ mapOptions.touchZoom = false;
+ mapOptions.boxZoom = false;
+ mapOptions.tap = false;
+ mapOptions.keyboard = false;
+ mapOptions.zoomControl = false;
+ mapOptions.dragging = false;
+ }
- if ( options.copycoords ) {
- marker.on(
- 'contextmenu',
- function( e ) {
- prompt(mw.msg('maps-copycoords-prompt'), e.latlng.lat + ',' + e.latlng.lng);
- }
- );
- }
-
- return marker;
- };
+ return mapOptions;
+ }
- /**
- * Creates a new marker with the provided data, adds it to the map
- * and returns it.
- * @param {Object} properties Contains the fields lat, lon, title, text and icon
- * @return {L.Marker}
- */
- this.addMarker = function (properties) {
- var marker = this.createMarker(properties);
- if (!this.options.markercluster) {
- marker.addTo( this.map );
- }
- this.markers.push( marker );
- return marker;
- };
+ $.fn.leafletmaps = function ( options ) {
+ let _this = this;
+ _this.options = options; // needed by LeafletAjax.js
- this.removeMarker = function (marker) {
- this.map.removeLayer(marker);
- this.points = [];
- this.markers = this.markers.filter(function(object) {
- return object !== marker;
- });
- };
+ this.setup = function() {
+ this.map = L.map( this.get(0), getMapOptions(options) );
+ this.mapContent = maps.leaflet.FeatureBuilder.contentLayerFromOptions(options).addTo(this.map);
- this.removeMarkers = function () {
- if (this.markercluster) {
- this.map.removeLayer(this.markercluster);
- this.markercluster = null;
- }
- var map = this.map;
- $.each(this.markers, function(index, marker) {
- map.removeLayer(marker);
- });
+ this.hideLoadingMessage();
+ this.addLayersAndOverlays(this.map);
+ this.centerAndZoomMap();
+ this.bindClickTarget();
+ this.applyResizable();
+ this.bindAjaxEvents();
- this.points = [];
- this.markers = [];
+ this.maybeAddEditButton();
};
- this.addLine = function (properties) {
- var options = {
- color: properties.strokeColor,
- weight:properties.strokeWeight,
- opacity:properties.strokeOpacity
- };
+ this.shouldLoadEditorJs = function() {
+ if ( options.geojson === '' || options.GeoJsonSource === null ) {
+ return false;
+ }
- var latlngs = [];
- for (var x = 0; x < properties.pos.length; x++) {
- latlngs.push([properties.pos[x].lat, properties.pos[x].lon]);
- this.points.push( new L.LatLng(properties.pos[x].lat, properties.pos[x].lon) );
+ if (mw.config.get('wgCurRevisionId') !== mw.config.get('wgRevisionId')) {
+ return false;
}
- var line = L.polyline(latlngs, options).addTo(this.map);
+ return true;
+ };
- if( properties.hasOwnProperty('text') && properties.text.trim().length > 0 ) {
- line.bindPopup( properties.text );
+ this.maybeAddEditButton = function() {
+ if ( this.shouldLoadEditorJs() ) {
+ maps.api.canEditPage('GeoJson:' + options.GeoJsonSource).done(
+ function(canEdit) {
+ if (canEdit) {
+ _this.addEditButton();
+ }
+ }
+ );
}
};
- this.addPolygon = function (properties) {
- properties.pos.forEach(function(position) {
- _this.points.push( new L.LatLng(position.lat, position.lon) );
- });
+ this.addEditButton = function() {
+ this.editButton = L.easyButton(
+ '<img src="' + mw.config.get('egMapsScriptPath') + 'resources/leaflet/images/edit-solid.svg">',
+ this.startEditMode,
+ mw.msg('maps-editor-edit-geojson')
+ ).addTo(this.map);
+ };
+
+ this.startEditMode = function() {
+ _this.removeEditButton();
+ _this.mapContent.remove();
- var polygon = L.polygon(
- properties.pos.map(function(position) {
- return [position.lat, position.lon];
- }),
- {
- color: properties.strokeColor,
- weight:properties.strokeWeight,
- opacity:properties.strokeOpacity,
- fillColor:properties.fillColor,
- fillOpacity:properties.fillOpacity
+ maps.api.getLatestRevision('GeoJson:' + options.GeoJsonSource).done(
+ function(revision) {
+ if (revision.revid === options.GeoJsonRevisionId) {
+ _this.initializeEditor(options.geojson);
+ }
+ else {
+ _this.purgePage();
+ _this.initializeEditor(JSON.parse(revision['*']));
+ }
}
);
+ };
- polygon.addTo(this.map);
+ this.initializeEditor = function(geoJson) {
+ let editor = _this.getEditor();
+ editor.initialize(geoJson);
- if( properties.hasOwnProperty('text') && properties.text.trim().length > 0 ) {
- console.log(properties.text);
- polygon.bindPopup( properties.text );
- }
- };
+ editor.onSaved(function() {
+ _this.purgePage();
- this.addCircle = function (properties) {
- var circle = L.circle(
- [properties.centre.lat, properties.centre.lon],
- {
- radius: properties.radius,
- color: properties.strokeColor,
- weight:properties.strokeWeight,
- opacity:properties.strokeOpacity,
- fillColor:properties.fillColor,
- fillOpacity:properties.fillOpacity,
- }
- ).addTo(this.map);
+ editor.remove();
+ options.geojson = editor.getLayer().toGeoJSON();
+ _this.mapContent = maps.leaflet.FeatureBuilder.contentLayerFromOptions(options).addTo(_this.map);
- this.points.push( new L.LatLng(properties.centre.lat, properties.centre.lon) );
+ alert(mw.msg('maps-json-editor-changes-saved'));
+ _this.addEditButton();
+ });
+ };
- if( properties.hasOwnProperty('text') && properties.text.trim().length > 0 ) {
- circle.bindPopup( properties.text );
+ this.getEditor = function() {
+ if (!this.editor) {
+ this.editor = maps.leaflet.LeafletEditor(
+ _this.map,
+ new maps.MapSaver('GeoJson:' + options.GeoJsonSource)
+ );
}
+
+ return this.editor;
};
- this.addRectangle = function (properties) {
- this.points.push( new L.LatLng(properties.sw.lat, properties.sw.lon) );
- this.points.push( new L.LatLng(properties.ne.lat, properties.ne.lon) );
+ this.purgePage = function() {
+ new mw.Api().post({
+ action: 'purge',
+ titles: mw.config.get( 'wgPageName' )
+ }).then(function(response) {
- var options = {
- color: properties.strokeColor,
- weight:properties.strokeWeight,
- opacity:properties.strokeOpacity,
- fillColor:properties.fillColor,
- fillOpacity:properties.fillOpacity
- };
+ });
+ };
- var bounds = [[properties.sw.lat, properties.sw.lon], [properties.ne.lat, properties.ne.lon]];
+ this.removeEditButton = function() {
+ if (this.editButton) {
+ this.editButton.remove();
+ this.editButton = null;
+ }
+ };
- var rectangle = L.rectangle( bounds, options ).addTo(this.map);
+ this.hideLoadingMessage = function() {
+ this.map.on(
+ 'load',
+ function() {
+ $(_this).find('div.maps-loading-message').hide();
+ }
+ );
+ };
- if( properties.hasOwnProperty('text') && properties.text.trim().length > 0 ) {
- rectangle.bindPopup( properties.text );
+ this.applyResizable = function() {
+ if (options.resizable) {
+ _this.resizable();
}
};
- this.createMarkerCluster = function () {
- if ( !options.markercluster ) {
- return;
- }
- var markers = this.markers;
-
- var markercluster = new L.MarkerClusterGroup({
- maxClusterRadius: options.clustermaxradius,
- disableClusteringAtZoom: options.clustermaxzoom + 1,
- zoomToBoundsOnClick: options.clusterzoomonclick,
- spiderfyOnMaxZoom: options.clusterspiderfy,
- iconCreateFunction: function(cluster) {
- var childCount = cluster.getChildCount();
-
- var imagePath = mw.config.get( 'egMapsScriptPath' ) + '/resources/leaflet/cluster/';
-
- var styles = [
- {
- iconUrl: imagePath + 'm1.png',
- iconSize: [53, 52]
- },
- {
- iconUrl: imagePath + 'm2.png',
- iconSize: [56, 55]
- },
- {
- iconUrl: imagePath + 'm3.png',
- iconSize: [66, 65]
- },
- {
- iconUrl: imagePath + 'm4.png',
- iconSize: [78, 77]
- },
- {
- iconUrl: imagePath + 'm5.png',
- iconSize: [90, 89]
- }
- ];
+ // Caution: used by ajaxUpdateMarker
+ this.addMarker = function (properties) {
+ this.mapContent.markerLayer.addLayer(maps.leaflet.FeatureBuilder.createMarker(properties, options));
+ };
- var index = 0;
- var dv = childCount;
- while (dv !== 0) {
- dv = parseInt(dv / 10, 10);
- index++;
- }
- var index = Math.min(index, styles.length);
- index = Math.max(0, index - 1);
- index = Math.min(styles.length - 1, index);
- var style = styles[index];
-
- return new L.divIcon({
- iconSize: style.iconSize,
- className: '',
- html: '<img style="' +
- '" src="' + style.iconUrl + '" />' +
- '<span style="' +
- 'position: absolute; font-size: 11px; font-weight: bold; text-align: center; ' +
- 'top: 0; left: 0; ' +
- 'line-height: ' + style.iconSize[1] + 'px;' +
- 'width: ' + style.iconSize[0] + 'px;' +
- '">' + childCount + '</span>'
- });
- }
- });
- $.each(this.markers, function(index, marker) {
- markercluster.addLayer(marker);
- });
- if (this.markercluster) {
- this.map.removeLayer(this.markercluster);
- this.markercluster = null;
- }
- this.map.addLayer(markercluster);
- this.markercluster = markercluster;
+ // Caution: used by ajaxUpdateMarker
+ this.removeMarkers = function () {
+ this.mapContent.markerLayer.clearLayers();
};
- this.addGeoJson = function(options) {
- if (options.geojson !== '') {
- var geoJson = options.geojson;
- var geoJsonLayer = L.geoJSON( geoJson ).addTo( this.map );
+ this.bindClickTarget = function() {
+ function newClickTargetUrl(latlng) {
+ return options.clicktarget
+ .replace( /%lat%/g, latlng.lat )
+ .replace( /%long%/g, latlng.lng );
+ }
- this.points.push( geoJsonLayer.getBounds().getNorthEast() );
- this.points.push( geoJsonLayer.getBounds().getSouthWest() );
+ if (options.clicktarget !== '') {
+ this.map.on(
+ 'click',
+ function(e) {
+ window.location.href = newClickTargetUrl(e.latlng);
+ }
+ );
}
};
- this.setup = function () {
-
- var mapOptions = {};
- if (options.minzoom !== false ) mapOptions.minZoom = options.minzoom;
- if (options.maxzoom !== false ) mapOptions.maxZoom = options.maxzoom;
+ this.isUserUsesDarkMode = function () {
+ return window.matchMedia( '(prefers-color-scheme: dark)' ).matches;
+ };
- if (options.enablefullscreen) {
- mapOptions.fullscreenControl = true;
- mapOptions.fullscreenControlOptions= {
- position: 'topleft'
- };
- }
-
- mapOptions.scrollWheelZoom = options.scrollwheelzoom;
-
- if (options.static) {
- mapOptions.scrollWheelZoom = false;
- mapOptions.doubleClickZoom = false;
- mapOptions.touchZoom = false;
- mapOptions.boxZoom = false;
- mapOptions.tap = false;
- mapOptions.keyboard = false;
- mapOptions.zoomControl = false;
- mapOptions.dragging = false;
+ this.getLayerNames = function () {
+ if ( this.isUserUsesDarkMode() ) {
+ return mw.config.get('egMapsLeafletLayersDark');
}
- var map = L.map( this.get(0), mapOptions ).fitWorld();
- this.map = map;
+ return options.layers;
+ };
+
+ this.addLayers = function() {
+ let apiKeys = mw.config.get('egMapsLeafletLayersApiKeys');
+ let layers = {};
- var layers = {};
- $.each(options.layers.reverse(), function(index, layerName) {
+ $.each( this.getLayerNames().reverse(), function(index, layerName) {
var options = {} ;
var providerName = layerName.split('.')[0] ;
- if (apikeys.hasOwnProperty(providerName) && apikeys[providerName] !== '') {
- options.apikey = apikeys[providerName] ;
- }
+ if (apiKeys.hasOwnProperty(providerName) && apiKeys[providerName] !== '') {
+ options.apikey = apiKeys[providerName] ;
+ }
if (layerName === 'MapQuestOpen') {
- layers[layerName] = new MQ.TileLayer().addTo(map);
+ layers[layerName] = new window.MQ.TileLayer().addTo(_this.map);
} else {
- layers[layerName] = new L.tileLayer.provider(layerName,options).addTo(map);
+ layers[layerName] = new L.tileLayer.provider(layerName,options).addTo(_this.map);
}
});
- var overlaylayers = {};
- $.each(options.overlaylayers, function(index, overlaylayerName) {
- overlaylayers[overlaylayerName] = new L.tileLayer.provider(overlaylayerName).addTo(_this.map);
+ return layers;
+ };
+
+ this.addOverlays = function() {
+ let overlays = {};
+
+ $.each(options.overlays, function(index, overlayName) {
+ overlays[overlayName] = new L.tileLayer.provider(overlayName).addTo(_this.map);
});
- if (options.layers.length > 1) {
- L.control.layers(layers, overlaylayers).addTo(map);
- }
+ return overlays;
+ };
- if (options.resizable) {
- //TODO: Fix moving map when resized
- _this.resizable();
- }
+ this.addLayersAndOverlays = function() {
+ let layers = this.addLayers();
+ let overlays = this.addOverlays();
- if (!options.locations) {
- options.locations = [];
+ if (options.layers.length > 1 || options.overlays.length > 0) {
+ L.control.layers(layers, overlays).addTo(this.map);
}
+ };
- // Add the markers.
- for (var i = options.locations.length - 1; i >= 0; i--) {
- this.addMarker(options.locations[i]);
+ this.bindAjaxEvents = function() {
+ if ( !options.ajaxquery || !options.ajaxcoordproperty ) {
+ return;
}
- // Add markercluster
- if (options.markercluster) {
- this.createMarkerCluster();
- }
+ let ajaxRequest = null;
- // Add lines
- if (options.lines) {
- for (var i = 0; i < options.lines.length; i++) {
- this.addLine(options.lines[i]);
- }
- }
+ this.map.on( 'dragend zoomend', function() {
+ let bounds = _this.map.getBounds();
- // Add polygons
- if (options.polygons) {
- for (var i = 0; i < options.polygons.length; i++) {
- this.addPolygon(options.polygons[i]);
- }
- }
+ let query = sm.buildQueryString(
+ decodeURIComponent( options.ajaxquery.replace( /\+/g, ' ' ) ),
+ options.ajaxcoordproperty,
+ bounds.getNorthEast().lat,
+ bounds.getNorthEast().lng,
+ bounds.getSouthWest().lat,
+ bounds.getSouthWest().lng
+ );
- // Add circles
- if (options.circles) {
- for (var i = 0; i < options.circles.length; i++) {
- this.addCircle(options.circles[i]);
+ if( ajaxRequest !== null ) {
+ ajaxRequest.abort();
}
+
+ ajaxRequest = sm.ajaxUpdateMarker( _this, query, options.icon ).done( function() {
+ ajaxRequest = null;
+ } );
+ } );
+ };
+
+ this.centerAndZoomMap = function() {
+ this.map.fitWorld();
+ this.fitContent();
+
+ if (options.zoom !== false) {
+ this.map.setZoom(options.zoom);
}
- // Add rectangles
- if (options.rectangles) {
- for (var i = 0; i < options.rectangles.length; i++) {
- this.addRectangle(options.rectangles[i]);
- }
+ if (options.centre !== false) {
+ this.map.setView(
+ new L.LatLng(options.centre.lat, options.centre.lon),
+ this.map.getZoom()
+ );
}
+ };
- this.addGeoJson(options);
-
- // Set map position (centre and zoom)
- var centre;
- if (options.centre === false) {
- switch ( this.points.length ) {
- case 0:
- centre = new L.LatLng(0, 0);
- break;
- case 1:
- centre = this.points[0];
- break;
- default:
- var bounds = new L.LatLngBounds( this.points );
- if (options.zoom === false) {
- map.fitBounds( bounds );
- centre = false;
- } else {
- centre = bounds.getCenter();
- }
- break;
+ this.fitContent = function() {
+ let bounds = this.mapContent.getBounds();
+
+ if (bounds.isValid()) {
+ if (bounds.getNorthEast().equals(bounds.getSouthWest())) {
+ this.map.setView(
+ bounds.getCenter(),
+ options.defzoom
+ );
+ }
+ else {
+ this.map.fitBounds(bounds);
}
- this.points = [];
- } else {
- centre = new L.LatLng(options.centre.lat, options.centre.lon);
- }
- if(centre) {
- map.setView( centre, options.zoom !== false ? options.zoom : options.defzoom );
}
};
this.getDependencies = function ( options ) {
var dependencies = [];
- if (options.layers !== ['MapQuestOpen'] || options.overlaylayers.length > 0) {
- dependencies.push( 'ext.maps.leaflet.providers' );
+
+ if (this.shouldLoadEditorJs()) {
+ dependencies.push( 'ext.maps.leaflet.editor' );
}
- if (options.enablefullscreen) {
+
+ if (options.fullscreen) {
dependencies.push( 'ext.maps.leaflet.fullscreen' );
}
+
if (options.resizable) {
dependencies.push( 'ext.maps.resizable' );
}
- if (options.markercluster) {
+
+ if (options.cluster) {
dependencies.push( 'ext.maps.leaflet.markercluster' );
}
+
return dependencies;
};
@@ -429,6 +327,5 @@
} );
return this;
-
};
-})(jQuery, window.mediaWiki, L, window.MQ);
+})(window.jQuery, window.mediaWiki, window.L, window.maps, window.sm);