[fusion-commits] r2234 - in branches/fusion-2.2: . layers
layers/Generic layers/MapGuide layers/MapGuide/php
layers/MapServer lib lib/OpenLayers
templates/mapserver/standard text widgets widgets/BufferPanel
widgets/QuickPlot widgets/Search widgets/SelectWithin
widgets/widgetinfo
svn_fusion at osgeo.org
svn_fusion at osgeo.org
Fri Sep 24 14:32:16 EDT 2010
Author: madair
Date: 2010-09-24 18:32:16 +0000 (Fri, 24 Sep 2010)
New Revision: 2234
Added:
branches/fusion-2.2/lib/MapMessage.js
branches/fusion-2.2/lib/proj4js-combined.js
branches/fusion-2.2/widgets/QuickPlot.js
branches/fusion-2.2/widgets/QuickPlot/
branches/fusion-2.2/widgets/QuickPlot/GeneratePicture.php
branches/fusion-2.2/widgets/QuickPlot/MapCapturer.js
branches/fusion-2.2/widgets/QuickPlot/PreviewDialog.js
branches/fusion-2.2/widgets/QuickPlot/QuickPlotPanel.js
branches/fusion-2.2/widgets/QuickPlot/QuickPlotPanel.php
branches/fusion-2.2/widgets/QuickPlot/QuickPlotPanel.templ
branches/fusion-2.2/widgets/QuickPlot/QuickPlotPreview.js
branches/fusion-2.2/widgets/QuickPlot/QuickPlotPreviewInner.php
branches/fusion-2.2/widgets/QuickPlot/QuickPlotPreviewInner.templ
branches/fusion-2.2/widgets/QuickPlot/north_arrow.png
branches/fusion-2.2/widgets/QuickPlot/pixel.gif
branches/fusion-2.2/widgets/QuickPlot/progress_indicator.gif
branches/fusion-2.2/widgets/QuickPlot/rotate.cur
branches/fusion-2.2/widgets/widgetinfo/quickplot.xml
Removed:
branches/fusion-2.2/widgets/QuickPlot/GeneratePicture.php
branches/fusion-2.2/widgets/QuickPlot/MapCapturer.js
branches/fusion-2.2/widgets/QuickPlot/PreviewDialog.js
branches/fusion-2.2/widgets/QuickPlot/QuickPlotPanel.js
branches/fusion-2.2/widgets/QuickPlot/QuickPlotPanel.php
branches/fusion-2.2/widgets/QuickPlot/QuickPlotPanel.templ
branches/fusion-2.2/widgets/QuickPlot/QuickPlotPreview.js
branches/fusion-2.2/widgets/QuickPlot/QuickPlotPreviewInner.php
branches/fusion-2.2/widgets/QuickPlot/QuickPlotPreviewInner.templ
branches/fusion-2.2/widgets/QuickPlot/north_arrow.png
branches/fusion-2.2/widgets/QuickPlot/pixel.gif
branches/fusion-2.2/widgets/QuickPlot/progress_indicator.gif
branches/fusion-2.2/widgets/QuickPlot/rotate.cur
Modified:
branches/fusion-2.2/
branches/fusion-2.2/build.xml
branches/fusion-2.2/config_dist.json
branches/fusion-2.2/fusion.cfg
branches/fusion-2.2/layers/Generic/Generic.js
branches/fusion-2.2/layers/Layers.js
branches/fusion-2.2/layers/MapGuide/
branches/fusion-2.2/layers/MapGuide/MapGuide.js
branches/fusion-2.2/layers/MapGuide/php/Common.php
branches/fusion-2.2/layers/MapGuide/php/Utilities.php
branches/fusion-2.2/layers/MapServer/
branches/fusion-2.2/layers/MapServer/MapServer.js
branches/fusion-2.2/lib/ApplicationDefinition.js
branches/fusion-2.2/lib/Map.js
branches/fusion-2.2/lib/OpenLayers/OpenLayers.js
branches/fusion-2.2/lib/fusion.js
branches/fusion-2.2/lib/proj4js-compressed.js
branches/fusion-2.2/templates/mapserver/standard/ApplicationDefinition.xml
branches/fusion-2.2/text/en
branches/fusion-2.2/text/en.json
branches/fusion-2.2/text/fr
branches/fusion-2.2/text/fr.json
branches/fusion-2.2/widgets/BasemapSwitcher.js
branches/fusion-2.2/widgets/BufferPanel/Buffer.php
branches/fusion-2.2/widgets/BufferPanel/BufferPanel.templ
branches/fusion-2.2/widgets/BufferPanel/BufferReport.templ
branches/fusion-2.2/widgets/BufferPanel/ErrorPage.templ
branches/fusion-2.2/widgets/Measure.js
branches/fusion-2.2/widgets/Search/ErrorPage.templ
branches/fusion-2.2/widgets/Search/Search.templ
branches/fusion-2.2/widgets/Search/SearchPrompt.templ
branches/fusion-2.2/widgets/SelectWithin/SelectWithinPanel.templ
Log:
merge of revisions 2191-2233 from trunk to the 2.2 branch to bring it back in sync with trunk
Property changes on: branches/fusion-2.2
___________________________________________________________________
Added: svn:mergeinfo
+ /trunk:2192-2233
Modified: branches/fusion-2.2/build.xml
===================================================================
--- branches/fusion-2.2/build.xml 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/build.xml 2010-09-24 18:32:16 UTC (rev 2234)
@@ -221,7 +221,8 @@
MGBroker.js
Widget.js
Search.js
- Map.js"
+ Map.js
+ MapMessage.js"
/>
<filelist dir="${build.home}/layers" files="Layers.js"/>
<fileset dir="${build.home}/text" includes="**/*.json"/>
Property changes on: branches/fusion-2.2/config_dist.json
___________________________________________________________________
Deleted: svn:mergeinfo
-
Modified: branches/fusion-2.2/fusion.cfg
===================================================================
--- branches/fusion-2.2/fusion.cfg 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/fusion.cfg 2010-09-24 18:32:16 UTC (rev 2234)
@@ -32,6 +32,7 @@
OpenLayers/Layer/Yahoo.js
OpenLayers/Layer/Vector.js
OpenLayers/Layer/Markers.js
+OpenLayers/Layer/XYZ.js
OpenLayers/Tile.js
OpenLayers/Tile/Image.js
OpenLayers/Control/OverviewMap.js
Modified: branches/fusion-2.2/layers/Generic/Generic.js
===================================================================
--- branches/fusion-2.2/layers/Generic/Generic.js 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/layers/Generic/Generic.js 2010-09-24 18:32:16 UTC (rev 2234)
@@ -155,6 +155,14 @@
break;
}
break;
+ case 'OpenStreetMap':
+ if (this.mapTag.layerOptions.type) {
+ this.mapTag.layerOptions.type = this.mapTag.layerOptions.type;
+ }
+ else {
+ this.mapTag.layerOptions.type = 'Mapnik';
+ }
+ break;
default:
this.oLayerOL = new OpenLayers.Layer[this.layerType](
this.getMapName(),
@@ -185,7 +193,12 @@
if (typeof this.mapTag.layerOptions.numZoomLevels == 'undefined') {
this.mapTag.layerOptions.numZoomLevels = 20;
}
- this.oLayerOL = new OpenLayers.Layer[this.layerType](this.getMapName(), this.mapTag.layerOptions );
+ if(this.layerType == 'OpenStreetMap') {
+ this.oLayerOL = new OpenLayers.Layer.OSM[this.mapTag.layerOptions.type](this.getMapName(), this.mapTag.layerOptions );
+ }
+ else {
+ this.oLayerOL = new OpenLayers.Layer[this.layerType](this.getMapName(), this.mapTag.layerOptions );
+ }
this.mapWidget.fractionalZoom = false; //fractionalZoom not permitted with Google layers
this.mapWidget.oMapOL.setOptions({fractionalZoom: false});
}
@@ -258,6 +271,13 @@
getSessionID: function() {
return '';
- }
+ },
+
+ getLinkParams: function() {
+ var queryParams = {};
+ queryParams.layerType = this.layerType; //need this? and one for this.mapTag.layerOptions.type?
+ return queryParams;
+ }
+
});
Modified: branches/fusion-2.2/layers/Layers.js
===================================================================
--- branches/fusion-2.2/layers/Layers.js 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/layers/Layers.js 2010-09-24 18:32:16 UTC (rev 2234)
@@ -327,9 +327,9 @@
return;
}
this.oMap.showGroup(this, noDraw ? true : false);
- this.visible = true;
- if (this.legend && this.legend.checkBox) {
- this.legend.checkBox.checked = true;
+ this.set('visible', true);
+ if (this.legend && this.legend.treeItem && this.legend.treeItem.checkBox) {
+ this.legend.treeItem.checkBox.checked = true;
}
},
@@ -338,9 +338,9 @@
return;
}
this.oMap.hideGroup(this, noDraw ? true : false);
- this.visible = false;
- if (this.legend && this.legend.checkBox) {
- this.legend.checkBox.checked = false;
+ this.set('visible', false);
+ if (this.legend && this.legend.treeItem && this.legend.treeItem.checkBox) {
+ this.legend.treeItem.checkBox.checked = false;
}
},
@@ -504,8 +504,8 @@
}
this.set('visible', true);
this.oMap.showLayer(this, noDraw ? true : false);
- if (this.legend && this.legend.checkBox) {
- this.legend.checkBox.checked = true;
+ if (this.legend && this.legend.treeItem && this.legend.treeItem.checkBox) {
+ this.legend.treeItem.checkBox.checked = true;
}
},
@@ -515,8 +515,8 @@
}
this.set('visible',false);
this.oMap.hideLayer(this, noDraw ? true : false);
- if (this.legend && this.legend.checkBox) {
- this.legend.checkBox.checked = false;
+ if (this.legend && this.legend.treeItem && this.legend.treeItem.checkBox) {
+ this.legend.treeItem.checkBox.checked = false;
}
},
Property changes on: branches/fusion-2.2/layers/MapGuide
___________________________________________________________________
Deleted: svn:mergeinfo
-
Modified: branches/fusion-2.2/layers/MapGuide/MapGuide.js
===================================================================
--- branches/fusion-2.2/layers/MapGuide/MapGuide.js 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/layers/MapGuide/MapGuide.js 2010-09-24 18:32:16 UTC (rev 2234)
@@ -165,7 +165,7 @@
}
this.loadMap(this.sMapResourceId, options);
}
- window.setInterval(OpenLayers.Function.bind(this.pingServer, this), this.keepAliveInterval * 1000);
+ this.keepAliveTimer = window.setInterval(OpenLayers.Function.bind(this.pingServer, this), this.keepAliveInterval * 1000);
},
sessionReady: function() {
@@ -301,18 +301,15 @@
}
//set projection units and code if supplied
+ var wktProj;
if (o.epsg != 0) {
this.mapTag.layerOptions.projection = "EPSG:" + o.epsg;
} else {
- if (o.wkt.length > 0) {
- var wkt = o.wkt;
- var wktContentRE = /(\w+)\[(.*)\]/;
- var wktContent = wkt.match(wktContentRE);
- var wktName = wktContent[2].split(",")[0];
- wktName = wktName.toUpperCase();
- this.mapTag.layerOptions.projection = wktName;
- Proj4js.defs[wktName] = "+proj=identity +"+wkt;
- }
+ //default to the local non-projected system if not otherwise specified
+ if (!o.wkt || o.wkt.length == 0){
+ o.wkt = "LOCAL_CS[\"Non-Earth (Meter)\",LOCAL_DATUM[\"Local Datum\",0],UNIT[\"Meter\", 1],AXIS[\"X\",EAST],AXIS[\"Y\",NORTH]]";
+ }
+ wktProj = new OpenLayers.Projection(o.wkt);
}
//TODO: consider passing the metersPerUnit value into the framework
//to allow for scaling that doesn't match any of the pre-canned units
@@ -334,6 +331,9 @@
}
this.oLayerOL = this.createOLLayer(this._sMapname, this.bSingleTile,2,false);
+ if (wktProj) {
+ this.oLayerOL.projection = wktProj;
+ }
this.oLayerOL.events.register("loadstart", this, this.loadStart);
this.oLayerOL.events.register("loadend", this, this.loadEnd);
this.oLayerOL.events.register("loadcancel", this, this.loadEnd);
@@ -1127,10 +1127,21 @@
pingServer: function() {
var s = 'layers/' + this.arch + '/' + Fusion.getScriptLanguage() + "/Common." + Fusion.getScriptLanguage() ;
- var params = {};
+ var params = {onSuccess: OpenLayers.Function.bind(this.checkPingResponse, this)};
params.parameters = {'session': this.getSessionID()};
Fusion.ajaxRequest(s, params);
},
+
+ checkPingResponse: function(xhr) {
+ if (xhr.responseText) {
+ var o;
+ eval("o="+xhr.responseText);
+ if (!o.success) {
+ Fusion.reportError(o.message);
+ clearInterval(this.keepAliveTimer);
+ }
+ }
+ },
getLinkParams: function() {
var queryParams = {};
Modified: branches/fusion-2.2/layers/MapGuide/php/Common.php
===================================================================
--- branches/fusion-2.2/layers/MapGuide/php/Common.php 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/layers/MapGuide/php/Common.php 2010-09-24 18:32:16 UTC (rev 2234)
@@ -138,6 +138,8 @@
$initializationErrorDetail = $e->GetDetails();
$initializationErrorStackTrace = $e->GetStackTrace();
$initializationErrorOccurred = true;
+ echo "{success: false, message:'".$initializationErrorMessage."'}";
+ //DisplayInitializationErrorHTML();
}
function InitializationErrorOccurred()
Modified: branches/fusion-2.2/layers/MapGuide/php/Utilities.php
===================================================================
--- branches/fusion-2.2/layers/MapGuide/php/Utilities.php 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/layers/MapGuide/php/Utilities.php 2010-09-24 18:32:16 UTC (rev 2234)
@@ -773,7 +773,7 @@
array_push($properties->$layerName->metadatanames, 'length');
$mappings = $_SESSION['property_mappings'][$layerObj->GetObjectId()];
- foreach($mappings as $name => $value)
+ foreach((array)$mappings as $name => $value)
{
$propType = $featureReader->GetPropertyType($name);
array_push($properties->$layerName->propertynames, $name);
Property changes on: branches/fusion-2.2/layers/MapServer
___________________________________________________________________
Deleted: svn:mergeinfo
-
Modified: branches/fusion-2.2/layers/MapServer/MapServer.js
===================================================================
--- branches/fusion-2.2/layers/MapServer/MapServer.js 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/layers/MapServer/MapServer.js 2010-09-24 18:32:16 UTC (rev 2234)
@@ -174,12 +174,28 @@
mapSessionCreated: function() {
// restore the mapfile from a saved state.
- if(this.bRestoreMapState === true && this.oRestoredState.loadmap ){
+ if (this.bRestoreMapState === true && this.oRestoredState.loadmap ) {
this.loadMap(this.oRestoredState.loadmap);
+ } else if (this.sMapFile != '') {
+ var options = {};
+ if (this.bIsMapWidgetLayer) {
+ var showlayers = Fusion.getQueryParam('showlayers');
+ Fusion.queryParams['showlayers'] = null;
+ var hidelayers = Fusion.getQueryParam('hidelayers');
+ Fusion.queryParams['hidelayers'] = null;
+ var showgroups = Fusion.getQueryParam('showgroups');
+ Fusion.queryParams['showgroups'] = null;
+ var hidegroups = Fusion.getQueryParam('hidegroups');
+ Fusion.queryParams['hidegroups'] = null;
+ var options = {
+ showlayers: showlayers == '' ? [] : showlayers.split(','),
+ hidelayers: hidelayers == '' ? [] : hidelayers.split(','),
+ showgroups: showgroups == '' ? [] : showgroups.split(','),
+ hidegroups: hidegroups == '' ? [] : hidegroups.split(',')
+ };
+ }
+ this.loadMap(this.sMapFile, options);
}
- else if (this.sMapFile != '') {
- this.loadMap(this.sMapFile);
- }
window.setInterval(OpenLayers.Function.bind(this.pingServer, this),
this.keepAliveInterval * 1000);
},
@@ -215,8 +231,11 @@
options = options || {};
- this.aVisibleLayers = options.showlayers || [];
- this.aVisibleGroups = options.showgroups || [];
+ this.aShowLayers = options.showlayers || [];
+ this.aHideLayers = options.hidelayers || [];
+ this.aShowGroups = options.showgroups || [];
+ this.aHideGroups = options.showgroups || [];
+ this.aVisibleLayers = [];
this.aLayers = [];
this.oSelection = null;
@@ -273,8 +292,27 @@
var minScale = 1.0e10;
var maxScale = 0;
for (var i=0; i<this.aLayers.length; i++) {
+ var testLayer = this.aLayers[i].layerName;
if (this.aLayers[i].visible) {
- this.aVisibleLayers.push(this.aLayers[i].layerName);
+ var layerName = testLayer;
+ for (var j=0; j<this.aHideLayers.length; ++j) {
+ if (layerName == this.aHideLayers[j]) {
+ layerName = null;
+ this.aLayers[i].hide(true);
+ break;
+ }
+ }
+ if (layerName) this.aVisibleLayers.push(layerName);
+ } else {
+ var layerName = null;
+ for (var j=0; j<this.aShowLayers.length; ++j) {
+ if (testLayer == this.aShowLayers[j]) {
+ layerName = testLayer;
+ this.aLayers[i].show(true);
+ break;
+ }
+ }
+ if (layerName) this.aVisibleLayers.push(layerName);
}
minScale = Math.min(minScale, this.aLayers[i].minScale);
maxScale = Math.max(maxScale, this.aLayers[i].maxScale);
@@ -529,19 +567,23 @@
this.oLayerOL.mergeNewParams(params);
},
- showLayer: function( sLayer ) {
+ showLayer: function( sLayer, noDraw ) {
this.aVisibleLayers.push(sLayer.layerName);
- this.drawMap();
+ if (!noDraw) {
+ this.drawMap();
+ }
},
- hideLayer: function( sLayer ) {
+ hideLayer: function( sLayer, noDraw ) {
for (var i=0; i<this.aLayers.length; i++) {
if (this.aVisibleLayers[i] == sLayer.layerName) {
this.aVisibleLayers.splice(i,1);
break;
}
}
- this.drawMap();
+ if (!noDraw) {
+ this.drawMap();
+ }
},
showGroup: function( group, noDraw ) {
@@ -859,6 +901,43 @@
return url + '?'+params;
},
+ getLinkParams: function() {
+ var queryParams = {};
+ queryParams.theme = this.sMapResourceId;
+
+ //determine which layers have been toggled
+ var showLayers = [];
+ var hideLayers = [];
+ for (var i=0; i<this.aLayers.length; ++i) {
+ var layer = this.aLayers[i];
+ if (layer.visible && !layer.initiallyVisible) { //layer was turned on
+ showLayers.push(layer.layerName);
+ }
+ if (!layer.visible && layer.initiallyVisible) { //layer was turned off
+ hideLayers.push(layer.layerName);
+ }
+ }
+ queryParams.showlayers = showLayers.join(',');
+ queryParams.hidelayers = hideLayers.join(',');
+
+ //determine which groups have been toggled
+ var showGroups = [];
+ var hideGroups = [];
+ for (var i=0; i<this.layerRoot.groups.length; ++i) {
+ var group = this.layerRoot.groups[i];
+ if (group.visible && !group.initiallyVisible) { //layer was turned on
+ showGroups.push(group.groupName);
+ }
+ if (!group.visible && group.initiallyVisible) { //layer was turned off
+ hideGroups.push(group.groupName);
+ }
+ }
+ queryParams.showgroups = showGroups.join(',');
+ queryParams.hidegroups = hideGroups.join(',');
+
+ return queryParams;
+ },
+
getMapTip: function(oMapTips){
if(this.bMapTipFired == false){
//console.log("MAPSERVER:getMapTip");
Modified: branches/fusion-2.2/lib/ApplicationDefinition.js
===================================================================
--- branches/fusion-2.2/lib/ApplicationDefinition.js 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/lib/ApplicationDefinition.js 2010-09-24 18:32:16 UTC (rev 2234)
@@ -677,6 +677,14 @@
this.mapWidget.setMenu();
$(this.mapWidgetTag.name).widget = this.mapWidget;
+ //create the floating map message
+ this.mapWidget.message = new Fusion.MapMessage(this.mapWidget.oMapOL.viewPortDiv);
+ this.mapWidget.registerForEvent(Fusion.Event.MAP_EXTENTS_CHANGED, (function(){
+ if (this.message != null){
+ this.message.refreshLayout();
+ }
+ }).bind(this.mapWidget));
+
//create all the other widgets for the widget set
for (var i=0; i<this.widgetTags.length; i++) {
this.widgetTags[i].create(this);
Modified: branches/fusion-2.2/lib/Map.js
===================================================================
--- branches/fusion-2.2/lib/Map.js 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/lib/Map.js 2010-09-24 18:32:16 UTC (rev 2234)
@@ -533,10 +533,10 @@
}
this.oMapOL.addLayer(map.oLayerOL);
if (map.oLayerOL.isBaseLayer) {
- this.projection = map.projection;
- this.units = map.units;
+ this.projection = this.oMapOL.baseLayer.projection;
+ this.units = this.oMapOL.baseLayer.units;
this.oMapOL.setOptions({
- units: map.units,
+ units: this.units,
projection: this.projection
});
}
Copied: branches/fusion-2.2/lib/MapMessage.js (from rev 2233, trunk/lib/MapMessage.js)
===================================================================
--- branches/fusion-2.2/lib/MapMessage.js (rev 0)
+++ branches/fusion-2.2/lib/MapMessage.js 2010-09-24 18:32:16 UTC (rev 2234)
@@ -0,0 +1,112 @@
+/*****************************************************************************
+ * Class: Fusion.MapMessage
+ *
+ * It is to show a floating message bar over the main map viewer
+ */
+Fusion.MapMessage = OpenLayers.Class({
+ parentNode : null,
+ domObj : null,
+ leadingIcon : null,
+ textCell : null,
+ message : "",
+
+ infoIconName : "images/icons/info.png",
+ warningIconName : "images/icons/warning.png",
+ errorIconName : "images/icons/error.png",
+
+ containerCssText : "position:absolute; z-index:10000; padding:10px; border:solid 2px #ECECEC; background:#FFFFBB",
+ iconCssText : "margin-right:10px",
+ textCellCssText : "width:100%; vertical-align:top; font: 8pt Tahoma",
+
+ opacity: 0.95,
+
+ initialize : function(parentNode)
+ {
+ this.parentNode = $(parentNode);
+ // Create the div container
+ var container = document.createElement("div");
+ container.style.visibility = "hidden";
+ this.container = $(container);
+ parentNode.appendChild(container);
+
+ container.style.cssText = this.containerCssText;
+ var offset = {left:10, top:10};
+ container.style.left = offset.left + "px";
+ container.style.top = offset.top + "px";
+
+ // Create the inner table
+ var table = document.createElement("table");
+ container.appendChild(table);
+ table.style.width = "100%";
+ table.cellSpacing = "0";
+ table.cellPadding = "0";
+ table.border = "0";
+ // Create the table row
+ var row = table.insertRow(0);
+ // The icon cell
+ var cell = row.insertCell(0);
+ // Add the info icon by default
+ var icon = document.createElement("img");
+ icon.src = this.infoIconName;
+ cell.appendChild(icon);
+ icon.style.cssText = this.iconCssText;
+ this.leadingIcon = icon;
+ // Create the text cell
+ cell = row.insertCell(1);
+ cell.style.cssText = this.textCellCssText;
+ this.textCell = $(cell);
+ this.textCell.innerHTML = this.message;
+
+ this.refreshLayout();
+ // Hide message bar by default
+ this.container.setOpacity(0);
+ this.container.style.visibility = "visible";
+ },
+
+ info : function(message)
+ {
+ this.message = message;
+ this.leadingIcon.src = this.infoIconName;
+ this.show();
+ },
+
+ warn : function(message)
+ {
+ this.message = message;
+ this.leadingIcon.src = this.warningIconName;
+ this.show();
+ },
+
+ error : function(message)
+ {
+ this.message = message;
+ this.leadingIcon.src = this.errorIconName;
+ this.show();
+ },
+
+ clear : function()
+ {
+ this.message = "";
+ this.textCell.innerHTML = "";
+ this.hide();
+ },
+
+ show : function()
+ {
+ this.textCell.innerHTML = this.message;
+ this.container.fade(this.opacity);
+ },
+
+ hide : function()
+ {
+ this.container.fade(0);
+ },
+
+ refreshLayout: function()
+ {
+ // 44 = 2 * padding (10) + 2 * offset(10) + 2 * border (2)
+ this.container.style.width = this.parentNode.offsetWidth - 44 + "px";
+ },
+
+ CLASS_NAME: "Fusion.MapMessage"
+});
\ No newline at end of file
Modified: branches/fusion-2.2/lib/OpenLayers/OpenLayers.js
===================================================================
--- branches/fusion-2.2/lib/OpenLayers/OpenLayers.js 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/lib/OpenLayers/OpenLayers.js 2010-09-24 18:32:16 UTC (rev 2234)
@@ -1,101 +1,102 @@
-/*
-
- OpenLayers.js -- OpenLayers Map Viewer Library
-
- Copyright 2005-2008 MetaCarta, Inc., released under the Clear BSD license.
- Please see http://svn.openlayers.org/trunk/openlayers/license.txt
- for the full text of the license.
-
- Includes compressed code under the following licenses:
-
- (For uncompressed versions of the code used please see the
- OpenLayers SVN repository: <http://openlayers.org/>)
-
-*/
-
-/* Contains portions of Prototype.js:
- *
- * Prototype JavaScript framework, version 1.4.0
- * (c) 2005 Sam Stephenson <sam at conio.net>
- *
- * Prototype is freely distributable under the terms of an MIT-style license.
- * For details, see the Prototype web site: http://prototype.conio.net/
- *
- *--------------------------------------------------------------------------*/
-
-/**
-*
-* Contains portions of Rico <http://openrico.org/>
-*
-* Copyright 2005 Sabre Airline Solutions
-*
-* Licensed under the Apache License, Version 2.0 (the "License"); you
-* may not use this file except in compliance with the License. You
-* may obtain a copy of the License at
-*
-* http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-* implied. See the License for the specific language governing
-* permissions and limitations under the License.
-*
-**/
-
-/**
- * Contains XMLHttpRequest.js <http://code.google.com/p/xmlhttprequest/>
- * Copyright 2007 Sergey Ilinsky (http://www.ilinsky.com)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- */
-
-/**
- * Contains portions of Gears <http://code.google.com/apis/gears/>
- *
- * Copyright 2007, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of Google Inc. nor the names of its contributors may be
- * used to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Sets up google.gears.*, which is *the only* supported way to access Gears.
- *
- * Circumvent this file at your own risk!
- *
- * In the future, Gears may automatically define google.gears.* without this
- * file. Gears may use these objects to transparently fix bugs and compatibility
- * issues. Applications that use the code below will continue to work seamlessly
- * when that happens.
- */
+/*
+
+ OpenLayers.js -- OpenLayers Map Viewer Library
+
+ Copyright 2005-2010 OpenLayers Contributors, released under the Clear BSD
+ license. Please see http://svn.openlayers.org/trunk/openlayers/license.txt
+ for the full text of the license.
+
+ Includes compressed code under the following licenses:
+
+ (For uncompressed versions of the code used please see the
+ OpenLayers SVN repository: <http://openlayers.org/>)
+
+*/
+
+/* Contains portions of Prototype.js:
+ *
+ * Prototype JavaScript framework, version 1.4.0
+ * (c) 2005 Sam Stephenson <sam at conio.net>
+ *
+ * Prototype is freely distributable under the terms of an MIT-style license.
+ * For details, see the Prototype web site: http://prototype.conio.net/
+ *
+ *--------------------------------------------------------------------------*/
+
+/**
+*
+* Contains portions of Rico <http://openrico.org/>
+*
+* Copyright 2005 Sabre Airline Solutions
+*
+* Licensed under the Apache License, Version 2.0 (the "License"); you
+* may not use this file except in compliance with the License. You
+* may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* permissions and limitations under the License.
+*
+**/
+
+/**
+ * Contains XMLHttpRequest.js <http://code.google.com/p/xmlhttprequest/>
+ * Copyright 2007 Sergey Ilinsky (http://www.ilinsky.com)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * http://www.apache.org/licenses/LICENSE-2.0
+ */
+
+/**
+ * Contains portions of Gears <http://code.google.com/apis/gears/>
+ *
+ * Copyright 2007, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Google Inc. nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Sets up google.gears.*, which is *the only* supported way to access Gears.
+ *
+ * Circumvent this file at your own risk!
+ *
+ * In the future, Gears may automatically define google.gears.* without this
+ * file. Gears may use these objects to transparently fix bugs and compatibility
+ * issues. Applications that use the code below will continue to work seamlessly
+ * when that happens.
+ */
/* ======================================================================
OpenLayers/SingleFile.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
var OpenLayers = {
@@ -107,15 +108,16 @@
OpenLayers.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
-/*
+/*
* @requires OpenLayers/BaseTypes.js
* @requires OpenLayers/Lang/en.js
* @requires OpenLayers/Console.js
- */
+ */
(function() {
/**
@@ -125,13 +127,19 @@
* case with single file builds.
*/
var singleFile = (typeof OpenLayers == "object" && OpenLayers.singleFile);
-
+
/**
+ * Cache for the script location returned from
+ * OpenLayers._getScriptLocation
+ */
+ var scriptLocation;
+
+ /**
* Namespace: OpenLayers
* The OpenLayers object provides a namespace for all things OpenLayers
*/
window.OpenLayers = {
-
+
/**
* Property: _scriptName
* {String} Relative path of this script.
@@ -146,9 +154,12 @@
* {String} Path to this script
*/
_getScriptLocation: function () {
- var scriptLocation = "";
+ if (scriptLocation != undefined) {
+ return scriptLocation;
+ }
+ scriptLocation = "";
var isOL = new RegExp("(^|(.*?\\/))(" + OpenLayers._scriptName + ")(\\?|$)");
-
+
var scripts = document.getElementsByTagName('script');
for (var i=0, len=scripts.length; i<len; i++) {
var src = scripts[i].getAttribute('src');
@@ -166,11 +177,11 @@
/**
* OpenLayers.singleFile is a flag indicating this file is being included
* in a Single File Library build of the OpenLayers Library.
- *
+ *
* When we are *not* part of a SFL build we dynamically include the
* OpenLayers library code.
- *
- * When we *are* part of a SFL build we do not dynamically include the
+ *
+ * When we *are* part of a SFL build we do not dynamically include the
* OpenLayers library code as it will be appended at the end of this file.
*/
if(!singleFile) {
@@ -200,12 +211,14 @@
"OpenLayers/Popup.js",
"OpenLayers/Tile.js",
"OpenLayers/Tile/Image.js",
+ "OpenLayers/Tile/Image/IFrame.js",
"OpenLayers/Tile/WFS.js",
"OpenLayers/Layer/Image.js",
"OpenLayers/Layer/SphericalMercator.js",
"OpenLayers/Layer/EventPane.js",
"OpenLayers/Layer/FixedZoomLevels.js",
"OpenLayers/Layer/Google.js",
+ "OpenLayers/Layer/Google/v3.js",
"OpenLayers/Layer/VirtualEarth.js",
"OpenLayers/Layer/Yahoo.js",
"OpenLayers/Layer/HTTPRequest.js",
@@ -222,12 +235,15 @@
"OpenLayers/Layer/ArcGIS93Rest.js",
"OpenLayers/Layer/WMS.js",
"OpenLayers/Layer/WMS/Untiled.js",
+ "OpenLayers/Layer/WMS/Post.js",
+ "OpenLayers/Layer/WMTS.js",
"OpenLayers/Layer/ArcIMS.js",
"OpenLayers/Layer/GeoRSS.js",
"OpenLayers/Layer/Boxes.js",
"OpenLayers/Layer/XYZ.js",
"OpenLayers/Layer/TMS.js",
"OpenLayers/Layer/TileCache.js",
+ "OpenLayers/Layer/Zoomify.js",
"OpenLayers/Popup/Anchored.js",
"OpenLayers/Popup/AnchoredBubble.js",
"OpenLayers/Popup/Framed.js",
@@ -275,6 +291,10 @@
"OpenLayers/Control/NavigationHistory.js",
"OpenLayers/Control/Measure.js",
"OpenLayers/Control/WMSGetFeatureInfo.js",
+ "OpenLayers/Control/WMTSGetFeatureInfo.js",
+ "OpenLayers/Control/Graticule.js",
+ "OpenLayers/Control/TransformFeature.js",
+ "OpenLayers/Control/SLDSelect.js",
"OpenLayers/Geometry.js",
"OpenLayers/Geometry/Rectangle.js",
"OpenLayers/Geometry/Collection.js",
@@ -282,7 +302,7 @@
"OpenLayers/Geometry/MultiPoint.js",
"OpenLayers/Geometry/Curve.js",
"OpenLayers/Geometry/LineString.js",
- "OpenLayers/Geometry/LinearRing.js",
+ "OpenLayers/Geometry/LinearRing.js",
"OpenLayers/Geometry/Polygon.js",
"OpenLayers/Geometry/MultiLineString.js",
"OpenLayers/Geometry/MultiPolygon.js",
@@ -295,11 +315,18 @@
"OpenLayers/Layer/Vector.js",
"OpenLayers/Layer/Vector/RootContainer.js",
"OpenLayers/Strategy.js",
+ "OpenLayers/Strategy/Filter.js",
"OpenLayers/Strategy/Fixed.js",
"OpenLayers/Strategy/Cluster.js",
"OpenLayers/Strategy/Paging.js",
"OpenLayers/Strategy/BBOX.js",
"OpenLayers/Strategy/Save.js",
+ "OpenLayers/Strategy/Refresh.js",
+ "OpenLayers/Filter.js",
+ "OpenLayers/Filter/FeatureId.js",
+ "OpenLayers/Filter/Logical.js",
+ "OpenLayers/Filter/Comparison.js",
+ "OpenLayers/Filter/Spatial.js",
"OpenLayers/Protocol.js",
"OpenLayers/Protocol/HTTP.js",
"OpenLayers/Protocol/SQL.js",
@@ -308,24 +335,24 @@
"OpenLayers/Protocol/WFS/v1.js",
"OpenLayers/Protocol/WFS/v1_0_0.js",
"OpenLayers/Protocol/WFS/v1_1_0.js",
+ "OpenLayers/Protocol/SOS.js",
+ "OpenLayers/Protocol/SOS/v1_0_0.js",
"OpenLayers/Layer/PointTrack.js",
"OpenLayers/Layer/GML.js",
"OpenLayers/Style.js",
+ "OpenLayers/Style2.js",
"OpenLayers/StyleMap.js",
"OpenLayers/Rule.js",
- "OpenLayers/Filter.js",
- "OpenLayers/Filter/FeatureId.js",
- "OpenLayers/Filter/Logical.js",
- "OpenLayers/Filter/Comparison.js",
- "OpenLayers/Filter/Spatial.js",
"OpenLayers/Format.js",
"OpenLayers/Format/XML.js",
+ "OpenLayers/Format/Context.js",
"OpenLayers/Format/ArcXML.js",
"OpenLayers/Format/ArcXML/Features.js",
"OpenLayers/Format/GML.js",
"OpenLayers/Format/GML/Base.js",
"OpenLayers/Format/GML/v2.js",
"OpenLayers/Format/GML/v3.js",
+ "OpenLayers/Format/Atom.js",
"OpenLayers/Format/KML.js",
"OpenLayers/Format/GeoRSS.js",
"OpenLayers/Format/WFS.js",
@@ -346,7 +373,13 @@
"OpenLayers/Format/SLD.js",
"OpenLayers/Format/SLD/v1.js",
"OpenLayers/Format/SLD/v1_0_0.js",
- "OpenLayers/Format/SLD/v1.js",
+ "OpenLayers/Format/OWSCommon/v1.js",
+ "OpenLayers/Format/OWSCommon/v1_0_0.js",
+ "OpenLayers/Format/OWSCommon/v1_1_0.js",
+ "OpenLayers/Format/CSWGetDomain.js",
+ "OpenLayers/Format/CSWGetDomain/v2_0_2.js",
+ "OpenLayers/Format/CSWGetRecords.js",
+ "OpenLayers/Format/CSWGetRecords/v2_0_2.js",
"OpenLayers/Format/WFST.js",
"OpenLayers/Format/WFST/v1.js",
"OpenLayers/Format/WFST/v1_0_0.js",
@@ -359,10 +392,21 @@
"OpenLayers/Format/WMC/v1_0_0.js",
"OpenLayers/Format/WMC/v1_1_0.js",
"OpenLayers/Format/WMSCapabilities.js",
+ "OpenLayers/Format/WMSCapabilities/v1.js",
"OpenLayers/Format/WMSCapabilities/v1_1.js",
"OpenLayers/Format/WMSCapabilities/v1_1_0.js",
"OpenLayers/Format/WMSCapabilities/v1_1_1.js",
+ "OpenLayers/Format/WMSCapabilities/v1_3.js",
+ "OpenLayers/Format/WMSCapabilities/v1_3_0.js",
"OpenLayers/Format/WMSGetFeatureInfo.js",
+ "OpenLayers/Format/SOSCapabilities.js",
+ "OpenLayers/Format/SOSCapabilities/v1_0_0.js",
+ "OpenLayers/Format/SOSGetObservation.js",
+ "OpenLayers/Format/SOSGetFeatureOfInterest.js",
+ "OpenLayers/Format/OWSContext.js",
+ "OpenLayers/Format/OWSContext/v0_3_1.js",
+ "OpenLayers/Format/WMTSCapabilities.js",
+ "OpenLayers/Format/WMTSCapabilities/v1_0_0.js",
"OpenLayers/Layer/WFS.js",
"OpenLayers/Control/GetFeature.js",
"OpenLayers/Control/MouseToolbar.js",
@@ -373,6 +417,12 @@
"OpenLayers/Control/ZoomOut.js",
"OpenLayers/Control/ZoomPanel.js",
"OpenLayers/Control/EditingToolbar.js",
+ "OpenLayers/Symbolizer.js",
+ "OpenLayers/Symbolizer/Point.js",
+ "OpenLayers/Symbolizer/Line.js",
+ "OpenLayers/Symbolizer/Polygon.js",
+ "OpenLayers/Symbolizer/Text.js",
+ "OpenLayers/Symbolizer/Raster.js",
"OpenLayers/Lang.js",
"OpenLayers/Lang/en.js"
); // etc.
@@ -382,16 +432,16 @@
if(docWrite) {
var allScriptTags = new Array(jsfiles.length);
}
- var host = OpenLayers._getScriptLocation() + "lib/";
+ var host = OpenLayers._getScriptLocation() + "lib/";
for (var i=0, len=jsfiles.length; i<len; i++) {
if (docWrite) {
allScriptTags[i] = "<script src='" + host + jsfiles[i] +
- "'></script>";
+ "'></script>";
} else {
var s = document.createElement("script");
s.src = host + jsfiles[i];
- var h = document.getElementsByTagName("head").length ?
- document.getElementsByTagName("head")[0] :
+ var h = document.getElementsByTagName("head").length ?
+ document.getElementsByTagName("head")[0] :
document.body;
h.appendChild(s);
}
@@ -405,13 +455,14 @@
/**
* Constant: VERSION_NUMBER
*/
-OpenLayers.VERSION_NUMBER="OpenLayers 2.8 -- $Revision$";
+OpenLayers.VERSION_NUMBER="OpenLayers 2.10 -- $Revision$";
/* ======================================================================
OpenLayers/Util.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -423,7 +474,7 @@
*/
OpenLayers.Util = {};
-/**
+/**
* Function: getElement
* This is the old $() from prototype
*/
@@ -444,10 +495,24 @@
};
/**
+ * Function: isElement
+ * A cross-browser implementation of "e instanceof Element".
+ *
+ * Parameters:
+ * o - {Object} The object to test.
+ *
+ * Returns:
+ * {Boolean}
+ */
+OpenLayers.Util.isElement = function(o) {
+ return !!(o && o.nodeType === 1);
+};
+
+/**
* Maintain existing definition of $.
*/
if(typeof window.$ === "undefined") {
- window.$ = OpenLayers.Util.getElement;
+ //window.$ = OpenLayers.Util.getElement;
}
/**
@@ -497,7 +562,7 @@
};
-/**
+/**
* Function: removeItem
* Remove an object from an array. Iterates through the array
* to find the item, then removes it.
@@ -505,7 +570,7 @@
* Parameters:
* array - {Array}
* item - {Object}
- *
+ *
* Return
* {Array} A reference to the array
*/
@@ -523,7 +588,7 @@
* Function: clearArray
* *Deprecated*. This function will disappear in 3.0.
* Please use "array.length = 0" instead.
- *
+ *
* Parameters:
* array - {Array}
*/
@@ -536,48 +601,52 @@
array.length = 0;
};
-/**
+/**
* Function: indexOf
* Seems to exist already in FF, but not in MOZ.
- *
+ *
* Parameters:
* array - {Array}
* obj - {Object}
- *
+ *
* Returns:
- * {Integer} The index at, which the object was found in the array.
+ * {Integer} The index at, which the first object was found in the array.
* If not found, returns -1.
*/
OpenLayers.Util.indexOf = function(array, obj) {
-
- for(var i=0, len=array.length; i<len; i++) {
- if (array[i] == obj) {
- return i;
+ // use the build-in function if available.
+ if (typeof array.indexOf == "function") {
+ return array.indexOf(obj);
+ } else {
+ for (var i = 0, len = array.length; i < len; i++) {
+ if (array[i] == obj) {
+ return i;
+ }
}
+ return -1;
}
- return -1;
};
/**
* Function: modifyDOMElement
- *
- * Modifies many properties of a DOM element all at once. Passing in
+ *
+ * Modifies many properties of a DOM element all at once. Passing in
* null to an individual parameter will avoid setting the attribute.
*
* Parameters:
* id - {String} The element id attribute to set.
* px - {<OpenLayers.Pixel>} The left and top style position.
* sz - {<OpenLayers.Size>} The width and height style attributes.
- * position - {String} The position attribute. eg: absolute,
+ * position - {String} The position attribute. eg: absolute,
* relative, etc.
* border - {String} The style.border attribute. eg:
* solid black 2px
- * overflow - {String} The style.overview attribute.
+ * overflow - {String} The style.overview attribute.
* opacity - {Float} Fractional value (0.0 - 1.0)
*/
-OpenLayers.Util.modifyDOMElement = function(element, id, px, sz, position,
+OpenLayers.Util.modifyDOMElement = function(element, id, px, sz, position,
border, overflow, opacity) {
if (id) {
@@ -609,32 +678,32 @@
}
};
-/**
+/**
* Function: createDiv
* Creates a new div and optionally set some standard attributes.
* Null may be passed to each parameter if you do not wish to
* set a particular attribute.
* Note - zIndex is NOT set on the resulting div.
- *
+ *
* Parameters:
* id - {String} An identifier for this element. If no id is
- * passed an identifier will be created
+ * passed an identifier will be created
* automatically.
- * px - {<OpenLayers.Pixel>} The element left and top position.
+ * px - {<OpenLayers.Pixel>} The element left and top position.
* sz - {<OpenLayers.Size>} The element width and height.
- * imgURL - {String} A url pointing to an image to use as a
+ * imgURL - {String} A url pointing to an image to use as a
* background image.
* position - {String} The style.position value. eg: absolute,
* relative etc.
- * border - {String} The the style.border value.
+ * border - {String} The the style.border value.
* eg: 2px solid black
* overflow - {String} The style.overflow value. Eg. hidden
* opacity - {Float} Fractional value (0.0 - 1.0)
- *
- * Returns:
+ *
+ * Returns:
* {DOMElement} A DOM Div created with the specified attributes.
*/
-OpenLayers.Util.createDiv = function(id, px, sz, imgURL, position,
+OpenLayers.Util.createDiv = function(id, px, sz, imgURL, position,
border, overflow, opacity) {
var dom = document.createElement('div');
@@ -650,7 +719,7 @@
if (!position) {
position = "absolute";
}
- OpenLayers.Util.modifyDOMElement(dom, id, px, sz, position,
+ OpenLayers.Util.modifyDOMElement(dom, id, px, sz, position,
border, overflow, opacity);
return dom;
@@ -659,7 +728,7 @@
/**
* Function: createImage
* Creates an img element with specific attribute values.
- *
+ *
* Parameters:
* id - {String} The id field for the img. If none assigned one will be
* automatically generated.
@@ -671,7 +740,7 @@
* opacity - {Float} Fractional value (0.0 - 1.0)
* delayDisplay - {Boolean} If true waits until the image has been
* loaded.
- *
+ *
* Returns:
* {DOMElement} A DOM Image created with the specified attributes.
*/
@@ -687,18 +756,18 @@
if (!position) {
position = "relative";
}
- OpenLayers.Util.modifyDOMElement(image, id, px, sz, position,
+ OpenLayers.Util.modifyDOMElement(image, id, px, sz, position,
border, null, opacity);
if(delayDisplay) {
image.style.display = "none";
- OpenLayers.Event.observe(image, "load",
+ OpenLayers.Event.observe(image, "load",
OpenLayers.Function.bind(OpenLayers.Util.onImageLoad, image));
- OpenLayers.Event.observe(image, "error",
+ OpenLayers.Event.observe(image, "error",
OpenLayers.Function.bind(OpenLayers.Util.onImageLoadError, image));
-
+
}
-
+
//set special properties
image.style.alt = id;
image.galleryImg = "no";
@@ -707,17 +776,17 @@
}
-
+
return image;
};
/**
* Function: setOpacity
- * *Deprecated*. This function has been deprecated. Instead, please use
- * <OpenLayers.Util.modifyDOMElement>
- * or
+ * *Deprecated*. This function has been deprecated. Instead, please use
+ * <OpenLayers.Util.modifyDOMElement>
+ * or
* <OpenLayers.Util.modifyAlphaImageDiv>
- *
+ *
* Set the opacity of a DOM Element
* Note that for this function to work in IE, elements must "have layout"
* according to:
@@ -739,34 +808,27 @@
*/
OpenLayers.Util.onImageLoad = function() {
// The complex check here is to solve issues described in #480.
- // Every time a map view changes, it increments the 'viewRequestID'
+ // Every time a map view changes, it increments the 'viewRequestID'
// property. As the requests for the images for the new map view are sent
- // out, they are tagged with this unique viewRequestID.
- //
- // If an image has no viewRequestID property set, we display it regardless,
- // but if it does have a viewRequestID property, we check that it matches
+ // out, they are tagged with this unique viewRequestID.
+ //
+ // If an image has no viewRequestID property set, we display it regardless,
+ // but if it does have a viewRequestID property, we check that it matches
// the viewRequestID set on the map.
- //
+ //
// If the viewRequestID on the map has changed, that means that the user
// has changed the map view since this specific request was sent out, and
// therefore this tile does not need to be displayed (so we do not execute
// this code that turns its display on).
//
if (!this.viewRequestID ||
- (this.map && this.viewRequestID == this.map.viewRequestID)) {
- this.style.backgroundColor ="transparent";
- this.style.display = "";
+ (this.map && this.viewRequestID == this.map.viewRequestID)) {
+ this.style.display = "";
}
+ OpenLayers.Element.removeClass(this, "olImageLoadError");
};
/**
- * Property: onImageLoadErrorColor
- * {String} The color tiles with load errors will turn.
- * Default is "pink"
- */
-OpenLayers.Util.onImageLoadErrorColor = "pink";
-
-/**
* Property: IMAGE_RELOAD_ATTEMPTS
* {Integer} How many times should we try to reload an image before giving up?
* Default is 0
@@ -774,7 +836,7 @@
OpenLayers.IMAGE_RELOAD_ATTEMPTS = 0;
/**
- * Function: onImageLoadError
+ * Function: onImageLoadError
*/
OpenLayers.Util.onImageLoadError = function() {
this._attempts = (this._attempts) ? (this._attempts + 1) : 1;
@@ -800,7 +862,7 @@
this.src = this.src;
}
} else {
- this.style.backgroundColor = OpenLayers.Util.onImageLoadErrorColor;
+ OpenLayers.Element.addClass(this, "olImageLoadError");
}
this.style.display = "";
};
@@ -816,7 +878,7 @@
* Checks whether it's necessary (and possible) to use the png alpha
* hack which allows alpha transparency for png images under Internet
* Explorer.
- *
+ *
* Returns:
* {Boolean} true if the png alpha hack is necessary and possible, false otherwise.
*/
@@ -825,25 +887,25 @@
var arVersion = navigator.appVersion.split("MSIE");
var version = parseFloat(arVersion[1]);
var filter = false;
-
- // IEs4Lin dies when trying to access document.body.filters, because
+
+ // IEs4Lin dies when trying to access document.body.filters, because
// the property is there, but requires a DLL that can't be provided. This
// means that we need to wrap this in a try/catch so that this can
// continue.
-
- try {
+
+ try {
filter = !!(document.body.filters);
- } catch (e) {}
-
- OpenLayers.Util.alphaHackNeeded = (filter &&
+ } catch (e) {}
+
+ OpenLayers.Util.alphaHackNeeded = (filter &&
(version >= 5.5) && (version < 7));
}
return OpenLayers.Util.alphaHackNeeded;
};
-/**
+/**
* Function: modifyAlphaImageDiv
- *
+ *
* div - {DOMElement} Div containing Alpha-adjusted Image
* id - {String}
* px - {<OpenLayers.Pixel>}
@@ -853,9 +915,9 @@
* border - {String}
* sizing {String} 'crop', 'scale', or 'image'. Default is "scale"
* opacity - {Float} Fractional value (0.0 - 1.0)
- */
-OpenLayers.Util.modifyAlphaImageDiv = function(div, id, px, sz, imgURL,
- position, border, sizing,
+ */
+OpenLayers.Util.modifyAlphaImageDiv = function(div, id, px, sz, imgURL,
+ position, border, sizing,
opacity) {
OpenLayers.Util.modifyDOMElement(div, id, px, sz, position,
@@ -866,9 +928,9 @@
if (imgURL) {
img.src = imgURL;
}
- OpenLayers.Util.modifyDOMElement(img, div.id + "_innerImage", null, sz,
+ OpenLayers.Util.modifyDOMElement(img, div.id + "_innerImage", null, sz,
"relative", border);
-
+
if (OpenLayers.Util.alphaHack()) {
if(div.style.display != "none") {
div.style.display = "inline-block";
@@ -876,11 +938,11 @@
if (sizing == null) {
sizing = "scale";
}
-
+
div.style.filter = "progid:DXImageTransform.Microsoft" +
".AlphaImageLoader(src='" + img.src + "', " +
"sizingMethod='" + sizing + "')";
- if (parseFloat(div.style.opacity) >= 0.0 &&
+ if (parseFloat(div.style.opacity) >= 0.0 &&
parseFloat(div.style.opacity) < 1.0) {
div.style.filter += " alpha(opacity=" + div.style.opacity * 100 + ")";
}
@@ -889,9 +951,9 @@
}
};
-/**
+/**
* Function: createAlphaImageDiv
- *
+ *
* id - {String}
* px - {<OpenLayers.Pixel>}
* sz - {<OpenLayers.Size>}
@@ -902,17 +964,17 @@
* opacity - {Float} Fractional value (0.0 - 1.0)
* delayDisplay - {Boolean} If true waits until the image has been
* loaded.
- *
+ *
* Returns:
- * {DOMElement} A DOM Div created with a DOM Image inside it. If the hack is
+ * {DOMElement} A DOM Div created with a DOM Image inside it. If the hack is
* needed for transparency in IE, it is added.
- */
-OpenLayers.Util.createAlphaImageDiv = function(id, px, sz, imgURL,
- position, border, sizing,
+ */
+OpenLayers.Util.createAlphaImageDiv = function(id, px, sz, imgURL,
+ position, border, sizing,
opacity, delayDisplay) {
-
+
var div = OpenLayers.Util.createDiv();
- var img = OpenLayers.Util.createImage(null, null, null, null, null, null,
+ var img = OpenLayers.Util.createImage(null, null, null, null, null, null,
null, false);
div.appendChild(img);
@@ -924,23 +986,23 @@
OpenLayers.Function.bind(OpenLayers.Util.onImageLoadError, div));
}
- OpenLayers.Util.modifyAlphaImageDiv(div, id, px, sz, imgURL, position,
+ OpenLayers.Util.modifyAlphaImageDiv(div, id, px, sz, imgURL, position,
border, sizing, opacity);
-
+
return div;
};
-/**
+/**
* Function: upperCaseObject
- * Creates a new hashtable and copies over all the keys from the
+ * Creates a new hashtable and copies over all the keys from the
* passed-in object, but storing them under an uppercased
* version of the key at which they were stored.
- *
- * Parameters:
+ *
+ * Parameters:
* object - {Object}
- *
- * Returns:
+ *
+ * Returns:
* {Object} A new Object with all the same keys but uppercased
*/
OpenLayers.Util.upperCaseObject = function (object) {
@@ -951,12 +1013,12 @@
return uObject;
};
-/**
+/**
* Function: applyDefaults
* Takes an object and copies any properties that don't exist from
* another properties, by analogy with OpenLayers.Util.extend() from
* Prototype.js.
- *
+ *
* Parameters:
* to - {Object} The destination object.
* from - {Object} The source object. Any properties of this object that
@@ -992,27 +1054,27 @@
&& from.hasOwnProperty('toString') && !to.hasOwnProperty('toString')) {
to.toString = from.toString;
}
-
+
return to;
};
/**
* Function: getParameterString
- *
+ *
* Parameters:
* params - {Object}
- *
+ *
* Returns:
- * {String} A concatenation of the properties of an object in
- * http parameter notation.
+ * {String} A concatenation of the properties of an object in
+ * http parameter notation.
* (ex. <i>"key1=value1&key2=value2&key3=value3"</i>)
* If a parameter is actually a list, that parameter will then
* be set to a comma-seperated list of values (foo,bar) instead
- * of being URL escaped (foo%3Abar).
+ * of being URL escaped (foo%3Abar).
*/
OpenLayers.Util.getParameterString = function(params) {
var paramsArray = [];
-
+
for (var key in params) {
var value = params[key];
if ((value != null) && (typeof value != 'function')) {
@@ -1020,8 +1082,12 @@
if (typeof value == 'object' && value.constructor == Array) {
/* value is an array; encode items and separate with "," */
var encodedItemArray = [];
+ var item;
for (var itemIndex=0, len=value.length; itemIndex<len; itemIndex++) {
- encodedItemArray.push(encodeURIComponent(value[itemIndex]));
+ item = value[itemIndex];
+ encodedItemArray.push(encodeURIComponent(
+ (item === null || item === undefined) ? "" : item)
+ );
}
encodedValue = encodedItemArray.join(",");
}
@@ -1032,19 +1098,43 @@
paramsArray.push(encodeURIComponent(key) + "=" + encodedValue);
}
}
-
+
return paramsArray.join("&");
};
/**
+ * Function: urlAppend
+ * Appends a parameter string to a url. This function includes the logic for
+ * using the appropriate character (none, & or ?) to append to the url before
+ * appending the param string.
+ *
+ * Parameters:
+ * url - {String} The url to append to
+ * paramStr - {String} The param string to append
+ *
+ * Returns:
+ * {String} The new url
+ */
+OpenLayers.Util.urlAppend = function(url, paramStr) {
+ var newUrl = url;
+ if(paramStr) {
+ var parts = (url + " ").split(/[?&]/);
+ newUrl += (parts.pop() === " " ?
+ paramStr :
+ parts.length ? "&" + paramStr : "?" + paramStr);
+ }
+ return newUrl;
+};
+
+/**
* Property: ImgPath
* {String} Default is ''.
*/
OpenLayers.ImgPath = '';
-/**
+/**
* Function: getImagesLocation
- *
+ *
* Returns:
* {String} The fully formatted image location string
*/
@@ -1053,18 +1143,18 @@
};
-/**
+/**
* Function: Try
- * Execute functions until one of them doesn't throw an error.
+ * Execute functions until one of them doesn't throw an error.
* Capitalized because "try" is a reserved word in JavaScript.
* Taken directly from OpenLayers.Util.Try()
- *
+ *
* Parameters:
* [*] - {Function} Any number of parameters may be passed to Try()
- * It will attempt to execute each of them until one of them
- * successfully executes.
+ * It will attempt to execute each of them until one of them
+ * successfully executes.
* If none executes successfully, returns null.
- *
+ *
* Returns:
* {*} The value returned by the first successfully executed function.
*/
@@ -1083,15 +1173,15 @@
};
-/**
+/**
* Function: getNodes
- *
+ *
* These could/should be made namespace aware?
- *
+ *
* Parameters:
* p - {}
* tagName - {String}
- *
+ *
* Returns:
* {Array}
*/
@@ -1110,11 +1200,11 @@
/**
* Function: _getNodes
- *
+ *
* Parameters:
* nodes - {Array}
* tagName - {String}
- *
+ *
* Returns:
* {Array}
*/
@@ -1133,12 +1223,12 @@
/**
* Function: getTagText
- *
+ *
* Parameters:
* parent - {}
* item - {String}
* index - {Integer}
- *
+ *
* Returns:
* {String}
*/
@@ -1150,28 +1240,28 @@
index=0;
}
if (result[index].childNodes.length > 1) {
- return result.childNodes[1].nodeValue;
+ return result.childNodes[1].nodeValue;
}
else if (result[index].childNodes.length == 1) {
- return result[index].firstChild.nodeValue;
+ return result[index].firstChild.nodeValue;
}
- } else {
- return "";
+ } else {
+ return "";
}
};
/**
* Function: getXmlNodeValue
- *
+ *
* Parameters:
* node - {XMLNode}
- *
+ *
* Returns:
* {String} The text value of the given node, without breaking in firefox or IE
*/
OpenLayers.Util.getXmlNodeValue = function(node) {
var val = null;
- OpenLayers.Util.Try(
+ OpenLayers.Util.Try(
function() {
val = node.text;
if (!val) {
@@ -1180,20 +1270,20 @@
if (!val) {
val = node.firstChild.nodeValue;
}
- },
+ },
function() {
val = node.textContent;
- });
+ });
return val;
};
-/**
+/**
* Function: mouseLeft
- *
+ *
* Parameters:
* evt - {Event}
* div - {HTMLDivElement}
- *
+ *
* Returns:
* {Boolean}
*/
@@ -1255,6 +1345,17 @@
/**
* Function: rad
+ *
+ * Parameters:
+ * x - {Float}
+ *
+ * Returns:
+ * {Float}
+ */
+OpenLayers.Util.rad = function(x) {return x*Math.PI/180;};
+
+/**
+ * Function: deg
*
* Parameters:
* x - {Float}
@@ -1262,10 +1363,20 @@
* Returns:
* {Float}
*/
-OpenLayers.Util.rad = function(x) {return x*Math.PI/180;};
+OpenLayers.Util.deg = function(x) {return x*180/Math.PI;};
/**
- * Function: distVincenty
+ * Property: VincentyConstants
+ * {Object} Constants for Vincenty functions.
+ */
+OpenLayers.Util.VincentyConstants = {
+ a: 6378137,
+ b: 6356752.3142,
+ f: 1/298.257223563
+};
+
+/**
+ * APIFunction: distVincenty
* Given two objects representing points with geographic coordinates, this
* calculates the distance between those points on the surface of an
* ellipsoid.
@@ -1279,8 +1390,10 @@
* ellipsoid. Note that the input point objects must be in geographic
* coordinates (decimal degrees) and the return distance is in kilometers.
*/
-OpenLayers.Util.distVincenty=function(p1, p2) {
- var a = 6378137, b = 6356752.3142, f = 1/298.257223563;
+OpenLayers.Util.distVincenty = function(p1, p2) {
+ var ct = OpenLayers.Util.VincentyConstants;
+ var a = ct.a, b = ct.b, f = ct.f;
+
var L = OpenLayers.Util.rad(p2.lon - p1.lon);
var U1 = Math.atan((1-f) * Math.tan(OpenLayers.Util.rad(p1.lat)));
var U2 = Math.atan((1-f) * Math.tan(OpenLayers.Util.rad(p2.lat)));
@@ -1319,15 +1432,77 @@
};
/**
+ * APIFunction: destinationVincenty
+ * Calculate destination point given start point lat/long (numeric degrees),
+ * bearing (numeric degrees) & distance (in m).
+ * Adapted from Chris Veness work, see
+ * http://www.movable-type.co.uk/scripts/latlong-vincenty-direct.html
+ *
+ * Parameters:
+ * lonlat - {<OpenLayers.LonLat>} (or any object with both .lat, .lon
+ * properties) The start point.
+ * brng - {Float} The bearing (degrees).
+ * distance - {Float} The ground distance (meters).
+ *
+ * Returns:
+ * {<OpenLayers.LonLat>} The destination point.
+ */
+OpenLayers.Util.destinationVincenty = function(lonlat, brng, dist) {
+ var u = OpenLayers.Util;
+ var ct = u.VincentyConstants;
+ var a = ct.a, b = ct.b, f = ct.f;
+
+ var lon1 = lonlat.lon;
+ var lat1 = lonlat.lat;
+
+ var s = dist;
+ var alpha1 = u.rad(brng);
+ var sinAlpha1 = Math.sin(alpha1);
+ var cosAlpha1 = Math.cos(alpha1);
+
+ var tanU1 = (1-f) * Math.tan(u.rad(lat1));
+ var cosU1 = 1 / Math.sqrt((1 + tanU1*tanU1)), sinU1 = tanU1*cosU1;
+ var sigma1 = Math.atan2(tanU1, cosAlpha1);
+ var sinAlpha = cosU1 * sinAlpha1;
+ var cosSqAlpha = 1 - sinAlpha*sinAlpha;
+ var uSq = cosSqAlpha * (a*a - b*b) / (b*b);
+ var A = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));
+ var B = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)));
+
+ var sigma = s / (b*A), sigmaP = 2*Math.PI;
+ while (Math.abs(sigma-sigmaP) > 1e-12) {
+ var cos2SigmaM = Math.cos(2*sigma1 + sigma);
+ var sinSigma = Math.sin(sigma);
+ var cosSigma = Math.cos(sigma);
+ var deltaSigma = B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-
+ B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));
+ sigmaP = sigma;
+ sigma = s / (b*A) + deltaSigma;
+ }
+
+ var tmp = sinU1*sinSigma - cosU1*cosSigma*cosAlpha1;
+ var lat2 = Math.atan2(sinU1*cosSigma + cosU1*sinSigma*cosAlpha1,
+ (1-f)*Math.sqrt(sinAlpha*sinAlpha + tmp*tmp));
+ var lambda = Math.atan2(sinSigma*sinAlpha1, cosU1*cosSigma - sinU1*sinSigma*cosAlpha1);
+ var C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));
+ var L = lambda - (1-C) * f * sinAlpha *
+ (sigma + C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));
+
+ var revAz = Math.atan2(sinAlpha, -tmp); // final bearing
+
+ return new OpenLayers.LonLat(lon1+u.deg(L), u.deg(lat2));
+};
+
+/**
* Function: getParameters
- * Parse the parameters from a URL or from the current page itself into a
+ * Parse the parameters from a URL or from the current page itself into a
* JavaScript Object. Note that parameter values with commas are separated
* out into an Array.
- *
+ *
* Parameters:
* url - {String} Optional url used to extract the query string.
* If null, query string is taken from page location.
- *
+ *
* Returns:
* {Object} An object of key/value pairs from the query string.
*/
@@ -1352,17 +1527,14 @@
var key = decodeURIComponent(keyValue[0]);
var value = keyValue[1] || ''; //empty string if no value
- //decode individual values
- value = value.split(",");
- for(var j=0, jlen=value.length; j<jlen; j++) {
- value[j] = decodeURIComponent(value[j]);
- }
+ //decode individual values (being liberal by replacing "+" with " ")
+ value = decodeURIComponent(value.replace(/\+/g, " ")).split(",");
- //if there's only one value, do not return as array
+ //if there's only one value, do not return as array
if (value.length == 1) {
value = value[0];
- }
-
+ }
+
parameters[key] = value;
}
}
@@ -1373,11 +1545,11 @@
* Function: getArgs
* *Deprecated*. Will be removed in 3.0. Please use instead
* <OpenLayers.Util.getParameters>
- *
+ *
* Parameters:
* url - {String} Optional url used to extract the query string.
* If null, query string is taken from page location.
- *
+ *
* Returns:
* {Object} An object of key/value pairs from the query string.
*/
@@ -1402,10 +1574,10 @@
* Create a unique identifier for this session. Each time this function
* is called, a counter is incremented. The return will be the optional
* prefix (defaults to "id_") appended with the counter value.
- *
+ *
* Parameters:
* prefix {String} Optionsal string to prefix unique id. Default is "id_".
- *
+ *
* Returns:
* {String} A unique id string, built on the passed in prefix.
*/
@@ -1413,8 +1585,8 @@
if (prefix == null) {
prefix = "id_";
}
- OpenLayers.Util.lastSeqID += 1;
- return prefix + OpenLayers.Util.lastSeqID;
+ OpenLayers.Util.lastSeqID += 1;
+ return prefix + OpenLayers.Util.lastSeqID;
};
/**
@@ -1426,7 +1598,7 @@
* The hardcoded table is maintain in a CS-MAP source code module named CSdataU.c
* The hardcoded table of PROJ.4 units are in pj_units.c.
*/
-OpenLayers.INCHES_PER_UNIT = {
+OpenLayers.INCHES_PER_UNIT = {
'inches': 1.0,
'ft': 12.0,
'mi': 63360.0,
@@ -1512,8 +1684,8 @@
"ch": OpenLayers.INCHES_PER_UNIT["IntnlChain"], //International Chain
"link": OpenLayers.INCHES_PER_UNIT["IntnlLink"], //International Link
"us-in": OpenLayers.INCHES_PER_UNIT["inches"], //U.S. Surveyor's Inch
- "us-ft": OpenLayers.INCHES_PER_UNIT["Foot"], //U.S. Surveyor's Foot
- "us-yd": OpenLayers.INCHES_PER_UNIT["Yard"], //U.S. Surveyor's Yard
+ "us-ft": OpenLayers.INCHES_PER_UNIT["Foot"], //U.S. Surveyor's Foot
+ "us-yd": OpenLayers.INCHES_PER_UNIT["Yard"], //U.S. Surveyor's Yard
"us-ch": OpenLayers.INCHES_PER_UNIT["GunterChain"], //U.S. Surveyor's Chain
"us-mi": OpenLayers.INCHES_PER_UNIT["Mile"], //U.S. Surveyor's Statute Mile
"ind-yd": OpenLayers.INCHES_PER_UNIT["IndianYd37"], //Indian Yard
@@ -1521,7 +1693,7 @@
"ind-ch": 20.11669506 / OpenLayers.METERS_PER_INCH //Indian Chain
});
-/**
+/**
* Constant: DOTS_PER_INCH
* {Integer} 72 (A sensible default)
*/
@@ -1529,57 +1701,58 @@
/**
* Function: normalizeScale
- *
+ *
* Parameters:
* scale - {float}
- *
+ *
* Returns:
- * {Float} A normalized scale value, in 1 / X format.
+ * {Float} A normalized scale value, in 1 / X format.
* This means that if a value less than one ( already 1/x) is passed
- * in, it just returns scale directly. Otherwise, it returns
+ * in, it just returns scale directly. Otherwise, it returns
* 1 / scale
*/
OpenLayers.Util.normalizeScale = function (scale) {
- var normScale = (scale > 1.0) ? (1.0 / scale)
+ var normScale = (scale > 1.0) ? (1.0 / scale)
: scale;
return normScale;
};
/**
* Function: getResolutionFromScale
- *
+ *
* Parameters:
* scale - {Float}
* units - {String} Index into OpenLayers.INCHES_PER_UNIT hashtable.
* Default is degrees
- *
+ *
* Returns:
- * {Float} The corresponding resolution given passed-in scale and unit
- * parameters.
+ * {Float} The corresponding resolution given passed-in scale and unit
+ * parameters. If the given scale is falsey, the returned resolution will
+ * be undefined.
*/
OpenLayers.Util.getResolutionFromScale = function (scale, units) {
-
- if (units == null) {
- units = "degrees";
+ var resolution;
+ if (scale) {
+ if (units == null) {
+ units = "degrees";
+ }
+ var normScale = OpenLayers.Util.normalizeScale(scale);
+ resolution = 1 / (normScale * OpenLayers.INCHES_PER_UNIT[units]
+ * OpenLayers.DOTS_PER_INCH);
}
-
- var normScale = OpenLayers.Util.normalizeScale(scale);
-
- var resolution = 1 / (normScale * OpenLayers.INCHES_PER_UNIT[units]
- * OpenLayers.DOTS_PER_INCH);
return resolution;
};
/**
* Function: getScaleFromResolution
- *
+ *
* Parameters:
* resolution - {Float}
* units - {String} Index into OpenLayers.INCHES_PER_UNIT hashtable.
* Default is degrees
- *
+ *
* Returns:
- * {Float} The corresponding scale given passed-in resolution and unit
+ * {Float} The corresponding scale given passed-in resolution and unit
* parameters.
*/
OpenLayers.Util.getScaleFromResolution = function (resolution, units) {
@@ -1595,13 +1768,13 @@
/**
* Function: safeStopPropagation
- * *Deprecated*. This function has been deprecated. Please use directly
- * <OpenLayers.Event.stop> passing 'true' as the 2nd
+ * *Deprecated*. This function has been deprecated. Please use directly
+ * <OpenLayers.Event.stop> passing 'true' as the 2nd
* argument (preventDefault)
- *
+ *
* Safely stop the propagation of an event *without* preventing
* the default browser action from occurring.
- *
+ *
* Parameter:
* evt - {Event}
*/
@@ -1611,11 +1784,11 @@
/**
* Function: pagePositon
- * Calculates the position of an element on the page.
+ * Calculates the position of an element on the page.
*
* Parameters:
* forElement - {DOMElement}
- *
+ *
* Returns:
* {Array} two item array, L value then T value.
*/
@@ -1631,7 +1804,7 @@
break;
}
}
-
+
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
@@ -1652,25 +1825,25 @@
valueL -= element.scrollLeft || 0;
element = element.parentNode;
}
-
+
return [valueL, valueT];
};
-/**
+/**
* Function: isEquivalentUrl
- * Test two URLs for equivalence.
- *
+ * Test two URLs for equivalence.
+ *
* Setting 'ignoreCase' allows for case-independent comparison.
- *
- * Comparison is based on:
+ *
+ * Comparison is based on:
* - Protocol
* - Host (evaluated without the port)
* - Port (set 'ignorePort80' to ignore "80" values)
* - Hash ( set 'ignoreHash' to disable)
- * - Pathname (for relative <-> absolute comparison)
+ * - Pathname (for relative <-> absolute comparison)
* - Arguments (so they can be out of order)
- *
+ *
* Parameters:
* url1 - {String}
* url2 - {String}
@@ -1714,22 +1887,22 @@
for(var key in urlObj2.args) {
return false;
}
-
+
return true;
};
/**
* Function: createUrlObject
- *
+ *
* Parameters:
* url - {String}
* options - {Object} A hash of options. Can be one of:
* ignoreCase: lowercase url,
* ignorePort80: don't include explicit port if port is 80,
* ignoreHash: Don't include part of url after the hash (#).
- *
+ *
* Returns:
- * {Object} An object with separate url, a, port, host, and args parsed out
+ * {Object} An object with separate url, a, port, host, and args parsed out
* and ready for comparison
*/
OpenLayers.Util.createUrlObject = function(url, options) {
@@ -1750,21 +1923,21 @@
url = fullUrl + parts.join("/") + "/" + url;
}
}
-
+
if (options.ignoreCase) {
- url = url.toLowerCase();
+ url = url.toLowerCase();
}
var a = document.createElement('a');
a.href = url;
-
+
var urlObject = {};
-
+
//host (without port)
urlObject.host = a.host.split(":").shift();
//protocol
- urlObject.protocol = a.protocol;
+ urlObject.protocol = a.protocol;
//port (get uniform browser behavior with port 80 here)
if(options.ignorePort80) {
@@ -1774,8 +1947,8 @@
}
//hash
- urlObject.hash = (options.ignoreHash || a.hash === "#") ? "" : a.hash;
-
+ urlObject.hash = (options.ignoreHash || a.hash === "#") ? "" : a.hash;
+
//args
var queryString = a.search;
if (!queryString) {
@@ -1786,30 +1959,30 @@
//pathname (uniform browser behavior with leading "/")
urlObject.pathname = (a.pathname.charAt(0) == "/") ? a.pathname : "/" + a.pathname;
-
- return urlObject;
+
+ return urlObject;
};
-
+
/**
* Function: removeTail
* Takes a url and removes everything after the ? and #
- *
+ *
* Parameters:
* url - {String} The url to process
- *
+ *
* Returns:
* {String} The string with all queryString and Hash removed
*/
OpenLayers.Util.removeTail = function(url) {
var head = null;
-
+
var qMark = url.indexOf("?");
var hashMark = url.indexOf("#");
if (qMark == -1) {
head = (hashMark != -1) ? url.substr(0,hashMark) : url;
} else {
- head = (hashMark != -1) ? url.substr(0,Math.min(qMark, hashMark))
+ head = (hashMark != -1) ? url.substr(0,Math.min(qMark, hashMark))
: url.substr(0, qMark);
}
return head;
@@ -1818,24 +1991,24 @@
/**
* Function: getBrowserName
- *
+ *
* Returns:
- * {String} A string which specifies which is the current
- * browser in which we are running.
- *
+ * {String} A string which specifies which is the current
+ * browser in which we are running.
+ *
* Currently-supported browser detection and codes:
* * 'opera' -- Opera
* * 'msie' -- Internet Explorer
* * 'safari' -- Safari
* * 'firefox' -- FireFox
* * 'mozilla' -- Mozilla
- *
- * If we are unable to property identify the browser, we
+ *
+ * If we are unable to property identify the browser, we
* return an empty string.
*/
OpenLayers.Util.getBrowserName = function() {
var browserName = "";
-
+
var ua = navigator.userAgent.toLowerCase();
if ( ua.indexOf( "opera" ) != -1 ) {
browserName = "opera";
@@ -1850,46 +2023,46 @@
browserName = "mozilla";
}
}
-
+
return browserName;
};
-
+
/**
* Method: getRenderedDimensions
* Renders the contentHTML offscreen to determine actual dimensions for
* popup sizing. As we need layout to determine dimensions the content
- * is rendered -9999px to the left and absolute to ensure the
+ * is rendered -9999px to the left and absolute to ensure the
* scrollbars do not flicker
- *
+ *
* Parameters:
* contentHTML
- * size - {<OpenLayers.Size>} If either the 'w' or 'h' properties is
- * specified, we fix that dimension of the div to be measured. This is
- * useful in the case where we have a limit in one dimension and must
+ * size - {<OpenLayers.Size>} If either the 'w' or 'h' properties is
+ * specified, we fix that dimension of the div to be measured. This is
+ * useful in the case where we have a limit in one dimension and must
* therefore meaure the flow in the other dimension.
* options - {Object}
* displayClass - {String} Optional parameter. A CSS class name(s) string
* to provide the CSS context of the rendered content.
- * containerElement - {DOMElement} Optional parameter. Insert the HTML to
- * this node instead of the body root when calculating dimensions.
- *
+ * containerElement - {DOMElement} Optional parameter. Insert the HTML to
+ * this node instead of the body root when calculating dimensions.
+ *
* Returns:
* {OpenLayers.Size}
*/
OpenLayers.Util.getRenderedDimensions = function(contentHTML, size, options) {
-
+
var w, h;
-
+
// create temp container div with restricted size
var container = document.createElement("div");
container.style.visibility = "hidden";
+
+ var containerElement = (options && options.containerElement)
+ ? options.containerElement : document.body;
- var containerElement = (options && options.containerElement)
- ? options.containerElement : document.body;
-
//fix a dimension, if specified.
if (size) {
if (size.w) {
@@ -1905,11 +2078,11 @@
if (options && options.displayClass) {
container.className = options.displayClass;
}
-
+
// create temp content div and assign content
var content = document.createElement("div");
content.innerHTML = contentHTML;
-
+
// we need overflow visible when calculating the size
content.style.overflow = "visible";
if (content.childNodes) {
@@ -1918,13 +2091,13 @@
content.childNodes[i].style.overflow = "visible";
}
}
-
- // add content to restricted container
+
+ // add content to restricted container
container.appendChild(content);
-
+
// append container to body for rendering
containerElement.appendChild(container);
-
+
// Opera and IE7 can't handle a node with position:aboslute if it inherits
// position:absolute from a parent.
var parentHasPositionAbsolute = false;
@@ -1943,14 +2116,14 @@
if(!parentHasPositionAbsolute) {
container.style.position = "absolute";
}
-
+
// calculate scroll width of content and add corners and shadow width
if (!w) {
w = parseInt(content.scrollWidth);
-
+
// update container width to allow height to adjust
container.style.width = w + "px";
- }
+ }
// capture height and add shadow and corner image widths
if (!h) {
h = parseInt(content.scrollHeight);
@@ -1959,35 +2132,35 @@
// remove elements
container.removeChild(content);
containerElement.removeChild(container);
-
+
return new OpenLayers.Size(w, h);
};
/**
* APIFunction: getScrollbarWidth
* This function has been modified by the OpenLayers from the original version,
- * written by Matthew Eernisse and released under the Apache 2
+ * written by Matthew Eernisse and released under the Apache 2
* license here:
- *
+ *
* http://www.fleegix.org/articles/2006/05/30/getting-the-scrollbar-width-in-pixels
- *
- * It has been modified simply to cache its value, since it is physically
- * impossible that this code could ever run in more than one browser at
- * once.
- *
+ *
+ * It has been modified simply to cache its value, since it is physically
+ * impossible that this code could ever run in more than one browser at
+ * once.
+ *
* Returns:
* {Integer}
*/
OpenLayers.Util.getScrollbarWidth = function() {
-
+
var scrollbarWidth = OpenLayers.Util._scrollbarWidth;
-
+
if (scrollbarWidth == null) {
var scr = null;
var inn = null;
var wNoScroll = 0;
var wScroll = 0;
-
+
// Outer scrolling div
scr = document.createElement('div');
scr.style.position = 'absolute';
@@ -1997,28 +2170,28 @@
scr.style.height = '50px';
// Start with no scrollbar
scr.style.overflow = 'hidden';
-
+
// Inner content div
inn = document.createElement('div');
inn.style.width = '100%';
inn.style.height = '200px';
-
+
// Put the inner div in the scrolling div
scr.appendChild(inn);
// Append the scrolling div to the doc
document.body.appendChild(scr);
-
+
// Width of the inner div sans scrollbar
wNoScroll = inn.offsetWidth;
-
+
// Add the scrollbar
scr.style.overflow = 'scroll';
// Width of the inner div width scrollbar
wScroll = inn.offsetWidth;
-
+
// Remove the scrolling div from the doc
document.body.removeChild(document.body.lastChild);
-
+
// Pixel width of the scroller
OpenLayers.Util._scrollbarWidth = (wNoScroll - wScroll);
scrollbarWidth = OpenLayers.Util._scrollbarWidth;
@@ -2026,12 +2199,71 @@
return scrollbarWidth;
};
+
+/**
+ * APIFunction: getFormattedLonLat
+ * This function will return latitude or longitude value formatted as
+ *
+ * Parameters:
+ * coordinate - {Float} the coordinate value to be formatted
+ * axis - {String} value of either 'lat' or 'lon' to indicate which axis is to
+ * to be formatted (default = lat)
+ * dmsOption - {String} specify the precision of the output can be one of:
+ * 'dms' show degrees minutes and seconds
+ * 'dm' show only degrees and minutes
+ * 'd' show only degrees
+ *
+ * Returns:
+ * {String} the coordinate value formatted as a string
+ */
+OpenLayers.Util.getFormattedLonLat = function(coordinate, axis, dmsOption) {
+ if (!dmsOption) {
+ dmsOption = 'dms'; //default to show degree, minutes, seconds
+ }
+ var abscoordinate = Math.abs(coordinate)
+ var coordinatedegrees = Math.floor(abscoordinate);
+
+ var coordinateminutes = (abscoordinate - coordinatedegrees)/(1/60);
+ var tempcoordinateminutes = coordinateminutes;
+ coordinateminutes = Math.floor(coordinateminutes);
+ var coordinateseconds = (tempcoordinateminutes - coordinateminutes)/(1/60);
+ coordinateseconds = Math.round(coordinateseconds*10);
+ coordinateseconds /= 10;
+
+ if( coordinatedegrees < 10 ) {
+ coordinatedegrees = "0" + coordinatedegrees;
+ }
+ var str = coordinatedegrees + "\u00B0";
+
+ if (dmsOption.indexOf('dm') >= 0) {
+ if( coordinateminutes < 10 ) {
+ coordinateminutes = "0" + coordinateminutes;
+ }
+ str += coordinateminutes + "'";
+
+ if (dmsOption.indexOf('dms') >= 0) {
+ if( coordinateseconds < 10 ) {
+ coordinateseconds = "0" + coordinateseconds;
+ }
+ str += coordinateseconds + '"';
+ }
+ }
+
+ if (axis == "lon") {
+ str += coordinate < 0 ? OpenLayers.i18n("W") : OpenLayers.i18n("E");
+ } else {
+ str += coordinate < 0 ? OpenLayers.i18n("S") : OpenLayers.i18n("N");
+ }
+ return str;
+};
+
/* ======================================================================
OpenLayers/Console.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -2046,7 +2278,7 @@
* Note that behavior will differ with the Firebug extention and Firebug Lite.
* Most notably, the Firebug Lite console does not currently allow for
* hyperlinks to code or for clicking on object to explore their properties.
- *
+ *
*/
OpenLayers.Console = {
/**
@@ -2055,7 +2287,7 @@
* included. We explicitly require the Firebug Lite script to trigger
* functionality of the OpenLayers.Console methods.
*/
-
+
/**
* APIFunction: log
* Log an object in the console. The Firebug Lite console logs string
@@ -2065,7 +2297,7 @@
* will be used in string substitution. Any additional arguments (beyond
* the number substituted in a format string) will be appended in a space-
* delimited line.
- *
+ *
* Parameters:
* object - {Object}
*/
@@ -2077,7 +2309,7 @@
* where it was called.
*
* May be called with multiple arguments as with OpenLayers.Console.log().
- *
+ *
* Parameters:
* object - {Object}
*/
@@ -2089,7 +2321,7 @@
* coding and a hyperlink to the line where it was called.
*
* May be called with multiple arguments as with OpenLayers.Console.log().
- *
+ *
* Parameters:
* object - {Object}
*/
@@ -2101,7 +2333,7 @@
* color coding and a hyperlink to the line where it was called.
*
* May be called with multiple arguments as with OpenLayers.Console.log().
- *
+ *
* Parameters:
* object - {Object}
*/
@@ -2113,12 +2345,12 @@
* coding and a hyperlink to the line where it was called.
*
* May be called with multiple arguments as with OpenLayers.Console.log().
- *
+ *
* Parameters:
* object - {Object}
*/
error: function() {},
-
+
/**
* APIFunction: userError
* A single interface for showing error messages to the user. The default
@@ -2126,7 +2358,7 @@
* reassigning OpenLayers.Console.userError to a different function.
*
* Expects a single error message
- *
+ *
* Parameters:
* object - {Object}
*/
@@ -2140,7 +2372,7 @@
* the console and throw an exception.
*
* May be called with multiple arguments as with OpenLayers.Console.log().
- *
+ *
* Parameters:
* object - {Object}
*/
@@ -2150,7 +2382,7 @@
* APIFunction: dir
* Prints an interactive listing of all properties of the object. This
* looks identical to the view that you would see in the DOM tab.
- *
+ *
* Parameters:
* object - {Object}
*/
@@ -2161,7 +2393,7 @@
* Prints the XML source tree of an HTML or XML element. This looks
* identical to the view that you would see in the HTML tab. You can click
* on any node to inspect it in the HTML tab.
- *
+ *
* Parameters:
* object - {Object}
*/
@@ -2174,7 +2406,7 @@
* as well as the values that were passed as arguments to each function.
* You can click each function to take you to its source in the Script tab,
* and click each argument value to inspect it in the DOM or HTML tabs.
- *
+ *
*/
trace: function() {},
@@ -2185,7 +2417,7 @@
* to close the block.
*
* May be called with multiple arguments as with OpenLayers.Console.log().
- *
+ *
* Parameters:
* object - {Object}
*/
@@ -2197,7 +2429,7 @@
* OpenLayers.Console.group
*/
groupEnd: function() {},
-
+
/**
* APIFunction: time
* Creates a new timer under the given name. Call
@@ -2225,7 +2457,7 @@
* contain the text to be printed in the header of the profile report.
*
* This function is not currently implemented in Firebug Lite.
- *
+ *
* Parameters:
* title - {String} Optional title for the profiler
*/
@@ -2234,7 +2466,7 @@
/**
* APIFunction: profileEnd
* Turns off the JavaScript profiler and prints its report.
- *
+ *
* This function is not currently implemented in Firebug Lite.
*/
profileEnd: function() {},
@@ -2279,8 +2511,9 @@
OpenLayers/BaseTypes.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -2293,8 +2526,8 @@
* @requires OpenLayers/Lang/en.js
* @requires OpenLayers/Console.js
*/
-
-/**
+
+/**
* Header: OpenLayers Base Types
* OpenLayers custom string, number and function functions are described here.
*/
@@ -2307,12 +2540,12 @@
/**
* APIFunction: startsWith
- * Test whether a string starts with another string.
- *
+ * Test whether a string starts with another string.
+ *
* Parameters:
* str - {String} The string to test.
* sub - {Sring} The substring to look for.
- *
+ *
* Returns:
* {Boolean} The first string starts with the second.
*/
@@ -2323,43 +2556,43 @@
/**
* APIFunction: contains
* Test whether a string contains another string.
- *
+ *
* Parameters:
* str - {String} The string to test.
* sub - {String} The substring to look for.
- *
+ *
* Returns:
* {Boolean} The first string contains the second.
*/
contains: function(str, sub) {
return (str.indexOf(sub) != -1);
},
-
+
/**
* APIFunction: trim
* Removes leading and trailing whitespace characters from a string.
- *
+ *
* Parameters:
* str - {String} The (potentially) space padded string. This string is not
* modified.
- *
+ *
* Returns:
- * {String} A trimmed version of the string with all leading and
+ * {String} A trimmed version of the string with all leading and
* trailing spaces removed.
*/
trim: function(str) {
return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
},
-
+
/**
* APIFunction: camelize
- * Camel-case a hyphenated string.
+ * Camel-case a hyphenated string.
* Ex. "chicken-head" becomes "chickenHead", and
* "-chicken-head" becomes "ChickenHead".
*
* Parameters:
* str - {String} The string to be camelized. The original is not modified.
- *
+ *
* Returns:
* {String} The string, camelized
*/
@@ -2372,7 +2605,7 @@
}
return camelizedString;
},
-
+
/**
* APIFunction: format
* Given a string with tokens in the form ${token}, return a string
@@ -2399,7 +2632,7 @@
context = window;
}
- // Example matching:
+ // Example matching:
// str = ${foo.bar}
// match = foo.bar
var replacer = function(str, match) {
@@ -2425,13 +2658,13 @@
}
// If replacement is undefined, return the string 'undefined'.
- // This is a workaround for a bugs in browsers not properly
+ // This is a workaround for a bugs in browsers not properly
// dealing with non-participating groups in regular expressions:
// http://blog.stevenlevithan.com/archives/npcg-javascript
if (typeof replacement == 'undefined') {
return 'undefined';
} else {
- return replacement;
+ return replacement;
}
};
@@ -2444,13 +2677,13 @@
* Examples: ${a}, ${a.b.c}, ${a-b}, ${5}
*/
tokenRegEx: /\$\{([\w.]+?)\}/g,
-
+
/**
* Property: OpenLayers.String.numberRegEx
* Used to test strings as numbers.
*/
numberRegEx: /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/,
-
+
/**
* APIFunction: OpenLayers.String.isNumeric
* Determine whether a string contains only a numeric value.
@@ -2469,14 +2702,14 @@
isNumeric: function(value) {
return OpenLayers.String.numberRegEx.test(value);
},
-
+
/**
* APIFunction: numericIf
* Converts a string that appears to be a numeric value into a number.
- *
+ *
* Returns
* {Number|String} a Number if the passed value is a number, a String
- * otherwise.
+ * otherwise.
*/
numericIf: function(value) {
return OpenLayers.String.isNumeric(value) ? parseFloat(value) : value;
@@ -2487,11 +2720,11 @@
if (!String.prototype.startsWith) {
/**
* APIMethod: String.startsWith
- * *Deprecated*. Whether or not a string starts with another string.
- *
+ * *Deprecated*. Whether or not a string starts with another string.
+ *
* Parameters:
* sStart - {Sring} The string we're testing for.
- *
+ *
* Returns:
* {Boolean} Whether or not this string starts with the string passed in.
*/
@@ -2506,10 +2739,10 @@
/**
* APIMethod: String.contains
* *Deprecated*. Whether or not a string contains another string.
- *
+ *
* Parameters:
* str - {String} The string that we're testing for.
- *
+ *
* Returns:
* {Boolean} Whether or not this string contains with the string passed in.
*/
@@ -2524,9 +2757,9 @@
/**
* APIMethod: String.trim
* *Deprecated*. Removes leading and trailing whitespace characters from a string.
- *
+ *
* Returns:
- * {String} A trimmed version of the string - all leading and
+ * {String} A trimmed version of the string - all leading and
* trailing spaces removed
*/
String.prototype.trim = function() {
@@ -2539,10 +2772,10 @@
if (!String.prototype.camelize) {
/**
* APIMethod: String.camelize
- * *Deprecated*. Camel-case a hyphenated string.
+ * *Deprecated*. Camel-case a hyphenated string.
* Ex. "chicken-head" becomes "chickenHead", and
* "-chicken-head" becomes "ChickenHead".
- *
+ *
* Returns:
* {String} The string, camelized
*/
@@ -2564,21 +2797,21 @@
* Decimal separator to use when formatting numbers.
*/
decimalSeparator: ".",
-
+
/**
* Property: thousandsSeparator
* Thousands separator to use when formatting numbers.
*/
thousandsSeparator: ",",
-
+
/**
* APIFunction: limitSigDigs
* Limit the number of significant digits on a float.
- *
+ *
* Parameters:
* num - {Float}
* sig - {Integer}
- *
+ *
* Returns:
* {Float} The number, rounded to the specified number of significant
* digits.
@@ -2590,11 +2823,11 @@
}
return fig;
},
-
+
/**
* APIFunction: format
* Formats a number for output.
- *
+ *
* Parameters:
* num - {Float}
* dec - {Integer} Number of decimal places to round to.
@@ -2608,9 +2841,9 @@
* {String} A string representing the formatted number.
*/
format: function(num, dec, tsep, dsep) {
- dec = (typeof dec != "undefined") ? dec : 0;
+ dec = (typeof dec != "undefined") ? dec : 0;
tsep = (typeof tsep != "undefined") ? tsep :
- OpenLayers.Number.thousandsSeparator;
+ OpenLayers.Number.thousandsSeparator;
dsep = (typeof dsep != "undefined") ? dsep :
OpenLayers.Number.decimalSeparator;
@@ -2623,15 +2856,15 @@
// integer where we do not want to touch the decimals
dec = 0;
}
-
+
var integer = parts[0];
if (tsep) {
- var thousands = /(-?[0-9]+)([0-9]{3})/;
- while(thousands.test(integer)) {
- integer = integer.replace(thousands, "$1" + tsep + "$2");
+ var thousands = /(-?[0-9]+)([0-9]{3})/;
+ while(thousands.test(integer)) {
+ integer = integer.replace(thousands, "$1" + tsep + "$2");
}
}
-
+
var str;
if (dec == 0) {
str = integer;
@@ -2651,10 +2884,10 @@
* APIMethod: Number.limitSigDigs
* *Deprecated*. Limit the number of significant digits on an integer. Does *not*
* work with floats!
- *
+ *
* Parameters:
* sig - {Integer}
- *
+ *
* Returns:
* {Integer} The number, rounded to the specified number of significant digits.
* If null, 0, or negative value passed in, returns 0
@@ -2675,11 +2908,11 @@
* APIFunction: bind
* Bind a function to an object. Method to easily create closures with
* 'this' altered.
- *
+ *
* Parameters:
* func - {Function} Input function.
* object - {Object} The object to bind to the input function (as this).
- *
+ *
* Returns:
* {Function} A closure with 'this' set to the passed in object.
*/
@@ -2695,16 +2928,16 @@
return func.apply(object, newArgs);
};
},
-
+
/**
* APIFunction: bindAsEventListener
* Bind a function to an object, and configure it to receive the event
- * object as first parameter when called.
- *
+ * object as first parameter when called.
+ *
* Parameters:
* func - {Function} Input function to serve as an event listener.
* object - {Object} A reference to this.
- *
+ *
* Returns:
* {Function}
*/
@@ -2712,18 +2945,50 @@
return function(event) {
return func.call(object, event || window.event);
};
+ },
+
+ /**
+ * APIFunction: False
+ * A simple function to that just does "return false". We use this to
+ * avoid attaching anonymous functions to DOM event handlers, which
+ * causes "issues" on IE<8.
+ *
+ * Usage:
+ * document.onclick = OpenLayers.Function.False;
+ *
+ * Returns:
+ * {Boolean}
+ */
+ False : function() {
+ return false;
+ },
+
+ /**
+ * APIFunction: True
+ * A simple function to that just does "return true". We use this to
+ * avoid attaching anonymous functions to DOM event handlers, which
+ * causes "issues" on IE<8.
+ *
+ * Usage:
+ * document.onclick = OpenLayers.Function.True;
+ *
+ * Returns:
+ * {Boolean}
+ */
+ True : function() {
+ return true;
}
};
if (!Function.prototype.bind) {
/**
* APIMethod: Function.bind
- * *Deprecated*. Bind a function to an object.
+ * *Deprecated*. Bind a function to an object.
* Method to easily create closures with 'this' altered.
- *
+ *
* Parameters:
* object - {Object} the this parameter
- *
+ *
* Returns:
* {Function} A closure with 'this' altered to the first
* argument.
@@ -2741,11 +3006,11 @@
/**
* APIMethod: Function.bindAsEventListener
* *Deprecated*. Bind a function to an object, and configure it to receive the
- * event object as first parameter when called.
- *
+ * event object as first parameter when called.
+ *
* Parameters:
* object - {Object} A reference to this.
- *
+ *
* Returns:
* {Function}
*/
@@ -2768,7 +3033,7 @@
* Array.prototype.filter extension to the ECMA-262 standard. Where
* available, Array.prototype.filter will be used.
*
- * Based on well known example from http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Objects:Array:filter
+ * Based on well known example from http://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/filter
*
* Parameters:
* array - {Array} The array to be filtered. This array is not mutated.
@@ -2802,29 +3067,150 @@
selected.push(val);
}
}
- }
+ }
}
return selected;
}
+
+};
+/**
+ * Namespace: OpenLayers.Date
+ * Contains implementations of Date.parse and date.toISOString that match the
+ * ECMAScript 5 specification for parsing RFC 3339 dates.
+ * http://tools.ietf.org/html/rfc3339
+ */
+OpenLayers.Date = {
+
+ /**
+ * APIMethod: toISOString
+ * Generates a string representing a date. The format of the string follows
+ * the profile of ISO 8601 for date and time on the Internet (see
+ * http://tools.ietf.org/html/rfc3339). If the toISOString method is
+ * available on the Date prototype, that is used. The toISOString
+ * method for Date instances is defined in ECMA-262.
+ *
+ * Parameters:
+ * date - {Date} A date object.
+ *
+ * Returns:
+ * {String} A string representing the date (e.g.
+ * "2010-08-07T16:58:23.123Z"). If the date does not have a valid time
+ * (i.e. isNaN(date.getTime())) this method returns the string "Invalid
+ * Date". The ECMA standard says the toISOString method should throw
+ * RangeError in this case, but Firefox returns a string instead. For
+ * best results, use isNaN(date.getTime()) to determine date validity
+ * before generating date strings.
+ */
+ toISOString: (function() {
+ if ("toISOString" in Date.prototype) {
+ return function(date) {
+ return date.toISOString();
+ }
+ } else {
+ function pad(num, len) {
+ var str = num + "";
+ while (str.length < len) {
+ str = "0" + str;
+ }
+ return str;
+ }
+ return function(date) {
+ var str;
+ if (isNaN(date.getTime())) {
+ // ECMA-262 says throw RangeError, Firefox returns
+ // "Invalid Date"
+ str = "Invalid Date";
+ } else {
+ str =
+ date.getUTCFullYear() + "-" +
+ pad(date.getUTCMonth() + 1, 2) + "-" +
+ pad(date.getUTCDate(), 2) + "T" +
+ pad(date.getUTCHours(), 2) + ":" +
+ pad(date.getUTCMinutes(), 2) + ":" +
+ pad(date.getUTCSeconds(), 2) + "." +
+ pad(date.getUTCMilliseconds(), 3) + "Z";
+ }
+ return str;
+ }
+ }
+
+ })(),
+
+ /**
+ * APIMethod: parse
+ * Generate a date object from a string. The format for the string follows
+ * the profile of ISO 8601 for date and time on the Internet (see
+ * http://tools.ietf.org/html/rfc3339). If the parse method on
+ * the Date constructor returns a valid date for the given string,
+ * that method is used.
+ *
+ * Parameters:
+ * str - {String} A string representing the date (e.g.
+ * "2010", "2010-08", "2010-08-07", "2010-08-07T16:58:23.123Z",
+ * "2010-08-07T11:58:23.123-06").
+ *
+ * Returns:
+ * {Date} A date object. If the string could not be parsed, an invalid
+ * date is returned (i.e. isNaN(date.getTime())).
+ */
+ parse: function(str) {
+ var date;
+ // first check if the native parse method can parse it
+ var elapsed = Date.parse(str);
+ if (!isNaN(elapsed)) {
+ date = new Date(elapsed);
+ } else {
+ var match = str.match(/^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:T(\d{1,2}):(\d{2}):(\d{2}(?:\.\d+)?)(Z|(?:[+-]\d{1,2}(?::(\d{2}))?)))?$/);
+ var date;
+ if (match && (match[1] || match[7])) { // must have at least year or time
+ var year = parseInt(match[1], 10) || 0;
+ var month = (parseInt(match[2], 10) - 1) || 0;
+ var day = parseInt(match[3], 10) || 1;
+ date = new Date(Date.UTC(year, month, day));
+ // optional time
+ var type = match[7];
+ if (type) {
+ var hours = parseInt(match[4], 10);
+ var minutes = parseInt(match[5], 10);
+ var secFrac = parseFloat(match[6]);
+ var seconds = secFrac | 0;
+ var milliseconds = Math.round(1000 * (secFrac - seconds));
+ date.setUTCHours(hours, minutes, seconds, milliseconds);
+ // check offset
+ if (type !== "Z") {
+ var hoursOffset = parseInt(type, 10);
+ var minutesOffset = parseInt(match[8]) || 0;
+ var offset = -1000 * (60 * (hoursOffset * 60) + minutesOffset * 60);
+ date = new Date(date.getTime() + offset);
+ }
+ }
+ } else {
+ date = new Date("invalid");
+ }
+ }
+ return date;
+ }
+
};
/* ======================================================================
OpenLayers/BaseTypes/Class.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
* Constructor: OpenLayers.Class
- * Base class used to construct all other classes. Includes support for
- * multiple inheritance.
- *
- * This constructor is new in OpenLayers 2.5. At OpenLayers 3.0, the old
- * syntax for creating classes and dealing with inheritance
+ * Base class used to construct all other classes. Includes support for
+ * multiple inheritance.
+ *
+ * This constructor is new in OpenLayers 2.5. At OpenLayers 3.0, the old
+ * syntax for creating classes and dealing with inheritance
* will be removed.
- *
+ *
* To create a new OpenLayers-style class, use the following syntax:
* > var MyClass = OpenLayers.Class(prototype);
*
@@ -2849,30 +3235,31 @@
}
};
var extended = {};
- var parent, initialize;
+ var parent, initialize, Type;
for(var i=0, len=arguments.length; i<len; ++i) {
- if(typeof arguments[i] == "function") {
+ Type = arguments[i];
+ if(typeof Type == "function") {
// make the class passed as the first argument the superclass
if(i == 0 && len > 1) {
- initialize = arguments[i].prototype.initialize;
+ initialize = Type.prototype.initialize;
// replace the initialize method with an empty function,
// because we do not want to create a real instance here
- arguments[i].prototype.initialize = function() {};
+ Type.prototype.initialize = function() {};
// the line below makes sure that the new class has a
// superclass
- extended = new arguments[i];
+ extended = new Type();
// restore the original initialize method
if(initialize === undefined) {
- delete arguments[i].prototype.initialize;
+ delete Type.prototype.initialize;
} else {
- arguments[i].prototype.initialize = initialize;
+ Type.prototype.initialize = initialize;
}
}
// get the prototype of the superclass
- parent = arguments[i].prototype;
+ parent = Type.prototype;
} else {
// in this case we're extending with the prototype
- parent = arguments[i];
+ parent = Type;
}
OpenLayers.Util.extend(extended, parent);
}
@@ -2930,8 +3317,9 @@
OpenLayers/BaseTypes/Size.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -2945,7 +3333,7 @@
* {Number} width
*/
w: 0.0,
-
+
/**
* APIProperty: h
* {Number} height
@@ -2971,7 +3359,7 @@
* Return the string representation of a size object
*
* Returns:
- * {String} The string representation of OpenLayers.Size object.
+ * {String} The string representation of OpenLayers.Size object.
* (ex. <i>"w=55,h=66"</i>)
*/
toString:function() {
@@ -2998,7 +3386,7 @@
* Parameters:
* sz - {<OpenLayers.Size>}
*
- * Returns:
+ * Returns:
* {Boolean} The passed in size has the same h and w properties as this one.
* Note that if sz passed in is null, returns false.
*
@@ -3018,8 +3406,9 @@
OpenLayers/BaseTypes/Bounds.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -3031,7 +3420,7 @@
* Instances of this class represent bounding boxes. Data stored as left,
* bottom, right, top floats. All values are initialized to null, however,
* you should make sure you set them before using the bounds for anything.
- *
+ *
* Possible use case:
* > bounds = new OpenLayers.Bounds();
* > bounds.extend(new OpenLayers.LonLat(4,5));
@@ -3063,7 +3452,7 @@
* {Number} Maximum vertical coordinate.
*/
top: null,
-
+
/**
* Property: centerLonLat
* {<OpenLayers.LonLat>} A cached center location. This should not be
@@ -3106,7 +3495,7 @@
* {<OpenLayers.Bounds>} A fresh copy of the bounds
*/
clone:function() {
- return new OpenLayers.Bounds(this.left, this.bottom,
+ return new OpenLayers.Bounds(this.left, this.bottom,
this.right, this.top);
},
@@ -3119,25 +3508,25 @@
*
* Returns:
* {Boolean} The passed-in bounds object has the same left,
- * right, top, bottom components as this. Note that if bounds
+ * right, top, bottom components as this. Note that if bounds
* passed in is null, returns false.
*/
equals:function(bounds) {
var equals = false;
if (bounds != null) {
- equals = ((this.left == bounds.left) &&
+ equals = ((this.left == bounds.left) &&
(this.right == bounds.right) &&
- (this.top == bounds.top) &&
+ (this.top == bounds.top) &&
(this.bottom == bounds.bottom));
}
return equals;
},
- /**
+ /**
* APIMethod: toString
- *
+ *
* Returns:
- * {String} String representation of bounds object.
+ * {String} String representation of bounds object.
* (ex.<i>"left-bottom=(5,42) right-top=(10,45)"</i>)
*/
toString:function() {
@@ -3148,37 +3537,48 @@
/**
* APIMethod: toArray
*
+ * Parameters:
+ * reverseAxisOrder - {Boolean} Should we reverse the axis order?
+ *
* Returns:
* {Array} array of left, bottom, right, top
*/
- toArray: function() {
- return [this.left, this.bottom, this.right, this.top];
- },
+ toArray: function(reverseAxisOrder) {
+ if (reverseAxisOrder === true) {
+ return [this.bottom, this.left, this.top, this.right];
+ } else {
+ return [this.left, this.bottom, this.right, this.top];
+ }
+ },
- /**
+ /**
* APIMethod: toBBOX
- *
+ *
* Parameters:
* decimal - {Integer} How many significant digits in the bbox coords?
* Default is 6
- *
+ * reverseAxisOrder - {Boolean} Should we reverse the axis order?
+ *
* Returns:
* {String} Simple String representation of bounds object.
* (ex. <i>"5,42,10,45"</i>)
*/
- toBBOX:function(decimal) {
+ toBBOX:function(decimal, reverseAxisOrder) {
if (decimal== null) {
- decimal = 6;
+ decimal = 6;
}
var mult = Math.pow(10, decimal);
- var bbox = Math.round(this.left * mult) / mult + "," +
- Math.round(this.bottom * mult) / mult + "," +
- Math.round(this.right * mult) / mult + "," +
- Math.round(this.top * mult) / mult;
-
- return bbox;
+ var xmin = Math.round(this.left * mult) / mult;
+ var ymin = Math.round(this.bottom * mult) / mult;
+ var xmax = Math.round(this.right * mult) / mult;
+ var ymax = Math.round(this.top * mult) / mult;
+ if (reverseAxisOrder === true) {
+ return ymin + "," + xmin + "," + ymax + "," + xmax;
+ } else {
+ return xmin + "," + ymin + "," + xmax + "," + ymax;
+ }
},
-
+
/**
* APIMethod: toGeometry
* Create a new polygon geometry based on this bounds.
@@ -3197,10 +3597,10 @@
])
]);
},
-
+
/**
* APIMethod: getWidth
- *
+ *
* Returns:
* {Float} The width of the bounds
*/
@@ -3210,7 +3610,7 @@
/**
* APIMethod: getHeight
- *
+ *
* Returns:
* {Float} The height of the bounds (top minus bottom).
*/
@@ -3220,7 +3620,7 @@
/**
* APIMethod: getSize
- *
+ *
* Returns:
* {<OpenLayers.Size>} The size of the box.
*/
@@ -3230,7 +3630,7 @@
/**
* APIMethod: getCenterPixel
- *
+ *
* Returns:
* {<OpenLayers.Pixel>} The center of the bounds in pixel space.
*/
@@ -3241,7 +3641,7 @@
/**
* APIMethod: getCenterLonLat
- *
+ *
* Returns:
* {<OpenLayers.LonLat>} The center of the bounds in map space.
*/
@@ -3256,12 +3656,12 @@
/**
* Method: scale
- * Scales the bounds around a pixel or lonlat. Note that the new
+ * Scales the bounds around a pixel or lonlat. Note that the new
* bounds may return non-integer properties, even if a pixel
- * is passed.
- *
+ * is passed.
+ *
* Parameters:
- * ratio - {Float}
+ * ratio - {Float}
* origin - {<OpenLayers.Pixel> or <OpenLayers.LonLat>}
* Default is center.
*
@@ -3274,9 +3674,7 @@
if(origin == null){
origin = this.getCenterLonLat();
}
-
- var bounds = [];
-
+
var origx,origy;
// get origin coordinates
@@ -3292,17 +3690,17 @@
var bottom = (this.bottom - origy) * ratio + origy;
var right = (this.right - origx) * ratio + origx;
var top = (this.top - origy) * ratio + origy;
-
+
return new OpenLayers.Bounds(left, bottom, right, top);
},
/**
* APIMethod: add
- *
+ *
* Parameters:
* x - {Float}
* y - {Float}
- *
+ *
* Returns:
* {<OpenLayers.Bounds>} A new bounds whose coordinates are the same as
* this, but shifted by the passed-in x and y values.
@@ -3316,13 +3714,13 @@
return new OpenLayers.Bounds(this.left + x, this.bottom + y,
this.right + x, this.top + y);
},
-
+
/**
* APIMethod: extend
* Extend the bounds to include the point, lonlat, or bounds specified.
* Note, this function assumes that left < right and bottom < top.
- *
- * Parameters:
+ *
+ * Parameters:
* object - {Object} Can be LonLat, Point, or Bounds
*/
extend:function(object) {
@@ -3330,7 +3728,7 @@
if (object) {
// clear cached center location
switch(object.CLASS_NAME) {
- case "OpenLayers.LonLat":
+ case "OpenLayers.LonLat":
bounds = new OpenLayers.Bounds(object.lon, object.lat,
object.lon, object.lat);
break;
@@ -3338,12 +3736,12 @@
bounds = new OpenLayers.Bounds(object.x, object.y,
object.x, object.y);
break;
-
- case "OpenLayers.Bounds":
+
+ case "OpenLayers.Bounds":
bounds = object;
break;
}
-
+
if (bounds) {
this.centerLonLat = null;
if ( (this.left == null) || (bounds.left < this.left)) {
@@ -3351,11 +3749,11 @@
}
if ( (this.bottom == null) || (bounds.bottom < this.bottom) ) {
this.bottom = bounds.bottom;
- }
+ }
if ( (this.right == null) || (bounds.right > this.right) ) {
this.right = bounds.right;
}
- if ( (this.top == null) || (bounds.top > this.top) ) {
+ if ( (this.top == null) || (bounds.top > this.top) ) {
this.top = bounds.top;
}
}
@@ -3364,7 +3762,7 @@
/**
* APIMethod: containsLonLat
- *
+ *
* Parameters:
* ll - {<OpenLayers.LonLat>}
* inclusive - {Boolean} Whether or not to include the border.
@@ -3379,7 +3777,7 @@
/**
* APIMethod: containsPixel
- *
+ *
* Parameters:
* px - {<OpenLayers.Pixel>}
* inclusive - {Boolean} Whether or not to include the border. Default is
@@ -3391,10 +3789,10 @@
containsPixel:function(px, inclusive) {
return this.contains(px.x, px.y, inclusive);
},
-
+
/**
* APIMethod: contains
- *
+ *
* Parameters:
* x - {Float}
* y - {Float}
@@ -3420,12 +3818,12 @@
var contains = false;
if (inclusive) {
- contains = ((x >= this.left) && (x <= this.right) &&
+ contains = ((x >= this.left) && (x <= this.right) &&
(y >= this.bottom) && (y <= this.top));
} else {
- contains = ((x > this.left) && (x < this.right) &&
+ contains = ((x > this.left) && (x < this.right) &&
(y > this.bottom) && (y < this.top));
- }
+ }
return contains;
},
@@ -3434,7 +3832,7 @@
* Determine whether the target bounds intersects this bounds. Bounds are
* considered intersecting if any of their edges intersect or if one
* bounds contains the other.
- *
+ *
* Parameters:
* bounds - {<OpenLayers.Bounds>} The target bounds.
* inclusive - {Boolean} Treat coincident borders as intersecting. Default
@@ -3455,7 +3853,7 @@
this.top == bounds.bottom ||
this.bottom == bounds.top
);
-
+
// if the two bounds only touch at an edge, and inclusive is false,
// then the bounds don't *really* intersect.
if (inclusive || !mightTouch) {
@@ -3481,20 +3879,20 @@
}
return intersects;
},
-
+
/**
* APIMethod: containsBounds
* Determine whether the target bounds is contained within this bounds.
- *
+ *
* bounds - {<OpenLayers.Bounds>} The target bounds.
* partial - {Boolean} If any of the target corners is within this bounds
- * consider the bounds contained. Default is false. If true, the
+ * consider the bounds contained. Default is false. If false, the
* entire target bounds must be contained within this bounds.
* inclusive - {Boolean} Treat shared edges as contained. Default is
* true.
*
* Returns:
- * {Boolean} The passed-in bounds object is contained within this bounds.
+ * {Boolean} The passed-in bounds object is contained within this bounds.
*/
containsBounds:function(bounds, partial, inclusive) {
if (partial == null) {
@@ -3507,39 +3905,39 @@
var bottomRight = this.contains(bounds.right, bounds.bottom, inclusive);
var topLeft = this.contains(bounds.left, bounds.top, inclusive);
var topRight = this.contains(bounds.right, bounds.top, inclusive);
-
+
return (partial) ? (bottomLeft || bottomRight || topLeft || topRight)
: (bottomLeft && bottomRight && topLeft && topRight);
},
- /**
+ /**
* APIMethod: determineQuadrant
- *
+ *
* Parameters:
* lonlat - {<OpenLayers.LonLat>}
- *
+ *
* Returns:
* {String} The quadrant ("br" "tr" "tl" "bl") of the bounds in which the
* coordinate lies.
*/
determineQuadrant: function(lonlat) {
-
+
var quadrant = "";
var center = this.getCenterLonLat();
-
+
quadrant += (lonlat.lat < center.lat) ? "b" : "t";
quadrant += (lonlat.lon < center.lon) ? "l" : "r";
-
- return quadrant;
+
+ return quadrant;
},
-
+
/**
* APIMethod: transform
- * Transform the Bounds object from source to dest.
+ * Transform the Bounds object from source to dest.
*
- * Parameters:
- * source - {<OpenLayers.Projection>} Source projection.
- * dest - {<OpenLayers.Projection>} Destination projection.
+ * Parameters:
+ * source - {<OpenLayers.Projection>} Source projection.
+ * dest - {<OpenLayers.Projection>} Destination projection.
*
* Returns:
* {<OpenLayers.Bounds>} Itself, for use in chaining operations.
@@ -3564,68 +3962,68 @@
/**
* APIMethod: wrapDateLine
- *
+ *
* Parameters:
* maxExtent - {<OpenLayers.Bounds>}
* options - {Object} Some possible options are:
- * leftTolerance - {float} Allow for a margin of error
- * with the 'left' value of this
+ * leftTolerance - {float} Allow for a margin of error
+ * with the 'left' value of this
* bound.
* Default is 0.
- * rightTolerance - {float} Allow for a margin of error
- * with the 'right' value of
+ * rightTolerance - {float} Allow for a margin of error
+ * with the 'right' value of
* this bound.
* Default is 0.
- *
+ *
* Returns:
- * {<OpenLayers.Bounds>} A copy of this bounds, but wrapped around the
- * "dateline" (as specified by the borders of
- * maxExtent). Note that this function only returns
- * a different bounds value if this bounds is
- * *entirely* outside of the maxExtent. If this
- * bounds straddles the dateline (is part in/part
- * out of maxExtent), the returned bounds will be
+ * {<OpenLayers.Bounds>} A copy of this bounds, but wrapped around the
+ * "dateline" (as specified by the borders of
+ * maxExtent). Note that this function only returns
+ * a different bounds value if this bounds is
+ * *entirely* outside of the maxExtent. If this
+ * bounds straddles the dateline (is part in/part
+ * out of maxExtent), the returned bounds will be
* merely a copy of this one.
*/
- wrapDateLine: function(maxExtent, options) {
+ wrapDateLine: function(maxExtent, options) {
options = options || {};
-
+
var leftTolerance = options.leftTolerance || 0;
var rightTolerance = options.rightTolerance || 0;
var newBounds = this.clone();
-
+
if (maxExtent) {
//shift right?
- while ( newBounds.left < maxExtent.left &&
- (newBounds.right - rightTolerance) <= maxExtent.left ) {
+ while ( newBounds.left < maxExtent.left &&
+ (newBounds.right - rightTolerance) <= maxExtent.left ) {
newBounds = newBounds.add(maxExtent.getWidth(), 0);
}
//shift left?
- while ( (newBounds.left + leftTolerance) >= maxExtent.right &&
- newBounds.right > maxExtent.right ) {
+ while ( (newBounds.left + leftTolerance) >= maxExtent.right &&
+ newBounds.right > maxExtent.right ) {
newBounds = newBounds.add(-maxExtent.getWidth(), 0);
}
}
-
+
return newBounds;
},
CLASS_NAME: "OpenLayers.Bounds"
});
-/**
+/**
* APIFunction: fromString
- * Alternative constructor that builds a new OpenLayers.Bounds from a
+ * Alternative constructor that builds a new OpenLayers.Bounds from a
* parameter string
- *
- * Parameters:
+ *
+ * Parameters:
* str - {String}Comma-separated bounds string. (ex. <i>"5,42,10,45"</i>)
- *
+ *
* Returns:
- * {<OpenLayers.Bounds>} New bounds object built from the
+ * {<OpenLayers.Bounds>} New bounds object built from the
* passed-in String.
*/
OpenLayers.Bounds.fromString = function(str) {
@@ -3633,11 +4031,11 @@
return OpenLayers.Bounds.fromArray(bounds);
};
-/**
+/**
* APIFunction: fromArray
* Alternative constructor that builds a new OpenLayers.Bounds
* from an array
- *
+ *
* Parameters:
* bbox - {Array(Float)} Array of bounds values (ex. <i>[5,42,10,45]</i>)
*
@@ -3651,13 +4049,13 @@
parseFloat(bbox[3]));
};
-/**
+/**
* APIFunction: fromSize
* Alternative constructor that builds a new OpenLayers.Bounds
* from a size
- *
+ *
* Parameters:
- * size - {<OpenLayers.Size>}
+ * size - {<OpenLayers.Size>}
*
* Returns:
* {<OpenLayers.Bounds>} New bounds object built from the passed-in size.
@@ -3677,24 +4075,25 @@
* quadrant - {String} two character quadrant shortstring
*
* Returns:
- * {String} The opposing quadrant ("br" "tr" "tl" "bl"). For Example, if
- * you pass in "bl" it returns "tr", if you pass in "br" it
+ * {String} The opposing quadrant ("br" "tr" "tl" "bl"). For Example, if
+ * you pass in "bl" it returns "tr", if you pass in "br" it
* returns "tl", etc.
*/
OpenLayers.Bounds.oppositeQuadrant = function(quadrant) {
var opp = "";
-
+
opp += (quadrant.charAt(0) == 't') ? 'b' : 't';
opp += (quadrant.charAt(1) == 'l') ? 'r' : 'l';
-
+
return opp;
};
/* ======================================================================
OpenLayers/BaseTypes/Element.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -3704,10 +4103,10 @@
/**
* APIFunction: visible
- *
- * Parameters:
+ *
+ * Parameters:
* element - {DOMElement}
- *
+ *
* Returns:
* {Boolean} Is the element visible?
*/
@@ -3718,14 +4117,14 @@
/**
* APIFunction: toggle
* Toggle the visibility of element(s) passed in
- *
+ *
* Parameters:
* element - {DOMElement} Actually user can pass any number of elements
*/
toggle: function() {
for (var i=0, len=arguments.length; i<len; i++) {
var element = OpenLayers.Util.getElement(arguments[i]);
- var display = OpenLayers.Element.visible(element) ? 'hide'
+ var display = OpenLayers.Element.visible(element) ? 'hide'
: 'show';
OpenLayers.Element[display](element);
}
@@ -3735,35 +4134,39 @@
/**
* APIFunction: hide
* Hide element(s) passed in
- *
+ *
* Parameters:
* element - {DOMElement} Actually user can pass any number of elements
*/
hide: function() {
for (var i=0, len=arguments.length; i<len; i++) {
var element = OpenLayers.Util.getElement(arguments[i]);
- element.style.display = 'none';
+ if (element) {
+ element.style.display = 'none';
+ }
}
},
/**
* APIFunction: show
* Show element(s) passed in
- *
+ *
* Parameters:
* element - {DOMElement} Actually user can pass any number of elements
*/
show: function() {
for (var i=0, len=arguments.length; i<len; i++) {
var element = OpenLayers.Util.getElement(arguments[i]);
- element.style.display = '';
+ if (element) {
+ element.style.display = '';
+ }
}
},
/**
* APIFunction: remove
* Remove the specified element from the DOM.
- *
+ *
* Parameters:
* element - {DOMElement}
*/
@@ -3774,10 +4177,10 @@
/**
* APIFunction: getHeight
- *
+ *
* Parameters:
* element - {DOMElement}
- *
+ *
* Returns:
* {Integer} The offset height of the element passed in
*/
@@ -3788,12 +4191,13 @@
/**
* APIFunction: getDimensions
- *
+ * *Deprecated*. Returns dimensions of the element passed in.
+ *
* Parameters:
* element - {DOMElement}
- *
+ *
* Returns:
- * {Object} Object with 'width' and 'height' properties which are the
+ * {Object} Object with 'width' and 'height' properties which are the
* dimensions of the element passed in.
*/
getDimensions: function(element) {
@@ -3801,18 +4205,19 @@
if (OpenLayers.Element.getStyle(element, 'display') != 'none') {
return {width: element.offsetWidth, height: element.offsetHeight};
}
-
+
// All *Width and *Height properties give 0 on elements with display none,
// so enable the element temporarily
var els = element.style;
var originalVisibility = els.visibility;
var originalPosition = els.position;
+ var originalDisplay = els.display;
els.visibility = 'hidden';
els.position = 'absolute';
els.display = '';
var originalWidth = element.clientWidth;
var originalHeight = element.clientHeight;
- els.display = 'none';
+ els.display = originalDisplay;
els.position = originalPosition;
els.visibility = originalVisibility;
return {width: originalWidth, height: originalHeight};
@@ -3833,7 +4238,7 @@
var names = element.className;
return (!!names && new RegExp("(^|\\s)" + name + "(\\s|$)").test(names));
},
-
+
/**
* Function: addClass
* Add a CSS class name to an element. Safe where element already has
@@ -3900,11 +4305,11 @@
/**
* APIFunction: getStyle
- *
+ *
* Parameters:
* element - {DOMElement}
* style - {?}
- *
+ *
* Returns:
* {?}
*/
@@ -3915,24 +4320,24 @@
if (element && element.style) {
value = element.style[OpenLayers.String.camelize(style)];
if (!value) {
- if (document.defaultView &&
+ if (document.defaultView &&
document.defaultView.getComputedStyle) {
-
+
var css = document.defaultView.getComputedStyle(element, null);
value = css ? css.getPropertyValue(style) : null;
} else if (element.currentStyle) {
value = element.currentStyle[OpenLayers.String.camelize(style)];
}
}
-
+
var positions = ['left', 'top', 'right', 'bottom'];
if (window.opera &&
(OpenLayers.Util.indexOf(positions,style) != -1) &&
- (OpenLayers.Element.getStyle(element, 'position') == 'static')) {
+ (OpenLayers.Element.getStyle(element, 'position') == 'static')) {
value = 'auto';
}
}
-
+
return value == 'auto' ? null : value;
}
@@ -3941,8 +4346,9 @@
OpenLayers/BaseTypes/LonLat.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -3955,13 +4361,13 @@
*/
OpenLayers.LonLat = OpenLayers.Class({
- /**
+ /**
* APIProperty: lon
* {Float} The x-axis coodinate in map units
*/
lon: 0.0,
-
- /**
+
+ /**
* APIProperty: lat
* {Float} The y-axis coordinate in map units
*/
@@ -3983,51 +4389,51 @@
this.lon = OpenLayers.Util.toFloat(lon);
this.lat = OpenLayers.Util.toFloat(lat);
},
-
+
/**
* Method: toString
* Return a readable string version of the lonlat
*
* Returns:
- * {String} String representation of OpenLayers.LonLat object.
+ * {String} String representation of OpenLayers.LonLat object.
* (ex. <i>"lon=5,lat=42"</i>)
*/
toString:function() {
return ("lon=" + this.lon + ",lat=" + this.lat);
},
- /**
+ /**
* APIMethod: toShortString
- *
+ *
* Returns:
- * {String} Shortened String representation of OpenLayers.LonLat object.
+ * {String} Shortened String representation of OpenLayers.LonLat object.
* (ex. <i>"5, 42"</i>)
*/
toShortString:function() {
return (this.lon + ", " + this.lat);
},
- /**
+ /**
* APIMethod: clone
- *
+ *
* Returns:
- * {<OpenLayers.LonLat>} New OpenLayers.LonLat object with the same lon
+ * {<OpenLayers.LonLat>} New OpenLayers.LonLat object with the same lon
* and lat values
*/
clone:function() {
return new OpenLayers.LonLat(this.lon, this.lat);
},
- /**
+ /**
* APIMethod: add
- *
+ *
* Parameters:
* lon - {Float}
* lat - {Float}
- *
+ *
* Returns:
- * {<OpenLayers.LonLat>} A new OpenLayers.LonLat object with the lon and
- * lat passed-in added to this's.
+ * {<OpenLayers.LonLat>} A new OpenLayers.LonLat object with the lon and
+ * lat passed-in added to this's.
*/
add:function(lon, lat) {
if ( (lon == null) || (lat == null) ) {
@@ -4035,18 +4441,19 @@
OpenLayers.Console.error(msg);
return null;
}
- return new OpenLayers.LonLat(this.lon + lon, this.lat + lat);
+ return new OpenLayers.LonLat(this.lon + OpenLayers.Util.toFloat(lon),
+ this.lat + OpenLayers.Util.toFloat(lat));
},
- /**
+ /**
* APIMethod: equals
- *
+ *
* Parameters:
* ll - {<OpenLayers.LonLat>}
- *
+ *
* Returns:
- * {Boolean} Boolean value indicating whether the passed-in
- * <OpenLayers.LonLat> object has the same lon and lat
+ * {Boolean} Boolean value indicating whether the passed-in
+ * <OpenLayers.LonLat> object has the same lon and lat
* components as this.
* Note: if ll passed in is null, returns false
*/
@@ -4064,9 +4471,9 @@
* Transform the LonLat object from source to dest. This transformation is
* *in place*: if you want a *new* lonlat, use .clone() first.
*
- * Parameters:
- * source - {<OpenLayers.Projection>} Source projection.
- * dest - {<OpenLayers.Projection>} Destination projection.
+ * Parameters:
+ * source - {<OpenLayers.Projection>} Source projection.
+ * dest - {<OpenLayers.Projection>} Destination projection.
*
* Returns:
* {<OpenLayers.LonLat>} Itself, for use in chaining operations.
@@ -4078,64 +4485,64 @@
this.lat = point.y;
return this;
},
-
+
/**
* APIMethod: wrapDateLine
- *
+ *
* Parameters:
* maxExtent - {<OpenLayers.Bounds>}
- *
+ *
* Returns:
- * {<OpenLayers.LonLat>} A copy of this lonlat, but wrapped around the
- * "dateline" (as specified by the borders of
+ * {<OpenLayers.LonLat>} A copy of this lonlat, but wrapped around the
+ * "dateline" (as specified by the borders of
* maxExtent)
*/
- wrapDateLine: function(maxExtent) {
+ wrapDateLine: function(maxExtent) {
var newLonLat = this.clone();
-
+
if (maxExtent) {
//shift right?
while (newLonLat.lon < maxExtent.left) {
newLonLat.lon += maxExtent.getWidth();
- }
-
+ }
+
//shift left?
while (newLonLat.lon > maxExtent.right) {
newLonLat.lon -= maxExtent.getWidth();
- }
+ }
}
-
+
return newLonLat;
},
CLASS_NAME: "OpenLayers.LonLat"
});
-/**
+/**
* Function: fromString
- * Alternative constructor that builds a new <OpenLayers.LonLat> from a
+ * Alternative constructor that builds a new <OpenLayers.LonLat> from a
* parameter string
- *
+ *
* Parameters:
- * str - {String} Comma-separated Lon,Lat coordinate string.
+ * str - {String} Comma-separated Lon,Lat coordinate string.
* (ex. <i>"5,40"</i>)
- *
+ *
* Returns:
- * {<OpenLayers.LonLat>} New <OpenLayers.LonLat> object built from the
+ * {<OpenLayers.LonLat>} New <OpenLayers.LonLat> object built from the
* passed-in String.
*/
OpenLayers.LonLat.fromString = function(str) {
var pair = str.split(",");
- return new OpenLayers.LonLat(parseFloat(pair[0]),
- parseFloat(pair[1]));
+ return new OpenLayers.LonLat(pair[0], pair[1]);
};
/* ======================================================================
OpenLayers/BaseTypes/Pixel.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -4147,7 +4554,7 @@
* This class represents a screen coordinate, in x and y coordinates
*/
OpenLayers.Pixel = OpenLayers.Class({
-
+
/**
* APIProperty: x
* {Number} The x coordinate
@@ -4159,7 +4566,7 @@
* {Number} The y coordinate
*/
y: 0.0,
-
+
/**
* Constructor: OpenLayers.Pixel
* Create a new OpenLayers.Pixel instance
@@ -4175,7 +4582,7 @@
this.x = parseFloat(x);
this.y = parseFloat(y);
},
-
+
/**
* Method: toString
* Cast this object into a string
@@ -4195,9 +4602,9 @@
* {<OpenLayers.Pixel>} A clone pixel
*/
clone:function() {
- return new OpenLayers.Pixel(this.x, this.y);
+ return new OpenLayers.Pixel(this.x, this.y);
},
-
+
/**
* APIMethod: equals
* Determine whether one pixel is equivalent to another
@@ -4226,7 +4633,7 @@
* y - {Integer}
*
* Returns:
- * {<OpenLayers.Pixel>} A new Pixel with this pixel's x&y augmented by the
+ * {<OpenLayers.Pixel>} A new Pixel with this pixel's x&y augmented by the
* values passed in.
*/
add:function(x, y) {
@@ -4240,12 +4647,12 @@
/**
* APIMethod: offset
- *
+ *
* Parameters
* px - {<OpenLayers.Pixel>}
- *
+ *
* Returns:
- * {<OpenLayers.Pixel>} A new Pixel with this pixel's x&y augmented by the
+ * {<OpenLayers.Pixel>} A new Pixel with this pixel's x&y augmented by the
* x&y values of the pixel passed in.
*/
offset:function(px) {
@@ -4262,69 +4669,69 @@
OpenLayers/Icon.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
-
/**
* Class: OpenLayers.Icon
- *
+ *
* The icon represents a graphical icon on the screen. Typically used in
* conjunction with a <OpenLayers.Marker> to represent markers on a screen.
*
- * An icon has a url, size and position. It also contains an offset which
+ * An icon has a url, size and position. It also contains an offset which
* allows the center point to be represented correctly. This can be
* provided either as a fixed offset or a function provided to calculate
- * the desired offset.
- *
+ * the desired offset.
+ *
*/
OpenLayers.Icon = OpenLayers.Class({
-
- /**
- * Property: url
+
+ /**
+ * Property: url
* {String} image url
*/
url: null,
-
- /**
- * Property: size
- * {<OpenLayers.Size>}
+
+ /**
+ * Property: size
+ * {<OpenLayers.Size>}
*/
size: null,
- /**
- * Property: offset
+ /**
+ * Property: offset
* {<OpenLayers.Pixel>} distance in pixels to offset the image when being rendered
*/
- offset: null,
-
- /**
- * Property: calculateOffset
- * {<OpenLayers.Pixel>} Function to calculate the offset (based on the size)
+ offset: null,
+
+ /**
+ * Property: calculateOffset
+ * {<OpenLayers.Pixel>} Function to calculate the offset (based on the size)
*/
- calculateOffset: null,
-
- /**
- * Property: imageDiv
- * {DOMElement}
+ calculateOffset: null,
+
+ /**
+ * Property: imageDiv
+ * {DOMElement}
*/
imageDiv: null,
- /**
- * Property: px
- * {<OpenLayers.Pixel>}
+ /**
+ * Property: px
+ * {<OpenLayers.Pixel>}
*/
px: null,
-
- /**
+
+ /**
* Constructor: OpenLayers.Icon
- * Creates an icon, which is an image tag in a div.
+ * Creates an icon, which is an image tag in a div.
*
- * url - {String}
- * size - {<OpenLayers.Size>}
+ * url - {String}
+ * size - {<OpenLayers.Size>}
* offset - {<OpenLayers.Pixel>}
- * calculateOffset - {Function}
+ * calculateOffset - {Function}
*/
initialize: function(url, size, offset, calculateOffset) {
this.url = url;
@@ -4335,39 +4742,39 @@
var id = OpenLayers.Util.createUniqueID("OL_Icon_");
this.imageDiv = OpenLayers.Util.createAlphaImageDiv(id);
},
-
- /**
+
+ /**
* Method: destroy
- * Nullify references and remove event listeners to prevent circular
+ * Nullify references and remove event listeners to prevent circular
* references and memory leaks
*/
destroy: function() {
// erase any drawn elements
this.erase();
- OpenLayers.Event.stopObservingElement(this.imageDiv.firstChild);
+ OpenLayers.Event.stopObservingElement(this.imageDiv.firstChild);
this.imageDiv.innerHTML = "";
this.imageDiv = null;
},
- /**
+ /**
* Method: clone
- *
+ *
* Returns:
* {<OpenLayers.Icon>} A fresh copy of the icon.
*/
clone: function() {
- return new OpenLayers.Icon(this.url,
- this.size,
- this.offset,
+ return new OpenLayers.Icon(this.url,
+ this.size,
+ this.offset,
this.calculateOffset);
},
-
+
/**
* Method: setSize
- *
+ *
* Parameters:
- * size - {<OpenLayers.Size>}
+ * size - {<OpenLayers.Size>}
*/
setSize: function(size) {
if (size != null) {
@@ -4375,12 +4782,12 @@
}
this.draw();
},
-
+
/**
* Method: setUrl
- *
+ *
* Parameters:
- * url - {String}
+ * url - {String}
*/
setUrl: function(url) {
if (url != null) {
@@ -4389,28 +4796,28 @@
this.draw();
},
- /**
+ /**
* Method: draw
* Move the div to the given pixel.
- *
+ *
* Parameters:
- * px - {<OpenLayers.Pixel>}
- *
+ * px - {<OpenLayers.Pixel>}
+ *
* Returns:
* {DOMElement} A new DOM Image of this icon set at the location passed-in
*/
draw: function(px) {
- OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv,
- null,
- null,
- this.size,
- this.url,
+ OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv,
+ null,
+ null,
+ this.size,
+ this.url,
"absolute");
this.moveTo(px);
return this.imageDiv;
- },
+ },
- /**
+ /**
* Method: erase
* Erase the underlying image element.
*
@@ -4419,27 +4826,27 @@
if (this.imageDiv != null && this.imageDiv.parentNode != null) {
OpenLayers.Element.remove(this.imageDiv);
}
- },
-
- /**
+ },
+
+ /**
* Method: setOpacity
* Change the icon's opacity
*
* Parameters:
- * opacity - {float}
+ * opacity - {float}
*/
setOpacity: function(opacity) {
- OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv, null, null, null,
+ OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv, null, null, null,
null, null, null, null, opacity);
},
-
+
/**
* Method: moveTo
* move icon to passed in px.
*
* Parameters:
- * px - {<OpenLayers.Pixel>}
+ * px - {<OpenLayers.Pixel>}
*/
moveTo: function (px) {
//if no px passed in, use stored location
@@ -4452,39 +4859,39 @@
this.display(false);
} else {
if (this.calculateOffset) {
- this.offset = this.calculateOffset(this.size);
+ this.offset = this.calculateOffset(this.size);
}
var offsetPx = this.px.offset(this.offset);
OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv, null, offsetPx);
}
}
},
-
- /**
+
+ /**
* Method: display
* Hide or show the icon
*
* Parameters:
- * display - {Boolean}
+ * display - {Boolean}
*/
display: function(display) {
- this.imageDiv.style.display = (display) ? "" : "none";
+ this.imageDiv.style.display = (display) ? "" : "none";
},
+
-
/**
* APIMethod: isDrawn
- *
+ *
* Returns:
* {Boolean} Whether or not the icon is drawn.
*/
isDrawn: function() {
// nodeType 11 for ie, whose nodes *always* have a parentNode
// (of type document fragment)
- var isDrawn = (this.imageDiv && this.imageDiv.parentNode &&
- (this.imageDiv.parentNode.nodeType != 11));
+ var isDrawn = (this.imageDiv && this.imageDiv.parentNode &&
+ (this.imageDiv.parentNode.nodeType != 11));
- return isDrawn;
+ return isDrawn;
},
CLASS_NAME: "OpenLayers.Icon"
@@ -4493,112 +4900,113 @@
OpenLayers/Popup.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
* Class: OpenLayers.Popup
* A popup is a small div that can opened and closed on the map.
- * Typically opened in response to clicking on a marker.
+ * Typically opened in response to clicking on a marker.
* See <OpenLayers.Marker>. Popup's don't require their own
* layer and are added the the map using the <OpenLayers.Map.addPopup>
* method.
*
* Example:
* (code)
- * popup = new OpenLayers.Popup("chicken",
+ * popup = new OpenLayers.Popup("chicken",
* new OpenLayers.LonLat(5,40),
* new OpenLayers.Size(200,200),
* "example popup",
* true);
- *
+ *
* map.addPopup(popup);
* (end)
*/
OpenLayers.Popup = OpenLayers.Class({
- /**
- * Property: events
- * {<OpenLayers.Events>} custom event manager
+ /**
+ * Property: events
+ * {<OpenLayers.Events>} custom event manager
*/
events: null,
-
+
/** Property: id
* {String} the unique identifier assigned to this popup.
*/
id: "",
- /**
- * Property: lonlat
+ /**
+ * Property: lonlat
* {<OpenLayers.LonLat>} the position of this popup on the map
*/
lonlat: null,
- /**
- * Property: div
+ /**
+ * Property: div
* {DOMElement} the div that contains this popup.
*/
div: null,
- /**
- * Property: contentSize
+ /**
+ * Property: contentSize
* {<OpenLayers.Size>} the width and height of the content.
*/
- contentSize: null,
+ contentSize: null,
- /**
- * Property: size
+ /**
+ * Property: size
* {<OpenLayers.Size>} the width and height of the popup.
*/
- size: null,
+ size: null,
- /**
- * Property: contentHTML
+ /**
+ * Property: contentHTML
* {String} An HTML string for this popup to display.
*/
contentHTML: null,
-
- /**
- * Property: backgroundColor
+
+ /**
+ * Property: backgroundColor
* {String} the background color used by the popup.
*/
backgroundColor: "",
-
- /**
- * Property: opacity
+
+ /**
+ * Property: opacity
* {float} the opacity of this popup (between 0.0 and 1.0)
*/
opacity: "",
- /**
- * Property: border
+ /**
+ * Property: border
* {String} the border size of the popup. (eg 2px)
*/
border: "",
-
- /**
- * Property: contentDiv
+
+ /**
+ * Property: contentDiv
* {DOMElement} a reference to the element that holds the content of
* the div.
*/
contentDiv: null,
-
- /**
- * Property: groupDiv
+
+ /**
+ * Property: groupDiv
* {DOMElement} First and only child of 'div'. The group Div contains the
* 'contentDiv' and the 'closeDiv'.
*/
groupDiv: null,
- /**
+ /**
* Property: closeDiv
* {DOMElement} the optional closer image
*/
closeDiv: null,
- /**
+ /**
* APIProperty: autoSize
* {Boolean} Resize the popup to auto-fit the contents.
* Default is false.
@@ -4617,40 +5025,40 @@
*/
maxSize: null,
- /**
+ /**
* Property: displayClass
* {String} The CSS class of the popup.
*/
displayClass: "olPopup",
- /**
+ /**
* Property: contentDisplayClass
* {String} The CSS class of the popup content div.
*/
contentDisplayClass: "olPopupContent",
- /**
- * Property: padding
- * {int or <OpenLayers.Bounds>} An extra opportunity to specify internal
+ /**
+ * Property: padding
+ * {int or <OpenLayers.Bounds>} An extra opportunity to specify internal
* padding of the content div inside the popup. This was originally
- * confused with the css padding as specified in style.css's
+ * confused with the css padding as specified in style.css's
* 'olPopupContent' class. We would like to get rid of this altogether,
* except that it does come in handy for the framed and anchoredbubble
- * popups, who need to maintain yet another barrier between their
- * content and the outer border of the popup itself.
- *
- * Note that in order to not break API, we must continue to support
- * this property being set as an integer. Really, though, we'd like to
+ * popups, who need to maintain yet another barrier between their
+ * content and the outer border of the popup itself.
+ *
+ * Note that in order to not break API, we must continue to support
+ * this property being set as an integer. Really, though, we'd like to
* have this specified as a Bounds object so that user can specify
* distinct left, top, right, bottom paddings. With the 3.0 release
* we can make this only a bounds.
*/
padding: 0,
- /**
+ /**
* Property: disableFirefoxOverflowHack
- * {Boolean} The hack for overflow in Firefox causes all elements
- * to be re-drawn, which causes Flash elements to be
+ * {Boolean} The hack for overflow in Firefox causes all elements
+ * to be re-drawn, which causes Flash elements to be
* re-initialized, which is troublesome.
* With this property the hack can be disabled.
*/
@@ -4658,8 +5066,8 @@
/**
* Method: fixPadding
- * To be removed in 3.0, this function merely helps us to deal with the
- * case where the user may have set an integer value for padding,
+ * To be removed in 3.0, this function merely helps us to deal with the
+ * case where the user may have set an integer value for padding,
* instead of an <OpenLayers.Bounds> object.
*/
fixPadding: function() {
@@ -4677,17 +5085,17 @@
* Default is false.
*/
panMapIfOutOfView: false,
-
+
/**
- * APIProperty: keepInMap
- * {Boolean} If panMapIfOutOfView is false, and this property is true,
+ * APIProperty: keepInMap
+ * {Boolean} If panMapIfOutOfView is false, and this property is true,
* contrain the popup such that it always fits in the available map
* space. By default, this is not set on the base class. If you are
* creating popups that are near map edges and not allowing pannning,
* and especially if you have a popup which has a
* fixedRelativePosition, setting this to false may be a smart thing to
* do. Subclasses may want to override this setting.
- *
+ *
* Default is false.
*/
keepInMap: false,
@@ -4698,24 +5106,24 @@
* Default is false.
*/
closeOnMove: false,
-
- /**
- * Property: map
+
+ /**
+ * Property: map
* {<OpenLayers.Map>} this gets set in Map.js when the popup is added to the map
*/
map: null,
- /**
+ /**
* Constructor: OpenLayers.Popup
* Create a popup.
- *
- * Parameters:
+ *
+ * Parameters:
* id - {String} a unqiue identifier for this popup. If null is passed
- * an identifier will be automatically generated.
+ * an identifier will be automatically generated.
* lonlat - {<OpenLayers.LonLat>} The position on the map the popup will
* be shown.
* contentSize - {<OpenLayers.Size>} The size of the content.
- * contentHTML - {String} An HTML string to display inside the
+ * contentHTML - {String} An HTML string to display inside the
* popup.
* closeBox - {Boolean} Whether to display a close box inside
* the popup.
@@ -4729,28 +5137,28 @@
this.id = id;
this.lonlat = lonlat;
- this.contentSize = (contentSize != null) ? contentSize
+ this.contentSize = (contentSize != null) ? contentSize
: new OpenLayers.Size(
OpenLayers.Popup.WIDTH,
OpenLayers.Popup.HEIGHT);
- if (contentHTML != null) {
+ if (contentHTML != null) {
this.contentHTML = contentHTML;
}
this.backgroundColor = OpenLayers.Popup.COLOR;
this.opacity = OpenLayers.Popup.OPACITY;
this.border = OpenLayers.Popup.BORDER;
- this.div = OpenLayers.Util.createDiv(this.id, null, null,
+ this.div = OpenLayers.Util.createDiv(this.id, null, null,
null, null, null, "hidden");
this.div.className = this.displayClass;
-
+
var groupDivId = this.id + "_GroupDiv";
- this.groupDiv = OpenLayers.Util.createDiv(groupDivId, null, null,
+ this.groupDiv = OpenLayers.Util.createDiv(groupDivId, null, null,
null, "relative", null,
"hidden");
var id = this.div.id + "_contentDiv";
- this.contentDiv = OpenLayers.Util.createDiv(id, null, this.contentSize.clone(),
+ this.contentDiv = OpenLayers.Util.createDiv(id, null, this.contentSize.clone(),
null, "relative");
this.contentDiv.className = this.contentDisplayClass;
this.groupDiv.appendChild(this.contentDiv);
@@ -4758,12 +5166,12 @@
if (closeBox) {
this.addCloseBox(closeBoxCallback);
- }
+ }
this.registerEvents();
},
- /**
+ /**
* Method: destroy
* nullify references to prevent circular references and memory leaks
*/
@@ -4773,24 +5181,24 @@
this.lonlat = null;
this.size = null;
this.contentHTML = null;
-
+
this.backgroundColor = null;
this.opacity = null;
this.border = null;
-
+
if (this.closeOnMove && this.map) {
this.map.events.unregister("movestart", this, this.hide);
}
this.events.destroy();
this.events = null;
-
+
if (this.closeDiv) {
- OpenLayers.Event.stopObservingElement(this.closeDiv);
+ OpenLayers.Event.stopObservingElement(this.closeDiv);
this.groupDiv.removeChild(this.closeDiv);
}
this.closeDiv = null;
-
+
this.div.removeChild(this.groupDiv);
this.groupDiv = null;
@@ -4799,7 +5207,7 @@
}
this.map = null;
this.div = null;
-
+
this.autoSize = null;
this.minSize = null;
this.maxSize = null;
@@ -4807,13 +5215,13 @@
this.panMapIfOutOfView = null;
},
- /**
+ /**
* Method: draw
* Constructs the elements that make up the popup.
*
* Parameters:
* px - {<OpenLayers.Pixel>} the position the popup in pixels.
- *
+ *
* Returns:
* {DOMElement} Reference to a div that contains the drawn popup
*/
@@ -4824,12 +5232,12 @@
}
}
- // this assumes that this.map already exists, which is okay because
+ // this assumes that this.map already exists, which is okay because
// this.draw is only called once the popup has been added to the map.
if (this.closeOnMove) {
this.map.events.register("movestart", this, this.hide);
}
-
+
//listen to movestart, moveend to disable overflow (FF bug)
if (!this.disableFirefoxOverflowHack && OpenLayers.Util.getBrowserName() == 'firefox') {
this.map.events.register("movestart", this, function() {
@@ -4859,33 +5267,33 @@
this.setOpacity();
this.setBorder();
this.setContentHTML();
-
+
if (this.panMapIfOutOfView) {
this.panIntoView();
- }
+ }
return this.div;
},
- /**
+ /**
* Method: updatePosition
- * if the popup has a lonlat and its map members set,
+ * if the popup has a lonlat and its map members set,
* then have it move itself to its proper position
*/
updatePosition: function() {
if ((this.lonlat) && (this.map)) {
var px = this.map.getLayerPxFromLonLat(this.lonlat);
if (px) {
- this.moveTo(px);
- }
+ this.moveTo(px);
+ }
}
},
/**
* Method: moveTo
- *
+ *
* Parameters:
- * px - {<OpenLayers.Pixel>} the top and left position of the popup div.
+ * px - {<OpenLayers.Pixel>} the top and left position of the popup div.
*/
moveTo: function(px) {
if ((px != null) && (this.div != null)) {
@@ -4897,7 +5305,7 @@
/**
* Method: visible
*
- * Returns:
+ * Returns:
* {Boolean} Boolean indicating whether or not the popup is visible
*/
visible: function() {
@@ -4925,7 +5333,7 @@
if (this.panMapIfOutOfView) {
this.panIntoView();
- }
+ }
},
/**
@@ -4938,17 +5346,17 @@
/**
* Method: setSize
- * Used to adjust the size of the popup.
+ * Used to adjust the size of the popup.
*
* Parameters:
- * contentSize - {<OpenLayers.Size>} the new size for the popup's
+ * contentSize - {<OpenLayers.Size>} the new size for the popup's
* contents div (in pixels).
*/
- setSize:function(contentSize) {
- this.size = contentSize.clone();
-
- // if our contentDiv has a css 'padding' set on it by a stylesheet, we
- // must add that to the desired "size".
+ setSize:function(contentSize) {
+ this.size = contentSize.clone();
+
+ // if our contentDiv has a css 'padding' set on it by a stylesheet, we
+ // must add that to the desired "size".
var contentDivPadding = this.getContentDivPadding();
var wPadding = contentDivPadding.left + contentDivPadding.right;
var hPadding = contentDivPadding.top + contentDivPadding.bottom;
@@ -4964,18 +5372,18 @@
wPadding += closeDivWidth + contentDivPadding.right;
}
- //increase size of the main popup div to take into account the
- // users's desired padding and close div.
+ //increase size of the main popup div to take into account the
+ // users's desired padding and close div.
this.size.w += wPadding;
this.size.h += hPadding;
- //now if our browser is IE, we need to actually make the contents
- // div itself bigger to take its own padding into effect. this makes
+ //now if our browser is IE, we need to actually make the contents
+ // div itself bigger to take its own padding into effect. this makes
// me want to shoot someone, but so it goes.
if (OpenLayers.Util.getBrowserName() == "msie") {
- this.contentSize.w +=
+ this.contentSize.w +=
contentDivPadding.left + contentDivPadding.right;
- this.contentSize.h +=
+ this.contentSize.h +=
contentDivPadding.bottom + contentDivPadding.top;
}
@@ -4987,26 +5395,26 @@
this.contentDiv.style.width = contentSize.w + "px";
this.contentDiv.style.height = contentSize.h + "px";
}
- },
+ },
/**
* APIMethod: updateSize
- * Auto size the popup so that it precisely fits its contents (as
+ * Auto size the popup so that it precisely fits its contents (as
* determined by this.contentDiv.innerHTML). Popup size will, of
* course, be limited by the available space on the current map
*/
updateSize: function() {
-
+
// determine actual render dimensions of the contents by putting its
// contents into a fake contentDiv (for the CSS) and then measuring it
- var preparedHTML = "<div class='" + this.contentDisplayClass+ "'>" +
- this.contentDiv.innerHTML +
+ var preparedHTML = "<div class='" + this.contentDisplayClass+ "'>" +
+ this.contentDiv.innerHTML +
"</div>";
-
+
var containerElement = (this.map) ? this.map.layerContainerDiv
- : document.body;
+ : document.body;
var realSize = OpenLayers.Util.getRenderedDimensions(
- preparedHTML, null, {
+ preparedHTML, null, {
displayClass: this.displayClass,
containerElement: containerElement
}
@@ -5017,25 +5425,25 @@
var newSize = null;
if (safeSize.equals(realSize)) {
- //real size of content is small enough to fit on the map,
+ //real size of content is small enough to fit on the map,
// so we use real size.
newSize = realSize;
} else {
- //make a new OL.Size object with the clipped dimensions
+ //make a new OL.Size object with the clipped dimensions
// set or null if not clipped.
var fixedSize = new OpenLayers.Size();
fixedSize.w = (safeSize.w < realSize.w) ? safeSize.w : null;
fixedSize.h = (safeSize.h < realSize.h) ? safeSize.h : null;
-
+
if (fixedSize.w && fixedSize.h) {
- //content is too big in both directions, so we will use
- // max popup size (safeSize), knowing well that it will
- // overflow both ways.
+ //content is too big in both directions, so we will use
+ // max popup size (safeSize), knowing well that it will
+ // overflow both ways.
newSize = safeSize;
} else {
- //content is clipped in only one direction, so we need to
+ //content is clipped in only one direction, so we need to
// run getRenderedDimensions() again with a fixed dimension
var clippedSize = OpenLayers.Util.getRenderedDimensions(
preparedHTML, fixedSize, {
@@ -5043,17 +5451,17 @@
containerElement: containerElement
}
);
-
- //if the clipped size is still the same as the safeSize,
- // that means that our content must be fixed in the
- // offending direction. If overflow is 'auto', this means
- // we are going to have a scrollbar for sure, so we must
+
+ //if the clipped size is still the same as the safeSize,
+ // that means that our content must be fixed in the
+ // offending direction. If overflow is 'auto', this means
+ // we are going to have a scrollbar for sure, so we must
// adjust for that.
//
var currentOverflow = OpenLayers.Element.getStyle(
this.contentDiv, "overflow"
);
- if ( (currentOverflow != "hidden") &&
+ if ( (currentOverflow != "hidden") &&
(clippedSize.equals(safeSize)) ) {
var scrollBar = OpenLayers.Util.getScrollbarWidth();
if (fixedSize.w) {
@@ -5062,12 +5470,12 @@
clippedSize.w += scrollBar;
}
}
-
+
newSize = this.getSafeContentSize(clippedSize);
}
- }
- this.setSize(newSize);
- },
+ }
+ this.setSize(newSize);
+ },
/**
* Method: setBackgroundColor
@@ -5076,28 +5484,28 @@
* Parameters:
* color - {String} the background color. eg "#FFBBBB"
*/
- setBackgroundColor:function(color) {
+ setBackgroundColor:function(color) {
if (color != undefined) {
- this.backgroundColor = color;
+ this.backgroundColor = color;
}
-
+
if (this.div != null) {
this.div.style.backgroundColor = this.backgroundColor;
}
- },
-
+ },
+
/**
* Method: setOpacity
* Sets the opacity of the popup.
- *
+ *
* Parameters:
- * opacity - {float} A value between 0.0 (transparent) and 1.0 (solid).
+ * opacity - {float} A value between 0.0 (transparent) and 1.0 (solid).
*/
- setOpacity:function(opacity) {
+ setOpacity:function(opacity) {
if (opacity != undefined) {
- this.opacity = opacity;
+ this.opacity = opacity;
}
-
+
if (this.div != null) {
// for Mozilla and Safari
this.div.style.opacity = this.opacity;
@@ -5105,25 +5513,25 @@
// for IE
this.div.style.filter = 'alpha(opacity=' + this.opacity*100 + ')';
}
- },
-
+ },
+
/**
* Method: setBorder
* Sets the border style of the popup.
*
* Parameters:
- * border - {String} The border style value. eg 2px
+ * border - {String} The border style value. eg 2px
*/
- setBorder:function(border) {
+ setBorder:function(border) {
if (border != undefined) {
this.border = border;
}
-
+
if (this.div != null) {
this.div.style.border = this.border;
}
- },
-
+ },
+
/**
* Method: setContentHTML
* Allows the user to set the HTML content of the popup.
@@ -5136,15 +5544,15 @@
if (contentHTML != null) {
this.contentHTML = contentHTML;
}
-
- if ((this.contentDiv != null) &&
+
+ if ((this.contentDiv != null) &&
(this.contentHTML != null) &&
(this.contentHTML != this.contentDiv.innerHTML)) {
-
+
this.contentDiv.innerHTML = this.contentHTML;
-
+
if (this.autoSize) {
-
+
//if popup has images, listen for when they finish
// loading and resize accordingly
this.registerImageListeners();
@@ -5152,31 +5560,31 @@
//auto size the popup to its current contents
this.updateSize();
}
- }
+ }
},
-
+
/**
* Method: registerImageListeners
* Called when an image contained by the popup loaded. this function
* updates the popup size, then unregisters the image load listener.
- */
- registerImageListeners: function() {
+ */
+ registerImageListeners: function() {
- // As the images load, this function will call updateSize() to
+ // As the images load, this function will call updateSize() to
// resize the popup to fit the content div (which presumably is now
// bigger than when the image was not loaded).
- //
+ //
// If the 'panMapIfOutOfView' property is set, we will pan the newly
// resized popup back into view.
- //
- // Note that this function, when called, will have 'popup' and
+ //
+ // Note that this function, when called, will have 'popup' and
// 'img' properties in the context.
//
var onImgLoad = function() {
-
+
this.popup.updateSize();
-
+
if ( this.popup.visible() && this.popup.panMapIfOutOfView ) {
this.popup.panIntoView();
}
@@ -5184,12 +5592,12 @@
OpenLayers.Event.stopObserving(
this.img, "load", this.img._onImageLoad
);
-
+
};
- //cycle through the images and if their size is 0x0, that means that
- // they haven't been loaded yet, so we attach the listener, which
- // will fire when the images finish loading and will resize the
+ //cycle through the images and if their size is 0x0, that means that
+ // they haven't been loaded yet, so we attach the listener, which
+ // will fire when the images finish loading and will resize the
// popup accordingly to its new size.
var images = this.contentDiv.getElementsByTagName("img");
for (var i = 0, len = images.length; i < len; i++) {
@@ -5206,27 +5614,27 @@
img._onImgLoad = OpenLayers.Function.bind(onImgLoad, context);
OpenLayers.Event.observe(img, 'load', img._onImgLoad);
- }
- }
+ }
+ }
},
/**
* APIMethod: getSafeContentSize
- *
+ *
* Parameters:
* size - {<OpenLayers.Size>} Desired size to make the popup.
- *
+ *
* Returns:
* {<OpenLayers.Size>} A size to make the popup which is neither smaller
- * than the specified minimum size, nor bigger than the maximum
+ * than the specified minimum size, nor bigger than the maximum
* size (which is calculated relative to the size of the viewport).
*/
getSafeContentSize: function(size) {
var safeContentSize = size.clone();
- // if our contentDiv has a css 'padding' set on it by a stylesheet, we
- // must add that to the desired "size".
+ // if our contentDiv has a css 'padding' set on it by a stylesheet, we
+ // must add that to the desired "size".
var contentDivPadding = this.getContentDivPadding();
var wPadding = contentDivPadding.left + contentDivPadding.right;
var hPadding = contentDivPadding.top + contentDivPadding.bottom;
@@ -5243,25 +5651,25 @@
// prevent the popup from being smaller than a specified minimal size
if (this.minSize) {
- safeContentSize.w = Math.max(safeContentSize.w,
+ safeContentSize.w = Math.max(safeContentSize.w,
(this.minSize.w - wPadding));
- safeContentSize.h = Math.max(safeContentSize.h,
+ safeContentSize.h = Math.max(safeContentSize.h,
(this.minSize.h - hPadding));
}
// prevent the popup from being bigger than a specified maximum size
if (this.maxSize) {
- safeContentSize.w = Math.min(safeContentSize.w,
+ safeContentSize.w = Math.min(safeContentSize.w,
(this.maxSize.w - wPadding));
- safeContentSize.h = Math.min(safeContentSize.h,
+ safeContentSize.h = Math.min(safeContentSize.h,
(this.maxSize.h - hPadding));
}
-
- //make sure the desired size to set doesn't result in a popup that
+
+ //make sure the desired size to set doesn't result in a popup that
// is bigger than the map's viewport.
//
if (this.map && this.map.size) {
-
+
var extraX = 0, extraY = 0;
if (this.keepInMap && !this.panMapIfOutOfView) {
var px = this.map.getPixelFromLonLat(this.lonlat);
@@ -5282,39 +5690,39 @@
extraX = px.x;
extraY = px.y;
break;
- default:
+ default:
extraX = px.x;
extraY = this.map.size.h - px.y;
break;
}
- }
-
- var maxY = this.map.size.h -
- this.map.paddingForPopups.top -
- this.map.paddingForPopups.bottom -
+ }
+
+ var maxY = this.map.size.h -
+ this.map.paddingForPopups.top -
+ this.map.paddingForPopups.bottom -
hPadding - extraY;
-
- var maxX = this.map.size.w -
- this.map.paddingForPopups.left -
- this.map.paddingForPopups.right -
+
+ var maxX = this.map.size.w -
+ this.map.paddingForPopups.left -
+ this.map.paddingForPopups.right -
wPadding - extraX;
-
+
safeContentSize.w = Math.min(safeContentSize.w, maxX);
safeContentSize.h = Math.min(safeContentSize.h, maxY);
}
-
+
return safeContentSize;
},
-
+
/**
* Method: getContentDivPadding
- * Glorious, oh glorious hack in order to determine the css 'padding' of
- * the contentDiv. IE/Opera return null here unless we actually add the
- * popup's main 'div' element (which contains contentDiv) to the DOM.
- * So we make it invisible and then add it to the document temporarily.
+ * Glorious, oh glorious hack in order to determine the css 'padding' of
+ * the contentDiv. IE/Opera return null here unless we actually add the
+ * popup's main 'div' element (which contains contentDiv) to the DOM.
+ * So we make it invisible and then add it to the document temporarily.
*
- * Once we've taken the padding readings we need, we then remove it
- * from the DOM (it will actually get added to the DOM in
+ * Once we've taken the padding readings we need, we then remove it
+ * from the DOM (it will actually get added to the DOM in
* Map.js's addPopup)
*
* Returns:
@@ -5326,27 +5734,27 @@
var contentDivPadding = this._contentDivPadding;
if (!contentDivPadding) {
- if (this.div.parentNode == null) {
- //make the div invisible and add it to the page
- this.div.style.display = "none";
- document.body.appendChild(this.div);
- }
-
- //read the padding settings from css, put them in an OL.Bounds
+ if (this.div.parentNode == null) {
+ //make the div invisible and add it to the page
+ this.div.style.display = "none";
+ document.body.appendChild(this.div);
+ }
+
+ //read the padding settings from css, put them in an OL.Bounds
contentDivPadding = new OpenLayers.Bounds(
OpenLayers.Element.getStyle(this.contentDiv, "padding-left"),
OpenLayers.Element.getStyle(this.contentDiv, "padding-bottom"),
OpenLayers.Element.getStyle(this.contentDiv, "padding-right"),
OpenLayers.Element.getStyle(this.contentDiv, "padding-top")
);
-
+
//cache the value
this._contentDivPadding = contentDivPadding;
if (this.div.parentNode == document.body) {
- //remove the div from the page and make it visible again
- document.body.removeChild(this.div);
- this.div.style.display = "";
+ //remove the div from the page and make it visible again
+ document.body.removeChild(this.div);
+ this.div.style.display = "";
}
}
return contentDivPadding;
@@ -5354,7 +5762,7 @@
/**
* Method: addCloseBox
- *
+ *
* Parameters:
* callback - {Function} The callback to be called when the close button
* is clicked.
@@ -5364,12 +5772,12 @@
this.closeDiv = OpenLayers.Util.createDiv(
this.id + "_close", null, new OpenLayers.Size(17, 17)
);
- this.closeDiv.className = "olPopupCloseBox";
-
+ this.closeDiv.className = "olPopupCloseBox";
+
// use the content div's css padding to determine if we should
// padd the close div
var contentDivPadding = this.getContentDivPadding();
-
+
this.closeDiv.style.right = contentDivPadding.right + "px";
this.closeDiv.style.top = contentDivPadding.top + "px";
this.groupDiv.appendChild(this.closeDiv);
@@ -5378,7 +5786,7 @@
this.hide();
OpenLayers.Event.stop(e);
};
- OpenLayers.Event.observe(this.closeDiv, "click",
+ OpenLayers.Event.observe(this.closeDiv, "click",
OpenLayers.Function.bindAsEventListener(closePopup, this));
},
@@ -5387,58 +5795,58 @@
* Pans the map such that the popup is totaly viewable (if necessary)
*/
panIntoView: function() {
-
+
var mapSize = this.map.getSize();
-
- //start with the top left corner of the popup, in px,
+
+ //start with the top left corner of the popup, in px,
// relative to the viewport
var origTL = this.map.getViewPortPxFromLayerPx( new OpenLayers.Pixel(
parseInt(this.div.style.left),
parseInt(this.div.style.top)
));
var newTL = origTL.clone();
-
+
//new left (compare to margins, using this.size to calculate right)
if (origTL.x < this.map.paddingForPopups.left) {
newTL.x = this.map.paddingForPopups.left;
- } else
+ } else
if ( (origTL.x + this.size.w) > (mapSize.w - this.map.paddingForPopups.right)) {
newTL.x = mapSize.w - this.map.paddingForPopups.right - this.size.w;
}
-
+
//new top (compare to margins, using this.size to calculate bottom)
if (origTL.y < this.map.paddingForPopups.top) {
newTL.y = this.map.paddingForPopups.top;
- } else
+ } else
if ( (origTL.y + this.size.h) > (mapSize.h - this.map.paddingForPopups.bottom)) {
newTL.y = mapSize.h - this.map.paddingForPopups.bottom - this.size.h;
}
-
+
var dx = origTL.x - newTL.x;
var dy = origTL.y - newTL.y;
-
+
this.map.pan(dx, dy);
},
- /**
+ /**
* Method: registerEvents
* Registers events on the popup.
*
- * Do this in a separate function so that subclasses can
+ * Do this in a separate function so that subclasses can
* choose to override it if they wish to deal differently
* with mouse events
- *
+ *
* Note in the following handler functions that some special
- * care is needed to deal correctly with mousing and popups.
- *
+ * care is needed to deal correctly with mousing and popups.
+ *
* Because the user might select the zoom-rectangle option and
* then drag it over a popup, we need a safe way to allow the
* mousemove and mouseup events to pass through the popup when
* they are initiated from outside.
- *
+ *
* Otherwise, we want to essentially kill the event propagation
- * for all other events, though we have to do so carefully,
- * without disabling basic html functionality, like clicking on
+ * for all other events, though we have to do so carefully,
+ * without disabling basic html functionality, like clicking on
* hyperlinks or drag-selecting text.
*/
registerEvents:function() {
@@ -5453,31 +5861,31 @@
"dblclick": this.ondblclick,
scope: this
});
-
+
},
- /**
- * Method: onmousedown
+ /**
+ * Method: onmousedown
* When mouse goes down within the popup, make a note of
- * it locally, and then do not propagate the mousedown
+ * it locally, and then do not propagate the mousedown
* (but do so safely so that user can select text inside)
- *
+ *
* Parameters:
- * evt - {Event}
+ * evt - {Event}
*/
onmousedown: function (evt) {
this.mousedown = true;
OpenLayers.Event.stop(evt, true);
},
- /**
+ /**
* Method: onmousemove
- * If the drag was started within the popup, then
+ * If the drag was started within the popup, then
* do not propagate the mousemove (but do so safely
* so that user can select text inside)
- *
+ *
* Parameters:
- * evt - {Event}
+ * evt - {Event}
*/
onmousemove: function (evt) {
if (this.mousedown) {
@@ -5485,15 +5893,15 @@
}
},
- /**
+ /**
* Method: onmouseup
- * When mouse comes up within the popup, after going down
- * in it, reset the flag, and then (once again) do not
- * propagate the event, but do so safely so that user can
+ * When mouse comes up within the popup, after going down
+ * in it, reset the flag, and then (once again) do not
+ * propagate the event, but do so safely so that user can
* select text inside
- *
+ *
* Parameters:
- * evt - {Event}
+ * evt - {Event}
*/
onmouseup: function (evt) {
if (this.mousedown) {
@@ -5505,32 +5913,32 @@
/**
* Method: onclick
* Ignore clicks, but allowing default browser handling
- *
+ *
* Parameters:
- * evt - {Event}
+ * evt - {Event}
*/
onclick: function (evt) {
OpenLayers.Event.stop(evt, true);
},
- /**
+ /**
* Method: onmouseout
* When mouse goes out of the popup set the flag to false so that
* if they let go and then drag back in, we won't be confused.
- *
+ *
* Parameters:
- * evt - {Event}
+ * evt - {Event}
*/
onmouseout: function (evt) {
this.mousedown = false;
},
-
- /**
+
+ /**
* Method: ondblclick
* Ignore double-clicks, but allowing default browser handling
- *
+ *
* Parameters:
- * evt - {Event}
+ * evt - {Event}
*/
ondblclick: function (evt) {
OpenLayers.Event.stop(evt, true);
@@ -5548,8 +5956,9 @@
OpenLayers/Protocol.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -5558,13 +5967,13 @@
* one of the protocol subclasses instead.
*/
OpenLayers.Protocol = OpenLayers.Class({
-
+
/**
* Property: format
* {<OpenLayers.Format>} The format used by this protocol.
*/
format: null,
-
+
/**
* Property: options
* {Object} Any options sent to the constructor.
@@ -5578,8 +5987,14 @@
* true.
*/
autoDestroy: true,
-
+
/**
+ * Property: defaultFilter
+ * {OpenLayers.Filter} Optional default filter to read requests
+ */
+ defaultFilter: null,
+
+ /**
* Constructor: OpenLayers.Protocol
* Abstract class for vector protocols. Create instances of a subclass.
*
@@ -5594,6 +6009,26 @@
},
/**
+ * Method: mergeWithDefaultFilter
+ * Merge filter passed to the read method with the default one
+ *
+ * Parameters:
+ * filter - {OpenLayers.Filter}
+ */
+ mergeWithDefaultFilter: function(filter) {
+ var merged;
+ if (filter && this.defaultFilter) {
+ merged = new OpenLayers.Filter.Logical({
+ type: OpenLayers.Filter.Logical.AND,
+ filters: [this.defaultFilter, filter]
+ });
+ } else {
+ merged = filter || this.defaultFilter || undefined;
+ }
+ return merged;
+ },
+
+ /**
* APIMethod: destroy
* Clean up the protocol.
*/
@@ -5601,7 +6036,7 @@
this.options = null;
this.format = null;
},
-
+
/**
* APIMethod: read
* Construct a request for reading new features.
@@ -5614,10 +6049,12 @@
* object, the same object will be passed to the callback function passed
* if one exists in the options object.
*/
- read: function() {
+ read: function(options) {
+ options = options || {};
+ options.filter = this.mergeWithDefaultFilter(options.filter);
},
-
-
+
+
/**
* APIMethod: create
* Construct a request for writing newly created features.
@@ -5634,7 +6071,7 @@
*/
create: function() {
},
-
+
/**
* APIMethod: update
* Construct a request updating modified features.
@@ -5651,7 +6088,7 @@
*/
update: function() {
},
-
+
/**
* APIMethod: delete
* Construct a request deleting a removed feature.
@@ -5699,8 +6136,24 @@
*/
abort: function(response) {
},
-
- CLASS_NAME: "OpenLayers.Protocol"
+
+ /**
+ * Method: createCallback
+ * Returns a function that applies the given public method with resp and
+ * options arguments.
+ *
+ * Parameters:
+ * method - {Function} The method to be applied by the callback.
+ * response - {<OpenLayers.Protocol.Response>} The protocol response object.
+ * options - {Object} Options sent to the protocol method
+ */
+ createCallback: function(method, response, options) {
+ return OpenLayers.Function.bind(function() {
+ method.apply(this, [response, options]);
+ }, this);
+ },
+
+ CLASS_NAME: "OpenLayers.Protocol"
});
/**
@@ -5779,42 +6232,43 @@
OpenLayers/Renderer.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
- * Class: OpenLayers.Renderer
+ * Class: OpenLayers.Renderer
* This is the base class for all renderers.
*
* This is based on a merger code written by Paul Spencer and Bertil Chapuis.
* It is largely composed of virtual functions that are to be implemented
* in technology-specific subclasses, but there is some generic code too.
- *
+ *
* The functions that *are* implemented here merely deal with the maintenance
- * of the size and extent variables, as well as the cached 'resolution'
- * value.
- *
+ * of the size and extent variables, as well as the cached 'resolution'
+ * value.
+ *
* A note to the user that all subclasses should use getResolution() instead
- * of directly accessing this.resolution in order to correctly use the
+ * of directly accessing this.resolution in order to correctly use the
* cacheing system.
*
*/
OpenLayers.Renderer = OpenLayers.Class({
- /**
+ /**
* Property: container
- * {DOMElement}
+ * {DOMElement}
*/
container: null,
-
+
/**
* Property: root
* {DOMElement}
*/
root: null,
- /**
+ /**
* Property: extent
* {<OpenLayers.Bounds>}
*/
@@ -5823,44 +6277,44 @@
/**
* Property: locked
* {Boolean} If the renderer is currently in a state where many things
- * are changing, the 'locked' property is set to true. This means
+ * are changing, the 'locked' property is set to true. This means
* that renderers can expect at least one more drawFeature event to be
* called with the 'locked' property set to 'true': In some renderers,
* this might make sense to use as a 'only update local information'
- * flag.
- */
+ * flag.
+ */
locked: false,
-
- /**
+
+ /**
* Property: size
- * {<OpenLayers.Size>}
+ * {<OpenLayers.Size>}
*/
size: null,
-
+
/**
* Property: resolution
* {Float} cache of current map resolution
*/
resolution: null,
-
+
/**
- * Property: map
+ * Property: map
* {<OpenLayers.Map>} Reference to the map -- this is set in Vector's setMap()
*/
map: null,
-
+
/**
- * Constructor: OpenLayers.Renderer
+ * Constructor: OpenLayers.Renderer
*
* Parameters:
- * containerID - {<String>}
+ * containerID - {<String>}
* options - {Object} options for this renderer. See sublcasses for
* supported options.
*/
initialize: function(containerID, options) {
this.container = OpenLayers.Util.getElement(containerID);
},
-
+
/**
* APIMethod: destroy
*/
@@ -5875,20 +6329,20 @@
/**
* APIMethod: supported
* This should be overridden by specific subclasses
- *
+ *
* Returns:
* {Boolean} Whether or not the browser supports the renderer class
*/
supported: function() {
return false;
- },
-
+ },
+
/**
* Method: setExtent
* Set the visible part of the layer.
*
- * Resolution has probably changed, so we nullify the resolution
- * cache (this.resolution) -- this way it will be re-computed when
+ * Resolution has probably changed, so we nullify the resolution
+ * cache (this.resolution) -- this way it will be re-computed when
* next it is needed.
* We nullify the resolution cache (this.resolution) if resolutionChanged
* is set to true - this way it will be re-computed on the next
@@ -5904,27 +6358,27 @@
this.resolution = null;
}
},
-
+
/**
* Method: setSize
* Sets the size of the drawing surface.
- *
- * Resolution has probably changed, so we nullify the resolution
- * cache (this.resolution) -- this way it will be re-computed when
+ *
+ * Resolution has probably changed, so we nullify the resolution
+ * cache (this.resolution) -- this way it will be re-computed when
* next it is needed.
*
* Parameters:
- * size - {<OpenLayers.Size>}
+ * size - {<OpenLayers.Size>}
*/
setSize: function(size) {
this.size = size.clone();
this.resolution = null;
},
-
- /**
+
+ /**
* Method: getResolution
* Uses cached copy of resolution if available to minimize computing
- *
+ *
* Returns:
* The current map's resolution
*/
@@ -5932,7 +6386,7 @@
this.resolution = this.resolution || this.map.getResolution();
return this.resolution;
},
-
+
/**
* Method: drawFeature
* Draw the feature. The optional style argument can be used
@@ -5940,9 +6394,9 @@
* be called from layer.drawFeature().
*
* Parameters:
- * feature - {<OpenLayers.Feature.Vector>}
+ * feature - {<OpenLayers.Feature.Vector>}
* style - {<Object>}
- *
+ *
* Returns:
* {Boolean} true if the feature has been drawn completely, false if not,
* undefined if the feature had no geometry
@@ -5959,7 +6413,14 @@
}
var rendered = this.drawGeometry(feature.geometry, style, feature.id);
if(style.display != "none" && style.label && rendered !== false) {
- this.drawText(feature.id, style, feature.geometry.getCentroid());
+ var location = feature.geometry.getCentroid();
+ if(style.labelXOffset || style.labelYOffset) {
+ xOffset = isNaN(style.labelXOffset) ? 0 : style.labelXOffset;
+ yOffset = isNaN(style.labelYOffset) ? 0 : style.labelYOffset;
+ var res = this.getResolution();
+ location.move(xOffset*res, yOffset*res);
+ }
+ this.drawText(feature.id, style, location);
} else {
this.removeText(feature.id);
}
@@ -5969,26 +6430,26 @@
},
- /**
+ /**
* Method: drawGeometry
- *
+ *
* Draw a geometry. This should only be called from the renderer itself.
* Use layer.drawFeature() from outside the renderer.
* virtual function
*
* Parameters:
- * geometry - {<OpenLayers.Geometry>}
- * style - {Object}
- * featureId - {<String>}
+ * geometry - {<OpenLayers.Geometry>}
+ * style - {Object}
+ * featureId - {<String>}
*/
drawGeometry: function(geometry, style, featureId) {},
-
+
/**
* Method: drawText
* Function for drawing text labels.
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* featureId - {String}
* style -
* location - {<OpenLayers.Geometry.Point>}
@@ -5999,67 +6460,69 @@
* Method: removeText
* Function for removing text labels.
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* featureId - {String}
*/
removeText: function(featureId) {},
-
+
/**
* Method: clear
* Clear all vectors from the renderer.
* virtual function.
- */
+ */
clear: function() {},
/**
* Method: getFeatureIdFromEvent
- * Returns a feature id from an event on the renderer.
+ * Returns a feature id from an event on the renderer.
* How this happens is specific to the renderer. This should be
* called from layer.getFeatureFromEvent().
* Virtual function.
- *
+ *
* Parameters:
- * evt - {<OpenLayers.Event>}
+ * evt - {<OpenLayers.Event>}
*
* Returns:
* {String} A feature id or null.
*/
getFeatureIdFromEvent: function(evt) {},
-
+
/**
- * Method: eraseFeatures
+ * Method: eraseFeatures
* This is called by the layer to erase features
- *
+ *
* Parameters:
- * features - {Array(<OpenLayers.Feature.Vector>)}
+ * features - {Array(<OpenLayers.Feature.Vector>)}
*/
eraseFeatures: function(features) {
if(!(features instanceof Array)) {
features = [features];
}
for(var i=0, len=features.length; i<len; ++i) {
- this.eraseGeometry(features[i].geometry);
- this.removeText(features[i].id);
+ var feature = features[i];
+ this.eraseGeometry(feature.geometry, feature.id);
+ this.removeText(feature.id);
}
},
-
+
/**
* Method: eraseGeometry
* Remove a geometry from the renderer (by id).
* virtual function.
- *
+ *
* Parameters:
- * geometry - {<OpenLayers.Geometry>}
+ * geometry - {<OpenLayers.Geometry>}
+ * featureId - {String}
*/
- eraseGeometry: function(geometry) {},
-
+ eraseGeometry: function(geometry, featureId) {},
+
/**
* Method: moveRoot
* moves this renderer's root to a (different) renderer.
* To be implemented by subclasses that require a common renderer root for
* feature selection.
- *
+ *
* Parameters:
* renderer - {<OpenLayers.Renderer>} target renderer for the moved root
*/
@@ -6070,22 +6533,74 @@
* Gets the layer that this renderer's output appears on. If moveRoot was
* used, this will be different from the id of the layer containing the
* features rendered by this renderer.
- *
+ *
* Returns:
* {String} the id of the output layer.
*/
getRenderLayerId: function() {
return this.container.id;
},
+
+ /**
+ * Method: applyDefaultSymbolizer
+ *
+ * Parameters:
+ * symbolizer - {Object}
+ *
+ * Returns:
+ * {Object}
+ */
+ applyDefaultSymbolizer: function(symbolizer) {
+ var result = OpenLayers.Util.extend({},
+ OpenLayers.Renderer.defaultSymbolizer);
+ if(symbolizer.stroke === false) {
+ delete result.strokeWidth;
+ delete result.strokeColor;
+ }
+ if(symbolizer.fill === false) {
+ delete result.fillColor;
+ }
+ OpenLayers.Util.extend(result, symbolizer);
+ return result;
+ },
CLASS_NAME: "OpenLayers.Renderer"
});
+
+/**
+ * Constant: OpenLayers.Renderer.defaultSymbolizer
+ * {Object} Properties from this symbolizer will be applied to symbolizers
+ * with missing properties. This can also be used to set a global
+ * symbolizer default in OpenLayers. To be SLD 1.x compliant, add the
+ * following code before rendering any vector features:
+ * (code)
+ * OpenLayers.Renderer.defaultSymbolizer = {
+ * fillColor: "#808080",
+ * fillOpacity: 1,
+ * strokeColor: "#000000",
+ * strokeOpacity: 1,
+ * strokeWidth: 1,
+ * pointRadius: 3,
+ * graphicName: "square"
+ * };
+ * (end)
+ */
+OpenLayers.Renderer.defaultSymbolizer = {
+ fillColor: "#000000",
+ strokeColor: "#000000",
+ strokeWidth: 2,
+ fillOpacity: 1,
+ strokeOpacity: 1,
+ pointRadius: 0
+};
+
/* ======================================================================
OpenLayers/Strategy.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -6094,21 +6609,21 @@
* one of the strategy subclasses instead.
*/
OpenLayers.Strategy = OpenLayers.Class({
-
+
/**
* Property: layer
* {<OpenLayers.Layer.Vector>} The layer this strategy belongs to.
*/
layer: null,
-
+
/**
* Property: options
* {Object} Any options sent to the constructor.
*/
options: null,
- /**
- * Property: active
+ /**
+ * Property: active
* {Boolean} The control is active.
*/
active: null,
@@ -6143,7 +6658,7 @@
// set the active property here, so that user cannot override it
this.active = false;
},
-
+
/**
* APIMethod: destroy
* Clean up the strategy.
@@ -6164,7 +6679,7 @@
setLayer: function(layer) {
this.layer = layer;
},
-
+
/**
* Method: activate
* Activate the strategy. Register any listeners, do appropriate setup.
@@ -6180,7 +6695,7 @@
}
return false;
},
-
+
/**
* Method: deactivate
* Deactivate the strategy. Unregister any listeners, do appropriate
@@ -6197,15 +6712,71 @@
}
return false;
},
+
+ CLASS_NAME: "OpenLayers.Strategy"
+});
+/* ======================================================================
+ OpenLayers/Symbolizer.js
+ ====================================================================== */
- CLASS_NAME: "OpenLayers.Strategy"
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+/**
+ * Class: OpenLayers.Symbolizer
+ * Base class representing a symbolizer used for feature rendering.
+ */
+OpenLayers.Symbolizer = OpenLayers.Class({
+
+
+ /**
+ * APIProperty: zIndex
+ * {Number} The zIndex determines the rendering order for a symbolizer.
+ * Symbolizers with larger zIndex values are rendered over symbolizers
+ * with smaller zIndex values. Default is 0.
+ */
+ zIndex: 0,
+
+ /**
+ * Constructor: OpenLayers.Symbolizer
+ * Instances of this class are not useful. See one of the subclasses.
+ *
+ * Parameters:
+ * config - {Object} An object containing properties to be set on the
+ * symbolizer. Any documented symbolizer property can be set at
+ * construction.
+ *
+ * Returns:
+ * A new symbolizer.
+ */
+ initialize: function(config) {
+ OpenLayers.Util.extend(this, config);
+ },
+
+ /**
+ * APIMethod: clone
+ * Create a copy of this symbolizer.
+ *
+ * Returns a symbolizer of the same type with the same properties.
+ */
+ clone: function() {
+ var Type = eval(this.CLASS_NAME);
+ return new Type(OpenLayers.Util.extend({}, this));
+ },
+
+ CLASS_NAME: "OpenLayers.Symbolizer"
+
});
+
/* ======================================================================
OpenLayers/Control.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -6215,15 +6786,15 @@
/**
* Class: OpenLayers.Control
* Controls affect the display or behavior of the map. They allow everything
- * from panning and zooming to displaying a scale indicator. Controls by
+ * from panning and zooming to displaying a scale indicator. Controls by
* default are added to the map they are contained within however it is
* possible to add a control to an external div by passing the div in the
* options parameter.
- *
+ *
* Example:
* The following example shows how to add many of the common controls
* to a map.
- *
+ *
* > var map = new OpenLayers.Map('map', { controls: [] });
* >
* > map.addControl(new OpenLayers.Control.PanZoomBar());
@@ -6235,10 +6806,10 @@
* > map.addControl(new OpenLayers.Control.OverviewMap());
* > map.addControl(new OpenLayers.Control.KeyboardDefaults());
*
- * The next code fragment is a quick example of how to intercept
+ * The next code fragment is a quick example of how to intercept
* shift-mouse click to display the extent of the bounding box
* dragged out by the user. Usually controls are not created
- * in exactly this manner. See the source for a more complete
+ * in exactly this manner. See the source for a more complete
* example:
*
* > var control = new OpenLayers.Control();
@@ -6246,7 +6817,7 @@
* > draw: function () {
* > // this Handler.Box will intercept the shift-mousedown
* > // before Control.MouseDefault gets to see it
- * > this.box = new OpenLayers.Handler.Box( control,
+ * > this.box = new OpenLayers.Handler.Box( control,
* > {"done": this.notice},
* > {keyMask: OpenLayers.Handler.MOD_SHIFT});
* > this.box.activate();
@@ -6255,70 +6826,77 @@
* > notice: function (bounds) {
* > OpenLayers.Console.userError(bounds);
* > }
- * > });
+ * > });
* > map.addControl(control);
- *
+ *
*/
OpenLayers.Control = OpenLayers.Class({
- /**
- * Property: id
- * {String}
+ /**
+ * Property: id
+ * {String}
*/
id: null,
-
- /**
- * Property: map
+
+ /**
+ * Property: map
* {<OpenLayers.Map>} this gets set in the addControl() function in
- * OpenLayers.Map
+ * OpenLayers.Map
*/
map: null,
- /**
- * Property: div
- * {DOMElement}
+ /**
+ * Property: div
+ * {DOMElement}
*/
div: null,
- /**
- * Property: type
- * {OpenLayers.Control.TYPES} Controls can have a 'type'. The type
- * determines the type of interactions which are possible with them when
- * they are placed into a toolbar.
+ /**
+ * Property: type
+ * {Number} Controls can have a 'type'. The type determines the type of
+ * interactions which are possible with them when they are placed in an
+ * <OpenLayers.Control.Panel>.
*/
- type: null,
+ type: null,
- /**
+ /**
* Property: allowSelection
* {Boolean} By deafault, controls do not allow selection, because
* it may interfere with map dragging. If this is true, OpenLayers
* will not prevent selection of the control.
* Default is false.
*/
- allowSelection: false,
+ allowSelection: false,
- /**
- * Property: displayClass
+ /**
+ * Property: displayClass
* {string} This property is used for CSS related to the drawing of the
- * Control.
+ * Control.
*/
displayClass: "",
-
+
/**
- * Property: title
- * {string} This property is used for showing a tooltip over the
- * Control.
- */
+ * Property: title
+ * {string} This property is used for showing a tooltip over the
+ * Control.
+ */
title: "",
/**
- * Property: active
+ * APIProperty: autoActivate
+ * {Boolean} Activate the control when it is added to a map. Default is
+ * false.
+ */
+ autoActivate: false,
+
+ /**
+ * Property: active
* {Boolean} The control is active.
*/
active: null,
- /**
- * Property: handler
+ /**
+ * Property: handler
* {<OpenLayers.Handler>} null
*/
handler: null,
@@ -6332,7 +6910,7 @@
*/
eventListeners: null,
- /**
+ /**
* Property: events
* {<OpenLayers.Events>} Events instance for triggering control specific
* events.
@@ -6366,22 +6944,22 @@
* Constructor: OpenLayers.Control
* Create an OpenLayers Control. The options passed as a parameter
* directly extend the control. For example passing the following:
- *
+ *
* > var control = new OpenLayers.Control({div: myDiv});
*
* Overrides the default div attribute value of null.
- *
+ *
* Parameters:
- * options - {Object}
+ * options - {Object}
*/
initialize: function (options) {
// We do this before the extend so that instances can override
// className in options.
- this.displayClass =
+ this.displayClass =
this.CLASS_NAME.replace("OpenLayers.", "ol").replace(/\./g, "");
-
+
OpenLayers.Util.extend(this, options);
-
+
this.events = new OpenLayers.Events(this, null, this.EVENT_TYPES);
if(this.eventListeners instanceof Object) {
this.events.on(this.eventListeners);
@@ -6427,14 +7005,14 @@
}
},
- /**
+ /**
* Method: setMap
* Set the map property for the control. This is done through an accessor
- * so that subclasses can override this and take special action once
- * they have their map variable set.
+ * so that subclasses can override this and take special action once
+ * they have their map variable set.
*
* Parameters:
- * map - {<OpenLayers.Map>}
+ * map - {<OpenLayers.Map>}
*/
setMap: function(map) {
this.map = map;
@@ -6442,13 +7020,13 @@
this.handler.setMap(map);
}
},
-
+
/**
* Method: draw
* The draw method is called when the control is ready to be displayed
* on the page. If a div has not been created one is created. Controls
- * with a visual component will almost always want to override this method
- * to customize the look of control.
+ * with a visual component will almost always want to override this method
+ * to customize the look of control.
*
* Parameters:
* px - {<OpenLayers.Pixel>} The top-left pixel position of the control
@@ -6464,8 +7042,8 @@
if (!this.allowSelection) {
this.div.className += " olControlNoSelect";
this.div.setAttribute("unselectable", "on", 0);
- this.div.onselectstart = function() { return(false); };
- }
+ this.div.onselectstart = OpenLayers.Function.False;
+ }
if (this.title != "") {
this.div.title = this.title;
}
@@ -6479,7 +7057,7 @@
/**
* Method: moveTo
- * Sets the left and top style attributes to the passed in pixel
+ * Sets the left and top style attributes to the passed in pixel
* coordinates.
*
* Parameters:
@@ -6497,7 +7075,7 @@
* Explicitly activates a control and it's associated
* handler if one has been set. Controls can be
* deactivated by calling the deactivate() method.
- *
+ *
* Returns:
* {Boolean} True if the control was successfully activated or
* false if the control was already active.
@@ -6519,12 +7097,12 @@
this.events.triggerEvent("activate");
return true;
},
-
+
/**
* Method: deactivate
* Deactivates a control and it's associated handler if any. The exact
* effect of this depends on the control itself.
- *
+ *
* Returns:
* {Boolean} True if the control was effectively deactivated or false
* if the control was already inactive.
@@ -6550,15 +7128,27 @@
CLASS_NAME: "OpenLayers.Control"
});
+/**
+ * Constant: OpenLayers.Control.TYPE_BUTTON
+ */
OpenLayers.Control.TYPE_BUTTON = 1;
+
+/**
+ * Constant: OpenLayers.Control.TYPE_TOGGLE
+ */
OpenLayers.Control.TYPE_TOGGLE = 2;
+
+/**
+ * Constant: OpenLayers.Control.TYPE_TOOL
+ */
OpenLayers.Control.TYPE_TOOL = 3;
/* ======================================================================
OpenLayers/Lang.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -6571,8 +7161,8 @@
* and methods to set and get the current language.
*/
OpenLayers.Lang = {
-
- /**
+
+ /**
* Property: code
* {String} Current language code to use in OpenLayers. Use the
* <setCode> method to set this value and the <getCode> method to
@@ -6580,13 +7170,13 @@
*/
code: null,
- /**
+ /**
* APIProperty: defaultCode
* {String} Default language to use when a specific language can't be
* found. Default is "en".
*/
defaultCode: "en",
-
+
/**
* APIFunction: getCode
* Get the current language code.
@@ -6600,7 +7190,7 @@
}
return OpenLayers.Lang.code;
},
-
+
/**
* APIFunction: setCode
* Set the language code for string translation. This code is used by
@@ -6639,7 +7229,7 @@
);
lang = OpenLayers.Lang.defaultCode;
}
-
+
OpenLayers.Lang.code = lang;
},
@@ -6653,7 +7243,7 @@
* key - {String} The key for an i18n string value in the dictionary.
* context - {Object} Optional context to be used with
* <OpenLayers.String.format>.
- *
+ *
* Returns:
* {String} A internationalized string.
*/
@@ -6669,7 +7259,7 @@
}
return message;
}
-
+
};
@@ -6684,7 +7274,7 @@
* key - {String} The key for an i18n string value in the dictionary.
* context - {Object} Optional context to be used with
* <OpenLayers.String.format>.
- *
+ *
* Returns:
* {String} A internationalized string.
*/
@@ -6693,8 +7283,9 @@
OpenLayers/Popup/Anchored.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
@@ -6704,28 +7295,28 @@
/**
* Class: OpenLayers.Popup.Anchored
- *
+ *
* Inherits from:
* - <OpenLayers.Popup>
*/
-OpenLayers.Popup.Anchored =
+OpenLayers.Popup.Anchored =
OpenLayers.Class(OpenLayers.Popup, {
- /**
+ /**
* Parameter: relativePosition
* {String} Relative position of the popup ("br", "tr", "tl" or "bl").
*/
relativePosition: null,
-
+
/**
- * APIProperty: keepInMap
- * {Boolean} If panMapIfOutOfView is false, and this property is true,
+ * APIProperty: keepInMap
+ * {Boolean} If panMapIfOutOfView is false, and this property is true,
* contrain the popup such that it always fits in the available map
* space. By default, this is set. If you are creating popups that are
* near map edges and not allowing pannning, and especially if you have
* a popup which has a fixedRelativePosition, setting this to false may
* be a smart thing to do.
- *
+ *
* For anchored popups, default is true, since subclasses will
* usually want this functionality.
*/
@@ -6733,20 +7324,20 @@
/**
* Parameter: anchor
- * {Object} Object to which we'll anchor the popup. Must expose a
+ * {Object} Object to which we'll anchor the popup. Must expose a
* 'size' (<OpenLayers.Size>) and 'offset' (<OpenLayers.Pixel>).
*/
anchor: null,
- /**
+ /**
* Constructor: OpenLayers.Popup.Anchored
- *
+ *
* Parameters:
* id - {String}
* lonlat - {<OpenLayers.LonLat>}
* contentSize - {<OpenLayers.Size>}
* contentHTML - {String}
- * anchor - {Object} Object which must expose a 'size' <OpenLayers.Size>
+ * anchor - {Object} Object which must expose a 'size' <OpenLayers.Size>
* and 'offset' <OpenLayers.Pixel> (generally an <OpenLayers.Icon>).
* closeBox - {Boolean}
* closeBoxCallback - {Function} Function to be called on closeBox click.
@@ -6758,7 +7349,7 @@
];
OpenLayers.Popup.prototype.initialize.apply(this, newArguments);
- this.anchor = (anchor != null) ? anchor
+ this.anchor = (anchor != null) ? anchor
: { size: new OpenLayers.Size(0,0),
offset: new OpenLayers.Pixel(0,0)};
},
@@ -6769,13 +7360,13 @@
destroy: function() {
this.anchor = null;
this.relativePosition = null;
-
- OpenLayers.Popup.prototype.destroy.apply(this, arguments);
+
+ OpenLayers.Popup.prototype.destroy.apply(this, arguments);
},
/**
* APIMethod: show
- * Overridden from Popup since user might hide popup and then show() it
+ * Overridden from Popup since user might hide popup and then show() it
* in a new location (meaning we might want to update the relative
* position on the show)
*/
@@ -6787,27 +7378,27 @@
/**
* Method: moveTo
* Since the popup is moving to a new px, it might need also to be moved
- * relative to where the marker is. We first calculate the new
- * relativePosition, and then we calculate the new px where we will
- * put the popup, based on the new relative position.
- *
- * If the relativePosition has changed, we must also call
- * updateRelativePosition() to make any visual changes to the popup
+ * relative to where the marker is. We first calculate the new
+ * relativePosition, and then we calculate the new px where we will
+ * put the popup, based on the new relative position.
+ *
+ * If the relativePosition has changed, we must also call
+ * updateRelativePosition() to make any visual changes to the popup
* which are associated with putting it in a new relativePosition.
- *
+ *
* Parameters:
* px - {<OpenLayers.Pixel>}
*/
moveTo: function(px) {
var oldRelativePosition = this.relativePosition;
this.relativePosition = this.calculateRelativePosition(px);
-
+
var newPx = this.calculateNewPx(px);
-
- var newArguments = new Array(newPx);
+
+ var newArguments = new Array(newPx);
OpenLayers.Popup.prototype.moveTo.apply(this, newArguments);
-
- //if this move has caused the popup to change its relative position,
+
+ //if this move has caused the popup to change its relative position,
// we need to make the appropriate cosmetic changes.
if (this.relativePosition != oldRelativePosition) {
this.updateRelativePosition();
@@ -6816,76 +7407,76 @@
/**
* APIMethod: setSize
- *
+ *
* Parameters:
- * contentSize - {<OpenLayers.Size>} the new size for the popup's
+ * contentSize - {<OpenLayers.Size>} the new size for the popup's
* contents div (in pixels).
*/
- setSize:function(contentSize) {
+ setSize:function(contentSize) {
OpenLayers.Popup.prototype.setSize.apply(this, arguments);
if ((this.lonlat) && (this.map)) {
var px = this.map.getLayerPxFromLonLat(this.lonlat);
this.moveTo(px);
}
- },
-
- /**
+ },
+
+ /**
* Method: calculateRelativePosition
- *
+ *
* Parameters:
* px - {<OpenLayers.Pixel>}
- *
+ *
* Returns:
* {String} The relative position ("br" "tr" "tl" "bl") at which the popup
* should be placed.
*/
calculateRelativePosition:function(px) {
- var lonlat = this.map.getLonLatFromLayerPx(px);
-
+ var lonlat = this.map.getLonLatFromLayerPx(px);
+
var extent = this.map.getExtent();
var quadrant = extent.determineQuadrant(lonlat);
-
+
return OpenLayers.Bounds.oppositeQuadrant(quadrant);
- },
+ },
/**
* Method: updateRelativePosition
- * The popup has been moved to a new relative location, so we may want to
- * make some cosmetic adjustments to it.
- *
- * Note that in the classic Anchored popup, there is nothing to do
+ * The popup has been moved to a new relative location, so we may want to
+ * make some cosmetic adjustments to it.
+ *
+ * Note that in the classic Anchored popup, there is nothing to do
* here, since the popup looks exactly the same in all four positions.
- * Subclasses such as the AnchoredBubble and Framed, however, will
+ * Subclasses such as the AnchoredBubble and Framed, however, will
* want to do something special here.
*/
updateRelativePosition: function() {
//to be overridden by subclasses
},
- /**
+ /**
* Method: calculateNewPx
- *
+ *
* Parameters:
* px - {<OpenLayers.Pixel>}
- *
+ *
* Returns:
* {<OpenLayers.Pixel>} The the new px position of the popup on the screen
* relative to the passed-in px.
*/
calculateNewPx:function(px) {
var newPx = px.offset(this.anchor.offset);
-
+
//use contentSize if size is not already set
var size = this.size || this.contentSize;
var top = (this.relativePosition.charAt(0) == 't');
- newPx.y += (top) ? -size.h : this.anchor.size.h;
-
+ newPx.y += (top) ? -(size.h + this.anchor.size.h) : this.anchor.size.h;
+
var left = (this.relativePosition.charAt(1) == 'l');
- newPx.x += (left) ? -size.w : this.anchor.size.w;
+ newPx.x += (left) ? -(size.w + this.anchor.size.w) : this.anchor.size.w;
- return newPx;
+ return newPx;
},
CLASS_NAME: "OpenLayers.Popup.Anchored"
@@ -6894,8 +7485,9 @@
OpenLayers/Renderer/Canvas.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -6903,9 +7495,9 @@
*/
/**
- * Class: OpenLayers.Renderer.Canvas
+ * Class: OpenLayers.Renderer.Canvas
* A renderer based on the 2D 'canvas' drawing element.element
- *
+ *
* Inherits:
* - <OpenLayers.Renderer>
*/
@@ -6915,27 +7507,19 @@
* Property: canvas
* {Canvas} The canvas context object.
*/
- canvas: null,
-
+ canvas: null,
+
/**
* Property: features
* {Object} Internal object of feature/style pairs for use in redrawing the layer.
*/
- features: null,
-
+ features: null,
+
/**
- * Property: geometryMap
- * {Object} Geometry -> Feature lookup table. Used by eraseGeometry to
- * lookup features to remove from our internal table (this.features)
- * when erasing geoms.
- */
- geometryMap: null,
-
- /**
* Constructor: OpenLayers.Renderer.Canvas
*
* Parameters:
- * containerID - {<String>}
+ * containerID - {<String>}
*/
initialize: function(containerID) {
OpenLayers.Renderer.prototype.initialize.apply(this, arguments);
@@ -6943,49 +7527,49 @@
this.container.appendChild(this.root);
this.canvas = this.root.getContext("2d");
this.features = {};
- this.geometryMap = {};
},
-
- /**
+
+ /**
* Method: eraseGeometry
* Erase a geometry from the renderer. Because the Canvas renderer has
* 'memory' of the features that it has drawn, we have to remove the
- * feature so it doesn't redraw.
- *
+ * feature so it doesn't redraw.
+ *
* Parameters:
* geometry - {<OpenLayers.Geometry>}
+ * featureId - {String}
*/
- eraseGeometry: function(geometry) {
- this.eraseFeatures(this.features[this.geometryMap[geometry.id]][0]);
+ eraseGeometry: function(geometry, featureId) {
+ this.eraseFeatures(this.features[featureId][0]);
},
/**
* APIMethod: supported
- *
+ *
* Returns:
* {Boolean} Whether or not the browser supports the renderer class
*/
supported: function() {
var canvas = document.createElement("canvas");
return !!canvas.getContext;
- },
-
+ },
+
/**
* Method: setExtent
* Set the visible part of the layer.
*
- * Resolution has probably changed, so we nullify the resolution
- * cache (this.resolution), then redraw.
+ * Resolution has probably changed, so we nullify the resolution
+ * cache (this.resolution), then redraw.
*
* Parameters:
- * extent - {<OpenLayers.Bounds>}
+ * extent - {<OpenLayers.Bounds>}
*/
setExtent: function(extent) {
this.extent = extent.clone();
this.resolution = null;
this.redraw();
},
-
+
/**
* Method: setSize
* Sets the size of the drawing surface.
@@ -6993,7 +7577,7 @@
* Once the size is updated, redraw the canvas.
*
* Parameters:
- * size - {<OpenLayers.Size>}
+ * size - {<OpenLayers.Size>}
*/
setSize: function(size) {
this.size = size.clone();
@@ -7003,43 +7587,33 @@
this.root.height = size.h;
this.resolution = null;
},
-
+
/**
* Method: drawFeature
* Draw the feature. Stores the feature in the features list,
- * then redraws the layer.
+ * then redraws the layer.
*
* Parameters:
- * feature - {<OpenLayers.Feature.Vector>}
- * style - {<Object>}
+ * feature - {<OpenLayers.Feature.Vector>}
+ * style - {<Object>}
*/
drawFeature: function(feature, style) {
- if(style == null) {
- style = feature.style;
- }
- style = OpenLayers.Util.extend({
- 'fillColor': '#000000',
- 'strokeColor': '#000000',
- 'strokeWidth': 2,
- 'fillOpacity': 1,
- 'strokeOpacity': 1
- }, style);
- this.features[feature.id] = [feature, style];
- if (feature.geometry) {
- this.geometryMap[feature.geometry.id] = feature.id;
- }
+ style = style || feature.style;
+ style = this.applyDefaultSymbolizer(style);
+
+ this.features[feature.id] = [feature, style];
this.redraw();
},
- /**
+ /**
* Method: drawGeometry
* Used when looping (in redraw) over the features; draws
- * the canvas.
+ * the canvas.
*
* Parameters:
- * geometry - {<OpenLayers.Geometry>}
- * style - {Object}
+ * geometry - {<OpenLayers.Geometry>}
+ * style - {Object}
*/
drawGeometry: function(geometry, style) {
var className = geometry.CLASS_NAME;
@@ -7051,7 +7625,7 @@
this.drawGeometry(geometry.components[i], style);
}
return;
- };
+ }
switch (geometry.CLASS_NAME) {
case "OpenLayers.Geometry.Point":
this.drawPoint(geometry, style);
@@ -7072,18 +7646,17 @@
/**
* Method: drawExternalGraphic
- * Called to draw External graphics.
- *
- * Parameters:
+ * Called to draw External graphics.
+ *
+ * Parameters:
* geometry - {<OpenLayers.Geometry>}
* style - {Object}
- */
+ */
drawExternalGraphic: function(pt, style) {
var img = new Image();
- img.src = style.externalGraphic;
-
+
if(style.graphicTitle) {
- img.title=style.graphicTitle;
+ img.title=style.graphicTitle;
}
var width = style.graphicWidth || style.graphicHeight;
@@ -7094,19 +7667,21 @@
style.graphicXOffset : -(0.5 * width);
var yOffset = (style.graphicYOffset != undefined) ?
style.graphicYOffset : -(0.5 * height);
- var opacity = style.graphicOpacity || style.fillOpacity;
-
- var context = { img: img,
- x: (pt[0]+xOffset),
- y: (pt[1]+yOffset),
- width: width,
- height: height,
+
+ var context = { img: img,
+ x: (pt[0]+xOffset),
+ y: (pt[1]+yOffset),
+ width: width,
+ height: height,
+ opacity: style.graphicOpacity || style.fillOpacity,
canvas: this.canvas };
img.onload = OpenLayers.Function.bind( function() {
- this.canvas.drawImage(this.img, this.x,
+ this.canvas.globalAlpha = this.opacity;
+ this.canvas.drawImage(this.img, this.x,
this.y, this.width, this.height);
}, context);
+ img.src = style.externalGraphic;
},
/**
@@ -7118,10 +7693,10 @@
* style - {Object} Symbolizer hash
*/
setCanvasStyle: function(type, style) {
- if (type == "fill") {
+ if (type == "fill") {
this.canvas.globalAlpha = style['fillOpacity'];
this.canvas.fillStyle = style['fillColor'];
- } else if (type == "stroke") {
+ } else if (type == "stroke") {
this.canvas.globalAlpha = style['strokeOpacity'];
this.canvas.strokeStyle = style['strokeColor'];
this.canvas.lineWidth = style['strokeWidth'];
@@ -7134,29 +7709,29 @@
/**
* Method: drawPoint
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* geometry - {<OpenLayers.Geometry>}
* style - {Object}
- */
+ */
drawPoint: function(geometry, style) {
if(style.graphic !== false) {
var pt = this.getLocalXY(geometry);
-
+
if (style.externalGraphic) {
this.drawExternalGraphic(pt, style);
} else {
if(style.fill !== false) {
this.setCanvasStyle("fill", style);
this.canvas.beginPath();
- this.canvas.arc(pt[0], pt[1], 6, 0, Math.PI*2, true);
+ this.canvas.arc(pt[0], pt[1], style.pointRadius, 0, Math.PI*2, true);
this.canvas.fill();
}
-
+
if(style.stroke !== false) {
this.setCanvasStyle("stroke", style);
this.canvas.beginPath();
- this.canvas.arc(pt[0], pt[1], 6, 0, Math.PI*2, true);
+ this.canvas.arc(pt[0], pt[1], style.pointRadius, 0, Math.PI*2, true);
this.canvas.stroke();
this.setCanvasStyle("reset");
}
@@ -7167,11 +7742,11 @@
/**
* Method: drawLineString
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* geometry - {<OpenLayers.Geometry>}
* style - {Object}
- */
+ */
drawLineString: function(geometry, style) {
if(style.stroke !== false) {
this.setCanvasStyle("stroke", style);
@@ -7185,16 +7760,16 @@
this.canvas.stroke();
}
this.setCanvasStyle("reset");
- },
-
+ },
+
/**
* Method: drawLinearRing
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* geometry - {<OpenLayers.Geometry>}
* style - {Object}
- */
+ */
drawLinearRing: function(geometry, style) {
if(style.fill !== false) {
this.setCanvasStyle("fill", style);
@@ -7207,9 +7782,8 @@
}
this.canvas.fill();
}
-
+
if(style.stroke !== false) {
- var oldWidth = this.canvas.lineWidth;
this.setCanvasStyle("stroke", style);
this.canvas.beginPath();
var start = this.getLocalXY(geometry.components[0]);
@@ -7221,29 +7795,29 @@
this.canvas.stroke();
}
this.setCanvasStyle("reset");
- },
-
+ },
+
/**
* Method: drawPolygon
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* geometry - {<OpenLayers.Geometry>}
* style - {Object}
- */
+ */
drawPolygon: function(geometry, style) {
this.drawLinearRing(geometry.components[0], style);
for (var i = 1; i < geometry.components.length; i++) {
this.drawLinearRing(geometry.components[i], {
- fillOpacity: 0,
- strokeWidth: 0,
- strokeOpacity: 0,
- strokeColor: '#000000',
+ fillOpacity: 0,
+ strokeWidth: 0,
+ strokeOpacity: 0,
+ strokeColor: '#000000',
fillColor: '#000000'}
- ); // inner rings are 'empty'
+ ); // inner rings are 'empty'
}
},
-
+
/**
* Method: drawText
* This method is only called by the renderer itself.
@@ -7258,16 +7832,16 @@
labelAlign: "cm"
}, style);
var pt = this.getLocalXY(location);
-
+
this.setCanvasStyle("reset");
this.canvas.fillStyle = style.fontColor;
- this.canvas.globalAlpha = 1;
+ this.canvas.globalAlpha = style.fontOpacity || 1.0;
var fontStyle = style.fontWeight + " " + style.fontSize + " " + style.fontFamily;
if (this.canvas.fillText) {
// HTML5
var labelAlign =
OpenLayers.Renderer.Canvas.LABEL_ALIGN[style.labelAlign[0]] ||
- "middle";
+ "center";
this.canvas.font = fontStyle;
this.canvas.textAlign = labelAlign;
this.canvas.fillText(style.label, pt[0], pt[1]);
@@ -7287,7 +7861,7 @@
pt[0] -= len / 2;
}
this.canvas.translate(pt[0], pt[1]);
-
+
this.canvas.mozDrawText(style.label);
this.canvas.translate(-1*pt[0], -1*pt[1]);
}
@@ -7298,7 +7872,7 @@
* Method: getLocalXY
* transform geographic xy into pixel xy
*
- * Parameters:
+ * Parameters:
* point - {<OpenLayers.Geometry.Point>}
*/
getLocalXY: function(point) {
@@ -7312,18 +7886,18 @@
/**
* Method: clear
* Clear all vectors from the renderer.
- * virtual function.
- */
+ */
clear: function() {
this.canvas.clearRect(0, 0, this.root.width, this.root.height);
+ this.features = {};
},
/**
* Method: getFeatureIdFromEvent
- * Returns a feature id from an event on the renderer.
- *
+ * Returns a feature id from an event on the renderer.
+ *
* Parameters:
- * evt - {<OpenLayers.Event>}
+ * evt - {<OpenLayers.Event>}
*
* Returns:
* {String} A feature id or null.
@@ -7331,9 +7905,9 @@
getFeatureIdFromEvent: function(evt) {
var loc = this.map.getLonLatFromPixel(evt.xy);
var resolution = this.getResolution();
- var bounds = new OpenLayers.Bounds(loc.lon - resolution * 5,
- loc.lat - resolution * 5,
- loc.lon + resolution * 5,
+ var bounds = new OpenLayers.Bounds(loc.lon - resolution * 5,
+ loc.lat - resolution * 5,
+ loc.lon + resolution * 5,
loc.lat + resolution * 5);
var geom = bounds.toGeometry();
for (var feat in this.features) {
@@ -7341,17 +7915,17 @@
if (this.features[feat][0].geometry.intersects(geom)) {
return feat;
}
- }
+ }
return null;
},
-
+
/**
- * Method: eraseFeatures
+ * Method: eraseFeatures
* This is called by the layer to erase features; removes the feature from
* the list, then redraws the layer.
- *
+ *
* Parameters:
- * features - {Array(<OpenLayers.Feature.Vector>)}
+ * features - {Array(<OpenLayers.Feature.Vector>)}
*/
eraseFeatures: function(features) {
if(!(features instanceof Array)) {
@@ -7373,7 +7947,7 @@
*/
redraw: function() {
if (!this.locked) {
- this.clear();
+ this.canvas.clearRect(0, 0, this.root.width, this.root.height);
var labelMap = [];
var feature, style;
for (var id in this.features) {
@@ -7387,11 +7961,11 @@
}
}
var item;
- for (var i=0; len=labelMap.length, i<len; ++i) {
+ for (var i=0, len=labelMap.length; i<len; ++i) {
item = labelMap[i];
this.drawText(item[0].geometry.getCentroid(), item[1]);
}
- }
+ }
},
CLASS_NAME: "OpenLayers.Renderer.Canvas"
@@ -7409,8 +7983,9 @@
OpenLayers/Renderer/Elements.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -7420,33 +7995,33 @@
/**
* Class: OpenLayers.ElementsIndexer
* This class takes care of figuring out which order elements should be
- * placed in the DOM based on given indexing methods.
+ * placed in the DOM based on given indexing methods.
*/
OpenLayers.ElementsIndexer = OpenLayers.Class({
-
+
/**
* Property: maxZIndex
* {Integer} This is the largest-most z-index value for a node
* contained within the indexer.
*/
maxZIndex: null,
-
+
/**
* Property: order
* {Array<String>} This is an array of node id's stored in the
* order that they should show up on screen. Id's higher up in the
* array (higher array index) represent nodes with higher z-indeces.
*/
- order: null,
-
+ order: null,
+
/**
* Property: indices
* {Object} This is a hash that maps node ids to their z-index value
- * stored in the indexer. This is done to make finding a nodes z-index
+ * stored in the indexer. This is done to make finding a nodes z-index
* value O(1).
*/
indices: null,
-
+
/**
* Property: compare
* {Function} This is the function used to determine placement of
@@ -7454,34 +8029,34 @@
* the Z_ORDER_DRAWING_ORDER comparison method.
*/
compare: null,
-
+
/**
* APIMethod: initialize
- * Create a new indexer with
- *
+ * Create a new indexer with
+ *
* Parameters:
* yOrdering - {Boolean} Whether to use y-ordering.
*/
initialize: function(yOrdering) {
- this.compare = yOrdering ?
+ this.compare = yOrdering ?
OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER_Y_ORDER :
OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER_DRAWING_ORDER;
-
+
this.order = [];
this.indices = {};
this.maxZIndex = 0;
},
-
+
/**
* APIMethod: insert
- * Insert a new node into the indexer. In order to find the correct
- * positioning for the node to be inserted, this method uses a binary
- * search. This makes inserting O(log(n)).
- *
+ * Insert a new node into the indexer. In order to find the correct
+ * positioning for the node to be inserted, this method uses a binary
+ * search. This makes inserting O(log(n)).
+ *
* Parameters:
* newNode - {DOMElement} The new node to be inserted.
- *
+ *
* Returns
* {DOMElement} the node before which we should insert our newNode, or
* null if newNode can just be appended.
@@ -7492,40 +8067,40 @@
if (this.exists(newNode)) {
this.remove(newNode);
}
-
+
var nodeId = newNode.id;
+
+ this.determineZIndex(newNode);
- this.determineZIndex(newNode);
-
var leftIndex = -1;
var rightIndex = this.order.length;
var middle;
while (rightIndex - leftIndex > 1) {
middle = parseInt((leftIndex + rightIndex) / 2);
-
+
var placement = this.compare(this, newNode,
OpenLayers.Util.getElement(this.order[middle]));
-
+
if (placement > 0) {
leftIndex = middle;
} else {
rightIndex = middle;
- }
+ }
}
-
+
this.order.splice(rightIndex, 0, nodeId);
this.indices[nodeId] = this.getZIndex(newNode);
-
+
// If the new node should be before another in the index
// order, return the node before which we have to insert the new one;
// else, return null to indicate that the new node can be appended.
- return this.getNextElement(rightIndex);
+ return this.getNextElement(rightIndex);
},
-
+
/**
* APIMethod: remove
- *
+ *
* Parameters:
* node - {DOMElement} The node to be removed.
*/
@@ -7537,8 +8112,8 @@
// from the indeces hash.
this.order.splice(arrayIndex, 1);
delete this.indices[nodeId];
-
- // Reset the maxium z-index based on the last item in the
+
+ // Reset the maxium z-index based on the last item in the
// order array.
if (this.order.length > 0) {
var lastId = this.order[this.order.length - 1];
@@ -7548,7 +8123,7 @@
}
}
},
-
+
/**
* APIMethod: clear
*/
@@ -7557,7 +8132,7 @@
this.indices = {};
this.maxZIndex = 0;
},
-
+
/**
* APIMethod: exists
*
@@ -7574,29 +8149,29 @@
/**
* APIMethod: getZIndex
* Get the z-index value for the current node from the node data itself.
- *
+ *
* Parameters:
* node - {DOMElement} The node whose z-index to get.
- *
+ *
* Returns:
- * {Integer} The z-index value for the specified node (from the node
+ * {Integer} The z-index value for the specified node (from the node
* data itself).
*/
getZIndex: function(node) {
- return node._style.graphicZIndex;
+ return node._style.graphicZIndex;
},
-
+
/**
* Method: determineZIndex
- * Determine the z-index for the current node if there isn't one,
+ * Determine the z-index for the current node if there isn't one,
* and set the maximum value if we've found a new maximum.
- *
+ *
* Parameters:
- * node - {DOMElement}
+ * node - {DOMElement}
*/
determineZIndex: function(node) {
var zIndex = node._style.graphicZIndex;
-
+
// Everything must have a zIndex. If none is specified,
// this means the user *must* (hint: assumption) want this
// node to succomb to drawing order. To enforce drawing order
@@ -7604,7 +8179,7 @@
// greater than any currently in the indexer.
if (zIndex == null) {
zIndex = this.maxZIndex;
- node._style.graphicZIndex = zIndex;
+ node._style.graphicZIndex = zIndex;
} else if (zIndex > this.maxZIndex) {
this.maxZIndex = zIndex;
}
@@ -7613,50 +8188,50 @@
/**
* APIMethod: getNextElement
* Get the next element in the order stack.
- *
+ *
* Parameters:
* index - {Integer} The index of the current node in this.order.
- *
+ *
* Returns:
* {DOMElement} the node following the index passed in, or
* null.
*/
getNextElement: function(index) {
var nextIndex = index + 1;
- if (nextIndex < this.order.length){
+ if (nextIndex < this.order.length) {
var nextElement = OpenLayers.Util.getElement(this.order[nextIndex]);
- if (nextElement == undefined){
- nextElement = this.getNextElement(nextIndex);
+ if (nextElement == undefined) {
+ nextElement = this.getNextElement(nextIndex);
}
return nextElement;
} else {
return null;
- }
+ }
},
-
+
CLASS_NAME: "OpenLayers.ElementsIndexer"
});
/**
* Namespace: OpenLayers.ElementsIndexer.IndexingMethods
- * These are the compare methods for figuring out where a new node should be
- * placed within the indexer. These methods are very similar to general
- * sorting methods in that they return -1, 0, and 1 to specify the
+ * These are the compare methods for figuring out where a new node should be
+ * placed within the indexer. These methods are very similar to general
+ * sorting methods in that they return -1, 0, and 1 to specify the
* direction in which new nodes fall in the ordering.
*/
OpenLayers.ElementsIndexer.IndexingMethods = {
-
+
/**
* Method: Z_ORDER
* This compare method is used by other comparison methods.
* It can be used individually for ordering, but is not recommended,
* because it doesn't subscribe to drawing order.
- *
+ *
* Parameters:
* indexer - {<OpenLayers.ElementsIndexer>}
* newNode - {DOMElement}
* nextNode - {DOMElement}
- *
+ *
* Returns:
* {Integer}
*/
@@ -7666,93 +8241,90 @@
var returnVal = 0;
if (nextNode) {
var nextZIndex = indexer.getZIndex(nextNode);
- returnVal = newZIndex - nextZIndex;
+ returnVal = newZIndex - nextZIndex;
}
-
+
return returnVal;
},
/**
* APIMethod: Z_ORDER_DRAWING_ORDER
* This method orders nodes by their z-index, but does so in a way
- * that, if there are other nodes with the same z-index, the newest
- * drawn will be the front most within that z-index. This is the
+ * that, if there are other nodes with the same z-index, the newest
+ * drawn will be the front most within that z-index. This is the
* default indexing method.
- *
+ *
* Parameters:
* indexer - {<OpenLayers.ElementsIndexer>}
* newNode - {DOMElement}
* nextNode - {DOMElement}
- *
+ *
* Returns:
* {Integer}
*/
Z_ORDER_DRAWING_ORDER: function(indexer, newNode, nextNode) {
var returnVal = OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER(
- indexer,
- newNode,
+ indexer,
+ newNode,
nextNode
);
-
+
// Make Z_ORDER subscribe to drawing order by pushing it above
// all of the other nodes with the same z-index.
if (nextNode && returnVal == 0) {
returnVal = 1;
}
-
+
return returnVal;
},
/**
* APIMethod: Z_ORDER_Y_ORDER
* This one should really be called Z_ORDER_Y_ORDER_DRAWING_ORDER, as it
- * best describes which ordering methods have precedence (though, the
- * name would be too long). This method orders nodes by their z-index,
- * but does so in a way that, if there are other nodes with the same
- * z-index, the nodes with the lower y position will be "closer" than
- * those with a higher y position. If two nodes have the exact same y
- * position, however, then this method will revert to using drawing
+ * best describes which ordering methods have precedence (though, the
+ * name would be too long). This method orders nodes by their z-index,
+ * but does so in a way that, if there are other nodes with the same
+ * z-index, the nodes with the lower y position will be "closer" than
+ * those with a higher y position. If two nodes have the exact same y
+ * position, however, then this method will revert to using drawing
* order to decide placement.
- *
+ *
* Parameters:
* indexer - {<OpenLayers.ElementsIndexer>}
* newNode - {DOMElement}
* nextNode - {DOMElement}
- *
+ *
* Returns:
* {Integer}
*/
Z_ORDER_Y_ORDER: function(indexer, newNode, nextNode) {
var returnVal = OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER(
- indexer,
- newNode,
+ indexer,
+ newNode,
nextNode
);
-
- if (nextNode && returnVal == 0) {
- var newLat = newNode._geometry.getBounds().bottom;
- var nextLat = nextNode._geometry.getBounds().bottom;
-
- var result = nextLat - newLat;
- returnVal = (result ==0) ? 1 : result;
+
+ if (nextNode && returnVal === 0) {
+ var result = nextNode._boundsBottom - newNode._boundsBottom;
+ returnVal = (result === 0) ? 1 : result;
}
-
- return returnVal;
+
+ return returnVal;
}
};
/**
* Class: OpenLayers.Renderer.Elements
- * This is another virtual class in that it should never be instantiated by
- * itself as a Renderer. It exists because there is *tons* of shared
+ * This is another virtual class in that it should never be instantiated by
+ * itself as a Renderer. It exists because there is *tons* of shared
* functionality between different vector libraries which use nodes/elements
- * as a base for rendering vectors.
- *
- * The highlevel bits of code that are implemented here are the adding and
- * removing of geometries, which is essentially the same for any
+ * as a base for rendering vectors.
+ *
+ * The highlevel bits of code that are implemented here are the adding and
+ * removing of geometries, which is essentially the same for any
* element-based renderer. The details of creating each node and drawing the
- * paths are of course different, but the machinery is the same.
- *
+ * paths are of course different, but the machinery is the same.
+ *
* Inherits:
* - <OpenLayers.Renderer>
*/
@@ -7763,13 +8335,13 @@
* {DOMElement}
*/
rendererRoot: null,
-
+
/**
* Property: root
* {DOMElement}
*/
root: null,
-
+
/**
* Property: vectorRoot
* {DOMElement}
@@ -7785,44 +8357,32 @@
/**
* Property: xmlns
* {String}
- */
+ */
xmlns: null,
-
+
/**
* Property: Indexer
- * {<OpenLayers.ElementIndexer>} An instance of OpenLayers.ElementsIndexer
+ * {<OpenLayers.ElementIndexer>} An instance of OpenLayers.ElementsIndexer
* created upon initialization if the zIndexing or yOrdering options
* passed to this renderer's constructor are set to true.
*/
- indexer: null,
-
+ indexer: null,
+
/**
* Constant: BACKGROUND_ID_SUFFIX
* {String}
*/
BACKGROUND_ID_SUFFIX: "_background",
-
+
/**
* Constant: BACKGROUND_ID_SUFFIX
* {String}
*/
LABEL_ID_SUFFIX: "_label",
-
+
/**
- * Property: minimumSymbolizer
- * {Object}
- */
- minimumSymbolizer: {
- strokeLinecap: "round",
- strokeOpacity: 1,
- strokeDashstyle: "solid",
- fillOpacity: 1,
- pointRadius: 0
- },
-
- /**
* Constructor: OpenLayers.Renderer.Elements
- *
+ *
* Parameters:
* containerID - {String}
* options - {Object} options for this renderer. Supported options are:
@@ -7837,24 +8397,24 @@
this.root = this.createRoot("_root");
this.vectorRoot = this.createRoot("_vroot");
this.textRoot = this.createRoot("_troot");
-
+
this.root.appendChild(this.vectorRoot);
this.root.appendChild(this.textRoot);
-
+
this.rendererRoot.appendChild(this.root);
this.container.appendChild(this.rendererRoot);
-
+
if(options && (options.zIndexing || options.yOrdering)) {
this.indexer = new OpenLayers.ElementsIndexer(options.yOrdering);
}
},
-
+
/**
* Method: destroy
*/
destroy: function() {
- this.clear();
+ this.clear();
this.rendererRoot = null;
this.root = null;
@@ -7862,20 +8422,23 @@
OpenLayers.Renderer.prototype.destroy.apply(this, arguments);
},
-
+
/**
* Method: clear
* Remove all the elements from the root
- */
+ */
clear: function() {
- if (this.vectorRoot) {
- while (this.vectorRoot.childNodes.length > 0) {
- this.vectorRoot.removeChild(this.vectorRoot.firstChild);
+ var child;
+ var root = this.vectorRoot;
+ if (root) {
+ while (child = root.firstChild) {
+ root.removeChild(child);
}
}
- if (this.textRoot) {
- while (this.textRoot.childNodes.length > 0) {
- this.textRoot.removeChild(this.textRoot.firstChild);
+ root = this.textRoot;
+ if (root) {
+ while (child = root.firstChild) {
+ root.removeChild(child);
}
}
if (this.indexer) {
@@ -7883,26 +8446,26 @@
}
},
- /**
+ /**
* Method: getNodeType
* This function is in charge of asking the specific renderer which type
* of node to create for the given geometry and style. All geometries
* in an Elements-based renderer consist of one node and some
* attributes. We have the nodeFactory() function which creates a node
* for us, but it takes a 'type' as input, and that is precisely what
- * this function tells us.
- *
+ * this function tells us.
+ *
* Parameters:
* geometry - {<OpenLayers.Geometry>}
* style - {Object}
- *
+ *
* Returns:
* {String} The corresponding node type for the specified geometry
*/
getNodeType: function(geometry, style) { },
- /**
- * Method: drawGeometry
+ /**
+ * Method: drawGeometry
* Draw the geometry, creating new nodes, setting paths, setting style,
* setting featureId on the node. This method should only be called
* by the renderer itself.
@@ -7911,7 +8474,7 @@
* geometry - {<OpenLayers.Geometry>}
* style - {Object}
* featureId - {String}
- *
+ *
* Returns:
* {Boolean} true if the geometry has been drawn completely; null if
* incomplete; false otherwise
@@ -7951,27 +8514,28 @@
}
return rendered;
},
-
+
/**
* Method: redrawNode
- *
+ *
* Parameters:
* id - {String}
* geometry - {<OpenLayers.Geometry>}
* style - {Object}
* featureId - {String}
- *
+ *
* Returns:
* {Boolean} true if the complete geometry could be drawn, null if parts of
* the geometry could not be drawn, false otherwise
*/
redrawNode: function(id, geometry, style, featureId) {
+ style = this.applyDefaultSymbolizer(style);
// Get the node if it's already on the map.
var node = this.nodeFactory(id, this.getNodeType(geometry, style));
-
+
// Set the data for the node, then draw it.
node._featureId = featureId;
- node._geometry = geometry;
+ node._boundsBottom = geometry.getBounds().bottom;
node._geometryClass = geometry.CLASS_NAME;
node._style = style;
@@ -7979,9 +8543,9 @@
if(drawResult === false) {
return false;
}
-
+
node = drawResult.node;
-
+
// Insert the node into the indexer so it can show us where to
// place it. Note that this operation is O(log(n)). If there's a
// performance problem (when dragging, for instance) this is
@@ -7996,39 +8560,39 @@
} else {
// if there's no indexer, simply append the node to root,
// but only if the node is a new one
- if (node.parentNode !== this.vectorRoot){
+ if (node.parentNode !== this.vectorRoot){
this.vectorRoot.appendChild(node);
}
}
-
+
this.postDraw(node);
-
+
return drawResult.complete;
},
-
+
/**
* Method: redrawBackgroundNode
* Redraws the node using special 'background' style properties. Basically
- * just calls redrawNode(), but instead of directly using the
- * 'externalGraphic', 'graphicXOffset', 'graphicYOffset', and
- * 'graphicZIndex' properties directly from the specified 'style'
- * parameter, we create a new style object and set those properties
- * from the corresponding 'background'-prefixed properties from
+ * just calls redrawNode(), but instead of directly using the
+ * 'externalGraphic', 'graphicXOffset', 'graphicYOffset', and
+ * 'graphicZIndex' properties directly from the specified 'style'
+ * parameter, we create a new style object and set those properties
+ * from the corresponding 'background'-prefixed properties from
* specified 'style' parameter.
- *
+ *
* Parameters:
* id - {String}
* geometry - {<OpenLayers.Geometry>}
* style - {Object}
* featureId - {String}
- *
+ *
* Returns:
* {Boolean} true if the complete geometry could be drawn, null if parts of
* the geometry could not be drawn, false otherwise
*/
redrawBackgroundNode: function(id, geometry, style, featureId) {
var backgroundStyle = OpenLayers.Util.extend({}, style);
-
+
// Set regular style attributes to apply to the background styles.
backgroundStyle.externalGraphic = backgroundStyle.backgroundGraphic;
backgroundStyle.graphicXOffset = backgroundStyle.backgroundXOffset;
@@ -8036,17 +8600,17 @@
backgroundStyle.graphicZIndex = backgroundStyle.backgroundGraphicZIndex;
backgroundStyle.graphicWidth = backgroundStyle.backgroundWidth || backgroundStyle.graphicWidth;
backgroundStyle.graphicHeight = backgroundStyle.backgroundHeight || backgroundStyle.graphicHeight;
-
+
// Erase background styles.
backgroundStyle.backgroundGraphic = null;
backgroundStyle.backgroundXOffset = null;
backgroundStyle.backgroundYOffset = null;
backgroundStyle.backgroundGraphicZIndex = null;
-
+
return this.redrawNode(
- id + this.BACKGROUND_ID_SUFFIX,
- geometry,
- backgroundStyle,
+ id + this.BACKGROUND_ID_SUFFIX,
+ geometry,
+ backgroundStyle,
null
);
},
@@ -8061,7 +8625,7 @@
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
* style - {Object}
- *
+ *
* Returns:
* {Object} a hash with properties "node" (the drawn node) and "complete"
* (null if parts of the geometry could not be drawn, false if nothing
@@ -8069,7 +8633,6 @@
*/
drawGeometryNode: function(node, geometry, style) {
style = style || node._style;
- OpenLayers.Util.applyDefaults(style, this.minimumSymbolizer);
var options = {
'isFilled': style.fill === undefined ?
@@ -8108,8 +8671,7 @@
break;
}
- node._style = style;
- node._options = options;
+ node._options = options;
//set style
//TBD simplify this
@@ -8122,129 +8684,129 @@
return false;
}
},
-
+
/**
* Method: postDraw
* Things that have do be done after the geometry node is appended
* to its parent node. To be overridden by subclasses.
- *
+ *
* Parameters:
* node - {DOMElement}
*/
postDraw: function(node) {},
-
+
/**
* Method: drawPoint
- * Virtual function for drawing Point Geometry.
+ * Virtual function for drawing Point Geometry.
* Should be implemented by subclasses.
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
- *
+ *
* Returns:
* {DOMElement} or false if the renderer could not draw the point
- */
+ */
drawPoint: function(node, geometry) {},
/**
* Method: drawLineString
- * Virtual function for drawing LineString Geometry.
+ * Virtual function for drawing LineString Geometry.
* Should be implemented by subclasses.
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
- *
+ *
* Returns:
* {DOMElement} or null if the renderer could not draw all components of
* the linestring, or false if nothing could be drawn
- */
+ */
drawLineString: function(node, geometry) {},
/**
* Method: drawLinearRing
- * Virtual function for drawing LinearRing Geometry.
+ * Virtual function for drawing LinearRing Geometry.
* Should be implemented by subclasses.
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
- *
+ *
* Returns:
* {DOMElement} or null if the renderer could not draw all components
* of the linear ring, or false if nothing could be drawn
- */
+ */
drawLinearRing: function(node, geometry) {},
/**
* Method: drawPolygon
- * Virtual function for drawing Polygon Geometry.
+ * Virtual function for drawing Polygon Geometry.
* Should be implemented by subclasses.
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
- *
+ *
* Returns:
* {DOMElement} or null if the renderer could not draw all components
* of the polygon, or false if nothing could be drawn
- */
+ */
drawPolygon: function(node, geometry) {},
/**
* Method: drawRectangle
- * Virtual function for drawing Rectangle Geometry.
+ * Virtual function for drawing Rectangle Geometry.
* Should be implemented by subclasses.
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
- *
+ *
* Returns:
* {DOMElement} or false if the renderer could not draw the rectangle
- */
+ */
drawRectangle: function(node, geometry) {},
/**
* Method: drawCircle
- * Virtual function for drawing Circle Geometry.
+ * Virtual function for drawing Circle Geometry.
* Should be implemented by subclasses.
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
- *
+ *
* Returns:
* {DOMElement} or false if the renderer could not draw the circle
- */
+ */
drawCircle: function(node, geometry) {},
/**
* Method: drawSurface
- * Virtual function for drawing Surface Geometry.
+ * Virtual function for drawing Surface Geometry.
* Should be implemented by subclasses.
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
- *
+ *
* Returns:
* {DOMElement} or false if the renderer could not draw the surface
- */
+ */
drawSurface: function(node, geometry) {},
/**
* Method: removeText
* Removes a label
- *
+ *
* Parameters:
* featureId - {String}
*/
@@ -8257,12 +8819,12 @@
/**
* Method: getFeatureIdFromEvent
- *
+ *
* Parameters:
* evt - {Object} An <OpenLayers.Event> object
*
* Returns:
- * {<OpenLayers.Geometry>} A geometry from an event that
+ * {<OpenLayers.Geometry>} A geometry from an event that
* happened on a layer.
*/
getFeatureIdFromEvent: function(evt) {
@@ -8273,25 +8835,26 @@
return featureId;
},
- /**
+ /**
* Method: eraseGeometry
- * Erase a geometry from the renderer. In the case of a multi-geometry,
- * we cycle through and recurse on ourselves. Otherwise, we look for a
+ * Erase a geometry from the renderer. In the case of a multi-geometry,
+ * we cycle through and recurse on ourselves. Otherwise, we look for a
* node with the geometry.id, destroy its geometry, and remove it from
* the DOM.
- *
+ *
* Parameters:
* geometry - {<OpenLayers.Geometry>}
+ * featureId - {String}
*/
- eraseGeometry: function(geometry) {
+ eraseGeometry: function(geometry, featureId) {
if ((geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPoint") ||
(geometry.CLASS_NAME == "OpenLayers.Geometry.MultiLineString") ||
(geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPolygon") ||
(geometry.CLASS_NAME == "OpenLayers.Geometry.Collection")) {
for (var i=0, len=geometry.components.length; i<len; i++) {
- this.eraseGeometry(geometry.components[i]);
+ this.eraseGeometry(geometry.components[i], featureId);
}
- } else {
+ } else {
var element = OpenLayers.Util.getElement(geometry.id);
if (element && element.parentNode) {
if (element.geometry) {
@@ -8303,7 +8866,7 @@
if (this.indexer) {
this.indexer.remove(element);
}
-
+
if (element._style.backgroundGraphic) {
var backgroundId = geometry.id + this.BACKGROUND_ID_SUFFIX;
var bElem = OpenLayers.Util.getElement(backgroundId);
@@ -8317,17 +8880,17 @@
}
},
- /**
+ /**
* Method: nodeFactory
* Create new node of the specified type, with the (optional) specified id.
- *
+ *
* If node already exists with same ID and a different type, we remove it
* and then call ourselves again to recreate it.
- *
+ *
* Parameters:
* id - {String}
* type - {String} type Kind of node to draw.
- *
+ *
* Returns:
* {DOMElement} A new node of the given type and id.
*/
@@ -8343,27 +8906,27 @@
}
return node;
},
-
- /**
+
+ /**
* Method: nodeTypeCompare
- *
+ *
* Parameters:
* node - {DOMElement}
* type - {String} Kind of node
- *
+ *
* Returns:
* {Boolean} Whether or not the specified node is of the specified type
* This function must be overridden by subclasses.
*/
nodeTypeCompare: function(node, type) {},
-
- /**
+
+ /**
* Method: createNode
- *
+ *
* Parameters:
* type - {String} Kind of node to draw.
* id - {String} Id for node.
- *
+ *
* Returns:
* {DOMElement} A new node of the given type and id.
* This function must be overridden by subclasses.
@@ -8373,7 +8936,7 @@
/**
* Method: moveRoot
* moves this renderer's root to a different renderer.
- *
+ *
* Parameters:
* renderer - {<OpenLayers.Renderer>} target renderer for the moved root
*/
@@ -8385,27 +8948,27 @@
root.parentNode.removeChild(root);
renderer.rendererRoot.appendChild(root);
},
-
+
/**
* Method: getRenderLayerId
* Gets the layer that this renderer's output appears on. If moveRoot was
* used, this will be different from the id of the layer containing the
* features rendered by this renderer.
- *
+ *
* Returns:
* {String} the id of the output layer.
*/
getRenderLayerId: function() {
return this.root.parentNode.parentNode.id;
},
-
+
/**
* Method: isComplexSymbol
* Determines if a symbol cannot be rendered using drawCircle
- *
+ *
* Parameters:
* graphicName - {String}
- *
+ *
* Returns
* {Boolean} true if the symbol is complex, false if not
*/
@@ -8434,8 +8997,9 @@
OpenLayers/Strategy/Fixed.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -8450,12 +9014,12 @@
* - <OpenLayers.Strategy>
*/
OpenLayers.Strategy.Fixed = OpenLayers.Class(OpenLayers.Strategy, {
-
+
/**
* APIProperty: preload
* {Boolean} Load data before layer made visible. Enabling this may result
* in considerable overhead if your application loads many data layers
- * that are not visible by default. Default is true.
+ * that are not visible by default. Default is false.
*/
preload: false,
@@ -8505,11 +9069,11 @@
}
return false;
},
-
+
/**
* Method: deactivate
* Deactivate the strategy. Undo what is done in <activate>.
- *
+ *
* Returns:
* {Boolean} The strategy was successfully deactivated.
*/
@@ -8536,6 +9100,7 @@
this.layer.events.triggerEvent("loadstart");
this.layer.protocol.read(OpenLayers.Util.applyDefaults({
callback: this.merge,
+ filter: this.layer.filter,
scope: this
}, options));
this.layer.events.un({
@@ -8571,11 +9136,422 @@
CLASS_NAME: "OpenLayers.Strategy.Fixed"
});
/* ======================================================================
+ OpenLayers/Symbolizer/Line.js
+ ====================================================================== */
+
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+/**
+ * @requires OpenLayers/Symbolizer.js
+ */
+
+/**
+ * Class: OpenLayers.Symbolizer.Line
+ * A symbolizer used to render line features.
+ */
+OpenLayers.Symbolizer.Line = OpenLayers.Class(OpenLayers.Symbolizer, {
+
+ /**
+ * APIProperty: strokeColor
+ * {String} Color for line stroke. This is a RGB hex value (e.g. "#ff0000"
+ * for red).
+ */
+ strokeColor: null,
+
+ /**
+ * APIProperty: strokeOpacity
+ * {Number} Stroke opacity (0-1).
+ */
+ strokeOpacity: null,
+
+ /**
+ * APIProperty: strokeWidth
+ * {Number} Pixel stroke width.
+ */
+ strokeWidth: null,
+
+ /**
+ * APIProperty: strokeLinecap
+ * {String} Stroke cap type ("butt", "round", or "square").
+ */
+ strokeLinecap: null,
+
+ /**
+ * Property: strokeDashstyle
+ * {String} Stroke dash style according to the SLD spec. Note that the
+ * OpenLayers values for strokeDashstyle ("dot", "dash", "dashdot",
+ * "longdash", "longdashdot", or "solid") will not work in SLD, but
+ * most SLD patterns will render correctly in OpenLayers.
+ */
+ strokeDashstyle: null,
+
+ /**
+ * Constructor: OpenLayers.Symbolizer.Line
+ * Create a symbolizer for rendering lines.
+ *
+ * Parameters:
+ * config - {Object} An object containing properties to be set on the
+ * symbolizer. Any documented symbolizer property can be set at
+ * construction.
+ *
+ * Returns:
+ * A new line symbolizer.
+ */
+ initialize: function(config) {
+ OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments);
+ },
+
+ CLASS_NAME: "OpenLayers.Symbolizer.Line"
+
+});
+
+/* ======================================================================
+ OpenLayers/Symbolizer/Point.js
+ ====================================================================== */
+
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+/**
+ * @requires OpenLayers/Symbolizer.js
+ */
+
+/**
+ * Class: OpenLayers.Symbolizer.Point
+ * A symbolizer used to render point features.
+ */
+OpenLayers.Symbolizer.Point = OpenLayers.Class(OpenLayers.Symbolizer, {
+
+ /**
+ * APIProperty: strokeColor
+ * {String} Color for line stroke. This is a RGB hex value (e.g. "#ff0000"
+ * for red).
+ */
+ strokeColor: null,
+
+ /**
+ * APIProperty: strokeOpacity
+ * {Number} Stroke opacity (0-1).
+ */
+ strokeOpacity: null,
+
+ /**
+ * APIProperty: strokeWidth
+ * {Number} Pixel stroke width.
+ */
+ strokeWidth: null,
+
+ /**
+ * APIProperty: strokeLinecap
+ * {String} Stroke cap type ("butt", "round", or "square").
+ */
+ strokeLinecap: null,
+
+ /**
+ * Property: strokeDashstyle
+ * {String} Stroke dash style according to the SLD spec. Note that the
+ * OpenLayers values for strokeDashstyle ("dot", "dash", "dashdot",
+ * "longdash", "longdashdot", or "solid") will not work in SLD, but
+ * most SLD patterns will render correctly in OpenLayers.
+ */
+ strokeDashstyle: null,
+
+ /**
+ * APIProperty: fillColor
+ * {String} RGB hex fill color (e.g. "#ff0000" for red).
+ */
+ fillColor: null,
+
+ /**
+ * APIProperty: fillOpacity
+ * {Number} Fill opacity (0-1).
+ */
+ fillOpacity: null,
+
+ /**
+ * APIProperty: pointRadius
+ * {Number} Pixel point radius.
+ */
+ pointRadius: null,
+
+ /**
+ * APIProperty: externalGraphic
+ * {String} Url to an external graphic that will be used for rendering
+ * points.
+ */
+ externalGraphic: null,
+
+ /**
+ * APIProperty: graphicWidth
+ * {Number} Pixel width for sizing an external graphic.
+ */
+ graphicWidth: null,
+
+ /**
+ * APIProperty: graphicHeight
+ * {Number} Pixel height for sizing an external graphic.
+ */
+ graphicHeight: null,
+
+ /**
+ * APIProperty: graphicOpacity
+ * {Number} Opacity (0-1) for an external graphic.
+ */
+ graphicOpacity: null,
+
+ /**
+ * APIProperty: graphicXOffset
+ * {Number} Pixel offset along the positive x axis for displacing an
+ * external graphic.
+ */
+ graphicXOffset: null,
+
+ /**
+ * APIProperty: graphicYOffset
+ * {Number} Pixel offset along the positive y axis for displacing an
+ * external graphic.
+ */
+ graphicYOffset: null,
+
+ /**
+ * APIProperty: rotation
+ * {Number} The rotation of a graphic in the clockwise direction about its
+ * center point (or any point off center as specified by
+ * <graphicXOffset> and <graphicYOffset>).
+ */
+ rotation: null,
+
+ /**
+ * APIProperty: graphicName
+ * {String} Named graphic to use when rendering points. Supported values
+ * include "circle", "square", "star", "x", "cross", and "triangle".
+ */
+ graphicName: null,
+
+ /**
+ * Constructor: OpenLayers.Symbolizer.Point
+ * Create a symbolizer for rendering points.
+ *
+ * Parameters:
+ * config - {Object} An object containing properties to be set on the
+ * symbolizer. Any documented symbolizer property can be set at
+ * construction.
+ *
+ * Returns:
+ * A new point symbolizer.
+ */
+ initialize: function(config) {
+ OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments);
+ },
+
+ CLASS_NAME: "OpenLayers.Symbolizer.Point"
+
+});
+
+/* ======================================================================
+ OpenLayers/Symbolizer/Polygon.js
+ ====================================================================== */
+
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+/**
+ * @requires OpenLayers/Symbolizer.js
+ */
+
+/**
+ * Class: OpenLayers.Symbolizer.Polygon
+ * A symbolizer used to render line features.
+ */
+OpenLayers.Symbolizer.Polygon = OpenLayers.Class(OpenLayers.Symbolizer, {
+
+ /**
+ * APIProperty: strokeColor
+ * {String} Color for line stroke. This is a RGB hex value (e.g. "#ff0000"
+ * for red).
+ */
+ strokeColor: null,
+
+ /**
+ * APIProperty: strokeOpacity
+ * {Number} Stroke opacity (0-1).
+ */
+ strokeOpacity: null,
+
+ /**
+ * APIProperty: strokeWidth
+ * {Number} Pixel stroke width.
+ */
+ strokeWidth: null,
+
+ /**
+ * APIProperty: strokeLinecap
+ * {String} Stroke cap type ("butt", "round", or "square").
+ */
+ strokeLinecap: null,
+
+ /**
+ * Property: strokeDashstyle
+ * {String} Stroke dash style according to the SLD spec. Note that the
+ * OpenLayers values for strokeDashstyle ("dot", "dash", "dashdot",
+ * "longdash", "longdashdot", or "solid") will not work in SLD, but
+ * most SLD patterns will render correctly in OpenLayers.
+ */
+ strokeDashstyle: null,
+
+ /**
+ * APIProperty: fillColor
+ * {String} RGB hex fill color (e.g. "#ff0000" for red).
+ */
+ fillColor: null,
+
+ /**
+ * APIProperty: fillOpacity
+ * {Number} Fill opacity (0-1).
+ */
+ fillOpacity: null,
+
+ /**
+ * Constructor: OpenLayers.Symbolizer.Polygon
+ * Create a symbolizer for rendering polygons.
+ *
+ * Parameters:
+ * config - {Object} An object containing properties to be set on the
+ * symbolizer. Any documented symbolizer property can be set at
+ * construction.
+ *
+ * Returns:
+ * A new polygon symbolizer.
+ */
+ initialize: function(config) {
+ OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments);
+ },
+
+ CLASS_NAME: "OpenLayers.Symbolizer.Polygon"
+
+});
+
+/* ======================================================================
+ OpenLayers/Symbolizer/Raster.js
+ ====================================================================== */
+
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+/**
+ * @requires OpenLayers/Symbolizer.js
+ */
+
+/**
+ * Class: OpenLayers.Symbolizer.Raster
+ * A symbolizer used to render raster images.
+ */
+OpenLayers.Symbolizer.Raster = OpenLayers.Class(OpenLayers.Symbolizer, {
+
+ /**
+ * Constructor: OpenLayers.Symbolizer.Raster
+ * Create a symbolizer for rendering rasters.
+ *
+ * Parameters:
+ * config - {Object} An object containing properties to be set on the
+ * symbolizer. Any documented symbolizer property can be set at
+ * construction.
+ *
+ * Returns:
+ * A new raster symbolizer.
+ */
+ initialize: function(config) {
+ OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments);
+ },
+
+ CLASS_NAME: "OpenLayers.Symbolizer.Raster"
+
+});
+/* ======================================================================
+ OpenLayers/Symbolizer/Text.js
+ ====================================================================== */
+
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+/**
+ * @requires OpenLayers/Symbolizer.js
+ */
+
+/**
+ * Class: OpenLayers.Symbolizer.Text
+ * A symbolizer used to render text labels for features.
+ */
+OpenLayers.Symbolizer.Text = OpenLayers.Class(OpenLayers.Symbolizer, {
+
+ /**
+ * APIProperty: label
+ * {String} The text for the label.
+ */
+ label: null,
+
+ /**
+ * APIProperty: fontFamily
+ * {String} The font family for the label.
+ */
+ fontFamily: null,
+
+ /**
+ * APIProperty: fontSize
+ * {String} The font size for the label.
+ */
+ fontSize: null,
+
+ /**
+ * APIProperty: fontWeight
+ * {String} The font weight for the label.
+ */
+ fontWeight: null,
+
+ /**
+ * Property: fontStyle
+ * {String} The font style for the label.
+ */
+ fontStyle: null,
+
+ /**
+ * Constructor: OpenLayers.Symbolizer.Text
+ * Create a symbolizer for rendering text labels.
+ *
+ * Parameters:
+ * config - {Object} An object containing properties to be set on the
+ * symbolizer. Any documented symbolizer property can be set at
+ * construction.
+ *
+ * Returns:
+ * A new text symbolizer.
+ */
+ initialize: function(config) {
+ OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments);
+ },
+
+ CLASS_NAME: "OpenLayers.Symbolizer.Text"
+
+});
+
+/* ======================================================================
OpenLayers/Tween.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -8586,38 +9562,38 @@
* Namespace: OpenLayers.Tween
*/
OpenLayers.Tween = OpenLayers.Class({
-
+
/**
* Constant: INTERVAL
* {int} Interval in milliseconds between 2 steps
*/
INTERVAL: 10,
-
+
/**
* APIProperty: easing
* {<OpenLayers.Easing>(Function)} Easing equation used for the animation
* Defaultly set to OpenLayers.Easing.Expo.easeOut
*/
easing: null,
-
+
/**
* APIProperty: begin
* {Object} Values to start the animation with
*/
begin: null,
-
+
/**
* APIProperty: finish
* {Object} Values to finish the animation with
*/
finish: null,
-
+
/**
* APIProperty: duration
* {int} duration of the tween (number of steps)
*/
duration: null,
-
+
/**
* APIProperty: callbacks
* {Object} An object with start, eachStep and done properties whose values
@@ -8625,40 +9601,40 @@
* current computed value as argument.
*/
callbacks: null,
-
+
/**
* Property: time
* {int} Step counter
*/
time: null,
-
+
/**
* Property: interval
* {int} Interval id returned by window.setInterval
*/
interval: null,
-
+
/**
* Property: playing
* {Boolean} Tells if the easing is currently playing
*/
playing: false,
-
- /**
+
+ /**
* Constructor: OpenLayers.Tween
* Creates a Tween.
*
* Parameters:
* easing - {<OpenLayers.Easing>(Function)} easing function method to use
- */
+ */
initialize: function(easing) {
this.easing = (easing) ? easing : OpenLayers.Easing.Expo.easeOut;
},
-
+
/**
* APIMethod: start
* Plays the Tween, and calls the callback method on each step
- *
+ *
* Parameters:
* begin - {Object} values to start the animation with
* finish - {Object} values to finish the animation with
@@ -8682,7 +9658,7 @@
this.interval = window.setInterval(
OpenLayers.Function.bind(this.play, this), this.INTERVAL);
},
-
+
/**
* APIMethod: stop
* Stops the Tween, and calls the done callback
@@ -8692,7 +9668,7 @@
if (!this.playing) {
return;
}
-
+
if (this.callbacks && this.callbacks.done) {
this.callbacks.done.call(this, this.finish);
}
@@ -8700,7 +9676,7 @@
this.interval = null;
this.playing = false;
},
-
+
/**
* Method: play
* Calls the appropriate easing method
@@ -8713,26 +9689,21 @@
if (b == null || f == null || isNaN(b) || isNaN(f)) {
OpenLayers.Console.error('invalid value for Tween');
}
-
+
var c = f - b;
value[i] = this.easing.apply(this, [this.time, b, c, this.duration]);
}
this.time++;
-
+
if (this.callbacks && this.callbacks.eachStep) {
this.callbacks.eachStep.call(this, value);
}
-
+
if (this.time > this.duration) {
- if (this.callbacks && this.callbacks.done) {
- this.callbacks.done.call(this, this.finish);
- this.playing = false;
- }
- window.clearInterval(this.interval);
- this.interval = null;
+ this.stop();
}
},
-
+
/**
* Create empty functions for all easing methods.
*/
@@ -8741,7 +9712,7 @@
/**
* Namespace: OpenLayers.Easing
- *
+ *
* Credits:
* Easing Equations by Robert Penner, <http://www.robertpenner.com/easing/>
*/
@@ -8756,10 +9727,10 @@
* Namespace: OpenLayers.Easing.Linear
*/
OpenLayers.Easing.Linear = {
-
+
/**
* Function: easeIn
- *
+ *
* Parameters:
* t - {Float} time
* b - {Float} beginning position
@@ -8769,10 +9740,10 @@
easeIn: function(t, b, c, d) {
return c*t/d + b;
},
-
+
/**
* Function: easeOut
- *
+ *
* Parameters:
* t - {Float} time
* b - {Float} beginning position
@@ -8782,10 +9753,10 @@
easeOut: function(t, b, c, d) {
return c*t/d + b;
},
-
+
/**
* Function: easeInOut
- *
+ *
* Parameters:
* t - {Float} time
* b - {Float} beginning position
@@ -8803,10 +9774,10 @@
* Namespace: OpenLayers.Easing.Expo
*/
OpenLayers.Easing.Expo = {
-
+
/**
* Function: easeIn
- *
+ *
* Parameters:
* t - {Float} time
* b - {Float} beginning position
@@ -8816,10 +9787,10 @@
easeIn: function(t, b, c, d) {
return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
},
-
+
/**
* Function: easeOut
- *
+ *
* Parameters:
* t - {Float} time
* b - {Float} beginning position
@@ -8829,10 +9800,10 @@
easeOut: function(t, b, c, d) {
return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
},
-
+
/**
* Function: easeInOut
- *
+ *
* Parameters:
* t - {Float} time
* b - {Float} beginning position
@@ -8853,10 +9824,10 @@
* Namespace: OpenLayers.Easing.Quad
*/
OpenLayers.Easing.Quad = {
-
+
/**
* Function: easeIn
- *
+ *
* Parameters:
* t - {Float} time
* b - {Float} beginning position
@@ -8866,10 +9837,10 @@
easeIn: function(t, b, c, d) {
return c*(t/=d)*t + b;
},
-
+
/**
* Function: easeOut
- *
+ *
* Parameters:
* t - {Float} time
* b - {Float} beginning position
@@ -8879,10 +9850,10 @@
easeOut: function(t, b, c, d) {
return -c *(t/=d)*(t-2) + b;
},
-
+
/**
* Function: easeInOut
- *
+ *
* Parameters:
* t - {Float} time
* b - {Float} beginning position
@@ -8900,8 +9871,9 @@
OpenLayers/Control/ArgParser.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
@@ -8911,11 +9883,11 @@
/**
* Class: OpenLayers.Control.ArgParser
- * The ArgParser control adds location bar querystring parsing functionality
+ * The ArgParser control adds location bar querystring parsing functionality
* to an OpenLayers Map.
- * When added to a Map control, on a page load/refresh, the Map will
- * automatically take the href string and parse it for lon, lat, zoom, and
- * layers information.
+ * When added to a Map control, on a page load/refresh, the Map will
+ * automatically take the href string and parse it for lon, lat, zoom, and
+ * layers information.
*
* Inherits from:
* - <OpenLayers.Control>
@@ -8927,7 +9899,7 @@
* {<OpenLayers.LonLat>}
*/
center: null,
-
+
/**
* Parameter: zoom
* {int}
@@ -8935,14 +9907,14 @@
zoom: null,
/**
- * Parameter: layers
+ * Parameter: layers
* {Array(<OpenLayers.Layer>)}
*/
layers: null,
-
- /**
+
+ /**
* APIProperty: displayProjection
- * {<OpenLayers.Projection>} Requires proj4js support.
+ * {<OpenLayers.Projection>} Requires proj4js support.
* Projection used when reading the coordinates from the URL. This will
*
* reproject the map coordinates from the URL into the map's
@@ -8951,9 +9923,9 @@
* If you are using this functionality, be aware that any permalink
* which is added to the map will determine the coordinate type which
* is read from the URL, which means you should not add permalinks with
- * different displayProjections to the same map.
+ * different displayProjections to the same map.
*/
- displayProjection: null,
+ displayProjection: null,
/**
* Constructor: OpenLayers.Control.ArgParser
@@ -8967,10 +9939,10 @@
/**
* Method: setMap
- * Set the map property for the control.
- *
+ * Set the map property for the control.
+ *
* Parameters:
- * map - {<OpenLayers.Map>}
+ * map - {<OpenLayers.Map>}
*/
setMap: function(map) {
OpenLayers.Control.prototype.setMap.apply(this, arguments);
@@ -8980,14 +9952,14 @@
var control = this.map.controls[i];
if ( (control != this) &&
(control.CLASS_NAME == "OpenLayers.Control.ArgParser") ) {
-
- // If a second argparser is added to the map, then we
+
+ // If a second argparser is added to the map, then we
// override the displayProjection to be the one added to the
- // map.
+ // map.
if (control.displayProjection != this.displayProjection) {
this.displayProjection = control.displayProjection;
- }
-
+ }
+
break;
}
}
@@ -8997,9 +9969,9 @@
// Be careful to set layer first, to not trigger unnecessary layer loads
if (args.layers) {
this.layers = args.layers;
-
- // when we add a new layer, set its visibility
- this.map.events.register('addlayer', this,
+
+ // when we add a new layer, set its visibility
+ this.map.events.register('addlayer', this,
this.configureLayers);
this.configureLayers();
}
@@ -9009,51 +9981,51 @@
if (args.zoom) {
this.zoom = parseInt(args.zoom);
}
-
+
// when we add a new baselayer to see when we can set the center
- this.map.events.register('changebaselayer', this,
+ this.map.events.register('changebaselayer', this,
this.setCenter);
this.setCenter();
}
}
},
-
- /**
+
+ /**
* Method: setCenter
* As soon as a baseLayer has been loaded, we center and zoom
* ...and remove the handler.
*/
setCenter: function() {
-
+
if (this.map.baseLayer) {
//dont need to listen for this one anymore
- this.map.events.unregister('changebaselayer', this,
+ this.map.events.unregister('changebaselayer', this,
this.setCenter);
-
+
if (this.displayProjection) {
- this.center.transform(this.displayProjection,
- this.map.getProjectionObject());
- }
+ this.center.transform(this.displayProjection,
+ this.map.getProjectionObject());
+ }
this.map.setCenter(this.center, this.zoom);
}
},
- /**
+ /**
* Method: configureLayers
- * As soon as all the layers are loaded, cycle through them and
- * hide or show them.
+ * As soon as all the layers are loaded, cycle through them and
+ * hide or show them.
*/
configureLayers: function() {
- if (this.layers.length == this.map.layers.length) {
+ if (this.layers.length == this.map.layers.length) {
this.map.events.unregister('addlayer', this, this.configureLayers);
for(var i=0, len=this.layers.length; i<len; i++) {
-
+
var layer = this.map.layers[i];
var c = this.layers.charAt(i);
-
+
if (c == "B") {
this.map.setBaseLayer(layer);
} else if ( (c == "T") || (c == "F") ) {
@@ -9061,7 +10033,7 @@
}
}
}
- },
+ },
CLASS_NAME: "OpenLayers.Control.ArgParser"
});
@@ -9069,8 +10041,9 @@
OpenLayers/Control/PanZoom.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
@@ -9089,38 +10062,38 @@
*/
OpenLayers.Control.PanZoom = OpenLayers.Class(OpenLayers.Control, {
- /**
+ /**
* APIProperty: slideFactor
- * {Integer} Number of pixels by which we'll pan the map in any direction
+ * {Integer} Number of pixels by which we'll pan the map in any direction
* on clicking the arrow buttons. If you want to pan by some ratio
* of the map dimensions, use <slideRatio> instead.
*/
slideFactor: 50,
- /**
+ /**
* APIProperty: slideRatio
- * {Number} The fraction of map width/height by which we'll pan the map
+ * {Number} The fraction of map width/height by which we'll pan the map
* on clicking the arrow buttons. Default is null. If set, will
* override <slideFactor>. E.g. if slideRatio is .5, then the Pan Up
- * button will pan up half the map height.
+ * button will pan up half the map height.
*/
slideRatio: null,
- /**
+ /**
* Property: buttons
- * {Array(DOMElement)} Array of Button Divs
+ * {Array(DOMElement)} Array of Button Divs
*/
buttons: null,
- /**
+ /**
* Property: position
- * {<OpenLayers.Pixel>}
+ * {<OpenLayers.Pixel>}
*/
position: null,
/**
* Constructor: OpenLayers.Control.PanZoom
- *
+ *
* Parameters:
* options - {Object}
*/
@@ -9144,8 +10117,8 @@
* Method: draw
*
* Parameters:
- * px - {<OpenLayers.Pixel>}
- *
+ * px - {<OpenLayers.Pixel>}
+ *
* Returns:
* {DOMElement} A reference to the container div for the PanZoom control.
*/
@@ -9164,26 +10137,26 @@
px.y = centered.y+sz.h;
this._addButton("panleft", "west-mini.png", px, sz);
this._addButton("panright", "east-mini.png", px.add(sz.w, 0), sz);
- this._addButton("pandown", "south-mini.png",
+ this._addButton("pandown", "south-mini.png",
centered.add(0, sz.h*2), sz);
- this._addButton("zoomin", "zoom-plus-mini.png",
+ this._addButton("zoomin", "zoom-plus-mini.png",
centered.add(0, sz.h*3+5), sz);
- this._addButton("zoomworld", "zoom-world-mini.png",
+ this._addButton("zoomworld", "zoom-world-mini.png",
centered.add(0, sz.h*4+5), sz);
- this._addButton("zoomout", "zoom-minus-mini.png",
+ this._addButton("zoomout", "zoom-minus-mini.png",
centered.add(0, sz.h*5+5), sz);
return this.div;
},
-
+
/**
* Method: _addButton
- *
+ *
* Parameters:
- * id - {String}
- * img - {String}
- * xy - {<OpenLayers.Pixel>}
- * sz - {<OpenLayers.Size>}
- *
+ * id - {String}
+ * img - {String}
+ * xy - {<OpenLayers.Pixel>}
+ * sz - {<OpenLayers.Size>}
+ *
* Returns:
* {DOMElement} A Div (an alphaImageDiv, to be precise) that contains the
* image of the button, and has all the proper event handlers set.
@@ -9191,21 +10164,21 @@
_addButton:function(id, img, xy, sz) {
var imgLocation = OpenLayers.Util.getImagesLocation() + img;
var btn = OpenLayers.Util.createAlphaImageDiv(
- this.id + "_" + id,
+ this.id + "_" + id,
xy, sz, imgLocation, "absolute");
//we want to add the outer div
this.div.appendChild(btn);
- OpenLayers.Event.observe(btn, "mousedown",
+ OpenLayers.Event.observe(btn, "mousedown",
OpenLayers.Function.bindAsEventListener(this.buttonDown, btn));
- OpenLayers.Event.observe(btn, "dblclick",
+ OpenLayers.Event.observe(btn, "dblclick",
OpenLayers.Function.bindAsEventListener(this.doubleClick, btn));
- OpenLayers.Event.observe(btn, "click",
+ OpenLayers.Event.observe(btn, "click",
OpenLayers.Function.bindAsEventListener(this.doubleClick, btn));
btn.action = id;
btn.map = this.map;
-
+
if(!this.slideRatio){
var slideFactorPixels = this.slideFactor;
var getSlideFactor = function() {
@@ -9224,20 +10197,21 @@
this.buttons.push(btn);
return btn;
},
-
+
/**
* Method: _removeButton
- *
+ *
* Parameters:
* btn - {Object}
*/
_removeButton: function(btn) {
OpenLayers.Event.stopObservingElement(btn);
btn.map = null;
+ btn.getSlideFactor = null;
this.div.removeChild(btn);
OpenLayers.Util.removeItem(this.buttons, btn);
},
-
+
/**
* Method: removeButtons
*/
@@ -9246,12 +10220,12 @@
this._removeButton(this.buttons[i]);
}
},
-
+
/**
* Method: doubleClick
*
* Parameters:
- * evt - {Event}
+ * evt - {Event}
*
* Returns:
* {Boolean}
@@ -9260,12 +10234,12 @@
OpenLayers.Event.stop(evt);
return false;
},
-
+
/**
* Method: buttonDown
*
* Parameters:
- * evt - {Event}
+ * evt - {Event}
*/
buttonDown: function (evt) {
if (!OpenLayers.Event.isLeftClick(evt)) {
@@ -9273,26 +10247,26 @@
}
switch (this.action) {
- case "panup":
+ case "panup":
this.map.pan(0, -this.getSlideFactor("h"));
break;
- case "pandown":
+ case "pandown":
this.map.pan(0, this.getSlideFactor("h"));
break;
- case "panleft":
+ case "panleft":
this.map.pan(-this.getSlideFactor("w"), 0);
break;
- case "panright":
+ case "panright":
this.map.pan(this.getSlideFactor("w"), 0);
break;
- case "zoomin":
- this.map.zoomIn();
+ case "zoomin":
+ this.map.zoomIn();
break;
- case "zoomout":
- this.map.zoomOut();
+ case "zoomout":
+ this.map.zoomOut();
break;
- case "zoomworld":
- this.map.zoomToMaxExtent();
+ case "zoomworld":
+ this.map.zoomToMaxExtent();
break;
}
@@ -9317,9 +10291,10 @@
OpenLayers/Control/ScaleLine.js
====================================================================== */
-/* Copyright (c) 2006-2007 MetaCarta, Inc., published under a modified BSD license.
- * See http://svn.openlayers.org/trunk/openlayers/repository-license.txt
- * for the full text of the license. */
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
/**
* @requires OpenLayers/Control.js
@@ -9327,13 +10302,13 @@
/**
* Class: OpenLayers.Control.ScaleLine
- * The ScaleLine displays a small line indicator representing the current
+ * The ScaleLine displays a small line indicator representing the current
* map scale on the map. By default it is drawn in the lower left corner of
* the map.
- *
+ *
* Inherits from:
* - <OpenLayers.Control>
- *
+ *
* Is a very close copy of:
* - <OpenLayers.Control.Scale>
*/
@@ -9350,7 +10325,7 @@
* {String} Units for zoomed out on top bar. Default is km.
*/
topOutUnits: "km",
-
+
/**
* Property: topInUnits
* {String} Units for zoomed in on top bar. Default is m.
@@ -9368,7 +10343,7 @@
* {String} Units for zoomed in on bottom bar. Default is ft.
*/
bottomInUnits: "ft",
-
+
/**
* Property: eTop
* {DOMElement}
@@ -9380,31 +10355,37 @@
* {DOMElement}
*/
eBottom:null,
+
+ /**
+ * APIProperty: geodesic
+ * {Boolean} Use geodesic measurement. Default is false. The recommended
+ * setting for maps in EPSG:4326 is false, and true EPSG:900913. If set to
+ * true, the scale will be calculated based on the horizontal size of the
+ * pixel in the center of the map viewport.
+ */
+ geodesic: false,
/**
* Constructor: OpenLayers.Control.ScaleLine
* Create a new scale line control.
- *
+ *
* Parameters:
* options - {Object} An optional object whose properties will be used
* to extend the control.
*/
initialize: function(options) {
- OpenLayers.Control.prototype.initialize.apply(this, [options]);
+ OpenLayers.Control.prototype.initialize.apply(this, [options]);
},
/**
* Method: draw
- *
+ *
* Returns:
* {DOMElement}
*/
draw: function() {
OpenLayers.Control.prototype.draw.apply(this, arguments);
if (!this.eTop) {
- this.div.style.display = "block";
- this.div.style.position = "absolute";
-
// stick in the top bar
this.eTop = document.createElement("div");
this.eTop.className = this.displayClass + "Top";
@@ -9431,14 +10412,14 @@
return this.div;
},
- /**
+ /**
* Method: getBarLen
* Given a number, round it down to the nearest 1,2,5 times a power of 10.
* That seems a fairly useful set of number groups to use.
- *
+ *
* Parameters:
* maxLen - {float} the number we're rounding down from
- *
+ *
* Returns:
* {Float} the rounded number (less than or equal to maxLen)
*/
@@ -9446,7 +10427,7 @@
// nearest power of 10 lower than maxLen
var digits = parseInt(Math.log(maxLen) / Math.log(10));
var pow10 = Math.pow(10, digits);
-
+
// ok, find first character
var firstChar = parseInt(maxLen / pow10);
@@ -9479,8 +10460,16 @@
// convert maxWidth to map units
var maxSizeData = this.maxWidth * res * inches[curMapUnits];
+ var geodesicRatio = 1;
+ if(this.geodesic === true) {
+ var maxSizeGeodesic = (this.map.getGeodesicPixelSize().w ||
+ 0.000001) * this.maxWidth;
+ var maxSizeKilometers = maxSizeData / inches["km"];
+ geodesicRatio = maxSizeGeodesic / maxSizeKilometers;
+ maxSizeData *= geodesicRatio;
+ }
- // decide whether to use large or small scale units
+ // decide whether to use large or small scale units
var topUnits;
var bottomUnits;
if(maxSizeData > 100000) {
@@ -9504,24 +10493,24 @@
bottomMax = bottomRounded / inches[curMapUnits] * inches[bottomUnits];
// and to pixel units
- var topPx = topMax / res;
- var bottomPx = bottomMax / res;
-
+ var topPx = topMax / res / geodesicRatio;
+ var bottomPx = bottomMax / res / geodesicRatio;
+
// now set the pixel widths
// and the values inside them
-
+
if (this.eBottom.style.visibility == "visible"){
- this.eBottom.style.width = Math.round(bottomPx) + "px";
+ this.eBottom.style.width = Math.round(bottomPx) + "px";
this.eBottom.innerHTML = bottomRounded + " " + bottomUnits ;
}
-
+
if (this.eTop.style.visibility == "visible"){
this.eTop.style.width = Math.round(topPx) + "px";
this.eTop.innerHTML = topRounded + " " + topUnits;
}
+
+ },
- },
-
CLASS_NAME: "OpenLayers.Control.ScaleLine"
});
@@ -9529,8 +10518,9 @@
OpenLayers/Events.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
@@ -9544,64 +10534,64 @@
*/
OpenLayers.Event = {
- /**
- * Property: observers
+ /**
+ * Property: observers
* {Object} A hashtable cache of the event observers. Keyed by
- * element._eventCacheID
+ * element._eventCacheID
*/
observers: false,
-
- /**
- * Constant: KEY_BACKSPACE
- * {int}
+
+ /**
+ * Constant: KEY_BACKSPACE
+ * {int}
*/
KEY_BACKSPACE: 8,
- /**
- * Constant: KEY_TAB
- * {int}
+ /**
+ * Constant: KEY_TAB
+ * {int}
*/
KEY_TAB: 9,
- /**
- * Constant: KEY_RETURN
- * {int}
+ /**
+ * Constant: KEY_RETURN
+ * {int}
*/
KEY_RETURN: 13,
- /**
- * Constant: KEY_ESC
- * {int}
+ /**
+ * Constant: KEY_ESC
+ * {int}
*/
KEY_ESC: 27,
- /**
- * Constant: KEY_LEFT
- * {int}
+ /**
+ * Constant: KEY_LEFT
+ * {int}
*/
KEY_LEFT: 37,
- /**
- * Constant: KEY_UP
- * {int}
+ /**
+ * Constant: KEY_UP
+ * {int}
*/
KEY_UP: 38,
- /**
- * Constant: KEY_RIGHT
- * {int}
+ /**
+ * Constant: KEY_RIGHT
+ * {int}
*/
KEY_RIGHT: 39,
- /**
- * Constant: KEY_DOWN
- * {int}
+ /**
+ * Constant: KEY_DOWN
+ * {int}
*/
KEY_DOWN: 40,
- /**
- * Constant: KEY_DELETE
- * {int}
+ /**
+ * Constant: KEY_DELETE
+ * {int}
*/
KEY_DELETE: 46,
@@ -9609,12 +10599,12 @@
/**
* Method: element
* Cross browser event element detection.
- *
+ *
* Parameters:
- * event - {Event}
- *
+ * event - {Event}
+ *
* Returns:
- * {DOMElement} The element that caused the event
+ * {DOMElement} The element that caused the event
*/
element: function(event) {
return event.target || event.srcElement;
@@ -9622,11 +10612,11 @@
/**
* Method: isLeftClick
- * Determine whether event was caused by a left click.
+ * Determine whether event was caused by a left click.
*
* Parameters:
- * event - {Event}
- *
+ * event - {Event}
+ *
* Returns:
* {Boolean}
*/
@@ -9637,11 +10627,11 @@
/**
* Method: isRightClick
- * Determine whether event was caused by a right mouse click.
+ * Determine whether event was caused by a right mouse click.
*
* Parameters:
- * event - {Event}
- *
+ * event - {Event}
+ *
* Returns:
* {Boolean}
*/
@@ -9649,29 +10639,29 @@
return (((event.which) && (event.which == 3)) ||
((event.button) && (event.button == 2)));
},
-
+
/**
* Method: stop
- * Stops an event from propagating.
+ * Stops an event from propagating.
*
- * Parameters:
- * event - {Event}
- * allowDefault - {Boolean} If true, we stop the event chain but
- * still allow the default browser
- * behaviour (text selection, radio-button
+ * Parameters:
+ * event - {Event}
+ * allowDefault - {Boolean} If true, we stop the event chain but
+ * still allow the default browser
+ * behaviour (text selection, radio-button
* clicking, etc)
* Default false
*/
stop: function(event, allowDefault) {
-
- if (!allowDefault) {
+
+ if (!allowDefault) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
}
-
+
if (event.stopPropagation) {
event.stopPropagation();
} else {
@@ -9679,13 +10669,13 @@
}
},
- /**
+ /**
* Method: findElement
- *
+ *
* Parameters:
- * event - {Event}
- * tagName - {String}
- *
+ * event - {Event}
+ * tagName - {String}
+ *
* Returns:
* {DOMElement} The first node with the given tagName, starting from the
* node the event was triggered on and traversing the DOM upwards
@@ -9699,14 +10689,14 @@
return element;
},
- /**
+ /**
* Method: observe
- *
+ *
* Parameters:
- * elementParam - {DOMElement || String}
- * name - {String}
- * observer - {function}
- * useCapture - {Boolean}
+ * elementParam - {DOMElement || String}
+ * name - {String}
+ * observer - {function}
+ * useCapture - {Boolean}
*/
observe: function(elementParam, name, observer, useCapture) {
var element = OpenLayers.Util.getElement(elementParam);
@@ -9755,14 +10745,14 @@
}
},
- /**
+ /**
* Method: stopObservingElement
- * Given the id of an element to stop observing, cycle through the
- * element's cached observers, calling stopObserving on each one,
+ * Given the id of an element to stop observing, cycle through the
+ * element's cached observers, calling stopObserving on each one,
* skipping those entries which can no longer be removed.
- *
+ *
* parameters:
- * elementParam - {DOMElement || String}
+ * elementParam - {DOMElement || String}
*/
stopObservingElement: function(elementParam) {
var element = OpenLayers.Util.getElement(elementParam);
@@ -9775,8 +10765,8 @@
* Method: _removeElementObservers
*
* Parameters:
- * elementObservers - {Array(Object)} Array of (element, name,
- * observer, usecapture) objects,
+ * elementObservers - {Array(Object)} Array of (element, name,
+ * observer, usecapture) objects,
* taken directly from hashtable
*/
_removeElementObservers: function(elementObservers) {
@@ -9794,24 +10784,24 @@
/**
* Method: stopObserving
- *
+ *
* Parameters:
- * elementParam - {DOMElement || String}
- * name - {String}
- * observer - {function}
- * useCapture - {Boolean}
- *
+ * elementParam - {DOMElement || String}
+ * name - {String}
+ * observer - {function}
+ * useCapture - {Boolean}
+ *
* Returns:
* {Boolean} Whether or not the event observer was removed
*/
stopObserving: function(elementParam, name, observer, useCapture) {
useCapture = useCapture || false;
-
+
var element = OpenLayers.Util.getElement(elementParam);
var cacheID = element._eventCacheID;
if (name == 'keypress') {
- if ( navigator.appVersion.match(/Konqueror|Safari|KHTML/) ||
+ if ( navigator.appVersion.match(/Konqueror|Safari|KHTML/) ||
element.detachEvent) {
name = 'keydown';
}
@@ -9821,27 +10811,27 @@
var foundEntry = false;
var elementObservers = OpenLayers.Event.observers[cacheID];
if (elementObservers) {
-
+
// find the specific event type in the element's list
var i=0;
while(!foundEntry && i < elementObservers.length) {
var cacheEntry = elementObservers[i];
-
+
if ((cacheEntry.name == name) &&
(cacheEntry.observer == observer) &&
(cacheEntry.useCapture == useCapture)) {
-
+
elementObservers.splice(i, 1);
if (elementObservers.length == 0) {
delete OpenLayers.Event.observers[cacheID];
}
foundEntry = true;
- break;
+ break;
}
- i++;
+ i++;
}
}
-
+
//actually remove the event listener from browser
if (foundEntry) {
if (element.removeEventListener) {
@@ -9852,11 +10842,11 @@
}
return foundEntry;
},
-
- /**
+
+ /**
* Method: unloadCache
* Cycle through all the element entries in the events cache and call
- * stopObservingElement on each.
+ * stopObservingElement on each.
*/
unloadCache: function() {
// check for OpenLayers.Event before checking for observers, because
@@ -9865,7 +10855,7 @@
if (OpenLayers.Event && OpenLayers.Event.observers) {
for (var cacheID in OpenLayers.Event.observers) {
var elementObservers = OpenLayers.Event.observers[cacheID];
- OpenLayers.Event._removeElementObservers.apply(this,
+ OpenLayers.Event._removeElementObservers.apply(this,
[elementObservers]);
}
OpenLayers.Event.observers = false;
@@ -9891,65 +10881,65 @@
*/
OpenLayers.Events = OpenLayers.Class({
- /**
+ /**
* Constant: BROWSER_EVENTS
- * {Array(String)} supported events
+ * {Array(String)} supported events
*/
BROWSER_EVENTS: [
"mouseover", "mouseout",
- "mousedown", "mouseup", "mousemove",
+ "mousedown", "mouseup", "mousemove",
"click", "dblclick", "rightclick", "dblrightclick",
"resize", "focus", "blur"
],
- /**
- * Property: listeners
- * {Object} Hashtable of Array(Function): events listener functions
+ /**
+ * Property: listeners
+ * {Object} Hashtable of Array(Function): events listener functions
*/
listeners: null,
- /**
- * Property: object
- * {Object} the code object issuing application events
+ /**
+ * Property: object
+ * {Object} the code object issuing application events
*/
object: null,
- /**
- * Property: element
- * {DOMElement} the DOM element receiving browser events
+ /**
+ * Property: element
+ * {DOMElement} the DOM element receiving browser events
*/
element: null,
- /**
- * Property: eventTypes
- * {Array(String)} list of support application events
+ /**
+ * Property: eventTypes
+ * {Array(String)} list of support application events
*/
eventTypes: null,
- /**
- * Property: eventHandler
- * {Function} bound event handler attached to elements
+ /**
+ * Property: eventHandler
+ * {Function} bound event handler attached to elements
*/
eventHandler: null,
- /**
- * APIProperty: fallThrough
- * {Boolean}
+ /**
+ * APIProperty: fallThrough
+ * {Boolean}
*/
fallThrough: null,
- /**
+ /**
* APIProperty: includeXY
* {Boolean} Should the .xy property automatically be created for browser
* mouse events? In general, this should be false. If it is true, then
- * mouse events will automatically generate a '.xy' property on the
+ * mouse events will automatically generate a '.xy' property on the
* event object that is passed. (Prior to OpenLayers 2.7, this was true
* by default.) Otherwise, you can call the getMousePosition on the
* relevant events handler on the object available via the 'evt.object'
* property of the evt object. So, for most events, you can call:
- * function named(evt) {
- * this.xy = this.object.events.getMousePosition(evt)
- * }
+ * function named(evt) {
+ * this.xy = this.object.events.getMousePosition(evt)
+ * }
*
* This option typically defaults to false for performance reasons:
* when creating an events object whose primary purpose is to manage
@@ -9959,12 +10949,12 @@
* This option is also used to control whether the events object caches
* offsets. If this is false, it will not: the reason for this is that
* it is only expected to be called many times if the includeXY property
- * is set to true. If you set this to true, you are expected to clear
+ * is set to true. If you set this to true, you are expected to clear
* the offset cache manually (using this.clearMouseCache()) if:
* the border of the element changes
* the location of the element in the page changes
*/
- includeXY: false,
+ includeXY: false,
/**
* Method: clearMouseListener
@@ -9981,7 +10971,7 @@
* Parameters:
* object - {Object} The js object to which this Events object is being
* added element - {DOMElement} A dom element to respond to browser events
- * eventTypes - {Array(String)} Array of custom application events
+ * eventTypes - {Array(String)} Array of custom application events
* fallThrough - {Boolean} Allow events to fall through after these have
* been handled?
* options - {Object} Options for the events object.
@@ -9997,13 +10987,13 @@
this.eventHandler = OpenLayers.Function.bindAsEventListener(
this.handleBrowserEvent, this
);
-
+
// to be used with observe and stopObserving
this.clearMouseListener = OpenLayers.Function.bind(
this.clearMouseCache, this
);
- // if eventTypes is specified, create a listeners list for each
+ // if eventTypes is specified, create a listeners list for each
// custom application event.
this.eventTypes = [];
if (eventTypes != null) {
@@ -10011,8 +11001,8 @@
this.addEventType(eventTypes[i]);
}
}
-
- // if a dom element is specified, add a listeners list
+
+ // if a dom element is specified, add a listeners list
// for browser events on the element and register them
if (element != null) {
this.attachToElement(element);
@@ -10044,7 +11034,7 @@
* APIMethod: addEventType
* Add a new event type to this events object.
* If the event type has already been added, do nothing.
- *
+ *
* Parameters:
* eventName - {String}
*/
@@ -10069,28 +11059,41 @@
for (var i=0, len=this.BROWSER_EVENTS.length; i<len; i++) {
var eventType = this.BROWSER_EVENTS[i];
- // every browser event has a corresponding application event
+ // every browser event has a corresponding application event
// (whether it's listened for or not).
this.addEventType(eventType);
-
+
// use Prototype to register the event cross-browser
OpenLayers.Event.observe(element, eventType, this.eventHandler);
}
// disable dragstart in IE so that mousedown/move/up works normally
OpenLayers.Event.observe(element, "dragstart", OpenLayers.Event.stop);
},
-
+
/**
- * Method: on
+ * APIMethod: on
* Convenience method for registering listeners with a common scope.
+ * Internally, this method calls <register> as shown in the examples
+ * below.
*
* Example use:
* (code)
+ * // register a single listener for the "loadstart" event
+ * events.on({"loadstart", loadStartListener});
+ *
+ * // this is equivalent to the following
+ * events.register("loadstart", undefined, loadStartListener);
+ *
+ * // register multiple listeners to be called with the same `this` object
* events.on({
* "loadstart": loadStartListener,
* "loadend": loadEndListener,
* scope: object
* });
+ *
+ * // this is equivalent to the following
+ * events.register("loadstart", object, loadStartListener);
+ * events.register("loadstart", object, loadEndListener);
* (end)
*/
on: function(object) {
@@ -10106,31 +11109,31 @@
* Register an event on the events object.
*
* When the event is triggered, the 'func' function will be called, in the
- * context of 'obj'. Imagine we were to register an event, specifying an
- * OpenLayers.Bounds Object as 'obj'. When the event is triggered, the
+ * context of 'obj'. Imagine we were to register an event, specifying an
+ * OpenLayers.Bounds Object as 'obj'. When the event is triggered, the
* context in the callback function will be our Bounds object. This means
- * that within our callback function, we can access the properties and
- * methods of the Bounds object through the "this" variable. So our
- * callback could execute something like:
+ * that within our callback function, we can access the properties and
+ * methods of the Bounds object through the "this" variable. So our
+ * callback could execute something like:
* : leftStr = "Left: " + this.left;
- *
+ *
* or
- *
+ *
* : centerStr = "Center: " + this.getCenterLonLat();
*
* Parameters:
* type - {String} Name of the event to register
* obj - {Object} The object to bind the context to for the callback#.
- * If no object is specified, default is the Events's
+ * If no object is specified, default is the Events's
* 'object' property.
- * func - {Function} The callback function. If no callback is
+ * func - {Function} The callback function. If no callback is
* specified, this function does nothing.
- *
- *
+ *
+ *
*/
register: function (type, obj, func) {
- if ( (func != null) &&
+ if ( (func != null) &&
(OpenLayers.Util.indexOf(this.eventTypes, type) != -1) ) {
if (obj == null) {
@@ -10145,17 +11148,17 @@
* APIMethod: registerPriority
* Same as register() but adds the new listener to the *front* of the
* events queue instead of to the end.
- *
- * TODO: get rid of this in 3.0 - Decide whether listeners should be
+ *
+ * TODO: get rid of this in 3.0 - Decide whether listeners should be
* called in the order they were registered or in reverse order.
*
*
* Parameters:
* type - {String} Name of the event to register
* obj - {Object} The object to bind the context to for the callback#.
- * If no object is specified, default is the Events's
+ * If no object is specified, default is the Events's
* 'object' property.
- * func - {Function} The callback function. If no callback is
+ * func - {Function} The callback function. If no callback is
* specified, this function does nothing.
*/
registerPriority: function (type, obj, func) {
@@ -10170,18 +11173,31 @@
}
}
},
-
+
/**
- * Method: un
+ * APIMethod: un
* Convenience method for unregistering listeners with a common scope.
+ * Internally, this method calls <unregister> as shown in the examples
+ * below.
*
* Example use:
* (code)
+ * // unregister a single listener for the "loadstart" event
+ * events.un({"loadstart", loadStartListener});
+ *
+ * // this is equivalent to the following
+ * events.unregister("loadstart", undefined, loadStartListener);
+ *
+ * // unregister multiple listeners with the same `this` object
* events.un({
* "loadstart": loadStartListener,
* "loadend": loadEndListener,
* scope: object
* });
+ *
+ * // this is equivalent to the following
+ * events.unregister("loadstart", object, loadStartListener);
+ * events.unregister("loadstart", object, loadEndListener);
* (end)
*/
un: function(object) {
@@ -10196,9 +11212,9 @@
* APIMethod: unregister
*
* Parameters:
- * type - {String}
+ * type - {String}
* obj - {Object} If none specified, defaults to this.object
- * func - {Function}
+ * func - {Function}
*/
unregister: function (type, obj, func) {
if (obj == null) {
@@ -10215,13 +11231,13 @@
}
},
- /**
+ /**
* Method: remove
* Remove all listeners for a given event type. If type is not registered,
* does nothing.
*
* Parameters:
- * type - {String}
+ * type - {String}
*/
remove: function(type) {
if (this.listeners[type] != null) {
@@ -10231,10 +11247,10 @@
/**
* APIMethod: triggerEvent
- * Trigger a specified registered event.
- *
+ * Trigger a specified registered event.
+ *
* Parameters:
- * type - {String}
+ * type - {String}
* evt - {Event}
*
* Returns:
@@ -10258,7 +11274,7 @@
if(!evt.type) {
evt.type = type;
}
-
+
// execute all callbacks registered for specified type
// get a clone of the listeners array to
// allow for splicing during callbacks
@@ -10274,7 +11290,7 @@
}
}
// don't fall through to other DOM elements
- if (!this.fallThrough) {
+ if (!this.fallThrough) {
OpenLayers.Event.stop(evt, true);
}
return continueChain;
@@ -10282,38 +11298,38 @@
/**
* Method: handleBrowserEvent
- * Basically just a wrapper to the triggerEvent() function, but takes
- * care to set a property 'xy' on the event with the current mouse
+ * Basically just a wrapper to the triggerEvent() function, but takes
+ * care to set a property 'xy' on the event with the current mouse
* position.
*
* Parameters:
- * evt - {Event}
+ * evt - {Event}
*/
handleBrowserEvent: function (evt) {
if (this.includeXY) {
evt.xy = this.getMousePosition(evt);
- }
+ }
this.triggerEvent(evt.type, evt);
},
/**
* APIMethod: clearMouseCache
- * Clear cached data about the mouse position. This should be called any
- * time the element that events are registered on changes position
+ * Clear cached data about the mouse position. This should be called any
+ * time the element that events are registered on changes position
* within the page.
*/
- clearMouseCache: function() {
+ clearMouseCache: function() {
this.element.scrolls = null;
this.element.lefttop = null;
this.element.offsets = null;
- },
+ },
/**
* Method: getMousePosition
- *
+ *
* Parameters:
- * evt - {Event}
- *
+ * evt - {Event}
+ *
* Returns:
* {<OpenLayers.Pixel>} The current xy coordinate of the mouse, adjusted
* for offsets
@@ -10325,7 +11341,7 @@
OpenLayers.Event.observe(window, "scroll", this.clearMouseListener);
this.element.hasScrollEvent = true;
}
-
+
if (!this.element.scrolls) {
this.element.scrolls = [
(document.documentElement.scrollLeft
@@ -10341,7 +11357,7 @@
(document.documentElement.clientTop || 0)
];
}
-
+
if (!this.element.offsets) {
this.element.offsets = OpenLayers.Util.pagePosition(this.element);
this.element.offsets[0] += this.element.scrolls[0];
@@ -10349,10 +11365,10 @@
}
return new OpenLayers.Pixel(
(evt.clientX + this.element.scrolls[0]) - this.element.offsets[0]
- - this.element.lefttop[0],
+ - this.element.lefttop[0],
(evt.clientY + this.element.scrolls[1]) - this.element.offsets[1]
- this.element.lefttop[1]
- );
+ );
},
CLASS_NAME: "OpenLayers.Events"
@@ -10361,8 +11377,9 @@
OpenLayers/Format.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -10376,13 +11393,13 @@
* of OpenLayers.Format are expected to have read and write methods.
*/
OpenLayers.Format = OpenLayers.Class({
-
+
/**
* Property: options
* {Object} A reference to options passed to the constructor.
*/
options: null,
-
+
/**
* APIProperty: externalProjection
* {<OpenLayers.Projection>} When passed a externalProjection and
@@ -10390,7 +11407,7 @@
* reads or writes. The externalProjection is the projection used by
* the content which is passed into read or which comes out of write.
* In order to reproject, a projection transformation function for the
- * specified projections must be available. This support may be
+ * specified projections must be available. This support may be
* provided via proj4js or via a custom transformation function. See
* {<OpenLayers.Projection.addTransform>} for more information on
* custom transformations.
@@ -10444,7 +11461,7 @@
OpenLayers.Util.extend(this, options);
this.options = options;
},
-
+
/**
* APIMethod: destroy
* Clean up.
@@ -10455,8 +11472,8 @@
/**
* Method: read
* Read data from a string, and return an object whose type depends on the
- * subclass.
- *
+ * subclass.
+ *
* Parameters:
* data - {string} Data to read/parse.
*
@@ -10466,10 +11483,10 @@
read: function(data) {
OpenLayers.Console.userError(OpenLayers.i18n("readNotImplemented"));
},
-
+
/**
* Method: write
- * Accept an object, and return a string.
+ * Accept an object, and return a string.
*
* Parameters:
* object - {Object} Object to be serialized
@@ -10482,15 +11499,11 @@
},
CLASS_NAME: "OpenLayers.Format"
-});
+});
/* ======================================================================
OpenLayers/Lang/en.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
- * full text of the license. */
-
/**
* @requires OpenLayers/Lang.js
*/
@@ -10570,6 +11583,13 @@
"target='_blank'>click here</a>",
'scale': "Scale = 1 : ${scaleDenom}",
+
+ //labels for the graticule control
+ 'W': 'W',
+ 'E': 'E',
+ 'N': 'N',
+ 'S': 'S',
+ 'graticule': 'Graticule',
// console message
'layerAlreadyAdded':
@@ -10579,7 +11599,7 @@
'reprojectDeprecated':
"You are using the 'reproject' option " +
"on the ${layerName} layer. This option is deprecated: " +
- "its use was designed to support displaying data over commercial " +
+ "its use was designed to support displaying data over commercial " +
"basemaps, but that functionality should now be achieved by using " +
"Spherical Mercator support. More information is available from " +
"http://trac.openlayers.org/wiki/SphericalMercator.",
@@ -10605,17 +11625,20 @@
'pagePositionFailed':
"OpenLayers.Util.pagePosition failed: element with id ${elemId} may be misplaced.",
- 'end': '',
+ // console message
+ 'filterEvaluateNotImplemented': "evaluate is not implemented for this filter type.",
- // console message
- 'filterEvaluateNotImplemented': "evaluate is not implemented for this filter type."
+ // **** end ****
+ 'end': ''
+
};
/* ======================================================================
OpenLayers/Popup/AnchoredBubble.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
@@ -10625,36 +11648,36 @@
/**
* Class: OpenLayers.Popup.AnchoredBubble
- *
- * Inherits from:
+ *
+ * Inherits from:
* - <OpenLayers.Popup.Anchored>
*/
-OpenLayers.Popup.AnchoredBubble =
+OpenLayers.Popup.AnchoredBubble =
OpenLayers.Class(OpenLayers.Popup.Anchored, {
/**
* Property: rounded
* {Boolean} Has the popup been rounded yet?
*/
- rounded: false,
-
- /**
+ rounded: false,
+
+ /**
* Constructor: OpenLayers.Popup.AnchoredBubble
- *
+ *
* Parameters:
* id - {String}
* lonlat - {<OpenLayers.LonLat>}
* contentSize - {<OpenLayers.Size>}
* contentHTML - {String}
- * anchor - {Object} Object to which we'll anchor the popup. Must expose
- * a 'size' (<OpenLayers.Size>) and 'offset' (<OpenLayers.Pixel>)
+ * anchor - {Object} Object to which we'll anchor the popup. Must expose
+ * a 'size' (<OpenLayers.Size>) and 'offset' (<OpenLayers.Pixel>)
* (Note that this is generally an <OpenLayers.Icon>).
* closeBox - {Boolean}
* closeBoxCallback - {Function} Function to be called on closeBox click.
*/
initialize:function(id, lonlat, contentSize, contentHTML, anchor, closeBox,
closeBoxCallback) {
-
+
this.padding = new OpenLayers.Bounds(
0, OpenLayers.Popup.AnchoredBubble.CORNER_SIZE,
0, OpenLayers.Popup.AnchoredBubble.CORNER_SIZE
@@ -10662,23 +11685,23 @@
OpenLayers.Popup.Anchored.prototype.initialize.apply(this, arguments);
},
- /**
+ /**
* Method: draw
- *
+ *
* Parameters:
* px - {<OpenLayers.Pixel>}
- *
+ *
* Returns:
* {DOMElement} Reference to a div that contains the drawn popup.
*/
draw: function(px) {
-
+
OpenLayers.Popup.Anchored.prototype.draw.apply(this, arguments);
this.setContentHTML();
-
- //set the popup color and opacity
- this.setBackgroundColor();
+
+ //set the popup color and opacity
+ this.setBackgroundColor();
this.setOpacity();
return this.div;
@@ -10695,71 +11718,71 @@
/**
* APIMethod: setSize
- *
+ *
* Parameters:
- * contentSize - {<OpenLayers.Size>} the new size for the popup's
+ * contentSize - {<OpenLayers.Size>} the new size for the popup's
* contents div (in pixels).
*/
- setSize:function(contentSize) {
+ setSize:function(contentSize) {
OpenLayers.Popup.Anchored.prototype.setSize.apply(this, arguments);
this.setRicoCorners();
- },
+ },
/**
* APIMethod: setBackgroundColor
- *
+ *
* Parameters:
* color - {String}
*/
- setBackgroundColor:function(color) {
+ setBackgroundColor:function(color) {
if (color != undefined) {
- this.backgroundColor = color;
+ this.backgroundColor = color;
}
-
+
if (this.div != null) {
if (this.contentDiv != null) {
this.div.style.background = "transparent";
- OpenLayers.Rico.Corner.changeColor(this.groupDiv,
+ OpenLayers.Rico.Corner.changeColor(this.groupDiv,
this.backgroundColor);
}
}
- },
-
+ },
+
/**
* APIMethod: setOpacity
- *
- * Parameters:
+ *
+ * Parameters:
* opacity - {float}
*/
- setOpacity:function(opacity) {
+ setOpacity:function(opacity) {
OpenLayers.Popup.Anchored.prototype.setOpacity.call(this, opacity);
-
+
if (this.div != null) {
if (this.groupDiv != null) {
- OpenLayers.Rico.Corner.changeOpacity(this.groupDiv,
+ OpenLayers.Rico.Corner.changeOpacity(this.groupDiv,
this.opacity);
}
}
- },
-
- /**
+ },
+
+ /**
* Method: setBorder
* Always sets border to 0. Bubble Popups can not have a border.
- *
+ *
* Parameters:
* border - {Integer}
*/
- setBorder:function(border) {
+ setBorder:function(border) {
this.border = 0;
- },
-
- /**
+ },
+
+ /**
* Method: setRicoCorners
* Update RICO corners according to the popup's current relative postion.
*/
setRicoCorners:function() {
-
+
var corners = this.getCornersToRound(this.relativePosition);
var options = {corners: corners,
color: this.backgroundColor,
@@ -10772,14 +11795,14 @@
} else {
OpenLayers.Rico.Corner.reRound(this.groupDiv, options);
//set the popup color and opacity
- this.setBackgroundColor();
+ this.setBackgroundColor();
this.setOpacity();
}
},
- /**
+ /**
* Method: getCornersToRound
- *
+ *
* Returns:
* {String} The proper corners string ("tr tl bl br") for rico to round.
*/
@@ -10787,7 +11810,7 @@
var corners = ['tl', 'tr', 'bl', 'br'];
- //we want to round all the corners _except_ the opposite one.
+ //we want to round all the corners _except_ the opposite one.
var corner = OpenLayers.Bounds.oppositeQuadrant(this.relativePosition);
OpenLayers.Util.removeItem(corners, corner);
@@ -10807,9 +11830,10 @@
OpenLayers/Projection.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under a modified BSD license.
- * See http://svn.openlayers.org/trunk/openlayers/repository-license.txt
- * for the full text of the license. */
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
/**
* @requires OpenLayers/Util.js
@@ -10818,7 +11842,7 @@
/**
* Class: OpenLayers.Projection
* Class for coordinate transforms between coordinate systems.
- * Depends on the proj4js library. If proj4js is not available,
+ * Depends on the proj4js library. If proj4js is not available,
* then this is just an empty stub.
*/
OpenLayers.Projection = OpenLayers.Class({
@@ -10828,7 +11852,7 @@
* {Object} Proj4js.Proj instance.
*/
proj: null,
-
+
/**
* Property: projCode
* {String}
@@ -10837,8 +11861,8 @@
/**
* Constructor: OpenLayers.Projection
- * This class offers several methods for interacting with a wrapped
- * pro4js projection object.
+ * This class offers several methods for interacting with a wrapped
+ * pro4js projection object.
*
* Parameters:
* projCode - {String} A string identifying the Well Known Identifier for
@@ -10856,7 +11880,7 @@
this.proj = new Proj4js.Proj(projCode);
}
},
-
+
/**
* APIMethod: getCode
* Get the string SRS code.
@@ -10867,10 +11891,10 @@
getCode: function() {
return this.proj ? this.proj.srsCode : this.projCode;
},
-
+
/**
* APIMethod: getUnits
- * Get the units string for the projection -- returns null if
+ * Get the units string for the projection -- returns null if
* proj4js is not available.
*
* Returns:
@@ -10904,7 +11928,7 @@
return this.getCode() == projection.getCode();
} else {
return false;
- }
+ }
},
/* Method: destroy
@@ -10914,21 +11938,21 @@
delete this.proj;
delete this.projCode;
},
+
+ CLASS_NAME: "OpenLayers.Projection"
+});
- CLASS_NAME: "OpenLayers.Projection"
-});
-
/**
* Property: transforms
* Transforms is an object, with from properties, each of which may
- * have a to property. This allows you to define projections without
+ * have a to property. This allows you to define projections without
* requiring support for proj4js to be included.
*
* This object has keys which correspond to a 'source' projection object. The
* keys should be strings, corresponding to the projection.getCode() value.
* Each source projection object should have a set of destination projection
- * keys included in the object.
- *
+ * keys included in the object.
+ *
* Each value in the destination object should be a transformation function,
* where the function is expected to be passed an object with a .x and a .y
* property. The function should return the object, with the .x and .y
@@ -10964,7 +11988,7 @@
* APIMethod: transform
* Transform a point coordinate from one projection to another. Note that
* the input point is transformed in place.
- *
+ *
* Parameters:
* point - {{OpenLayers.Geometry.Point> | Object} An object with x and y
* properties representing coordinates in those dimensions.
@@ -10977,10 +12001,10 @@
OpenLayers.Projection.transform = function(point, source, dest) {
if (source.proj && dest.proj) {
point = Proj4js.transform(source.proj, dest.proj, point);
- } else if (source && dest &&
- OpenLayers.Projection.transforms[source.getCode()] &&
+ } else if (source && dest &&
+ OpenLayers.Projection.transforms[source.getCode()] &&
OpenLayers.Projection.transforms[source.getCode()][dest.getCode()]) {
- OpenLayers.Projection.transforms[source.getCode()][dest.getCode()](point);
+ OpenLayers.Projection.transforms[source.getCode()][dest.getCode()](point);
}
return point;
};
@@ -10988,8 +12012,9 @@
OpenLayers/Renderer/SVG.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -10998,18 +12023,18 @@
/**
* Class: OpenLayers.Renderer.SVG
- *
+ *
* Inherits:
* - <OpenLayers.Renderer.Elements>
*/
OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
- /**
+ /**
* Property: xmlns
* {String}
*/
xmlns: "http://www.w3.org/2000/svg",
-
+
/**
* Property: xlinkns
* {String}
@@ -11018,8 +12043,8 @@
/**
* Constant: MAX_PIXEL
- * {Integer} Firefox has a limitation where values larger or smaller than
- * about 15000 in an SVG document lock the browser up. This
+ * {Integer} Firefox has a limitation where values larger or smaller than
+ * about 15000 in an SVG document lock the browser up. This
* works around it.
*/
MAX_PIXEL: 15000,
@@ -11029,13 +12054,15 @@
* {Object} Hash with "x" and "y" properties
*/
translationParameters: null,
-
+
/**
- * Property: symbolSize
- * {Object} Cache for symbol sizes according to their svg coordinate space
+ * Property: symbolMetrics
+ * {Object} Cache for symbol metrics according to their svg coordinate
+ * space. This is an object keyed by the symbol's id, and values are
+ * an array of [width, centerX, centerY].
*/
- symbolSize: {},
-
+ symbolMetrics: null,
+
/**
* Property: isGecko
* {Boolean}
@@ -11043,19 +12070,30 @@
isGecko: null,
/**
+ * Property: supportUse
+ * {Boolean} true if defs/use is supported - known to not work as expected
+ * at least in some applewebkit/5* builds.
+ * See https://bugs.webkit.org/show_bug.cgi?id=33322
+ */
+ supportUse: null,
+
+ /**
* Constructor: OpenLayers.Renderer.SVG
- *
+ *
* Parameters:
* containerID - {String}
*/
initialize: function(containerID) {
- if (!this.supported()) {
- return;
+ if (!this.supported()) {
+ return;
}
- OpenLayers.Renderer.Elements.prototype.initialize.apply(this,
+ OpenLayers.Renderer.Elements.prototype.initialize.apply(this,
arguments);
this.translationParameters = {x: 0, y: 0};
+ this.supportUse = (navigator.userAgent.toLowerCase().indexOf("applewebkit/5") == -1);
this.isGecko = (navigator.userAgent.toLowerCase().indexOf("gecko/") != -1);
+
+ this.symbolMetrics = {};
},
/**
@@ -11064,20 +12102,20 @@
destroy: function() {
OpenLayers.Renderer.Elements.prototype.destroy.apply(this, arguments);
},
-
+
/**
* APIMethod: supported
- *
+ *
* Returns:
* {Boolean} Whether or not the browser supports the SVG renderer
*/
supported: function() {
var svgFeature = "http://www.w3.org/TR/SVG11/feature#";
- return (document.implementation &&
- (document.implementation.hasFeature("org.w3c.svg", "1.0") ||
- document.implementation.hasFeature(svgFeature + "SVG", "1.1") ||
+ return (document.implementation &&
+ (document.implementation.hasFeature("org.w3c.svg", "1.0") ||
+ document.implementation.hasFeature(svgFeature + "SVG", "1.1") ||
document.implementation.hasFeature(svgFeature + "BasicStructure", "1.1") ));
- },
+ },
/**
* Method: inValidRange
@@ -11088,11 +12126,11 @@
* y - {Integer}
* xyOnly - {Boolean} whether or not to just check for x and y, which means
* to not take the current translation parameters into account if true.
- *
+ *
* Returns:
- * {Boolean} Whether or not the 'x' and 'y' coordinates are in the
+ * {Boolean} Whether or not the 'x' and 'y' coordinates are in the
* valid range.
- */
+ */
inValidRange: function(x, y, xyOnly) {
var left = x + (xyOnly ? 0 : this.translationParameters.x);
var top = y + (xyOnly ? 0 : this.translationParameters.y);
@@ -11102,20 +12140,20 @@
/**
* Method: setExtent
- *
+ *
* Parameters:
* extent - {<OpenLayers.Bounds>}
* resolutionChanged - {Boolean}
- *
+ *
* Returns:
* {Boolean} true to notify the layer that the new extent does not exceed
* the coordinate range, and the features will not need to be redrawn.
* False otherwise.
*/
setExtent: function(extent, resolutionChanged) {
- OpenLayers.Renderer.Elements.prototype.setExtent.apply(this,
+ OpenLayers.Renderer.Elements.prototype.setExtent.apply(this,
arguments);
-
+
var resolution = this.getResolution();
var left = -extent.left / resolution;
var top = extent.top / resolution;
@@ -11140,15 +12178,15 @@
return inRange;
}
},
-
+
/**
* Method: translate
* Transforms the SVG coordinate system
- *
+ *
* Parameters:
* x - {Float}
* y - {Float}
- *
+ *
* Returns:
* {Boolean} true if the translation parameters are in the valid coordinates
* range, false otherwise.
@@ -11170,24 +12208,24 @@
/**
* Method: setSize
* Sets the size of the drawing surface.
- *
+ *
* Parameters:
* size - {<OpenLayers.Size>} The size of the drawing surface
*/
setSize: function(size) {
OpenLayers.Renderer.prototype.setSize.apply(this, arguments);
-
+
this.rendererRoot.setAttributeNS(null, "width", this.size.w);
this.rendererRoot.setAttributeNS(null, "height", this.size.h);
},
- /**
- * Method: getNodeType
- *
+ /**
+ * Method: getNodeType
+ *
* Parameters:
* geometry - {<OpenLayers.Geometry>}
* style - {Object}
- *
+ *
* Returns:
* {String} The corresponding node type for the specified geometry
*/
@@ -11198,7 +12236,7 @@
if (style.externalGraphic) {
nodeType = "image";
} else if (this.isComplexSymbol(style.graphicName)) {
- nodeType = "use";
+ nodeType = this.supportUse === false ? "svg" : "use";
} else {
nodeType = "circle";
}
@@ -11223,17 +12261,17 @@
return nodeType;
},
- /**
+ /**
* Method: setStyle
* Use to set all the style attributes to a SVG node.
- *
+ *
* Takes care to adjust stroke width and point radius to be
* resolution-relative
*
* Parameters:
* node - {SVGDomElement} An SVG element to decorate
* style - {Object}
- * options - {Object} Currently supported options include
+ * options - {Object} Currently supported options include
* 'isFilled' {Boolean} and
* 'isStroked' {Boolean}
*/
@@ -11249,7 +12287,7 @@
node.style.visibility = "hidden";
} else if (style.externalGraphic) {
pos = this.getPosition(node);
-
+
if (style.graphicTitle) {
node.setAttributeNS(null, "title", style.graphicTitle);
}
@@ -11266,7 +12304,7 @@
style.graphicYOffset : -(0.5 * height);
var opacity = style.graphicOpacity || style.fillOpacity;
-
+
node.setAttributeNS(null, "x", (pos.x + xOffset).toFixed());
node.setAttributeNS(null, "y", (pos.y + yOffset).toFixed());
node.setAttributeNS(null, "width", width);
@@ -11278,10 +12316,9 @@
var offset = style.pointRadius * 3;
var size = offset * 2;
var id = this.importSymbol(style.graphicName);
- var href = "#" + id;
pos = this.getPosition(node);
- widthFactor = this.symbolSize[id] / size;
-
+ widthFactor = this.symbolMetrics[id][0] * 3 / size;
+
// remove the node from the dom before we modify it. This
// prevents various rendering issues in Safari and FF
var parent = node.parentNode;
@@ -11289,13 +12326,23 @@
if(parent) {
parent.removeChild(node);
}
-
- node.setAttributeNS(this.xlinkns, "href", href);
+
+ if(this.supportUse === false) {
+ // workaround for webkit versions that cannot do defs/use
+ // (see https://bugs.webkit.org/show_bug.cgi?id=33322):
+ // copy the symbol instead of referencing it
+ var src = document.getElementById(id);
+ node.firstChild && node.removeChild(node.firstChild);
+ node.appendChild(src.firstChild.cloneNode(true));
+ node.setAttributeNS(null, "viewBox", src.getAttributeNS(null, "viewBox"));
+ } else {
+ node.setAttributeNS(this.xlinkns, "href", "#" + id);
+ }
node.setAttributeNS(null, "width", size);
node.setAttributeNS(null, "height", size);
node.setAttributeNS(null, "x", pos.x - offset);
node.setAttributeNS(null, "y", pos.y - offset);
-
+
// now that the node has all its new properties, insert it
// back into the dom where it was
if(nextSibling) {
@@ -11307,13 +12354,23 @@
node.setAttributeNS(null, "r", style.pointRadius);
}
- if (typeof style.rotation != "undefined" && pos) {
- var rotation = OpenLayers.String.format(
- "rotate(${0} ${1} ${2})", [style.rotation, pos.x, pos.y]);
- node.setAttributeNS(null, "transform", rotation);
+ var rotation = style.rotation;
+ if ((rotation !== undefined || node._rotation !== undefined) && pos) {
+ node._rotation = rotation;
+ rotation |= 0;
+ if(node.nodeName !== "svg") {
+ node.setAttributeNS(null, "transform",
+ "rotate(" + rotation + " " + pos.x + " " +
+ pos.y + ")");
+ } else {
+ var metrics = this.symbolMetrics[id];
+ node.firstChild.setAttributeNS(null, "transform",
+ "rotate(" + style.rotation + " " + metrics[1] +
+ " " + metrics[2] + ")");
+ }
}
}
-
+
if (options.isFilled) {
node.setAttributeNS(null, "fill", style.fillColor);
node.setAttributeNS(null, "fill-opacity", style.fillOpacity);
@@ -11325,41 +12382,41 @@
node.setAttributeNS(null, "stroke", style.strokeColor);
node.setAttributeNS(null, "stroke-opacity", style.strokeOpacity);
node.setAttributeNS(null, "stroke-width", style.strokeWidth * widthFactor);
- node.setAttributeNS(null, "stroke-linecap", style.strokeLinecap);
+ node.setAttributeNS(null, "stroke-linecap", style.strokeLinecap || "round");
// Hard-coded linejoin for now, to make it look the same as in VML.
// There is no strokeLinejoin property yet for symbolizers.
node.setAttributeNS(null, "stroke-linejoin", "round");
- node.setAttributeNS(null, "stroke-dasharray", this.dashStyle(style,
- widthFactor));
+ style.strokeDashstyle && node.setAttributeNS(null,
+ "stroke-dasharray", this.dashStyle(style, widthFactor));
} else {
node.setAttributeNS(null, "stroke", "none");
}
-
+
if (style.pointerEvents) {
node.setAttributeNS(null, "pointer-events", style.pointerEvents);
}
-
+
if (style.cursor != null) {
node.setAttributeNS(null, "cursor", style.cursor);
}
-
+
return node;
},
- /**
+ /**
* Method: dashStyle
- *
+ *
* Parameters:
* style - {Object}
* widthFactor - {Number}
- *
+ *
* Returns:
* {String} A SVG compliant 'stroke-dasharray' value
*/
dashStyle: function(style, widthFactor) {
var w = style.strokeWidth * widthFactor;
-
- switch (style.strokeDashstyle) {
+ var str = style.strokeDashstyle;
+ switch (str) {
case 'solid':
return 'none';
case 'dot':
@@ -11373,17 +12430,17 @@
case 'longdashdot':
return [8 * w, 4 * w, 1, 4 * w].join();
default:
- return style.strokeDashstyle.replace(/ /g, ",");
+ return OpenLayers.String.trim(str).replace(/\s+/g, ",");
}
},
-
- /**
+
+ /**
* Method: createNode
- *
+ *
* Parameters:
* type - {String} Kind of node to draw
* id - {String} Id for node
- *
+ *
* Returns:
* {DOMElement} A new node of the given type and id
*/
@@ -11392,26 +12449,26 @@
if (id) {
node.setAttributeNS(null, "id", id);
}
- return node;
+ return node;
},
-
- /**
+
+ /**
* Method: nodeTypeCompare
- *
+ *
* Parameters:
* node - {SVGDomElement} An SVG element
* type - {String} Kind of node
- *
+ *
* Returns:
* {Boolean} Whether or not the specified node is of the specified type
*/
nodeTypeCompare: function(node, type) {
return (type == node.nodeName);
},
-
+
/**
* Method: createRenderRoot
- *
+ *
* Returns:
* {DOMElement} The specific render engine's root element
*/
@@ -11421,10 +12478,10 @@
/**
* Method: createRoot
- *
+ *
* Parameter:
* suffix - {String} suffix to append to the id
- *
+ *
* Returns:
* {DOMElement}
*/
@@ -11453,14 +12510,14 @@
/**
* Method: drawPoint
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
- *
+ *
* Returns:
* {DOMElement} or false if the renderer could not draw the point
- */
+ */
drawPoint: function(node, geometry) {
return this.drawCircle(node, geometry, 1);
},
@@ -11468,12 +12525,12 @@
/**
* Method: drawCircle
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
* radius - {Float}
- *
+ *
* Returns:
* {DOMElement} or false if the renderer could not draw the circle
*/
@@ -11482,73 +12539,73 @@
var x = (geometry.x / resolution + this.left);
var y = (this.top - geometry.y / resolution);
- if (this.inValidRange(x, y)) {
+ if (this.inValidRange(x, y)) {
node.setAttributeNS(null, "cx", x);
node.setAttributeNS(null, "cy", y);
node.setAttributeNS(null, "r", radius);
return node;
} else {
return false;
- }
-
+ }
+
},
-
+
/**
* Method: drawLineString
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
- *
+ *
* Returns:
* {DOMElement} or null if the renderer could not draw all components of
* the linestring, or false if nothing could be drawn
- */
+ */
drawLineString: function(node, geometry) {
var componentsResult = this.getComponentsString(geometry.components);
if (componentsResult.path) {
node.setAttributeNS(null, "points", componentsResult.path);
- return (componentsResult.complete ? node : null);
+ return (componentsResult.complete ? node : null);
} else {
return false;
}
},
-
+
/**
* Method: drawLinearRing
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
- *
+ *
* Returns:
* {DOMElement} or null if the renderer could not draw all components
* of the linear ring, or false if nothing could be drawn
- */
+ */
drawLinearRing: function(node, geometry) {
var componentsResult = this.getComponentsString(geometry.components);
if (componentsResult.path) {
node.setAttributeNS(null, "points", componentsResult.path);
- return (componentsResult.complete ? node : null);
+ return (componentsResult.complete ? node : null);
} else {
return false;
}
},
-
+
/**
* Method: drawPolygon
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
- *
+ *
* Returns:
* {DOMElement} or null if the renderer could not draw all components
* of the polygon, or false if nothing could be drawn
- */
+ */
drawPolygon: function(node, geometry) {
var d = "";
var draw = true;
@@ -11573,26 +12630,26 @@
return complete ? node : null;
} else {
return false;
- }
+ }
},
-
+
/**
* Method: drawRectangle
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
- *
+ *
* Returns:
* {DOMElement} or false if the renderer could not draw the rectangle
- */
+ */
drawRectangle: function(node, geometry) {
var resolution = this.getResolution();
var x = (geometry.x / resolution + this.left);
var y = (this.top - geometry.y / resolution);
- if (this.inValidRange(x, y)) {
+ if (this.inValidRange(x, y)) {
node.setAttributeNS(null, "x", x);
node.setAttributeNS(null, "y", y);
node.setAttributeNS(null, "width", geometry.width / resolution);
@@ -11602,18 +12659,18 @@
return false;
}
},
-
+
/**
* Method: drawSurface
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
- *
+ *
* Returns:
* {DOMElement} or false if the renderer could not draw the surface
- */
+ */
drawSurface: function(node, geometry) {
// create the svg path string representation
@@ -11640,34 +12697,36 @@
return node;
} else {
return false;
- }
+ }
},
-
+
/**
* Method: drawText
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* featureId - {String}
* style -
* location - {<OpenLayers.Geometry.Point>}
*/
drawText: function(featureId, style, location) {
var resolution = this.getResolution();
-
+
var x = (location.x / resolution + this.left);
var y = (location.y / resolution - this.top);
-
+
var label = this.nodeFactory(featureId + this.LABEL_ID_SUFFIX, "text");
var tspan = this.nodeFactory(featureId + this.LABEL_ID_SUFFIX + "_tspan", "tspan");
label.setAttributeNS(null, "x", x);
label.setAttributeNS(null, "y", -y);
- label.setAttributeNS(null, "pointer-events", "none");
-
+
if (style.fontColor) {
label.setAttributeNS(null, "fill", style.fontColor);
}
+ if (style.fontOpacity) {
+ label.setAttributeNS(null, "opacity", style.fontOpacity);
+ }
if (style.fontFamily) {
label.setAttributeNS(null, "font-family", style.fontFamily);
}
@@ -11677,6 +12736,15 @@
if (style.fontWeight) {
label.setAttributeNS(null, "font-weight", style.fontWeight);
}
+ if(style.labelSelect === true) {
+ label.setAttributeNS(null, "pointer-events", "visible");
+ label._featureId = featureId;
+ tspan._featureId = featureId;
+ tspan._geometry = location;
+ tspan._geometryClass = location.CLASS_NAME;
+ } else {
+ label.setAttributeNS(null, "pointer-events", "none");
+ }
var align = style.labelAlign || "cm";
label.setAttributeNS(null, "text-anchor",
OpenLayers.Renderer.SVG.LABEL_ALIGN[align[0]] || "middle");
@@ -11690,20 +12758,20 @@
}
tspan.textContent = style.label;
-
+
if(!label.parentNode) {
label.appendChild(tspan);
this.textRoot.appendChild(label);
- }
+ }
},
-
- /**
+
+ /**
* Method: getComponentString
- *
+ *
* Parameters:
* components - {Array(<OpenLayers.Geometry.Point>)} Array of points
* separator - {String} character between coordinate pairs. Defaults to ","
- *
+ *
* Returns:
* {Object} hash with properties "path" (the string created from the
* components and "complete" (false if the renderer was unable to
@@ -11714,7 +12782,7 @@
var complete = true;
var len = components.length;
var strings = [];
- var str, component, j;
+ var str, component;
for(var i=0; i<len; i++) {
component = components[i];
renderCmp.push(component);
@@ -11747,13 +12815,13 @@
complete: complete
};
},
-
+
/**
* Method: clipLine
* Given two points (one inside the valid range, and one outside),
* clips the line betweeen the two points so that the new points are both
* inside the valid range.
- *
+ *
* Parameters:
* badComponent - {<OpenLayers.Geometry.Point>)} original geometry of the
* invalid point
@@ -11789,12 +12857,12 @@
return x2 + "," + y2;
},
- /**
+ /**
* Method: getShortString
- *
+ *
* Parameters:
* point - {<OpenLayers.Geometry.Point>}
- *
+ *
* Returns:
* {String} or false if point is outside the valid range
*/
@@ -11803,20 +12871,20 @@
var x = (point.x / resolution + this.left);
var y = (this.top - point.y / resolution);
- if (this.inValidRange(x, y)) {
+ if (this.inValidRange(x, y)) {
return x + "," + y;
} else {
return false;
}
},
-
+
/**
* Method: getPosition
* Finds the position of an svg node.
- *
+ *
* Parameters:
* node - {DOMElement}
- *
+ *
* Returns:
* {Object} hash with x and y properties, representing the coordinates
* within the svg coordinate system
@@ -11831,29 +12899,28 @@
/**
* Method: importSymbol
* add a new symbol definition from the rendererer's symbol hash
- *
+ *
* Parameters:
* graphicName - {String} name of the symbol to import
- *
+ *
* Returns:
* {String} - id of the imported symbol
- */
+ */
importSymbol: function (graphicName) {
if (!this.defs) {
// create svg defs tag
this.defs = this.createDefs();
}
var id = this.container.id + "-" + graphicName;
-
+
// check if symbol already exists in the defs
if (document.getElementById(id) != null) {
return id;
}
-
+
var symbol = OpenLayers.Renderer.symbol[graphicName];
if (!symbol) {
throw new Error(graphicName + ' is not a valid symbol name');
- return;
}
var symbolNode = this.nodeFactory(id, "symbol");
@@ -11862,7 +12929,7 @@
var symbolExtent = new OpenLayers.Bounds(
Number.MAX_VALUE, Number.MAX_VALUE, 0, 0);
- var points = "";
+ var points = [];
var x,y;
for (var i=0; i<symbol.length; i=i+2) {
x = symbol[i];
@@ -11871,11 +12938,11 @@
symbolExtent.bottom = Math.min(symbolExtent.bottom, y);
symbolExtent.right = Math.max(symbolExtent.right, x);
symbolExtent.top = Math.max(symbolExtent.top, y);
- points += " " + x + "," + y;
+ points.push(x, ",", y);
}
-
- node.setAttributeNS(null, "points", points);
-
+
+ node.setAttributeNS(null, "points", points.join(" "));
+
var width = symbolExtent.getWidth();
var height = symbolExtent.getHeight();
// create a viewBox three times as large as the symbol itself,
@@ -11883,11 +12950,35 @@
var viewBox = [symbolExtent.left - width,
symbolExtent.bottom - height, width * 3, height * 3];
symbolNode.setAttributeNS(null, "viewBox", viewBox.join(" "));
- this.symbolSize[id] = Math.max(width, height) * 3;
-
+ this.symbolMetrics[id] = [
+ Math.max(width, height),
+ symbolExtent.getCenterLonLat().lon,
+ symbolExtent.getCenterLonLat().lat
+ ];
+
this.defs.appendChild(symbolNode);
return symbolNode.id;
},
+
+ /**
+ * Method: getFeatureIdFromEvent
+ *
+ * Parameters:
+ * evt - {Object} An <OpenLayers.Event> object
+ *
+ * Returns:
+ * {<OpenLayers.Geometry>} A geometry from an event that
+ * happened on a layer.
+ */
+ getFeatureIdFromEvent: function(evt) {
+ var featureId = OpenLayers.Renderer.Elements.prototype.getFeatureIdFromEvent.apply(this, arguments);
+ if(this.supportUse === false && !featureId) {
+ var target = evt.target;
+ featureId = target.parentNode && target != this.rendererRoot &&
+ target.parentNode._featureId;
+ }
+ return featureId;
+ },
CLASS_NAME: "OpenLayers.Renderer.SVG"
});
@@ -11914,14 +13005,15 @@
// bottom to the top of the baseline, so -35% moves the text to
// the center of the baseline.
"t": "-70%",
- "b": "0"
+ "b": "0"
};
/* ======================================================================
OpenLayers/Renderer/VML.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -11932,9 +13024,9 @@
* Class: OpenLayers.Renderer.VML
* Render vector features in browsers with VML capability. Construct a new
* VML renderer with the <OpenLayers.Renderer.VML> constructor.
- *
- * Note that for all calculations in this class, we use toFixed() to round a
- * float value to an integer. This is done because it seems that VML doesn't
+ *
+ * Note that for all calculations in this class, we use (num | 0) to truncate a
+ * float value to an integer. This is done because it seems that VML doesn't
* support float values.
*
* Inherits from:
@@ -11947,7 +13039,7 @@
* {String} XML Namespace URN
*/
xmlns: "urn:schemas-microsoft-com:vml",
-
+
/**
* Property: symbolCache
* {DOMElement} node holding symbols. This hash is keyed by symbol name,
@@ -11960,7 +13052,7 @@
* {Object} Hash with "x" and "y" properties
*/
offset: null,
-
+
/**
* Constructor: OpenLayers.Renderer.VML
* Create a new VML renderer.
@@ -11969,23 +13061,22 @@
* containerID - {String} The id for the element that contains the renderer
*/
initialize: function(containerID) {
- if (!this.supported()) {
- return;
+ if (!this.supported()) {
+ return;
}
if (!document.namespaces.olv) {
document.namespaces.add("olv", this.xmlns);
var style = document.createStyleSheet();
- var shapes = ['shape','rect', 'oval', 'fill', 'stroke', 'imagedata', 'group','textbox'];
+ var shapes = ['shape','rect', 'oval', 'fill', 'stroke', 'imagedata', 'group','textbox'];
for (var i = 0, len = shapes.length; i < len; i++) {
style.addRule('olv\\:' + shapes[i], "behavior: url(#default#VML); " +
"position: absolute; display: inline-block;");
- }
+ }
}
-
- OpenLayers.Renderer.Elements.prototype.initialize.apply(this,
+
+ OpenLayers.Renderer.Elements.prototype.initialize.apply(this,
arguments);
- this.offset = {x: 0, y: 0};
},
/**
@@ -12005,7 +13096,7 @@
*/
supported: function() {
return !!(document.namespaces);
- },
+ },
/**
* Method: setExtent
@@ -12014,19 +13105,19 @@
* Parameters:
* extent - {<OpenLayers.Bounds>}
* resolutionChanged - {Boolean}
- *
+ *
* Returns:
* {Boolean} true to notify the layer that the new extent does not exceed
* the coordinate range, and the features will not need to be redrawn.
*/
setExtent: function(extent, resolutionChanged) {
- OpenLayers.Renderer.Elements.prototype.setExtent.apply(this,
+ OpenLayers.Renderer.Elements.prototype.setExtent.apply(this,
arguments);
var resolution = this.getResolution();
-
- var left = extent.left/resolution;
- var top = extent.top/resolution - this.size.h;
- if (resolutionChanged) {
+
+ var left = (extent.left/resolution) | 0;
+ var top = (extent.top/resolution - this.size.h) | 0;
+ if (resolutionChanged || !this.offset) {
this.offset = {x: left, y: top};
left = 0;
top = 0;
@@ -12035,7 +13126,7 @@
top = top - this.offset.y;
}
-
+
var org = left + " " + top;
this.root.coordorigin = org;
var roots = [this.root, this.vectorRoot, this.textRoot];
@@ -12045,12 +13136,12 @@
var size = this.size.w + " " + this.size.h;
root.coordsize = size;
-
+
}
- // flip the VML display Y axis upside down so it
+ // flip the VML display Y axis upside down so it
// matches the display Y axis of the map
this.root.style.flip = "y";
-
+
return true;
},
@@ -12064,7 +13155,7 @@
*/
setSize: function(size) {
OpenLayers.Renderer.prototype.setSize.apply(this, arguments);
-
+
// setting width and height on all roots to avoid flicker which we
// would get with 100% width and height on child roots
var roots = [
@@ -12129,7 +13220,7 @@
* Parameters:
* node - {DOMElement} An VML element to decorate
* style - {Object}
- * options - {Object} Currently supported options include
+ * options - {Object} Currently supported options include
* 'isFilled' {Boolean} and
* 'isStroked' {Boolean}
* geometry - {<OpenLayers.Geometry>}
@@ -12137,13 +13228,13 @@
setStyle: function(node, style, options, geometry) {
style = style || node._style;
options = options || node._options;
- var widthFactor = 1;
+ var fillColor = style.fillColor;
- if (node._geometryClass == "OpenLayers.Geometry.Point") {
+ if (node._geometryClass === "OpenLayers.Geometry.Point") {
if (style.externalGraphic) {
if (style.graphicTitle) {
node.title=style.graphicTitle;
- }
+ }
var width = style.graphicWidth || style.graphicHeight;
var height = style.graphicHeight || style.graphicWidth;
width = width ? width : style.pointRadius*2;
@@ -12154,22 +13245,22 @@
style.graphicXOffset : -(0.5 * width);
var yOffset = (style.graphicYOffset != undefined) ?
style.graphicYOffset : -(0.5 * height);
-
- node.style.left = ((geometry.x/resolution - this.offset.x)+xOffset).toFixed();
- node.style.top = ((geometry.y/resolution - this.offset.y)-(yOffset+height)).toFixed();
+
+ node.style.left = (((geometry.x/resolution - this.offset.x)+xOffset) | 0) + "px";
+ node.style.top = (((geometry.y/resolution - this.offset.y)-(yOffset+height)) | 0) + "px";
node.style.width = width + "px";
node.style.height = height + "px";
node.style.flip = "y";
-
- // modify style/options for fill and stroke styling below
- style.fillColor = "none";
+
+ // modify fillColor and options for stroke styling below
+ fillColor = "none";
options.isStroked = false;
} else if (this.isComplexSymbol(style.graphicName)) {
var cache = this.importSymbol(style.graphicName);
node.path = cache.path;
node.coordorigin = cache.left + "," + cache.bottom;
var size = cache.size;
- node.coordsize = size + "," + size;
+ node.coordsize = size + "," + size;
this.drawCircle(node, geometry, style.pointRadius);
node.style.flip = "y";
} else {
@@ -12177,11 +13268,11 @@
}
}
- // fill
- if (options.isFilled) {
- node.fillcolor = style.fillColor;
- } else {
- node.filled = "false";
+ // fill
+ if (options.isFilled) {
+ node.fillcolor = fillColor;
+ } else {
+ node.filled = "false";
}
var fills = node.getElementsByTagName("fill");
var fill = (fills.length == 0) ? null : fills[0];
@@ -12195,20 +13286,20 @@
}
fill.opacity = style.fillOpacity;
- if (node._geometryClass == "OpenLayers.Geometry.Point" &&
+ if (node._geometryClass === "OpenLayers.Geometry.Point" &&
style.externalGraphic) {
// override fillOpacity
if (style.graphicOpacity) {
fill.opacity = style.graphicOpacity;
}
-
+
fill.src = style.externalGraphic;
fill.type = "frame";
-
+
if (!(style.graphicWidth && style.graphicHeight)) {
fill.aspect = "atmost";
- }
+ }
}
if (fill.parentNode != node) {
node.appendChild(fill);
@@ -12216,42 +13307,45 @@
}
// additional rendering for rotated graphics or symbols
- if (typeof style.rotation != "undefined") {
+ var rotation = style.rotation;
+ if ((rotation !== undefined || node._rotation !== undefined)) {
+ node._rotation = rotation;
if (style.externalGraphic) {
- this.graphicRotate(node, xOffset, yOffset);
+ this.graphicRotate(node, xOffset, yOffset, style);
// make the fill fully transparent, because we now have
// the graphic as imagedata element. We cannot just remove
// the fill, because this is part of the hack described
// in graphicRotate
fill.opacity = 0;
- } else {
- node.style.rotation = style.rotation;
+ } else if(node._geometryClass === "OpenLayers.Geometry.Point") {
+ node.style.rotation = rotation || 0;
}
}
- // stroke
- if (options.isStroked) {
- node.strokecolor = style.strokeColor;
- node.strokeweight = style.strokeWidth + "px";
- } else {
- node.stroked = false;
- }
+ // stroke
var strokes = node.getElementsByTagName("stroke");
var stroke = (strokes.length == 0) ? null : strokes[0];
if (!options.isStroked) {
+ node.stroked = false;
if (stroke) {
- node.removeChild(stroke);
+ stroke.on = false;
}
} else {
if (!stroke) {
stroke = this.createNode('olv:stroke', node.id + "_stroke");
node.appendChild(stroke);
}
+ stroke.on = true;
+ stroke.color = style.strokeColor;
+ stroke.weight = style.strokeWidth + "px";
stroke.opacity = style.strokeOpacity;
- stroke.endcap = !style.strokeLinecap || style.strokeLinecap == 'butt' ? 'flat' : style.strokeLinecap;
- stroke.dashstyle = this.dashStyle(style);
+ stroke.endcap = style.strokeLinecap == 'butt' ? 'flat' :
+ (style.strokeLinecap || 'round');
+ if (style.strokeDashstyle) {
+ stroke.dashstyle = this.dashStyle(style);
+ }
}
-
+
if (style.cursor != "inherit" && style.cursor != null) {
node.style.cursor = style.cursor;
}
@@ -12271,16 +13365,17 @@
* insertion point of the rotated image, because DXImageTransform.Matrix
* does the rotation without the ability to specify a rotation center
* point.
- *
+ *
* Parameters:
* node - {DOMElement}
* xOffset - {Number} rotation center relative to image, x coordinate
* yOffset - {Number} rotation center relative to image, y coordinate
+ * style - {Object}
*/
- graphicRotate: function(node, xOffset, yOffset) {
+ graphicRotate: function(node, xOffset, yOffset, style) {
var style = style || node._style;
- var options = node._options;
-
+ var rotation = style.rotation || 0;
+
var aspectRatio, size;
if (!(style.graphicWidth && style.graphicHeight)) {
// load the image to determine its size
@@ -12289,29 +13384,29 @@
if(img.readyState == "complete" ||
img.readyState == "interactive") {
aspectRatio = img.width / img.height;
- size = Math.max(style.pointRadius * 2,
+ size = Math.max(style.pointRadius * 2,
style.graphicWidth || 0,
style.graphicHeight || 0);
xOffset = xOffset * aspectRatio;
style.graphicWidth = size * aspectRatio;
style.graphicHeight = size;
- this.graphicRotate(node, xOffset, yOffset);
+ this.graphicRotate(node, xOffset, yOffset, style);
}
}, this);
img.src = style.externalGraphic;
-
+
// will be called again by the onreadystate handler
return;
} else {
size = Math.max(style.graphicWidth, style.graphicHeight);
aspectRatio = style.graphicWidth / style.graphicHeight;
}
-
+
var width = Math.round(style.graphicWidth || size * aspectRatio);
var height = Math.round(style.graphicHeight || size);
node.style.width = width + "px";
node.style.height = height + "px";
-
+
// Three steps are required to remove artefacts for images with
// transparent backgrounds (resulting from using DXImageTransform
// filters on svg objects), while preserving awareness for browser
@@ -12330,12 +13425,12 @@
image.style.height = height + "px";
image.src = style.externalGraphic;
image.style.filter =
- "progid:DXImageTransform.Microsoft.AlphaImageLoader(" +
+ "progid:DXImageTransform.Microsoft.AlphaImageLoader(" +
"src='', sizingMethod='scale')";
- var rotation = style.rotation * Math.PI / 180;
- var sintheta = Math.sin(rotation);
- var costheta = Math.cos(rotation);
+ var rot = rotation * Math.PI / 180;
+ var sintheta = Math.sin(rot);
+ var costheta = Math.cos(rot);
// do the rotation on the image
var filter =
@@ -12346,8 +13441,8 @@
// set the opacity (needed for the imagedata)
var opacity = style.graphicOpacity || style.fillOpacity;
if (opacity && opacity != 1) {
- filter +=
- "progid:DXImageTransform.Microsoft.BasicImage(opacity=" +
+ filter +=
+ "progid:DXImageTransform.Microsoft.BasicImage(opacity=" +
opacity+")\n";
}
node.style.filter = filter;
@@ -12366,15 +13461,19 @@
/**
* Method: postDraw
- * Some versions of Internet Explorer seem to be unable to set fillcolor
- * and strokecolor to "none" correctly before the fill node is appended to
- * a visible vml node. This method takes care of that and sets fillcolor
- * and strokecolor again if needed.
- *
+ * Does some node postprocessing to work around browser issues:
+ * - Some versions of Internet Explorer seem to be unable to set fillcolor
+ * and strokecolor to "none" correctly before the fill node is appended
+ * to a visible vml node. This method takes care of that and sets
+ * fillcolor and strokecolor again if needed.
+ * - In some cases, a node won't become visible after being drawn. Setting
+ * style.visibility to "visible" works around that.
+ *
* Parameters:
* node - {DOMElement}
*/
postDraw: function(node) {
+ node.style.visibility = "visible";
var fillColor = node._style.fillColor;
var strokeColor = node._style.strokeColor;
if (fillColor == "none" &&
@@ -12390,9 +13489,9 @@
/**
* Method: setNodeDimension
- * Get the geometry's bounds, convert it to our vml coordinate system,
+ * Get the geometry's bounds, convert it to our vml coordinate system,
* then set the node's position, size, and local coordinate system.
- *
+ *
* Parameters:
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
@@ -12402,30 +13501,30 @@
var bbox = geometry.getBounds();
if(bbox) {
var resolution = this.getResolution();
-
- var scaledBox =
- new OpenLayers.Bounds((bbox.left/resolution - this.offset.x).toFixed(),
- (bbox.bottom/resolution - this.offset.y).toFixed(),
- (bbox.right/resolution - this.offset.x).toFixed(),
- (bbox.top/resolution - this.offset.y).toFixed());
-
+
+ var scaledBox =
+ new OpenLayers.Bounds((bbox.left/resolution - this.offset.x) | 0,
+ (bbox.bottom/resolution - this.offset.y) | 0,
+ (bbox.right/resolution - this.offset.x) | 0,
+ (bbox.top/resolution - this.offset.y) | 0);
+
// Set the internal coordinate system to draw the path
node.style.left = scaledBox.left + "px";
node.style.top = scaledBox.top + "px";
node.style.width = scaledBox.getWidth() + "px";
node.style.height = scaledBox.getHeight() + "px";
-
+
node.coordorigin = scaledBox.left + " " + scaledBox.top;
node.coordsize = scaledBox.getWidth()+ " " + scaledBox.getHeight();
}
},
-
- /**
+
+ /**
* Method: dashStyle
- *
+ *
* Parameters:
* style - {Object}
- *
+ *
* Returns:
* {String} A VML compliant 'stroke-dasharray' value
*/
@@ -12471,15 +13570,15 @@
if (id) {
node.id = id;
}
-
+
// IE hack to make elements unselectable, to prevent 'blue flash'
// while dragging vectors; #1410
node.unselectable = 'on';
- node.onselectstart = function() { return(false); };
-
- return node;
+ node.onselectstart = OpenLayers.Function.False;
+
+ return node;
},
-
+
/**
* Method: nodeTypeCompare
* Determine whether a node is of a given type
@@ -12524,7 +13623,7 @@
/**
* Method: createRoot
* Create the main root element
- *
+ *
* Parameters:
* suffix - {String} suffix to append to the id
*
@@ -12534,21 +13633,21 @@
createRoot: function(suffix) {
return this.nodeFactory(this.container.id + suffix, "olv:group");
},
-
+
/**************************************
* *
* GEOMETRY DRAWING FUNCTIONS *
* *
**************************************/
-
+
/**
* Method: drawPoint
* Render a point
- *
+ *
* Parameters:
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
- *
+ *
* Returns:
* {DOMElement} or false if the point could not be drawn
*/
@@ -12560,12 +13659,12 @@
* Method: drawCircle
* Render a circle.
* Size and Center a circle given geometry (x,y center) and radius
- *
+ *
* Parameters:
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
* radius - {float}
- *
+ *
* Returns:
* {DOMElement} or false if the circle could not ne drawn
*/
@@ -12573,11 +13672,11 @@
if(!isNaN(geometry.x)&& !isNaN(geometry.y)) {
var resolution = this.getResolution();
- node.style.left = ((geometry.x /resolution - this.offset.x).toFixed() - radius) + "px";
- node.style.top = ((geometry.y /resolution - this.offset.y).toFixed() - radius) + "px";
-
+ node.style.left = (((geometry.x /resolution - this.offset.x) | 0) - radius) + "px";
+ node.style.top = (((geometry.y /resolution - this.offset.y) | 0) - radius) + "px";
+
var diameter = radius * 2;
-
+
node.style.width = diameter + "px";
node.style.height = diameter + "px";
return node;
@@ -12589,11 +13688,11 @@
/**
* Method: drawLineString
* Render a linestring.
- *
+ *
* Parameters:
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
- *
+ *
* Returns:
* {DOMElement}
*/
@@ -12604,11 +13703,11 @@
/**
* Method: drawLinearRing
* Render a linearring
- *
+ *
* Parameters:
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
- *
+ *
* Returns:
* {DOMElement}
*/
@@ -12619,12 +13718,12 @@
/**
* Method: DrawLine
* Render a line.
- *
+ *
* Parameters:
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
* closeLine - {Boolean} Close the line? (make it a ring?)
- *
+ *
* Returns:
* {DOMElement}
*/
@@ -12639,9 +13738,9 @@
var comp, x, y;
for (var i = 0; i < numComponents; i++) {
comp = geometry.components[i];
- x = (comp.x/resolution - this.offset.x);
- y = (comp.y/resolution - this.offset.y);
- parts[i] = " " + x.toFixed() + "," + y.toFixed() + " l ";
+ x = (comp.x/resolution - this.offset.x) | 0;
+ y = (comp.y/resolution - this.offset.y) | 0;
+ parts[i] = " " + x + "," + y + " l ";
}
var end = (closeLine) ? " x e" : " e";
node.path = "m" + parts.join("") + end;
@@ -12651,11 +13750,11 @@
/**
* Method: drawPolygon
* Render a polygon
- *
+ *
* Parameters:
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
- *
+ *
* Returns:
* {DOMElement}
*/
@@ -12663,7 +13762,7 @@
this.setNodeDimension(node, geometry);
var resolution = this.getResolution();
-
+
var path = [];
var linearRing, i, j, len, ilen, comp, x, y;
for (j = 0, len=geometry.components.length; j<len; j++) {
@@ -12672,9 +13771,9 @@
path.push("m");
for (i=0, ilen=linearRing.components.length; i<ilen; i++) {
comp = linearRing.components[i];
- x = comp.x / resolution - this.offset.x;
- y = comp.y / resolution - this.offset.y;
- path.push(" " + x.toFixed() + "," + y.toFixed());
+ x = (comp.x / resolution - this.offset.x) | 0;
+ y = (comp.y / resolution - this.offset.y) | 0;
+ path.push(" " + x + "," + y);
if (i==0) {
path.push(" l");
}
@@ -12689,30 +13788,30 @@
/**
* Method: drawRectangle
* Render a rectangle
- *
+ *
* Parameters:
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
- *
+ *
* Returns:
* {DOMElement}
*/
drawRectangle: function(node, geometry) {
var resolution = this.getResolution();
-
- node.style.left = (geometry.x/resolution - this.offset.x) + "px";
- node.style.top = (geometry.y/resolution - this.offset.y) + "px";
- node.style.width = geometry.width/resolution + "px";
- node.style.height = geometry.height/resolution + "px";
-
+
+ node.style.left = ((geometry.x/resolution - this.offset.x) | 0) + "px";
+ node.style.top = ((geometry.y/resolution - this.offset.y) | 0) + "px";
+ node.style.width = ((geometry.width/resolution) | 0) + "px";
+ node.style.height = ((geometry.height/resolution) | 0) + "px";
+
return node;
},
-
+
/**
* Method: drawText
* This method is only called by the renderer itself.
- *
- * Parameters:
+ *
+ * Parameters:
* featureId - {String}
* style -
* location - {<OpenLayers.Geometry.Point>}
@@ -12720,17 +13819,20 @@
drawText: function(featureId, style, location) {
var label = this.nodeFactory(featureId + this.LABEL_ID_SUFFIX, "olv:rect");
var textbox = this.nodeFactory(featureId + this.LABEL_ID_SUFFIX + "_textbox", "olv:textbox");
-
+
var resolution = this.getResolution();
- label.style.left = (location.x/resolution - this.offset.x).toFixed() + "px";
- label.style.top = (location.y/resolution - this.offset.y).toFixed() + "px";
+ label.style.left = ((location.x/resolution - this.offset.x) | 0) + "px";
+ label.style.top = ((location.y/resolution - this.offset.y) | 0) + "px";
label.style.flip = "y";
textbox.innerText = style.label;
- if (style.fillColor) {
+ if (style.fontColor) {
textbox.style.color = style.fontColor;
}
+ if (style.fontOpacity) {
+ textbox.style.filter = 'alpha(opacity=' + (style.fontOpacity * 100) + ')';
+ }
if (style.fontFamily) {
textbox.style.fontFamily = style.fontFamily;
}
@@ -12740,6 +13842,12 @@
if (style.fontWeight) {
textbox.style.fontWeight = style.fontWeight;
}
+ if(style.labelSelect === true) {
+ label._featureId = featureId;
+ textbox._featureId = featureId;
+ textbox._geometry = location;
+ textbox._geometryClass = location.CLASS_NAME;
+ }
textbox.style.whiteSpace = "nowrap";
// fun with IE: IE7 in standards compliant mode does not display any
// text with a left inset of 0. So we set this to 1px and subtract one
@@ -12752,21 +13860,25 @@
}
var align = style.labelAlign || "cm";
+ if (align.length == 1) {
+ align += "m";
+ }
var xshift = textbox.clientWidth *
(OpenLayers.Renderer.VML.LABEL_SHIFT[align.substr(0,1)]);
var yshift = textbox.clientHeight *
(OpenLayers.Renderer.VML.LABEL_SHIFT[align.substr(1,1)]);
label.style.left = parseInt(label.style.left)-xshift-1+"px";
label.style.top = parseInt(label.style.top)+yshift+"px";
+
},
/**
* Method: drawSurface
- *
+ *
* Parameters:
* node - {DOMElement}
* geometry - {<OpenLayers.Geometry>}
- *
+ *
* Returns:
* {DOMElement}
*/
@@ -12775,13 +13887,13 @@
this.setNodeDimension(node, geometry);
var resolution = this.getResolution();
-
+
var path = [];
var comp, x, y;
for (var i=0, len=geometry.components.length; i<len; i++) {
comp = geometry.components[i];
- x = comp.x / resolution - this.offset.x;
- y = comp.y / resolution - this.offset.y;
+ x = (comp.x / resolution - this.offset.x) | 0;
+ y = (comp.y / resolution - this.offset.y) | 0;
if ((i%3)==0 && (i/3)==0) {
path.push("m");
} else if ((i%3)==1) {
@@ -12794,17 +13906,17 @@
node.path = path.join("");
return node;
},
-
+
/**
* Method: moveRoot
* moves this renderer's root to a different renderer.
- *
+ *
* Parameters:
* renderer - {<OpenLayers.Renderer>} target renderer for the moved root
* root - {DOMElement} optional root node. To be used when this renderer
* holds roots from multiple layers to tell this method which one to
* detach
- *
+ *
* Returns:
* {Boolean} true if successful, false otherwise
*/
@@ -12817,39 +13929,38 @@
OpenLayers.Renderer.Elements.prototype.moveRoot.apply(this, arguments);
layer && layer.redraw();
},
-
+
/**
* Method: importSymbol
* add a new symbol definition from the rendererer's symbol hash
- *
+ *
* Parameters:
* graphicName - {String} name of the symbol to import
- *
+ *
* Returns:
* {Object} - hash of {DOMElement} "symbol" and {Number} "size"
- */
+ */
importSymbol: function (graphicName) {
var id = this.container.id + "-" + graphicName;
-
+
// check if symbol already exists in the cache
var cache = this.symbolCache[id];
if (cache) {
return cache;
}
-
+
var symbol = OpenLayers.Renderer.symbol[graphicName];
if (!symbol) {
throw new Error(graphicName + ' is not a valid symbol name');
- return;
}
var symbolExtent = new OpenLayers.Bounds(
Number.MAX_VALUE, Number.MAX_VALUE, 0, 0);
-
+
var pathitems = ["m"];
for (var i=0; i<symbol.length; i=i+2) {
- x = symbol[i];
- y = symbol[i+1];
+ var x = symbol[i];
+ var y = symbol[i+1];
symbolExtent.left = Math.min(symbolExtent.left, x);
symbolExtent.bottom = Math.min(symbolExtent.bottom, y);
symbolExtent.right = Math.max(symbolExtent.right, x);
@@ -12869,10 +13980,10 @@
symbolExtent.bottom = symbolExtent.bottom - diff;
symbolExtent.top = symbolExtent.top + diff;
} else {
- symbolExtent.left = symbolExtent.left - diff;
- symbolExtent.right = symbolExtent.right + diff;
+ symbolExtent.left = symbolExtent.left + diff;
+ symbolExtent.right = symbolExtent.right - diff;
}
-
+
cache = {
path: path,
size: symbolExtent.getWidth(), // equals getHeight() now
@@ -12880,10 +13991,10 @@
bottom: symbolExtent.bottom
};
this.symbolCache[id] = cache;
-
+
return cache;
},
-
+
CLASS_NAME: "OpenLayers.Renderer.VML"
});
@@ -12903,8 +14014,9 @@
OpenLayers/Tile.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
@@ -12914,70 +14026,70 @@
*/
/*
- * Class: OpenLayers.Tile
+ * Class: OpenLayers.Tile
* This is a class designed to designate a single tile, however
- * it is explicitly designed to do relatively little. Tiles store
+ * it is explicitly designed to do relatively little. Tiles store
* information about themselves -- such as the URL that they are related
- * to, and their size - but do not add themselves to the layer div
- * automatically, for example. Create a new tile with the
- * <OpenLayers.Tile> constructor, or a subclass.
- *
+ * to, and their size - but do not add themselves to the layer div
+ * automatically, for example. Create a new tile with the
+ * <OpenLayers.Tile> constructor, or a subclass.
+ *
* TBD 3.0 - remove reference to url in above paragraph
- *
+ *
*/
OpenLayers.Tile = OpenLayers.Class({
-
- /**
+
+ /**
* Constant: EVENT_TYPES
* {Array(String)} Supported application event types
*/
EVENT_TYPES: [ "loadstart", "loadend", "reload", "unload"],
-
+
/**
* APIProperty: events
- * {<OpenLayers.Events>} An events object that handles all
+ * {<OpenLayers.Events>} An events object that handles all
* events on the tile.
*/
events: null,
/**
- * Property: id
+ * Property: id
* {String} null
*/
id: null,
-
- /**
- * Property: layer
- * {<OpenLayers.Layer>} layer the tile is attached to
+
+ /**
+ * Property: layer
+ * {<OpenLayers.Layer>} layer the tile is attached to
*/
layer: null,
-
+
/**
* Property: url
* {String} url of the request.
*
- * TBD 3.0
- * Deprecated. The base tile class does not need an url. This should be
+ * TBD 3.0
+ * Deprecated. The base tile class does not need an url. This should be
* handled in subclasses. Does not belong here.
*/
url: null,
- /**
- * APIProperty: bounds
+ /**
+ * APIProperty: bounds
* {<OpenLayers.Bounds>} null
*/
bounds: null,
-
- /**
- * Property: size
+
+ /**
+ * Property: size
* {<OpenLayers.Size>} null
*/
size: null,
-
- /**
- * Property: position
+
+ /**
+ * Property: position
* {<OpenLayers.Pixel>} Top Left pixel of the tile
- */
+ */
position: null,
/**
@@ -12985,20 +14097,20 @@
* {Boolean} Is the tile loading?
*/
isLoading: false,
-
+
/** TBD 3.0 -- remove 'url' from the list of parameters to the constructor.
* there is no need for the base tile class to have a url.
- *
+ *
* Constructor: OpenLayers.Tile
* Constructor for a new <OpenLayers.Tile> instance.
- *
+ *
* Parameters:
* layer - {<OpenLayers.Layer>} layer that the tile will go in.
* position - {<OpenLayers.Pixel>}
* bounds - {<OpenLayers.Bounds>}
* url - {<String>}
* size - {<OpenLayers.Size>}
- */
+ */
initialize: function(layer, position, bounds, url, size) {
this.layer = layer;
this.position = position.clone();
@@ -13008,7 +14120,7 @@
//give the tile a unique id based on its BBOX.
this.id = OpenLayers.Util.createUniqueID("Tile_");
-
+
this.events = new OpenLayers.Events(this, null, this.EVENT_TYPES);
},
@@ -13020,13 +14132,13 @@
* still loading.
*/
unload: function() {
- if (this.isLoading) {
- this.isLoading = false;
- this.events.triggerEvent("unload");
+ if (this.isLoading) {
+ this.isLoading = false;
+ this.events.triggerEvent("unload");
}
},
-
- /**
+
+ /**
* APIMethod: destroy
* Nullify references to prevent circular references and memory leaks.
*/
@@ -13035,11 +14147,11 @@
this.bounds = null;
this.size = null;
this.position = null;
-
+
this.events.destroy();
this.events = null;
},
-
+
/**
* Method: clone
*
@@ -13051,27 +14163,27 @@
*/
clone: function (obj) {
if (obj == null) {
- obj = new OpenLayers.Tile(this.layer,
- this.position,
- this.bounds,
- this.url,
+ obj = new OpenLayers.Tile(this.layer,
+ this.position,
+ this.bounds,
+ this.url,
this.size);
- }
-
+ }
+
// catch any randomly tagged-on properties
OpenLayers.Util.applyDefaults(obj, this);
-
+
return obj;
},
/**
* Method: draw
- * Clear whatever is currently in the tile, then return whether or not
+ * Clear whatever is currently in the tile, then return whether or not
* it should actually be re-drawn.
- *
+ *
* Returns:
- * {Boolean} Whether or not the tile should actually be drawn. Note that
- * this is not really the best way of doing things, but such is
+ * {Boolean} Whether or not the tile should actually be drawn. Note that
+ * this is not really the best way of doing things, but such is
* the way the code has been developed. Subclasses call this and
* depend on the return to know if they should draw or not.
*/
@@ -13079,18 +14191,18 @@
var maxExtent = this.layer.maxExtent;
var withinMaxExtent = (maxExtent &&
this.bounds.intersectsBounds(maxExtent, false));
-
- // The only case where we *wouldn't* want to draw the tile is if the
+
+ // The only case where we *wouldn't* want to draw the tile is if the
// tile is outside its layer's maxExtent.
this.shouldDraw = (withinMaxExtent || this.layer.displayOutsideMaxExtent);
-
+
//clear tile's contents and mark as not drawn
this.clear();
-
+
return this.shouldDraw;
},
-
- /**
+
+ /**
* Method: moveTo
* Reposition the tile.
*
@@ -13112,83 +14224,84 @@
}
},
- /**
+ /**
* Method: clear
- * Clear the tile of any bounds/position-related data so that it can
+ * Clear the tile of any bounds/position-related data so that it can
* be reused in a new location. To be implemented by subclasses.
*/
clear: function() {
// to be implemented by subclasses
},
-
- /**
+
+ /**
* Method: getBoundsFromBaseLayer
- * Take the pixel locations of the corner of the tile, and pass them to
- * the base layer and ask for the location of those pixels, so that
+ * Take the pixel locations of the corner of the tile, and pass them to
+ * the base layer and ask for the location of those pixels, so that
* displaying tiles over Google works fine.
*
* Parameters:
* position - {<OpenLayers.Pixel>}
*
* Returns:
- * bounds - {<OpenLayers.Bounds>}
+ * bounds - {<OpenLayers.Bounds>}
*/
getBoundsFromBaseLayer: function(position) {
var msg = OpenLayers.i18n('reprojectDeprecated',
{'layerName':this.layer.name});
OpenLayers.Console.warn(msg);
- var topLeft = this.layer.map.getLonLatFromLayerPx(position);
+ var topLeft = this.layer.map.getLonLatFromLayerPx(position);
var bottomRightPx = position.clone();
bottomRightPx.x += this.size.w;
bottomRightPx.y += this.size.h;
- var bottomRight = this.layer.map.getLonLatFromLayerPx(bottomRightPx);
+ var bottomRight = this.layer.map.getLonLatFromLayerPx(bottomRightPx);
// Handle the case where the base layer wraps around the date line.
- // Google does this, and it breaks WMS servers to request bounds in
- // that fashion.
+ // Google does this, and it breaks WMS servers to request bounds in
+ // that fashion.
if (topLeft.lon > bottomRight.lon) {
if (topLeft.lon < 0) {
topLeft.lon = -180 - (topLeft.lon+180);
} else {
bottomRight.lon = 180+bottomRight.lon+180;
- }
+ }
}
- var bounds = new OpenLayers.Bounds(topLeft.lon,
- bottomRight.lat,
- bottomRight.lon,
- topLeft.lat);
+ var bounds = new OpenLayers.Bounds(topLeft.lon,
+ bottomRight.lat,
+ bottomRight.lon,
+ topLeft.lat);
return bounds;
- },
-
- /**
+ },
+
+ /**
* Method: showTile
* Show the tile only if it should be drawn.
*/
- showTile: function() {
+ showTile: function() {
if (this.shouldDraw) {
this.show();
}
},
-
- /**
+
+ /**
* Method: show
* Show the tile. To be implemented by subclasses.
*/
show: function() { },
-
- /**
+
+ /**
* Method: hide
* Hide the tile. To be implemented by subclasses.
*/
hide: function() { },
-
+
CLASS_NAME: "OpenLayers.Tile"
});
/* ======================================================================
OpenLayers/Format/XML.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -13207,7 +14320,7 @@
* - <OpenLayers.Format>
*/
OpenLayers.Format.XML = OpenLayers.Class(OpenLayers.Format, {
-
+
/**
* Property: namespaces
* {Object} Mapping of namespace aliases to namespace URIs. Properties
@@ -13216,20 +14329,20 @@
* <setNamespace> to add or set a namespace alias after construction.
*/
namespaces: null,
-
+
/**
* Property: namespaceAlias
* {Object} Mapping of namespace URI to namespace alias. This object
* is read-only. Use <setNamespace> to add or set a namespace alias.
*/
namespaceAlias: null,
-
+
/**
* Property: defaultPrefix
* {String} The default namespace alias for creating element nodes.
*/
defaultPrefix: null,
-
+
/**
* Property: readers
* Contains public functions, grouped by namespace prefix, that will
@@ -13239,7 +14352,7 @@
* from the parent.
*/
readers: {},
-
+
/**
* Property: writers
* As a compliment to the <readers> property, this structure contains public
@@ -13280,7 +14393,7 @@
this.namespaceAlias[this.namespaces[alias]] = alias;
}
},
-
+
/**
* APIMethod: destroy
* Clean up.
@@ -13289,7 +14402,7 @@
this.xmldom = null;
OpenLayers.Format.prototype.destroy.apply(this, arguments);
},
-
+
/**
* Method: setNamespace
* Set a namespace alias and URI for the format.
@@ -13309,7 +14422,7 @@
*
* Parameters:
* text - {String} A XML string
-
+
* Returns:
* {DOMElement} A DOM node
*/
@@ -13330,7 +14443,7 @@
xmldom = new ActiveXObject("Microsoft.XMLDOM");
} else {
xmldom = this.xmldom;
-
+
}
xmldom.loadXML(text);
return xmldom;
@@ -13361,7 +14474,7 @@
/**
* APIMethod: write
* Serialize a DOM node into a XML string.
- *
+ *
* Parameters:
* node - {DOMElement} A DOM node.
*
@@ -13400,7 +14513,7 @@
* Parameters:
* uri - {String} Namespace URI for the element.
* name - {String} The qualified name of the element (prefix:localname).
- *
+ *
* Returns:
* {Element} A DOM element with namespace.
*/
@@ -13423,15 +14536,18 @@
* Create a text node. This node can be appended to another node with
* the standard node.appendChild method. For cross-browser support,
* this method must be used instead of document.createTextNode.
- *
+ *
* Parameters:
* text - {String} The text of the node.
- *
- * Returns:
+ *
+ * Returns:
* {DOMElement} A DOM text node.
*/
createTextNode: function(text) {
var node;
+ if (typeof text !== "string") {
+ text = String(text);
+ }
if(this.xmldom) {
node = this.xmldom.createTextNode(text);
} else {
@@ -13446,12 +14562,12 @@
* To return all nodes in a given namespace, use '*' for the name
* argument. To return all nodes of a given (local) name, regardless
* of namespace, use '*' for the uri argument.
- *
+ *
* Parameters:
* node - {Element} Node on which to search for other nodes.
* uri - {String} Namespace URI.
* name - {String} Local name of the tag (without the prefix).
- *
+ *
* Returns:
* {NodeList} A node list or array of elements.
*/
@@ -13480,12 +14596,12 @@
/**
* APIMethod: getAttributeNodeNS
* Get an attribute node given the namespace URI and local name.
- *
+ *
* Parameters:
* node - {Element} Node on which to search for attribute nodes.
* uri - {String} Namespace URI.
* name - {String} Local name of the attribute (without the prefix).
- *
+ *
* Returns:
* {DOMElement} An attribute node or null if none found.
*/
@@ -13514,12 +14630,12 @@
/**
* APIMethod: getAttributeNS
* Get an attribute value given the namespace URI and local name.
- *
+ *
* Parameters:
* node - {Element} Node on which to search for an attribute.
* uri - {String} Namespace URI.
* name - {String} Local name of the attribute (without the prefix).
- *
+ *
* Returns:
* {String} An attribute value or and empty string if none found.
*/
@@ -13535,7 +14651,7 @@
}
return attributeValue;
},
-
+
/**
* APIMethod: getChildValue
* Get the textual value of the node if it exists, or return an
@@ -13597,7 +14713,7 @@
}
return value;
},
-
+
/**
* APIMethod: isSimpleContent
* Test if the given node has only simple content (i.e. no child element
@@ -13607,7 +14723,7 @@
* node - {DOMElement} An element node.
*
* Returns:
- * {Boolean} The node has no child element nodes (nodes of type 1).
+ * {Boolean} The node has no child element nodes (nodes of type 1).
*/
isSimpleContent: function(node) {
var simple = true;
@@ -13619,7 +14735,7 @@
}
return simple;
},
-
+
/**
* APIMethod: contentType
* Determine the content type for a given node.
@@ -13634,7 +14750,7 @@
contentType: function(node) {
var simple = false,
complex = false;
-
+
var type = OpenLayers.Format.XML.CONTENT_TYPE.EMPTY;
for(var child=node.firstChild; child; child=child.nextSibling) {
@@ -13651,7 +14767,7 @@
break;
}
}
-
+
if(complex && simple) {
type = OpenLayers.Format.XML.CONTENT_TYPE.MIXED;
} else if(complex) {
@@ -13666,12 +14782,12 @@
* APIMethod: hasAttributeNS
* Determine whether a node has a particular attribute matching the given
* name and namespace.
- *
+ *
* Parameters:
* node - {Element} Node on which to search for an attribute.
* uri - {String} Namespace URI.
* name - {String} Local name of the attribute (without the prefix).
- *
+ *
* Returns:
* {Boolean} The node has an attribute matching the name and namespace.
*/
@@ -13684,7 +14800,7 @@
}
return found;
},
-
+
/**
* APIMethod: setAttributeNS
* Adds a new attribute or changes the value of an attribute with the given
@@ -13757,14 +14873,11 @@
}
var value = options.value;
if(value != null) {
- if(typeof value == "boolean") {
- value = String(value);
- }
node.appendChild(this.createTextNode(value));
}
return node;
},
-
+
/**
* Method: setAttributes
* Set multiple attributes given key value pairs from an object.
@@ -13806,7 +14919,7 @@
if(!obj) {
obj = {};
}
- var group = this.readers[this.namespaceAlias[node.namespaceURI]];
+ var group = this.readers[node.namespaceURI ? this.namespaceAlias[node.namespaceURI]: this.defaultPrefix];
if(group) {
var local = node.localName || node.nodeName.split(":").pop();
var reader = group[local] || group["*"];
@@ -13903,7 +15016,7 @@
getChildEl: function(node, name, uri) {
return node && this.getThisOrNextEl(node.firstChild, name, uri);
},
-
+
/**
* APIMethod: getNextEl
* Get the next sibling element. Optionally get the first sibling only
@@ -13922,7 +15035,7 @@
getNextEl: function(node, name, uri) {
return node && this.getThisOrNextEl(node.nextSibling, name, uri);
},
-
+
/**
* Method: getThisOrNextEl
* Return this node or the next element node. Optionally get the first
@@ -13964,7 +15077,7 @@
}
return sibling || null;
},
-
+
/**
* APIMethod: lookupNamespaceURI
* Takes a prefix and returns the namespace URI associated with it on the given
@@ -13977,11 +15090,11 @@
*
* For browsers that don't support the attribute.ownerElement property, this
* method cannot be called on attribute nodes.
- *
+ *
* Parameters:
* node - {DOMElement} The node from which to start looking.
* prefix - {String} The prefix to lookup or null to lookup the default namespace.
- *
+ *
* Returns:
* {String} The namespace URI for the given prefix. Returns null if the prefix
* cannot be found or the node is the wrong type.
@@ -14025,7 +15138,7 @@
case 10: // DOCUMENT_TYPE_NODE
case 11: // DOCUMENT_FRAGMENT_NODE
break outer;
- default:
+ default:
// TEXT_NODE (3), CDATA_SECTION_NODE (4), ENTITY_REFERENCE_NODE (5),
// PROCESSING_INSTRUCTION_NODE (7), COMMENT_NODE (8)
uri = this.lookupNamespaceURI(node.parentNode, prefix);
@@ -14035,11 +15148,11 @@
}
return uri;
},
+
+ CLASS_NAME: "OpenLayers.Format.XML"
- CLASS_NAME: "OpenLayers.Format.XML"
+});
-});
-
OpenLayers.Format.XML.CONTENT_TYPE = {EMPTY: 0, SIMPLE: 1, COMPLEX: 2, MIXED: 3};
/**
@@ -14054,11 +15167,11 @@
*
* For browsers that don't support the attribute.ownerElement property, this
* method cannot be called on attribute nodes.
- *
+ *
* Parameters:
* node - {DOMElement} The node from which to start looking.
* prefix - {String} The prefix to lookup or null to lookup the default namespace.
- *
+ *
* Returns:
* {String} The namespace URI for the given prefix. Returns null if the prefix
* cannot be found or the node is the wrong type.
@@ -14071,8 +15184,9 @@
OpenLayers/Handler.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -14094,7 +15208,7 @@
* correspond to these abstract events - so instead of listening for
* individual browser events, they only listen for the abstract events
* defined by the handler.
- *
+ *
* Handlers are created by controls, which ultimately have the responsibility
* of making changes to the the state of the application. Handlers
* themselves may make temporary changes, but in general are expected to
@@ -14107,7 +15221,7 @@
* {String}
*/
id: null,
-
+
/**
* APIProperty: control
* {<OpenLayers.Control>}. The control that initialized this handler. The
@@ -14146,7 +15260,7 @@
* {Boolean}
*/
active: false,
-
+
/**
* Property: evt
* {Event} This property references the last event handled by the handler.
@@ -14164,7 +15278,8 @@
* Parameters:
* control - {<OpenLayers.Control>} The control that initialized this
* handler. The control is assumed to have a valid map property; that
- * map is used in the handler's own setMap method.
+ * map is used in the handler's own setMap method. If a map property
+ * is present in the options argument it will be used instead.
* callbacks - {Object} An object whose properties correspond to abstracted
* events or sequences of browser events. The values for these
* properties are functions defined by the control that get called by
@@ -14176,15 +15291,15 @@
OpenLayers.Util.extend(this, options);
this.control = control;
this.callbacks = callbacks;
- if (control.map) {
- this.setMap(control.map);
+
+ var map = this.map || control.map;
+ if (map) {
+ this.setMap(map);
}
-
- OpenLayers.Util.extend(this, options);
-
+
this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
},
-
+
/**
* Method: setMap
*/
@@ -14210,7 +15325,7 @@
(evt.shiftKey ? OpenLayers.Handler.MOD_SHIFT : 0) |
(evt.ctrlKey ? OpenLayers.Handler.MOD_CTRL : 0) |
(evt.altKey ? OpenLayers.Handler.MOD_ALT : 0);
-
+
/* if it differs from the handler object's key mask,
bail out of the event handler */
return (keyModifiers == this.keyMask);
@@ -14219,8 +15334,8 @@
/**
* APIMethod: activate
* Turn on the handler. Returns false if the handler was already active.
- *
- * Returns:
+ *
+ * Returns:
* {Boolean} The handler was activated.
*/
activate: function() {
@@ -14231,17 +15346,17 @@
var events = OpenLayers.Events.prototype.BROWSER_EVENTS;
for (var i=0, len=events.length; i<len; i++) {
if (this[events[i]]) {
- this.register(events[i], this[events[i]]);
+ this.register(events[i], this[events[i]]);
}
- }
+ }
this.active = true;
return true;
},
-
+
/**
* APIMethod: deactivate
* Turn off the handler. Returns false if the handler was already inactive.
- *
+ *
* Returns:
* {Boolean} The handler was deactivated.
*/
@@ -14253,9 +15368,9 @@
var events = OpenLayers.Events.prototype.BROWSER_EVENTS;
for (var i=0, len=events.length; i<len; i++) {
if (this[events[i]]) {
- this.unregister(events[i], this[events[i]]);
+ this.unregister(events[i], this[events[i]]);
}
- }
+ }
this.active = false;
return true;
},
@@ -14267,7 +15382,7 @@
* Parameters:
* name - {String} The key for the callback that is one of the properties
* of the handler's callbacks object.
- * args - {Array(*)} An array of arguments (any type) with which to call
+ * args - {Array(*)} An array of arguments (any type) with which to call
* the callback (defined by the control).
*/
callback: function (name, args) {
@@ -14291,10 +15406,10 @@
* unregister an event from the map
*/
unregister: function (name, method) {
- this.map.events.unregister(name, this, method);
+ this.map.events.unregister(name, this, method);
this.map.events.unregister(name, this, this.setEvent);
},
-
+
/**
* Method: setEvent
* With each registered browser event, the handler sets its own evt
@@ -14325,7 +15440,7 @@
// unregister event listeners
this.deactivate();
// eliminate circular references
- this.control = this.map = null;
+ this.control = this.map = null;
},
CLASS_NAME: "OpenLayers.Handler"
@@ -14360,8 +15475,9 @@
OpenLayers/Map.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -14375,16 +15491,16 @@
* Class: OpenLayers.Map
* Instances of OpenLayers.Map are interactive maps embedded in a web page.
* Create a new map with the <OpenLayers.Map> constructor.
- *
+ *
* On their own maps do not provide much functionality. To extend a map
- * it's necessary to add controls (<OpenLayers.Control>) and
- * layers (<OpenLayers.Layer>) to the map.
+ * it's necessary to add controls (<OpenLayers.Control>) and
+ * layers (<OpenLayers.Layer>) to the map.
*/
OpenLayers.Map = OpenLayers.Class({
-
+
/**
* Constant: Z_INDEX_BASE
- * {Object} Base z-indexes for different classes of thing
+ * {Object} Base z-indexes for different classes of thing
*/
Z_INDEX_BASE: {
BaseLayer: 100,
@@ -14416,35 +15532,30 @@
*
* Supported map event types:
* - *preaddlayer* triggered before a layer has been added. The event
- * object will include a *layer* property that references the layer
+ * object will include a *layer* property that references the layer
* to be added.
* - *addlayer* triggered after a layer has been added. The event object
* will include a *layer* property that references the added layer.
* - *removelayer* triggered after a layer has been removed. The event
* object will include a *layer* property that references the removed
* layer.
- * - *changelayer* triggered after a layer name change, order change, or
- * visibility change (due to resolution thresholds). Listeners will
- * receive an event object with *layer* and *property* properties. The
- * *layer* property will be a reference to the changed layer. The
- * *property* property will be a key to the changed property (name,
- * visibility, or order).
+ * - *changelayer* triggered after a layer name change, order change,
+ * opacity change, params change or visibility change
+ * (due to resolution thresholds). Listeners will receive an event
+ * object with *layer* and *property* properties. The *layer*
+ * property will be a reference to the changed layer.
+ * The *property* property will be a key to the
+ * changed property (name, order, opacity, params or visibility).
* - *movestart* triggered after the start of a drag, pan, or zoom
* - *move* triggered after each drag, pan, or zoom
* - *moveend* triggered after a drag, pan, or zoom completes
* - *zoomend* triggered after a zoom completes
- * - *addmarker* triggered after a marker has been added
- * - *removemarker* triggered after a marker has been removed
- * - *clearmarkers* triggered after markers have been cleared
* - *mouseover* triggered after mouseover the map
* - *mouseout* triggered after mouseout the map
* - *mousemove* triggered after mousemove the map
- * - *dragstart* Does not work. Register for movestart instead.
- * - *drag* Does not work. Register for move instead.
- * - *dragend* Does not work. Register for moveend instead.
* - *changebaselayer* triggered after the base layer changes
*/
- EVENT_TYPES: [
+ EVENT_TYPES: [
"preaddlayer", "addlayer", "removelayer", "changelayer", "movestart",
"move", "moveend", "zoomend", "popupopen", "popupclose",
"addmarker", "removemarker", "clearmarkers", "mouseover",
@@ -14456,7 +15567,7 @@
* {String} Unique identifier for the map
*/
id: null,
-
+
/**
* Property: fractionalZoom
* {Boolean} For a base layer that supports it, allow the map resolution
@@ -14475,14 +15586,14 @@
* former works for non-integer zoom levels.
*/
fractionalZoom: false,
-
+
/**
* APIProperty: events
- * {<OpenLayers.Events>} An events object that handles all
+ * {<OpenLayers.Events>} An events object that handles all
* events on the map
*/
events: null,
-
+
/**
* APIProperty: allOverlays
* {Boolean} Allow the map to function with "overlays" only. Defaults to
@@ -14509,13 +15620,14 @@
* div property may or may not be provided. If the div property
* is not provided, the map can be rendered to a container later
* using the <render> method.
- *
- * Note: If you calling <render> after map construction, do not use
+ *
+ * Note:
+ * If you are calling <render> after map construction, do not use
* <maxResolution> auto. Instead, divide your <maxExtent> by your
* maximum expected dimension.
*/
div: null,
-
+
/**
* Property: dragging
* {Boolean} The map is currently being dragged.
@@ -14527,7 +15639,7 @@
* {<OpenLayers.Size>} Size of the main div (this.div)
*/
size: null,
-
+
/**
* Property: viewPortDiv
* {HTMLDivElement} The element that represents the map viewport
@@ -14578,7 +15690,7 @@
* min/max zoom level, projection, etc.
*/
baseLayer: null,
-
+
/**
* Property: center
* {<OpenLayers.LonLat>} The current center of the map
@@ -14595,25 +15707,25 @@
* Property: zoom
* {Integer} The current zoom level of the map
*/
- zoom: 0,
+ zoom: 0,
/**
* Property: panRatio
* {Float} The ratio of the current extent within
* which panning will tween.
*/
- panRatio: 1.5,
+ panRatio: 1.5,
/**
* Property: viewRequestID
- * {String} Used to store a unique identifier that changes when the map
- * view changes. viewRequestID should be used when adding data
- * asynchronously to the map: viewRequestID is incremented when
- * you initiate your request (right now during changing of
- * baselayers and changing of zooms). It is stored here in the
- * map and also in the data that will be coming back
- * asynchronously. Before displaying this data on request
- * completion, we check that the viewRequestID of the data is
+ * {String} Used to store a unique identifier that changes when the map
+ * view changes. viewRequestID should be used when adding data
+ * asynchronously to the map: viewRequestID is incremented when
+ * you initiate your request (right now during changing of
+ * baselayers and changing of zooms). It is stored here in the
+ * map and also in the data that will be coming back
+ * asynchronously. Before displaying this data on request
+ * completion, we check that the viewRequestID of the data is
* still the same as that of the map. Fix for #480
*/
viewRequestID: 0,
@@ -14629,12 +15741,12 @@
/**
* APIProperty: projection
- * {String} Set in the map options to override the default projection
- * string this map - also set maxExtent, maxResolution, and
+ * {String} Set in the map options to override the default projection
+ * string this map - also set maxExtent, maxResolution, and
* units if appropriate. Default is "EPSG:4326".
*/
- projection: "EPSG:4326",
-
+ projection: "EPSG:4326",
+
/**
* APIProperty: units
* {String} The map units. Defaults to 'degrees'. Possible values are
@@ -14644,9 +15756,9 @@
/**
* APIProperty: resolutions
- * {Array(Float)} A list of map resolutions (map units per pixel) in
- * descending order. If this is not set in the layer constructor, it
- * will be set based on other resolution related properties
+ * {Array(Float)} A list of map resolutions (map units per pixel) in
+ * descending order. If this is not set in the layer constructor, it
+ * will be set based on other resolution related properties
* (maxExtent, maxResolution, maxScale, etc.).
*/
resolutions: null,
@@ -14654,8 +15766,8 @@
/**
* APIProperty: maxResolution
* {Float} Default max is 360 deg / 256 px, which corresponds to
- * zoom level 0 on gmaps. Specify a different value in the map
- * options if you are not using a geographic projection and
+ * zoom level 0 on gmaps. Specify a different value in the map
+ * options if you are not using a geographic projection and
* displaying the whole world.
*/
maxResolution: 1.40625,
@@ -14681,20 +15793,20 @@
/**
* APIProperty: maxExtent
* {<OpenLayers.Bounds>} The maximum extent for the map. Defaults to the
- * whole world in decimal degrees
+ * whole world in decimal degrees
* (-180, -90, 180, 90). Specify a different
- * extent in the map options if you are not using a
- * geographic projection and displaying the whole
+ * extent in the map options if you are not using a
+ * geographic projection and displaying the whole
* world.
*/
maxExtent: null,
-
+
/**
* APIProperty: minExtent
* {<OpenLayers.Bounds>}
*/
minExtent: null,
-
+
/**
* APIProperty: restrictedExtent
* {<OpenLayers.Bounds>} Limit map navigation to this extent where possible.
@@ -14716,18 +15828,18 @@
/**
* APIProperty: theme
* {String} Relative path to a CSS file from which to load theme styles.
- * Specify null in the map options (e.g. {theme: null}) if you
- * want to get cascading style declarations - by putting links to
+ * Specify null in the map options (e.g. {theme: null}) if you
+ * want to get cascading style declarations - by putting links to
* stylesheets or style declarations directly in your page.
*/
theme: null,
-
- /**
+
+ /**
* APIProperty: displayProjection
* {<OpenLayers.Projection>} Requires proj4js support.Projection used by
* several controls to display data to user. If this property is set,
* it will be set on any control which has a null displayProjection
- * property at the time the control is added to the map.
+ * property at the time the control is added to the map.
*/
displayProjection: null,
@@ -14738,7 +15850,7 @@
* Default is to fall through.
*/
fallThrough: true,
-
+
/**
* Property: panTween
* {OpenLayers.Tween} Animated panning tween object, see panTo()
@@ -14761,7 +15873,7 @@
* animated panning.
*/
panMethod: OpenLayers.Easing.Expo.easeOut,
-
+
/**
* Property: panDuration
* {Integer} The number of steps to be passed to the
@@ -14770,23 +15882,23 @@
* Default is 50.
*/
panDuration: 50,
-
+
/**
* Property: paddingForPopups
- * {<OpenLayers.Bounds>} Outside margin of the popup. Used to prevent
+ * {<OpenLayers.Bounds>} Outside margin of the popup. Used to prevent
* the popup from getting too close to the map border.
*/
paddingForPopups : null,
-
+
/**
* Constructor: OpenLayers.Map
* Constructor for a new OpenLayers.Map instance. There are two possible
* ways to call the map constructor. See the examples below.
*
* Parameters:
- * div - {String} Id of an element in your page that will contain the map.
- * May be omitted if the <div> option is provided or if you intend
- * to use <render> later.
+ * div - {DOMElement|String} The element or id of an element in your page
+ * that will contain the map. May be omitted if the <div> option is
+ * provided or if you intend to call the <render> method later.
* options - {Object} Optional object with properties to tag onto the map.
*
* Examples (method one):
@@ -14822,30 +15934,33 @@
* units: 'm',
* projection: "EPSG:41001"
* });
- */
+ */
initialize: function (div, options) {
-
+
// If only one argument is provided, check if it is an object.
if(arguments.length === 1 && typeof div === "object") {
options = div;
div = options && options.div;
}
- // Simple-type defaults are set in class definition.
- // Now set complex-type defaults
+ // Simple-type defaults are set in class definition.
+ // Now set complex-type defaults
this.tileSize = new OpenLayers.Size(OpenLayers.Map.TILE_WIDTH,
OpenLayers.Map.TILE_HEIGHT);
-
+
this.maxExtent = new OpenLayers.Bounds(-180, -90, 180, 90);
-
+
this.paddingForPopups = new OpenLayers.Bounds(15, 15, 15, 15);
- this.theme = OpenLayers._getScriptLocation() +
- 'theme/default/style.css';
+ this.theme = OpenLayers._getScriptLocation() +
+ 'theme/default/style.css';
- // now override default options
+ // now override default options
OpenLayers.Util.extend(this, options);
+ // initialize layers array
+ this.layers = [];
+
this.id = OpenLayers.Util.createUniqueID("OpenLayers.Map_");
this.div = OpenLayers.Util.getElement(div);
@@ -14854,11 +15969,11 @@
this.div.style.height = "1px";
this.div.style.width = "1px";
}
-
+
OpenLayers.Element.addClass(this.div, 'olMap');
// the viewPortDiv is the outermost div we modify
- var id = this.div.id + "_OpenLayers_ViewPort";
+ var id = this.id + "_OpenLayers_ViewPort";
this.viewPortDiv = OpenLayers.Util.createDiv(id, null, null, null,
"relative", null,
"hidden");
@@ -14868,40 +15983,40 @@
this.div.appendChild(this.viewPortDiv);
// the layerContainerDiv is the one that holds all the layers
- id = this.div.id + "_OpenLayers_Container";
+ id = this.id + "_OpenLayers_Container";
this.layerContainerDiv = OpenLayers.Util.createDiv(id);
this.layerContainerDiv.style.zIndex=this.Z_INDEX_BASE['Popup']-1;
-
+
this.viewPortDiv.appendChild(this.layerContainerDiv);
- this.events = new OpenLayers.Events(this,
- this.div,
- this.EVENT_TYPES,
- this.fallThrough,
+ this.events = new OpenLayers.Events(this,
+ this.div,
+ this.EVENT_TYPES,
+ this.fallThrough,
{includeXY: true});
this.updateSize();
if(this.eventListeners instanceof Object) {
this.events.on(this.eventListeners);
}
-
+
// update the map size and location before the map moves
this.events.register("movestart", this, this.updateSize);
- // Because Mozilla does not support the "resize" event for elements
- // other than "window", we need to put a hack here.
+ // Because Mozilla does not support the "resize" event for elements
+ // other than "window", we need to put a hack here.
if (OpenLayers.String.contains(navigator.appName, "Microsoft")) {
// If IE, register the resize on the div
this.events.register("resize", this, this.updateSize);
} else {
// Else updateSize on catching the window's resize
- // Note that this is ok, as updateSize() does nothing if the
+ // Note that this is ok, as updateSize() does nothing if the
// map's size has not actually changed.
- this.updateSizeDestroy = OpenLayers.Function.bind(this.updateSize,
+ this.updateSizeDestroy = OpenLayers.Function.bind(this.updateSize,
this);
OpenLayers.Event.observe(window, 'resize',
this.updateSizeDestroy);
}
-
+
// only append link stylesheet if the theme property is set
if(this.theme) {
// check existing links for equivalent url
@@ -14924,9 +16039,7 @@
document.getElementsByTagName('head')[0].appendChild(cssNode);
}
}
-
- this.layers = [];
-
+
if (this.controls == null) {
if (OpenLayers.Control != null) { // running full or lite?
this.controls = [ new OpenLayers.Control.Navigation(),
@@ -14946,16 +16059,26 @@
this.popups = [];
this.unloadDestroy = OpenLayers.Function.bind(this.destroy, this);
+
-
// always call map.destroy()
OpenLayers.Event.observe(window, 'unload', this.unloadDestroy);
+
+ // add any initial layers
+ if (options && options.layers) {
+ this.addLayers(options.layers);
+ // set center (and optionally zoom)
+ if (options.center) {
+ // zoom can be undefined here
+ this.setCenter(options.center, options.zoom);
+ }
+ }
},
-
+
/**
* APIMethod: render
* Render the map to a specified container.
- *
+ *
* Parameters:
* div - {String|DOMElement} The container that the map should be rendered
* to. If different than the current container, the map viewport
@@ -14976,11 +16099,11 @@
* so that if map is manually destroyed, we can unregister this.
*/
unloadDestroy: null,
-
+
/**
* Method: updateSizeDestroy
* When the map is destroyed, we need to stop listening to updateSize
- * events: this method stores the function we need to unregister in
+ * events: this method stores the function we need to unregister in
* non-IE browsers.
*/
updateSizeDestroy: null,
@@ -14994,32 +16117,38 @@
if (!this.unloadDestroy) {
return false;
}
+
+ // make sure panning doesn't continue after destruction
+ if(this.panTween) {
+ this.panTween.stop();
+ this.panTween = null;
+ }
// map has been destroyed. dont do it again!
OpenLayers.Event.stopObserving(window, 'unload', this.unloadDestroy);
this.unloadDestroy = null;
if (this.updateSizeDestroy) {
- OpenLayers.Event.stopObserving(window, 'resize',
+ OpenLayers.Event.stopObserving(window, 'resize',
this.updateSizeDestroy);
} else {
this.events.unregister("resize", this, this.updateSize);
- }
+ }
+
+ this.paddingForPopups = null;
- this.paddingForPopups = null;
-
if (this.controls != null) {
for (var i = this.controls.length - 1; i>=0; --i) {
this.controls[i].destroy();
- }
+ }
this.controls = null;
}
if (this.layers != null) {
for (var i = this.layers.length - 1; i>=0; --i) {
- //pass 'false' to destroy so that map wont try to set a new
+ //pass 'false' to destroy so that map wont try to set a new
// baselayer after each baselayer is removed
this.layers[i].destroy(false);
- }
+ }
this.layers = null;
}
if (this.viewPortDiv) {
@@ -15194,7 +16323,7 @@
/* The following functions deal with adding and */
/* removing Layers to and from the Map */
/* */
- /********************************************************/
+ /********************************************************/
/**
* APIMethod: getLayer
@@ -15204,7 +16333,7 @@
* id - {String} A layer id
*
* Returns:
- * {<OpenLayers.Layer>} The Layer with the corresponding id from the map's
+ * {<OpenLayers.Layer>} The Layer with the corresponding id from the map's
* layer collection, or null if not found.
*/
getLayer: function(id) {
@@ -15221,11 +16350,11 @@
/**
* Method: setLayerZIndex
- *
+ *
* Parameters:
- * layer - {<OpenLayers.Layer>}
- * zIdx - {int}
- */
+ * layer - {<OpenLayers.Layer>}
+ * zIdx - {int}
+ */
setLayerZIndex: function (layer, zIdx) {
layer.setZIndex(
this.Z_INDEX_BASE[layer.isBaseLayer ? 'BaseLayer' : 'Overlay']
@@ -15247,12 +16376,12 @@
* APIMethod: addLayer
*
* Parameters:
- * layer - {<OpenLayers.Layer>}
- */
+ * layer - {<OpenLayers.Layer>}
+ */
addLayer: function (layer) {
for(var i=0, len=this.layers.length; i <len; i++) {
if (this.layers[i] == layer) {
- var msg = OpenLayers.i18n('layerAlreadyAdded',
+ var msg = OpenLayers.i18n('layerAlreadyAdded',
{'layerName':layer.name});
OpenLayers.Console.warn(msg);
return false;
@@ -15262,8 +16391,10 @@
layer.isBaseLayer = false;
}
- this.events.triggerEvent("preaddlayer", {layer: layer});
-
+ if (this.events.triggerEvent("preaddlayer", {layer: layer}) === false) {
+ return;
+ }
+
layer.div.className = "olLayerDiv";
layer.div.style.overflow = "";
this.setLayerZIndex(layer, this.layers.length);
@@ -15292,43 +16423,43 @@
},
/**
- * APIMethod: addLayers
+ * APIMethod: addLayers
*
* Parameters:
- * layers - {Array(<OpenLayers.Layer>)}
- */
+ * layers - {Array(<OpenLayers.Layer>)}
+ */
addLayers: function (layers) {
for (var i=0, len=layers.length; i<len; i++) {
this.addLayer(layers[i]);
}
},
- /**
+ /**
* APIMethod: removeLayer
- * Removes a layer from the map by removing its visual element (the
- * layer.div property), then removing it from the map's internal list
- * of layers, setting the layer's map property to null.
- *
+ * Removes a layer from the map by removing its visual element (the
+ * layer.div property), then removing it from the map's internal list
+ * of layers, setting the layer's map property to null.
+ *
* a "removelayer" event is triggered.
- *
+ *
* very worthy of mention is that simply removing a layer from a map
* will not cause the removal of any popups which may have been created
* by the layer. this is due to the fact that it was decided at some
- * point that popups would not belong to layers. thus there is no way
+ * point that popups would not belong to layers. thus there is no way
* for us to know here to which layer the popup belongs.
- *
+ *
* A simple solution to this is simply to call destroy() on the layer.
* the default OpenLayers.Layer class's destroy() function
* automatically takes care to remove itself from whatever map it has
- * been attached to.
- *
- * The correct solution is for the layer itself to register an
- * event-handler on "removelayer" and when it is called, if it
+ * been attached to.
+ *
+ * The correct solution is for the layer itself to register an
+ * event-handler on "removelayer" and when it is called, if it
* recognizes itself as the layer being removed, then it cycles through
* its own personal list of popups, removing them from the map.
- *
+ *
* Parameters:
- * layer - {<OpenLayers.Layer>}
+ * layer - {<OpenLayers.Layer>}
* setNewBaseLayer - {Boolean} Default is true
*/
removeLayer: function(layer, setNewBaseLayer) {
@@ -15366,7 +16497,7 @@
/**
* APIMethod: getNumLayers
- *
+ *
* Returns:
* {Int} The number of layers attached to the map.
*/
@@ -15374,7 +16505,7 @@
return this.layers.length;
},
- /**
+ /**
* APIMethod: getLayerIndex
*
* Parameters:
@@ -15387,8 +16518,8 @@
getLayerIndex: function (layer) {
return OpenLayers.Util.indexOf(this.layers, layer);
},
-
- /**
+
+ /**
* APIMethod: setLayerIndex
* Move the given layer to the specified (zero-based) index in the layer
* list, changing its z-index in the map display. Use
@@ -15397,8 +16528,8 @@
* raise base layers above overlays.
*
* Parameters:
- * layer - {<OpenLayers.Layer>}
- * idx - {int}
+ * layer - {<OpenLayers.Layer>}
+ * idx - {int}
*/
setLayerIndex: function (layer, idx) {
var base = this.getLayerIndex(layer);
@@ -15426,81 +16557,73 @@
}
},
- /**
+ /**
* APIMethod: raiseLayer
- * Change the index of the given layer by delta. If delta is positive,
+ * Change the index of the given layer by delta. If delta is positive,
* the layer is moved up the map's layer stack; if delta is negative,
* the layer is moved down. Again, note that this cannot (or at least
* should not) be effectively used to raise base layers above overlays.
*
* Paremeters:
- * layer - {<OpenLayers.Layer>}
- * delta - {int}
+ * layer - {<OpenLayers.Layer>}
+ * delta - {int}
*/
raiseLayer: function (layer, delta) {
var idx = this.getLayerIndex(layer) + delta;
this.setLayerIndex(layer, idx);
},
-
- /**
+
+ /**
* APIMethod: setBaseLayer
* Allows user to specify one of the currently-loaded layers as the Map's
* new base layer.
- *
+ *
* Parameters:
* newBaseLayer - {<OpenLayers.Layer>}
*/
setBaseLayer: function(newBaseLayer) {
- var oldExtent = null;
- if (this.baseLayer) {
- oldExtent = this.baseLayer.getExtent();
- }
-
+
if (newBaseLayer != this.baseLayer) {
-
- // is newBaseLayer an already loaded layer?m
+
+ // ensure newBaseLayer is already loaded
if (OpenLayers.Util.indexOf(this.layers, newBaseLayer) != -1) {
- // make the old base layer invisible
+ // preserve center and scale when changing base layers
+ var center = this.getCenter();
+ var newResolution = OpenLayers.Util.getResolutionFromScale(
+ this.getScale(), newBaseLayer.units
+ );
+
+ // make the old base layer invisible
if (this.baseLayer != null && !this.allOverlays) {
this.baseLayer.setVisibility(false);
}
// set new baselayer
this.baseLayer = newBaseLayer;
-
- // Increment viewRequestID since the baseLayer is
- // changing. This is used by tiles to check if they should
+
+ // Increment viewRequestID since the baseLayer is
+ // changing. This is used by tiles to check if they should
// draw themselves.
this.viewRequestID++;
- if(!this.allOverlays) {
- this.baseLayer.visibility = true;
+ if(!this.allOverlays || this.baseLayer.visibility) {
+ this.baseLayer.setVisibility(true);
}
- //redraw all layers
- var center = this.getCenter();
+ // recenter the map
if (center != null) {
-
- //either get the center from the old Extent or just from
- // the current center of the map.
- var newCenter = (oldExtent)
- ? oldExtent.getCenterLonLat()
- : center;
-
- //the new zoom will either come from the old Extent or
- // from the current resolution of the map
- var newZoom = (oldExtent)
- ? this.getZoomForExtent(oldExtent, true)
- : this.getZoomForResolution(this.resolution, true);
-
+ // new zoom level derived from old scale
+ var newZoom = this.getZoomForResolution(
+ newResolution || this.resolution, true
+ );
// zoom and force zoom change
- this.setCenter(newCenter, newZoom, false, true);
+ this.setCenter(center, newZoom, false, true);
}
this.events.triggerEvent("changebaselayer", {
layer: this.baseLayer
});
- }
+ }
}
},
@@ -15512,39 +16635,63 @@
/* The following functions deal with adding and */
/* removing Controls to and from the Map */
/* */
- /********************************************************/
+ /********************************************************/
/**
* APIMethod: addControl
- *
+ * Add the passed over control to the map. Optionally
+ * position the control at the given pixel.
+ *
* Parameters:
* control - {<OpenLayers.Control>}
* px - {<OpenLayers.Pixel>}
- */
+ */
addControl: function (control, px) {
this.controls.push(control);
this.addControlToMap(control, px);
},
+
+ /**
+ * APIMethod: addControls
+ * Add all of the passed over controls to the map.
+ * You can pass over an optional second array
+ * with pixel-objects to position the controls.
+ * The indices of the two arrays should match and
+ * you can add null as pixel for those controls
+ * you want to be autopositioned.
+ *
+ * Parameters:
+ * controls - {Array(<OpenLayers.Control>)}
+ * pixels - {Array(<OpenLayers.Pixel>)}
+ */
+ addControls: function (controls, pixels) {
+ var pxs = (arguments.length === 1) ? [] : pixels;
+ for (var i=0, len=controls.length; i<len; i++) {
+ var ctrl = controls[i];
+ var px = (pxs[i]) ? pxs[i] : null;
+ this.addControl( ctrl, px );
+ }
+ },
/**
* Method: addControlToMap
- *
+ *
* Parameters:
- *
+ *
* control - {<OpenLayers.Control>}
* px - {<OpenLayers.Pixel>}
- */
+ */
addControlToMap: function (control, px) {
// If a control doesn't have a div at this point, it belongs in the
// viewport.
control.outsideViewport = (control.div != null);
-
- // If the map has a displayProjection, and the control doesn't, set
+
+ // If the map has a displayProjection, and the control doesn't, set
// the display projection.
if (this.displayProjection && !control.displayProjection) {
control.displayProjection = this.displayProjection;
- }
-
+ }
+
control.setMap(this);
var div = control.draw(px);
if (div) {
@@ -15554,19 +16701,22 @@
this.viewPortDiv.appendChild( div );
}
}
+ if(control.autoActivate) {
+ control.activate();
+ }
},
-
+
/**
* APIMethod: getControl
- *
+ *
* Parameters:
* id - {String} ID of the control to return.
- *
+ *
* Returns:
- * {<OpenLayers.Control>} The control from the map's list of controls
- * which has a matching 'id'. If none found,
+ * {<OpenLayers.Control>} The control from the map's list of controls
+ * which has a matching 'id'. If none found,
* returns null.
- */
+ */
getControl: function (id) {
var returnControl = null;
for(var i=0, len=this.controls.length; i<len; i++) {
@@ -15578,16 +16728,16 @@
}
return returnControl;
},
-
- /**
+
+ /**
* APIMethod: removeControl
- * Remove a control from the map. Removes the control both from the map
- * object's internal array of controls, as well as from the map's
+ * Remove a control from the map. Removes the control both from the map
+ * object's internal array of controls, as well as from the map's
* viewPort (assuming the control was not added outsideViewport)
- *
+ *
* Parameters:
* control - {<OpenLayers.Control>} The control to remove.
- */
+ */
removeControl: function (control) {
//make sure control is non-null and actually part of our map
if ( (control) && (control == this.getControl(control.id)) ) {
@@ -15605,11 +16755,11 @@
/* The following functions deal with adding and */
/* removing Popups to and from the Map */
/* */
- /********************************************************/
+ /********************************************************/
- /**
+ /**
* APIMethod: addPopup
- *
+ *
* Parameters:
* popup - {<OpenLayers.Popup>}
* exclusive - {Boolean} If true, closes all other popups first
@@ -15632,10 +16782,10 @@
this.layerContainerDiv.appendChild(popupDiv);
}
},
-
- /**
+
+ /**
* APIMethod: removePopup
- *
+ *
* Parameters:
* popup - {<OpenLayers.Popup>}
*/
@@ -15656,15 +16806,15 @@
/* The following functions deal with the access to */
/* and maintenance of the size of the container div */
/* */
- /********************************************************/
+ /********************************************************/
/**
* APIMethod: getSize
- *
+ *
* Returns:
- * {<OpenLayers.Size>} An <OpenLayers.Size> object that represents the
- * size, in pixels, of the div into which OpenLayers
- * has been loaded.
+ * {<OpenLayers.Size>} An <OpenLayers.Size> object that represents the
+ * size, in pixels, of the div into which OpenLayers
+ * has been loaded.
* Note - A clone() of this locally cached variable is
* returned, so as not to allow users to modify it.
*/
@@ -15679,55 +16829,55 @@
/**
* APIMethod: updateSize
* This function should be called by any external code which dynamically
- * changes the size of the map div (because mozilla wont let us catch
+ * changes the size of the map div (because mozilla wont let us catch
* the "onresize" for an element)
*/
updateSize: function() {
// the div might have moved on the page, also
- this.events.clearMouseCache();
var newSize = this.getCurrentSize();
- var oldSize = this.getSize();
- if (oldSize == null) {
- this.size = oldSize = newSize;
- }
- if (!newSize.equals(oldSize)) {
-
- // store the new size
- this.size = newSize;
-
- //notify layers of mapresize
- for(var i=0, len=this.layers.length; i<len; i++) {
- this.layers[i].onMapResize();
+ if (newSize && !isNaN(newSize.h) && !isNaN(newSize.w)) {
+ this.events.clearMouseCache();
+ var oldSize = this.getSize();
+ if (oldSize == null) {
+ this.size = oldSize = newSize;
}
-
- if (this.baseLayer != null) {
- var center = new OpenLayers.Pixel(newSize.w /2, newSize.h / 2);
- var centerLL = this.getLonLatFromViewPortPx(center);
- var zoom = this.getZoom();
- this.zoom = null;
- this.setCenter(this.getCenter(), zoom);
+ if (!newSize.equals(oldSize)) {
+
+ // store the new size
+ this.size = newSize;
+
+ //notify layers of mapresize
+ for(var i=0, len=this.layers.length; i<len; i++) {
+ this.layers[i].onMapResize();
+ }
+
+ var center = this.getCenter();
+
+ if (this.baseLayer != null && center != null) {
+ var zoom = this.getZoom();
+ this.zoom = null;
+ this.setCenter(center, zoom);
+ }
+
}
-
}
},
-
+
/**
* Method: getCurrentSize
- *
+ *
* Returns:
- * {<OpenLayers.Size>} A new <OpenLayers.Size> object with the dimensions
+ * {<OpenLayers.Size>} A new <OpenLayers.Size> object with the dimensions
* of the map div
*/
getCurrentSize: function() {
- var size = new OpenLayers.Size(this.div.clientWidth,
+ var size = new OpenLayers.Size(this.div.clientWidth,
this.div.clientHeight);
- // Workaround for the fact that hidden elements return 0 for size.
if (size.w == 0 && size.h == 0 || isNaN(size.w) && isNaN(size.h)) {
- var dim = OpenLayers.Element.getDimensions(this.div);
- size.w = dim.width;
- size.h = dim.height;
+ size.w = this.div.offsetWidth;
+ size.h = this.div.offsetHeight;
}
if (size.w == 0 && size.h == 0 || isNaN(size.w) && isNaN(size.h)) {
size.w = parseInt(this.div.style.width);
@@ -15736,39 +16886,39 @@
return size;
},
- /**
+ /**
* Method: calculateBounds
- *
+ *
* Parameters:
* center - {<OpenLayers.LonLat>} Default is this.getCenter()
- * resolution - {float} Default is this.getResolution()
- *
+ * resolution - {float} Default is this.getResolution()
+ *
* Returns:
- * {<OpenLayers.Bounds>} A bounds based on resolution, center, and
+ * {<OpenLayers.Bounds>} A bounds based on resolution, center, and
* current mapsize.
*/
calculateBounds: function(center, resolution) {
var extent = null;
-
+
if (center == null) {
center = this.getCenter();
- }
+ }
if (resolution == null) {
resolution = this.getResolution();
}
-
+
if ((center != null) && (resolution != null)) {
var size = this.getSize();
var w_deg = size.w * resolution;
var h_deg = size.h * resolution;
-
+
extent = new OpenLayers.Bounds(center.lon - w_deg / 2,
center.lat - h_deg / 2,
center.lon + w_deg / 2,
center.lat + h_deg / 2);
-
+
}
return extent;
@@ -15786,7 +16936,7 @@
/********************************************************/
/**
* APIMethod: getCenter
- *
+ *
* Returns:
* {<OpenLayers.LonLat>}
*/
@@ -15801,18 +16951,18 @@
/**
* APIMethod: getZoom
- *
+ *
* Returns:
* {Integer}
*/
getZoom: function () {
return this.zoom;
},
-
- /**
+
+ /**
* APIMethod: pan
* Allows user to pan by a value of screen pixels
- *
+ *
* Parameters:
* dx - {Integer}
* dy - {Integer}
@@ -15831,7 +16981,7 @@
// adjust
var newCenterPx = centerPx.add(dx, dy);
-
+
// only call setCenter if not dragging or there has been a change
if (!options.dragging || !newCenterPx.equals(centerPx)) {
var newCenterLonLat = this.getLonLatFromViewPortPx(newCenterPx);
@@ -15839,16 +16989,16 @@
this.panTo(newCenterLonLat);
} else {
this.setCenter(newCenterLonLat, null, options.dragging);
- }
+ }
}
},
-
- /**
+
+ /**
* APIMethod: panTo
* Allows user to pan to a new lonlat
* If the new lonlat is in the current extent the map will slide smoothly
- *
+ *
* Parameters:
* lonlat - {<OpenLayers.Lonlat>}
*/
@@ -15902,13 +17052,13 @@
/**
* APIMethod: setCenter
* Set the map center (and optionally, the zoom level).
- *
+ *
* Parameters:
* lonlat - {<OpenLayers.LonLat>} The new center location.
* zoom - {Integer} Optional zoom level.
- * dragging - {Boolean} Specifies whether or not to trigger
+ * dragging - {Boolean} Specifies whether or not to trigger
* movestart/end events
- * forceZoomChange - {Boolean} Specifies whether or not to trigger zoom
+ * forceZoomChange - {Boolean} Specifies whether or not to trigger zoom
* change events (needed on baseLayer change)
*
* TBD: reconsider forceZoomChange in 3.0
@@ -15930,9 +17080,15 @@
* options - {Object}
*/
moveTo: function(lonlat, zoom, options) {
- if (!options) {
+ if (!options) {
options = {};
}
+ if (zoom != null) {
+ zoom = parseFloat(zoom);
+ if (!this.fractionalZoom) {
+ zoom = Math.round(zoom);
+ }
+ }
// dragging is false by default
var dragging = options.dragging;
// forceZoomChange is false by default
@@ -15942,51 +17098,51 @@
if (this.panTween && options.caller == "setCenter") {
this.panTween.stop();
- }
-
+ }
+
if (!this.center && !this.isValidLonLat(lonlat)) {
lonlat = this.maxExtent.getCenterLonLat();
}
if(this.restrictedExtent != null) {
// In 3.0, decide if we want to change interpretation of maxExtent.
- if(lonlat == null) {
- lonlat = this.getCenter();
+ if(lonlat == null) {
+ lonlat = this.getCenter();
}
- if(zoom == null) {
- zoom = this.getZoom();
+ if(zoom == null) {
+ zoom = this.getZoom();
}
var resolution = this.getResolutionForZoom(zoom);
- var extent = this.calculateBounds(lonlat, resolution);
+ var extent = this.calculateBounds(lonlat, resolution);
if(!this.restrictedExtent.containsBounds(extent)) {
- var maxCenter = this.restrictedExtent.getCenterLonLat();
- if(extent.getWidth() > this.restrictedExtent.getWidth()) {
- lonlat = new OpenLayers.LonLat(maxCenter.lon, lonlat.lat);
+ var maxCenter = this.restrictedExtent.getCenterLonLat();
+ if(extent.getWidth() > this.restrictedExtent.getWidth()) {
+ lonlat = new OpenLayers.LonLat(maxCenter.lon, lonlat.lat);
} else if(extent.left < this.restrictedExtent.left) {
lonlat = lonlat.add(this.restrictedExtent.left -
- extent.left, 0);
- } else if(extent.right > this.restrictedExtent.right) {
+ extent.left, 0);
+ } else if(extent.right > this.restrictedExtent.right) {
lonlat = lonlat.add(this.restrictedExtent.right -
- extent.right, 0);
- }
- if(extent.getHeight() > this.restrictedExtent.getHeight()) {
- lonlat = new OpenLayers.LonLat(lonlat.lon, maxCenter.lat);
- } else if(extent.bottom < this.restrictedExtent.bottom) {
+ extent.right, 0);
+ }
+ if(extent.getHeight() > this.restrictedExtent.getHeight()) {
+ lonlat = new OpenLayers.LonLat(lonlat.lon, maxCenter.lat);
+ } else if(extent.bottom < this.restrictedExtent.bottom) {
lonlat = lonlat.add(0, this.restrictedExtent.bottom -
- extent.bottom);
- }
- else if(extent.top > this.restrictedExtent.top) {
+ extent.bottom);
+ }
+ else if(extent.top > this.restrictedExtent.top) {
lonlat = lonlat.add(0, this.restrictedExtent.top -
- extent.top);
- }
+ extent.top);
+ }
}
}
-
+
var zoomChanged = forceZoomChange || (
- (this.isValidZoomLevel(zoom)) &&
+ (this.isValidZoomLevel(zoom)) &&
(zoom != this.getZoom()) );
- var centerChanged = (this.isValidLonLat(lonlat)) &&
+ var centerChanged = (this.isValidLonLat(lonlat)) &&
(!lonlat.equals(this.center));
@@ -15998,7 +17154,7 @@
}
if (centerChanged) {
- if ((!zoomChanged) && (this.center)) {
+ if ((!zoomChanged) && (this.center)) {
// if zoom hasnt changed, just slide layerContainer
// (must be done before setting this.center to new value)
this.centerLayerContainer(lonlat);
@@ -16018,12 +17174,12 @@
this.resolution = this.getResolutionForZoom(zoom);
// zoom level has changed, increment viewRequestID.
this.viewRequestID++;
- }
-
+ }
+
var bounds = this.getExtent();
+
+ //send the move call to the baselayer and all the overlays
- //send the move call to the baselayer and all the overlays
-
if(this.baseLayer.visibility) {
this.baseLayer.moveTo(bounds, zoomChanged, dragging);
if(dragging) {
@@ -16034,9 +17190,9 @@
);
}
}
-
+
bounds = this.baseLayer.getExtent();
-
+
for (var i=0, len=this.layers.length; i<len; i++) {
var layer = this.layers[i];
if (layer !== this.baseLayer && !layer.isBaseLayer) {
@@ -16064,18 +17220,18 @@
);
}
}
- }
+ }
}
-
+
if (zoomChanged) {
//redraw popups
for (var i=0, len=this.popups.length; i<len; i++) {
this.popups[i].updatePosition();
}
- }
-
+ }
+
this.events.triggerEvent("move");
-
+
if (zoomChanged) { this.events.triggerEvent("zoomend"); }
}
@@ -16083,16 +17239,16 @@
if (!dragging && !noEvent) {
this.events.triggerEvent("moveend");
}
-
+
// Store the map dragging state for later use
- this.dragging = !!dragging;
+ this.dragging = !!dragging;
},
- /**
+ /**
* Method: centerLayerContainer
* This function takes care to recenter the layerContainerDiv.
- *
+ *
* Parameters:
* lonlat - {<OpenLayers.LonLat>}
*/
@@ -16109,26 +17265,26 @@
/**
* Method: isValidZoomLevel
- *
+ *
* Parameters:
* zoomLevel - {Integer}
- *
+ *
* Returns:
- * {Boolean} Whether or not the zoom level passed in is non-null and
+ * {Boolean} Whether or not the zoom level passed in is non-null and
* within the min/max range of zoom levels.
*/
isValidZoomLevel: function(zoomLevel) {
return ( (zoomLevel != null) &&
- (zoomLevel >= 0) &&
+ (zoomLevel >= 0) &&
(zoomLevel < this.getNumZoomLevels()) );
},
-
+
/**
* Method: isValidLonLat
- *
+ *
* Parameters:
* lonlat - {<OpenLayers.LonLat>}
- *
+ *
* Returns:
* {Boolean} Whether or not the lonlat passed in is non-null and within
* the maxExtent bounds
@@ -16137,7 +17293,7 @@
var valid = false;
if (lonlat != null) {
var maxExtent = this.getMaxExtent();
- valid = maxExtent.containsLonLat(lonlat);
+ valid = maxExtent.containsLonLat(lonlat);
}
return valid;
},
@@ -16149,25 +17305,25 @@
/* Accessor functions to Layer Options parameters */
/* */
/********************************************************/
-
+
/**
* APIMethod: getProjection
- * This method returns a string representing the projection. In
+ * This method returns a string representing the projection. In
* the case of projection support, this will be the srsCode which
* is loaded -- otherwise it will simply be the string value that
* was passed to the projection at startup.
*
* FIXME: In 3.0, we will remove getProjectionObject, and instead
- * return a Projection object from this function.
- *
+ * return a Projection object from this function.
+ *
* Returns:
- * {String} The Projection string from the base layer or null.
+ * {String} The Projection string from the base layer or null.
*/
getProjection: function() {
var projection = this.getProjectionObject();
return projection ? projection.getCode() : null;
},
-
+
/**
* APIMethod: getProjectionObject
* Returns the projection obect from the baselayer.
@@ -16182,10 +17338,10 @@
}
return projection;
},
-
+
/**
* APIMethod: getMaxResolution
- *
+ *
* Returns:
* {String} The Map's Maximum Resolution
*/
@@ -16196,19 +17352,19 @@
}
return maxResolution;
},
-
+
/**
* APIMethod: getMaxExtent
*
* Parameters:
- * options - {Object}
- *
+ * options - {Object}
+ *
* Allowed Options:
- * restricted - {Boolean} If true, returns restricted extent (if it is
+ * restricted - {Boolean} If true, returns restricted extent (if it is
* available.)
*
* Returns:
- * {<OpenLayers.Bounds>} The maxExtent property as set on the current
+ * {<OpenLayers.Bounds>} The maxExtent property as set on the current
* baselayer, unless the 'restricted' option is set, in which case
* the 'restrictedExtent' option from the map is returned (if it
* is set).
@@ -16219,15 +17375,15 @@
maxExtent = this.restrictedExtent;
} else if (this.baseLayer != null) {
maxExtent = this.baseLayer.maxExtent;
- }
+ }
return maxExtent;
},
-
+
/**
* APIMethod: getNumZoomLevels
- *
+ *
* Returns:
- * {Integer} The total number of zoom levels that can be displayed by the
+ * {Integer} The total number of zoom levels that can be displayed by the
* current baseLayer.
*/
getNumZoomLevels: function() {
@@ -16251,10 +17407,10 @@
/**
* APIMethod: getExtent
- *
+ *
* Returns:
- * {<OpenLayers.Bounds>} A Bounds object which represents the lon/lat
- * bounds of the current viewPort.
+ * {<OpenLayers.Bounds>} A Bounds object which represents the lon/lat
+ * bounds of the current viewPort.
* If no baselayer is set, returns null.
*/
getExtent: function () {
@@ -16267,24 +17423,29 @@
/**
* APIMethod: getResolution
- *
+ *
* Returns:
- * {Float} The current resolution of the map.
+ * {Float} The current resolution of the map.
* If no baselayer is set, returns null.
*/
getResolution: function () {
var resolution = null;
if (this.baseLayer != null) {
resolution = this.baseLayer.getResolution();
+ } else if(this.allOverlays === true && this.layers.length > 0) {
+ // while adding the 1st layer to the map in allOverlays mode,
+ // this.baseLayer is not set yet when we need the resolution
+ // for calculateInRange.
+ resolution = this.layers[0].getResolution();
}
return resolution;
},
/**
* APIMethod: getUnits
- *
+ *
* Returns:
- * {Float} The current units of the map.
+ * {Float} The current units of the map.
* If no baselayer is set, returns null.
*/
getUnits: function () {
@@ -16297,9 +17458,9 @@
/**
* APIMethod: getScale
- *
+ *
* Returns:
- * {Float} The current scale denominator of the map.
+ * {Float} The current scale denominator of the map.
* If no baselayer is set, returns null.
*/
getScale: function () {
@@ -16315,14 +17476,14 @@
/**
* APIMethod: getZoomForExtent
- *
- * Parameters:
+ *
+ * Parameters:
* bounds - {<OpenLayers.Bounds>}
- * closest - {Boolean} Find the zoom level that most closely fits the
- * specified bounds. Note that this may result in a zoom that does
+ * closest - {Boolean} Find the zoom level that most closely fits the
+ * specified bounds. Note that this may result in a zoom that does
* not exactly contain the entire extent.
* Default is false.
- *
+ *
* Returns:
* {Integer} A suitable zoom level for the specified bounds.
* If no baselayer is set, returns null.
@@ -16337,10 +17498,10 @@
/**
* APIMethod: getResolutionForZoom
- *
+ *
* Parameter:
* zoom - {Float}
- *
+ *
* Returns:
* {Float} A suitable resolution for the specified zoom. If no baselayer
* is set, returns null.
@@ -16355,17 +17516,17 @@
/**
* APIMethod: getZoomForResolution
- *
+ *
* Parameter:
* resolution - {Float}
- * closest - {Boolean} Find the zoom level that corresponds to the absolute
+ * closest - {Boolean} Find the zoom level that corresponds to the absolute
* closest resolution, which may result in a zoom whose corresponding
* resolution is actually smaller than we would have desired (if this
* is being called from a getZoomForExtent() call, then this means that
- * the returned zoom index might not actually contain the entire
+ * the returned zoom index might not actually contain the entire
* extent specified... but it'll be close).
* Default is false.
- *
+ *
* Returns:
* {Integer} A suitable zoom level for the specified resolution.
* If no baselayer is set, returns null.
@@ -16387,11 +17548,11 @@
/* the setCenter() function */
/* */
/********************************************************/
-
- /**
+
+ /**
* APIMethod: zoomTo
* Zoom to a specific zoom level
- *
+ *
* Parameters:
* zoom - {Integer}
*/
@@ -16400,20 +17561,20 @@
this.setCenter(null, zoom);
}
},
-
+
/**
* APIMethod: zoomIn
- *
+ *
* Parameters:
* zoom - {int}
*/
zoomIn: function() {
this.zoomTo(this.getZoom() + 1);
},
-
+
/**
* APIMethod: zoomOut
- *
+ *
* Parameters:
* zoom - {int}
*/
@@ -16424,35 +17585,35 @@
/**
* APIMethod: zoomToExtent
* Zoom to the passed in bounds, recenter
- *
+ *
* Parameters:
* bounds - {<OpenLayers.Bounds>}
- * closest - {Boolean} Find the zoom level that most closely fits the
- * specified bounds. Note that this may result in a zoom that does
+ * closest - {Boolean} Find the zoom level that most closely fits the
+ * specified bounds. Note that this may result in a zoom that does
* not exactly contain the entire extent.
* Default is false.
- *
+ *
*/
zoomToExtent: function(bounds, closest) {
var center = bounds.getCenterLonLat();
if (this.baseLayer.wrapDateLine) {
var maxExtent = this.getMaxExtent();
- //fix straddling bounds (in the case of a bbox that straddles the
- // dateline, it's left and right boundaries will appear backwards.
+ //fix straddling bounds (in the case of a bbox that straddles the
+ // dateline, it's left and right boundaries will appear backwards.
// we fix this by allowing a right value that is greater than the
- // max value at the dateline -- this allows us to pass a valid
+ // max value at the dateline -- this allows us to pass a valid
// bounds to calculate zoom)
//
bounds = bounds.clone();
while (bounds.right < bounds.left) {
bounds.right += maxExtent.getWidth();
}
- //if the bounds was straddling (see above), then the center point
+ //if the bounds was straddling (see above), then the center point
// we got from it was wrong. So we take our new bounds and ask it
- // for the center. Because our new bounds is at least partially
- // outside the bounds of maxExtent, the new calculated center
- // might also be. We don't want to pass a bad center value to
+ // for the center. Because our new bounds is at least partially
+ // outside the bounds of maxExtent, the new calculated center
+ // might also be. We don't want to pass a bad center value to
// setCenter, so we have it wrap itself across the date line.
//
center = bounds.getCenterLonLat().wrapDateLine(maxExtent);
@@ -16460,15 +17621,15 @@
this.setCenter(center, this.getZoomForExtent(bounds, closest));
},
- /**
+ /**
* APIMethod: zoomToMaxExtent
* Zoom to the full extent and recenter.
*
* Parameters:
- * options -
- *
+ * options -
+ *
* Allowed Options:
- * restricted - {Boolean} True to zoom to restricted extent if it is
+ * restricted - {Boolean} True to zoom to restricted extent if it is
* set. Defaults to true.
*/
zoomToMaxExtent: function(options) {
@@ -16476,25 +17637,25 @@
var restricted = (options) ? options.restricted : true;
var maxExtent = this.getMaxExtent({
- 'restricted': restricted
+ 'restricted': restricted
});
this.zoomToExtent(maxExtent);
},
- /**
+ /**
* APIMethod: zoomToScale
- * Zoom to a specified scale
- *
+ * Zoom to a specified scale
+ *
* Parameters:
* scale - {float}
- * closest - {Boolean} Find the zoom level that most closely fits the
- * specified scale. Note that this may result in a zoom that does
+ * closest - {Boolean} Find the zoom level that most closely fits the
+ * specified scale. Note that this may result in a zoom that does
* not exactly contain the entire extent.
* Default is false.
- *
+ *
*/
zoomToScale: function(scale, closest) {
- var res = OpenLayers.Util.getResolutionFromScale(scale,
+ var res = OpenLayers.Util.getResolutionFromScale(scale,
this.baseLayer.units);
var size = this.getSize();
var w_deg = size.w * res;
@@ -16507,7 +17668,7 @@
center.lat + h_deg / 2);
this.zoomToExtent(extent, closest);
},
-
+
/********************************************************/
/* */
/* Translation Functions */
@@ -16516,24 +17677,24 @@
/* LonLat, LayerPx, and ViewPortPx */
/* */
/********************************************************/
-
+
//
// TRANSLATION: LonLat <-> ViewPortPx
//
/**
* Method: getLonLatFromViewPortPx
- *
+ *
* Parameters:
* viewPortPx - {<OpenLayers.Pixel>}
- *
+ *
* Returns:
- * {<OpenLayers.LonLat>} An OpenLayers.LonLat which is the passed-in view
+ * {<OpenLayers.LonLat>} An OpenLayers.LonLat which is the passed-in view
* port <OpenLayers.Pixel>, translated into lon/lat
* by the current base layer.
*/
getLonLatFromViewPortPx: function (viewPortPx) {
- var lonlat = null;
+ var lonlat = null;
if (this.baseLayer != null) {
lonlat = this.baseLayer.getLonLatFromViewPortPx(viewPortPx);
}
@@ -16542,37 +17703,37 @@
/**
* APIMethod: getViewPortPxFromLonLat
- *
+ *
* Parameters:
* lonlat - {<OpenLayers.LonLat>}
- *
+ *
* Returns:
- * {<OpenLayers.Pixel>} An OpenLayers.Pixel which is the passed-in
- * <OpenLayers.LonLat>, translated into view port
+ * {<OpenLayers.Pixel>} An OpenLayers.Pixel which is the passed-in
+ * <OpenLayers.LonLat>, translated into view port
* pixels by the current base layer.
*/
getViewPortPxFromLonLat: function (lonlat) {
- var px = null;
+ var px = null;
if (this.baseLayer != null) {
px = this.baseLayer.getViewPortPxFromLonLat(lonlat);
}
return px;
},
-
+
//
// CONVENIENCE TRANSLATION FUNCTIONS FOR API
//
/**
* APIMethod: getLonLatFromPixel
- *
+ *
* Parameters:
* px - {<OpenLayers.Pixel>}
*
* Returns:
* {<OpenLayers.LonLat>} An OpenLayers.LonLat corresponding to the given
- * OpenLayers.Pixel, translated into lon/lat by the
+ * OpenLayers.Pixel, translated into lon/lat by the
* current base layer
*/
getLonLatFromPixel: function (px) {
@@ -16584,12 +17745,12 @@
* Returns a pixel location given a map location. The map location is
* translated to an integer pixel location (in viewport pixel
* coordinates) by the current base layer.
- *
+ *
* Parameters:
* lonlat - {<OpenLayers.LonLat>} A map location.
- *
- * Returns:
- * {<OpenLayers.Pixel>} An OpenLayers.Pixel corresponding to the
+ *
+ * Returns:
+ * {<OpenLayers.Pixel>} An OpenLayers.Pixel corresponding to the
* <OpenLayers.LonLat> translated into view port pixels by the current
* base layer.
*/
@@ -16599,6 +17760,39 @@
px.y = Math.round(px.y);
return px;
},
+
+ /**
+ * Method: getGeodesicPixelSize
+ *
+ * Parameters:
+ * px - {<OpenLayers.Pixel>} The pixel to get the geodesic length for. If
+ * not provided, the center pixel of the map viewport will be used.
+ *
+ * Returns:
+ * {<OpenLayers.Size>} The geodesic size of the pixel in kilometers.
+ */
+ getGeodesicPixelSize: function(px) {
+ var lonlat = px ? this.getLonLatFromPixel(px) : (this.getCenter() ||
+ new OpenLayers.LonLat(0, 0));
+ var res = this.getResolution();
+ var left = lonlat.add(-res / 2, 0);
+ var right = lonlat.add(res / 2, 0);
+ var bottom = lonlat.add(0, -res / 2);
+ var top = lonlat.add(0, res / 2);
+ var dest = new OpenLayers.Projection("EPSG:4326");
+ var source = this.getProjectionObject() || dest;
+ if(!source.equals(dest)) {
+ left.transform(source, dest);
+ right.transform(source, dest);
+ bottom.transform(source, dest);
+ top.transform(source, dest);
+ }
+
+ return new OpenLayers.Size(
+ OpenLayers.Util.distVincenty(left, right),
+ OpenLayers.Util.distVincenty(bottom, top)
+ );
+ },
@@ -16608,12 +17802,12 @@
/**
* APIMethod: getViewPortPxFromLayerPx
- *
+ *
* Parameters:
* layerPx - {<OpenLayers.Pixel>}
- *
+ *
* Returns:
- * {<OpenLayers.Pixel>} Layer Pixel translated into ViewPort Pixel
+ * {<OpenLayers.Pixel>} Layer Pixel translated into ViewPort Pixel
* coordinates
*/
getViewPortPxFromLayerPx:function(layerPx) {
@@ -16621,19 +17815,19 @@
if (layerPx != null) {
var dX = parseInt(this.layerContainerDiv.style.left);
var dY = parseInt(this.layerContainerDiv.style.top);
- viewPortPx = layerPx.add(dX, dY);
+ viewPortPx = layerPx.add(dX, dY);
}
return viewPortPx;
},
-
+
/**
* APIMethod: getLayerPxFromViewPortPx
- *
+ *
* Parameters:
* viewPortPx - {<OpenLayers.Pixel>}
- *
+ *
* Returns:
- * {<OpenLayers.Pixel>} ViewPort Pixel translated into Layer Pixel
+ * {<OpenLayers.Pixel>} ViewPort Pixel translated into Layer Pixel
* coordinates
*/
getLayerPxFromViewPortPx:function(viewPortPx) {
@@ -16648,14 +17842,14 @@
}
return layerPx;
},
-
+
//
// TRANSLATION: LonLat <-> LayerPx
//
/**
* Method: getLonLatFromLayerPx
- *
+ *
* Parameters:
* px - {<OpenLayers.Pixel>}
*
@@ -16665,24 +17859,24 @@
getLonLatFromLayerPx: function (px) {
//adjust for displacement of layerContainerDiv
px = this.getViewPortPxFromLayerPx(px);
- return this.getLonLatFromViewPortPx(px);
+ return this.getLonLatFromViewPortPx(px);
},
-
+
/**
* APIMethod: getLayerPxFromLonLat
- *
+ *
* Parameters:
* lonlat - {<OpenLayers.LonLat>} lonlat
*
* Returns:
- * {<OpenLayers.Pixel>} An OpenLayers.Pixel which is the passed-in
- * <OpenLayers.LonLat>, translated into layer pixels
+ * {<OpenLayers.Pixel>} An OpenLayers.Pixel which is the passed-in
+ * <OpenLayers.LonLat>, translated into layer pixels
* by the current base layer
*/
getLayerPxFromLonLat: function (lonlat) {
//adjust for displacement of layerContainerDiv
var px = this.getPixelFromLonLat(lonlat);
- return this.getLayerPxFromViewPortPx(px);
+ return this.getLayerPxFromViewPortPx(px);
},
CLASS_NAME: "OpenLayers.Map"
@@ -16702,8 +17896,9 @@
OpenLayers/Marker.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
@@ -16714,8 +17909,8 @@
/**
* Class: OpenLayers.Marker
- * Instances of OpenLayers.Marker are a combination of a
- * <OpenLayers.LonLat> and an <OpenLayers.Icon>.
+ * Instances of OpenLayers.Marker are a combination of a
+ * <OpenLayers.LonLat> and an <OpenLayers.Icon>.
*
* Markers are generally added to a special layer called
* <OpenLayers.Layer.Markers>.
@@ -16725,9 +17920,9 @@
* var markers = new OpenLayers.Layer.Markers( "Markers" );
* map.addLayer(markers);
*
- * var size = new OpenLayers.Size(10,17);
+ * var size = new OpenLayers.Size(21,25);
* var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);
- * var icon = new OpenLayers.Icon('http://boston.openguides.org/markers/AQUA.png',size,offset);
+ * var icon = new OpenLayers.Icon('http://www.openlayers.org/dev/img/marker.png', size, offset);
* markers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(0,0),icon));
* markers.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(0,0),icon.clone()));
*
@@ -16739,32 +17934,32 @@
* markers using that same icon.
*/
OpenLayers.Marker = OpenLayers.Class({
-
- /**
- * Property: icon
+
+ /**
+ * Property: icon
* {<OpenLayers.Icon>} The icon used by this marker.
*/
icon: null,
- /**
- * Property: lonlat
+ /**
+ * Property: lonlat
* {<OpenLayers.LonLat>} location of object
*/
lonlat: null,
-
- /**
- * Property: events
+
+ /**
+ * Property: events
* {<OpenLayers.Events>} the event handler.
*/
events: null,
-
- /**
- * Property: map
+
+ /**
+ * Property: map
* {<OpenLayers.Map>} the map this marker is attached to
*/
map: null,
-
- /**
+
+ /**
* Constructor: OpenLayers.Marker
* Parameters:
* lonlat - {<OpenLayers.LonLat>} the position of this marker
@@ -16772,7 +17967,7 @@
*/
initialize: function(lonlat, icon) {
this.lonlat = lonlat;
-
+
var newIcon = (icon) ? icon : OpenLayers.Marker.defaultIcon();
if (this.icon == null) {
this.icon = newIcon;
@@ -16784,10 +17979,10 @@
}
this.events = new OpenLayers.Events(this, this.icon.imageDiv, null);
},
-
+
/**
* APIMethod: destroy
- * Destroy the marker. You must first remove the marker from any
+ * Destroy the marker. You must first remove the marker from any
* layer which it has been added to, or you will get buggy behavior.
* (This can not be done within the marker since the marker does not
* know which layer it is attached to.)
@@ -16806,23 +18001,23 @@
this.icon = null;
}
},
-
- /**
+
+ /**
* Method: draw
* Calls draw on the icon, and returns that output.
- *
+ *
* Parameters:
* px - {<OpenLayers.Pixel>}
- *
+ *
* Returns:
- * {DOMElement} A new DOM Image with this marker's icon set at the
+ * {DOMElement} A new DOM Image with this marker's icon set at the
* location passed-in
*/
draw: function(px) {
return this.icon.draw(px);
- },
+ },
- /**
+ /**
* Method: erase
* Erases any drawn elements for this marker.
*/
@@ -16830,7 +18025,7 @@
if (this.icon != null) {
this.icon.erase();
}
- },
+ },
/**
* Method: moveTo
@@ -16842,19 +18037,19 @@
moveTo: function (px) {
if ((px != null) && (this.icon != null)) {
this.icon.moveTo(px);
- }
+ }
this.lonlat = this.map.getLonLatFromLayerPx(px);
},
/**
* APIMethod: isDrawn
- *
+ *
* Returns:
* {Boolean} Whether or not the marker is drawn.
*/
isDrawn: function() {
var isDrawn = (this.icon && this.icon.isDrawn());
- return isDrawn;
+ return isDrawn;
},
/**
@@ -16864,15 +18059,15 @@
* {Boolean} Whether or not the marker is currently visible on screen.
*/
onScreen:function() {
-
+
var onScreen = false;
if (this.map) {
var screenBounds = this.map.getExtent();
onScreen = screenBounds.containsLonLat(this.lonlat);
- }
+ }
return onScreen;
},
-
+
/**
* Method: inflate
* Englarges the markers icon by the specified ratio.
@@ -16886,14 +18081,14 @@
var newSize = new OpenLayers.Size(this.icon.size.w * inflate,
this.icon.size.h * inflate);
this.icon.setSize(newSize);
- }
+ }
},
-
- /**
+
+ /**
* Method: setOpacity
- * Change the opacity of the marker by changin the opacity of
+ * Change the opacity of the marker by changin the opacity of
* its icon
- *
+ *
* Parameters:
* opacity - {float} Specified as fraction (0.4, etc)
*/
@@ -16904,18 +18099,18 @@
/**
* Method: setUrl
* Change URL of the Icon Image.
- *
- * url - {String}
+ *
+ * url - {String}
*/
setUrl: function(url) {
this.icon.setUrl(url);
- },
+ },
- /**
+ /**
* Method: display
* Hide or show the icon
- *
- * display - {Boolean}
+ *
+ * display - {Boolean}
*/
display: function(display) {
this.icon.display(display);
@@ -16928,7 +18123,7 @@
/**
* Function: defaultIcon
* Creates a default <OpenLayers.Icon>.
- *
+ *
* Returns:
* {<OpenLayers.Icon>} A default OpenLayers.Icon to use for a marker
*/
@@ -16939,16 +18134,17 @@
return new OpenLayers.Pixel(-(size.w/2), -size.h);
};
- return new OpenLayers.Icon(url, size, null, calculateOffset);
+ return new OpenLayers.Icon(url, size, null, calculateOffset);
};
+
-
/* ======================================================================
OpenLayers/Request.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -16962,7 +18158,7 @@
* W3C compliant <OpenLayers.Request.XMLHttpRequest> class.
*/
OpenLayers.Request = {
-
+
/**
* Constant: DEFAULT_CONFIG
* {Object} Default configuration for all requests.
@@ -16982,17 +18178,17 @@
failure: null,
scope: null
},
-
+
/**
* APIProperty: events
- * {<OpenLayers.Events>} An events object that handles all
+ * {<OpenLayers.Events>} An events object that handles all
* events on the {<OpenLayers.Request>} object.
*
* All event listeners will receive an event object with three properties:
* request - {<OpenLayers.Request.XMLHttpRequest>} The request object.
* config - {Object} The config object sent to the specific request method.
* requestUrl - {String} The request url.
- *
+ *
* Supported event types:
* complete - Triggered when we have a response from the request, if a
* listener returns false, no further response processing will take
@@ -17001,7 +18197,7 @@
* failure - Triggered when the HTTP response does not have a success code.
*/
events: new OpenLayers.Events(this, null, ["complete", "success", "failure"]),
-
+
/**
* APIMethod: issue
* Create a new XMLHttpRequest object, open it, set any headers, bind
@@ -17058,7 +18254,7 @@
* {XMLHttpRequest} Request object. To abort the request before a response
* is received, call abort() on the request object.
*/
- issue: function(config) {
+ issue: function(config) {
// apply default config - proxy host may have changed
var defaultConfig = OpenLayers.Util.extend(
this.DEFAULT_CONFIG,
@@ -17077,7 +18273,11 @@
}
}
if(config.proxy && (url.indexOf("http") == 0)) {
- url = config.proxy + encodeURIComponent(url);
+ if(typeof config.proxy == "function") {
+ url = config.proxy(url);
+ } else {
+ url = config.proxy + encodeURIComponent(url);
+ }
}
request.open(
config.method, url, config.async, config.user, config.password
@@ -17086,11 +18286,61 @@
request.setRequestHeader(header, config.headers[header]);
}
+ var events = this.events;
+
+ // we want to execute runCallbacks with "this" as the
+ // execution scope
+ var self = this;
+
+ request.onreadystatechange = function() {
+ if(request.readyState == OpenLayers.Request.XMLHttpRequest.DONE) {
+ var proceed = events.triggerEvent(
+ "complete",
+ {request: request, config: config, requestUrl: url}
+ );
+ if(proceed !== false) {
+ self.runCallbacks(
+ {request: request, config: config, requestUrl: url}
+ );
+ }
+ }
+ };
+
+ // send request (optionally with data) and return
+ // call in a timeout for asynchronous requests so the return is
+ // available before readyState == 4 for cached docs
+ if(config.async === false) {
+ request.send(config.data);
+ } else {
+ window.setTimeout(function(){
+ if (request._aborted !== true) {
+ request.send(config.data);
+ }
+ }, 0);
+ }
+ return request;
+ },
+
+ /**
+ * Method: runCallbacks
+ * Calls the complete, success and failure callbacks. Application
+ * can listen to the "complete" event, have the listener
+ * display a confirm window and always return false, and
+ * execute OpenLayers.Request.runCallbacks if the user
+ * hits "yes" in the confirm window.
+ *
+ * Parameters:
+ * options - {Object} Hash containing request, config and requestUrl keys
+ */
+ runCallbacks: function(options) {
+ var request = options.request;
+ var config = options.config;
+
// bind callbacks to readyState 4 (done)
var complete = (config.scope) ?
OpenLayers.Function.bind(config.callback, config.scope) :
config.callback;
-
+
// optional success callback
var success;
if(config.success) {
@@ -17107,51 +18357,22 @@
config.failure;
}
- var events = this.events;
+ complete(request);
- request.onreadystatechange = function() {
- if(request.readyState == OpenLayers.Request.XMLHttpRequest.DONE) {
- var proceed = events.triggerEvent(
- "complete",
- {request: request, config: config, requestUrl: url}
- );
- if(proceed !== false) {
- complete(request);
- if (!request.status || (request.status >= 200 && request.status < 300)) {
- events.triggerEvent(
- "success",
- {request: request, config: config, requestUrl: url}
- );
- if(success) {
- success(request);
- }
- }
- if(request.status && (request.status < 200 || request.status >= 300)) {
- events.triggerEvent(
- "failure",
- {request: request, config: config, requestUrl: url}
- );
- if(failure) {
- failure(request);
- }
- }
- }
+ if (!request.status || (request.status >= 200 && request.status < 300)) {
+ this.events.triggerEvent("success", options);
+ if(success) {
+ success(request);
}
- };
-
- // send request (optionally with data) and return
- // call in a timeout for asynchronous requests so the return is
- // available before readyState == 4 for cached docs
- if(config.async === false) {
- request.send(config.data);
- } else {
- window.setTimeout(function(){
- request.send(config.data);
- }, 0);
}
- return request;
+ if(request.status && (request.status < 200 || request.status >= 300)) {
+ this.events.triggerEvent("failure", options);
+ if(failure) {
+ failure(request);
+ }
+ }
},
-
+
/**
* APIMethod: GET
* Send an HTTP GET request. Additional configuration properties are
@@ -17162,7 +18383,7 @@
* config - {Object} Object with properties for configuring the request.
* See the <issue> method for documentation of allowed properties.
* This object is modified and should not be reused.
- *
+ *
* Returns:
* {XMLHttpRequest} Request object.
*/
@@ -17170,7 +18391,7 @@
config = OpenLayers.Util.extend(config, {method: "GET"});
return OpenLayers.Request.issue(config);
},
-
+
/**
* APIMethod: POST
* Send a POST request. Additional configuration properties are
@@ -17182,7 +18403,7 @@
* See the <issue> method for documentation of allowed properties. The
* default "Content-Type" header will be set to "application-xml" if
* none is provided. This object is modified and should not be reused.
- *
+ *
* Returns:
* {XMLHttpRequest} Request object.
*/
@@ -17195,7 +18416,7 @@
}
return OpenLayers.Request.issue(config);
},
-
+
/**
* APIMethod: PUT
* Send an HTTP PUT request. Additional configuration properties are
@@ -17207,7 +18428,7 @@
* See the <issue> method for documentation of allowed properties. The
* default "Content-Type" header will be set to "application-xml" if
* none is provided. This object is modified and should not be reused.
- *
+ *
* Returns:
* {XMLHttpRequest} Request object.
*/
@@ -17220,7 +18441,7 @@
}
return OpenLayers.Request.issue(config);
},
-
+
/**
* APIMethod: DELETE
* Send an HTTP DELETE request. Additional configuration properties are
@@ -17231,7 +18452,7 @@
* config - {Object} Object with properties for configuring the request.
* See the <issue> method for documentation of allowed properties.
* This object is modified and should not be reused.
- *
+ *
* Returns:
* {XMLHttpRequest} Request object.
*/
@@ -17239,7 +18460,7 @@
config = OpenLayers.Util.extend(config, {method: "DELETE"});
return OpenLayers.Request.issue(config);
},
-
+
/**
* APIMethod: HEAD
* Send an HTTP HEAD request. Additional configuration properties are
@@ -17250,7 +18471,7 @@
* config - {Object} Object with properties for configuring the request.
* See the <issue> method for documentation of allowed properties.
* This object is modified and should not be reused.
- *
+ *
* Returns:
* {XMLHttpRequest} Request object.
*/
@@ -17258,7 +18479,7 @@
config = OpenLayers.Util.extend(config, {method: "HEAD"});
return OpenLayers.Request.issue(config);
},
-
+
/**
* APIMethod: OPTIONS
* Send an HTTP OPTIONS request. Additional configuration properties are
@@ -17269,7 +18490,7 @@
* config - {Object} Object with properties for configuring the request.
* See the <issue> method for documentation of allowed properties.
* This object is modified and should not be reused.
- *
+ *
* Returns:
* {XMLHttpRequest} Request object.
*/
@@ -17283,8 +18504,9 @@
OpenLayers/Tile/Image.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
@@ -17303,14 +18525,14 @@
*/
OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
- /**
+ /**
* Property: url
* {String} The URL of the image being requested. No default. Filled in by
- * layer.getURL() function.
+ * layer.getURL() function.
*/
url: null,
-
- /**
+
+ /**
* Property: imgDiv
* {DOMElement} The div element which wraps the image.
*/
@@ -17319,22 +18541,22 @@
/**
* Property: frame
* {DOMElement} The image element is appended to the frame. Any gutter on
- * the image will be hidden behind the frame.
- */
- frame: null,
-
+ * the image will be hidden behind the frame.
+ */
+ frame: null,
+
/**
* Property: layerAlphaHack
* {Boolean} True if the png alpha hack needs to be applied on the layer's div.
*/
layerAlphaHack: null,
-
+
/**
* Property: isBackBuffer
* {Boolean} Is this tile a back buffer tile?
*/
isBackBuffer: false,
-
+
/**
* Property: lastRatio
* {Float} Used in transition code only. This is the previous ratio
@@ -17353,7 +18575,7 @@
* tiles that have been loaded can be used.
*/
isFirstDraw: true,
-
+
/**
* Property: backBufferTile
* {<OpenLayers.Tile>} A clone of the tile used to create transition
@@ -17361,33 +18583,33 @@
*/
backBufferTile: null,
- /** TBD 3.0 - reorder the parameters to the init function to remove
- * URL. the getUrl() function on the layer gets called on
+ /** TBD 3.0 - reorder the parameters to the init function to remove
+ * URL. the getUrl() function on the layer gets called on
* each draw(), so no need to specify it here.
- *
+ *
* Constructor: OpenLayers.Tile.Image
* Constructor for a new <OpenLayers.Tile.Image> instance.
- *
+ *
* Parameters:
* layer - {<OpenLayers.Layer>} layer that the tile will go in.
* position - {<OpenLayers.Pixel>}
* bounds - {<OpenLayers.Bounds>}
* url - {<String>} Deprecated. Remove me in 3.0.
* size - {<OpenLayers.Size>}
- */
+ */
initialize: function(layer, position, bounds, url, size) {
OpenLayers.Tile.prototype.initialize.apply(this, arguments);
this.url = url; //deprecated remove me
+
+ this.frame = document.createElement('div');
+ this.frame.style.overflow = 'hidden';
+ this.frame.style.position = 'absolute';
- this.frame = document.createElement('div');
- this.frame.style.overflow = 'hidden';
- this.frame.style.position = 'absolute';
-
this.layerAlphaHack = this.layer.alpha && OpenLayers.Util.alphaHack();
},
- /**
+ /**
* APIMethod: destroy
* nullify references to prevent circular references and memory leaks
*/
@@ -17395,13 +18617,13 @@
if (this.imgDiv != null) {
if (this.layerAlphaHack) {
// unregister the "load" handler
- OpenLayers.Event.stopObservingElement(this.imgDiv.childNodes[0].id);
+ OpenLayers.Event.stopObservingElement(this.imgDiv.childNodes[0]);
}
// unregister the "load" and "error" handlers. Only the "error" handler if
// this.layerAlphaHack is true.
- OpenLayers.Event.stopObservingElement(this.imgDiv.id);
-
+ OpenLayers.Event.stopObservingElement(this.imgDiv);
+
if (this.imgDiv.parentNode == this.frame) {
this.frame.removeChild(this.imgDiv);
this.imgDiv.map = null;
@@ -17411,19 +18633,19 @@
this.imgDiv.src = OpenLayers.Util.getImagesLocation() + "blank.gif";
}
this.imgDiv = null;
- if ((this.frame != null) && (this.frame.parentNode == this.layer.div)) {
- this.layer.div.removeChild(this.frame);
+ if ((this.frame != null) && (this.frame.parentNode == this.layer.div)) {
+ this.layer.div.removeChild(this.frame);
}
- this.frame = null;
-
+ this.frame = null;
+
/* clean up the backBufferTile if it exists */
if (this.backBufferTile) {
this.backBufferTile.destroy();
this.backBufferTile = null;
}
-
+
this.layer.events.unregister("loadend", this, this.resetBackBuffer);
-
+
OpenLayers.Tile.prototype.destroy.apply(this, arguments);
},
@@ -17438,27 +18660,27 @@
*/
clone: function (obj) {
if (obj == null) {
- obj = new OpenLayers.Tile.Image(this.layer,
- this.position,
- this.bounds,
- this.url,
- this.size);
- }
-
+ obj = new OpenLayers.Tile.Image(this.layer,
+ this.position,
+ this.bounds,
+ this.url,
+ this.size);
+ }
+
//pick up properties from superclass
obj = OpenLayers.Tile.prototype.clone.apply(this, [obj]);
-
+
//dont want to directly copy the image div
obj.imgDiv = null;
-
-
+
+
return obj;
},
-
+
/**
* Method: draw
* Check that a tile should be drawn, and draw it.
- *
+ *
* Returns:
* {Boolean} Always returns true.
*/
@@ -17467,8 +18689,9 @@
this.bounds = this.getBoundsFromBaseLayer(this.position);
}
var drawTile = OpenLayers.Tile.prototype.draw.apply(this, arguments);
-
- if (OpenLayers.Util.indexOf(this.layer.SUPPORTED_TRANSITIONS, this.layer.transitionEffect) != -1) {
+
+ if ((OpenLayers.Util.indexOf(this.layer.SUPPORTED_TRANSITIONS, this.layer.transitionEffect) != -1) ||
+ this.layer.singleTile) {
if (drawTile) {
//we use a clone of this tile to create a double buffer for visual
//continuity. The backBufferTile is used to create transition
@@ -17481,10 +18704,10 @@
// the backBufferTile behind the main tile so the tiles can
// load over top and display as soon as they are loaded.
this.backBufferTile.isBackBuffer = true;
-
+
// potentially end any transition effects when the tile loads
this.events.register('loadend', this, this.resetBackBuffer);
-
+
// clear transition back buffer tile only after all tiles in
// this layer have loaded to avoid visual glitches
this.layer.events.register("loadend", this, this.resetBackBuffer);
@@ -17502,45 +18725,45 @@
if (drawTile && this.isFirstDraw) {
this.events.register('loadend', this, this.showTile);
this.isFirstDraw = false;
- }
- }
-
+ }
+ }
+
if (!drawTile) {
return false;
}
-
+
if (this.isLoading) {
//if we're already loading, send 'reload' instead of 'loadstart'.
- this.events.triggerEvent("reload");
+ this.events.triggerEvent("reload");
} else {
this.isLoading = true;
this.events.triggerEvent("loadstart");
}
-
+
return this.renderTile();
},
-
- /**
+
+ /**
* Method: resetBackBuffer
* Triggered by two different events, layer loadend, and tile loadend.
- * In any of these cases, we check to see if we can hide the
- * backBufferTile yet and update its parameters to match the
+ * In any of these cases, we check to see if we can hide the
+ * backBufferTile yet and update its parameters to match the
* foreground tile.
*
* Basic logic:
* - If the backBufferTile hasn't been drawn yet, reset it
* - If layer is still loading, show foreground tile but don't hide
* the backBufferTile yet
- * - If layer is done loading, reset backBuffer tile and show
+ * - If layer is done loading, reset backBuffer tile and show
* foreground tile
*/
resetBackBuffer: function() {
this.showTile();
- if (this.backBufferTile &&
+ if (this.backBufferTile &&
(this.isFirstDraw || !this.layer.numLoadingTiles)) {
this.isFirstDraw = false;
// check to see if the backBufferTile is within the max extents
- // before rendering it
+ // before rendering it
var maxExtent = this.layer.maxExtent;
var withinMaxExtent = (maxExtent &&
this.bounds.intersectsBounds(maxExtent, false));
@@ -17548,7 +18771,7 @@
this.backBufferTile.position = this.position;
this.backBufferTile.bounds = this.bounds;
this.backBufferTile.size = this.size;
- this.backBufferTile.imageSize = this.layer.imageSize || this.size;
+ this.backBufferTile.imageSize = this.layer.getImageSize(this.bounds) || this.size;
this.backBufferTile.imageOffset = this.layer.imageOffset;
this.backBufferTile.resolution = this.layer.getResolution();
this.backBufferTile.renderTile();
@@ -17557,7 +18780,7 @@
this.backBufferTile.hide();
}
},
-
+
/**
* Method: renderTile
* Internal function to actually initialize the image tile,
@@ -17569,7 +18792,7 @@
}
this.imgDiv.viewRequestID = this.layer.map.viewRequestID;
-
+
if (this.layer.async) {
// Asyncronous image requests call the asynchronous getURL method
// on the layer to fetch an image that covers 'this.bounds', in the scope of
@@ -17579,16 +18802,16 @@
} else {
// syncronous image requests get the url and position the frame immediately,
// and don't wait for an image request to come back.
-
+
// needed for changing to a different server for onload error
if (this.layer.url instanceof Array) {
this.imgDiv.urls = this.layer.url.slice();
}
-
+
this.url = this.layer.getURL(this.bounds);
-
+
// position the frame immediately
- this.positionImage();
+ this.positionImage();
}
return true;
},
@@ -17602,14 +18825,14 @@
positionImage: function() {
// if the this layer doesn't exist at the point the image is
// returned, do not attempt to use it for size computation
- if ( this.layer == null )
+ if (this.layer === null) {
return;
+ }
+ // position the frame
+ OpenLayers.Util.modifyDOMElement(this.frame,
+ null, this.position, this.size);
- // position the frame
- OpenLayers.Util.modifyDOMElement(this.frame,
- null, this.position, this.size);
-
- var imageSize = this.layer.getImageSize();
+ var imageSize = this.layer.getImageSize(this.bounds);
if (this.layerAlphaHack) {
OpenLayers.Util.modifyAlphaImageDiv(this.imgDiv,
null, null, imageSize, this.url);
@@ -17620,17 +18843,17 @@
}
},
- /**
+ /**
* Method: clear
- * Clear the tile of any bounds/position-related data so that it can
+ * Clear the tile of any bounds/position-related data so that it can
* be reused in a new location.
*/
clear: function() {
if(this.imgDiv) {
this.hide();
- if (OpenLayers.Tile.Image.useBlankTile) {
+ if (OpenLayers.Tile.Image.useBlankTile) {
this.imgDiv.src = OpenLayers.Util.getImagesLocation() + "blank.gif";
- }
+ }
}
},
@@ -17639,10 +18862,10 @@
* Creates the imgDiv property on the tile.
*/
initImgDiv: function() {
-
- var offset = this.layer.imageOffset;
- var size = this.layer.getImageSize();
-
+
+ var offset = this.layer.imageOffset;
+ var size = this.layer.getImageSize(this.bounds);
+
if (this.layerAlphaHack) {
this.imgDiv = OpenLayers.Util.createAlphaImageDiv(null,
offset,
@@ -17663,7 +18886,7 @@
null,
true);
}
-
+
this.imgDiv.className = 'olTileImage';
/* checkImgURL used to be used to called as a work around, but it
@@ -17675,43 +18898,43 @@
OpenLayers.Function.bind(this.checkImgURL, this) );
*/
this.frame.style.zIndex = this.isBackBuffer ? 0 : 1;
- this.frame.appendChild(this.imgDiv);
- this.layer.div.appendChild(this.frame);
+ this.frame.appendChild(this.imgDiv);
+ this.layer.div.appendChild(this.frame);
if(this.layer.opacity != null) {
-
+
OpenLayers.Util.modifyDOMElement(this.imgDiv, null, null, null,
- null, null, null,
+ null, null, null,
this.layer.opacity);
}
// we need this reference to check back the viewRequestID
this.imgDiv.map = this.layer.map;
- //bind a listener to the onload of the image div so that we
+ //bind a listener to the onload of the image div so that we
// can register when a tile has finished loading.
var onload = function() {
-
- //normally isLoading should always be true here but there are some
+
+ //normally isLoading should always be true here but there are some
// right funky conditions where loading and then reloading a tile
- // with the same url *really*fast*. this check prevents sending
+ // with the same url *really*fast*. this check prevents sending
// a 'loadend' if the msg has already been sent
//
- if (this.isLoading) {
- this.isLoading = false;
- this.events.triggerEvent("loadend");
+ if (this.isLoading) {
+ this.isLoading = false;
+ this.events.triggerEvent("loadend");
}
};
+
+ if (this.layerAlphaHack) {
+ OpenLayers.Event.observe(this.imgDiv.childNodes[0], 'load',
+ OpenLayers.Function.bind(onload, this));
+ } else {
+ OpenLayers.Event.observe(this.imgDiv, 'load',
+ OpenLayers.Function.bind(onload, this));
+ }
+
- if (this.layerAlphaHack) {
- OpenLayers.Event.observe(this.imgDiv.childNodes[0], 'load',
- OpenLayers.Function.bind(onload, this));
- } else {
- OpenLayers.Event.observe(this.imgDiv, 'load',
- OpenLayers.Function.bind(onload, this));
- }
-
-
// Bind a listener to the onerror of the image div so that we
// can registere when a tile has finished loading with errors.
var onerror = function() {
@@ -17737,18 +18960,18 @@
* the imgDiv display to 'none', as either (a) it will be reset to visible
* when the new URL loads in the image, or (b) we don't want to display
* this tile after all because its new bounds are outside our maxExtent.
- *
+ *
* This function should no longer be neccesary with the improvements to
* Grid.js in OpenLayers 2.3. The lack of a good isEquivilantURL function
- * caused problems in 2.2, but it's possible that with the improved
+ * caused problems in 2.2, but it's possible that with the improved
* isEquivilant URL function, this might be neccesary at some point.
- *
- * See discussion in the thread at
+ *
+ * See discussion in the thread at
* http://openlayers.org/pipermail/dev/2007-January/000205.html
*/
checkImgURL: function () {
// Sometimes our image will load after it has already been removed
- // from the map, in which case this check is not needed.
+ // from the map, in which case this check is not needed.
if (this.layer) {
var loaded = this.layerAlphaHack ? this.imgDiv.firstChild.src : this.imgDiv.src;
if (!OpenLayers.Util.isEquivalentUrl(loaded, this.url)) {
@@ -17756,7 +18979,7 @@
}
}
},
-
+
/**
* Method: startTransition
* This method is invoked on tiles that are backBuffers for tiles in the
@@ -17778,15 +19001,15 @@
if (this.backBufferTile.resolution) {
ratio = this.backBufferTile.resolution / this.layer.getResolution();
}
-
+
// if the ratio is not the same as it was last time (i.e. we are
// zooming), then we need to adjust the backBuffer tile
if (ratio != this.lastRatio) {
if (this.layer.transitionEffect == 'resize') {
- // In this case, we can just immediately resize the
+ // In this case, we can just immediately resize the
// backBufferTile.
var upperLeft = new OpenLayers.LonLat(
- this.backBufferTile.bounds.left,
+ this.backBufferTile.bounds.left,
this.backBufferTile.bounds.top
);
var size = new OpenLayers.Size(
@@ -17795,10 +19018,10 @@
);
var px = this.layer.map.getLayerPxFromLonLat(upperLeft);
- OpenLayers.Util.modifyDOMElement(this.backBufferTile.frame,
+ OpenLayers.Util.modifyDOMElement(this.backBufferTile.frame,
null, px, size);
var imageSize = this.backBufferTile.imageSize;
- imageSize = new OpenLayers.Size(imageSize.w * ratio,
+ imageSize = new OpenLayers.Size(imageSize.w * ratio,
imageSize.h * ratio);
var imageOffset = this.backBufferTile.imageOffset;
if(imageOffset) {
@@ -17827,8 +19050,8 @@
this.lastRatio = ratio;
},
-
- /**
+
+ /**
* Method: show
* Show the tile by showing its frame.
*/
@@ -17836,38 +19059,39 @@
this.frame.style.display = '';
// Force a reflow on gecko based browsers to actually show the element
// before continuing execution.
- if (OpenLayers.Util.indexOf(this.layer.SUPPORTED_TRANSITIONS,
+ if (OpenLayers.Util.indexOf(this.layer.SUPPORTED_TRANSITIONS,
this.layer.transitionEffect) != -1) {
- if (navigator.userAgent.toLowerCase().indexOf("gecko") != -1) {
- this.frame.scrollLeft = this.frame.scrollLeft;
- }
+ if (navigator.userAgent.toLowerCase().indexOf("gecko") != -1) {
+ this.frame.scrollLeft = this.frame.scrollLeft;
+ }
}
},
-
- /**
+
+ /**
* Method: hide
* Hide the tile by hiding its frame.
*/
hide: function() {
this.frame.style.display = 'none';
},
-
+
CLASS_NAME: "OpenLayers.Tile.Image"
}
);
-OpenLayers.Tile.Image.useBlankTile = (
- OpenLayers.Util.getBrowserName() == "safari" ||
- OpenLayers.Util.getBrowserName() == "opera");
+OpenLayers.Tile.Image.useBlankTile = (
+ OpenLayers.Util.getBrowserName() == "safari" ||
+ OpenLayers.Util.getBrowserName() == "opera");
/* ======================================================================
OpenLayers/Control/OverviewMap.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
-/**
+/**
* @requires OpenLayers/Control.js
* @requires OpenLayers/BaseTypes.js
* @requires OpenLayers/Events.js
@@ -17875,8 +19099,8 @@
/**
* Class: OpenLayers.Control.OverviewMap
- * The OverMap control creates a small overview map, useful to display the
- * extent of a zoomed map and your main map and provide additional
+ * The OverMap control creates a small overview map, useful to display the
+ * extent of a zoomed map and your main map and provide additional
* navigation options to the User. By default the overview map is drawn in
* the lower right corner of the main map. Create a new overview map with the
* <OpenLayers.Control.OverviewMap> constructor.
@@ -17891,7 +19115,7 @@
* {DOMElement} The DOM element that contains the overview map
*/
element: null,
-
+
/**
* APIProperty: ovmap
* {<OpenLayers.Map>} A reference to the overview map itself.
@@ -17913,7 +19137,7 @@
* If none are sent at construction, the base layer for the main map is used.
*/
layers: null,
-
+
/**
* APIProperty: minRectSize
* {Integer} The minimum width or height (in pixels) of the extent
@@ -17922,7 +19146,7 @@
* <minRectDisplayClass> property. Default is 15 pixels.
*/
minRectSize: 15,
-
+
/**
* APIProperty: minRectDisplayClass
* {String} Replacement style class name for the extent rectangle when
@@ -17955,7 +19179,7 @@
* resolution at which to zoom farther in on the overview map.
*/
maxRatio: 32,
-
+
/**
* APIProperty: mapOptions
* {Object} An object containing any non-default properties to be sent to
@@ -17972,7 +19196,7 @@
* to the center.
*/
autoPan: false,
-
+
/**
* Property: handlers
* {Object}
@@ -17986,6 +19210,12 @@
resolutionFactor: 1,
/**
+ * APIProperty: maximized
+ * {Boolean} Start as maximized (visible). Defaults to false.
+ */
+ maximized: false,
+
+ /**
* Constructor: OpenLayers.Control.OverviewMap
* Create a new overview map
*
@@ -17999,7 +19229,7 @@
this.handlers = {};
OpenLayers.Control.prototype.initialize.apply(this, [options]);
},
-
+
/**
* APIMethod: destroy
* Deconstruct the control
@@ -18008,16 +19238,26 @@
if (!this.mapDiv) { // we've already been destroyed
return;
}
- this.handlers.click.destroy();
+ if (this.handlers.click) {
+ this.handlers.click.destroy();
+ }
+ if (this.handlers.drag) {
+ this.handlers.drag.destroy();
+ }
this.mapDiv.removeChild(this.extentRectangle);
this.extentRectangle = null;
- this.rectEvents.destroy();
- this.rectEvents = null;
- this.ovmap.destroy();
- this.ovmap = null;
+ if (this.rectEvents) {
+ this.rectEvents.destroy();
+ this.rectEvents = null;
+ }
+ if (this.ovmap) {
+ this.ovmap.destroy();
+ this.ovmap = null;
+ }
+
this.element.removeChild(this.mapDiv);
this.mapDiv = null;
@@ -18029,7 +19269,7 @@
this.div.removeChild(this.maximizeDiv);
this.maximizeDiv = null;
}
-
+
if (this.minimizeDiv) {
OpenLayers.Event.stopObservingElement(this.minimizeDiv);
this.div.removeChild(this.minimizeDiv);
@@ -18042,13 +19282,13 @@
scope: this
});
- OpenLayers.Control.prototype.destroy.apply(this, arguments);
+ OpenLayers.Control.prototype.destroy.apply(this, arguments);
},
/**
* Method: draw
* Render the control in the browser.
- */
+ */
draw: function() {
OpenLayers.Control.prototype.draw.apply(this, arguments);
if(!(this.layers.length > 0)) {
@@ -18072,14 +19312,14 @@
this.mapDiv.style.position = 'relative';
this.mapDiv.style.overflow = 'hidden';
this.mapDiv.id = OpenLayers.Util.createUniqueID('overviewMap');
-
+
this.extentRectangle = document.createElement('div');
this.extentRectangle.style.position = 'absolute';
this.extentRectangle.style.zIndex = 1000; //HACK
this.extentRectangle.className = this.displayClass+'ExtentRectangle';
this.mapDiv.appendChild(this.extentRectangle);
- this.element.appendChild(this.mapDiv);
+ this.element.appendChild(this.mapDiv);
this.div.appendChild(this.element);
@@ -18091,48 +19331,48 @@
// maximize button div
var img = imgLocation + 'layer-switcher-maximize.png';
this.maximizeDiv = OpenLayers.Util.createAlphaImageDiv(
- this.displayClass + 'MaximizeButton',
- null,
- new OpenLayers.Size(18,18),
- img,
+ this.displayClass + 'MaximizeButton',
+ null,
+ new OpenLayers.Size(18,18),
+ img,
'absolute');
this.maximizeDiv.style.display = 'none';
this.maximizeDiv.className = this.displayClass + 'MaximizeButton';
- OpenLayers.Event.observe(this.maximizeDiv, 'click',
+ OpenLayers.Event.observe(this.maximizeDiv, 'click',
OpenLayers.Function.bindAsEventListener(this.maximizeControl,
this)
);
this.div.appendChild(this.maximizeDiv);
-
+
// minimize button div
var img = imgLocation + 'layer-switcher-minimize.png';
this.minimizeDiv = OpenLayers.Util.createAlphaImageDiv(
- 'OpenLayers_Control_minimizeDiv',
- null,
- new OpenLayers.Size(18,18),
- img,
+ 'OpenLayers_Control_minimizeDiv',
+ null,
+ new OpenLayers.Size(18,18),
+ img,
'absolute');
this.minimizeDiv.style.display = 'none';
this.minimizeDiv.className = this.displayClass + 'MinimizeButton';
- OpenLayers.Event.observe(this.minimizeDiv, 'click',
+ OpenLayers.Event.observe(this.minimizeDiv, 'click',
OpenLayers.Function.bindAsEventListener(this.minimizeControl,
this)
);
this.div.appendChild(this.minimizeDiv);
-
+
var eventsToStop = ['dblclick','mousedown'];
-
+
for (var i=0, len=eventsToStop.length; i<len; i++) {
- OpenLayers.Event.observe(this.maximizeDiv,
- eventsToStop[i],
+ OpenLayers.Event.observe(this.maximizeDiv,
+ eventsToStop[i],
OpenLayers.Event.stop);
OpenLayers.Event.observe(this.minimizeDiv,
- eventsToStop[i],
+ eventsToStop[i],
OpenLayers.Event.stop);
}
-
+
this.minimizeControl();
} else {
// show the overview map
@@ -18141,12 +19381,15 @@
if(this.map.getExtent()) {
this.update();
}
-
+
this.map.events.register('moveend', this, this.update);
-
+
+ if (this.maximized) {
+ this.maximizeControl();
+ }
return this.div;
},
-
+
/**
* Method: baseLayerDraw
* Draw the base layer - called if unable to complete in the initial draw
@@ -18184,7 +19427,7 @@
newTop));
}
},
-
+
/**
* Method: mapDivClick
* Handle browser events
@@ -18222,15 +19465,15 @@
this.element.style.display = '';
this.showToggle(false);
if (e != null) {
- OpenLayers.Event.stop(e);
+ OpenLayers.Event.stop(e);
}
},
/**
* Method: minimizeControl
- * Hide all the contents of the control, shrink the size,
+ * Hide all the contents of the control, shrink the size,
* add the maximize icon
- *
+ *
* Parameters:
* e - {<OpenLayers.Event>}
*/
@@ -18238,7 +19481,7 @@
this.element.style.display = 'none';
this.showToggle(true);
if (e != null) {
- OpenLayers.Event.stop(e);
+ OpenLayers.Event.stop(e);
}
},
@@ -18247,7 +19490,7 @@
* Hide/Show the toggle depending on whether the control is minimized
*
* Parameters:
- * minimize - {Boolean}
+ * minimize - {Boolean}
*/
showToggle: function(minimize) {
this.maximizeDiv.style.display = minimize ? '' : 'none';
@@ -18262,15 +19505,15 @@
if(this.ovmap == null) {
this.createMap();
}
-
+
if(this.autoPan || !this.isSuitableOverview()) {
this.updateOverview();
}
-
+
// update extent rectangle
this.updateRectToMap();
},
-
+
/**
* Method: isSuitableOverview
* Determines if the overview map is suitable given the extent and
@@ -18283,7 +19526,7 @@
Math.max(mapExtent.left, maxExtent.left),
Math.max(mapExtent.bottom, maxExtent.bottom),
Math.min(mapExtent.right, maxExtent.right),
- Math.min(mapExtent.top, maxExtent.top));
+ Math.min(mapExtent.top, maxExtent.top));
if (this.ovmap.getProjection() != this.map.getProjection()) {
testExtent = testExtent.transform(
@@ -18296,7 +19539,7 @@
(resRatio <= this.maxRatio) &&
(this.ovmap.getExtent().containsBounds(testExtent)));
},
-
+
/**
* Method updateOverview
* Called by <update> if <isSuitableOverview> returns true
@@ -18307,7 +19550,7 @@
var resRatio = targetRes / mapRes;
if(resRatio > this.maxRatio) {
// zoom in overview map
- targetRes = this.minRatio * mapRes;
+ targetRes = this.minRatio * mapRes;
} else if(resRatio <= this.minRatio) {
// zoom out overview map
targetRes = this.maxRatio * mapRes;
@@ -18324,7 +19567,7 @@
targetRes * this.resolutionFactor));
this.updateRectToMap();
},
-
+
/**
* Method: createMap
* Construct the map that this control contains
@@ -18332,14 +19575,14 @@
createMap: function() {
// create the overview map
var options = OpenLayers.Util.extend(
- {controls: [], maxResolution: 'auto',
+ {controls: [], maxResolution: 'auto',
fallThrough: false}, this.mapOptions);
this.ovmap = new OpenLayers.Map(this.mapDiv, options);
-
+
// prevent ovmap from being destroyed when the page unloads, because
// the OverviewMap control has to do this (and does it).
OpenLayers.Event.stopObserving(window, 'unload', this.ovmap.unloadDestroy);
-
+
this.ovmap.addLayers(this.layers);
this.ovmap.zoomToMaxExtent();
// check extent rectangle border width
@@ -18369,7 +19612,7 @@
}
);
this.handlers.click.activate();
-
+
this.rectEvents = new OpenLayers.Events(this, this.extentRectangle,
null, true);
this.rectEvents.register("mouseover", this, function(e) {
@@ -18393,7 +19636,7 @@
OpenLayers.INCHES_PER_UNIT[targetUnits] : 1;
}
},
-
+
/**
* Method: updateRectToMap
* Updates the extent rectangle position and size to match the map extent
@@ -18403,7 +19646,7 @@
var bounds;
if (this.ovmap.getProjection() != this.map.getProjection()) {
bounds = this.map.getExtent().transform(
- this.map.getProjectionObject(),
+ this.map.getProjectionObject(),
this.ovmap.getProjectionObject() );
} else {
bounds = this.map.getExtent();
@@ -18413,7 +19656,7 @@
this.setRectPxBounds(pxBounds);
}
},
-
+
/**
* Method: updateMapToRect
* Updates the map extent to match the extent rectangle position and size
@@ -18530,12 +19773,12 @@
var size = this.ovmap.size;
var res = this.ovmap.getResolution();
var center = this.ovmap.getExtent().getCenterLonLat();
-
+
var delta_x = overviewMapPx.x - (size.w / 2);
var delta_y = overviewMapPx.y - (size.h / 2);
-
+
return new OpenLayers.LonLat(center.lon + delta_x * res ,
- center.lat - delta_y * res);
+ center.lat - delta_y * res);
},
/**
@@ -18546,7 +19789,7 @@
* lonlat - {<OpenLayers.LonLat>}
*
* Returns:
- * {<OpenLayers.Pixel>} Location which is the passed-in OpenLayers.LonLat,
+ * {<OpenLayers.Pixel>} Location which is the passed-in OpenLayers.LonLat,
* translated into overview map pixels
*/
getOverviewPxFromLonLat: function(lonlat) {
@@ -18557,7 +19800,7 @@
px = new OpenLayers.Pixel(
Math.round(1/res * (lonlat.lon - extent.left)),
Math.round(1/res * (extent.top - lonlat.lat)));
- }
+ }
return px;
},
@@ -18567,8 +19810,9 @@
OpenLayers/Feature.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
@@ -18585,33 +19829,33 @@
*/
OpenLayers.Feature = OpenLayers.Class({
- /**
- * Property: layer
- * {<OpenLayers.Layer>}
+ /**
+ * Property: layer
+ * {<OpenLayers.Layer>}
*/
layer: null,
- /**
- * Property: id
- * {String}
+ /**
+ * Property: id
+ * {String}
*/
id: null,
-
- /**
- * Property: lonlat
- * {<OpenLayers.LonLat>}
+
+ /**
+ * Property: lonlat
+ * {<OpenLayers.LonLat>}
*/
lonlat: null,
- /**
- * Property: data
- * {Object}
+ /**
+ * Property: data
+ * {Object}
*/
data: null,
- /**
- * Property: marker
- * {<OpenLayers.Marker>}
+ /**
+ * Property: marker
+ * {<OpenLayers.Marker>}
*/
marker: null,
@@ -18622,21 +19866,21 @@
*/
popupClass: OpenLayers.Popup.AnchoredBubble,
- /**
- * Property: popup
- * {<OpenLayers.Popup>}
+ /**
+ * Property: popup
+ * {<OpenLayers.Popup>}
*/
popup: null,
- /**
+ /**
* Constructor: OpenLayers.Feature
* Constructor for features.
*
* Parameters:
- * layer - {<OpenLayers.Layer>}
- * lonlat - {<OpenLayers.LonLat>}
- * data - {Object}
- *
+ * layer - {<OpenLayers.Layer>}
+ * lonlat - {<OpenLayers.LonLat>}
+ * data - {Object}
+ *
* Returns:
* {<OpenLayers.Feature>}
*/
@@ -18644,10 +19888,10 @@
this.layer = layer;
this.lonlat = lonlat;
this.data = (data != null) ? data : {};
- this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
+ this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
},
- /**
+ /**
* Method: destroy
* nullify references to prevent circular references and memory leaks
*/
@@ -18659,6 +19903,10 @@
this.layer.map.removePopup(this.popup);
}
}
+ // remove the marker from the layer
+ if (this.layer != null && this.marker != null) {
+ this.layer.removeMarker(this.marker);
+ }
this.layer = null;
this.id = null;
@@ -18673,36 +19921,36 @@
this.popup = null;
}
},
-
+
/**
* Method: onScreen
- *
+ *
* Returns:
* {Boolean} Whether or not the feature is currently visible on screen
* (based on its 'lonlat' property)
*/
onScreen:function() {
-
+
var onScreen = false;
if ((this.layer != null) && (this.layer.map != null)) {
var screenBounds = this.layer.map.getExtent();
onScreen = screenBounds.containsLonLat(this.lonlat);
- }
+ }
return onScreen;
},
+
-
/**
* Method: createMarker
* Based on the data associated with the Feature, create and return a marker object.
*
- * Returns:
+ * Returns:
* {<OpenLayers.Marker>} A Marker Object created from the 'lonlat' and 'icon' properties
* set in this.data. If no 'lonlat' is set, returns null. If no
* 'icon' is set, OpenLayers.Marker() will load the default image.
- *
+ *
* Note - this.marker is set to return value
- *
+ *
*/
createMarker: function() {
@@ -18719,64 +19967,64 @@
* to also specify an alternative function for destroying it
*/
destroyMarker: function() {
- this.marker.destroy();
+ this.marker.destroy();
},
/**
* Method: createPopup
* Creates a popup object created from the 'lonlat', 'popupSize',
* and 'popupContentHTML' properties set in this.data. It uses
- * this.marker.icon as default anchor.
- *
- * If no 'lonlat' is set, returns null.
+ * this.marker.icon as default anchor.
+ *
+ * If no 'lonlat' is set, returns null.
* If no this.marker has been created, no anchor is sent.
*
* Note - the returned popup object is 'owned' by the feature, so you
* cannot use the popup's destroy method to discard the popup.
* Instead, you must use the feature's destroyPopup
- *
+ *
* Note - this.popup is set to return value
- *
- * Parameters:
+ *
+ * Parameters:
* closeBox - {Boolean} create popup with closebox or not
- *
+ *
* Returns:
* {<OpenLayers.Popup>} Returns the created popup, which is also set
* as 'popup' property of this feature. Will be of whatever type
* specified by this feature's 'popupClass' property, but must be
* of type <OpenLayers.Popup>.
- *
+ *
*/
createPopup: function(closeBox) {
if (this.lonlat != null) {
-
+
var id = this.id + "_popup";
var anchor = (this.marker) ? this.marker.icon : null;
if (!this.popup) {
- this.popup = new this.popupClass(id,
+ this.popup = new this.popupClass(id,
this.lonlat,
this.data.popupSize,
this.data.popupContentHTML,
- anchor,
- closeBox);
- }
+ anchor,
+ closeBox);
+ }
if (this.data.overflow != null) {
this.popup.contentDiv.style.overflow = this.data.overflow;
- }
-
+ }
+
this.popup.feature = this;
- }
+ }
return this.popup;
},
-
+
/**
* Method: destroyPopup
* Destroys the popup created via createPopup.
*
- * As with the marker, if user overrides the createPopup() function, s/he
+ * As with the marker, if user overrides the createPopup() function, s/he
* should also be able to override the destruction
*/
destroyPopup: function() {
@@ -18784,7 +20032,7 @@
this.popup.feature = null;
this.popup.destroy();
this.popup = null;
- }
+ }
},
CLASS_NAME: "OpenLayers.Feature"
@@ -18793,9 +20041,10 @@
OpenLayers/Handler/Click.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the clear BSD license.
- * See http://svn.openlayers.org/trunk/openlayers/license.txt
- * for the full text of the license. */
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
/**
* @requires OpenLayers/Handler.js
@@ -18811,9 +20060,9 @@
* click. By setting a <pixelTolerance>, controls can also ignore clicks
* that include a drag. Create a new instance with the
* <OpenLayers.Handler.Click> constructor.
- *
+ *
* Inherits from:
- * - <OpenLayers.Handler>
+ * - <OpenLayers.Handler>
*/
OpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, {
@@ -18823,20 +20072,20 @@
* considered a double-click.
*/
delay: 300,
-
+
/**
* APIProperty: single
* {Boolean} Handle single clicks. Default is true. If false, clicks
* will not be reported. If true, single-clicks will be reported.
*/
single: true,
-
+
/**
* APIProperty: double
* {Boolean} Handle double-clicks. Default is false.
*/
'double': false,
-
+
/**
* APIProperty: pixelTolerance
* {Number} Maximum number of pixels between mouseup and mousedown for an
@@ -18846,7 +20095,7 @@
* constructed.
*/
pixelTolerance: 0,
-
+
/**
* APIProperty: stopSingle
* {Boolean} Stop other listeners from being notified of clicks. Default
@@ -18855,13 +20104,13 @@
* or single clicks).
*/
stopSingle: false,
-
+
/**
* APIProperty: stopDouble
* {Boolean} Stop other listeners from being notified of double-clicks.
* Default is false. If true, any click listeners registered before
* this one will not be notified of *any* double-click events.
- *
+ *
* The one caveat with stopDouble is that given a map with two click
* handlers, one with stopDouble true and the other with stopSingle
* true, the stopSingle handler should be activated last to get
@@ -18877,24 +20126,24 @@
* {Number} The id of the timeout waiting to clear the <delayedCall>.
*/
timerId: null,
-
+
/**
* Property: down
* {<OpenLayers.Pixel>} The pixel location of the last mousedown.
*/
down: null,
-
+
/**
* Property: rightclickTimerId
- * {Number} The id of the right mouse timeout waiting to clear the
+ * {Number} The id of the right mouse timeout waiting to clear the
* <delayedEvent>.
*/
rightclickTimerId: null,
-
+
/**
* Constructor: OpenLayers.Handler.Click
* Create a new click handler.
- *
+ *
* Parameters:
* control - {<OpenLayers.Control>} The control that is making use of
* this handler. If a handler is being used without a control, the
@@ -18917,7 +20166,7 @@
};
}
},
-
+
/**
* Method: mousedown
* Handle mousedown. Only registered as a listener if pixelTolerance is
@@ -18931,7 +20180,7 @@
/**
* Method: mouseup
* Handle mouseup. Installed to support collection of right mouse events.
- *
+ *
* Returns:
* {Boolean} Continue propagating this event.
*/
@@ -18941,55 +20190,55 @@
// Collect right mouse clicks from the mouseup
// IE - ignores the second right click in mousedown so using
// mouseup instead
- if (this.checkModifiers(evt) &&
- this.control.handleRightClicks &&
+ if (this.checkModifiers(evt) &&
+ this.control.handleRightClicks &&
OpenLayers.Event.isRightClick(evt)) {
propagate = this.rightclick(evt);
}
return propagate;
},
-
+
/**
* Method: rightclick
- * Handle rightclick. For a dblrightclick, we get two clicks so we need
- * to always register for dblrightclick to properly handle single
+ * Handle rightclick. For a dblrightclick, we get two clicks so we need
+ * to always register for dblrightclick to properly handle single
* clicks.
- *
+ *
* Returns:
* {Boolean} Continue propagating this event.
*/
rightclick: function(evt) {
if(this.passesTolerance(evt)) {
if(this.rightclickTimerId != null) {
- //Second click received before timeout this must be
+ //Second click received before timeout this must be
// a double click
- this.clearTimer();
+ this.clearTimer();
this.callback('dblrightclick', [evt]);
return !this.stopDouble;
- } else {
- //Set the rightclickTimerId, send evt only if double is
+ } else {
+ //Set the rightclickTimerId, send evt only if double is
// true else trigger single
var clickEvent = this['double'] ?
- OpenLayers.Util.extend({}, evt) :
+ OpenLayers.Util.extend({}, evt) :
this.callback('rightclick', [evt]);
var delayedRightCall = OpenLayers.Function.bind(
- this.delayedRightCall,
- this,
+ this.delayedRightCall,
+ this,
clickEvent
);
this.rightclickTimerId = window.setTimeout(
delayedRightCall, this.delay
);
- }
+ }
}
return !this.stopSingle;
},
-
+
/**
* Method: delayedRightCall
- * Sets <rightclickTimerId> to null. And optionally triggers the
+ * Sets <rightclickTimerId> to null. And optionally triggers the
* rightclick callback if evt is set.
*/
delayedRightCall: function(evt) {
@@ -18999,13 +20248,13 @@
}
return !this.stopSingle;
},
-
+
/**
* Method: dblclick
* Handle dblclick. For a dblclick, we get two clicks in some browsers
* (FF) and one in others (IE). So we need to always register for
* dblclick to properly handle single clicks.
- *
+ *
* Returns:
* {Boolean} Continue propagating this event.
*/
@@ -19018,7 +20267,7 @@
}
return !this.stopDouble;
},
-
+
/**
* Method: click
* Handle click.
@@ -19033,7 +20282,7 @@
this.clearTimer();
} else {
// set the timer, send evt only if single is true
- //use a clone of the event object because it will no longer
+ //use a clone of the event object because it will no longer
//be a valid event object in IE in the timer callback
var clickEvent = this.single ?
OpenLayers.Util.extend({}, evt) : null;
@@ -19045,7 +20294,7 @@
}
return !this.stopSingle;
},
-
+
/**
* Method: passesTolerance
* Determine whether the event is within the optional pixel tolerance. Note
@@ -19085,7 +20334,7 @@
this.rightclickTimerId = null;
}
},
-
+
/**
* Method: delayedCall
* Sets <timerId> to null. And optionally triggers the click callback if
@@ -19121,8 +20370,9 @@
OpenLayers/Handler/Drag.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -19151,14 +20401,14 @@
* - <OpenLayers.Handler>
*/
OpenLayers.Handler.Drag = OpenLayers.Class(OpenLayers.Handler, {
-
- /**
+
+ /**
* Property: started
* {Boolean} When a mousedown event is received, we want to record it, but
- * not set 'dragging' until the mouse moves after starting.
+ * not set 'dragging' until the mouse moves after starting.
*/
started: false,
-
+
/**
* Property: stopDown
* {Boolean} Stop propagation of mousedown events from getting to listeners
@@ -19166,19 +20416,19 @@
*/
stopDown: true,
- /**
- * Property: dragging
- * {Boolean}
+ /**
+ * Property: dragging
+ * {Boolean}
*/
dragging: false,
- /**
+ /**
* Property: last
* {<OpenLayers.Pixel>} The last pixel location of the drag.
*/
last: null,
- /**
+ /**
* Property: start
* {<OpenLayers.Pixel>} The first pixel location of the drag.
*/
@@ -19189,28 +20439,42 @@
* {Function}
*/
oldOnselectstart: null,
-
+
/**
* Property: interval
- * {Integer} In order to increase performance, an interval (in
- * milliseconds) can be set to reduce the number of drag events
- * called. If set, a new drag event will not be set until the
- * interval has passed.
- * Defaults to 0, meaning no interval.
+ * {Integer} In order to increase performance, an interval (in
+ * milliseconds) can be set to reduce the number of drag events
+ * called. If set, a new drag event will not be set until the
+ * interval has passed.
+ * Defaults to 0, meaning no interval.
*/
interval: 0,
-
+
/**
* Property: timeoutId
* {String} The id of the timeout used for the mousedown interval.
* This is "private", and should be left alone.
*/
timeoutId: null,
+
+ /**
+ * APIProperty: documentDrag
+ * {Boolean} If set to true, the handler will also handle mouse moves when
+ * the cursor has moved out of the map viewport. Default is false.
+ */
+ documentDrag: false,
+
+ /**
+ * Property: documentEvents
+ * {<OpenLayers.Events>} Event instance for observing document events. Will
+ * be set on mouseout if documentDrag is set to true.
+ */
+ documentEvents: null,
/**
* Constructor: OpenLayers.Handler.Drag
* Returns OpenLayers.Handler.Drag
- *
+ *
* Parameters:
* control - {<OpenLayers.Control>} The control that is making use of
* this handler. If a handler is being used without a control, the
@@ -19221,17 +20485,17 @@
* expect to recieve a single argument, the pixel location of the event.
* Callbacks for 'move' and 'done' are supported. You can also speficy
* callbacks for 'down', 'up', and 'out' to respond to those events.
- * options - {Object}
+ * options - {Object}
*/
initialize: function(control, callbacks, options) {
OpenLayers.Handler.prototype.initialize.apply(this, arguments);
},
-
+
/**
* The four methods below (down, move, up, and out) are used by subclasses
* to do their own processing related to these mouse events.
*/
-
+
/**
* Method: down
* This method is called during the handling of the mouse down event.
@@ -19242,7 +20506,7 @@
*/
down: function(evt) {
},
-
+
/**
* Method: move
* This method is called during the handling of the mouse move event.
@@ -19288,7 +20552,7 @@
* Handle mousedown events
*
* Parameters:
- * evt - {Event}
+ * evt - {Event}
*
* Returns:
* {Boolean} Let the event propagate.
@@ -19306,12 +20570,12 @@
this.down(evt);
this.callback("down", [evt.xy]);
OpenLayers.Event.stop(evt);
-
+
if(!this.oldOnselectstart) {
- this.oldOnselectstart = (document.onselectstart) ? document.onselectstart : function() { return true; };
- document.onselectstart = function() {return false;};
+ this.oldOnselectstart = (document.onselectstart) ? document.onselectstart : OpenLayers.Function.True;
}
-
+ document.onselectstart = OpenLayers.Function.False;
+
propagate = !this.stopDown;
} else {
this.started = false;
@@ -19326,13 +20590,23 @@
* Handle mousemove events
*
* Parameters:
- * evt - {Event}
+ * evt - {Event}
*
* Returns:
* {Boolean} Let the event propagate.
*/
mousemove: function (evt) {
if (this.started && !this.timeoutId && (evt.xy.x != this.last.x || evt.xy.y != this.last.y)) {
+ if(this.documentDrag === true && this.documentEvents) {
+ if(evt.element === document) {
+ this.adjustXY(evt);
+ // do setEvent manually because the documentEvents are not
+ // registered with the map
+ this.setEvent(evt);
+ } else {
+ this.destroyDocumentEvents();
+ }
+ }
if (this.interval > 0) {
this.timeoutId = setTimeout(OpenLayers.Function.bind(this.removeTimeout, this), this.interval);
}
@@ -19341,13 +20615,13 @@
this.callback("move", [evt.xy]);
if(!this.oldOnselectstart) {
this.oldOnselectstart = document.onselectstart;
- document.onselectstart = function() {return false;};
+ document.onselectstart = OpenLayers.Function.False;
}
this.last = this.evt.xy;
}
return true;
},
-
+
/**
* Method: removeTimeout
* Private. Called by mousemove() to remove the drag timeout.
@@ -19361,13 +20635,17 @@
* Handle mouseup events
*
* Parameters:
- * evt - {Event}
+ * evt - {Event}
*
* Returns:
* {Boolean} Let the event propagate.
*/
mouseup: function (evt) {
if (this.started) {
+ if(this.documentDrag === true && this.documentEvents) {
+ this.adjustXY(evt);
+ this.destroyDocumentEvents();
+ }
var dragged = (this.start != this.last);
this.started = false;
this.dragging = false;
@@ -19389,27 +20667,39 @@
* Handle mouseout events
*
* Parameters:
- * evt - {Event}
+ * evt - {Event}
*
* Returns:
* {Boolean} Let the event propagate.
*/
mouseout: function (evt) {
if (this.started && OpenLayers.Util.mouseLeft(evt, this.map.div)) {
- var dragged = (this.start != this.last);
- this.started = false;
- this.dragging = false;
- OpenLayers.Element.removeClass(
- this.map.viewPortDiv, "olDragDown"
- );
- this.out(evt);
- this.callback("out", []);
- if(dragged) {
- this.callback("done", [evt.xy]);
+ if(this.documentDrag === true) {
+ this.documentEvents = new OpenLayers.Events(this, document,
+ null, null, {includeXY: true});
+ this.documentEvents.on({
+ mousemove: this.mousemove,
+ mouseup: this.mouseup
+ });
+ OpenLayers.Element.addClass(
+ document.body, "olDragDown"
+ );
+ } else {
+ var dragged = (this.start != this.last);
+ this.started = false;
+ this.dragging = false;
+ OpenLayers.Element.removeClass(
+ this.map.viewPortDiv, "olDragDown"
+ );
+ this.out(evt);
+ this.callback("out", []);
+ if(dragged) {
+ this.callback("done", [evt.xy]);
+ }
+ if(document.onselectstart) {
+ document.onselectstart = this.oldOnselectstart;
+ }
}
- if(document.onselectstart) {
- document.onselectstart = this.oldOnselectstart;
- }
}
return true;
},
@@ -19417,12 +20707,12 @@
/**
* Method: click
* The drag handler captures the click event. If something else registers
- * for clicks on the same element, its listener will not be called
+ * for clicks on the same element, its listener will not be called
* after a drag.
- *
- * Parameters:
- * evt - {Event}
- *
+ *
+ * Parameters:
+ * evt - {Event}
+ *
* Returns:
* {Boolean} Let the event propagate.
*/
@@ -19434,7 +20724,7 @@
/**
* Method: activate
* Activate the handler.
- *
+ *
* Returns:
* {Boolean} The handler was successfully activated.
*/
@@ -19448,9 +20738,9 @@
},
/**
- * Method: deactivate
+ * Method: deactivate
* Deactivate the handler.
- *
+ *
* Returns:
* {Boolean} The handler was successfully deactivated.
*/
@@ -19468,6 +20758,35 @@
}
return deactivated;
},
+
+ /**
+ * Method: adjustXY
+ * Converts event coordinates that are relative to the document body to
+ * ones that are relative to the map viewport. The latter is the default in
+ * OpenLayers.
+ *
+ * Parameters:
+ * evt - {Object}
+ */
+ adjustXY: function(evt) {
+ var pos = OpenLayers.Util.pagePosition(this.map.div);
+ evt.xy.x -= pos[0];
+ evt.xy.y -= pos[1];
+ },
+
+ /**
+ * Method: destroyDocumentEvents
+ * Destroys the events instance that gets added to the document body when
+ * documentDrag is true and the mouse cursor leaves the map viewport while
+ * dragging.
+ */
+ destroyDocumentEvents: function() {
+ OpenLayers.Element.removeClass(
+ document.body, "olDragDown"
+ );
+ this.documentEvents.destroy();
+ this.documentEvents = null;
+ },
CLASS_NAME: "OpenLayers.Handler.Drag"
});
@@ -19475,8 +20794,9 @@
OpenLayers/Handler/Feature.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
@@ -19485,7 +20805,7 @@
*/
/**
- * Class: OpenLayers.Handler.Feature
+ * Class: OpenLayers.Handler.Feature
* Handler to respond to mouse events related to a drawn feature. Callbacks
* with the following keys will be notified of the following events
* associated with features: click, clickout, over, out, and dblclick.
@@ -19531,7 +20851,7 @@
* {<OpenLayers.Pixel>} The location of the last mouseup.
*/
up: null,
-
+
/**
* Property: clickTolerance
* {Number} The number of pixels the mouse can move between mousedown
@@ -19545,7 +20865,7 @@
* Property: geometryTypes
* To restrict dragging to a limited set of geometry types, send a list
* of strings corresponding to the geometry class names.
- *
+ *
* @type Array(String)
*/
geometryTypes: null,
@@ -19576,17 +20896,17 @@
* value of stopUp. Defaults to false.
*/
stopUp: false,
-
+
/**
* Constructor: OpenLayers.Handler.Feature
*
* Parameters:
- * control - {<OpenLayers.Control>}
+ * control - {<OpenLayers.Control>}
* layer - {<OpenLayers.Layer.Vector>}
* callbacks - {Object} An object with a 'over' property whos value is
- * a function to be called when the mouse is over a feature. The
+ * a function to be called when the mouse is over a feature. The
* callback should expect to recieve a single argument, the feature.
- * options - {Object}
+ * options - {Object}
*/
initialize: function(control, layer, callbacks, options) {
OpenLayers.Handler.prototype.initialize.apply(this, [control, callbacks, options]);
@@ -19598,22 +20918,22 @@
* Method: mousedown
* Handle mouse down. Stop propagation if a feature is targeted by this
* event (stops map dragging during feature selection).
- *
+ *
* Parameters:
- * evt - {Event}
+ * evt - {Event}
*/
mousedown: function(evt) {
this.down = evt.xy;
return this.handle(evt) ? !this.stopDown : true;
},
-
+
/**
* Method: mouseup
* Handle mouse up. Stop propagation if a feature is targeted by this
* event.
- *
+ *
* Parameters:
- * evt - {Event}
+ * evt - {Event}
*/
mouseup: function(evt) {
this.up = evt.xy;
@@ -19624,9 +20944,9 @@
* Method: click
* Handle click. Call the "click" callback if click on a feature,
* or the "clickout" callback if click outside any feature.
- *
+ *
* Parameters:
- * evt - {Event}
+ * evt - {Event}
*
* Returns:
* {Boolean}
@@ -19634,14 +20954,14 @@
click: function(evt) {
return this.handle(evt) ? !this.stopClick : true;
},
-
+
/**
* Method: mousemove
* Handle mouse moves. Call the "over" callback if moving in to a feature,
* or the "out" callback if moving out of a feature.
- *
+ *
* Parameters:
- * evt - {Event}
+ * evt - {Event}
*
* Returns:
* {Boolean}
@@ -19649,17 +20969,17 @@
mousemove: function(evt) {
if (!this.callbacks['over'] && !this.callbacks['out']) {
return true;
- }
+ }
this.handle(evt);
return true;
},
-
+
/**
* Method: dblclick
* Handle dblclick. Call the "dblclick" callback if dblclick on a feature.
*
* Parameters:
- * evt - {Event}
+ * evt - {Event}
*
* Returns:
* {Boolean}
@@ -19748,7 +21068,7 @@
}
return handled;
},
-
+
/**
* Method: triggerCallback
* Call the callback keyed in the event map with the supplied arguments.
@@ -19776,7 +21096,7 @@
},
/**
- * Method: activate
+ * Method: activate
* Turn on the handler. Returns false if the handler was already active.
*
* Returns:
@@ -19795,12 +21115,12 @@
}
return activated;
},
-
+
/**
- * Method: deactivate
+ * Method: deactivate
* Turn off the handler. Returns false if the handler was already active.
*
- * Returns:
+ * Returns:
* {Boolean}
*/
deactivate: function() {
@@ -19820,10 +21140,10 @@
}
return deactivated;
},
-
+
/**
* Method handleMapEvents
- *
+ *
* Parameters:
* evt - {Object}
*/
@@ -19832,7 +21152,7 @@
this.moveLayerToTop();
}
},
-
+
/**
* Method: moveLayerToTop
* Moves the layer for this handler to the top, so mouse events can reach
@@ -19842,9 +21162,9 @@
var index = Math.max(this.map.Z_INDEX_BASE['Feature'] - 1,
this.layer.getZIndex()) + 1;
this.layer.setZIndex(index);
-
+
},
-
+
/**
* Method: moveLayerBack
* Moves the layer back to the position determined by the map's layers
@@ -19866,9 +21186,10 @@
OpenLayers/Handler/Hover.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the clear BSD license.
- * See http://svn.openlayers.org/trunk/openlayers/license.txt
- * for the full text of the license. */
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
/**
* @requires OpenLayers/Handler.js
@@ -19880,9 +21201,9 @@
* on the map that aren't DOM elements. For example one can use
* this handler to send WMS/GetFeatureInfo requests as the user
* moves the mouve over the map.
- *
+ *
* Inherits from:
- * - <OpenLayers.Handler>
+ * - <OpenLayers.Handler>
*/
OpenLayers.Handler.Hover = OpenLayers.Class(OpenLayers.Handler, {
@@ -19892,7 +21213,7 @@
* the event is considered a hover. Default is 500.
*/
delay: 500,
-
+
/**
* APIProperty: pixelTolerance
* {Integer} - Maximum number of pixels between mousemoves for
@@ -19919,7 +21240,7 @@
* {Number} - The id of the timer.
*/
timerId: null,
-
+
/**
* Constructor: OpenLayers.Handler.Hover
* Construct a hover handler.
@@ -20052,8 +21373,9 @@
OpenLayers/Handler/MouseWheel.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -20063,18 +21385,18 @@
/**
* Class: OpenLayers.Handler.MouseWheel
* Handler for wheel up/down events.
- *
+ *
* Inherits from:
* - <OpenLayers.Handler>
*/
OpenLayers.Handler.MouseWheel = OpenLayers.Class(OpenLayers.Handler, {
- /**
- * Property: wheelListener
- * {function}
+ /**
+ * Property: wheelListener
+ * {function}
*/
wheelListener: null,
- /**
+ /**
* Property: mousePosition
* {<OpenLayers.Pixel>} mousePosition is necessary because
* evt.clientX/Y is buggy in Moz on wheel events, so we cache and use the
@@ -20083,15 +21405,41 @@
mousePosition: null,
/**
+ * Property: interval
+ * {Integer} In order to increase server performance, an interval (in
+ * milliseconds) can be set to reduce the number of up/down events
+ * called. If set, a new up/down event will not be set until the
+ * interval has passed.
+ * Defaults to 0, meaning no interval.
+ */
+ interval: 0,
+
+ /**
+ * Property: delta
+ * {Integer} When interval is set, delta collects the mousewheel z-deltas
+ * of the events that occur within the interval.
+ * See also the cumulative option
+ */
+ delta: 0,
+
+ /**
+ * Property: cumulative
+ * {Boolean} When interval is set: true to collect all the mousewheel
+ * z-deltas, false to only record the delta direction (positive or
+ * negative)
+ */
+ cumulative: true,
+
+ /**
* Constructor: OpenLayers.Handler.MouseWheel
*
* Parameters:
- * control - {<OpenLayers.Control>}
+ * control - {<OpenLayers.Control>}
* callbacks - {Object} An object containing a single function to be
* called when the drag operation is finished.
* The callback should expect to recieve a single
* argument, the point geometry.
- * options - {Object}
+ * options - {Object}
*/
initialize: function(control, callbacks, options) {
OpenLayers.Handler.prototype.initialize.apply(this, arguments);
@@ -20102,7 +21450,7 @@
/**
* Method: destroy
- */
+ */
destroy: function() {
OpenLayers.Handler.prototype.destroy.apply(this, arguments);
this.wheelListener = null;
@@ -20112,22 +21460,22 @@
* Mouse ScrollWheel code thanks to http://adomas.org/javascript-mouse-wheel/
*/
- /**
+ /**
* Method: onWheelEvent
* Catch the wheel event and handle it xbrowserly
- *
+ *
* Parameters:
- * e - {Event}
+ * e - {Event}
*/
onWheelEvent: function(e){
-
+
// make sure we have a map and check keyboard modifiers
if (!this.map || !this.checkModifiers(e)) {
return;
}
-
- // Ride up the element's DOM hierarchy to determine if it or any of
- // its ancestors was:
+
+ // Ride up the element's DOM hierarchy to determine if it or any of
+ // its ancestors was:
// * specifically marked as scrollable
// * one of our layer divs
// * the map div
@@ -20135,7 +21483,7 @@
var overScrollableDiv = false;
var overLayerDiv = false;
var overMapDiv = false;
-
+
var elem = OpenLayers.Event.element(e);
while((elem != null) && !overMapDiv && !overScrollableDiv) {
@@ -20144,14 +21492,14 @@
if (elem.currentStyle) {
overflow = elem.currentStyle["overflow"];
} else {
- var style =
+ var style =
document.defaultView.getComputedStyle(elem, null);
var overflow = style.getPropertyValue("overflow");
}
- overScrollableDiv = ( overflow &&
+ overScrollableDiv = ( overflow &&
(overflow == "auto") || (overflow == "scroll") );
} catch(err) {
- //sometimes when scrolling in a popup, this causes
+ //sometimes when scrolling in a popup, this causes
// obscure browser error
}
}
@@ -20159,10 +21507,10 @@
if (!overLayerDiv) {
for(var i=0, len=this.map.layers.length; i<len; i++) {
// Are we in the layer div? Note that we have two cases
- // here: one is to catch EventPane layers, which have a
+ // here: one is to catch EventPane layers, which have a
// pane above the layer (layer.pane)
- if (elem == this.map.layers[i].div
- || elem == this.map.layers[i].pane) {
+ if (elem == this.map.layers[i].div
+ || elem == this.map.layers[i].pane) {
overLayerDiv = true;
break;
}
@@ -20172,27 +21520,51 @@
elem = elem.parentNode;
}
-
+
// Logic below is the following:
//
// If we are over a scrollable div or not over the map div:
// * do nothing (let the browser handle scrolling)
//
- // otherwise
- //
- // If we are over the layer div:
+ // otherwise
+ //
+ // If we are over the layer div:
// * zoom/in out
// then
// * kill event (so as not to also scroll the page after zooming)
//
// otherwise
//
- // Kill the event (dont scroll the page if we wheel over the
+ // Kill the event (dont scroll the page if we wheel over the
// layerswitcher or the pan/zoom control)
//
if (!overScrollableDiv && overMapDiv) {
if (overLayerDiv) {
- this.wheelZoom(e);
+ var delta = 0;
+ if (!e) {
+ e = window.event;
+ }
+ if (e.wheelDelta) {
+ delta = e.wheelDelta/120;
+ if (window.opera && window.opera.version() < 9.2) {
+ delta = -delta;
+ }
+ } else if (e.detail) {
+ delta = -e.detail / 3;
+ }
+ this.delta = this.delta + delta;
+
+ if(this.interval) {
+ window.clearTimeout(this._timeoutId);
+ this._timeoutId = window.setTimeout(
+ OpenLayers.Function.bind(function(){
+ this.wheelZoom(e);
+ }, this),
+ this.interval
+ );
+ } else {
+ this.wheelZoom(e);
+ }
}
OpenLayers.Event.stop(e);
}
@@ -20202,58 +21574,48 @@
* Method: wheelZoom
* Given the wheel event, we carry out the appropriate zooming in or out,
* based on the 'wheelDelta' or 'detail' property of the event.
- *
+ *
* Parameters:
* e - {Event}
*/
wheelZoom: function(e) {
-
- var delta = 0;
- if (!e) {
- e = window.event;
- }
- if (e.wheelDelta) {
- delta = e.wheelDelta/120;
- if (window.opera && window.opera.version() < 9.2) {
- delta = -delta;
- }
- } else if (e.detail) {
- delta = -e.detail / 3;
- }
+ var delta = this.delta;
+ this.delta = 0;
+
if (delta) {
- // add the mouse position to the event because mozilla has
- // a bug with clientX and clientY (see
+ // add the mouse position to the event because mozilla has
+ // a bug with clientX and clientY (see
// https://bugzilla.mozilla.org/show_bug.cgi?id=352179)
// getLonLatFromViewPortPx(e) returns wrong values
if (this.mousePosition) {
e.xy = this.mousePosition;
- }
+ }
if (!e.xy) {
// If the mouse hasn't moved over the map yet, then
// we don't have a mouse position (in FF), so we just
// act as if the mouse was at the center of the map.
- // Note that we can tell we are in the map -- and
+ // Note that we can tell we are in the map -- and
// this.map is ensured to be true above.
e.xy = this.map.getPixelFromLonLat(
this.map.getCenter()
);
}
if (delta < 0) {
- this.callback("down", [e, delta]);
+ this.callback("down", [e, this.cumulative ? delta : -1]);
} else {
- this.callback("up", [e, delta]);
+ this.callback("up", [e, this.cumulative ? delta : 1]);
}
}
},
-
+
/**
* Method: mousemove
* Update the stored mousePosition on every move.
- *
+ *
* Parameters:
* evt - {Event} The browser event
*
- * Returns:
+ * Returns:
* {Boolean} Allow event propagation
*/
mousemove: function (evt) {
@@ -20261,7 +21623,7 @@
},
/**
- * Method: activate
+ * Method: activate
*/
activate: function (evt) {
if (OpenLayers.Handler.prototype.activate.apply(this, arguments)) {
@@ -20277,7 +21639,7 @@
},
/**
- * Method: deactivate
+ * Method: deactivate
*/
deactivate: function (evt) {
if (OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {
@@ -20298,8 +21660,9 @@
OpenLayers/Layer.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
@@ -20319,13 +21682,13 @@
*/
id: null,
- /**
+ /**
* APIProperty: name
* {String}
*/
name: null,
- /**
+ /**
* APIProperty: div
* {DOMElement}
*/
@@ -20339,20 +21702,20 @@
/**
* APIProperty: alwaysInRange
- * {Boolean} If a layer's display should not be scale-based, this should
- * be set to true. This will cause the layer, as an overlay, to always
- * be 'active', by always returning true from the calculateInRange()
- * function.
- *
- * If not explicitly specified for a layer, its value will be
- * determined on startup in initResolutions() based on whether or not
- * any scale-specific properties have been set as options on the
- * layer. If no scale-specific options have been set on the layer, we
+ * {Boolean} If a layer's display should not be scale-based, this should
+ * be set to true. This will cause the layer, as an overlay, to always
+ * be 'active', by always returning true from the calculateInRange()
+ * function.
+ *
+ * If not explicitly specified for a layer, its value will be
+ * determined on startup in initResolutions() based on whether or not
+ * any scale-specific properties have been set as options on the
+ * layer. If no scale-specific options have been set on the layer, we
* assume that it should always be in range.
- *
+ *
* See #987 for more info.
*/
- alwaysInRange: null,
+ alwaysInRange: null,
/**
* Constant: EVENT_TYPES
@@ -20384,6 +21747,18 @@
"move", "moveend"],
/**
+ * Constant: RESOLUTION_PROPERTIES
+ * {Array} The properties that are used for calculating resolutions
+ * information.
+ */
+ RESOLUTION_PROPERTIES: [
+ 'scales', 'resolutions',
+ 'maxScale', 'minScale',
+ 'maxResolution', 'minResolution',
+ 'numZoomLevels', 'maxZoomLevel'
+ ],
+
+ /**
* APIProperty: events
* {<OpenLayers.Events>}
*/
@@ -20391,25 +21766,25 @@
/**
* APIProperty: map
- * {<OpenLayers.Map>} This variable is set when the layer is added to
+ * {<OpenLayers.Map>} This variable is set when the layer is added to
* the map, via the accessor function setMap().
*/
map: null,
-
+
/**
* APIProperty: isBaseLayer
- * {Boolean} Whether or not the layer is a base layer. This should be set
+ * {Boolean} Whether or not the layer is a base layer. This should be set
* individually by all subclasses. Default is false
*/
isBaseLayer: false,
-
+
/**
* Property: alpha
- * {Boolean} The layer's images have an alpha channel. Default is false.
+ * {Boolean} The layer's images have an alpha channel. Default is false.
*/
alpha: false,
- /**
+ /**
* APIProperty: displayInLayerSwitcher
* {Boolean} Display the layer's name in the layer switcher. Default is
* true.
@@ -20424,36 +21799,36 @@
/**
* APIProperty: attribution
- * {String} Attribution string, displayed when an
+ * {String} Attribution string, displayed when an
* <OpenLayers.Control.Attribution> has been added to the map.
*/
- attribution: null,
+ attribution: null,
- /**
+ /**
* Property: inRange
- * {Boolean} The current map resolution is within the layer's min/max
- * range. This is set in <OpenLayers.Map.setCenter> whenever the zoom
+ * {Boolean} The current map resolution is within the layer's min/max
+ * range. This is set in <OpenLayers.Map.setCenter> whenever the zoom
* changes.
*/
inRange: false,
-
+
/**
* Propery: imageSize
- * {<OpenLayers.Size>} For layers with a gutter, the image is larger than
+ * {<OpenLayers.Size>} For layers with a gutter, the image is larger than
* the tile by twice the gutter in each dimension.
*/
imageSize: null,
-
+
/**
* Property: imageOffset
- * {<OpenLayers.Pixel>} For layers with a gutter, the image offset
+ * {<OpenLayers.Pixel>} For layers with a gutter, the image offset
* represents displacement due to the gutter.
*/
imageOffset: null,
// OPTIONS
- /**
+ /**
* Property: options
* {Object} An optional object whose properties will be set on the layer.
* Any of the layer properties can be set as a property of the options
@@ -20479,8 +21854,8 @@
* at tile edges to be ignored. Set a gutter value that is equal to
* half the size of the widest symbol that needs to be displayed.
* Defaults to zero. Non-tiled layers always have zero gutter.
- */
- gutter: 0,
+ */
+ gutter: 0,
/**
* APIProperty: projection
@@ -20488,10 +21863,10 @@
* override the default projection string this layer - also set maxExtent,
* maxResolution, and units if appropriate. Can be either a string or
* an <OpenLayers.Projection> object when created -- will be converted
- * to an object when setMap is called if a string is passed.
+ * to an object when setMap is called if a string is passed.
*/
- projection: null,
-
+ projection: null,
+
/**
* APIProperty: units
* {String} The layer map units. Defaults to 'degrees'. Possible values
@@ -20518,7 +21893,7 @@
* maxResolution, maxScale, etc.).
*/
resolutions: null,
-
+
/**
* APIProperty: maxExtent
* {<OpenLayers.Bounds>} The center of these bounds will not stray outside
@@ -20527,18 +21902,18 @@
* requested that falls completely outside of these bounds.
*/
maxExtent: null,
-
+
/**
* APIProperty: minExtent
* {<OpenLayers.Bounds>}
*/
minExtent: null,
-
+
/**
* APIProperty: maxResolution
* {Float} Default max is 360 deg / 256 px, which corresponds to
- * zoom level 0 on gmaps. Specify a different value in the layer
- * options if you are not using a geographic projection and
+ * zoom level 0 on gmaps. Specify a different value in the layer
+ * options if you are not using a geographic projection and
* displaying the whole world.
*/
maxResolution: null,
@@ -20554,13 +21929,13 @@
* {Integer}
*/
numZoomLevels: null,
-
+
/**
* APIProperty: minScale
* {Float}
*/
minScale: null,
-
+
/**
* APIProperty: maxScale
* {Float}
@@ -20569,21 +21944,21 @@
/**
* APIProperty: displayOutsideMaxExtent
- * {Boolean} Request map tiles that are completely outside of the max
+ * {Boolean} Request map tiles that are completely outside of the max
* extent for this layer. Defaults to false.
*/
displayOutsideMaxExtent: false,
/**
* APIProperty: wrapDateLine
- * {Boolean} #487 for more info.
+ * {Boolean} #487 for more info.
*/
wrapDateLine: false,
-
+
/**
* APIProperty: transitionEffect
* {String} The transition effect to use when the map is panned or
- * zoomed.
+ * zoomed.
*
* There are currently two supported values:
* - *null* No transition effect (the default).
@@ -20593,15 +21968,22 @@
* resized tiles.
*/
transitionEffect: null,
-
+
/**
* Property: SUPPORTED_TRANSITIONS
- * {Array} An immutable (that means don't change it!) list of supported
+ * {Array} An immutable (that means don't change it!) list of supported
* transitionEffect values.
*/
SUPPORTED_TRANSITIONS: ['resize'],
/**
+ * Property: metadata
+ * {Object} This object can be used to store additional information on a
+ * layer object.
+ */
+ metadata: {},
+
+ /**
* Constructor: OpenLayers.Layer
*
* Parameters:
@@ -20613,7 +21995,7 @@
this.addOptions(options);
this.name = name;
-
+
if (this.id == null) {
this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
@@ -20623,7 +22005,7 @@
this.div.style.height = "100%";
this.div.dir = "ltr";
- this.events = new OpenLayers.Events(this, this.div,
+ this.events = new OpenLayers.Events(this, this.div,
this.EVENT_TYPES);
if(this.eventListeners instanceof Object) {
this.events.on(this.eventListeners);
@@ -20635,7 +22017,7 @@
this.displayOutsideMaxExtent = true;
}
},
-
+
/**
* Method: destroy
* Destroy is a destructor: this is to alleviate cyclic references which
@@ -20667,7 +22049,7 @@
this.eventListeners = null;
this.events = null;
},
-
+
/**
* Method: clone
*
@@ -20678,22 +22060,39 @@
* {<OpenLayers.Layer>} An exact clone of this <OpenLayers.Layer>
*/
clone: function (obj) {
-
+
if (obj == null) {
- obj = new OpenLayers.Layer(this.name, this.options);
+ obj = new OpenLayers.Layer(this.name, this.getOptions());
}
-
+
// catch any randomly tagged-on properties
OpenLayers.Util.applyDefaults(obj, this);
-
+
// a cloned layer should never have its map property set
- // because it has not been added to a map yet.
+ // because it has not been added to a map yet.
obj.map = null;
-
+
return obj;
},
-
+
/**
+ * Method: getOptions
+ * Extracts an object from the layer with the properties that were set as
+ * options, but updates them with the values currently set on the
+ * instance.
+ *
+ * Returns:
+ * {Object} the <options> of the layer, representing the current state.
+ */
+ getOptions: function() {
+ var options = {};
+ for(var o in this.options) {
+ options[o] = this[o];
+ }
+ return options;
+ },
+
+ /**
* APIMethod: setName
* Sets the new layer name for this layer. Can trigger a changelayer event
* on the map.
@@ -20711,11 +22110,11 @@
});
}
}
- },
-
+ },
+
/**
* APIMethod: addOptions
- *
+ *
* Parameters:
* newOptions - {Object}
*/
@@ -20730,6 +22129,34 @@
// add new options to this
OpenLayers.Util.extend(this, newOptions);
+
+ // make sure this.projection references a projection object
+ if(typeof this.projection == "string") {
+ this.projection = new OpenLayers.Projection(this.projection);
+ }
+
+ // get the units from the projection, if we have a projection
+ // and it it has units
+ if(this.projection && this.projection.getUnits()) {
+ this.units = this.projection.getUnits();
+ }
+
+ // re-initialize resolutions if necessary, i.e. if any of the
+ // properties of the "properties" array defined below is set
+ // in the new options
+ if(this.map) {
+ var properties = this.RESOLUTION_PROPERTIES.concat(
+ ["projection", "units", "minExtent", "maxExtent"]
+ );
+ for(var o in newOptions) {
+ if(newOptions.hasOwnProperty(o) &&
+ OpenLayers.Util.indexOf(properties, o) >= 0) {
+
+ this.initResolutions();
+ break;
+ }
+ }
+ }
},
/**
@@ -20737,7 +22164,7 @@
* This function can be implemented by subclasses
*/
onMapResize: function() {
- //this function can be implemented by subclasses
+ //this function can be implemented by subclasses
},
/**
@@ -20770,7 +22197,7 @@
/**
* Method: moveTo
- *
+ *
* Parameters:
* bound - {<OpenLayers.Bounds>}
* zoomChanged - {Boolean} Tells when zoom has changed, as layers have to
@@ -20788,26 +22215,27 @@
/**
* Method: setMap
* Set the map property for the layer. This is done through an accessor
- * so that subclasses can override this and take special action once
- * they have their map variable set.
- *
- * Here we take care to bring over any of the necessary default
- * properties from the map.
- *
+ * so that subclasses can override this and take special action once
+ * they have their map variable set.
+ *
+ * Here we take care to bring over any of the necessary default
+ * properties from the map.
+ *
* Parameters:
* map - {<OpenLayers.Map>}
*/
setMap: function(map) {
if (this.map == null) {
-
+
this.map = map;
-
+
// grab some essential layer data from the map if it hasn't already
// been set
this.maxExtent = this.maxExtent || this.map.maxExtent;
+ this.minExtent = this.minExtent || this.map.minExtent;
+
this.projection = this.projection || this.map.projection;
-
- if (this.projection && typeof this.projection == "string") {
+ if (typeof this.projection == "string") {
this.projection = new OpenLayers.Projection(this.projection);
}
@@ -20815,20 +22243,20 @@
// to properties.
this.units = this.projection.getUnits() ||
this.units || this.map.units;
-
+
this.initResolutions();
-
+
if (!this.isBaseLayer) {
this.inRange = this.calculateInRange();
var show = ((this.visibility) && (this.inRange));
this.div.style.display = show ? "" : "none";
}
-
+
// deal with gutters
this.setTileSize();
}
},
-
+
/**
* Method: afterAdd
* Called at the end of the map.addLayer sequence. At this point, the map
@@ -20836,39 +22264,44 @@
*/
afterAdd: function() {
},
-
+
/**
* APIMethod: removeMap
- * Just as setMap() allows each layer the possibility to take a
+ * Just as setMap() allows each layer the possibility to take a
* personalized action on being added to the map, removeMap() allows
- * each layer to take a personalized action on being removed from it.
+ * each layer to take a personalized action on being removed from it.
* For now, this will be mostly unused, except for the EventPane layer,
* which needs this hook so that it can remove the special invisible
- * pane.
- *
+ * pane.
+ *
* Parameters:
* map - {<OpenLayers.Map>}
*/
removeMap: function(map) {
//to be overridden by subclasses
},
-
+
/**
* APIMethod: getImageSize
*
+ * Parameters:
+ * bounds - {<OpenLayers.Bounds>} optional tile bounds, can be used
+ * by subclasses that have to deal with different tile sizes at the
+ * layer extent edges (e.g. Zoomify)
+ *
* Returns:
- * {<OpenLayers.Size>} The size that the image should be, taking into
+ * {<OpenLayers.Size>} The size that the image should be, taking into
* account gutters.
- */
- getImageSize: function() {
- return (this.imageSize || this.tileSize);
- },
-
+ */
+ getImageSize: function(bounds) {
+ return (this.imageSize || this.tileSize);
+ },
+
/**
* APIMethod: setTileSize
* Set the tile size based on the map size. This also sets layer.imageSize
* and layer.imageOffset for use by Tile.Image.
- *
+ *
* Parameters:
* size - {<OpenLayers.Size>}
*/
@@ -20884,16 +22317,16 @@
// this.name + ": layers with " +
// "gutters need non-null tile sizes");
//}
- this.imageOffset = new OpenLayers.Pixel(-this.gutter,
- -this.gutter);
- this.imageSize = new OpenLayers.Size(tileSize.w + (2*this.gutter),
- tileSize.h + (2*this.gutter));
+ this.imageOffset = new OpenLayers.Pixel(-this.gutter,
+ -this.gutter);
+ this.imageSize = new OpenLayers.Size(tileSize.w + (2*this.gutter),
+ tileSize.h + (2*this.gutter));
}
},
/**
* APIMethod: getVisibility
- *
+ *
* Returns:
* {Boolean} The layer should be displayed (if in range).
*/
@@ -20901,18 +22334,18 @@
return this.visibility;
},
- /**
+ /**
* APIMethod: setVisibility
- * Set the visibility flag for the layer and hide/show & redraw
+ * Set the visibility flag for the layer and hide/show & redraw
* accordingly. Fire event unless otherwise specified
- *
+ *
* Note that visibility is no longer simply whether or not the layer's
- * style.display is set to "block". Now we store a 'visibility' state
- * property on the layer class, this allows us to remember whether or
- * not we *desire* for a layer to be visible. In the case where the
- * map's resolution is out of the layer's range, this desire may be
+ * style.display is set to "block". Now we store a 'visibility' state
+ * property on the layer class, this allows us to remember whether or
+ * not we *desire* for a layer to be visible. In the case where the
+ * map's resolution is out of the layer's range, this desire may be
* subverted.
- *
+ *
* Parameters:
* visible - {Boolean} Whether or not to display the layer (if in range)
*/
@@ -20931,26 +22364,25 @@
}
},
- /**
+ /**
* APIMethod: display
* Hide or show the Layer
- *
+ *
* Parameters:
* display - {Boolean}
*/
display: function(display) {
- var inRange = this.calculateInRange();
if (display != (this.div.style.display != "none")) {
- this.div.style.display = (display && inRange) ? "block" : "none";
+ this.div.style.display = (display && this.calculateInRange()) ? "block" : "none";
}
},
/**
* APIMethod: calculateInRange
- *
+ *
* Returns:
* {Boolean} The layer is displayable at the current map's current
- * resolution. Note that if 'alwaysInRange' is true for the layer,
+ * resolution. Note that if 'alwaysInRange' is true for the layer,
* this function will always return true.
*/
calculateInRange: function() {
@@ -20968,9 +22400,9 @@
return inRange;
},
- /**
+ /**
* APIMethod: setIsBaseLayer
- *
+ *
* Parameters:
* isBaseLayer - {Boolean}
*/
@@ -20990,205 +22422,263 @@
/* Baselayer Functions */
/* */
/********************************************************/
-
- /**
+
+ /**
* Method: initResolutions
- * This method's responsibility is to set up the 'resolutions' array
+ * This method's responsibility is to set up the 'resolutions' array
* for the layer -- this array is what the layer will use to interface
- * between the zoom levels of the map and the resolution display
+ * between the zoom levels of the map and the resolution display
* of the layer.
- *
+ *
* The user has several options that determine how the array is set up.
- *
- * For a detailed explanation, see the following wiki from the
+ *
+ * For a detailed explanation, see the following wiki from the
* openlayers.org homepage:
* http://trac.openlayers.org/wiki/SettingZoomLevels
*/
initResolutions: function() {
- // These are the relevant options which are used for calculating
- // resolutions information.
+ // ok we want resolutions, here's our strategy:
//
- var props = new Array(
- 'projection', 'units',
- 'scales', 'resolutions',
- 'maxScale', 'minScale',
- 'maxResolution', 'minResolution',
- 'minExtent', 'maxExtent',
- 'numZoomLevels', 'maxZoomLevel'
- );
+ // 1. if resolutions are defined in the layer config, use them
+ // 2. else, if scales are defined in the layer config then derive
+ // resolutions from these scales
+ // 3. else, attempt to calculate resolutions from maxResolution,
+ // minResolution, numZoomLevels, maxZoomLevel set in the
+ // layer config
+ // 4. if we still don't have resolutions, and if resolutions
+ // are defined in the same, use them
+ // 5. else, if scales are defined in the map then derive
+ // resolutions from these scales
+ // 6. else, attempt to calculate resolutions from maxResolution,
+ // minResolution, numZoomLevels, maxZoomLevel set in the
+ // map
+ // 7. hope for the best!
- //these are the properties which do *not* imply that user wishes
- // this layer to be scale-dependant
- var notScaleProps = ['projection', 'units'];
+ var i, len;
+ var props = {}, alwaysInRange = true;
- //should the layer be scale-dependant? default is false -- this will
- // only be set true if we find that the user has specified a property
- // from the 'props' array that is not in 'notScaleProps'
- var useInRange = false;
-
- // First we create a new object where we will store all of the
- // resolution-related properties that we find in either the layer's
- // 'options' array or from the map.
- //
- var confProps = {};
- for(var i=0, len=props.length; i<len; i++) {
- var property = props[i];
-
- // If the layer had one of these properties set *and* it is
- // a scale property (is not a non-scale property), then we assume
- // the user did intend to use scale-dependant display (useInRange).
- if (this.options[property] &&
- OpenLayers.Util.indexOf(notScaleProps, property) == -1) {
- useInRange = true;
+ // get resolution data from layer config
+ // (we also set alwaysInRange in the layer as appropriate)
+ for(i=0, len=this.RESOLUTION_PROPERTIES.length; i<len; i++) {
+ var p = this.RESOLUTION_PROPERTIES[i];
+ props[p] = this.options[p];
+ if(alwaysInRange && this.options[p]) {
+ alwaysInRange = false;
}
+ }
+ if(this.alwaysInRange == null) {
+ this.alwaysInRange = alwaysInRange;
+ }
- confProps[property] = this.options[property] || this.map[property];
+ // if we don't have resolutions then attempt to derive them from scales
+ if(props.resolutions == null) {
+ props.resolutions = this.resolutionsFromScales(props.scales);
}
- //only automatically set 'alwaysInRange' if the user hasn't already
- // set it (to true or false, since the default is null). If user did
- // not intend to use scale-dependant display then we set they layer
- // as alwaysInRange. This means calculateInRange() will always return
- // true and the layer will never be turned off due to scale changes.
- //
- if (this.alwaysInRange == null) {
- this.alwaysInRange = !useInRange;
+ // if we still don't have resolutions then attempt to calculate them
+ if(props.resolutions == null) {
+ props.resolutions = this.calculateResolutions(props);
}
- // Do not use the scales array set at the map level if
- // either minScale or maxScale or both are set at the
- // layer level
- if ((this.options.minScale != null ||
- this.options.maxScale != null) &&
- this.options.scales == null) {
-
- confProps.scales = null;
+ // if we couldn't calculate resolutions then we look at we have
+ // in the map
+ if(props.resolutions == null) {
+ for(i=0, len=this.RESOLUTION_PROPERTIES.length; i<len; i++) {
+ var p = this.RESOLUTION_PROPERTIES[i];
+ props[p] = this.options[p] != null ?
+ this.options[p] : this.map[p];
+ }
+ if(props.resolutions == null) {
+ props.resolutions = this.resolutionsFromScales(props.scales);
+ }
+ if(props.resolutions == null) {
+ props.resolutions = this.calculateResolutions(props);
+ }
}
- // Do not use the resolutions array set at the map level if
- // either minResolution or maxResolution or both are set at the
- // layer level
- if ((this.options.minResolution != null ||
- this.options.maxResolution != null) &&
- this.options.resolutions == null) {
- confProps.resolutions = null;
+ // ok, we new need to set properties in the instance
+
+ // get maxResolution from the config if it's defined there
+ var maxResolution;
+ if(this.options.maxResolution &&
+ this.options.maxResolution !== "auto") {
+ maxResolution = this.options.maxResolution;
}
+ if(this.options.minScale) {
+ maxResolution = OpenLayers.Util.getResolutionFromScale(
+ this.options.minScale, this.units);
+ }
- // If numZoomLevels hasn't been set and the maxZoomLevel *has*,
- // then use maxZoomLevel to calculate numZoomLevels
- //
- if ( (!confProps.numZoomLevels) && (confProps.maxZoomLevel) ) {
- confProps.numZoomLevels = confProps.maxZoomLevel + 1;
+ // get minResolution from the config if it's defined there
+ var minResolution;
+ if(this.options.minResolution &&
+ this.options.minResolution !== "auto") {
+ minResolution = this.options.minResolution;
}
+ if(this.options.maxScale) {
+ minResolution = OpenLayers.Util.getResolutionFromScale(
+ this.options.maxScale, this.units);
+ }
- // First off, we take whatever hodge-podge of values we have and
- // calculate/distill them down into a resolutions[] array
- //
- if ((confProps.scales != null) || (confProps.resolutions != null)) {
- //preset levels
- if (confProps.scales != null) {
- confProps.resolutions = [];
- for(var i=0, len=confProps.scales.length; i<len; i++) {
- var scale = confProps.scales[i];
- confProps.resolutions[i] =
- OpenLayers.Util.getResolutionFromScale(scale,
- confProps.units);
- }
- }
- confProps.numZoomLevels = confProps.resolutions.length;
+ if(props.resolutions) {
- } else {
- //maxResolution and numZoomLevels based calculation
+ //sort resolutions array descendingly
+ props.resolutions.sort(function(a, b) {
+ return (b - a);
+ });
- // determine maxResolution
- if (confProps.minScale) {
- confProps.maxResolution =
- OpenLayers.Util.getResolutionFromScale(confProps.minScale,
- confProps.units);
- } else if (confProps.maxResolution == "auto") {
- var viewSize = this.map.getSize();
- var wRes = confProps.maxExtent.getWidth() / viewSize.w;
- var hRes = confProps.maxExtent.getHeight()/ viewSize.h;
- confProps.maxResolution = Math.max(wRes, hRes);
+ // if we still don't have a maxResolution get it from the
+ // resolutions array
+ if(!maxResolution) {
+ maxResolution = props.resolutions[0];
}
- // determine minResolution
- if (confProps.maxScale != null) {
- confProps.minResolution =
- OpenLayers.Util.getResolutionFromScale(confProps.maxScale,
- confProps.units);
- } else if ( (confProps.minResolution == "auto") &&
- (confProps.minExtent != null) ) {
- var viewSize = this.map.getSize();
- var wRes = confProps.minExtent.getWidth() / viewSize.w;
- var hRes = confProps.minExtent.getHeight()/ viewSize.h;
- confProps.minResolution = Math.max(wRes, hRes);
+ // if we still don't have a minResolution get it from the
+ // resolutions array
+ if(!minResolution) {
+ var lastIdx = props.resolutions.length - 1;
+ minResolution = props.resolutions[lastIdx];
}
+ }
- // determine numZoomLevels if not already set on the layer
- // this gives numZoomLevels assuming approximately base 2 scaling
- if (confProps.minResolution != null &&
- this.options.numZoomLevels == undefined) {
- var ratio = confProps.maxResolution / confProps.minResolution;
- confProps.numZoomLevels =
- Math.floor(Math.log(ratio) / Math.log(2)) + 1;
+ this.resolutions = props.resolutions;
+ if(this.resolutions) {
+ len = this.resolutions.length;
+ this.scales = new Array(len);
+ for(i=0; i<len; i++) {
+ this.scales[i] = OpenLayers.Util.getScaleFromResolution(
+ this.resolutions[i], this.units);
}
+ this.numZoomLevels = len;
+ }
+ this.minResolution = minResolution;
+ if(minResolution) {
+ this.maxScale = OpenLayers.Util.getScaleFromResolution(
+ minResolution, this.units);
+ }
+ this.maxResolution = maxResolution;
+ if(maxResolution) {
+ this.minScale = OpenLayers.Util.getScaleFromResolution(
+ maxResolution, this.units);
+ }
+ },
- // now we have numZoomLevels and maxResolution,
- // we can populate the resolutions array
- confProps.resolutions = new Array(confProps.numZoomLevels);
- var base = 2;
- if(typeof confProps.minResolution == "number" &&
- confProps.numZoomLevels > 1) {
- /**
- * If maxResolution and minResolution are set (or related
- * scale properties), we calculate the base for exponential
- * scaling that starts at maxResolution and ends at
- * minResolution in numZoomLevels steps.
- */
- base = Math.pow(
- (confProps.maxResolution / confProps.minResolution),
- (1 / (confProps.numZoomLevels - 1))
- );
- }
- for (var i=0; i < confProps.numZoomLevels; i++) {
- var res = confProps.maxResolution / Math.pow(base, i);
- confProps.resolutions[i] = res;
- }
+ /**
+ * Method: resolutionsFromScales
+ * Derive resolutions from scales.
+ *
+ * Parameters:
+ * scales - {Array(Number)} Scales
+ *
+ * Returns
+ * {Array(Number)} Resolutions
+ */
+ resolutionsFromScales: function(scales) {
+ if(scales == null) {
+ return;
}
+ var resolutions, i, len;
+ len = scales.length;
+ resolutions = new Array(len);
+ for(i=0; i<len; i++) {
+ resolutions[i] = OpenLayers.Util.getResolutionFromScale(
+ scales[i], this.units);
+ }
+ return resolutions;
+ },
- //sort resolutions array ascendingly
- //
- confProps.resolutions.sort( function(a, b) { return(b-a); } );
+ /**
+ * Method: calculateResolutions
+ * Calculate resolutions based on the provided properties.
+ *
+ * Parameters:
+ * props - {Object} Properties
+ *
+ * Return:
+ * {Array({Number})} Array of resolutions.
+ */
+ calculateResolutions: function(props) {
- // now set our newly calculated values back to the layer
- // Note: We specifically do *not* set them to layer.options, which we
- // will preserve as it was when we added this layer to the map.
- // this way cloned layers reset themselves to new map div
- // dimensions)
- //
+ // determine maxResolution
+ var maxResolution = props.maxResolution;
+ if(props.minScale != null) {
+ maxResolution =
+ OpenLayers.Util.getResolutionFromScale(props.minScale,
+ this.units);
+ } else if(maxResolution == "auto" && this.maxExtent != null) {
+ var viewSize = this.map.getSize();
+ var wRes = this.maxExtent.getWidth() / viewSize.w;
+ var hRes = this.maxExtent.getHeight() / viewSize.h;
+ maxResolution = Math.max(wRes, hRes);
+ }
- this.resolutions = confProps.resolutions;
- this.maxResolution = confProps.resolutions[0];
- var lastIndex = confProps.resolutions.length - 1;
- this.minResolution = confProps.resolutions[lastIndex];
+ // determine minResolution
+ var minResolution = props.minResolution;
+ if(props.maxScale != null) {
+ minResolution =
+ OpenLayers.Util.getResolutionFromScale(props.maxScale,
+ this.units);
+ } else if(props.minResolution == "auto" && this.minExtent != null) {
+ var viewSize = this.map.getSize();
+ var wRes = this.minExtent.getWidth() / viewSize.w;
+ var hRes = this.minExtent.getHeight()/ viewSize.h;
+ minResolution = Math.max(wRes, hRes);
+ }
- this.scales = [];
- for(var i=0, len=confProps.resolutions.length; i<len; i++) {
- this.scales[i] =
- OpenLayers.Util.getScaleFromResolution(confProps.resolutions[i],
- confProps.units);
+ // determine numZoomLevels
+ var maxZoomLevel = props.maxZoomLevel;
+ var numZoomLevels = props.numZoomLevels;
+ if(typeof minResolution === "number" &&
+ typeof maxResolution === "number" && numZoomLevels === undefined) {
+ var ratio = maxResolution / minResolution;
+ numZoomLevels = Math.floor(Math.log(ratio) / Math.log(2)) + 1;
+ } else if(numZoomLevels === undefined && maxZoomLevel != null) {
+ numZoomLevels = maxZoomLevel + 1;
}
- this.minScale = this.scales[0];
- this.maxScale = this.scales[this.scales.length - 1];
- this.numZoomLevels = confProps.numZoomLevels;
+ // are we able to calculate resolutions?
+ if(typeof numZoomLevels !== "number" || numZoomLevels <= 0 ||
+ (typeof maxResolution !== "number" &&
+ typeof minResolution !== "number")) {
+ return;
+ }
+
+ // now we have numZoomLevels and at least one of maxResolution
+ // or minResolution, we can populate the resolutions array
+
+ var resolutions = new Array(numZoomLevels);
+ var base = 2;
+ if(typeof minResolution == "number" &&
+ typeof maxResolution == "number") {
+ // if maxResolution and minResolution are set, we calculate
+ // the base for exponential scaling that starts at
+ // maxResolution and ends at minResolution in numZoomLevels
+ // steps.
+ base = Math.pow(
+ (maxResolution / minResolution),
+ (1 / (numZoomLevels - 1))
+ );
+ }
+
+ var i;
+ if(typeof maxResolution === "number") {
+ for(i=0; i<numZoomLevels; i++) {
+ resolutions[i] = maxResolution / Math.pow(base, i);
+ }
+ } else {
+ for(i=0; i<numZoomLevels; i++) {
+ resolutions[numZoomLevels - 1 - i] =
+ minResolution * Math.pow(base, i);
+ }
+ }
+
+ return resolutions;
},
/**
* APIMethod: getResolution
- *
+ *
* Returns:
* {Float} The currently selected resolution of the map, taken from the
* resolutions array, indexed by current zoom level.
@@ -21198,11 +22688,11 @@
return this.getResolutionForZoom(zoom);
},
- /**
+ /**
* APIMethod: getExtent
- *
+ *
* Returns:
- * {<OpenLayers.Bounds>} A Bounds object which represents the lon/lat
+ * {<OpenLayers.Bounds>} A Bounds object which represents the lon/lat
* bounds of the current viewPort.
*/
getExtent: function() {
@@ -21214,18 +22704,18 @@
/**
* APIMethod: getZoomForExtent
- *
+ *
* Parameters:
* bounds - {<OpenLayers.Bounds>}
- * closest - {Boolean} Find the zoom level that most closely fits the
- * specified bounds. Note that this may result in a zoom that does
+ * closest - {Boolean} Find the zoom level that most closely fits the
+ * specified bounds. Note that this may result in a zoom that does
* not exactly contain the entire extent.
* Default is false.
*
* Returns:
- * {Integer} The index of the zoomLevel (entry in the resolutions array)
- * for the passed-in extent. We do this by calculating the ideal
- * resolution for the given extent (based on the map size) and then
+ * {Integer} The index of the zoomLevel (entry in the resolutions array)
+ * for the passed-in extent. We do this by calculating the ideal
+ * resolution for the given extent (based on the map size) and then
* calling getZoomForResolution(), passing along the 'closest'
* parameter.
*/
@@ -21236,12 +22726,12 @@
return this.getZoomForResolution(idealResolution, closest);
},
-
- /**
+
+ /**
* Method: getDataExtent
* Calculates the max extent which includes all of the data for the layer.
* This function is to be implemented by subclasses.
- *
+ *
* Returns:
* {<OpenLayers.Bounds>}
*/
@@ -21251,10 +22741,10 @@
/**
* APIMethod: getResolutionForZoom
- *
+ *
* Parameter:
* zoom - {Float}
- *
+ *
* Returns:
* {Float} A suitable resolution for the specified zoom.
*/
@@ -21274,20 +22764,20 @@
/**
* APIMethod: getZoomForResolution
- *
+ *
* Parameters:
* resolution - {Float}
- * closest - {Boolean} Find the zoom level that corresponds to the absolute
+ * closest - {Boolean} Find the zoom level that corresponds to the absolute
* closest resolution, which may result in a zoom whose corresponding
* resolution is actually smaller than we would have desired (if this
* is being called from a getZoomForExtent() call, then this means that
- * the returned zoom index might not actually contain the entire
+ * the returned zoom index might not actually contain the entire
* extent specified... but it'll be close).
* Default is false.
- *
+ *
* Returns:
- * {Integer} The index of the zoomLevel (entry in the resolutions array)
- * that corresponds to the best fit resolution given the passed in
+ * {Integer} The index of the zoomLevel (entry in the resolutions array)
+ * that corresponds to the best fit resolution given the passed in
* value and the 'closest' specification.
*/
getZoomForResolution: function(resolution, closest) {
@@ -21319,7 +22809,7 @@
} else {
var diff;
var minDiff = Number.POSITIVE_INFINITY;
- for(var i=0, len=this.resolutions.length; i<len; i++) {
+ for(var i=0, len=this.resolutions.length; i<len; i++) {
if (closest) {
diff = Math.abs(this.resolutions[i] - resolution);
if (diff > minDiff) {
@@ -21336,15 +22826,15 @@
}
return zoom;
},
-
+
/**
* APIMethod: getLonLatFromViewPortPx
- *
+ *
* Parameters:
* viewPortPx - {<OpenLayers.Pixel>}
*
* Returns:
- * {<OpenLayers.LonLat>} An OpenLayers.LonLat which is the passed-in
+ * {<OpenLayers.LonLat>} An OpenLayers.LonLat which is the passed-in
* view port <OpenLayers.Pixel>, translated into lon/lat by the layer.
*/
getLonLatFromViewPortPx: function (viewPortPx) {
@@ -21354,12 +22844,12 @@
var center = this.map.getCenter();
if (center) {
var res = this.map.getResolution();
-
+
var delta_x = viewPortPx.x - (size.w / 2);
var delta_y = viewPortPx.y - (size.h / 2);
-
+
lonlat = new OpenLayers.LonLat(center.lon + delta_x * res ,
- center.lat - delta_y * res);
+ center.lat - delta_y * res);
if (this.wrapDateLine) {
lonlat = lonlat.wrapDateLine(this.maxExtent);
@@ -21373,31 +22863,31 @@
* APIMethod: getViewPortPxFromLonLat
* Returns a pixel location given a map location. This method will return
* fractional pixel values.
- *
+ *
* Parameters:
* lonlat - {<OpenLayers.LonLat>}
*
- * Returns:
- * {<OpenLayers.Pixel>} An <OpenLayers.Pixel> which is the passed-in
+ * Returns:
+ * {<OpenLayers.Pixel>} An <OpenLayers.Pixel> which is the passed-in
* <OpenLayers.LonLat>,translated into view port pixels.
*/
getViewPortPxFromLonLat: function (lonlat) {
- var px = null;
+ var px = null;
if (lonlat != null) {
var resolution = this.map.getResolution();
var extent = this.map.getExtent();
px = new OpenLayers.Pixel(
(1/resolution * (lonlat.lon - extent.left)),
(1/resolution * (extent.top - lonlat.lat))
- );
+ );
}
return px;
},
-
+
/**
* APIMethod: setOpacity
* Sets the opacity for the entire layer (all images)
- *
+ *
* Parameter:
* opacity - {Float}
*/
@@ -21406,28 +22896,34 @@
this.opacity = opacity;
for(var i=0, len=this.div.childNodes.length; i<len; ++i) {
var element = this.div.childNodes[i].firstChild;
- OpenLayers.Util.modifyDOMElement(element, null, null, null,
+ OpenLayers.Util.modifyDOMElement(element, null, null, null,
null, null, null, opacity);
}
+ if (this.map != null) {
+ this.map.events.triggerEvent("changelayer", {
+ layer: this,
+ property: "opacity"
+ });
+ }
}
},
/**
* Method: getZIndex
- *
- * Returns:
+ *
+ * Returns:
* {Integer} the z-index of this layer
- */
+ */
getZIndex: function () {
return this.div.style.zIndex;
},
/**
* Method: setZIndex
- *
- * Parameters:
+ *
+ * Parameters:
* zIndex - {Integer}
- */
+ */
setZIndex: function (zIndex) {
this.div.style.zIndex = zIndex;
},
@@ -21435,18 +22931,18 @@
/**
* Method: adjustBounds
* This function will take a bounds, and if wrapDateLine option is set
- * on the layer, it will return a bounds which is wrapped around the
- * world. We do not wrap for bounds which *cross* the
- * maxExtent.left/right, only bounds which are entirely to the left
+ * on the layer, it will return a bounds which is wrapped around the
+ * world. We do not wrap for bounds which *cross* the
+ * maxExtent.left/right, only bounds which are entirely to the left
* or entirely to the right.
- *
+ *
* Parameters:
* bounds - {<OpenLayers.Bounds>}
*/
adjustBounds: function (bounds) {
if (this.gutter) {
- // Adjust the extent of a bounds in map units by the
+ // Adjust the extent of a bounds in map units by the
// layer's gutter in pixels.
var mapGutter = this.gutter * this.map.getResolution();
bounds = new OpenLayers.Bounds(bounds.left - mapGutter,
@@ -21457,11 +22953,11 @@
if (this.wrapDateLine) {
// wrap around the date line, within the limits of rounding error
- var wrappingOptions = {
+ var wrappingOptions = {
'rightTolerance':this.getResolution()
- };
+ };
bounds = bounds.wrapDateLine(this.maxExtent, wrappingOptions);
-
+
}
return bounds;
},
@@ -21472,8 +22968,9 @@
OpenLayers/Marker/Box.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
@@ -21485,29 +22982,29 @@
* Class: OpenLayers.Marker.Box
*
* Inherits from:
- * - <OpenLayers.Marker>
+ * - <OpenLayers.Marker>
*/
OpenLayers.Marker.Box = OpenLayers.Class(OpenLayers.Marker, {
- /**
- * Property: bounds
- * {<OpenLayers.Bounds>}
+ /**
+ * Property: bounds
+ * {<OpenLayers.Bounds>}
*/
bounds: null,
- /**
- * Property: div
- * {DOMElement}
+ /**
+ * Property: div
+ * {DOMElement}
*/
div: null,
-
- /**
+
+ /**
* Constructor: OpenLayers.Marker.Box
*
* Parameters:
- * bounds - {<OpenLayers.Bounds>}
- * borderColor - {String}
- * borderWidth - {int}
+ * bounds - {<OpenLayers.Bounds>}
+ * borderColor - {String}
+ * borderWidth - {int}
*/
initialize: function(bounds, borderColor, borderWidth) {
this.bounds = bounds;
@@ -21518,8 +23015,8 @@
},
/**
- * Method: destroy
- */
+ * Method: destroy
+ */
destroy: function() {
this.bounds = null;
@@ -21528,10 +23025,10 @@
OpenLayers.Marker.prototype.destroy.apply(this, arguments);
},
- /**
+ /**
* Method: setBorder
* Allow the user to change the box's color and border width
- *
+ *
* Parameters:
* color - {String} Default is "red"
* width - {int} Default is 2
@@ -21545,26 +23042,26 @@
}
this.div.style.border = width + "px solid " + color;
},
-
- /**
+
+ /**
* Method: draw
- *
+ *
* Parameters:
- * px - {<OpenLayers.Pixel>}
- * sz - {<OpenLayers.Size>}
- *
- * Returns:
- * {DOMElement} A new DOM Image with this marker´s icon set at the
+ * px - {<OpenLayers.Pixel>}
+ * sz - {<OpenLayers.Size>}
+ *
+ * Returns:
+ * {DOMElement} A new DOM Image with this marker´s icon set at the
* location passed-in
*/
draw: function(px, sz) {
OpenLayers.Util.modifyDOMElement(this.div, null, px, sz);
return this.div;
- },
+ },
/**
* Method: onScreen
- *
+ *
* Rreturn:
* {Boolean} Whether or not the marker is currently visible on screen.
*/
@@ -21573,16 +23070,16 @@
if (this.map) {
var screenBounds = this.map.getExtent();
onScreen = screenBounds.containsBounds(this.bounds, true, true);
- }
+ }
return onScreen;
},
-
+
/**
* Method: display
* Hide or show the icon
- *
+ *
* Parameters:
- * display - {Boolean}
+ * display - {Boolean}
*/
display: function(display) {
this.div.style.display = (display) ? "" : "none";
@@ -21595,7 +23092,7 @@
OpenLayers/Request/XMLHttpRequest.js
====================================================================== */
-// Copyright 2007 Sergey Ilinsky (http://www.ilinsky.com)
+// XMLHttpRequest.js Copyright (C) 2010 Sergey Ilinsky (http://www.ilinsky.com)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -21620,11 +23117,13 @@
// Define on browser type
var bGecko = !!window.controllers,
- bIE = window.document.all && !window.opera;
+ bIE = window.document.all && !window.opera,
+ bIE7 = bIE && window.navigator.userAgent.match(/MSIE ([\.0-9]+)/) && RegExp.$1 == 7;
// Constructor
function cXMLHttpRequest() {
- this._object = oXMLHttpRequest ? new oXMLHttpRequest : new window.ActiveXObject('Microsoft.XMLHTTP');
+ this._object = oXMLHttpRequest && !bIE7 ? new oXMLHttpRequest : new window.ActiveXObject("Microsoft.XMLHTTP");
+ this._listeners = [];
};
// BUGFIX: Firefox with Firebug installed would break pages if not executed
@@ -21640,10 +23139,10 @@
// Public Properties
cXMLHttpRequest.prototype.readyState = cXMLHttpRequest.UNSENT;
- cXMLHttpRequest.prototype.responseText = "";
+ cXMLHttpRequest.prototype.responseText = '';
cXMLHttpRequest.prototype.responseXML = null;
cXMLHttpRequest.prototype.status = 0;
- cXMLHttpRequest.prototype.statusText = "";
+ cXMLHttpRequest.prototype.statusText = '';
// Instance-level Events Handlers
cXMLHttpRequest.prototype.onreadystatechange = null;
@@ -21656,24 +23155,50 @@
// Public Methods
cXMLHttpRequest.prototype.open = function(sMethod, sUrl, bAsync, sUser, sPassword) {
+ // Delete headers, required when object is reused
+ delete this._headers;
+ // When bAsync parameter value is omitted, use true as default
+ if (arguments.length < 3)
+ bAsync = true;
+
// Save async parameter for fixing Gecko bug with missing readystatechange in synchronous requests
this._async = bAsync;
// Set the onreadystatechange handler
var oRequest = this,
- nState = this.readyState;
+ nState = this.readyState,
+ fOnUnload;
// BUGFIX: IE - memory leak on page unload (inter-page leak)
- if (bIE) {
- var fOnUnload = function() {
- if (oRequest._object.readyState != cXMLHttpRequest.DONE)
+ if (bIE && bAsync) {
+ fOnUnload = function() {
+ if (nState != cXMLHttpRequest.DONE) {
fCleanTransport(oRequest);
+ // Safe to abort here since onreadystatechange handler removed
+ oRequest.abort();
+ }
};
- if (bAsync)
window.attachEvent("onunload", fOnUnload);
}
+ // Add method sniffer
+ if (cXMLHttpRequest.onopen)
+ cXMLHttpRequest.onopen.apply(this, arguments);
+
+ if (arguments.length > 4)
+ this._object.open(sMethod, sUrl, bAsync, sUser, sPassword);
+ else
+ if (arguments.length > 3)
+ this._object.open(sMethod, sUrl, bAsync, sUser);
+ else
+ this._object.open(sMethod, sUrl, bAsync);
+
+ if (!bGecko && !bIE) {
+ this.readyState = cXMLHttpRequest.OPENED;
+ fReadyStateChange(this);
+ }
+
this._object.onreadystatechange = function() {
if (bGecko && !bAsync)
return;
@@ -21684,7 +23209,7 @@
//
fSynchronizeValues(oRequest);
- // BUGFIX: Firefox fires unneccesary DONE when aborting
+ // BUGFIX: Firefox fires unnecessary DONE when aborting
if (oRequest._aborted) {
// Reset readyState to UNSENT
oRequest.readyState = cXMLHttpRequest.UNSENT;
@@ -21707,7 +23232,14 @@
cXMLHttpRequest.call(oRequest);
// Re-send request
+ if (sUser) {
+ if (sPassword)
oRequest._object.open(sMethod, sUrl, bAsync, sUser, sPassword);
+ else
+ oRequest._object.open(sMethod, sUrl, bAsync, sUser);
+ }
+ else
+ oRequest._object.open(sMethod, sUrl, bAsync);
oRequest._object.setRequestHeader("If-Modified-Since", oRequest._cached.getResponseHeader("Last-Modified") || new window.Date(0));
// Copy headers set
if (oRequest._headers)
@@ -21751,7 +23283,7 @@
};
oRequest._object.send(null);
- // Return now - wait untill re-sent request is finished
+ // Return now - wait until re-sent request is finished
return;
};
*/
@@ -21765,19 +23297,6 @@
fReadyStateChange(oRequest);
nState = oRequest.readyState;
- };
-
- // Add method sniffer
- if (cXMLHttpRequest.onopen)
- cXMLHttpRequest.onopen.apply(this, arguments);
-
- this._object.open(sMethod, sUrl, bAsync, sUser, sPassword);
-
- // BUGFIX: Gecko - missing readystatechange calls in synchronous requests
- if (!bAsync && bGecko) {
- this.readyState = cXMLHttpRequest.OPENED;
-
- fReadyStateChange(this);
}
};
cXMLHttpRequest.prototype.send = function(vData) {
@@ -21818,7 +23337,7 @@
if (cXMLHttpRequest.onabort)
cXMLHttpRequest.onabort.apply(this, arguments);
- // BUGFIX: Gecko - unneccesary DONE when aborting
+ // BUGFIX: Gecko - unnecessary DONE when aborting
if (this.readyState > cXMLHttpRequest.UNSENT)
this._aborted = true;
@@ -21841,34 +23360,86 @@
return this._object.setRequestHeader(sName, sValue);
};
+
+ // EventTarget interface implementation
+ cXMLHttpRequest.prototype.addEventListener = function(sName, fHandler, bUseCapture) {
+ for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++)
+ if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture)
+ return;
+ // Add listener
+ this._listeners.push([sName, fHandler, bUseCapture]);
+ };
+
+ cXMLHttpRequest.prototype.removeEventListener = function(sName, fHandler, bUseCapture) {
+ for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++)
+ if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture)
+ break;
+ // Remove listener
+ if (oListener)
+ this._listeners.splice(nIndex, 1);
+ };
+
+ cXMLHttpRequest.prototype.dispatchEvent = function(oEvent) {
+ var oEventPseudo = {
+ 'type': oEvent.type,
+ 'target': this,
+ 'currentTarget':this,
+ 'eventPhase': 2,
+ 'bubbles': oEvent.bubbles,
+ 'cancelable': oEvent.cancelable,
+ 'timeStamp': oEvent.timeStamp,
+ 'stopPropagation': function() {}, // There is no flow
+ 'preventDefault': function() {}, // There is no default action
+ 'initEvent': function() {} // Original event object should be initialized
+ };
+
+ // Execute onreadystatechange
+ if (oEventPseudo.type == "readystatechange" && this.onreadystatechange)
+ (this.onreadystatechange.handleEvent || this.onreadystatechange).apply(this, [oEventPseudo]);
+
+ // Execute listeners
+ for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++)
+ if (oListener[0] == oEventPseudo.type && !oListener[2])
+ (oListener[1].handleEvent || oListener[1]).apply(this, [oEventPseudo]);
+ };
+
+ //
cXMLHttpRequest.prototype.toString = function() {
return '[' + "object" + ' ' + "XMLHttpRequest" + ']';
};
+
cXMLHttpRequest.toString = function() {
return '[' + "XMLHttpRequest" + ']';
};
// Helper function
function fReadyStateChange(oRequest) {
- // Execute onreadystatechange
- if (oRequest.onreadystatechange)
- oRequest.onreadystatechange.apply(oRequest);
-
// Sniffing code
if (cXMLHttpRequest.onreadystatechange)
cXMLHttpRequest.onreadystatechange.apply(oRequest);
+
+ // Fake event
+ oRequest.dispatchEvent({
+ 'type': "readystatechange",
+ 'bubbles': false,
+ 'cancelable': false,
+ 'timeStamp': new Date + 0
+ });
};
function fGetDocument(oRequest) {
- var oDocument = oRequest.responseXML;
+ var oDocument = oRequest.responseXML,
+ sResponse = oRequest.responseText;
// Try parsing responseText
- if (bIE && oDocument && !oDocument.documentElement && oRequest.getResponseHeader("Content-Type").match(/[^\/]+\/[^\+]+\+xml/)) {
- oDocument = new ActiveXObject('Microsoft.XMLDOM');
- oDocument.loadXML(oRequest.responseText);
+ if (bIE && sResponse && oDocument && !oDocument.documentElement && oRequest.getResponseHeader("Content-Type").match(/[^\/]+\/[^\+]+\+xml/)) {
+ oDocument = new window.ActiveXObject("Microsoft.XMLDOM");
+ oDocument.async = false;
+ oDocument.validateOnParse = false;
+ oDocument.loadXML(sResponse);
}
// Check if there is no error in document
if (oDocument)
- if ((bIE && oDocument.parseError != 0) || (oDocument.documentElement && oDocument.documentElement.tagName == "parsererror"))
+ if ((bIE && oDocument.parseError != 0) || !oDocument.documentElement || (oDocument.documentElement && oDocument.documentElement.tagName == "parsererror"))
return null;
return oDocument;
};
@@ -21883,9 +23454,6 @@
function fCleanTransport(oRequest) {
// BUGFIX: IE - memory leak (on-page leak)
oRequest._object.onreadystatechange = new window.Function;
-
- // Delete private properties
- delete oRequest._headers;
};
// Internet Explorer 5.0 (missing apply)
@@ -21912,8 +23480,9 @@
OpenLayers/Ajax.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -21930,19 +23499,19 @@
* @uri url to do remote XML http get
* @param {String} 'get' format params (x=y&a=b...)
* @who object to handle callbacks for this request
- * @complete the function to be called on success
+ * @complete the function to be called on success
* @failure the function to be called on failure
- *
+ *
* example usage from a caller:
- *
+ *
* caps: function(request) {
- * -blah-
+ * -blah-
* },
- *
+ *
* OpenLayers.loadURL(url,params,this,caps);
*
* Notice the above example does not provide an error handler; a default empty
- * handler is provided which merely logs the error if a failure handler is not
+ * handler is provided which merely logs the error if a failure handler is not
* supplied
*
*/
@@ -21956,8 +23525,8 @@
OpenLayers.Console.userError(OpenLayers.i18n("unhandledRequest", {'statusText':request.statusText}));
};
-/**
- * APIFunction: loadURL
+/**
+ * APIFunction: OpenLayers.loadURL
* Background load a document. For more flexibility in using XMLHttpRequest,
* see the <OpenLayers.Request> methods.
*
@@ -21970,7 +23539,7 @@
* onComplete - {Function} Optional callback for success. The callback
* will be called with this set to caller and will receive the request
* object as an argument. Note that if you do not specify an onComplete
- * function, <OpenLayers.nullHandler> will be called (which pops up a
+ * function, <OpenLayers.nullHandler> will be called (which pops up a
* user friendly error message dialog).
* onFailure - {Function} Optional callback for failure. In the event of
* a failure, the callback will be called with this set to caller and will
@@ -21984,26 +23553,26 @@
*/
OpenLayers.loadURL = function(uri, params, caller,
onComplete, onFailure) {
-
+
if(typeof params == 'string') {
params = OpenLayers.Util.getParameters(params);
}
var success = (onComplete) ? onComplete : OpenLayers.nullHandler;
var failure = (onFailure) ? onFailure : OpenLayers.nullHandler;
-
+
return OpenLayers.Request.GET({
url: uri, params: params,
success: success, failure: failure, scope: caller
});
};
-/**
- * Function: parseXMLString
+/**
+ * Function: OpenLayers.parseXMLString
* Parse XML into a doc structure
- *
+ *
* Parameters:
- * text - {String}
- *
+ * text - {String}
+ *
* Returns:
* {?} Parsed AJAX Responsev
*/
@@ -22052,8 +23621,8 @@
/**
* Method: getTransport
- *
- * Returns:
+ *
+ * Returns:
* {Object} Transport mechanism for whichever browser we're in, or false if
* none available.
*/
@@ -22077,7 +23646,7 @@
* {Object}
*/
OpenLayers.Ajax.Responders = {
-
+
/**
* Property: responders
* {Array}
@@ -22086,7 +23655,7 @@
/**
* Method: register
- *
+ *
* Parameters:
* responderToAdd - {?}
*/
@@ -22101,7 +23670,7 @@
/**
* Method: unregister
- *
+ *
* Parameters:
* responderToRemove - {?}
*/
@@ -22111,7 +23680,7 @@
/**
* Method: dispatch
- *
+ *
* Parameters:
* callback - {?}
* request - {?}
@@ -22121,11 +23690,11 @@
var responder;
for (var i = 0; i < this.responders.length; i++) {
responder = this.responders[i];
-
- if (responder[callback] &&
+
+ if (responder[callback] &&
typeof responder[callback] == 'function') {
try {
- responder[callback].apply(responder,
+ responder[callback].apply(responder,
[request, transport]);
} catch (e) {}
}
@@ -22134,7 +23703,7 @@
};
OpenLayers.Ajax.Responders.register({
- /**
+ /**
* Function: onCreate
*/
onCreate: function() {
@@ -22153,11 +23722,11 @@
* Class: OpenLayers.Ajax.Base
*/
OpenLayers.Ajax.Base = OpenLayers.Class({
-
+
/**
* Constructor: OpenLayers.Ajax.Base
- *
- * Parameters:
+ *
+ * Parameters:
* options - {Object}
*/
initialize: function(options) {
@@ -22168,11 +23737,11 @@
parameters: ''
};
OpenLayers.Util.extend(this.options, options || {});
-
+
this.options.method = this.options.method.toLowerCase();
-
+
if (typeof this.options.parameters == 'string') {
- this.options.parameters =
+ this.options.parameters =
OpenLayers.Util.getParameters(this.options.parameters);
}
}
@@ -22193,28 +23762,28 @@
* {Boolean}
*/
_complete: false,
-
+
/**
* Constructor: OpenLayers.Ajax.Request
- *
- * Parameters:
+ *
+ * Parameters:
* url - {String}
* options - {Object}
*/
initialize: function(url, options) {
OpenLayers.Ajax.Base.prototype.initialize.apply(this, [options]);
-
+
if (OpenLayers.ProxyHost && OpenLayers.String.startsWith(url, "http")) {
url = OpenLayers.ProxyHost + encodeURIComponent(url);
}
-
+
this.transport = OpenLayers.Ajax.getTransport();
this.request(url);
},
/**
* Method: request
- *
+ *
* Parameters:
* url - {String}
*/
@@ -22222,15 +23791,15 @@
this.url = url;
this.method = this.options.method;
var params = OpenLayers.Util.extend({}, this.options.parameters);
-
+
if (this.method != 'get' && this.method != 'post') {
// simulate other verbs over post
params['_method'] = this.method;
this.method = 'post';
}
- this.parameters = params;
-
+ this.parameters = params;
+
if (params = OpenLayers.Util.getParameterString(params)) {
// when GET, append parameters to URL
if (this.method == 'get') {
@@ -22244,31 +23813,31 @@
if (this.options.onCreate) {
this.options.onCreate(response);
}
-
- OpenLayers.Ajax.Responders.dispatch('onCreate',
- this,
+
+ OpenLayers.Ajax.Responders.dispatch('onCreate',
+ this,
response);
-
- this.transport.open(this.method.toUpperCase(),
+
+ this.transport.open(this.method.toUpperCase(),
this.url,
this.options.asynchronous);
-
+
if (this.options.asynchronous) {
window.setTimeout(
OpenLayers.Function.bind(this.respondToReadyState, this, 1),
10);
}
-
- this.transport.onreadystatechange =
- OpenLayers.Function.bind(this.onStateChange, this);
+
+ this.transport.onreadystatechange =
+ OpenLayers.Function.bind(this.onStateChange, this);
this.setRequestHeaders();
-
+
this.body = this.method == 'post' ?
(this.options.postBody || params) : null;
this.transport.send(this.body);
-
+
// Force Firefox to handle ready state 4 for synchronous requests
- if (!this.options.asynchronous &&
+ if (!this.options.asynchronous &&
this.transport.overrideMimeType) {
this.onStateChange();
}
@@ -22286,7 +23855,7 @@
this.respondToReadyState(this.transport.readyState);
}
},
-
+
/**
* Method: setRequestHeaders
*/
@@ -22300,7 +23869,7 @@
if (this.method == 'post') {
headers['Content-type'] = this.options.contentType +
(this.options.encoding ? '; charset=' + this.options.encoding : '');
-
+
/* Force "Connection: close" for older Mozilla browsers to work
* around a bug where XMLHttpRequest sends an incorrect
* Content-length header. See Mozilla Bugzilla #246651.
@@ -22311,9 +23880,9 @@
}
}
// user-defined headers
- if (typeof this.options.requestHeaders == 'object') {
+ if (typeof this.options.requestHeaders == 'object') {
var extras = this.options.requestHeaders;
-
+
if (typeof extras.push == 'function') {
for (var i = 0, length = extras.length; i < length; i += 2) {
headers[extras[i]] = extras[i+1];
@@ -22324,23 +23893,23 @@
}
}
}
-
+
for (var name in headers) {
this.transport.setRequestHeader(name, headers[name]);
}
},
-
+
/**
* Method: success
*
* Returns:
- * {Boolean} -
+ * {Boolean} -
*/
success: function() {
var status = this.getStatus();
return !status || (status >=200 && status < 300);
},
-
+
/**
* Method: getStatus
*
@@ -22364,7 +23933,7 @@
respondToReadyState: function(readyState) {
var state = OpenLayers.Ajax.Request.Events[readyState];
var response = new OpenLayers.Ajax.Response(this);
-
+
if (state == 'Complete') {
try {
this._complete = true;
@@ -22374,29 +23943,29 @@
} catch (e) {
this.dispatchException(e);
}
-
+
var contentType = response.getHeader('Content-type');
}
-
+
try {
- (this.options['on' + state] ||
+ (this.options['on' + state] ||
OpenLayers.Ajax.emptyFunction)(response);
- OpenLayers.Ajax.Responders.dispatch('on' + state,
- this,
+ OpenLayers.Ajax.Responders.dispatch('on' + state,
+ this,
response);
} catch (e) {
this.dispatchException(e);
}
-
+
if (state == 'Complete') {
// avoid memory leak in MSIE: clean up
this.transport.onreadystatechange = OpenLayers.Ajax.emptyFunction;
}
},
-
+
/**
* Method: getHeader
- *
+ *
* Parameters:
* name - {String} Header name
*
@@ -22416,7 +23985,7 @@
* If the optional onException function is set, execute it
* and then dispatch the call to any other listener registered
* for onException.
- *
+ *
* If no optional onException function is set, we suspect that
* the user may have also not used
* OpenLayers.Ajax.Responders.register to register a listener
@@ -22428,7 +23997,7 @@
* request.options.onException to an empty function (function(){})
* or register an empty function with <OpenLayers.Ajax.Responders>
* for onException.
- *
+ *
* Parameters:
* exception - {?}
*/
@@ -22459,7 +24028,7 @@
}
});
-/**
+/**
* Property: Events
* {Array(String)}
*/
@@ -22477,26 +24046,26 @@
* {Integer}
*/
status: 0,
+
-
/**
* Property: statusText
*
* {String}
*/
statusText: '',
-
+
/**
* Constructor: OpenLayers.Ajax.Response
- *
- * Parameters:
+ *
+ * Parameters:
* request - {Object}
*/
initialize: function(request) {
this.request = request;
var transport = this.transport = request.transport,
readyState = this.readyState = transport.readyState;
-
+
if ((readyState > 2 &&
!(!!(window.attachEvent && !window.opera))) ||
readyState == 4) {
@@ -22505,18 +24074,18 @@
this.responseText = transport.responseText == null ?
'' : String(transport.responseText);
}
-
+
if(readyState == 4) {
var xml = transport.responseXML;
this.responseXML = xml === undefined ? null : xml;
}
},
-
+
/**
* Method: getStatus
*/
getStatus: OpenLayers.Ajax.Request.prototype.getStatus,
-
+
/**
* Method: getStatustext
*
@@ -22530,13 +24099,13 @@
return '';
}
},
-
+
/**
* Method: getHeader
*/
getHeader: OpenLayers.Ajax.Request.prototype.getHeader,
-
- /**
+
+ /**
* Method: getResponseHeader
*
* Returns:
@@ -22550,17 +24119,17 @@
/**
* Function: getElementsByTagNameNS
- *
+ *
* Parameters:
* parentnode - {?}
* nsuri - {?}
* nsprefix - {?}
* tagname - {?}
- *
+ *
* Returns:
* {?}
*/
-OpenLayers.Ajax.getElementsByTagNameNS = function(parentnode, nsuri,
+OpenLayers.Ajax.getElementsByTagNameNS = function(parentnode, nsuri,
nsprefix, tagname) {
var elem = null;
if (parentnode.getElementsByTagNameNS) {
@@ -22578,9 +24147,9 @@
* IE/Safari. We need to come up with a way to serialize in those browser:
* for now, these browsers will just fail. #535, #536
*
- * Parameters:
+ * Parameters:
* xmldom {XMLNode} xml dom to serialize
- *
+ *
* Returns:
* {?}
*/
@@ -22593,8 +24162,9 @@
OpenLayers/Control/DragPan.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -22611,18 +24181,18 @@
*/
OpenLayers.Control.DragPan = OpenLayers.Class(OpenLayers.Control, {
- /**
+ /**
* Property: type
* {OpenLayers.Control.TYPES}
*/
type: OpenLayers.Control.TYPE_TOOL,
-
+
/**
* Property: panned
* {Boolean} The map moved.
*/
panned: false,
-
+
/**
* Property: interval
* {Integer} The number of milliseconds that should ellapse before
@@ -22630,18 +24200,26 @@
* Defaults to 25 milliseconds.
*/
interval: 25,
-
+
/**
+ * APIProperty: documentDrag
+ * {Boolean} If set to true, mouse dragging will continue even if the
+ * mouse cursor leaves the map viewport. Default is false.
+ */
+ documentDrag: false,
+
+ /**
* Method: draw
* Creates a Drag handler, using <panMap> and
* <panMapDone> as callbacks.
- */
+ */
draw: function() {
this.handler = new OpenLayers.Handler.Drag(this, {
"move": this.panMap,
"done": this.panMapDone
}, {
- interval: this.interval
+ interval: this.interval,
+ documentDrag: this.documentDrag
}
);
},
@@ -22660,7 +24238,7 @@
{dragging: this.handler.dragging, animate: false}
);
},
-
+
/**
* Method: panMapDone
* Finish the panning operation. Only call setCenter (through <panMap>)
@@ -22682,8 +24260,9 @@
OpenLayers/Feature/Vector.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
// TRASH THIS
@@ -22704,30 +24283,30 @@
* Class: OpenLayers.Feature.Vector
* Vector features use the OpenLayers.Geometry classes as geometry description.
* They have an 'attributes' property, which is the data object, and a 'style'
- * property, the default values of which are defined in the
+ * property, the default values of which are defined in the
* <OpenLayers.Feature.Vector.style> objects.
- *
+ *
* Inherits from:
* - <OpenLayers.Feature>
*/
OpenLayers.Feature.Vector = OpenLayers.Class(OpenLayers.Feature, {
- /**
- * Property: fid
- * {String}
+ /**
+ * Property: fid
+ * {String}
*/
fid: null,
-
- /**
- * APIProperty: geometry
- * {<OpenLayers.Geometry>}
+
+ /**
+ * APIProperty: geometry
+ * {<OpenLayers.Geometry>}
*/
geometry: null,
- /**
- * APIProperty: attributes
- * {Object} This object holds arbitrary properties that describe the
- * feature.
+ /**
+ * APIProperty: attributes
+ * {Object} This object holds arbitrary, serializable properties that
+ * describe the feature.
*/
attributes: null,
@@ -22736,37 +24315,44 @@
* {<OpenLayers.Bounds>} The box bounding that feature's geometry, that
* property can be set by an <OpenLayers.Format> object when
* deserializing the feature, so in most cases it represents an
- * information set by the server.
+ * information set by the server.
*/
bounds: null,
- /**
- * Property: state
- * {String}
+ /**
+ * Property: state
+ * {String}
*/
state: null,
-
- /**
- * APIProperty: style
- * {Object}
+
+ /**
+ * APIProperty: style
+ * {Object}
*/
style: null,
/**
+ * APIProperty: url
+ * {String} If this property is set it will be taken into account by
+ * {<OpenLayers.HTTP>} when upadting or deleting the feature.
+ */
+ url: null,
+
+ /**
* Property: renderIntent
* {String} rendering intent currently being used
*/
renderIntent: "default",
- /**
+ /**
* Constructor: OpenLayers.Feature.Vector
- * Create a vector feature.
- *
+ * Create a vector feature.
+ *
* Parameters:
* geometry - {<OpenLayers.Geometry>} The geometry that this feature
* represents.
* attributes - {Object} An optional object that will be mapped to the
- * <attributes> property.
+ * <attributes> property.
* style - {Object} An optional style object.
*/
initialize: function(geometry, attributes, style) {
@@ -22780,10 +24366,10 @@
this.attributes = OpenLayers.Util.extend(this.attributes,
attributes);
}
- this.style = style ? style : null;
+ this.style = style ? style : null;
},
-
- /**
+
+ /**
* Method: destroy
* nullify references to prevent circular references and memory leaks
*/
@@ -22792,11 +24378,11 @@
this.layer.removeFeatures(this);
this.layer = null;
}
-
+
this.geometry = null;
OpenLayers.Feature.prototype.destroy.apply(this, arguments);
},
-
+
/**
* Method: clone
* Create a clone of this vector feature. Does not set any non-standard
@@ -22824,7 +24410,7 @@
* boundsOnly - {Boolean} Only test whether a feature's bounds intersects
* the viewport bounds. Default is false. If false, the feature's
* geometry must intersect the viewport for onScreen to return true.
- *
+ *
* Returns:
* {Boolean} The feature is currently visible on screen (optionally
* based on its bounds if boundsOnly is true).
@@ -22840,15 +24426,36 @@
var screenPoly = screenBounds.toGeometry();
onScreen = screenPoly.intersects(this.geometry);
}
- }
+ }
return onScreen;
},
/**
+ * Method: getVisibility
+ * Determine whether the feature is displayed or not. It may not displayed
+ * because:
+ * - its style display property is set to 'none',
+ * - it doesn't belong to any layer,
+ * - the styleMap creates a symbolizer with display property set to 'none'
+ * for it,
+ * - the layer which it belongs to is not visible.
+ *
+ * Returns:
+ * {Boolean} The feature is currently displayed.
+ */
+ getVisibility: function() {
+ return !(this.style && this.style.display == 'none' ||
+ !this.layer ||
+ this.layer && this.layer.styleMap &&
+ this.layer.styleMap.createSymbolizer(this, this.renderIntent).display == 'none' ||
+ this.layer && !this.layer.getVisibility());
+ },
+
+ /**
* Method: createMarker
* HACK - we need to decide if all vector features should be able to
* create markers
- *
+ *
* Returns:
* {<OpenLayers.Marker>} For now just returns null
*/
@@ -22860,7 +24467,7 @@
* Method: destroyMarker
* HACK - we need to decide if all vector features should be able to
* delete markers
- *
+ *
* If user overrides the createMarker() function, s/he should be able
* to also specify an alternative function for destroying it
*/
@@ -22872,7 +24479,7 @@
* Method: createPopup
* HACK - we need to decide if all vector features should be able to
* create popups
- *
+ *
* Returns:
* {<OpenLayers.Popup>} For now just returns null
*/
@@ -22883,19 +24490,19 @@
/**
* Method: atPoint
* Determins whether the feature intersects with the specified location.
- *
- * Parameters:
- * lonlat - {<OpenLayers.LonLat>}
+ *
+ * Parameters:
+ * lonlat - {<OpenLayers.LonLat>}
* toleranceLon - {float} Optional tolerance in Geometric Coords
* toleranceLat - {float} Optional tolerance in Geographic Coords
- *
+ *
* Returns:
* {Boolean} Whether or not the feature is at the specified location
*/
atPoint: function(lonlat, toleranceLon, toleranceLat) {
var atPoint = false;
if(this.geometry) {
- atPoint = this.geometry.atPoint(lonlat, toleranceLon,
+ atPoint = this.geometry.atPoint(lonlat, toleranceLon,
toleranceLat);
}
return atPoint;
@@ -22931,7 +24538,7 @@
} else {
pixel = location;
}
-
+
var lastPixel = this.layer.getViewPortPxFromLonLat(this.geometry.getBounds().getCenterLonLat());
var res = this.layer.map.getResolution();
this.geometry.move(res * (pixel.x - lastPixel.x),
@@ -22939,13 +24546,13 @@
this.layer.drawFeature(this);
return lastPixel;
},
-
+
/**
* Method: toState
* Sets the new state
*
* Parameters:
- * state - {String}
+ * state - {String}
*/
toState: function(state) {
if (state == OpenLayers.State.UPDATE) {
@@ -22982,24 +24589,24 @@
this.state = state;
}
},
-
+
CLASS_NAME: "OpenLayers.Feature.Vector"
});
/**
* Constant: OpenLayers.Feature.Vector.style
- * OpenLayers features can have a number of style attributes. The 'default'
+ * OpenLayers features can have a number of style attributes. The 'default'
* style will typically be used if no other style is specified. These
* styles correspond for the most part, to the styling properties defined
- * by the SVG standard.
+ * by the SVG standard.
* Information on fill properties: http://www.w3.org/TR/SVG/painting.html#FillProperties
* Information on stroke properties: http://www.w3.org/TR/SVG/painting.html#StrokeProperties
*
* Symbolizer properties:
* fill - {Boolean} Set to false if no fill is desired.
* fillColor - {String} Hex fill color. Default is "#ee9900".
- * fillOpacity - {Number} Fill opacity (0-1). Default is 0.4
+ * fillOpacity - {Number} Fill opacity (0-1). Default is 0.4
* stroke - {Boolean} Set to false if no stroke is desired.
* strokeColor - {String} Hex stroke color. Default is "#ee9900".
* strokeOpacity - {Number} Stroke opacity (0-1). Default is 1.
@@ -23016,6 +24623,7 @@
* graphicOpacity - {Number} Opacity (0-1) for an external graphic.
* graphicXOffset - {Number} Pixel offset along the positive x axis for displacing an external graphic.
* graphicYOffset - {Number} Pixel offset along the positive y axis for displacing an external graphic.
+ * rotation - {Number} For point symbolizers, this is the rotation of a graphic in the clockwise direction about its center point (or any point off center as specified by graphicXOffset and graphicYOffset).
* graphicZIndex - {Number} The integer z-index value to use in rendering.
* graphicName - {String} Named graphic to use when rendering points. Supported values include "circle" (default),
* "square", "star", "x", "cross", "triangle".
@@ -23033,16 +24641,21 @@
* alignment. Valid values for horizontal alignment: "l"=left, "c"=center, "r"=right. Valid values for vertical
* alignment: "t"=top, "m"=middle, "b"=bottom. Example values: "lt", "cm", "rb". The canvas renderer does not
* support vertical alignment, it will always use "b".
+ * labelXOffset - {Number} Pixel offset along the positive x axis for displacing the label.
+ * labelYOffset - {Number} Pixel offset along the positive y axis for displacing the label.
+ * labelSelect - {Boolean} If set to true, labels will be selectable using SelectFeature or similar controls.
+ * Default is false.
* fontColor - {String} The font color for the label, to be provided like CSS.
+ * fontOpacity - {Number} Opacity (0-1) for the label
* fontFamily - {String} The font family for the label, to be provided like in CSS.
* fontSize - {String} The font size for the label, to be provided like in CSS.
* fontWeight - {String} The font weight for the label, to be provided like in CSS.
* display - {String} Symbolizers will have no effect if display is set to "none". All other values have no effect.
- */
+ */
OpenLayers.Feature.Vector.style = {
'default': {
fillColor: "#ee9900",
- fillOpacity: 0.4,
+ fillOpacity: 0.4,
hoverFillColor: "white",
hoverFillOpacity: 0.8,
strokeColor: "#ee9900",
@@ -23061,7 +24674,7 @@
},
'select': {
fillColor: "blue",
- fillOpacity: 0.4,
+ fillOpacity: 0.4,
hoverFillColor: "white",
hoverFillOpacity: 0.8,
strokeColor: "blue",
@@ -23080,7 +24693,7 @@
},
'temporary': {
fillColor: "#66cccc",
- fillOpacity: 0.2,
+ fillOpacity: 0.2,
hoverFillColor: "white",
hoverFillOpacity: 0.8,
strokeColor: "#66cccc",
@@ -23100,13 +24713,14 @@
'delete': {
display: "none"
}
-};
+};
/* ======================================================================
OpenLayers/Handler/Box.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -23116,17 +24730,17 @@
/**
* Class: OpenLayers.Handler.Box
- * Handler for dragging a rectangle across the map. Box is displayed
+ * Handler for dragging a rectangle across the map. Box is displayed
* on mouse down, moves on mouse move, and is finished on mouse up.
*
* Inherits from:
- * - <OpenLayers.Handler>
+ * - <OpenLayers.Handler>
*/
OpenLayers.Handler.Box = OpenLayers.Class(OpenLayers.Handler, {
- /**
- * Property: dragHandler
- * {<OpenLayers.Handler.Drag>}
+ /**
+ * Property: dragHandler
+ * {<OpenLayers.Handler.Drag>}
*/
dragHandler: null,
@@ -23136,7 +24750,7 @@
* olHandlerBoxZoomBox
*/
boxDivClassName: 'olHandlerBoxZoomBox',
-
+
/**
* Property: boxCharacteristics
* {Object} Caches some box characteristics from css. This is used
@@ -23148,18 +24762,18 @@
* Constructor: OpenLayers.Handler.Box
*
* Parameters:
- * control - {<OpenLayers.Control>}
+ * control - {<OpenLayers.Control>}
* callbacks - {Object} An object containing a single function to be
* called when the drag operation is finished.
* The callback should expect to recieve a single
* argument, the point geometry.
- * options - {Object}
+ * options - {Object}
*/
initialize: function(control, callbacks, options) {
OpenLayers.Handler.prototype.initialize.apply(this, arguments);
var callbacks = {
- "down": this.startBox,
- "move": this.moveBox,
+ "down": this.startBox,
+ "move": this.moveBox,
"out": this.removeBox,
"up": this.endBox
};
@@ -23168,6 +24782,17 @@
},
/**
+ * Method: destroy
+ */
+ destroy: function() {
+ if (this.dragHandler) {
+ this.dragHandler.destroy();
+ this.dragHandler = null;
+ }
+ OpenLayers.Handler.prototype.destroy.apply(this, arguments);
+ },
+
+ /**
* Method: setMap
*/
setMap: function (map) {
@@ -23181,12 +24806,12 @@
* Method: startBox
*
* Parameters:
- * evt - {Event}
+ * evt - {Event}
*/
startBox: function (xy) {
this.zoomBox = OpenLayers.Util.createDiv('zoomBox',
this.dragHandler.start);
- this.zoomBox.className = this.boxDivClassName;
+ this.zoomBox.className = this.boxDivClassName;
this.zoomBox.style.zIndex = this.map.Z_INDEX_BASE["Popup"] - 1;
this.map.viewPortDiv.appendChild(this.zoomBox);
@@ -23228,8 +24853,8 @@
*/
endBox: function(end) {
var result;
- if (Math.abs(this.dragHandler.start.x - end.x) > 5 ||
- Math.abs(this.dragHandler.start.y - end.y) > 5) {
+ if (Math.abs(this.dragHandler.start.x - end.x) > 5 ||
+ Math.abs(this.dragHandler.start.y - end.y) > 5) {
var start = this.dragHandler.start;
var top = Math.min(start.y, end.y);
var bottom = Math.max(start.y, end.y);
@@ -23238,7 +24863,7 @@
result = new OpenLayers.Bounds(left, bottom, right, top);
} else {
result = this.dragHandler.start.clone(); // i.e. OL.Pixel
- }
+ }
this.removeBox();
this.callback("done", [result]);
@@ -23281,11 +24906,11 @@
return false;
}
},
-
+
/**
* Method: getCharacteristics
* Determines offset and box model for a box.
- *
+ *
* Returns:
* {Object} a hash with the following properties:
* - xOffset - Corner offset in x-direction
@@ -23318,8 +24943,9 @@
OpenLayers/Handler/RegularPolygon.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
@@ -23333,12 +24959,12 @@
* down, moves or is modified on mouse move, and is finished on mouse up.
* The handler triggers callbacks for 'done' and 'cancel'. Create a new
* instance with the <OpenLayers.Handler.RegularPolygon> constructor.
- *
+ *
* Inherits from:
* - <OpenLayers.Handler>
*/
OpenLayers.Handler.RegularPolygon = OpenLayers.Class(OpenLayers.Handler.Drag, {
-
+
/**
* APIProperty: sides
* {Integer} Number of sides for the regular polygon. Needs to be greater
@@ -23355,15 +24981,15 @@
* default.
*/
radius: null,
-
+
/**
* APIProperty: snapAngle
* {Float} If set to a non-zero value, the handler will snap the polygon
* rotation to multiples of the snapAngle. Value is an angle measured
- * in degrees counterclockwise from the positive x-axis.
+ * in degrees counterclockwise from the positive x-axis.
*/
snapAngle: null,
-
+
/**
* APIProperty: snapToggle
* {String} If set, snapToggle is checked on mouse events and will set
@@ -23374,6 +25000,12 @@
* non-zero value.
*/
snapToggle: 'shiftKey',
+
+ /**
+ * Property: layerOptions
+ * {Object} Any optional properties to be set on the sketch layer.
+ */
+ layerOptions: null,
/**
* APIProperty: persist
@@ -23450,24 +25082,26 @@
* cancel callback will receive a geometry.
*/
initialize: function(control, callbacks, options) {
- this.style = OpenLayers.Util.extend(OpenLayers.Feature.Vector.style['default'], {});
+ if(!(options && options.layerOptions && options.layerOptions.styleMap)) {
+ this.style = OpenLayers.Util.extend(OpenLayers.Feature.Vector.style['default'], {});
+ }
OpenLayers.Handler.prototype.initialize.apply(this,
[control, callbacks, options]);
- this.options = (options) ? options : new Object();
+ this.options = (options) ? options : {};
},
-
+
/**
* APIMethod: setOptions
- *
+ *
* Parameters:
- * newOptions - {Object}
+ * newOptions - {Object}
*/
setOptions: function (newOptions) {
OpenLayers.Util.extend(this.options, newOptions);
OpenLayers.Util.extend(this, newOptions);
},
-
+
/**
* APIMethod: activate
* Turn on the handler.
@@ -23479,14 +25113,14 @@
var activated = false;
if(OpenLayers.Handler.prototype.activate.apply(this, arguments)) {
// create temporary vector layer for rendering geometry sketch
- var options = {
+ var options = OpenLayers.Util.extend({
displayInLayerSwitcher: false,
// indicate that the temp vector layer will never be out of range
// without this, resolution properties must be specified at the
// map-level for this temporary layer to init its resolutions
// correctly
- calculateInRange: function() { return true; }
- };
+ calculateInRange: OpenLayers.Function.True
+ }, this.layerOptions);
this.layer = new OpenLayers.Layer.Vector(this.CLASS_NAME, options);
this.map.addLayer(this.layer);
activated = true;
@@ -23525,7 +25159,7 @@
}
return deactivated;
},
-
+
/**
* Method: down
* Start drawing a new feature
@@ -23552,7 +25186,7 @@
this.layer.addFeatures([this.feature], {silent: true});
this.layer.drawFeature(this.feature, this.style);
},
-
+
/**
* Method: move
* Respond to drag move events
@@ -23632,13 +25266,13 @@
this.origin, this.radius, this.sides, this.snapAngle
);
},
-
+
/**
* Method: modifyGeometry
* Modify the polygon geometry in place.
*/
modifyGeometry: function() {
- var angle, dx, dy, point;
+ var angle, point;
var ring = this.feature.geometry.components[0];
// if the number of sides ever changes, create a new geometry
if(ring.components.length != (this.sides + 1)) {
@@ -23653,7 +25287,7 @@
point.clearBounds();
}
},
-
+
/**
* Method: calculateAngle
* Calculate the angle based on settings.
@@ -23699,10 +25333,12 @@
* is true).
*/
clear: function() {
- this.layer.renderer.clear();
- this.layer.destroyFeatures();
+ if (this.layer) {
+ this.layer.renderer.clear();
+ this.layer.destroyFeatures();
+ }
},
-
+
/**
* Method: callback
* Trigger the control's named callback with the given arguments
@@ -23732,8 +25368,9 @@
OpenLayers/Layer/EventPane.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
@@ -23746,21 +25383,21 @@
* Class: OpenLayers.Layer.EventPane
* Base class for 3rd party layers. Create a new event pane layer with the
* <OpenLayers.Layer.EventPane> constructor.
- *
+ *
* Inherits from:
* - <OpenLayers.Layer>
*/
OpenLayers.Layer.EventPane = OpenLayers.Class(OpenLayers.Layer, {
-
+
/**
* APIProperty: smoothDragPan
* {Boolean} smoothDragPan determines whether non-public/internal API
- * methods are used for better performance while dragging EventPane
- * layers. When not in sphericalMercator mode, the smoother dragging
- * doesn't actually move north/south directly with the number of
- * pixels moved, resulting in a slight offset when you drag your mouse
- * north south with this option on. If this visual disparity bothers
- * you, you should turn this option off, or use spherical mercator.
+ * methods are used for better performance while dragging EventPane
+ * layers. When not in sphericalMercator mode, the smoother dragging
+ * doesn't actually move north/south directly with the number of
+ * pixels moved, resulting in a slight offset when you drag your mouse
+ * north south with this option on. If this visual disparity bothers
+ * you, you should turn this option off, or use spherical mercator.
* Default is on.
*/
smoothDragPan: true,
@@ -23768,13 +25405,13 @@
/**
* Property: isBaseLayer
* {Boolean} EventPaned layers are always base layers, by necessity.
- */
+ */
isBaseLayer: true,
/**
* APIProperty: isFixed
* {Boolean} EventPaned layers are fixed by default.
- */
+ */
isFixed: true,
/**
@@ -23787,9 +25424,9 @@
/**
* Property: mapObject
* {Object} This is the object which will be used to load the 3rd party library
- * in the case of the google layer, this will be of type GMap,
+ * in the case of the google layer, this will be of type GMap,
* in the case of the ve layer, this will be of type VEMap
- */
+ */
mapObject: null,
@@ -23807,35 +25444,36 @@
this.pane = OpenLayers.Util.createDiv(this.div.id + "_EventPane");
}
},
-
+
/**
* APIMethod: destroy
* Deconstruct this layer.
*/
destroy: function() {
this.mapObject = null;
- OpenLayers.Layer.prototype.destroy.apply(this, arguments);
+ this.pane = null;
+ OpenLayers.Layer.prototype.destroy.apply(this, arguments);
},
-
+
/**
* Method: setMap
* Set the map property for the layer. This is done through an accessor
- * so that subclasses can override this and take special action once
- * they have their map variable set.
+ * so that subclasses can override this and take special action once
+ * they have their map variable set.
*
* Parameters:
* map - {<OpenLayers.Map>}
*/
setMap: function(map) {
OpenLayers.Layer.prototype.setMap.apply(this, arguments);
-
+
this.pane.style.zIndex = parseInt(this.div.style.zIndex) + 1;
this.pane.style.display = this.div.style.display;
this.pane.style.width="100%";
this.pane.style.height="100%";
if (OpenLayers.Util.getBrowserName() == "msie") {
- this.pane.style.background =
+ this.pane.style.background =
"url(" + OpenLayers.Util.getImagesLocation() + "blank.gif)";
}
@@ -23847,7 +25485,7 @@
// once our layer has been added to the map, we can load it
this.loadMapObject();
-
+
// if map didn't load, display warning
if (this.mapObject == null) {
this.loadWarningMessage();
@@ -23857,26 +25495,25 @@
/**
* APIMethod: removeMap
* On being removed from the map, we'll like to remove the invisible 'pane'
- * div that we added to it on creation.
- *
+ * div that we added to it on creation.
+ *
* Parameters:
* map - {<OpenLayers.Map>}
*/
removeMap: function(map) {
if (this.pane && this.pane.parentNode) {
this.pane.parentNode.removeChild(this.pane);
- this.pane = null;
}
OpenLayers.Layer.prototype.removeMap.apply(this, arguments);
},
-
+
/**
* Method: loadWarningMessage
- * If we can't load the map lib, then display an error message to the
+ * If we can't load the map lib, then display an error message to the
* user and tell them where to go for help.
- *
+ *
* This function sets up the layout for the warning message. Each 3rd
- * party layer must implement its own getWarningHTML() function to
+ * party layer must implement its own getWarningHTML() function to
* provide the actual warning message.
*/
loadWarningMessage:function() {
@@ -23884,17 +25521,17 @@
this.div.style.backgroundColor = "darkblue";
var viewSize = this.map.getSize();
-
+
var msgW = Math.min(viewSize.w, 300);
var msgH = Math.min(viewSize.h, 200);
var size = new OpenLayers.Size(msgW, msgH);
var centerPx = new OpenLayers.Pixel(viewSize.w/2, viewSize.h/2);
- var topLeft = centerPx.add(-size.w/2, -size.h/2);
+ var topLeft = centerPx.add(-size.w/2, -size.h/2);
- var div = OpenLayers.Util.createDiv(this.name + "_warning",
- topLeft,
+ var div = OpenLayers.Util.createDiv(this.name + "_warning",
+ topLeft,
size,
null,
null,
@@ -23907,11 +25544,11 @@
div.innerHTML = this.getWarningHTML();
this.div.appendChild(div);
},
-
- /**
+
+ /**
* Method: getWarningHTML
* To be implemented by subclasses.
- *
+ *
* Returns:
* {String} String with information on why layer is broken, how to get
* it working.
@@ -23920,7 +25557,7 @@
//should be implemented by subclasses
return "";
},
-
+
/**
* Method: display
* Set the display on the pane
@@ -23932,11 +25569,11 @@
OpenLayers.Layer.prototype.display.apply(this, arguments);
this.pane.style.display = this.div.style.display;
},
-
+
/**
* Method: setZIndex
* Set the z-index order for the pane.
- *
+ *
* Parameters:
* zIndex - {int}
*/
@@ -23948,7 +25585,7 @@
/**
* Method: moveTo
* Handle calls to move the layer.
- *
+ *
* Parameters:
* bounds - {<OpenLayers.Bounds>}
* zoomChanged - {Boolean}
@@ -23970,10 +25607,10 @@
var moOldZoom = this.getMapObjectZoom();
var oldZoom= this.getOLZoomFromMapObjectZoom(moOldZoom);
- if ( !(newCenter.equals(oldCenter)) ||
+ if ( !(newCenter.equals(oldCenter)) ||
!(newZoom == oldZoom) ) {
- if (dragging && this.dragPanMapObject &&
+ if (dragging && this.dragPanMapObject &&
this.smoothDragPan) {
var oldPx = this.map.getViewPortPxFromLonLat(oldCenter);
var newPx = this.map.getViewPortPxFromLonLat(newCenter);
@@ -23998,7 +25635,7 @@
/**
* Method: getLonLatFromViewPortPx
* Get a map location from a pixel location
- *
+ *
* Parameters:
* viewPortPx - {<OpenLayers.Pixel>}
*
@@ -24009,7 +25646,7 @@
*/
getLonLatFromViewPortPx: function (viewPortPx) {
var lonlat = null;
- if ( (this.mapObject != null) &&
+ if ( (this.mapObject != null) &&
(this.getMapObjectCenter() != null) ) {
var moPixel = this.getMapObjectPixelFromOLPixel(viewPortPx);
var moLonLat = this.getMapObjectLonLatFromMapObjectPixel(moPixel);
@@ -24018,7 +25655,7 @@
return lonlat;
},
-
+
/**
* Method: getViewPortPxFromLonLat
* Get a pixel location from a map location
@@ -24033,12 +25670,12 @@
*/
getViewPortPxFromLonLat: function (lonlat) {
var viewPortPx = null;
- if ( (this.mapObject != null) &&
+ if ( (this.mapObject != null) &&
(this.getMapObjectCenter() != null) ) {
var moLonLat = this.getMapObjectLonLatFromOLLonLat(lonlat);
var moPixel = this.getMapObjectPixelFromMapObjectLonLat(moLonLat);
-
+
viewPortPx = this.getOLPixelFromMapObjectPixel(moPixel);
}
return viewPortPx;
@@ -24063,9 +25700,9 @@
*
* Parameters
* moLonLat - {Object}
- *
+ *
* Returns:
- * {<OpenLayers.LonLat>} An OpenLayers.LonLat, translated from the passed in
+ * {<OpenLayers.LonLat>} An OpenLayers.LonLat, translated from the passed in
* MapObject LonLat
* Returns null if null value is passed in
*/
@@ -24085,9 +25722,9 @@
*
* Parameters:
* olLonLat - {<OpenLayers.LonLat>}
- *
+ *
* Returns:
- * {Object} A MapObject LonLat, translated from the passed in
+ * {Object} A MapObject LonLat, translated from the passed in
* OpenLayers.LonLat
* Returns null if null value is passed in
*/
@@ -24111,9 +25748,9 @@
*
* Parameters:
* moPixel - {Object}
- *
+ *
* Returns:
- * {<OpenLayers.Pixel>} An OpenLayers.Pixel, translated from the passed in
+ * {<OpenLayers.Pixel>} An OpenLayers.Pixel, translated from the passed in
* MapObject Pixel
* Returns null if null value is passed in
*/
@@ -24133,9 +25770,9 @@
*
* Parameters:
* olPixel - {<OpenLayers.Pixel>}
- *
+ *
* Returns:
- * {Object} A MapObject Pixel, translated from the passed in
+ * {Object} A MapObject Pixel, translated from the passed in
* OpenLayers.Pixel
* Returns null if null value is passed in
*/
@@ -24153,8 +25790,9 @@
OpenLayers/Layer/FixedZoomLevels.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -24163,47 +25801,47 @@
/**
* Class: OpenLayers.Layer.FixedZoomLevels
- * Some Layers will already have established zoom levels (like google
+ * Some Layers will already have established zoom levels (like google
* or ve). Instead of trying to determine them and populate a resolutions[]
* Array with those values, we will hijack the resolution functionality
* here.
- *
- * When you subclass FixedZoomLevels:
- *
- * The initResolutions() call gets nullified, meaning no resolutions[] array
- * is set up. Which would be a big problem getResolution() in Layer, since
+ *
+ * When you subclass FixedZoomLevels:
+ *
+ * The initResolutions() call gets nullified, meaning no resolutions[] array
+ * is set up. Which would be a big problem getResolution() in Layer, since
* it merely takes map.zoom and indexes into resolutions[]... but....
- *
- * The getResolution() call is also overridden. Instead of using the
+ *
+ * The getResolution() call is also overridden. Instead of using the
* resolutions[] array, we simply calculate the current resolution based
* on the current extent and the current map size. But how will we be able
* to calculate the current extent without knowing the resolution...?
- *
+ *
* The getExtent() function is also overridden. Instead of calculating extent
- * based on the center point and the current resolution, we instead
- * calculate the extent by getting the lonlats at the top-left and
+ * based on the center point and the current resolution, we instead
+ * calculate the extent by getting the lonlats at the top-left and
* bottom-right by using the getLonLatFromViewPortPx() translation function,
- * taken from the pixel locations (0,0) and the size of the map. But how
+ * taken from the pixel locations (0,0) and the size of the map. But how
* will we be able to do lonlat-px translation without resolution....?
- *
+ *
* The getZoomForResolution() method is overridden. Instead of indexing into
* the resolutions[] array, we call OpenLayers.Layer.getExent(), passing in
- * the desired resolution. With this extent, we then call getZoomForExtent()
- *
- *
- * Whenever you implement a layer using OpenLayers.Layer.FixedZoomLevels,
+ * the desired resolution. With this extent, we then call getZoomForExtent()
+ *
+ *
+ * Whenever you implement a layer using OpenLayers.Layer.FixedZoomLevels,
* it is your responsibility to provide the following three functions:
- *
+ *
* - getLonLatFromViewPortPx
* - getViewPortPxFromLonLat
* - getZoomForExtent
- *
- * ...those three functions should generally be provided by any reasonable
+ *
+ * ...those three functions should generally be provided by any reasonable
* API that you might be working from.
*
*/
OpenLayers.Layer.FixedZoomLevels = OpenLayers.Class({
-
+
/********************************************************/
/* */
/* Baselayer Functions */
@@ -24212,19 +25850,19 @@
/* by all base layers */
/* */
/********************************************************/
-
+
/**
* Constructor: OpenLayers.Layer.FixedZoomLevels
* Create a new fixed zoom levels layer.
*/
initialize: function() {
- //this class is only just to add the following functions...
+ //this class is only just to add the following functions...
// nothing to actually do here... but it is probably a good
- // idea to have layers that use these functions call this
- // inititalize() anyways, in case at some point we decide we
- // do want to put some functionality or state in here.
+ // idea to have layers that use these functions call this
+ // inititalize() anyways, in case at some point we decide we
+ // do want to put some functionality or state in here.
},
-
+
/**
* Method: initResolutions
* Populate the resolutions array
@@ -24232,64 +25870,64 @@
initResolutions: function() {
var props = new Array('minZoomLevel', 'maxZoomLevel', 'numZoomLevels');
-
+
for(var i=0, len=props.length; i<len; i++) {
var property = props[i];
- this[property] = (this.options[property] != null)
- ? this.options[property]
+ this[property] = (this.options[property] != null)
+ ? this.options[property]
: this.map[property];
}
if ( (this.minZoomLevel == null) ||
(this.minZoomLevel < this.MIN_ZOOM_LEVEL) ){
this.minZoomLevel = this.MIN_ZOOM_LEVEL;
- }
+ }
//
// At this point, we know what the minimum desired zoom level is, and
- // we must calculate the total number of zoom levels.
- //
+ // we must calculate the total number of zoom levels.
+ //
// Because we allow for the setting of either the 'numZoomLevels'
- // or the 'maxZoomLevel' properties... on either the layer or the
+ // or the 'maxZoomLevel' properties... on either the layer or the
// map, we have to define some rules to see which we take into
- // account first in this calculation.
+ // account first in this calculation.
//
// The following is the precedence list for these properties:
- //
+ //
// (1) numZoomLevels set on layer
// (2) maxZoomLevel set on layer
// (3) numZoomLevels set on map
// (4) maxZoomLevel set on map*
// (5) none of the above*
//
- // *Note that options (4) and (5) are only possible if the user
- // _explicitly_ sets the 'numZoomLevels' property on the map to
- // null, since it is set by default to 16.
+ // *Note that options (4) and (5) are only possible if the user
+ // _explicitly_ sets the 'numZoomLevels' property on the map to
+ // null, since it is set by default to 16.
//
//
- // Note to future: In 3.0, I think we should remove the default
- // value of 16 for map.numZoomLevels. Rather, I think that value
+ // Note to future: In 3.0, I think we should remove the default
+ // value of 16 for map.numZoomLevels. Rather, I think that value
// should be set as a default on the Layer.WMS class. If someone
- // creates a 3rd party layer and does not specify any 'minZoomLevel',
- // 'maxZoomLevel', or 'numZoomLevels', and has not explicitly
+ // creates a 3rd party layer and does not specify any 'minZoomLevel',
+ // 'maxZoomLevel', or 'numZoomLevels', and has not explicitly
// specified any of those on the map object either.. then I think
// it is fair to say that s/he wants all the zoom levels available.
- //
- // By making map.numZoomLevels *null* by default, that will be the
+ //
+ // By making map.numZoomLevels *null* by default, that will be the
// case. As it is, I don't feel comfortable changing that right now
// as it would be a glaring API change and actually would probably
- // break many peoples' codes.
+ // break many peoples' codes.
//
//the number of zoom levels we'd like to have.
var desiredZoomLevels;
- //this is the maximum number of zoom levels the layer will allow,
+ //this is the maximum number of zoom levels the layer will allow,
// given the specified starting minimum zoom level.
var limitZoomLevels = this.MAX_ZOOM_LEVEL - this.minZoomLevel + 1;
- if ( ((this.options.numZoomLevels == null) &&
+ if ( ((this.options.numZoomLevels == null) &&
(this.options.maxZoomLevel != null)) // (2)
||
((this.numZoomLevels == null) &&
@@ -24306,18 +25944,18 @@
if (desiredZoomLevels != null) {
//Now that we know what we would *like* the number of zoom levels
// to be, based on layer or map options, we have to make sure that
- // it does not conflict with the actual limit, as specified by
+ // it does not conflict with the actual limit, as specified by
// the constants on the layer itself (and calculated into the
- // 'limitZoomLevels' variable).
+ // 'limitZoomLevels' variable).
this.numZoomLevels = Math.min(desiredZoomLevels, limitZoomLevels);
} else {
- // case (5) -- neither 'numZoomLevels' not 'maxZoomLevel' was
- // set on either the layer or the map. So we just use the
+ // case (5) -- neither 'numZoomLevels' not 'maxZoomLevel' was
+ // set on either the layer or the map. So we just use the
// maximum limit as calculated by the layer's constants.
this.numZoomLevels = limitZoomLevels;
}
- //now that the 'numZoomLevels' is appropriately, safely set,
+ //now that the 'numZoomLevels' is appropriately, safely set,
// we go back and re-calculate the 'maxZoomLevel'.
this.maxZoomLevel = this.minZoomLevel + this.numZoomLevels - 1;
@@ -24325,17 +25963,17 @@
var resolutionsIndex = 0;
this.resolutions = [];
for(var i= this.minZoomLevel; i <= this.maxZoomLevel; i++) {
- this.resolutions[resolutionsIndex++] = this.RESOLUTIONS[i];
+ this.resolutions[resolutionsIndex++] = this.RESOLUTIONS[i];
}
this.maxResolution = this.resolutions[0];
this.minResolution = this.resolutions[this.resolutions.length - 1];
- }
+ }
},
-
+
/**
* APIMethod: getResolution
* Get the current map resolution
- *
+ *
* Returns:
* {Float} Map units per Pixel
*/
@@ -24345,10 +25983,10 @@
return OpenLayers.Layer.prototype.getResolution.apply(this, arguments);
} else {
var resolution = null;
-
+
var viewSize = this.map.getSize();
var extent = this.getExtent();
-
+
if ((viewSize != null) && (extent != null)) {
resolution = Math.max( extent.getWidth() / viewSize.w,
extent.getHeight() / viewSize.h );
@@ -24359,29 +25997,29 @@
/**
* APIMethod: getExtent
- * Calculates using px-> lonlat translation functions on tl and br
+ * Calculates using px-> lonlat translation functions on tl and br
* corners of viewport
- *
+ *
* Returns:
- * {<OpenLayers.Bounds>} A Bounds object which represents the lon/lat
+ * {<OpenLayers.Bounds>} A Bounds object which represents the lon/lat
* bounds of the current viewPort.
*/
getExtent: function () {
var extent = null;
-
-
+
+
var size = this.map.getSize();
-
+
var tlPx = new OpenLayers.Pixel(0,0);
var tlLL = this.getLonLatFromViewPortPx(tlPx);
var brPx = new OpenLayers.Pixel(size.w, size.h);
var brLL = this.getLonLatFromViewPortPx(brPx);
-
+
if ((tlLL != null) && (brLL != null)) {
- extent = new OpenLayers.Bounds(tlLL.lon,
- brLL.lat,
- brLL.lon,
+ extent = new OpenLayers.Bounds(tlLL.lon,
+ brLL.lat,
+ brLL.lon,
tlLL.lat);
}
@@ -24400,7 +26038,7 @@
* If no baselayer is set, returns null.
*/
getZoomForResolution: function(resolution) {
-
+
if (this.resolutions != null) {
return OpenLayers.Layer.prototype.getZoomForResolution.apply(this, arguments);
} else {
@@ -24411,28 +26049,28 @@
-
+
/********************************************************/
/* */
/* Translation Functions */
/* */
- /* The following functions translate GMaps and OL */
+ /* The following functions translate GMaps and OL */
/* formats for Pixel, LonLat, Bounds, and Zoom */
/* */
/********************************************************/
-
-
+
+
//
// TRANSLATION: MapObject Zoom <-> OpenLayers Zoom
//
-
+
/**
* Method: getOLZoomFromMapObjectZoom
* Get the OL zoom index from the map object zoom level
*
* Parameters:
* moZoom - {Integer}
- *
+ *
* Returns:
* {Integer} An OpenLayers Zoom level, translated from the passed in zoom
* Returns null if null value is passed in
@@ -24444,20 +26082,20 @@
}
return zoom;
},
-
+
/**
* Method: getMapObjectZoomFromOLZoom
* Get the map object zoom level from the OL zoom level
*
* Parameters:
* olZoom - {Integer}
- *
+ *
* Returns:
* {Integer} A MapObject level, translated from the passed in olZoom
* Returns null if null value is passed in
*/
getMapObjectZoomFromOLZoom: function(olZoom) {
- var zoom = null;
+ var zoom = null;
if (olZoom != null) {
zoom = olZoom + this.minZoomLevel;
}
@@ -24471,8 +26109,9 @@
OpenLayers/Layer/HTTPRequest.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
@@ -24482,47 +26121,47 @@
/**
* Class: OpenLayers.Layer.HTTPRequest
- *
- * Inherits from:
+ *
+ * Inherits from:
* - <OpenLayers.Layer>
*/
OpenLayers.Layer.HTTPRequest = OpenLayers.Class(OpenLayers.Layer, {
- /**
+ /**
* Constant: URL_HASH_FACTOR
* {Float} Used to hash URL param strings for multi-WMS server selection.
* Set to the Golden Ratio per Knuth's recommendation.
*/
URL_HASH_FACTOR: (Math.sqrt(5) - 1) / 2,
- /**
+ /**
* Property: url
- * {Array(String) or String} This is either an array of url strings or
- * a single url string.
+ * {Array(String) or String} This is either an array of url strings or
+ * a single url string.
*/
url: null,
- /**
+ /**
* Property: params
* {Object} Hashtable of key/value parameters
*/
params: null,
-
- /**
+
+ /**
* APIProperty: reproject
* *Deprecated*. See http://trac.openlayers.org/wiki/SpatialMercator
- * for information on the replacement for this functionality.
- * {Boolean} Whether layer should reproject itself based on base layer
- * locations. This allows reprojection onto commercial layers.
- * Default is false: Most layers can't reproject, but layers
+ * for information on the replacement for this functionality.
+ * {Boolean} Whether layer should reproject itself based on base layer
+ * locations. This allows reprojection onto commercial layers.
+ * Default is false: Most layers can't reproject, but layers
* which can create non-square geographic pixels can, like WMS.
- *
+ *
*/
reproject: false,
/**
* Constructor: OpenLayers.Layer.HTTPRequest
- *
+ *
* Parameters:
* name - {String}
* url - {Array(String) or String}
@@ -24543,39 +26182,39 @@
destroy: function() {
this.url = null;
this.params = null;
- OpenLayers.Layer.prototype.destroy.apply(this, arguments);
+ OpenLayers.Layer.prototype.destroy.apply(this, arguments);
},
-
+
/**
* APIMethod: clone
- *
+ *
* Parameters:
* obj - {Object}
- *
+ *
* Returns:
- * {<OpenLayers.Layer.HTTPRequest>} An exact clone of this
+ * {<OpenLayers.Layer.HTTPRequest>} An exact clone of this
* <OpenLayers.Layer.HTTPRequest>
*/
clone: function (obj) {
-
+
if (obj == null) {
obj = new OpenLayers.Layer.HTTPRequest(this.name,
this.url,
this.params,
- this.options);
+ this.getOptions());
}
-
+
//get all additions from superclasses
obj = OpenLayers.Layer.prototype.clone.apply(this, [obj]);
// copy/set any non-init, non-simple values here
-
+
return obj;
},
- /**
+ /**
* APIMethod: setUrl
- *
+ *
* Parameters:
* newUrl - {String}
*/
@@ -24585,7 +26224,7 @@
/**
* APIMethod: mergeNewParams
- *
+ *
* Parameters:
* newParams - {Object}
*
@@ -24594,7 +26233,14 @@
*/
mergeNewParams:function(newParams) {
this.params = OpenLayers.Util.extend(this.params, newParams);
- return this.redraw();
+ var ret = this.redraw();
+ if(this.map != null) {
+ this.map.events.triggerEvent("changelayer", {
+ layer: this,
+ property: "params"
+ });
+ }
+ return ret;
},
/**
@@ -24607,18 +26253,18 @@
* Returns:
* {Boolean} The layer was redrawn.
*/
- redraw: function(force) {
+ redraw: function(force) {
if (force) {
return this.mergeNewParams({"_olSalt": Math.random()});
} else {
return OpenLayers.Layer.prototype.redraw.apply(this, []);
}
},
-
+
/**
* Method: selectUrl
* selectUrl() implements the standard floating-point multiplicative
- * hash function described by Knuth, and hashes the contents of the
+ * hash function described by Knuth, and hashes the contents of the
* given param string into a float between 0 and 1. This float is then
* scaled to the size of the provided urls array, and used to select
* a URL.
@@ -24626,60 +26272,60 @@
* Parameters:
* paramString - {String}
* urls - {Array(String)}
- *
+ *
* Returns:
* {String} An entry from the urls array, deterministically selected based
* on the paramString.
*/
selectUrl: function(paramString, urls) {
var product = 1;
- for (var i=0, len=paramString.length; i<len; i++) {
- product *= paramString.charCodeAt(i) * this.URL_HASH_FACTOR;
- product -= Math.floor(product);
+ for (var i=0, len=paramString.length; i<len; i++) {
+ product *= paramString.charCodeAt(i) * this.URL_HASH_FACTOR;
+ product -= Math.floor(product);
}
return urls[Math.floor(product * urls.length)];
},
- /**
+ /**
* Method: getFullRequestString
- * Combine url with layer's params and these newParams.
+ * Combine url with layer's params and these newParams.
+ *
+ * does checking on the serverPath variable, allowing for cases when it
+ * is supplied with trailing ? or &, as well as cases where not.
*
- * does checking on the serverPath variable, allowing for cases when it
- * is supplied with trailing ? or &, as well as cases where not.
- *
* return in formatted string like this:
* "server?key1=value1&key2=value2&key3=value3"
- *
+ *
* WARNING: The altUrl parameter is deprecated and will be removed in 3.0.
*
* Parameters:
* newParams - {Object}
* altUrl - {String} Use this as the url instead of the layer's url
- *
- * Returns:
+ *
+ * Returns:
* {String}
*/
getFullRequestString:function(newParams, altUrl) {
// if not altUrl passed in, use layer's url
var url = altUrl || this.url;
-
- // create a new params hashtable with all the layer params and the
+
+ // create a new params hashtable with all the layer params and the
// new params together. then convert to string
var allParams = OpenLayers.Util.extend({}, this.params);
allParams = OpenLayers.Util.extend(allParams, newParams);
var paramsString = OpenLayers.Util.getParameterString(allParams);
-
- // if url is not a string, it should be an array of strings,
- // in which case we will deterministically select one of them in
+
+ // if url is not a string, it should be an array of strings,
+ // in which case we will deterministically select one of them in
// order to evenly distribute requests to different urls.
//
if (url instanceof Array) {
url = this.selectUrl(paramsString, url);
- }
-
+ }
+
// ignore parameters that are already in the url search string
- var urlParams =
+ var urlParams =
OpenLayers.Util.upperCaseObject(OpenLayers.Util.getParameters(url));
for(var key in allParams) {
if(key.toUpperCase() in urlParams) {
@@ -24687,26 +26333,8 @@
}
}
paramsString = OpenLayers.Util.getParameterString(allParams);
-
- // requestString always starts with url
- var requestString = url;
-
- if (paramsString != "") {
- var lastServerChar = url.charAt(url.length - 1);
- if ((lastServerChar == "&") || (lastServerChar == "?")) {
- requestString += paramsString;
- } else {
- if (url.indexOf('?') == -1) {
- //serverPath has no ? -- add one
- requestString += '?' + paramsString;
- } else {
- //serverPath contains ?, so must already have
- // paramsString at the end
- requestString += '&' + paramsString;
- }
- }
- }
- return requestString;
+
+ return OpenLayers.Util.urlAppend(url, paramsString);
},
CLASS_NAME: "OpenLayers.Layer.HTTPRequest"
@@ -24715,8 +26343,9 @@
OpenLayers/Layer/Markers.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
@@ -24726,49 +26355,49 @@
/**
* Class: OpenLayers.Layer.Markers
- *
+ *
* Inherits from:
- * - <OpenLayers.Layer>
+ * - <OpenLayers.Layer>
*/
OpenLayers.Layer.Markers = OpenLayers.Class(OpenLayers.Layer, {
-
- /**
- * APIProperty: isBaseLayer
- * {Boolean} Markers layer is never a base layer.
+
+ /**
+ * APIProperty: isBaseLayer
+ * {Boolean} Markers layer is never a base layer.
*/
isBaseLayer: false,
-
- /**
- * APIProperty: markers
- * {Array(<OpenLayers.Marker>)} internal marker list
+
+ /**
+ * APIProperty: markers
+ * {Array(<OpenLayers.Marker>)} internal marker list
*/
markers: null,
- /**
- * Property: drawn
+ /**
+ * Property: drawn
* {Boolean} internal state of drawing. This is a workaround for the fact
* that the map does not call moveTo with a zoomChanged when the map is
* first starting up. This lets us catch the case where we have *never*
* drawn the layer, and draw it even if the zoom hasn't changed.
*/
drawn: false,
-
+
/**
- * Constructor: OpenLayers.Layer.Markers
+ * Constructor: OpenLayers.Layer.Markers
* Create a Markers layer.
*
* Parameters:
- * name - {String}
+ * name - {String}
* options - {Object} Hashtable of extra options to tag onto the layer
*/
initialize: function(name, options) {
OpenLayers.Layer.prototype.initialize.apply(this, arguments);
this.markers = [];
},
-
+
/**
- * APIMethod: destroy
+ * APIMethod: destroy
*/
destroy: function() {
this.clearMarkers();
@@ -24779,7 +26408,7 @@
/**
* APIMethod: setOpacity
* Sets the opacity for all the markers.
- *
+ *
* Parameter:
* opacity - {Float}
*/
@@ -24792,13 +26421,13 @@
}
},
- /**
+ /**
* Method: moveTo
*
* Parameters:
- * bounds - {<OpenLayers.Bounds>}
- * zoomChanged - {Boolean}
- * dragging - {Boolean}
+ * bounds - {<OpenLayers.Bounds>}
+ * zoomChanged - {Boolean}
+ * dragging - {Boolean}
*/
moveTo:function(bounds, zoomChanged, dragging) {
OpenLayers.Layer.prototype.moveTo.apply(this, arguments);
@@ -24815,7 +26444,7 @@
* APIMethod: addMarker
*
* Parameters:
- * marker - {<OpenLayers.Marker>}
+ * marker - {<OpenLayers.Marker>}
*/
addMarker: function(marker) {
this.markers.push(marker);
@@ -24834,7 +26463,7 @@
* APIMethod: removeMarker
*
* Parameters:
- * marker - {<OpenLayers.Marker>}
+ * marker - {<OpenLayers.Marker>}
*/
removeMarker: function(marker) {
if (this.markers && this.markers.length) {
@@ -24856,13 +26485,13 @@
}
},
- /**
+ /**
* Method: drawMarker
- * Calculate the pixel location for the marker, create it, and
+ * Calculate the pixel location for the marker, create it, and
* add it to the layer's div
*
* Parameters:
- * marker - {<OpenLayers.Marker>}
+ * marker - {<OpenLayers.Marker>}
*/
drawMarker: function(marker) {
var px = this.map.getLayerPxFromLonLat(marker.lonlat);
@@ -24877,17 +26506,17 @@
}
}
},
-
- /**
+
+ /**
* APIMethod: getDataExtent
* Calculates the max extent which includes all of the markers.
- *
+ *
* Returns:
* {<OpenLayers.Bounds>}
*/
getDataExtent: function () {
var maxExtent = null;
-
+
if ( this.markers && (this.markers.length > 0)) {
var maxExtent = new OpenLayers.Bounds();
for(var i=0, len=this.markers.length; i<len; i++) {
@@ -24905,6 +26534,11 @@
OpenLayers/Layer/SphericalMercator.js
====================================================================== */
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
/**
* @requires OpenLayers/Layer.js
* @requires OpenLayers/Projection.js
@@ -24929,12 +26563,12 @@
*
* WKT:
* 900913=PROJCS["WGS84 / Simple Mercator", GEOGCS["WGS 84",
- * DATUM["WGS_1984", SPHEROID["WGS_1984", 6378137.0, 298.257223563]],
- * PRIMEM["Greenwich", 0.0], UNIT["degree", 0.017453292519943295],
+ * DATUM["WGS_1984", SPHEROID["WGS_1984", 6378137.0, 298.257223563]],
+ * PRIMEM["Greenwich", 0.0], UNIT["degree", 0.017453292519943295],
* AXIS["Longitude", EAST], AXIS["Latitude", NORTH]],
- * PROJECTION["Mercator_1SP_Google"],
- * PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 0.0],
- * PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0],
+ * PROJECTION["Mercator_1SP_Google"],
+ * PARAMETER["latitude_of_origin", 0.0], PARAMETER["central_meridian", 0.0],
+ * PARAMETER["scale_factor", 1.0], PARAMETER["false_easting", 0.0],
* PARAMETER["false_northing", 0.0], UNIT["m", 1.0], AXIS["x", EAST],
* AXIS["y", NORTH], AUTHORITY["EPSG","900913"]]
*/
@@ -24958,7 +26592,39 @@
},
/**
- * Method: initMercatorParameters
+ * Method: getLonLatFromViewPortPx
+ * Get a map location from a pixel location
+ *
+ * Parameters:
+ * viewPortPx - {<OpenLayers.Pixel>}
+ *
+ * Returns:
+ * {<OpenLayers.LonLat>} An OpenLayers.LonLat which is the passed-in view
+ * port OpenLayers.Pixel, translated into lon/lat by map lib
+ * If the map lib is not loaded or not centered, returns null
+ */
+ getLonLatFromViewPortPx: function (viewPortPx) {
+ return OpenLayers.Layer.prototype.getLonLatFromViewPortPx.apply(this, arguments);
+ },
+
+ /**
+ * Method: getViewPortPxFromLonLat
+ * Get a pixel location from a map location
+ *
+ * Parameters:
+ * lonlat - {<OpenLayers.LonLat>}
+ *
+ * Returns:
+ * {<OpenLayers.Pixel>} An OpenLayers.Pixel which is the passed-in
+ * OpenLayers.LonLat, translated into view port pixels by map lib
+ * If map lib is not loaded or not centered, returns null
+ */
+ getViewPortPxFromLonLat: function (lonlat) {
+ return OpenLayers.Layer.prototype.getViewPortPxFromLonLat.apply(this, arguments);
+ },
+
+ /**
+ * Method: initMercatorParameters
* Set up the mercator parameters on the layer: resolutions,
* projection, units.
*/
@@ -24970,7 +26636,7 @@
this.RESOLUTIONS[zoom] = maxResolution / Math.pow(2, zoom);
}
this.units = "m";
- this.projection = "EPSG:900913";
+ this.projection = this.projection || "EPSG:900913";
},
/**
@@ -24978,9 +26644,9 @@
* Given a lon,lat in EPSG:4326, return a point in Spherical Mercator.
*
* Parameters:
- * lon - {float}
+ * lon - {float}
* lat - {float}
- *
+ *
* Returns:
* {<OpenLayers.LonLat>} The coordinates transformed to Mercator.
*/
@@ -24989,7 +26655,7 @@
var y = Math.log(Math.tan((90 + lat) * Math.PI / 360)) / (Math.PI / 180);
y = y * 20037508.34 / 180;
-
+
return new OpenLayers.LonLat(x, y);
},
@@ -25000,7 +26666,7 @@
* Parameters:
* x - {float} A map x in Spherical Mercator.
* y - {float} A map y in Spherical Mercator.
- *
+ *
* Returns:
* {<OpenLayers.LonLat>} The coordinates transformed to EPSG:4326.
*/
@@ -25010,19 +26676,19 @@
var lat = (y / 20037508.34) * 180;
lat = 180/Math.PI * (2 * Math.atan(Math.exp(lat * Math.PI / 180)) - Math.PI / 2);
-
+
return new OpenLayers.LonLat(lon, lat);
},
/**
- * Method: projectForward
+ * Method: projectForward
* Given an object with x and y properties in EPSG:4326, modify the x,y
* properties on the object to be the Spherical Mercator projected
* coordinates.
*
* Parameters:
- * point - {Object} An object with x and y properties.
- *
+ * point - {Object} An object with x and y properties.
+ *
* Returns:
* {Object} The point, with the x and y properties transformed to spherical
* mercator.
@@ -25033,15 +26699,15 @@
point.y = lonlat.lat;
return point;
},
-
+
/**
* Method: projectInverse
* Given an object with x and y properties in Spherical Mercator, modify
* the x,y properties on the object to be the unprojected coordinates.
*
* Parameters:
- * point - {Object} An object with x and y properties.
- *
+ * point - {Object} An object with x and y properties.
+ *
* Returns:
* {Object} The point, with the x and y properties transformed from
* spherical mercator to unprojected coordinates..
@@ -25068,8 +26734,9 @@
OpenLayers/Control/DrawFeature.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
@@ -25087,7 +26754,7 @@
* - <OpenLayers.Control>
*/
OpenLayers.Control.DrawFeature = OpenLayers.Class(OpenLayers.Control, {
-
+
/**
* Property: layer
* {<OpenLayers.Layer.Vector>}
@@ -25099,7 +26766,7 @@
* {Object} The functions that are sent to the handler for callback
*/
callbacks: null,
-
+
/**
* Constant: EVENT_TYPES
*
@@ -25107,6 +26774,13 @@
* featureadded - Triggered when a feature is added
*/
EVENT_TYPES: ["featureadded"],
+
+ /**
+ * APIProperty: multi
+ * {Boolean} Cast features to multi-part geometries before passing to the
+ * layer. Default is false.
+ */
+ multi: false,
/**
* APIProperty: featureAdded
@@ -25119,23 +26793,23 @@
* {Object} Used to set non-default properties on the control's handler
*/
handlerOptions: null,
-
+
/**
* Constructor: OpenLayers.Control.DrawFeature
- *
+ *
* Parameters:
- * layer - {<OpenLayers.Layer.Vector>}
- * handler - {<OpenLayers.Handler>}
- * options - {Object}
+ * layer - {<OpenLayers.Layer.Vector>}
+ * handler - {<OpenLayers.Handler>}
+ * options - {Object}
*/
initialize: function(layer, handler, options) {
-
+
// concatenate events specific to vector with those from the base
this.EVENT_TYPES =
OpenLayers.Control.DrawFeature.prototype.EVENT_TYPES.concat(
OpenLayers.Control.prototype.EVENT_TYPES
);
-
+
OpenLayers.Control.prototype.initialize.apply(this, [options]);
this.callbacks = OpenLayers.Util.extend(
{
@@ -25154,9 +26828,12 @@
this.callbacks
);
this.layer = layer;
+ this.handlerOptions = this.handlerOptions || {};
+ if (!("multi" in this.handlerOptions)) {
+ this.handlerOptions.multi = this.multi;
+ }
var sketchStyle = this.layer.styleMap && this.layer.styleMap.styles.temporary;
if(sketchStyle) {
- this.handlerOptions = this.handlerOptions || {};
this.handlerOptions.layerOptions = OpenLayers.Util.applyDefaults(
this.handlerOptions.layerOptions,
{styleMap: new OpenLayers.StyleMap({"default": sketchStyle})}
@@ -25187,8 +26864,9 @@
OpenLayers/Control/Measure.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -25231,20 +26909,20 @@
* {Object} Used to set non-default properties on the control's handler
*/
handlerOptions: null,
-
+
/**
* Property: callbacks
* {Object} The functions that are sent to the handler for callback
*/
callbacks: null,
-
+
/**
* Property: displaySystem
* {String} Display system for output measurements. Supported values
* are 'english', 'metric', and 'geographic'. Default is 'metric'.
*/
displaySystem: 'metric',
-
+
/**
* Property: geodesic
* {Boolean} Calculate geodesic metrics instead of planar metrics. This
@@ -25252,7 +26930,7 @@
* (if that is not already the map projection). Default is false.
*/
geodesic: false,
-
+
/**
* Property: displaySystemUnits
* {Object} Units for various measurement systems. Values are arrays
@@ -25281,7 +26959,7 @@
* {Number} Timeout id of trigger for measurepartial.
*/
delayedTrigger: null,
-
+
/**
* APIProperty: persist
* {Boolean} Keep the temporary measurement sketch drawn after the
@@ -25293,10 +26971,10 @@
/**
* Constructor: OpenLayers.Control.Measure
- *
+ *
* Parameters:
- * handler - {<OpenLayers.Handler>}
- * options - {Object}
+ * handler - {<OpenLayers.Handler>}
+ * options - {Object}
*/
initialize: function(handler, options) {
// concatenate events specific to measure with those from the base
@@ -25310,14 +26988,14 @@
this.callbacks
);
- // let the handler options override, so old code that passes 'persist'
+ // let the handler options override, so old code that passes 'persist'
// directly to the handler does not need an update
this.handlerOptions = OpenLayers.Util.extend(
{persist: this.persist}, this.handlerOptions
);
this.handler = new handler(this, this.callbacks, this.handlerOptions);
},
-
+
/**
* APIMethod: cancel
* Stop the control from measuring. If <persist> is true, the temporary
@@ -25326,7 +27004,7 @@
cancel: function() {
this.handler.cancel();
},
-
+
/**
* Method: updateHandler
*
@@ -25358,7 +27036,7 @@
}
this.measure(geometry, "measure");
},
-
+
/**
* Method: measurePartial
* Called each time a new point is added to the measurement sketch.
@@ -25368,12 +27046,15 @@
* geometry - {<OpenLayers.Geometry>} The sketch geometry.
*/
measurePartial: function(point, geometry) {
- this.delayedTrigger = window.setTimeout(
- OpenLayers.Function.bind(function() {
- this.measure(geometry, "measurepartial");
- }, this),
- this.partialDelay
- );
+ if (geometry.getLength() > 0) {
+ geometry = geometry.clone();
+ this.delayedTrigger = window.setTimeout(
+ OpenLayers.Function.bind(function() {
+ this.measure(geometry, "measurepartial");
+ }, this),
+ this.partialDelay
+ );
+ }
},
/**
@@ -25399,7 +27080,7 @@
geometry: geometry
});
},
-
+
/**
* Method: getBestArea
* Based on the <displaySystem> returns the area of a geometry.
@@ -25423,7 +27104,7 @@
}
return [area, unit];
},
-
+
/**
* Method: getArea
*
@@ -25450,7 +27131,7 @@
}
return area;
},
-
+
/**
* Method: getBestLength
* Based on the <displaySystem> returns the length of a geometry.
@@ -25508,8 +27189,9 @@
OpenLayers/Control/ZoomBox.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -25519,8 +27201,8 @@
/**
* Class: OpenLayers.Control.ZoomBox
- * The ZoomBox control enables zooming directly to a given extent, by drawing
- * a box on the map. The box is drawn by holding down shift, whilst dragging
+ * The ZoomBox control enables zooming directly to a given extent, by drawing
+ * a box on the map. The box is drawn by holding down shift, whilst dragging
* the mouse.
*
* Inherits from:
@@ -25541,13 +27223,13 @@
/**
* Property: alwaysZoom
- * {Boolean} Always zoom in/out, when box drawed
+ * {Boolean} Always zoom in/out, when box drawed
*/
alwaysZoom: false,
/**
* Method: draw
- */
+ */
draw: function() {
this.handler = new OpenLayers.Handler.Box( this,
{done: this.zoomBox}, {keyMask: this.keyMask} );
@@ -25561,12 +27243,13 @@
*/
zoomBox: function (position) {
if (position instanceof OpenLayers.Bounds) {
+ var bounds;
if (!this.out) {
var minXY = this.map.getLonLatFromPixel(
new OpenLayers.Pixel(position.left, position.bottom));
var maxXY = this.map.getLonLatFromPixel(
new OpenLayers.Pixel(position.right, position.top));
- var bounds = new OpenLayers.Bounds(minXY.lon, minXY.lat,
+ bounds = new OpenLayers.Bounds(minXY.lon, minXY.lat,
maxXY.lon, maxXY.lat);
} else {
var pixWidth = Math.abs(position.right-position.left);
@@ -25580,13 +27263,13 @@
var xmax = center.lon + (extent.getWidth()/2)*zoomFactor;
var ymin = center.lat - (extent.getHeight()/2)*zoomFactor;
var ymax = center.lat + (extent.getHeight()/2)*zoomFactor;
- var bounds = new OpenLayers.Bounds(xmin, ymin, xmax, ymax);
+ bounds = new OpenLayers.Bounds(xmin, ymin, xmax, ymax);
}
- // always zoom in/out
- var lastZoom = this.map.getZoom();
+ // always zoom in/out
+ var lastZoom = this.map.getZoom();
this.map.zoomToExtent(bounds);
- if (lastZoom == this.map.getZoom() && this.alwaysZoom == true){
- this.map.zoomTo(lastZoom + (this.out ? -1 : 1));
+ if (lastZoom == this.map.getZoom() && this.alwaysZoom == true){
+ this.map.zoomTo(lastZoom + (this.out ? -1 : 1));
}
} else { // it's a pixel
if (!this.out) {
@@ -25605,8 +27288,9 @@
OpenLayers/Format/WKT.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -25618,12 +27302,12 @@
* Class: OpenLayers.Format.WKT
* Class for reading and writing Well-Known Text. Create a new instance
* with the <OpenLayers.Format.WKT> constructor.
- *
+ *
* Inherits from:
* - <OpenLayers.Format>
*/
OpenLayers.Format.WKT = OpenLayers.Class(OpenLayers.Format, {
-
+
/**
* Constructor: OpenLayers.Format.WKT
* Create a new parser for WKT
@@ -25670,7 +27354,7 @@
features = this.parse[type].apply(this, [str]);
}
if (this.internalProjection && this.externalProjection) {
- if (features &&
+ if (features &&
features.CLASS_NAME == "OpenLayers.Feature.Vector") {
features.geometry.transform(this.externalProjection,
this.internalProjection);
@@ -25684,7 +27368,7 @@
}
}
}
- }
+ }
return features;
},
@@ -25723,9 +27407,9 @@
}
if (this.internalProjection && this.externalProjection) {
geometry = geometry.clone();
- geometry.transform(this.internalProjection,
+ geometry.transform(this.internalProjection,
this.externalProjection);
- }
+ }
data = this.extract[type].apply(this, [geometry]);
pieces.push(type.toUpperCase() + '(' + data + ')');
}
@@ -25734,7 +27418,7 @@
}
return pieces.join('');
},
-
+
/**
* Object with properties corresponding to the geometry types.
* Property values are functions that do the actual data extraction.
@@ -25758,11 +27442,13 @@
'multipoint': function(multipoint) {
var array = [];
for(var i=0, len=multipoint.components.length; i<len; ++i) {
- array.push(this.extract.point.apply(this, [multipoint.components[i]]));
+ array.push('(' +
+ this.extract.point.apply(this, [multipoint.components[i]]) +
+ ')');
}
return array.join(',');
},
-
+
/**
* Return a comma delimited string of point coordinates from a line.
* @param {<OpenLayers.Geometry.LineString>} linestring
@@ -25792,7 +27478,7 @@
}
return array.join(',');
},
-
+
/**
* Return a comma delimited string of linear ring arrays from a polygon.
* @param {<OpenLayers.Geometry.Polygon>} polygon
@@ -25851,16 +27537,18 @@
* @private
*/
'multipoint': function(str) {
- var points = OpenLayers.String.trim(str).split(',');
+ var point;
+ var points = OpenLayers.String.trim(str).split(this.regExes.parenComma);
var components = [];
for(var i=0, len=points.length; i<len; ++i) {
- components.push(this.parse.point.apply(this, [points[i]]).geometry);
+ point = points[i].replace(this.regExes.trimParens, '$1');
+ components.push(this.parse.point.apply(this, [point]).geometry);
}
return new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.MultiPoint(components)
);
},
-
+
/**
* Return a linestring feature given a linestring WKT fragment.
* @param {String} A WKT fragment representing the linestring
@@ -25896,7 +27584,7 @@
new OpenLayers.Geometry.MultiLineString(components)
);
},
-
+
/**
* Return a polygon feature given a polygon WKT fragment.
* @param {String} A WKT fragment representing the polygon
@@ -25956,14 +27644,15 @@
},
- CLASS_NAME: "OpenLayers.Format.WKT"
-});
+ CLASS_NAME: "OpenLayers.Format.WKT"
+});
/* ======================================================================
OpenLayers/Layer/Google.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
@@ -25971,59 +27660,60 @@
* @requires OpenLayers/Layer/SphericalMercator.js
* @requires OpenLayers/Layer/EventPane.js
* @requires OpenLayers/Layer/FixedZoomLevels.js
- * @requires OpenLayers/Console.js
*/
/**
* Class: OpenLayers.Layer.Google
- *
+ *
* Inherits from:
* - <OpenLayers.Layer.SphericalMercator>
* - <OpenLayers.Layer.EventPane>
* - <OpenLayers.Layer.FixedZoomLevels>
*/
OpenLayers.Layer.Google = OpenLayers.Class(
- OpenLayers.Layer.EventPane,
+ OpenLayers.Layer.EventPane,
OpenLayers.Layer.FixedZoomLevels, {
-
- /**
+
+ /**
* Constant: MIN_ZOOM_LEVEL
- * {Integer} 0
+ * {Integer} 0
*/
MIN_ZOOM_LEVEL: 0,
-
- /**
+
+ /**
* Constant: MAX_ZOOM_LEVEL
- * {Integer} 19
+ * {Integer} 21
*/
- MAX_ZOOM_LEVEL: 19,
+ MAX_ZOOM_LEVEL: 21,
- /**
+ /**
* Constant: RESOLUTIONS
* {Array(Float)} Hardcode these resolutions so that they are more closely
* tied with the standard wms projection
*/
RESOLUTIONS: [
- 1.40625,
- 0.703125,
- 0.3515625,
- 0.17578125,
- 0.087890625,
+ 1.40625,
+ 0.703125,
+ 0.3515625,
+ 0.17578125,
+ 0.087890625,
0.0439453125,
- 0.02197265625,
- 0.010986328125,
- 0.0054931640625,
+ 0.02197265625,
+ 0.010986328125,
+ 0.0054931640625,
0.00274658203125,
- 0.001373291015625,
- 0.0006866455078125,
+ 0.001373291015625,
+ 0.0006866455078125,
0.00034332275390625,
- 0.000171661376953125,
- 0.0000858306884765625,
+ 0.000171661376953125,
+ 0.0000858306884765625,
0.00004291534423828125,
- 0.00002145767211914062,
+ 0.00002145767211914062,
0.00001072883605957031,
- 0.00000536441802978515,
- 0.00000268220901489257
+ 0.00000536441802978515,
+ 0.00000268220901489257,
+ 0.0000013411045074462891,
+ 0.00000067055225372314453
],
/**
@@ -26033,147 +27723,504 @@
type: null,
/**
- * APIProperty: sphericalMercator
- * {Boolean} Should the map act as a mercator-projected map? This will
- * cause all interactions with the map to be in the actual map
- * projection, which allows support for vector drawing, overlaying
- * other maps, etc.
+ * APIProperty: wrapDateLine
+ * {Boolean} Allow user to pan forever east/west. Default is true.
+ * Setting this to false only restricts panning if
+ * <sphericalMercator> is true.
*/
- sphericalMercator: false,
+ wrapDateLine: true,
/**
- * Property: dragObject
- * {GDraggableObject} Since 2.93, Google has exposed the ability to get
- * the maps GDraggableObject. We can now use this for smooth panning
+ * APIProperty: sphericalMercator
+ * {Boolean} Should the map act as a mercator-projected map? This will
+ * cause all interactions with the map to be in the actual map
+ * projection, which allows support for vector drawing, overlaying
+ * other maps, etc.
*/
- dragObject: null,
-
+ sphericalMercator: false,
+
/**
- * Property: termsOfUse
- * {DOMElement} Div for Google's copyright and terms of use link
+ * Property: version
+ * {Number} The version of the Google Maps API
*/
- termsOfUse: null,
+ version: null,
- /**
- * Property: poweredBy
- * {DOMElement} Div for Google's powered by logo and link
- */
- poweredBy: null,
-
- /**
+ /**
* Constructor: OpenLayers.Layer.Google
- *
+ *
* Parameters:
* name - {String} A name for the layer.
* options - {Object} An optional object whose properties will be set
* on the layer.
*/
initialize: function(name, options) {
- OpenLayers.Layer.EventPane.prototype.initialize.apply(this, arguments);
- OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this,
- arguments);
- this.addContainerPxFunction();
+ options = options || {};
+ if(!options.version) {
+ options.version = typeof GMap2 === "function" ? "2" : "3";
+ }
+ var mixin = OpenLayers.Layer.Google["v" +
+ options.version.replace(/\./g, "_")];
+ if (mixin) {
+ OpenLayers.Util.applyDefaults(options, mixin);
+ } else {
+ throw "Unsupported Google Maps API version: " + options.version;
+ }
+
+ OpenLayers.Util.applyDefaults(options, mixin.DEFAULTS);
+ if (options.maxExtent) {
+ options.maxExtent = options.maxExtent.clone();
+ }
+
+ OpenLayers.Layer.EventPane.prototype.initialize.apply(this,
+ [name, options]);
+ OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this,
+ [name, options]);
+
if (this.sphericalMercator) {
OpenLayers.Util.extend(this, OpenLayers.Layer.SphericalMercator);
this.initMercatorParameters();
- }
+ }
},
/**
- * Method: loadMapObject
- * Load the GMap and register appropriate event listeners. If we can't
- * load GMap2, then display a warning message.
+ * Method: clone
+ * Create a clone of this layer
+ *
+ * Returns:
+ * {<OpenLayers.Layer.Google>} An exact clone of this layer
*/
- loadMapObject:function() {
+ clone: function() {
+ /**
+ * This method isn't intended to be called by a subclass and it
+ * doesn't call the same method on the superclass. We don't call
+ * the super's clone because we don't want properties that are set
+ * on this layer after initialize (i.e. this.mapObject etc.).
+ */
+ return new OpenLayers.Layer.Google(
+ this.name, this.getOptions()
+ );
+ },
- //has gmaps library has been loaded?
- try {
- // create GMap, hide nav controls
- this.mapObject = new GMap2( this.div );
+ /**
+ * APIMethod: setVisibility
+ * Set the visibility flag for the layer and hide/show & redraw
+ * accordingly. Fire event unless otherwise specified
+ *
+ * Note that visibility is no longer simply whether or not the layer's
+ * style.display is set to "block". Now we store a 'visibility' state
+ * property on the layer class, this allows us to remember whether or
+ * not we *desire* for a layer to be visible. In the case where the
+ * map's resolution is out of the layer's range, this desire may be
+ * subverted.
+ *
+ * Parameters:
+ * visible - {Boolean} Display the layer (if in range)
+ */
+ setVisibility: function(visible) {
+ // sharing a map container, opacity has to be set per layer
+ var opacity = this.opacity == null ? 1 : this.opacity;
+ OpenLayers.Layer.EventPane.prototype.setVisibility.apply(this, arguments);
+ this.setOpacity(opacity);
+ },
+
+ /**
+ * APIMethod: display
+ * Hide or show the Layer
+ *
+ * Parameters:
+ * display - {Boolean}
+ */
+ display: function(visible) {
+ if (!this._dragging) {
+ this.setGMapVisibility(visible);
+ }
+ OpenLayers.Layer.EventPane.prototype.display.apply(this, arguments);
+ },
+
+ /**
+ * Method: moveTo
+ *
+ * Parameters:
+ * bound - {<OpenLayers.Bounds>}
+ * zoomChanged - {Boolean} Tells when zoom has changed, as layers have to
+ * do some init work in that case.
+ * dragging - {Boolean}
+ */
+ moveTo: function(bounds, zoomChanged, dragging) {
+ this._dragging = dragging;
+ OpenLayers.Layer.EventPane.prototype.moveTo.apply(this, arguments);
+ delete this._dragging;
+ },
+
+ /**
+ * APIMethod: setOpacity
+ * Sets the opacity for the entire layer (all images)
+ *
+ * Parameter:
+ * opacity - {Float}
+ */
+ setOpacity: function(opacity) {
+ if (opacity !== this.opacity) {
+ if (this.map != null) {
+ this.map.events.triggerEvent("changelayer", {
+ layer: this,
+ property: "opacity"
+ });
+ }
+ this.opacity = opacity;
+ }
+ // Though this layer's opacity may not change, we're sharing a container
+ // and need to update the opacity for the entire container.
+ if (this.getVisibility()) {
+ var container = this.getMapContainer();
+ OpenLayers.Util.modifyDOMElement(
+ container, null, null, null, null, null, null, opacity
+ );
+ }
+ },
- //since v 2.93 getDragObject is now available.
- if(typeof this.mapObject.getDragObject == "function") {
- this.dragObject = this.mapObject.getDragObject();
- } else {
- this.dragPanMapObject = null;
+ /**
+ * APIMethod: destroy
+ * Clean up this layer.
+ */
+ destroy: function() {
+ /**
+ * We have to override this method because the event pane destroy
+ * deletes the mapObject reference before removing this layer from
+ * the map.
+ */
+ if (this.map) {
+ this.setGMapVisibility(false);
+ var cache = OpenLayers.Layer.Google.cache[this.map.id];
+ if (cache && cache.count <= 1) {
+ this.removeGMapElements();
+ }
+ }
+ OpenLayers.Layer.EventPane.prototype.destroy.apply(this, arguments);
+ },
+
+ /**
+ * Method: removeGMapElements
+ * Remove all elements added to the dom. This should only be called if
+ * this is the last of the Google layers for the given map.
+ */
+ removeGMapElements: function() {
+ var cache = OpenLayers.Layer.Google.cache[this.map.id];
+ if (cache) {
+ // remove shared elements from dom
+ var container = this.mapObject && this.getMapContainer();
+ if (container && container.parentNode) {
+ container.parentNode.removeChild(container);
}
+ var termsOfUse = cache.termsOfUse;
+ if (termsOfUse && termsOfUse.parentNode) {
+ termsOfUse.parentNode.removeChild(termsOfUse);
+ }
+ var poweredBy = cache.poweredBy;
+ if (poweredBy && poweredBy.parentNode) {
+ poweredBy.parentNode.removeChild(poweredBy);
+ }
+ }
+ },
- // move the ToS and branding stuff up to the container div
- this.termsOfUse = this.div.lastChild;
- this.div.removeChild(this.termsOfUse);
- if (this.isFixed) {
- this.map.viewPortDiv.appendChild(this.termsOfUse);
+ /**
+ * APIMethod: removeMap
+ * On being removed from the map, also remove termsOfUse and poweredBy divs
+ *
+ * Parameters:
+ * map - {<OpenLayers.Map>}
+ */
+ removeMap: function(map) {
+ // hide layer before removing
+ if (this.visibility && this.mapObject) {
+ this.setGMapVisibility(false);
+ }
+ // check to see if last Google layer in this map
+ var cache = OpenLayers.Layer.Google.cache[map.id];
+ if (cache) {
+ if (cache.count <= 1) {
+ this.removeGMapElements();
+ delete OpenLayers.Layer.Google.cache[map.id];
} else {
- this.map.layerContainerDiv.appendChild(this.termsOfUse);
+ // decrement the layer count
+ --cache.count;
}
- this.termsOfUse.style.zIndex = "1100";
- this.termsOfUse.style.display = this.div.style.display;
- this.termsOfUse.style.right = "";
- this.termsOfUse.style.bottom = "";
- this.termsOfUse.className = "olLayerGoogleCopyright";
+ }
+ // remove references to gmap elements
+ delete this.termsOfUse;
+ delete this.poweredBy;
+ delete this.mapObject;
+ delete this.dragObject;
+ OpenLayers.Layer.EventPane.prototype.removeMap.apply(this, arguments);
+ },
+
+ //
+ // TRANSLATION: MapObject Bounds <-> OpenLayers.Bounds
+ //
- this.poweredBy = this.div.lastChild;
- this.div.removeChild(this.poweredBy);
- if (this.isFixed) {
- this.map.viewPortDiv.appendChild(this.poweredBy);
+ /**
+ * APIMethod: getOLBoundsFromMapObjectBounds
+ *
+ * Parameters:
+ * moBounds - {Object}
+ *
+ * Returns:
+ * {<OpenLayers.Bounds>} An <OpenLayers.Bounds>, translated from the
+ * passed-in MapObject Bounds.
+ * Returns null if null value is passed in.
+ */
+ getOLBoundsFromMapObjectBounds: function(moBounds) {
+ var olBounds = null;
+ if (moBounds != null) {
+ var sw = moBounds.getSouthWest();
+ var ne = moBounds.getNorthEast();
+ if (this.sphericalMercator) {
+ sw = this.forwardMercator(sw.lng(), sw.lat());
+ ne = this.forwardMercator(ne.lng(), ne.lat());
} else {
- this.map.layerContainerDiv.appendChild(this.poweredBy);
- }
- this.poweredBy.style.zIndex = "1100";
- this.poweredBy.style.display = this.div.style.display;
- this.poweredBy.style.right = "";
- this.poweredBy.style.bottom = "";
- this.poweredBy.className = "olLayerGooglePoweredBy gmnoprint";
-
- } catch (e) {
- OpenLayers.Console.error(e);
+ sw = new OpenLayers.LonLat(sw.lng(), sw.lat());
+ ne = new OpenLayers.LonLat(ne.lng(), ne.lat());
+ }
+ olBounds = new OpenLayers.Bounds(sw.lon,
+ sw.lat,
+ ne.lon,
+ ne.lat );
}
+ return olBounds;
+ },
+ /**
+ * APIMethod: getWarningHTML
+ *
+ * Returns:
+ * {String} String with information on why layer is broken, how to get
+ * it working.
+ */
+ getWarningHTML:function() {
+ return OpenLayers.i18n("googleWarning");
},
+
+ /************************************
+ * *
+ * MapObject Interface Controls *
+ * *
+ ************************************/
+
+
+ // Get&Set Center, Zoom
+
/**
- * APIMethod: setMap
- * Overridden from EventPane because if a map type has been specified,
- * we need to attach a listener for the first moveend -- this is how
- * we will know that the map has been centered. Only once the map has
- * been centered is it safe to change the gmap object's map type.
- *
+ * APIMethod: getMapObjectCenter
+ *
+ * Returns:
+ * {Object} The mapObject's current center in Map Object format
+ */
+ getMapObjectCenter: function() {
+ return this.mapObject.getCenter();
+ },
+
+ /**
+ * APIMethod: getMapObjectZoom
+ *
+ * Returns:
+ * {Integer} The mapObject's current zoom, in Map Object format
+ */
+ getMapObjectZoom: function() {
+ return this.mapObject.getZoom();
+ },
+
+
+ /************************************
+ * *
+ * MapObject Primitives *
+ * *
+ ************************************/
+
+
+ // LonLat
+
+ /**
+ * APIMethod: getLongitudeFromMapObjectLonLat
+ *
* Parameters:
- * map - {<OpenLayers.Map>}
+ * moLonLat - {Object} MapObject LonLat format
+ *
+ * Returns:
+ * {Float} Longitude of the given MapObject LonLat
*/
- setMap: function(map) {
- OpenLayers.Layer.EventPane.prototype.setMap.apply(this, arguments);
+ getLongitudeFromMapObjectLonLat: function(moLonLat) {
+ return this.sphericalMercator ?
+ this.forwardMercator(moLonLat.lng(), moLonLat.lat()).lon :
+ moLonLat.lng();
+ },
- if (this.type != null) {
- this.map.events.register("moveend", this, this.setMapType);
- }
+ /**
+ * APIMethod: getLatitudeFromMapObjectLonLat
+ *
+ * Parameters:
+ * moLonLat - {Object} MapObject LonLat format
+ *
+ * Returns:
+ * {Float} Latitude of the given MapObject LonLat
+ */
+ getLatitudeFromMapObjectLonLat: function(moLonLat) {
+ var lat = this.sphericalMercator ?
+ this.forwardMercator(moLonLat.lng(), moLonLat.lat()).lat :
+ moLonLat.lat();
+ return lat;
},
+
+ // Pixel
+
+ /**
+ * APIMethod: getXFromMapObjectPixel
+ *
+ * Parameters:
+ * moPixel - {Object} MapObject Pixel format
+ *
+ * Returns:
+ * {Integer} X value of the MapObject Pixel
+ */
+ getXFromMapObjectPixel: function(moPixel) {
+ return moPixel.x;
+ },
/**
- * Method: setMapType
- * The map has been centered, and a map type was specified, so we
- * set the map type on the gmap object, then unregister the listener
- * so that we dont keep doing this every time the map moves.
+ * APIMethod: getYFromMapObjectPixel
+ *
+ * Parameters:
+ * moPixel - {Object} MapObject Pixel format
+ *
+ * Returns:
+ * {Integer} Y value of the MapObject Pixel
*/
- setMapType: function() {
- if (this.mapObject.getCenter() != null) {
+ getYFromMapObjectPixel: function(moPixel) {
+ return moPixel.y;
+ },
+
+ CLASS_NAME: "OpenLayers.Layer.Google"
+});
- // Support for custom map types.
- if (OpenLayers.Util.indexOf(this.mapObject.getMapTypes(),
- this.type) == -1) {
- this.mapObject.addMapType(this.type);
+/**
+ * Property: OpenLayers.Layer.Google.cache
+ * {Object} Cache for elements that should only be created once per map.
+ */
+OpenLayers.Layer.Google.cache = {};
+
+
+/**
+ * Constant: OpenLayers.Layer.Google.v2
+ *
+ * Mixin providing functionality specific to the Google Maps API v2.
+ */
+OpenLayers.Layer.Google.v2 = {
+
+ /**
+ * Property: termsOfUse
+ * {DOMElement} Div for Google's copyright and terms of use link
+ */
+ termsOfUse: null,
+
+ /**
+ * Property: poweredBy
+ * {DOMElement} Div for Google's powered by logo and link
+ */
+ poweredBy: null,
+
+ /**
+ * Property: dragObject
+ * {GDraggableObject} Since 2.93, Google has exposed the ability to get
+ * the maps GDraggableObject. We can now use this for smooth panning
+ */
+ dragObject: null,
+
+ /**
+ * Method: loadMapObject
+ * Load the GMap and register appropriate event listeners. If we can't
+ * load GMap2, then display a warning message.
+ */
+ loadMapObject:function() {
+ if (!this.type) {
+ this.type = G_NORMAL_MAP;
+ }
+ var mapObject, termsOfUse, poweredBy;
+ var cache = OpenLayers.Layer.Google.cache[this.map.id];
+ if (cache) {
+ // there are already Google layers added to this map
+ mapObject = cache.mapObject;
+ termsOfUse = cache.termsOfUse;
+ poweredBy = cache.poweredBy;
+ // increment the layer count
+ ++cache.count;
+ } else {
+ // this is the first Google layer for this map
+
+ var container = this.map.viewPortDiv;
+ var div = document.createElement("div");
+ div.id = this.map.id + "_GMap2Container";
+ div.style.position = "absolute";
+ div.style.width = "100%";
+ div.style.height = "100%";
+ container.appendChild(div);
+
+ // create GMap and shuffle elements
+ try {
+ mapObject = new GMap2(div);
+
+ // move the ToS and branding stuff up to the container div
+ termsOfUse = div.lastChild;
+ container.appendChild(termsOfUse);
+ termsOfUse.style.zIndex = "1100";
+ termsOfUse.style.right = "";
+ termsOfUse.style.bottom = "";
+ termsOfUse.className = "olLayerGoogleCopyright";
+
+ poweredBy = div.lastChild;
+ container.appendChild(poweredBy);
+ poweredBy.style.zIndex = "1100";
+ poweredBy.style.right = "";
+ poweredBy.style.bottom = "";
+ poweredBy.className = "olLayerGooglePoweredBy gmnoprint";
+
+ } catch (e) {
+ throw(e);
}
+ // cache elements for use by any other google layers added to
+ // this same map
+ OpenLayers.Layer.Google.cache[this.map.id] = {
+ mapObject: mapObject,
+ termsOfUse: termsOfUse,
+ poweredBy: poweredBy,
+ count: 1
+ };
+ }
- this.mapObject.setMapType(this.type);
- this.map.events.unregister("moveend", this, this.setMapType);
+ this.mapObject = mapObject;
+ this.termsOfUse = termsOfUse;
+ this.poweredBy = poweredBy;
+
+ // ensure this layer type is one of the mapObject types
+ if (OpenLayers.Util.indexOf(this.mapObject.getMapTypes(),
+ this.type) === -1) {
+ this.mapObject.addMapType(this.type);
}
+
+ //since v 2.93 getDragObject is now available.
+ if(typeof mapObject.getDragObject == "function") {
+ this.dragObject = mapObject.getDragObject();
+ } else {
+ this.dragPanMapObject = null;
+ }
+
+ if(this.isBaseLayer === false) {
+ this.setGMapVisibility(this.div.style.display !== "none");
+ }
+
},
/**
* APIMethod: onMapResize
- *
- * Parameters:
- * evt - {Event}
*/
onMapResize: function() {
// workaround for resizing of invisible or not yet fully loaded layers
@@ -26191,112 +28238,69 @@
delete layer._resized;
layer.mapObject.checkResize();
layer.moveTo(layer.map.getCenter(), layer.map.getZoom());
- })
+ });
}
this._resized = true;
}
},
/**
- * Method: display
- * Hide or show the layer
- *
+ * Method: setGMapVisibility
+ * Display the GMap container and associated elements.
+ *
* Parameters:
- * display - {Boolean}
+ * visible - {Boolean} Display the GMap elements.
*/
- display: function(display) {
- OpenLayers.Layer.EventPane.prototype.display.apply(this, arguments);
- this.termsOfUse.style.display = this.div.style.display;
- this.poweredBy.style.display = this.div.style.display;
- },
-
- /**
- * APIMethod: removeMap
- * On being removed from the map, also remove termsOfUse and poweredBy divs
- *
- * Parameters:
- * map - {<OpenLayers.Map>}
- */
- removeMap: function(map) {
- if (this.termsOfUse && this.termsOfUse.parentNode) {
- this.termsOfUse.parentNode.removeChild(this.termsOfUse);
- this.termsOfUse = null;
+ setGMapVisibility: function(visible) {
+ var cache = OpenLayers.Layer.Google.cache[this.map.id];
+ if (cache) {
+ var container = this.mapObject.getContainer();
+ if (visible === true) {
+ this.mapObject.setMapType(this.type);
+ container.style.display = "";
+ this.termsOfUse.style.left = "";
+ this.termsOfUse.style.display = "";
+ this.poweredBy.style.display = "";
+ cache.displayed = this.id;
+ } else {
+ if (cache.displayed === this.id) {
+ delete cache.displayed;
+ }
+ if (!cache.displayed) {
+ container.style.display = "none";
+ this.termsOfUse.style.display = "none";
+ // move ToU far to the left in addition to setting display
+ // to "none", because at the end of the GMap2 load
+ // sequence, display: none will be unset and ToU would be
+ // visible after loading a map with a google layer that is
+ // initially hidden.
+ this.termsOfUse.style.left = "-9999px";
+ this.poweredBy.style.display = "none";
+ }
+ }
}
- if (this.poweredBy && this.poweredBy.parentNode) {
- this.poweredBy.parentNode.removeChild(this.poweredBy);
- this.poweredBy = null;
- }
- OpenLayers.Layer.EventPane.prototype.removeMap.apply(this, arguments);
},
-
+
/**
- * APIMethod: getZoomForExtent
- *
- * Parameters:
- * bounds - {<OpenLayers.Bounds>}
- *
+ * Method: getMapContainer
+ *
* Returns:
- * {Integer} Corresponding zoom level for a specified Bounds.
- * If mapObject is not loaded or not centered, returns null
- *
- getZoomForExtent: function (bounds) {
- var zoom = null;
- if (this.mapObject != null) {
- var moBounds = this.getMapObjectBoundsFromOLBounds(bounds);
- var moZoom = this.getMapObjectZoomFromMapObjectBounds(moBounds);
-
- //make sure zoom is within bounds
- var moZoom = Math.min(Math.max(moZoom, this.minZoomLevel),
- this.maxZoomLevel);
-
- zoom = this.getOLZoomFromMapObjectZoom(moZoom);
- }
- return zoom;
+ * {DOMElement} the GMap container's div
+ */
+ getMapContainer: function() {
+ return this.mapObject.getContainer();
},
- */
-
//
// TRANSLATION: MapObject Bounds <-> OpenLayers.Bounds
//
/**
- * APIMethod: getOLBoundsFromMapObjectBounds
- *
- * Parameters:
- * moBounds - {Object}
- *
- * Returns:
- * {<OpenLayers.Bounds>} An <OpenLayers.Bounds>, translated from the
- * passed-in MapObject Bounds.
- * Returns null if null value is passed in.
- */
- getOLBoundsFromMapObjectBounds: function(moBounds) {
- var olBounds = null;
- if (moBounds != null) {
- var sw = moBounds.getSouthWest();
- var ne = moBounds.getNorthEast();
- if (this.sphericalMercator) {
- sw = this.forwardMercator(sw.lng(), sw.lat());
- ne = this.forwardMercator(ne.lng(), ne.lat());
- } else {
- sw = new OpenLayers.LonLat(sw.lng(), sw.lat());
- ne = new OpenLayers.LonLat(ne.lng(), ne.lat());
- }
- olBounds = new OpenLayers.Bounds(sw.lon,
- sw.lat,
- ne.lon,
- ne.lat );
- }
- return olBounds;
- },
-
- /**
* APIMethod: getMapObjectBoundsFromOLBounds
- *
+ *
* Parameters:
* olBounds - {<OpenLayers.Bounds>}
- *
+ *
* Returns:
* {Object} A MapObject Bounds, translated from olBounds
* Returns null if null value is passed in
@@ -26304,11 +28308,11 @@
getMapObjectBoundsFromOLBounds: function(olBounds) {
var moBounds = null;
if (olBounds != null) {
- var sw = this.sphericalMercator ?
- this.inverseMercator(olBounds.bottom, olBounds.left) :
+ var sw = this.sphericalMercator ?
+ this.inverseMercator(olBounds.bottom, olBounds.left) :
new OpenLayers.LonLat(olBounds.bottom, olBounds.left);
- var ne = this.sphericalMercator ?
- this.inverseMercator(olBounds.top, olBounds.right) :
+ var ne = this.sphericalMercator ?
+ this.inverseMercator(olBounds.top, olBounds.right) :
new OpenLayers.LonLat(olBounds.top, olBounds.right);
moBounds = new GLatLngBounds(new GLatLng(sw.lat, sw.lon),
new GLatLng(ne.lat, ne.lon));
@@ -26316,49 +28320,7 @@
return moBounds;
},
- /**
- * Method: addContainerPxFunction
- * Hack-on function because GMAPS does not give it to us
- *
- * Parameters:
- * gLatLng - {GLatLng}
- *
- * Returns:
- * {GPoint} A GPoint specifying gLatLng translated into "Container" coords
- */
- addContainerPxFunction: function() {
- if ( (typeof GMap2 != "undefined") &&
- !GMap2.prototype.fromLatLngToContainerPixel) {
- GMap2.prototype.fromLatLngToContainerPixel = function(gLatLng) {
-
- // first we translate into "DivPixel"
- var gPoint = this.fromLatLngToDivPixel(gLatLng);
-
- // locate the sliding "Div" div
- var div = this.getContainer().firstChild.firstChild;
-
- // adjust by the offset of "Div" and voila!
- gPoint.x += div.offsetLeft;
- gPoint.y += div.offsetTop;
-
- return gPoint;
- };
- }
- },
-
- /**
- * APIMethod: getWarningHTML
- *
- * Returns:
- * {String} String with information on why layer is broken, how to get
- * it working.
- */
- getWarningHTML:function() {
- return OpenLayers.i18n("googleWarning");
- },
-
-
/************************************
* *
* MapObject Interface Controls *
@@ -26368,21 +28330,21 @@
// Get&Set Center, Zoom
- /**
+ /**
* APIMethod: setMapObjectCenter
* Set the mapObject to the specified center and zoom
- *
+ *
* Parameters:
* center - {Object} MapObject LonLat format
* zoom - {int} MapObject zoom format
*/
setMapObjectCenter: function(center, zoom) {
- this.mapObject.setCenter(center, zoom);
+ this.mapObject.setCenter(center, zoom);
},
-
+
/**
* APIMethod: dragPanMapObject
- *
+ *
* Parameters:
* dX - {Integer}
* dY - {Integer}
@@ -26391,35 +28353,15 @@
this.dragObject.moveBy(new GSize(-dX, dY));
},
- /**
- * APIMethod: getMapObjectCenter
- *
- * Returns:
- * {Object} The mapObject's current center in Map Object format
- */
- getMapObjectCenter: function() {
- return this.mapObject.getCenter();
- },
- /**
- * APIMethod: getMapObjectZoom
- *
- * Returns:
- * {Integer} The mapObject's current zoom, in Map Object format
- */
- getMapObjectZoom: function() {
- return this.mapObject.getZoom();
- },
-
-
// LonLat - Pixel Translation
-
+
/**
* APIMethod: getMapObjectLonLatFromMapObjectPixel
- *
+ *
* Parameters:
* moPixel - {Object} MapObject Pixel format
- *
+ *
* Returns:
* {Object} MapObject LonLat translated from MapObject Pixel
*/
@@ -26429,10 +28371,10 @@
/**
* APIMethod: getMapObjectPixelFromMapObjectLonLat
- *
+ *
* Parameters:
* moLonLat - {Object} MapObject LonLat format
- *
+ *
* Returns:
* {Object} MapObject Pixel transtlated from MapObject LonLat
*/
@@ -26440,15 +28382,15 @@
return this.mapObject.fromLatLngToContainerPixel(moLonLat);
},
-
+
// Bounds
-
- /**
+
+ /**
* APIMethod: getMapObjectZoomFromMapObjectBounds
- *
+ *
* Parameters:
* moBounds - {Object} MapObject Bounds format
- *
+ *
* Returns:
* {Object} MapObject Zoom for specified MapObject Bounds
*/
@@ -26464,45 +28406,14 @@
// LonLat
-
+
/**
- * APIMethod: getLongitudeFromMapObjectLonLat
- *
- * Parameters:
- * moLonLat - {Object} MapObject LonLat format
- *
- * Returns:
- * {Float} Longitude of the given MapObject LonLat
- */
- getLongitudeFromMapObjectLonLat: function(moLonLat) {
- return this.sphericalMercator ?
- this.forwardMercator(moLonLat.lng(), moLonLat.lat()).lon :
- moLonLat.lng();
- },
-
- /**
- * APIMethod: getLatitudeFromMapObjectLonLat
- *
- * Parameters:
- * moLonLat - {Object} MapObject LonLat format
- *
- * Returns:
- * {Float} Latitude of the given MapObject LonLat
- */
- getLatitudeFromMapObjectLonLat: function(moLonLat) {
- var lat = this.sphericalMercator ?
- this.forwardMercator(moLonLat.lng(), moLonLat.lat()).lat :
- moLonLat.lat();
- return lat;
- },
-
- /**
* APIMethod: getMapObjectLonLatFromLonLat
- *
+ *
* Parameters:
* lon - {Float}
* lat - {Float}
- *
+ *
* Returns:
* {Object} MapObject LonLat built from lon and lat params
*/
@@ -26518,55 +28429,29 @@
},
// Pixel
-
+
/**
- * APIMethod: getXFromMapObjectPixel
- *
- * Parameters:
- * moPixel - {Object} MapObject Pixel format
- *
- * Returns:
- * {Integer} X value of the MapObject Pixel
- */
- getXFromMapObjectPixel: function(moPixel) {
- return moPixel.x;
- },
-
- /**
- * APIMethod: getYFromMapObjectPixel
- *
- * Parameters:
- * moPixel - {Object} MapObject Pixel format
- *
- * Returns:
- * {Integer} Y value of the MapObject Pixel
- */
- getYFromMapObjectPixel: function(moPixel) {
- return moPixel.y;
- },
-
- /**
* APIMethod: getMapObjectPixelFromXY
- *
+ *
* Parameters:
* x - {Integer}
* y - {Integer}
- *
+ *
* Returns:
* {Object} MapObject Pixel from x and y parameters
*/
getMapObjectPixelFromXY: function(x, y) {
return new GPoint(x, y);
- },
-
- CLASS_NAME: "OpenLayers.Layer.Google"
-});
+ }
+
+};
/* ======================================================================
OpenLayers/Layer/Grid.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
@@ -26584,38 +28469,38 @@
* - <OpenLayers.Layer.HTTPRequest>
*/
OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
-
+
/**
* APIProperty: tileSize
* {<OpenLayers.Size>}
*/
tileSize: null,
-
+
/**
* Property: grid
- * {Array(Array(<OpenLayers.Tile>))} This is an array of rows, each row is
+ * {Array(Array(<OpenLayers.Tile>))} This is an array of rows, each row is
* an array of tiles.
*/
grid: null,
/**
* APIProperty: singleTile
- * {Boolean} Moves the layer into single-tile mode, meaning that one tile
+ * {Boolean} Moves the layer into single-tile mode, meaning that one tile
* will be loaded. The tile's size will be determined by the 'ratio'
- * property. When the tile is dragged such that it does not cover the
+ * property. When the tile is dragged such that it does not cover the
* entire viewport, it is reloaded.
*/
singleTile: false,
/** APIProperty: ratio
- * {Float} Used only when in single-tile mode, this specifies the
+ * {Float} Used only when in single-tile mode, this specifies the
* ratio of the size of the single tile to the size of the map.
*/
ratio: 1.5,
/**
* APIProperty: buffer
- * {Integer} Used only when in gridded mode, this specifies the number of
+ * {Integer} Used only when in gridded mode, this specifies the number of
* extra rows and colums of tiles on each side which will
* surround the minimum grid tiles to cover the map.
*/
@@ -26638,10 +28523,10 @@
* options - {Object} Hashtable of extra options to tag onto the layer
*/
initialize: function(name, url, params, options) {
- OpenLayers.Layer.HTTPRequest.prototype.initialize.apply(this,
+ OpenLayers.Layer.HTTPRequest.prototype.initialize.apply(this,
arguments);
-
- //grid layers will trigger 'tileloaded' when each new tile is
+
+ //grid layers will trigger 'tileloaded' when each new tile is
// loaded, as a means of progress update to listeners.
// listeners can access 'numLoadingTiles' if they wish to keep track
// of the loading progress
@@ -26659,7 +28544,7 @@
this.clearGrid();
this.grid = null;
this.tileSize = null;
- OpenLayers.Layer.HTTPRequest.prototype.destroy.apply(this, arguments);
+ OpenLayers.Layer.HTTPRequest.prototype.destroy.apply(this, arguments);
},
/**
@@ -26687,17 +28572,17 @@
*
* Parameters:
* obj - {Object} Is this ever used?
- *
+ *
* Returns:
* {<OpenLayers.Layer.Grid>} An exact clone of this OpenLayers.Layer.Grid
*/
clone: function (obj) {
-
+
if (obj == null) {
obj = new OpenLayers.Layer.Grid(this.name,
this.url,
this.params,
- this.options);
+ this.getOptions());
}
//get all additions from superclasses
@@ -26707,12 +28592,12 @@
if (this.tileSize != null) {
obj.tileSize = this.tileSize.clone();
}
-
+
// we do not want to copy reference to grid, so we make a new array
obj.grid = [];
return obj;
- },
+ },
/**
* Method: moveTo
@@ -26727,32 +28612,32 @@
*/
moveTo:function(bounds, zoomChanged, dragging) {
OpenLayers.Layer.HTTPRequest.prototype.moveTo.apply(this, arguments);
-
+
bounds = bounds || this.map.getExtent();
if (bounds != null) {
-
+
// if grid is empty or zoom has changed, we *must* re-tile
var forceReTile = !this.grid.length || zoomChanged;
// total bounds of the tiles
- var tilesBounds = this.getTilesBounds();
-
+ var tilesBounds = this.getTilesBounds();
+
if (this.singleTile) {
-
- // We want to redraw whenever even the slightest part of the
+
+ // We want to redraw whenever even the slightest part of the
// current bounds is not contained by our tile.
// (thus, we do not specify partial -- its default is false)
- if ( forceReTile ||
+ if ( forceReTile ||
(!dragging && !tilesBounds.containsBounds(bounds))) {
this.initSingleTile(bounds);
}
} else {
-
- // if the bounds have changed such that they are not even
- // *partially* contained by our tiles (IE user has
- // programmatically panned to the other side of the earth)
- // then we want to reTile (thus, partial true).
+
+ // if the bounds have changed such that they are not even
+ // *partially* contained by our tiles (IE user has
+ // programmatically panned to the other side of the earth)
+ // then we want to reTile (thus, partial true).
//
if (forceReTile || !tilesBounds.containsBounds(bounds, true)) {
this.initGriddedTiles(bounds);
@@ -26763,32 +28648,32 @@
}
}
},
-
+
/**
* APIMethod: setTileSize
* Check if we are in singleTile mode and if so, set the size as a ratio
* of the map size (as specified by the layer's 'ratio' property).
- *
+ *
* Parameters:
* size - {<OpenLayers.Size>}
*/
- setTileSize: function(size) {
+ setTileSize: function(size) {
if (this.singleTile) {
- size = this.map.getSize().clone();
+ size = this.map.getSize();
size.h = parseInt(size.h * this.ratio);
size.w = parseInt(size.w * this.ratio);
- }
+ }
OpenLayers.Layer.HTTPRequest.prototype.setTileSize.apply(this, [size]);
},
-
+
/**
* Method: getGridBounds
- * Deprecated. This function will be removed in 3.0. Please use
+ * Deprecated. This function will be removed in 3.0. Please use
* getTilesBounds() instead.
- *
+ *
* Returns:
* {<OpenLayers.Bounds>} A Bounds object representing the bounds of all the
- * currently loaded tiles (including those partially or not at all seen
+ * currently loaded tiles (including those partially or not at all seen
* onscreen)
*/
getGridBounds: function() {
@@ -26804,32 +28689,32 @@
*
* Returns:
* {<OpenLayers.Bounds>} A Bounds object representing the bounds of all the
- * currently loaded tiles (including those partially or not at all seen
+ * currently loaded tiles (including those partially or not at all seen
* onscreen).
*/
- getTilesBounds: function() {
- var bounds = null;
-
+ getTilesBounds: function() {
+ var bounds = null;
+
if (this.grid.length) {
var bottom = this.grid.length - 1;
var bottomLeftTile = this.grid[bottom][0];
-
- var right = this.grid[0].length - 1;
+
+ var right = this.grid[0].length - 1;
var topRightTile = this.grid[0][right];
-
- bounds = new OpenLayers.Bounds(bottomLeftTile.bounds.left,
+
+ bounds = new OpenLayers.Bounds(bottomLeftTile.bounds.left,
bottomLeftTile.bounds.bottom,
- topRightTile.bounds.right,
+ topRightTile.bounds.right,
topRightTile.bounds.top);
-
- }
+
+ }
return bounds;
},
/**
* Method: initSingleTile
- *
- * Parameters:
+ *
+ * Parameters:
* bounds - {<OpenLayers.Bounds>}
*/
initSingleTile: function(bounds) {
@@ -26838,13 +28723,13 @@
var center = bounds.getCenterLonLat();
var tileWidth = bounds.getWidth() * this.ratio;
var tileHeight = bounds.getHeight() * this.ratio;
-
- var tileBounds =
+
+ var tileBounds =
new OpenLayers.Bounds(center.lon - (tileWidth/2),
center.lat - (tileHeight/2),
center.lon + (tileWidth/2),
center.lat + (tileHeight/2));
-
+
var ul = new OpenLayers.LonLat(tileBounds.left, tileBounds.top);
var px = this.map.getLayerPxFromLonLat(ul);
@@ -26855,21 +28740,21 @@
var tile = this.grid[0][0];
if (!tile) {
tile = this.addTile(tileBounds, px);
-
+
this.addTileMonitoringHooks(tile);
tile.draw();
this.grid[0][0] = tile;
} else {
tile.moveTo(tileBounds, px);
- }
-
+ }
+
//remove all but our single tile
this.removeExcessTiles(1,1);
},
- /**
+ /**
* Method: calculateGridLayout
- * Generate parameters for the grid layout. This
+ * Generate parameters for the grid layout. This
*
* Parameters:
* bounds - {<OpenLayers.Bound>}
@@ -26883,20 +28768,20 @@
calculateGridLayout: function(bounds, extent, resolution) {
var tilelon = resolution * this.tileSize.w;
var tilelat = resolution * this.tileSize.h;
-
+
var offsetlon = bounds.left - extent.left;
var tilecol = Math.floor(offsetlon/tilelon) - this.buffer;
var tilecolremain = offsetlon/tilelon - tilecol;
var tileoffsetx = -tilecolremain * this.tileSize.w;
var tileoffsetlon = extent.left + tilecol * tilelon;
-
- var offsetlat = bounds.top - (extent.bottom + tilelat);
+
+ var offsetlat = bounds.top - (extent.bottom + tilelat);
var tilerow = Math.ceil(offsetlat/tilelat) + this.buffer;
var tilerowremain = tilerow - offsetlat/tilelat;
var tileoffsety = -tilerowremain * this.tileSize.h;
var tileoffsetlat = extent.bottom + tilerow * tilelat;
-
- return {
+
+ return {
tilelon: tilelon, tilelat: tilelat,
tileoffsetlon: tileoffsetlon, tileoffsetlat: tileoffsetlat,
tileoffsetx: tileoffsetx, tileoffsety: tileoffsety
@@ -26906,24 +28791,24 @@
/**
* Method: initGriddedTiles
- *
+ *
* Parameters:
* bounds - {<OpenLayers.Bounds>}
*/
initGriddedTiles:function(bounds) {
-
+
// work out mininum number of rows and columns; this is the number of
// tiles required to cover the viewport plus at least one for panning
var viewSize = this.map.getSize();
- var minRows = Math.ceil(viewSize.h/this.tileSize.h) +
+ var minRows = Math.ceil(viewSize.h/this.tileSize.h) +
Math.max(1, 2 * this.buffer);
var minCols = Math.ceil(viewSize.w/this.tileSize.w) +
Math.max(1, 2 * this.buffer);
-
- var extent = this.maxExtent;
+
+ var extent = this.getMaxExtent();
var resolution = this.map.getResolution();
-
+
var tileLayout = this.calculateGridLayout(bounds, extent, resolution);
var tileoffsetx = Math.round(tileLayout.tileoffsetx); // heaven help us
@@ -26931,21 +28816,21 @@
var tileoffsetlon = tileLayout.tileoffsetlon;
var tileoffsetlat = tileLayout.tileoffsetlat;
-
+
var tilelon = tileLayout.tilelon;
var tilelat = tileLayout.tilelat;
this.origin = new OpenLayers.Pixel(tileoffsetx, tileoffsety);
- var startX = tileoffsetx;
+ var startX = tileoffsetx;
var startLon = tileoffsetlon;
var rowidx = 0;
-
+
var layerContainerDivLeft = parseInt(this.map.layerContainerDiv.style.left);
var layerContainerDivTop = parseInt(this.map.layerContainerDiv.style.top);
-
-
+
+
do {
var row = this.grid[rowidx++];
if (!row) {
@@ -26956,11 +28841,11 @@
tileoffsetlon = startLon;
tileoffsetx = startX;
var colidx = 0;
-
+
do {
- var tileBounds =
- new OpenLayers.Bounds(tileoffsetlon,
- tileoffsetlat,
+ var tileBounds =
+ new OpenLayers.Bounds(tileoffsetlon,
+ tileoffsetlat,
tileoffsetlon + tilelon,
tileoffsetlat + tilelat);
@@ -26979,17 +28864,17 @@
} else {
tile.moveTo(tileBounds, px, false);
}
-
- tileoffsetlon += tilelon;
+
+ tileoffsetlon += tilelon;
tileoffsetx += this.tileSize.w;
} while ((tileoffsetlon <= bounds.right + tilelon * this.buffer)
|| colidx < minCols);
-
+
tileoffsetlat -= tilelat;
tileoffsety += this.tileSize.h;
} while((tileoffsetlat >= bounds.bottom - tilelat * this.buffer)
|| rowidx < minRows);
-
+
//shave off exceess rows and colums
this.removeExcessTiles(rowidx, colidx);
@@ -26998,25 +28883,37 @@
},
/**
- * Method: spiralTileLoad
- * Starts at the top right corner of the grid and proceeds in a spiral
- * towards the center, adding tiles one at a time to the beginning of a
- * queue.
+ * Method: getMaxExtent
+ * Get this layer's maximum extent. (Implemented as a getter for
+ * potential specific implementations in sub-classes.)
*
- * Once all the grid's tiles have been added to the queue, we go back
- * and iterate through the queue (thus reversing the spiral order from
- * outside-in to inside-out), calling draw() on each tile.
+ * Returns:
+ * {OpenLayers.Bounds}
*/
+ getMaxExtent: function() {
+ return this.maxExtent;
+ },
+
+ /**
+ * Method: spiralTileLoad
+ * Starts at the top right corner of the grid and proceeds in a spiral
+ * towards the center, adding tiles one at a time to the beginning of a
+ * queue.
+ *
+ * Once all the grid's tiles have been added to the queue, we go back
+ * and iterate through the queue (thus reversing the spiral order from
+ * outside-in to inside-out), calling draw() on each tile.
+ */
spiralTileLoad: function() {
var tileQueue = [];
-
+
var directions = ["right", "down", "left", "up"];
var iRow = 0;
var iCell = -1;
var direction = OpenLayers.Util.indexOf(directions, "right");
var directionsTried = 0;
-
+
while( directionsTried < directions.length) {
var testRow = iRow;
@@ -27035,21 +28932,21 @@
case "up":
testRow--;
break;
- }
-
- // if the test grid coordinates are within the bounds of the
+ }
+
+ // if the test grid coordinates are within the bounds of the
// grid, get a reference to the tile.
var tile = null;
if ((testRow < this.grid.length) && (testRow >= 0) &&
(testCell < this.grid[0].length) && (testCell >= 0)) {
tile = this.grid[testRow][testCell];
}
-
+
if ((tile != null) && (!tile.queued)) {
//add tile to beginning of queue, mark it as queued.
tileQueue.unshift(tile);
tile.queued = true;
-
+
//restart the directions counter and take on the new coords
directionsTried = 0;
iRow = testRow;
@@ -27059,21 +28956,21 @@
direction = (direction + 1) % 4;
directionsTried++;
}
- }
-
+ }
+
// now we go through and draw the tiles in forward order
for(var i=0, len=tileQueue.length; i<len; i++) {
var tile = tileQueue[i];
tile.draw();
//mark tile as unqueued for the next time (since tiles are reused)
- tile.queued = false;
+ tile.queued = false;
}
},
/**
* APIMethod: addTile
- * Gives subclasses of Grid the opportunity to create an
- * OpenLayer.Tile of their choosing. The implementer should initialize
+ * Gives subclasses of Grid the opportunity to create an
+ * OpenLayer.Tile of their choosing. The implementer should initialize
* the new tile and take whatever steps necessary to display it.
*
* Parameters
@@ -27086,17 +28983,17 @@
addTile:function(bounds, position) {
// Should be implemented by subclasses
},
-
- /**
+
+ /**
* Method: addTileMonitoringHooks
- * This function takes a tile as input and adds the appropriate hooks to
+ * This function takes a tile as input and adds the appropriate hooks to
* the tile so that the layer can keep track of the loading tiles.
- *
- * Parameters:
+ *
+ * Parameters:
* tile - {<OpenLayers.Tile>}
*/
addTileMonitoringHooks: function(tile) {
-
+
tile.onLoadStart = function() {
//if that was first tile then trigger a 'loadstart' on the layer
if (this.numLoadingTiles == 0) {
@@ -27105,7 +29002,7 @@
this.numLoadingTiles++;
};
tile.events.register("loadstart", this, tile.onLoadStart);
-
+
tile.onLoadEnd = function() {
this.numLoadingTiles--;
this.events.triggerEvent("tileloaded");
@@ -27118,12 +29015,12 @@
tile.events.register("unload", this, tile.onLoadEnd);
},
- /**
+ /**
* Method: removeTileMonitoringHooks
- * This function takes a tile as input and removes the tile hooks
+ * This function takes a tile as input and removes the tile hooks
* that were added in addTileMonitoringHooks()
- *
- * Parameters:
+ *
+ * Parameters:
* tile - {<OpenLayers.Tile>}
*/
removeTileMonitoringHooks: function(tile) {
@@ -27135,10 +29032,10 @@
scope: this
});
},
-
+
/**
* Method: moveGriddedTiles
- *
+ *
* Parameters:
* bounds - {<OpenLayers.Bounds>}
*/
@@ -27146,7 +29043,7 @@
var buffer = this.buffer || 1;
while (true) {
var tlLayer = this.grid[0][0].position;
- var tlViewPort =
+ var tlViewPort =
this.map.getViewPortPxFromLayerPx(tlLayer);
if (tlViewPort.x > -this.tileSize.w * (buffer - 1)) {
this.shiftColumn(true);
@@ -27215,7 +29112,7 @@
var row = this.grid[i];
var modelTileIndex = (prepend) ? 0 : (row.length - 1);
var modelTile = row[modelTileIndex];
-
+
var bounds = modelTile.bounds.clone();
var position = modelTile.position.clone();
bounds.left = bounds.left + deltaLon;
@@ -27231,18 +29128,18 @@
}
}
},
-
+
/**
* Method: removeExcessTiles
* When the size of the map or the buffer changes, we may need to
* remove some excess rows and columns.
- *
+ *
* Parameters:
* rows - {Integer} Maximum number of rows we want our grid to have.
* colums - {Integer} Maximum number of columns we want our grid to have.
*/
removeExcessTiles: function(rows, columns) {
-
+
// remove extra rows
while (this.grid.length > rows) {
var row = this.grid.pop();
@@ -27252,7 +29149,7 @@
tile.destroy();
}
}
-
+
// remove extra columns
while (this.grid[0].length > columns) {
for (var i=0, l=this.grid.length; i<l; i++) {
@@ -27275,7 +29172,7 @@
this.setTileSize();
}
},
-
+
/**
* APIMethod: getTileBounds
* Returns The tile bounds for a layer given a pixel location.
@@ -27304,26 +29201,28 @@
tileLeft + tileMapWidth,
tileBottom + tileMapHeight);
},
-
+
CLASS_NAME: "OpenLayers.Layer.Grid"
});
/* ======================================================================
OpenLayers/Layer/VirtualEarth.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
+ * @requires OpenLayers/Layer/SphericalMercator.js
* @requires OpenLayers/Layer/EventPane.js
* @requires OpenLayers/Layer/FixedZoomLevels.js
*/
/**
* Class: OpenLayers.Layer.VirtualEarth
- *
+ *
* Inherits from:
* - <OpenLayers.Layer.EventPane>
* - <OpenLayers.Layer.FixedZoomLevels>
@@ -27331,42 +29230,44 @@
OpenLayers.Layer.VirtualEarth = OpenLayers.Class(
OpenLayers.Layer.EventPane,
OpenLayers.Layer.FixedZoomLevels, {
-
- /**
+
+ /**
* Constant: MIN_ZOOM_LEVEL
- * {Integer} 1
+ * {Integer} 1
*/
MIN_ZOOM_LEVEL: 1,
-
- /**
+
+ /**
* Constant: MAX_ZOOM_LEVEL
- * {Integer} 17
+ * {Integer} 19
*/
- MAX_ZOOM_LEVEL: 17,
+ MAX_ZOOM_LEVEL: 19,
- /**
+ /**
* Constant: RESOLUTIONS
* {Array(Float)} Hardcode these resolutions so that they are more closely
* tied with the standard wms projection
*/
RESOLUTIONS: [
- 1.40625,
- 0.703125,
- 0.3515625,
- 0.17578125,
- 0.087890625,
+ 1.40625,
+ 0.703125,
+ 0.3515625,
+ 0.17578125,
+ 0.087890625,
0.0439453125,
- 0.02197265625,
- 0.010986328125,
- 0.0054931640625,
+ 0.02197265625,
+ 0.010986328125,
+ 0.0054931640625,
0.00274658203125,
- 0.001373291015625,
- 0.0006866455078125,
- 0.00034332275390625,
- 0.000171661376953125,
- 0.0000858306884765625,
+ 0.001373291015625,
+ 0.0006866455078125,
+ 0.00034332275390625,
+ 0.000171661376953125,
+ 0.0000858306884765625,
0.00004291534423828125,
- 0.00002145767211914062
+ 0.00002145767211914062,
+ 0.00001072883605957031,
+ 0.00000536441802978515
],
/**
@@ -27376,39 +29277,47 @@
type: null,
/**
+ * APIProperty: wrapDateLine
+ * {Boolean} Allow user to pan forever east/west. Default is true.
+ * Setting this to false only restricts panning if
+ * <sphericalMercator> is true.
+ */
+ wrapDateLine: true,
+
+ /**
* APIProperty: sphericalMercator
* {Boolean} Should the map act as a mercator-projected map? This will
* cause all interactions with the map to be in the actual map
* projection, which allows support for vector drawing, overlaying
- * other maps, etc.
+ * other maps, etc.
*/
sphericalMercator: false,
-
+
/**
* APIProperty: animationEnabled
* {Boolean} If set to true, the transition between zoom levels will be
* animated. Set to false to match the zooming experience of other
* layer types. Default is true.
*/
- animationEnabled: true,
+ animationEnabled: true,
- /**
+ /**
* Constructor: OpenLayers.Layer.VirtualEarth
- *
+ *
* Parameters:
* name - {String}
* options - {Object}
*/
initialize: function(name, options) {
OpenLayers.Layer.EventPane.prototype.initialize.apply(this, arguments);
- OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this,
+ OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this,
arguments);
if(this.sphericalMercator) {
OpenLayers.Util.extend(this, OpenLayers.Layer.SphericalMercator);
this.initMercatorParameters();
}
},
-
+
/**
* Method: loadMapObject
*/
@@ -27428,23 +29337,21 @@
if (this.mapObject != null) {
try { // this is to catch a Mozilla bug without falling apart
- // The fourth argument is whether the map is 'fixed' -- not
- // draggable. See:
+ // The fourth argument is whether the map is 'fixed' -- not
+ // draggable. See:
// http://blogs.msdn.com/virtualearth/archive/2007/09/28/locking-a-virtual-earth-map.aspx
//
this.mapObject.LoadMap(null, null, this.type, true);
- this.mapObject.AttachEvent("onmousedown", function() {return true; });
+ this.mapObject.AttachEvent("onmousedown", OpenLayers.Function.True);
} catch (e) { }
- this.mapObject.AttachEvent("onresize",
- OpenLayers.Function.bindAsEventListener(this.redrawDependentLayers, this));
this.mapObject.HideDashboard();
if(typeof this.mapObject.SetAnimationEnabled == "function") {
this.mapObject.SetAnimationEnabled(this.animationEnabled);
}
}
- //can we do smooth panning? this is an unpublished method, so we need
+ //can we do smooth panning? this is an unpublished method, so we need
// to be careful
if ( !this.mapObject ||
!this.mapObject.vemapcontrol ||
@@ -27455,35 +29362,18 @@
}
},
-
- /**
- * Method: redrawDependentLayers
- */
- redrawDependentLayers: function(event) {
- if(this.isBaseLayer)
- {
- for(var i=0, len=this.map.layers.length; i<len; i++)
- {
- var otherLayer = this.map.layers[i];
- if(otherLayer != this)
- {
- otherLayer.redraw();
- }
- }
- }
- },
-
- /**
- * Method: onMapResize
- */
- onMapResize: function() {
- this.mapObject.Resize(this.map.size.w, this.map.size.h);
- },
/**
+ * Method: onMapResize
+ */
+ onMapResize: function() {
+ this.mapObject.Resize(this.map.size.w, this.map.size.h);
+ },
+
+ /**
* APIMethod: getWarningHTML
- *
- * Returns:
+ *
+ * Returns:
* {String} String with information on why layer is broken, how to get
* it working.
*/
@@ -27504,22 +29394,22 @@
// Get&Set Center, Zoom
- /**
+ /**
* APIMethod: setMapObjectCenter
* Set the mapObject to the specified center and zoom
- *
+ *
* Parameters:
* center - {Object} MapObject LonLat format
* zoom - {int} MapObject zoom format
*/
setMapObjectCenter: function(center, zoom) {
- this.mapObject.SetCenterAndZoom(center, zoom);
+ this.mapObject.SetCenterAndZoom(center, zoom);
},
-
+
/**
* APIMethod: getMapObjectCenter
- *
- * Returns:
+ *
+ * Returns:
* {Object} The mapObject's current center in Map Object format
*/
getMapObjectCenter: function() {
@@ -27528,7 +29418,7 @@
/**
* APIMethod: dragPanMapObject
- *
+ *
* Parameters:
* dX - {Integer}
* dY - {Integer}
@@ -27537,9 +29427,9 @@
this.mapObject.vemapcontrol.PanMap(dX, -dY);
},
- /**
+ /**
* APIMethod: getMapObjectZoom
- *
+ *
* Returns:
* {Integer} The mapObject's current zoom, in Map Object format
*/
@@ -27549,29 +29439,29 @@
// LonLat - Pixel Translation
-
+
/**
* APIMethod: getMapObjectLonLatFromMapObjectPixel
- *
+ *
* Parameters:
* moPixel - {Object} MapObject Pixel format
- *
+ *
* Returns:
* {Object} MapObject LonLat translated from MapObject Pixel
*/
getMapObjectLonLatFromMapObjectPixel: function(moPixel) {
//the conditional here is to test if we are running the v6 of VE
- return (typeof VEPixel != 'undefined')
+ return (typeof VEPixel != 'undefined')
? this.mapObject.PixelToLatLong(moPixel)
: this.mapObject.PixelToLatLong(moPixel.x, moPixel.y);
},
/**
* APIMethod: getMapObjectPixelFromMapObjectLonLat
- *
+ *
* Parameters:
* moLonLat - {Object} MapObject LonLat format
- *
+ *
* Returns:
* {Object} MapObject Pixel transtlated from MapObject LonLat
*/
@@ -27588,44 +29478,44 @@
// LonLat
-
+
/**
* APIMethod: getLongitudeFromMapObjectLonLat
- *
+ *
* Parameters:
* moLonLat - {Object} MapObject LonLat format
- *
+ *
* Returns:
* {Float} Longitude of the given MapObject LonLat
*/
getLongitudeFromMapObjectLonLat: function(moLonLat) {
- return this.sphericalMercator ?
+ return this.sphericalMercator ?
this.forwardMercator(moLonLat.Longitude, moLonLat.Latitude).lon :
moLonLat.Longitude;
},
/**
* APIMethod: getLatitudeFromMapObjectLonLat
- *
+ *
* Parameters:
* moLonLat - {Object} MapObject LonLat format
- *
+ *
* Returns:
* {Float} Latitude of the given MapObject LonLat
*/
getLatitudeFromMapObjectLonLat: function(moLonLat) {
- return this.sphericalMercator ?
+ return this.sphericalMercator ?
this.forwardMercator(moLonLat.Longitude, moLonLat.Latitude).lat :
moLonLat.Latitude;
},
/**
* APIMethod: getMapObjectLonLatFromLonLat
- *
+ *
* Parameters:
* lon - {Float}
* lat - {Float}
- *
+ *
* Returns:
* {Object} MapObject LonLat built from lon and lat params
*/
@@ -27641,13 +29531,13 @@
},
// Pixel
-
+
/**
* APIMethod: getXFromMapObjectPixel
- *
+ *
* Parameters:
* moPixel - {Object} MapObject Pixel format
- *
+ *
* Returns:
* {Integer} X value of the MapObject Pixel
*/
@@ -27657,10 +29547,10 @@
/**
* APIMethod: getYFromMapObjectPixel
- *
+ *
* Parameters:
* moPixel - {Object} MapObject Pixel format
- *
+ *
* Returns:
* {Integer} Y value of the MapObject Pixel
*/
@@ -27670,11 +29560,11 @@
/**
* APIMethod: getMapObjectPixelFromXY
- *
+ *
* Parameters:
* x - {Integer}
* y - {Integer}
- *
+ *
* Returns:
* {Object} MapObject Pixel from x and y parameters
*/
@@ -27690,59 +29580,61 @@
OpenLayers/Layer/Yahoo.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
+ * @requires OpenLayers/Layer/SphericalMercator.js
* @requires OpenLayers/Layer/EventPane.js
* @requires OpenLayers/Layer/FixedZoomLevels.js
*/
/**
* Class: OpenLayers.Layer.Yahoo
- *
+ *
* Inherits from:
* - <OpenLayers.Layer.EventPane>
* - <OpenLayers.Layer.FixedZoomLevels>
*/
OpenLayers.Layer.Yahoo = OpenLayers.Class(
OpenLayers.Layer.EventPane, OpenLayers.Layer.FixedZoomLevels, {
-
- /**
+
+ /**
* Constant: MIN_ZOOM_LEVEL
- * {Integer} 0
+ * {Integer} 0
*/
MIN_ZOOM_LEVEL: 0,
-
- /**
+
+ /**
* Constant: MAX_ZOOM_LEVEL
* {Integer} 17
*/
MAX_ZOOM_LEVEL: 17,
- /**
+ /**
* Constant: RESOLUTIONS
* {Array(Float)} Hardcode these resolutions so that they are more closely
* tied with the standard wms projection
*/
RESOLUTIONS: [
- 1.40625,
- 0.703125,
- 0.3515625,
- 0.17578125,
- 0.087890625,
+ 1.40625,
+ 0.703125,
+ 0.3515625,
+ 0.17578125,
+ 0.087890625,
0.0439453125,
- 0.02197265625,
- 0.010986328125,
- 0.0054931640625,
- 0.00274658203125,
- 0.001373291015625,
- 0.0006866455078125,
- 0.00034332275390625,
- 0.000171661376953125,
- 0.0000858306884765625,
+ 0.02197265625,
+ 0.010986328125,
+ 0.0054931640625,
+ 0.00274658203125,
+ 0.001373291015625,
+ 0.0006866455078125,
+ 0.00034332275390625,
+ 0.000171661376953125,
+ 0.0000858306884765625,
0.00004291534423828125,
0.00002145767211914062,
0.00001072883605957031
@@ -27753,69 +29645,77 @@
* {YahooMapType}
*/
type: null,
+
+ /**
+ * APIProperty: wrapDateLine
+ * {Boolean} Allow user to pan forever east/west. Default is true.
+ * Setting this to false only restricts panning if
+ * <sphericalMercator> is true.
+ */
+ wrapDateLine: true,
/**
* APIProperty: sphericalMercator
* {Boolean} Should the map act as a mercator-projected map? This will
* cause all interactions with the map to be in the actual map projection,
- * which allows support for vector drawing, overlaying other maps, etc.
+ * which allows support for vector drawing, overlaying other maps, etc.
*/
- sphericalMercator: false,
+ sphericalMercator: false,
- /**
+ /**
* Constructor: OpenLayers.Layer.Yahoo
- *
+ *
* Parameters:
* name - {String}
* options - {Object}
*/
initialize: function(name, options) {
OpenLayers.Layer.EventPane.prototype.initialize.apply(this, arguments);
- OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this,
+ OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this,
arguments);
if(this.sphericalMercator) {
OpenLayers.Util.extend(this, OpenLayers.Layer.SphericalMercator);
this.initMercatorParameters();
}
},
-
+
/**
* Method: loadMapObject
*/
loadMapObject:function() {
- try { //do not crash!
+ try { //do not crash!
var size = this.getMapObjectSizeFromOLSize(this.map.getSize());
this.mapObject = new YMap(this.div, this.type, size);
this.mapObject.disableKeyControls();
this.mapObject.disableDragMap();
//can we do smooth panning? (moveByXY is not an API function)
- if ( !this.mapObject.moveByXY ||
+ if ( !this.mapObject.moveByXY ||
(typeof this.mapObject.moveByXY != "function" ) ) {
this.dragPanMapObject = null;
- }
+ }
} catch(e) {}
},
/**
* Method: onMapResize
- *
+ *
*/
onMapResize: function() {
try {
var size = this.getMapObjectSizeFromOLSize(this.map.getSize());
this.mapObject.resizeTo(size);
- } catch(e) {}
- },
-
-
- /**
+ } catch(e) {}
+ },
+
+
+ /**
* APIMethod: setMap
* Overridden from EventPane because we need to remove this yahoo event
- * pane which prohibits our drag and drop, and we can only do this
+ * pane which prohibits our drag and drop, and we can only do this
* once the map has been loaded and centered.
- *
+ *
* Parameters:
* map - {<OpenLayers.Map>}
*/
@@ -27825,7 +29725,7 @@
this.map.events.register("moveend", this, this.fixYahooEventPane);
},
- /**
+ /**
* Method: fixYahooEventPane
* The map has been centered, so the mysterious yahoo eventpane has been
* added. we remove it so that it doesnt mess with *our* event pane.
@@ -27836,15 +29736,15 @@
if (yahooEventPane.parentNode != null) {
yahooEventPane.parentNode.removeChild(yahooEventPane);
}
- this.map.events.unregister("moveend", this,
+ this.map.events.unregister("moveend", this,
this.fixYahooEventPane);
}
},
- /**
+ /**
* APIMethod: getWarningHTML
- *
- * Returns:
+ *
+ * Returns:
* {String} String with information on why layer is broken, how to get
* it working.
*/
@@ -27858,7 +29758,7 @@
/* */
/* Translation Functions */
/* */
- /* The following functions translate GMaps and OL */
+ /* The following functions translate GMaps and OL */
/* formats for Pixel, LonLat, Bounds, and Zoom */
/* */
/********************************************************/
@@ -27867,13 +29767,13 @@
//
// TRANSLATION: MapObject Zoom <-> OpenLayers Zoom
//
-
+
/**
* APIMethod: getOLZoomFromMapObjectZoom
- *
+ *
* Parameters:
* gZoom - {Integer}
- *
+ *
* Returns:
* {Integer} An OpenLayers Zoom level, translated from the passed in gZoom
* Returns null if null value is passed in.
@@ -27886,19 +29786,19 @@
}
return zoom;
},
-
+
/**
* APIMethod: getMapObjectZoomFromOLZoom
- *
+ *
* Parameters:
* olZoom - {Integer}
- *
+ *
* Returns:
* {Integer} A MapObject level, translated from the passed in olZoom
* Returns null if null value is passed in
*/
getMapObjectZoomFromOLZoom: function(olZoom) {
- var zoom = null;
+ var zoom = null;
if (olZoom != null) {
zoom = OpenLayers.Layer.FixedZoomLevels.prototype.getMapObjectZoomFromOLZoom.apply(this, [olZoom]);
zoom = 18 - zoom;
@@ -27915,22 +29815,22 @@
// Get&Set Center, Zoom
- /**
+ /**
* APIMethod: setMapObjectCenter
* Set the mapObject to the specified center and zoom
- *
+ *
* Parameters:
* center - {Object} MapObject LonLat format
* zoom - {int} MapObject zoom format
*/
setMapObjectCenter: function(center, zoom) {
- this.mapObject.drawZoomAndCenter(center, zoom);
+ this.mapObject.drawZoomAndCenter(center, zoom);
},
-
+
/**
* APIMethod: getMapObjectCenter
- *
- * Returns:
+ *
+ * Returns:
* {Object} The mapObject's current center in Map Object format
*/
getMapObjectCenter: function() {
@@ -27939,7 +29839,7 @@
/**
* APIMethod: dragPanMapObject
- *
+ *
* Parameters:
* dX - {Integer}
* dY - {Integer}
@@ -27950,10 +29850,10 @@
'y': dY
});
},
-
- /**
+
+ /**
* APIMethod: getMapObjectZoom
- *
+ *
* Returns:
* {Integer} The mapObject's current zoom, in Map Object format
*/
@@ -27963,13 +29863,13 @@
// LonLat - Pixel Translation
-
+
/**
* APIMethod: getMapObjectLonLatFromMapObjectPixel
- *
+ *
* Parameters:
* moPixel - {Object} MapObject Pixel format
- *
+ *
* Returns:
* {Object} MapObject LonLat translated from MapObject Pixel
*/
@@ -27979,10 +29879,10 @@
/**
* APIMethod: getMapObjectPixelFromMapObjectLonLat
- *
+ *
* Parameters:
* moLonLat - {Object} MapObject LonLat format
- *
+ *
* Returns:
* {Object} MapObject Pixel transtlated from MapObject LonLat
*/
@@ -27999,44 +29899,44 @@
// LonLat
-
+
/**
* APIMethod: getLongitudeFromMapObjectLonLat
- *
+ *
* Parameters:
* moLonLat - {Object} MapObject LonLat format
- *
+ *
* Returns:
* {Float} Longitude of the given MapObject LonLat
*/
getLongitudeFromMapObjectLonLat: function(moLonLat) {
- return this.sphericalMercator ?
+ return this.sphericalMercator ?
this.forwardMercator(moLonLat.Lon, moLonLat.Lat).lon :
moLonLat.Lon;
},
/**
* APIMethod: getLatitudeFromMapObjectLonLat
- *
+ *
* Parameters:
* moLonLat - {Object} MapObject LonLat format
- *
+ *
* Returns:
* {Float} Latitude of the given MapObject LonLat
*/
getLatitudeFromMapObjectLonLat: function(moLonLat) {
- return this.sphericalMercator ?
+ return this.sphericalMercator ?
this.forwardMercator(moLonLat.Lon, moLonLat.Lat).lat :
moLonLat.Lat;
},
/**
* APIMethod: getMapObjectLonLatFromLonLat
- *
+ *
* Parameters:
* lon - {Float}
* lat - {Float}
- *
+ *
* Returns:
* {Object} MapObject LonLat built from lon and lat params
*/
@@ -28052,13 +29952,13 @@
},
// Pixel
-
+
/**
* APIMethod: getXFromMapObjectPixel
- *
+ *
* Parameters:
* moPixel - {Object} MapObject Pixel format
- *
+ *
* Returns:
* {Integer} X value of the MapObject Pixel
*/
@@ -28068,10 +29968,10 @@
/**
* APIMethod: getYFromMapObjectPixel
- *
+ *
* Parameters:
* moPixel - {Object} MapObject Pixel format
- *
+ *
* Returns:
* {Integer} Y value of the MapObject Pixel
*/
@@ -28081,570 +29981,46 @@
/**
* APIMethod: getMapObjectPixelFromXY
- *
+ *
* Parameters:
* x - {Integer}
* y - {Integer}
- *
+ *
* Returns:
* {Object} MapObject Pixel from x and y parameters
*/
getMapObjectPixelFromXY: function(x, y) {
return new YCoordPoint(x, y);
},
-
+
// Size
-
+
/**
* APIMethod: getMapObjectSizeFromOLSize
- *
+ *
* Parameters:
* olSize - {<OpenLayers.Size>}
- *
+ *
* Returns:
* {Object} MapObject Size from olSize parameter
*/
getMapObjectSizeFromOLSize: function(olSize) {
return new YSize(olSize.w, olSize.h);
},
-
+
CLASS_NAME: "OpenLayers.Layer.Yahoo"
});
/* ======================================================================
- OpenLayers/Protocol/HTTP.js
+ OpenLayers/Style.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
-/**
- * @requires OpenLayers/Protocol.js
- * @requires OpenLayers/Feature/Vector.js
- */
/**
- * Class: OpenLayers.Protocol.HTTP
- * A basic HTTP protocol for vector layers. Create a new instance with the
- * <OpenLayers.Protocol.HTTP> constructor.
- *
- * Inherits from:
- * - <OpenLayers.Protocol>
- */
-OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {
-
- /**
- * Property: url
- * {String} Service URL, read-only, set through the options
- * passed to constructor.
- */
- url: null,
-
- /**
- * Property: headers
- * {Object} HTTP request headers, read-only, set through the options
- * passed to the constructor,
- * Example: {'Content-Type': 'plain/text'}
- */
- headers: null,
-
- /**
- * Property: params
- * {Object} Parameters of GET requests, read-only, set through the options
- * passed to the constructor,
- * Example: {'bbox': '5,5,5,5'}
- */
- params: null,
-
- /**
- * Property: callback
- * {Object} Function to be called when the <read>, <create>,
- * <update>, <delete> or <commit> operation completes, read-only,
- * set through the options passed to the constructor.
- */
- callback: null,
-
- /**
- * Property: scope
- * {Object} Callback execution scope, read-only, set through the
- * options passed to the constructor.
- */
- scope: null,
-
- /**
- * Property: readWithPOST
- * {Boolean} true if read operations are done with POST requests
- * instead of GET, defaults to false.
- */
- readWithPOST: false,
-
- /**
- * Constructor: OpenLayers.Protocol.HTTP
- * A class for giving layers generic HTTP protocol.
- *
- * Parameters:
- * options - {Object} Optional object whose properties will be set on the
- * instance.
- *
- * Valid options include:
- * url - {String}
- * headers - {Object}
- * params - {Object}
- * format - {<OpenLayers.Format>}
- * callback - {Function}
- * scope - {Object}
- */
- initialize: function(options) {
- this.params = {};
- this.headers = {};
- OpenLayers.Protocol.prototype.initialize.apply(this, arguments);
- },
-
- /**
- * APIMethod: destroy
- * Clean up the protocol.
- */
- destroy: function() {
- this.params = null;
- this.headers = null;
- OpenLayers.Protocol.prototype.destroy.apply(this);
- },
-
- /**
- * Method: createCallback
- * Returns a function that applies the given public method with resp and
- * options arguments.
- *
- * Parameters:
- * method - {Function} The method to be applied by the callback.
- * response - {<OpenLayers.Protocol.Response>} The protocol response object.
- * options - {Object} Options sent to the protocol method (read, create,
- * update, or delete).
- */
- createCallback: function(method, response, options) {
- return OpenLayers.Function.bind(function() {
- method.apply(this, [response, options]);
- }, this);
- },
-
- /**
- * APIMethod: read
- * Construct a request for reading new features.
- *
- * Parameters:
- * options - {Object} Optional object for configuring the request.
- * This object is modified and should not be reused.
- *
- * Valid options:
- * url - {String} Url for the request.
- * params - {Object} Parameters to get serialized as a query string.
- * headers - {Object} Headers to be set on the request.
- * filter - {<OpenLayers.Filter.BBOX>} If a bbox filter is sent, it will be
- * serialized according to the OpenSearch Geo extension
- * (bbox=minx,miny,maxx,maxy). Note that a BBOX filter as the child
- * of a logical filter will not be serialized.
- * readWithPOST - {Boolean} If the request should be done with POST.
- *
- * Returns:
- * {<OpenLayers.Protocol.Response>} A response object, whose "priv" property
- * references the HTTP request, this object is also passed to the
- * callback function when the request completes, its "features" property
- * is then populated with the the features received from the server.
- */
- read: function(options) {
- options = OpenLayers.Util.applyDefaults(options, this.options);
- var readWithPOST = (options.readWithPOST !== undefined) ?
- options.readWithPOST : this.readWithPOST;
- var resp = new OpenLayers.Protocol.Response({requestType: "read"});
-
- if(options.filter && options.filter instanceof OpenLayers.Filter.Spatial) {
- if(options.filter.type == OpenLayers.Filter.Spatial.BBOX) {
- options.params = OpenLayers.Util.extend(options.params, {
- bbox: options.filter.value.toArray()
- });
- }
- }
-
- if(readWithPOST) {
- resp.priv = OpenLayers.Request.POST({
- url: options.url,
- callback: this.createCallback(this.handleRead, resp, options),
- data: OpenLayers.Util.getParameterString(options.params),
- headers: {
- "Content-Type": "application/x-www-form-urlencoded"
- }
- });
- } else {
- resp.priv = OpenLayers.Request.GET({
- url: options.url,
- callback: this.createCallback(this.handleRead, resp, options),
- params: options.params,
- headers: options.headers
- });
- }
-
- return resp;
- },
-
- /**
- * Method: handleRead
- * Individual callbacks are created for read, create and update, should
- * a subclass need to override each one separately.
- *
- * Parameters:
- * resp - {<OpenLayers.Protocol.Response>} The response object to pass to
- * the user callback.
- * options - {Object} The user options passed to the read call.
- */
- handleRead: function(resp, options) {
- this.handleResponse(resp, options);
- },
-
- /**
- * APIMethod: create
- * Construct a request for writing newly created features.
- *
- * Parameters:
- * features - {Array({<OpenLayers.Feature.Vector>})} or
- * {<OpenLayers.Feature.Vector>}
- * options - {Object} Optional object for configuring the request.
- * This object is modified and should not be reused.
- *
- * Returns:
- * {<OpenLayers.Protocol.Response>} An <OpenLayers.Protocol.Response>
- * object, whose "priv" property references the HTTP request, this
- * object is also passed to the callback function when the request
- * completes, its "features" property is then populated with the
- * the features received from the server.
- */
- create: function(features, options) {
- options = OpenLayers.Util.applyDefaults(options, this.options);
-
- var resp = new OpenLayers.Protocol.Response({
- reqFeatures: features,
- requestType: "create"
- });
-
- resp.priv = OpenLayers.Request.POST({
- url: options.url,
- callback: this.createCallback(this.handleCreate, resp, options),
- headers: options.headers,
- data: this.format.write(features)
- });
-
- return resp;
- },
-
- /**
- * Method: handleCreate
- * Called the the request issued by <create> is complete. May be overridden
- * by subclasses.
- *
- * Parameters:
- * resp - {<OpenLayers.Protocol.Response>} The response object to pass to
- * any user callback.
- * options - {Object} The user options passed to the create call.
- */
- handleCreate: function(resp, options) {
- this.handleResponse(resp, options);
- },
-
- /**
- * APIMethod: update
- * Construct a request updating modified feature.
- *
- * Parameters:
- * feature - {<OpenLayers.Feature.Vector>}
- * options - {Object} Optional object for configuring the request.
- * This object is modified and should not be reused.
- *
- * Returns:
- * {<OpenLayers.Protocol.Response>} An <OpenLayers.Protocol.Response>
- * object, whose "priv" property references the HTTP request, this
- * object is also passed to the callback function when the request
- * completes, its "features" property is then populated with the
- * the feature received from the server.
- */
- update: function(feature, options) {
- var url = options.url || feature.url || this.options.url;
- options = OpenLayers.Util.applyDefaults(options, this.options);
-
- var resp = new OpenLayers.Protocol.Response({
- reqFeatures: feature,
- requestType: "update"
- });
-
- resp.priv = OpenLayers.Request.PUT({
- url: url,
- callback: this.createCallback(this.handleUpdate, resp, options),
- headers: options.headers,
- data: this.format.write(feature)
- });
-
- return resp;
- },
-
- /**
- * Method: handleUpdate
- * Called the the request issued by <update> is complete. May be overridden
- * by subclasses.
- *
- * Parameters:
- * resp - {<OpenLayers.Protocol.Response>} The response object to pass to
- * any user callback.
- * options - {Object} The user options passed to the update call.
- */
- handleUpdate: function(resp, options) {
- this.handleResponse(resp, options);
- },
-
- /**
- * APIMethod: delete
- * Construct a request deleting a removed feature.
- *
- * Parameters:
- * feature - {<OpenLayers.Feature.Vector>}
- * options - {Object} Optional object for configuring the request.
- * This object is modified and should not be reused.
- *
- * Returns:
- * {<OpenLayers.Protocol.Response>} An <OpenLayers.Protocol.Response>
- * object, whose "priv" property references the HTTP request, this
- * object is also passed to the callback function when the request
- * completes.
- */
- "delete": function(feature, options) {
- var url = options.url || feature.url || this.options.url;
- options = OpenLayers.Util.applyDefaults(options, this.options);
-
- var resp = new OpenLayers.Protocol.Response({
- reqFeatures: feature,
- requestType: "delete"
- });
-
- resp.priv = OpenLayers.Request.DELETE({
- url: url,
- callback: this.createCallback(this.handleDelete, resp, options),
- headers: options.headers
- });
-
- return resp;
- },
-
- /**
- * Method: handleDelete
- * Called the the request issued by <delete> is complete. May be overridden
- * by subclasses.
- *
- * Parameters:
- * resp - {<OpenLayers.Protocol.Response>} The response object to pass to
- * any user callback.
- * options - {Object} The user options passed to the delete call.
- */
- handleDelete: function(resp, options) {
- this.handleResponse(resp, options);
- },
-
- /**
- * Method: handleResponse
- * Called by CRUD specific handlers.
- *
- * Parameters:
- * resp - {<OpenLayers.Protocol.Response>} The response object to pass to
- * any user callback.
- * options - {Object} The user options passed to the create, read, update,
- * or delete call.
- */
- handleResponse: function(resp, options) {
- var request = resp.priv;
- if(options.callback) {
- if(request.status >= 200 && request.status < 300) {
- // success
- if(resp.requestType != "delete") {
- resp.features = this.parseFeatures(request);
- }
- resp.code = OpenLayers.Protocol.Response.SUCCESS;
- } else {
- // failure
- resp.code = OpenLayers.Protocol.Response.FAILURE;
- }
- options.callback.call(options.scope, resp);
- }
- },
-
- /**
- * Method: parseFeatures
- * Read HTTP response body and return features.
- *
- * Parameters:
- * request - {XMLHttpRequest} The request object
- *
- * Returns:
- * {Array({<OpenLayers.Feature.Vector>})} or
- * {<OpenLayers.Feature.Vector>} Array of features or a single feature.
- */
- parseFeatures: function(request) {
- var doc = request.responseXML;
- if (!doc || !doc.documentElement) {
- doc = request.responseText;
- }
- if (!doc || doc.length <= 0) {
- return null;
- }
- return this.format.read(doc);
- },
-
- /**
- * APIMethod: commit
- * Iterate over each feature and take action based on the feature state.
- * Possible actions are create, update and delete.
- *
- * Parameters:
- * features - {Array({<OpenLayers.Feature.Vector>})}
- * options - {Object} Optional object for setting up intermediate commit
- * callbacks.
- *
- * Valid options:
- * create - {Object} Optional object to be passed to the <create> method.
- * update - {Object} Optional object to be passed to the <update> method.
- * delete - {Object} Optional object to be passed to the <delete> method.
- * callback - {Function} Optional function to be called when the commit
- * is complete.
- * scope - {Object} Optional object to be set as the scope of the callback.
- *
- * Returns:
- * {Array(<OpenLayers.Protocol.Response>)} An array of response objects,
- * one per request made to the server, each object's "priv" property
- * references the corresponding HTTP request.
- */
- commit: function(features, options) {
- options = OpenLayers.Util.applyDefaults(options, this.options);
- var resp = [], nResponses = 0;
-
- // Divide up features before issuing any requests. This properly
- // counts requests in the event that any responses come in before
- // all requests have been issued.
- var types = {};
- types[OpenLayers.State.INSERT] = [];
- types[OpenLayers.State.UPDATE] = [];
- types[OpenLayers.State.DELETE] = [];
- var feature, list, requestFeatures = [];
- for(var i=0, len=features.length; i<len; ++i) {
- feature = features[i];
- list = types[feature.state];
- if(list) {
- list.push(feature);
- requestFeatures.push(feature);
- }
- }
- // tally up number of requests
- var nRequests = (types[OpenLayers.State.INSERT].length > 0 ? 1 : 0) +
- types[OpenLayers.State.UPDATE].length +
- types[OpenLayers.State.DELETE].length;
-
- // This response will be sent to the final callback after all the others
- // have been fired.
- var success = true;
- var finalResponse = new OpenLayers.Protocol.Response({
- reqFeatures: requestFeatures
- });
-
- function insertCallback(response) {
- var len = response.features ? response.features.length : 0;
- var fids = new Array(len);
- for(var i=0; i<len; ++i) {
- fids[i] = response.features[i].fid;
- }
- finalResponse.insertIds = fids;
- callback.apply(this, [response]);
- }
-
- function callback(response) {
- this.callUserCallback(response, options);
- success = success && response.success();
- nResponses++;
- if (nResponses >= nRequests) {
- if (options.callback) {
- finalResponse.code = success ?
- OpenLayers.Protocol.Response.SUCCESS :
- OpenLayers.Protocol.Response.FAILURE;
- options.callback.apply(options.scope, [finalResponse]);
- }
- }
- }
-
- // start issuing requests
- var queue = types[OpenLayers.State.INSERT];
- if(queue.length > 0) {
- resp.push(this.create(
- queue, OpenLayers.Util.applyDefaults(
- {callback: insertCallback, scope: this}, options.create
- )
- ));
- }
- queue = types[OpenLayers.State.UPDATE];
- for(var i=queue.length-1; i>=0; --i) {
- resp.push(this.update(
- queue[i], OpenLayers.Util.applyDefaults(
- {callback: callback, scope: this}, options.update
- ))
- );
- }
- queue = types[OpenLayers.State.DELETE];
- for(var i=queue.length-1; i>=0; --i) {
- resp.push(this["delete"](
- queue[i], OpenLayers.Util.applyDefaults(
- {callback: callback, scope: this}, options["delete"]
- ))
- );
- }
- return resp;
- },
-
- /**
- * APIMethod: abort
- * Abort an ongoing request, the response object passed to
- * this method must come from this HTTP protocol (as a result
- * of a create, read, update, delete or commit operation).
- *
- * Parameters:
- * response - {<OpenLayers.Protocol.Response>}
- */
- abort: function(response) {
- if (response) {
- response.priv.abort();
- }
- },
-
- /**
- * Method: callUserCallback
- * This method is used from within the commit method each time an
- * an HTTP response is received from the server, it is responsible
- * for calling the user-supplied callbacks.
- *
- * Parameters:
- * resp - {<OpenLayers.Protocol.Response>}
- * options - {Object} The map of options passed to the commit call.
- */
- callUserCallback: function(resp, options) {
- var opt = options[resp.requestType];
- if(opt && opt.callback) {
- opt.callback.call(opt.scope, resp);
- }
- },
-
- CLASS_NAME: "OpenLayers.Protocol.HTTP"
-});
-/* ======================================================================
- OpenLayers/Style.js
- ====================================================================== */
-
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
- * full text of the license. */
-
-
-/**
* @requires OpenLayers/Util.js
* @requires OpenLayers/Feature/Vector.js
*/
@@ -28657,17 +30033,23 @@
OpenLayers.Style = OpenLayers.Class({
/**
+ * Property: id
+ * {String} A unique id for this session.
+ */
+ id: null,
+
+ /**
* APIProperty: name
* {String}
*/
name: null,
-
+
/**
* Property: title
* {String} Title of this style (set if included in SLD)
*/
title: null,
-
+
/**
* Property: description
* {String} Description of this style (set if abstract is included in SLD)
@@ -28680,19 +30062,19 @@
* according to the NamedLayer attribute of an SLD document.
*/
layerName: null,
-
+
/**
* APIProperty: isDefault
* {Boolean}
*/
isDefault: false,
-
- /**
- * Property: rules
+
+ /**
+ * Property: rules
* {Array(<OpenLayers.Rule>)}
*/
rules: null,
-
+
/**
* Property: context
* {Object} An optional object with properties that symbolizers' property
@@ -28710,7 +30092,7 @@
* rules defined.
*/
defaultStyle: null,
-
+
/**
* Property: defaultsPerSymbolizer
* {Boolean} If set to true, the <defaultStyle> will extend the symbolizer
@@ -28719,16 +30101,16 @@
* graphic set to true. Default is false.
*/
defaultsPerSymbolizer: false,
-
+
/**
* Property: propertyStyles
* {Hash of Boolean} cache of style properties that need to be parsed for
* propertyNames. Property names are keys, values won't be used.
*/
propertyStyles: null,
+
-
- /**
+ /**
* Constructor: OpenLayers.Style
* Creates a UserStyle.
*
@@ -28743,7 +30125,7 @@
* Valid options:
* rules - {Array(<OpenLayers.Rule>)} List of rules to be added to the
* style.
- *
+ *
* Return:
* {<OpenLayers.Style>}
*/
@@ -28760,9 +30142,10 @@
this.setDefaultStyle(style ||
OpenLayers.Feature.Vector.style["default"]);
+ this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
},
- /**
+ /**
* APIMethod: destroy
* nullify references to prevent circular references and memory leaks
*/
@@ -28774,22 +30157,22 @@
this.rules = null;
this.defaultStyle = null;
},
-
+
/**
* Method: createSymbolizer
* creates a style by applying all feature-dependent rules to the base
* style.
- *
+ *
* Parameters:
* feature - {<OpenLayers.Feature>} feature to evaluate rules for
- *
+ *
* Returns:
* {Object} symbolizer hash
*/
createSymbolizer: function(feature) {
var style = this.defaultsPerSymbolizer ? {} : this.createLiterals(
OpenLayers.Util.extend({}, this.defaultStyle), feature);
-
+
var rules = this.rules;
var rule, context;
@@ -28799,7 +30182,7 @@
rule = rules[i];
// does the rule apply?
var applies = rule.evaluate(feature);
-
+
if(applies) {
if(rule instanceof OpenLayers.Rule && rule.elseFilter) {
elseRules.push(rule);
@@ -28809,7 +30192,7 @@
}
}
}
-
+
// if no other rules apply, apply the rules with else filters
if(appliedRules == false && elseRules.length > 0) {
appliedRules = true;
@@ -28822,10 +30205,10 @@
if(rules.length > 0 && appliedRules == false) {
style.display = "none";
}
-
+
return style;
},
-
+
/**
* Method: applySymbolizer
*
@@ -28843,7 +30226,7 @@
OpenLayers.Style.SYMBOLIZER_PREFIXES[0];
var symbolizer = rule.symbolizer[symbolizerPrefix] || rule.symbolizer;
-
+
if(this.defaultsPerSymbolizer === true) {
var defaults = this.defaultStyle;
OpenLayers.Util.applyDefaults(symbolizer, {
@@ -28882,35 +30265,36 @@
return this.createLiterals(
OpenLayers.Util.extend(style, symbolizer), feature);
},
-
+
/**
* Method: createLiterals
* creates literals for all style properties that have an entry in
* <this.propertyStyles>.
- *
+ *
* Parameters:
* style - {Object} style to create literals for. Will be modified
* inline.
* feature - {Object}
- *
+ *
* Returns:
* {Object} the modified style
*/
createLiterals: function(style, feature) {
- var context = this.context || feature.attributes || feature.data;
-
+ var context = OpenLayers.Util.extend({}, feature.attributes || feature.data);
+ OpenLayers.Util.extend(context, this.context);
+
for (var i in this.propertyStyles) {
- style[i] = OpenLayers.Style.createLiteral(style[i], context, feature);
+ style[i] = OpenLayers.Style.createLiteral(style[i], context, feature, i);
}
return style;
},
-
+
/**
* Method: findPropertyStyles
* Looks into all rules for this style and the defaultStyle to collect
* all the style hash property names containing ${...} strings that have
* to be replaced using the createLiteral method before returning them.
- *
+ *
* Returns:
* {Object} hash of property names that need createLiteral parsing. The
* name of the property is the key, and the value is true;
@@ -28941,15 +30325,15 @@
}
return propertyStyles;
},
-
+
/**
* Method: addPropertyStyles
- *
+ *
* Parameters:
* propertyStyles - {Object} hash to add new property styles to. Will be
* modified inline
* symbolizer - {Object} search this symbolizer for property styles
- *
+ *
* Returns:
* {Object} propertyStyles hash
*/
@@ -28964,39 +30348,39 @@
}
return propertyStyles;
},
-
+
/**
* APIMethod: addRules
* Adds rules to this style.
- *
+ *
* Parameters:
* rules - {Array(<OpenLayers.Rule>)}
*/
addRules: function(rules) {
- this.rules = this.rules.concat(rules);
+ Array.prototype.push.apply(this.rules, rules);
this.propertyStyles = this.findPropertyStyles();
},
-
+
/**
* APIMethod: setDefaultStyle
* Sets the default style for this style object.
- *
+ *
* Parameters:
* style - {Object} Hash of style properties
*/
setDefaultStyle: function(style) {
- this.defaultStyle = style;
+ this.defaultStyle = style;
this.propertyStyles = this.findPropertyStyles();
},
-
+
/**
* Method: getSymbolizerPrefix
* Returns the correct symbolizer prefix according to the
* geometry type of the passed geometry
- *
+ *
* Parameters:
* geometry {<OpenLayers.Geometry>}
- *
+ *
* Returns:
* {String} key of the according symbolizer
*/
@@ -29008,7 +30392,30 @@
}
}
},
-
+
+ /**
+ * APIMethod: clone
+ * Clones this style.
+ *
+ * Returns:
+ * {<OpenLayers.Style>} Clone of this style.
+ */
+ clone: function() {
+ var options = OpenLayers.Util.extend({}, this);
+ // clone rules
+ if(this.rules) {
+ options.rules = [];
+ for(var i=0, len=this.rules.length; i<len; ++i) {
+ options.rules.push(this.rules[i].clone());
+ }
+ }
+ // clone context
+ options.context = this.context && OpenLayers.Util.extend({}, this.context);
+ //clone default style
+ var defaultStyle = OpenLayers.Util.extend({}, this.defaultStyle);
+ return new OpenLayers.Style(defaultStyle, options);
+ },
+
CLASS_NAME: "OpenLayers.Style"
});
@@ -29017,41 +30424,46 @@
* Function: createLiteral
* converts a style value holding a combination of PropertyName and Literal
* into a Literal, taking the property values from the passed features.
- *
+ *
* Parameters:
* value - {String} value to parse. If this string contains a construct like
* "foo ${bar}", then "foo " will be taken as literal, and "${bar}"
* will be replaced by the value of the "bar" attribute of the passed
* feature.
* context - {Object} context to take attribute values from
- * feature - {OpenLayers.Feature.Vector} The feature that will be passed
- * to <OpenLayers.String.format> for evaluating functions in the context.
- *
+ * feature - {<OpenLayers.Feature.Vector>} optional feature to pass to
+ * <OpenLayers.String.format> for evaluating functions in the
+ * context.
+ * property - {String} optional, name of the property for which the literal is
+ * being created for evaluating functions in the context.
+ *
* Returns:
* {String} the parsed value. In the example of the value parameter above, the
* result would be "foo valueOfBar", assuming that the passed feature has an
* attribute named "bar" with the value "valueOfBar".
*/
-OpenLayers.Style.createLiteral = function(value, context, feature) {
+OpenLayers.Style.createLiteral = function(value, context, feature, property) {
if (typeof value == "string" && value.indexOf("${") != -1) {
- value = OpenLayers.String.format(value, context, [feature]);
+ value = OpenLayers.String.format(value, context, [feature, property]);
value = (isNaN(value) || !value) ? value : parseFloat(value);
}
return value;
};
-
+
/**
* Constant: OpenLayers.Style.SYMBOLIZER_PREFIXES
* {Array} prefixes of the sld symbolizers. These are the
* same as the main geometry types
*/
-OpenLayers.Style.SYMBOLIZER_PREFIXES = ['Point', 'Line', 'Polygon', 'Text'];
+OpenLayers.Style.SYMBOLIZER_PREFIXES = ['Point', 'Line', 'Polygon', 'Text',
+ 'Raster'];
/* ======================================================================
OpenLayers/Control/Navigation.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -29064,21 +30476,21 @@
/**
* Class: OpenLayers.Control.Navigation
* The navigation control handles map browsing with mouse events (dragging,
- * double-clicking, and scrolling the wheel). Create a new navigation
- * control with the <OpenLayers.Control.Navigation> control.
- *
- * Note that this control is added to the map by default (if no controls
- * array is sent in the options object to the <OpenLayers.Map>
+ * double-clicking, and scrolling the wheel). Create a new navigation
+ * control with the <OpenLayers.Control.Navigation> control.
+ *
+ * Note that this control is added to the map by default (if no controls
+ * array is sent in the options object to the <OpenLayers.Map>
* constructor).
- *
+ *
* Inherits:
* - <OpenLayers.Control>
*/
OpenLayers.Control.Navigation = OpenLayers.Class(OpenLayers.Control, {
- /**
+ /**
* Property: dragPan
- * {<OpenLayers.Control.DragPan>}
+ * {<OpenLayers.Control.DragPan>}
*/
dragPan: null,
@@ -29089,16 +30501,36 @@
dragPanOptions: null,
/**
+ * APIProperty: documentDrag
+ * {Boolean} Allow panning of the map by dragging outside map viewport.
+ * Default is false.
+ */
+ documentDrag: false,
+
+ /**
* Property: zoomBox
* {<OpenLayers.Control.ZoomBox>}
*/
zoomBox: null,
/**
+ * APIProperty: zoomBoxEnabled
+ * {Boolean} Whether the user can draw a box to zoom
+ */
+ zoomBoxEnabled: true,
+
+ /**
* APIProperty: zoomWheelEnabled
* {Boolean} Whether the mousewheel should zoom the map
*/
zoomWheelEnabled: true,
+
+ /**
+ * Property: mouseWheelOptions
+ * {Object} Options passed to the MouseWheel control (only useful if
+ * <zoomWheelEnabled> is set to true)
+ */
+ mouseWheelOptions: null,
/**
* APIProperty: handleRightClicks
@@ -29109,18 +30541,25 @@
/**
* APIProperty: zoomBoxKeyMask
* {Integer} <OpenLayers.Handler> key code of the key, which has to be
- * pressed, while drawing the zoom box with the mouse on the screen.
+ * pressed, while drawing the zoom box with the mouse on the screen.
* You should probably set handleRightClicks to true if you use this
* with MOD_CTRL, to disable the context menu for machines which use
* CTRL-Click as a right click.
* Default: <OpenLayers.Handler.MOD_SHIFT
*/
zoomBoxKeyMask: OpenLayers.Handler.MOD_SHIFT,
+
+ /**
+ * APIProperty: autoActivate
+ * {Boolean} Activate the control when it is added to a map. Default is
+ * true.
+ */
+ autoActivate: true,
/**
* Constructor: OpenLayers.Control.Navigation
* Create a new navigation control
- *
+ *
* Parameters:
* options - {Object} An optional object whose properties will be set on
* the control
@@ -29150,7 +30589,7 @@
this.zoomBox = null;
OpenLayers.Control.prototype.destroy.apply(this,arguments);
},
-
+
/**
* Method: activate
*/
@@ -29158,9 +30597,11 @@
this.dragPan.activate();
if (this.zoomWheelEnabled) {
this.handlers.wheel.activate();
+ }
+ this.handlers.click.activate();
+ if (this.zoomBoxEnabled) {
+ this.zoomBox.activate();
}
- this.handlers.click.activate();
- this.zoomBox.activate();
return OpenLayers.Control.prototype.activate.apply(this,arguments);
},
@@ -29174,29 +30615,32 @@
this.handlers.wheel.deactivate();
return OpenLayers.Control.prototype.deactivate.apply(this,arguments);
},
-
+
/**
* Method: draw
*/
draw: function() {
// disable right mouse context menu for support of right click events
if (this.handleRightClicks) {
- this.map.viewPortDiv.oncontextmenu = function () { return false;};
+ this.map.viewPortDiv.oncontextmenu = OpenLayers.Function.False;
}
- var clickCallbacks = {
- 'dblclick': this.defaultDblClick,
- 'dblrightclick': this.defaultDblRightClick
+ var clickCallbacks = {
+ 'dblclick': this.defaultDblClick,
+ 'dblrightclick': this.defaultDblRightClick
};
var clickOptions = {
- 'double': true,
+ 'double': true,
'stopDouble': true
};
this.handlers.click = new OpenLayers.Handler.Click(
this, clickCallbacks, clickOptions
);
this.dragPan = new OpenLayers.Control.DragPan(
- OpenLayers.Util.extend({map: this.map}, this.dragPanOptions)
+ OpenLayers.Util.extend({
+ map: this.map,
+ documentDrag: this.documentDrag
+ }, this.dragPanOptions)
);
this.zoomBox = new OpenLayers.Control.ZoomBox(
{map: this.map, keyMask: this.zoomBoxKeyMask});
@@ -29204,42 +30648,45 @@
this.zoomBox.draw();
this.handlers.wheel = new OpenLayers.Handler.MouseWheel(
this, {"up" : this.wheelUp,
- "down": this.wheelDown} );
- this.activate();
+ "down": this.wheelDown},
+ this.mouseWheelOptions );
},
/**
- * Method: defaultDblClick
- *
+ * Method: defaultDblClick
+ *
* Parameters:
- * evt - {Event}
+ * evt - {Event}
*/
defaultDblClick: function (evt) {
- var newCenter = this.map.getLonLatFromViewPortPx( evt.xy );
+ var newCenter = this.map.getLonLatFromViewPortPx( evt.xy );
this.map.setCenter(newCenter, this.map.zoom + 1);
},
/**
- * Method: defaultDblRightClick
- *
+ * Method: defaultDblRightClick
+ *
* Parameters:
- * evt - {Event}
+ * evt - {Event}
*/
defaultDblRightClick: function (evt) {
- var newCenter = this.map.getLonLatFromViewPortPx( evt.xy );
+ var newCenter = this.map.getLonLatFromViewPortPx( evt.xy );
this.map.setCenter(newCenter, this.map.zoom - 1);
},
-
+
/**
- * Method: wheelChange
+ * Method: wheelChange
*
* Parameters:
* evt - {Event}
* deltaZ - {Integer}
*/
wheelChange: function(evt, deltaZ) {
- var newZoom = this.map.getZoom() + deltaZ;
- if (!this.map.isValidZoomLevel(newZoom)) {
+ var currentZoom = this.map.getZoom();
+ var newZoom = this.map.getZoom() + Math.round(deltaZ);
+ newZoom = Math.max(newZoom, 0);
+ newZoom = Math.min(newZoom, this.map.getNumZoomLevels());
+ if (newZoom === currentZoom) {
return;
}
var size = this.map.getSize();
@@ -29253,59 +30700,152 @@
this.map.setCenter( newCenter, newZoom );
},
- /**
+ /**
* Method: wheelUp
* User spun scroll wheel up
- *
+ *
* Parameters:
* evt - {Event}
+ * delta - {Integer}
*/
- wheelUp: function(evt) {
- this.wheelChange(evt, 1);
+ wheelUp: function(evt, delta) {
+ this.wheelChange(evt, delta || 1);
},
- /**
+ /**
* Method: wheelDown
* User spun scroll wheel down
- *
+ *
* Parameters:
* evt - {Event}
+ * delta - {Integer}
*/
- wheelDown: function(evt) {
- this.wheelChange(evt, -1);
+ wheelDown: function(evt, delta) {
+ this.wheelChange(evt, delta || -1);
},
-
+
/**
+ * Method: disableZoomBox
+ */
+ disableZoomBox : function() {
+ this.zoomBoxEnabled = false;
+ this.zoomBox.deactivate();
+ },
+
+ /**
+ * Method: enableZoomBox
+ */
+ enableZoomBox : function() {
+ this.zoomBoxEnabled = true;
+ if (this.active) {
+ this.zoomBox.activate();
+ }
+ },
+
+ /**
* Method: disableZoomWheel
*/
-
+
disableZoomWheel : function() {
this.zoomWheelEnabled = false;
- this.handlers.wheel.deactivate();
+ this.handlers.wheel.deactivate();
},
-
+
/**
* Method: enableZoomWheel
*/
-
+
enableZoomWheel : function() {
this.zoomWheelEnabled = true;
if (this.active) {
this.handlers.wheel.activate();
- }
+ }
},
CLASS_NAME: "OpenLayers.Control.Navigation"
});
/* ======================================================================
- OpenLayers/Geometry.js
+ OpenLayers/Filter.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
+
/**
+ * @requires OpenLayers/Util.js
+ * @requires OpenLayers/Style.js
+ */
+
+/**
+ * Class: OpenLayers.Filter
+ * This class represents an OGC Filter.
+ */
+OpenLayers.Filter = OpenLayers.Class({
+
+ /**
+ * Constructor: OpenLayers.Filter
+ * This is an abstract class. Create an instance of a filter subclass.
+ *
+ * Parameters:
+ * options - {Object} Optional object whose properties will be set on the
+ * instance.
+ *
+ * Returns:
+ * {<OpenLayers.Filter>}
+ */
+ initialize: function(options) {
+ OpenLayers.Util.extend(this, options);
+ },
+
+ /**
+ * APIMethod: destroy
+ * Remove reference to anything added.
+ */
+ destroy: function() {
+ },
+
+ /**
+ * APIMethod: evaluate
+ * Evaluates this filter in a specific context. Should be implemented by
+ * subclasses.
+ *
+ * Parameters:
+ * context - {Object} Context to use in evaluating the filter. If a vector
+ * feature is provided, the feature.attributes will be used as context.
+ *
+ * Returns:
+ * {Boolean} The filter applies.
+ */
+ evaluate: function(context) {
+ return true;
+ },
+
+ /**
+ * APIMethod: clone
+ * Clones this filter. Should be implementted by subclasses.
+ *
+ * Returns:
+ * {<OpenLayers.Filter>} Clone of this filter.
+ */
+ clone: function() {
+ return null;
+ },
+
+ CLASS_NAME: "OpenLayers.Filter"
+});
+/* ======================================================================
+ OpenLayers/Geometry.js
+ ====================================================================== */
+
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+/**
* @requires OpenLayers/Format/WKT.js
* @requires OpenLayers/Feature/Vector.js
*/
@@ -29332,19 +30872,19 @@
parent: null,
/**
- * Property: bounds
+ * Property: bounds
* {<OpenLayers.Bounds>} The bounds of this geometry
*/
bounds: null,
/**
* Constructor: OpenLayers.Geometry
- * Creates a geometry object.
+ * Creates a geometry object.
*/
initialize: function() {
this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME+ "_");
},
-
+
/**
* Method: destroy
* Destroy this geometry.
@@ -29353,31 +30893,31 @@
this.id = null;
this.bounds = null;
},
-
+
/**
* APIMethod: clone
* Create a clone of this geometry. Does not set any non-standard
* properties of the cloned geometry.
- *
+ *
* Returns:
* {<OpenLayers.Geometry>} An exact clone of this geometry.
*/
clone: function() {
return new OpenLayers.Geometry();
},
-
+
/**
* Set the bounds for this Geometry.
- *
+ *
* Parameters:
- * object - {<OpenLayers.Bounds>}
+ * object - {<OpenLayers.Bounds>}
*/
setBounds: function(bounds) {
if (bounds) {
this.bounds = bounds.clone();
}
},
-
+
/**
* Method: clearBounds
* Nullify this components bounds and that of its parent as well.
@@ -29386,16 +30926,16 @@
this.bounds = null;
if (this.parent) {
this.parent.clearBounds();
- }
+ }
},
-
+
/**
* Method: extendBounds
- * Extend the existing bounds to include the new bounds.
+ * Extend the existing bounds to include the new bounds.
* If geometry's bounds is not yet set, then set a new Bounds.
- *
+ *
* Parameters:
- * newBounds - {<OpenLayers.Bounds>}
+ * newBounds - {<OpenLayers.Bounds>}
*/
extendBounds: function(newBounds){
var bounds = this.getBounds();
@@ -29405,12 +30945,12 @@
this.bounds.extend(newBounds);
}
},
-
+
/**
* APIMethod: getBounds
- * Get the bounds for this Geometry. If bounds is not set, it
+ * Get the bounds for this Geometry. If bounds is not set, it
* is calculated again, this makes queries faster.
- *
+ *
* Returns:
* {<OpenLayers.Bounds>}
*/
@@ -29420,17 +30960,17 @@
}
return this.bounds;
},
-
- /**
+
+ /**
* APIMethod: calculateBounds
- * Recalculate the bounds for the geometry.
+ * Recalculate the bounds for the geometry.
*/
calculateBounds: function() {
//
// This should be overridden by subclasses.
//
},
-
+
/**
* APIMethod: distanceTo
* Calculate the closest distance between two geometries (on the x-y plane).
@@ -29441,7 +30981,7 @@
* calculation.
*
* Valid options depend on the specific geometry type.
- *
+ *
* Returns:
* {Number | Object} The distance between this geometry and the target.
* If details is true, the return will be an object with distance,
@@ -29452,7 +30992,7 @@
*/
distanceTo: function(geometry, options) {
},
-
+
/**
* APIMethod: getVertices
* Return a list of all points in this geometry.
@@ -29471,14 +31011,14 @@
/**
* Method: atPoint
- * Note - This is only an approximation based on the bounds of the
+ * Note - This is only an approximation based on the bounds of the
* geometry.
- *
+ *
* Parameters:
- * lonlat - {<OpenLayers.LonLat>}
+ * lonlat - {<OpenLayers.LonLat>}
* toleranceLon - {float} Optional tolerance in Geometric Coords
* toleranceLat - {float} Optional tolerance in Geographic Coords
- *
+ *
* Returns:
* {Boolean} Whether or not the geometry is at the specified location
*/
@@ -29489,8 +31029,8 @@
var dX = (toleranceLon != null) ? toleranceLon : 0;
var dY = (toleranceLat != null) ? toleranceLat : 0;
-
- var toleranceBounds =
+
+ var toleranceBounds =
new OpenLayers.Bounds(this.bounds.left - dX,
this.bounds.bottom - dY,
this.bounds.right + dX,
@@ -29500,12 +31040,12 @@
}
return atPoint;
},
-
+
/**
* Method: getLength
* Calculate the length of this geometry. This method is defined in
* subclasses.
- *
+ *
* Returns:
* {Float} The length of the collection by summing its parts
*/
@@ -29518,7 +31058,7 @@
/**
* Method: getArea
* Calculate the area of this geometry. This method is defined in subclasses.
- *
+ *
* Returns:
* {Float} The area of the collection by summing its parts
*/
@@ -29527,7 +31067,7 @@
//
return 0.0;
},
-
+
/**
* APIMethod: getCentroid
* Calculate the centroid of this geometry. This method is defined in subclasses.
@@ -29585,7 +31125,7 @@
}
return geom;
};
-
+
/**
* Method: OpenLayers.Geometry.segmentsIntersect
* Determine whether two line segments intersect. Optionally calculates
@@ -29684,7 +31224,7 @@
}
}
}
-
+
}
} else {
// no calculated intersection, but segments could be within
@@ -29760,8 +31300,9 @@
OpenLayers/Layer/MapGuide.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * licence. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -29779,52 +31320,52 @@
*/
OpenLayers.Layer.MapGuide = OpenLayers.Class(OpenLayers.Layer.Grid, {
- /**
+ /**
* APIProperty: isBaseLayer
* {Boolean} Treat this layer as a base layer. Default is true.
**/
isBaseLayer: true,
-
+
/**
* APIProperty: useHttpTile
- * {Boolean} use a tile cache exposed directly via a webserver rather than the
- * via mapguide server. This does require extra configuration on the Mapguide Server,
- * and will only work when singleTile is false. The url for the layer must be set to the
- * webserver path rather than the Mapguide mapagent.
- * See http://trac.osgeo.org/mapguide/wiki/CodeSamples/Tiles/ServingTilesViaHttp
+ * {Boolean} use a tile cache exposed directly via a webserver rather than the
+ * via mapguide server. This does require extra configuration on the Mapguide Server,
+ * and will only work when singleTile is false. The url for the layer must be set to the
+ * webserver path rather than the Mapguide mapagent.
+ * See http://trac.osgeo.org/mapguide/wiki/CodeSamples/Tiles/ServingTilesViaHttp
**/
useHttpTile: false,
-
- /**
+
+ /**
* APIProperty: singleTile
- * {Boolean} use tile server or request single tile image.
+ * {Boolean} use tile server or request single tile image.
**/
singleTile: false,
-
- /**
+
+ /**
* APIProperty: useOverlay
* {Boolean} flag to indicate if the layer should be retrieved using
* GETMAPIMAGE (default) or using GETDYNAMICOVERLAY requests.
**/
useOverlay: false,
-
- /**
+
+ /**
* APIProperty: useAsyncOverlay
- * {Boolean} indicates if the MapGuide site supports the asynchronous
+ * {Boolean} indicates if the MapGuide site supports the asynchronous
* GETDYNAMICOVERLAY requests which is available in MapGuide Enterprise 2010
- * and MapGuide Open Source v2.0.3 or higher. The newer versions of MG
- * is called asynchronously, allows selections to be drawn separately from
+ * and MapGuide Open Source v2.0.3 or higher. The newer versions of MG
+ * is called asynchronously, allows selections to be drawn separately from
* the map and offers styling options.
- *
+ *
* With older versions of MapGuide, set useAsyncOverlay=false. Note that in
* this case a synchronous AJAX call is issued and the mapname and session
* parameters must be used to initialize the layer, not the mapdefinition
- * parameter. Also note that this will issue a synchronous AJAX request
+ * parameter. Also note that this will issue a synchronous AJAX request
* before the image request can be issued so the users browser may lock
* up if the MG Web tier does not respond in a timely fashion.
**/
useAsyncOverlay: true,
-
+
/**
* Constant: TILE_PARAMS
* {Object} Hashtable of default parameter key/value pairs for tiled layer
@@ -29845,7 +31386,7 @@
clip: '1',
version: '1.0.0'
},
-
+
/**
* Constant: OVERLAY_PARAMS
* {Object} Hashtable of default parameter key/value pairs for untiled layer
@@ -29857,11 +31398,11 @@
clip: '1',
version: '2.0.0'
},
-
- /**
+
+ /**
* Constant: FOLDER_PARAMS
- * {Object} Hashtable of parameter key/value pairs which describe
- * the folder structure for tiles as configured in the mapguide
+ * {Object} Hashtable of parameter key/value pairs which describe
+ * the folder structure for tiles as configured in the mapguide
* serverconfig.ini section [TileServiceProperties]
*/
FOLDER_PARAMS: {
@@ -29869,9 +31410,9 @@
tileRowsPerFolder: 30,
format: 'png',
querystring: null
- },
+ },
- /**
+ /**
* Property: defaultSize
* {<OpenLayers.Size>} Tile size as produced by MapGuide server
**/
@@ -29879,21 +31420,21 @@
/**
* Constructor: OpenLayers.Layer.MapGuide
- * Create a new Mapguide layer, either tiled or untiled.
+ * Create a new Mapguide layer, either tiled or untiled.
*
- * For tiled layers, the 'groupName' and 'mapDefinition' values
+ * For tiled layers, the 'groupName' and 'mapDefinition' values
* must be specified as parameters in the constructor.
*
* For untiled base layers, specify either combination of 'mapName' and
- * 'session', or 'mapDefinition' and 'locale'.
+ * 'session', or 'mapDefinition' and 'locale'.
*
- * For older versions of MapGuide and overlay layers, set useAsyncOverlay
- * to false and in this case mapName and session are required parameters
+ * For older versions of MapGuide and overlay layers, set useAsyncOverlay
+ * to false and in this case mapName and session are required parameters
* for the constructor.
*
- * NOTE: MapGuide OS uses a DPI value and degrees to meters conversion
- * factor that are different than the defaults used in OpenLayers,
- * so these must be adjusted accordingly in your application.
+ * NOTE: MapGuide OS uses a DPI value and degrees to meters conversion
+ * factor that are different than the defaults used in OpenLayers,
+ * so these must be adjusted accordingly in your application.
* See the MapGuide example for how to set these values for MGOS.
*
* Parameters:
@@ -29902,14 +31443,14 @@
* (e.g. http://localhost:8008/mapguide/mapagent/mapagent.fcgi)
* params - {Object} hashtable of additional parameters to use. Some
* parameters may require additional code on the server. The ones that
- * you may want to use are:
+ * you may want to use are:
* - mapDefinition - {String} The MapGuide resource definition
* (e.g. Library://Samples/Gmap/Maps/gmapTiled.MapDefinition)
- * - locale - Locale setting
+ * - locale - Locale setting
* (for untiled overlays layers only)
* - mapName - {String} Name of the map as stored in the MapGuide session.
* (for untiled layers with a session parameter only)
- * - session - { String} MapGuide session ID
+ * - session - { String} MapGuide session ID
* (for untiled overlays layers only)
* - basemaplayergroupname - {String} GroupName for tiled MapGuide layers only
* - format - Image format to be returned (for untiled overlay layers only)
@@ -29923,24 +31464,24 @@
* groups to hide eg: 'cvc-xcv34,453-345-345sdf'
* - selectionXml - {String} A selection xml string Some server plumbing
* is required to read such a value.
- * options - {Ojbect} Hashtable of extra options to tag onto the layer;
+ * options - {Ojbect} Hashtable of extra options to tag onto the layer;
* will vary depending if tiled or untiled maps are being requested
*/
initialize: function(name, url, params, options) {
-
+
OpenLayers.Layer.Grid.prototype.initialize.apply(this, arguments);
-
- // unless explicitly set in options, if the layer is transparent,
+
+ // unless explicitly set in options, if the layer is transparent,
// it will be an overlay
if (options == null || options.isBaseLayer == null) {
- this.isBaseLayer = ((this.transparent != "true") &&
+ this.isBaseLayer = ((this.transparent != "true") &&
(this.transparent != true));
}
if (options && options.useOverlay!=null) {
this.useOverlay = options.useOverlay;
}
-
+
//initialize for untiled layers
if (this.singleTile) {
if (this.useOverlay) {
@@ -29956,7 +31497,7 @@
this.params,
this.SINGLE_TILE_PARAMS
);
- }
+ }
} else {
//initialize for tiled layers
if (this.useHttpTile) {
@@ -29970,7 +31511,7 @@
this.TILE_PARAMS
);
}
- this.setTileSize(this.defaultSize);
+ this.setTileSize(this.defaultSize);
}
},
@@ -29986,7 +31527,7 @@
obj = new OpenLayers.Layer.MapGuide(this.name,
this.url,
this.params,
- this.options);
+ this.getOptions());
}
//get all additions from superclasses
obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);
@@ -29996,17 +31537,17 @@
/**
* Method: addTile
- * Creates a tile, initializes it, and adds it to the layer div.
+ * Creates a tile, initializes it, and adds it to the layer div.
*
* Parameters:
* bounds - {<OpenLayers.Bounds>}
* position - {<OpenLayers.Pixel>}
- *
+ *
* Returns:
* {<OpenLayers.Tile.Image>} The added OpenLayers.Tile.Image
*/
addTile:function(bounds,position) {
- return new OpenLayers.Tile.Image(this, position, bounds,
+ return new OpenLayers.Tile.Image(this, position, bounds,
null, this.tileSize);
},
@@ -30015,18 +31556,18 @@
* Return a query string for this layer
*
* Parameters:
- * bounds - {<OpenLayers.Bounds>} A bounds representing the bbox
+ * bounds - {<OpenLayers.Bounds>} A bounds representing the bbox
* for the request
*
* Returns:
- * {String} A string with the layer's url and parameters and also
- * the passed-in bounds and appropriate tile size specified
+ * {String} A string with the layer's url and parameters and also
+ * the passed-in bounds and appropriate tile size specified
* as parameters.
*/
getURL: function (bounds) {
var url;
var center = bounds.getCenterLonLat();
- var mapSize = this.map.getCurrentSize();
+ var mapSize = this.map.getSize();
if (this.singleTile) {
//set up the call for GETMAPIMAGE or GETDYNAMICMAPOVERLAY with
@@ -30039,7 +31580,7 @@
setviewcentery: center.lat,
setviewscale: this.map.getScale()
};
-
+
if (this.useOverlay && !this.useAsyncOverlay) {
//first we need to call GETVISIBLEMAPEXTENT to set the extent
var getVisParams = {};
@@ -30050,7 +31591,7 @@
getVisParams.mapName = this.params.mapName;
getVisParams.format = 'text/xml';
url = this.getFullRequestString( getVisParams );
-
+
OpenLayers.Request.GET({url: url, async: false});
}
//construct the full URL
@@ -30065,13 +31606,13 @@
rowidx = Math.round(rowidx/this.tileSize.h);
if (this.useHttpTile){
- url = this.getImageFilePath(
+ url = this.getImageFilePath(
{
tilecol: colidx,
tilerow: rowidx,
scaleindex: this.resolutions.length - this.map.zoom - 1
});
-
+
} else {
url = this.getFullRequestString(
{
@@ -30086,7 +31627,7 @@
/**
* Method: getFullRequestString
- * getFullRequestString on MapGuide layers is special, because we
+ * getFullRequestString on MapGuide layers is special, because we
* do a regular expression replace on ',' in parameters to '+'.
* This is why it is subclassed here.
*
@@ -30099,30 +31640,30 @@
getFullRequestString:function(newParams, altUrl) {
// use layer's url unless altUrl passed in
var url = (altUrl == null) ? this.url : altUrl;
-
- // if url is not a string, it should be an array of strings,
+
+ // if url is not a string, it should be an array of strings,
// in which case we will randomly select one of them in order
// to evenly distribute requests to different urls.
if (typeof url == "object") {
url = url[Math.floor(Math.random()*url.length)];
- }
+ }
// requestString always starts with url
- var requestString = url;
+ var requestString = url;
- // create a new params hashtable with all the layer params and the
+ // create a new params hashtable with all the layer params and the
// new params together. then convert to string
var allParams = OpenLayers.Util.extend({}, this.params);
allParams = OpenLayers.Util.extend(allParams, newParams);
// ignore parameters that are already in the url search string
var urlParams = OpenLayers.Util.upperCaseObject(
- OpenLayers.Util.getArgs(url));
+ OpenLayers.Util.getParameters(url));
for(var key in allParams) {
if(key.toUpperCase() in urlParams) {
delete allParams[key];
}
}
var paramsString = OpenLayers.Util.getParameterString(allParams);
-
+
/* MapGuide needs '+' seperating things like bounds/height/width.
Since typically this is URL encoded, we use a slight hack: we
depend on the list-like functionality of getParameterString to
@@ -30130,7 +31671,7 @@
encoded) then do a regular expression replace on the , characters
to '+' */
paramsString = paramsString.replace(/,/g, "+");
-
+
if (paramsString != "") {
var lastServerChar = url.charAt(url.length - 1);
if ((lastServerChar == "&") || (lastServerChar == "?")) {
@@ -30148,9 +31689,9 @@
return requestString;
},
- /**
+ /**
* Method: getImageFilePath
- * special handler to request mapguide tiles from an http exposed tilecache
+ * special handler to request mapguide tiles from an http exposed tilecache
*
* Parameters:
* altUrl - {String} Alternative base URL to use.
@@ -30161,58 +31702,58 @@
getImageFilePath:function(newParams, altUrl) {
// use layer's url unless altUrl passed in
var url = (altUrl == null) ? this.url : altUrl;
-
- // if url is not a string, it should be an array of strings,
+
+ // if url is not a string, it should be an array of strings,
// in which case we will randomly select one of them in order
// to evenly distribute requests to different urls.
if (typeof url == "object") {
url = url[Math.floor(Math.random()*url.length)];
- }
+ }
// requestString always starts with url
- var requestString = url;
+ var requestString = url;
var tileRowGroup = "";
var tileColGroup = "";
-
+
if (newParams.tilerow < 0) {
tileRowGroup = '-';
}
-
+
if (newParams.tilerow == 0 ) {
tileRowGroup += '0';
} else {
tileRowGroup += Math.floor(Math.abs(newParams.tilerow/this.params.tileRowsPerFolder)) * this.params.tileRowsPerFolder;
}
-
+
if (newParams.tilecol < 0) {
tileColGroup = '-';
}
-
+
if (newParams.tilecol == 0) {
tileColGroup += '0';
} else {
tileColGroup += Math.floor(Math.abs(newParams.tilecol/this.params.tileColumnsPerFolder)) * this.params.tileColumnsPerFolder;
- }
-
+ }
+
var tilePath = '/S' + Math.floor(newParams.scaleindex)
+ '/' + this.params.basemaplayergroupname
+ '/R' + tileRowGroup
+ '/C' + tileColGroup
- + '/' + (newParams.tilerow % this.params.tileRowsPerFolder)
- + '_' + (newParams.tilecol % this.params.tileColumnsPerFolder)
+ + '/' + (newParams.tilerow % this.params.tileRowsPerFolder)
+ + '_' + (newParams.tilecol % this.params.tileColumnsPerFolder)
+ '.' + this.params.format;
-
+
if (this.params.querystring) {
tilePath += "?" + this.params.querystring;
}
-
+
requestString += tilePath;
return requestString;
},
-
- /**
+
+ /**
* Method: calculateGridLayout
- * Generate parameters for the grid layout. This
+ * Generate parameters for the grid layout. This
*
* Parameters:
* bounds - {<OpenLayers.Bound>}
@@ -30226,34 +31767,35 @@
calculateGridLayout: function(bounds, extent, resolution) {
var tilelon = resolution * this.tileSize.w;
var tilelat = resolution * this.tileSize.h;
-
+
var offsetlon = bounds.left - extent.left;
var tilecol = Math.floor(offsetlon/tilelon) - this.buffer;
var tilecolremain = offsetlon/tilelon - tilecol;
var tileoffsetx = -tilecolremain * this.tileSize.w;
var tileoffsetlon = extent.left + tilecol * tilelon;
-
- var offsetlat = extent.top - bounds.top + tilelat;
+
+ var offsetlat = extent.top - bounds.top + tilelat;
var tilerow = Math.floor(offsetlat/tilelat) - this.buffer;
var tilerowremain = tilerow - offsetlat/tilelat;
var tileoffsety = tilerowremain * this.tileSize.h;
var tileoffsetlat = extent.top - tilelat*tilerow;
-
- return {
+
+ return {
tilelon: tilelon, tilelat: tilelat,
tileoffsetlon: tileoffsetlon, tileoffsetlat: tileoffsetlat,
tileoffsetx: tileoffsetx, tileoffsety: tileoffsety
};
},
-
+
CLASS_NAME: "OpenLayers.Layer.MapGuide"
});
/* ======================================================================
OpenLayers/Layer/MapServer.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -30272,7 +31814,7 @@
/**
* Constant: DEFAULT_PARAMS
- * {Object} Hashtable of default parameter key/value pairs
+ * {Object} Hashtable of default parameter key/value pairs
*/
DEFAULT_PARAMS: {
mode: "map",
@@ -30300,10 +31842,10 @@
this.params, this.DEFAULT_PARAMS
);
- // unless explicitly set in options, if the layer is transparent,
+ // unless explicitly set in options, if the layer is transparent,
// it will be an overlay
if (options == null || options.isBaseLayer == null) {
- this.isBaseLayer = ((this.params.transparent != "true") &&
+ this.isBaseLayer = ((this.params.transparent != "true") &&
(this.params.transparent != true));
}
},
@@ -30320,7 +31862,7 @@
obj = new OpenLayers.Layer.MapServer(this.name,
this.url,
this.params,
- this.options);
+ this.getOptions());
}
//get all additions from superclasses
obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);
@@ -30332,41 +31874,41 @@
/**
* Method: addTile
- * Creates a tile, initializes it, and adds it to the layer div.
+ * Creates a tile, initializes it, and adds it to the layer div.
*
* Parameters:
* bounds - {<OpenLayers.Bounds>}
* position - {<OpenLayers.Pixel>}
- *
+ *
* Returns:
* {<OpenLayers.Tile.Image>} The added OpenLayers.Tile.Image
*/
addTile:function(bounds,position) {
- return new OpenLayers.Tile.Image(this, position, bounds,
+ return new OpenLayers.Tile.Image(this, position, bounds,
null, this.tileSize);
},
-
+
/**
* Method: getURL
* Return a query string for this layer
*
* Parameters:
- * bounds - {<OpenLayers.Bounds>} A bounds representing the bbox
+ * bounds - {<OpenLayers.Bounds>} A bounds representing the bbox
* for the request
*
* Returns:
- * {String} A string with the layer's url and parameters and also
- * the passed-in bounds and appropriate tile size specified
+ * {String} A string with the layer's url and parameters and also
+ * the passed-in bounds and appropriate tile size specified
* as parameters.
*/
getURL: function (bounds) {
bounds = this.adjustBounds(bounds);
- // Make a list, so that getFullRequestString uses literal ","
+ // Make a list, so that getFullRequestString uses literal ","
var extent = [bounds.left, bounds. bottom, bounds.right, bounds.top];
- var imageSize = this.getImageSize();
-
- // make lists, so that literal ','s are used
+ var imageSize = this.getImageSize();
+
+ // make lists, so that literal ','s are used
var url = this.getFullRequestString(
{mapext: extent,
imgext: extent,
@@ -30375,40 +31917,40 @@
imgy: imageSize.h / 2,
imgxy: [imageSize.w, imageSize.h]
});
-
+
return url;
},
-
- /**
+
+ /**
* Method: getFullRequestString
- * combine the layer's url with its params and these newParams.
- *
+ * combine the layer's url with its params and these newParams.
+ *
* Parameter:
- * newParams - {Object} New parameters that should be added to the
+ * newParams - {Object} New parameters that should be added to the
* request string.
- * altUrl - {String} (optional) Replace the URL in the full request
+ * altUrl - {String} (optional) Replace the URL in the full request
* string with the provided URL.
- *
- * Returns:
+ *
+ * Returns:
* {String} A string with the layer's url and parameters embedded in it.
*/
getFullRequestString:function(newParams, altUrl) {
// use layer's url unless altUrl passed in
var url = (altUrl == null) ? this.url : altUrl;
-
- // create a new params hashtable with all the layer params and the
+
+ // create a new params hashtable with all the layer params and the
// new params together. then convert to string
var allParams = OpenLayers.Util.extend({}, this.params);
allParams = OpenLayers.Util.extend(allParams, newParams);
var paramsString = OpenLayers.Util.getParameterString(allParams);
-
- // if url is not a string, it should be an array of strings,
- // in which case we will deterministically select one of them in
+
+ // if url is not a string, it should be an array of strings,
+ // in which case we will deterministically select one of them in
// order to evenly distribute requests to different urls.
if (url instanceof Array) {
url = this.selectUrl(paramsString, url);
- }
-
+ }
+
// ignore parameters that are already in the url search string
var urlParams = OpenLayers.Util.upperCaseObject(
OpenLayers.Util.getParameters(url));
@@ -30418,9 +31960,9 @@
}
}
paramsString = OpenLayers.Util.getParameterString(allParams);
-
+
// requestString always starts with url
- var requestString = url;
+ var requestString = url;
// MapServer needs '+' seperating things like bounds/height/width.
// Since typically this is URL encoded, we use a slight hack: we
@@ -30430,7 +31972,7 @@
// to '+'
//
paramsString = paramsString.replace(/,/g, "+");
-
+
if (paramsString != "") {
var lastServerChar = url.charAt(url.length - 1);
if ((lastServerChar == "&") || (lastServerChar == "?")) {
@@ -30454,8 +31996,9 @@
OpenLayers/Layer/WMS.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
@@ -30469,7 +32012,7 @@
* Instances of OpenLayers.Layer.WMS are used to display data from OGC Web
* Mapping Services. Create a new WMS layer with the <OpenLayers.Layer.WMS>
* constructor.
- *
+ *
* Inherits from:
* - <OpenLayers.Layer.Grid>
*/
@@ -30477,7 +32020,7 @@
/**
* Constant: DEFAULT_PARAMS
- * {Object} Hashtable of default parameter key/value pairs
+ * {Object} Hashtable of default parameter key/value pairs
*/
DEFAULT_PARAMS: { service: "WMS",
version: "1.1.1",
@@ -30486,40 +32029,48 @@
exceptions: "application/vnd.ogc.se_inimage",
format: "image/jpeg"
},
-
+
/**
* Property: reproject
* *Deprecated*. See http://trac.openlayers.org/wiki/SphericalMercator
- * for information on the replacement for this functionality.
+ * for information on the replacement for this functionality.
* {Boolean} Try to reproject this layer if its coordinate reference system
- * is different than that of the base layer. Default is true.
- * Set this in the layer options. Should be set to false in
+ * is different than that of the base layer. Default is true.
+ * Set this in the layer options. Should be set to false in
* most cases.
*/
reproject: false,
-
+
/**
* APIProperty: isBaseLayer
* {Boolean} Default is true for WMS layer
*/
isBaseLayer: true,
-
+
/**
* APIProperty: encodeBBOX
- * {Boolean} Should the BBOX commas be encoded? The WMS spec says 'no',
+ * {Boolean} Should the BBOX commas be encoded? The WMS spec says 'no',
* but some services want it that way. Default false.
*/
encodeBBOX: false,
-
+
+ /**
+ * APIProperty: noMagic
+ * {Boolean} If true, the image format will not be automagicaly switched
+ * from image/jpeg to image/png or image/gif when using
+ * TRANSPARENT=TRUE. Also isBaseLayer will not changed by the
+ * constructor. Default false.
+ */
+ noMagic: false,
+
/**
- * APIProperty: noMagic
- * {Boolean} If true, the image format will not be automagicaly switched
- * from image/jpeg to image/png or image/gif when using
- * TRANSPARENT=TRUE. Also isBaseLayer will not changed by the
- * constructor. Default false.
+ * Property: yx
+ * {Object} Keys in this object are EPSG codes for which the axis order
+ * is to be reversed (yx instead of xy, LatLon instead of LonLat), with
+ * true as value. This is only relevant for WMS versions >= 1.3.0.
*/
- noMagic: false,
-
+ yx: {'EPSG:4326': true},
+
/**
* Constructor: OpenLayers.Layer.WMS
* Create a new WMS layer object
@@ -30527,7 +32078,7 @@
* Example:
* (code)
* var wms = new OpenLayers.Layer.WMS("NASA Global Mosaic",
- * "http://wms.jpl.nasa.gov/wms.cgi",
+ * "http://wms.jpl.nasa.gov/wms.cgi",
* {layers: "modis,global_mosaic"});
* (end)
*
@@ -30543,24 +32094,27 @@
var newArguments = [];
//uppercase params
params = OpenLayers.Util.upperCaseObject(params);
+ if (parseFloat(params.VERSION) >= 1.3 && !params.EXCEPTIONS) {
+ params.EXCEPTIONS = "INIMAGE";
+ }
newArguments.push(name, url, params, options);
OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);
OpenLayers.Util.applyDefaults(
- this.params,
+ this.params,
OpenLayers.Util.upperCaseObject(this.DEFAULT_PARAMS)
);
- //layer is transparent
- if (!this.noMagic && this.params.TRANSPARENT &&
+ //layer is transparent
+ if (!this.noMagic && this.params.TRANSPARENT &&
this.params.TRANSPARENT.toString().toLowerCase() == "true") {
-
+
// unless explicitly set in options, make layer an overlay
if ( (options == null) || (!options.isBaseLayer) ) {
this.isBaseLayer = false;
- }
-
- // jpegs can never be transparent, so intelligently switch the
+ }
+
+ // jpegs can never be transparent, so intelligently switch the
// format, depending on teh browser's capabilities
if (this.params.FORMAT == "image/jpeg") {
this.params.FORMAT = OpenLayers.Util.alphaHack() ? "image/gif"
@@ -30568,18 +32122,18 @@
}
}
- },
+ },
/**
* Method: destroy
* Destroy this layer
*/
destroy: function() {
- // for now, nothing special to do here.
- OpenLayers.Layer.Grid.prototype.destroy.apply(this, arguments);
+ // for now, nothing special to do here.
+ OpenLayers.Layer.Grid.prototype.destroy.apply(this, arguments);
},
-
+
/**
* Method: clone
* Create a clone of this layer
@@ -30588,12 +32142,12 @@
* {<OpenLayers.Layer.WMS>} An exact clone of this layer
*/
clone: function (obj) {
-
+
if (obj == null) {
obj = new OpenLayers.Layer.WMS(this.name,
this.url,
this.params,
- this.options);
+ this.getOptions());
}
//get all additions from superclasses
@@ -30602,8 +32156,21 @@
// copy/set any non-init, non-simple values here
return obj;
+ },
+
+ /**
+ * APIMethod: reverseAxisOrder
+ * Returns true if the axis order is reversed for the WMS version and
+ * projection of the layer.
+ *
+ * Returns:
+ * {Boolean} true if the axis order is reversed, false otherwise.
+ */
+ reverseAxisOrder: function() {
+ return (parseFloat(this.params.VERSION) >= 1.3 &&
+ !!this.yx[this.map.getProjectionObject().getCode()]);
},
-
+
/**
* Method: getURL
* Return a GetMap query string for this layer
@@ -30614,35 +32181,38 @@
*
* Returns:
* {String} A string with the layer's url and parameters and also the
- * passed-in bounds and appropriate tile size specified as
+ * passed-in bounds and appropriate tile size specified as
* parameters.
*/
getURL: function (bounds) {
bounds = this.adjustBounds(bounds);
-
+
var imageSize = this.getImageSize();
- var newParams = {
- 'BBOX': this.encodeBBOX ? bounds.toBBOX() : bounds.toArray(),
- 'WIDTH': imageSize.w,
- 'HEIGHT': imageSize.h
- };
+ var newParams = {};
+ // WMS 1.3 introduced axis order
+ var reverseAxisOrder = this.reverseAxisOrder();
+ newParams.BBOX = this.encodeBBOX ?
+ bounds.toBBOX(null, reverseAxisOrder) :
+ bounds.toArray(reverseAxisOrder);
+ newParams.WIDTH = imageSize.w;
+ newParams.HEIGHT = imageSize.h;
var requestString = this.getFullRequestString(newParams);
return requestString;
},
/**
* Method: addTile
- * addTile creates a tile, initializes it, and adds it to the layer div.
+ * addTile creates a tile, initializes it, and adds it to the layer div.
*
* Parameters:
* bounds - {<OpenLayers.Bounds>}
* position - {<OpenLayers.Pixel>}
- *
+ *
* Returns:
* {<OpenLayers.Tile.Image>} The added OpenLayers.Tile.Image
*/
addTile:function(bounds,position) {
- return new OpenLayers.Tile.Image(this, position, bounds,
+ return new OpenLayers.Tile.Image(this, position, bounds,
null, this.tileSize);
},
@@ -30650,38 +32220,43 @@
* APIMethod: mergeNewParams
* Catch changeParams and uppercase the new params to be merged in
* before calling changeParams on the super class.
- *
+ *
* Once params have been changed, the tiles will be reloaded with
* the new parameters.
- *
+ *
* Parameters:
* newParams - {Object} Hashtable of new params to use
*/
mergeNewParams:function(newParams) {
var upperParams = OpenLayers.Util.upperCaseObject(newParams);
var newArguments = [upperParams];
- return OpenLayers.Layer.Grid.prototype.mergeNewParams.apply(this,
+ return OpenLayers.Layer.Grid.prototype.mergeNewParams.apply(this,
newArguments);
},
- /**
+ /**
* APIMethod: getFullRequestString
- * Combine the layer's url with its params and these newParams.
- *
+ * Combine the layer's url with its params and these newParams.
+ *
* Add the SRS parameter from projection -- this is probably
- * more eloquently done via a setProjection() method, but this
+ * more eloquently done via a setProjection() method, but this
* works for now and always.
*
* Parameters:
* newParams - {Object}
* altUrl - {String} Use this as the url instead of the layer's url
- *
+ *
* Returns:
- * {String}
+ * {String}
*/
getFullRequestString:function(newParams, altUrl) {
var projectionCode = this.map.getProjection();
- this.params.SRS = (projectionCode == "none") ? null : projectionCode;
+ var value = (projectionCode == "none") ? null : projectionCode
+ if (parseFloat(this.params.VERSION) >= 1.3) {
+ this.params.CRS = value;
+ } else {
+ this.params.SRS = value;
+ }
return OpenLayers.Layer.Grid.prototype.getFullRequestString.apply(
this, arguments);
@@ -30690,17 +32265,223 @@
CLASS_NAME: "OpenLayers.Layer.WMS"
});
/* ======================================================================
+ OpenLayers/Layer/XYZ.js
+ ====================================================================== */
+
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+/**
+ * @requires OpenLayers/Layer/Grid.js
+ * @requires OpenLayers/Tile/Image.js
+ */
+
+/**
+ * Class: OpenLayers.Layer.XYZ
+ * The XYZ class is designed to make it easier for people who have tiles
+ * arranged by a standard XYZ grid.
+ *
+ * Inherits from:
+ * - <OpenLayers.Layer.Grid>
+ */
+OpenLayers.Layer.XYZ = OpenLayers.Class(OpenLayers.Layer.Grid, {
+
+ /**
+ * APIProperty: isBaseLayer
+ * Default is true, as this is designed to be a base tile source.
+ */
+ isBaseLayer: true,
+
+ /**
+ * APIProperty: sphericalMecator
+ * Whether the tile extents should be set to the defaults for
+ * spherical mercator. Useful for things like OpenStreetMap.
+ * Default is false, except for the OSM subclass.
+ */
+ sphericalMercator: false,
+
+ /**
+ * APIProperty: zoomOffset
+ * {Number} If your cache has more zoom levels than you want to provide
+ * access to with this layer, supply a zoomOffset. This zoom offset
+ * is added to the current map zoom level to determine the level
+ * for a requested tile. For example, if you supply a zoomOffset
+ * of 3, when the map is at the zoom 0, tiles will be requested from
+ * level 3 of your cache. Default is 0 (assumes cache level and map
+ * zoom are equivalent).
+ */
+ zoomOffset: 0,
+
+ /**
+ * Constructor: OpenLayers.Layer.XYZ
+ *
+ * Parameters:
+ * name - {String}
+ * url - {String}
+ * options - {Object} Hashtable of extra options to tag onto the layer
+ */
+ initialize: function(name, url, options) {
+ if (options && options.sphericalMercator || this.sphericalMercator) {
+ options = OpenLayers.Util.extend({
+ maxExtent: new OpenLayers.Bounds(
+ -128 * 156543.0339,
+ -128 * 156543.0339,
+ 128 * 156543.0339,
+ 128 * 156543.0339
+ ),
+ maxResolution: 156543.0339,
+ numZoomLevels: 19,
+ units: "m",
+ projection: "EPSG:900913"
+ }, options);
+ }
+ url = url || this.url;
+ name = name || this.name;
+ var newArguments = [name, url, {}, options];
+ OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);
+ },
+
+ /**
+ * APIMethod: clone
+ * Create a clone of this layer
+ *
+ * Parameters:
+ * obj - {Object} Is this ever used?
+ *
+ * Returns:
+ * {<OpenLayers.Layer.XYZ>} An exact clone of this OpenLayers.Layer.XYZ
+ */
+ clone: function (obj) {
+
+ if (obj == null) {
+ obj = new OpenLayers.Layer.XYZ(this.name,
+ this.url,
+ this.getOptions());
+ }
+
+ //get all additions from superclasses
+ obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);
+
+ return obj;
+ },
+
+ /**
+ * Method: getUrl
+ *
+ * Parameters:
+ * bounds - {<OpenLayers.Bounds>}
+ *
+ * Returns:
+ * {String} A string with the layer's url and parameters and also the
+ * passed-in bounds and appropriate tile size specified as
+ * parameters
+ */
+ getURL: function (bounds) {
+ var res = this.map.getResolution();
+ var x = Math.round((bounds.left - this.maxExtent.left)
+ / (res * this.tileSize.w));
+ var y = Math.round((this.maxExtent.top - bounds.top)
+ / (res * this.tileSize.h));
+ var z = this.map.getZoom() + this.zoomOffset;
+
+ var url = this.url;
+ var s = '' + x + y + z;
+ if (url instanceof Array)
+ {
+ url = this.selectUrl(s, url);
+ }
+
+ var path = OpenLayers.String.format(url, {'x': x, 'y': y, 'z': z});
+
+ return path;
+ },
+
+ /**
+ * Method: addTile
+ * addTile creates a tile, initializes it, and adds it to the layer div.
+ *
+ * Parameters:
+ * bounds - {<OpenLayers.Bounds>}
+ * position - {<OpenLayers.Pixel>}
+ *
+ * Returns:
+ * {<OpenLayers.Tile.Image>} The added OpenLayers.Tile.Image
+ */
+ addTile:function(bounds,position) {
+ return new OpenLayers.Tile.Image(this, position, bounds,
+ null, this.tileSize);
+ },
+
+ /* APIMethod: setMap
+ * When the layer is added to a map, then we can fetch our origin
+ * (if we don't have one.)
+ *
+ * Parameters:
+ * map - {<OpenLayers.Map>}
+ */
+ setMap: function(map) {
+ OpenLayers.Layer.Grid.prototype.setMap.apply(this, arguments);
+ if (!this.tileOrigin) {
+ this.tileOrigin = new OpenLayers.LonLat(this.maxExtent.left,
+ this.maxExtent.bottom);
+ }
+ },
+
+ CLASS_NAME: "OpenLayers.Layer.XYZ"
+});
+
+
+/**
+ * Class: OpenLayers.Layer.OSM
+ * A class to access OpenStreetMap tiles. By default, uses the OpenStreetMap
+ * hosted tile.openstreetmap.org 'Mapnik' tileset. If you wish to use
+ * tiles at home / osmarender layer instead, you can pass a layer like:
+ *
+ * (code)
+ * new OpenLayers.Layer.OSM("t at h",
+ * "http://tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png");
+ * (end)
+ *
+ * This layer defaults to Spherical Mercator.
+ *
+ * Inherits from:
+ * - <OpenLayers.Layer.XYZ>
+ */
+OpenLayers.Layer.OSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
+ name: "OpenStreetMap",
+ attribution: "Data CC-By-SA by <a href='http://openstreetmap.org/'>OpenStreetMap</a>",
+ sphericalMercator: true,
+ url: 'http://tile.openstreetmap.org/${z}/${x}/${y}.png',
+ clone: function(obj) {
+ if (obj == null) {
+ obj = new OpenLayers.Layer.OSM(
+ this.name, this.url, this.getOptions());
+ }
+ obj = OpenLayers.Layer.XYZ.prototype.clone.apply(this, [obj]);
+ return obj;
+ },
+ CLASS_NAME: "OpenLayers.Layer.OSM"
+});
+/* ======================================================================
OpenLayers/Rule.js
====================================================================== */
-/* Copyright (c) 2006 MetaCarta, Inc., published under a modified BSD license.
- * See http://svn.openlayers.org/trunk/openlayers/repository-license.txt
- * for the full text of the license. */
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
/**
* @requires OpenLayers/Util.js
* @requires OpenLayers/Style.js
+ * @requires OpenLayers/Symbolizer/Point.js
+ * @requires OpenLayers/Symbolizer/Line.js
+ * @requires OpenLayers/Symbolizer/Polygon.js
+ * @requires OpenLayers/Symbolizer/Text.js
+ * @requires OpenLayers/Symbolizer/Raster.js
*/
/**
@@ -30708,25 +32489,25 @@
* This class represents an SLD Rule, as being used for rule-based SLD styling.
*/
OpenLayers.Rule = OpenLayers.Class({
-
+
/**
* Property: id
* {String} A unique id for this session.
*/
id: null,
-
+
/**
* APIProperty: name
* {String} name of this rule
*/
- name: 'default',
-
+ name: null,
+
/**
* Property: title
* {String} Title of this rule (set if included in SLD)
*/
title: null,
-
+
/**
* Property: description
* {String} Description of this rule (set if abstract is included in SLD)
@@ -30740,7 +32521,7 @@
* be used.
*/
context: null,
-
+
/**
* Property: filter
* {<OpenLayers.Filter>} Optional filter for the rule.
@@ -30750,13 +32531,13 @@
/**
* Property: elseFilter
* {Boolean} Determines whether this rule is only to be applied only if
- * no other rules match (ElseFilter according to the SLD specification).
+ * no other rules match (ElseFilter according to the SLD specification).
* Default is false. For instances of OpenLayers.Rule, if elseFilter is
- * false, the rule will always apply. For subclasses, the else property is
+ * false, the rule will always apply. For subclasses, the else property is
* ignored.
*/
elseFilter: false,
-
+
/**
* Property: symbolizer
* {Object} Symbolizer or hash of symbolizers for this rule. If hash of
@@ -30767,8 +32548,19 @@
* SLD.
*/
symbolizer: null,
-
+
/**
+ * Property: symbolizers
+ * {Array} Collection of symbolizers associated with this rule. If
+ * provided at construction, the symbolizers array has precedence
+ * over the deprecated symbolizer property. Note that multiple
+ * symbolizers are not currently supported by the vector renderers.
+ * Rules with multiple symbolizers are currently only useful for
+ * maintaining elements in an SLD document.
+ */
+ symbolizers: null,
+
+ /**
* APIProperty: minScaleDenominator
* {Number} or {String} minimum scale at which to draw the feature.
* In the case of a String, this can be a combination of text and
@@ -30783,25 +32575,28 @@
* propertyNames in the form "literal ${propertyName}"
*/
maxScaleDenominator: null,
-
- /**
+
+ /**
* Constructor: OpenLayers.Rule
* Creates a Rule.
*
* Parameters:
* options - {Object} An optional object with properties to set on the
* rule
- *
+ *
* Returns:
* {<OpenLayers.Rule>}
*/
initialize: function(options) {
this.symbolizer = {};
OpenLayers.Util.extend(this, options);
+ if (this.symbolizers) {
+ delete this.symbolizer;
+ }
this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
},
- /**
+ /**
* APIMethod: destroy
* nullify references to prevent circular references and memory leaks
*/
@@ -30810,15 +32605,16 @@
this.symbolizer[i] = null;
}
this.symbolizer = null;
+ delete this.symbolizers;
},
-
+
/**
* APIMethod: evaluate
* evaluates this rule for a specific feature
- *
+ *
* Parameters:
* feature - {<OpenLayers.Feature>} feature to apply the rule to.
- *
+ *
* Returns:
* {Boolean} true if the rule applies, false if it does not.
* This rule is the default rule and always returns true.
@@ -30830,7 +32626,7 @@
if (this.minScaleDenominator || this.maxScaleDenominator) {
var scale = feature.layer.map.getScale();
}
-
+
// check if within minScale/maxScale bounds
if (this.minScaleDenominator) {
applies = scale >= OpenLayers.Style.createLiteral(
@@ -30840,7 +32636,7 @@
applies = scale < OpenLayers.Style.createLiteral(
this.maxScaleDenominator, context);
}
-
+
// check if optional filter applies
if(applies && this.filter) {
// feature id filters get the feature, others get the context
@@ -30853,11 +32649,11 @@
return applies;
},
-
+
/**
* Method: getContext
* Gets the context for evaluating this rule
- *
+ *
* Paramters:
* feature - {<OpenLayers.Feature>} feature to take the context from if
* none is specified.
@@ -30872,26 +32668,36 @@
}
return context;
},
-
+
/**
* APIMethod: clone
* Clones this rule.
- *
+ *
* Returns:
* {<OpenLayers.Rule>} Clone of this rule.
*/
clone: function() {
var options = OpenLayers.Util.extend({}, this);
- // clone symbolizer
- options.symbolizer = {};
- for(var key in this.symbolizer) {
- value = this.symbolizer[key];
- type = typeof value;
- if(type === "object") {
- options.symbolizer[key] = OpenLayers.Util.extend({}, value);
- } else if(type === "string") {
- options.symbolizer[key] = value;
+ if (this.symbolizers) {
+ // clone symbolizers
+ var len = this.symbolizers.length;
+ options.symbolizers = new Array(len);
+ for (var i=0; i<len; ++i) {
+ options.symbolizers[i] = this.symbolizers[i].clone();
}
+ } else {
+ // clone symbolizer
+ options.symbolizer = {};
+ var value, type;
+ for(var key in this.symbolizer) {
+ value = this.symbolizer[key];
+ type = typeof value;
+ if(type === "object") {
+ options.symbolizer[key] = OpenLayers.Util.extend({}, value);
+ } else if(type === "string") {
+ options.symbolizer[key] = value;
+ }
+ }
}
// clone filter
options.filter = this.filter && this.filter.clone();
@@ -30899,34 +32705,35 @@
options.context = this.context && OpenLayers.Util.extend({}, this.context);
return new OpenLayers.Rule(options);
},
-
+
CLASS_NAME: "OpenLayers.Rule"
});
/* ======================================================================
OpenLayers/StyleMap.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
* @requires OpenLayers/Style.js
* @requires OpenLayers/Feature/Vector.js
*/
-
+
/**
* Class: OpenLayers.StyleMap
*/
OpenLayers.StyleMap = OpenLayers.Class({
-
+
/**
* Property: styles
* Hash of {<OpenLayers.Style>}, keyed by names of well known
* rendering intents (e.g. "default", "temporary", "select", "delete").
*/
styles: null,
-
+
/**
* Property: extendDefault
* {Boolean} if true, every render intent will extend the symbolizers
@@ -30934,10 +32741,10 @@
* rendering intent will be treated as a completely independent style.
*/
extendDefault: true,
-
+
/**
* Constructor: OpenLayers.StyleMap
- *
+ *
* Parameters:
* style - {Object} Optional. Either a style hash, or a style object, or
* a hash of style objects (style hashes) keyed by rendering
@@ -30958,7 +32765,7 @@
"delete": new OpenLayers.Style(
OpenLayers.Feature.Vector.style["delete"])
};
-
+
// take whatever the user passed as style parameter and convert it
// into parts of stylemap.
if(style instanceof OpenLayers.Style) {
@@ -30997,11 +32804,11 @@
}
this.styles = null;
},
-
+
/**
* Method: createSymbolizer
* Creates the symbolizer for a feature for a render intent.
- *
+ *
* Parameters:
* feature - {<OpenLayers.Feature>} The feature to evaluate the rules
* of the intended style against.
@@ -31009,7 +32816,7 @@
* used to draw the feature. Well known intents are "default"
* (for just drawing the features), "select" (for selected
* features) and "temporary" (for drawing features).
- *
+ *
* Returns:
* {Object} symbolizer hash
*/
@@ -31028,20 +32835,20 @@
return OpenLayers.Util.extend(defaultSymbolizer,
this.styles[intent].createSymbolizer(feature));
},
-
+
/**
* Method: addUniqueValueRules
* Convenience method to create comparison rules for unique values of a
* property. The rules will be added to the style object for a specified
* rendering intent. This method is a shortcut for creating something like
* the "unique value legends" familiar from well known desktop GIS systems
- *
+ *
* Parameters:
* renderIntent - {String} rendering intent to add the rules to
* property - {String} values of feature attributes to create the
* rules for
* symbolizers - {Object} Hash of symbolizers, keyed by the desired
- * property values
+ * property values
* context - {Object} An optional object with properties that
* symbolizers' property values should be evaluated
* against. If no context is specified, feature.attributes
@@ -31066,11 +32873,529 @@
CLASS_NAME: "OpenLayers.StyleMap"
});
/* ======================================================================
+ OpenLayers/Filter/Comparison.js
+ ====================================================================== */
+
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+/**
+ * @requires OpenLayers/Filter.js
+ * @requires OpenLayers/Console.js
+ */
+
+/**
+ * Class: OpenLayers.Filter.Comparison
+ * This class represents a comparison filter.
+ *
+ * Inherits from
+ * - <OpenLayers.Filter>
+ */
+OpenLayers.Filter.Comparison = OpenLayers.Class(OpenLayers.Filter, {
+
+ /**
+ * APIProperty: type
+ * {String} type: type of the comparison. This is one of
+ * - OpenLayers.Filter.Comparison.EQUAL_TO = "==";
+ * - OpenLayers.Filter.Comparison.NOT_EQUAL_TO = "!=";
+ * - OpenLayers.Filter.Comparison.LESS_THAN = "<";
+ * - OpenLayers.Filter.Comparison.GREATER_THAN = ">";
+ * - OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO = "<=";
+ * - OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO = ">=";
+ * - OpenLayers.Filter.Comparison.BETWEEN = "..";
+ * - OpenLayers.Filter.Comparison.LIKE = "~";
+ */
+ type: null,
+
+ /**
+ * APIProperty: property
+ * {String}
+ * name of the context property to compare
+ */
+ property: null,
+
+ /**
+ * APIProperty: value
+ * {Number} or {String}
+ * comparison value for binary comparisons. In the case of a String, this
+ * can be a combination of text and propertyNames in the form
+ * "literal ${propertyName}"
+ */
+ value: null,
+
+ /**
+ * Property: matchCase
+ * {Boolean} Force case sensitive searches for EQUAL_TO and NOT_EQUAL_TO
+ * comparisons. The Filter Encoding 1.1 specification added a matchCase
+ * attribute to ogc:PropertyIsEqualTo and ogc:PropertyIsNotEqualTo
+ * elements. This property will be serialized with those elements only
+ * if using the v1.1.0 filter format. However, when evaluating filters
+ * here, the matchCase property will always be respected (for EQUAL_TO
+ * and NOT_EQUAL_TO). Default is true.
+ */
+ matchCase: true,
+
+ /**
+ * APIProperty: lowerBoundary
+ * {Number} or {String}
+ * lower boundary for between comparisons. In the case of a String, this
+ * can be a combination of text and propertyNames in the form
+ * "literal ${propertyName}"
+ */
+ lowerBoundary: null,
+
+ /**
+ * APIProperty: upperBoundary
+ * {Number} or {String}
+ * upper boundary for between comparisons. In the case of a String, this
+ * can be a combination of text and propertyNames in the form
+ * "literal ${propertyName}"
+ */
+ upperBoundary: null,
+
+ /**
+ * Constructor: OpenLayers.Filter.Comparison
+ * Creates a comparison rule.
+ *
+ * Parameters:
+ * options - {Object} An optional object with properties to set on the
+ * rule
+ *
+ * Returns:
+ * {<OpenLayers.Filter.Comparison>}
+ */
+ initialize: function(options) {
+ OpenLayers.Filter.prototype.initialize.apply(this, [options]);
+ },
+
+ /**
+ * APIMethod: evaluate
+ * Evaluates this filter in a specific context.
+ *
+ * Parameters:
+ * context - {Object} Context to use in evaluating the filter. If a vector
+ * feature is provided, the feature.attributes will be used as context.
+ *
+ * Returns:
+ * {Boolean} The filter applies.
+ */
+ evaluate: function(context) {
+ if (context instanceof OpenLayers.Feature.Vector) {
+ context = context.attributes;
+ }
+ var result = false;
+ var got = context[this.property];
+ switch(this.type) {
+ case OpenLayers.Filter.Comparison.EQUAL_TO:
+ var exp = this.value;
+ if(!this.matchCase &&
+ typeof got == "string" && typeof exp == "string") {
+ result = (got.toUpperCase() == exp.toUpperCase());
+ } else {
+ result = (got == exp);
+ }
+ break;
+ case OpenLayers.Filter.Comparison.NOT_EQUAL_TO:
+ var exp = this.value;
+ if(!this.matchCase &&
+ typeof got == "string" && typeof exp == "string") {
+ result = (got.toUpperCase() != exp.toUpperCase());
+ } else {
+ result = (got != exp);
+ }
+ break;
+ case OpenLayers.Filter.Comparison.LESS_THAN:
+ result = got < this.value;
+ break;
+ case OpenLayers.Filter.Comparison.GREATER_THAN:
+ result = got > this.value;
+ break;
+ case OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO:
+ result = got <= this.value;
+ break;
+ case OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO:
+ result = got >= this.value;
+ break;
+ case OpenLayers.Filter.Comparison.BETWEEN:
+ result = (got >= this.lowerBoundary) &&
+ (got <= this.upperBoundary);
+ break;
+ case OpenLayers.Filter.Comparison.LIKE:
+ var regexp = new RegExp(this.value, "gi");
+ result = regexp.test(got);
+ break;
+ }
+ return result;
+ },
+
+ /**
+ * APIMethod: value2regex
+ * Converts the value of this rule into a regular expression string,
+ * according to the wildcard characters specified. This method has to
+ * be called after instantiation of this class, if the value is not a
+ * regular expression already.
+ *
+ * Parameters:
+ * wildCard - {<Char>} wildcard character in the above value, default
+ * is "*"
+ * singleChar - {<Char>) single-character wildcard in the above value
+ * default is "."
+ * escape - {<Char>) escape character in the above value, default is
+ * "!"
+ *
+ * Returns:
+ * {String} regular expression string
+ */
+ value2regex: function(wildCard, singleChar, escapeChar) {
+ if (wildCard == ".") {
+ var msg = "'.' is an unsupported wildCard character for "+
+ "OpenLayers.Filter.Comparison";
+ OpenLayers.Console.error(msg);
+ return null;
+ }
+
+
+ // set UMN MapServer defaults for unspecified parameters
+ wildCard = wildCard ? wildCard : "*";
+ singleChar = singleChar ? singleChar : ".";
+ escapeChar = escapeChar ? escapeChar : "!";
+
+ this.value = this.value.replace(
+ new RegExp("\\"+escapeChar+"(.|$)", "g"), "\\$1");
+ this.value = this.value.replace(
+ new RegExp("\\"+singleChar, "g"), ".");
+ this.value = this.value.replace(
+ new RegExp("\\"+wildCard, "g"), ".*");
+ this.value = this.value.replace(
+ new RegExp("\\\\.\\*", "g"), "\\"+wildCard);
+ this.value = this.value.replace(
+ new RegExp("\\\\\\.", "g"), "\\"+singleChar);
+
+ return this.value;
+ },
+
+ /**
+ * Method: regex2value
+ * Convert the value of this rule from a regular expression string into an
+ * ogc literal string using a wildCard of *, a singleChar of ., and an
+ * escape of !. Leaves the <value> property unmodified.
+ *
+ * Returns:
+ * {String} A string value.
+ */
+ regex2value: function() {
+
+ var value = this.value;
+
+ // replace ! with !!
+ value = value.replace(/!/g, "!!");
+
+ // replace \. with !. (watching out for \\.)
+ value = value.replace(/(\\)?\\\./g, function($0, $1) {
+ return $1 ? $0 : "!.";
+ });
+
+ // replace \* with #* (watching out for \\*)
+ value = value.replace(/(\\)?\\\*/g, function($0, $1) {
+ return $1 ? $0 : "!*";
+ });
+
+ // replace \\ with \
+ value = value.replace(/\\\\/g, "\\");
+
+ // convert .* to * (the sequence #.* is not allowed)
+ value = value.replace(/\.\*/g, "*");
+
+ return value;
+ },
+
+ /**
+ * APIMethod: clone
+ * Clones this filter.
+ *
+ * Returns:
+ * {<OpenLayers.Filter.Comparison>} Clone of this filter.
+ */
+ clone: function() {
+ return OpenLayers.Util.extend(new OpenLayers.Filter.Comparison(), this);
+ },
+
+ CLASS_NAME: "OpenLayers.Filter.Comparison"
+});
+
+
+OpenLayers.Filter.Comparison.EQUAL_TO = "==";
+OpenLayers.Filter.Comparison.NOT_EQUAL_TO = "!=";
+OpenLayers.Filter.Comparison.LESS_THAN = "<";
+OpenLayers.Filter.Comparison.GREATER_THAN = ">";
+OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO = "<=";
+OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO = ">=";
+OpenLayers.Filter.Comparison.BETWEEN = "..";
+OpenLayers.Filter.Comparison.LIKE = "~";
+/* ======================================================================
+ OpenLayers/Filter/Logical.js
+ ====================================================================== */
+
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+
+/**
+ * @requires OpenLayers/Filter.js
+ */
+
+/**
+ * Class: OpenLayers.Filter.Logical
+ * This class represents ogc:And, ogc:Or and ogc:Not rules.
+ *
+ * Inherits from
+ * - <OpenLayers.Filter>
+ */
+OpenLayers.Filter.Logical = OpenLayers.Class(OpenLayers.Filter, {
+
+ /**
+ * APIProperty: filters
+ * {Array(<OpenLayers.Filter>)} Child filters for this filter.
+ */
+ filters: null,
+
+ /**
+ * APIProperty: type
+ * {String} type of logical operator. Available types are:
+ * - OpenLayers.Filter.Logical.AND = "&&";
+ * - OpenLayers.Filter.Logical.OR = "||";
+ * - OpenLayers.Filter.Logical.NOT = "!";
+ */
+ type: null,
+
+ /**
+ * Constructor: OpenLayers.Filter.Logical
+ * Creates a logical filter (And, Or, Not).
+ *
+ * Parameters:
+ * options - {Object} An optional object with properties to set on the
+ * filter.
+ *
+ * Returns:
+ * {<OpenLayers.Filter.Logical>}
+ */
+ initialize: function(options) {
+ this.filters = [];
+ OpenLayers.Filter.prototype.initialize.apply(this, [options]);
+ },
+
+ /**
+ * APIMethod: destroy
+ * Remove reference to child filters.
+ */
+ destroy: function() {
+ this.filters = null;
+ OpenLayers.Filter.prototype.destroy.apply(this);
+ },
+
+ /**
+ * APIMethod: evaluate
+ * Evaluates this filter in a specific context.
+ *
+ * Parameters:
+ * context - {Object} Context to use in evaluating the filter. A vector
+ * feature may also be provided to evaluate feature attributes in
+ * comparison filters or geometries in spatial filters.
+ *
+ * Returns:
+ * {Boolean} The filter applies.
+ */
+ evaluate: function(context) {
+ switch(this.type) {
+ case OpenLayers.Filter.Logical.AND:
+ for (var i=0, len=this.filters.length; i<len; i++) {
+ if (this.filters[i].evaluate(context) == false) {
+ return false;
+ }
+ }
+ return true;
+
+ case OpenLayers.Filter.Logical.OR:
+ for (var i=0, len=this.filters.length; i<len; i++) {
+ if (this.filters[i].evaluate(context) == true) {
+ return true;
+ }
+ }
+ return false;
+
+ case OpenLayers.Filter.Logical.NOT:
+ return (!this.filters[0].evaluate(context));
+ }
+ },
+
+ /**
+ * APIMethod: clone
+ * Clones this filter.
+ *
+ * Returns:
+ * {<OpenLayers.Filter.Logical>} Clone of this filter.
+ */
+ clone: function() {
+ var filters = [];
+ for(var i=0, len=this.filters.length; i<len; ++i) {
+ filters.push(this.filters[i].clone());
+ }
+ return new OpenLayers.Filter.Logical({
+ type: this.type,
+ filters: filters
+ });
+ },
+
+ CLASS_NAME: "OpenLayers.Filter.Logical"
+});
+
+
+OpenLayers.Filter.Logical.AND = "&&";
+OpenLayers.Filter.Logical.OR = "||";
+OpenLayers.Filter.Logical.NOT = "!";
+/* ======================================================================
+ OpenLayers/Filter/Spatial.js
+ ====================================================================== */
+
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+/**
+ * @requires OpenLayers/Filter.js
+ * @requires OpenLayers/Console.js
+ */
+
+/**
+ * Class: OpenLayers.Filter.Spatial
+ * This class represents a spatial filter.
+ * Currently implemented: BBOX, DWithin and Intersects
+ *
+ * Inherits from
+ * - <OpenLayers.Filter>
+ */
+OpenLayers.Filter.Spatial = OpenLayers.Class(OpenLayers.Filter, {
+
+ /**
+ * APIProperty: type
+ * {String} Type of spatial filter.
+ *
+ * The type should be one of:
+ * - OpenLayers.Filter.Spatial.BBOX
+ * - OpenLayers.Filter.Spatial.INTERSECTS
+ * - OpenLayers.Filter.Spatial.DWITHIN
+ * - OpenLayers.Filter.Spatial.WITHIN
+ * - OpenLayers.Filter.Spatial.CONTAINS
+ */
+ type: null,
+
+ /**
+ * APIProperty: property
+ * {String} Name of the context property to compare.
+ */
+ property: null,
+
+ /**
+ * APIProperty: value
+ * {<OpenLayers.Bounds> || <OpenLayers.Geometry>} The bounds or geometry
+ * to be used by the filter. Use bounds for BBOX filters and geometry
+ * for INTERSECTS or DWITHIN filters.
+ */
+ value: null,
+
+ /**
+ * APIProperty: distance
+ * {Number} The distance to use in a DWithin spatial filter.
+ */
+ distance: null,
+
+ /**
+ * APIProperty: distanceUnits
+ * {String} The units to use for the distance, e.g. 'm'.
+ */
+ distanceUnits: null,
+
+ /**
+ * Constructor: OpenLayers.Filter.Spatial
+ * Creates a spatial filter.
+ *
+ * Parameters:
+ * options - {Object} An optional object with properties to set on the
+ * filter.
+ *
+ * Returns:
+ * {<OpenLayers.Filter.Spatial>}
+ */
+ initialize: function(options) {
+ OpenLayers.Filter.prototype.initialize.apply(this, [options]);
+ },
+
+ /**
+ * Method: evaluate
+ * Evaluates this filter for a specific feature.
+ *
+ * Parameters:
+ * feature - {<OpenLayers.Feature.Vector>} feature to apply the filter to.
+ *
+ * Returns:
+ * {Boolean} The feature meets filter criteria.
+ */
+ evaluate: function(feature) {
+ var intersect = false;
+ switch(this.type) {
+ case OpenLayers.Filter.Spatial.BBOX:
+ case OpenLayers.Filter.Spatial.INTERSECTS:
+ if(feature.geometry) {
+ var geom = this.value;
+ if(this.value.CLASS_NAME == "OpenLayers.Bounds") {
+ geom = this.value.toGeometry();
+ }
+ if(feature.geometry.intersects(geom)) {
+ intersect = true;
+ }
+ }
+ break;
+ default:
+ OpenLayers.Console.error(
+ OpenLayers.i18n("filterEvaluateNotImplemented"));
+ break;
+ }
+ return intersect;
+ },
+
+ /**
+ * APIMethod: clone
+ * Clones this filter.
+ *
+ * Returns:
+ * {<OpenLayers.Filter.Spatial>} Clone of this filter.
+ */
+ clone: function() {
+ var options = OpenLayers.Util.applyDefaults({
+ value: this.value && this.value.clone && this.value.clone()
+ }, this);
+ return new OpenLayers.Filter.Spatial(options);
+ },
+ CLASS_NAME: "OpenLayers.Filter.Spatial"
+});
+
+OpenLayers.Filter.Spatial.BBOX = "BBOX";
+OpenLayers.Filter.Spatial.INTERSECTS = "INTERSECTS";
+OpenLayers.Filter.Spatial.DWITHIN = "DWITHIN";
+OpenLayers.Filter.Spatial.WITHIN = "WITHIN";
+OpenLayers.Filter.Spatial.CONTAINS = "CONTAINS";
+/* ======================================================================
OpenLayers/Geometry/Collection.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -31079,21 +33404,21 @@
/**
* Class: OpenLayers.Geometry.Collection
- * A Collection is exactly what it sounds like: A collection of different
+ * A Collection is exactly what it sounds like: A collection of different
* Geometries. These are stored in the local parameter <components> (which
- * can be passed as a parameter to the constructor).
- *
- * As new geometries are added to the collection, they are NOT cloned.
- * When removing geometries, they need to be specified by reference (ie you
+ * can be passed as a parameter to the constructor).
+ *
+ * As new geometries are added to the collection, they are NOT cloned.
+ * When removing geometries, they need to be specified by reference (ie you
* have to pass in the *exact* geometry to be removed).
- *
+ *
* The <getArea> and <getLength> functions here merely iterate through
* the components, summing their respective areas and lengths.
*
* Create a new instance with the <OpenLayers.Geometry.Collection> constructor.
*
* Inerhits from:
- * - <OpenLayers.Geometry>
+ * - <OpenLayers.Geometry>
*/
OpenLayers.Geometry.Collection = OpenLayers.Class(OpenLayers.Geometry, {
@@ -31102,7 +33427,7 @@
* {Array(<OpenLayers.Geometry>)} The component parts of this geometry
*/
components: null,
-
+
/**
* Property: componentTypes
* {Array(String)} An array of class names representing the types of
@@ -31115,7 +33440,7 @@
* Constructor: OpenLayers.Geometry.Collection
* Creates a Geometry Collection -- a list of geoms.
*
- * Parameters:
+ * Parameters:
* components - {Array(<OpenLayers.Geometry>)} Optional array of geometries
*
*/
@@ -31134,6 +33459,7 @@
destroy: function () {
this.components.length = 0;
this.components = null;
+ OpenLayers.Geometry.prototype.destroy.apply(this, arguments);
},
/**
@@ -31148,31 +33474,31 @@
for(var i=0, len=this.components.length; i<len; i++) {
geometry.addComponent(this.components[i].clone());
}
-
+
// catch any randomly tagged-on properties
OpenLayers.Util.applyDefaults(geometry, this);
-
+
return geometry;
},
/**
* Method: getComponentsString
* Get a string representing the components for this collection
- *
+ *
* Returns:
* {String} A string representation of the components of this geometry
*/
getComponentsString: function(){
var strings = [];
for(var i=0, len=this.components.length; i<len; i++) {
- strings.push(this.components[i].toShortString());
+ strings.push(this.components[i].toShortString());
}
return strings.join(",");
},
/**
* APIMethod: calculateBounds
- * Recalculate the bounds by iterating through the components and
+ * Recalculate the bounds by iterating through the components and
* calling calling extendBounds() on each item.
*/
calculateBounds: function() {
@@ -31207,14 +33533,14 @@
* is set, then the component class name must be in the componentTypes array.
*
* The bounds cache is reset.
- *
+ *
* Parameters:
* component - {<OpenLayers.Geometry>} A geometry to add
* index - {int} Optional index into the array to insert the component
*
* Returns:
* {Boolean} The component geometry was successfully added
- */
+ */
addComponent: function(component, index) {
var added = false;
if(component) {
@@ -31224,7 +33550,7 @@
if(index != null && (index < this.components.length)) {
var components1 = this.components.slice(0, index);
- var components2 = this.components.slice(index,
+ var components2 = this.components.slice(index,
this.components.length);
components1.push(component);
this.components = components1.concat(components2);
@@ -31238,7 +33564,7 @@
}
return added;
},
-
+
/**
* APIMethod: removeComponents
* Remove components from this geometry.
@@ -31254,18 +33580,18 @@
this.removeComponent(components[i]);
}
},
-
+
/**
* Method: removeComponent
* Remove a component from this geometry.
*
* Parameters:
- * component - {<OpenLayers.Geometry>}
+ * component - {<OpenLayers.Geometry>}
*/
removeComponent: function(component) {
-
+
OpenLayers.Util.removeItem(this.components, component);
-
+
// clearBounds() so that it gets recalculated on the next call
// to this.getBounds();
this.clearBounds();
@@ -31285,7 +33611,7 @@
}
return length;
},
-
+
/**
* APIMethod: getArea
* Calculate the area of this geometry. Note how this function is overridden
@@ -31302,7 +33628,7 @@
return area;
},
- /**
+ /**
* APIMethod: getGeodesicArea
* Calculate the approximate area of the polygon were it projected onto
* the earth.
@@ -31311,7 +33637,7 @@
* projection - {<OpenLayers.Projection>} The spatial reference system
* for the geometry coordinates. If not provided, Geographic/WGS84 is
* assumed.
- *
+ *
* Reference:
* Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for
* Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion
@@ -31327,26 +33653,71 @@
}
return area;
},
-
+
/**
* APIMethod: getCentroid
*
+ * Compute the centroid for this geometry collection.
+ *
+ * Parameters:
+ * weighted - {Boolean} Perform the getCentroid computation recursively,
+ * returning an area weighted average of all geometries in this collection.
+ *
* Returns:
* {<OpenLayers.Geometry.Point>} The centroid of the collection
*/
- getCentroid: function() {
- return this.components.length && this.components[0].getCentroid();
- /*
- var centroid;
- for (var i=0, len=this.components.length; i<len; i++) {
- if (!centroid) {
- centroid = this.components[i].getCentroid();
- } else {
- centroid.resize(this.components[i].getCentroid(), 0.5);
+ getCentroid: function(weighted) {
+ if (!weighted) {
+ return this.components.length && this.components[0].getCentroid();
+ }
+ var len = this.components.length;
+ if (!len) {
+ return false;
+ }
+
+ var areas = [];
+ var centroids = [];
+ var areaSum = 0;
+ var minArea = Number.MAX_VALUE;
+ var component;
+ for (var i=0; i<len; ++i) {
+ component = this.components[i];
+ var area = component.getArea();
+ var centroid = component.getCentroid(true);
+ if (isNaN(area) || isNaN(centroid.x) || isNaN(centroid.y)) {
+ continue;
}
+ areas.push(area);
+ areaSum += area;
+ minArea = (area < minArea && area > 0) ? area : minArea;
+ centroids.push(centroid);
}
- return centroid;
- */
+ len = areas.length;
+ if (areaSum === 0) {
+ // all the components in this collection have 0 area
+ // probably a collection of points -- weight all the points the same
+ for (var i=0; i<len; ++i) {
+ areas[i] = 1;
+ }
+ areaSum = areas.length;
+ } else {
+ // normalize all the areas where the smallest area will get
+ // a value of 1
+ for (var i=0; i<len; ++i) {
+ areas[i] /= minArea;
+ }
+ areaSum /= minArea;
+ }
+
+ var xSum = 0, ySum = 0, centroid, area;
+ for (var i=0; i<len; ++i) {
+ centroid = centroids[i];
+ area = areas[i];
+ xSum += centroid.x * area;
+ ySum += centroid.y * area;
+ }
+
+ return new OpenLayers.Geometry.Point(xSum/areaSum, ySum/areaSum);
},
/**
@@ -31357,7 +33728,7 @@
* projection - {<OpenLayers.Projection>} The spatial reference system
* for the geometry coordinates. If not provided, Geographic/WGS84 is
* assumed.
- *
+ *
* Returns:
* {Float} The appoximate geodesic length of the geometry in meters.
*/
@@ -31376,7 +33747,7 @@
* bounds.
*
* Parameters:
- * x - {Float} Distance to move geometry in positive x direction.
+ * x - {Float} Distance to move geometry in positive x direction.
* y - {Float} Distance to move geometry in positive y direction.
*/
move: function(x, y) {
@@ -31412,9 +33783,9 @@
* will have four times the area).
* origin - {<OpenLayers.Geometry.Point>} Point of origin for resizing
* ratio - {Float} Optional x:y ratio for resizing. Default ratio is 1.
- *
+ *
* Returns:
- * {OpenLayers.Geometry} - The current geometry.
+ * {OpenLayers.Geometry} - The current geometry.
*/
resize: function(scale, origin, ratio) {
for(var i=0; i<this.components.length; ++i) {
@@ -31453,7 +33824,7 @@
distanceTo: function(geometry, options) {
var edge = !(options && options.edge === false);
var details = edge && options && options.details;
- var result, best;
+ var result, best, distance;
var min = Number.POSITIVE_INFINITY;
for(var i=0, len=this.components.length; i<len; ++i) {
result = this.components[i].distanceTo(geometry, options);
@@ -31469,13 +33840,13 @@
return best;
},
- /**
+ /**
* APIMethod: equals
* Determine whether another geometry is equivalent to this one. Geometries
* are considered equivalent if all components have the same coordinates.
- *
+ *
* Parameters:
- * geom - {<OpenLayers.Geometry>} The geometry to test.
+ * geom - {<OpenLayers.Geometry>} The geometry to test.
*
* Returns:
* {Boolean} The supplied geometry is equivalent to this geometry.
@@ -31502,17 +33873,17 @@
/**
* APIMethod: transform
* Reproject the components geometry from source to dest.
- *
+ *
* Parameters:
- * source - {<OpenLayers.Projection>}
+ * source - {<OpenLayers.Projection>}
* dest - {<OpenLayers.Projection>}
- *
+ *
* Returns:
- * {<OpenLayers.Geometry>}
+ * {<OpenLayers.Geometry>}
*/
transform: function(source, dest) {
if (source && dest) {
- for (var i=0, len=this.components.length; i<len; i++) {
+ for (var i=0, len=this.components.length; i<len; i++) {
var component = this.components[i];
component.transform(source, dest);
}
@@ -31572,8 +33943,9 @@
OpenLayers/Geometry/Point.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -31582,22 +33954,22 @@
/**
* Class: OpenLayers.Geometry.Point
- * Point geometry class.
- *
+ * Point geometry class.
+ *
* Inherits from:
- * - <OpenLayers.Geometry>
+ * - <OpenLayers.Geometry>
*/
OpenLayers.Geometry.Point = OpenLayers.Class(OpenLayers.Geometry, {
- /**
- * APIProperty: x
- * {float}
+ /**
+ * APIProperty: x
+ * {float}
*/
x: null,
- /**
- * APIProperty: y
- * {float}
+ /**
+ * APIProperty: y
+ * {float}
*/
y: null,
@@ -31606,20 +33978,20 @@
* Construct a point geometry.
*
* Parameters:
- * x - {float}
+ * x - {float}
* y - {float}
- *
+ *
*/
initialize: function(x, y) {
OpenLayers.Geometry.prototype.initialize.apply(this, arguments);
-
+
this.x = parseFloat(x);
this.y = parseFloat(y);
},
/**
* APIMethod: clone
- *
+ *
* Returns:
* {<OpenLayers.Geometry.Point>} An exact clone of this OpenLayers.Geometry.Point
*/
@@ -31634,7 +34006,7 @@
return obj;
},
- /**
+ /**
* Method: calculateBounds
* Create a new Bounds based on the lon/lat
*/
@@ -31695,14 +34067,14 @@
}
return result;
},
-
- /**
+
+ /**
* APIMethod: equals
* Determine whether another geometry is equivalent to this one. Geometries
* are considered equivalent if all components have the same coordinates.
- *
+ *
* Parameters:
- * geom - {<OpenLayers.Geometry.Point>} The geometry to test.
+ * geom - {<OpenLayers.Geometry.Point>} The geometry to test.
*
* Returns:
* {Boolean} The supplied geometry is equivalent to this geometry.
@@ -31715,18 +34087,18 @@
}
return equals;
},
-
+
/**
* Method: toShortString
*
* Returns:
- * {String} Shortened String representation of Point object.
+ * {String} Shortened String representation of Point object.
* (ex. <i>"5, 42"</i>)
*/
toShortString: function() {
return (this.x + ", " + this.y);
},
-
+
/**
* APIMethod: move
* Moves a geometry by the given displacement along positive x and y axes.
@@ -31734,7 +34106,7 @@
* bounds.
*
* Parameters:
- * x - {Float} Distance to move geometry in positive x direction.
+ * x - {Float} Distance to move geometry in positive x direction.
* y - {Float} Distance to move geometry in positive y direction.
*/
move: function(x, y) {
@@ -31760,7 +34132,7 @@
this.y = origin.y + (radius * Math.sin(theta));
this.clearBounds();
},
-
+
/**
* APIMethod: getCentroid
*
@@ -31783,9 +34155,9 @@
* distance between the point and origin.
* origin - {<OpenLayers.Geometry.Point>} Point of origin for resizing
* ratio - {Float} Optional x:y ratio for resizing. Default ratio is 1.
- *
+ *
* Returns:
- * {OpenLayers.Geometry} - The current geometry.
+ * {OpenLayers.Geometry} - The current geometry.
*/
resize: function(scale, origin, ratio) {
ratio = (ratio == undefined) ? 1 : ratio;
@@ -31794,7 +34166,7 @@
this.clearBounds();
return this;
},
-
+
/**
* APIMethod: intersects
* Determine if the input geometry intersects this one.
@@ -31814,24 +34186,24 @@
}
return intersect;
},
-
+
/**
* APIMethod: transform
* Translate the x,y properties of the point from source to dest.
- *
+ *
* Parameters:
- * source - {<OpenLayers.Projection>}
+ * source - {<OpenLayers.Projection>}
* dest - {<OpenLayers.Projection>}
- *
+ *
* Returns:
- * {<OpenLayers.Geometry>}
+ * {<OpenLayers.Geometry>}
*/
transform: function(source, dest) {
if ((source && dest)) {
OpenLayers.Projection.transform(
- this, source, dest);
+ this, source, dest);
this.bounds = null;
- }
+ }
return this;
},
@@ -31858,8 +34230,9 @@
OpenLayers/Layer/Vector.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -31914,6 +34287,9 @@
* beforefeatureremoved - Triggered before a feature is removed. Listeners
* will receive an object with a *feature* property referencing the
* feature to be removed.
+ * beforefeaturesremoved - Triggered before multiple features are removed.
+ * Listeners will receive an object with a *features* property
+ * referencing the features to be removed.
* featureremoved - Triggerd after a feature is removed. The event
* object passed to listeners will have a *feature* property with a
* reference to the removed feature.
@@ -31926,14 +34302,14 @@
* featureunselected - Triggered after a feature is unselected.
* Listeners will receive an object with a *feature* property
* referencing the unselected feature.
- * beforefeaturemodified - Triggered when a feature is selected to
- * be modified. Listeners will receive an object with a *feature*
+ * beforefeaturemodified - Triggered when a feature is selected to
+ * be modified. Listeners will receive an object with a *feature*
* property referencing the selected feature.
* featuremodified - Triggered when a feature has been modified.
- * Listeners will receive an object with a *feature* property referencing
+ * Listeners will receive an object with a *feature* property referencing
* the modified feature.
* afterfeaturemodified - Triggered when a feature is finished being modified.
- * Listeners will receive an object with a *feature* property referencing
+ * Listeners will receive an object with a *feature* property referencing
* the modified feature.
* vertexmodified - Triggered when a vertex within any feature geometry
* has been modified. Listeners will receive an object with a
@@ -31957,45 +34333,53 @@
* for a new set of features.
*/
EVENT_TYPES: ["beforefeatureadded", "beforefeaturesadded",
- "featureadded", "featuresadded",
- "beforefeatureremoved", "featureremoved", "featuresremoved",
- "beforefeatureselected", "featureselected", "featureunselected",
+ "featureadded", "featuresadded", "beforefeatureremoved",
+ "beforefeaturesremoved", "featureremoved", "featuresremoved",
+ "beforefeatureselected", "featureselected", "featureunselected",
"beforefeaturemodified", "featuremodified", "afterfeaturemodified",
"vertexmodified", "sketchstarted", "sketchmodified",
"sketchcomplete", "refresh"],
/**
* APIProperty: isBaseLayer
- * {Boolean} The layer is a base layer. Default is true. Set this property
- * in the layer options
+ * {Boolean} The layer is a base layer. Default is false. Set this property
+ * in the layer options.
*/
isBaseLayer: false,
- /**
+ /**
* APIProperty: isFixed
* {Boolean} Whether the layer remains in one place while dragging the
* map.
*/
isFixed: false,
- /**
+ /**
* APIProperty: isVector
* {Boolean} Whether the layer is a vector layer.
*/
isVector: true,
-
- /**
+
+ /**
* APIProperty: features
- * {Array(<OpenLayers.Feature.Vector>)}
+ * {Array(<OpenLayers.Feature.Vector>)}
*/
features: null,
-
- /**
+
+ /**
+ * Property: filter
+ * {<OpenLayers.Filter>} The filter set in this layer,
+ * a strategy launching read requests can combined
+ * this filter with its own filter.
+ */
+ filter: null,
+
+ /**
* Property: selectedFeatures
- * {Array(<OpenLayers.Feature.Vector>)}
+ * {Array(<OpenLayers.Feature.Vector>)}
*/
selectedFeatures: null,
-
+
/**
* Property: unrenderedFeatures
* {Object} hash of features, keyed by feature.id, that the renderer
@@ -32008,32 +34392,32 @@
* {Boolean} report friendly error message when loading of renderer
* fails.
*/
- reportError: true,
+ reportError: true,
- /**
+ /**
* APIProperty: style
* {Object} Default style for the layer
*/
style: null,
-
+
/**
* Property: styleMap
* {<OpenLayers.StyleMap>}
*/
styleMap: null,
-
+
/**
* Property: strategies
* {Array(<OpenLayers.Strategy>})} Optional list of strategies for the layer.
*/
strategies: null,
-
+
/**
* Property: protocol
* {<OpenLayers.Protocol>} Optional protocol for the layer.
*/
protocol: null,
-
+
/**
* Property: renderers
* {Array(String)} List of supported Renderer classes. Add to this list to
@@ -32042,21 +34426,21 @@
* method will be used, if not defined in the 'renderer' option.
*/
renderers: ['SVG', 'VML', 'Canvas'],
-
- /**
+
+ /**
* Property: renderer
* {<OpenLayers.Renderer>}
*/
renderer: null,
-
+
/**
* APIProperty: rendererOptions
* {Object} Options for the renderer. See {<OpenLayers.Renderer>} for
* supported options.
*/
rendererOptions: null,
-
- /**
+
+ /**
* APIProperty: geometryType
* {String} geometryType allows you to limit the types of geometries this
* layer supports. This should be set to something like
@@ -32064,7 +34448,7 @@
*/
geometryType: null,
- /**
+ /**
* Property: drawn
* {Boolean} Whether the Vector Layer features have been drawn yet.
*/
@@ -32083,7 +34467,7 @@
* {<OpenLayers.Layer.Vector>} A new vector layer
*/
initialize: function(name, options) {
-
+
// concatenate events specific to vector with those from the base
this.EVENT_TYPES =
OpenLayers.Layer.Vector.prototype.EVENT_TYPES.concat(
@@ -32093,7 +34477,7 @@
OpenLayers.Layer.prototype.initialize.apply(this, arguments);
// allow user-set renderer, otherwise assign one
- if (!this.renderer || !this.renderer.supported()) {
+ if (!this.renderer || !this.renderer.supported()) {
this.assignRenderer();
}
@@ -32101,7 +34485,7 @@
if (!this.renderer || !this.renderer.supported()) {
this.renderer = null;
this.displayError();
- }
+ }
if (!this.styleMap) {
this.styleMap = new OpenLayers.StyleMap();
@@ -32110,7 +34494,7 @@
this.features = [];
this.selectedFeatures = [];
this.unrenderedFeatures = {};
-
+
// Allow for custom layer behavior
if(this.strategies){
for(var i=0, len=this.strategies.length; i<len; i++) {
@@ -32151,10 +34535,40 @@
this.renderer = null;
this.geometryType = null;
this.drawn = null;
- OpenLayers.Layer.prototype.destroy.apply(this, arguments);
+ OpenLayers.Layer.prototype.destroy.apply(this, arguments);
},
/**
+ * Method: clone
+ * Create a clone of this layer.
+ *
+ * Note: Features of the layer are also cloned.
+ *
+ * Returns:
+ * {<OpenLayers.Layer.Vector>} An exact clone of this layer
+ */
+ clone: function (obj) {
+
+ if (obj == null) {
+ obj = new OpenLayers.Layer.Vector(this.name, this.getOptions());
+ }
+
+ //get all additions from superclasses
+ obj = OpenLayers.Layer.prototype.clone.apply(this, [obj]);
+
+ // copy/set any non-init, non-simple values here
+ var features = this.features;
+ var len = features.length;
+ var clonedFeatures = new Array(len);
+ for(var i=0; i<len; ++i) {
+ clonedFeatures[i] = features[i].clone();
+ }
+ obj.features = clonedFeatures;
+
+ return obj;
+ },
+
+ /**
* Method: refresh
* Ask the layer to request features again and redraw them. Triggers
* the refresh event if the layer is in range and visible.
@@ -32169,44 +34583,46 @@
}
},
- /**
+ /**
* Method: assignRenderer
- * Iterates through the available renderer implementations and selects
+ * Iterates through the available renderer implementations and selects
* and assigns the first one whose "supported()" function returns true.
- */
+ */
assignRenderer: function() {
for (var i=0, len=this.renderers.length; i<len; i++) {
- var rendererClass = OpenLayers.Renderer[this.renderers[i]];
- if (rendererClass && rendererClass.prototype.supported()) {
- this.renderer = new rendererClass(this.div,
- this.rendererOptions);
+ var rendererClass = this.renderers[i];
+ var renderer = (typeof rendererClass == "function") ?
+ rendererClass :
+ OpenLayers.Renderer[rendererClass];
+ if (renderer && renderer.prototype.supported()) {
+ this.renderer = new renderer(this.div, this.rendererOptions);
break;
- }
- }
+ }
+ }
},
- /**
- * Method: displayError
+ /**
+ * Method: displayError
* Let the user know their browser isn't supported.
*/
displayError: function() {
if (this.reportError) {
- OpenLayers.Console.userError(OpenLayers.i18n("browserNotSupported",
+ OpenLayers.Console.userError(OpenLayers.i18n("browserNotSupported",
{'renderers':this.renderers.join("\n")}));
- }
+ }
},
- /**
+ /**
* Method: setMap
- * The layer has been added to the map.
- *
+ * The layer has been added to the map.
+ *
* If there is no renderer set, the layer can't be used. Remove it.
* Otherwise, give the renderer a reference to the map and set its size.
- *
+ *
* Parameters:
- * map - {<OpenLayers.Map>}
+ * map - {<OpenLayers.Map>}
*/
- setMap: function(map) {
+ setMap: function(map) {
OpenLayers.Layer.prototype.setMap.apply(this, arguments);
if (!this.renderer) {
@@ -32243,6 +34659,7 @@
* map - {<OpenLayers.Map>}
*/
removeMap: function(map) {
+ this.drawn = false;
if(this.strategies) {
var strategy, i, len;
for(i=0, len=this.strategies.length; i<len; i++) {
@@ -32253,11 +34670,11 @@
}
}
},
-
+
/**
* Method: onMapResize
- * Notify the renderer of the change in size.
- *
+ * Notify the renderer of the change in size.
+ *
*/
onMapResize: function() {
OpenLayers.Layer.prototype.onMapResize.apply(this, arguments);
@@ -32266,32 +34683,32 @@
/**
* Method: moveTo
- * Reset the vector layer's div so that it once again is lined up with
+ * Reset the vector layer's div so that it once again is lined up with
* the map. Notify the renderer of the change of extent, and in the
- * case of a change of zoom level (resolution), have the
+ * case of a change of zoom level (resolution), have the
* renderer redraw features.
- *
- * If the layer has not yet been drawn, cycle through the layer's
+ *
+ * If the layer has not yet been drawn, cycle through the layer's
* features and draw each one.
- *
+ *
* Parameters:
- * bounds - {<OpenLayers.Bounds>}
- * zoomChanged - {Boolean}
- * dragging - {Boolean}
+ * bounds - {<OpenLayers.Bounds>}
+ * zoomChanged - {Boolean}
+ * dragging - {Boolean}
*/
moveTo: function(bounds, zoomChanged, dragging) {
OpenLayers.Layer.prototype.moveTo.apply(this, arguments);
-
+
var coordSysUnchanged = true;
if (!dragging) {
this.renderer.root.style.visibility = "hidden";
-
+
this.div.style.left = -parseInt(this.map.layerContainerDiv.style.left) + "px";
this.div.style.top = -parseInt(this.map.layerContainerDiv.style.top) + "px";
var extent = this.map.getExtent();
coordSysUnchanged = this.renderer.setExtent(extent, zoomChanged);
-
+
this.renderer.root.style.visibility = "visible";
// Force a reflow on gecko based browsers to prevent jump/flicker.
@@ -32300,7 +34717,7 @@
if (navigator.userAgent.toLowerCase().indexOf("gecko") != -1) {
this.div.scrollLeft = this.div.scrollLeft;
}
-
+
if(!zoomChanged && coordSysUnchanged) {
for(var i in this.unrenderedFeatures) {
var feature = this.unrenderedFeatures[i];
@@ -32308,7 +34725,7 @@
}
}
}
-
+
if (!this.drawn || zoomChanged || !coordSysUnchanged) {
this.drawn = true;
var feature;
@@ -32317,13 +34734,13 @@
feature = this.features[i];
this.drawFeature(feature);
}
- }
+ }
},
-
- /**
+
+ /**
* APIMethod: display
* Hide or show the Layer
- *
+ *
* Parameters:
* display - {Boolean}
*/
@@ -32342,14 +34759,14 @@
* Add Features to the layer.
*
* Parameters:
- * features - {Array(<OpenLayers.Feature.Vector>)}
+ * features - {Array(<OpenLayers.Feature.Vector>)}
* options - {Object}
*/
addFeatures: function(features, options) {
if (!(features instanceof Array)) {
features = [features];
}
-
+
var notify = !options || !options.silent;
if(notify) {
var event = {features: features};
@@ -32359,16 +34776,18 @@
}
features = event.features;
}
-
-
+
+ // Track successfully added features for featuresadded event, since
+ // beforefeatureadded can veto single features.
+ var featuresAdded = [];
for (var i=0, len=features.length; i<len; i++) {
if (i != (features.length - 1)) {
this.renderer.locked = true;
} else {
this.renderer.locked = false;
- }
+ }
var feature = features[i];
-
+
if (this.geometryType &&
!(feature.geometry instanceof this.geometryType)) {
var throwStr = OpenLayers.i18n('componentShouldBe',
@@ -32376,8 +34795,6 @@
throw throwStr;
}
- this.features.push(feature);
-
//give feature reference to its layer
feature.layer = this;
@@ -32393,8 +34810,10 @@
this.preFeatureInsert(feature);
}
+ featuresAdded.push(feature);
+ this.features.push(feature);
this.drawFeature(feature);
-
+
if (notify) {
this.events.triggerEvent("featureadded", {
feature: feature
@@ -32402,9 +34821,9 @@
this.onFeatureInsert(feature);
}
}
-
+
if(notify) {
- this.events.triggerEvent("featuresadded", {features: features});
+ this.events.triggerEvent("featuresadded", {features: featuresAdded});
}
},
@@ -32416,7 +34835,7 @@
* and featureremoved events will be triggered for each feature. The
* featuresremoved event will be triggered after all features have
* been removed. To supress event triggering, use the silent option.
- *
+ *
* Parameters:
* features - {Array(<OpenLayers.Feature.Vector>)} List of features to be
* removed.
@@ -32430,14 +34849,23 @@
if(!features || features.length === 0) {
return;
}
+ if (features === this.features) {
+ return this.removeAllFeatures(options);
+ }
if (!(features instanceof Array)) {
features = [features];
}
- if (features === this.features) {
+ if (features === this.selectedFeatures) {
features = features.slice();
}
var notify = !options || !options.silent;
+
+ if (notify) {
+ this.events.triggerEvent(
+ "beforefeaturesremoved", {features: features}
+ );
+ }
for (var i = features.length - 1; i >= 0; i--) {
// We remain locked so long as we're not at 0
@@ -32445,15 +34873,15 @@
// because if all the features after the current one are 'null', we
// won't call eraseGeometry, so we break the 'renderer functions
// will always be called with locked=false *last*' rule. The end result
- // is a possible gratiutious unlocking to save a loop through the rest
+ // is a possible gratiutious unlocking to save a loop through the rest
// of the list checking the remaining features every time. So long as
- // null geoms are rare, this is probably okay.
+ // null geoms are rare, this is probably okay.
if (i != 0 && features[i-1].geometry) {
this.renderer.locked = true;
} else {
this.renderer.locked = false;
}
-
+
var feature = features[i];
delete this.unrenderedFeatures[feature.id];
@@ -32470,8 +34898,8 @@
if (feature.geometry) {
this.renderer.eraseFeatures(feature);
}
-
- //in the case that this feature is one of the selected features,
+
+ //in the case that this feature is one of the selected features,
// remove it from that array as well.
if (OpenLayers.Util.indexOf(this.selectedFeatures, feature) != -1){
OpenLayers.Util.removeItem(this.selectedFeatures, feature);
@@ -32488,6 +34916,49 @@
this.events.triggerEvent("featuresremoved", {features: features});
}
},
+
+ /**
+ * APIMethod: removeAllFeatures
+ * Remove all features from the layer.
+ *
+ * Parameters:
+ * options - {Object} Optional properties for changing behavior of the
+ * removal.
+ *
+ * Valid options:
+ * silent - {Boolean} Supress event triggering. Default is false.
+ */
+ removeAllFeatures: function(options) {
+ var notify = !options || !options.silent;
+ var features = this.features;
+ if (notify) {
+ this.events.triggerEvent(
+ "beforefeaturesremoved", {features: features}
+ );
+ }
+ var feature;
+ for (var i = features.length-1; i >= 0; i--) {
+ feature = features[i];
+ if (notify) {
+ this.events.triggerEvent("beforefeatureremoved", {
+ feature: feature
+ });
+ }
+ feature.layer = null;
+ if (notify) {
+ this.events.triggerEvent("featureremoved", {
+ feature: feature
+ });
+ }
+ }
+ this.renderer.clear();
+ this.features = [];
+ this.unrenderedFeatures = {};
+ this.selectedFeatures = [];
+ if (notify) {
+ this.events.triggerEvent("featuresremoved", {features: features});
+ }
+ },
/**
* APIMethod: destroyFeatures
@@ -32519,20 +34990,20 @@
* is included, this style will be used. If no style is included, the
* feature's style will be used. If the feature doesn't have a style,
* the layer's style will be used.
- *
- * This function is not designed to be used when adding features to
+ *
+ * This function is not designed to be used when adding features to
* the layer (use addFeatures instead). It is meant to be used when
- * the style of a feature has changed, or in some other way needs to
+ * the style of a feature has changed, or in some other way needs to
* visually updated *after* it has already been added to a layer. You
- * must add the feature to the layer for most layer-related events to
+ * must add the feature to the layer for most layer-related events to
* happen.
*
- * Parameters:
- * feature - {<OpenLayers.Feature.Vector>}
- * style - {Object} Symbolizer hash or {String} renderIntent
+ * Parameters:
+ * feature - {<OpenLayers.Feature.Vector>}
+ * style - {String | Object} Named render intent or full symbolizer object.
*/
drawFeature: function(feature, style) {
- // don't try to draw the feature with the renderer if the layer is not
+ // don't try to draw the feature with the renderer if the layer is not
// drawn itself
if (!this.drawn) {
return
@@ -32547,20 +35018,20 @@
style = this.styleMap.createSymbolizer(feature, renderIntent);
}
}
-
+
if (!this.renderer.drawFeature(feature, style)) {
this.unrenderedFeatures[feature.id] = feature;
} else {
delete this.unrenderedFeatures[feature.id];
};
},
-
+
/**
* Method: eraseFeatures
* Erase features from the layer.
*
* Parameters:
- * features - {Array(<OpenLayers.Feature.Vector>)}
+ * features - {Array(<OpenLayers.Feature.Vector>)}
*/
eraseFeatures: function(features) {
this.renderer.eraseFeatures(features);
@@ -32572,36 +35043,37 @@
* Otherwise, return null.
*
* Parameters:
- * evt - {Event}
+ * evt - {Event}
*
* Returns:
* {<OpenLayers.Feature.Vector>} A feature if one was under the event.
*/
getFeatureFromEvent: function(evt) {
if (!this.renderer) {
- OpenLayers.Console.error(OpenLayers.i18n("getFeatureError"));
+ OpenLayers.Console.error(OpenLayers.i18n("getFeatureError"));
return null;
- }
+ }
var featureId = this.renderer.getFeatureIdFromEvent(evt);
return this.getFeatureById(featureId);
},
/**
- * APIMethod: getFeatureById
- * Given a feature id, return the feature if it exists in the features array
+ * APIMethod: getFeatureBy
+ * Given a property value, return the feature if it exists in the features array
*
* Parameters:
- * featureId - {String}
+ * property - {String}
+ * value - {String}
*
* Returns:
* {<OpenLayers.Feature.Vector>} A feature corresponding to the given
- * featureId
+ * property value or null if there is no such feature.
*/
- getFeatureById: function(featureId) {
+ getFeatureBy: function(property, value) {
//TBD - would it be more efficient to use a hash for this.features?
var feature = null;
for(var i=0, len=this.features.length; i<len; ++i) {
- if(this.features[i].id == featureId) {
+ if(this.features[i][property] == value) {
feature = this.features[i];
break;
}
@@ -32610,6 +35082,36 @@
},
/**
+ * APIMethod: getFeatureById
+ * Given a feature id, return the feature if it exists in the features array
+ *
+ * Parameters:
+ * featureId - {String}
+ *
+ * Returns:
+ * {<OpenLayers.Feature.Vector>} A feature corresponding to the given
+ * featureId or null if there is no such feature.
+ */
+ getFeatureById: function(featureId) {
+ return this.getFeatureBy('id', featureId);
+ },
+
+ /**
+ * APIMethod: getFeatureByFid
+ * Given a feature fid, return the feature if it exists in the features array
+ *
+ * Parameters:
+ * featureFid - {String}
+ *
+ * Returns:
+ * {<OpenLayers.Feature.Vector>} A feature corresponding to the given
+ * featureFid or null if there is no such feature.
+ */
+ getFeatureByFid: function(featureFid) {
+ return this.getFeatureBy('fid', featureFid);
+ },
+
+ /**
* Unselect the selected features
* i.e. clears the featureSelection array
* change the style back
@@ -32631,12 +35133,12 @@
* Does nothing by default. Override this if you
* need to do something on feature updates.
*
- * Paarameters:
- * feature - {<OpenLayers.Feature.Vector>}
+ * Paarameters:
+ * feature - {<OpenLayers.Feature.Vector>}
*/
onFeatureInsert: function(feature) {
},
-
+
/**
* APIMethod: preFeatureInsert
* method called before a feature is inserted.
@@ -32645,28 +35147,31 @@
* layer, but before they are drawn, such as adjust the style.
*
* Parameters:
- * feature - {<OpenLayers.Feature.Vector>}
+ * feature - {<OpenLayers.Feature.Vector>}
*/
preFeatureInsert: function(feature) {
},
- /**
+ /**
* APIMethod: getDataExtent
* Calculates the max extent which includes all of the features.
- *
+ *
* Returns:
* {<OpenLayers.Bounds>}
*/
getDataExtent: function () {
var maxExtent = null;
-
- if(this.features && (this.features.length > 0)) {
+ var features = this.features;
+ if(features && (features.length > 0)) {
maxExtent = new OpenLayers.Bounds();
- for(var i=0, len=this.features.length; i<len; i++) {
- maxExtent.extend(this.features[i].geometry.getBounds());
+ var geometry = null;
+ for(var i=0, len=features.length; i<len; i++) {
+ geometry = features[i].geometry;
+ if (geometry) {
+ maxExtent.extend(geometry.getBounds());
+ }
}
}
-
return maxExtent;
},
@@ -32676,8 +35181,9 @@
OpenLayers/Geometry/MultiPoint.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -32710,13 +35216,13 @@
* Create a new MultiPoint Geometry
*
* Parameters:
- * components - {Array(<OpenLayers.Geometry.Point>)}
+ * components - {Array(<OpenLayers.Geometry.Point>)}
*
* Returns:
* {<OpenLayers.Geometry.MultiPoint>}
*/
initialize: function(components) {
- OpenLayers.Geometry.Collection.prototype.initialize.apply(this,
+ OpenLayers.Geometry.Collection.prototype.initialize.apply(this,
arguments);
},
@@ -32731,7 +35237,7 @@
addPoint: function(point, index) {
this.addComponent(point, index);
},
-
+
/**
* APIMethod: removePoint
* Wrapper for <OpenLayers.Geometry.Collection.removeComponent>
@@ -32749,8 +35255,9 @@
OpenLayers/Handler/Point.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
@@ -32767,12 +35274,12 @@
* called with each change in the sketch and will receive the latest point
* drawn. Create a new instance with the <OpenLayers.Handler.Point>
* constructor.
- *
+ *
* Inherits from:
* - <OpenLayers.Handler>
*/
OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, {
-
+
/**
* Property: point
* {<OpenLayers.Feature.Vector>} The currently drawn point
@@ -32784,20 +35291,20 @@
* {<OpenLayers.Layer.Vector>} The temporary drawing layer
*/
layer: null,
-
+
/**
- * Property: multi
+ * APIProperty: multi
* {Boolean} Cast features to multi-part geometries before passing to the
* layer. Default is false.
*/
multi: false,
-
+
/**
- * Property: drawing
+ * Property: drawing
* {Boolean} A point is being drawn
*/
drawing: false,
-
+
/**
* Property: mouseDown
* {Boolean} The mouse is down
@@ -32859,7 +35366,7 @@
OpenLayers.Handler.prototype.initialize.apply(this, arguments);
},
-
+
/**
* APIMethod: activate
* turn on the handler
@@ -32876,13 +35383,13 @@
// without this, resolution properties must be specified at the
// map-level for this temporary layer to init its resolutions
// correctly
- calculateInRange: function() { return true; }
+ calculateInRange: OpenLayers.Function.True
}, this.layerOptions);
this.layer = new OpenLayers.Layer.Vector(this.CLASS_NAME, options);
this.map.addLayer(this.layer);
return true;
},
-
+
/**
* Method: createFeature
* Add temporary features
@@ -32924,7 +35431,7 @@
this.layer = null;
return true;
},
-
+
/**
* Method: destroyFeature
* Destroy the temporary geometries
@@ -32968,11 +35475,11 @@
* Method: click
* Handle clicks. Clicks are stopped from propagating to other listeners
* on map.events or other dom elements.
- *
+ *
* Parameters:
* evt - {Event} The browser event
*
- * Returns:
+ * Returns:
* {Boolean} Allow event propagation
*/
click: function(evt) {
@@ -32984,18 +35491,18 @@
* Method: dblclick
* Handle double-clicks. Double-clicks are stopped from propagating to other
* listeners on map.events or other dom elements.
- *
+ *
* Parameters:
* evt - {Event} The browser event
*
- * Returns:
+ * Returns:
* {Boolean} Allow event propagation
*/
dblclick: function(evt) {
OpenLayers.Event.stop(evt);
return false;
},
-
+
/**
* Method: modifyFeature
* Modify the existing geometry given a pixel location.
@@ -33019,7 +35526,7 @@
drawFeature: function() {
this.layer.drawFeature(this.point, this.style);
},
-
+
/**
* Method: getGeometry
* Return the sketch geometry. If <multi> is true, this will return
@@ -33047,16 +35554,16 @@
var geom = this.getGeometry();
return geom && geom.clone();
},
-
+
/**
* Method: mousedown
* Handle mouse down. Adjust the geometry and redraw.
* Return determines whether to propagate the event on the map.
- *
+ *
* Parameters:
* evt - {Event} The browser event
*
- * Returns:
+ * Returns:
* {Boolean} Allow event propagation
*/
mousedown: function(evt) {
@@ -33085,11 +35592,11 @@
* Method: mousemove
* Handle mouse move. Adjust the geometry and redraw.
* Return determines whether to propagate the event on the map.
- *
+ *
* Parameters:
* evt - {Event} The browser event
*
- * Returns:
+ * Returns:
* {Boolean} Allow event propagation
*/
mousemove: function (evt) {
@@ -33107,7 +35614,7 @@
* Parameters:
* evt - {Event} The browser event
*
- * Returns:
+ * Returns:
* {Boolean} Allow event propagation
*/
mouseup: function (evt) {
@@ -33122,11 +35629,671 @@
CLASS_NAME: "OpenLayers.Handler.Point"
});
/* ======================================================================
+ OpenLayers/Protocol/HTTP.js
+ ====================================================================== */
+
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+ * full text of the license. */
+
+/**
+ * @requires OpenLayers/Protocol.js
+ * @requires OpenLayers/Feature/Vector.js
+ * @requires OpenLayers/Filter/Spatial.js
+ * @requires OpenLayers/Filter/Comparison.js
+ * @requires OpenLayers/Filter/Logical.js
+ * @requires OpenLayers/Request/XMLHttpRequest.js
+ */
+
+/**
+ * Class: OpenLayers.Protocol.HTTP
+ * A basic HTTP protocol for vector layers. Create a new instance with the
+ * <OpenLayers.Protocol.HTTP> constructor.
+ *
+ * Inherits from:
+ * - <OpenLayers.Protocol>
+ */
+OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {
+
+ /**
+ * Property: url
+ * {String} Service URL, read-only, set through the options
+ * passed to constructor.
+ */
+ url: null,
+
+ /**
+ * Property: headers
+ * {Object} HTTP request headers, read-only, set through the options
+ * passed to the constructor,
+ * Example: {'Content-Type': 'plain/text'}
+ */
+ headers: null,
+
+ /**
+ * Property: params
+ * {Object} Parameters of GET requests, read-only, set through the options
+ * passed to the constructor,
+ * Example: {'bbox': '5,5,5,5'}
+ */
+ params: null,
+
+ /**
+ * Property: callback
+ * {Object} Function to be called when the <read>, <create>,
+ * <update>, <delete> or <commit> operation completes, read-only,
+ * set through the options passed to the constructor.
+ */
+ callback: null,
+
+ /**
+ * Property: scope
+ * {Object} Callback execution scope, read-only, set through the
+ * options passed to the constructor.
+ */
+ scope: null,
+
+ /**
+ * Property: readWithPOST
+ * {Boolean} true if read operations are done with POST requests
+ * instead of GET, defaults to false.
+ */
+ readWithPOST: false,
+
+ /**
+ * Property: wildcarded.
+ * {Boolean} If true percent signs are added around values
+ * read from LIKE filters, for example if the protocol
+ * read method is passed a LIKE filter whose property
+ * is "foo" and whose value is "bar" the string
+ * "foo__ilike=%bar%" will be sent in the query string;
+ * defaults to false.
+ */
+ wildcarded: false,
+
+ /**
+ * Constructor: OpenLayers.Protocol.HTTP
+ * A class for giving layers generic HTTP protocol.
+ *
+ * Parameters:
+ * options - {Object} Optional object whose properties will be set on the
+ * instance.
+ *
+ * Valid options include:
+ * url - {String}
+ * headers - {Object}
+ * params - {Object}
+ * format - {<OpenLayers.Format>}
+ * callback - {Function}
+ * scope - {Object}
+ */
+ initialize: function(options) {
+ options = options || {};
+ this.params = {};
+ this.headers = {};
+ OpenLayers.Protocol.prototype.initialize.apply(this, arguments);
+ },
+
+ /**
+ * APIMethod: destroy
+ * Clean up the protocol.
+ */
+ destroy: function() {
+ this.params = null;
+ this.headers = null;
+ OpenLayers.Protocol.prototype.destroy.apply(this);
+ },
+
+ /**
+ * APIMethod: read
+ * Construct a request for reading new features.
+ *
+ * Parameters:
+ * options - {Object} Optional object for configuring the request.
+ * This object is modified and should not be reused.
+ *
+ * Valid options:
+ * url - {String} Url for the request.
+ * params - {Object} Parameters to get serialized as a query string.
+ * headers - {Object} Headers to be set on the request.
+ * filter - {<OpenLayers.Filter>} Filter to get serialized as a
+ * query string.
+ * readWithPOST - {Boolean} If the request should be done with POST.
+ *
+ * Returns:
+ * {<OpenLayers.Protocol.Response>} A response object, whose "priv" property
+ * references the HTTP request, this object is also passed to the
+ * callback function when the request completes, its "features" property
+ * is then populated with the the features received from the server.
+ */
+ read: function(options) {
+ OpenLayers.Protocol.prototype.read.apply(this, arguments);
+ options = OpenLayers.Util.applyDefaults(options, this.options);
+ options.params = OpenLayers.Util.applyDefaults(
+ options.params, this.options.params);
+ if(options.filter) {
+ options.params = this.filterToParams(
+ options.filter, options.params);
+ }
+ var readWithPOST = (options.readWithPOST !== undefined) ?
+ options.readWithPOST : this.readWithPOST;
+ var resp = new OpenLayers.Protocol.Response({requestType: "read"});
+ if(readWithPOST) {
+ resp.priv = OpenLayers.Request.POST({
+ url: options.url,
+ callback: this.createCallback(this.handleRead, resp, options),
+ data: OpenLayers.Util.getParameterString(options.params),
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded"
+ }
+ });
+ } else {
+ resp.priv = OpenLayers.Request.GET({
+ url: options.url,
+ callback: this.createCallback(this.handleRead, resp, options),
+ params: options.params,
+ headers: options.headers
+ });
+ }
+ return resp;
+ },
+
+ /**
+ * Method: handleRead
+ * Individual callbacks are created for read, create and update, should
+ * a subclass need to override each one separately.
+ *
+ * Parameters:
+ * resp - {<OpenLayers.Protocol.Response>} The response object to pass to
+ * the user callback.
+ * options - {Object} The user options passed to the read call.
+ */
+ handleRead: function(resp, options) {
+ this.handleResponse(resp, options);
+ },
+
+ /**
+ * Method: filterToParams
+ * Convert an <OpenLayers.Filter> object to parameters.
+ *
+ * Parameters:
+ * filter - {OpenLayers.Filter} filter to convert.
+ * params - {Object} The parameters object.
+ *
+ * Returns:
+ * {Object} The resulting parameters object.
+ */
+ filterToParams: function(filter, params) {
+ params = params || {};
+ var className = filter.CLASS_NAME;
+ var filterType = className.substring(className.lastIndexOf(".") + 1);
+ switch(filterType) {
+ case "Spatial":
+ switch(filter.type) {
+ case OpenLayers.Filter.Spatial.BBOX:
+ params.bbox = filter.value.toArray();
+ break;
+ case OpenLayers.Filter.Spatial.DWITHIN:
+ params.tolerance = filter.distance;
+ // no break here
+ case OpenLayers.Filter.Spatial.WITHIN:
+ params.lon = filter.value.x;
+ params.lat = filter.value.y;
+ break;
+ default:
+ OpenLayers.Console.warn(
+ "Unknown spatial filter type " + filter.type);
+ }
+ break;
+ case "Comparison":
+ var op = OpenLayers.Protocol.HTTP.COMP_TYPE_TO_OP_STR[filter.type];
+ if(op !== undefined) {
+ var value = filter.value;
+ if(filter.type == OpenLayers.Filter.Comparison.LIKE) {
+ value = this.regex2value(value);
+ if(this.wildcarded) {
+ value = "%" + value + "%";
+ }
+ }
+ params[filter.property + "__" + op] = value;
+ params.queryable = params.queryable || [];
+ params.queryable.push(filter.property);
+ } else {
+ OpenLayers.Console.warn(
+ "Unknown comparison filter type " + filter.type);
+ }
+ break;
+ case "Logical":
+ if(filter.type === OpenLayers.Filter.Logical.AND) {
+ for(var i=0,len=filter.filters.length; i<len; i++) {
+ params = this.filterToParams(filter.filters[i], params);
+ }
+ } else {
+ OpenLayers.Console.warn(
+ "Unsupported logical filter type " + filter.type);
+ }
+ break;
+ default:
+ OpenLayers.Console.warn("Unknown filter type " + filterType);
+ }
+ return params;
+ },
+
+ /**
+ * Method: regex2value
+ * Convert the value from a regular expression string to a LIKE/ILIKE
+ * string known to the web service.
+ *
+ * Parameters:
+ * value - {String} The regex string.
+ *
+ * Returns:
+ * {String} The converted string.
+ */
+ regex2value: function(value) {
+
+ // highly sensitive!! Do not change this without running the
+ // Protocol/HTTP.html unit tests
+
+ // convert % to \%
+ value = value.replace(/%/g, "\\%");
+
+ // convert \\. to \\_ (\\.* occurences converted later)
+ value = value.replace(/\\\\\.(\*)?/g, function($0, $1) {
+ return $1 ? $0 : "\\\\_";
+ });
+
+ // convert \\.* to \\%
+ value = value.replace(/\\\\\.\*/g, "\\\\%");
+
+ // convert . to _ (\. and .* occurences converted later)
+ value = value.replace(/(\\)?\.(\*)?/g, function($0, $1, $2) {
+ return $1 || $2 ? $0 : "_";
+ });
+
+ // convert .* to % (\.* occurnces converted later)
+ value = value.replace(/(\\)?\.\*/g, function($0, $1) {
+ return $1 ? $0 : "%";
+ });
+
+ // convert \. to .
+ value = value.replace(/\\\./g, ".");
+
+ // replace \* with * (watching out for \\*)
+ value = value.replace(/(\\)?\\\*/g, function($0, $1) {
+ return $1 ? $0 : "*";
+ });
+
+ return value;
+ },
+
+ /**
+ * APIMethod: create
+ * Construct a request for writing newly created features.
+ *
+ * Parameters:
+ * features - {Array({<OpenLayers.Feature.Vector>})} or
+ * {<OpenLayers.Feature.Vector>}
+ * options - {Object} Optional object for configuring the request.
+ * This object is modified and should not be reused.
+ *
+ * Returns:
+ * {<OpenLayers.Protocol.Response>} An <OpenLayers.Protocol.Response>
+ * object, whose "priv" property references the HTTP request, this
+ * object is also passed to the callback function when the request
+ * completes, its "features" property is then populated with the
+ * the features received from the server.
+ */
+ create: function(features, options) {
+ options = OpenLayers.Util.applyDefaults(options, this.options);
+
+ var resp = new OpenLayers.Protocol.Response({
+ reqFeatures: features,
+ requestType: "create"
+ });
+
+ resp.priv = OpenLayers.Request.POST({
+ url: options.url,
+ callback: this.createCallback(this.handleCreate, resp, options),
+ headers: options.headers,
+ data: this.format.write(features)
+ });
+
+ return resp;
+ },
+
+ /**
+ * Method: handleCreate
+ * Called the the request issued by <create> is complete. May be overridden
+ * by subclasses.
+ *
+ * Parameters:
+ * resp - {<OpenLayers.Protocol.Response>} The response object to pass to
+ * any user callback.
+ * options - {Object} The user options passed to the create call.
+ */
+ handleCreate: function(resp, options) {
+ this.handleResponse(resp, options);
+ },
+
+ /**
+ * APIMethod: update
+ * Construct a request updating modified feature.
+ *
+ * Parameters:
+ * feature - {<OpenLayers.Feature.Vector>}
+ * options - {Object} Optional object for configuring the request.
+ * This object is modified and should not be reused.
+ *
+ * Returns:
+ * {<OpenLayers.Protocol.Response>} An <OpenLayers.Protocol.Response>
+ * object, whose "priv" property references the HTTP request, this
+ * object is also passed to the callback function when the request
+ * completes, its "features" property is then populated with the
+ * the feature received from the server.
+ */
+ update: function(feature, options) {
+ options = options || {};
+ var url = options.url ||
+ feature.url ||
+ this.options.url + "/" + feature.fid;
+ options = OpenLayers.Util.applyDefaults(options, this.options);
+
+ var resp = new OpenLayers.Protocol.Response({
+ reqFeatures: feature,
+ requestType: "update"
+ });
+
+ resp.priv = OpenLayers.Request.PUT({
+ url: url,
+ callback: this.createCallback(this.handleUpdate, resp, options),
+ headers: options.headers,
+ data: this.format.write(feature)
+ });
+
+ return resp;
+ },
+
+ /**
+ * Method: handleUpdate
+ * Called the the request issued by <update> is complete. May be overridden
+ * by subclasses.
+ *
+ * Parameters:
+ * resp - {<OpenLayers.Protocol.Response>} The response object to pass to
+ * any user callback.
+ * options - {Object} The user options passed to the update call.
+ */
+ handleUpdate: function(resp, options) {
+ this.handleResponse(resp, options);
+ },
+
+ /**
+ * APIMethod: delete
+ * Construct a request deleting a removed feature.
+ *
+ * Parameters:
+ * feature - {<OpenLayers.Feature.Vector>}
+ * options - {Object} Optional object for configuring the request.
+ * This object is modified and should not be reused.
+ *
+ * Returns:
+ * {<OpenLayers.Protocol.Response>} An <OpenLayers.Protocol.Response>
+ * object, whose "priv" property references the HTTP request, this
+ * object is also passed to the callback function when the request
+ * completes.
+ */
+ "delete": function(feature, options) {
+ options = options || {};
+ var url = options.url ||
+ feature.url ||
+ this.options.url + "/" + feature.fid;
+ options = OpenLayers.Util.applyDefaults(options, this.options);
+
+ var resp = new OpenLayers.Protocol.Response({
+ reqFeatures: feature,
+ requestType: "delete"
+ });
+
+ resp.priv = OpenLayers.Request.DELETE({
+ url: url,
+ callback: this.createCallback(this.handleDelete, resp, options),
+ headers: options.headers
+ });
+
+ return resp;
+ },
+
+ /**
+ * Method: handleDelete
+ * Called the the request issued by <delete> is complete. May be overridden
+ * by subclasses.
+ *
+ * Parameters:
+ * resp - {<OpenLayers.Protocol.Response>} The response object to pass to
+ * any user callback.
+ * options - {Object} The user options passed to the delete call.
+ */
+ handleDelete: function(resp, options) {
+ this.handleResponse(resp, options);
+ },
+
+ /**
+ * Method: handleResponse
+ * Called by CRUD specific handlers.
+ *
+ * Parameters:
+ * resp - {<OpenLayers.Protocol.Response>} The response object to pass to
+ * any user callback.
+ * options - {Object} The user options passed to the create, read, update,
+ * or delete call.
+ */
+ handleResponse: function(resp, options) {
+ var request = resp.priv;
+ if(options.callback) {
+ if(request.status >= 200 && request.status < 300) {
+ // success
+ if(resp.requestType != "delete") {
+ resp.features = this.parseFeatures(request);
+ }
+ resp.code = OpenLayers.Protocol.Response.SUCCESS;
+ } else {
+ // failure
+ resp.code = OpenLayers.Protocol.Response.FAILURE;
+ }
+ options.callback.call(options.scope, resp);
+ }
+ },
+
+ /**
+ * Method: parseFeatures
+ * Read HTTP response body and return features.
+ *
+ * Parameters:
+ * request - {XMLHttpRequest} The request object
+ *
+ * Returns:
+ * {Array({<OpenLayers.Feature.Vector>})} or
+ * {<OpenLayers.Feature.Vector>} Array of features or a single feature.
+ */
+ parseFeatures: function(request) {
+ var doc = request.responseXML;
+ if (!doc || !doc.documentElement) {
+ doc = request.responseText;
+ }
+ if (!doc || doc.length <= 0) {
+ return null;
+ }
+ return this.format.read(doc);
+ },
+
+ /**
+ * APIMethod: commit
+ * Iterate over each feature and take action based on the feature state.
+ * Possible actions are create, update and delete.
+ *
+ * Parameters:
+ * features - {Array({<OpenLayers.Feature.Vector>})}
+ * options - {Object} Optional object for setting up intermediate commit
+ * callbacks.
+ *
+ * Valid options:
+ * create - {Object} Optional object to be passed to the <create> method.
+ * update - {Object} Optional object to be passed to the <update> method.
+ * delete - {Object} Optional object to be passed to the <delete> method.
+ * callback - {Function} Optional function to be called when the commit
+ * is complete.
+ * scope - {Object} Optional object to be set as the scope of the callback.
+ *
+ * Returns:
+ * {Array(<OpenLayers.Protocol.Response>)} An array of response objects,
+ * one per request made to the server, each object's "priv" property
+ * references the corresponding HTTP request.
+ */
+ commit: function(features, options) {
+ options = OpenLayers.Util.applyDefaults(options, this.options);
+ var resp = [], nResponses = 0;
+
+ // Divide up features before issuing any requests. This properly
+ // counts requests in the event that any responses come in before
+ // all requests have been issued.
+ var types = {};
+ types[OpenLayers.State.INSERT] = [];
+ types[OpenLayers.State.UPDATE] = [];
+ types[OpenLayers.State.DELETE] = [];
+ var feature, list, requestFeatures = [];
+ for(var i=0, len=features.length; i<len; ++i) {
+ feature = features[i];
+ list = types[feature.state];
+ if(list) {
+ list.push(feature);
+ requestFeatures.push(feature);
+ }
+ }
+ // tally up number of requests
+ var nRequests = (types[OpenLayers.State.INSERT].length > 0 ? 1 : 0) +
+ types[OpenLayers.State.UPDATE].length +
+ types[OpenLayers.State.DELETE].length;
+
+ // This response will be sent to the final callback after all the others
+ // have been fired.
+ var success = true;
+ var finalResponse = new OpenLayers.Protocol.Response({
+ reqFeatures: requestFeatures
+ });
+
+ function insertCallback(response) {
+ var len = response.features ? response.features.length : 0;
+ var fids = new Array(len);
+ for(var i=0; i<len; ++i) {
+ fids[i] = response.features[i].fid;
+ }
+ finalResponse.insertIds = fids;
+ callback.apply(this, [response]);
+ }
+
+ function callback(response) {
+ this.callUserCallback(response, options);
+ success = success && response.success();
+ nResponses++;
+ if (nResponses >= nRequests) {
+ if (options.callback) {
+ finalResponse.code = success ?
+ OpenLayers.Protocol.Response.SUCCESS :
+ OpenLayers.Protocol.Response.FAILURE;
+ options.callback.apply(options.scope, [finalResponse]);
+ }
+ }
+ }
+
+ // start issuing requests
+ var queue = types[OpenLayers.State.INSERT];
+ if(queue.length > 0) {
+ resp.push(this.create(
+ queue, OpenLayers.Util.applyDefaults(
+ {callback: insertCallback, scope: this}, options.create
+ )
+ ));
+ }
+ queue = types[OpenLayers.State.UPDATE];
+ for(var i=queue.length-1; i>=0; --i) {
+ resp.push(this.update(
+ queue[i], OpenLayers.Util.applyDefaults(
+ {callback: callback, scope: this}, options.update
+ ))
+ );
+ }
+ queue = types[OpenLayers.State.DELETE];
+ for(var i=queue.length-1; i>=0; --i) {
+ resp.push(this["delete"](
+ queue[i], OpenLayers.Util.applyDefaults(
+ {callback: callback, scope: this}, options["delete"]
+ ))
+ );
+ }
+ return resp;
+ },
+
+ /**
+ * APIMethod: abort
+ * Abort an ongoing request, the response object passed to
+ * this method must come from this HTTP protocol (as a result
+ * of a create, read, update, delete or commit operation).
+ *
+ * Parameters:
+ * response - {<OpenLayers.Protocol.Response>}
+ */
+ abort: function(response) {
+ if (response) {
+ response.priv.abort();
+ }
+ },
+
+ /**
+ * Method: callUserCallback
+ * This method is used from within the commit method each time an
+ * an HTTP response is received from the server, it is responsible
+ * for calling the user-supplied callbacks.
+ *
+ * Parameters:
+ * resp - {<OpenLayers.Protocol.Response>}
+ * options - {Object} The map of options passed to the commit call.
+ */
+ callUserCallback: function(resp, options) {
+ var opt = options[resp.requestType];
+ if(opt && opt.callback) {
+ opt.callback.call(opt.scope, resp);
+ }
+ },
+
+ CLASS_NAME: "OpenLayers.Protocol.HTTP"
+});
+
+/**
+ * Property: OpenLayers.Protocol.HTTP.COMP_TYPE_TO_OP_STR
+ * {Object} A private class-level property mapping the
+ * OpenLayers.Filter.Comparison types to the operation
+ * strings of the protocol.
+ */
+(function() {
+ var o = OpenLayers.Protocol.HTTP.COMP_TYPE_TO_OP_STR = {};
+ o[OpenLayers.Filter.Comparison.EQUAL_TO] = "eq";
+ o[OpenLayers.Filter.Comparison.NOT_EQUAL_TO] = "ne";
+ o[OpenLayers.Filter.Comparison.LESS_THAN] = "lt";
+ o[OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO] = "lte";
+ o[OpenLayers.Filter.Comparison.GREATER_THAN] = "gt";
+ o[OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO] = "gte";
+ o[OpenLayers.Filter.Comparison.LIKE] = "ilike";
+})();
+
+/* ======================================================================
OpenLayers/Geometry/Curve.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -33135,37 +36302,37 @@
/**
* Class: OpenLayers.Geometry.Curve
- * A Curve is a MultiPoint, whose points are assumed to be connected. To
- * this end, we provide a "getLength()" function, which iterates through
- * the points, summing the distances between them.
- *
- * Inherits:
+ * A Curve is a MultiPoint, whose points are assumed to be connected. To
+ * this end, we provide a "getLength()" function, which iterates through
+ * the points, summing the distances between them.
+ *
+ * Inherits:
* - <OpenLayers.Geometry.MultiPoint>
*/
OpenLayers.Geometry.Curve = OpenLayers.Class(OpenLayers.Geometry.MultiPoint, {
/**
* Property: componentTypes
- * {Array(String)} An array of class names representing the types of
- * components that the collection can include. A null
+ * {Array(String)} An array of class names representing the types of
+ * components that the collection can include. A null
* value means the component types are not restricted.
*/
componentTypes: ["OpenLayers.Geometry.Point"],
/**
* Constructor: OpenLayers.Geometry.Curve
- *
+ *
* Parameters:
* point - {Array(<OpenLayers.Geometry.Point>)}
*/
initialize: function(points) {
- OpenLayers.Geometry.MultiPoint.prototype.initialize.apply(this,
+ OpenLayers.Geometry.MultiPoint.prototype.initialize.apply(this,
arguments);
},
-
+
/**
* APIMethod: getLength
- *
+ *
* Returns:
* {Float} The length of the curve
*/
@@ -33187,7 +36354,7 @@
* projection - {<OpenLayers.Projection>} The spatial reference system
* for the geometry coordinates. If not provided, Geographic/WGS84 is
* assumed.
- *
+ *
* Returns:
* {Float} The appoximate geodesic length of the geometry in meters.
*/
@@ -33221,8 +36388,9 @@
OpenLayers/Geometry/LineString.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -33231,9 +36399,9 @@
/**
* Class: OpenLayers.Geometry.LineString
- * A LineString is a Curve which, once two points have been added to it, can
+ * A LineString is a Curve which, once two points have been added to it, can
* never be less than two points long.
- *
+ *
* Inherits from:
* - <OpenLayers.Geometry.Curve>
*/
@@ -33249,24 +36417,24 @@
*
*/
initialize: function(points) {
- OpenLayers.Geometry.Curve.prototype.initialize.apply(this, arguments);
+ OpenLayers.Geometry.Curve.prototype.initialize.apply(this, arguments);
},
/**
* APIMethod: removeComponent
- * Only allows removal of a point if there are three or more points in
+ * Only allows removal of a point if there are three or more points in
* the linestring. (otherwise the result would be just a single point)
*
- * Parameters:
+ * Parameters:
* point - {<OpenLayers.Geometry.Point>} The point to be removed
*/
removeComponent: function(point) {
if ( this.components && (this.components.length > 2)) {
- OpenLayers.Geometry.Collection.prototype.removeComponent.apply(this,
+ OpenLayers.Geometry.Collection.prototype.removeComponent.apply(this,
arguments);
}
},
-
+
/**
* APIMethod: intersects
* Test for instersection between two geometries. This is a cheapo
@@ -33338,7 +36506,7 @@
}
return intersect;
},
-
+
/**
* Method: getSortedSegments
*
@@ -33350,7 +36518,7 @@
*/
getSortedSegments: function() {
var numSeg = this.components.length - 1;
- var segments = new Array(numSeg);
+ var segments = new Array(numSeg), point1, point2;
for(var i=0; i<numSeg; ++i) {
point1 = this.components[i];
point2 = this.components[i + 1];
@@ -33376,7 +36544,7 @@
}
return segments.sort(byX1);
},
-
+
/**
* Method: splitWithSegment
* Split this geometry with the given segment.
@@ -33473,7 +36641,7 @@
/**
* Method: split
* Use this geometry (the source) to attempt to split a target geometry.
- *
+ *
* Parameters:
* target - {<OpenLayers.Geometry>} The target geometry.
* options - {Object} Properties of this object will be used to determine
@@ -33488,7 +36656,7 @@
* tolerance - {Number} If a non-null value is provided, intersections
* within the tolerance distance of an existing vertex on the source
* will be assumed to occur at the vertex.
- *
+ *
* Returns:
* {Array} A list of geometries (of this same type as the target) that
* result from splitting the target with the source geometry. The
@@ -33592,7 +36760,7 @@
* tolerance - {Number} If a non-null value is provided, intersections
* within the tolerance distance of an existing vertex on the source
* will be assumed to occur at the vertex.
- *
+ *
* Returns:
* {Array} A list of geometries (of this same type as the target) that
* result from splitting the target with the source geometry. The
@@ -33698,7 +36866,7 @@
} else {
best = best.distance;
}
- } else if(geometry instanceof OpenLayers.Geometry.LineString) {
+ } else if(geometry instanceof OpenLayers.Geometry.LineString) {
var segs0 = this.getSortedSegments();
var segs1 = geometry.getSortedSegments();
var seg0, seg1, intersection, x0, y0;
@@ -33776,8 +36944,9 @@
OpenLayers/Geometry/LinearRing.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -33786,14 +36955,14 @@
/**
* Class: OpenLayers.Geometry.LinearRing
- *
- * A Linear Ring is a special LineString which is closed. It closes itself
+ *
+ * A Linear Ring is a special LineString which is closed. It closes itself
* automatically on every addPoint/removePoint by adding a copy of the first
- * point as the last point.
- *
+ * point as the last point.
+ *
* Also, as it is the first in the line family to close itself, a getArea()
* function is defined to calculate the enclosed area of the linearRing
- *
+ *
* Inherits:
* - <OpenLayers.Geometry.LineString>
*/
@@ -33802,8 +36971,8 @@
/**
* Property: componentTypes
- * {Array(String)} An array of class names representing the types of
- * components that the collection can include. A null
+ * {Array(String)} An array of class names representing the types of
+ * components that the collection can include. A null
* value means the component types are not restricted.
*/
componentTypes: ["OpenLayers.Geometry.Point"],
@@ -33815,12 +36984,12 @@
* point does not equal the first point), the constructor will close
* the ring. If the ring is already closed (the last point does equal
* the first point), it will be left closed.
- *
+ *
* Parameters:
* points - {Array(<OpenLayers.Geometry.Point>)} points
*/
initialize: function(points) {
- OpenLayers.Geometry.LineString.prototype.initialize.apply(this,
+ OpenLayers.Geometry.LineString.prototype.initialize.apply(this,
arguments);
},
@@ -33828,16 +36997,16 @@
* APIMethod: addComponent
* Adds a point to geometry components. If the point is to be added to
* the end of the components array and it is the same as the last point
- * already in that array, the duplicate point is not added. This has
- * the effect of closing the ring if it is not already closed, and
- * doing the right thing if it is already closed. This behavior can
- * be overridden by calling the method with a non-null index as the
+ * already in that array, the duplicate point is not added. This has
+ * the effect of closing the ring if it is not already closed, and
+ * doing the right thing if it is already closed. This behavior can
+ * be overridden by calling the method with a non-null index as the
* second argument.
*
* Parameter:
* point - {<OpenLayers.Geometry.Point>}
* index - {Integer} Index into the array to insert the component
- *
+ *
* Returns:
* {Boolean} Was the Point successfully added?
*/
@@ -33850,18 +37019,18 @@
// given an index, add the point
// without an index only add non-duplicate points
if(index != null || !point.equals(lastPoint)) {
- added = OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,
+ added = OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,
arguments);
}
//append copy of first point
var firstPoint = this.components[0];
- OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,
+ OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,
[firstPoint]);
-
+
return added;
},
-
+
/**
* APIMethod: removeComponent
* Removes a point from geometry components.
@@ -33874,17 +37043,17 @@
//remove last point
this.components.pop();
-
+
//remove our point
- OpenLayers.Geometry.Collection.prototype.removeComponent.apply(this,
+ OpenLayers.Geometry.Collection.prototype.removeComponent.apply(this,
arguments);
//append copy of first point
var firstPoint = this.components[0];
- OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,
+ OpenLayers.Geometry.Collection.prototype.addComponent.apply(this,
[firstPoint]);
}
},
-
+
/**
* APIMethod: move
* Moves a geometry by the given displacement along positive x and y axes.
@@ -33892,7 +37061,7 @@
* bounds.
*
* Parameters:
- * x - {Float} Distance to move geometry in positive x direction.
+ * x - {Float} Distance to move geometry in positive x direction.
* y - {Float} Distance to move geometry in positive y direction.
*/
move: function(x, y) {
@@ -33928,9 +37097,9 @@
* will have four times the area).
* origin - {<OpenLayers.Geometry.Point>} Point of origin for resizing
* ratio - {Float} Optional x:y ratio for resizing. Default ratio is 1.
- *
+ *
* Returns:
- * {OpenLayers.Geometry} - The current geometry.
+ * {OpenLayers.Geometry} - The current geometry.
*/
resize: function(scale, origin, ratio) {
for(var i=0, len=this.components.length; i<len - 1; ++i) {
@@ -33938,7 +37107,7 @@
}
return this;
},
-
+
/**
* APIMethod: transform
* Reproject the components geometry from source to dest.
@@ -33946,9 +37115,9 @@
* Parameters:
* source - {<OpenLayers.Projection>}
* dest - {<OpenLayers.Projection>}
- *
+ *
* Returns:
- * {<OpenLayers.Geometry>}
+ * {<OpenLayers.Geometry>}
*/
transform: function(source, dest) {
if (source && dest) {
@@ -33960,7 +37129,7 @@
}
return this;
},
-
+
/**
* APIMethod: getCentroid
*
@@ -33968,7 +37137,7 @@
* {<OpenLayers.Geometry.Point>} The centroid of the collection
*/
getCentroid: function() {
- if ( this.components && (this.components.length > 2)) {
+ if (this.components && (this.components.length > 2)) {
var sumX = 0.0;
var sumY = 0.0;
for (var i = 0; i < this.components.length - 1; i++) {
@@ -33980,15 +37149,17 @@
var area = -1 * this.getArea();
var x = sumX / (6 * area);
var y = sumY / (6 * area);
+ return new OpenLayers.Geometry.Point(x, y);
+ } else {
+ return null;
}
- return new OpenLayers.Geometry.Point(x, y);
},
/**
* APIMethod: getArea
* Note - The area is positive if the ring is oriented CW, otherwise
* it will be negative.
- *
+ *
* Returns:
* {Float} The signed area for a ring.
*/
@@ -34005,7 +37176,7 @@
}
return area;
},
-
+
/**
* APIMethod: getGeodesicArea
* Calculate the approximate area of the polygon were it projected onto
@@ -34016,7 +37187,7 @@
* projection - {<OpenLayers.Projection>} The spatial reference system
* for the geometry coordinates. If not provided, Geographic/WGS84 is
* assumed.
- *
+ *
* Reference:
* Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for
* Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion
@@ -34049,7 +37220,7 @@
}
return area;
},
-
+
/**
* Method: containsPoint
* Test if a point is inside a linear ring. For the case where a point
@@ -34081,7 +37252,7 @@
end = this.components[i + 1];
x2 = approx(end.x, digs);
y2 = approx(end.y, digs);
-
+
/**
* The following conditions enforce five edge-crossing rules:
* 1. points coincident with edges are considered contained;
@@ -34194,8 +37365,9 @@
OpenLayers/Geometry/MultiLineString.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -34207,10 +37379,10 @@
* Class: OpenLayers.Geometry.MultiLineString
* A MultiLineString is a geometry with multiple <OpenLayers.Geometry.LineString>
* components.
- *
+ *
* Inherits from:
* - <OpenLayers.Geometry.Collection>
- * - <OpenLayers.Geometry>
+ * - <OpenLayers.Geometry>
*/
OpenLayers.Geometry.MultiLineString = OpenLayers.Class(
OpenLayers.Geometry.Collection, {
@@ -34227,19 +37399,19 @@
* Constructor: OpenLayers.Geometry.MultiLineString
* Constructor for a MultiLineString Geometry.
*
- * Parameters:
- * components - {Array(<OpenLayers.Geometry.LineString>)}
+ * Parameters:
+ * components - {Array(<OpenLayers.Geometry.LineString>)}
*
*/
initialize: function(components) {
- OpenLayers.Geometry.Collection.prototype.initialize.apply(this,
- arguments);
+ OpenLayers.Geometry.Collection.prototype.initialize.apply(this,
+ arguments);
},
-
+
/**
* Method: split
* Use this geometry (the source) to attempt to split a target geometry.
- *
+ *
* Parameters:
* target - {<OpenLayers.Geometry>} The target geometry.
* options - {Object} Properties of this object will be used to determine
@@ -34254,7 +37426,7 @@
* tolerance - {Number} If a non-null value is provided, intersections
* within the tolerance distance of an existing vertex on the source
* will be assumed to occur at the vertex.
- *
+ *
* Returns:
* {Array} A list of geometries (of this same type as the target) that
* result from splitting the target with the source geometry. The
@@ -34274,7 +37446,7 @@
for(var i=0, len=this.components.length; i<len; ++i) {
sourceLine = this.components[i];
sourceSplit = false;
- for(var j=0; j < targetParts.length; ++j) {
+ for(var j=0; j < targetParts.length; ++j) {
splits = sourceLine.split(targetParts[j], options);
if(splits) {
if(mutual) {
@@ -34339,7 +37511,7 @@
}
return results;
},
-
+
/**
* Method: splitWith
* Split this geometry (the target) with the given geometry (the source).
@@ -34359,7 +37531,7 @@
* tolerance - {Number} If a non-null value is provided, intersections
* within the tolerance distance of an existing vertex on the source
* will be assumed to occur at the vertex.
- *
+ *
* Returns:
* {Array} A list of geometries (of this same type as the target) that
* result from splitting the target with the source geometry. The
@@ -34409,7 +37581,7 @@
);
}
}
- targetSplit = true;
+ targetSplit = true;
}
}
if(!targetSplit) {
@@ -34427,7 +37599,7 @@
])
];
}
-
+
}
}
} else {
@@ -34459,8 +37631,9 @@
OpenLayers/Handler/Path.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
@@ -34479,13 +37652,13 @@
* - <OpenLayers.Handler.Point>
*/
OpenLayers.Handler.Path = OpenLayers.Class(OpenLayers.Handler.Point, {
-
+
/**
* Property: line
* {<OpenLayers.Feature.Vector>}
*/
line: null,
-
+
/**
* Property: freehand
* {Boolean} In freehand mode, the handler starts the path on mouse down,
@@ -34494,7 +37667,7 @@
* click and double-click finishes the path.
*/
freehand: false,
-
+
/**
* Property: freehandToggle
* {String} If set, freehandToggle is checked on mouse events and will set
@@ -34529,7 +37702,7 @@
initialize: function(control, callbacks, options) {
OpenLayers.Handler.Point.prototype.initialize.apply(this, arguments);
},
-
+
/**
* Method: createFeature
* Add temporary geometries
@@ -34550,7 +37723,7 @@
this.point.geometry.clearBounds();
this.layer.addFeatures([this.line, this.point], {silent: true});
},
-
+
/**
* Method: destroyFeature
* Destroy temporary geometries
@@ -34569,7 +37742,7 @@
this.layer.removeFeatures([this.point]);
}
},
-
+
/**
* Method: addPoint
* Add point to geometry. Send the point index to override
@@ -34591,7 +37764,7 @@
this.callback("modify", [this.point.geometry, this.getSketch()]);
this.drawFeature();
},
-
+
/**
* Method: freehandMode
* Determine whether to behave in freehand mode or not.
@@ -34661,11 +37834,11 @@
* Method: mousedown
* Handle mouse down. Add a new point to the geometry and
* render it. Return determines whether to propagate the event on the map.
- *
+ *
* Parameters:
* evt - {Event} The browser event
*
- * Returns:
+ * Returns:
* {Boolean} Allow event propagation
*/
mousedown: function(evt) {
@@ -34691,15 +37864,15 @@
* Method: mousemove
* Handle mouse move. Adjust the geometry and redraw.
* Return determines whether to propagate the event on the map.
- *
+ *
* Parameters:
* evt - {Event} The browser event
*
- * Returns:
+ * Returns:
* {Boolean} Allow event propagation
*/
mousemove: function (evt) {
- if(this.drawing) {
+ if(this.drawing) {
if(this.mouseDown && this.freehandMode(evt)) {
this.addPoint(evt.xy);
} else {
@@ -34708,16 +37881,16 @@
}
return true;
},
-
+
/**
* Method: mouseup
* Handle mouse up. Send the latest point in the geometry to
* the control. Return determines whether to propagate the event on the map.
- *
+ *
* Parameters:
* evt - {Event} The browser event
*
- * Returns:
+ * Returns:
* {Boolean} Allow event propagation
*/
mouseup: function (evt) {
@@ -34736,16 +37909,16 @@
}
return true;
},
-
+
/**
- * Method: dblclick
+ * Method: dblclick
* Handle double-clicks. Finish the geometry and send it back
* to the control.
- *
+ *
* Parameters:
* evt - {Event} The browser event
*
- * Returns:
+ * Returns:
* {Boolean} Allow event propagation
*/
dblclick: function(evt) {
@@ -34764,8 +37937,9 @@
OpenLayers/Geometry/Polygon.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -34774,12 +37948,12 @@
*/
/**
- * Class: OpenLayers.Geometry.Polygon
- * Polygon is a collection of Geometry.LinearRings.
- *
+ * Class: OpenLayers.Geometry.Polygon
+ * Polygon is a collection of Geometry.LinearRings.
+ *
* Inherits from:
- * - <OpenLayers.Geometry.Collection>
- * - <OpenLayers.Geometry>
+ * - <OpenLayers.Geometry.Collection>
+ * - <OpenLayers.Geometry>
*/
OpenLayers.Geometry.Polygon = OpenLayers.Class(
OpenLayers.Geometry.Collection, {
@@ -34794,24 +37968,24 @@
/**
* Constructor: OpenLayers.Geometry.Polygon
- * Constructor for a Polygon geometry.
- * The first ring (this.component[0])is the outer bounds of the polygon and
+ * Constructor for a Polygon geometry.
+ * The first ring (this.component[0])is the outer bounds of the polygon and
* all subsequent rings (this.component[1-n]) are internal holes.
*
*
* Parameters:
- * components - {Array(<OpenLayers.Geometry.LinearRing>)}
+ * components - {Array(<OpenLayers.Geometry.LinearRing>)}
*/
initialize: function(components) {
- OpenLayers.Geometry.Collection.prototype.initialize.apply(this,
+ OpenLayers.Geometry.Collection.prototype.initialize.apply(this,
arguments);
},
-
- /**
+
+ /**
* APIMethod: getArea
- * Calculated by subtracting the areas of the internal holes from the
+ * Calculated by subtracting the areas of the internal holes from the
* area of the outer hole.
- *
+ *
* Returns:
* {float} The area of the geometry
*/
@@ -34826,7 +38000,7 @@
return area;
},
- /**
+ /**
* APIMethod: getGeodesicArea
* Calculate the approximate area of the polygon were it projected onto
* the earth.
@@ -34835,7 +38009,7 @@
* projection - {<OpenLayers.Projection>} The spatial reference system
* for the geometry coordinates. If not provided, Geographic/WGS84 is
* assumed.
- *
+ *
* Reference:
* Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for
* Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion
@@ -34886,7 +38060,7 @@
} else {
// in hole
contained = false;
- }
+ }
break;
}
}
@@ -34997,7 +38171,7 @@
/**
* APIMethod: createRegularPolygon
- * Create a regular polygon around a radius. Useful for creating circles
+ * Create a regular polygon around a radius. Useful for creating circles
* and the like.
*
* Parameters:
@@ -35006,7 +38180,7 @@
* sides - {Integer} Number of sides. 20 approximates a circle.
* rotation - {Float} original angle of rotation, in degrees.
*/
-OpenLayers.Geometry.Polygon.createRegularPolygon = function(origin, radius, sides, rotation) {
+OpenLayers.Geometry.Polygon.createRegularPolygon = function(origin, radius, sides, rotation) {
var angle = Math.PI * ((1/sides) - (1/2));
if(rotation) {
angle += (rotation / 180) * Math.PI;
@@ -35026,8 +38200,9 @@
OpenLayers/Geometry/MultiPolygon.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -35040,7 +38215,7 @@
* MultiPolygon is a geometry with multiple <OpenLayers.Geometry.Polygon>
* components. Create a new instance with the <OpenLayers.Geometry.MultiPolygon>
* constructor.
- *
+ *
* Inherits from:
* - <OpenLayers.Geometry.Collection>
*/
@@ -35065,7 +38240,7 @@
*
*/
initialize: function(components) {
- OpenLayers.Geometry.Collection.prototype.initialize.apply(this,
+ OpenLayers.Geometry.Collection.prototype.initialize.apply(this,
arguments);
},
@@ -35075,8 +38250,9 @@
OpenLayers/Handler/Polygon.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
@@ -35095,7 +38271,7 @@
* - <OpenLayers.Handler>
*/
OpenLayers.Handler.Polygon = OpenLayers.Class(OpenLayers.Handler.Path, {
-
+
/**
* Parameter: polygon
* {<OpenLayers.Feature.Vector>}
@@ -35127,7 +38303,7 @@
initialize: function(control, callbacks, options) {
OpenLayers.Handler.Path.prototype.initialize.apply(this, arguments);
},
-
+
/**
* Method: createFeature
* Add temporary geometries
@@ -35169,7 +38345,7 @@
this.layer.drawFeature(this.polygon, this.style);
this.layer.drawFeature(this.point, this.style);
},
-
+
/**
* Method: getSketch
* Return the sketch feature.
@@ -35201,9 +38377,9 @@
* Method: dblclick
* Handle double-clicks. Finish the geometry and send it back
* to the control.
- *
+ *
* Parameters:
- * evt - {Event}
+ * evt - {Event}
*/
dblclick: function(evt) {
if(!this.freehandMode(evt)) {
@@ -35222,8 +38398,9 @@
OpenLayers/Format/GML.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -35242,50 +38419,50 @@
* Class: OpenLayers.Format.GML
* Read/Wite GML. Create a new instance with the <OpenLayers.Format.GML>
* constructor. Supports the GML simple features profile.
- *
+ *
* Inherits from:
* - <OpenLayers.Format>
*/
OpenLayers.Format.GML = OpenLayers.Class(OpenLayers.Format.XML, {
-
+
/*
* APIProperty: featureNS
* {String} Namespace used for feature attributes. Default is
* "http://mapserver.gis.umn.edu/mapserver".
*/
featureNS: "http://mapserver.gis.umn.edu/mapserver",
-
+
/**
* APIProperty: featurePrefix
* {String} Namespace alias (or prefix) for feature nodes. Default is
* "feature".
*/
featurePrefix: "feature",
-
+
/*
* APIProperty: featureName
* {String} Element name for features. Default is "featureMember".
*/
- featureName: "featureMember",
-
+ featureName: "featureMember",
+
/*
* APIProperty: layerName
* {String} Name of data layer. Default is "features".
*/
layerName: "features",
-
+
/**
* APIProperty: geometryName
* {String} Name of geometry element. Defaults to "geometry".
*/
geometryName: "geometry",
-
- /**
+
+ /**
* APIProperty: collectionName
* {String} Name of featureCollection element.
*/
collectionName: "FeatureCollection",
-
+
/**
* APIProperty: gmlns
* {String} GML Namespace.
@@ -35297,14 +38474,14 @@
* {Boolean} Extract attributes from GML.
*/
extractAttributes: true,
-
+
/**
* APIProperty: xy
* {Boolean} Order of the GML coordinate true:(x,y) or false:(y,x)
* Changing is not recommended, a new Format should be instantiated.
- */
+ */
xy: true,
-
+
/**
* Constructor: OpenLayers.Format.GML
* Create a new parser for GML.
@@ -35326,8 +38503,8 @@
/**
* APIMethod: read
- * Read data from a string, and return a list of features.
- *
+ * Read data from a string, and return a list of features.
+ *
* Parameters:
* data - {String} or {DOMElement} data to read/parse.
*
@@ -35335,7 +38512,7 @@
* {Array(<OpenLayers.Feature.Vector>)} An array of features.
*/
read: function(data) {
- if(typeof data == "string") {
+ if(typeof data == "string") {
data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);
}
var featureNodes = this.getElementsByTagNameNS(data.documentElement,
@@ -35350,34 +38527,36 @@
}
return features;
},
-
+
/**
* Method: parseFeature
* This function is the core of the GML parsing code in OpenLayers.
* It creates the geometries that are then attached to the returned
* feature, and calls parseAttributes() to get attribute data out.
- *
+ *
* Parameters:
- * node - {DOMElement} A GML feature node.
+ * node - {DOMElement} A GML feature node.
*/
parseFeature: function(node) {
// only accept one geometry per feature - look for highest "order"
var order = ["MultiPolygon", "Polygon",
"MultiLineString", "LineString",
- "MultiPoint", "Point", "Envelope", "Box"];
+ "MultiPoint", "Point", "Envelope"];
+ // FIXME: In case we parse a feature with no geometry, but boundedBy an Envelope,
+ // this code creates a geometry derived from the Envelope. This is not correct.
var type, nodeList, geometry, parser;
for(var i=0; i<order.length; ++i) {
type = order[i];
nodeList = this.getElementsByTagNameNS(node, this.gmlns, type);
if(nodeList.length > 0) {
// only deal with first geometry of this type
- var parser = this.parseGeometry[type.toLowerCase()];
+ parser = this.parseGeometry[type.toLowerCase()];
if(parser) {
geometry = parser.apply(this, [nodeList[0]]);
if (this.internalProjection && this.externalProjection) {
- geometry.transform(this.externalProjection,
- this.internalProjection);
- }
+ geometry.transform(this.externalProjection,
+ this.internalProjection);
+ }
} else {
OpenLayers.Console.error(OpenLayers.i18n(
"unsupportedGeometryType", {'geomType':type}));
@@ -35387,19 +38566,35 @@
}
}
+ var bounds;
+ var boxNodes = this.getElementsByTagNameNS(node, this.gmlns, "Box");
+ for(i=0; i<boxNodes.length; ++i) {
+ var boxNode = boxNodes[i];
+ var box = this.parseGeometry["box"].apply(this, [boxNode]);
+ var parentNode = boxNode.parentNode;
+ var parentName = parentNode.localName ||
+ parentNode.nodeName.split(":").pop();
+ if(parentName === "boundedBy") {
+ bounds = box;
+ } else {
+ geometry = box.toGeometry();
+ }
+ }
+
// construct feature (optionally with attributes)
var attributes;
if(this.extractAttributes) {
attributes = this.parseAttributes(node);
}
var feature = new OpenLayers.Feature.Vector(geometry, attributes);
-
+ feature.bounds = bounds;
+
feature.gml = {
featureType: node.firstChild.nodeName.split(":")[1],
featureNS: node.firstChild.namespaceURI,
featureNSPrefix: node.firstChild.prefix
};
-
+
// assign fid - this can come from a "fid" or "id" attribute
var childNode = node.firstChild;
var fid;
@@ -35416,14 +38611,14 @@
feature.fid = fid;
return feature;
},
-
+
/**
* Property: parseGeometry
* Properties of this object are the functions that parse geometries based
* on their type.
*/
parseGeometry: {
-
+
/**
* Method: parseGeometry.point
* Given a GML node representing a point geometry, create an OpenLayers
@@ -35480,12 +38675,12 @@
}
}
}
-
+
// preserve third dimension
if(coords.length == 2) {
coords[2] = null;
}
-
+
if (this.xy) {
return new OpenLayers.Geometry.Point(coords[0], coords[1],
coords[2]);
@@ -35495,7 +38690,7 @@
coords[2]);
}
},
-
+
/**
* Method: parseGeometry.multipoint
* Given a GML node representing a multipoint geometry, create an
@@ -35522,7 +38717,7 @@
}
return new OpenLayers.Geometry.MultiPoint(components);
},
-
+
/**
* Method: parseGeometry.linestring
* Given a GML node representing a linestring geometry, create an
@@ -35604,7 +38799,7 @@
}
return line;
},
-
+
/**
* Method: parseGeometry.multilinestring
* Given a GML node representing a multilinestring geometry, create an
@@ -35632,7 +38827,7 @@
}
return new OpenLayers.Geometry.MultiLineString(components);
},
-
+
/**
* Method: parseGeometry.polygon
* Given a GML node representing a polygon geometry, create an
@@ -35661,7 +38856,7 @@
}
return new OpenLayers.Geometry.Polygon(components);
},
-
+
/**
* Method: parseGeometry.multipolygon
* Given a GML node representing a multipolygon geometry, create an
@@ -35689,22 +38884,22 @@
}
return new OpenLayers.Geometry.MultiPolygon(components);
},
-
+
envelope: function(node) {
var components = [];
var coordString;
var envelope;
-
+
var lpoint = this.getElementsByTagNameNS(node, this.gmlns, "lowerCorner");
if (lpoint.length > 0) {
var coords = [];
-
+
if(lpoint.length > 0) {
coordString = lpoint[0].firstChild.nodeValue;
coordString = coordString.replace(this.regExes.trimSpace, "");
coords = coordString.split(this.regExes.splitSpace);
}
-
+
if(coords.length == 2) {
coords[2] = null;
}
@@ -35714,17 +38909,17 @@
var lowerPoint = new OpenLayers.Geometry.Point(coords[1], coords[0],coords[2]);
}
}
-
+
var upoint = this.getElementsByTagNameNS(node, this.gmlns, "upperCorner");
if (upoint.length > 0) {
var coords = [];
-
+
if(upoint.length > 0) {
coordString = upoint[0].firstChild.nodeValue;
coordString = coordString.replace(this.regExes.trimSpace, "");
coords = coordString.split(this.regExes.splitSpace);
}
-
+
if(coords.length == 2) {
coords[2] = null;
}
@@ -35734,21 +38929,54 @@
var upperPoint = new OpenLayers.Geometry.Point(coords[1], coords[0],coords[2]);
}
}
-
+
if (lowerPoint && upperPoint) {
components.push(new OpenLayers.Geometry.Point(lowerPoint.x, lowerPoint.y));
components.push(new OpenLayers.Geometry.Point(upperPoint.x, lowerPoint.y));
components.push(new OpenLayers.Geometry.Point(upperPoint.x, upperPoint.y));
components.push(new OpenLayers.Geometry.Point(lowerPoint.x, upperPoint.y));
components.push(new OpenLayers.Geometry.Point(lowerPoint.x, lowerPoint.y));
-
+
var ring = new OpenLayers.Geometry.LinearRing(components);
envelope = new OpenLayers.Geometry.Polygon([ring]);
}
- return envelope;
+ return envelope;
+ },
+
+ /**
+ * Method: parseGeometry.box
+ * Given a GML node representing a box geometry, create an
+ * OpenLayers.Bounds.
+ *
+ * Parameters:
+ * node - {DOMElement} A GML node.
+ *
+ * Returns:
+ * {<OpenLayers.Bounds>} A bounds representing the box.
+ */
+ box: function(node) {
+ var nodeList = this.getElementsByTagNameNS(node, this.gmlns,
+ "coordinates");
+ var coordString;
+ var coords, beginPoint = null, endPoint = null;
+ if (nodeList.length > 0) {
+ coordString = nodeList[0].firstChild.nodeValue;
+ coords = coordString.split(" ");
+ if (coords.length == 2) {
+ beginPoint = coords[0].split(",");
+ endPoint = coords[1].split(",");
+ }
+ }
+ if (beginPoint !== null && endPoint !== null) {
+ return new OpenLayers.Bounds(parseFloat(beginPoint[0]),
+ parseFloat(beginPoint[1]),
+ parseFloat(endPoint[0]),
+ parseFloat(endPoint[1]) );
+ }
}
+
},
-
+
/**
* Method: parseAttributes
*
@@ -35797,11 +39025,11 @@
}
return attributes;
},
-
+
/**
* APIMethod: write
- * Generate a GML document string given a list of features.
- *
+ * Generate a GML document string given a list of features.
+ *
* Parameters:
* features - {Array(<OpenLayers.Feature.Vector>)} List of features to
* serialize into a string.
@@ -35821,7 +39049,7 @@
return OpenLayers.Format.XML.prototype.write.apply(this, [gml]);
},
- /**
+ /**
* Method: createFeatureXML
* Accept an OpenLayers.Feature.Vector, and build a GML node for it.
*
@@ -35847,27 +39075,27 @@
featureContainer.setAttribute("fid", fid);
featureContainer.appendChild(geomContainer);
for(var attr in feature.attributes) {
- var attrText = this.createTextNode(feature.attributes[attr]);
+ var attrText = this.createTextNode(feature.attributes[attr]);
var nodename = attr.substring(attr.lastIndexOf(":") + 1);
var attrContainer = this.createElementNS(this.featureNS,
this.featurePrefix + ":" +
nodename);
attrContainer.appendChild(attrText);
featureContainer.appendChild(attrContainer);
- }
+ }
featureNode.appendChild(featureContainer);
return featureNode;
},
-
+
/**
* APIMethod: buildGeometryNode
*/
buildGeometryNode: function(geometry) {
if (this.externalProjection && this.internalProjection) {
geometry = geometry.clone();
- geometry.transform(this.internalProjection,
+ geometry.transform(this.internalProjection,
this.externalProjection);
- }
+ }
var className = geometry.CLASS_NAME;
var type = className.substring(className.lastIndexOf(".") + 1);
var builder = this.buildGeometry[type.toLowerCase()];
@@ -35900,7 +39128,7 @@
gml.appendChild(this.buildCoordinatesNode(geometry));
return gml;
},
-
+
/**
* Method: buildGeometry.multipoint
* Given an OpenLayers multipoint geometry, create a GML multipoint.
@@ -35915,7 +39143,7 @@
var gml = this.createElementNS(this.gmlns, "gml:MultiPoint");
var points = geometry.components;
var pointMember, pointGeom;
- for(var i=0; i<points.length; i++) {
+ for(var i=0; i<points.length; i++) {
pointMember = this.createElementNS(this.gmlns,
"gml:pointMember");
pointGeom = this.buildGeometry.point.apply(this,
@@ -35923,9 +39151,9 @@
pointMember.appendChild(pointGeom);
gml.appendChild(pointMember);
}
- return gml;
+ return gml;
},
-
+
/**
* Method: buildGeometry.linestring
* Given an OpenLayers linestring geometry, create a GML linestring.
@@ -35941,7 +39169,7 @@
gml.appendChild(this.buildCoordinatesNode(geometry));
return gml;
},
-
+
/**
* Method: buildGeometry.multilinestring
* Given an OpenLayers multilinestring geometry, create a GML
@@ -35968,7 +39196,7 @@
}
return gml;
},
-
+
/**
* Method: buildGeometry.linearring
* Given an OpenLayers linearring geometry, create a GML linearring.
@@ -35984,7 +39212,7 @@
gml.appendChild(this.buildCoordinatesNode(geometry));
return gml;
},
-
+
/**
* Method: buildGeometry.polygon
* Given an OpenLayers polygon geometry, create a GML polygon.
@@ -36010,7 +39238,7 @@
}
return gml;
},
-
+
/**
* Method: buildGeometry.multipolygon
* Given an OpenLayers multipolygon geometry, create a GML multipolygon.
@@ -36037,7 +39265,7 @@
return gml;
},
-
+
/**
* Method: buildGeometry.bounds
* Given an OpenLayers bounds, create a GML box.
@@ -36061,8 +39289,8 @@
* (code)
* <gml:coordinates decimal="." cs="," ts=" ">...</gml:coordinates>
* (end)
- * Parameters:
- * geometry - {<OpenLayers.Geometry>}
+ * Parameters:
+ * geometry - {<OpenLayers.Geometry>}
*
* Returns:
* {XmlNode} created xmlNode
@@ -36082,24 +39310,25 @@
} else {
var points = (geometry.components) ? geometry.components : [geometry];
for(var i=0; i<points.length; i++) {
- parts.push(points[i].x + "," + points[i].y);
- }
+ parts.push(points[i].x + "," + points[i].y);
+ }
}
var txtNode = this.createTextNode(parts.join(" "));
coordinatesNode.appendChild(txtNode);
-
+
return coordinatesNode;
},
- CLASS_NAME: "OpenLayers.Format.GML"
+ CLASS_NAME: "OpenLayers.Format.GML"
});
/* ======================================================================
OpenLayers/Format/GML/Base.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -36123,7 +39352,7 @@
* - <OpenLayers.Format.XML>
*/
OpenLayers.Format.GML.Base = OpenLayers.Class(OpenLayers.Format.XML, {
-
+
/**
* Property: namespaces
* {Object} Mapping of namespace aliases to namespace URIs.
@@ -36134,7 +39363,7 @@
xsi: "http://www.w3.org/2001/XMLSchema-instance",
wfs: "http://www.opengis.net/wfs" // this is a convenience for reading wfs:FeatureCollection
},
-
+
/**
* Property: defaultPrefix
*/
@@ -36145,13 +39374,13 @@
* {String} Schema location for a particular minor version.
*/
schemaLocation: null,
-
+
/**
* APIProperty: featureType
* {Array(String) or String} The local (without prefix) feature typeName(s).
*/
featureType: null,
-
+
/**
* APIProperty: featureNS
* {String} The feature namespace. Must be set in the options at
@@ -36170,7 +39399,7 @@
* {Boolean} Extract attributes from GML. Default is true.
*/
extractAttributes: true,
-
+
/**
* APIProperty: srsName
* {String} URI for spatial reference system. This is optional for
@@ -36184,7 +39413,7 @@
* APIProperty: xy
* {Boolean} Order of the GML coordinate true:(x,y) or false:(y,x)
* Changing is not recommended, a new Format should be instantiated.
- */
+ */
xy: true,
/**
@@ -36223,7 +39452,7 @@
* this instance.
*
* Valid options properties:
- * featureType - {Array(String) or String} Local (without prefix) feature
+ * featureType - {Array(String) or String} Local (without prefix) feature
* typeName(s) (required).
* featureNS - {String} Feature namespace (required).
* geometryName - {String} Geometry element name.
@@ -36236,7 +39465,7 @@
}
this.singleFeatureType = !options || (typeof options.featureType === "string");
},
-
+
/**
* Method: read
*
@@ -36248,7 +39477,7 @@
* {Array(<OpenLayers.Feature.Vector>)} An array of features.
*/
read: function(data) {
- if(typeof data == "string") {
+ if(typeof data == "string") {
data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);
}
if(data && data.nodeType == 9) {
@@ -36278,7 +39507,7 @@
}
return features;
},
-
+
/**
* Property: readers
* Contains public functions, grouped by namespace prefix, that will
@@ -36293,7 +39522,7 @@
this.readChildNodes(node, obj);
},
"featureMembers": function(node, obj) {
- this.readChildNodes(node, obj);
+ this.readChildNodes(node, obj);
},
"name": function(node, obj) {
obj.name = this.getChildValue(node);
@@ -36431,12 +39660,17 @@
// geometry or attributes.
var name;
var local = node.localName || node.nodeName.split(":").pop();
- if (!this.singleFeatureType &&
- (OpenLayers.Util.indexOf(this.featureType, local) != -1)) {
+ // Since an attribute can have the same name as the feature type
+ // we only want to read the node as a feature if the parent
+ // node can have feature nodes as children. In this case, the
+ // obj.features property is set.
+ if (obj.features) {
+ if (!this.singleFeatureType &&
+ (OpenLayers.Util.indexOf(this.featureType, local) !== -1)) {
name = "_typeName";
- }
- else if(local == this.featureType) {
- name = "_typeName";
+ } else if(local === this.featureType) {
+ name = "_typeName";
+ }
} else {
// Assume attribute elements have one child node and that the child
// is a text node. Otherwise assume it is a geometry node.
@@ -36479,7 +39713,7 @@
);
}
if(container.bounds) {
- feature.geometry.bounds = container.bounds;
+ feature.bounds = container.bounds;
}
obj.features.push(feature);
},
@@ -36498,7 +39732,7 @@
}
}
},
-
+
/**
* Method: write
*
@@ -36526,7 +39760,7 @@
return OpenLayers.Format.XML.prototype.write.apply(this, [root]);
},
-
+
/**
* Property: writers
* As a compliment to the readers property, this structure contains public
@@ -36616,7 +39850,7 @@
geometry = geometry.clone().transform(
this.internalProjection, this.externalProjection
);
- }
+ }
var node = this.createElementNSPlus(
"feature:" + this.geometryName
);
@@ -36650,7 +39884,7 @@
}
}
},
-
+
/**
* Function: setGeometryTypes
* Sets the <geometryTypes> mapping.
@@ -36667,15 +39901,16 @@
};
},
- CLASS_NAME: "OpenLayers.Format.GML.Base"
+ CLASS_NAME: "OpenLayers.Format.GML.Base"
});
/* ======================================================================
OpenLayers/Format/GML/v2.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -36690,7 +39925,7 @@
* - <OpenLayers.Format.GML.Base>
*/
OpenLayers.Format.GML.v2 = OpenLayers.Class(OpenLayers.Format.GML.Base, {
-
+
/**
* Property: schemaLocation
* {String} Schema location for a particular minor version.
@@ -36862,16 +40097,17 @@
"feature": OpenLayers.Format.GML.Base.prototype.writers["feature"],
"wfs": OpenLayers.Format.GML.Base.prototype.writers["wfs"]
},
+
+ CLASS_NAME: "OpenLayers.Format.GML.v2"
- CLASS_NAME: "OpenLayers.Format.GML.v2"
-
});
/* ======================================================================
OpenLayers/Format/GML/v3.js
====================================================================== */
-/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
- * license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
+/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
+ * full list of contributors). Published under the Clear BSD license.
+ * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
@@ -36886,7 +40122,7 @@
* - <OpenLayers.Format.GML.Base>
*/
OpenLayers.Format.GML.v3 = OpenLayers.Class(OpenLayers.Format.GML.Base, {
-
+
/**
* Property: schemaLocation
* {String} Schema location for a particular minor version. The writers
@@ -36903,7 +40139,7 @@
* instantiation).
*/
curve: false,
-
+
/**
* Property: multiCurve
* {Boolean} Write gml:MultiCurve instead of gml:MultiLineString. Since
@@ -36913,7 +40149,7 @@
* instantiation).
*/
multiCurve: true,
-
+
/**
* Property: surface
* {Boolean} Write gml:Surface instead of gml:Polygon elements. This also
@@ -37102,11 +40338,11 @@
this.readers.gml.pos.apply(this, [node, obj]);
container.points[1] = obj.points[0];
}
- }, OpenLayers.Format.GML.Base.prototype.readers["gml"]),
+ }, OpenLayers.Format.GML.Base.prototype.readers["gml"]),
"feature": OpenLayers.Format.GML.Base.prototype.readers["feature"],
"wfs": OpenLayers.Format.GML.Base.prototype.readers["wfs"]
},
-
+
/**
* Method: write
*
@@ -37198,7 +40434,7 @@
}
return this.createElementNSPlus("gml:posList", {
value: parts.join(" ")
- });
+ });
},
"Surface": function(geometry) {
var node = this.createElementNSPlus("gml:Surface");
@@ -37327,7 +40563,7 @@
"OpenLayers.Geometry.Collection": "GeometryCollection"
};
},
+
+ CLASS_NAME: "OpenLayers.Format.GML.v3"
- CLASS_NAME: "OpenLayers.Format.GML.v3"
-
});
Modified: branches/fusion-2.2/lib/fusion.js
===================================================================
--- branches/fusion-2.2/lib/fusion.js 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/lib/fusion.js 2010-09-24 18:32:16 UTC (rev 2234)
@@ -1365,6 +1365,7 @@
'lib/MGBroker.js',
'lib/Widget.js',
'lib/Map.js',
+ 'lib/MapMessage.js',
'layers/Layers.js',
'lib/Search.js',
'text/en.json'];
@@ -1510,11 +1511,13 @@
if(appDefXML){
var googleElement = appDefXML.getElementsByTagName("GoogleScript")[0];
var yahooElement = appDefXML.getElementsByTagName("YahooScript")[0];
- var veElement = appDefXML.getElementsByTagName("VirtualEarthScript")[0];
+ var veElement = appDefXML.getElementsByTagName("VirtualEarthScript")[0];
+ var osmElement = appDefXML.getElementsByTagName("OpenStreetMapScript")[0];
addElement(googleElement);
addElement(yahooElement);
addElement(veElement);
+ addElement(osmElement);
}
}
Copied: branches/fusion-2.2/lib/proj4js-combined.js (from rev 2233, trunk/lib/proj4js-combined.js)
===================================================================
--- branches/fusion-2.2/lib/proj4js-combined.js (rev 0)
+++ branches/fusion-2.2/lib/proj4js-combined.js 2010-09-24 18:32:16 UTC (rev 2234)
@@ -0,0 +1,5142 @@
+/*
+ proj4js.js -- Javascript reprojection library.
+
+ Authors: Mike Adair madairATdmsolutions.ca
+ Richard Greenwood richATgreenwoodmap.com
+ Didier Richard didier.richardATign.fr
+ Stephen Irons
+ License: LGPL as per: http://www.gnu.org/copyleft/lesser.html
+ Note: This program is an almost direct port of the C library
+ Proj4.
+*/
+/* ======================================================================
+ proj4js.js
+ ====================================================================== */
+
+/*
+Author: Mike Adair madairATdmsolutions.ca
+ Richard Greenwood rich at greenwoodmap.com
+License: LGPL as per: http://www.gnu.org/copyleft/lesser.html
+
+$Id: Proj.js 2956 2007-07-09 12:17:52Z steven $
+*/
+
+/**
+ * Namespace: Proj4js
+ *
+ * Proj4js is a JavaScript library to transform point coordinates from one
+ * coordinate system to another, including datum transformations.
+ *
+ * This library is a port of both the Proj.4 and GCTCP C libraries to JavaScript.
+ * Enabling these transformations in the browser allows geographic data stored
+ * in different projections to be combined in browser-based web mapping
+ * applications.
+ *
+ * Proj4js must have access to coordinate system initialization strings (which
+ * are the same as for PROJ.4 command line). Thes can be included in your
+ * application using a <script> tag or Proj4js can load CS initialization
+ * strings from a local directory or a web service such as spatialreference.org.
+ *
+ * Similarly, Proj4js must have access to projection transform code. These can
+ * be included individually using a <script> tag in your page, built into a
+ * custom build of Proj4js or loaded dynamically at run-time. Using the
+ * -combined and -compressed versions of Proj4js includes all projection class
+ * code by default.
+ *
+ * Note that dynamic loading of defs and code happens ascynchrously, check the
+ * Proj.readyToUse flag before using the Proj object. If the defs and code
+ * required by your application are loaded through script tags, dynamic loading
+ * is not required and the Proj object will be readyToUse on return from the
+ * constructor.
+ *
+ * All coordinates are handled as points which have a .x and a .y property
+ * which will be modified in place.
+ *
+ * Override Proj4js.reportError for output of alerts and warnings.
+ *
+ * See http://trac.osgeo.org/proj4js/wiki/UserGuide for full details.
+*/
+
+/**
+ * Global namespace object for Proj4js library
+ */
+Proj4js = {
+
+ /**
+ * Property: defaultDatum
+ * The datum to use when no others a specified
+ */
+ defaultDatum: 'WGS84', //default datum
+
+ /**
+ * Method: transform(source, dest, point)
+ * Transform a point coordinate from one map projection to another. This is
+ * really the only public method you should need to use.
+ *
+ * Parameters:
+ * source - {Proj4js.Proj} source map projection for the transformation
+ * dest - {Proj4js.Proj} destination map projection for the transformation
+ * point - {Object} point to transform, may be geodetic (long, lat) or
+ * projected Cartesian (x,y), but should always have x,y properties.
+ */
+ transform: function(source, dest, point) {
+ if (!source.readyToUse) {
+ this.reportError("Proj4js initialization for:"+source.srsCode+" not yet complete");
+ return point;
+ }
+ if (!dest.readyToUse) {
+ this.reportError("Proj4js initialization for:"+dest.srsCode+" not yet complete");
+ return point;
+ }
+
+ // Workaround for Spherical Mercator
+ if ((source.srsProjNumber =="900913" && dest.datumCode != "WGS84") ||
+ (dest.srsProjNumber == "900913" && source.datumCode != "WGS84")) {
+ var wgs84 = Proj4js.WGS84;
+ this.transform(source, wgs84, point);
+ source = wgs84;
+ }
+
+ // Transform source points to long/lat, if they aren't already.
+ if ( source.projName=="longlat") {
+ point.x *= Proj4js.common.D2R; // convert degrees to radians
+ point.y *= Proj4js.common.D2R;
+ } else {
+ if (source.to_meter) {
+ point.x *= source.to_meter;
+ point.y *= source.to_meter;
+ }
+ source.inverse(point); // Convert Cartesian to longlat
+ }
+
+ // Adjust for the prime meridian if necessary
+ if (source.from_greenwich) {
+ point.x += source.from_greenwich;
+ }
+
+ // Convert datums if needed, and if possible.
+ point = this.datum_transform( source.datum, dest.datum, point );
+
+ // Adjust for the prime meridian if necessary
+ if (dest.from_greenwich) {
+ point.x -= dest.from_greenwich;
+ }
+
+ if( dest.projName=="longlat" ) {
+ // convert radians to decimal degrees
+ point.x *= Proj4js.common.R2D;
+ point.y *= Proj4js.common.R2D;
+ } else { // else project
+ dest.forward(point);
+ if (dest.to_meter) {
+ point.x /= dest.to_meter;
+ point.y /= dest.to_meter;
+ }
+ }
+ return point;
+ }, // transform()
+
+ /** datum_transform()
+ source coordinate system definition,
+ destination coordinate system definition,
+ point to transform in geodetic coordinates (long, lat, height)
+ */
+ datum_transform : function( source, dest, point ) {
+
+ // Short cut if the datums are identical.
+ if( source.compare_datums( dest ) ) {
+ return point; // in this case, zero is sucess,
+ // whereas cs_compare_datums returns 1 to indicate TRUE
+ // confusing, should fix this
+ }
+
+ // Explicitly skip datum transform by setting 'datum=none' as parameter for either source or dest
+ if( source.datum_type == Proj4js.common.PJD_NODATUM
+ || dest.datum_type == Proj4js.common.PJD_NODATUM) {
+ return point;
+ }
+
+ // If this datum requires grid shifts, then apply it to geodetic coordinates.
+ if( source.datum_type == Proj4js.common.PJD_GRIDSHIFT )
+ {
+ alert("ERROR: Grid shift transformations are not implemented yet.");
+ /*
+ pj_apply_gridshift( pj_param(source.params,"snadgrids").s, 0,
+ point_count, point_offset, x, y, z );
+ CHECK_RETURN;
+
+ src_a = SRS_WGS84_SEMIMAJOR;
+ src_es = 0.006694379990;
+ */
+ }
+
+ if( dest.datum_type == Proj4js.common.PJD_GRIDSHIFT )
+ {
+ alert("ERROR: Grid shift transformations are not implemented yet.");
+ /*
+ dst_a = ;
+ dst_es = 0.006694379990;
+ */
+ }
+
+ // Do we need to go through geocentric coordinates?
+ if( source.es != dest.es || source.a != dest.a
+ || source.datum_type == Proj4js.common.PJD_3PARAM
+ || source.datum_type == Proj4js.common.PJD_7PARAM
+ || dest.datum_type == Proj4js.common.PJD_3PARAM
+ || dest.datum_type == Proj4js.common.PJD_7PARAM)
+ {
+
+ // Convert to geocentric coordinates.
+ source.geodetic_to_geocentric( point );
+ // CHECK_RETURN;
+
+ // Convert between datums
+ if( source.datum_type == Proj4js.common.PJD_3PARAM || source.datum_type == Proj4js.common.PJD_7PARAM ) {
+ source.geocentric_to_wgs84(point);
+ // CHECK_RETURN;
+ }
+
+ if( dest.datum_type == Proj4js.common.PJD_3PARAM || dest.datum_type == Proj4js.common.PJD_7PARAM ) {
+ dest.geocentric_from_wgs84(point);
+ // CHECK_RETURN;
+ }
+
+ // Convert back to geodetic coordinates
+ dest.geocentric_to_geodetic( point );
+ // CHECK_RETURN;
+ }
+
+ // Apply grid shift to destination if required
+ if( dest.datum_type == Proj4js.common.PJD_GRIDSHIFT )
+ {
+ alert("ERROR: Grid shift transformations are not implemented yet.");
+ // pj_apply_gridshift( pj_param(dest.params,"snadgrids").s, 1, point);
+ // CHECK_RETURN;
+ }
+ return point;
+ }, // cs_datum_transform
+
+ /**
+ * Function: reportError
+ * An internal method to report errors back to user.
+ * Override this in applications to report error messages or throw exceptions.
+ */
+ reportError: function(msg) {
+ //console.log(msg);
+ },
+
+/**
+ *
+ * Title: Private Methods
+ * The following properties and methods are intended for internal use only.
+ *
+ * This is a minimal implementation of JavaScript inheritance methods so that
+ * Proj4js can be used as a stand-alone library.
+ * These are copies of the equivalent OpenLayers methods at v2.7
+ */
+
+/**
+ * Function: extend
+ * Copy all properties of a source object to a destination object. Modifies
+ * the passed in destination object. Any properties on the source object
+ * that are set to undefined will not be (re)set on the destination object.
+ *
+ * Parameters:
+ * destination - {Object} The object that will be modified
+ * source - {Object} The object with properties to be set on the destination
+ *
+ * Returns:
+ * {Object} The destination object.
+ */
+ extend: function(destination, source) {
+ destination = destination || {};
+ if(source) {
+ for(var property in source) {
+ var value = source[property];
+ if(value !== undefined) {
+ destination[property] = value;
+ }
+ }
+ }
+ return destination;
+ },
+
+/**
+ * Constructor: Class
+ * Base class used to construct all other classes. Includes support for
+ * multiple inheritance.
+ *
+ */
+ Class: function() {
+ var Class = function() {
+ this.initialize.apply(this, arguments);
+ };
+
+ var extended = {};
+ var parent;
+ for(var i=0; i<arguments.length; ++i) {
+ if(typeof arguments[i] == "function") {
+ // get the prototype of the superclass
+ parent = arguments[i].prototype;
+ } else {
+ // in this case we're extending with the prototype
+ parent = arguments[i];
+ }
+ Proj4js.extend(extended, parent);
+ }
+ Class.prototype = extended;
+
+ return Class;
+ },
+
+ /**
+ * Function: bind
+ * Bind a function to an object. Method to easily create closures with
+ * 'this' altered.
+ *
+ * Parameters:
+ * func - {Function} Input function.
+ * object - {Object} The object to bind to the input function (as this).
+ *
+ * Returns:
+ * {Function} A closure with 'this' set to the passed in object.
+ */
+ bind: function(func, object) {
+ // create a reference to all arguments past the second one
+ var args = Array.prototype.slice.apply(arguments, [2]);
+ return function() {
+ // Push on any additional arguments from the actual function call.
+ // These will come after those sent to the bind call.
+ var newArgs = args.concat(
+ Array.prototype.slice.apply(arguments, [0])
+ );
+ return func.apply(object, newArgs);
+ };
+ },
+
+/**
+ * The following properties and methods handle dynamic loading of JSON objects.
+ *
+ /**
+ * Property: scriptName
+ * {String} The filename of this script without any path.
+ */
+ scriptName: "proj4js-combined.js",
+
+ /**
+ * Property: defsLookupService
+ * AJAX service to retreive projection definition parameters from
+ */
+ defsLookupService: 'http://spatialreference.org/ref',
+
+ /**
+ * Property: libPath
+ * internal: http server path to library code.
+ */
+ libPath: null,
+
+ /**
+ * Function: getScriptLocation
+ * Return the path to this script.
+ *
+ * Returns:
+ * Path to this script
+ */
+ getScriptLocation: function () {
+ if (this.libPath) return this.libPath;
+ var scriptName = this.scriptName;
+ var scriptNameLen = scriptName.length;
+
+ var scripts = document.getElementsByTagName('script');
+ for (var i = 0; i < scripts.length; i++) {
+ var src = scripts[i].getAttribute('src');
+ if (src) {
+ var index = src.lastIndexOf(scriptName);
+ // is it found, at the end of the URL?
+ if ((index > -1) && (index + scriptNameLen == src.length)) {
+ this.libPath = src.slice(0, -scriptNameLen);
+ break;
+ }
+ }
+ }
+ return this.libPath||"";
+ },
+
+ /**
+ * Function: loadScript
+ * Load a JS file from a URL into a <script> tag in the page.
+ *
+ * Parameters:
+ * url - {String} The URL containing the script to load
+ * onload - {Function} A method to be executed when the script loads successfully
+ * onfail - {Function} A method to be executed when there is an error loading the script
+ * loadCheck - {Function} A boolean method that checks to see if the script
+ * has loaded. Typically this just checks for the existance of
+ * an object in the file just loaded.
+ */
+ loadScript: function(url, onload, onfail, loadCheck) {
+ var script = document.createElement('script');
+ script.defer = false;
+ script.type = "text/javascript";
+ script.id = url;
+ script.src = url;
+ script.onload = onload;
+ script.onerror = onfail;
+ script.loadCheck = loadCheck;
+ if (/MSIE/.test(navigator.userAgent)) {
+ script.onreadystatechange = this.checkReadyState;
+ }
+ document.getElementsByTagName('head')[0].appendChild(script);
+ },
+
+ /**
+ * Function: checkReadyState
+ * IE workaround since there is no onerror handler. Calls the user defined
+ * loadCheck method to determine if the script is loaded.
+ *
+ */
+ checkReadyState: function() {
+ if (this.readyState == 'loaded') {
+ if (!this.loadCheck()) {
+ this.onerror();
+ } else {
+ this.onload();
+ }
+ }
+ }
+};
+
+/**
+ * Class: Proj4js.Proj
+ *
+ * Proj objects provide transformation methods for point coordinates
+ * between geodetic latitude/longitude and a projected coordinate system.
+ * once they have been initialized with a projection code.
+ *
+ * Initialization of Proj objects is with a projection code, usually EPSG codes,
+ * which is the key that will be used with the Proj4js.defs array.
+ *
+ * The code passed in will be stripped of colons and converted to uppercase
+ * to locate projection definition files.
+ *
+ * A projection object has properties for units and title strings.
+ */
+Proj4js.Proj = Proj4js.Class({
+
+ /**
+ * Property: readyToUse
+ * Flag to indicate if initialization is complete for this Proj object
+ */
+ readyToUse: false,
+
+ /**
+ * Property: title
+ * The title to describe the projection
+ */
+ title: null,
+
+ /**
+ * Property: projName
+ * The projection class for this projection, e.g. lcc (lambert conformal conic,
+ * or merc for mercator). These are exactly equivalent to their Proj4
+ * counterparts.
+ */
+ projName: null,
+ /**
+ * Property: units
+ * The units of the projection. Values include 'm' and 'degrees'
+ */
+ units: null,
+ /**
+ * Property: datum
+ * The datum specified for the projection
+ */
+ datum: null,
+ /**
+ * Property: x0
+ * The x coordinate origin
+ */
+ x0: 0,
+ /**
+ * Property: y0
+ * The y coordinate origin
+ */
+ y0: 0,
+ /**
+ * Property: localCS
+ * Flag to indicate if the projection is a local one in which no transforms
+ * are required.
+ */
+ localCS: false,
+
+ /**
+ * Constructor: initialize
+ * Constructor for Proj4js.Proj objects
+ *
+ * Parameters:
+ * srsCode - a code for map projection definition parameters. These are usually
+ * (but not always) EPSG codes.
+ */
+ initialize: function(srsCode) {
+ this.srsCodeInput = srsCode;
+
+ //check to see if this is a WKT string
+ if ((srsCode.indexOf('GEOGCS') >= 0) ||
+ (srsCode.indexOf('GEOCCS') >= 0) ||
+ (srsCode.indexOf('PROJCS') >= 0) ||
+ (srsCode.indexOf('LOCAL_CS') >= 0)) {
+ this.parseWKT(srsCode);
+ this.datum = new Proj4js.datum(this);
+ this.loadProjCode(this.projName);
+ return;
+ }
+
+ // DGR 2008-08-03 : support urn and url
+ if (srsCode.indexOf('urn:') == 0) {
+ //urn:ORIGINATOR:def:crs:CODESPACE:VERSION:ID
+ var urn = srsCode.split(':');
+ if ((urn[1] == 'ogc' || urn[1] =='x-ogc') &&
+ (urn[2] =='def') &&
+ (urn[3] =='crs')) {
+ srsCode = urn[4]+':'+urn[urn.length-1];
+ }
+ } else if (srsCode.indexOf('http://') == 0) {
+ //url#ID
+ var url = srsCode.split('#');
+ if (url[0].match(/epsg.org/)) {
+ // http://www.epsg.org/#
+ srsCode = 'EPSG:'+url[1];
+ } else if (url[0].match(/RIG.xml/)) {
+ //http://librairies.ign.fr/geoportail/resources/RIG.xml#
+ //http://interop.ign.fr/registers/ign/RIG.xml#
+ srsCode = 'IGNF:'+url[1];
+ }
+ }
+ this.srsCode = srsCode.toUpperCase();
+ if (this.srsCode.indexOf("EPSG") == 0) {
+ this.srsCode = this.srsCode;
+ this.srsAuth = 'epsg';
+ this.srsProjNumber = this.srsCode.substring(5);
+ // DGR 2007-11-20 : authority IGNF
+ } else if (this.srsCode.indexOf("IGNF") == 0) {
+ this.srsCode = this.srsCode;
+ this.srsAuth = 'IGNF';
+ this.srsProjNumber = this.srsCode.substring(5);
+ // DGR 2008-06-19 : pseudo-authority CRS for WMS
+ } else if (this.srsCode.indexOf("CRS") == 0) {
+ this.srsCode = this.srsCode;
+ this.srsAuth = 'CRS';
+ this.srsProjNumber = this.srsCode.substring(4);
+ } else {
+ this.srsAuth = '';
+ this.srsProjNumber = this.srsCode;
+ }
+ this.loadProjDefinition();
+ },
+
+/**
+ * Function: loadProjDefinition
+ * Loads the coordinate system initialization string if required.
+ * Note that dynamic loading happens asynchronously so an application must
+ * wait for the readyToUse property is set to true.
+ * To prevent dynamic loading, include the defs through a script tag in
+ * your application.
+ *
+ */
+ loadProjDefinition: function() {
+ //check in memory
+ if (Proj4js.defs[this.srsCode]) {
+ this.defsLoaded();
+ return;
+ }
+
+ //else check for def on the server
+ var url = Proj4js.getScriptLocation() + 'defs/' + this.srsAuth.toUpperCase() + this.srsProjNumber + '.js';
+ Proj4js.loadScript(url,
+ Proj4js.bind(this.defsLoaded, this),
+ Proj4js.bind(this.loadFromService, this),
+ Proj4js.bind(this.checkDefsLoaded, this) );
+ },
+
+/**
+ * Function: loadFromService
+ * Creates the REST URL for loading the definition from a web service and
+ * loads it.
+ *
+ */
+ loadFromService: function() {
+ //else load from web service
+ var url = Proj4js.defsLookupService +'/' + this.srsAuth +'/'+ this.srsProjNumber + '/proj4js/';
+ Proj4js.loadScript(url,
+ Proj4js.bind(this.defsLoaded, this),
+ Proj4js.bind(this.defsFailed, this),
+ Proj4js.bind(this.checkDefsLoaded, this) );
+ },
+
+/**
+ * Function: defsLoaded
+ * Continues the Proj object initilization once the def file is loaded
+ *
+ */
+ defsLoaded: function() {
+ this.parseDefs();
+ this.loadProjCode(this.projName);
+ },
+
+/**
+ * Function: checkDefsLoaded
+ * This is the loadCheck method to see if the def object exists
+ *
+ */
+ checkDefsLoaded: function() {
+ if (Proj4js.defs[this.srsCode]) {
+ return true;
+ } else {
+ return false;
+ }
+ },
+
+ /**
+ * Function: defsFailed
+ * Report an error in loading the defs file, but continue on using WGS84
+ *
+ */
+ defsFailed: function() {
+ Proj4js.reportError('failed to load projection definition for: '+this.srsCode);
+ Proj4js.defs[this.srsCode] = Proj4js.defs['WGS84']; //set it to something so it can at least continue
+ this.defsLoaded();
+ },
+
+/**
+ * Function: loadProjCode
+ * Loads projection class code dynamically if required.
+ * Projection code may be included either through a script tag or in
+ * a built version of proj4js
+ *
+ */
+ loadProjCode: function(projName) {
+ if (Proj4js.Proj[projName]) {
+ this.initTransforms();
+ return;
+ }
+
+ //the URL for the projection code
+ var url = Proj4js.getScriptLocation() + 'projCode/' + projName + '.js';
+ Proj4js.loadScript(url,
+ Proj4js.bind(this.loadProjCodeSuccess, this, projName),
+ Proj4js.bind(this.loadProjCodeFailure, this, projName),
+ Proj4js.bind(this.checkCodeLoaded, this, projName) );
+ },
+
+ /**
+ * Function: loadProjCodeSuccess
+ * Loads any proj dependencies or continue on to final initialization.
+ *
+ */
+ loadProjCodeSuccess: function(projName) {
+ if (Proj4js.Proj[projName].dependsOn){
+ this.loadProjCode(Proj4js.Proj[projName].dependsOn);
+ } else {
+ this.initTransforms();
+ }
+ },
+
+ /**
+ * Function: defsFailed
+ * Report an error in loading the proj file. Initialization of the Proj
+ * object has failed and the readyToUse flag will never be set.
+ *
+ */
+ loadProjCodeFailure: function(projName) {
+ Proj4js.reportError("failed to find projection file for: " + projName);
+ //TBD initialize with identity transforms so proj will still work?
+ },
+
+/**
+ * Function: checkCodeLoaded
+ * This is the loadCheck method to see if the projection code is loaded
+ *
+ */
+ checkCodeLoaded: function(projName) {
+ if (Proj4js.Proj[projName]) {
+ return true;
+ } else {
+ return false;
+ }
+ },
+
+/**
+ * Function: initTransforms
+ * Finalize the initialization of the Proj object
+ *
+ */
+ initTransforms: function() {
+ Proj4js.extend(this, Proj4js.Proj[this.projName]);
+ this.init();
+ this.readyToUse = true;
+ },
+
+/**
+ * Function: parseWKT
+ * Parses a WKT string to get initialization parameters
+ *
+ */
+ wktRE: /^(\w+)\[(.*)\]$/,
+ parseWKT: function(wkt) {
+ var wktMatch = wkt.match(this.wktRE);
+ if (!wktMatch) return;
+ var wktObject = wktMatch[1];
+ var wktContent = wktMatch[2];
+ var wktTemp = wktContent.split(",");
+ var wktName = wktTemp.shift();
+ wktName = wktName.replace(/^\"/,"");
+ wktName = wktName.replace(/\"$/,"");
+
+ /*
+ wktContent = wktTemp.join(",");
+ var wktArray = wktContent.split("],");
+ for (var i=0; i<wktArray.length-1; ++i) {
+ wktArray[i] += "]";
+ }
+ */
+
+ var wktArray = new Array();
+ var bkCount = 0;
+ var obj = "";
+ for (var i=0; i<wktTemp.length; ++i) {
+ var token = wktTemp[i];
+ for (var j=0; j<token.length; ++j) {
+ if (token.charAt(j) == "[") ++bkCount;
+ if (token.charAt(j) == "]") --bkCount;
+ }
+ obj += token;
+ if (bkCount === 0) {
+ wktArray.push(obj);
+ obj = "";
+ } else {
+ obj += ",";
+ }
+ }
+
+ //do something based on the type of the wktObject being parsed
+ //add in variations in the spelling as required
+ switch (wktObject) {
+ case 'LOCAL_CS':
+ this.projName = 'identity'
+ this.localCS = true;
+ this.srsCode = wktName;
+ break;
+ case 'GEOGCS':
+ this.projName = 'longlat'
+ this.geocsCode = wktName;
+ if (!this.srsCode) this.srsCode = wktName;
+ break;
+ case 'PROJCS':
+ this.srsCode = wktName;
+ break;
+ case 'GEOCCS':
+ break;
+ case 'PROJECTION':
+ this.projName = Proj4js.wktProjections[wktName]
+ break;
+ case 'DATUM':
+ this.datumName = wktName;
+ break;
+ case 'LOCAL_DATUM':
+ this.datumCode = 'none';
+ break;
+ case 'SPHEROID':
+ this.ellps = wktName;
+ this.a = parseFloat(wktArray.shift());
+ this.rf = parseFloat(wktArray.shift());
+ break;
+ case 'PRIMEM':
+ this.from_greenwich = parseFloat(wktArray.shift()); //to radians?
+ break;
+ case 'UNIT':
+ this.units = wktName;
+ this.unitsPerMeter = parseFloat(wktArray.shift());
+ break;
+ case 'PARAMETER':
+ var name = wktName;
+ var value = parseFloat(parseFloat(wktArray.shift()));
+ //there amy be many variations on the wktName values, add in case
+ //statements as required
+ switch (name) {
+ case 'false_easting':
+ this.x0 = value;
+ break;
+ case 'false_northing':
+ this.y0 = value;
+ break;
+ case 'scale_factor':
+ this.k0 = value;
+ break;
+ case 'central_meridian':
+ this.long0 = value;
+ break;
+ case 'latitude_of_origin':
+ this.lat0 = value;
+ break;
+ case 'more_here':
+ break;
+ default:
+ break;
+ }
+ break;
+ case 'TOWGS84':
+ this.datum_params = wktArray;
+ break;
+ case 'MORE_HERE':
+ break;
+ default:
+ break;
+ }
+ for (var i=0; i<wktArray.length; ++i) {
+ this.parseWKT(wktArray[i]);
+ }
+ },
+
+/**
+ * Function: parseDefs
+ * Parses the PROJ.4 initialization string and sets the associated properties.
+ *
+ */
+ parseDefs: function() {
+ this.defData = Proj4js.defs[this.srsCode];
+ var paramName, paramVal;
+ if (!this.defData) {
+ return;
+ }
+ var paramArray=this.defData.split("+");
+
+ for (var prop=0; prop<paramArray.length; prop++) {
+ var property = paramArray[prop].split("=");
+ paramName = property[0].toLowerCase();
+ paramVal = property[1];
+
+ switch (paramName.replace(/\s/gi,"")) { // trim out spaces
+ case "": break; // throw away nameless parameter
+ case "title": this.title = paramVal; break;
+ case "proj": this.projName = paramVal.replace(/\s/gi,""); break;
+ case "units": this.units = paramVal.replace(/\s/gi,""); break;
+ case "datum": this.datumCode = paramVal.replace(/\s/gi,""); break;
+ case "nadgrids": this.nagrids = paramVal.replace(/\s/gi,""); break;
+ case "ellps": this.ellps = paramVal.replace(/\s/gi,""); break;
+ case "a": this.a = parseFloat(paramVal); break; // semi-major radius
+ case "b": this.b = parseFloat(paramVal); break; // semi-minor radius
+ // DGR 2007-11-20
+ case "rf": this.rf = parseFloat(paramVal); break; // inverse flattening rf= a/(a-b)
+ case "lat_0": this.lat0 = paramVal*Proj4js.common.D2R; break; // phi0, central latitude
+ case "lat_1": this.lat1 = paramVal*Proj4js.common.D2R; break; //standard parallel 1
+ case "lat_2": this.lat2 = paramVal*Proj4js.common.D2R; break; //standard parallel 2
+ case "lat_ts": this.lat_ts = paramVal*Proj4js.common.D2R; break; // used in merc and eqc
+ case "lon_0": this.long0 = paramVal*Proj4js.common.D2R; break; // lam0, central longitude
+ case "alpha": this.alpha = parseFloat(paramVal)*Proj4js.common.D2R; break; //for somerc projection
+ case "lonc": this.longc = paramVal*Proj4js.common.D2R; break; //for somerc projection
+ case "x_0": this.x0 = parseFloat(paramVal); break; // false easting
+ case "y_0": this.y0 = parseFloat(paramVal); break; // false northing
+ case "k_0": this.k0 = parseFloat(paramVal); break; // projection scale factor
+ case "k": this.k0 = parseFloat(paramVal); break; // both forms returned
+ case "r_a": this.R_A = true; break; // sphere--area of ellipsoid
+ case "zone": this.zone = parseInt(paramVal); break; // UTM Zone
+ case "south": this.utmSouth = true; break; // UTM north/south
+ case "towgs84":this.datum_params = paramVal.split(","); break;
+ case "to_meter": this.to_meter = parseFloat(paramVal); break; // cartesian scaling
+ case "from_greenwich": this.from_greenwich = paramVal*Proj4js.common.D2R; break;
+ // DGR 2008-07-09 : if pm is not a well-known prime meridian take
+ // the value instead of 0.0, then convert to radians
+ case "pm": paramVal = paramVal.replace(/\s/gi,"");
+ this.from_greenwich = Proj4js.PrimeMeridian[paramVal] ?
+ Proj4js.PrimeMeridian[paramVal] : parseFloat(paramVal);
+ this.from_greenwich *= Proj4js.common.D2R;
+ break;
+ case "no_defs": break;
+ default: //alert("Unrecognized parameter: " + paramName);
+ } // switch()
+ } // for paramArray
+ this.deriveConstants();
+ },
+
+/**
+ * Function: deriveConstants
+ * Sets several derived constant values and initialization of datum and ellipse
+ * parameters.
+ *
+ */
+ deriveConstants: function() {
+ if (this.nagrids == '@null') this.datumCode = 'none';
+ if (this.datumCode && this.datumCode != 'none') {
+ var datumDef = Proj4js.Datum[this.datumCode];
+ if (datumDef) {
+ this.datum_params = datumDef.towgs84 ? datumDef.towgs84.split(',') : null;
+ this.ellps = datumDef.ellipse;
+ this.datumName = datumDef.datumName ? datumDef.datumName : this.datumCode;
+ }
+ }
+ if (!this.a) { // do we have an ellipsoid?
+ var ellipse = Proj4js.Ellipsoid[this.ellps] ? Proj4js.Ellipsoid[this.ellps] : Proj4js.Ellipsoid['WGS84'];
+ Proj4js.extend(this, ellipse);
+ }
+ if (this.rf && !this.b) this.b = (1.0 - 1.0/this.rf) * this.a;
+ if (Math.abs(this.a - this.b)<Proj4js.common.EPSLN) {
+ this.sphere = true;
+ this.b= this.a;
+ }
+ this.a2 = this.a * this.a; // used in geocentric
+ this.b2 = this.b * this.b; // used in geocentric
+ this.es = (this.a2-this.b2)/this.a2; // e ^ 2
+ this.e = Math.sqrt(this.es); // eccentricity
+ if (this.R_A) {
+ this.a *= 1. - this.es * (Proj4js.common.SIXTH + this.es * (Proj4js.common.RA4 + this.es * Proj4js.common.RA6));
+ this.a2 = this.a * this.a;
+ this.b2 = this.b * this.b;
+ this.es = 0.;
+ }
+ this.ep2=(this.a2-this.b2)/this.b2; // used in geocentric
+ if (!this.k0) this.k0 = 1.0; //default value
+
+ this.datum = new Proj4js.datum(this);
+ }
+});
+
+Proj4js.Proj.longlat = {
+ init: function() {
+ //no-op for longlat
+ },
+ forward: function(pt) {
+ //identity transform
+ return pt;
+ },
+ inverse: function(pt) {
+ //identity transform
+ return pt;
+ }
+};
+Proj4js.Proj.identity = Proj4js.Proj.longlat;
+
+/**
+ Proj4js.defs is a collection of coordinate system definition objects in the
+ PROJ.4 command line format.
+ Generally a def is added by means of a separate .js file for example:
+
+ <SCRIPT type="text/javascript" src="defs/EPSG26912.js"></SCRIPT>
+
+ def is a CS definition in PROJ.4 WKT format, for example:
+ +proj="tmerc" //longlat, etc.
+ +a=majorRadius
+ +b=minorRadius
+ +lat0=somenumber
+ +long=somenumber
+*/
+Proj4js.defs = {
+ // These are so widely used, we'll go ahead and throw them in
+ // without requiring a separate .js file
+ 'WGS84': "+title=long/lat:WGS84 +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees",
+ 'EPSG:4326': "+title=long/lat:WGS84 +proj=longlat +a=6378137.0 +b=6356752.31424518 +ellps=WGS84 +datum=WGS84 +units=degrees",
+ 'EPSG:4269': "+title=long/lat:NAD83 +proj=longlat +a=6378137.0 +b=6356752.31414036 +ellps=GRS80 +datum=NAD83 +units=degrees",
+ 'EPSG:3785': "+title= Google Mercator +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs"
+};
+Proj4js.defs['GOOGLE'] = Proj4js.defs['EPSG:3785'];
+Proj4js.defs['EPSG:900913'] = Proj4js.defs['EPSG:3785'];
+Proj4js.defs['EPSG:102113'] = Proj4js.defs['EPSG:3785'];
+
+Proj4js.common = {
+ PI : 3.141592653589793238, //Math.PI,
+ HALF_PI : 1.570796326794896619, //Math.PI*0.5,
+ TWO_PI : 6.283185307179586477, //Math.PI*2,
+ FORTPI : 0.78539816339744833,
+ R2D : 57.29577951308232088,
+ D2R : 0.01745329251994329577,
+ SEC_TO_RAD : 4.84813681109535993589914102357e-6, /* SEC_TO_RAD = Pi/180/3600 */
+ EPSLN : 1.0e-10,
+ MAX_ITER : 20,
+ // following constants from geocent.c
+ COS_67P5 : 0.38268343236508977, /* cosine of 67.5 degrees */
+ AD_C : 1.0026000, /* Toms region 1 constant */
+
+ /* datum_type values */
+ PJD_UNKNOWN : 0,
+ PJD_3PARAM : 1,
+ PJD_7PARAM : 2,
+ PJD_GRIDSHIFT: 3,
+ PJD_WGS84 : 4, // WGS84 or equivalent
+ PJD_NODATUM : 5, // WGS84 or equivalent
+ SRS_WGS84_SEMIMAJOR : 6378137.0, // only used in grid shift transforms
+
+ // ellipoid pj_set_ell.c
+ SIXTH : .1666666666666666667, /* 1/6 */
+ RA4 : .04722222222222222222, /* 17/360 */
+ RA6 : .02215608465608465608, /* 67/3024 */
+ RV4 : .06944444444444444444, /* 5/72 */
+ RV6 : .04243827160493827160, /* 55/1296 */
+
+// Function to compute the constant small m which is the radius of
+// a parallel of latitude, phi, divided by the semimajor axis.
+// -----------------------------------------------------------------
+ msfnz : function(eccent, sinphi, cosphi) {
+ var con = eccent * sinphi;
+ return cosphi/(Math.sqrt(1.0 - con * con));
+ },
+
+// Function to compute the constant small t for use in the forward
+// computations in the Lambert Conformal Conic and the Polar
+// Stereographic projections.
+// -----------------------------------------------------------------
+ tsfnz : function(eccent, phi, sinphi) {
+ var con = eccent * sinphi;
+ var com = .5 * eccent;
+ con = Math.pow(((1.0 - con) / (1.0 + con)), com);
+ return (Math.tan(.5 * (this.HALF_PI - phi))/con);
+ },
+
+// Function to compute the latitude angle, phi2, for the inverse of the
+// Lambert Conformal Conic and Polar Stereographic projections.
+// ----------------------------------------------------------------
+ phi2z : function(eccent, ts) {
+ var eccnth = .5 * eccent;
+ var con, dphi;
+ var phi = this.HALF_PI - 2 * Math.atan(ts);
+ for (var i = 0; i <= 15; i++) {
+ con = eccent * Math.sin(phi);
+ dphi = this.HALF_PI - 2 * Math.atan(ts *(Math.pow(((1.0 - con)/(1.0 + con)),eccnth))) - phi;
+ phi += dphi;
+ if (Math.abs(dphi) <= .0000000001) return phi;
+ }
+ alert("phi2z has NoConvergence");
+ return (-9999);
+ },
+
+/* Function to compute constant small q which is the radius of a
+ parallel of latitude, phi, divided by the semimajor axis.
+------------------------------------------------------------*/
+ qsfnz : function(eccent,sinphi) {
+ var con;
+ if (eccent > 1.0e-7) {
+ con = eccent * sinphi;
+ return (( 1.0- eccent * eccent) * (sinphi /(1.0 - con * con) - (.5/eccent)*Math.log((1.0 - con)/(1.0 + con))));
+ } else {
+ return(2.0 * sinphi);
+ }
+ },
+
+/* Function to eliminate roundoff errors in asin
+----------------------------------------------*/
+ asinz : function(x) {
+ if (Math.abs(x)>1.0) {
+ x=(x>1.0)?1.0:-1.0;
+ }
+ return Math.asin(x);
+ },
+
+// following functions from gctpc cproj.c for transverse mercator projections
+ e0fn : function(x) {return(1.0-0.25*x*(1.0+x/16.0*(3.0+1.25*x)));},
+ e1fn : function(x) {return(0.375*x*(1.0+0.25*x*(1.0+0.46875*x)));},
+ e2fn : function(x) {return(0.05859375*x*x*(1.0+0.75*x));},
+ e3fn : function(x) {return(x*x*x*(35.0/3072.0));},
+ mlfn : function(e0,e1,e2,e3,phi) {return(e0*phi-e1*Math.sin(2.0*phi)+e2*Math.sin(4.0*phi)-e3*Math.sin(6.0*phi));},
+
+ srat : function(esinp, exp) {
+ return(Math.pow((1.0-esinp)/(1.0+esinp), exp));
+ },
+
+// Function to return the sign of an argument
+ sign : function(x) { if (x < 0.0) return(-1); else return(1);},
+
+// Function to adjust longitude to -180 to 180; input in radians
+ adjust_lon : function(x) {
+ x = (Math.abs(x) < this.PI) ? x: (x - (this.sign(x)*this.TWO_PI) );
+ return x;
+ },
+
+// IGNF - DGR : algorithms used by IGN France
+
+// Function to adjust latitude to -90 to 90; input in radians
+ adjust_lat : function(x) {
+ x= (Math.abs(x) < this.HALF_PI) ? x: (x - (this.sign(x)*this.PI) );
+ return x;
+ },
+
+// Latitude Isometrique - close to tsfnz ...
+ latiso : function(eccent, phi, sinphi) {
+ if (Math.abs(phi) > this.HALF_PI) return +Number.NaN;
+ if (phi==this.HALF_PI) return Number.POSITIVE_INFINITY;
+ if (phi==-1.0*this.HALF_PI) return -1.0*Number.POSITIVE_INFINITY;
+
+ var con= eccent*sinphi;
+ return Math.log(Math.tan((this.HALF_PI+phi)/2.0))+eccent*Math.log((1.0-con)/(1.0+con))/2.0;
+ },
+
+ fL : function(x,L) {
+ return 2.0*Math.atan(x*Math.exp(L)) - this.HALF_PI;
+ },
+
+// Inverse Latitude Isometrique - close to ph2z
+ invlatiso : function(eccent, ts) {
+ var phi= this.fL(1.0,ts);
+ var Iphi= 0.0;
+ var con= 0.0;
+ do {
+ Iphi= phi;
+ con= eccent*Math.sin(Iphi);
+ phi= this.fL(Math.exp(eccent*Math.log((1.0+con)/(1.0-con))/2.0),ts)
+ } while (Math.abs(phi-Iphi)>1.0e-12);
+ return phi;
+ },
+
+// Needed for Gauss Schreiber
+// Original: Denis Makarov (info at binarythings.com)
+// Web Site: http://www.binarythings.com
+ sinh : function(x)
+ {
+ var r= Math.exp(x);
+ r= (r-1.0/r)/2.0;
+ return r;
+ },
+
+ cosh : function(x)
+ {
+ var r= Math.exp(x);
+ r= (r+1.0/r)/2.0;
+ return r;
+ },
+
+ tanh : function(x)
+ {
+ var r= Math.exp(x);
+ r= (r-1.0/r)/(r+1.0/r);
+ return r;
+ },
+
+ asinh : function(x)
+ {
+ var s= (x>= 0? 1.0:-1.0);
+ return s*(Math.log( Math.abs(x) + Math.sqrt(x*x+1.0) ));
+ },
+
+ acosh : function(x)
+ {
+ return 2.0*Math.log(Math.sqrt((x+1.0)/2.0) + Math.sqrt((x-1.0)/2.0));
+ },
+
+ atanh : function(x)
+ {
+ return Math.log((x-1.0)/(x+1.0))/2.0;
+ },
+
+// Grande Normale
+ gN : function(a,e,sinphi)
+ {
+ var temp= e*sinphi;
+ return a/Math.sqrt(1.0 - temp*temp);
+ }
+
+};
+
+/** datum object
+*/
+Proj4js.datum = Proj4js.Class({
+
+ initialize : function(proj) {
+ this.datum_type = Proj4js.common.PJD_WGS84; //default setting
+ if (proj.datumCode && proj.datumCode == 'none') {
+ this.datum_type = Proj4js.common.PJD_NODATUM;
+ }
+ if (proj && proj.datum_params) {
+ for (var i=0; i<proj.datum_params.length; i++) {
+ proj.datum_params[i]=parseFloat(proj.datum_params[i]);
+ }
+ if (proj.datum_params[0] != 0 || proj.datum_params[1] != 0 || proj.datum_params[2] != 0 ) {
+ this.datum_type = Proj4js.common.PJD_3PARAM;
+ }
+ if (proj.datum_params.length > 3) {
+ if (proj.datum_params[3] != 0 || proj.datum_params[4] != 0 ||
+ proj.datum_params[5] != 0 || proj.datum_params[6] != 0 ) {
+ this.datum_type = Proj4js.common.PJD_7PARAM;
+ proj.datum_params[3] *= Proj4js.common.SEC_TO_RAD;
+ proj.datum_params[4] *= Proj4js.common.SEC_TO_RAD;
+ proj.datum_params[5] *= Proj4js.common.SEC_TO_RAD;
+ proj.datum_params[6] = (proj.datum_params[6]/1000000.0) + 1.0;
+ }
+ }
+ }
+ if (proj) {
+ this.a = proj.a; //datum object also uses these values
+ this.b = proj.b;
+ this.es = proj.es;
+ this.ep2 = proj.ep2;
+ this.datum_params = proj.datum_params;
+ }
+ },
+
+ /****************************************************************/
+ // cs_compare_datums()
+ // Returns 1 (TRUE) if the two datums match, otherwise 0 (FALSE).
+ compare_datums : function( dest ) {
+ if( this.datum_type != dest.datum_type ) {
+ return false; // false, datums are not equal
+ } else if( this.a != dest.a || Math.abs(this.es-dest.es) > 0.000000000050 ) {
+ // the tolerence for es is to ensure that GRS80 and WGS84
+ // are considered identical
+ return false;
+ } else if( this.datum_type == Proj4js.common.PJD_3PARAM ) {
+ return (this.datum_params[0] == dest.datum_params[0]
+ && this.datum_params[1] == dest.datum_params[1]
+ && this.datum_params[2] == dest.datum_params[2]);
+ } else if( this.datum_type == Proj4js.common.PJD_7PARAM ) {
+ return (this.datum_params[0] == dest.datum_params[0]
+ && this.datum_params[1] == dest.datum_params[1]
+ && this.datum_params[2] == dest.datum_params[2]
+ && this.datum_params[3] == dest.datum_params[3]
+ && this.datum_params[4] == dest.datum_params[4]
+ && this.datum_params[5] == dest.datum_params[5]
+ && this.datum_params[6] == dest.datum_params[6]);
+ } else if( this.datum_type == Proj4js.common.PJD_GRIDSHIFT ) {
+ return strcmp( pj_param(this.params,"snadgrids").s,
+ pj_param(dest.params,"snadgrids").s ) == 0;
+ } else {
+ return true; // datums are equal
+ }
+ }, // cs_compare_datums()
+
+ /*
+ * The function Convert_Geodetic_To_Geocentric converts geodetic coordinates
+ * (latitude, longitude, and height) to geocentric coordinates (X, Y, Z),
+ * according to the current ellipsoid parameters.
+ *
+ * Latitude : Geodetic latitude in radians (input)
+ * Longitude : Geodetic longitude in radians (input)
+ * Height : Geodetic height, in meters (input)
+ * X : Calculated Geocentric X coordinate, in meters (output)
+ * Y : Calculated Geocentric Y coordinate, in meters (output)
+ * Z : Calculated Geocentric Z coordinate, in meters (output)
+ *
+ */
+ geodetic_to_geocentric : function(p) {
+ var Longitude = p.x;
+ var Latitude = p.y;
+ var Height = p.z ? p.z : 0; //Z value not always supplied
+ var X; // output
+ var Y;
+ var Z;
+
+ var Error_Code=0; // GEOCENT_NO_ERROR;
+ var Rn; /* Earth radius at location */
+ var Sin_Lat; /* Math.sin(Latitude) */
+ var Sin2_Lat; /* Square of Math.sin(Latitude) */
+ var Cos_Lat; /* Math.cos(Latitude) */
+
+ /*
+ ** Don't blow up if Latitude is just a little out of the value
+ ** range as it may just be a rounding issue. Also removed longitude
+ ** test, it should be wrapped by Math.cos() and Math.sin(). NFW for PROJ.4, Sep/2001.
+ */
+ if( Latitude < -Proj4js.common.HALF_PI && Latitude > -1.001 * Proj4js.common.HALF_PI ) {
+ Latitude = -Proj4js.common.HALF_PI;
+ } else if( Latitude > Proj4js.common.HALF_PI && Latitude < 1.001 * Proj4js.common.HALF_PI ) {
+ Latitude = Proj4js.common.HALF_PI;
+ } else if ((Latitude < -Proj4js.common.HALF_PI) || (Latitude > Proj4js.common.HALF_PI)) {
+ /* Latitude out of range */
+ Proj4js.reportError('geocent:lat out of range:'+Latitude);
+ return null;
+ }
+
+ if (Longitude > Proj4js.common.PI) Longitude -= (2*Proj4js.common.PI);
+ Sin_Lat = Math.sin(Latitude);
+ Cos_Lat = Math.cos(Latitude);
+ Sin2_Lat = Sin_Lat * Sin_Lat;
+ Rn = this.a / (Math.sqrt(1.0e0 - this.es * Sin2_Lat));
+ X = (Rn + Height) * Cos_Lat * Math.cos(Longitude);
+ Y = (Rn + Height) * Cos_Lat * Math.sin(Longitude);
+ Z = ((Rn * (1 - this.es)) + Height) * Sin_Lat;
+
+ p.x = X;
+ p.y = Y;
+ p.z = Z;
+ return Error_Code;
+ }, // cs_geodetic_to_geocentric()
+
+
+ geocentric_to_geodetic : function (p) {
+/* local defintions and variables */
+/* end-criterium of loop, accuracy of sin(Latitude) */
+var genau = 1.E-12;
+var genau2 = (genau*genau);
+var maxiter = 30;
+
+ var P; /* distance between semi-minor axis and location */
+ var RR; /* distance between center and location */
+ var CT; /* sin of geocentric latitude */
+ var ST; /* cos of geocentric latitude */
+ var RX;
+ var RK;
+ var RN; /* Earth radius at location */
+ var CPHI0; /* cos of start or old geodetic latitude in iterations */
+ var SPHI0; /* sin of start or old geodetic latitude in iterations */
+ var CPHI; /* cos of searched geodetic latitude */
+ var SPHI; /* sin of searched geodetic latitude */
+ var SDPHI; /* end-criterium: addition-theorem of sin(Latitude(iter)-Latitude(iter-1)) */
+ var At_Pole; /* indicates location is in polar region */
+ var iter; /* # of continous iteration, max. 30 is always enough (s.a.) */
+
+ var X = p.x;
+ var Y = p.y;
+ var Z = p.z ? p.z : 0.0; //Z value not always supplied
+ var Longitude;
+ var Latitude;
+ var Height;
+
+ At_Pole = false;
+ P = Math.sqrt(X*X+Y*Y);
+ RR = Math.sqrt(X*X+Y*Y+Z*Z);
+
+/* special cases for latitude and longitude */
+ if (P/this.a < genau) {
+
+/* special case, if P=0. (X=0., Y=0.) */
+ At_Pole = true;
+ Longitude = 0.0;
+
+/* if (X,Y,Z)=(0.,0.,0.) then Height becomes semi-minor axis
+ * of ellipsoid (=center of mass), Latitude becomes PI/2 */
+ if (RR/this.a < genau) {
+ Latitude = Proj4js.common.HALF_PI;
+ Height = -this.b;
+ return;
+ }
+ } else {
+/* ellipsoidal (geodetic) longitude
+ * interval: -PI < Longitude <= +PI */
+ Longitude=Math.atan2(Y,X);
+ }
+
+/* --------------------------------------------------------------
+ * Following iterative algorithm was developped by
+ * "Institut für Erdmessung", University of Hannover, July 1988.
+ * Internet: www.ife.uni-hannover.de
+ * Iterative computation of CPHI,SPHI and Height.
+ * Iteration of CPHI and SPHI to 10**-12 radian resp.
+ * 2*10**-7 arcsec.
+ * --------------------------------------------------------------
+ */
+ CT = Z/RR;
+ ST = P/RR;
+ RX = 1.0/Math.sqrt(1.0-this.es*(2.0-this.es)*ST*ST);
+ CPHI0 = ST*(1.0-this.es)*RX;
+ SPHI0 = CT*RX;
+ iter = 0;
+
+/* loop to find sin(Latitude) resp. Latitude
+ * until |sin(Latitude(iter)-Latitude(iter-1))| < genau */
+ do
+ {
+ iter++;
+ RN = this.a/Math.sqrt(1.0-this.es*SPHI0*SPHI0);
+
+/* ellipsoidal (geodetic) height */
+ Height = P*CPHI0+Z*SPHI0-RN*(1.0-this.es*SPHI0*SPHI0);
+
+ RK = this.es*RN/(RN+Height);
+ RX = 1.0/Math.sqrt(1.0-RK*(2.0-RK)*ST*ST);
+ CPHI = ST*(1.0-RK)*RX;
+ SPHI = CT*RX;
+ SDPHI = SPHI*CPHI0-CPHI*SPHI0;
+ CPHI0 = CPHI;
+ SPHI0 = SPHI;
+ }
+ while (SDPHI*SDPHI > genau2 && iter < maxiter);
+
+/* ellipsoidal (geodetic) latitude */
+ Latitude=Math.atan(SPHI/Math.abs(CPHI));
+
+ p.x = Longitude;
+ p.y = Latitude;
+ p.z = Height;
+ return p;
+ }, // cs_geocentric_to_geodetic()
+
+ /** Convert_Geocentric_To_Geodetic
+ * The method used here is derived from 'An Improved Algorithm for
+ * Geocentric to Geodetic Coordinate Conversion', by Ralph Toms, Feb 1996
+ */
+ geocentric_to_geodetic_noniter : function (p) {
+ var X = p.x;
+ var Y = p.y;
+ var Z = p.z ? p.z : 0; //Z value not always supplied
+ var Longitude;
+ var Latitude;
+ var Height;
+
+ var W; /* distance from Z axis */
+ var W2; /* square of distance from Z axis */
+ var T0; /* initial estimate of vertical component */
+ var T1; /* corrected estimate of vertical component */
+ var S0; /* initial estimate of horizontal component */
+ var S1; /* corrected estimate of horizontal component */
+ var Sin_B0; /* Math.sin(B0), B0 is estimate of Bowring aux variable */
+ var Sin3_B0; /* cube of Math.sin(B0) */
+ var Cos_B0; /* Math.cos(B0) */
+ var Sin_p1; /* Math.sin(phi1), phi1 is estimated latitude */
+ var Cos_p1; /* Math.cos(phi1) */
+ var Rn; /* Earth radius at location */
+ var Sum; /* numerator of Math.cos(phi1) */
+ var At_Pole; /* indicates location is in polar region */
+
+ X = parseFloat(X); // cast from string to float
+ Y = parseFloat(Y);
+ Z = parseFloat(Z);
+
+ At_Pole = false;
+ if (X != 0.0)
+ {
+ Longitude = Math.atan2(Y,X);
+ }
+ else
+ {
+ if (Y > 0)
+ {
+ Longitude = Proj4js.common.HALF_PI;
+ }
+ else if (Y < 0)
+ {
+ Longitude = -Proj4js.common.HALF_PI;
+ }
+ else
+ {
+ At_Pole = true;
+ Longitude = 0.0;
+ if (Z > 0.0)
+ { /* north pole */
+ Latitude = Proj4js.common.HALF_PI;
+ }
+ else if (Z < 0.0)
+ { /* south pole */
+ Latitude = -Proj4js.common.HALF_PI;
+ }
+ else
+ { /* center of earth */
+ Latitude = Proj4js.common.HALF_PI;
+ Height = -this.b;
+ return;
+ }
+ }
+ }
+ W2 = X*X + Y*Y;
+ W = Math.sqrt(W2);
+ T0 = Z * Proj4js.common.AD_C;
+ S0 = Math.sqrt(T0 * T0 + W2);
+ Sin_B0 = T0 / S0;
+ Cos_B0 = W / S0;
+ Sin3_B0 = Sin_B0 * Sin_B0 * Sin_B0;
+ T1 = Z + this.b * this.ep2 * Sin3_B0;
+ Sum = W - this.a * this.es * Cos_B0 * Cos_B0 * Cos_B0;
+ S1 = Math.sqrt(T1*T1 + Sum * Sum);
+ Sin_p1 = T1 / S1;
+ Cos_p1 = Sum / S1;
+ Rn = this.a / Math.sqrt(1.0 - this.es * Sin_p1 * Sin_p1);
+ if (Cos_p1 >= Proj4js.common.COS_67P5)
+ {
+ Height = W / Cos_p1 - Rn;
+ }
+ else if (Cos_p1 <= -Proj4js.common.COS_67P5)
+ {
+ Height = W / -Cos_p1 - Rn;
+ }
+ else
+ {
+ Height = Z / Sin_p1 + Rn * (this.es - 1.0);
+ }
+ if (At_Pole == false)
+ {
+ Latitude = Math.atan(Sin_p1 / Cos_p1);
+ }
+
+ p.x = Longitude;
+ p.y = Latitude;
+ p.z = Height;
+ return p;
+ }, // geocentric_to_geodetic_noniter()
+
+ /****************************************************************/
+ // pj_geocentic_to_wgs84( p )
+ // p = point to transform in geocentric coordinates (x,y,z)
+ geocentric_to_wgs84 : function ( p ) {
+
+ if( this.datum_type == Proj4js.common.PJD_3PARAM )
+ {
+ // if( x[io] == HUGE_VAL )
+ // continue;
+ p.x += this.datum_params[0];
+ p.y += this.datum_params[1];
+ p.z += this.datum_params[2];
+
+ }
+ else if (this.datum_type == Proj4js.common.PJD_7PARAM)
+ {
+ var Dx_BF =this.datum_params[0];
+ var Dy_BF =this.datum_params[1];
+ var Dz_BF =this.datum_params[2];
+ var Rx_BF =this.datum_params[3];
+ var Ry_BF =this.datum_params[4];
+ var Rz_BF =this.datum_params[5];
+ var M_BF =this.datum_params[6];
+ // if( x[io] == HUGE_VAL )
+ // continue;
+ var x_out = M_BF*( p.x - Rz_BF*p.y + Ry_BF*p.z) + Dx_BF;
+ var y_out = M_BF*( Rz_BF*p.x + p.y - Rx_BF*p.z) + Dy_BF;
+ var z_out = M_BF*(-Ry_BF*p.x + Rx_BF*p.y + p.z) + Dz_BF;
+ p.x = x_out;
+ p.y = y_out;
+ p.z = z_out;
+ }
+ }, // cs_geocentric_to_wgs84
+
+ /****************************************************************/
+ // pj_geocentic_from_wgs84()
+ // coordinate system definition,
+ // point to transform in geocentric coordinates (x,y,z)
+ geocentric_from_wgs84 : function( p ) {
+
+ if( this.datum_type == Proj4js.common.PJD_3PARAM )
+ {
+ //if( x[io] == HUGE_VAL )
+ // continue;
+ p.x -= this.datum_params[0];
+ p.y -= this.datum_params[1];
+ p.z -= this.datum_params[2];
+
+ }
+ else if (this.datum_type == Proj4js.common.PJD_7PARAM)
+ {
+ var Dx_BF =this.datum_params[0];
+ var Dy_BF =this.datum_params[1];
+ var Dz_BF =this.datum_params[2];
+ var Rx_BF =this.datum_params[3];
+ var Ry_BF =this.datum_params[4];
+ var Rz_BF =this.datum_params[5];
+ var M_BF =this.datum_params[6];
+ var x_tmp = (p.x - Dx_BF) / M_BF;
+ var y_tmp = (p.y - Dy_BF) / M_BF;
+ var z_tmp = (p.z - Dz_BF) / M_BF;
+ //if( x[io] == HUGE_VAL )
+ // continue;
+
+ p.x = x_tmp + Rz_BF*y_tmp - Ry_BF*z_tmp;
+ p.y = -Rz_BF*x_tmp + y_tmp + Rx_BF*z_tmp;
+ p.z = Ry_BF*x_tmp - Rx_BF*y_tmp + z_tmp;
+ } //cs_geocentric_from_wgs84()
+ }
+});
+
+/** point object, nothing fancy, just allows values to be
+ passed back and forth by reference rather than by value.
+ Other point classes may be used as long as they have
+ x and y properties, which will get modified in the transform method.
+*/
+Proj4js.Point = Proj4js.Class({
+
+ /**
+ * Constructor: Proj4js.Point
+ *
+ * Parameters:
+ * - x {float} or {Array} either the first coordinates component or
+ * the full coordinates
+ * - y {float} the second component
+ * - z {float} the third component, optional.
+ */
+ initialize : function(x,y,z) {
+ if (typeof x == 'object') {
+ this.x = x[0];
+ this.y = x[1];
+ this.z = x[2] || 0.0;
+ } else if (typeof x == 'string') {
+ var coords = x.split(',');
+ this.x = parseFloat(coords[0]);
+ this.y = parseFloat(coords[1]);
+ this.z = parseFloat(coords[2]) || 0.0;
+ } else {
+ this.x = x;
+ this.y = y;
+ this.z = z || 0.0;
+ }
+ },
+
+ /**
+ * APIMethod: clone
+ * Build a copy of a Proj4js.Point object.
+ *
+ * Return:
+ * {Proj4js}.Point the cloned point.
+ */
+ clone : function() {
+ return new Proj4js.Point(this.x, this.y, this.z);
+ },
+
+ /**
+ * APIMethod: toString
+ * Return a readable string version of the point
+ *
+ * Return:
+ * {String} String representation of Proj4js.Point object.
+ * (ex. <i>"x=5,y=42"</i>)
+ */
+ toString : function() {
+ return ("x=" + this.x + ",y=" + this.y);
+ },
+
+ /**
+ * APIMethod: toShortString
+ * Return a short string version of the point.
+ *
+ * Return:
+ * {String} Shortened String representation of Proj4js.Point object.
+ * (ex. <i>"5, 42"</i>)
+ */
+ toShortString : function() {
+ return (this.x + ", " + this.y);
+ }
+});
+
+Proj4js.PrimeMeridian = {
+ "greenwich": 0.0, //"0dE",
+ "lisbon": -9.131906111111, //"9d07'54.862\"W",
+ "paris": 2.337229166667, //"2d20'14.025\"E",
+ "bogota": -74.080916666667, //"74d04'51.3\"W",
+ "madrid": -3.687938888889, //"3d41'16.58\"W",
+ "rome": 12.452333333333, //"12d27'8.4\"E",
+ "bern": 7.439583333333, //"7d26'22.5\"E",
+ "jakarta": 106.807719444444, //"106d48'27.79\"E",
+ "ferro": -17.666666666667, //"17d40'W",
+ "brussels": 4.367975, //"4d22'4.71\"E",
+ "stockholm": 18.058277777778, //"18d3'29.8\"E",
+ "athens": 23.7163375, //"23d42'58.815\"E",
+ "oslo": 10.722916666667 //"10d43'22.5\"E"
+};
+
+Proj4js.Ellipsoid = {
+ "MERIT": {a:6378137.0, rf:298.257, ellipseName:"MERIT 1983"},
+ "SGS85": {a:6378136.0, rf:298.257, ellipseName:"Soviet Geodetic System 85"},
+ "GRS80": {a:6378137.0, rf:298.257222101, ellipseName:"GRS 1980(IUGG, 1980)"},
+ "IAU76": {a:6378140.0, rf:298.257, ellipseName:"IAU 1976"},
+ "airy": {a:6377563.396, b:6356256.910, ellipseName:"Airy 1830"},
+ "APL4.": {a:6378137, rf:298.25, ellipseName:"Appl. Physics. 1965"},
+ "NWL9D": {a:6378145.0, rf:298.25, ellipseName:"Naval Weapons Lab., 1965"},
+ "mod_airy": {a:6377340.189, b:6356034.446, ellipseName:"Modified Airy"},
+ "andrae": {a:6377104.43, rf:300.0, ellipseName:"Andrae 1876 (Den., Iclnd.)"},
+ "aust_SA": {a:6378160.0, rf:298.25, ellipseName:"Australian Natl & S. Amer. 1969"},
+ "GRS67": {a:6378160.0, rf:298.2471674270, ellipseName:"GRS 67(IUGG 1967)"},
+ "bessel": {a:6377397.155, rf:299.1528128, ellipseName:"Bessel 1841"},
+ "bess_nam": {a:6377483.865, rf:299.1528128, ellipseName:"Bessel 1841 (Namibia)"},
+ "clrk66": {a:6378206.4, b:6356583.8, ellipseName:"Clarke 1866"},
+ "clrk80": {a:6378249.145, rf:293.4663, ellipseName:"Clarke 1880 mod."},
+ "CPM": {a:6375738.7, rf:334.29, ellipseName:"Comm. des Poids et Mesures 1799"},
+ "delmbr": {a:6376428.0, rf:311.5, ellipseName:"Delambre 1810 (Belgium)"},
+ "engelis": {a:6378136.05, rf:298.2566, ellipseName:"Engelis 1985"},
+ "evrst30": {a:6377276.345, rf:300.8017, ellipseName:"Everest 1830"},
+ "evrst48": {a:6377304.063, rf:300.8017, ellipseName:"Everest 1948"},
+ "evrst56": {a:6377301.243, rf:300.8017, ellipseName:"Everest 1956"},
+ "evrst69": {a:6377295.664, rf:300.8017, ellipseName:"Everest 1969"},
+ "evrstSS": {a:6377298.556, rf:300.8017, ellipseName:"Everest (Sabah & Sarawak)"},
+ "fschr60": {a:6378166.0, rf:298.3, ellipseName:"Fischer (Mercury Datum) 1960"},
+ "fschr60m": {a:6378155.0, rf:298.3, ellipseName:"Fischer 1960"},
+ "fschr68": {a:6378150.0, rf:298.3, ellipseName:"Fischer 1968"},
+ "helmert": {a:6378200.0, rf:298.3, ellipseName:"Helmert 1906"},
+ "hough": {a:6378270.0, rf:297.0, ellipseName:"Hough"},
+ "intl": {a:6378388.0, rf:297.0, ellipseName:"International 1909 (Hayford)"},
+ "kaula": {a:6378163.0, rf:298.24, ellipseName:"Kaula 1961"},
+ "lerch": {a:6378139.0, rf:298.257, ellipseName:"Lerch 1979"},
+ "mprts": {a:6397300.0, rf:191.0, ellipseName:"Maupertius 1738"},
+ "new_intl": {a:6378157.5, b:6356772.2, ellipseName:"New International 1967"},
+ "plessis": {a:6376523.0, rf:6355863.0, ellipseName:"Plessis 1817 (France)"},
+ "krass": {a:6378245.0, rf:298.3, ellipseName:"Krassovsky, 1942"},
+ "SEasia": {a:6378155.0, b:6356773.3205, ellipseName:"Southeast Asia"},
+ "walbeck": {a:6376896.0, b:6355834.8467, ellipseName:"Walbeck"},
+ "WGS60": {a:6378165.0, rf:298.3, ellipseName:"WGS 60"},
+ "WGS66": {a:6378145.0, rf:298.25, ellipseName:"WGS 66"},
+ "WGS72": {a:6378135.0, rf:298.26, ellipseName:"WGS 72"},
+ "WGS84": {a:6378137.0, rf:298.257223563, ellipseName:"WGS 84"},
+ "sphere": {a:6370997.0, b:6370997.0, ellipseName:"Normal Sphere (r=6370997)"}
+};
+
+Proj4js.Datum = {
+ "WGS84": {towgs84: "0,0,0", ellipse: "WGS84", datumName: "WGS84"},
+ "GGRS87": {towgs84: "-199.87,74.79,246.62", ellipse: "GRS80", datumName: "Greek_Geodetic_Reference_System_1987"},
+ "NAD83": {towgs84: "0,0,0", ellipse: "GRS80", datumName: "North_American_Datum_1983"},
+ "NAD27": {nadgrids: "@conus, at alaska, at ntv2_0.gsb, at ntv1_can.dat", ellipse: "clrk66", datumName: "North_American_Datum_1927"},
+ "potsdam": {towgs84: "606.0,23.0,413.0", ellipse: "bessel", datumName: "Potsdam Rauenberg 1950 DHDN"},
+ "carthage": {towgs84: "-263.0,6.0,431.0", ellipse: "clark80", datumName: "Carthage 1934 Tunisia"},
+ "hermannskogel": {towgs84: "653.0,-212.0,449.0", ellipse: "bessel", datumName: "Hermannskogel"},
+ "ire65": {towgs84: "482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15", ellipse: "mod_airy", datumName: "Ireland 1965"},
+ "nzgd49": {towgs84: "59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993", ellipse: "intl", datumName: "New Zealand Geodetic Datum 1949"},
+ "OSGB36": {towgs84: "446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894", ellipse: "airy", datumName: "Airy 1830"}
+};
+
+Proj4js.WGS84 = new Proj4js.Proj('WGS84');
+Proj4js.Datum['OSB36'] = Proj4js.Datum['OSGB36']; //as returned from spatialreference.org
+
+//lookup table to go from the projection name in WKT to the Proj4js projection name
+//build this out as required
+Proj4js.wktProjections = {
+ "Lambert Tangential Conformal Conic Projection": "lcc",
+ "Mercator": "merc",
+ "Transverse_Mercator": "tmerc",
+ "Transverse Mercator": "tmerc",
+ "Lambert Azimuthal Equal Area": "laea",
+ "Universal Transverse Mercator System": "utm"
+};
+
+
+/* ======================================================================
+ projCode/aea.js
+ ====================================================================== */
+
+/*******************************************************************************
+NAME ALBERS CONICAL EQUAL AREA
+
+PURPOSE: Transforms input longitude and latitude to Easting and Northing
+ for the Albers Conical Equal Area projection. The longitude
+ and latitude must be in radians. The Easting and Northing
+ values will be returned in meters.
+
+PROGRAMMER DATE
+---------- ----
+T. Mittan, Feb, 1992
+
+ALGORITHM REFERENCES
+
+1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
+ Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
+ State Government Printing Office, Washington D.C., 1987.
+
+2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
+ U.S. Geological Survey Professional Paper 1453 , United State Government
+ Printing Office, Washington D.C., 1989.
+*******************************************************************************/
+
+
+Proj4js.Proj.aea = {
+ init : function() {
+
+ if (Math.abs(this.lat1 + this.lat2) < Proj4js.common.EPSLN) {
+ Proj4js.reportError("aeaInitEqualLatitudes");
+ return;
+ }
+ this.temp = this.b / this.a;
+ this.es = 1.0 - Math.pow(this.temp,2);
+ this.e3 = Math.sqrt(this.es);
+
+ this.sin_po=Math.sin(this.lat1);
+ this.cos_po=Math.cos(this.lat1);
+ this.t1=this.sin_po;
+ this.con = this.sin_po;
+ this.ms1 = Proj4js.common.msfnz(this.e3,this.sin_po,this.cos_po);
+ this.qs1 = Proj4js.common.qsfnz(this.e3,this.sin_po,this.cos_po);
+
+ this.sin_po=Math.sin(this.lat2);
+ this.cos_po=Math.cos(this.lat2);
+ this.t2=this.sin_po;
+ this.ms2 = Proj4js.common.msfnz(this.e3,this.sin_po,this.cos_po);
+ this.qs2 = Proj4js.common.qsfnz(this.e3,this.sin_po,this.cos_po);
+
+ this.sin_po=Math.sin(this.lat0);
+ this.cos_po=Math.cos(this.lat0);
+ this.t3=this.sin_po;
+ this.qs0 = Proj4js.common.qsfnz(this.e3,this.sin_po,this.cos_po);
+
+ if (Math.abs(this.lat1 - this.lat2) > Proj4js.common.EPSLN) {
+ this.ns0 = (this.ms1 * this.ms1 - this.ms2 *this.ms2)/ (this.qs2 - this.qs1);
+ } else {
+ this.ns0 = this.con;
+ }
+ this.c = this.ms1 * this.ms1 + this.ns0 * this.qs1;
+ this.rh = this.a * Math.sqrt(this.c - this.ns0 * this.qs0)/this.ns0;
+ },
+
+/* Albers Conical Equal Area forward equations--mapping lat,long to x,y
+ -------------------------------------------------------------------*/
+ forward: function(p){
+
+ var lon=p.x;
+ var lat=p.y;
+
+ this.sin_phi=Math.sin(lat);
+ this.cos_phi=Math.cos(lat);
+
+ var qs = Proj4js.common.qsfnz(this.e3,this.sin_phi,this.cos_phi);
+ var rh1 =this.a * Math.sqrt(this.c - this.ns0 * qs)/this.ns0;
+ var theta = this.ns0 * Proj4js.common.adjust_lon(lon - this.long0);
+ var x = rh1 * Math.sin(theta) + this.x0;
+ var y = this.rh - rh1 * Math.cos(theta) + this.y0;
+
+ p.x = x;
+ p.y = y;
+ return p;
+ },
+
+
+ inverse: function(p) {
+ var rh1,qs,con,theta,lon,lat;
+
+ p.x -= this.x0;
+ p.y = this.rh - p.y + this.y0;
+ if (this.ns0 >= 0) {
+ rh1 = Math.sqrt(p.x *p.x + p.y * p.y);
+ con = 1.0;
+ } else {
+ rh1 = -Math.sqrt(p.x * p.x + p.y *p.y);
+ con = -1.0;
+ }
+ theta = 0.0;
+ if (rh1 != 0.0) {
+ theta = Math.atan2(con * p.x, con * p.y);
+ }
+ con = rh1 * this.ns0 / this.a;
+ qs = (this.c - con * con) / this.ns0;
+ if (this.e3 >= 1e-10) {
+ con = 1 - .5 * (1.0 -this.es) * Math.log((1.0 - this.e3) / (1.0 + this.e3))/this.e3;
+ if (Math.abs(Math.abs(con) - Math.abs(qs)) > .0000000001 ) {
+ lat = this.phi1z(this.e3,qs);
+ } else {
+ if (qs >= 0) {
+ lat = .5 * PI;
+ } else {
+ lat = -.5 * PI;
+ }
+ }
+ } else {
+ lat = this.phi1z(e3,qs);
+ }
+
+ lon = Proj4js.common.adjust_lon(theta/this.ns0 + this.long0);
+ p.x = lon;
+ p.y = lat;
+ return p;
+ },
+
+/* Function to compute phi1, the latitude for the inverse of the
+ Albers Conical Equal-Area projection.
+-------------------------------------------*/
+ phi1z: function (eccent,qs) {
+ var con, com, dphi;
+ var phi = Proj4js.common.asinz(.5 * qs);
+ if (eccent < Proj4js.common.EPSLN) return phi;
+
+ var eccnts = eccent * eccent;
+ for (var i = 1; i <= 25; i++) {
+ sinphi = Math.sin(phi);
+ cosphi = Math.cos(phi);
+ con = eccent * sinphi;
+ com = 1.0 - con * con;
+ dphi = .5 * com * com / cosphi * (qs / (1.0 - eccnts) - sinphi / com + .5 / eccent * Math.log((1.0 - con) / (1.0 + con)));
+ phi = phi + dphi;
+ if (Math.abs(dphi) <= 1e-7) return phi;
+ }
+ Proj4js.reportError("aea:phi1z:Convergence error");
+ return null;
+ }
+
+};
+
+
+
+/* ======================================================================
+ projCode/sterea.js
+ ====================================================================== */
+
+
+Proj4js.Proj.sterea = {
+ dependsOn : 'gauss',
+
+ init : function() {
+ Proj4js.Proj['gauss'].init.apply(this);
+ if (!this.rc) {
+ Proj4js.reportError("sterea:init:E_ERROR_0");
+ return;
+ }
+ this.sinc0 = Math.sin(this.phic0);
+ this.cosc0 = Math.cos(this.phic0);
+ this.R2 = 2.0 * this.rc;
+ if (!this.title) this.title = "Oblique Stereographic Alternative";
+ },
+
+ forward : function(p) {
+ p.x = Proj4js.common.adjust_lon(p.x-this.long0); /* adjust del longitude */
+ Proj4js.Proj['gauss'].forward.apply(this, [p]);
+ sinc = Math.sin(p.y);
+ cosc = Math.cos(p.y);
+ cosl = Math.cos(p.x);
+ k = this.k0 * this.R2 / (1.0 + this.sinc0 * sinc + this.cosc0 * cosc * cosl);
+ p.x = k * cosc * Math.sin(p.x);
+ p.y = k * (this.cosc0 * sinc - this.sinc0 * cosc * cosl);
+ p.x = this.a * p.x + this.x0;
+ p.y = this.a * p.y + this.y0;
+ return p;
+ },
+
+ inverse : function(p) {
+ var lon,lat;
+ p.x = (p.x - this.x0) / this.a; /* descale and de-offset */
+ p.y = (p.y - this.y0) / this.a;
+
+ p.x /= this.k0;
+ p.y /= this.k0;
+ if ( (rho = Math.sqrt(p.x*p.x + p.y*p.y)) ) {
+ c = 2.0 * Math.atan2(rho, this.R2);
+ sinc = Math.sin(c);
+ cosc = Math.cos(c);
+ lat = Math.asin(cosc * this.sinc0 + p.y * sinc * this.cosc0 / rho);
+ lon = Math.atan2(p.x * sinc, rho * this.cosc0 * cosc - p.y * this.sinc0 * sinc);
+ } else {
+ lat = this.phic0;
+ lon = 0.;
+ }
+
+ p.x = lon;
+ p.y = lat;
+ Proj4js.Proj['gauss'].inverse.apply(this,[p]);
+ p.x = Proj4js.common.adjust_lon(p.x + this.long0); /* adjust longitude to CM */
+ return p;
+ }
+};
+
+/* ======================================================================
+ projCode/poly.js
+ ====================================================================== */
+
+/* Function to compute, phi4, the latitude for the inverse of the
+ Polyconic projection.
+------------------------------------------------------------*/
+function phi4z (eccent,e0,e1,e2,e3,a,b,c,phi) {
+ var sinphi, sin2ph, tanph, ml, mlp, con1, con2, con3, dphi, i;
+
+ phi = a;
+ for (i = 1; i <= 15; i++) {
+ sinphi = Math.sin(phi);
+ tanphi = Math.tan(phi);
+ c = tanphi * Math.sqrt (1.0 - eccent * sinphi * sinphi);
+ sin2ph = Math.sin (2.0 * phi);
+ /*
+ ml = e0 * *phi - e1 * sin2ph + e2 * sin (4.0 * *phi);
+ mlp = e0 - 2.0 * e1 * cos (2.0 * *phi) + 4.0 * e2 * cos (4.0 * *phi);
+ */
+ ml = e0 * phi - e1 * sin2ph + e2 * Math.sin (4.0 * phi) - e3 * Math.sin (6.0 * phi);
+ mlp = e0 - 2.0 * e1 * Math.cos (2.0 * phi) + 4.0 * e2 * Math.cos (4.0 * phi) - 6.0 * e3 * Math.cos (6.0 * phi);
+ con1 = 2.0 * ml + c * (ml * ml + b) - 2.0 * a * (c * ml + 1.0);
+ con2 = eccent * sin2ph * (ml * ml + b - 2.0 * a * ml) / (2.0 *c);
+ con3 = 2.0 * (a - ml) * (c * mlp - 2.0 / sin2ph) - 2.0 * mlp;
+ dphi = con1 / (con2 + con3);
+ phi += dphi;
+ if (Math.abs(dphi) <= .0000000001 ) return(phi);
+ }
+ Proj4js.reportError("phi4z: No convergence");
+ return null;
+}
+
+
+/* Function to compute the constant e4 from the input of the eccentricity
+ of the spheroid, x. This constant is used in the Polar Stereographic
+ projection.
+--------------------------------------------------------------------*/
+function e4fn(x) {
+ var con, com;
+ con = 1.0 + x;
+ com = 1.0 - x;
+ return (Math.sqrt((Math.pow(con,con))*(Math.pow(com,com))));
+}
+
+
+
+
+
+/*******************************************************************************
+NAME POLYCONIC
+
+PURPOSE: Transforms input longitude and latitude to Easting and
+ Northing for the Polyconic projection. The
+ longitude and latitude must be in radians. The Easting
+ and Northing values will be returned in meters.
+
+PROGRAMMER DATE
+---------- ----
+T. Mittan Mar, 1993
+
+ALGORITHM REFERENCES
+
+1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
+ Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
+ State Government Printing Office, Washington D.C., 1987.
+
+2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
+ U.S. Geological Survey Professional Paper 1453 , United State Government
+ Printing Office, Washington D.C., 1989.
+*******************************************************************************/
+
+Proj4js.Proj.poly = {
+
+ /* Initialize the POLYCONIC projection
+ ----------------------------------*/
+ init: function() {
+ var temp; /* temporary variable */
+ if (this.lat0=0) this.lat0=90;//this.lat0 ca
+
+ /* Place parameters in static storage for common use
+ -------------------------------------------------*/
+ this.temp = this.b / this.a;
+ this.es = 1.0 - Math.pow(this.temp,2);// devait etre dans tmerc.js mais n y est pas donc je commente sinon retour de valeurs nulles
+ this.e = Math.sqrt(this.es);
+ this.e0 = Proj4js.common.e0fn(this.es);
+ this.e1 = Proj4js.common.e1fn(this.es);
+ this.e2 = Proj4js.common.e2fn(this.es);
+ this.e3 = Proj4js.common.e3fn(this.es);
+ this.ml0 = Proj4js.common.mlfn(this.e0, this.e1,this.e2, this.e3, this.lat0);//si que des zeros le calcul ne se fait pas
+ //if (!this.ml0) {this.ml0=0;}
+ },
+
+
+ /* Polyconic forward equations--mapping lat,long to x,y
+ ---------------------------------------------------*/
+ forward: function(p) {
+ var sinphi, cosphi; /* sin and cos value */
+ var al; /* temporary values */
+ var c; /* temporary values */
+ var con, ml; /* cone constant, small m */
+ var ms; /* small m */
+ var x,y;
+
+ var lon=p.x;
+ var lat=p.y;
+
+ con = Proj4js.common.adjust_lon(lon - this.long0);
+ if (Math.abs(lat) <= .0000001) {
+ x = this.x0 + this.a * con;
+ y = this.y0 - this.a * this.ml0;
+ } else {
+ sinphi = Math.sin(lat);
+ cosphi = Math.cos(lat);
+
+ ml = Proj4js.common.mlfn(this.e0, this.e1, this.e2, this.e3, lat);
+ ms = Proj4js.common.msfnz(this.e,sinphi,cosphi);
+ con = sinphi;
+ x = this.x0 + this.a * ms * Math.sin(con)/sinphi;
+ y = this.y0 + this.a * (ml - this.ml0 + ms * (1.0 - Math.cos(con))/sinphi);
+ }
+
+ p.x=x;
+ p.y=y;
+ return p;
+ },
+
+
+ /* Inverse equations
+ -----------------*/
+ inverse: function(p) {
+ var sin_phi, cos_phi; /* sin and cos value */
+ var al; /* temporary values */
+ var b; /* temporary values */
+ var c; /* temporary values */
+ var con, ml; /* cone constant, small m */
+ var iflg; /* error flag */
+ var lon,lat;
+ p.x -= this.x0;
+ p.y -= this.y0;
+ al = this.ml0 + p.y/this.a;
+ iflg = 0;
+
+ if (Math.abs(al) <= .0000001) {
+ lon = p.x/this.a + this.long0;
+ lat = 0.0;
+ } else {
+ b = al * al + (p.x/this.a) * (p.x/this.a);
+ iflg = phi4z(this.es,this.e0,this.e1,this.e2,this.e3,this.al,b,c,lat);
+ if (iflg != 1) return(iflg);
+ lon = Proj4js.common.adjust_lon((Proj4js.common.asinz(p.x * c / this.a) / Math.sin(lat)) + this.long0);
+ }
+
+ p.x=lon;
+ p.y=lat;
+ return p;
+ }
+};
+
+
+
+/* ======================================================================
+ projCode/equi.js
+ ====================================================================== */
+
+/*******************************************************************************
+NAME EQUIRECTANGULAR
+
+PURPOSE: Transforms input longitude and latitude to Easting and
+ Northing for the Equirectangular projection. The
+ longitude and latitude must be in radians. The Easting
+ and Northing values will be returned in meters.
+
+PROGRAMMER DATE
+---------- ----
+T. Mittan Mar, 1993
+
+ALGORITHM REFERENCES
+
+1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
+ Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
+ State Government Printing Office, Washington D.C., 1987.
+
+2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
+ U.S. Geological Survey Professional Paper 1453 , United State Government
+ Printing Office, Washington D.C., 1989.
+*******************************************************************************/
+Proj4js.Proj.equi = {
+
+ init: function() {
+ if(!this.x0) this.x0=0;
+ if(!this.y0) this.y0=0;
+ if(!this.lat0) this.lat0=0;
+ if(!this.long0) this.long0=0;
+ ///this.t2;
+ },
+
+
+
+/* Equirectangular forward equations--mapping lat,long to x,y
+ ---------------------------------------------------------*/
+ forward: function(p) {
+
+ var lon=p.x;
+ var lat=p.y;
+
+ var dlon = Proj4js.common.adjust_lon(lon - this.long0);
+ var x = this.x0 +this. a * dlon *Math.cos(this.lat0);
+ var y = this.y0 + this.a * lat;
+
+ this.t1=x;
+ this.t2=Math.cos(this.lat0);
+ p.x=x;
+ p.y=y;
+ return p;
+ }, //equiFwd()
+
+
+
+/* Equirectangular inverse equations--mapping x,y to lat/long
+ ---------------------------------------------------------*/
+ inverse: function(p) {
+
+ p.x -= this.x0;
+ p.y -= this.y0;
+ var lat = p.y /this. a;
+
+ if ( Math.abs(lat) > Proj4js.common.HALF_PI) {
+ Proj4js.reportError("equi:Inv:DataError");
+ }
+ var lon = Proj4js.common.adjust_lon(this.long0 + p.x / (this.a * Math.cos(this.lat0)));
+ p.x=lon;
+ p.y=lat;
+ }//equiInv()
+};
+
+
+/* ======================================================================
+ projCode/merc.js
+ ====================================================================== */
+
+/*******************************************************************************
+NAME MERCATOR
+
+PURPOSE: Transforms input longitude and latitude to Easting and
+ Northing for the Mercator projection. The
+ longitude and latitude must be in radians. The Easting
+ and Northing values will be returned in meters.
+
+PROGRAMMER DATE
+---------- ----
+D. Steinwand, EROS Nov, 1991
+T. Mittan Mar, 1993
+
+ALGORITHM REFERENCES
+
+1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
+ Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
+ State Government Printing Office, Washington D.C., 1987.
+
+2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
+ U.S. Geological Survey Professional Paper 1453 , United State Government
+ Printing Office, Washington D.C., 1989.
+*******************************************************************************/
+
+//static double r_major = a; /* major axis */
+//static double r_minor = b; /* minor axis */
+//static double lon_center = long0; /* Center longitude (projection center) */
+//static double lat_origin = lat0; /* center latitude */
+//static double e,es; /* eccentricity constants */
+//static double m1; /* small value m */
+//static double false_northing = y0; /* y offset in meters */
+//static double false_easting = x0; /* x offset in meters */
+//scale_fact = k0
+
+Proj4js.Proj.merc = {
+ init : function() {
+ //?this.temp = this.r_minor / this.r_major;
+ //this.temp = this.b / this.a;
+ //this.es = 1.0 - Math.sqrt(this.temp);
+ //this.e = Math.sqrt( this.es );
+ //?this.m1 = Math.cos(this.lat_origin) / (Math.sqrt( 1.0 - this.es * Math.sin(this.lat_origin) * Math.sin(this.lat_origin)));
+ //this.m1 = Math.cos(0.0) / (Math.sqrt( 1.0 - this.es * Math.sin(0.0) * Math.sin(0.0)));
+ if (this.lat_ts) {
+ if (this.sphere) {
+ this.k0 = Math.cos(this.lat_ts);
+ } else {
+ this.k0 = Proj4js.common.msfnz(this.es, Math.sin(this.lat_ts), Math.cos(this.lat_ts));
+ }
+ }
+ },
+
+/* Mercator forward equations--mapping lat,long to x,y
+ --------------------------------------------------*/
+
+ forward : function(p) {
+ //alert("ll2m coords : "+coords);
+ var lon = p.x;
+ var lat = p.y;
+ // convert to radians
+ if ( lat*Proj4js.common.R2D > 90.0 &&
+ lat*Proj4js.common.R2D < -90.0 &&
+ lon*Proj4js.common.R2D > 180.0 &&
+ lon*Proj4js.common.R2D < -180.0) {
+ Proj4js.reportError("merc:forward: llInputOutOfRange: "+ lon +" : " + lat);
+ return null;
+ }
+
+ var x,y;
+ if(Math.abs( Math.abs(lat) - Proj4js.common.HALF_PI) <= Proj4js.common.EPSLN) {
+ Proj4js.reportError("merc:forward: ll2mAtPoles");
+ return null;
+ } else {
+ if (this.sphere) {
+ x = this.x0 + this.a * this.k0 * Proj4js.common.adjust_lon(lon - this.long0);
+ y = this.y0 + this.a * this.k0 * Math.log(Math.tan(Proj4js.common.FORTPI + 0.5*lat));
+ } else {
+ var sinphi = Math.sin(lat);
+ var ts = Proj4js.common.tsfnz(this.e,lat,sinphi);
+ x = this.x0 + this.a * this.k0 * Proj4js.common.adjust_lon(lon - this.long0);
+ y = this.y0 - this.a * this.k0 * Math.log(ts);
+ }
+ p.x = x;
+ p.y = y;
+ return p;
+ }
+ },
+
+
+ /* Mercator inverse equations--mapping x,y to lat/long
+ --------------------------------------------------*/
+ inverse : function(p) {
+
+ var x = p.x - this.x0;
+ var y = p.y - this.y0;
+ var lon,lat;
+
+ if (this.sphere) {
+ lat = Proj4js.common.HALF_PI - 2.0 * Math.atan(Math.exp(-y / this.a * this.k0));
+ } else {
+ var ts = Math.exp(-y / (this.a * this.k0));
+ lat = Proj4js.common.phi2z(this.e,ts);
+ if(lat == -9999) {
+ Proj4js.reportError("merc:inverse: lat = -9999");
+ return null;
+ }
+ }
+ lon = Proj4js.common.adjust_lon(this.long0+ x / (this.a * this.k0));
+
+ p.x = lon;
+ p.y = lat;
+ return p;
+ }
+};
+
+
+/* ======================================================================
+ projCode/utm.js
+ ====================================================================== */
+
+/*******************************************************************************
+NAME TRANSVERSE MERCATOR
+
+PURPOSE: Transforms input longitude and latitude to Easting and
+ Northing for the Transverse Mercator projection. The
+ longitude and latitude must be in radians. The Easting
+ and Northing values will be returned in meters.
+
+ALGORITHM REFERENCES
+
+1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
+ Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
+ State Government Printing Office, Washington D.C., 1987.
+
+2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
+ U.S. Geological Survey Professional Paper 1453 , United State Government
+ Printing Office, Washington D.C., 1989.
+*******************************************************************************/
+
+
+/**
+ Initialize Transverse Mercator projection
+*/
+
+Proj4js.Proj.utm = {
+ dependsOn : 'tmerc',
+
+ init : function() {
+ if (!this.zone) {
+ Proj4js.reportError("utm:init: zone must be specified for UTM");
+ return;
+ }
+ this.lat0 = 0.0;
+ this.long0 = ((6 * Math.abs(this.zone)) - 183) * Proj4js.common.D2R;
+ this.x0 = 500000.0;
+ this.y0 = this.utmSouth ? 10000000.0 : 0.0;
+ this.k0 = 0.9996;
+
+ Proj4js.Proj['tmerc'].init.apply(this);
+ this.forward = Proj4js.Proj['tmerc'].forward;
+ this.inverse = Proj4js.Proj['tmerc'].inverse;
+ }
+};
+/* ======================================================================
+ projCode/eqdc.js
+ ====================================================================== */
+
+/*******************************************************************************
+NAME EQUIDISTANT CONIC
+
+PURPOSE: Transforms input longitude and latitude to Easting and Northing
+ for the Equidistant Conic projection. The longitude and
+ latitude must be in radians. The Easting and Northing values
+ will be returned in meters.
+
+PROGRAMMER DATE
+---------- ----
+T. Mittan Mar, 1993
+
+ALGORITHM REFERENCES
+
+1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
+ Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
+ State Government Printing Office, Washington D.C., 1987.
+
+2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
+ U.S. Geological Survey Professional Paper 1453 , United State Government
+ Printing Office, Washington D.C., 1989.
+*******************************************************************************/
+
+/* Variables common to all subroutines in this code file
+ -----------------------------------------------------*/
+
+Proj4js.Proj.eqdc = {
+
+/* Initialize the Equidistant Conic projection
+ ------------------------------------------*/
+ init: function() {
+
+ /* Place parameters in static storage for common use
+ -------------------------------------------------*/
+
+ if(!this.mode) this.mode=0;//chosen default mode
+ this.temp = this.b / this.a;
+ this.es = 1.0 - Math.pow(this.temp,2);
+ this.e = Math.sqrt(this.es);
+ this.e0 = Proj4js.common.e0fn(this.es);
+ this.e1 = Proj4js.common.e1fn(this.es);
+ this.e2 = Proj4js.common.e2fn(this.es);
+ this.e3 = Proj4js.common.e3fn(this.es);
+
+ this.sinphi=Math.sin(this.lat1);
+ this.cosphi=Math.cos(this.lat1);
+
+ this.ms1 = Proj4js.common.msfnz(this.e,this.sinphi,this.cosphi);
+ this.ml1 = Proj4js.common.mlfn(this.e0, this.e1, this.e2,this.e3, this.lat1);
+
+ /* format B
+ ---------*/
+ if (this.mode != 0) {
+ if (Math.abs(this.lat1 + this.lat2) < Proj4js.common.EPSLN) {
+ Proj4js.reportError("eqdc:Init:EqualLatitudes");
+ //return(81);
+ }
+ this.sinphi=Math.sin(this.lat2);
+ this.cosphi=Math.cos(this.lat2);
+
+ this.ms2 = Proj4js.common.msfnz(this.e,this.sinphi,this.cosphi);
+ this.ml2 = Proj4js.common.mlfn(this.e0, this.e1, this.e2, this.e3, this.lat2);
+ if (Math.abs(this.lat1 - this.lat2) >= Proj4js.common.EPSLN) {
+ this.ns = (this.ms1 - this.ms2) / (this.ml2 - this.ml1);
+ } else {
+ this.ns = this.sinphi;
+ }
+ } else {
+ this.ns = this.sinphi;
+ }
+ this.g = this.ml1 + this.ms1/this.ns;
+ this.ml0 = Proj4js.common.mlfn(this.e0, this.e1,this. e2, this.e3, this.lat0);
+ this.rh = this.a * (this.g - this.ml0);
+ },
+
+
+/* Equidistant Conic forward equations--mapping lat,long to x,y
+ -----------------------------------------------------------*/
+ forward: function(p) {
+ var lon=p.x;
+ var lat=p.y;
+
+ /* Forward equations
+ -----------------*/
+ var ml = Proj4js.common.mlfn(this.e0, this.e1, this.e2, this.e3, lat);
+ var rh1 = this.a * (this.g - ml);
+ var theta = this.ns * Proj4js.common.adjust_lon(lon - this.long0);
+
+ var x = this.x0 + rh1 * Math.sin(theta);
+ var y = this.y0 + this.rh - rh1 * Math.cos(theta);
+ p.x=x;
+ p.y=y;
+ return p;
+ },
+
+/* Inverse equations
+ -----------------*/
+ inverse: function(p) {
+ p.x -= this.x0;
+ p.y = this.rh - p.y + this.y0;
+ var con, rh1;
+ if (this.ns >= 0) {
+ var rh1 = Math.sqrt(p.x *p.x + p.y * p.y);
+ var con = 1.0;
+ } else {
+ rh1 = -Math.sqrt(p.x *p. x +p. y * p.y);
+ con = -1.0;
+ }
+ var theta = 0.0;
+ if (rh1 != 0.0) theta = Math.atan2(con *p.x, con *p.y);
+ var ml = this.g - rh1 /this.a;
+ var lat = this.phi3z(ml,this.e0,this.e1,this.e2,this.e3);
+ var lon = Proj4js.common.adjust_lon(this.long0 + theta / this.ns);
+
+ p.x=lon;
+ p.y=lat;
+ return p;
+ },
+
+/* Function to compute latitude, phi3, for the inverse of the Equidistant
+ Conic projection.
+-----------------------------------------------------------------*/
+ phi3z: function(ml,e0,e1,e2,e3) {
+ var phi;
+ var dphi;
+
+ phi = ml;
+ for (var i = 0; i < 15; i++) {
+ dphi = (ml + e1 * Math.sin(2.0 * phi) - e2 * Math.sin(4.0 * phi) + e3 * Math.sin(6.0 * phi))/ e0 - phi;
+ phi += dphi;
+ if (Math.abs(dphi) <= .0000000001) {
+ return phi;
+ }
+ }
+ Proj4js.reportError("PHI3Z-CONV:Latitude failed to converge after 15 iterations");
+ return null;
+ }
+
+
+};
+/* ======================================================================
+ projCode/tmerc.js
+ ====================================================================== */
+
+/*******************************************************************************
+NAME TRANSVERSE MERCATOR
+
+PURPOSE: Transforms input longitude and latitude to Easting and
+ Northing for the Transverse Mercator projection. The
+ longitude and latitude must be in radians. The Easting
+ and Northing values will be returned in meters.
+
+ALGORITHM REFERENCES
+
+1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
+ Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
+ State Government Printing Office, Washington D.C., 1987.
+
+2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
+ U.S. Geological Survey Professional Paper 1453 , United State Government
+ Printing Office, Washington D.C., 1989.
+*******************************************************************************/
+
+
+/**
+ Initialize Transverse Mercator projection
+*/
+
+Proj4js.Proj.tmerc = {
+ init : function() {
+ this.e0 = Proj4js.common.e0fn(this.es);
+ this.e1 = Proj4js.common.e1fn(this.es);
+ this.e2 = Proj4js.common.e2fn(this.es);
+ this.e3 = Proj4js.common.e3fn(this.es);
+ this.ml0 = this.a * Proj4js.common.mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0);
+ },
+
+ /**
+ Transverse Mercator Forward - long/lat to x/y
+ long/lat in radians
+ */
+ forward : function(p) {
+ var lon = p.x;
+ var lat = p.y;
+
+ var delta_lon = Proj4js.common.adjust_lon(lon - this.long0); // Delta longitude
+ var con; // cone constant
+ var x, y;
+ var sin_phi=Math.sin(lat);
+ var cos_phi=Math.cos(lat);
+
+ if (this.sphere) { /* spherical form */
+ var b = cos_phi * Math.sin(delta_lon);
+ if ((Math.abs(Math.abs(b) - 1.0)) < .0000000001) {
+ Proj4js.reportError("tmerc:forward: Point projects into infinity");
+ return(93);
+ } else {
+ x = .5 * this.a * this.k0 * Math.log((1.0 + b)/(1.0 - b));
+ con = Math.acos(cos_phi * Math.cos(delta_lon)/Math.sqrt(1.0 - b*b));
+ if (lat < 0) con = - con;
+ y = this.a * this.k0 * (con - this.lat0);
+ }
+ } else {
+ var al = cos_phi * delta_lon;
+ var als = Math.pow(al,2);
+ var c = this.ep2 * Math.pow(cos_phi,2);
+ var tq = Math.tan(lat);
+ var t = Math.pow(tq,2);
+ con = 1.0 - this.es * Math.pow(sin_phi,2);
+ var n = this.a / Math.sqrt(con);
+ var ml = this.a * Proj4js.common.mlfn(this.e0, this.e1, this.e2, this.e3, lat);
+
+ x = this.k0 * n * al * (1.0 + als / 6.0 * (1.0 - t + c + als / 20.0 * (5.0 - 18.0 * t + Math.pow(t,2) + 72.0 * c - 58.0 * this.ep2))) + this.x0;
+ y = this.k0 * (ml - this.ml0 + n * tq * (als * (0.5 + als / 24.0 * (5.0 - t + 9.0 * c + 4.0 * Math.pow(c,2) + als / 30.0 * (61.0 - 58.0 * t + Math.pow(t,2) + 600.0 * c - 330.0 * this.ep2))))) + this.y0;
+
+ }
+ p.x = x; p.y = y;
+ return p;
+ }, // tmercFwd()
+
+ /**
+ Transverse Mercator Inverse - x/y to long/lat
+ */
+ inverse : function(p) {
+ var con, phi; /* temporary angles */
+ var delta_phi; /* difference between longitudes */
+ var i;
+ var max_iter = 6; /* maximun number of iterations */
+ var lat, lon;
+
+ if (this.sphere) { /* spherical form */
+ var f = Math.exp(p.x/(this.a * this.k0));
+ var g = .5 * (f - 1/f);
+ var temp = this.lat0 + p.y/(this.a * this.k0);
+ var h = Math.cos(temp);
+ con = Math.sqrt((1.0 - h * h)/(1.0 + g * g));
+ lat = Proj4js.common.asinz(con);
+ if (temp < 0)
+ lat = -lat;
+ if ((g == 0) && (h == 0)) {
+ lon = this.long0;
+ } else {
+ lon = Proj4js.common.adjust_lon(Math.atan2(g,h) + this.long0);
+ }
+ } else { // ellipsoidal form
+ var x = p.x - this.x0;
+ var y = p.y - this.y0;
+
+ con = (this.ml0 + y / this.k0) / this.a;
+ phi = con;
+ for (i=0;true;i++) {
+ delta_phi=((con + this.e1 * Math.sin(2.0*phi) - this.e2 * Math.sin(4.0*phi) + this.e3 * Math.sin(6.0*phi)) / this.e0) - phi;
+ phi += delta_phi;
+ if (Math.abs(delta_phi) <= Proj4js.common.EPSLN) break;
+ if (i >= max_iter) {
+ Proj4js.reportError("tmerc:inverse: Latitude failed to converge");
+ return(95);
+ }
+ } // for()
+ if (Math.abs(phi) < Proj4js.common.HALF_PI) {
+ // sincos(phi, &sin_phi, &cos_phi);
+ var sin_phi=Math.sin(phi);
+ var cos_phi=Math.cos(phi);
+ var tan_phi = Math.tan(phi);
+ var c = this.ep2 * Math.pow(cos_phi,2);
+ var cs = Math.pow(c,2);
+ var t = Math.pow(tan_phi,2);
+ var ts = Math.pow(t,2);
+ con = 1.0 - this.es * Math.pow(sin_phi,2);
+ var n = this.a / Math.sqrt(con);
+ var r = n * (1.0 - this.es) / con;
+ var d = x / (n * this.k0);
+ var ds = Math.pow(d,2);
+ lat = phi - (n * tan_phi * ds / r) * (0.5 - ds / 24.0 * (5.0 + 3.0 * t + 10.0 * c - 4.0 * cs - 9.0 * this.ep2 - ds / 30.0 * (61.0 + 90.0 * t + 298.0 * c + 45.0 * ts - 252.0 * this.ep2 - 3.0 * cs)));
+ lon = Proj4js.common.adjust_lon(this.long0 + (d * (1.0 - ds / 6.0 * (1.0 + 2.0 * t + c - ds / 20.0 * (5.0 - 2.0 * c + 28.0 * t - 3.0 * cs + 8.0 * this.ep2 + 24.0 * ts))) / cos_phi));
+ } else {
+ lat = Proj4js.common.HALF_PI * Proj4js.common.sign(y);
+ lon = this.long0;
+ }
+ }
+ p.x = lon;
+ p.y = lat;
+ return p;
+ } // tmercInv()
+};
+/* ======================================================================
+ defs/GOOGLE.js
+ ====================================================================== */
+
+Proj4js.defs["GOOGLE"]="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs";
+Proj4js.defs["EPSG:900913"]=Proj4js.defs["GOOGLE"];
+/* ======================================================================
+ projCode/gstmerc.js
+ ====================================================================== */
+
+Proj4js.Proj.gstmerc = {
+ init : function() {
+
+ // array of: a, b, lon0, lat0, k0, x0, y0
+ var temp= this.b / this.a;
+ this.e= Math.sqrt(1.0 - temp*temp);
+ this.lc= this.long0;
+ this.rs= Math.sqrt(1.0+this.e*this.e*Math.pow(Math.cos(this.lat0),4.0)/(1.0-this.e*this.e));
+ var sinz= Math.sin(this.lat0);
+ var pc= Math.asin(sinz/this.rs);
+ var sinzpc= Math.sin(pc);
+ this.cp= Proj4js.common.latiso(0.0,pc,sinzpc)-this.rs*Proj4js.common.latiso(this.e,this.lat0,sinz);
+ this.n2= this.k0*this.a*Math.sqrt(1.0-this.e*this.e)/(1.0-this.e*this.e*sinz*sinz);
+ this.xs= this.x0;
+ this.ys= this.y0-this.n2*pc;
+
+ if (!this.title) this.title = "Gauss Schreiber transverse mercator";
+ },
+
+
+ // forward equations--mapping lat,long to x,y
+ // -----------------------------------------------------------------
+ forward : function(p) {
+
+ var lon= p.x;
+ var lat= p.y;
+
+ var L= this.rs*(lon-this.lc);
+ var Ls= this.cp+(this.rs*Proj4js.common.latiso(this.e,lat,Math.sin(lat)));
+ var lat1= Math.asin(Math.sin(L)/Proj4js.common.cosh(Ls));
+ var Ls1= Proj4js.common.latiso(0.0,lat1,Math.sin(lat1));
+ p.x= this.xs+(this.n2*Ls1);
+ p.y= this.ys+(this.n2*Math.atan(Proj4js.common.sinh(Ls)/Math.cos(L)));
+ return p;
+ },
+
+ // inverse equations--mapping x,y to lat/long
+ // -----------------------------------------------------------------
+ inverse : function(p) {
+
+ var x= p.x;
+ var y= p.y;
+
+ var L= Math.atan(Proj4js.common.sinh((x-this.xs)/this.n2)/Math.cos((y-this.ys)/this.n2));
+ var lat1= Math.asin(Math.sin((y-this.ys)/this.n2)/Proj4js.common.cosh((x-this.xs)/this.n2));
+ var LC= Proj4js.common.latiso(0.0,lat1,Math.sin(lat1));
+ p.x= this.lc+L/this.rs;
+ p.y= Proj4js.common.invlatiso(this.e,(LC-this.cp)/this.rs);
+ return p;
+ }
+
+};
+/* ======================================================================
+ projCode/ortho.js
+ ====================================================================== */
+
+/*******************************************************************************
+NAME ORTHOGRAPHIC
+
+PURPOSE: Transforms input longitude and latitude to Easting and
+ Northing for the Orthographic projection. The
+ longitude and latitude must be in radians. The Easting
+ and Northing values will be returned in meters.
+
+PROGRAMMER DATE
+---------- ----
+T. Mittan Mar, 1993
+
+ALGORITHM REFERENCES
+
+1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
+ Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
+ State Government Printing Office, Washington D.C., 1987.
+
+2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
+ U.S. Geological Survey Professional Paper 1453 , United State Government
+ Printing Office, Washington D.C., 1989.
+*******************************************************************************/
+
+Proj4js.Proj.ortho = {
+
+ /* Initialize the Orthographic projection
+ -------------------------------------*/
+ init: function(def) {
+ //double temp; /* temporary variable */
+
+ /* Place parameters in static storage for common use
+ -------------------------------------------------*/;
+ this.sin_p14=Math.sin(this.lat0);
+ this.cos_p14=Math.cos(this.lat0);
+ },
+
+
+ /* Orthographic forward equations--mapping lat,long to x,y
+ ---------------------------------------------------*/
+ forward: function(p) {
+ var sinphi, cosphi; /* sin and cos value */
+ var dlon; /* delta longitude value */
+ var coslon; /* cos of longitude */
+ var ksp; /* scale factor */
+ var g;
+ var lon=p.x;
+ var lat=p.y;
+ /* Forward equations
+ -----------------*/
+ dlon = Proj4js.common.adjust_lon(lon - this.long0);
+
+ sinphi=Math.sin(lat);
+ cosphi=Math.cos(lat);
+
+ coslon = Math.cos(dlon);
+ g = this.sin_p14 * sinphi + this.cos_p14 * cosphi * coslon;
+ ksp = 1.0;
+ if ((g > 0) || (Math.abs(g) <= Proj4js.common.EPSLN)) {
+ var x = this.a * ksp * cosphi * Math.sin(dlon);
+ var y = this.y0 + this.a * ksp * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon);
+ } else {
+ Proj4js.reportError("orthoFwdPointError");
+ }
+ p.x=x;
+ p.y=y;
+ return p;
+ },
+
+
+ inverse: function(p) {
+ var rh; /* height above ellipsoid */
+ var z; /* angle */
+ var sinz,cosz; /* sin of z and cos of z */
+ var temp;
+ var con;
+ var lon , lat;
+ /* Inverse equations
+ -----------------*/
+ p.x -= this.x0;
+ p.y -= this.y0;
+ rh = Math.sqrt(p.x * p.x + p.y * p.y);
+ if (rh > this.a + .0000001) {
+ Proj4js.reportError("orthoInvDataError");
+ }
+ z = Proj4js.common.asinz(rh / this.a);
+
+ sinz=Math.sin(z);
+ cosz=Math.cos(z);
+
+ lon = this.long0;
+ if (Math.abs(rh) <= Proj4js.common.EPSLN) {
+ lat = this.lat0;
+ }
+ lat = Proj4js.common.asinz(cosz * this.sin_p14 + (p.y * sinz * this.cos_p14)/rh);
+ con = Math.abs(this.lat0) - Proj4js.common.HALF_PI;
+ if (Math.abs(con) <= Proj4js.common.EPSLN) {
+ if (this.lat0 >= 0) {
+ lon = Proj4js.common.adjust_lon(this.long0 + Math.atan2(p.x, -p.y));
+ } else {
+ lon = Proj4js.common.adjust_lon(this.long0 -Math.atan2(-p.x, p.y));
+ }
+ }
+ con = cosz - this.sin_p14 * Math.sin(lat);
+ p.x=lon;
+ p.y=lat;
+ return p;
+ }
+};
+
+
+/* ======================================================================
+ projCode/somerc.js
+ ====================================================================== */
+
+/*******************************************************************************
+NAME SWISS OBLIQUE MERCATOR
+
+PURPOSE: Swiss projection.
+WARNING: X and Y are inverted (weird) in the swiss coordinate system. Not
+ here, since we want X to be horizontal and Y vertical.
+
+ALGORITHM REFERENCES
+1. "Formules et constantes pour le Calcul pour la
+ projection cylindrique conforme à axe oblique et pour la transformation entre
+ des systèmes de référence".
+ http://www.swisstopo.admin.ch/internet/swisstopo/fr/home/topics/survey/sys/refsys/switzerland.parsysrelated1.31216.downloadList.77004.DownloadFile.tmp/swissprojectionfr.pdf
+
+*******************************************************************************/
+
+Proj4js.Proj.somerc = {
+
+ init: function() {
+ var phy0 = this.lat0;
+ this.lambda0 = this.long0;
+ var sinPhy0 = Math.sin(phy0);
+ var semiMajorAxis = this.a;
+ var invF = this.rf;
+ var flattening = 1 / invF;
+ var e2 = 2 * flattening - Math.pow(flattening, 2);
+ var e = this.e = Math.sqrt(e2);
+ this.R = this.k0 * semiMajorAxis * Math.sqrt(1 - e2) / (1 - e2 * Math.pow(sinPhy0, 2.0));
+ this.alpha = Math.sqrt(1 + e2 / (1 - e2) * Math.pow(Math.cos(phy0), 4.0));
+ this.b0 = Math.asin(sinPhy0 / this.alpha);
+ this.K = Math.log(Math.tan(Math.PI / 4.0 + this.b0 / 2.0))
+ - this.alpha
+ * Math.log(Math.tan(Math.PI / 4.0 + phy0 / 2.0))
+ + this.alpha
+ * e / 2
+ * Math.log((1 + e * sinPhy0)
+ / (1 - e * sinPhy0));
+ },
+
+
+ forward: function(p) {
+ var Sa1 = Math.log(Math.tan(Math.PI / 4.0 - p.y / 2.0));
+ var Sa2 = this.e / 2.0
+ * Math.log((1 + this.e * Math.sin(p.y))
+ / (1 - this.e * Math.sin(p.y)));
+ var S = -this.alpha * (Sa1 + Sa2) + this.K;
+
+ // spheric latitude
+ var b = 2.0 * (Math.atan(Math.exp(S)) - Math.PI / 4.0);
+
+ // spheric longitude
+ var I = this.alpha * (p.x - this.lambda0);
+
+ // psoeudo equatorial rotation
+ var rotI = Math.atan(Math.sin(I)
+ / (Math.sin(this.b0) * Math.tan(b) +
+ Math.cos(this.b0) * Math.cos(I)));
+
+ var rotB = Math.asin(Math.cos(this.b0) * Math.sin(b) -
+ Math.sin(this.b0) * Math.cos(b) * Math.cos(I));
+
+ p.y = this.R / 2.0
+ * Math.log((1 + Math.sin(rotB)) / (1 - Math.sin(rotB)))
+ + this.y0;
+ p.x = this.R * rotI + this.x0;
+ return p;
+ },
+
+ inverse: function(p) {
+ var Y = p.x - this.x0;
+ var X = p.y - this.y0;
+
+ var rotI = Y / this.R;
+ var rotB = 2 * (Math.atan(Math.exp(X / this.R)) - Math.PI / 4.0);
+
+ var b = Math.asin(Math.cos(this.b0) * Math.sin(rotB)
+ + Math.sin(this.b0) * Math.cos(rotB) * Math.cos(rotI));
+ var I = Math.atan(Math.sin(rotI)
+ / (Math.cos(this.b0) * Math.cos(rotI) - Math.sin(this.b0)
+ * Math.tan(rotB)));
+
+ var lambda = this.lambda0 + I / this.alpha;
+
+ var S = 0.0;
+ var phy = b;
+ var prevPhy = -1000.0;
+ var iteration = 0;
+ while (Math.abs(phy - prevPhy) > 0.0000001)
+ {
+ if (++iteration > 20)
+ {
+ Proj4js.reportError("omercFwdInfinity");
+ return;
+ }
+ //S = Math.log(Math.tan(Math.PI / 4.0 + phy / 2.0));
+ S = 1.0
+ / this.alpha
+ * (Math.log(Math.tan(Math.PI / 4.0 + b / 2.0)) - this.K)
+ + this.e
+ * Math.log(Math.tan(Math.PI / 4.0
+ + Math.asin(this.e * Math.sin(phy))
+ / 2.0));
+ prevPhy = phy;
+ phy = 2.0 * Math.atan(Math.exp(S)) - Math.PI / 2.0;
+ }
+
+ p.x = lambda;
+ p.y = phy;
+ return p;
+ }
+};
+/* ======================================================================
+ projCode/stere.js
+ ====================================================================== */
+
+
+// Initialize the Stereographic projection
+
+Proj4js.Proj.stere = {
+ ssfn_: function(phit, sinphi, eccen) {
+ sinphi *= eccen;
+ return (Math.tan (.5 * (Proj4js.common.HALF_PI + phit)) * Math.pow((1. - sinphi) / (1. + sinphi), .5 * eccen));
+ },
+ TOL: 1.e-8,
+ NITER: 8,
+ CONV: 1.e-10,
+ S_POLE: 0,
+ N_POLE: 1,
+ OBLIQ: 2,
+ EQUIT: 3,
+
+ init : function() {
+ this.phits = this.lat_ts ? this.lat_ts : Proj4js.common.HALF_PI;
+ var t = Math.abs(this.lat0);
+ if ((Math.abs(t) - Proj4js.common.HALF_PI) < Proj4js.common.EPSLN) {
+ this.mode = this.lat0 < 0. ? this.S_POLE : this.N_POLE;
+ } else {
+ this.mode = t > Proj4js.common.EPSLN ? this.OBLIQ : this.EQUIT;
+ }
+ this.phits = Math.abs(this.phits);
+ if (this.es) {
+ var X;
+
+ switch (this.mode) {
+ case this.N_POLE:
+ case this.S_POLE:
+ if (Math.abs(this.phits - Proj4js.common.HALF_PI) < Proj4js.common.EPSLN) {
+ this.akm1 = 2. * this.k0 / Math.sqrt(Math.pow(1+this.e,1+this.e)*Math.pow(1-this.e,1-this.e));
+ } else {
+ t = Math.sin(this.phits);
+ this.akm1 = Math.cos(this.phits) / Proj4js.common.tsfnz(this.e, this.phits, t);
+ t *= this.e;
+ this.akm1 /= Math.sqrt(1. - t * t);
+ }
+ break;
+ case this.EQUIT:
+ this.akm1 = 2. * this.k0;
+ break;
+ case this.OBLIQ:
+ t = Math.sin(this.lat0);
+ X = 2. * Math.atan(this.ssfn_(this.lat0, t, this.e)) - Proj4js.common.HALF_PI;
+ t *= this.e;
+ this.akm1 = 2. * this.k0 * Math.cos(this.lat0) / Math.sqrt(1. - t * t);
+ this.sinX1 = Math.sin(X);
+ this.cosX1 = Math.cos(X);
+ break;
+ }
+ } else {
+ switch (this.mode) {
+ case this.OBLIQ:
+ this.sinph0 = Math.sin(this.lat0);
+ this.cosph0 = Math.cos(this.lat0);
+ case this.EQUIT:
+ this.akm1 = 2. * this.k0;
+ break;
+ case this.S_POLE:
+ case this.N_POLE:
+ this.akm1 = Math.abs(this.phits - Proj4js.common.HALF_PI) >= Proj4js.common.EPSLN ?
+ Math.cos(this.phits) / Math.tan(Proj4js.common.FORTPI - .5 * this.phits) :
+ 2. * this.k0 ;
+ break;
+ }
+ }
+ },
+
+// Stereographic forward equations--mapping lat,long to x,y
+ forward: function(p) {
+ var lon = p.x;
+ lon = Proj4js.common.adjust_lon(lon - this.long0);
+ var lat = p.y;
+ var x, y;
+
+ if (this.sphere) {
+ var sinphi, cosphi, coslam, sinlam;
+
+ sinphi = Math.sin(lat);
+ cosphi = Math.cos(lat);
+ coslam = Math.cos(lon);
+ sinlam = Math.sin(lon);
+ switch (this.mode) {
+ case this.EQUIT:
+ y = 1. + cosphi * coslam;
+ if (y <= Proj4js.common.EPSLN) {
+ F_ERROR;
+ }
+ y = this.akm1 / y;
+ x = y * cosphi * sinlam;
+ y *= sinphi;
+ break;
+ case this.OBLIQ:
+ y = 1. + this.sinph0 * sinphi + this.cosph0 * cosphi * coslam;
+ if (y <= Proj4js.common.EPSLN) {
+ F_ERROR;
+ }
+ y = this.akm1 / y;
+ x = y * cosphi * sinlam;
+ y *= this.cosph0 * sinphi - this.sinph0 * cosphi * coslam;
+ break;
+ case this.N_POLE:
+ coslam = -coslam;
+ lat = -lat;
+ //Note no break here so it conitnues through S_POLE
+ case this.S_POLE:
+ if (Math.abs(lat - Proj4js.common.HALF_PI) < this.TOL) {
+ F_ERROR;
+ }
+ y = this.akm1 * Math.tan(Proj4js.common.FORTPI + .5 * lat);
+ x = sinlam * y;
+ y *= coslam;
+ break;
+ }
+ } else {
+ coslam = Math.cos(lon);
+ sinlam = Math.sin(lon);
+ sinphi = Math.sin(lat);
+ if (this.mode == this.OBLIQ || this.mode == this.EQUIT) {
+ X = 2. * Math.atan(this.ssfn_(lat, sinphi, this.e));
+ sinX = Math.sin(X - Proj4js.common.HALF_PI);
+ cosX = Math.cos(X);
+ }
+ switch (this.mode) {
+ case this.OBLIQ:
+ A = this.akm1 / (this.cosX1 * (1. + this.sinX1 * sinX + this.cosX1 * cosX * coslam));
+ y = A * (this.cosX1 * sinX - this.sinX1 * cosX * coslam);
+ x = A * cosX;
+ break;
+ case this.EQUIT:
+ A = 2. * this.akm1 / (1. + cosX * coslam);
+ y = A * sinX;
+ x = A * cosX;
+ break;
+ case this.S_POLE:
+ lat = -lat;
+ coslam = - coslam;
+ sinphi = -sinphi;
+ case this.N_POLE:
+ x = this.akm1 * Proj4js.common.tsfnz(this.e, lat, sinphi);
+ y = - x * coslam;
+ break;
+ }
+ x = x * sinlam;
+ }
+ p.x = x*this.a + this.x0;
+ p.y = y*this.a + this.y0;
+ return p;
+ },
+
+
+//* Stereographic inverse equations--mapping x,y to lat/long
+ inverse: function(p) {
+ var x = (p.x - this.x0)/this.a; /* descale and de-offset */
+ var y = (p.y - this.y0)/this.a;
+ var lon, lat;
+
+ var cosphi, sinphi, tp=0.0, phi_l=0.0, rho, halfe=0.0, pi2=0.0;
+ var i;
+
+ if (this.sphere) {
+ var c, rh, sinc, cosc;
+
+ rh = Math.sqrt(x*x + y*y);
+ c = 2. * Math.atan(rh / this.akm1);
+ sinc = Math.sin(c);
+ cosc = Math.cos(c);
+ lon = 0.;
+ switch (this.mode) {
+ case this.EQUIT:
+ if (Math.abs(rh) <= Proj4js.common.EPSLN) {
+ lat = 0.;
+ } else {
+ lat = Math.asin(y * sinc / rh);
+ }
+ if (cosc != 0. || x != 0.) lon = Math.atan2(x * sinc, cosc * rh);
+ break;
+ case this.OBLIQ:
+ if (Math.abs(rh) <= Proj4js.common.EPSLN) {
+ lat = this.phi0;
+ } else {
+ lat = Math.asin(cosc * sinph0 + y * sinc * cosph0 / rh);
+ }
+ c = cosc - sinph0 * Math.sin(lat);
+ if (c != 0. || x != 0.) {
+ lon = Math.atan2(x * sinc * cosph0, c * rh);
+ }
+ break;
+ case this.N_POLE:
+ y = -y;
+ case this.S_POLE:
+ if (Math.abs(rh) <= Proj4js.common.EPSLN) {
+ lat = this.phi0;
+ } else {
+ lat = Math.asin(this.mode == this.S_POLE ? -cosc : cosc);
+ }
+ lon = (x == 0. && y == 0.) ? 0. : Math.atan2(x, y);
+ break;
+ }
+ } else {
+ rho = Math.sqrt(x*x + y*y);
+ switch (this.mode) {
+ case this.OBLIQ:
+ case this.EQUIT:
+ tp = 2. * Math.atan2(rho * this.cosX1 , this.akm1);
+ cosphi = Math.cos(tp);
+ sinphi = Math.sin(tp);
+ if( rho == 0.0 ) {
+ phi_l = Math.asin(cosphi * this.sinX1);
+ } else {
+ phi_l = Math.asin(cosphi * this.sinX1 + (y * sinphi * this.cosX1 / rho));
+ }
+
+ tp = Math.tan(.5 * (Proj4js.common.HALF_PI + phi_l));
+ x *= sinphi;
+ y = rho * this.cosX1 * cosphi - y * this.sinX1* sinphi;
+ pi2 = Proj4js.common.HALF_PI;
+ halfe = .5 * this.e;
+ break;
+ case this.N_POLE:
+ y = -y;
+ case this.S_POLE:
+ tp = - rho / this.akm1;
+ phi_l = Proj4js.common.HALF_PI - 2. * Math.atan(tp);
+ pi2 = -Proj4js.common.HALF_PI;
+ halfe = -.5 * this.e;
+ break;
+ }
+ for (i = this.NITER; i--; phi_l = lat) { //check this
+ sinphi = this.e * Math.sin(phi_l);
+ lat = 2. * Math.atan(tp * Math.pow((1.+sinphi)/(1.-sinphi), halfe)) - pi2;
+ if (Math.abs(phi_l - lat) < this.CONV) {
+ if (this.mode == this.S_POLE) lat = -lat;
+ lon = (x == 0. && y == 0.) ? 0. : Math.atan2(x, y);
+ p.x = Proj4js.common.adjust_lon(lon + this.long0);
+ p.y = lat;
+ return p;
+ }
+ }
+ }
+ }
+};
+/* ======================================================================
+ projCode/nzmg.js
+ ====================================================================== */
+
+/*******************************************************************************
+NAME NEW ZEALAND MAP GRID
+
+PURPOSE: Transforms input longitude and latitude to Easting and
+ Northing for the New Zealand Map Grid projection. The
+ longitude and latitude must be in radians. The Easting
+ and Northing values will be returned in meters.
+
+
+ALGORITHM REFERENCES
+
+1. Department of Land and Survey Technical Circular 1973/32
+ http://www.linz.govt.nz/docs/miscellaneous/nz-map-definition.pdf
+
+2. OSG Technical Report 4.1
+ http://www.linz.govt.nz/docs/miscellaneous/nzmg.pdf
+
+
+IMPLEMENTATION NOTES
+
+The two references use different symbols for the calculated values. This
+implementation uses the variable names similar to the symbols in reference [1].
+
+The alogrithm uses different units for delta latitude and delta longitude.
+The delta latitude is assumed to be in units of seconds of arc x 10^-5.
+The delta longitude is the usual radians. Look out for these conversions.
+
+The algorithm is described using complex arithmetic. There were three
+options:
+ * find and use a Javascript library for complex arithmetic
+ * write my own complex library
+ * expand the complex arithmetic by hand to simple arithmetic
+
+This implementation has expanded the complex multiplication operations
+into parallel simple arithmetic operations for the real and imaginary parts.
+The imaginary part is way over to the right of the display; this probably
+violates every coding standard in the world, but, to me, it makes it much
+more obvious what is going on.
+
+The following complex operations are used:
+ - addition
+ - multiplication
+ - division
+ - complex number raised to integer power
+ - summation
+
+A summary of complex arithmetic operations:
+ (from http://en.wikipedia.org/wiki/Complex_arithmetic)
+ addition: (a + bi) + (c + di) = (a + c) + (b + d)i
+ subtraction: (a + bi) - (c + di) = (a - c) + (b - d)i
+ multiplication: (a + bi) x (c + di) = (ac - bd) + (bc + ad)i
+ division: (a + bi) / (c + di) = [(ac + bd)/(cc + dd)] + [(bc - ad)/(cc + dd)]i
+
+The algorithm needs to calculate summations of simple and complex numbers. This is
+implemented using a for-loop, pre-loading the summed value to zero.
+
+The algorithm needs to calculate theta^2, theta^3, etc while doing a summation.
+There are three possible implementations:
+ - use Math.pow in the summation loop - except for complex numbers
+ - precalculate the values before running the loop
+ - calculate theta^n = theta^(n-1) * theta during the loop
+This implementation uses the third option for both real and complex arithmetic.
+
+For example
+ psi_n = 1;
+ sum = 0;
+ for (n = 1; n <=6; n++) {
+ psi_n1 = psi_n * psi; // calculate psi^(n+1)
+ psi_n = psi_n1;
+ sum = sum + A[n] * psi_n;
+ }
+
+
+TEST VECTORS
+
+NZMG E, N: 2487100.638 6751049.719 metres
+NZGD49 long, lat: 172.739194 -34.444066 degrees
+
+NZMG E, N: 2486533.395 6077263.661 metres
+NZGD49 long, lat: 172.723106 -40.512409 degrees
+
+NZMG E, N: 2216746.425 5388508.765 metres
+NZGD49 long, lat: 169.172062 -46.651295 degrees
+
+Note that these test vectors convert from NZMG metres to lat/long referenced
+to NZGD49, not the more usual WGS84. The difference is about 70m N/S and about
+10m E/W.
+
+These test vectors are provided in reference [1]. Many more test
+vectors are available in
+ http://www.linz.govt.nz/docs/topography/topographicdata/placenamesdatabase/nznamesmar08.zip
+which is a catalog of names on the 260-series maps.
+
+
+EPSG CODES
+
+NZMG EPSG:27200
+NZGD49 EPSG:4272
+
+http://spatialreference.org/ defines these as
+ Proj4js.defs["EPSG:4272"] = "+proj=longlat +ellps=intl +datum=nzgd49 +no_defs ";
+ Proj4js.defs["EPSG:27200"] = "+proj=nzmg +lat_0=-41 +lon_0=173 +x_0=2510000 +y_0=6023150 +ellps=intl +datum=nzgd49 +units=m +no_defs ";
+
+
+LICENSE
+ Copyright: Stephen Irons 2008
+ Released under terms of the LGPL as per: http://www.gnu.org/copyleft/lesser.html
+
+*******************************************************************************/
+
+
+/**
+ Initialize New Zealand Map Grip projection
+*/
+
+Proj4js.Proj.nzmg = {
+
+ /**
+ * iterations: Number of iterations to refine inverse transform.
+ * 0 -> km accuracy
+ * 1 -> m accuracy -- suitable for most mapping applications
+ * 2 -> mm accuracy
+ */
+ iterations: 1,
+
+ init : function() {
+ this.A = new Array();
+ this.A[1] = +0.6399175073;
+ this.A[2] = -0.1358797613;
+ this.A[3] = +0.063294409;
+ this.A[4] = -0.02526853;
+ this.A[5] = +0.0117879;
+ this.A[6] = -0.0055161;
+ this.A[7] = +0.0026906;
+ this.A[8] = -0.001333;
+ this.A[9] = +0.00067;
+ this.A[10] = -0.00034;
+
+ this.B_re = new Array(); this.B_im = new Array();
+ this.B_re[1] = +0.7557853228; this.B_im[1] = 0.0;
+ this.B_re[2] = +0.249204646; this.B_im[2] = +0.003371507;
+ this.B_re[3] = -0.001541739; this.B_im[3] = +0.041058560;
+ this.B_re[4] = -0.10162907; this.B_im[4] = +0.01727609;
+ this.B_re[5] = -0.26623489; this.B_im[5] = -0.36249218;
+ this.B_re[6] = -0.6870983; this.B_im[6] = -1.1651967;
+
+ this.C_re = new Array(); this.C_im = new Array();
+ this.C_re[1] = +1.3231270439; this.C_im[1] = 0.0;
+ this.C_re[2] = -0.577245789; this.C_im[2] = -0.007809598;
+ this.C_re[3] = +0.508307513; this.C_im[3] = -0.112208952;
+ this.C_re[4] = -0.15094762; this.C_im[4] = +0.18200602;
+ this.C_re[5] = +1.01418179; this.C_im[5] = +1.64497696;
+ this.C_re[6] = +1.9660549; this.C_im[6] = +2.5127645;
+
+ this.D = new Array();
+ this.D[1] = +1.5627014243;
+ this.D[2] = +0.5185406398;
+ this.D[3] = -0.03333098;
+ this.D[4] = -0.1052906;
+ this.D[5] = -0.0368594;
+ this.D[6] = +0.007317;
+ this.D[7] = +0.01220;
+ this.D[8] = +0.00394;
+ this.D[9] = -0.0013;
+ },
+
+ /**
+ New Zealand Map Grid Forward - long/lat to x/y
+ long/lat in radians
+ */
+ forward : function(p) {
+ var lon = p.x;
+ var lat = p.y;
+
+ var delta_lat = lat - this.lat0;
+ var delta_lon = lon - this.long0;
+
+ // 1. Calculate d_phi and d_psi ... // and d_lambda
+ // For this algorithm, delta_latitude is in seconds of arc x 10-5, so we need to scale to those units. Longitude is radians.
+ var d_phi = delta_lat / Proj4js.common.SEC_TO_RAD * 1E-5; var d_lambda = delta_lon;
+ var d_phi_n = 1; // d_phi^0
+
+ var d_psi = 0;
+ for (n = 1; n <= 10; n++) {
+ d_phi_n = d_phi_n * d_phi;
+ d_psi = d_psi + this.A[n] * d_phi_n;
+ }
+
+ // 2. Calculate theta
+ var th_re = d_psi; var th_im = d_lambda;
+
+ // 3. Calculate z
+ var th_n_re = 1; var th_n_im = 0; // theta^0
+ var th_n_re1; var th_n_im1;
+
+ var z_re = 0; var z_im = 0;
+ for (n = 1; n <= 6; n++) {
+ th_n_re1 = th_n_re*th_re - th_n_im*th_im; th_n_im1 = th_n_im*th_re + th_n_re*th_im;
+ th_n_re = th_n_re1; th_n_im = th_n_im1;
+ z_re = z_re + this.B_re[n]*th_n_re - this.B_im[n]*th_n_im; z_im = z_im + this.B_im[n]*th_n_re + this.B_re[n]*th_n_im;
+ }
+
+ // 4. Calculate easting and northing
+ x = (z_im * this.a) + this.x0;
+ y = (z_re * this.a) + this.y0;
+
+ p.x = x; p.y = y;
+
+ return p;
+ },
+
+
+ /**
+ New Zealand Map Grid Inverse - x/y to long/lat
+ */
+ inverse : function(p) {
+
+ var x = p.x;
+ var y = p.y;
+
+ var delta_x = x - this.x0;
+ var delta_y = y - this.y0;
+
+ // 1. Calculate z
+ var z_re = delta_y / this.a; var z_im = delta_x / this.a;
+
+ // 2a. Calculate theta - first approximation gives km accuracy
+ var z_n_re = 1; var z_n_im = 0; // z^0
+ var z_n_re1; var z_n_im1;
+
+ var th_re = 0; var th_im = 0;
+ for (n = 1; n <= 6; n++) {
+ z_n_re1 = z_n_re*z_re - z_n_im*z_im; z_n_im1 = z_n_im*z_re + z_n_re*z_im;
+ z_n_re = z_n_re1; z_n_im = z_n_im1;
+ th_re = th_re + this.C_re[n]*z_n_re - this.C_im[n]*z_n_im; th_im = th_im + this.C_im[n]*z_n_re + this.C_re[n]*z_n_im;
+ }
+
+ // 2b. Iterate to refine the accuracy of the calculation
+ // 0 iterations gives km accuracy
+ // 1 iteration gives m accuracy -- good enough for most mapping applications
+ // 2 iterations bives mm accuracy
+ for (i = 0; i < this.iterations; i++) {
+ var th_n_re = th_re; var th_n_im = th_im;
+ var th_n_re1; var th_n_im1;
+
+ var num_re = z_re; var num_im = z_im;
+ for (n = 2; n <= 6; n++) {
+ th_n_re1 = th_n_re*th_re - th_n_im*th_im; th_n_im1 = th_n_im*th_re + th_n_re*th_im;
+ th_n_re = th_n_re1; th_n_im = th_n_im1;
+ num_re = num_re + (n-1)*(this.B_re[n]*th_n_re - this.B_im[n]*th_n_im); num_im = num_im + (n-1)*(this.B_im[n]*th_n_re + this.B_re[n]*th_n_im);
+ }
+
+ th_n_re = 1; th_n_im = 0;
+ var den_re = this.B_re[1]; var den_im = this.B_im[1];
+ for (n = 2; n <= 6; n++) {
+ th_n_re1 = th_n_re*th_re - th_n_im*th_im; th_n_im1 = th_n_im*th_re + th_n_re*th_im;
+ th_n_re = th_n_re1; th_n_im = th_n_im1;
+ den_re = den_re + n * (this.B_re[n]*th_n_re - this.B_im[n]*th_n_im); den_im = den_im + n * (this.B_im[n]*th_n_re + this.B_re[n]*th_n_im);
+ }
+
+ // Complex division
+ var den2 = den_re*den_re + den_im*den_im;
+ th_re = (num_re*den_re + num_im*den_im) / den2; th_im = (num_im*den_re - num_re*den_im) / den2;
+ }
+
+ // 3. Calculate d_phi ... // and d_lambda
+ var d_psi = th_re; var d_lambda = th_im;
+ var d_psi_n = 1; // d_psi^0
+
+ var d_phi = 0;
+ for (n = 1; n <= 9; n++) {
+ d_psi_n = d_psi_n * d_psi;
+ d_phi = d_phi + this.D[n] * d_psi_n;
+ }
+
+ // 4. Calculate latitude and longitude
+ // d_phi is calcuated in second of arc * 10^-5, so we need to scale back to radians. d_lambda is in radians.
+ var lat = this.lat0 + (d_phi * Proj4js.common.SEC_TO_RAD * 1E5);
+ var lon = this.long0 + d_lambda;
+
+ p.x = lon;
+ p.y = lat;
+
+ return p;
+ }
+};
+/* ======================================================================
+ projCode/mill.js
+ ====================================================================== */
+
+/*******************************************************************************
+NAME MILLER CYLINDRICAL
+
+PURPOSE: Transforms input longitude and latitude to Easting and
+ Northing for the Miller Cylindrical projection. The
+ longitude and latitude must be in radians. The Easting
+ and Northing values will be returned in meters.
+
+PROGRAMMER DATE
+---------- ----
+T. Mittan March, 1993
+
+This function was adapted from the Lambert Azimuthal Equal Area projection
+code (FORTRAN) in the General Cartographic Transformation Package software
+which is available from the U.S. Geological Survey National Mapping Division.
+
+ALGORITHM REFERENCES
+
+1. "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder,
+ The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355.
+
+2. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
+ Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
+ State Government Printing Office, Washington D.C., 1987.
+
+3. "Software Documentation for GCTP General Cartographic Transformation
+ Package", U.S. Geological Survey National Mapping Division, May 1982.
+*******************************************************************************/
+
+Proj4js.Proj.mill = {
+
+/* Initialize the Miller Cylindrical projection
+ -------------------------------------------*/
+ init: function() {
+ //no-op
+ },
+
+
+ /* Miller Cylindrical forward equations--mapping lat,long to x,y
+ ------------------------------------------------------------*/
+ forward: function(p) {
+ var lon=p.x;
+ var lat=p.y;
+ /* Forward equations
+ -----------------*/
+ var dlon = Proj4js.common.adjust_lon(lon -this.long0);
+ var x = this.x0 + this.a * dlon;
+ var y = this.y0 + this.a * Math.log(Math.tan((Proj4js.common.PI / 4.0) + (lat / 2.5))) * 1.25;
+
+ p.x=x;
+ p.y=y;
+ return p;
+ },//millFwd()
+
+ /* Miller Cylindrical inverse equations--mapping x,y to lat/long
+ ------------------------------------------------------------*/
+ inverse: function(p) {
+ p.x -= this.x0;
+ p.y -= this.y0;
+
+ var lon = Proj4js.common.adjust_lon(this.long0 + p.x /this.a);
+ var lat = 2.5 * (Math.atan(Math.exp(0.8*p.y/this.a)) - Proj4js.common.PI / 4.0);
+
+ p.x=lon;
+ p.y=lat;
+ return p;
+ }//millInv()
+};
+/* ======================================================================
+ projCode/gnom.js
+ ====================================================================== */
+
+/*****************************************************************************
+NAME GNOMONIC
+
+PURPOSE: Transforms input longitude and latitude to Easting and
+ Northing for the Gnomonic Projection.
+ Implementation based on the existing sterea and ortho
+ implementations.
+
+PROGRAMMER DATE
+---------- ----
+Richard Marsden November 2009
+
+ALGORITHM REFERENCES
+
+1. Snyder, John P., "Flattening the Earth - Two Thousand Years of Map
+ Projections", University of Chicago Press 1993
+
+2. Wolfram Mathworld "Gnomonic Projection"
+ http://mathworld.wolfram.com/GnomonicProjection.html
+ Accessed: 12th November 2009
+******************************************************************************/
+
+Proj4js.Proj.gnom = {
+
+ /* Initialize the Gnomonic projection
+ -------------------------------------*/
+ init: function(def) {
+
+ /* Place parameters in static storage for common use
+ -------------------------------------------------*/
+ this.sin_p14=Math.sin(this.lat0);
+ this.cos_p14=Math.cos(this.lat0);
+ // Approximation for projecting points to the horizon (infinity)
+ this.infinity_dist = 1000 * this.a;
+ this.rc = 1;
+ },
+
+
+ /* Gnomonic forward equations--mapping lat,long to x,y
+ ---------------------------------------------------*/
+ forward: function(p) {
+ var sinphi, cosphi; /* sin and cos value */
+ var dlon; /* delta longitude value */
+ var coslon; /* cos of longitude */
+ var ksp; /* scale factor */
+ var g;
+ var lon=p.x;
+ var lat=p.y;
+ /* Forward equations
+ -----------------*/
+ dlon = Proj4js.common.adjust_lon(lon - this.long0);
+
+ sinphi=Math.sin(lat);
+ cosphi=Math.cos(lat);
+
+ coslon = Math.cos(dlon);
+ g = this.sin_p14 * sinphi + this.cos_p14 * cosphi * coslon;
+ ksp = 1.0;
+ if ((g > 0) || (Math.abs(g) <= Proj4js.common.EPSLN)) {
+ x = this.x0 + this.a * ksp * cosphi * Math.sin(dlon) / g;
+ y = this.y0 + this.a * ksp * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon) / g;
+ } else {
+ Proj4js.reportError("orthoFwdPointError");
+
+ // Point is in the opposing hemisphere and is unprojectable
+ // We still need to return a reasonable point, so we project
+ // to infinity, on a bearing
+ // equivalent to the northern hemisphere equivalent
+ // This is a reasonable approximation for short shapes and lines that
+ // straddle the horizon.
+
+ x = this.x0 + this.infinity_dist * cosphi * Math.sin(dlon);
+ y = this.y0 + this.infinity_dist * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon);
+
+ }
+ p.x=x;
+ p.y=y;
+ return p;
+ },
+
+
+ inverse: function(p) {
+ var rh; /* Rho */
+ var z; /* angle */
+ var sinc, cosc;
+ var c;
+ var lon , lat;
+
+ /* Inverse equations
+ -----------------*/
+ p.x = (p.x - this.x0) / this.a;
+ p.y = (p.y - this.y0) / this.a;
+
+ p.x /= this.k0;
+ p.y /= this.k0;
+
+ if ( (rh = Math.sqrt(p.x * p.x + p.y * p.y)) ) {
+ c = Math.atan2(rh, this.rc);
+ sinc = Math.sin(c);
+ cosc = Math.cos(c);
+
+ lat = Proj4js.common.asinz(cosc*this.sin_p14 + (p.y*sinc*this.cos_p14) / rh);
+ lon = Math.atan2(p.x*sinc, rh*this.cos_p14*cosc - p.y*this.sin_p14*sinc);
+ lon = Proj4js.common.adjust_lon(this.long0+lon);
+ } else {
+ lat = this.phic0;
+ lon = 0.0;
+ }
+
+ p.x=lon;
+ p.y=lat;
+ return p;
+ }
+};
+
+
+/* ======================================================================
+ projCode/sinu.js
+ ====================================================================== */
+
+/*******************************************************************************
+NAME SINUSOIDAL
+
+PURPOSE: Transforms input longitude and latitude to Easting and
+ Northing for the Sinusoidal projection. The
+ longitude and latitude must be in radians. The Easting
+ and Northing values will be returned in meters.
+
+PROGRAMMER DATE
+---------- ----
+D. Steinwand, EROS May, 1991
+
+This function was adapted from the Sinusoidal projection code (FORTRAN) in the
+General Cartographic Transformation Package software which is available from
+the U.S. Geological Survey National Mapping Division.
+
+ALGORITHM REFERENCES
+
+1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
+ Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
+ State Government Printing Office, Washington D.C., 1987.
+
+2. "Software Documentation for GCTP General Cartographic Transformation
+ Package", U.S. Geological Survey National Mapping Division, May 1982.
+*******************************************************************************/
+
+Proj4js.Proj.sinu = {
+
+ /* Initialize the Sinusoidal projection
+ ------------------------------------*/
+ init: function() {
+ /* Place parameters in static storage for common use
+ -------------------------------------------------*/
+ this.R = 6370997.0; //Radius of earth
+ },
+
+ /* Sinusoidal forward equations--mapping lat,long to x,y
+ -----------------------------------------------------*/
+ forward: function(p) {
+ var x,y,delta_lon;
+ var lon=p.x;
+ var lat=p.y;
+ /* Forward equations
+ -----------------*/
+ delta_lon = Proj4js.common.adjust_lon(lon - this.long0);
+ x = this.R * delta_lon * Math.cos(lat) + this.x0;
+ y = this.R * lat + this.y0;
+
+ p.x=x;
+ p.y=y;
+ return p;
+ },
+
+ inverse: function(p) {
+ var lat,temp,lon;
+
+ /* Inverse equations
+ -----------------*/
+ p.x -= this.x0;
+ p.y -= this.y0;
+ lat = p.y / this.R;
+ if (Math.abs(lat) > Proj4js.common.HALF_PI) {
+ Proj4js.reportError("sinu:Inv:DataError");
+ }
+ temp = Math.abs(lat) - Proj4js.common.HALF_PI;
+ if (Math.abs(temp) > Proj4js.common.EPSLN) {
+ temp = this.long0+ p.x / (this.R *Math.cos(lat));
+ lon = Proj4js.common.adjust_lon(temp);
+ } else {
+ lon = this.long0;
+ }
+
+ p.x=lon;
+ p.y=lat;
+ return p;
+ }
+};
+
+
+/* ======================================================================
+ projCode/vandg.js
+ ====================================================================== */
+
+/*******************************************************************************
+NAME VAN DER GRINTEN
+
+PURPOSE: Transforms input Easting and Northing to longitude and
+ latitude for the Van der Grinten projection. The
+ Easting and Northing must be in meters. The longitude
+ and latitude values will be returned in radians.
+
+PROGRAMMER DATE
+---------- ----
+T. Mittan March, 1993
+
+This function was adapted from the Van Der Grinten projection code
+(FORTRAN) in the General Cartographic Transformation Package software
+which is available from the U.S. Geological Survey National Mapping Division.
+
+ALGORITHM REFERENCES
+
+1. "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder,
+ The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355.
+
+2. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
+ Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
+ State Government Printing Office, Washington D.C., 1987.
+
+3. "Software Documentation for GCTP General Cartographic Transformation
+ Package", U.S. Geological Survey National Mapping Division, May 1982.
+*******************************************************************************/
+
+Proj4js.Proj.vandg = {
+
+/* Initialize the Van Der Grinten projection
+ ----------------------------------------*/
+ init: function() {
+ this.R = 6370997.0; //Radius of earth
+ },
+
+ forward: function(p) {
+
+ var lon=p.x;
+ var lat=p.y;
+
+ /* Forward equations
+ -----------------*/
+ var dlon = Proj4js.common.adjust_lon(lon - this.long0);
+ var x,y;
+
+ if (Math.abs(lat) <= Proj4js.common.EPSLN) {
+ x = this.x0 + this.R * dlon;
+ y = this.y0;
+ }
+ var theta = Proj4js.common.asinz(2.0 * Math.abs(lat / Proj4js.common.PI));
+ if ((Math.abs(dlon) <= Proj4js.common.EPSLN) || (Math.abs(Math.abs(lat) - Proj4js.common.HALF_PI) <= Proj4js.common.EPSLN)) {
+ x = this.x0;
+ if (lat >= 0) {
+ y = this.y0 + Proj4js.common.PI * this.R * Math.tan(.5 * theta);
+ } else {
+ y = this.y0 + Proj4js.common.PI * this.R * - Math.tan(.5 * theta);
+ }
+ // return(OK);
+ }
+ var al = .5 * Math.abs((Proj4js.common.PI / dlon) - (dlon / Proj4js.common.PI));
+ var asq = al * al;
+ var sinth = Math.sin(theta);
+ var costh = Math.cos(theta);
+
+ var g = costh / (sinth + costh - 1.0);
+ var gsq = g * g;
+ var m = g * (2.0 / sinth - 1.0);
+ var msq = m * m;
+ var con = Proj4js.common.PI * this.R * (al * (g - msq) + Math.sqrt(asq * (g - msq) * (g - msq) - (msq + asq) * (gsq - msq))) / (msq + asq);
+ if (dlon < 0) {
+ con = -con;
+ }
+ x = this.x0 + con;
+ con = Math.abs(con / (Proj4js.common.PI * this.R));
+ if (lat >= 0) {
+ y = this.y0 + Proj4js.common.PI * this.R * Math.sqrt(1.0 - con * con - 2.0 * al * con);
+ } else {
+ y = this.y0 - Proj4js.common.PI * this.R * Math.sqrt(1.0 - con * con - 2.0 * al * con);
+ }
+ p.x = x;
+ p.y = y;
+ return p;
+ },
+
+/* Van Der Grinten inverse equations--mapping x,y to lat/long
+ ---------------------------------------------------------*/
+ inverse: function(p) {
+ var dlon;
+ var xx,yy,xys,c1,c2,c3;
+ var al,asq;
+ var a1;
+ var m1;
+ var con;
+ var th1;
+ var d;
+
+ /* inverse equations
+ -----------------*/
+ p.x -= this.x0;
+ p.y -= this.y0;
+ con = Proj4js.common.PI * this.R;
+ xx = p.x / con;
+ yy =p.y / con;
+ xys = xx * xx + yy * yy;
+ c1 = -Math.abs(yy) * (1.0 + xys);
+ c2 = c1 - 2.0 * yy * yy + xx * xx;
+ c3 = -2.0 * c1 + 1.0 + 2.0 * yy * yy + xys * xys;
+ d = yy * yy / c3 + (2.0 * c2 * c2 * c2 / c3 / c3 / c3 - 9.0 * c1 * c2 / c3 /c3) / 27.0;
+ a1 = (c1 - c2 * c2 / 3.0 / c3) / c3;
+ m1 = 2.0 * Math.sqrt( -a1 / 3.0);
+ con = ((3.0 * d) / a1) / m1;
+ if (Math.abs(con) > 1.0) {
+ if (con >= 0.0) {
+ con = 1.0;
+ } else {
+ con = -1.0;
+ }
+ }
+ th1 = Math.acos(con) / 3.0;
+ if (p.y >= 0) {
+ lat = (-m1 *Math.cos(th1 + Proj4js.common.PI / 3.0) - c2 / 3.0 / c3) * Proj4js.common.PI;
+ } else {
+ lat = -(-m1 * Math.cos(th1 + Proj4js.common.PI / 3.0) - c2 / 3.0 / c3) * Proj4js.common.PI;
+ }
+
+ if (Math.abs(xx) < Proj4js.common.EPSLN) {
+ lon = this.long0;
+ }
+ lon = Proj4js.common.adjust_lon(this.long0 + Proj4js.common.PI * (xys - 1.0 + Math.sqrt(1.0 + 2.0 * (xx * xx - yy * yy) + xys * xys)) / 2.0 / xx);
+
+ p.x=lon;
+ p.y=lat;
+ return p;
+ }
+};
+/* ======================================================================
+ projCode/cea.js
+ ====================================================================== */
+
+/*******************************************************************************
+NAME LAMBERT CYLINDRICAL EQUAL AREA
+
+PURPOSE: Transforms input longitude and latitude to Easting and
+ Northing for the Lambert Cylindrical Equal Area projection.
+ This class of projection includes the Behrmann and
+ Gall-Peters Projections. The
+ longitude and latitude must be in radians. The Easting
+ and Northing values will be returned in meters.
+
+PROGRAMMER DATE
+---------- ----
+R. Marsden August 2009
+Winwaed Software Tech LLC, http://www.winwaed.com
+
+This function was adapted from the Miller Cylindrical Projection in the Proj4JS
+library.
+
+Note: This implementation assumes a Spherical Earth. The (commented) code
+has been included for the ellipsoidal forward transform, but derivation of
+the ellispoidal inverse transform is beyond me. Note that most of the
+Proj4JS implementations do NOT currently support ellipsoidal figures.
+Therefore this is not seen as a problem - especially this lack of support
+is explicitly stated here.
+
+ALGORITHM REFERENCES
+
+1. "Cartographic Projection Procedures for the UNIX Environment -
+ A User's Manual" by Gerald I. Evenden, USGS Open File Report 90-284
+ and Release 4 Interim Reports (2003)
+
+2. Snyder, John P., "Flattening the Earth - Two Thousand Years of Map
+ Projections", Univ. Chicago Press, 1993
+*******************************************************************************/
+
+Proj4js.Proj.cea = {
+
+/* Initialize the Cylindrical Equal Area projection
+ -------------------------------------------*/
+ init: function() {
+ //no-op
+ },
+
+
+ /* Cylindrical Equal Area forward equations--mapping lat,long to x,y
+ ------------------------------------------------------------*/
+ forward: function(p) {
+ var lon=p.x;
+ var lat=p.y;
+ /* Forward equations
+ -----------------*/
+ dlon = Proj4js.common.adjust_lon(lon -this.long0);
+ var x = this.x0 + this.a * dlon * Math.cos(this.lat_ts);
+ var y = this.y0 + this.a * Math.sin(lat) / Math.cos(this.lat_ts);
+ /* Elliptical Forward Transform
+ Not implemented due to a lack of a matchign inverse function
+ {
+ var Sin_Lat = Math.sin(lat);
+ var Rn = this.a * (Math.sqrt(1.0e0 - this.es * Sin_Lat * Sin_Lat ));
+ x = this.x0 + this.a * dlon * Math.cos(this.lat_ts);
+ y = this.y0 + Rn * Math.sin(lat) / Math.cos(this.lat_ts);
+ }
+ */
+
+
+ p.x=x;
+ p.y=y;
+ return p;
+ },//ceaFwd()
+
+ /* Cylindrical Equal Area inverse equations--mapping x,y to lat/long
+ ------------------------------------------------------------*/
+ inverse: function(p) {
+ p.x -= this.x0;
+ p.y -= this.y0;
+
+ var lon = Proj4js.common.adjust_lon( this.long0 + (p.x / this.a) / Math.cos(this.lat_ts) );
+
+ var lat = Math.asin( (p.y/this.a) * Math.cos(this.lat_ts) );
+
+ p.x=lon;
+ p.y=lat;
+ return p;
+ }//ceaInv()
+};
+/* ======================================================================
+ projCode/eqc.js
+ ====================================================================== */
+
+/* similar to equi.js FIXME proj4 uses eqc */
+Proj4js.Proj.eqc = {
+ init : function() {
+
+ if(!this.x0) this.x0=0;
+ if(!this.y0) this.y0=0;
+ if(!this.lat0) this.lat0=0;
+ if(!this.long0) this.long0=0;
+ if(!this.lat_ts) this.lat_ts=0;
+ if (!this.title) this.title = "Equidistant Cylindrical (Plate Carre)";
+
+ this.rc= Math.cos(this.lat_ts);
+ },
+
+
+ // forward equations--mapping lat,long to x,y
+ // -----------------------------------------------------------------
+ forward : function(p) {
+
+ var lon= p.x;
+ var lat= p.y;
+
+ var dlon = Proj4js.common.adjust_lon(lon - this.long0);
+ var dlat = Proj4js.common.adjust_lat(lat - this.lat0 );
+ p.x= this.x0 + (this.a*dlon*this.rc);
+ p.y= this.y0 + (this.a*dlat );
+ return p;
+ },
+
+ // inverse equations--mapping x,y to lat/long
+ // -----------------------------------------------------------------
+ inverse : function(p) {
+
+ var x= p.x;
+ var y= p.y;
+
+ p.x= Proj4js.common.adjust_lon(this.long0 + ((x - this.x0)/(this.a*this.rc)));
+ p.y= Proj4js.common.adjust_lat(this.lat0 + ((y - this.y0)/(this.a )));
+ return p;
+ }
+
+};
+/* ======================================================================
+ projCode/cass.js
+ ====================================================================== */
+
+/*******************************************************************************
+NAME CASSINI
+
+PURPOSE: Transforms input longitude and latitude to Easting and
+ Northing for the Cassini projection. The
+ longitude and latitude must be in radians. The Easting
+ and Northing values will be returned in meters.
+ Ported from PROJ.4.
+
+
+ALGORITHM REFERENCES
+
+1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
+ Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
+ State Government Printing Office, Washington D.C., 1987.
+
+2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
+ U.S. Geological Survey Professional Paper 1453 , United State Government
+*******************************************************************************/
+
+
+//Proj4js.defs["EPSG:28191"] = "+proj=cass +lat_0=31.73409694444445 +lon_0=35.21208055555556 +x_0=170251.555 +y_0=126867.909 +a=6378300.789 +b=6356566.435 +towgs84=-275.722,94.7824,340.894,-8.001,-4.42,-11.821,1 +units=m +no_defs";
+
+// Initialize the Cassini projection
+// -----------------------------------------------------------------
+
+Proj4js.Proj.cass = {
+ init : function() {
+ if (!this.sphere) {
+ this.en = this.pj_enfn(this.es)
+ this.m0 = this.pj_mlfn(this.lat0, Math.sin(this.lat0), Math.cos(this.lat0), this.en);
+ }
+ },
+
+ C1: .16666666666666666666,
+ C2: .00833333333333333333,
+ C3: .04166666666666666666,
+ C4: .33333333333333333333,
+ C5: .06666666666666666666,
+
+
+/* Cassini forward equations--mapping lat,long to x,y
+ -----------------------------------------------------------------------*/
+ forward: function(p) {
+
+ /* Forward equations
+ -----------------*/
+ var x,y;
+ var lam=p.x;
+ var phi=p.y;
+ lam = Proj4js.common.adjust_lon(lam - this.long0);
+
+ if (this.sphere) {
+ x = Math.asin(Math.cos(phi) * Math.sin(lam));
+ y = Math.atan2(Math.tan(phi) , Math.cos(lam)) - this.phi0;
+ } else {
+ //ellipsoid
+ this.n = Math.sin(phi);
+ this.c = Math.cos(phi);
+ y = this.pj_mlfn(phi, this.n, this.c, this.en);
+ this.n = 1./Math.sqrt(1. - this.es * this.n * this.n);
+ this.tn = Math.tan(phi);
+ this.t = this.tn * this.tn;
+ this.a1 = lam * this.c;
+ this.c *= this.es * this.c / (1 - this.es);
+ this.a2 = this.a1 * this.a1;
+ x = this.n * this.a1 * (1. - this.a2 * this.t * (this.C1 - (8. - this.t + 8. * this.c) * this.a2 * this.C2));
+ y -= this.m0 - this.n * this.tn * this.a2 * (.5 + (5. - this.t + 6. * this.c) * this.a2 * this.C3);
+ }
+
+ p.x = this.a*x + this.x0;
+ p.y = this.a*y + this.y0;
+ return p;
+ },//cassFwd()
+
+/* Inverse equations
+ -----------------*/
+ inverse: function(p) {
+ p.x -= this.x0;
+ p.y -= this.y0;
+ var x = p.x/this.a;
+ var y = p.y/this.a;
+
+ if (this.sphere) {
+ this.dd = y + this.lat0;
+ phi = Math.asin(Math.sin(this.dd) * Math.cos(x));
+ lam = Math.atan2(Math.tan(x), Math.cos(this.dd));
+ } else {
+ /* ellipsoid */
+ ph1 = this.pj_inv_mlfn(this.m0 + y, this.es, this.en);
+ this.tn = Math.tan(ph1);
+ this.t = this.tn * this.tn;
+ this.n = Math.sin(ph1);
+ this.r = 1. / (1. - this.es * this.n * this.n);
+ this.n = Math.sqrt(this.r);
+ this.r *= (1. - this.es) * this.n;
+ this.dd = x / this.n;
+ this.d2 = this.dd * this.dd;
+ phi = ph1 - (this.n * this.tn / this.r) * this.d2 * (.5 - (1. + 3. * this.t) * this.d2 * this.C3);
+ lam = this.dd * (1. + this.t * this.d2 * (-this.C4 + (1. + 3. * this.t) * this.d2 * this.C5)) / Math.cos(ph1);
+ }
+ p.x = Proj4js.common.adjust_lon(this.long0+lam);
+ p.y = phi;
+ return p;
+ },//lamazInv()
+
+
+ //code from the PROJ.4 pj_mlfn.c file; this may be useful for other projections
+ pj_enfn: function(es) {
+ en = new Array();
+ en[0] = this.C00 - es * (this.C02 + es * (this.C04 + es * (this.C06 + es * this.C08)));
+ en[1] = es * (this.C22 - es * (this.C04 + es * (this.C06 + es * this.C08)));
+ var t = es * es;
+ en[2] = t * (this.C44 - es * (this.C46 + es * this.C48));
+ t *= es;
+ en[3] = t * (this.C66 - es * this.C68);
+ en[4] = t * es * this.C88;
+ return en;
+ },
+
+ pj_mlfn: function(phi, sphi, cphi, en) {
+ cphi *= sphi;
+ sphi *= sphi;
+ return(en[0] * phi - cphi * (en[1] + sphi*(en[2]+ sphi*(en[3] + sphi*en[4]))));
+ },
+
+ pj_inv_mlfn: function(arg, es, en) {
+ k = 1./(1.-es);
+ phi = arg;
+ for (i = Proj4js.common.MAX_ITER; i ; --i) { /* rarely goes over 2 iterations */
+ s = Math.sin(phi);
+ t = 1. - es * s * s;
+ //t = this.pj_mlfn(phi, s, Math.cos(phi), en) - arg;
+ //phi -= t * (t * Math.sqrt(t)) * k;
+ t = (this.pj_mlfn(phi, s, Math.cos(phi), en) - arg) * (t * Math.sqrt(t)) * k;
+ phi -= t;
+ if (Math.abs(t) < Proj4js.common.EPSLN)
+ return phi;
+ }
+ Proj4js.reportError("cass:pj_inv_mlfn: Convergence error");
+ return phi;
+ },
+
+/* meridinal distance for ellipsoid and inverse
+** 8th degree - accurate to < 1e-5 meters when used in conjuction
+** with typical major axis values.
+** Inverse determines phi to EPS (1e-11) radians, about 1e-6 seconds.
+*/
+ C00: 1.0,
+ C02: .25,
+ C04: .046875,
+ C06: .01953125,
+ C08: .01068115234375,
+ C22: .75,
+ C44: .46875,
+ C46: .01302083333333333333,
+ C48: .00712076822916666666,
+ C66: .36458333333333333333,
+ C68: .00569661458333333333,
+ C88: .3076171875
+
+}
+/* ======================================================================
+ projCode/gauss.js
+ ====================================================================== */
+
+
+Proj4js.Proj.gauss = {
+
+ init : function() {
+ sphi = Math.sin(this.lat0);
+ cphi = Math.cos(this.lat0);
+ cphi *= cphi;
+ this.rc = Math.sqrt(1.0 - this.es) / (1.0 - this.es * sphi * sphi);
+ this.C = Math.sqrt(1.0 + this.es * cphi * cphi / (1.0 - this.es));
+ this.phic0 = Math.asin(sphi / this.C);
+ this.ratexp = 0.5 * this.C * this.e;
+ this.K = Math.tan(0.5 * this.phic0 + Proj4js.common.FORTPI) / (Math.pow(Math.tan(0.5*this.lat0 + Proj4js.common.FORTPI), this.C) * Proj4js.common.srat(this.e*sphi, this.ratexp));
+ },
+
+ forward : function(p) {
+ var lon = p.x;
+ var lat = p.y;
+
+ p.y = 2.0 * Math.atan( this.K * Math.pow(Math.tan(0.5 * lat + Proj4js.common.FORTPI), this.C) * Proj4js.common.srat(this.e * Math.sin(lat), this.ratexp) ) - Proj4js.common.HALF_PI;
+ p.x = this.C * lon;
+ return p;
+ },
+
+ inverse : function(p) {
+ var DEL_TOL = 1e-14;
+ var lon = p.x / this.C;
+ var lat = p.y;
+ num = Math.pow(Math.tan(0.5 * lat + Proj4js.common.FORTPI)/this.K, 1./this.C);
+ for (var i = Proj4js.common.MAX_ITER; i>0; --i) {
+ lat = 2.0 * Math.atan(num * Proj4js.common.srat(this.e * Math.sin(p.y), -0.5 * this.e)) - Proj4js.common.HALF_PI;
+ if (Math.abs(lat - p.y) < DEL_TOL) break;
+ p.y = lat;
+ }
+ /* convergence failed */
+ if (!i) {
+ Proj4js.reportError("gauss:inverse:convergence failed");
+ return null;
+ }
+ p.x = lon;
+ p.y = lat;
+ return p;
+ }
+};
+
+/* ======================================================================
+ projCode/omerc.js
+ ====================================================================== */
+
+/*******************************************************************************
+NAME OBLIQUE MERCATOR (HOTINE)
+
+PURPOSE: Transforms input longitude and latitude to Easting and
+ Northing for the Oblique Mercator projection. The
+ longitude and latitude must be in radians. The Easting
+ and Northing values will be returned in meters.
+
+PROGRAMMER DATE
+---------- ----
+T. Mittan Mar, 1993
+
+ALGORITHM REFERENCES
+
+1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
+ Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
+ State Government Printing Office, Washington D.C., 1987.
+
+2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
+ U.S. Geological Survey Professional Paper 1453 , United State Government
+ Printing Office, Washington D.C., 1989.
+*******************************************************************************/
+
+Proj4js.Proj.omerc = {
+
+ /* Initialize the Oblique Mercator projection
+ ------------------------------------------*/
+ init: function() {
+ if (!this.mode) this.mode=0;
+ if (!this.lon1) {this.lon1=0;this.mode=1;}
+ if (!this.lon2) this.lon2=0;
+ if (!this.lat2) this.lat2=0;
+
+ /* Place parameters in static storage for common use
+ -------------------------------------------------*/
+ var temp = this.b/ this.a;
+ var es = 1.0 - Math.pow(temp,2);
+ var e = Math.sqrt(es);
+
+ this.sin_p20=Math.sin(this.lat0);
+ this.cos_p20=Math.cos(this.lat0);
+
+ this.con = 1.0 - this.es * this.sin_p20 * this.sin_p20;
+ this.com = Math.sqrt(1.0 - es);
+ this.bl = Math.sqrt(1.0 + this.es * Math.pow(this.cos_p20,4.0)/(1.0 - es));
+ this.al = this.a * this.bl * this.k0 * this.com / this.con;
+ if (Math.abs(this.lat0) < Proj4js.common.EPSLN) {
+ this.ts = 1.0;
+ this.d = 1.0;
+ this.el = 1.0;
+ } else {
+ this.ts = Proj4js.common.tsfnz(this.e,this.lat0,this.sin_p20);
+ this.con = Math.sqrt(this.con);
+ this.d = this.bl * this.com / (this.cos_p20 * this.con);
+ if ((this.d * this.d - 1.0) > 0.0) {
+ if (this.lat0 >= 0.0) {
+ this.f = this.d + Math.sqrt(this.d * this.d - 1.0);
+ } else {
+ this.f = this.d - Math.sqrt(this.d * this.d - 1.0);
+ }
+ } else {
+ this.f = this.d;
+ }
+ this.el = this.f * Math.pow(this.ts,this.bl);
+ }
+
+ //this.longc=52.60353916666667;
+
+ if (this.mode != 0) {
+ this.g = .5 * (this.f - 1.0/this.f);
+ this.gama = Proj4js.common.asinz(Math.sin(this.alpha) / this.d);
+ this.longc= this.longc - Proj4js.common.asinz(this.g * Math.tan(this.gama))/this.bl;
+
+ /* Report parameters common to format B
+ -------------------------------------*/
+ //genrpt(azimuth * R2D,"Azimuth of Central Line: ");
+ //cenlon(lon_origin);
+ // cenlat(lat_origin);
+
+ this.con = Math.abs(this.lat0);
+ if ((this.con > Proj4js.common.EPSLN) && (Math.abs(this.con - Proj4js.common.HALF_PI) > Proj4js.common.EPSLN)) {
+ this.singam=Math.sin(this.gama);
+ this.cosgam=Math.cos(this.gama);
+
+ this.sinaz=Math.sin(this.alpha);
+ this.cosaz=Math.cos(this.alpha);
+
+ if (this.lat0>= 0) {
+ this.u = (this.al / this.bl) * Math.atan(Math.sqrt(this.d*this.d - 1.0)/this.cosaz);
+ } else {
+ this.u = -(this.al / this.bl) *Math.atan(Math.sqrt(this.d*this.d - 1.0)/this.cosaz);
+ }
+ } else {
+ Proj4js.reportError("omerc:Init:DataError");
+ }
+ } else {
+ this.sinphi =Math. sin(this.at1);
+ this.ts1 = Proj4js.common.tsfnz(this.e,this.lat1,this.sinphi);
+ this.sinphi = Math.sin(this.lat2);
+ this.ts2 = Proj4js.common.tsfnz(this.e,this.lat2,this.sinphi);
+ this.h = Math.pow(this.ts1,this.bl);
+ this.l = Math.pow(this.ts2,this.bl);
+ this.f = this.el/this.h;
+ this.g = .5 * (this.f - 1.0/this.f);
+ this.j = (this.el * this.el - this.l * this.h)/(this.el * this.el + this.l * this.h);
+ this.p = (this.l - this.h) / (this.l + this.h);
+ this.dlon = this.lon1 - this.lon2;
+ if (this.dlon < -Proj4js.common.PI) this.lon2 = this.lon2 - 2.0 * Proj4js.common.PI;
+ if (this.dlon > Proj4js.common.PI) this.lon2 = this.lon2 + 2.0 * Proj4js.common.PI;
+ this.dlon = this.lon1 - this.lon2;
+ this.longc = .5 * (this.lon1 + this.lon2) -Math.atan(this.j * Math.tan(.5 * this.bl * this.dlon)/this.p)/this.bl;
+ this.dlon = Proj4js.common.adjust_lon(this.lon1 - this.longc);
+ this.gama = Math.atan(Math.sin(this.bl * this.dlon)/this.g);
+ this.alpha = Proj4js.common.asinz(this.d * Math.sin(this.gama));
+
+ /* Report parameters common to format A
+ -------------------------------------*/
+
+ if (Math.abs(this.lat1 - this.lat2) <= Proj4js.common.EPSLN) {
+ Proj4js.reportError("omercInitDataError");
+ //return(202);
+ } else {
+ this.con = Math.abs(this.lat1);
+ }
+ if ((this.con <= Proj4js.common.EPSLN) || (Math.abs(this.con - HALF_PI) <= Proj4js.common.EPSLN)) {
+ Proj4js.reportError("omercInitDataError");
+ //return(202);
+ } else {
+ if (Math.abs(Math.abs(this.lat0) - Proj4js.common.HALF_PI) <= Proj4js.common.EPSLN) {
+ Proj4js.reportError("omercInitDataError");
+ //return(202);
+ }
+ }
+
+ this.singam=Math.sin(this.gam);
+ this.cosgam=Math.cos(this.gam);
+
+ this.sinaz=Math.sin(this.alpha);
+ this.cosaz=Math.cos(this.alpha);
+
+
+ if (this.lat0 >= 0) {
+ this.u = (this.al/this.bl) * Math.atan(Math.sqrt(this.d * this.d - 1.0)/this.cosaz);
+ } else {
+ this.u = -(this.al/this.bl) * Math.atan(Math.sqrt(this.d * this.d - 1.0)/this.cosaz);
+ }
+ }
+ },
+
+
+ /* Oblique Mercator forward equations--mapping lat,long to x,y
+ ----------------------------------------------------------*/
+ forward: function(p) {
+ var theta; /* angle */
+ var sin_phi, cos_phi;/* sin and cos value */
+ var b; /* temporary values */
+ var c, t, tq; /* temporary values */
+ var con, n, ml; /* cone constant, small m */
+ var q,us,vl;
+ var ul,vs;
+ var s;
+ var dlon;
+ var ts1;
+
+ var lon=p.x;
+ var lat=p.y;
+ /* Forward equations
+ -----------------*/
+ sin_phi = Math.sin(lat);
+ dlon = Proj4js.common.adjust_lon(lon - this.longc);
+ vl = Math.sin(this.bl * dlon);
+ if (Math.abs(Math.abs(lat) - Proj4js.common.HALF_PI) > Proj4js.common.EPSLN) {
+ ts1 = Proj4js.common.tsfnz(this.e,lat,sin_phi);
+ q = this.el / (Math.pow(ts1,this.bl));
+ s = .5 * (q - 1.0 / q);
+ t = .5 * (q + 1.0/ q);
+ ul = (s * this.singam - vl * this.cosgam) / t;
+ con = Math.cos(this.bl * dlon);
+ if (Math.abs(con) < .0000001) {
+ us = this.al * this.bl * dlon;
+ } else {
+ us = this.al * Math.atan((s * this.cosgam + vl * this.singam) / con)/this.bl;
+ if (con < 0) us = us + Proj4js.common.PI * this.al / this.bl;
+ }
+ } else {
+ if (lat >= 0) {
+ ul = this.singam;
+ } else {
+ ul = -this.singam;
+ }
+ us = this.al * lat / this.bl;
+ }
+ if (Math.abs(Math.abs(ul) - 1.0) <= Proj4js.common.EPSLN) {
+ //alert("Point projects into infinity","omer-for");
+ Proj4js.reportError("omercFwdInfinity");
+ //return(205);
+ }
+ vs = .5 * this.al * Math.log((1.0 - ul)/(1.0 + ul)) / this.bl;
+ us = us - this.u;
+ var x = this.x0 + vs * this.cosaz + us * this.sinaz;
+ var y = this.y0 + us * this.cosaz - vs * this.sinaz;
+
+ p.x=x;
+ p.y=y;
+ return p;
+ },
+
+ inverse: function(p) {
+ var delta_lon; /* Delta longitude (Given longitude - center */
+ var theta; /* angle */
+ var delta_theta; /* adjusted longitude */
+ var sin_phi, cos_phi;/* sin and cos value */
+ var b; /* temporary values */
+ var c, t, tq; /* temporary values */
+ var con, n, ml; /* cone constant, small m */
+ var vs,us,q,s,ts1;
+ var vl,ul,bs;
+ var dlon;
+ var flag;
+
+ /* Inverse equations
+ -----------------*/
+ p.x -= this.x0;
+ p.y -= this.y0;
+ flag = 0;
+ vs = p.x * this.cosaz - p.y * this.sinaz;
+ us = p.y * this.cosaz + p.x * this.sinaz;
+ us = us + this.u;
+ q = Math.exp(-this.bl * vs / this.al);
+ s = .5 * (q - 1.0/q);
+ t = .5 * (q + 1.0/q);
+ vl = Math.sin(this.bl * us / this.al);
+ ul = (vl * this.cosgam + s * this.singam)/t;
+ if (Math.abs(Math.abs(ul) - 1.0) <= Proj4js.common.EPSLN)
+ {
+ lon = this.longc;
+ if (ul >= 0.0) {
+ lat = Proj4js.common.HALF_PI;
+ } else {
+ lat = -Proj4js.common.HALF_PI;
+ }
+ } else {
+ con = 1.0 / this.bl;
+ ts1 =Math.pow((this.el / Math.sqrt((1.0 + ul) / (1.0 - ul))),con);
+ lat = Proj4js.common.phi2z(this.e,ts1);
+ //if (flag != 0)
+ //return(flag);
+ //~ con = Math.cos(this.bl * us /al);
+ theta = this.longc - Math.atan2((s * this.cosgam - vl * this.singam) , con)/this.bl;
+ lon = Proj4js.common.adjust_lon(theta);
+ }
+ p.x=lon;
+ p.y=lat;
+ return p;
+ }
+};
+/* ======================================================================
+ projCode/lcc.js
+ ====================================================================== */
+
+/*******************************************************************************
+NAME LAMBERT CONFORMAL CONIC
+
+PURPOSE: Transforms input longitude and latitude to Easting and
+ Northing for the Lambert Conformal Conic projection. The
+ longitude and latitude must be in radians. The Easting
+ and Northing values will be returned in meters.
+
+
+ALGORITHM REFERENCES
+
+1. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
+ Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
+ State Government Printing Office, Washington D.C., 1987.
+
+2. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
+ U.S. Geological Survey Professional Paper 1453 , United State Government
+*******************************************************************************/
+
+
+//<2104> +proj=lcc +lat_1=10.16666666666667 +lat_0=10.16666666666667 +lon_0=-71.60561777777777 +k_0=1 +x0=-17044 +x0=-23139.97 +ellps=intl +units=m +no_defs no_defs
+
+// Initialize the Lambert Conformal conic projection
+// -----------------------------------------------------------------
+
+//Proj4js.Proj.lcc = Class.create();
+Proj4js.Proj.lcc = {
+ init : function() {
+
+ // array of: r_maj,r_min,lat1,lat2,c_lon,c_lat,false_east,false_north
+ //double c_lat; /* center latitude */
+ //double c_lon; /* center longitude */
+ //double lat1; /* first standard parallel */
+ //double lat2; /* second standard parallel */
+ //double r_maj; /* major axis */
+ //double r_min; /* minor axis */
+ //double false_east; /* x offset in meters */
+ //double false_north; /* y offset in meters */
+
+ if (!this.lat2){this.lat2=this.lat0;}//if lat2 is not defined
+ if (!this.k0) this.k0 = 1.0;
+
+ // Standard Parallels cannot be equal and on opposite sides of the equator
+ if (Math.abs(this.lat1+this.lat2) < Proj4js.common.EPSLN) {
+ Proj4js.reportError("lcc:init: Equal Latitudes");
+ return;
+ }
+
+ var temp = this.b / this.a;
+ this.e = Math.sqrt(1.0 - temp*temp);
+
+ var sin1 = Math.sin(this.lat1);
+ var cos1 = Math.cos(this.lat1);
+ var ms1 = Proj4js.common.msfnz(this.e, sin1, cos1);
+ var ts1 = Proj4js.common.tsfnz(this.e, this.lat1, sin1);
+
+ var sin2 = Math.sin(this.lat2);
+ var cos2 = Math.cos(this.lat2);
+ var ms2 = Proj4js.common.msfnz(this.e, sin2, cos2);
+ var ts2 = Proj4js.common.tsfnz(this.e, this.lat2, sin2);
+
+ var ts0 = Proj4js.common.tsfnz(this.e, this.lat0, Math.sin(this.lat0));
+
+ if (Math.abs(this.lat1 - this.lat2) > Proj4js.common.EPSLN) {
+ this.ns = Math.log(ms1/ms2)/Math.log(ts1/ts2);
+ } else {
+ this.ns = sin1;
+ }
+ this.f0 = ms1 / (this.ns * Math.pow(ts1, this.ns));
+ this.rh = this.a * this.f0 * Math.pow(ts0, this.ns);
+ if (!this.title) this.title = "Lambert Conformal Conic";
+ },
+
+
+ // Lambert Conformal conic forward equations--mapping lat,long to x,y
+ // -----------------------------------------------------------------
+ forward : function(p) {
+
+ var lon = p.x;
+ var lat = p.y;
+
+ // convert to radians
+ if ( lat <= 90.0 && lat >= -90.0 && lon <= 180.0 && lon >= -180.0) {
+ //lon = lon * Proj4js.common.D2R;
+ //lat = lat * Proj4js.common.D2R;
+ } else {
+ Proj4js.reportError("lcc:forward: llInputOutOfRange: "+ lon +" : " + lat);
+ return null;
+ }
+
+ var con = Math.abs( Math.abs(lat) - Proj4js.common.HALF_PI);
+ var ts, rh1;
+ if (con > Proj4js.common.EPSLN) {
+ ts = Proj4js.common.tsfnz(this.e, lat, Math.sin(lat) );
+ rh1 = this.a * this.f0 * Math.pow(ts, this.ns);
+ } else {
+ con = lat * this.ns;
+ if (con <= 0) {
+ Proj4js.reportError("lcc:forward: No Projection");
+ return null;
+ }
+ rh1 = 0;
+ }
+ var theta = this.ns * Proj4js.common.adjust_lon(lon - this.long0);
+ p.x = this.k0 * (rh1 * Math.sin(theta)) + this.x0;
+ p.y = this.k0 * (this.rh - rh1 * Math.cos(theta)) + this.y0;
+
+ return p;
+ },
+
+ // Lambert Conformal Conic inverse equations--mapping x,y to lat/long
+ // -----------------------------------------------------------------
+ inverse : function(p) {
+
+ var rh1, con, ts;
+ var lat, lon;
+ var x = (p.x - this.x0)/this.k0;
+ var y = (this.rh - (p.y - this.y0)/this.k0);
+ if (this.ns > 0) {
+ rh1 = Math.sqrt (x * x + y * y);
+ con = 1.0;
+ } else {
+ rh1 = -Math.sqrt (x * x + y * y);
+ con = -1.0;
+ }
+ var theta = 0.0;
+ if (rh1 != 0) {
+ theta = Math.atan2((con * x),(con * y));
+ }
+ if ((rh1 != 0) || (this.ns > 0.0)) {
+ con = 1.0/this.ns;
+ ts = Math.pow((rh1/(this.a * this.f0)), con);
+ lat = Proj4js.common.phi2z(this.e, ts);
+ if (lat == -9999) return null;
+ } else {
+ lat = -Proj4js.common.HALF_PI;
+ }
+ lon = Proj4js.common.adjust_lon(theta/this.ns + this.long0);
+
+ p.x = lon;
+ p.y = lat;
+ return p;
+ }
+};
+
+
+
+
+/* ======================================================================
+ projCode/laea.js
+ ====================================================================== */
+
+/*******************************************************************************
+NAME LAMBERT AZIMUTHAL EQUAL-AREA
+
+PURPOSE: Transforms input longitude and latitude to Easting and
+ Northing for the Lambert Azimuthal Equal-Area projection. The
+ longitude and latitude must be in radians. The Easting
+ and Northing values will be returned in meters.
+
+PROGRAMMER DATE
+---------- ----
+D. Steinwand, EROS March, 1991
+
+This function was adapted from the Lambert Azimuthal Equal Area projection
+code (FORTRAN) in the General Cartographic Transformation Package software
+which is available from the U.S. Geological Survey National Mapping Division.
+
+ALGORITHM REFERENCES
+
+1. "New Equal-Area Map Projections for Noncircular Regions", John P. Snyder,
+ The American Cartographer, Vol 15, No. 4, October 1988, pp. 341-355.
+
+2. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
+ Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
+ State Government Printing Office, Washington D.C., 1987.
+
+3. "Software Documentation for GCTP General Cartographic Transformation
+ Package", U.S. Geological Survey National Mapping Division, May 1982.
+*******************************************************************************/
+
+Proj4js.Proj.laea = {
+ S_POLE: 1,
+ N_POLE: 2,
+ EQUIT: 3,
+ OBLIQ: 4,
+
+
+/* Initialize the Lambert Azimuthal Equal Area projection
+ ------------------------------------------------------*/
+ init: function() {
+ var t = Math.abs(this.lat0);
+ if (Math.abs(t - Proj4js.common.HALF_PI) < Proj4js.common.EPSLN) {
+ this.mode = this.lat0 < 0. ? this.S_POLE : this.N_POLE;
+ } else if (Math.abs(t) < Proj4js.common.EPSLN) {
+ this.mode = this.EQUIT;
+ } else {
+ this.mode = this.OBLIQ;
+ }
+ if (this.es > 0) {
+ var sinphi;
+
+ this.qp = Proj4js.common.qsfnz(this.e, 1.0);
+ this.mmf = .5 / (1. - this.es);
+ this.apa = this.authset(this.es);
+ switch (this.mode) {
+ case this.N_POLE:
+ case this.S_POLE:
+ this.dd = 1.;
+ break;
+ case this.EQUIT:
+ this.rq = Math.sqrt(.5 * this.qp);
+ this.dd = 1. / this.rq;
+ this.xmf = 1.;
+ this.ymf = .5 * this.qp;
+ break;
+ case this.OBLIQ:
+ this.rq = Math.sqrt(.5 * this.qp);
+ sinphi = Math.sin(this.lat0);
+ this.sinb1 = Proj4js.common.qsfnz(this.e, sinphi) / this.qp;
+ this.cosb1 = Math.sqrt(1. - this.sinb1 * this.sinb1);
+ this.dd = Math.cos(this.lat0) / (Math.sqrt(1. - this.es * sinphi * sinphi) * this.rq * this.cosb1);
+ this.ymf = (this.xmf = this.rq) / this.dd;
+ this.xmf *= this.dd;
+ break;
+ }
+ } else {
+ if (this.mode == this.OBLIQ) {
+ this.sinph0 = Math.sin(this.lat0);
+ this.cosph0 = Math.cos(this.lat0);
+ }
+ }
+ },
+
+/* Lambert Azimuthal Equal Area forward equations--mapping lat,long to x,y
+ -----------------------------------------------------------------------*/
+ forward: function(p) {
+
+ /* Forward equations
+ -----------------*/
+ var x,y;
+ var lam=p.x;
+ var phi=p.y;
+ lam = Proj4js.common.adjust_lon(lam - this.long0);
+
+ if (this.sphere) {
+ var coslam, cosphi, sinphi;
+
+ sinphi = Math.sin(phi);
+ cosphi = Math.cos(phi);
+ coslam = Math.cos(lam);
+ switch (this.mode) {
+ case this.EQUIT:
+ y = (this.mode == this.EQUIT) ? 1. + cosphi * coslam : 1. + this.sinph0 * sinphi + this.cosph0 * cosphi * coslam;
+ if (y <= Proj4js.common.EPSLN) {
+ Proj4js.reportError("laea:fwd:y less than eps");
+ return null;
+ }
+ y = Math.sqrt(2. / y);
+ x = y * cosphi * Math.sin(lam);
+ y *= (this.mode == this.EQUIT) ? sinphi : this.cosph0 * sinphi - this.sinph0 * cosphi * coslam;
+ break;
+ case this.N_POLE:
+ coslam = -coslam;
+ case this.S_POLE:
+ if (Math.abs(phi + this.phi0) < Proj4js.common.EPSLN) {
+ Proj4js.reportError("laea:fwd:phi < eps");
+ return null;
+ }
+ y = Proj4js.common.FORTPI - phi * .5;
+ y = 2. * ((this.mode == this.S_POLE) ? Math.cos(y) : Math.sin(y));
+ x = y * Math.sin(lam);
+ y *= coslam;
+ break;
+ }
+ } else {
+ var coslam, sinlam, sinphi, q, sinb=0.0, cosb=0.0, b=0.0;
+
+ coslam = Math.cos(lam);
+ sinlam = Math.sin(lam);
+ sinphi = Math.sin(phi);
+ q = Proj4js.common.qsfnz(this.e, sinphi);
+ if (this.mode == this.OBLIQ || this.mode == this.EQUIT) {
+ sinb = q / this.qp;
+ cosb = Math.sqrt(1. - sinb * sinb);
+ }
+ switch (this.mode) {
+ case this.OBLIQ:
+ b = 1. + this.sinb1 * sinb + this.cosb1 * cosb * coslam;
+ break;
+ case this.EQUIT:
+ b = 1. + cosb * coslam;
+ break;
+ case this.N_POLE:
+ b = Proj4js.common.HALF_PI + phi;
+ q = this.qp - q;
+ break;
+ case this.S_POLE:
+ b = phi - Proj4js.common.HALF_PI;
+ q = this.qp + q;
+ break;
+ }
+ if (Math.abs(b) < Proj4js.common.EPSLN) {
+ Proj4js.reportError("laea:fwd:b < eps");
+ return null;
+ }
+ switch (this.mode) {
+ case this.OBLIQ:
+ case this.EQUIT:
+ b = Math.sqrt(2. / b);
+ if (this.mode == this.OBLIQ) {
+ y = this.ymf * b * (this.cosb1 * sinb - this.sinb1 * cosb * coslam);
+ } else {
+ y = (b = Math.sqrt(2. / (1. + cosb * coslam))) * sinb * this.ymf;
+ }
+ x = this.xmf * b * cosb * sinlam;
+ break;
+ case this.N_POLE:
+ case this.S_POLE:
+ if (q >= 0.) {
+ x = (b = Math.sqrt(q)) * sinlam;
+ y = coslam * ((this.mode == this.S_POLE) ? b : -b);
+ } else {
+ x = y = 0.;
+ }
+ break;
+ }
+ }
+
+ //v 1.0
+ /*
+ var sin_lat=Math.sin(lat);
+ var cos_lat=Math.cos(lat);
+
+ var sin_delta_lon=Math.sin(delta_lon);
+ var cos_delta_lon=Math.cos(delta_lon);
+
+ var g =this.sin_lat_o * sin_lat +this.cos_lat_o * cos_lat * cos_delta_lon;
+ if (g == -1.0) {
+ Proj4js.reportError("laea:fwd:Point projects to a circle of radius "+ 2.0 * R);
+ return null;
+ }
+ var ksp = this.a * Math.sqrt(2.0 / (1.0 + g));
+ var x = ksp * cos_lat * sin_delta_lon + this.x0;
+ var y = ksp * (this.cos_lat_o * sin_lat - this.sin_lat_o * cos_lat * cos_delta_lon) + this.y0;
+ */
+ p.x = this.a*x + this.x0;
+ p.y = this.a*y + this.y0;
+ return p;
+ },//lamazFwd()
+
+/* Inverse equations
+ -----------------*/
+ inverse: function(p) {
+ p.x -= this.x0;
+ p.y -= this.y0;
+ var x = p.x/this.a;
+ var y = p.y/this.a;
+
+ if (this.sphere) {
+ var cosz=0.0, rh, sinz=0.0;
+
+ rh = Math.sqrt(x*x + y*y);
+ var phi = rh * .5;
+ if (phi > 1.) {
+ Proj4js.reportError("laea:Inv:DataError");
+ return null;
+ }
+ phi = 2. * Math.asin(phi);
+ if (this.mode == this.OBLIQ || this.mode == this.EQUIT) {
+ sinz = Math.sin(phi);
+ cosz = Math.cos(phi);
+ }
+ switch (this.mode) {
+ case this.EQUIT:
+ phi = (Math.abs(rh) <= Proj4js.common.EPSLN) ? 0. : Math.asin(y * sinz / rh);
+ x *= sinz;
+ y = cosz * rh;
+ break;
+ case this.OBLIQ:
+ phi = (Math.abs(rh) <= Proj4js.common.EPSLN) ? this.phi0 : Math.asin(cosz * sinph0 + y * sinz * cosph0 / rh);
+ x *= sinz * cosph0;
+ y = (cosz - Math.sin(phi) * sinph0) * rh;
+ break;
+ case this.N_POLE:
+ y = -y;
+ phi = Proj4js.common.HALF_PI - phi;
+ break;
+ case this.S_POLE:
+ phi -= Proj4js.common.HALF_PI;
+ break;
+ }
+ lam = (y == 0. && (this.mode == this.EQUIT || this.mode == this.OBLIQ)) ? 0. : Math.atan2(x, y);
+ } else {
+ var cCe, sCe, q, rho, ab=0.0;
+
+ switch (this.mode) {
+ case this.EQUIT:
+ case this.OBLIQ:
+ x /= this.dd;
+ y *= this.dd;
+ rho = Math.sqrt(x*x + y*y);
+ if (rho < Proj4js.common.EPSLN) {
+ p.x = 0.;
+ p.y = this.phi0;
+ return p;
+ }
+ sCe = 2. * Math.asin(.5 * rho / this.rq);
+ cCe = Math.cos(sCe);
+ x *= (sCe = Math.sin(sCe));
+ if (this.mode == this.OBLIQ) {
+ ab = cCe * this.sinb1 + y * sCe * this.cosb1 / rho
+ q = this.qp * ab;
+ y = rho * this.cosb1 * cCe - y * this.sinb1 * sCe;
+ } else {
+ ab = y * sCe / rho;
+ q = this.qp * ab;
+ y = rho * cCe;
+ }
+ break;
+ case this.N_POLE:
+ y = -y;
+ case this.S_POLE:
+ q = (x * x + y * y);
+ if (!q ) {
+ p.x = 0.;
+ p.y = this.phi0;
+ return p;
+ }
+ /*
+ q = this.qp - q;
+ */
+ ab = 1. - q / this.qp;
+ if (this.mode == this.S_POLE) {
+ ab = - ab;
+ }
+ break;
+ }
+ lam = Math.atan2(x, y);
+ phi = this.authlat(Math.asin(ab), this.apa);
+ }
+
+ /*
+ var Rh = Math.Math.sqrt(p.x *p.x +p.y * p.y);
+ var temp = Rh / (2.0 * this.a);
+
+ if (temp > 1) {
+ Proj4js.reportError("laea:Inv:DataError");
+ return null;
+ }
+
+ var z = 2.0 * Proj4js.common.asinz(temp);
+ var sin_z=Math.sin(z);
+ var cos_z=Math.cos(z);
+
+ var lon =this.long0;
+ if (Math.abs(Rh) > Proj4js.common.EPSLN) {
+ var lat = Proj4js.common.asinz(this.sin_lat_o * cos_z +this. cos_lat_o * sin_z *p.y / Rh);
+ var temp =Math.abs(this.lat0) - Proj4js.common.HALF_PI;
+ if (Math.abs(temp) > Proj4js.common.EPSLN) {
+ temp = cos_z -this.sin_lat_o * Math.sin(lat);
+ if(temp!=0.0) lon=Proj4js.common.adjust_lon(this.long0+Math.atan2(p.x*sin_z*this.cos_lat_o,temp*Rh));
+ } else if (this.lat0 < 0.0) {
+ lon = Proj4js.common.adjust_lon(this.long0 - Math.atan2(-p.x,p.y));
+ } else {
+ lon = Proj4js.common.adjust_lon(this.long0 + Math.atan2(p.x, -p.y));
+ }
+ } else {
+ lat = this.lat0;
+ }
+ */
+ //return(OK);
+ p.x = Proj4js.common.adjust_lon(this.long0+lam);
+ p.y = phi;
+ return p;
+ },//lamazInv()
+
+/* determine latitude from authalic latitude */
+ P00: .33333333333333333333,
+ P01: .17222222222222222222,
+ P02: .10257936507936507936,
+ P10: .06388888888888888888,
+ P11: .06640211640211640211,
+ P20: .01641501294219154443,
+
+ authset: function(es) {
+ var t;
+ var APA = new Array();
+ APA[0] = es * this.P00;
+ t = es * es;
+ APA[0] += t * this.P01;
+ APA[1] = t * this.P10;
+ t *= es;
+ APA[0] += t * this.P02;
+ APA[1] += t * this.P11;
+ APA[2] = t * this.P20;
+ return APA;
+ },
+
+ authlat: function(beta, APA) {
+ var t = beta+beta;
+ return(beta + APA[0] * Math.sin(t) + APA[1] * Math.sin(t+t) + APA[2] * Math.sin(t+t+t));
+ }
+
+};
+
+
+
+/* ======================================================================
+ projCode/aeqd.js
+ ====================================================================== */
+
+Proj4js.Proj.aeqd = {
+
+ init : function() {
+ this.sin_p12=Math.sin(this.lat0);
+ this.cos_p12=Math.cos(this.lat0);
+ },
+
+ forward: function(p) {
+ var lon=p.x;
+ var lat=p.y;
+ var ksp;
+
+ var sinphi=Math.sin(p.y);
+ var cosphi=Math.cos(p.y);
+ var dlon = Proj4js.common.adjust_lon(lon - this.long0);
+ var coslon = Math.cos(dlon);
+ var g = this.sin_p12 * sinphi + this.cos_p12 * cosphi * coslon;
+ if (Math.abs(Math.abs(g) - 1.0) < Proj4js.common.EPSLN) {
+ ksp = 1.0;
+ if (g < 0.0) {
+ Proj4js.reportError("aeqd:Fwd:PointError");
+ return;
+ }
+ } else {
+ var z = Math.acos(g);
+ ksp = z/Math.sin(z);
+ }
+ p.x = this.x0 + this.a * ksp * cosphi * Math.sin(dlon);
+ p.y = this.y0 + this.a * ksp * (this.cos_p12 * sinphi - this.sin_p12 * cosphi * coslon);
+ return p;
+ },
+
+ inverse: function(p){
+ p.x -= this.x0;
+ p.y -= this.y0;
+
+ var rh = Math.sqrt(p.x * p.x + p.y *p.y);
+ if (rh > (2.0 * Proj4js.common.HALF_PI * this.a)) {
+ Proj4js.reportError("aeqdInvDataError");
+ return;
+ }
+ var z = rh / this.a;
+
+ var sinz=Math.sin(z);
+ var cosz=Math.cos(z);
+
+ var lon = this.long0;
+ var lat;
+ if (Math.abs(rh) <= Proj4js.common.EPSLN) {
+ lat = this.lat0;
+ } else {
+ lat = Proj4js.common.asinz(cosz * this.sin_p12 + (p.y * sinz * this.cos_p12) / rh);
+ var con = Math.abs(this.lat0) - Proj4js.common.HALF_PI;
+ if (Math.abs(con) <= Proj4js.common.EPSLN) {
+ if (lat0 >= 0.0) {
+ lon = Proj4js.common.adjust_lon(this.long0 + Math.atan2(p.x , -p.y));
+ } else {
+ lon = Proj4js.common.adjust_lon(this.long0 - Math.atan2(-p.x , p.y));
+ }
+ } else {
+ con = cosz - this.sin_p12 * Math.sin(lat);
+ if ((Math.abs(con) < Proj4js.common.EPSLN) && (Math.abs(p.x) < Proj4js.common.EPSLN)) {
+ //no-op, just keep the lon value as is
+ } else {
+ var temp = Math.atan2((p.x * sinz * this.cos_p12), (con * rh));
+ lon = Proj4js.common.adjust_lon(this.long0 + Math.atan2((p.x * sinz * this.cos_p12), (con * rh)));
+ }
+ }
+ }
+
+ p.x = lon;
+ p.y = lat;
+ return p;
+ }
+};
+/* ======================================================================
+ projCode/moll.js
+ ====================================================================== */
+
+/*******************************************************************************
+NAME MOLLWEIDE
+
+PURPOSE: Transforms input longitude and latitude to Easting and
+ Northing for the MOllweide projection. The
+ longitude and latitude must be in radians. The Easting
+ and Northing values will be returned in meters.
+
+PROGRAMMER DATE
+---------- ----
+D. Steinwand, EROS May, 1991; Updated Sept, 1992; Updated Feb, 1993
+S. Nelson, EDC Jun, 2993; Made corrections in precision and
+ number of iterations.
+
+ALGORITHM REFERENCES
+
+1. Snyder, John P. and Voxland, Philip M., "An Album of Map Projections",
+ U.S. Geological Survey Professional Paper 1453 , United State Government
+ Printing Office, Washington D.C., 1989.
+
+2. Snyder, John P., "Map Projections--A Working Manual", U.S. Geological
+ Survey Professional Paper 1395 (Supersedes USGS Bulletin 1532), United
+ State Government Printing Office, Washington D.C., 1987.
+*******************************************************************************/
+
+Proj4js.Proj.moll = {
+
+ /* Initialize the Mollweide projection
+ ------------------------------------*/
+ init: function(){
+ //no-op
+ },
+
+ /* Mollweide forward equations--mapping lat,long to x,y
+ ----------------------------------------------------*/
+ forward: function(p) {
+
+ /* Forward equations
+ -----------------*/
+ var lon=p.x;
+ var lat=p.y;
+
+ var delta_lon = Proj4js.common.adjust_lon(lon - this.long0);
+ var theta = lat;
+ var con = Proj4js.common.PI * Math.sin(lat);
+
+ /* Iterate using the Newton-Raphson method to find theta
+ -----------------------------------------------------*/
+ for (var i=0;true;i++) {
+ var delta_theta = -(theta + Math.sin(theta) - con)/ (1.0 + Math.cos(theta));
+ theta += delta_theta;
+ if (Math.abs(delta_theta) < Proj4js.common.EPSLN) break;
+ if (i >= 50) {
+ Proj4js.reportError("moll:Fwd:IterationError");
+ //return(241);
+ }
+ }
+ theta /= 2.0;
+
+ /* If the latitude is 90 deg, force the x coordinate to be "0 + false easting"
+ this is done here because of precision problems with "cos(theta)"
+ --------------------------------------------------------------------------*/
+ if (Proj4js.common.PI/2 - Math.abs(lat) < Proj4js.common.EPSLN) delta_lon =0;
+ var x = 0.900316316158 * this.a * delta_lon * Math.cos(theta) + this.x0;
+ var y = 1.4142135623731 * this.a * Math.sin(theta) + this.y0;
+
+ p.x=x;
+ p.y=y;
+ return p;
+ },
+
+ inverse: function(p){
+ var theta;
+ var arg;
+
+ /* Inverse equations
+ -----------------*/
+ p.x-= this.x0;
+ //~ p.y -= this.y0;
+ var arg = p.y / (1.4142135623731 * this.a);
+
+ /* Because of division by zero problems, 'arg' can not be 1.0. Therefore
+ a number very close to one is used instead.
+ -------------------------------------------------------------------*/
+ if(Math.abs(arg) > 0.999999999999) arg=0.999999999999;
+ var theta =Math.asin(arg);
+ var lon = Proj4js.common.adjust_lon(this.long0 + (p.x / (0.900316316158 * this.a * Math.cos(theta))));
+ if(lon < (-Proj4js.common.PI)) lon= -Proj4js.common.PI;
+ if(lon > Proj4js.common.PI) lon= Proj4js.common.PI;
+ arg = (2.0 * theta + Math.sin(2.0 * theta)) / Proj4js.common.PI;
+ if(Math.abs(arg) > 1.0)arg=1.0;
+ var lat = Math.asin(arg);
+ //return(OK);
+
+ p.x=lon;
+ p.y=lat;
+ return p;
+ }
+};
+
Modified: branches/fusion-2.2/lib/proj4js-compressed.js
===================================================================
--- branches/fusion-2.2/lib/proj4js-compressed.js 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/lib/proj4js-compressed.js 2010-09-24 18:32:16 UTC (rev 2234)
@@ -9,7 +9,8 @@
Note: This program is an almost direct port of the C library
Proj4.
*/
-Proj4js={defaultDatum:'WGS84',transform:function(source,dest,point){if(!source.readyToUse||!dest.readyToUse){this.reportError("Proj4js initialization for "+source.srsCode+" not yet complete");return point;}
+Proj4js={defaultDatum:'WGS84',transform:function(source,dest,point){if(!source.readyToUse){this.reportError("Proj4js initialization for:"+source.srsCode+" not yet complete");return point;}
+if(!dest.readyToUse){this.reportError("Proj4js initialization for:"+dest.srsCode+" not yet complete");return point;}
if((source.srsProjNumber=="900913"&&dest.datumCode!="WGS84")||(dest.srsProjNumber=="900913"&&source.datumCode!="WGS84")){var wgs84=Proj4js.WGS84;this.transform(source,wgs84,point);source=wgs84;}
if(source.projName=="longlat"){point.x*=Proj4js.common.D2R;point.y*=Proj4js.common.D2R;}else{if(source.to_meter){point.x*=source.to_meter;point.y*=source.to_meter;}
source.inverse(point);}
@@ -33,17 +34,25 @@
Proj4js.extend(extended,parent);}
Class.prototype=extended;return Class;},bind:function(func,object){var args=Array.prototype.slice.apply(arguments,[2]);return function(){var newArgs=args.concat(Array.prototype.slice.apply(arguments,[0]));return func.apply(object,newArgs);};},scriptName:"proj4js-compressed.js",defsLookupService:'http://spatialreference.org/ref',libPath:null,getScriptLocation:function(){if(this.libPath)return this.libPath;var scriptName=this.scriptName;var scriptNameLen=scriptName.length;var scripts=document.getElementsByTagName('script');for(var i=0;i<scripts.length;i++){var src=scripts[i].getAttribute('src');if(src){var index=src.lastIndexOf(scriptName);if((index>-1)&&(index+scriptNameLen==src.length)){this.libPath=src.slice(0,-scriptNameLen);break;}}}
return this.libPath||"";},loadScript:function(url,onload,onfail,loadCheck){var script=document.createElement('script');script.defer=false;script.type="text/javascript";script.id=url;script.src=url;script.onload=onload;script.onerror=onfail;script.loadCheck=loadCheck;if(/MSIE/.test(navigator.userAgent)){script.onreadystatechange=this.checkReadyState;}
-document.getElementsByTagName('head')[0].appendChild(script);},checkReadyState:function(){if(this.readyState=='loaded'){if(!this.loadCheck()){this.onerror();}else{this.onload();}}}};Proj4js.Proj=Proj4js.Class({readyToUse:false,title:null,projName:null,units:null,datum:null,x0:0,y0:0,initialize:function(srsCode){this.srsCodeInput=srsCode;if(srsCode.indexOf('urn:')==0){var urn=srsCode.split(':');if((urn[1]=='ogc'||urn[1]=='x-ogc')&&(urn[2]=='def')&&(urn[3]=='crs')){srsCode=urn[4]+':'+urn[urn.length-1];}}else if(srsCode.indexOf('http://')==0){var url=srsCode.split('#');if(url[0].match(/epsg.org/)){srsCode='EPSG:'+url[1];}else if(url[0].match(/RIG.xml/)){srsCode='IGNF:'+url[1];}}
+document.getElementsByTagName('head')[0].appendChild(script);},checkReadyState:function(){if(this.readyState=='loaded'){if(!this.loadCheck()){this.onerror();}else{this.onload();}}}};Proj4js.Proj=Proj4js.Class({readyToUse:false,title:null,projName:null,units:null,datum:null,x0:0,y0:0,localCS:false,initialize:function(srsCode){this.srsCodeInput=srsCode;if((srsCode.indexOf('GEOGCS')>=0)||(srsCode.indexOf('GEOCCS')>=0)||(srsCode.indexOf('PROJCS')>=0)||(srsCode.indexOf('LOCAL_CS')>=0)){this.parseWKT(srsCode);this.datum=new Proj4js.datum(this);this.loadProjCode(this.projName);return;}
+if(srsCode.indexOf('urn:')==0){var urn=srsCode.split(':');if((urn[1]=='ogc'||urn[1]=='x-ogc')&&(urn[2]=='def')&&(urn[3]=='crs')){srsCode=urn[4]+':'+urn[urn.length-1];}}else if(srsCode.indexOf('http://')==0){var url=srsCode.split('#');if(url[0].match(/epsg.org/)){srsCode='EPSG:'+url[1];}else if(url[0].match(/RIG.xml/)){srsCode='IGNF:'+url[1];}}
this.srsCode=srsCode.toUpperCase();if(this.srsCode.indexOf("EPSG")==0){this.srsCode=this.srsCode;this.srsAuth='epsg';this.srsProjNumber=this.srsCode.substring(5);}else if(this.srsCode.indexOf("IGNF")==0){this.srsCode=this.srsCode;this.srsAuth='IGNF';this.srsProjNumber=this.srsCode.substring(5);}else if(this.srsCode.indexOf("CRS")==0){this.srsCode=this.srsCode;this.srsAuth='CRS';this.srsProjNumber=this.srsCode.substring(4);}else{this.srsAuth='';this.srsProjNumber=this.srsCode;}
this.loadProjDefinition();},loadProjDefinition:function(){if(Proj4js.defs[this.srsCode]){this.defsLoaded();return;}
var url=Proj4js.getScriptLocation()+'defs/'+this.srsAuth.toUpperCase()+this.srsProjNumber+'.js';Proj4js.loadScript(url,Proj4js.bind(this.defsLoaded,this),Proj4js.bind(this.loadFromService,this),Proj4js.bind(this.checkDefsLoaded,this));},loadFromService:function(){var url=Proj4js.defsLookupService+'/'+this.srsAuth+'/'+this.srsProjNumber+'/proj4js/';Proj4js.loadScript(url,Proj4js.bind(this.defsLoaded,this),Proj4js.bind(this.defsFailed,this),Proj4js.bind(this.checkDefsLoaded,this));},defsLoaded:function(){this.parseDefs();this.loadProjCode(this.projName);},checkDefsLoaded:function(){if(Proj4js.defs[this.srsCode]){return true;}else{return false;}},defsFailed:function(){Proj4js.reportError('failed to load projection definition for: '+this.srsCode);Proj4js.defs[this.srsCode]=Proj4js.defs['WGS84'];this.defsLoaded();},loadProjCode:function(projName){if(Proj4js.Proj[projName]){this.initTransforms();return;}
-var url=Proj4js.getScriptLocation()+'projCode/'+projName+'.js';Proj4js.loadScript(url,Proj4js.bind(this.loadProjCodeSuccess,this,projName),Proj4js.bind(this.loadProjCodeFailure,this,projName),Proj4js.bind(this.checkCodeLoaded,this,projName));},loadProjCodeSuccess:function(projName){if(Proj4js.Proj[projName].dependsOn){this.loadProjCode(Proj4js.Proj[projName].dependsOn);}else{this.initTransforms();}},loadProjCodeFailure:function(projName){Proj4js.reportError("failed to find projection file for: "+projName);},checkCodeLoaded:function(projName){if(Proj4js.Proj[projName]){return true;}else{return false;}},initTransforms:function(){Proj4js.extend(this,Proj4js.Proj[this.projName]);this.init();this.readyToUse=true;},parseDefs:function(){this.defData=Proj4js.defs[this.srsCode];var paramName,paramVal;if(!this.defData){return;}
+var url=Proj4js.getScriptLocation()+'projCode/'+projName+'.js';Proj4js.loadScript(url,Proj4js.bind(this.loadProjCodeSuccess,this,projName),Proj4js.bind(this.loadProjCodeFailure,this,projName),Proj4js.bind(this.checkCodeLoaded,this,projName));},loadProjCodeSuccess:function(projName){if(Proj4js.Proj[projName].dependsOn){this.loadProjCode(Proj4js.Proj[projName].dependsOn);}else{this.initTransforms();}},loadProjCodeFailure:function(projName){Proj4js.reportError("failed to find projection file for: "+projName);},checkCodeLoaded:function(projName){if(Proj4js.Proj[projName]){return true;}else{return false;}},initTransforms:function(){Proj4js.extend(this,Proj4js.Proj[this.projName]);this.init();this.readyToUse=true;},wktRE:/^(\w+)\[(.*)\]$/,parseWKT:function(wkt){var wktMatch=wkt.match(this.wktRE);if(!wktMatch)return;var wktObject=wktMatch[1];var wktContent=wktMatch[2];var wktTemp=wktContent.split(",");var wktName=wktTemp.shift();wktName=wktName.replace(/^\"/,"");wktName=wktName.rep
lace(/\"$/,"");var wktArray=new Array();var bkCount=0;var obj="";for(var i=0;i<wktTemp.length;++i){var token=wktTemp[i];for(var j=0;j<token.length;++j){if(token.charAt(j)=="[")++bkCount;if(token.charAt(j)=="]")--bkCount;}
+obj+=token;if(bkCount===0){wktArray.push(obj);obj="";}else{obj+=",";}}
+switch(wktObject){case'LOCAL_CS':this.projName='identity'
+this.localCS=true;this.srsCode=wktName;break;case'GEOGCS':this.projName='longlat'
+this.geocsCode=wktName;if(!this.srsCode)this.srsCode=wktName;break;case'PROJCS':this.srsCode=wktName;break;case'GEOCCS':break;case'PROJECTION':this.projName=Proj4js.wktProjections[wktName]
+break;case'DATUM':this.datumName=wktName;break;case'LOCAL_DATUM':this.datumCode='none';break;case'SPHEROID':this.ellps=wktName;this.a=parseFloat(wktArray.shift());this.rf=parseFloat(wktArray.shift());break;case'PRIMEM':this.from_greenwich=parseFloat(wktArray.shift());break;case'UNIT':this.units=wktName;this.unitsPerMeter=parseFloat(wktArray.shift());break;case'PARAMETER':var name=wktName;var value=parseFloat(parseFloat(wktArray.shift()));switch(name){case'false_easting':this.x0=value;break;case'false_northing':this.y0=value;break;case'scale_factor':this.k0=value;break;case'central_meridian':this.long0=value;break;case'latitude_of_origin':this.lat0=value;break;case'more_here':break;default:break;}
+break;case'TOWGS84':this.datum_params=wktArray;break;case'MORE_HERE':break;default:break;}
+for(var i=0;i<wktArray.length;++i){this.parseWKT(wktArray[i]);}},parseDefs:function(){this.defData=Proj4js.defs[this.srsCode];var paramName,paramVal;if(!this.defData){return;}
var paramArray=this.defData.split("+");for(var prop=0;prop<paramArray.length;prop++){var property=paramArray[prop].split("=");paramName=property[0].toLowerCase();paramVal=property[1];switch(paramName.replace(/\s/gi,"")){case"":break;case"title":this.title=paramVal;break;case"proj":this.projName=paramVal.replace(/\s/gi,"");break;case"units":this.units=paramVal.replace(/\s/gi,"");break;case"datum":this.datumCode=paramVal.replace(/\s/gi,"");break;case"nadgrids":this.nagrids=paramVal.replace(/\s/gi,"");break;case"ellps":this.ellps=paramVal.replace(/\s/gi,"");break;case"a":this.a=parseFloat(paramVal);break;case"b":this.b=parseFloat(paramVal);break;case"rf":this.rf=parseFloat(paramVal);break;case"lat_0":this.lat0=paramVal*Proj4js.common.D2R;break;case"lat_1":this.lat1=paramVal*Proj4js.common.D2R;break;case"lat_2":this.lat2=paramVal*Proj4js.common.D2R;break;case"lat_ts":this.lat_ts=paramVal*Proj4js.common.D2R;break;case"lon_0":this.long0=paramVal*Proj4js.common.D2R;break;case"alpha
":this.alpha=parseFloat(paramVal)*Proj4js.common.D2R;break;case"lonc":this.longc=paramVal*Proj4js.common.D2R;break;case"x_0":this.x0=parseFloat(paramVal);break;case"y_0":this.y0=parseFloat(paramVal);break;case"k_0":this.k0=parseFloat(paramVal);break;case"k":this.k0=parseFloat(paramVal);break;case"r_a":this.R_A=true;break;case"zone":this.zone=parseInt(paramVal);break;case"south":this.utmSouth=true;break;case"towgs84":this.datum_params=paramVal.split(",");break;case"to_meter":this.to_meter=parseFloat(paramVal);break;case"from_greenwich":this.from_greenwich=paramVal*Proj4js.common.D2R;break;case"pm":paramVal=paramVal.replace(/\s/gi,"");this.from_greenwich=Proj4js.PrimeMeridian[paramVal]?Proj4js.PrimeMeridian[paramVal]:parseFloat(paramVal);this.from_greenwich*=Proj4js.common.D2R;break;case"no_defs":break;default:}}
this.deriveConstants();},deriveConstants:function(){if(this.nagrids=='@null')this.datumCode='none';if(this.datumCode&&this.datumCode!='none'){var datumDef=Proj4js.Datum[this.datumCode];if(datumDef){this.datum_params=datumDef.towgs84?datumDef.towgs84.split(','):null;this.ellps=datumDef.ellipse;this.datumName=datumDef.datumName?datumDef.datumName:this.datumCode;}}
if(!this.a){var ellipse=Proj4js.Ellipsoid[this.ellps]?Proj4js.Ellipsoid[this.ellps]:Proj4js.Ellipsoid['WGS84'];Proj4js.extend(this,ellipse);}
if(this.rf&&!this.b)this.b=(1.0-1.0/this.rf)*this.a;if(Math.abs(this.a-this.b)<Proj4js.common.EPSLN){this.sphere=true;this.b=this.a;}
this.a2=this.a*this.a;this.b2=this.b*this.b;this.es=(this.a2-this.b2)/this.a2;this.e=Math.sqrt(this.es);if(this.R_A){this.a*=1.-this.es*(Proj4js.common.SIXTH+this.es*(Proj4js.common.RA4+this.es*Proj4js.common.RA6));this.a2=this.a*this.a;this.b2=this.b*this.b;this.es=0.;}
-this.ep2=(this.a2-this.b2)/this.b2;if(!this.k0)this.k0=1.0;this.datum=new Proj4js.datum(this);}});Proj4js.Proj.longlat={init:function(){},forward:function(pt){return pt;},inverse:function(pt){return pt;}};Proj4js.Proj.identity=Proj4js.Proj.longlat;Proj4js.defs={'WGS84':"+title=long/lat:WGS84 +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees",'EPSG:4326':"+title=long/lat:WGS84 +proj=longlat +a=6378137.0 +b=6356752.31424518 +ellps=WGS84 +datum=WGS84 +units=degrees",'EPSG:4269':"+title=long/lat:NAD83 +proj=longlat +a=6378137.0 +b=6356752.31414036 +ellps=GRS80 +datum=NAD83 +units=degrees",'EPSG:3785':"+title= Google Mercator +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs"};Proj4js.defs['GOOGLE']=Proj4js.defs['EPSG:3785'];Proj4js.defs['EPSG:900913']=Proj4js.defs['EPSG:3785'];Proj4js.defs['EPSG:102113']=Proj4js.defs['EPSG:3785'];Proj4js.common={PI:3.141592653589793238,HALF_PI:1.570796326794896619,TWO_PI:6.28318
5307179586477,FORTPI:0.78539816339744833,R2D:57.29577951308232088,D2R:0.01745329251994329577,SEC_TO_RAD:4.84813681109535993589914102357e-6,EPSLN:1.0e-10,MAX_ITER:20,COS_67P5:0.38268343236508977,AD_C:1.0026000,PJD_UNKNOWN:0,PJD_3PARAM:1,PJD_7PARAM:2,PJD_GRIDSHIFT:3,PJD_WGS84:4,PJD_NODATUM:5,SRS_WGS84_SEMIMAJOR:6378137.0,SIXTH:.1666666666666666667,RA4:.04722222222222222222,RA6:.02215608465608465608,RV4:.06944444444444444444,RV6:.04243827160493827160,msfnz:function(eccent,sinphi,cosphi){var con=eccent*sinphi;return cosphi/(Math.sqrt(1.0-con*con));},tsfnz:function(eccent,phi,sinphi){var con=eccent*sinphi;var com=.5*eccent;con=Math.pow(((1.0-con)/(1.0+con)),com);return(Math.tan(.5*(this.HALF_PI-phi))/con);},phi2z:function(eccent,ts){var eccnth=.5*eccent;var con,dphi;var phi=this.HALF_PI-2*Math.atan(ts);for(i=0;i<=15;i++){con=eccent*Math.sin(phi);dphi=this.HALF_PI-2*Math.atan(ts*(Math.pow(((1.0-con)/(1.0+con)),eccnth)))-phi;phi+=dphi;if(Math.abs(dphi)<=.0000000001)return phi;}
+this.ep2=(this.a2-this.b2)/this.b2;if(!this.k0)this.k0=1.0;this.datum=new Proj4js.datum(this);}});Proj4js.Proj.longlat={init:function(){},forward:function(pt){return pt;},inverse:function(pt){return pt;}};Proj4js.Proj.identity=Proj4js.Proj.longlat;Proj4js.defs={'WGS84':"+title=long/lat:WGS84 +proj=longlat +ellps=WGS84 +datum=WGS84 +units=degrees",'EPSG:4326':"+title=long/lat:WGS84 +proj=longlat +a=6378137.0 +b=6356752.31424518 +ellps=WGS84 +datum=WGS84 +units=degrees",'EPSG:4269':"+title=long/lat:NAD83 +proj=longlat +a=6378137.0 +b=6356752.31414036 +ellps=GRS80 +datum=NAD83 +units=degrees",'EPSG:3785':"+title= Google Mercator +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs"};Proj4js.defs['GOOGLE']=Proj4js.defs['EPSG:3785'];Proj4js.defs['EPSG:900913']=Proj4js.defs['EPSG:3785'];Proj4js.defs['EPSG:102113']=Proj4js.defs['EPSG:3785'];Proj4js.common={PI:3.141592653589793238,HALF_PI:1.570796326794896619,TWO_PI:6.28318
5307179586477,FORTPI:0.78539816339744833,R2D:57.29577951308232088,D2R:0.01745329251994329577,SEC_TO_RAD:4.84813681109535993589914102357e-6,EPSLN:1.0e-10,MAX_ITER:20,COS_67P5:0.38268343236508977,AD_C:1.0026000,PJD_UNKNOWN:0,PJD_3PARAM:1,PJD_7PARAM:2,PJD_GRIDSHIFT:3,PJD_WGS84:4,PJD_NODATUM:5,SRS_WGS84_SEMIMAJOR:6378137.0,SIXTH:.1666666666666666667,RA4:.04722222222222222222,RA6:.02215608465608465608,RV4:.06944444444444444444,RV6:.04243827160493827160,msfnz:function(eccent,sinphi,cosphi){var con=eccent*sinphi;return cosphi/(Math.sqrt(1.0-con*con));},tsfnz:function(eccent,phi,sinphi){var con=eccent*sinphi;var com=.5*eccent;con=Math.pow(((1.0-con)/(1.0+con)),com);return(Math.tan(.5*(this.HALF_PI-phi))/con);},phi2z:function(eccent,ts){var eccnth=.5*eccent;var con,dphi;var phi=this.HALF_PI-2*Math.atan(ts);for(var i=0;i<=15;i++){con=eccent*Math.sin(phi);dphi=this.HALF_PI-2*Math.atan(ts*(Math.pow(((1.0-con)/(1.0+con)),eccnth)))-phi;phi+=dphi;if(Math.abs(dphi)<=.0000000001)return phi;}
alert("phi2z has NoConvergence");return(-9999);},qsfnz:function(eccent,sinphi){var con;if(eccent>1.0e-7){con=eccent*sinphi;return((1.0-eccent*eccent)*(sinphi/(1.0-con*con)-(.5/eccent)*Math.log((1.0-con)/(1.0+con))));}else{return(2.0*sinphi);}},asinz:function(x){if(Math.abs(x)>1.0){x=(x>1.0)?1.0:-1.0;}
return Math.asin(x);},e0fn:function(x){return(1.0-0.25*x*(1.0+x/16.0*(3.0+1.25*x)));},e1fn:function(x){return(0.375*x*(1.0+0.25*x*(1.0+0.46875*x)));},e2fn:function(x){return(0.05859375*x*x*(1.0+0.75*x));},e3fn:function(x){return(x*x*x*(35.0/3072.0));},mlfn:function(e0,e1,e2,e3,phi){return(e0*phi-e1*Math.sin(2.0*phi)+e2*Math.sin(4.0*phi)-e3*Math.sin(6.0*phi));},srat:function(esinp,exp){return(Math.pow((1.0-esinp)/(1.0+esinp),exp));},sign:function(x){if(x<0.0)return(-1);else return(1);},adjust_lon:function(x){x=(Math.abs(x)<this.PI)?x:(x-(this.sign(x)*this.TWO_PI));return x;},adjust_lat:function(x){x=(Math.abs(x)<this.HALF_PI)?x:(x-(this.sign(x)*this.PI));return x;},latiso:function(eccent,phi,sinphi){if(Math.abs(phi)>this.HALF_PI)return+Number.NaN;if(phi==this.HALF_PI)return Number.POSITIVE_INFINITY;if(phi==-1.0*this.HALF_PI)return-1.0*Number.POSITIVE_INFINITY;var con=eccent*sinphi;return Math.log(Math.tan((this.HALF_PI+phi)/2.0))+eccent*Math.log((1.0-con)/(1.0+con))/2.0;},fL:
function(x,L){return 2.0*Math.atan(x*Math.exp(L))-this.HALF_PI;},invlatiso:function(eccent,ts){var phi=this.fL(1.0,ts);var Iphi=0.0;var con=0.0;do{Iphi=phi;con=eccent*Math.sin(Iphi);phi=this.fL(Math.exp(eccent*Math.log((1.0+con)/(1.0-con))/2.0),ts)}while(Math.abs(phi-Iphi)>1.0e-12);return phi;},sinh:function(x)
{var r=Math.exp(x);r=(r-1.0/r)/2.0;return r;},cosh:function(x)
@@ -88,7 +97,7 @@
{var Dx_BF=this.datum_params[0];var Dy_BF=this.datum_params[1];var Dz_BF=this.datum_params[2];var Rx_BF=this.datum_params[3];var Ry_BF=this.datum_params[4];var Rz_BF=this.datum_params[5];var M_BF=this.datum_params[6];var x_out=M_BF*(p.x-Rz_BF*p.y+Ry_BF*p.z)+Dx_BF;var y_out=M_BF*(Rz_BF*p.x+p.y-Rx_BF*p.z)+Dy_BF;var z_out=M_BF*(-Ry_BF*p.x+Rx_BF*p.y+p.z)+Dz_BF;p.x=x_out;p.y=y_out;p.z=z_out;}},geocentric_from_wgs84:function(p){if(this.datum_type==Proj4js.common.PJD_3PARAM)
{p.x-=this.datum_params[0];p.y-=this.datum_params[1];p.z-=this.datum_params[2];}
else if(this.datum_type==Proj4js.common.PJD_7PARAM)
-{var Dx_BF=this.datum_params[0];var Dy_BF=this.datum_params[1];var Dz_BF=this.datum_params[2];var Rx_BF=this.datum_params[3];var Ry_BF=this.datum_params[4];var Rz_BF=this.datum_params[5];var M_BF=this.datum_params[6];var x_tmp=(p.x-Dx_BF)/M_BF;var y_tmp=(p.y-Dy_BF)/M_BF;var z_tmp=(p.z-Dz_BF)/M_BF;p.x=x_tmp+Rz_BF*y_tmp-Ry_BF*z_tmp;p.y=-Rz_BF*x_tmp+y_tmp+Rx_BF*z_tmp;p.z=Ry_BF*x_tmp-Rx_BF*y_tmp+z_tmp;}}});Proj4js.Point=Proj4js.Class({initialize:function(x,y,z){if(typeof x=='object'){this.x=x[0];this.y=x[1];this.z=x[2]||0.0;}else if(typeof x=='string'){var coords=x.split(',');this.x=parseFloat(coords[0]);this.y=parseFloat(coords[1]);this.z=parseFloat(coords[2])||0.0;}else{this.x=x;this.y=y;this.z=z||0.0;}},clone:function(){return new Proj4js.Point(this.x,this.y,this.z);},toString:function(){return("x="+this.x+",y="+this.y);},toShortString:function(){return(this.x+", "+this.y);}});Proj4js.PrimeMeridian={"greenwich":0.0,"lisbon":-9.131906111111,"paris":2.337229166667,"bogota":-74.
080916666667,"madrid":-3.687938888889,"rome":12.452333333333,"bern":7.439583333333,"jakarta":106.807719444444,"ferro":-17.666666666667,"brussels":4.367975,"stockholm":18.058277777778,"athens":23.7163375,"oslo":10.722916666667};Proj4js.Ellipsoid={"MERIT":{a:6378137.0,rf:298.257,ellipseName:"MERIT 1983"},"SGS85":{a:6378136.0,rf:298.257,ellipseName:"Soviet Geodetic System 85"},"GRS80":{a:6378137.0,rf:298.257222101,ellipseName:"GRS 1980(IUGG, 1980)"},"IAU76":{a:6378140.0,rf:298.257,ellipseName:"IAU 1976"},"airy":{a:6377563.396,b:6356256.910,ellipseName:"Airy 1830"},"APL4.":{a:6378137,rf:298.25,ellipseName:"Appl. Physics. 1965"},"NWL9D":{a:6378145.0,rf:298.25,ellipseName:"Naval Weapons Lab., 1965"},"mod_airy":{a:6377340.189,b:6356034.446,ellipseName:"Modified Airy"},"andrae":{a:6377104.43,rf:300.0,ellipseName:"Andrae 1876 (Den., Iclnd.)"},"aust_SA":{a:6378160.0,rf:298.25,ellipseName:"Australian Natl & S. Amer. 1969"},"GRS67":{a:6378160.0,rf:298.2471674270,ellipseName:"GRS 67(IUGG
1967)"},"bessel":{a:6377397.155,rf:299.1528128,ellipseName:"Bessel 1841"},"bess_nam":{a:6377483.865,rf:299.1528128,ellipseName:"Bessel 1841 (Namibia)"},"clrk66":{a:6378206.4,b:6356583.8,ellipseName:"Clarke 1866"},"clrk80":{a:6378249.145,rf:293.4663,ellipseName:"Clarke 1880 mod."},"CPM":{a:6375738.7,rf:334.29,ellipseName:"Comm. des Poids et Mesures 1799"},"delmbr":{a:6376428.0,rf:311.5,ellipseName:"Delambre 1810 (Belgium)"},"engelis":{a:6378136.05,rf:298.2566,ellipseName:"Engelis 1985"},"evrst30":{a:6377276.345,rf:300.8017,ellipseName:"Everest 1830"},"evrst48":{a:6377304.063,rf:300.8017,ellipseName:"Everest 1948"},"evrst56":{a:6377301.243,rf:300.8017,ellipseName:"Everest 1956"},"evrst69":{a:6377295.664,rf:300.8017,ellipseName:"Everest 1969"},"evrstSS":{a:6377298.556,rf:300.8017,ellipseName:"Everest (Sabah & Sarawak)"},"fschr60":{a:6378166.0,rf:298.3,ellipseName:"Fischer (Mercury Datum) 1960"},"fschr60m":{a:6378155.0,rf:298.3,ellipseName:"Fischer 1960"},"fschr68":{a:6378150.0
,rf:298.3,ellipseName:"Fischer 1968"},"helmert":{a:6378200.0,rf:298.3,ellipseName:"Helmert 1906"},"hough":{a:6378270.0,rf:297.0,ellipseName:"Hough"},"intl":{a:6378388.0,rf:297.0,ellipseName:"International 1909 (Hayford)"},"kaula":{a:6378163.0,rf:298.24,ellipseName:"Kaula 1961"},"lerch":{a:6378139.0,rf:298.257,ellipseName:"Lerch 1979"},"mprts":{a:6397300.0,rf:191.0,ellipseName:"Maupertius 1738"},"new_intl":{a:6378157.5,b:6356772.2,ellipseName:"New International 1967"},"plessis":{a:6376523.0,rf:6355863.0,ellipseName:"Plessis 1817 (France)"},"krass":{a:6378245.0,rf:298.3,ellipseName:"Krassovsky, 1942"},"SEasia":{a:6378155.0,b:6356773.3205,ellipseName:"Southeast Asia"},"walbeck":{a:6376896.0,b:6355834.8467,ellipseName:"Walbeck"},"WGS60":{a:6378165.0,rf:298.3,ellipseName:"WGS 60"},"WGS66":{a:6378145.0,rf:298.25,ellipseName:"WGS 66"},"WGS72":{a:6378135.0,rf:298.26,ellipseName:"WGS 72"},"WGS84":{a:6378137.0,rf:298.257223563,ellipseName:"WGS 84"},"sphere":{a:6370997.0,b:6370997.0,el
lipseName:"Normal Sphere (r=6370997)"}};Proj4js.Datum={"WGS84":{towgs84:"0,0,0",ellipse:"WGS84",datumName:"WGS84"},"GGRS87":{towgs84:"-199.87,74.79,246.62",ellipse:"GRS80",datumName:"Greek_Geodetic_Reference_System_1987"},"NAD83":{towgs84:"0,0,0",ellipse:"GRS80",datumName:"North_American_Datum_1983"},"NAD27":{nadgrids:"@conus, at alaska, at ntv2_0.gsb, at ntv1_can.dat",ellipse:"clrk66",datumName:"North_American_Datum_1927"},"potsdam":{towgs84:"606.0,23.0,413.0",ellipse:"bessel",datumName:"Potsdam Rauenberg 1950 DHDN"},"carthage":{towgs84:"-263.0,6.0,431.0",ellipse:"clark80",datumName:"Carthage 1934 Tunisia"},"hermannskogel":{towgs84:"653.0,-212.0,449.0",ellipse:"bessel",datumName:"Hermannskogel"},"ire65":{towgs84:"482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15",ellipse:"mod_airy",datumName:"Ireland 1965"},"nzgd49":{towgs84:"59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993",ellipse:"intl",datumName:"New Zealand Geodetic Datum 1949"},"OSGB36":{towgs84:"446.448,-125.157,542.060,0.1502,0.2
470,0.8421,-20.4894",ellipse:"airy",datumName:"Airy 1830"}};Proj4js.WGS84=new Proj4js.Proj('WGS84');Proj4js.Datum['OSB36']=Proj4js.Datum['OSGB36'];Proj4js.Proj.aea={init:function(){if(Math.abs(this.lat1+this.lat2)<Proj4js.common.EPSLN){Proj4js.reportError("aeaInitEqualLatitudes");return;}
+{var Dx_BF=this.datum_params[0];var Dy_BF=this.datum_params[1];var Dz_BF=this.datum_params[2];var Rx_BF=this.datum_params[3];var Ry_BF=this.datum_params[4];var Rz_BF=this.datum_params[5];var M_BF=this.datum_params[6];var x_tmp=(p.x-Dx_BF)/M_BF;var y_tmp=(p.y-Dy_BF)/M_BF;var z_tmp=(p.z-Dz_BF)/M_BF;p.x=x_tmp+Rz_BF*y_tmp-Ry_BF*z_tmp;p.y=-Rz_BF*x_tmp+y_tmp+Rx_BF*z_tmp;p.z=Ry_BF*x_tmp-Rx_BF*y_tmp+z_tmp;}}});Proj4js.Point=Proj4js.Class({initialize:function(x,y,z){if(typeof x=='object'){this.x=x[0];this.y=x[1];this.z=x[2]||0.0;}else if(typeof x=='string'){var coords=x.split(',');this.x=parseFloat(coords[0]);this.y=parseFloat(coords[1]);this.z=parseFloat(coords[2])||0.0;}else{this.x=x;this.y=y;this.z=z||0.0;}},clone:function(){return new Proj4js.Point(this.x,this.y,this.z);},toString:function(){return("x="+this.x+",y="+this.y);},toShortString:function(){return(this.x+", "+this.y);}});Proj4js.PrimeMeridian={"greenwich":0.0,"lisbon":-9.131906111111,"paris":2.337229166667,"bogota":-74.
080916666667,"madrid":-3.687938888889,"rome":12.452333333333,"bern":7.439583333333,"jakarta":106.807719444444,"ferro":-17.666666666667,"brussels":4.367975,"stockholm":18.058277777778,"athens":23.7163375,"oslo":10.722916666667};Proj4js.Ellipsoid={"MERIT":{a:6378137.0,rf:298.257,ellipseName:"MERIT 1983"},"SGS85":{a:6378136.0,rf:298.257,ellipseName:"Soviet Geodetic System 85"},"GRS80":{a:6378137.0,rf:298.257222101,ellipseName:"GRS 1980(IUGG, 1980)"},"IAU76":{a:6378140.0,rf:298.257,ellipseName:"IAU 1976"},"airy":{a:6377563.396,b:6356256.910,ellipseName:"Airy 1830"},"APL4.":{a:6378137,rf:298.25,ellipseName:"Appl. Physics. 1965"},"NWL9D":{a:6378145.0,rf:298.25,ellipseName:"Naval Weapons Lab., 1965"},"mod_airy":{a:6377340.189,b:6356034.446,ellipseName:"Modified Airy"},"andrae":{a:6377104.43,rf:300.0,ellipseName:"Andrae 1876 (Den., Iclnd.)"},"aust_SA":{a:6378160.0,rf:298.25,ellipseName:"Australian Natl & S. Amer. 1969"},"GRS67":{a:6378160.0,rf:298.2471674270,ellipseName:"GRS 67(IUGG
1967)"},"bessel":{a:6377397.155,rf:299.1528128,ellipseName:"Bessel 1841"},"bess_nam":{a:6377483.865,rf:299.1528128,ellipseName:"Bessel 1841 (Namibia)"},"clrk66":{a:6378206.4,b:6356583.8,ellipseName:"Clarke 1866"},"clrk80":{a:6378249.145,rf:293.4663,ellipseName:"Clarke 1880 mod."},"CPM":{a:6375738.7,rf:334.29,ellipseName:"Comm. des Poids et Mesures 1799"},"delmbr":{a:6376428.0,rf:311.5,ellipseName:"Delambre 1810 (Belgium)"},"engelis":{a:6378136.05,rf:298.2566,ellipseName:"Engelis 1985"},"evrst30":{a:6377276.345,rf:300.8017,ellipseName:"Everest 1830"},"evrst48":{a:6377304.063,rf:300.8017,ellipseName:"Everest 1948"},"evrst56":{a:6377301.243,rf:300.8017,ellipseName:"Everest 1956"},"evrst69":{a:6377295.664,rf:300.8017,ellipseName:"Everest 1969"},"evrstSS":{a:6377298.556,rf:300.8017,ellipseName:"Everest (Sabah & Sarawak)"},"fschr60":{a:6378166.0,rf:298.3,ellipseName:"Fischer (Mercury Datum) 1960"},"fschr60m":{a:6378155.0,rf:298.3,ellipseName:"Fischer 1960"},"fschr68":{a:6378150.0
,rf:298.3,ellipseName:"Fischer 1968"},"helmert":{a:6378200.0,rf:298.3,ellipseName:"Helmert 1906"},"hough":{a:6378270.0,rf:297.0,ellipseName:"Hough"},"intl":{a:6378388.0,rf:297.0,ellipseName:"International 1909 (Hayford)"},"kaula":{a:6378163.0,rf:298.24,ellipseName:"Kaula 1961"},"lerch":{a:6378139.0,rf:298.257,ellipseName:"Lerch 1979"},"mprts":{a:6397300.0,rf:191.0,ellipseName:"Maupertius 1738"},"new_intl":{a:6378157.5,b:6356772.2,ellipseName:"New International 1967"},"plessis":{a:6376523.0,rf:6355863.0,ellipseName:"Plessis 1817 (France)"},"krass":{a:6378245.0,rf:298.3,ellipseName:"Krassovsky, 1942"},"SEasia":{a:6378155.0,b:6356773.3205,ellipseName:"Southeast Asia"},"walbeck":{a:6376896.0,b:6355834.8467,ellipseName:"Walbeck"},"WGS60":{a:6378165.0,rf:298.3,ellipseName:"WGS 60"},"WGS66":{a:6378145.0,rf:298.25,ellipseName:"WGS 66"},"WGS72":{a:6378135.0,rf:298.26,ellipseName:"WGS 72"},"WGS84":{a:6378137.0,rf:298.257223563,ellipseName:"WGS 84"},"sphere":{a:6370997.0,b:6370997.0,el
lipseName:"Normal Sphere (r=6370997)"}};Proj4js.Datum={"WGS84":{towgs84:"0,0,0",ellipse:"WGS84",datumName:"WGS84"},"GGRS87":{towgs84:"-199.87,74.79,246.62",ellipse:"GRS80",datumName:"Greek_Geodetic_Reference_System_1987"},"NAD83":{towgs84:"0,0,0",ellipse:"GRS80",datumName:"North_American_Datum_1983"},"NAD27":{nadgrids:"@conus, at alaska, at ntv2_0.gsb, at ntv1_can.dat",ellipse:"clrk66",datumName:"North_American_Datum_1927"},"potsdam":{towgs84:"606.0,23.0,413.0",ellipse:"bessel",datumName:"Potsdam Rauenberg 1950 DHDN"},"carthage":{towgs84:"-263.0,6.0,431.0",ellipse:"clark80",datumName:"Carthage 1934 Tunisia"},"hermannskogel":{towgs84:"653.0,-212.0,449.0",ellipse:"bessel",datumName:"Hermannskogel"},"ire65":{towgs84:"482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15",ellipse:"mod_airy",datumName:"Ireland 1965"},"nzgd49":{towgs84:"59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993",ellipse:"intl",datumName:"New Zealand Geodetic Datum 1949"},"OSGB36":{towgs84:"446.448,-125.157,542.060,0.1502,0.2
470,0.8421,-20.4894",ellipse:"airy",datumName:"Airy 1830"}};Proj4js.WGS84=new Proj4js.Proj('WGS84');Proj4js.Datum['OSB36']=Proj4js.Datum['OSGB36'];Proj4js.wktProjections={"Lambert Tangential Conformal Conic Projection":"lcc","Mercator":"merc","Transverse_Mercator":"tmerc","Transverse Mercator":"tmerc","Lambert Azimuthal Equal Area":"laea","Universal Transverse Mercator System":"utm"};Proj4js.Proj.aea={init:function(){if(Math.abs(this.lat1+this.lat2)<Proj4js.common.EPSLN){Proj4js.reportError("aeaInitEqualLatitudes");return;}
this.temp=this.b/this.a;this.es=1.0-Math.pow(this.temp,2);this.e3=Math.sqrt(this.es);this.sin_po=Math.sin(this.lat1);this.cos_po=Math.cos(this.lat1);this.t1=this.sin_po;this.con=this.sin_po;this.ms1=Proj4js.common.msfnz(this.e3,this.sin_po,this.cos_po);this.qs1=Proj4js.common.qsfnz(this.e3,this.sin_po,this.cos_po);this.sin_po=Math.sin(this.lat2);this.cos_po=Math.cos(this.lat2);this.t2=this.sin_po;this.ms2=Proj4js.common.msfnz(this.e3,this.sin_po,this.cos_po);this.qs2=Proj4js.common.qsfnz(this.e3,this.sin_po,this.cos_po);this.sin_po=Math.sin(this.lat0);this.cos_po=Math.cos(this.lat0);this.t3=this.sin_po;this.qs0=Proj4js.common.qsfnz(this.e3,this.sin_po,this.cos_po);if(Math.abs(this.lat1-this.lat2)>Proj4js.common.EPSLN){this.ns0=(this.ms1*this.ms1-this.ms2*this.ms2)/(this.qs2-this.qs1);}else{this.ns0=this.con;}
this.c=this.ms1*this.ms1+this.ns0*this.qs1;this.rh=this.a*Math.sqrt(this.c-this.ns0*this.qs0)/this.ns0;},forward:function(p){var lon=p.x;var lat=p.y;this.sin_phi=Math.sin(lat);this.cos_phi=Math.cos(lat);var qs=Proj4js.common.qsfnz(this.e3,this.sin_phi,this.cos_phi);var rh1=this.a*Math.sqrt(this.c-this.ns0*qs)/this.ns0;var theta=this.ns0*Proj4js.common.adjust_lon(lon-this.long0);var x=rh1*Math.sin(theta)+this.x0;var y=this.rh-rh1*Math.cos(theta)+this.y0;p.x=x;p.y=y;return p;},inverse:function(p){var rh1,qs,con,theta,lon,lat;p.x-=this.x0;p.y=this.rh-p.y+this.y0;if(this.ns0>=0){rh1=Math.sqrt(p.x*p.x+p.y*p.y);con=1.0;}else{rh1=-Math.sqrt(p.x*p.x+p.y*p.y);con=-1.0;}
theta=0.0;if(rh1!=0.0){theta=Math.atan2(con*p.x,con*p.y);}
@@ -109,7 +118,7 @@
this.lat0=0.0;this.long0=((6*Math.abs(this.zone))-183)*Proj4js.common.D2R;this.x0=500000.0;this.y0=this.utmSouth?10000000.0:0.0;this.k0=0.9996;Proj4js.Proj['tmerc'].init.apply(this);this.forward=Proj4js.Proj['tmerc'].forward;this.inverse=Proj4js.Proj['tmerc'].inverse;}};Proj4js.Proj.eqdc={init:function(){if(!this.mode)this.mode=0;this.temp=this.b/this.a;this.es=1.0-Math.pow(this.temp,2);this.e=Math.sqrt(this.es);this.e0=Proj4js.common.e0fn(this.es);this.e1=Proj4js.common.e1fn(this.es);this.e2=Proj4js.common.e2fn(this.es);this.e3=Proj4js.common.e3fn(this.es);this.sinphi=Math.sin(this.lat1);this.cosphi=Math.cos(this.lat1);this.ms1=Proj4js.common.msfnz(this.e,this.sinphi,this.cosphi);this.ml1=Proj4js.common.mlfn(this.e0,this.e1,this.e2,this.e3,this.lat1);if(this.mode!=0){if(Math.abs(this.lat1+this.lat2)<Proj4js.common.EPSLN){Proj4js.reportError("eqdc:Init:EqualLatitudes");}
this.sinphi=Math.sin(this.lat2);this.cosphi=Math.cos(this.lat2);this.ms2=Proj4js.common.msfnz(this.e,this.sinphi,this.cosphi);this.ml2=Proj4js.common.mlfn(this.e0,this.e1,this.e2,this.e3,this.lat2);if(Math.abs(this.lat1-this.lat2)>=Proj4js.common.EPSLN){this.ns=(this.ms1-this.ms2)/(this.ml2-this.ml1);}else{this.ns=this.sinphi;}}else{this.ns=this.sinphi;}
this.g=this.ml1+this.ms1/this.ns;this.ml0=Proj4js.common.mlfn(this.e0,this.e1,this.e2,this.e3,this.lat0);this.rh=this.a*(this.g-this.ml0);},forward:function(p){var lon=p.x;var lat=p.y;var ml=Proj4js.common.mlfn(this.e0,this.e1,this.e2,this.e3,lat);var rh1=this.a*(this.g-ml);var theta=this.ns*Proj4js.common.adjust_lon(lon-this.long0);var x=this.x0+rh1*Math.sin(theta);var y=this.y0+this.rh-rh1*Math.cos(theta);p.x=x;p.y=y;return p;},inverse:function(p){p.x-=this.x0;p.y=this.rh-p.y+this.y0;var con,rh1;if(this.ns>=0){var rh1=Math.sqrt(p.x*p.x+p.y*p.y);var con=1.0;}else{rh1=-Math.sqrt(p.x*p.x+p.y*p.y);con=-1.0;}
-var theta=0.0;if(rh1!=0.0)theta=Math.atan2(con*p.x,con*p.y);var ml=this.g-rh1/this.a;var lat=this.phi3z(this.ml,this.e0,this.e1,this.e2,this.e3);var lon=Proj4js.common.adjust_lon(this.long0+theta/this.ns);p.x=lon;p.y=lat;return p;},phi3z:function(ml,e0,e1,e2,e3){var phi;var dphi;phi=ml;for(var i=0;i<15;i++){dphi=(ml+e1*Math.sin(2.0*phi)-e2*Math.sin(4.0*phi)+e3*Math.sin(6.0*phi))/e0-phi;phi+=dphi;if(Math.abs(dphi)<=.0000000001){return phi;}}
+var theta=0.0;if(rh1!=0.0)theta=Math.atan2(con*p.x,con*p.y);var ml=this.g-rh1/this.a;var lat=this.phi3z(ml,this.e0,this.e1,this.e2,this.e3);var lon=Proj4js.common.adjust_lon(this.long0+theta/this.ns);p.x=lon;p.y=lat;return p;},phi3z:function(ml,e0,e1,e2,e3){var phi;var dphi;phi=ml;for(var i=0;i<15;i++){dphi=(ml+e1*Math.sin(2.0*phi)-e2*Math.sin(4.0*phi)+e3*Math.sin(6.0*phi))/e0-phi;phi+=dphi;if(Math.abs(dphi)<=.0000000001){return phi;}}
Proj4js.reportError("PHI3Z-CONV:Latitude failed to converge after 15 iterations");return null;}};Proj4js.Proj.tmerc={init:function(){this.e0=Proj4js.common.e0fn(this.es);this.e1=Proj4js.common.e1fn(this.es);this.e2=Proj4js.common.e2fn(this.es);this.e3=Proj4js.common.e3fn(this.es);this.ml0=this.a*Proj4js.common.mlfn(this.e0,this.e1,this.e2,this.e3,this.lat0);},forward:function(p){var lon=p.x;var lat=p.y;var delta_lon=Proj4js.common.adjust_lon(lon-this.long0);var con;var x,y;var sin_phi=Math.sin(lat);var cos_phi=Math.cos(lat);if(this.sphere){var b=cos_phi*Math.sin(delta_lon);if((Math.abs(Math.abs(b)-1.0))<.0000000001){Proj4js.reportError("tmerc:forward: Point projects into infinity");return(93);}else{x=.5*this.a*this.k0*Math.log((1.0+b)/(1.0-b));con=Math.acos(cos_phi*Math.cos(delta_lon)/Math.sqrt(1.0-b*b));if(lat<0)con=-con;y=this.a*this.k0*(con-this.lat0);}}else{var al=cos_phi*delta_lon;var als=Math.pow(al,2);var c=this.ep2*Math.pow(cos_phi,2);var tq=Math.tan(lat);var t=Math.
pow(tq,2);con=1.0-this.es*Math.pow(sin_phi,2);var n=this.a/Math.sqrt(con);var ml=this.a*Proj4js.common.mlfn(this.e0,this.e1,this.e2,this.e3,lat);x=this.k0*n*al*(1.0+als/6.0*(1.0-t+c+als/20.0*(5.0-18.0*t+Math.pow(t,2)+72.0*c-58.0*this.ep2)))+this.x0;y=this.k0*(ml-this.ml0+n*tq*(als*(0.5+als/24.0*(5.0-t+9.0*c+4.0*Math.pow(c,2)+als/30.0*(61.0-58.0*t+Math.pow(t,2)+600.0*c-330.0*this.ep2)))))+this.y0;}
p.x=x;p.y=y;return p;},inverse:function(p){var con,phi;var delta_phi;var i;var max_iter=6;var lat,lon;if(this.sphere){var f=Math.exp(p.x/(this.a*this.k0));var g=.5*(f-1/f);var temp=this.lat0+p.y/(this.a*this.k0);var h=Math.cos(temp);con=Math.sqrt((1.0-h*h)/(1.0+g*g));lat=Proj4js.common.asinz(con);if(temp<0)
lat=-lat;if((g==0)&&(h==0)){lon=this.long0;}else{lon=Proj4js.common.adjust_lon(Math.atan2(g,h)+this.long0);}}else{var x=p.x-this.x0;var y=p.y-this.y0;con=(this.ml0+y/this.k0)/this.a;phi=con;for(i=0;true;i++){delta_phi=((con+this.e1*Math.sin(2.0*phi)-this.e2*Math.sin(4.0*phi)+this.e3*Math.sin(6.0*phi))/this.e0)-phi;phi+=delta_phi;if(Math.abs(delta_phi)<=Proj4js.common.EPSLN)break;if(i>=max_iter){Proj4js.reportError("tmerc:inverse: Latitude failed to converge");return(95);}}
@@ -117,9 +126,8 @@
p.x=lon;p.y=lat;return p;}};Proj4js.defs["GOOGLE"]="+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs";Proj4js.defs["EPSG:900913"]=Proj4js.defs["GOOGLE"];Proj4js.Proj.gstmerc={init:function(){var temp=this.b/this.a;this.e=Math.sqrt(1.0-temp*temp);this.lc=this.long0;this.rs=Math.sqrt(1.0+this.e*this.e*Math.pow(Math.cos(this.lat0),4.0)/(1.0-this.e*this.e));var sinz=Math.sin(this.lat0);var pc=Math.asin(sinz/this.rs);var sinzpc=Math.sin(pc);this.cp=Proj4js.common.latiso(0.0,pc,sinzpc)-this.rs*Proj4js.common.latiso(this.e,this.lat0,sinz);this.n2=this.k0*this.a*Math.sqrt(1.0-this.e*this.e)/(1.0-this.e*this.e*sinz*sinz);this.xs=this.x0;this.ys=this.y0-this.n2*pc;if(!this.title)this.title="Gauss Schreiber transverse mercator";},forward:function(p){var lon=p.x;var lat=p.y;var L=this.rs*(lon-this.lc);var Ls=this.cp+(this.rs*Proj4js.common.latiso(this.e,lat,Math.sin(lat)));var lat1=Math.asin(Math.sin(L)/Proj4js.common.cosh(
Ls));var Ls1=Proj4js.common.latiso(0.0,lat1,Math.sin(lat1));p.x=this.xs+(this.n2*Ls1);p.y=this.ys+(this.n2*Math.atan(Proj4js.common.sinh(Ls)/Math.cos(L)));return p;},inverse:function(p){var x=p.x;var y=p.y;var L=Math.atan(Proj4js.common.sinh((x-this.xs)/this.n2)/Math.cos((y-this.ys)/this.n2));var lat1=Math.asin(Math.sin((y-this.ys)/this.n2)/Proj4js.common.cosh((x-this.xs)/this.n2));var LC=Proj4js.common.latiso(0.0,lat1,Math.sin(lat1));p.x=this.lc+L/this.rs;p.y=Proj4js.common.invlatiso(this.e,(LC-this.cp)/this.rs);return p;}};Proj4js.Proj.ortho={init:function(def){;this.sin_p14=Math.sin(this.lat0);this.cos_p14=Math.cos(this.lat0);},forward:function(p){var sinphi,cosphi;var dlon;var coslon;var ksp;var g;var lon=p.x;var lat=p.y;dlon=Proj4js.common.adjust_lon(lon-this.long0);sinphi=Math.sin(lat);cosphi=Math.cos(lat);coslon=Math.cos(dlon);g=this.sin_p14*sinphi+this.cos_p14*cosphi*coslon;ksp=1.0;if((g>0)||(Math.abs(g)<=Proj4js.common.EPSLN)){var x=this.a*ksp*cosphi*Math.sin(dlon);
var y=this.y0+this.a*ksp*(this.cos_p14*sinphi-this.sin_p14*cosphi*coslon);}else{Proj4js.reportError("orthoFwdPointError");}
p.x=x;p.y=y;return p;},inverse:function(p){var rh;var z;var sinz,cosz;var temp;var con;var lon,lat;p.x-=this.x0;p.y-=this.y0;rh=Math.sqrt(p.x*p.x+p.y*p.y);if(rh>this.a+.0000001){Proj4js.reportError("orthoInvDataError");}
z=Proj4js.common.asinz(rh/this.a);sinz=Math.sin(z);cosz=Math.cos(z);lon=this.long0;if(Math.abs(rh)<=Proj4js.common.EPSLN){lat=this.lat0;}
-lat=Proj4js.common.asinz(cosz*this.sin_p14+(p.y*sinz*this.cos_p14)/rh);con=Math.abs(lat0)-Proj4js.common.HALF_PI;if(Math.abs(con)<=Proj4js.common.EPSLN){if(this.lat0>=0){lon=Proj4js.common.adjust_lon(this.long0+Math.atan2(p.x,-p.y));}else{lon=Proj4js.common.adjust_lon(this.long0-Math.atan2(-p.x,p.y));}}
-con=cosz-this.sin_p14*Math.sin(lat);if((Math.abs(con)>=Proj4js.common.EPSLN)||(Math.abs(x)>=Proj4js.common.EPSLN)){lon=Proj4js.common.adjust_lon(this.long0+Math.atan2((p.x*sinz*this.cos_p14),(con*rh)));}
-p.x=lon;p.y=lat;return p;}};Proj4js.Proj.somerc={init:function(){var phy0=this.lat0;this.lambda0=this.long0;var sinPhy0=Math.sin(phy0);var semiMajorAxis=this.a;var invF=this.rf;var flattening=1/invF;var e2=2*flattening-Math.pow(flattening,2);var e=this.e=Math.sqrt(e2);this.R=semiMajorAxis*Math.sqrt(1-e2)/(1-e2*Math.pow(sinPhy0,2.0));this.alpha=Math.sqrt(1+e2/(1-e2)*Math.pow(Math.cos(phy0),4.0));this.b0=Math.asin(sinPhy0/this.alpha);this.K=Math.log(Math.tan(Math.PI/4.0+this.b0/2.0))
+lat=Proj4js.common.asinz(cosz*this.sin_p14+(p.y*sinz*this.cos_p14)/rh);con=Math.abs(this.lat0)-Proj4js.common.HALF_PI;if(Math.abs(con)<=Proj4js.common.EPSLN){if(this.lat0>=0){lon=Proj4js.common.adjust_lon(this.long0+Math.atan2(p.x,-p.y));}else{lon=Proj4js.common.adjust_lon(this.long0-Math.atan2(-p.x,p.y));}}
+con=cosz-this.sin_p14*Math.sin(lat);p.x=lon;p.y=lat;return p;}};Proj4js.Proj.somerc={init:function(){var phy0=this.lat0;this.lambda0=this.long0;var sinPhy0=Math.sin(phy0);var semiMajorAxis=this.a;var invF=this.rf;var flattening=1/invF;var e2=2*flattening-Math.pow(flattening,2);var e=this.e=Math.sqrt(e2);this.R=this.k0*semiMajorAxis*Math.sqrt(1-e2)/(1-e2*Math.pow(sinPhy0,2.0));this.alpha=Math.sqrt(1+e2/(1-e2)*Math.pow(Math.cos(phy0),4.0));this.b0=Math.asin(sinPhy0/this.alpha);this.K=Math.log(Math.tan(Math.PI/4.0+this.b0/2.0))
-this.alpha*Math.log(Math.tan(Math.PI/4.0+phy0/2.0))
+this.alpha*e/2*Math.log((1+e*sinPhy0)/(1-e*sinPhy0));},forward:function(p){var Sa1=Math.log(Math.tan(Math.PI/4.0-p.y/2.0));var Sa2=this.e/2.0*Math.log((1+this.e*Math.sin(p.y))/(1-this.e*Math.sin(p.y)));var S=-this.alpha*(Sa1+Sa2)+this.K;var b=2.0*(Math.atan(Math.exp(S))-Math.PI/4.0);var I=this.alpha*(p.x-this.lambda0);var rotI=Math.atan(Math.sin(I)/(Math.sin(this.b0)*Math.tan(b)+
Math.cos(this.b0)*Math.cos(I)));var rotB=Math.asin(Math.cos(this.b0)*Math.sin(b)-
@@ -152,7 +160,7 @@
th_n_re=1;th_n_im=0;var den_re=this.B_re[1];var den_im=this.B_im[1];for(n=2;n<=6;n++){th_n_re1=th_n_re*th_re-th_n_im*th_im;th_n_im1=th_n_im*th_re+th_n_re*th_im;th_n_re=th_n_re1;th_n_im=th_n_im1;den_re=den_re+n*(this.B_re[n]*th_n_re-this.B_im[n]*th_n_im);den_im=den_im+n*(this.B_im[n]*th_n_re+this.B_re[n]*th_n_im);}
var den2=den_re*den_re+den_im*den_im;th_re=(num_re*den_re+num_im*den_im)/den2;th_im=(num_im*den_re-num_re*den_im)/den2;}
var d_psi=th_re;var d_lambda=th_im;var d_psi_n=1;var d_phi=0;for(n=1;n<=9;n++){d_psi_n=d_psi_n*d_psi;d_phi=d_phi+this.D[n]*d_psi_n;}
-var lat=this.lat0+(d_phi*Proj4js.common.SEC_TO_RAD*1E5);var lon=this.long0+d_lambda;p.x=lon;p.y=lat;return p;}};Proj4js.Proj.mill={init:function(){},forward:function(p){var lon=p.x;var lat=p.y;var dlon=Proj4js.common.adjust_lon(lon-this.long0);var x=this.x0+this.a*dlon;var y=this.y0+this.a*Math.log(Math.tan((Proj4js.common.PI/4.0)+(lat/2.5)))*1.25;p.x=x;p.y=y;return p;},inverse:function(p){p.x-=this.x0;p.y-=this.y0;var lon=Proj4js.common.adjust_lon(this.long0+p.x/this.a);var lat=2.5*(Math.atan(Math.exp(0.8*p.y/this.a))-Proj4js.common.PI/4.0);p.x=lon;p.y=lat;return p;}};Proj4js.Proj.gnom={init:function(def){this.sin_p14=Math.sin(this.lat0);this.cos_p14=Math.cos(this.lat0);this.infinity_dist=1000*this.a;},forward:function(p){var sinphi,cosphi;var dlon;var coslon;var ksp;var g;var lon=p.x;var lat=p.y;dlon=Proj4js.common.adjust_lon(lon-this.long0);sinphi=Math.sin(lat);cosphi=Math.cos(lat);coslon=Math.cos(dlon);g=this.sin_p14*sinphi+this.cos_p14*cosphi*coslon;ksp=1.0;if((g>0)||(M
ath.abs(g)<=Proj4js.common.EPSLN)){x=this.x0+this.a*ksp*cosphi*Math.sin(dlon)/g;y=this.y0+this.a*ksp*(this.cos_p14*sinphi-this.sin_p14*cosphi*coslon)/g;}else{Proj4js.reportError("orthoFwdPointError");x=this.x0+this.infinity_dist*cosphi*Math.sin(dlon);y=this.y0+this.infinity_dist*(this.cos_p14*sinphi-this.sin_p14*cosphi*coslon);}
+var lat=this.lat0+(d_phi*Proj4js.common.SEC_TO_RAD*1E5);var lon=this.long0+d_lambda;p.x=lon;p.y=lat;return p;}};Proj4js.Proj.mill={init:function(){},forward:function(p){var lon=p.x;var lat=p.y;var dlon=Proj4js.common.adjust_lon(lon-this.long0);var x=this.x0+this.a*dlon;var y=this.y0+this.a*Math.log(Math.tan((Proj4js.common.PI/4.0)+(lat/2.5)))*1.25;p.x=x;p.y=y;return p;},inverse:function(p){p.x-=this.x0;p.y-=this.y0;var lon=Proj4js.common.adjust_lon(this.long0+p.x/this.a);var lat=2.5*(Math.atan(Math.exp(0.8*p.y/this.a))-Proj4js.common.PI/4.0);p.x=lon;p.y=lat;return p;}};Proj4js.Proj.gnom={init:function(def){this.sin_p14=Math.sin(this.lat0);this.cos_p14=Math.cos(this.lat0);this.infinity_dist=1000*this.a;this.rc=1;},forward:function(p){var sinphi,cosphi;var dlon;var coslon;var ksp;var g;var lon=p.x;var lat=p.y;dlon=Proj4js.common.adjust_lon(lon-this.long0);sinphi=Math.sin(lat);cosphi=Math.cos(lat);coslon=Math.cos(dlon);g=this.sin_p14*sinphi+this.cos_p14*cosphi*coslon;ksp=1.0;if
((g>0)||(Math.abs(g)<=Proj4js.common.EPSLN)){x=this.x0+this.a*ksp*cosphi*Math.sin(dlon)/g;y=this.y0+this.a*ksp*(this.cos_p14*sinphi-this.sin_p14*cosphi*coslon)/g;}else{Proj4js.reportError("orthoFwdPointError");x=this.x0+this.infinity_dist*cosphi*Math.sin(dlon);y=this.y0+this.infinity_dist*(this.cos_p14*sinphi-this.sin_p14*cosphi*coslon);}
p.x=x;p.y=y;return p;},inverse:function(p){var rh;var z;var sinc,cosc;var c;var lon,lat;p.x=(p.x-this.x0)/this.a;p.y=(p.y-this.y0)/this.a;p.x/=this.k0;p.y/=this.k0;if((rh=Math.sqrt(p.x*p.x+p.y*p.y))){c=Math.atan2(rh,this.rc);sinc=Math.sin(c);cosc=Math.cos(c);lat=Proj4js.common.asinz(cosc*this.sin_p14+(p.y*sinc*this.cos_p14)/rh);lon=Math.atan2(p.x*sinc,rh*this.cos_p14*cosc-p.y*this.sin_p14*sinc);lon=Proj4js.common.adjust_lon(this.long0+lon);}else{lat=this.phic0;lon=0.0;}
p.x=lon;p.y=lat;return p;}};Proj4js.Proj.sinu={init:function(){this.R=6370997.0;},forward:function(p){var x,y,delta_lon;var lon=p.x;var lat=p.y;delta_lon=Proj4js.common.adjust_lon(lon-this.long0);x=this.R*delta_lon*Math.cos(lat)+this.x0;y=this.R*lat+this.y0;p.x=x;p.y=y;return p;},inverse:function(p){var lat,temp,lon;p.x-=this.x0;p.y-=this.y0;lat=p.y/this.R;if(Math.abs(lat)>Proj4js.common.HALF_PI){Proj4js.reportError("sinu:Inv:DataError");}
temp=Math.abs(lat)-Proj4js.common.HALF_PI;if(Math.abs(temp)>Proj4js.common.EPSLN){temp=this.long0+p.x/(this.R*Math.cos(lat));lon=Proj4js.common.adjust_lon(temp);}else{lon=this.long0;}
@@ -161,7 +169,7 @@
var al=.5*Math.abs((Proj4js.common.PI/dlon)-(dlon/Proj4js.common.PI));var asq=al*al;var sinth=Math.sin(theta);var costh=Math.cos(theta);var g=costh/(sinth+costh-1.0);var gsq=g*g;var m=g*(2.0/sinth-1.0);var msq=m*m;var con=Proj4js.common.PI*this.R*(al*(g-msq)+Math.sqrt(asq*(g-msq)*(g-msq)-(msq+asq)*(gsq-msq)))/(msq+asq);if(dlon<0){con=-con;}
x=this.x0+con;con=Math.abs(con/(Proj4js.common.PI*this.R));if(lat>=0){y=this.y0+Proj4js.common.PI*this.R*Math.sqrt(1.0-con*con-2.0*al*con);}else{y=this.y0-Proj4js.common.PI*this.R*Math.sqrt(1.0-con*con-2.0*al*con);}
p.x=x;p.y=y;return p;},inverse:function(p){var dlon;var xx,yy,xys,c1,c2,c3;var al,asq;var a1;var m1;var con;var th1;var d;p.x-=this.x0;p.y-=this.y0;con=Proj4js.common.PI*this.R;xx=p.x/con;yy=p.y/con;xys=xx*xx+yy*yy;c1=-Math.abs(yy)*(1.0+xys);c2=c1-2.0*yy*yy+xx*xx;c3=-2.0*c1+1.0+2.0*yy*yy+xys*xys;d=yy*yy/c3+(2.0*c2*c2*c2/c3/c3/c3-9.0*c1*c2/c3/c3)/27.0;a1=(c1-c2*c2/3.0/c3)/c3;m1=2.0*Math.sqrt(-a1/3.0);con=((3.0*d)/a1)/m1;if(Math.abs(con)>1.0){if(con>=0.0){con=1.0;}else{con=-1.0;}}
-th1=Math.acos(con)/3.0;if(p.y>=0){lat=(-m1*Math.cos(th1+Proj4js.common.PI/3.0)-c2/3.0/c3)*Proj4js.common.PI;}else{lat=-(-m1*Math.cos(th1+PI/3.0)-c2/3.0/c3)*Proj4js.common.PI;}
+th1=Math.acos(con)/3.0;if(p.y>=0){lat=(-m1*Math.cos(th1+Proj4js.common.PI/3.0)-c2/3.0/c3)*Proj4js.common.PI;}else{lat=-(-m1*Math.cos(th1+Proj4js.common.PI/3.0)-c2/3.0/c3)*Proj4js.common.PI;}
if(Math.abs(xx)<Proj4js.common.EPSLN){lon=this.long0;}
lon=Proj4js.common.adjust_lon(this.long0+Proj4js.common.PI*(xys-1.0+Math.sqrt(1.0+2.0*(xx*xx-yy*yy)+xys*xys))/2.0/xx);p.x=lon;p.y=lat;return p;}};Proj4js.Proj.cea={init:function(){},forward:function(p){var lon=p.x;var lat=p.y;dlon=Proj4js.common.adjust_lon(lon-this.long0);var x=this.x0+this.a*dlon*Math.cos(this.lat_ts);var y=this.y0+this.a*Math.sin(lat)/Math.cos(this.lat_ts);p.x=x;p.y=y;return p;},inverse:function(p){p.x-=this.x0;p.y-=this.y0;var lon=Proj4js.common.adjust_lon(this.long0+(p.x/this.a)/Math.cos(this.lat_ts));var lat=Math.asin((p.y/this.a)*Math.cos(this.lat_ts));p.x=lon;p.y=lat;return p;}};Proj4js.Proj.eqc={init:function(){if(!this.x0)this.x0=0;if(!this.y0)this.y0=0;if(!this.lat0)this.lat0=0;if(!this.long0)this.long0=0;if(!this.lat_ts)this.lat_ts=0;if(!this.title)this.title="Equidistant Cylindrical (Plate Carre)";this.rc=Math.cos(this.lat_ts);},forward:function(p){var lon=p.x;var lat=p.y;var dlon=Proj4js.common.adjust_lon(lon-this.long0);var dlat=Proj4js.common.
adjust_lat(lat-this.lat0);p.x=this.x0+(this.a*dlon*this.rc);p.y=this.y0+(this.a*dlat);return p;},inverse:function(p){var x=p.x;var y=p.y;p.x=Proj4js.common.adjust_lon(this.long0+((x-this.x0)/(this.a*this.rc)));p.y=Proj4js.common.adjust_lat(this.lat0+((y-this.y0)/(this.a)));return p;}};Proj4js.Proj.cass={init:function(){if(!this.sphere){this.en=this.pj_enfn(this.es)
this.m0=this.pj_mlfn(this.lat0,Math.sin(this.lat0),Math.cos(this.lat0),this.en);}},C1:.16666666666666666666,C2:.00833333333333333333,C3:.04166666666666666666,C4:.33333333333333333333,C5:.06666666666666666666,forward:function(p){var x,y;var lam=p.x;var phi=p.y;lam=Proj4js.common.adjust_lon(lam-this.long0);if(this.sphere){x=Math.asin(Math.cos(phi)*Math.sin(lam));y=Math.atan2(Math.tan(phi),Math.cos(lam))-this.phi0;}else{this.n=Math.sin(phi);this.c=Math.cos(phi);y=this.pj_mlfn(phi,this.n,this.c,this.en);this.n=1./Math.sqrt(1.-this.es*this.n*this.n);this.tn=Math.tan(phi);this.t=this.tn*this.tn;this.a1=lam*this.c;this.c*=this.es*this.c/(1-this.es);this.a2=this.a1*this.a1;x=this.n*this.a1*(1.-this.a2*this.t*(this.C1-(8.-this.t+8.*this.c)*this.a2*this.C2));y-=this.m0-this.n*this.tn*this.a2*(.5+(5.-this.t+6.*this.c)*this.a2*this.C3);}
@@ -187,7 +195,7 @@
this.f0=ms1/(this.ns*Math.pow(ts1,this.ns));this.rh=this.a*this.f0*Math.pow(ts0,this.ns);if(!this.title)this.title="Lambert Conformal Conic";},forward:function(p){var lon=p.x;var lat=p.y;if(lat<=90.0&&lat>=-90.0&&lon<=180.0&&lon>=-180.0){}else{Proj4js.reportError("lcc:forward: llInputOutOfRange: "+lon+" : "+lat);return null;}
var con=Math.abs(Math.abs(lat)-Proj4js.common.HALF_PI);var ts,rh1;if(con>Proj4js.common.EPSLN){ts=Proj4js.common.tsfnz(this.e,lat,Math.sin(lat));rh1=this.a*this.f0*Math.pow(ts,this.ns);}else{con=lat*this.ns;if(con<=0){Proj4js.reportError("lcc:forward: No Projection");return null;}
rh1=0;}
-var theta=this.ns*Proj4js.common.adjust_lon(lon-this.long0);p.x=this.k0*(rh1*Math.sin(theta))+this.x0;p.y=this.k0*(this.rh-rh1*Math.cos(theta))+this.y0;return p;},inverse:function(p){var rh1,con,ts;var lat,lon;x=(p.x-this.x0)/this.k0;y=(this.rh-(p.y-this.y0)/this.k0);if(this.ns>0){rh1=Math.sqrt(x*x+y*y);con=1.0;}else{rh1=-Math.sqrt(x*x+y*y);con=-1.0;}
+var theta=this.ns*Proj4js.common.adjust_lon(lon-this.long0);p.x=this.k0*(rh1*Math.sin(theta))+this.x0;p.y=this.k0*(this.rh-rh1*Math.cos(theta))+this.y0;return p;},inverse:function(p){var rh1,con,ts;var lat,lon;var x=(p.x-this.x0)/this.k0;var y=(this.rh-(p.y-this.y0)/this.k0);if(this.ns>0){rh1=Math.sqrt(x*x+y*y);con=1.0;}else{rh1=-Math.sqrt(x*x+y*y);con=-1.0;}
var theta=0.0;if(rh1!=0){theta=Math.atan2((con*x),(con*y));}
if((rh1!=0)||(this.ns>0.0)){con=1.0/this.ns;ts=Math.pow((rh1/(this.a*this.f0)),con);lat=Proj4js.common.phi2z(this.e,ts);if(lat==-9999)return null;}else{lat=-Proj4js.common.HALF_PI;}
lon=Proj4js.common.adjust_lon(theta/this.ns+this.long0);p.x=lon;p.y=lat;return p;}};Proj4js.Proj.laea={S_POLE:1,N_POLE:2,EQUIT:3,OBLIQ:4,init:function(){var t=Math.abs(this.lat0);if(Math.abs(t-Proj4js.common.HALF_PI)<Proj4js.common.EPSLN){this.mode=this.lat0<0.?this.S_POLE:this.N_POLE;}else if(Math.abs(t)<Proj4js.common.EPSLN){this.mode=this.EQUIT;}else{this.mode=this.OBLIQ;}
Modified: branches/fusion-2.2/templates/mapserver/standard/ApplicationDefinition.xml
===================================================================
--- branches/fusion-2.2/templates/mapserver/standard/ApplicationDefinition.xml 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/templates/mapserver/standard/ApplicationDefinition.xml 2010-09-24 18:32:16 UTC (rev 2234)
@@ -14,7 +14,7 @@
<Type>MapServer</Type>
<SingleTile>true</SingleTile>
<Extension>
- <MapFile>/ms4w/apps/gmap/htdocs/gmap_groups.map</MapFile>
+ <MapFile>/ms4w/Apache/htdocs/gmap/htdocs/gmap_groups.map</MapFile>
</Extension>
</Map>
</MapGroup>
@@ -23,7 +23,7 @@
<Type>MapServer</Type>
<SingleTile>true</SingleTile>
<Extension>
- <MapFile>/ms4w/apps/gmap/htdocs/gmap75.map</MapFile>
+ <MapFile>/ms4w/Apache/htdocs/gmap/htdocs/gmap75.map</MapFile>
<!--ProjectionCode>EPSG:42304</ProjectionCode-->
<ProjectionDef>+title=LCC +proj=lcc +lat_1=49 +lat_2=77 +lat_0=49 +lon_0=-95 +x_0=0 +y_0=0 +ellps=GRS80 +datum=NAD83 +units=m +no_defs</ProjectionDef>
</Extension>
@@ -34,7 +34,7 @@
<Type>MapServer</Type>
<SingleTile>true</SingleTile>
<Extension>
- <MapFile>/ms4w/apps/gmap/htdocs/gmapLonLat2.map</MapFile>
+ <MapFile>/ms4w/Apache/htdocs/gmap/htdocs/gmapLonLat2.map</MapFile>
</Extension>
</Map>
</MapGroup>
@@ -60,7 +60,7 @@
<Type>MapServer</Type>
<SingleTile>true</SingleTile>
<Extension>
- <MapFile>/ms4w/apps/gmap/htdocs/gmapLonLat.map</MapFile>
+ <MapFile>/ms4w/Apache/htdocs/gmap/htdocs/gmapLonLat.map</MapFile>
<Options>
<isBaseLayer>false</isBaseLayer>
<singleTile>true</singleTile>
@@ -106,7 +106,7 @@
<Type>MapServer</Type>
<SingleTile>true</SingleTile>
<Extension>
- <MapFile>/ms4w/apps/gmap/htdocs/gmap75_key.map</MapFile>
+ <MapFile>/ms4w/Apache/htdocs/gmap/htdocs/gmap75_key.map</MapFile>
</Extension>
</Map>
</MapGroup>
Modified: branches/fusion-2.2/text/en
===================================================================
--- branches/fusion-2.2/text/en 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/text/en 2010-09-24 18:32:16 UTC (rev 2234)
@@ -332,3 +332,18 @@
# Localized Icon Files
POWEREDBYICON = PoweredBy_en.gif
+
+# Quick Plot UI
+QUICKPLOT_HEADER = Quick Plot
+QUICKPLOT_TITLE = Title
+QUICKPLOT_SUBTITLE = Sub title
+QUICKPLOT_PAPER_SIZE = Paper size
+QUICKPLOT_SCALING = Scaling
+QUICKPLOT_DPI = Print DPI
+QUICKPLOT_GENERATE = Generate
+QUICKPLOT_ADVANCED_OPTIONS = Advanced options
+QUICKPLOT_PRINT = Print
+QUICKPLOT_CANCEL = Cancel
+QUICKPLOT_PREVIEW_ERROR = The application resources required to generate the plot exceed the settings defined by the administrator
+QUICKPLOT_RESOLUTION_WARNING = The current settings exceed the map resolution. Zooming out or increasing the scaling will help create a more legible plot
+QUICKPLOT_SCALE_LABEL = Scale
Modified: branches/fusion-2.2/text/en.json
===================================================================
--- branches/fusion-2.2/text/en.json 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/text/en.json 2010-09-24 18:32:16 UTC (rev 2234)
@@ -59,5 +59,20 @@
'printShowLegend':'Show Legend?',
'printShowNorthArrow':'Show North Arrow?',
+'quickPlotResolutionWarning':'The current settings exceed the map resolution. Zooming out or increasing the scaling will help create a more legible plot',
+'noCommercialMapLayers':'NONE',
+'googleStreet':'Google Street',
+'googleSatellite':'Google Satellite',
+'googleTerrain':'Google Terrain',
+'googleHybrid':'Google Hybrid',
+'yahooStreet':'Yahoo Street',
+'yahooSatellite':'Yahoo Satellite',
+'yahooHybrid':'Yahoo Hybrid',
+'bingStreet':'Bing Street',
+'bingSatellite':'Bing Satellite',
+'bingHybrid':'Bing Hybrid',
+'openStreetMap':'Open Street Map',
+'openStreetMapOsmarender':'Open Street Map (Osmarender)',
+'openStreetMapCycleMap':'Open Street Map (CycleMap)',
'end': ''
};
Modified: branches/fusion-2.2/text/fr
===================================================================
--- branches/fusion-2.2/text/fr 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/text/fr 2010-09-24 18:32:16 UTC (rev 2234)
@@ -333,3 +333,18 @@
# Localized Icon Files
POWEREDBYICON = PoweredBy_en.gif
+
+# Quick Plot UI
+QUICKPLOT_HEADER = Quick Plot
+QUICKPLOT_TITLE = Title
+QUICKPLOT_SUBTITLE = Sub title
+QUICKPLOT_PAPER_SIZE = Paper size
+QUICKPLOT_SCALING = Scaling
+QUICKPLOT_DPI = Print DPI
+QUICKPLOT_GENERATE = Generate
+QUICKPLOT_ADVANCED_OPTIONS = Advanced options
+QUICKPLOT_PRINT = Print
+QUICKPLOT_CANCEL = Cancel
+QUICKPLOT_PREVIEW_ERROR = The application resources required to generate the plot exceed the settings defined by the administrator
+QUICKPLOT_RESOLUTION_WARNING = The current settings exceed the map resolution. Zooming out or increasing the scaling will help create a more legible plot
+QUICKPLOT_SCALE_LABEL = Scale
Modified: branches/fusion-2.2/text/fr.json
===================================================================
--- branches/fusion-2.2/text/fr.json 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/text/fr.json 2010-09-24 18:32:16 UTC (rev 2234)
@@ -50,5 +50,20 @@
'printGenerate': 'Generate',
'maptipLinkText': 'Cliquer pour plus d information',
+'quickPlotResolutionWarning':'The current settings exceed the map resolution. Zooming out or increasing the scaling will help create a more legible plot',
+'noCommercialMapLayers':'NONE',
+'googleStreet':'Google Street',
+'googleSatellite':'Google Satellite',
+'googleTerrain':'Google Terrain',
+'googleHybrid':'Google Hybrid',
+'yahooStreet':'Yahoo Street',
+'yahooSatellite':'Yahoo Satellite',
+'yahooHybrid':'Yahoo Hybrid',
+'bingStreet':'Bing Street',
+'bingSatellite':'Bing Satellite',
+'bingHybrid':'Bing Hybrid',
+'openStreetMap':'Open Street Map',
+'openStreetMapOsmarender':'Open Street Map (Osmarender)',
+'openStreetMapCycleMap':'Open Street Map (CycleMap)',
'end': ''
};
Modified: branches/fusion-2.2/widgets/BasemapSwitcher.js
===================================================================
--- branches/fusion-2.2/widgets/BasemapSwitcher.js 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/widgets/BasemapSwitcher.js 2010-09-24 18:32:16 UTC (rev 2234)
@@ -43,12 +43,16 @@
'G_NORMAL_MAP': null,
'G_SATELLITE_MAP': null,
'G_HYBRID_MAP': null,
+ 'G_PHYSICAL_MAP': null,
'YAHOO_MAP_REG': null,
'YAHOO_MAP_SAT': null,
'YAHOO_MAP_HYB': null,
'Road': null,
'Aerial': null,
'Hybrid': null,
+ 'Mapnik': null,
+ 'Osmarender': null,
+ 'CycleMap': null,
'None': null
};
},
@@ -62,13 +66,13 @@
var map = maps[i];
switch (map.layerType) {
case 'MapGuide':
- this.options['None'] = 'None';
+ this.options['None'] = OpenLayers.i18n('noCommercialMapLayers');
this.baseMaps['None'] = map;
break;
case 'Google':
// if user didn't indicate basemap types, use the default Google Street
if (!map.mapTag.extension.Options || !map.mapTag.extension.Options[0].type) {
- this.options['G_NORMAL_MAP'] = "Google Street";
+ this.options['G_NORMAL_MAP'] = OpenLayers.i18n('googleStreet');
this.baseMaps['G_NORMAL_MAP'] = map;
// The first non-MapGuide basemap will be the default basemap
@@ -79,26 +83,41 @@
else {
switch (map.mapTag.extension.Options[0].type[0]) {
case 'G_NORMAL_MAP':
- if (map.mapTag.extension.Options[0].name)
+ if (map.mapTag.extension.Options[0].name) {
this.options['G_NORMAL_MAP'] = map.mapTag.extension.Options[0].name[0];
- else
- this.options['G_NORMAL_MAP'] = "Google Street";
+ }
+ else {
+ this.options['G_NORMAL_MAP'] = OpenLayers.i18n('googleStreet');
+ }
this.baseMaps['G_NORMAL_MAP'] = map;
break;
case 'G_SATELLITE_MAP':
- if (map.mapTag.extension.Options[0].name)
+ if (map.mapTag.extension.Options[0].name) {
this.options['G_SATELLITE_MAP'] = map.mapTag.extension.Options[0].name[0];
- else
- this.options['G_SATELLITE_MAP'] = "Google Satellite";
+ }
+ else {
+ this.options['G_SATELLITE_MAP'] = OpenLayers.i18n('googleSatellite');
+ }
this.baseMaps['G_SATELLITE_MAP'] = map;
break;
case 'G_HYBRID_MAP':
- if (map.mapTag.extension.Options[0].name)
+ if (map.mapTag.extension.Options[0].name) {
this.options['G_HYBRID_MAP'] = map.mapTag.extension.Options[0].name[0];
- else
- this.options['G_HYBRID_MAP'] = "Google Hybrid";
+ }
+ else {
+ this.options['G_HYBRID_MAP'] = OpenLayers.i18n('googleHybrid');
+ }
this.baseMaps['G_HYBRID_MAP'] = map;
break;
+ case 'G_PHYSICAL_MAP':
+ if (map.mapTag.extension.Options[0].name) {
+ this.options['G_PHYSICAL_MAP'] = map.mapTag.extension.Options[0].name[0];
+ }
+ else {
+ this.options['G_PHYSICAL_MAP'] = OpenLayers.i18n('googleTerrain');
+ }
+ this.baseMaps['G_PHYSICAL_MAP'] = map;
+ break;
default:
break;
}
@@ -113,7 +132,7 @@
case 'Yahoo':
// if user didn't indicate basemap types, use the default Yahoo Street
if (!map.mapTag.extension.Options || !map.mapTag.extension.Options[0].type) {
- this.options['YAHOO_MAP_REG'] = "Yahoo Street";
+ this.options['YAHOO_MAP_REG'] = OpenLayers.i18n('yahooStreet');
this.baseMaps['YAHOO_MAP_REG'] = map;
// The first non-MapGuide basemap will be the default basemap
@@ -124,24 +143,30 @@
else {
switch (map.mapTag.extension.Options[0].type[0]) {
case 'YAHOO_MAP_REG':
- if (map.mapTag.extension.Options[0].name)
+ if (map.mapTag.extension.Options[0].name) {
this.options['YAHOO_MAP_REG'] = map.mapTag.extension.Options[0].name[0];
- else
+ }
+ else {
this.options['YAHOO_MAP_REG'] = "Yahoo Street";
+ }
this.baseMaps['YAHOO_MAP_REG'] = map;
break;
case 'YAHOO_MAP_SAT':
- if (map.mapTag.extension.Options[0].name)
+ if (map.mapTag.extension.Options[0].name) {
this.options['YAHOO_MAP_SAT'] = map.mapTag.extension.Options[0].name[0];
- else
- this.options['YAHOO_MAP_SAT'] = "Yahoo Satellite";
+ }
+ else {
+ this.options['YAHOO_MAP_SAT'] = OpenLayers.i18n('yahooStreet');
+ }
this.baseMaps['YAHOO_MAP_SAT'] = map;
break;
case 'YAHOO_MAP_HYB':
- if (map.mapTag.extension.Options[0].name)
+ if (map.mapTag.extension.Options[0].name) {
this.options['YAHOO_MAP_HYB'] = map.mapTag.extension.Options[0].name[0];
- else
- this.options['YAHOO_MAP_HYB'] = "Yahoo Hybrid";
+ }
+ else {
+ this.options['YAHOO_MAP_HYB'] = OpenLayers.i18n('yahooHybrid');
+ }
this.baseMaps['YAHOO_MAP_HYB'] = map;
break;
default:
@@ -156,7 +181,7 @@
case 'VirtualEarth':
// if user didn't indicate basemap types, use the default Bing Street
if (!map.mapTag.extension.Options || !map.mapTag.extension.Options[0].type) {
- this.options['Road'] = "Bing Street";
+ this.options['Road'] = OpenLayers.i18n('bingStreet');
this.baseMaps['Road'] = map;
// The first non-MapGuide basemap will be the default basemap
if (!this.defaultBasemap) {
@@ -167,24 +192,30 @@
switch (map.mapTag.extension.Options[0].type[0]) {
case 'Road':
- if (map.mapTag.extension.Options[0].name)
+ if (map.mapTag.extension.Options[0].name) {
this.options['Road'] = map.mapTag.extension.Options[0].name[0];
- else
- this.options['Road'] = "Bing Street";
+ }
+ else {
+ this.options['Road'] = OpenLayers.i18n('bingStreet');
+ }
this.baseMaps['Road'] = map;
break;
case 'Aerial':
- if (map.mapTag.extension.Options[0].name)
+ if (map.mapTag.extension.Options[0].name) {
this.options['Aerial'] = map.mapTag.extension.Options[0].name[0];
- else
- this.options['Aerial'] = "Bing Satellite";
+ }
+ else {
+ this.options['Aerial'] = OpenLayers.i18n('bingSatellite');
+ }
this.baseMaps['Aerial'] = map;
break;
case 'Hybrid':
- if (map.mapTag.extension.Options[0].name)
+ if (map.mapTag.extension.Options[0].name) {
this.options['Hybrid'] = map.mapTag.extension.Options[0].name[0];
- else
- this.options['Hybrid'] = "Bing Hybrid";
+ }
+ else {
+ this.options['Hybrid'] = OpenLayers.i18n('bingHybrid');
+ }
this.baseMaps['Hybrid'] = map;
break;
default:
@@ -196,6 +227,55 @@
}
}
break;
+ case 'OpenStreetMap':
+ // if user didn't indicate basemap types, use the default OSM Mapnik render
+ if (!map.mapTag.extension.Options || !map.mapTag.extension.Options[0].type) {
+ this.options['Mapnik'] = OpenLayers.i18n('openStreetMap');
+ this.baseMaps['Mapnik'] = map;
+ // The first non-MapGuide basemap will be the default basemap
+ if (!this.defaultBasemap) {
+ this.defaultBasemap = "Mapnik";
+ }
+ }
+ else {
+
+ switch (map.mapTag.extension.Options[0].type[0]) {
+ case 'Mapnik':
+ if (map.mapTag.extension.Options[0].name) {
+ this.options['Mapnik'] = map.mapTag.extension.Options[0].name[0];
+ }
+ else {
+ this.options['Mapnik'] = OpenLayers.i18n('openStreetMap');
+ }
+ this.baseMaps['Mapnik'] = map;
+ break;
+ case 'Osmarender':
+ if (map.mapTag.extension.Options[0].name) {
+ this.options['Osmarender'] = map.mapTag.extension.Options[0].name[0];
+ }
+ else {
+ this.options['Osmarender'] = OpenLayers.i18n('openStreetMapOsmarender');
+ }
+ this.baseMaps['Osmarender'] = map;
+ break;
+ case 'CycleMap':
+ if (map.mapTag.extension.Options[0].name) {
+ this.options['CycleMap'] = map.mapTag.extension.Options[0].name[0];
+ }
+ else {
+ this.options['CycleMap'] = OpenLayers.i18n('openStreetMapCycleMap');
+ }
+ this.baseMaps['CycleMap'] = map;
+ break;
+ default:
+ break;
+ }
+ // The first non-MapGuide basemap will be the default basemap
+ if (!this.defaultBasemap) {
+ this.defaultBasemap = map.mapTag.extension.Options[0].type[0];
+ }
+ }
+ break;
default:
break;
}
Modified: branches/fusion-2.2/widgets/BufferPanel/Buffer.php
===================================================================
--- branches/fusion-2.2/widgets/BufferPanel/Buffer.php 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/widgets/BufferPanel/Buffer.php 2010-09-24 18:32:16 UTC (rev 2234)
@@ -87,7 +87,7 @@
$layers = $map->GetLayers();
$layer = FindLayer($layers, $bufferName);
- $layerNames = split(",", $layersParam);
+ $layerNames = explode(",", $layersParam);
// convert distance to meters
if($units == "mi") //miles
Modified: branches/fusion-2.2/widgets/BufferPanel/BufferPanel.templ
===================================================================
--- branches/fusion-2.2/widgets/BufferPanel/BufferPanel.templ 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/widgets/BufferPanel/BufferPanel.templ 2010-09-24 18:32:16 UTC (rev 2234)
@@ -173,14 +173,15 @@
function GetParent()
{
- if (popup) {
- return opener;
- } else if (parent.Fusion) {
- return parent;
- } else if (parent.parent.Fusion) {
- return parent.parent;
- }
- return null;
+ if(popup)
+ return opener;
+ else
+ {
+ var node = parent;
+ while (!node.Fusion && node.parent && node != node.parent)
+ node = node.parent;
+ return node;
+ }
}
function PickColor(what, allowTransparency, transparent)
Modified: branches/fusion-2.2/widgets/BufferPanel/BufferReport.templ
===================================================================
--- branches/fusion-2.2/widgets/BufferPanel/BufferReport.templ 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/widgets/BufferPanel/BufferReport.templ 2010-09-24 18:32:16 UTC (rev 2234)
@@ -47,11 +47,16 @@
}
function GetParent()
-{
- if(popup)
- return opener;
- else
- return parent.parent;
+{debugger;
+ if(popup)
+ return opener;
+ else
+ {
+ var node = parent;
+ while (!node.Fusion && node.parent)
+ node = node.parent;
+ return node;
+ }
}
</script>
Modified: branches/fusion-2.2/widgets/BufferPanel/ErrorPage.templ
===================================================================
--- branches/fusion-2.2/widgets/BufferPanel/ErrorPage.templ 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/widgets/BufferPanel/ErrorPage.templ 2010-09-24 18:32:16 UTC (rev 2234)
@@ -49,10 +49,15 @@
function GetParent()
{
- if(popup)
- return opener;
- else
- return parent.parent;
+ if(popup)
+ return opener;
+ else
+ {
+ var node = parent;
+ while (!node.fusion && node.parent)
+ node = node.parent;
+ return node;
+ }
}
</script>
Modified: branches/fusion-2.2/widgets/Measure.js
===================================================================
--- branches/fusion-2.2/widgets/Measure.js 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/widgets/Measure.js 2010-09-24 18:32:16 UTC (rev 2234)
@@ -80,6 +80,9 @@
if(json.SegmentLabels){
this.segmentLabels = (json.SegmentLabels[0].toLowerCase == "true" && json.SegmentLabels[0]) ? true : false;
}
+ if(json.Geodesic){
+ this.geodesic = (json.Geodesic[0].toLowerCase == "false") ? false : true;
+ }
this.sTarget = json.Target ? json.Target[0] : "";
this.sBaseUrl = Fusion.getFusionURL() + 'widgets/Measure/Measure.php';
@@ -636,8 +639,12 @@
* Subsequent calls from a ViewOptions widget would override the value specified.
*/
setUnits: function(units) {
- units = (units == Fusion.UNKNOWN)?Fusion.unitFromName(this.getMap().getUnits()):units;
+ var map = this.getMap();
+ units = (units == Fusion.UNKNOWN)?Fusion.unitFromName(map.getUnits()):units;
this.setParameter('Units', Fusion.unitName(units));
+ if (map.oMapOL.baseLayer.projection.proj && map.oMapOL.baseLayer.projection.proj.localCS) {
+ this.geodesic = false;
+ }
},
setParameter: function(param, value) {
Deleted: branches/fusion-2.2/widgets/QuickPlot/GeneratePicture.php
===================================================================
--- trunk/widgets/QuickPlot/GeneratePicture.php 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/widgets/QuickPlot/GeneratePicture.php 2010-09-24 18:32:16 UTC (rev 2234)
@@ -1,182 +0,0 @@
-<?php
- $fusionMGpath = '../../layers/MapGuide/php/';
- include $fusionMGpath . 'Utilities.php';
-
- $fusionMGpath = '../../layers/MapGuide/php/';
- include $fusionMGpath . 'Common.php';
-
- $sessionID = "";
- $mapName = "";
- $rotation = 0.0;
- $printDpi = 300;
- $scaleDenominator = 0;
- $captureBox;
- $normalizedCapture;
- $printSize;
- $paperSize;
-
- GetParameters();
- GenerateMap($printSize);
-?>
-
-<?php
- function GetParameters()
- {
- global $sessionID, $mapName, $printDpi, $rotation, $paperSize, $captureBox, $printSize, $scaleDenominator, $normalizedCapture;
- $args = $_GET;
- if ($_SERVER["REQUEST_METHOD"] == "POST")
- {
- $args = $_POST;
- }
-
- // Not necessary to validate the parameters
- $sessionID = $args["session_id"];
- $mapName = $args["map_name"];
- $rotation = floatval($args["rotation"]);
- $printDpi = intval($args["print_dpi"]);
-
- $scaleDenominator = intval($args["scale_denominator"]);
-
- $array = explode(",", $args["paper_size"]);
- $paperSize = new Size(floatval($array[0]), floatval($array[1]));
- $printSize = new Size($paperSize->width / 25.4 * $printDpi, $paperSize->height / 25.4 * $printDpi);
-
- $array = explode(",", $args["box"]);
- $captureBox = CreatePolygon($array);
-
- $array = explode(",", $args["normalized_box"]);
- $normalizedCapture = CreatePolygon($array);
- }
-
- function CreatePolygon($coordinates)
- {
- $geometryFactory = new MgGeometryFactory();
- $coordinateCollection = new MgCoordinateCollection();
- $linearRingCollection = new MgLinearRingCollection();
-
- for ($index = 0; $index < count($coordinates); ++$index)
- {
- $coordinate = $geometryFactory->CreateCoordinateXY(floatval($coordinates[$index]), floatval($coordinates[++$index]));
- $coordinateCollection->Add($coordinate);
- }
-
- $coordinateCollection->Add($geometryFactory->CreateCoordinateXY(floatval($coordinates[0]), floatval($coordinates[1])));
-
- $linearRingCollection = $geometryFactory->CreateLinearRing($coordinateCollection);
- $captureBox = $geometryFactory->CreatePolygon($linearRingCollection, null);
-
- return $captureBox;
- }
-
- function GenerateMap($size)
- {
- global $sessionID, $mapName, $captureBox, $printSize, $normalizedCapture, $rotation, $scaleDenominator, $printDpi;
-
- $userInfo = new MgUserInformation($sessionID);
- $siteConnection = new MgSiteConnection();
- $siteConnection->Open($userInfo);
- $resourceService = $siteConnection->CreateService(MgServiceType::ResourceService);
- $renderingService = $siteConnection->CreateService(MgServiceType::RenderingService);
-
- $map = new MgMap();
- $map->Open($resourceService, $mapName);
-
- $selection = new MgSelection($map);
- $color = new MgColor(255, 255, 255);
-
- // Calculate the generated picture size
- $envelope = $captureBox->Envelope();
- $normalizedE = $normalizedCapture->Envelope();
- $size1 = new Size($envelope->getWidth(), $envelope->getHeight());
- $size2 = new Size($normalizedE->getWidth(), $normalizedE->getHeight());
- $toSize = new Size($size1->width / $size2->width * $size->width, $size1->height / $size2->height * $size->height);
- $center = $captureBox->GetCentroid()->GetCoordinate();
-
- // Get the map agent url
- // Get the correct http protocal
- $mapAgent = "http";
- if ($_SERVER["HTTPS"] == "on")
- {
- $mapAgent .= "s";
- }
- // Get the correct port number
- $mapAgent .= "://127.0.0.1:" . $_SERVER["SERVER_PORT"];
- // Get the correct virtual directory
- $mapAgent .= substr($_SERVER["REQUEST_URI"], 0, strpos($_SERVER["REQUEST_URI"], "/", 1));
- $mapAgent .="/mapagent/mapagent.fcgi?VERSION=1.0.0&OPERATION=GETMAPIMAGE" .
- "&SESSION=$sessionID" .
- "&MAPNAME=$mapName" .
- "&FORMAT=PNG" .
- "&SETVIEWCENTERX=" . $center->GetX() .
- "&SETVIEWCENTERY=" . $center->GetY() .
- "&SETVIEWSCALE=$scaleDenominator" .
- "&SETDISPLAYDPI=$printDpi" .
- "&SETDISPLAYWIDTH=$toSize->width" .
- "&SETDISPLAYHEIGHT=$toSize->height" .
- "&CLIP=0";
-
- $image = imagecreatefrompng($mapAgent);
- // Rotate the picture back to be normalized
- $normalizedImg = imagerotate($image, -$rotation, 0);
- // Free the original image
- imagedestroy($image);
- // Crop the normalized image
- $croppedImg = imagecreatetruecolor($size->width, $size->height);
- imagecopy($croppedImg, $normalizedImg, 0, 0, (imagesx($normalizedImg) - $size->width) / 2, (imagesy($normalizedImg) - $size->height) / 2, $size->width, $size->height);
- // Free the normalized image
- imagedestroy($normalizedImg);
- // Draw the north arrow on the map
- DrawNorthArrow($croppedImg);
-
- header ("Content-type: image/png");
- imagepng($croppedImg);
- imagedestroy($croppedImg);
- }
-
- function DrawNorthArrow($map)
- {
- global $paperSize, $rotation;
-
- // Load the north arrow image which has a 300 dpi resolution
- $na = imagecreatefrompng("./north_arrow.png");
- // Rotate the north arrow according to the capture rotation
- $transparent= imagecolortransparent($na);
- $rotatedNa = imagerotate($na, -$rotation, $transparent);
- // Free the north arrow image
- imagedestroy($na);
- // Get the size of north arrow image
- $naWidth = imagesx($rotatedNa);
- $naHeight = imagesy($rotatedNa);
- // Get the map size
- $mapWidth = imagesx($map);
- $mapHeight = imagesy($map);
- // Get the logical resolution of map
- $resolution = $mapWidth * 25.4 / $paperSize->width;
- // On printed paper, north arrow is located at the right bottom corner with 6 MM margin
- $naRes = 300;
- $naMargin = 12;
- // Calculate the margin as pixels according to the resolutions
- $margin = $resolution * $naMargin / 25.4;
- // Get the width of the north arrow on the map picture
- $drawWidth = $naWidth * $resolution / $naRes;
- $drawHeight = $naHeight * $resolution / $naRes;
- // Draw the north arrow on the map picture
- imagecopyresized($map, $rotatedNa, $mapWidth - $drawWidth - $margin, $mapHeight - $drawHeight - $margin, 0, 0, $drawWidth, $drawHeight, $naWidth, $naHeight);
- // Free the north arrow image
- imagedestroy($rotatedNa);
- }
-?>
-
-<?php
- class Size
- {
- public $width;
- public $height;
-
- public function __construct($width, $height)
- {
- $this->width = $width;
- $this->height = $height;
- }
- }
-?>
\ No newline at end of file
Copied: branches/fusion-2.2/widgets/QuickPlot/GeneratePicture.php (from rev 2233, trunk/widgets/QuickPlot/GeneratePicture.php)
===================================================================
--- branches/fusion-2.2/widgets/QuickPlot/GeneratePicture.php (rev 0)
+++ branches/fusion-2.2/widgets/QuickPlot/GeneratePicture.php 2010-09-24 18:32:16 UTC (rev 2234)
@@ -0,0 +1,182 @@
+<?php
+ $fusionMGpath = '../../layers/MapGuide/php/';
+ include $fusionMGpath . 'Utilities.php';
+
+ $fusionMGpath = '../../layers/MapGuide/php/';
+ include $fusionMGpath . 'Common.php';
+
+ $sessionID = "";
+ $mapName = "";
+ $rotation = 0.0;
+ $printDpi = 300;
+ $scaleDenominator = 0;
+ $captureBox;
+ $normalizedCapture;
+ $printSize;
+ $paperSize;
+
+ GetParameters();
+ GenerateMap($printSize);
+?>
+
+<?php
+ function GetParameters()
+ {
+ global $sessionID, $mapName, $printDpi, $rotation, $paperSize, $captureBox, $printSize, $scaleDenominator, $normalizedCapture;
+ $args = $_GET;
+ if ($_SERVER["REQUEST_METHOD"] == "POST")
+ {
+ $args = $_POST;
+ }
+
+ // Not necessary to validate the parameters
+ $sessionID = $args["session_id"];
+ $mapName = $args["map_name"];
+ $rotation = floatval($args["rotation"]);
+ $printDpi = intval($args["print_dpi"]);
+
+ $scaleDenominator = intval($args["scale_denominator"]);
+
+ $array = explode(",", $args["paper_size"]);
+ $paperSize = new Size(floatval($array[0]), floatval($array[1]));
+ $printSize = new Size($paperSize->width / 25.4 * $printDpi, $paperSize->height / 25.4 * $printDpi);
+
+ $array = explode(",", $args["box"]);
+ $captureBox = CreatePolygon($array);
+
+ $array = explode(",", $args["normalized_box"]);
+ $normalizedCapture = CreatePolygon($array);
+ }
+
+ function CreatePolygon($coordinates)
+ {
+ $geometryFactory = new MgGeometryFactory();
+ $coordinateCollection = new MgCoordinateCollection();
+ $linearRingCollection = new MgLinearRingCollection();
+
+ for ($index = 0; $index < count($coordinates); ++$index)
+ {
+ $coordinate = $geometryFactory->CreateCoordinateXY(floatval($coordinates[$index]), floatval($coordinates[++$index]));
+ $coordinateCollection->Add($coordinate);
+ }
+
+ $coordinateCollection->Add($geometryFactory->CreateCoordinateXY(floatval($coordinates[0]), floatval($coordinates[1])));
+
+ $linearRingCollection = $geometryFactory->CreateLinearRing($coordinateCollection);
+ $captureBox = $geometryFactory->CreatePolygon($linearRingCollection, null);
+
+ return $captureBox;
+ }
+
+ function GenerateMap($size)
+ {
+ global $sessionID, $mapName, $captureBox, $printSize, $normalizedCapture, $rotation, $scaleDenominator, $printDpi;
+
+ $userInfo = new MgUserInformation($sessionID);
+ $siteConnection = new MgSiteConnection();
+ $siteConnection->Open($userInfo);
+ $resourceService = $siteConnection->CreateService(MgServiceType::ResourceService);
+ $renderingService = $siteConnection->CreateService(MgServiceType::RenderingService);
+
+ $map = new MgMap();
+ $map->Open($resourceService, $mapName);
+
+ $selection = new MgSelection($map);
+ $color = new MgColor(255, 255, 255);
+
+ // Calculate the generated picture size
+ $envelope = $captureBox->Envelope();
+ $normalizedE = $normalizedCapture->Envelope();
+ $size1 = new Size($envelope->getWidth(), $envelope->getHeight());
+ $size2 = new Size($normalizedE->getWidth(), $normalizedE->getHeight());
+ $toSize = new Size($size1->width / $size2->width * $size->width, $size1->height / $size2->height * $size->height);
+ $center = $captureBox->GetCentroid()->GetCoordinate();
+
+ // Get the map agent url
+ // Get the correct http protocal
+ $mapAgent = "http";
+ if ($_SERVER["HTTPS"] == "on")
+ {
+ $mapAgent .= "s";
+ }
+ // Get the correct port number
+ $mapAgent .= "://127.0.0.1:" . $_SERVER["SERVER_PORT"];
+ // Get the correct virtual directory
+ $mapAgent .= substr($_SERVER["REQUEST_URI"], 0, strpos($_SERVER["REQUEST_URI"], "/", 1));
+ $mapAgent .="/mapagent/mapagent.fcgi?VERSION=1.0.0&OPERATION=GETMAPIMAGE" .
+ "&SESSION=$sessionID" .
+ "&MAPNAME=$mapName" .
+ "&FORMAT=PNG" .
+ "&SETVIEWCENTERX=" . $center->GetX() .
+ "&SETVIEWCENTERY=" . $center->GetY() .
+ "&SETVIEWSCALE=$scaleDenominator" .
+ "&SETDISPLAYDPI=$printDpi" .
+ "&SETDISPLAYWIDTH=$toSize->width" .
+ "&SETDISPLAYHEIGHT=$toSize->height" .
+ "&CLIP=0";
+
+ $image = imagecreatefrompng($mapAgent);
+ // Rotate the picture back to be normalized
+ $normalizedImg = imagerotate($image, -$rotation, 0);
+ // Free the original image
+ imagedestroy($image);
+ // Crop the normalized image
+ $croppedImg = imagecreatetruecolor($size->width, $size->height);
+ imagecopy($croppedImg, $normalizedImg, 0, 0, (imagesx($normalizedImg) - $size->width) / 2, (imagesy($normalizedImg) - $size->height) / 2, $size->width, $size->height);
+ // Free the normalized image
+ imagedestroy($normalizedImg);
+ // Draw the north arrow on the map
+ DrawNorthArrow($croppedImg);
+
+ header ("Content-type: image/png");
+ imagepng($croppedImg);
+ imagedestroy($croppedImg);
+ }
+
+ function DrawNorthArrow($map)
+ {
+ global $paperSize, $rotation;
+
+ // Load the north arrow image which has a 300 dpi resolution
+ $na = imagecreatefrompng("./north_arrow.png");
+ // Rotate the north arrow according to the capture rotation
+ $transparent= imagecolortransparent($na);
+ $rotatedNa = imagerotate($na, -$rotation, $transparent);
+ // Free the north arrow image
+ imagedestroy($na);
+ // Get the size of north arrow image
+ $naWidth = imagesx($rotatedNa);
+ $naHeight = imagesy($rotatedNa);
+ // Get the map size
+ $mapWidth = imagesx($map);
+ $mapHeight = imagesy($map);
+ // Get the logical resolution of map
+ $resolution = $mapWidth * 25.4 / $paperSize->width;
+ // On printed paper, north arrow is located at the right bottom corner with 6 MM margin
+ $naRes = 300;
+ $naMargin = 12;
+ // Calculate the margin as pixels according to the resolutions
+ $margin = $resolution * $naMargin / 25.4;
+ // Get the width of the north arrow on the map picture
+ $drawWidth = $naWidth * $resolution / $naRes;
+ $drawHeight = $naHeight * $resolution / $naRes;
+ // Draw the north arrow on the map picture
+ imagecopyresized($map, $rotatedNa, $mapWidth - $drawWidth - $margin, $mapHeight - $drawHeight - $margin, 0, 0, $drawWidth, $drawHeight, $naWidth, $naHeight);
+ // Free the north arrow image
+ imagedestroy($rotatedNa);
+ }
+?>
+
+<?php
+ class Size
+ {
+ public $width;
+ public $height;
+
+ public function __construct($width, $height)
+ {
+ $this->width = $width;
+ $this->height = $height;
+ }
+ }
+?>
\ No newline at end of file
Deleted: branches/fusion-2.2/widgets/QuickPlot/MapCapturer.js
===================================================================
--- trunk/widgets/QuickPlot/MapCapturer.js 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/widgets/QuickPlot/MapCapturer.js 2010-09-24 18:32:16 UTC (rev 2234)
@@ -1,853 +0,0 @@
-/**
- * Copyright (C) 2010 Autodesk, Inc. All rights reserved.
- */
-
-/**
- * @requires OpenLayers/Control.js
- * @requires OpenLayers/Handler/Drag.js
- * @requires OpenLayers/Handler/Feature.js
- */
-
-/**
- * Class: OpenLayers.Control.MapCapturer
- * The MapCapturer control shows a box on the map to illustrate the area that will be captured.
- * Normally the capture information will be used to print the map. If the MapCapturer is configured not
- * show the capture box, then the current viewport will be used as the capture area.
- *
- * The user can move or rotate the capture box to change the area he'd like to capture.
- * And the user can hold SHIFT key to snapp to a certain angle when he is rotating the capture box
- *
- * Inherits From:
- * - <OpenLayers.Control>
- */
-OpenLayers.Control.MapCapturer = OpenLayers.Class(OpenLayers.Control, {
- /**
- * Property: layer
- * {<OpenLayers.Layer.Vector>}
- */
- layer: null,
-
- /**
- * Property: feature. The active feature which is repsonding to mouse action
- * {<OpenLayers.Feature.Vector>}
- */
- feature: null,
-
- /**
- * Property: captureBox. It's the feature represnting the capture area
- * {<OpenLayers.Feature.Vector>}
- */
- captureBox: null,
-
- /**
- * Property: rotateHandle. It's the feature representing a rotate handle
- * (<OpenLayers.Feature.Vector)
- */
- rotateHandle: null,
-
- /**
- * Property: rotateHandleStart. It's the feature representing the center point of capture box.
- * And it's also the start point of the rotate handle.
- * (<OpenLayers.Feature.Vector>)
- */
- rotateHandleStart: null,
-
- /**
- * Property: rotateHandleEnd. It's the feature responding to the rotate command.
- * (<OpenLayers.Feature.Vector>)
- */
- rotateHandleEnd: null,
-
- /**
- * Property: snappingLine. It's the feature indicating a certain angle to snap to. It shows up in the rotate process
- * (<OpenLayers.Feature.Vector>)
- */
- snappingLine: null,
-
- /**
- * Property: rotation. The rotation of the capture box
- * {float}
- */
- rotation: 0.0,
-
- /**
- * Property: rotateHandleLength. Defines the length of the rotate handle
- * in pixel. default is 30 pixels
- * {int}
- */
- rotateHandleLength: 30,
-
- /**
- * Property: captureBoxStyle. Style for the capture box
- * {<OpenLayers.Style>}
- */
- captureBoxStyle: null,
-
- /**
- * Property: rotateHandleStyle. Style for the rotate handle
- * (<OpenLayers.Style>)
- */
- rotateHandleStyle: null,
-
- /**
- * Property: rotateHandlePointStyle. Style for the snap handle's start and end points
- * (<OpenLayers.Style>)
- */
- rotateHandlePointStyle: null,
-
- /**
- * Property: snappingLineStyle. Style for the snapping line
- * (<OpenLayers.Style>)
- */
- snappingLineStyle: null,
-
- /**
- * Indicates if the capture box is enabled. An enabled capture box will show up on the map
- * {bool}
- */
- enabled: false,
-
- /**
- * Property: warningMessage. The warning message when the capture box cannot display completely in current zoom level
- * (string)
- */
- warningMessage: OpenLayers.i18n("quickPlotResolutionWarning"),
-
- /**
- * Property: rotateSnappingStep. Defines the rotate snapping angle step. In degrees
- * (int)
- */
- rotateSnappingStep: 45,
-
- /**
- * Property: rotateSnappingTolerance. Defines the rotate snapping tolerance. In degress
- */
- rotateSnappingTolerance: 2,
-
- /**
- * Property: lastPixel. The last position the mouse action was responded
- * {<OpenLayers.Pixel>}
- */
- lastPixel: null,
-
- /**
- * Constructor: OpenLayers.Control.DragFeature
- * Create a new control to drag features.
- *
- * Parameters:
- * map - The widget map which encapsulates an OpenLayers.Map
- *
- * options - {Object} Optional object whose properties will be set on the control.
- */
- initialize: function(map, options)
- {
- OpenLayers.Control.prototype.initialize.apply(this, [options]);
-
- // Initialize the styles
- this.captureBoxStyle = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style["default"]);
- this.captureBoxStyle.fillOpacity = 0.8;
- this.captureBoxStyle.fillColor = "#476387";
- this.captureBoxStyle.strokeColor = "#39506F";
-
- this.rotateHandleStyle = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style["default"]);
- this.rotateHandleStyle.strokeColor = "#39506F";
- this.rotateHandlePointStyle = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style["default"]);
- this.rotateHandlePointStyle.strokeColor = "#39506F";
- this.rotateHandlePointStyle.fillOpacity = 1.0;
- this.rotateHandlePointStyle.fillColor = "#476387";
- this.rotateHandlePointStyle.pointRadius = 4;
-
- this.snappingLineStyle = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style["default"]);
- this.snappingLineStyle.strokeOpacity = 0.8;
- this.snappingLineStyle.strokeColor = "black";
- this.snappingLineStyle.strokeDashstyle = "dot";
-
-
- // The cursor styles
- this.cursorMove = "move";
- this.cursorRotate = "url(../../../Widgets/QuickPlot/rotate.cur), default";
-
- // The widget map
- this.wMap = map;
-
- // Create a new layer to show the capture box
- this.layer = new OpenLayers.Layer.Vector("Map Capturer Layer");
- map.oMapOL.addLayer(this.layer);
-
- // Create the features
- this.captureBox = new OpenLayers.Feature.Vector(null, null, this.captureBoxStyle);
- this.rotateHandle = new OpenLayers.Feature.Vector(null, null, this.rotateHandleStyle);
- this.rotateHandleStart = new OpenLayers.Feature.Vector(null, null, this.rotateHandlePointStyle);
- this.rotateHandleEnd = new OpenLayers.Feature.Vector(null, null, this.rotateHandlePointStyle);
- this.snappingLine = new OpenLayers.Feature.Vector(null, null, this.snappingLineStyle);
-
- // Add the features into the layer
- this.layer.addFeatures([this.captureBox, this.rotateHandle, this.rotateHandleStart, this.rotateHandleEnd, this.snappingLine]);
-
- // Overwrite layer's drawFeatures method to consider the map capturer's enable / disable
- this.layer.drawFeature = (function(f, item, style)
- {
- if (this.enabled)
- {
- f.apply(this.layer, Array.prototype.slice.call(arguments, 1));
- }
- }).bind(this, this.layer.drawFeature);
- this.handlers =
- {
- drag: new OpenLayers.Handler.Drag(
- this, OpenLayers.Util.extend({
- down: this.downFeature,
- up: this.upFeature,
- out: this.cancel,
- done: this.doneDragging
- }, this.dragCallbacks)),
- feature: new OpenLayers.Handler.Feature(
- this, this.layer, OpenLayers.Util.extend({
- over: this.overFeature,
- out: this.outFeature
- }, this.featureCallbacks),
- {geometryTypes: this.geometryTypes}
- )
- };
-
- // List to the mouse move event
- this.handlers.drag.move = this.mouseMove.bind(this);
-
- // Listen to MAP_EXTENTS_CHANGED event to refresh the outer box because the 'delta' is fixed regardless current scale
- var oMap = this.wMap.oMapOL;
- oMap.events.register("zoomend", this, this.drawFeatures.bind(this));
- },
-
- /**
- * APIMethod: destroy
- * Take care of things that are not handled in superclass
- */
- destroy: function()
- {
- this.layer = null;
- OpenLayers.Control.prototype.destroy.apply(this, []);
- },
-
- /**
- * APIMethod: activate
- * Activate the control and the feature handler.
- *
- * Returns:
- * {Boolean} Successfully activated the control and feature handler.
- */
- activate: function()
- {
- return (this.handlers.feature.activate() &&
- OpenLayers.Control.prototype.activate.apply(this, arguments));
- },
-
- /**
- * APIMethod: deactivate
- * Deactivate the control and all handlers.
- *
- * Returns:
- * {Boolean} Successfully deactivated the control.
- */
- deactivate: function() {
- // The return from the handlers is unimportant in this case
- this.handlers.feature.deactivate();
- this.handlers.drag.deactivate();
- this.feature = null;
- this.dragging = false;
- this.lastPixel = null;
-
- return OpenLayers.Control.prototype.deactivate.apply(this, arguments);
- },
-
- /**
- * Method: overFeature
- * Called when the feature handler detects a mouse-over on a feature.
- * This enables the drag control if the event target is the outer polygon,
- * and the rotate control will be activated if the event target is the inner polygon
- *
- * Parameters:
- * feature - {<OpenLayers.Feature.Vector>} The selected feature.
- */
- overFeature: function(feature)
- {
- // The feature that the cursor stops on
- this.stopFeature = feature;
-
- if(!this.handlers.drag.dragging)
- {
- this.feature = feature;
- this.handlers.drag.activate();
- this.over = true;
-
- this.setCursor();
- }
- else
- {
- if(this.captureBox.id == feature.id || this.rotateHandleEnd.id == feature.id)
- {
- this.over = true;
- }
- else
- {
- this.over = false;
- }
- }
- },
-
- /**
- * Method: dragging
- * Check if it's currently in dragging to move mode
- */
- dragging: function()
- {
- if (this.feature && this.captureBox)
- {
- return this.feature.id == this.captureBox.id || this.feature.id == this.rotateHandleStart.id;
- }
-
- return false;
- },
-
- /**
- * Method: dragging
- * Check if it's currently in dragging to rotate mode
- */
- rotating: function()
- {
- return this.feature && this.rotateHandleEnd && this.feature.id == this.rotateHandleEnd.id;
- },
-
- /**
- * Method: downFeature
- * Called when the drag handler detects a mouse-down.
- *
- * Parameters:
- * pixel - {<OpenLayers.Pixel>} Location of the mouse event.
- */
- downFeature: function(pixel)
- {
- this.setCursor();
- this.lastPixel = pixel;
- },
-
- /**
- * Method: setCursor
- * Set the cursor according to current action: moving or rotating
- */
- setCursor: function()
- {
- if (this.dragging())
- {
- this.wMap.setCursor(this.cursorMove);
- }
- else if (this.rotating())
- {
- this.wMap.setCursor(this.cursorRotate);
- }
- },
- /**
- * Method: moveFeature
- * Called when the drag handler detects a mouse-move. Also calls the
- * optional onDrag method.
- */
- mouseMove: function(evt)
- {
- if (this.dragging())
- {
- this.moveFeature(evt);
- }
- else if (this.rotating())
- {
- this.rotateFeature(evt);
- }
- },
-
- /**
- * Method: moveFeature
- * Move the feature according to the mouse-move
- */
- moveFeature: function(evt)
- {
- pixel = evt.xy;
- var res = this.wMap.getResolution();
- var delta = {x:res * (pixel.x - this.lastPixel.x), y:res * (this.lastPixel.y - pixel.y)};
-
- var features = this.layer.features;
- for (var i = 0; i < features.length; ++i)
- {
- // Don't touch the snapping line
- if (features[i].geometry != null && features[i].id != this.snappingLine.id)
- {
- features[i].geometry.move(delta.x, delta.y);
- this.layer.drawFeature(features[i]);
- }
- }
-
- this.lastPixel = pixel;
- },
-
- /**
- * Method: moveFeature
- * Called when the drag handler detects a mouse-move. Also calls the
- * optional onDrag method.
- */
- rotateFeature: function(evt)
- {
- pixel = evt.xy;
- var centroid = this.captureBox.geometry.getCentroid();
- var origin = this.map.getViewPortPxFromLonLat(new OpenLayers.LonLat(centroid.x, centroid.y));
- var angle = this.calculateAngle(pixel, origin);
- var rotation = this.rotation + angle;
-
- if (evt.shiftKey)
- {
- var a = rotation % this.rotateSnappingStep;
- var b = Math.round(rotation / this.rotateSnappingStep);
- var targetRotation = rotation;
-
- if (Math.abs(a) <= this.rotateSnappingTolerance || Math.abs(a)>= this.rotateSnappingStep - this.rotateSnappingTolerance)
- {
- targetRotation = b * this.rotateSnappingStep;
-
- // Draw the snapping guide
- if (this.snappingLine.geometry == null)
- {
- this.drawSnappingHint(targetRotation);
- }
- }
- else
- {
- this.clearSnappingHint();
- }
-
- angle = targetRotation - this.rotation;
- }
- else
- {
- this.clearSnappingHint();
- }
-
- this.rotation += angle;
-
- var features = this.layer.features;
- for (var i = 0; i < features.length; ++i)
- {
- // Don't touch the snapping line here because the snapping line is controlled only by drawSnappingHint
- if (features[i].geometry != null && features[i].id != this.snappingLine.id)
- {
- features[i].geometry.rotate(angle, centroid);
- this.layer.drawFeature(features[i]);
- }
- }
-
- this.lastPixel = angle == 0 ? this.lastPixel : pixel;
- },
-
- /**
- * Method: drawSnappingHint
- * Draw the snapping line
- */
- drawSnappingHint: function(angle)
- {
- var viewSize = this.wMap.getCurrentExtents().getSize();
- var length = Math.sqrt(Math.pow(viewSize.w, 2) + Math.pow(viewSize.h, 2));
- var origin = this.captureBox.geometry.getCentroid();
-
- var points = [];
- points.push(new OpenLayers.Geometry.Point(origin.x - length, origin.y));
- points.push(new OpenLayers.Geometry.Point(origin.x + length, origin.y));
- var hint = new OpenLayers.Geometry.LineString(points);
-
- hint.rotate(angle + 90, origin);
-
- this.snappingLine.geometry = hint;
- this.layer.drawFeature(this.snappingLine);
- },
-
- /**
- * Method: clearSnappingHint
- * Clear the snapping line
- */
- clearSnappingHint: function()
- {
- if (this.snappingLine != null && this.snappingLine.geometry != null)
- {
- this.layer.eraseFeatures([this.snappingLine]);
- this.snappingLine.geometry = null;
- }
- },
-
- /**
- * Method: calculateAngle
- * Calculates the rotate angle, in degree and counterclockwise
- */
- calculateAngle: function(pixel, origin)
- {
- var angle1 = Math.atan2(pixel.y - origin.y, pixel.x - origin.x);
- var angle2 = Math.atan2(this.lastPixel.y - origin.y, this.lastPixel.x - origin.x);
- return (angle2 - angle1) * 180 / Math.PI;
- },
-
- /**
- * Method: upFeature
- * Called when the drag handler detects a mouse-up.
- *
- * Parameters:
- * pixel - {<OpenLayers.Pixel>} Location of the mouse event.
- */
- upFeature: function(pixel)
- {
- if(!this.over)
- {
- this.handlers.drag.deactivate();
- }
- else
- {
- // Set the last-stop feature to be the active one
- this.feature = this.stopFeature;
- // Set the correct cursor
- this.setCursor();
- }
-
- this.clearSnappingHint();
- },
-
- /**
- * Method: outFeature
- * Called when the feature handler detects a mouse-out on a feature.
- *
- * Parameters:
- * feature - {<OpenLayers.Feature.Vector>} The feature that the mouse left.
- */
- outFeature: function(feature)
- {
- if(!this.handlers.drag.dragging)
- {
- this.over = false;
- this.handlers.drag.deactivate();
- this.wMap.setCursor("auto");
- this.feature = null;
- }
- else
- {
- if(this.feature.id == feature.id)
- {
- this.over = false;
- }
- }
- },
-
- /**
- * Method: cancel
- * Called when the drag handler detects a mouse-out (from the map viewport).
- */
- cancel: function()
- {
- this.handlers.drag.deactivate();
- this.over = false;
- },
-
- /**
- * Method: setMap
- * Set the map property for the control and all handlers.
- *
- * Parameters:
- * map - {<OpenLayers.Map>} The control's map.
- */
- setMap: function(map)
- {
- this.handlers.drag.setMap(map);
- this.handlers.feature.setMap(map);
- OpenLayers.Control.prototype.setMap.apply(this, arguments);
- },
-
- /**
- * Method: setRegion
- * Set the size of the capture box. Then the box will be redrawn on the map
- *
- * Parameters:
- * paperSize - {<OpenLayers.Size>} The paper size, in mm
- * scaleDenominator - The denominator of target scale
- */
- setSize: function(paperSize, scaleDenominator)
- {
- this.paperSize = paperSize;
- this.scaleDenominator = scaleDenominator;
- this.drawFeatures();
- // Active the handler
- this.activate();
- },
-
- /**
- * Method: drawFeatures
- * Draw the capture box, rotate handle etc. on the map
- */
- drawFeatures: function()
- {
- // The paper size is not set yet, so don't draw the features
- if (!this.paperSize)
- {
- return;
- }
-
- // Clear the previous drawn features
- this.clearFeatures();
-
- this.createCaptureBox();
- this.createRotateHandle();
-
- // Draw the box only when control is enabled and the resolution is valid
- if (this.enabled)
- {
- if (this.validateResolution())
- {
- this.layer.features.each(function(item){item.layer.drawFeature(item);});
- this.wMap.message.hide();
- }
- else
- {
- this.wMap.message.warn(this.warningMessage);
- }
- }
- },
-
- /**
- * Method: clearFeatures:
- * Clear the capture box, rotate handle etc. from the map
- */
- clearFeatures: function()
- {
- // Clear the previous drawn features
- var features = this.layer.features;
- var toErase = [];
- var feature = null;
-
- for (var i = 0; i < features.length; ++i)
- {
- feature = features[i];
- if (feature.geometry != null)
- {
- toErase.push(feature);
- }
- }
-
- this.layer.eraseFeatures(toErase);
- },
-
- /**
- * Method: createCaptureBox
- * Create the capture box feature
- */
- createCaptureBox: function()
- {
- var origin = null;
- var rotation = 0;
-
- if (this.captureBox.geometry != null)
- {
- origin = this.captureBox.geometry.getCentroid();
- rotation = this.rotation;
- }
- else
- {
- origin = this.wMap.getCurrentCenter();
- }
-
- var factor = this.scaleDenominator / (this.wMap.getMetersPerUnit() * 1000 * 2);
-
- var pointList = [];
- pointList.push(new OpenLayers.Geometry.Point(origin.x - this.paperSize.w * factor, origin.y - this.paperSize.h * factor));
- pointList.push(new OpenLayers.Geometry.Point(origin.x + this.paperSize.w * factor, origin.y - this.paperSize.h * factor));
- pointList.push(new OpenLayers.Geometry.Point(origin.x + this.paperSize.w * factor, origin.y + this.paperSize.h * factor));
- pointList.push(new OpenLayers.Geometry.Point(origin.x - this.paperSize.w * factor, origin.y + this.paperSize.h * factor));
- pointList.push(pointList[0]);
-
- var box = new OpenLayers.Geometry.Polygon(new OpenLayers.Geometry.LinearRing(pointList));
-
- if (rotation != 0)
- {
- box.rotate(rotation, box.getCentroid());
- }
-
- this.captureBox.geometry = box;
- },
-
- /**
- * Method: createRotateHandle
- * Create the rotate handle feature
- */
- createRotateHandle: function()
- {
- var box = this.captureBox.geometry.clone();
- var startPoint = box.getCentroid();
-
- if (this.rotation != 0)
- {
- box.rotate(-this.rotation, startPoint);
- }
-
- var length = this.rotateHandleLength * this.wMap.getResolution();
-
- var endPoint = new OpenLayers.Geometry.Point(startPoint.x, startPoint.y + box.getBounds().getHeight() / 2 + length);
- var line = new OpenLayers.Geometry.LineString([startPoint.clone(), endPoint.clone()]);
-
- if (this.rotation != 0)
- {
- endPoint.rotate(this.rotation, startPoint);
- line.rotate(this.rotation, startPoint);
- }
-
- this.rotateHandle.geometry = line;
- this.rotateHandleStart.geometry = startPoint;
- this.rotateHandleEnd.geometry = endPoint;
- },
-
- /**
- * Method: validateResolution
- * Check if the capture box could display completely on current screen view port.
- * If it cannot, then an warning message will show up to warn the user. Then the user could zoom out to get
- * the box back
- *
- * Returns:
- * (Boolean) True if the box can display completely, otherwise false.
- *
- */
- validateResolution: function()
- {
- if (this.captureBox)
- {
- var screenSize = this.map.getExtent().getSize();
- var boxSize = this.captureBox.geometry.getBounds().getSize();
-
- if (boxSize.w < screenSize.w || boxSize.h < screenSize.h)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- },
-
- /**
- * Method: getCaptureBox
- * Get the capture area.
- */
- getCaptureBox: function()
- {
- var geometry;
- // The capture box is not enabled, so just use the current viewport as capture box
- if (!this.enabled)
- {
- geometry = this.wMap.getCurrentExtents().toGeometry();
- }
- else
- {
- geometry = this.captureBox.geometry;
- }
-
- var info = "";
- var vertices = geometry.getVertices();
- var vertex = null;
-
- for (var i = 0; i < vertices.length; ++i)
- {
- vertex = vertices[i];
- info += vertex.x + "," + vertex.y + ",";
- }
-
- // Remove the last ","
- info = info.substr(0, info.length - 1);
-
- return {geometry:geometry, params:info};
- },
-
- /**
- * Method: getNormalizedCapture
- * Get the normalized capture box
- */
- getNormalizedCapture: function()
- {
- var info = "";
- var geometry = null;
- if (!this.enabled)
- {
- geometry = this.wMap.getCurrentExtents().toGeometry();
- // Calculate the scale denominator
-
- }
- else
- {
- geometry = this.captureBox.geometry.clone();
- geometry.rotate(-this.rotation, geometry.getCentroid());
- }
-
- var vertices = geometry.getVertices();
- var vertex = null;
-
- for (var i = 0; i < vertices.length; ++i)
- {
- vertex = vertices[i];
- info += vertex.x + "," + vertex.y + ",";
- }
-
- // Remove the last ","
- info = info.substr(0, info.length - 1);
-
- return {geometry:geometry, params:info};
- },
-
- /**
- * Method: getCaptureRotation
- * Get the capture rotation
- */
- getCaptureRotation: function()
- {
- if (this.enabled)
- {
- return this.rotation;
- }
- else
- {
- return 0.0;
- }
- },
-
- /**
- * Method: enable
- * Enable the capture box to display it on the map
- */
- enable: function()
- {
- // Reset everything first
- this.disable();
- this.enabled = true;
- },
-
- /**
- * Method: disable
- * Disable the capture box. Then the capture box will not show up on the Map,
- * and the current view port is treated as the capture area
- */
- disable: function()
- {
- this.enabled = false;
-
- this.wMap.message.hide();
- this.clearFeatures();
- this.rotation = 0;
-
- var features = this.layer.features;
- for (var i = 0; i < features.length; ++i)
- {
- features[i].geometry = null;
- }
- },
-
- /**
- * Property: CLASS_NAME. The class name
- */
- CLASS_NAME: "OpenLayers.Control.MapCapturer"
-});
-
Copied: branches/fusion-2.2/widgets/QuickPlot/MapCapturer.js (from rev 2233, trunk/widgets/QuickPlot/MapCapturer.js)
===================================================================
--- branches/fusion-2.2/widgets/QuickPlot/MapCapturer.js (rev 0)
+++ branches/fusion-2.2/widgets/QuickPlot/MapCapturer.js 2010-09-24 18:32:16 UTC (rev 2234)
@@ -0,0 +1,853 @@
+/**
+ * Copyright (C) 2010 Autodesk, Inc. All rights reserved.
+ */
+
+/**
+ * @requires OpenLayers/Control.js
+ * @requires OpenLayers/Handler/Drag.js
+ * @requires OpenLayers/Handler/Feature.js
+ */
+
+/**
+ * Class: OpenLayers.Control.MapCapturer
+ * The MapCapturer control shows a box on the map to illustrate the area that will be captured.
+ * Normally the capture information will be used to print the map. If the MapCapturer is configured not
+ * show the capture box, then the current viewport will be used as the capture area.
+ *
+ * The user can move or rotate the capture box to change the area he'd like to capture.
+ * And the user can hold SHIFT key to snapp to a certain angle when he is rotating the capture box
+ *
+ * Inherits From:
+ * - <OpenLayers.Control>
+ */
+OpenLayers.Control.MapCapturer = OpenLayers.Class(OpenLayers.Control, {
+ /**
+ * Property: layer
+ * {<OpenLayers.Layer.Vector>}
+ */
+ layer: null,
+
+ /**
+ * Property: feature. The active feature which is repsonding to mouse action
+ * {<OpenLayers.Feature.Vector>}
+ */
+ feature: null,
+
+ /**
+ * Property: captureBox. It's the feature represnting the capture area
+ * {<OpenLayers.Feature.Vector>}
+ */
+ captureBox: null,
+
+ /**
+ * Property: rotateHandle. It's the feature representing a rotate handle
+ * (<OpenLayers.Feature.Vector)
+ */
+ rotateHandle: null,
+
+ /**
+ * Property: rotateHandleStart. It's the feature representing the center point of capture box.
+ * And it's also the start point of the rotate handle.
+ * (<OpenLayers.Feature.Vector>)
+ */
+ rotateHandleStart: null,
+
+ /**
+ * Property: rotateHandleEnd. It's the feature responding to the rotate command.
+ * (<OpenLayers.Feature.Vector>)
+ */
+ rotateHandleEnd: null,
+
+ /**
+ * Property: snappingLine. It's the feature indicating a certain angle to snap to. It shows up in the rotate process
+ * (<OpenLayers.Feature.Vector>)
+ */
+ snappingLine: null,
+
+ /**
+ * Property: rotation. The rotation of the capture box
+ * {float}
+ */
+ rotation: 0.0,
+
+ /**
+ * Property: rotateHandleLength. Defines the length of the rotate handle
+ * in pixel. default is 30 pixels
+ * {int}
+ */
+ rotateHandleLength: 30,
+
+ /**
+ * Property: captureBoxStyle. Style for the capture box
+ * {<OpenLayers.Style>}
+ */
+ captureBoxStyle: null,
+
+ /**
+ * Property: rotateHandleStyle. Style for the rotate handle
+ * (<OpenLayers.Style>)
+ */
+ rotateHandleStyle: null,
+
+ /**
+ * Property: rotateHandlePointStyle. Style for the snap handle's start and end points
+ * (<OpenLayers.Style>)
+ */
+ rotateHandlePointStyle: null,
+
+ /**
+ * Property: snappingLineStyle. Style for the snapping line
+ * (<OpenLayers.Style>)
+ */
+ snappingLineStyle: null,
+
+ /**
+ * Indicates if the capture box is enabled. An enabled capture box will show up on the map
+ * {bool}
+ */
+ enabled: false,
+
+ /**
+ * Property: warningMessage. The warning message when the capture box cannot display completely in current zoom level
+ * (string)
+ */
+ warningMessage: OpenLayers.i18n("quickPlotResolutionWarning"),
+
+ /**
+ * Property: rotateSnappingStep. Defines the rotate snapping angle step. In degrees
+ * (int)
+ */
+ rotateSnappingStep: 45,
+
+ /**
+ * Property: rotateSnappingTolerance. Defines the rotate snapping tolerance. In degress
+ */
+ rotateSnappingTolerance: 2,
+
+ /**
+ * Property: lastPixel. The last position the mouse action was responded
+ * {<OpenLayers.Pixel>}
+ */
+ lastPixel: null,
+
+ /**
+ * Constructor: OpenLayers.Control.DragFeature
+ * Create a new control to drag features.
+ *
+ * Parameters:
+ * map - The widget map which encapsulates an OpenLayers.Map
+ *
+ * options - {Object} Optional object whose properties will be set on the control.
+ */
+ initialize: function(map, options)
+ {
+ OpenLayers.Control.prototype.initialize.apply(this, [options]);
+
+ // Initialize the styles
+ this.captureBoxStyle = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style["default"]);
+ this.captureBoxStyle.fillOpacity = 0.8;
+ this.captureBoxStyle.fillColor = "#476387";
+ this.captureBoxStyle.strokeColor = "#39506F";
+
+ this.rotateHandleStyle = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style["default"]);
+ this.rotateHandleStyle.strokeColor = "#39506F";
+ this.rotateHandlePointStyle = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style["default"]);
+ this.rotateHandlePointStyle.strokeColor = "#39506F";
+ this.rotateHandlePointStyle.fillOpacity = 1.0;
+ this.rotateHandlePointStyle.fillColor = "#476387";
+ this.rotateHandlePointStyle.pointRadius = 4;
+
+ this.snappingLineStyle = OpenLayers.Util.extend({}, OpenLayers.Feature.Vector.style["default"]);
+ this.snappingLineStyle.strokeOpacity = 0.8;
+ this.snappingLineStyle.strokeColor = "black";
+ this.snappingLineStyle.strokeDashstyle = "dot";
+
+
+ // The cursor styles
+ this.cursorMove = "move";
+ this.cursorRotate = "url(../../../Widgets/QuickPlot/rotate.cur), default";
+
+ // The widget map
+ this.wMap = map;
+
+ // Create a new layer to show the capture box
+ this.layer = new OpenLayers.Layer.Vector("Map Capturer Layer");
+ map.oMapOL.addLayer(this.layer);
+
+ // Create the features
+ this.captureBox = new OpenLayers.Feature.Vector(null, null, this.captureBoxStyle);
+ this.rotateHandle = new OpenLayers.Feature.Vector(null, null, this.rotateHandleStyle);
+ this.rotateHandleStart = new OpenLayers.Feature.Vector(null, null, this.rotateHandlePointStyle);
+ this.rotateHandleEnd = new OpenLayers.Feature.Vector(null, null, this.rotateHandlePointStyle);
+ this.snappingLine = new OpenLayers.Feature.Vector(null, null, this.snappingLineStyle);
+
+ // Add the features into the layer
+ this.layer.addFeatures([this.captureBox, this.rotateHandle, this.rotateHandleStart, this.rotateHandleEnd, this.snappingLine]);
+
+ // Overwrite layer's drawFeatures method to consider the map capturer's enable / disable
+ this.layer.drawFeature = (function(f, item, style)
+ {
+ if (this.enabled)
+ {
+ f.apply(this.layer, Array.prototype.slice.call(arguments, 1));
+ }
+ }).bind(this, this.layer.drawFeature);
+ this.handlers =
+ {
+ drag: new OpenLayers.Handler.Drag(
+ this, OpenLayers.Util.extend({
+ down: this.downFeature,
+ up: this.upFeature,
+ out: this.cancel,
+ done: this.doneDragging
+ }, this.dragCallbacks)),
+ feature: new OpenLayers.Handler.Feature(
+ this, this.layer, OpenLayers.Util.extend({
+ over: this.overFeature,
+ out: this.outFeature
+ }, this.featureCallbacks),
+ {geometryTypes: this.geometryTypes}
+ )
+ };
+
+ // List to the mouse move event
+ this.handlers.drag.move = this.mouseMove.bind(this);
+
+ // Listen to MAP_EXTENTS_CHANGED event to refresh the outer box because the 'delta' is fixed regardless current scale
+ var oMap = this.wMap.oMapOL;
+ oMap.events.register("zoomend", this, this.drawFeatures.bind(this));
+ },
+
+ /**
+ * APIMethod: destroy
+ * Take care of things that are not handled in superclass
+ */
+ destroy: function()
+ {
+ this.layer = null;
+ OpenLayers.Control.prototype.destroy.apply(this, []);
+ },
+
+ /**
+ * APIMethod: activate
+ * Activate the control and the feature handler.
+ *
+ * Returns:
+ * {Boolean} Successfully activated the control and feature handler.
+ */
+ activate: function()
+ {
+ return (this.handlers.feature.activate() &&
+ OpenLayers.Control.prototype.activate.apply(this, arguments));
+ },
+
+ /**
+ * APIMethod: deactivate
+ * Deactivate the control and all handlers.
+ *
+ * Returns:
+ * {Boolean} Successfully deactivated the control.
+ */
+ deactivate: function() {
+ // The return from the handlers is unimportant in this case
+ this.handlers.feature.deactivate();
+ this.handlers.drag.deactivate();
+ this.feature = null;
+ this.dragging = false;
+ this.lastPixel = null;
+
+ return OpenLayers.Control.prototype.deactivate.apply(this, arguments);
+ },
+
+ /**
+ * Method: overFeature
+ * Called when the feature handler detects a mouse-over on a feature.
+ * This enables the drag control if the event target is the outer polygon,
+ * and the rotate control will be activated if the event target is the inner polygon
+ *
+ * Parameters:
+ * feature - {<OpenLayers.Feature.Vector>} The selected feature.
+ */
+ overFeature: function(feature)
+ {
+ // The feature that the cursor stops on
+ this.stopFeature = feature;
+
+ if(!this.handlers.drag.dragging)
+ {
+ this.feature = feature;
+ this.handlers.drag.activate();
+ this.over = true;
+
+ this.setCursor();
+ }
+ else
+ {
+ if(this.captureBox.id == feature.id || this.rotateHandleEnd.id == feature.id)
+ {
+ this.over = true;
+ }
+ else
+ {
+ this.over = false;
+ }
+ }
+ },
+
+ /**
+ * Method: dragging
+ * Check if it's currently in dragging to move mode
+ */
+ dragging: function()
+ {
+ if (this.feature && this.captureBox)
+ {
+ return this.feature.id == this.captureBox.id || this.feature.id == this.rotateHandleStart.id;
+ }
+
+ return false;
+ },
+
+ /**
+ * Method: dragging
+ * Check if it's currently in dragging to rotate mode
+ */
+ rotating: function()
+ {
+ return this.feature && this.rotateHandleEnd && this.feature.id == this.rotateHandleEnd.id;
+ },
+
+ /**
+ * Method: downFeature
+ * Called when the drag handler detects a mouse-down.
+ *
+ * Parameters:
+ * pixel - {<OpenLayers.Pixel>} Location of the mouse event.
+ */
+ downFeature: function(pixel)
+ {
+ this.setCursor();
+ this.lastPixel = pixel;
+ },
+
+ /**
+ * Method: setCursor
+ * Set the cursor according to current action: moving or rotating
+ */
+ setCursor: function()
+ {
+ if (this.dragging())
+ {
+ this.wMap.setCursor(this.cursorMove);
+ }
+ else if (this.rotating())
+ {
+ this.wMap.setCursor(this.cursorRotate);
+ }
+ },
+ /**
+ * Method: moveFeature
+ * Called when the drag handler detects a mouse-move. Also calls the
+ * optional onDrag method.
+ */
+ mouseMove: function(evt)
+ {
+ if (this.dragging())
+ {
+ this.moveFeature(evt);
+ }
+ else if (this.rotating())
+ {
+ this.rotateFeature(evt);
+ }
+ },
+
+ /**
+ * Method: moveFeature
+ * Move the feature according to the mouse-move
+ */
+ moveFeature: function(evt)
+ {
+ pixel = evt.xy;
+ var res = this.wMap.getResolution();
+ var delta = {x:res * (pixel.x - this.lastPixel.x), y:res * (this.lastPixel.y - pixel.y)};
+
+ var features = this.layer.features;
+ for (var i = 0; i < features.length; ++i)
+ {
+ // Don't touch the snapping line
+ if (features[i].geometry != null && features[i].id != this.snappingLine.id)
+ {
+ features[i].geometry.move(delta.x, delta.y);
+ this.layer.drawFeature(features[i]);
+ }
+ }
+
+ this.lastPixel = pixel;
+ },
+
+ /**
+ * Method: moveFeature
+ * Called when the drag handler detects a mouse-move. Also calls the
+ * optional onDrag method.
+ */
+ rotateFeature: function(evt)
+ {
+ pixel = evt.xy;
+ var centroid = this.captureBox.geometry.getCentroid();
+ var origin = this.map.getViewPortPxFromLonLat(new OpenLayers.LonLat(centroid.x, centroid.y));
+ var angle = this.calculateAngle(pixel, origin);
+ var rotation = this.rotation + angle;
+
+ if (evt.shiftKey)
+ {
+ var a = rotation % this.rotateSnappingStep;
+ var b = Math.round(rotation / this.rotateSnappingStep);
+ var targetRotation = rotation;
+
+ if (Math.abs(a) <= this.rotateSnappingTolerance || Math.abs(a)>= this.rotateSnappingStep - this.rotateSnappingTolerance)
+ {
+ targetRotation = b * this.rotateSnappingStep;
+
+ // Draw the snapping guide
+ if (this.snappingLine.geometry == null)
+ {
+ this.drawSnappingHint(targetRotation);
+ }
+ }
+ else
+ {
+ this.clearSnappingHint();
+ }
+
+ angle = targetRotation - this.rotation;
+ }
+ else
+ {
+ this.clearSnappingHint();
+ }
+
+ this.rotation += angle;
+
+ var features = this.layer.features;
+ for (var i = 0; i < features.length; ++i)
+ {
+ // Don't touch the snapping line here because the snapping line is controlled only by drawSnappingHint
+ if (features[i].geometry != null && features[i].id != this.snappingLine.id)
+ {
+ features[i].geometry.rotate(angle, centroid);
+ this.layer.drawFeature(features[i]);
+ }
+ }
+
+ this.lastPixel = angle == 0 ? this.lastPixel : pixel;
+ },
+
+ /**
+ * Method: drawSnappingHint
+ * Draw the snapping line
+ */
+ drawSnappingHint: function(angle)
+ {
+ var viewSize = this.wMap.getCurrentExtents().getSize();
+ var length = Math.sqrt(Math.pow(viewSize.w, 2) + Math.pow(viewSize.h, 2));
+ var origin = this.captureBox.geometry.getCentroid();
+
+ var points = [];
+ points.push(new OpenLayers.Geometry.Point(origin.x - length, origin.y));
+ points.push(new OpenLayers.Geometry.Point(origin.x + length, origin.y));
+ var hint = new OpenLayers.Geometry.LineString(points);
+
+ hint.rotate(angle + 90, origin);
+
+ this.snappingLine.geometry = hint;
+ this.layer.drawFeature(this.snappingLine);
+ },
+
+ /**
+ * Method: clearSnappingHint
+ * Clear the snapping line
+ */
+ clearSnappingHint: function()
+ {
+ if (this.snappingLine != null && this.snappingLine.geometry != null)
+ {
+ this.layer.eraseFeatures([this.snappingLine]);
+ this.snappingLine.geometry = null;
+ }
+ },
+
+ /**
+ * Method: calculateAngle
+ * Calculates the rotate angle, in degree and counterclockwise
+ */
+ calculateAngle: function(pixel, origin)
+ {
+ var angle1 = Math.atan2(pixel.y - origin.y, pixel.x - origin.x);
+ var angle2 = Math.atan2(this.lastPixel.y - origin.y, this.lastPixel.x - origin.x);
+ return (angle2 - angle1) * 180 / Math.PI;
+ },
+
+ /**
+ * Method: upFeature
+ * Called when the drag handler detects a mouse-up.
+ *
+ * Parameters:
+ * pixel - {<OpenLayers.Pixel>} Location of the mouse event.
+ */
+ upFeature: function(pixel)
+ {
+ if(!this.over)
+ {
+ this.handlers.drag.deactivate();
+ }
+ else
+ {
+ // Set the last-stop feature to be the active one
+ this.feature = this.stopFeature;
+ // Set the correct cursor
+ this.setCursor();
+ }
+
+ this.clearSnappingHint();
+ },
+
+ /**
+ * Method: outFeature
+ * Called when the feature handler detects a mouse-out on a feature.
+ *
+ * Parameters:
+ * feature - {<OpenLayers.Feature.Vector>} The feature that the mouse left.
+ */
+ outFeature: function(feature)
+ {
+ if(!this.handlers.drag.dragging)
+ {
+ this.over = false;
+ this.handlers.drag.deactivate();
+ this.wMap.setCursor("auto");
+ this.feature = null;
+ }
+ else
+ {
+ if(this.feature.id == feature.id)
+ {
+ this.over = false;
+ }
+ }
+ },
+
+ /**
+ * Method: cancel
+ * Called when the drag handler detects a mouse-out (from the map viewport).
+ */
+ cancel: function()
+ {
+ this.handlers.drag.deactivate();
+ this.over = false;
+ },
+
+ /**
+ * Method: setMap
+ * Set the map property for the control and all handlers.
+ *
+ * Parameters:
+ * map - {<OpenLayers.Map>} The control's map.
+ */
+ setMap: function(map)
+ {
+ this.handlers.drag.setMap(map);
+ this.handlers.feature.setMap(map);
+ OpenLayers.Control.prototype.setMap.apply(this, arguments);
+ },
+
+ /**
+ * Method: setRegion
+ * Set the size of the capture box. Then the box will be redrawn on the map
+ *
+ * Parameters:
+ * paperSize - {<OpenLayers.Size>} The paper size, in mm
+ * scaleDenominator - The denominator of target scale
+ */
+ setSize: function(paperSize, scaleDenominator)
+ {
+ this.paperSize = paperSize;
+ this.scaleDenominator = scaleDenominator;
+ this.drawFeatures();
+ // Active the handler
+ this.activate();
+ },
+
+ /**
+ * Method: drawFeatures
+ * Draw the capture box, rotate handle etc. on the map
+ */
+ drawFeatures: function()
+ {
+ // The paper size is not set yet, so don't draw the features
+ if (!this.paperSize)
+ {
+ return;
+ }
+
+ // Clear the previous drawn features
+ this.clearFeatures();
+
+ this.createCaptureBox();
+ this.createRotateHandle();
+
+ // Draw the box only when control is enabled and the resolution is valid
+ if (this.enabled)
+ {
+ if (this.validateResolution())
+ {
+ this.layer.features.each(function(item){item.layer.drawFeature(item);});
+ this.wMap.message.hide();
+ }
+ else
+ {
+ this.wMap.message.warn(this.warningMessage);
+ }
+ }
+ },
+
+ /**
+ * Method: clearFeatures:
+ * Clear the capture box, rotate handle etc. from the map
+ */
+ clearFeatures: function()
+ {
+ // Clear the previous drawn features
+ var features = this.layer.features;
+ var toErase = [];
+ var feature = null;
+
+ for (var i = 0; i < features.length; ++i)
+ {
+ feature = features[i];
+ if (feature.geometry != null)
+ {
+ toErase.push(feature);
+ }
+ }
+
+ this.layer.eraseFeatures(toErase);
+ },
+
+ /**
+ * Method: createCaptureBox
+ * Create the capture box feature
+ */
+ createCaptureBox: function()
+ {
+ var origin = null;
+ var rotation = 0;
+
+ if (this.captureBox.geometry != null)
+ {
+ origin = this.captureBox.geometry.getCentroid();
+ rotation = this.rotation;
+ }
+ else
+ {
+ origin = this.wMap.getCurrentCenter();
+ }
+
+ var factor = this.scaleDenominator / (this.wMap.getMetersPerUnit() * 1000 * 2);
+
+ var pointList = [];
+ pointList.push(new OpenLayers.Geometry.Point(origin.x - this.paperSize.w * factor, origin.y - this.paperSize.h * factor));
+ pointList.push(new OpenLayers.Geometry.Point(origin.x + this.paperSize.w * factor, origin.y - this.paperSize.h * factor));
+ pointList.push(new OpenLayers.Geometry.Point(origin.x + this.paperSize.w * factor, origin.y + this.paperSize.h * factor));
+ pointList.push(new OpenLayers.Geometry.Point(origin.x - this.paperSize.w * factor, origin.y + this.paperSize.h * factor));
+ pointList.push(pointList[0]);
+
+ var box = new OpenLayers.Geometry.Polygon(new OpenLayers.Geometry.LinearRing(pointList));
+
+ if (rotation != 0)
+ {
+ box.rotate(rotation, box.getCentroid());
+ }
+
+ this.captureBox.geometry = box;
+ },
+
+ /**
+ * Method: createRotateHandle
+ * Create the rotate handle feature
+ */
+ createRotateHandle: function()
+ {
+ var box = this.captureBox.geometry.clone();
+ var startPoint = box.getCentroid();
+
+ if (this.rotation != 0)
+ {
+ box.rotate(-this.rotation, startPoint);
+ }
+
+ var length = this.rotateHandleLength * this.wMap.getResolution();
+
+ var endPoint = new OpenLayers.Geometry.Point(startPoint.x, startPoint.y + box.getBounds().getHeight() / 2 + length);
+ var line = new OpenLayers.Geometry.LineString([startPoint.clone(), endPoint.clone()]);
+
+ if (this.rotation != 0)
+ {
+ endPoint.rotate(this.rotation, startPoint);
+ line.rotate(this.rotation, startPoint);
+ }
+
+ this.rotateHandle.geometry = line;
+ this.rotateHandleStart.geometry = startPoint;
+ this.rotateHandleEnd.geometry = endPoint;
+ },
+
+ /**
+ * Method: validateResolution
+ * Check if the capture box could display completely on current screen view port.
+ * If it cannot, then an warning message will show up to warn the user. Then the user could zoom out to get
+ * the box back
+ *
+ * Returns:
+ * (Boolean) True if the box can display completely, otherwise false.
+ *
+ */
+ validateResolution: function()
+ {
+ if (this.captureBox)
+ {
+ var screenSize = this.map.getExtent().getSize();
+ var boxSize = this.captureBox.geometry.getBounds().getSize();
+
+ if (boxSize.w < screenSize.w || boxSize.h < screenSize.h)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ },
+
+ /**
+ * Method: getCaptureBox
+ * Get the capture area.
+ */
+ getCaptureBox: function()
+ {
+ var geometry;
+ // The capture box is not enabled, so just use the current viewport as capture box
+ if (!this.enabled)
+ {
+ geometry = this.wMap.getCurrentExtents().toGeometry();
+ }
+ else
+ {
+ geometry = this.captureBox.geometry;
+ }
+
+ var info = "";
+ var vertices = geometry.getVertices();
+ var vertex = null;
+
+ for (var i = 0; i < vertices.length; ++i)
+ {
+ vertex = vertices[i];
+ info += vertex.x + "," + vertex.y + ",";
+ }
+
+ // Remove the last ","
+ info = info.substr(0, info.length - 1);
+
+ return {geometry:geometry, params:info};
+ },
+
+ /**
+ * Method: getNormalizedCapture
+ * Get the normalized capture box
+ */
+ getNormalizedCapture: function()
+ {
+ var info = "";
+ var geometry = null;
+ if (!this.enabled)
+ {
+ geometry = this.wMap.getCurrentExtents().toGeometry();
+ // Calculate the scale denominator
+
+ }
+ else
+ {
+ geometry = this.captureBox.geometry.clone();
+ geometry.rotate(-this.rotation, geometry.getCentroid());
+ }
+
+ var vertices = geometry.getVertices();
+ var vertex = null;
+
+ for (var i = 0; i < vertices.length; ++i)
+ {
+ vertex = vertices[i];
+ info += vertex.x + "," + vertex.y + ",";
+ }
+
+ // Remove the last ","
+ info = info.substr(0, info.length - 1);
+
+ return {geometry:geometry, params:info};
+ },
+
+ /**
+ * Method: getCaptureRotation
+ * Get the capture rotation
+ */
+ getCaptureRotation: function()
+ {
+ if (this.enabled)
+ {
+ return this.rotation;
+ }
+ else
+ {
+ return 0.0;
+ }
+ },
+
+ /**
+ * Method: enable
+ * Enable the capture box to display it on the map
+ */
+ enable: function()
+ {
+ // Reset everything first
+ this.disable();
+ this.enabled = true;
+ },
+
+ /**
+ * Method: disable
+ * Disable the capture box. Then the capture box will not show up on the Map,
+ * and the current view port is treated as the capture area
+ */
+ disable: function()
+ {
+ this.enabled = false;
+
+ this.wMap.message.hide();
+ this.clearFeatures();
+ this.rotation = 0;
+
+ var features = this.layer.features;
+ for (var i = 0; i < features.length; ++i)
+ {
+ features[i].geometry = null;
+ }
+ },
+
+ /**
+ * Property: CLASS_NAME. The class name
+ */
+ CLASS_NAME: "OpenLayers.Control.MapCapturer"
+});
+
Deleted: branches/fusion-2.2/widgets/QuickPlot/PreviewDialog.js
===================================================================
--- trunk/widgets/QuickPlot/PreviewDialog.js 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/widgets/QuickPlot/PreviewDialog.js 2010-09-24 18:32:16 UTC (rev 2234)
@@ -1,368 +0,0 @@
-/**
- * Copyright (C) 2010 Autodesk, Inc. All rights reserved.
- */
-
-var PreviewDialog = function(options)
-{
- this.initialize(options);
-};
-
-PreviewDialog.prototype =
-{
- jxDialog : null,
- previewFrame : null,
- innerDoc : null,
- indicator : null,
- previewPicture : null,
- printPicture : null,
- topLeftXYLabel : null,
- bottomRightXYLabel : null,
- previewContainer : null,
- pictureContainer : null,
- printButton : null,
- cancelButton : null,
- loadingErrorMessage : null,
- printStyle: null,
- previewStyle: null,
- // The offset from the border of the paper, in px
- csLabelOffset : 5,
- // The print margin, in inches
- printMargin: 0,
- mapInfo : {sessionID: "", name: ""},
- captureInfo : {topLeftCs : {x : 0, y : 0}, bottomRightCs : {x : 0, y : 0}, paperSize:{w : 0, h : 0}, scaleDenominator : 0, rotation : 0, params1 : "", params2 : ""},
- params : null,
-
- // The callback will be called right after the JxDialog content has been loaded.
- // The callback accepts 1 parameter: windowName (string)
- // Here it is used to submit the quick plot form to the preview frame.
- contentLoadedCallback : null,
-
- initialize : function(options)
- {
- this.mapInfo = options.mapInfo;
- this.captureInfo = options.captureInfo;
- this.params = options.params;
-
- this.jxDialog = new Jx.Dialog(
- {
- modal: true,
- width:400,
- height: 400,
- content: '<table border="0" cellspacing="0" cellpadding="0" id="PreviewContainer">' +
- ' <tr>' +
- ' <td>' +
- ' <iframe id="PreviewFrame" scrolling="no" frameborder="0" style="border: 0px; width: 400px; height: 300px;" src="about:blank"></iframe>' +
- ' </td>' +
- ' </tr>' +
- '</table>'
- });
-
- this.jxDialog.addEvent("open", this.jxDialogOpened.bind(this, true));
- this.jxDialog.addEvent("contentLoaded", this.jxDialogContentLoaded.bind(this));
- // Listen to the fade complete event to close the dialog
- var o = this.jxDialog.domObj.get("tween").addEvent("complete", this.closeJxDialog.bind(this));
- },
-
- open : function(contentLoadedCallback)
- {
- this.contentLoadedCallback = contentLoadedCallback;
- this.jxDialog.loadContent(this.jxDialog.content);
- this.jxDialog.open();
- },
-
- print : function()
- {
- //
- this.previewFrame.contentWindow.doPrint();
- },
-
- cancel : function()
- {
- this.indicator.style.display = "inline";
- this.indicator.style.visibility = "visible";
- this.indicator.setOpacity(1);
-
- this.loadingErrorMessage.fade(0);
- this.loadingErrorMessage.style.display = "none";
- // Hide the picture but don't set the 'display' style property to avoid messing the print layout up
- this.printPicture.style.height = "0px";
-
- if (this.topLeftXYLabel && this.bottomRightXYLabel)
- {
- this.topLeftXYLabel.setOpacity(0);
- this.bottomRightXYLabel.setOpacity(0);
- this.printLabel.setOpacity(0);
- // Remove the labels
- this.topLeftXYLabel.parentNode.removeChild(this.topLeftXYLabel);
- this.topLeftXYLabel = null;
- this.bottomRightXYLabel.parentNode.removeChild(this.bottomRightXYLabel);
- this.bottomRightXYLabel = null;
- this.printLabel.parentNode.removeChild(this.printLabel);
- this.printLabel = null;
- }
-
- this.isClosing = true;
- this.jxDialog.blanket.fade(0);
- this.jxDialog.domObj.fade(0);
- },
-
- jxDialogContentLoaded : function()
- {
- // Set the window name for the preview frame
- this.previewFrame = $("PreviewFrame");
- this.previewFrame.contentWindow.name = "QuickPlotPreviewFrame";
-
- // Inform the listener that the content is ready, then the Quick Plot panel can submit its data to the preview frame
- if (this.contentLoadedCallback)
- {
- this.contentLoadedCallback(this.previewFrame.contentWindow.name);
- }
- },
-
- jxDialogOpened : function(setFrameUrl)
- {
- if (this.previewInnerIsLoaded)
- {
- // Resize the preview frame according to the monitor resolution
- this.innerDoc = this.previewFrame.contentWindow.document;
- var box = $(document.body).getDimensions();
- // Width of preview dialog = screen width * factor
- var factor = 0.5;
- this.previewContainer = $(this.innerDoc.getElementById("PreviewContainer"));
- this.previewContainer.style.width = box.width * factor + "px";
- this.pictureContainer = $(this.innerDoc.getElementById("PictureContainer"));
- var pcBox = this.pictureContainer.getContentBoxSize();
-
- this.indicator = $(this.innerDoc.getElementById("ProgressIndicator"));
-
- var paperSize = this.captureInfo.paperSize;
- this.paperSize = paperSize;
-
- var ratio = paperSize.w / paperSize.h;
-
- // Resize the indicator
- this.indicator.style.width = pcBox.width + "px";
- this.indicator.style.height = pcBox.width / ratio + "px";
- // Set a explicit size to the container
- this.pictureContainer.style.width = this.indicator.style.width;
- this.pictureContainer.style.height = this.indicator.style.height;
- // Get the styles for the print picture
- var rules = this.innerDoc.styleSheets[1].cssRules || this.innerDoc.styleSheets[1].rules;
- this.previewStyle = rules[0];
- rules = this.innerDoc.styleSheets[2].cssRules || this.innerDoc.styleSheets[2].rules;
- this.printStyle = rules[0];
-
- // Reset the background
- this.indicator.style.background = "url(progress_indicator.gif) no-repeat cneter center";
-
- this.loadingErrorMessage = $(this.innerDoc.getElementById("PictureLoadingErrorMessage"));
- this.loadingErrorMessage.setOpacity(0);
-
- // Set the picture url
- var src = "GeneratePicture.php?session_id=" + this.mapInfo.sessionID +
- "&map_name=" + this.mapInfo.name +
- "&print_dpi=" + this.params.printDpi +
- "&paper_size=" + this.captureInfo.paperSize.w + "," + this.captureInfo.paperSize.h +
- "&box=" + this.captureInfo.params1 +
- "&normalized_box=" + this.captureInfo.params2 +
- "&scale_denominator=" + this.captureInfo.scaleDenominator +
- "&rotation=" + this.captureInfo.rotation;
-
- this.printPicture = $(this.innerDoc.getElementById("PrintPicture"));
- this.printPicture.src = src;
-
- // Listen to print picture onload vent
- this.printPicture.addEvent("load", this.printPictureLoaded.bind(this));
- this.printPicture.addEvent("error", this.printPictureLoadError.bind(this));
-
- var innerBox = this.previewContainer.getMarginBoxSize();
- // Resize the frame according to the inner container's
- this.previewFrame.style.width = innerBox.width + "px";
- this.previewFrame.style.height = innerBox.height + "px";
-
- // Hide the title bar
- this.jxDialog.title.style.display = "none";
- // Hide the chrome
- this.jxDialog.chrome.style.display = "none";
-
- // Disable the print button until the image is ready
- this.printButton = this.innerDoc.getElementById("PrintButton");
- this.cancelButton = this.innerDoc.getElementById("CancelButton");
- this.printButton.disabled = true;
- this.cancelButton.disabled = true;
-
- var delta = {x: 22, y: 43};
- var container = $("PreviewContainer");
- var size = container.getMarginBoxSize();
- this.jxDialog.resize(size.width + delta.x, size.height + delta.y, true);
-
- this.jxDialog.blanket.fade(0.2);
- this.jxDialog.domObj.fade(1);
- this.resizeIsPending = false;
-
- this.previewInnerIsLoaded = false;
- }
- else
- {
- this.jxDialog.blanket.setOpacity(0);
- this.jxDialog.domObj.setOpacity(0);
- this.resizeIsPending = true;
- }
- },
-
- previewInnerLoaded: function()
- {
- this.previewInnerIsLoaded = true;
- if (this.resizeIsPending)
- {
- this.jxDialogOpened(false);
- }
- },
-
- closeJxDialog : function()
- {
- if (this.isClosing)
- {
- this.jxDialog.close();
- this.isClosing = false;
- }
- },
-
- printPictureLoaded : function()
- {
- var size = {width: parseInt(this.indicator.style.width), height: parseInt(this.indicator.style.height)};
-
- this.indicator.fade(0);
- this.indicator.style.display = "none";
-
- // Set the preview size
- this.printPicture.setOpacity(0);
- // Clear the inline style
- this.printPicture.style.width = "";
- this.previewStyle.style.width = size.width + "px";
- this.previewStyle.style.height = size.height + "px";
- this.printPicture.fade(1);
-
- // Set the print size
- // NOTE: It works only with a 96 dpi device dpi
- var deviceDpi = 96;
- var idealSize = {width:(this.paperSize.w / 25.4 - 2 * this.printMargin) * deviceDpi, height:(this.paperSize.h / 25.4 - 2 * this.printMargin) * deviceDpi};
- // Get the size of the print frame
- var docSize = $(this.innerDoc.body).getContentBoxSize();
- var realHeight = idealSize.height - (docSize.height - size.height);
- var realWidth = realHeight * this.paperSize.w / this.paperSize.h;
- if (realWidth > idealSize.width)
- {
- realWidth = idealSize.width;
- realHeight = realWidth / (this.paperSize.w / this.paperSize.h);
- }
-
- this.printStyle.style.width = realWidth + "px";
- this.printStyle.style.height = realHeight + "px";
-
- // Create the coordinates labels
- if (!this.topLeftXYLabel)
- {
- this.topLeftXYLabel = this.createCoordinateLabel(this.pictureContainer, this.captureInfo.topLeftCs.x, this.captureInfo.topLeftCs.y, "TopLeftXYLabel");
- this.topLeftXYLabel.setOpacity(0);
- }
-
- if (!this.bottomRightXYLabel)
- {
- this.bottomRightXYLabel = this.createCoordinateLabel(this.pictureContainer, this.captureInfo.bottomRightCs.x, this.captureInfo.bottomRightCs.y, "BottomRightXYLabel");
- this.bottomRightXYLabel.setOpacity(0);
- }
-
- if (!this.printLabel)
- {
- this.printLabel = this.createCoordinateLabel(this.pictureContainer, this.captureInfo.bottomRightCs.x, this.captureInfo.bottomRightCs.y, "PrintLabel");
- }
-
- // Set the correct positions for the labels
- var pos = this.getContentPosition(this.pictureContainer);
- var picDim = this.pictureContainer.getContentBoxSize();
- this.topLeftXYLabel.style.left = pos.left + this.csLabelOffset + "px";
- this.topLeftXYLabel.style.top = pos.top + this.csLabelOffset + "px";
- var labelDim = this.bottomRightXYLabel.getMarginBoxSize();
- this.bottomRightXYLabel.className = "ScreenOnly";
- this.bottomRightXYLabel.style.left = pos.left + picDim.width - this.csLabelOffset - labelDim.width + "px";
- this.bottomRightXYLabel.style.top = pos.top + picDim.height - this.csLabelOffset - labelDim.height + "px";
- labelDim = this.printLabel.getMarginBoxSize();
- this.printLabel.className = "PrintOnly";
- this.printLabel.style.left = pos.left + realWidth - this.csLabelOffset - labelDim.width + "px";
- this.printLabel.style.top = pos.top + realHeight - this.csLabelOffset - labelDim.height + "px";
-
- this.topLeftXYLabel.fade(1);
- this.bottomRightXYLabel.fade(1);
- // Enable the print button
- this.printButton.disabled = false;
- this.cancelButton.disabled = false;
- },
-
- printPictureLoadError : function()
- {
- this.indicator.fade(0);
- this.indicator.style.display = "none";
- this.loadingErrorMessage.style.display = "inline";
- this.loadingErrorMessage.setOpacity(0);
- this.loadingErrorMessage.fade(1);
- this.cancelButton.disabled = false;
- },
-
- createCoordinateLabel: function(container, cX, cY, id)
- {
- cX = cX + "";
- cY = cY + "";
- var digits = 6;
-
- var index = cX.indexOf(".");
- if (index > -1)
- {
- cX = cX.substr(0, index + digits + 1);
- }
-
- index = cY.indexOf(".");
- if (index > -1)
- {
- cY = cY.substr(0, index + digits + 1);
- }
-
- var label = this.innerDoc.createElement("div");
- container.appendChild(label);
- label.id = id;
- label.style.cssText = "border:solid 1px black; padding:1px; background:#F2F2F2; color:black; font-size:8pt; z-index:1000; " +
- "position:absolute; white-space:nowrap";
- label.innerHTML = "X: " + cX + " Y: " + cY;
-
- return $(label);
- },
-
- getContentPosition: function(element)
- {
- var offsetLeft = 0;
- var offsetTop = 0;
- var border = 0;
-
- while (element && element.tagName.toLowerCase() != "body" && element.tagName.toLowerCase() != "html")
- {
- offsetLeft += element.offsetLeft;
- offsetTop += element.offsetTop;
-
- border = parseInt(element.style.borderLeftWidth);
- if (!isNaN(border))
- {
- offsetLeft += border;
- }
-
- border = parseInt(element.style.borderTopWidth);
- if (!isNaN(border))
- {
- offsetTop += border;
- }
-
- element = element.offsetParent;
- }
-
- return {left: offsetLeft, top: offsetTop};
- }
-};
\ No newline at end of file
Copied: branches/fusion-2.2/widgets/QuickPlot/PreviewDialog.js (from rev 2233, trunk/widgets/QuickPlot/PreviewDialog.js)
===================================================================
--- branches/fusion-2.2/widgets/QuickPlot/PreviewDialog.js (rev 0)
+++ branches/fusion-2.2/widgets/QuickPlot/PreviewDialog.js 2010-09-24 18:32:16 UTC (rev 2234)
@@ -0,0 +1,368 @@
+/**
+ * Copyright (C) 2010 Autodesk, Inc. All rights reserved.
+ */
+
+var PreviewDialog = function(options)
+{
+ this.initialize(options);
+};
+
+PreviewDialog.prototype =
+{
+ jxDialog : null,
+ previewFrame : null,
+ innerDoc : null,
+ indicator : null,
+ previewPicture : null,
+ printPicture : null,
+ topLeftXYLabel : null,
+ bottomRightXYLabel : null,
+ previewContainer : null,
+ pictureContainer : null,
+ printButton : null,
+ cancelButton : null,
+ loadingErrorMessage : null,
+ printStyle: null,
+ previewStyle: null,
+ // The offset from the border of the paper, in px
+ csLabelOffset : 5,
+ // The print margin, in inches
+ printMargin: 0,
+ mapInfo : {sessionID: "", name: ""},
+ captureInfo : {topLeftCs : {x : 0, y : 0}, bottomRightCs : {x : 0, y : 0}, paperSize:{w : 0, h : 0}, scaleDenominator : 0, rotation : 0, params1 : "", params2 : ""},
+ params : null,
+
+ // The callback will be called right after the JxDialog content has been loaded.
+ // The callback accepts 1 parameter: windowName (string)
+ // Here it is used to submit the quick plot form to the preview frame.
+ contentLoadedCallback : null,
+
+ initialize : function(options)
+ {
+ this.mapInfo = options.mapInfo;
+ this.captureInfo = options.captureInfo;
+ this.params = options.params;
+
+ this.jxDialog = new Jx.Dialog(
+ {
+ modal: true,
+ width:400,
+ height: 400,
+ content: '<table border="0" cellspacing="0" cellpadding="0" id="PreviewContainer">' +
+ ' <tr>' +
+ ' <td>' +
+ ' <iframe id="PreviewFrame" scrolling="no" frameborder="0" style="border: 0px; width: 400px; height: 300px;" src="about:blank"></iframe>' +
+ ' </td>' +
+ ' </tr>' +
+ '</table>'
+ });
+
+ this.jxDialog.addEvent("open", this.jxDialogOpened.bind(this, true));
+ this.jxDialog.addEvent("contentLoaded", this.jxDialogContentLoaded.bind(this));
+ // Listen to the fade complete event to close the dialog
+ var o = this.jxDialog.domObj.get("tween").addEvent("complete", this.closeJxDialog.bind(this));
+ },
+
+ open : function(contentLoadedCallback)
+ {
+ this.contentLoadedCallback = contentLoadedCallback;
+ this.jxDialog.loadContent(this.jxDialog.content);
+ this.jxDialog.open();
+ },
+
+ print : function()
+ {
+ //
+ this.previewFrame.contentWindow.doPrint();
+ },
+
+ cancel : function()
+ {
+ this.indicator.style.display = "inline";
+ this.indicator.style.visibility = "visible";
+ this.indicator.setOpacity(1);
+
+ this.loadingErrorMessage.fade(0);
+ this.loadingErrorMessage.style.display = "none";
+ // Hide the picture but don't set the 'display' style property to avoid messing the print layout up
+ this.printPicture.style.height = "0px";
+
+ if (this.topLeftXYLabel && this.bottomRightXYLabel)
+ {
+ this.topLeftXYLabel.setOpacity(0);
+ this.bottomRightXYLabel.setOpacity(0);
+ this.printLabel.setOpacity(0);
+ // Remove the labels
+ this.topLeftXYLabel.parentNode.removeChild(this.topLeftXYLabel);
+ this.topLeftXYLabel = null;
+ this.bottomRightXYLabel.parentNode.removeChild(this.bottomRightXYLabel);
+ this.bottomRightXYLabel = null;
+ this.printLabel.parentNode.removeChild(this.printLabel);
+ this.printLabel = null;
+ }
+
+ this.isClosing = true;
+ this.jxDialog.blanket.fade(0);
+ this.jxDialog.domObj.fade(0);
+ },
+
+ jxDialogContentLoaded : function()
+ {
+ // Set the window name for the preview frame
+ this.previewFrame = $("PreviewFrame");
+ this.previewFrame.contentWindow.name = "QuickPlotPreviewFrame";
+
+ // Inform the listener that the content is ready, then the Quick Plot panel can submit its data to the preview frame
+ if (this.contentLoadedCallback)
+ {
+ this.contentLoadedCallback(this.previewFrame.contentWindow.name);
+ }
+ },
+
+ jxDialogOpened : function(setFrameUrl)
+ {
+ if (this.previewInnerIsLoaded)
+ {
+ // Resize the preview frame according to the monitor resolution
+ this.innerDoc = this.previewFrame.contentWindow.document;
+ var box = $(document.body).getDimensions();
+ // Width of preview dialog = screen width * factor
+ var factor = 0.5;
+ this.previewContainer = $(this.innerDoc.getElementById("PreviewContainer"));
+ this.previewContainer.style.width = box.width * factor + "px";
+ this.pictureContainer = $(this.innerDoc.getElementById("PictureContainer"));
+ var pcBox = this.pictureContainer.getContentBoxSize();
+
+ this.indicator = $(this.innerDoc.getElementById("ProgressIndicator"));
+
+ var paperSize = this.captureInfo.paperSize;
+ this.paperSize = paperSize;
+
+ var ratio = paperSize.w / paperSize.h;
+
+ // Resize the indicator
+ this.indicator.style.width = pcBox.width + "px";
+ this.indicator.style.height = pcBox.width / ratio + "px";
+ // Set a explicit size to the container
+ this.pictureContainer.style.width = this.indicator.style.width;
+ this.pictureContainer.style.height = this.indicator.style.height;
+ // Get the styles for the print picture
+ var rules = this.innerDoc.styleSheets[1].cssRules || this.innerDoc.styleSheets[1].rules;
+ this.previewStyle = rules[0];
+ rules = this.innerDoc.styleSheets[2].cssRules || this.innerDoc.styleSheets[2].rules;
+ this.printStyle = rules[0];
+
+ // Reset the background
+ this.indicator.style.background = "url(progress_indicator.gif) no-repeat cneter center";
+
+ this.loadingErrorMessage = $(this.innerDoc.getElementById("PictureLoadingErrorMessage"));
+ this.loadingErrorMessage.setOpacity(0);
+
+ // Set the picture url
+ var src = "GeneratePicture.php?session_id=" + this.mapInfo.sessionID +
+ "&map_name=" + this.mapInfo.name +
+ "&print_dpi=" + this.params.printDpi +
+ "&paper_size=" + this.captureInfo.paperSize.w + "," + this.captureInfo.paperSize.h +
+ "&box=" + this.captureInfo.params1 +
+ "&normalized_box=" + this.captureInfo.params2 +
+ "&scale_denominator=" + this.captureInfo.scaleDenominator +
+ "&rotation=" + this.captureInfo.rotation;
+
+ this.printPicture = $(this.innerDoc.getElementById("PrintPicture"));
+ this.printPicture.src = src;
+
+ // Listen to print picture onload vent
+ this.printPicture.addEvent("load", this.printPictureLoaded.bind(this));
+ this.printPicture.addEvent("error", this.printPictureLoadError.bind(this));
+
+ var innerBox = this.previewContainer.getMarginBoxSize();
+ // Resize the frame according to the inner container's
+ this.previewFrame.style.width = innerBox.width + "px";
+ this.previewFrame.style.height = innerBox.height + "px";
+
+ // Hide the title bar
+ this.jxDialog.title.style.display = "none";
+ // Hide the chrome
+ this.jxDialog.chrome.style.display = "none";
+
+ // Disable the print button until the image is ready
+ this.printButton = this.innerDoc.getElementById("PrintButton");
+ this.cancelButton = this.innerDoc.getElementById("CancelButton");
+ this.printButton.disabled = true;
+ this.cancelButton.disabled = true;
+
+ var delta = {x: 22, y: 43};
+ var container = $("PreviewContainer");
+ var size = container.getMarginBoxSize();
+ this.jxDialog.resize(size.width + delta.x, size.height + delta.y, true);
+
+ this.jxDialog.blanket.fade(0.2);
+ this.jxDialog.domObj.fade(1);
+ this.resizeIsPending = false;
+
+ this.previewInnerIsLoaded = false;
+ }
+ else
+ {
+ this.jxDialog.blanket.setOpacity(0);
+ this.jxDialog.domObj.setOpacity(0);
+ this.resizeIsPending = true;
+ }
+ },
+
+ previewInnerLoaded: function()
+ {
+ this.previewInnerIsLoaded = true;
+ if (this.resizeIsPending)
+ {
+ this.jxDialogOpened(false);
+ }
+ },
+
+ closeJxDialog : function()
+ {
+ if (this.isClosing)
+ {
+ this.jxDialog.close();
+ this.isClosing = false;
+ }
+ },
+
+ printPictureLoaded : function()
+ {
+ var size = {width: parseInt(this.indicator.style.width), height: parseInt(this.indicator.style.height)};
+
+ this.indicator.fade(0);
+ this.indicator.style.display = "none";
+
+ // Set the preview size
+ this.printPicture.setOpacity(0);
+ // Clear the inline style
+ this.printPicture.style.width = "";
+ this.previewStyle.style.width = size.width + "px";
+ this.previewStyle.style.height = size.height + "px";
+ this.printPicture.fade(1);
+
+ // Set the print size
+ // NOTE: It works only with a 96 dpi device dpi
+ var deviceDpi = 96;
+ var idealSize = {width:(this.paperSize.w / 25.4 - 2 * this.printMargin) * deviceDpi, height:(this.paperSize.h / 25.4 - 2 * this.printMargin) * deviceDpi};
+ // Get the size of the print frame
+ var docSize = $(this.innerDoc.body).getContentBoxSize();
+ var realHeight = idealSize.height - (docSize.height - size.height);
+ var realWidth = realHeight * this.paperSize.w / this.paperSize.h;
+ if (realWidth > idealSize.width)
+ {
+ realWidth = idealSize.width;
+ realHeight = realWidth / (this.paperSize.w / this.paperSize.h);
+ }
+
+ this.printStyle.style.width = realWidth + "px";
+ this.printStyle.style.height = realHeight + "px";
+
+ // Create the coordinates labels
+ if (!this.topLeftXYLabel)
+ {
+ this.topLeftXYLabel = this.createCoordinateLabel(this.pictureContainer, this.captureInfo.topLeftCs.x, this.captureInfo.topLeftCs.y, "TopLeftXYLabel");
+ this.topLeftXYLabel.setOpacity(0);
+ }
+
+ if (!this.bottomRightXYLabel)
+ {
+ this.bottomRightXYLabel = this.createCoordinateLabel(this.pictureContainer, this.captureInfo.bottomRightCs.x, this.captureInfo.bottomRightCs.y, "BottomRightXYLabel");
+ this.bottomRightXYLabel.setOpacity(0);
+ }
+
+ if (!this.printLabel)
+ {
+ this.printLabel = this.createCoordinateLabel(this.pictureContainer, this.captureInfo.bottomRightCs.x, this.captureInfo.bottomRightCs.y, "PrintLabel");
+ }
+
+ // Set the correct positions for the labels
+ var pos = this.getContentPosition(this.pictureContainer);
+ var picDim = this.pictureContainer.getContentBoxSize();
+ this.topLeftXYLabel.style.left = pos.left + this.csLabelOffset + "px";
+ this.topLeftXYLabel.style.top = pos.top + this.csLabelOffset + "px";
+ var labelDim = this.bottomRightXYLabel.getMarginBoxSize();
+ this.bottomRightXYLabel.className = "ScreenOnly";
+ this.bottomRightXYLabel.style.left = pos.left + picDim.width - this.csLabelOffset - labelDim.width + "px";
+ this.bottomRightXYLabel.style.top = pos.top + picDim.height - this.csLabelOffset - labelDim.height + "px";
+ labelDim = this.printLabel.getMarginBoxSize();
+ this.printLabel.className = "PrintOnly";
+ this.printLabel.style.left = pos.left + realWidth - this.csLabelOffset - labelDim.width + "px";
+ this.printLabel.style.top = pos.top + realHeight - this.csLabelOffset - labelDim.height + "px";
+
+ this.topLeftXYLabel.fade(1);
+ this.bottomRightXYLabel.fade(1);
+ // Enable the print button
+ this.printButton.disabled = false;
+ this.cancelButton.disabled = false;
+ },
+
+ printPictureLoadError : function()
+ {
+ this.indicator.fade(0);
+ this.indicator.style.display = "none";
+ this.loadingErrorMessage.style.display = "inline";
+ this.loadingErrorMessage.setOpacity(0);
+ this.loadingErrorMessage.fade(1);
+ this.cancelButton.disabled = false;
+ },
+
+ createCoordinateLabel: function(container, cX, cY, id)
+ {
+ cX = cX + "";
+ cY = cY + "";
+ var digits = 6;
+
+ var index = cX.indexOf(".");
+ if (index > -1)
+ {
+ cX = cX.substr(0, index + digits + 1);
+ }
+
+ index = cY.indexOf(".");
+ if (index > -1)
+ {
+ cY = cY.substr(0, index + digits + 1);
+ }
+
+ var label = this.innerDoc.createElement("div");
+ container.appendChild(label);
+ label.id = id;
+ label.style.cssText = "border:solid 1px black; padding:1px; background:#F2F2F2; color:black; font-size:8pt; z-index:1000; " +
+ "position:absolute; white-space:nowrap";
+ label.innerHTML = "X: " + cX + " Y: " + cY;
+
+ return $(label);
+ },
+
+ getContentPosition: function(element)
+ {
+ var offsetLeft = 0;
+ var offsetTop = 0;
+ var border = 0;
+
+ while (element && element.tagName.toLowerCase() != "body" && element.tagName.toLowerCase() != "html")
+ {
+ offsetLeft += element.offsetLeft;
+ offsetTop += element.offsetTop;
+
+ border = parseInt(element.style.borderLeftWidth);
+ if (!isNaN(border))
+ {
+ offsetLeft += border;
+ }
+
+ border = parseInt(element.style.borderTopWidth);
+ if (!isNaN(border))
+ {
+ offsetTop += border;
+ }
+
+ element = element.offsetParent;
+ }
+
+ return {left: offsetLeft, top: offsetTop};
+ }
+};
\ No newline at end of file
Deleted: branches/fusion-2.2/widgets/QuickPlot/QuickPlotPanel.js
===================================================================
--- trunk/widgets/QuickPlot/QuickPlotPanel.js 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/widgets/QuickPlot/QuickPlotPanel.js 2010-09-24 18:32:16 UTC (rev 2234)
@@ -1,155 +0,0 @@
-/**
- * Copyright (C) 2010 Autodesk, Inc. All rights reserved.
- */
-
-function restoreUI()
-{
- setAdvancedOptionsUI(false);
-
- // Read the last used options
- lastPaperSize = getParent().Cookie.read("QuickPlotLastUsedPaperSize");
- lastScale = getParent().Cookie.read("QuickPlotLastUsedScaling");
- lastDPI = getParent().Cookie.read("QuickPlotLastUsedDPI");
-
- if (lastPaperSize != null)
- {
- document.getElementById("PaperList").value = lastPaperSize;
- }
-
- if (lastScale != null)
- {
- document.getElementById("ScalingList").value = lastScale;
- }
-
- if (lastDPI != null)
- {
- document.getElementById("DPIList").value = lastDPI;
- }
-}
-
-function setAdvancedOptionsUI(enabled)
-{
- document.getElementById("PaperList").disabled = !enabled;
- document.getElementById("ScalingList").disabled = !enabled;
- document.getElementById("DPIList").disabled = !enabled;
-
- var mapCapturer = getParent().Fusion.getWidgetsByType("QuickPlot")[0].mapCapturer;
-
- if (enabled)
- {
- mapCapturer.enable();
- drawCaptureBox();
- }
- else
- {
- mapCapturer.disable();
- }
-}
-
-function generatePlot()
-{
- var widget = getParent().Fusion.getWidgetsByType("QuickPlot")[0];
- var mapCapturer = widget.mapCapturer;
-
- if (!advancedOptionsOn())
- {
- // Get paper size. Use the last used paper size by default
- mapCapturer.setSize(getPaperSize(), getScale());
-
- }
-
- widget.preview(submitForm, getPrintDpi());
-}
-
-function submitForm(windowName)
-{
- var form = document.getElementById("Form1");
- form.target = windowName;
- // Save the advanced options to a cookie
- var cookieDuration = 365;
- getParent().Cookie.write("QuickPlotLastUsedPaperSize", document.getElementById("PaperList").value, {duration:cookieDuration});
- getParent().Cookie.write("QuickPlotLastUsedScaling", document.getElementById("ScalingList").value, {duration:cookieDuration});
- getParent().Cookie.write("QuickPlotLastUsedDPI", document.getElementById("DPIList").value, {duration:cookieDuration});
- form.submit();
-}
-
-
-function advancedOptionsOn()
-{
- var o = document.getElementById("AdvancedOptionsCheckBox");
- if (o && o.checked)
- {
- return true;
- }
-
- return false;
-}
-
-function getPaperSize()
-{
- var value = document.getElementById("PaperList").value.split(",");
- var size = {w: parseFloat(value[0]), h: parseFloat(value[1])};
-
- if (!advancedOptionsOn())
- {
- // Calculate the paper size to make sure it has a same ratio with the viweport
- var map = getParent().Fusion.getWidgetById("Map");
- var paperRatio = size.w / size.h;
- var viewSize = map.getSize();
- var viewRatio = viewSize.w / viewSize.h;
-
- if (paperRatio > viewRatio)
- {
- size.w = size.h * viewRatio;
- }
- else
- {
- size.h = size.w / viewRatio;
- }
- }
-
- return size;
-}
-
-function getScale()
-{
- var scale = 0;
- if (advancedOptionsOn())
- {
- scale = document.getElementById("ScalingList").value;
- }
- else
- {
- var map = getParent().Fusion.getWidgetById("Map");
- var paperSize = getPaperSize();
- var viewerSize = map.getCurrentExtents().getSize();
- var factor = map.getMetersPerUnit();
-
- if (paperSize.w / paperSize.h > viewerSize.w / viewerSize.h)
- {
- scale = viewerSize.h * factor * 1000 / paperSize.h;
- }
- else
- {
- scale = viewerSize.w * factor * 1000 / paperSize.w;
- }
- }
-
- scale = parseInt(scale);
- // Set the value to a hidden field so that it could be sent by POST method
- // We cannot rely on the ScalingList.value because we have to handle also the viewport print
- document.getElementById("ScaleDenominator").value = scale;
-
- return scale;
-}
-
-function getPrintDpi()
-{
- return document.getElementById("DPIList").value;
-}
-
-function drawCaptureBox()
-{
- var mapCapturer = getParent().Fusion.getWidgetsByType("QuickPlot")[0].mapCapturer;
- mapCapturer.setSize(getPaperSize(), getScale());
-}
Copied: branches/fusion-2.2/widgets/QuickPlot/QuickPlotPanel.js (from rev 2233, trunk/widgets/QuickPlot/QuickPlotPanel.js)
===================================================================
--- branches/fusion-2.2/widgets/QuickPlot/QuickPlotPanel.js (rev 0)
+++ branches/fusion-2.2/widgets/QuickPlot/QuickPlotPanel.js 2010-09-24 18:32:16 UTC (rev 2234)
@@ -0,0 +1,155 @@
+/**
+ * Copyright (C) 2010 Autodesk, Inc. All rights reserved.
+ */
+
+function restoreUI()
+{
+ setAdvancedOptionsUI(false);
+
+ // Read the last used options
+ lastPaperSize = getParent().Cookie.read("QuickPlotLastUsedPaperSize");
+ lastScale = getParent().Cookie.read("QuickPlotLastUsedScaling");
+ lastDPI = getParent().Cookie.read("QuickPlotLastUsedDPI");
+
+ if (lastPaperSize != null)
+ {
+ document.getElementById("PaperList").value = lastPaperSize;
+ }
+
+ if (lastScale != null)
+ {
+ document.getElementById("ScalingList").value = lastScale;
+ }
+
+ if (lastDPI != null)
+ {
+ document.getElementById("DPIList").value = lastDPI;
+ }
+}
+
+function setAdvancedOptionsUI(enabled)
+{
+ document.getElementById("PaperList").disabled = !enabled;
+ document.getElementById("ScalingList").disabled = !enabled;
+ document.getElementById("DPIList").disabled = !enabled;
+
+ var mapCapturer = getParent().Fusion.getWidgetsByType("QuickPlot")[0].mapCapturer;
+
+ if (enabled)
+ {
+ mapCapturer.enable();
+ drawCaptureBox();
+ }
+ else
+ {
+ mapCapturer.disable();
+ }
+}
+
+function generatePlot()
+{
+ var widget = getParent().Fusion.getWidgetsByType("QuickPlot")[0];
+ var mapCapturer = widget.mapCapturer;
+
+ if (!advancedOptionsOn())
+ {
+ // Get paper size. Use the last used paper size by default
+ mapCapturer.setSize(getPaperSize(), getScale());
+
+ }
+
+ widget.preview(submitForm, getPrintDpi());
+}
+
+function submitForm(windowName)
+{
+ var form = document.getElementById("Form1");
+ form.target = windowName;
+ // Save the advanced options to a cookie
+ var cookieDuration = 365;
+ getParent().Cookie.write("QuickPlotLastUsedPaperSize", document.getElementById("PaperList").value, {duration:cookieDuration});
+ getParent().Cookie.write("QuickPlotLastUsedScaling", document.getElementById("ScalingList").value, {duration:cookieDuration});
+ getParent().Cookie.write("QuickPlotLastUsedDPI", document.getElementById("DPIList").value, {duration:cookieDuration});
+ form.submit();
+}
+
+
+function advancedOptionsOn()
+{
+ var o = document.getElementById("AdvancedOptionsCheckBox");
+ if (o && o.checked)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+function getPaperSize()
+{
+ var value = document.getElementById("PaperList").value.split(",");
+ var size = {w: parseFloat(value[0]), h: parseFloat(value[1])};
+
+ if (!advancedOptionsOn())
+ {
+ // Calculate the paper size to make sure it has a same ratio with the viweport
+ var map = getParent().Fusion.getWidgetById("Map");
+ var paperRatio = size.w / size.h;
+ var viewSize = map.getSize();
+ var viewRatio = viewSize.w / viewSize.h;
+
+ if (paperRatio > viewRatio)
+ {
+ size.w = size.h * viewRatio;
+ }
+ else
+ {
+ size.h = size.w / viewRatio;
+ }
+ }
+
+ return size;
+}
+
+function getScale()
+{
+ var scale = 0;
+ if (advancedOptionsOn())
+ {
+ scale = document.getElementById("ScalingList").value;
+ }
+ else
+ {
+ var map = getParent().Fusion.getWidgetById("Map");
+ var paperSize = getPaperSize();
+ var viewerSize = map.getCurrentExtents().getSize();
+ var factor = map.getMetersPerUnit();
+
+ if (paperSize.w / paperSize.h > viewerSize.w / viewerSize.h)
+ {
+ scale = viewerSize.h * factor * 1000 / paperSize.h;
+ }
+ else
+ {
+ scale = viewerSize.w * factor * 1000 / paperSize.w;
+ }
+ }
+
+ scale = parseInt(scale);
+ // Set the value to a hidden field so that it could be sent by POST method
+ // We cannot rely on the ScalingList.value because we have to handle also the viewport print
+ document.getElementById("ScaleDenominator").value = scale;
+
+ return scale;
+}
+
+function getPrintDpi()
+{
+ return document.getElementById("DPIList").value;
+}
+
+function drawCaptureBox()
+{
+ var mapCapturer = getParent().Fusion.getWidgetsByType("QuickPlot")[0].mapCapturer;
+ mapCapturer.setSize(getPaperSize(), getScale());
+}
Deleted: branches/fusion-2.2/widgets/QuickPlot/QuickPlotPanel.php
===================================================================
--- trunk/widgets/QuickPlot/QuickPlotPanel.php 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/widgets/QuickPlot/QuickPlotPanel.php 2010-09-24 18:32:16 UTC (rev 2234)
@@ -1,43 +0,0 @@
-<?php
-
- $fusionMGpath = '../../layers/MapGuide/php/';
- include $fusionMGpath . 'Common.php';
-
- $locale = GetDefaultLocale();
- $popup = 0;
- $mapName = "";
- $sessionId = "";
- $us = "";
- $popup = "false";
-
- GetRequestParameters();
-
- $templ = file_get_contents("QuickPlotPanel.templ");
- SetLocalizedFilesPath(GetLocalizationPath());
- $templ = Localize($templ, $locale, GetClientOS());
-
- $vpath = GetSurroundVirtualPath();
- $jsPath = "";
- print sprintf($templ, $popup, $jsPath);
-
-function GetParameters($params)
-{
- global $target, $cmdIndex, $clientWidth, $mapName, $sessionId, $popup, $us, $locale, $popup;
-
- $locale = $params['locale'];
- $mapName = $params['mapname'];
- $sessionId = $params['session'];
- $popup = $params['popup'];
- $us = $params['us'];
- $popup = $params['popup'];
-}
-
-function GetRequestParameters()
-{
- if($_SERVER['REQUEST_METHOD'] == "POST")
- GetParameters($_POST);
- else
- GetParameters($_GET);
-}
-
-?>
Copied: branches/fusion-2.2/widgets/QuickPlot/QuickPlotPanel.php (from rev 2233, trunk/widgets/QuickPlot/QuickPlotPanel.php)
===================================================================
--- branches/fusion-2.2/widgets/QuickPlot/QuickPlotPanel.php (rev 0)
+++ branches/fusion-2.2/widgets/QuickPlot/QuickPlotPanel.php 2010-09-24 18:32:16 UTC (rev 2234)
@@ -0,0 +1,43 @@
+<?php
+
+ $fusionMGpath = '../../layers/MapGuide/php/';
+ include $fusionMGpath . 'Common.php';
+
+ $locale = GetDefaultLocale();
+ $popup = 0;
+ $mapName = "";
+ $sessionId = "";
+ $us = "";
+ $popup = "false";
+
+ GetRequestParameters();
+
+ $templ = file_get_contents("QuickPlotPanel.templ");
+ SetLocalizedFilesPath(GetLocalizationPath());
+ $templ = Localize($templ, $locale, GetClientOS());
+
+ $vpath = GetSurroundVirtualPath();
+ $jsPath = "";
+ print sprintf($templ, $popup, $jsPath);
+
+function GetParameters($params)
+{
+ global $target, $cmdIndex, $clientWidth, $mapName, $sessionId, $popup, $us, $locale, $popup;
+
+ $locale = $params['locale'];
+ $mapName = $params['mapname'];
+ $sessionId = $params['session'];
+ $popup = $params['popup'];
+ $us = $params['us'];
+ $popup = $params['popup'];
+}
+
+function GetRequestParameters()
+{
+ if($_SERVER['REQUEST_METHOD'] == "POST")
+ GetParameters($_POST);
+ else
+ GetParameters($_GET);
+}
+
+?>
Deleted: branches/fusion-2.2/widgets/QuickPlot/QuickPlotPanel.templ
===================================================================
--- trunk/widgets/QuickPlot/QuickPlotPanel.templ 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/widgets/QuickPlot/QuickPlotPanel.templ 2010-09-24 18:32:16 UTC (rev 2234)
@@ -1,150 +0,0 @@
-<html>
-<head>
-<title>__#QUICKPLOT_HEADER#__</title>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-<style type="text/css">
-body, table, td, div, select, input
-{
- font: 8pt/1em __#@font#__;
-}
-
-div.Label
-{
- padding:5px 0px;
-}
-
-div.Ctrl
-{
- padding:5px 0px;
-}
-
-div.Title
-{
- font-size: 14px;
- font-weight: bold;
- padding: 10px 0px;
-}
-
-div.HPlaceholder5px
-{
- font-size:0px;
- height:5px;
-}
-
-div.ButtonContainer
-{
- padding: 5px 0px;
- text-align: right;
-}
-
-.FixWidth
-{
- width: 100%%;
-}
-
-input.Button
-{
- width:75px;
- height:23px;
- margin-left:7px;
-}
-</style>
-<script language="javascript" type="text/javascript">
-var popup = %s;
-
-// Get window where the Fusion object is available
-function getParent()
-{
- if (popup)
- {
- return opener;
- }
- else if (parent.Fusion)
- {
- return parent;
- }
- else if (parent.parent.Fusion)
- {
- return parent.parent;
- }
-
- return null;
-}
-
-</script>
-<script language="javascript" type="text/javascript" src="%sQuickPlotPanel.js"></script>
-
-</head>
-<body onload="restoreUI()">
- <form id="Form1" name="Form1" method="post" action="QuickPlotPreviewInner.php">
- <div class="Title FixWidth">__#QUICKPLOT_HEADER#__</div>
- <div class="Label ">__#QUICKPLOT_TITLE#__</div>
- <div class="Ctrl">
- <input type="text" class="FixWidth" name="{field:title}" maxLength=100"/>
- </div>
- <div class="HPlaceholder5px"></div>
- <div class="HPlaceholder5px"></div>
- <div class="Label">__#QUICKPLOT_SUBTITLE#__</div>
- <div class="Ctrl">
- <input type="text" class="FixWidth" name="{field:sub_title}" maxLength=100"/>
- </div>
- <div class="HPlaceholder5px"></div>
- <div class="HPlaceholder5px"></div>
- <div class="HPlaceholder5px"></div>
- <div class="Label">
- <table cellspacing="0" cellpadding="0">
- <tr>
- <td><input type="checkbox" id="AdvancedOptionsCheckBox" onclick="setAdvancedOptionsUI(this.checked)" /></td>
- <td><label for="AdvancedOptionsCheckBox">__#QUICKPLOT_ADVANCED_OPTIONS#__</label></td>
- </tr>
- </table>
- </div>
- <div class="HPlaceholder5px"></div>
- <div class="Label">__#QUICKPLOT_PAPER_SIZE#__</div>
- <div class="Ctrl">
- <!--
- The pre-defined paper size list. The value for each "option" item is in this format: [width,height]. The unit is in millimeter.
- We can change the html code to add more paper size or remove some ones.
- -->
- <select class="FixWidth" id="PaperList" onchange="drawCaptureBox(this)">
- <option value="297.0,210.0">A4 (210 MM x 297 MM)</option>
- <option value="420.0,297.0">A3 (297 MM) x 420 MM</option>
- <option value="279.4,215.9">Letter (8.50 x 11.00 Inches)</option>
- <option value="355.6,215.9">Legal (8.50 x 14.00 Inches)</option>
- </select>
- </div>
- <div class="HPlaceholder5px"></div>
- <div class="HPlaceholder5px"></div>
- <div class="Label">__#QUICKPLOT_SCALING#__</div>
- <div class="Ctrl">
- <!--
- The pre-defined scales. The value for each "option" item is the scale denominator.
- We can change the html code to extend the pre-defined scales
- -->
- <select class="FixWidth" id="ScalingList" onchange="drawCaptureBox(this)">
- <option value="500">1 : 500</option>
- <option value="1000">1 : 1000</option>
- <option value="2500">1 : 2500</option>
- <option value="5000">1 : 5000</option>
- </select>
- </div>
- <div class="Label">__#QUICKPLOT_DPI#__</div>
- <div class="Ctrl">
- <!--
- The pre-defined print DPI.
- We can change the html code to extend the pre-defined values
- -->
- <select class="FixWidth" id="DPIList">
- <option value="96">96</option>
- <option value="150" selected>150</option>
- <option value="300">300</option>
- <option value="600">600</option>
- </select>
- </div>
- <input type="hidden" id="ScaleDenominator" name="scale_denominator" />
- <div class="ButtonContainer FixWidth">
- <input type="button" class="Button" value="__#QUICKPLOT_GENERATE#__" onclick="generatePlot()" />
- </div>
- </form>
-</body>
-</html>
Copied: branches/fusion-2.2/widgets/QuickPlot/QuickPlotPanel.templ (from rev 2233, trunk/widgets/QuickPlot/QuickPlotPanel.templ)
===================================================================
--- branches/fusion-2.2/widgets/QuickPlot/QuickPlotPanel.templ (rev 0)
+++ branches/fusion-2.2/widgets/QuickPlot/QuickPlotPanel.templ 2010-09-24 18:32:16 UTC (rev 2234)
@@ -0,0 +1,150 @@
+<html>
+<head>
+<title>__#QUICKPLOT_HEADER#__</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<style type="text/css">
+body, table, td, div, select, input
+{
+ font: 8pt/1em __#@font#__;
+}
+
+div.Label
+{
+ padding:5px 0px;
+}
+
+div.Ctrl
+{
+ padding:5px 0px;
+}
+
+div.Title
+{
+ font-size: 14px;
+ font-weight: bold;
+ padding: 10px 0px;
+}
+
+div.HPlaceholder5px
+{
+ font-size:0px;
+ height:5px;
+}
+
+div.ButtonContainer
+{
+ padding: 5px 0px;
+ text-align: right;
+}
+
+.FixWidth
+{
+ width: 100%%;
+}
+
+input.Button
+{
+ width:75px;
+ height:23px;
+ margin-left:7px;
+}
+</style>
+<script language="javascript" type="text/javascript">
+var popup = %s;
+
+// Get window where the Fusion object is available
+function getParent()
+{
+ if (popup)
+ {
+ return opener;
+ }
+ else if (parent.Fusion)
+ {
+ return parent;
+ }
+ else if (parent.parent.Fusion)
+ {
+ return parent.parent;
+ }
+
+ return null;
+}
+
+</script>
+<script language="javascript" type="text/javascript" src="%sQuickPlotPanel.js"></script>
+
+</head>
+<body onload="restoreUI()">
+ <form id="Form1" name="Form1" method="post" action="QuickPlotPreviewInner.php">
+ <div class="Title FixWidth">__#QUICKPLOT_HEADER#__</div>
+ <div class="Label ">__#QUICKPLOT_TITLE#__</div>
+ <div class="Ctrl">
+ <input type="text" class="FixWidth" name="{field:title}" maxLength=100"/>
+ </div>
+ <div class="HPlaceholder5px"></div>
+ <div class="HPlaceholder5px"></div>
+ <div class="Label">__#QUICKPLOT_SUBTITLE#__</div>
+ <div class="Ctrl">
+ <input type="text" class="FixWidth" name="{field:sub_title}" maxLength=100"/>
+ </div>
+ <div class="HPlaceholder5px"></div>
+ <div class="HPlaceholder5px"></div>
+ <div class="HPlaceholder5px"></div>
+ <div class="Label">
+ <table cellspacing="0" cellpadding="0">
+ <tr>
+ <td><input type="checkbox" id="AdvancedOptionsCheckBox" onclick="setAdvancedOptionsUI(this.checked)" /></td>
+ <td><label for="AdvancedOptionsCheckBox">__#QUICKPLOT_ADVANCED_OPTIONS#__</label></td>
+ </tr>
+ </table>
+ </div>
+ <div class="HPlaceholder5px"></div>
+ <div class="Label">__#QUICKPLOT_PAPER_SIZE#__</div>
+ <div class="Ctrl">
+ <!--
+ The pre-defined paper size list. The value for each "option" item is in this format: [width,height]. The unit is in millimeter.
+ We can change the html code to add more paper size or remove some ones.
+ -->
+ <select class="FixWidth" id="PaperList" onchange="drawCaptureBox(this)">
+ <option value="297.0,210.0">A4 (210 MM x 297 MM)</option>
+ <option value="420.0,297.0">A3 (297 MM) x 420 MM</option>
+ <option value="279.4,215.9">Letter (8.50 x 11.00 Inches)</option>
+ <option value="355.6,215.9">Legal (8.50 x 14.00 Inches)</option>
+ </select>
+ </div>
+ <div class="HPlaceholder5px"></div>
+ <div class="HPlaceholder5px"></div>
+ <div class="Label">__#QUICKPLOT_SCALING#__</div>
+ <div class="Ctrl">
+ <!--
+ The pre-defined scales. The value for each "option" item is the scale denominator.
+ We can change the html code to extend the pre-defined scales
+ -->
+ <select class="FixWidth" id="ScalingList" onchange="drawCaptureBox(this)">
+ <option value="500">1 : 500</option>
+ <option value="1000">1 : 1000</option>
+ <option value="2500">1 : 2500</option>
+ <option value="5000">1 : 5000</option>
+ </select>
+ </div>
+ <div class="Label">__#QUICKPLOT_DPI#__</div>
+ <div class="Ctrl">
+ <!--
+ The pre-defined print DPI.
+ We can change the html code to extend the pre-defined values
+ -->
+ <select class="FixWidth" id="DPIList">
+ <option value="96">96</option>
+ <option value="150" selected>150</option>
+ <option value="300">300</option>
+ <option value="600">600</option>
+ </select>
+ </div>
+ <input type="hidden" id="ScaleDenominator" name="scale_denominator" />
+ <div class="ButtonContainer FixWidth">
+ <input type="button" class="Button" value="__#QUICKPLOT_GENERATE#__" onclick="generatePlot()" />
+ </div>
+ </form>
+</body>
+</html>
Deleted: branches/fusion-2.2/widgets/QuickPlot/QuickPlotPreview.js
===================================================================
--- trunk/widgets/QuickPlot/QuickPlotPreview.js 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/widgets/QuickPlot/QuickPlotPreview.js 2010-09-24 18:32:16 UTC (rev 2234)
@@ -1,27 +0,0 @@
-/**
- * Copyright (C) 2010 Autodesk, Inc. All rights reserved.
- */
-
-function innerLoaded()
-{
- if (parent.Fusion)
- {
- parent.Fusion.getWidgetsByType("QuickPlot")[0].previewInnerLoaded();
- }
-}
-
-function printIt()
-{
- parent.Fusion.getWidgetsByType("QuickPlot")[0].printPreview();
-}
-
-function cancelPreview()
-{
- parent.Fusion.getWidgetsByType("QuickPlot")[0].cancelPreview();
-}
-
-function doPrint()
-{
- window.focus();
- window.print();
-}
Copied: branches/fusion-2.2/widgets/QuickPlot/QuickPlotPreview.js (from rev 2233, trunk/widgets/QuickPlot/QuickPlotPreview.js)
===================================================================
--- branches/fusion-2.2/widgets/QuickPlot/QuickPlotPreview.js (rev 0)
+++ branches/fusion-2.2/widgets/QuickPlot/QuickPlotPreview.js 2010-09-24 18:32:16 UTC (rev 2234)
@@ -0,0 +1,27 @@
+/**
+ * Copyright (C) 2010 Autodesk, Inc. All rights reserved.
+ */
+
+function innerLoaded()
+{
+ if (parent.Fusion)
+ {
+ parent.Fusion.getWidgetsByType("QuickPlot")[0].previewInnerLoaded();
+ }
+}
+
+function printIt()
+{
+ parent.Fusion.getWidgetsByType("QuickPlot")[0].printPreview();
+}
+
+function cancelPreview()
+{
+ parent.Fusion.getWidgetsByType("QuickPlot")[0].cancelPreview();
+}
+
+function doPrint()
+{
+ window.focus();
+ window.print();
+}
Deleted: branches/fusion-2.2/widgets/QuickPlot/QuickPlotPreviewInner.php
===================================================================
--- trunk/widgets/QuickPlot/QuickPlotPreviewInner.php 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/widgets/QuickPlot/QuickPlotPreviewInner.php 2010-09-24 18:32:16 UTC (rev 2234)
@@ -1,69 +0,0 @@
-<?php
-
- $fusionMGpath = '../../layers/MapGuide/php/';
- include $fusionMGpath . 'Common.php';
-
- $locale = GetDefaultLocale();
- $scaleDenominator;
- $annotations;
-
- $args = GetRequestMethod();
- GetParameters($args);
-
- $templ = file_get_contents("QuickPlotPreviewInner.templ");
- SetLocalizedFilesPath(GetLocalizationPath());
-
- // Localize the page
- $templ = Localize($templ, $locale, GetClientOS());
-
- // Set some annotation labels in the page by replacing the placeholders in the html code
- $templ = str_replace(array_keys($annotations), array_values($annotations), $templ);
- // Set the date annotation according to its format mask
- $pattern = "/\{date:(.+?)\}/";
- $matches = array();
- if (preg_match($pattern, $templ, $matches))
- {
- $mask = $matches[1];
- $date = date($mask);
- $templ = preg_replace($pattern, $date, $templ);
- }
-
- $jsPath = "";
- print sprintf($templ, $jsPath);
-?>
-
-<?php
-function GetParameters($params)
-{
- global $scaleDenominator, $annotations;
-
- $scaleDenominator = intval($params["scale_denominator"]);
- $annotations = array();
-
- // The parameters whose name matches this pattern will be treated as annotation
- $pattern = "/^\{field:.+\}$/i";
- foreach ($params as $key => $value)
- {
- if (preg_match($pattern, $key) == 1)
- {
- $annotations[$key] = htmlspecialchars(urlDecode($value), ENT_QUOTES);
- }
- }
-
- // The scale annotation
- $annotations["{scale}"] = "1 : " . $scaleDenominator;
-}
-
-function GetRequestMethod()
-{
- if($_SERVER['REQUEST_METHOD'] == "POST")
- {
- return $_POST;
- }
- else
- {
- return $_GET;
- }
-}
-
-?>
Copied: branches/fusion-2.2/widgets/QuickPlot/QuickPlotPreviewInner.php (from rev 2233, trunk/widgets/QuickPlot/QuickPlotPreviewInner.php)
===================================================================
--- branches/fusion-2.2/widgets/QuickPlot/QuickPlotPreviewInner.php (rev 0)
+++ branches/fusion-2.2/widgets/QuickPlot/QuickPlotPreviewInner.php 2010-09-24 18:32:16 UTC (rev 2234)
@@ -0,0 +1,69 @@
+<?php
+
+ $fusionMGpath = '../../layers/MapGuide/php/';
+ include $fusionMGpath . 'Common.php';
+
+ $locale = GetDefaultLocale();
+ $scaleDenominator;
+ $annotations;
+
+ $args = GetRequestMethod();
+ GetParameters($args);
+
+ $templ = file_get_contents("QuickPlotPreviewInner.templ");
+ SetLocalizedFilesPath(GetLocalizationPath());
+
+ // Localize the page
+ $templ = Localize($templ, $locale, GetClientOS());
+
+ // Set some annotation labels in the page by replacing the placeholders in the html code
+ $templ = str_replace(array_keys($annotations), array_values($annotations), $templ);
+ // Set the date annotation according to its format mask
+ $pattern = "/\{date:(.+?)\}/";
+ $matches = array();
+ if (preg_match($pattern, $templ, $matches))
+ {
+ $mask = $matches[1];
+ $date = date($mask);
+ $templ = preg_replace($pattern, $date, $templ);
+ }
+
+ $jsPath = "";
+ print sprintf($templ, $jsPath);
+?>
+
+<?php
+function GetParameters($params)
+{
+ global $scaleDenominator, $annotations;
+
+ $scaleDenominator = intval($params["scale_denominator"]);
+ $annotations = array();
+
+ // The parameters whose name matches this pattern will be treated as annotation
+ $pattern = "/^\{field:.+\}$/i";
+ foreach ($params as $key => $value)
+ {
+ if (preg_match($pattern, $key) == 1)
+ {
+ $annotations[$key] = htmlspecialchars(urlDecode($value), ENT_QUOTES);
+ }
+ }
+
+ // The scale annotation
+ $annotations["{scale}"] = "1 : " . $scaleDenominator;
+}
+
+function GetRequestMethod()
+{
+ if($_SERVER['REQUEST_METHOD'] == "POST")
+ {
+ return $_POST;
+ }
+ else
+ {
+ return $_GET;
+ }
+}
+
+?>
Deleted: branches/fusion-2.2/widgets/QuickPlot/QuickPlotPreviewInner.templ
===================================================================
--- trunk/widgets/QuickPlot/QuickPlotPreviewInner.templ 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/widgets/QuickPlot/QuickPlotPreviewInner.templ 2010-09-24 18:32:16 UTC (rev 2234)
@@ -1,85 +0,0 @@
-<html>
-<head>
-<title>__#QUICKPLOT_HEADER#__</title>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-<style type="text/css">
-body, table, td, div, input
-{
- font: 9pt/1.5em __#@font#__;
-}
-
-td.LegalNotice
-{
- font-size: 8pt;
-}
-
-input.Button
-{
- width:75px;
- height:23px;
- margin-left:7px;
-}
-</style>
-
-<style type="text/css" media="screen">
-#PrintPicture { }
-
-.PrintOnly
-{
- display:none;
-}
-</style>
-
-<style type="text/css" media="print">
-#PrintPicture { }
-input.Button
-{
- visibility:hidden;
-}
-
-.ScreenOnly
-{
- display: none;
-}
-</style>
-
-<script language="javascript" type="text/javascript" src="%sQuickPlotPreview.js"></script>
-</head>
-<body style="margin:0px" onLoad="innerLoaded()">
-<table cellspacing="10" cellpadding="0" style="width:100%%; border-width:0px" id="PreviewContainer">
- <tr>
- <td><table style="width:100%%" border="0" cellspacing="0" cellpadding="0" id="AnnotationContainer">
- <tr>
- <td style="width:100%%">{field:title}</td>
- <!--
- The date format mask follows the php date() function's instruction
- see also here for more reference: http://cn.php.net/manual/en/function.date.php
- -->
- <td style="white-space:nowrap">{date:m/d/Y}</td>
- </tr>
- <tr>
- <td>{field:sub_title}</td>
- <td style="white-space:nowrap">__#QUICKPLOT_SCALE_LABEL#__: {scale}</td>
- </tr>
- </table></td>
- </tr>
- <tr>
- <td id="PictureContainer" style="border: solid 1px black; text-align:center; vertical-align:center;">
- <img style="width:1px; background:url(progress_indicator.gif) no-repeat center center" id="ProgressIndicator" src="pixel.gif" />
- <img style="width:1px" id="PrintPicture" src="pixel.gif" />
- <span id="PictureLoadingErrorMessage" style="display:none; text-align:center">__#QUICKPLOT_PREVIEW_ERROR#__</span>
- </td>
- </tr>
- <tr>
- <td><table width="100%%" border="0" cellspacing="0" cellpadding="0">
- <tr>
- <!-- Legal notice. Just replace it with the necessary statement -->
- <td style="width:100%%" class="LegalNotice">The materials available at this web site are for informational purposes only and do not constitute a legal document.</td>
- <td style="white-space:nowrap"><input type="button" id="PrintButton" class="Button" onClick="printIt()" value="__#QUICKPLOT_PRINT#__" /><input type="button" id="CancelButton" class="Button" onClick="cancelPreview()" value="__#QUICKPLOT_CANCEL#__" />
- </td>
- </tr>
- </table></td>
- </tr>
-</table>
-</body>
-</html>
Copied: branches/fusion-2.2/widgets/QuickPlot/QuickPlotPreviewInner.templ (from rev 2233, trunk/widgets/QuickPlot/QuickPlotPreviewInner.templ)
===================================================================
--- branches/fusion-2.2/widgets/QuickPlot/QuickPlotPreviewInner.templ (rev 0)
+++ branches/fusion-2.2/widgets/QuickPlot/QuickPlotPreviewInner.templ 2010-09-24 18:32:16 UTC (rev 2234)
@@ -0,0 +1,85 @@
+<html>
+<head>
+<title>__#QUICKPLOT_HEADER#__</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<style type="text/css">
+body, table, td, div, input
+{
+ font: 9pt/1.5em __#@font#__;
+}
+
+td.LegalNotice
+{
+ font-size: 8pt;
+}
+
+input.Button
+{
+ width:75px;
+ height:23px;
+ margin-left:7px;
+}
+</style>
+
+<style type="text/css" media="screen">
+#PrintPicture { }
+
+.PrintOnly
+{
+ display:none;
+}
+</style>
+
+<style type="text/css" media="print">
+#PrintPicture { }
+input.Button
+{
+ visibility:hidden;
+}
+
+.ScreenOnly
+{
+ display: none;
+}
+</style>
+
+<script language="javascript" type="text/javascript" src="%sQuickPlotPreview.js"></script>
+</head>
+<body style="margin:0px" onLoad="innerLoaded()">
+<table cellspacing="10" cellpadding="0" style="width:100%%; border-width:0px" id="PreviewContainer">
+ <tr>
+ <td><table style="width:100%%" border="0" cellspacing="0" cellpadding="0" id="AnnotationContainer">
+ <tr>
+ <td style="width:100%%">{field:title}</td>
+ <!--
+ The date format mask follows the php date() function's instruction
+ see also here for more reference: http://cn.php.net/manual/en/function.date.php
+ -->
+ <td style="white-space:nowrap">{date:m/d/Y}</td>
+ </tr>
+ <tr>
+ <td>{field:sub_title}</td>
+ <td style="white-space:nowrap">__#QUICKPLOT_SCALE_LABEL#__: {scale}</td>
+ </tr>
+ </table></td>
+ </tr>
+ <tr>
+ <td id="PictureContainer" style="border: solid 1px black; text-align:center; vertical-align:center;">
+ <img style="width:1px; background:url(progress_indicator.gif) no-repeat center center" id="ProgressIndicator" src="pixel.gif" />
+ <img style="width:1px" id="PrintPicture" src="pixel.gif" />
+ <span id="PictureLoadingErrorMessage" style="display:none; text-align:center">__#QUICKPLOT_PREVIEW_ERROR#__</span>
+ </td>
+ </tr>
+ <tr>
+ <td><table width="100%%" border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <!-- Legal notice. Just replace it with the necessary statement -->
+ <td style="width:100%%" class="LegalNotice">The materials available at this web site are for informational purposes only and do not constitute a legal document.</td>
+ <td style="white-space:nowrap"><input type="button" id="PrintButton" class="Button" onClick="printIt()" value="__#QUICKPLOT_PRINT#__" /><input type="button" id="CancelButton" class="Button" onClick="cancelPreview()" value="__#QUICKPLOT_CANCEL#__" />
+ </td>
+ </tr>
+ </table></td>
+ </tr>
+</table>
+</body>
+</html>
Deleted: branches/fusion-2.2/widgets/QuickPlot/north_arrow.png
===================================================================
(Binary files differ)
Copied: branches/fusion-2.2/widgets/QuickPlot/north_arrow.png (from rev 2233, trunk/widgets/QuickPlot/north_arrow.png)
===================================================================
(Binary files differ)
Deleted: branches/fusion-2.2/widgets/QuickPlot/pixel.gif
===================================================================
(Binary files differ)
Copied: branches/fusion-2.2/widgets/QuickPlot/pixel.gif (from rev 2233, trunk/widgets/QuickPlot/pixel.gif)
===================================================================
(Binary files differ)
Deleted: branches/fusion-2.2/widgets/QuickPlot/progress_indicator.gif
===================================================================
(Binary files differ)
Copied: branches/fusion-2.2/widgets/QuickPlot/progress_indicator.gif (from rev 2233, trunk/widgets/QuickPlot/progress_indicator.gif)
===================================================================
(Binary files differ)
Deleted: branches/fusion-2.2/widgets/QuickPlot/rotate.cur
===================================================================
(Binary files differ)
Copied: branches/fusion-2.2/widgets/QuickPlot/rotate.cur (from rev 2233, trunk/widgets/QuickPlot/rotate.cur)
===================================================================
(Binary files differ)
Copied: branches/fusion-2.2/widgets/QuickPlot.js (from rev 2233, trunk/widgets/QuickPlot.js)
===================================================================
--- branches/fusion-2.2/widgets/QuickPlot.js (rev 0)
+++ branches/fusion-2.2/widgets/QuickPlot.js 2010-09-24 18:32:16 UTC (rev 2234)
@@ -0,0 +1,160 @@
+/**
+ * Fusion.Widget.QuickPlot
+ * Copyright (C) 2010 Autodesk, Inc. All rights reserved.
+ */
+
+ /*****************************************************************************
+ * Class: Fusion.Widget.QuickPlot
+ * This widget provides a quick way to print a certain region of map in a good quality
+ * **********************************************************************/
+
+Fusion.require("widgets/QuickPlot/MapCapturer.js");
+Fusion.require("widgets/QuickPlot/PreviewDialog.js");
+
+Fusion.Widget.QuickPlot = OpenLayers.Class(Fusion.Widget,
+{
+ isExclusive: true,
+ uiClass: Jx.Button,
+ sFeatures : 'menubar=no,location=no,resizable=no,status=no',
+ options : {},
+
+ initializeWidget: function(widgetTag)
+ {
+ this.mapCapturer = new OpenLayers.Control.MapCapturer(this.getMap());
+ this.getMap().oMapOL.addControl(this.mapCapturer);
+
+ var json = widgetTag.extension;
+
+ this.sTarget = json.Target ? json.Target[0] : "PrintPanelWindow";
+ this.sBaseUrl = Fusion.getFusionURL() + 'widgets/QuickPlot/QuickPlotPanel.php';
+
+ this.additionalParameters = [];
+ if (json.AdditionalParameter)
+ {
+ for (var i=0; i<json.AdditionalParameter.length; i++)
+ {
+ var p = json.AdditionalParameter[i];
+ var k = p.Key[0];
+ var v = p.Value[0];
+ this.additionalParameters.push(k+'='+encodeURIComponent(v));
+ }
+ }
+ },
+
+ activate: function()
+ {
+ var url = this.sBaseUrl;
+ var map = this.getMap();
+ var mapLayers = map.getAllMaps();
+ var taskPaneTarget = Fusion.getWidgetById(this.sTarget);
+ var pageElement = $(this.sTarget);
+
+ var params = [];
+ params.push('locale='+Fusion.locale);
+ params.push('session='+mapLayers[0].getSessionID());
+ params.push('mapname='+mapLayers[0].getMapName());
+
+ if (taskPaneTarget || pageElement)
+ {
+ params.push('popup=false');
+ }
+ else
+ {
+ params.push('popup=true');
+ }
+
+ params = params.concat(this.additionalParameters);
+
+ if (url.indexOf('?') < 0)
+ {
+ url += '?';
+ }
+ else if (url.slice(-1) != '&')
+ {
+ url += '&';
+ }
+
+ url += params.join('&');
+
+ if (taskPaneTarget)
+ {
+ taskPaneTarget.setContent(url);
+ }
+ else
+ {
+ if (pageElement)
+ {
+ pageElement.src = url;
+ }
+ else
+ {
+ window.open(url, this.sTarget, this.sWinFeatures);
+ }
+ }
+
+ // Expand taskpane automatically if it is the target window
+ if (panelman)
+ {
+ var panel = null;
+ for (var i = 0; i < panelman.panels.length; ++i)
+ {
+ panel = panelman.panels[i];
+ if (panel.options.contentId == this.sTarget)
+ {
+ panelman.maximizePanel(panel);
+ return;
+ }
+ }
+ }
+ },
+
+ /***************************************************************************************
+ * The dialogContentLoadedCallback is used to submit the Quick Plot panel's parameters to the preview iframe
+ ***************************************************************************************/
+ preview: function(dialogConentLoadedCallback, printDpi)
+ {
+ var map = this.getMap();
+ var capture = this.mapCapturer.getCaptureBox();
+ var normalizedCapture = this.mapCapturer.getNormalizedCapture();
+ var vertices = capture.geometry.getVertices();
+ this.options.printDpi = printDpi;
+ var options = {mapInfo : {sessionID : map.getSessionID(), name : map.getMapName()},
+ captureInfo : {topLeftCs : {x : vertices[3].x, y : vertices[3].y},
+ bottomRightCs : {x : vertices[1].x, y : vertices[1].y},
+ paperSize : {w : this.mapCapturer.paperSize.w, h : this.mapCapturer.paperSize.h},
+ scaleDenominator : this.mapCapturer.scaleDenominator,
+ rotation : this.mapCapturer.rotation,
+ center : capture.geometry.getCentroid(),
+ params1 : capture.params,
+ params2 : normalizedCapture.params},
+ params : this.options};
+
+ if (!this.previewDialog)
+ {
+ this.previewDialog = new PreviewDialog(options);
+ }
+ else
+ {
+ this.previewDialog.mapInfo = options.mapInfo;
+ this.previewDialog.captureInfo = options.captureInfo;
+ this.previewDialog.params = options.params;
+ }
+
+ this.previewDialog.open(dialogConentLoadedCallback);
+ },
+
+ cancelPreview: function()
+ {
+ this.previewDialog.cancel();
+ },
+
+ printPreview: function()
+ {
+ this.previewDialog.print();
+ },
+
+ previewInnerLoaded: function()
+ {
+ this.previewDialog.previewInnerLoaded();
+ }
+});
\ No newline at end of file
Modified: branches/fusion-2.2/widgets/Search/ErrorPage.templ
===================================================================
--- branches/fusion-2.2/widgets/Search/ErrorPage.templ 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/widgets/Search/ErrorPage.templ 2010-09-24 18:32:16 UTC (rev 2234)
@@ -51,10 +51,15 @@
function GetParent()
{
- if(popup)
- return opener;
- else
- return parent.parent;
+ if(popup)
+ return opener;
+ else
+ {
+ var node = parent;
+ while (!node.fusion && node.parent)
+ node = node.parent;
+ return node;
+ }
}
</script>
Modified: branches/fusion-2.2/widgets/Search/Search.templ
===================================================================
--- branches/fusion-2.2/widgets/Search/Search.templ 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/widgets/Search/Search.templ 2010-09-24 18:32:16 UTC (rev 2234)
@@ -106,10 +106,15 @@
function GetParent()
{
- if(popup)
- return opener;
- else
- return parent.parent;
+ if(popup)
+ return opener;
+ else
+ {
+ var node = parent;
+ while (!node.Fusion && node.parent)
+ node = node.parent;
+ return node;
+ }
}
</script>
Modified: branches/fusion-2.2/widgets/Search/SearchPrompt.templ
===================================================================
--- branches/fusion-2.2/widgets/Search/SearchPrompt.templ 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/widgets/Search/SearchPrompt.templ 2010-09-24 18:32:16 UTC (rev 2234)
@@ -80,10 +80,15 @@
function GetParent()
{
- if(popup)
- return opener;
- else
- return parent.parent;
+ if(popup)
+ return opener;
+ else
+ {
+ var node = parent;
+ while (!node.fusion && node.parent)
+ node = node.parent;
+ return node;
+ }
}
function SetMatchLabel()
Modified: branches/fusion-2.2/widgets/SelectWithin/SelectWithinPanel.templ
===================================================================
--- branches/fusion-2.2/widgets/SelectWithin/SelectWithinPanel.templ 2010-09-22 19:14:57 UTC (rev 2233)
+++ branches/fusion-2.2/widgets/SelectWithin/SelectWithinPanel.templ 2010-09-24 18:32:16 UTC (rev 2234)
@@ -146,12 +146,16 @@
}
function GetParent()
-{
- if(popup) {
- return opener;
- } else {
- return parent.parent;
- }
+{debugger;
+ if(popup)
+ return opener;
+ else
+ {
+ var node = parent;
+ while (!node.Fusion && node.parent)
+ node = node.parent;
+ return node;
+ }
}
</script>
Copied: branches/fusion-2.2/widgets/widgetinfo/quickplot.xml (from rev 2233, trunk/widgets/widgetinfo/quickplot.xml)
===================================================================
--- branches/fusion-2.2/widgets/widgetinfo/quickplot.xml (rev 0)
+++ branches/fusion-2.2/widgets/widgetinfo/quickplot.xml 2010-09-24 18:32:16 UTC (rev 2234)
@@ -0,0 +1,19 @@
+<WidgetInfo>
+ <Type>QuickPlot</Type>
+ <LocalizedType>QuickPlot</LocalizedType>
+ <Description>This widget offers a quick way to print map</Description>
+ <Label>Quick Plot</Label>
+ <Tooltip>Click to create a plot quickly</Tooltip>
+ <ImageUrl>images/icons/print.png</ImageUrl>
+ <ImageClass></ImageClass>
+ <StandardUi>true</StandardUi>
+ <ContainableBy>Any</ContainableBy>
+ <Parameter>
+ <Name>Target</Name>
+ <Description>The frame, window, or TaskPane in which to display any UI for the widget. If empty, a new window is used</Description>
+ <Type>target</Type>
+ <Label>Target</Label>
+ <DefaultValue>TaskPane</DefaultValue>
+ <IsMandatory>true</IsMandatory>
+ </Parameter>
+</WidgetInfo>
More information about the fusion-commits
mailing list