| Current File : /home/jvzmxxx/wiki/extensions/Maps/includes/services/GoogleMaps3/jquery.googlemap.js |
/**
* JavaScript for Google Maps v3 maps in the Maps extension.
* @see http://www.mediawiki.org/wiki/Extension:Maps
*
* @author Jeroen De Dauw <jeroendedauw at gmail dot com>
* @author Peter Grassberger < petertheone@gmail.com >
*/
(function ($, mw) {
$.fn.googlemaps = function (options) {
var _this = this;
this.map = null;
this.markercluster = null;
this.options = options;
/**
* All markers that are currently on the map.
* @type {Array}
* @private
*/
this.markers = [];
/**
* All Polylines currently on the map,
* @type {Array}
* @private
*/
this.lines = [];
/**
* All polygons currently on the map,
*/
this.polygons = [];
/**
* All circles on the map
*/
this.circles = [];
/**
* All rectangles on the map
*/
this.rectangles = [];
/**
* All image overlays on the map
*/
this.imageoverlays = [];
var getBounds = function() {
if (( options.centre === false || options.zoom === false ) && options.locations.length > 1) {
var bounds = new google.maps.LatLngBounds();
for (var i = _this.markers.length - 1; i >= 0; i--) {
bounds.extend(_this.markers[i].getPosition());
}
return bounds;
}
return null;
};
var setZoom = function(bounds) {
if (options.zoom === false) {
_this.map.fitBounds(bounds);
}
else {
_this.map.setZoom(options.zoom);
}
};
/**
* Creates a new marker with the provided data,
* adds it to the map, and returns it.
* @param {Object} markerData Contains the fields lat, lon, title, text and icon
* @return {google.maps.Marker}
*/
this.addMarker = function (markerData) {
var markerOptions = {
position:new google.maps.LatLng(markerData.lat, markerData.lon),
title:markerData.title,
text:$(markerData.text).text(),
labelContent:markerData.inlineLabel,
labelAnchor:new google.maps.Point(-15, 34),
labelClass:'markerwithlabel'
};
if (!markerData.hasOwnProperty('icon') || markerData.icon !== '') {
markerOptions.icon = markerData.icon;
}
if (markerData.visitedicon !== '') {
if(markerData.visitedicon === 'on'){
//when keyword 'on' is set, set visitedicon to a default official marker
markerOptions.visitedicon = mw.config.get('wgScriptPath')+'/extensions/Maps/includes/services/GoogleMaps3/img/blue-dot.png';
}else{
markerOptions.visitedicon = markerData.visitedicon;
}
}
var addToMapAndHandlers = function( marker ) {
//Add onclick listener
google.maps.event.addListener(marker, 'click', function (e) {
if (e.target !== undefined && (e.target instanceof HTMLAnchorElement || e.target.tagName == 'A')) {
//click link defined in inlinelabel
window.location.href = e.target.href;
} else {
openBubbleOrLink.call(this, markerData, e, marker);
}
if (markerOptions.visitedicon) {
marker.setIcon(markerOptions.visitedicon);
markerOptions.visitedicon = undefined;
}
});
marker.setMap( _this.map );
_this.markers.push( marker );
return marker;
};
var marker;
if (markerData.inlineLabel === undefined || markerData.inlineLabel === null || markerData.inlineLabel.length == 0) {
marker = new google.maps.Marker( markerOptions );
return addToMapAndHandlers( marker );
} else {
mw.loader.using(
'ext.maps.gm3.markerwithlabel',
function() {
marker = new MarkerWithLabel( markerOptions );
addToMapAndHandlers( marker );
setZoom(getBounds());
}
);
}
};
/**
* Removes a single marker from the map.
* @param {google.maps.Marker} marker The marker to remove.
*/
this.removeMarker = function (marker) {
marker.setMap(null);
for (var i = this.markers.length - 1; i >= 0; i--) {
if (this.markers[i] === marker) {
delete this.markers[i];
break;
}
}
delete marker;
};
/**
* Removes all markers from the map.
*/
this.removeMarkers = function () {
if (this.markercluster) {
this.markercluster.setMap(null);
this.markercluster = null;
}
for (var i = this.markers.length - 1; i >= 0; i--) {
this.markers[i].setMap(null);
}
this.markers = [];
};
/**
* Remove the "earth" type from options.types if it's present.
*
* @since 1.0.1
*/
this.removeEarthType = function () {
if (Array.prototype.filter) {
options.types = options.types.filter(function (element, index, array) {
return element !== 'earth';
});
}
else {
// Seems someone is using the o-so-awesome browser that is IE.
var types = [];
for (i in options.types) {
if (typeof( options.types[i] ) !== 'function' && options.types[i] !== 'earth') {
types.push(options.types[i]);
}
}
options.types = types;
}
};
this.addOverlays = function () {
// Add the Google KML/KMZ layers.
for (i = options.gkml.length - 1; i >= 0; i--) {
var kmlLayer = new google.maps.KmlLayer(
options.gkml[i],
{
map:this.map,
preserveViewport:!options.kmlrezoom
}
);
}
// If there are any non-Google KML/KMZ layers, load the geoxml library and use it to add these layers.
if (options.kml.length != 0) {
mw.loader.using('ext.maps.gm3.geoxml', function () {
function addToCopyCoords(doc){
if(options.copycoords){
for(var i = 0; i < doc.length; i++){
addCopyCoordsOnRightClick([
doc[i].gpolygons,
doc[i].gpolylines,
doc[i].ggroundoverlays
]);
}
}
}
var geoXml = new geoXML3.parser({
map:_this.map,
zoom:options.kmlrezoom,
failedParse:function(){
alert(mw.msg('maps-kml-parsing-failed'));
}
});
geoXml.options.afterParse = function(docs){
//add toggle functionality
var toggleDiv = document.createElement('div');
toggleDiv.style.backgroundColor = 'white';
toggleDiv.style.marginTop = '5px';
toggleDiv.style.padding = '5px';
toggleDiv.style.border = '1px solid grey';
for(var i = docs.length-1; i >= 0; i--){
(function(doc){
var label = document.createElement('label');
label.style.display = 'block';
var text = document.createTextNode(doc.baseUrl.substring(doc.baseDir.length));
var checkbox = document.createElement('input');
checkbox.setAttribute('type','checkbox');
checkbox.style.verticalAlign = '-0.2em';
checkbox.checked = true;
checkbox.onclick = function(){
if(this.checked){
geoXml.showDocument(doc);
}else{
geoXml.hideDocument(doc);
}
};
label.appendChild(checkbox);
label.appendChild(text);
toggleDiv.appendChild(label);
})(docs[i]);
}
_this.map.controls[google.maps.ControlPosition.TOP_RIGHT].push(toggleDiv);
};
geoXml.parse(options.kml);
});
}
};
this.addLine = function (properties) {
var paths = new google.maps.MVCArray();
for (var x = 0; x < properties.pos.length; x++) {
paths.push(new google.maps.LatLng(properties.pos[x].lat, properties.pos[x].lon));
}
var line = new google.maps.Polyline({
map:this.map,
path:paths,
strokeColor:properties.strokeColor,
strokeOpacity:properties.strokeOpacity,
strokeWeight:properties.strokeWeight
});
this.lines.push(line);
google.maps.event.addListener(line, "click", function (event) {
openBubbleOrLink.call(this, properties, event, line);
});
};
this.removeLine = function (line) {
line.setMap(null);
for (var i = this.line.length - 1; i >= 0; i--) {
if (this.line[i] === line) {
delete this.line[i];
break;
}
}
delete line;
};
this.removeLines = function () {
for (var i = this.lines.length - 1; i >= 0; i--) {
this.lines[i].setMap(null);
}
this.lines = [];
};
this.addPolygon = function (properties) {
var paths = new google.maps.MVCArray();
for (var x = 0; x < properties.pos.length; x++) {
paths.push(new google.maps.LatLng(properties.pos[x].lat, properties.pos[x].lon));
}
var polygon = new google.maps.Polygon({
map:this.map,
path:paths,
strokeColor:properties.strokeColor,
strokeOpacity:properties.strokeOpacity,
strokeWeight:properties.strokeWeight,
fillColor:properties.fillColor,
fillOpacity:properties.fillOpacity
});
this.polygons.push(polygon);
//add hover event/effect
if (properties.onlyVisibleOnHover === true) {
function hidePolygon(polygon) {
polygon.setOptions({
fillOpacity:0,
strokeOpacity:0
});
}
hidePolygon(polygon);
google.maps.event.addListener(polygon, "mouseover", function () {
this.setOptions({
fillOpacity:properties.fillOpacity,
strokeOpacity:properties.strokeOpacity
});
});
google.maps.event.addListener(polygon, "mouseout", function () {
hidePolygon(this);
});
}
//add click event
google.maps.event.addListener(polygon, "click", function (event) {
openBubbleOrLink.call(this, properties, event, polygon);
});
};
this.addCircle = function (properties) {
var circle = new google.maps.Circle({
map:this.map,
center:new google.maps.LatLng(properties.centre.lat, properties.centre.lon),
radius:properties.radius,
fillColor:properties.fillColor,
fillOpacity:properties.fillOpacity,
strokeColor:properties.strokeColor,
strokeOpacity:properties.strokeOpacity,
strokeWeight:properties.strokeWeight
});
this.circles.push(circle);
//add click event
google.maps.event.addListener(circle, "click", function (event) {
openBubbleOrLink.call(this, properties, event, circle);
});
};
this.addRectangle = function (properties) {
var rectangle = new google.maps.Rectangle({
map:this.map,
bounds:new google.maps.LatLngBounds(
new google.maps.LatLng(properties.sw.lat, properties.sw.lon), //sw
new google.maps.LatLng(properties.ne.lat, properties.ne.lon) //ne
),
fillColor:properties.fillColor,
fillOpacity:properties.fillOpacity,
strokeColor:properties.strokeColor,
strokeOpacity:properties.strokeOpacity,
strokeWeight:properties.strokeWeight
})
this.rectangles.push(rectangle);
//add click event
google.maps.event.addListener(rectangle, "click", function (event) {
openBubbleOrLink.call(this, properties, event, rectangle);
});
};
this.addImageOverlay = function(properties){
var imageBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(properties.sw.lat,properties.sw.lon),
new google.maps.LatLng(properties.ne.lat,properties.ne.lon)
);
var image = new google.maps.GroundOverlay(properties.image,imageBounds);
image.setMap(this.map);
this.imageoverlays.push(image);
//add click event
google.maps.event.addListener(image, "click", function (event) {
openBubbleOrLink.call(this, properties, event, image);
});
};
this.removePolygon = function (polygon) {
polygon.setMap(null);
for (var i = this.polygon.length - 1; i >= 0; i--) {
if (this.polygon[i] === polygon) {
delete this.polygon[i];
break;
}
}
delete polygon;
};
this.removePolygons = function () {
for (var i = this.polygon.length - 1; i >= 0; i--) {
this.polygon[i].setMap(null);
}
this.polygon = [];
};
//Rezoom's the map to show all visible markers.
this.reZoom = function(){
var bounds = new google.maps.LatLngBounds();
for(var x = 0; x < this.markers.length; x++){
var marker = this.markers[x];
if (marker.getVisible() === true) {
bounds.extend(marker.getPosition());
}
}
this.map.fitBounds(bounds);
};
this.createMarkerCluster = function() {
if ( !options.markercluster ) {
return;
}
if (this.markercluster) {
this.markercluster.setMap(null);
this.markercluster = null;
}
this.markercluster = new MarkerClusterer( this.map, this.markers, {
imagePath: mw.config.get( 'wgScriptPath' ) +
'/extensions/Maps/includes/images/m',
gridSize: this.options.clustergridsize,
maxZoom: this.options.clustermaxzoom,
zoomOnClick: this.options.clusterzoomonclick,
averageCenter: this.options.clusteraveragecenter,
minimumClusterSize: this.options.clusterminsize
} );
};
this.initializeMap = function () {
var mapOptions = {
disableDefaultUI:true,
mapTypeId:options.type == 'earth' ? google.maps.MapTypeId.SATELLITE : eval('google.maps.MapTypeId.' + options.type)
};
// Map controls
mapOptions.panControl = $.inArray('pan', options.controls) != -1;
mapOptions.zoomControl = $.inArray('zoom', options.controls) != -1;
mapOptions.mapTypeControl = $.inArray('type', options.controls) != -1;
mapOptions.scaleControl = $.inArray('scale', options.controls) != -1;
mapOptions.streetViewControl = $.inArray('streetview', options.controls) != -1;
mapOptions.rotateControl = $.inArray('rotate', options.controls) != -1;
for (i in options.types) {
if (typeof( options.types[i] ) !== 'function') {
options.types[i] = eval('google.maps.MapTypeId.' + options.types[i].toUpperCase() );
}
}
// Map control styles
mapOptions.zoomControlOptions = { style:eval('google.maps.ZoomControlStyle.' + options.zoomstyle) };
mapOptions.mapTypeControlOptions = {
style:eval('google.maps.MapTypeControlStyle.' + options.typestyle),
mapTypeIds:options.types
};
//max/min -zoom
mapOptions.maxZoom = options.maxzoom === false ? null : options.maxzoom;
mapOptions.minZoom = options.minzoom === false ? null : options.minzoom;
//static mode
if (options['static']) {
mapOptions.draggable = false;
mapOptions.disableDoubleClickZoom = true;
mapOptions.panControl = false;
mapOptions.rotateControl = false;
mapOptions.zoomControl = false;
mapOptions.scrollwheel = false;
mapOptions.streetViewControl = false;
mapOptions.overviewMapControl = false;
mapOptions.mapTypeControl = false;
}
var map = new google.maps.Map(this.get(0), mapOptions);
google.maps.event.addListenerOnce(map, 'tilesloaded', function () {
_this.addOverlays();
});
this.map = map;
if (options.poi === false) {
map.setOptions({ styles:[
{
featureType:"poi",
stylers:[
{ visibility:"off" }
]
}
] });
}
if (!options.locations) {
options.locations = [];
}
// Add the markers.
for (var i = options.locations.length - 1; i >= 0; i--) {
this.addMarker(options.locations[i]);
}
for (i = options.fusiontables.length - 1; i >= 0; i--) {
var ftLayer = new google.maps.FusionTablesLayer(options.fusiontables[i], { map:map });
}
var layerMapping = {
'traffic':'new google.maps.TrafficLayer()',
'bicycling':'new google.maps.BicyclingLayer()'
};
for (i = options.layers.length - 1; i >= 0; i--) {
var layer = eval(layerMapping[options.layers[i]]);
layer.setMap(map);
}
var bounds = getBounds();
setZoom(bounds);
var centre;
if (options.centre === false) {
if (options.locations.length > 1) {
centre = bounds.getCenter();
}
else if (options.locations.length == 1) {
centre = new google.maps.LatLng(options.locations[0].lat, options.locations[0].lon);
}
else {
centre = new google.maps.LatLng(0, 0);
}
}
else {
centre = new google.maps.LatLng(options.centre.lat, options.centre.lon);
}
map.setCenter(centre);
setTimeout(
function() {
if ( options.autoinfowindows ) {
for ( var i = _this.markers.length - 1; i >= 0; i-- ) {
google.maps.event.trigger( _this.markers[i], 'click', {} );
}
}
},
500 // If we wait a bit, the map will re-position to accommodate for the info windows.
);
if (options.resizable) {
mw.loader.using('ext.maps.resizable', function () {
_this.resizable();
});
}
/**
* used in display_line functionality
* draws paths between markers
*/
if (options.lines) {
for (var i = 0; i < options.lines.length; i++) {
this.addLine(options.lines[i]);
}
}
/**
* used in display_line to draw polygons
*/
if (options.polygons) {
for (var i = 0; i < options.polygons.length; i++) {
this.addPolygon(options.polygons[i]);
}
}
/**
* used in display_line to draw circles
*/
if (options.circles) {
for (var i = 0; i < options.circles.length; i++) {
this.addCircle(options.circles[i]);
}
}
/**
* used in display_line to draw rectangles
*/
if (options.rectangles) {
for (var i = 0; i < options.rectangles.length; i++) {
this.addRectangle(options.rectangles[i]);
}
}
/**
* Allows grouping of markers.
*/
this.createMarkerCluster();
if (options.searchmarkers) {
var searchBoxValue = mw.msg('maps-searchmarkers-text');
var searchBox = $('<input type="text" value="' + searchBoxValue + '" />');
var searchContainer = document.createElement('div');
searchContainer.style.padding = '5px';
searchContainer.index = 1;
searchBox.appendTo(searchContainer);
map.controls[google.maps.ControlPosition.TOP_RIGHT].push(searchContainer);
//prevents markers and other map objects to be placed beneath searchfield
google.maps.event.addListenerOnce(map, 'bounds_changed', function () {
map.panBy(0,-30);
});
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.title;
} else {
haystack = marker.title + marker.text;
}
var visible = haystack.toLowerCase().indexOf(e.target.value.toLowerCase()) != -1;
marker.setVisible(visible);
}
_this.reZoom();
}).on('focusin',function () {
if ($(this).val() === searchBoxValue) {
$(this).val('');
}
}).on('focusout', function () {
if ($(this).val() === '') {
$(this).val(searchBoxValue);
}
});
}
if(options.imageoverlays){
for (var i = 0; i < options.imageoverlays.length; i++) {
this.addImageOverlay(options.imageoverlays[i]);
}
}
if (options.copycoords) {
addCopyCoordsOnRightClick([
this.lines,
this.circles,
this.polygons,
this.markers,
this.rectangles,
this.imageoverlays,
this.map
]);
}
if (options.wmsoverlay) {
var wmsOptions = {
alt: "OpenLayers",
getTileUrl:function (tile, zoom) {
var projection = _this.map.getProjection();
var zpow = Math.pow(2, zoom);
var ul = new google.maps.Point(tile.x * 256.0 / zpow, (tile.y + 1) * 256.0 / zpow);
var lr = new google.maps.Point((tile.x + 1) * 256.0 / zpow, (tile.y) * 256.0 / zpow);
var ulw = projection.fromPointToLatLng(ul);
var lrw = projection.fromPointToLatLng(lr);
//The user will enter the address to the public WMS layer here. The data must be in WGS84
var baseURL = options.wmsoverlay.wmsServerUrl;
//The layer ID. Can be found when using the layers properties tool in ArcMap or from the WMS settings
var layers = options.wmsoverlay.wmsLayerName;
var style = options.wmsoverlay.wmsStyleName;
//With the 1.3.0 version the coordinates are read in LatLon, as opposed to LonLat in previous versions
var bbox = ulw.lat() + "," + ulw.lng() + "," + lrw.lat() + "," + lrw.lng();
//Establish the baseURL. Several elements, including &EXCEPTIONS=INIMAGE and &Service are unique to openLayers addresses.
var url = baseURL + "version=1.3.0&EXCEPTIONS=INIMAGE&Service=WMS" +
"&request=GetMap&Styles=" + encodeURI(style) + "&format=image%2Fjpeg&CRS=EPSG:4326" +
"&width=256&height=256" + "&Layers=" + layers + "&BBOX=" + bbox;
return url;
},
isPng: false,
maxZoom: 17,
minZoom: 1,
name: "OpenLayers",
tileSize: new google.maps.Size(256, 256)
};
//Creating the object to create the ImageMapType that will call the WMS Layer Options.
openlayersWMS = new google.maps.ImageMapType(wmsOptions);
//Layers to appear on Map A. The first string will give the map the map a name in the dropdown and the second object calls the map type
map.mapTypes.set('OpenLayers', openlayersWMS);
map.setMapTypeId('OpenLayers');
}
//Add custom controls
// - Fullscreen
if(options.enablefullscreen){
this.map.controls[google.maps.ControlPosition.TOP_RIGHT].push(new FullscreenControl(this.map));
}
};
this.setup = function () {
var showEarth = $.inArray('earth', options.types) !== -1 || options.type == 'earth';
// If there are any non-Google KML/KMZ layers, load the geoxml library and use it to add these layers.
if (showEarth) {
this.removeEarthType();
$.getScript(
'https://www.google.com/jsapi',
function (data, textStatus) {
google.load('earth', '1', { callback:function () {
mw.loader.using('ext.maps.gm3.earth', function () {
_this.initializeMap();
if (google.earth.isSupported()) {
_this.ge = new GoogleEarth(_this.map);
}
});
} });
}
);
}else{
this.initializeMap();
}
};
function FullscreenControl(map) {
var controlDiv = document.createElement('div');
controlDiv.style.padding = '5px';
controlDiv.index = 1;
var controlUI = document.createElement('div');
controlUI.style.backgroundColor = 'white';
controlUI.style.borderStyle = 'solid';
controlUI.style.borderColor = 'rgba(0, 0, 0, 0.14902)';
controlUI.style.borderWidth = '1px';
controlUI.style.borderRadius = '2px';
controlUI.style.cursor = 'pointer';
controlUI.style.textAlign = 'center';
controlUI.style.boxShadow = 'rgba(0, 0, 0, 0.298039) 0px 1px 4px -1px';
controlUI.style.backgroundClip = 'padding-box';
controlUI.title = mw.msg('maps-fullscreen-button-tooltip');
controlDiv.appendChild(controlUI);
var controlText = document.createElement('div');
controlText.style.fontFamily = 'Roboto, Arial, sans-serif';
controlText.style.fontSize = '11px';
controlText.style.fontWeight = '400';
controlText.style.color = 'rgb(86, 86, 86)';
controlText.style.padding = '1px 6px';
controlText.innerHTML = mw.msg('maps-fullscreen-button');
controlUI.appendChild(controlText);
google.maps.event.addDomListener(controlUI, 'click', function() {
var mapDiv = $(map.getDiv());
if(mapDiv.data('preFullscreenCss') != null){
mapDiv.css(mapDiv.data('preFullscreenCss'));
mapDiv.removeData('preFullscreenCss');
}else{
var fullscreenCss = {
position:'fixed',
top: 0,
left:0,
width:'100%',
height:'100%',
zIndex:10000
};
var oldState = {};
for(var cssProp in fullscreenCss){
oldState[cssProp] = mapDiv.css(cssProp);
}
mapDiv.data('preFullscreenCss',oldState);
mapDiv.css(fullscreenCss);
}
google.maps.event.trigger(map, "resize");
});
return controlDiv;
}
function openBubbleOrLink(properties, event, obj) {
if (properties.link) {
window.location.href = properties.link;
} else if (properties.text !== '') {
openBubble.call(this, properties, event, obj);
}
}
function openBubble( properties, event, obj ) {
if ( this.openWindow !== undefined ) {
this.openWindow.close();
}
this.openWindow = new google.maps.InfoWindow();
this.openWindow.setContent( properties.text );
if ( event.latLng !== undefined ) {
this.openWindow.setPosition( event.latLng );
}
this.openWindow.closeclick = function () {
obj.openWindow = undefined;
};
if ( event.latLng === undefined ) {
this.openWindow.open( _this.map, this );
}
else {
this.openWindow.open( _this.map );
}
}
function addCopyCoordsOnRightClick(object) {
if(object instanceof Array){
for (var x = 0; x < object.length; x++) {
addCopyCoordsOnRightClick(object[x]);
}
}else{
google.maps.event.addListener(object, 'rightclick', function (event) {
prompt(mw.msg('maps-copycoords-prompt'), event.latLng.lat() + ',' + event.latLng.lng());
});
}
}
//Complete path to OpenLayers WMS layer
if (!options.markercluster) {
this.setup();
} else {
mw.loader.using( 'ext.maps.gm3.markercluster', function() {
_this.setup();
} );
}
return this;
};
})(jQuery, window.mediaWiki);