| Current File : /home/jvzmxxx/wiki/extensions/Maps/includes/services/OpenLayers/jquery.openlayers.js |
/**
* JavaSript for OpenLayers maps in the Maps extension.
* @see http://www.mediawiki.org/wiki/Extension:Maps
*
* @author Jeroen De Dauw <jeroendedauw at gmail dot com>
* @author Daniel Werner
* @author Peter Grassberger < petertheone@gmail.com >
*
* @todo This whole JS is very blown up and could use some quality refactoring.
*/
(function ($, mw, OpenLayers) {
$.fn.openlayers = function (mapElementId, options) {
this.map = null;
this.options = options;
this.bounds = null;
OpenLayers._getScriptLocation = function() {
return mw.config.get('wgScriptPath') + '/extensions/Maps/includes/services/OpenLayers/OpenLayers/';
};
this.getOLMarker = function (markerLayer, markerData) {
var marker;
if (markerData.hasOwnProperty('icon') && markerData.icon !== "") {
marker = new OpenLayers.Marker(markerData.lonlat, new OpenLayers.Icon(markerData.icon));
} else {
marker = new OpenLayers.Marker(markerData.lonlat, new OpenLayers.Icon(markerLayer.defaultIcon));
}
// This is the handler for the mousedown/touchstart event on the marker, and displays the popup.
function handleClickEvent(evt) {
if (markerData.link) {
window.location.href = markerData.link;
} else if (markerData.text !== '') {
var popup = new OpenLayers.Feature(markerLayer, markerData.lonlat).createPopup(true);
popup.setContentHTML(markerData.text);
markerLayer.map.addPopup(popup);
OpenLayers.Event.stop(evt); // Stop the event.
}
if (markerData.visitedicon && markerData.visitedicon !== '') {
if(markerData.visitedicon === 'on'){
//when keyword 'on' is set, set visitedicon to a default official marker
markerData.visitedicon = mw.config.get('wgScriptPath')+'/extensions/Maps/includes/services/OpenLayers/OpenLayers/img/marker3.png';
}
marker.setUrl(markerData.visitedicon);
markerData.visitedicon = undefined;
}
}
marker.events.register('mousedown', marker, handleClickEvent);
marker.events.register('touchstart', marker, handleClickEvent);
return marker;
};
this.addMarkers = function (map, options) {
if (!options.locations) {
options.locations = [];
}
var locations = options.locations;
if (locations.length > 1 && ( options.centre === false || options.zoom === false )) {
this.bounds = new OpenLayers.Bounds();
}
this.groupLayers = new Object();
this.groups = 0;
for (var i = locations.length - 1; i >= 0; i--) {
this.addMarker( locations[i] );
}
if (this.bounds != null) map.zoomToExtent(this.bounds); // If a bounds object has been created, use it to set the zoom and center.
};
this.addMarker = function (markerData) {
markerData.group = !markerData.hasOwnProperty('group') ? '' : markerData.group;
// Create a own marker-layer for the marker group:
if (!this.groupLayers[ markerData.group ]) {
// in case no group is specified, use default marker layer:
var layerName = markerData.group != '' ? markerData.group : mw.msg('maps-markers');
var curLayer = new OpenLayers.Layer.Markers(layerName);
this.groups++;
curLayer.id = 'markerLayer' + this.groups;
// define default icon, one of ten in different colors, if more than ten layers, colors will repeat:
curLayer.defaultIcon = mw.config.get( 'egMapsScriptPath' ) + '/includes/services/OpenLayers/OpenLayers/img/marker' + ( ( this.groups + 10 ) % 10 ) + '.png';
map.addLayer(curLayer);
this.groupLayers[ markerData.group ] = curLayer;
} else {
// if markers of this group exist already, they have an own layer already
var curLayer = this.groupLayers[ markerData.group ];
}
markerData.lonlat = new OpenLayers.LonLat(markerData.lon, markerData.lat);
if (!hasImageLayer) {
markerData.lonlat.transform(new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913"));
}
if (this.bounds != null) this.bounds.extend(markerData.lonlat); // Extend the bounds when no center is set.
var marker = this.getOLMarker(curLayer, markerData);
this.markers.push({
target:marker,
data:markerData
});
curLayer.addMarker(marker); // Create and add the marker.
};
this.removeMarkers = function () {
var map = this.map;
$.each(this.groupLayers, function(index, layer) {
map.removeLayer(layer);
});
this.groupLayers = new Object();
this.groups = 0;
this.markers = [];
};
this.addControls = function (map, controls, mapElement) {
// Add the controls.
for (var i = controls.length - 1; i >= 0; i--) {
// If a string is provided, find the correct name for the control, and use eval to create the object itself.
if (typeof controls[i] == 'string') {
if (controls[i].toLowerCase() == 'autopanzoom') {
if (mapElement.offsetHeight > 140) controls[i] = mapElement.offsetHeight > 320 ? 'panzoombar' : 'panzoom';
}
control = getValidControlName(controls[i]);
if (control) {
map.addControl(eval('new OpenLayers.Control.' + control + '() '));
}
}
else {
map.addControl(controls[i]); // If a control is provided, instead a string, just add it.
controls[i].activate(); // And activate it.
}
}
map.addControl(new OpenLayers.Control.Attribution());
map.addControl(new OpenLayers.Control.MousePosition({
formatOutput: function(lonLat) {
var digits = parseInt(this.numDigits);
var newHtml =
this.prefix +
lonLat.lat.toFixed(digits) +
this.separator +
lonLat.lon.toFixed(digits) +
this.suffix;
return newHtml;
}
}));
};
this.addLine = function (properties) {
var pos = [];
for (var x = 0; x < properties.pos.length; x++) {
var point = new OpenLayers.Geometry.Point(properties.pos[x].lon, properties.pos[x].lat);
point.transform(
new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984
map.getProjectionObject() // to Spherical Mercator Projection
);
pos.push(point);
}
var style = {
'strokeColor':properties.strokeColor,
'strokeWidth':properties.strokeWeight,
'strokeOpacity':properties.strokeOpacity
};
var line = new OpenLayers.Geometry.LineString(pos);
var lineFeature = new OpenLayers.Feature.Vector(line, properties, style);
this.lineLayer.addFeatures([lineFeature]);
};
this.addPolygon = function (properties) {
var pos = [];
for (var x = 0; x < properties.pos.length; x++) {
var point = new OpenLayers.Geometry.Point(properties.pos[x].lon, properties.pos[x].lat);
point.transform(
new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984
map.getProjectionObject() // to Spherical Mercator Projection
);
pos.push(point);
}
var style = {
'strokeColor':properties.strokeColor,
'strokeWidth':properties.strokeWeight,
'strokeOpacity':properties.onlyVisibleOnHover === true ? 0 : properties.strokeOpacity,
'fillColor':properties.fillColor,
'fillOpacity':properties.onlyVisibleOnHover === true ? 0 : properties.fillOpacity
};
var polygon = new OpenLayers.Geometry.LinearRing(pos);
var polygonFeature = new OpenLayers.Feature.Vector(polygon, properties, style);
this.polygonLayer.addFeatures([polygonFeature]);
};
this.addCircle = function (properties) {
var style = {
'strokeColor':properties.strokeColor,
'strokeWidth':properties.strokeWeight,
'strokeOpacity':properties.onlyVisibleOnHover === true ? 0 : properties.strokeOpacity,
'fillColor':properties.fillColor,
'fillOpacity':properties.onlyVisibleOnHover === true ? 0 : properties.fillOpacity
};
var point = new OpenLayers.Geometry.Point(properties.centre.lon, properties.centre.lat);
point.transform(
new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984
map.getProjectionObject() // to Spherical Mercator Projection
);
var circle = OpenLayers.Geometry.Polygon.createRegularPolygon(
point,
properties.radius,
30
);
var circleFeature = new OpenLayers.Feature.Vector(circle, properties, style);
this.circleLayer.addFeatures([circleFeature])
};
this.addRectangle = function (properties) {
var style = {
'strokeColor':properties.strokeColor,
'strokeWidth':properties.strokeWeight,
'strokeOpacity':properties.onlyVisibleOnHover === true ? 0 : properties.strokeOpacity,
'fillColor':properties.fillColor,
'fillOpacity':properties.onlyVisibleOnHover === true ? 0 : properties.fillOpacity
};
var point1 = new OpenLayers.Geometry.Point(properties.ne.lon, properties.ne.lat);
var point2 = new OpenLayers.Geometry.Point(properties.sw.lon, properties.sw.lat);
point1.transform(
new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984
map.getProjectionObject() // to Spherical Mercator Projection
);
point2.transform(
new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984
map.getProjectionObject() // to Spherical Mercator Projection
);
var bounds = new OpenLayers.Bounds();
bounds.extend(point1);
bounds.extend(point2);
var rectangle = bounds.toGeometry();
var rectangleFeature = new OpenLayers.Feature.Vector(rectangle, properties, style);
this.rectangleLayer.addFeatures([rectangleFeature])
};
/**
* Gets a valid control name (with excat lower and upper case letters),
* or returns false when the control is not allowed.
*/
function getValidControlName(control) {
var OLControls = [
'ArgParser', 'Attribution', 'Button', 'DragFeature', 'DragPan',
'DrawFeature', 'EditingToolbar', 'GetFeature', 'KeyboardDefaults', 'LayerSwitcher',
'Measure', 'ModifyFeature', 'MouseDefaults', 'MouseToolbar',
'Navigation', 'NavigationHistory', 'NavToolbar', 'OverviewMap', 'Pan',
'Panel', 'PanPanel', 'PanZoom', 'PanZoomBar', 'Permalink',
'Scale', 'ScaleLine', 'SelectFeature', 'Snapping', 'Split',
'WMSGetFeatureInfo', 'ZoomBox', 'ZoomIn', 'ZoomOut', 'ZoomPanel',
'ZoomToMaxExtent'
];
for (var i = OLControls.length - 1; i >= 0; i--) {
if (control == OLControls[i].toLowerCase()) {
return OLControls[i];
}
}
return false;
}
var _this = this;
this.markers = [];
// Remove the loading map message.
this.text('');
// Create a new OpenLayers map with without any controls on it.
var mapOptions = {
controls:[]
};
// Remove the loading map message.
this.text( '' );
/**
* ToDo: That layers being created by 'eval' will deny us the possibility to
* set certain options. It's possible to set properties of course but they will
* show no effect since they are not passed as options to the constructor.
* With this working we could adjust max/minScale to display overlays independent
* from the specified values in the layer which only make sense if the layer is
* displayed as base layer. On the other hand, it might be intended overlay
* layers are only seen at a certain zoom level.
*/
// collect all layers and check for custom image layer:
var hasImageLayer = false;
var layers = [];
// evaluate base layers:
for( i = 0, n = options.layers.length; i < n; i++ ) {
layer = eval( options.layers[i] );
layer.isBaseLayer = true;
// Ideally this would check if the object is of type OpenLayers.layer.image
if( layer.isImage === true ) {
hasImageLayer = true;
layer.transitionEffect = 'resize'; // makes transition smoother
}
layers.push( layer );
}
// Create KML layer and push it to layers
if (options.kml.length>0) {
var kmllayer = new OpenLayers.Layer.Vector("KML Layer", {
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP({
url: options.kml,
format: new OpenLayers.Format.KML({
extractStyles: true,
extractAttributes: true,
maxDepth: 2,
'internalProjection': new OpenLayers.Projection( "EPSG:900913" ), //EPSG:3785/900913
'externalProjection': new OpenLayers.Projection( "EPSG:4326" ) //EPSG:4326
})
})
});
layers.push( kmllayer );
}
// Create a new OpenLayers map with without any controls on it.
var mapOptions = {
controls: []
};
//mapOptions.units = "m";
if ( !hasImageLayer ) {
mapOptions.projection = new OpenLayers.Projection( "EPSG:900913" );
mapOptions.displayProjection = new OpenLayers.Projection( "EPSG:4326" );
mapOptions.units = "m";
mapOptions.numZoomLevels = 18;
mapOptions.maxResolution = 156543.0339;
mapOptions.maxExtent = new OpenLayers.Bounds( -20037508, -20037508, 20037508, 20037508 );
}
this.map = new OpenLayers.Map(mapElementId, mapOptions);
var map = this.map;
if (!options['static']) {
this.addControls(map, options.controls, this.get(0));
}
map.addLayers( layers ); // Add the base layers
//Add markers
this.addMarkers( map, options );
var centre = false;
if ( options.centre === false ) {
if ( options.locations.length == 1 ) {
centre = new OpenLayers.LonLat( options.locations[0].lon, options.locations[0].lat );
}
else if ( options.locations.length == 0 ) {
centre = new OpenLayers.LonLat( 0, 0 );
}
} else { // When the center is provided, set it.
centre = new OpenLayers.LonLat( options.centre.lon, options.centre.lat );
}
if( centre !== false ) {
if ( !hasImageLayer ) {
centre.transform(
new OpenLayers.Projection( "EPSG:4326" ),
new OpenLayers.Projection( "EPSG:900913" )
);
map.setCenter( centre );
} else {
map.zoomToMaxExtent();
}
}
if ( options.zoom !== false ) {
map.zoomTo( options.zoom );
}
if ( options.resizable ) {
mw.loader.using( 'ext.maps.resizable', function() {
_this.resizable();
} );
}
//ugly hack to allow for min/max zoom
if (options.maxzoom !== false && options.maxzoom !== undefined ||
options.minzoom !== false && options.minzoom !== undefined) {
if(options.maxzoom === false){
options.maxzoom = mapOptions.numZoomLevels;
}
map.getNumZoomLevels = function () {
var zoomLevels = 1;
zoomLevels += options.maxzoom !== false ? options.maxzoom : 0;
zoomLevels -= options.minzoom !== false ? options.minzoom : 0;
return zoomLevels;
};
map.isValidZoomLevel = function (zoomLevel) {
var valid = ( (zoomLevel != null) &&
(zoomLevel >= options.minzoom) &&
(zoomLevel <= options.maxzoom) );
if (!valid && map.getZoom() == 0) {
var maxzoom = options.maxzoom !== false ? options.maxzoom : 0;
var minzoom = options.minzoom !== false ? options.minzoom : 0;
var zoom = Math.round(maxzoom - (maxzoom - minzoom) / 2);
map.zoomTo(zoom);
}
return valid;
}
}
//Add line layer if applicable
if (options.lines && options.lines.length > 0) {
this.lineLayer = new OpenLayers.Layer.Vector("Line Layer");
var controls = {
select:new OpenLayers.Control.SelectFeature(this.lineLayer, {
clickout:true, toggle:false,
multiple:true, hover:true,
callbacks:{
'click':function (feature) {
openBubbleOrLink(feature.attributes);
}
}
})
};
for (var key in controls) {
var control = controls[key];
map.addControl(control);
control.activate();
}
map.addLayer(this.lineLayer);
map.raiseLayer(this.lineLayer, -1);
map.resetLayersZIndex();
for (var i = 0; i < options.lines.length; i++) {
this.addLine(options.lines[i]);
}
}
if (options.polygons && options.polygons.length > 0) {
this.polygonLayer = new OpenLayers.Layer.Vector("Polygon Layer");
var controls = {
select:new OpenLayers.Control.SelectFeature(this.polygonLayer, {
clickout:true, toggle:false,
multiple:true, hover:true,
callbacks:{
'over':function (feature) {
if (feature.attributes.onlyVisibleOnHover === true) {
var style = {
'strokeColor':feature.attributes.strokeColor,
'strokeWidth':feature.attributes.strokeWeight,
'strokeOpacity':feature.attributes.strokeOpacity,
'fillColor':feature.attributes.fillColor,
'fillOpacity':feature.attributes.fillOpacity
};
_this.polygonLayer.drawFeature(feature, style);
}
},
'out':function (feature) {
if (feature.attributes.onlyVisibleOnHover === true && _this.map.popups.length === 0) {
var style = {
'strokeColor':feature.attributes.strokeColor,
'strokeWidth':feature.attributes.strokeWeight,
'strokeOpacity':0,
'fillColor':feature.attributes.fillColor,
'fillOpacity':0
};
_this.polygonLayer.drawFeature(feature, style);
}
},
'click':function (feature) {
openBubbleOrLink(feature.attributes);
}
}
})
};
for (var key in controls) {
var control = controls[key];
map.addControl(control);
control.activate();
}
map.addLayer(this.polygonLayer);
map.raiseLayer(this.polygonLayer, -1);
map.resetLayersZIndex();
for (var i = 0; i < options.polygons.length; i++) {
this.addPolygon(options.polygons[i]);
}
}
if (options.circles && options.circles.length > 0) {
this.circleLayer = new OpenLayers.Layer.Vector("Circle Layer");
var controls = {
select:new OpenLayers.Control.SelectFeature(this.circleLayer, {
clickout:true, toggle:false,
multiple:true, hover:true,
callbacks:{
'click':function (feature) {
openBubbleOrLink(feature.attributes);
}
}
})
};
for (key in controls) {
var control = controls[key];
map.addControl(control);
control.activate();
}
map.addLayer(this.circleLayer);
map.raiseLayer(this.circleLayer, -1);
map.resetLayersZIndex();
for (var i = 0; i < options.circles.length; i++) {
this.addCircle(options.circles[i]);
}
}
if (options.rectangles && options.rectangles.length > 0) {
this.rectangleLayer = new OpenLayers.Layer.Vector("Rectangle Layer");
var controls = {
select:new OpenLayers.Control.SelectFeature(this.rectangleLayer, {
clickout:true, toggle:false,
multiple:true, hover:true,
callbacks:{
'click':function (feature) {
openBubbleOrLink(feature.attributes);
}
}
})
};
for (var key in controls) {
var control = controls[key];
map.addControl(control);
control.activate();
}
map.addLayer(this.rectangleLayer);
map.raiseLayer(this.rectangleLayer, -1);
map.resetLayersZIndex();
for (var i = 0; i < options.rectangles.length; i++) {
this.addRectangle(options.rectangles[i]);
}
}
if (options.zoom !== false) {
map.zoomTo(options.zoom);
}
if (options.copycoords) {
map.div.oncontextmenu = function () {
return false;
};
OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, {
defaultHandlerOptions:{
'single':true,
'double':false,
'pixelTolerance':0,
'stopSingle':false,
'stopDouble':false
},
handleRightClicks:true,
initialize:function (options) {
this.handlerOptions = OpenLayers.Util.extend(
{}, this.defaultHandlerOptions
);
OpenLayers.Control.prototype.initialize.apply(
this, arguments
);
this.handler = new OpenLayers.Handler.Click(
this, this.eventMethods, this.handlerOptions
);
}
});
var click = new OpenLayers.Control.Click({
eventMethods:{
'rightclick':function (e) {
var lonlat = map.getLonLatFromViewPortPx(e.xy);
if (!hasImageLayer) {
lonlat = lonlat.transform(new OpenLayers.Projection("EPSG:900913"), new OpenLayers.Projection("EPSG:4326"));
}
prompt(mw.msg('maps-copycoords-prompt'), lonlat.lat + ',' + lonlat.lon);
}
}
});
map.addControl(click);
click.activate();
}
if (options.searchmarkers) {
OpenLayers.Control.SearchField = OpenLayers.Class(OpenLayers.Control, {
draw:function (px) {
OpenLayers.Control.prototype.draw.apply(this, arguments);
var searchBoxValue = mw.msg('maps-searchmarkers-text');
var searchBoxContainer = document.createElement('div');
this.div.style.top = "5px";
this.div.style.right = "5px";
var searchBox = $('<input type="text" value="' + searchBoxValue + '" />');
searchBox.appendTo(searchBoxContainer);
searchBox.on('keyup',function (e) {
for (var i = 0; i < _this.markers.length; i++) {
var haystack = '';
var marker = _this.markers[i];
if (options.searchmarkers == 'title') {
haystack = marker.data.title;
} else if (options.searchmarkers == 'all') {
haystack = marker.data.title + $(marker.data.text).text();
}
marker.target.display(haystack.toLowerCase().indexOf(e.target.value.toLowerCase()) != -1);
}
}).on('focusin',function () {
if ($(this).val() === searchBoxValue) {
$(this).val('');
}
}).on('focusout', function () {
if ($(this).val() === '') {
$(this).val(searchBoxValue);
}
});
this.div.appendChild(searchBoxContainer);
return this.div;
}
});
var searchBox = new OpenLayers.Control.SearchField();
map.addControl(searchBox);
}
if (options.wmsoverlay) {
var layer = new OpenLayers.Layer.WMS( "WMSLayer", options.wmsoverlay.wmsServerUrl, { layers: options.wmsoverlay.wmsLayerName });
map.addLayer(layer);
map.setBaseLayer(layer);
}
function openBubbleOrLink(properties) {
if (properties.link) {
window.location.href = properties.link;
} else if (properties.text !== '') {
openBubble(properties);
}
}
function openBubble(properties) {
var mousePos = map.getControlsByClass("OpenLayers.Control.MousePosition")[0].lastXy;
var lonlat = map.getLonLatFromPixel(mousePos);
var popup = new OpenLayers.Popup(null, lonlat, null, properties.text, true, function () {
map.getControlsByClass('OpenLayers.Control.SelectFeature')[0].unselectAll();
map.removePopup(this);
});
_this.map.addPopup(popup);
}
return this;
};
})(jQuery, window.mediaWiki, OpenLayers);