diff --git a/build/build.py b/build/build.py
index ebb07d358f..0ca2a74a0e 100755
--- a/build/build.py
+++ b/build/build.py
@@ -51,10 +51,14 @@ def build(config_file = None, output_file = None, options = None):
outputFilename = output_file
print "Merging libraries."
- if use_compressor == "closure":
- sourceFiles = mergejs.getNames(sourceDirectory, configFilename)
- else:
- merged = mergejs.run(sourceDirectory, None, configFilename)
+ try:
+ if use_compressor == "closure":
+ sourceFiles = mergejs.getNames(sourceDirectory, configFilename)
+ else:
+ merged = mergejs.run(sourceDirectory, None, configFilename)
+ except mergejs.MissingImport, E:
+ print "\nAbnormal termination."
+ sys.exit("ERROR: %s" % E)
print "Compressing using %s" % use_compressor
if use_compressor == "jsmin":
diff --git a/build/light.cfg b/build/light.cfg
new file mode 100644
index 0000000000..f2f7a649a4
--- /dev/null
+++ b/build/light.cfg
@@ -0,0 +1,32 @@
+[first]
+
+[last]
+
+[include]
+OpenLayers/Map.js
+OpenLayers/Kinetic.js
+OpenLayers/Projection.js
+OpenLayers/Layer/Vector.js
+OpenLayers/Layer/OSM.js
+OpenLayers/Layer/Bing.js
+OpenLayers/Layer/WMS.js
+OpenLayers/Layer/Google/v3.js
+OpenLayers/Popup/FramedCloud.js
+OpenLayers/Control/Navigation.js
+OpenLayers/Control/ZoomPanel.js
+OpenLayers/Control/Attribution.js
+OpenLayers/Control/SelectFeature.js
+OpenLayers/Control/Panel.js
+OpenLayers/Control/LayerSwitcher.js
+OpenLayers/Renderer/SVG.js
+OpenLayers/Renderer/VML.js
+OpenLayers/Format/GeoJSON.js
+OpenLayers/Protocol/HTTP.js
+OpenLayers/Strategy/Fixed.js
+OpenLayers/Strategy/BBOX.js
+OpenLayers/StyleMap.js
+OpenLayers/Rule.js
+OpenLayers/Filter/Comparison.js
+OpenLayers/Filter/Logical.js
+
+[exclude]
diff --git a/build/mobile.cfg b/build/mobile.cfg
index 0fe32aaa6a..7bba251270 100644
--- a/build/mobile.cfg
+++ b/build/mobile.cfg
@@ -1,5 +1,4 @@
[first]
-OpenLayers/SingleFile.js
[last]
diff --git a/doc/walkthru.html b/doc/walkthru.html
deleted file mode 100644
index b135e63523..0000000000
--- a/doc/walkthru.html
+++ /dev/null
@@ -1,96 +0,0 @@
-
-
-OpenLayers examples walkthrough
-
-
-
-
-<ol>
-API documentation: http://dev.openlayers.org/docs/
-Examples: http://openlayers.org/dev/examples/
-Maps
-
- Basic example
- Layer switcher (aka legend)
- Base layers versus overlays
- Multiple WMS mirrors
- Full screen map
- Wrapping the date line
- Other cartographic projections
- Translucent overlays
-
-
-Raster Layers
-
- Untiled WMS layer
- Ka-Map layer
- MapServer layer
- Worldwind layer
- TMS layer
- Image layer
- Google layer
- VirtualEarth layer
- Spherical Mercator ("EPSG:900913")
- TileCache
-
-
-Marker Layers
-
- Markers
- Changing marker properties dynamically
- Popups
- GeoRSS (example data )
- GeoRSS with custom markers
- Point layer from WFS
- WFS GetFeatureInfo example
-
-
-Events and Controls
-
- Navigation tools on the map
- Navigation toolbar off the map
- Tracking the mouse position
- Overview map
- Layer attribution
- Full range of controls
- Custom controls #1
- Custom controls #2
- Custom control styles
- Trapping click events
- Tracking map events
-
-
-Vector Layers
-
- Generating features in JavaScript
- Loading features from GML
- Loading features from KML
- Serializing features to GML
- Serializing to other formats
- Selecting features
- Attaching popups to features
-
-
-Editing Tools
-
- Drawing features
- Editing toolbar (outside the map )
- Creating regular polygons
- Modifying features
- Resizing features
- Rotating features
- Transactional WFS example
- FeatureServer
-
-
-Testing
-
- Test.AnotherWay suite
-
-
-</ol>
-
-
diff --git a/examples/accessible-click-control.html b/examples/accessible-click-control.html
new file mode 100644
index 0000000000..c8d97cde88
--- /dev/null
+++ b/examples/accessible-click-control.html
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+ Accessible Custom Click Control
+
+
+
+
+
+
+
+
+
+ An accessible click control implementation
+
+
+ click, control, accessibility
+
+
+
+ Jump to map
+
+
+
+
+
+ Demonstrate the KeyboardDefaults control as well as a control that
+ allows clicking on the map using the keyboard.
+ First focus the map (using tab key or mouse), then press the 'i'
+ key to activate the query control. You can then move the point
+ using arrow keys. Press 'RETURN' to get the coordinate. Press 'i'
+ again to deactivate the control.
+
+
+
+
diff --git a/examples/accessible-click-control.js b/examples/accessible-click-control.js
new file mode 100644
index 0000000000..328e0da768
--- /dev/null
+++ b/examples/accessible-click-control.js
@@ -0,0 +1,199 @@
+var map, navigationControl, queryControl;
+
+function init(){
+ map = new OpenLayers.Map('map', {controls: []});
+ var layer = new OpenLayers.Layer.WMS(
+ "OpenLayers WMS",
+ "http://vmap0.tiles.osgeo.org/wms/vmap0",
+ {layers: 'basic'}
+ );
+ map.addLayers([layer]);
+
+ navigationControl = new OpenLayers.Control.KeyboardDefaults({
+ observeElement: 'map'
+ });
+ map.addControl(navigationControl);
+
+ queryControl = new OpenLayers.Control.KeyboardClick({
+ observeElement: 'map'
+ });
+ map.addControl(queryControl);
+
+ map.zoomToMaxExtent();
+}
+
+/**
+ * Class: OpenLayers.Control.KeyboardClick
+ *
+ * A custom control that (a) adds a vector point that can be moved using the
+ * arrow keys of the keyboard, and (b) displays a browser alert window when the
+ * RETURN key is pressed. The control can be activated/deactivated using the
+ * "i" key. When activated the control deactivates any KeyboardDefaults control
+ * in the map so that the map is not moved when the arrow keys are pressed.
+ *
+ * This control relies on the OpenLayers.Handler.KeyboardPoint custom handler.
+ */
+OpenLayers.Control.KeyboardClick = OpenLayers.Class(OpenLayers.Control, {
+ initialize: function(options) {
+ OpenLayers.Control.prototype.initialize.apply(this, [options]);
+ var observeElement = this.observeElement || document;
+ this.handler = new OpenLayers.Handler.KeyboardPoint(this, {
+ done: this.onClick,
+ cancel: this.deactivate
+ }, {
+ observeElement: observeElement
+ });
+ OpenLayers.Event.observe(
+ observeElement,
+ "keydown",
+ OpenLayers.Function.bindAsEventListener(
+ function(evt) {
+ if (evt.keyCode == 73) { // "i"
+ if (this.active) {
+ this.deactivate();
+ } else {
+ this.activate();
+ }
+ }
+ },
+ this
+ )
+ );
+ },
+
+ onClick: function(geometry) {
+ alert("You clicked near " + geometry.x + " N, " +
+ geometry.y + " E");
+ },
+
+ activate: function() {
+ if(!OpenLayers.Control.prototype.activate.apply(this, arguments)) {
+ return false;
+ }
+ // deactivate any KeyboardDefaults control
+ var keyboardDefaults = this.map.getControlsByClass(
+ 'OpenLayers.Control.KeyboardDefaults')[0];
+ if (keyboardDefaults) {
+ keyboardDefaults.deactivate();
+ }
+ return true;
+ },
+
+ deactivate: function() {
+ if(!OpenLayers.Control.prototype.deactivate.apply(this, arguments)) {
+ return false;
+ }
+ // reactivate any KeyboardDefaults control
+ var keyboardDefaults = this.map.getControlsByClass(
+ 'OpenLayers.Control.KeyboardDefaults')[0];
+ if (keyboardDefaults) {
+ keyboardDefaults.activate();
+ }
+ return true;
+ }
+});
+
+/**
+ * Class: OpenLayers.Handler.KeyboardPoint
+ *
+ * A custom handler that displays a vector point that can be moved
+ * using the arrow keys of the keyboard.
+ */
+OpenLayers.Handler.KeyboardPoint = OpenLayers.Class(OpenLayers.Handler, {
+
+ KEY_EVENTS: ["keydown"],
+
+
+ initialize: function(control, callbacks, options) {
+ OpenLayers.Handler.prototype.initialize.apply(this, arguments);
+ // cache the bound event listener method so it can be unobserved later
+ this.eventListener = OpenLayers.Function.bindAsEventListener(
+ this.handleKeyEvent, this
+ );
+ },
+
+ activate: function() {
+ if(!OpenLayers.Handler.prototype.activate.apply(this, arguments)) {
+ return false;
+ }
+ this.layer = new OpenLayers.Layer.Vector(this.CLASS_NAME);
+ this.map.addLayer(this.layer);
+ this.observeElement = this.observeElement || document;
+ for (var i=0, len=this.KEY_EVENTS.length; i
+
+
+
+
+
+ Custom and accessible panel
+
+
+
+
+
+
+
+ Custom and accessible panel
+
+ panels, CSS, style, accessibility, button
+
+
+ Create a custom and accessible panel, styled entirely with
+ CSS.
+
+
+
+
+
+
+
An accessible panel:
+
+
+ The buttons are actual HTML buttons. You can therefore
+ use the TAB key to give the focus to the panel's buttons, and the "ENTER"
+ key to activate or trigger the corresponding control.
+ The buttons include text and titles (displayed when a button
+ is hovered).
+ If you remove colors from the page (for example using FireFox's No
+ Color extension ) the buttons are still visible, and
+ accessible using the keyboard.
+
+
+
+
By default a panel creates buttons as divs. In this example the
+ createControlMarkup
panel function is overridden to create
+ a more accessible markup for the buttons. See the accessible-panel.js
+ source to see how this is done.
+
+
Note: in IE 8, when a button is pressed its content shifts by 1 pixel.
+ This is a known
+ IE8 bug , with known workarounds. No workaround is applied in this
+ example though.
+
+
+
+
+
diff --git a/examples/accessible-panel.js b/examples/accessible-panel.js
new file mode 100644
index 0000000000..f982fc624b
--- /dev/null
+++ b/examples/accessible-panel.js
@@ -0,0 +1,64 @@
+var lon = 5;
+var lat = 40;
+var zoom = 5;
+var map, layer;
+
+function init() {
+ map = new OpenLayers.Map( 'map', { controls: [] } );
+ layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
+ "http://vmap0.tiles.osgeo.org/wms/vmap0", {layers: 'basic'} );
+ map.addLayer(layer);
+
+ vlayer = new OpenLayers.Layer.Vector( "Editable" );
+ map.addLayer(vlayer);
+
+ zb = new OpenLayers.Control.ZoomBox({
+ title: "Zoom box: zoom clicking and dragging",
+ text: "Zoom"
+ });
+
+ var panel = new OpenLayers.Control.Panel({
+ defaultControl: zb,
+ createControlMarkup: function(control) {
+ var button = document.createElement('button'),
+ iconSpan = document.createElement('span'),
+ textSpan = document.createElement('span');
+ iconSpan.innerHTML = ' ';
+ button.appendChild(iconSpan);
+ if (control.text) {
+ textSpan.innerHTML = control.text;
+ }
+ button.appendChild(textSpan);
+ return button;
+ }
+ });
+
+ panel.addControls([
+ zb,
+ new OpenLayers.Control.DrawFeature(vlayer, OpenLayers.Handler.Path,
+ {title:'Draw a feature', text: 'Draw'}),
+ new OpenLayers.Control.ZoomToMaxExtent({
+ title:"Zoom to the max extent",
+ text: "World"
+ })
+ ]);
+
+ nav = new OpenLayers.Control.NavigationHistory({
+ previousOptions: {
+ title: "Go to previous map position",
+ text: "Prev"
+ },
+ nextOptions: {
+ title: "Go to next map position",
+ text: "Next"
+ },
+ displayClass: "navHistory"
+ });
+ // parent control must be added to the map
+ map.addControl(nav);
+ panel.addControls([nav.next, nav.previous]);
+
+ map.addControl(panel);
+
+ map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);
+}
diff --git a/examples/accessible.html b/examples/accessible.html
index d9b8a777b3..36236d5b97 100644
--- a/examples/accessible.html
+++ b/examples/accessible.html
@@ -31,13 +31,26 @@
font-size:1em;
text-decoration:underline;
}
+ a.accesskey {
+ color: white;
+ }
+ a.accesskey:focus {
+ color: #436976;
+ }
+ a.zoom {
+ padding-right: 20px;
+ }
+
diff --git a/examples/cross-origin-xml.html b/examples/cross-origin-xml.html
new file mode 100644
index 0000000000..b811bf72c1
--- /dev/null
+++ b/examples/cross-origin-xml.html
@@ -0,0 +1,32 @@
+
+
+
+ OpenLayers Script Protocol XML Example
+
+
+
+
+
+
+
+
+ Script Protocol With XML
+
+ protocol, script, cross origin, xml, advanced
+
+
+ Demonstrates how, with a custom parseFeatures method, the script protocol can be used with YQL for cross-origin loading of files in any of the XML formats supported by OpenLayers.
+
+
+
+
+ YQL can wrap a jsonp callback around an XML file, which effectively means Yahoo's servers are acting as a proxy for cross-origin feature loading. This example uses a GPX file, but the same technique can be used for other formats such as KML.
+
+
+ View the cross-origin-xml.js
+ source to see how this is done
+
+
+
+
+
diff --git a/examples/cross-origin-xml.js b/examples/cross-origin-xml.js
new file mode 100644
index 0000000000..a97cc1fdb6
--- /dev/null
+++ b/examples/cross-origin-xml.js
@@ -0,0 +1,25 @@
+var map = new OpenLayers.Map({
+ div: "map",
+ layers: [
+ new OpenLayers.Layer.OSM(),
+ new OpenLayers.Layer.Vector("Vectors", {
+ projection: new OpenLayers.Projection("EPSG:4326"),
+ strategies: [new OpenLayers.Strategy.Fixed()],
+ protocol: new OpenLayers.Protocol.Script({
+ url: "http://query.yahooapis.com/v1/public/yql",
+ params: {
+ q: "select * from xml where url='http://www.topografix.com/fells_loop.gpx'"
+ },
+ format: new OpenLayers.Format.GPX(),
+ parseFeatures: function(data) {
+ return this.format.read(data.results[0]);
+ }
+ }),
+ eventListeners: {
+ "featuresadded": function () {
+ this.map.zoomToExtent(this.getDataExtent());
+ }
+ }
+ })
+ ]
+});
diff --git a/examples/google-v3.html b/examples/google-v3.html
index c074bb62f5..849d7cd273 100644
--- a/examples/google-v3.html
+++ b/examples/google-v3.html
@@ -8,7 +8,7 @@
-
+
diff --git a/examples/gutter.html b/examples/gutter.html
index 1d16e504c0..3dd4dbf082 100644
--- a/examples/gutter.html
+++ b/examples/gutter.html
@@ -45,7 +45,7 @@ Gutter Example
"http://demo.opengeo.org/geoserver/wms",
{layers: 'topp:states'},
{gutter: 15});
- var states = new OpenLayers.Layer.WMS( "Roads (no gutter)",
+ var states = new OpenLayers.Layer.WMS( "States (no gutter)",
"http://demo.opengeo.org/geoserver/wms",
{layers: 'topp:states'});
map.addLayers([states, states15]);
diff --git a/examples/mapbox.html b/examples/mapbox.html
new file mode 100644
index 0000000000..3ccbffe776
--- /dev/null
+++ b/examples/mapbox.html
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+ OpenLayers MapBox Example
+
+
+
+
+
+ Basic MapBox OSM Example
+ mapbox xyz osm
+
+ Shows how to use MapBox tiles in an OpenLayers map.
+
+
+
+
+
This example demonstrates the use of an XYZ layer that accesses tiles from MapBox.
+
+ See the mapbox.js source
+ for details. Make sure to read the Terms of Service
+ before using MapBox tiles in your application.
+
+
+
+
+
+
diff --git a/examples/mapbox.js b/examples/mapbox.js
new file mode 100644
index 0000000000..ee57d66e0c
--- /dev/null
+++ b/examples/mapbox.js
@@ -0,0 +1,34 @@
+var streets = new OpenLayers.Layer.XYZ(
+ "MapBox Streets",
+ [
+ "http://a.tiles.mapbox.com/v3/mapbox.mapbox-streets/${z}/${x}/${y}.png",
+ "http://b.tiles.mapbox.com/v3/mapbox.mapbox-streets/${z}/${x}/${y}.png",
+ "http://c.tiles.mapbox.com/v3/mapbox.mapbox-streets/${z}/${x}/${y}.png",
+ "http://d.tiles.mapbox.com/v3/mapbox.mapbox-streets/${z}/${x}/${y}.png"
+ ], {
+ attribution: "Tiles © MapBox | " +
+ "Data © OpenStreetMap " +
+ "and contributors, CC-BY-SA",
+ sphericalMercator: true,
+ transitionEffect: "resize",
+ buffer: 1,
+ numZoomLevels: 16
+ }
+);
+
+var map = new OpenLayers.Map({
+ div: "map",
+ layers: [streets],
+ controls: [
+ new OpenLayers.Control.Attribution(),
+ new OpenLayers.Control.Navigation({
+ dragPanOptions: {
+ enableKinetic: true
+ }
+ }),
+ new OpenLayers.Control.ZoomPanel(),
+ new OpenLayers.Control.Permalink({anchor: true})
+ ],
+ center: [0, 0],
+ zoom: 1
+});
diff --git a/examples/osm-google.html b/examples/osm-google.html
index 3578246ccb..39c31dd910 100644
--- a/examples/osm-google.html
+++ b/examples/osm-google.html
@@ -8,7 +8,7 @@
-
+
diff --git a/examples/spherical-mercator.html b/examples/spherical-mercator.html
index ea6c2246d5..409a8e232f 100644
--- a/examples/spherical-mercator.html
+++ b/examples/spherical-mercator.html
@@ -22,7 +22,7 @@
}
-
+
diff --git a/examples/zoom.html b/examples/zoom.html
new file mode 100644
index 0000000000..7b15297d05
--- /dev/null
+++ b/examples/zoom.html
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+ OpenLayers Zoom Example
+
+
+
+
+
+ Zoom Control Example
+ zoom control
+
+ Shows how to use a simple zoom control.
+
+
+ The map above uses the default control configuration and style.
+ The map below uses the custom zoom elements and styling.
+
+
+
+
This example demonstrates the use of a Zoom control.
+
+ See the zoom.js source
+ for details.
+
+
+
+
+
+
diff --git a/examples/zoom.js b/examples/zoom.js
new file mode 100644
index 0000000000..08694ccad4
--- /dev/null
+++ b/examples/zoom.js
@@ -0,0 +1,34 @@
+var map = new OpenLayers.Map({
+ div: "map",
+ layers: [new OpenLayers.Layer.OSM()],
+ controls: [
+ new OpenLayers.Control.Navigation({
+ dragPanOptions: {
+ enableKinetic: true
+ }
+ }),
+ new OpenLayers.Control.Attribution(),
+ new OpenLayers.Control.Zoom()
+ ],
+ center: [0, 0],
+ zoom: 1
+});
+
+var map2 = new OpenLayers.Map({
+ div: "map2",
+ layers: [new OpenLayers.Layer.OSM()],
+ controls: [
+ new OpenLayers.Control.Navigation({
+ dragPanOptions: {
+ enableKinetic: true
+ }
+ }),
+ new OpenLayers.Control.Attribution(),
+ new OpenLayers.Control.Zoom({
+ zoomInId: "customZoomIn",
+ zoomOutId: "customZoomOut"
+ })
+ ],
+ center: [0, 0],
+ zoom: 1
+});
diff --git a/lib/OpenLayers.js b/lib/OpenLayers.js
index c257ce73c4..70e695dcb0 100644
--- a/lib/OpenLayers.js
+++ b/lib/OpenLayers.js
@@ -207,6 +207,7 @@
"OpenLayers/Control/TransformFeature.js",
"OpenLayers/Control/UTFGrid.js",
"OpenLayers/Control/SLDSelect.js",
+ "OpenLayers/Control/Zoom.js",
"OpenLayers/Geometry.js",
"OpenLayers/Geometry/Collection.js",
"OpenLayers/Geometry/Point.js",
@@ -272,6 +273,10 @@
"OpenLayers/Format/KML.js",
"OpenLayers/Format/GeoRSS.js",
"OpenLayers/Format/WFS.js",
+ "OpenLayers/Format/OWSCommon.js",
+ "OpenLayers/Format/OWSCommon/v1.js",
+ "OpenLayers/Format/OWSCommon/v1_0_0.js",
+ "OpenLayers/Format/OWSCommon/v1_1_0.js",
"OpenLayers/Format/WFSCapabilities.js",
"OpenLayers/Format/WFSCapabilities/v1.js",
"OpenLayers/Format/WFSCapabilities/v1_0_0.js",
diff --git a/lib/OpenLayers/BaseTypes.js b/lib/OpenLayers/BaseTypes.js
index ce7e291923..d2e5711ca8 100644
--- a/lib/OpenLayers/BaseTypes.js
+++ b/lib/OpenLayers/BaseTypes.js
@@ -3,6 +3,10 @@
* See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
+/**
+ * @requires OpenLayers/SingleFile.js
+ */
+
/**
* Header: OpenLayers Base Types
* OpenLayers custom string, number and function functions are described here.
diff --git a/lib/OpenLayers/BaseTypes/Date.js b/lib/OpenLayers/BaseTypes/Date.js
index 9af051c8b6..3b645fe852 100644
--- a/lib/OpenLayers/BaseTypes/Date.js
+++ b/lib/OpenLayers/BaseTypes/Date.js
@@ -3,6 +3,10 @@
* See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
+/**
+ * @requires OpenLayers/SingleFile.js
+ */
+
/**
* Namespace: OpenLayers.Date
* Contains implementations of Date.parse and date.toISOString that match the
diff --git a/lib/OpenLayers/Control/KeyboardDefaults.js b/lib/OpenLayers/Control/KeyboardDefaults.js
index f3505353f0..2589269590 100644
--- a/lib/OpenLayers/Control/KeyboardDefaults.js
+++ b/lib/OpenLayers/Control/KeyboardDefaults.js
@@ -34,6 +34,15 @@ OpenLayers.Control.KeyboardDefaults = OpenLayers.Class(OpenLayers.Control, {
*/
slideFactor: 75,
+ /**
+ * APIProperty: observeElement
+ * {DOMelement|String} The DOM element to handle keys for. You
+ * can use the map div here, to have the navigation keys
+ * work when the map div has the focus. If undefined the
+ * document is used.
+ */
+ observeElement: null,
+
/**
* Constructor: OpenLayers.Control.KeyboardDefaults
*/
@@ -43,8 +52,11 @@ OpenLayers.Control.KeyboardDefaults = OpenLayers.Class(OpenLayers.Control, {
* Create handler.
*/
draw: function() {
- this.handler = new OpenLayers.Handler.Keyboard( this, {
- "keydown": this.defaultKeyPress });
+ var observeElement = this.observeElement || document;
+ this.handler = new OpenLayers.Handler.Keyboard( this,
+ {"keydown": this.defaultKeyPress},
+ {observeElement: observeElement}
+ );
},
/**
@@ -62,7 +74,7 @@ OpenLayers.Control.KeyboardDefaults = OpenLayers.Class(OpenLayers.Control, {
* evt - {Event}
*/
defaultKeyPress: function (evt) {
- var size;
+ var size, handled = true;
switch(evt.keyCode) {
case OpenLayers.Event.KEY_LEFT:
this.map.pan(-this.slideFactor, 0);
@@ -106,7 +118,14 @@ OpenLayers.Control.KeyboardDefaults = OpenLayers.Class(OpenLayers.Control, {
case 95: // -/_ (some ASCII)
this.map.zoomOut();
break;
- }
+ default:
+ handled = false;
+ }
+ if (handled) {
+ // prevent browser default not to move the page
+ // when moving the page with the keyboard
+ OpenLayers.Event.stop(evt);
+ }
},
CLASS_NAME: "OpenLayers.Control.KeyboardDefaults"
diff --git a/lib/OpenLayers/Control/LayerSwitcher.js b/lib/OpenLayers/Control/LayerSwitcher.js
index a0e480e385..b1f2cc49cb 100644
--- a/lib/OpenLayers/Control/LayerSwitcher.js
+++ b/lib/OpenLayers/Control/LayerSwitcher.js
@@ -120,7 +120,7 @@ OpenLayers.Control.LayerSwitcher =
initialize: function(options) {
OpenLayers.Control.prototype.initialize.apply(this, arguments);
this.layerStates = [];
-
+
if(this.roundedCorner) {
OpenLayers.Console.warn('roundedCorner option is deprecated');
}
@@ -143,6 +143,7 @@ OpenLayers.Control.LayerSwitcher =
changebaselayer: this.redraw,
scope: this
});
+ this.events.unregister("buttonclick", this, this.onButtonClick);
OpenLayers.Control.prototype.destroy.apply(this, arguments);
},
@@ -157,13 +158,18 @@ OpenLayers.Control.LayerSwitcher =
OpenLayers.Control.prototype.setMap.apply(this, arguments);
this.map.events.on({
- buttonclick: this.onButtonClick,
addlayer: this.redraw,
changelayer: this.redraw,
removelayer: this.redraw,
changebaselayer: this.redraw,
scope: this
});
+ if (this.outsideViewport) {
+ this.events.attachToElement(this.div);
+ this.events.register("buttonclick", this, this.onButtonClick);
+ } else {
+ this.map.events.register("buttonclick", this, this.onButtonClick);
+ }
},
/**
diff --git a/lib/OpenLayers/Control/Measure.js b/lib/OpenLayers/Control/Measure.js
index 7eb05a02c2..0c6a057150 100644
--- a/lib/OpenLayers/Control/Measure.js
+++ b/lib/OpenLayers/Control/Measure.js
@@ -231,8 +231,8 @@ OpenLayers.Control.Measure = OpenLayers.Class(OpenLayers.Control, {
* mouseposition. feature - {} The sketch feature.
*/
measureImmediate : function(point, feature, drawing) {
- if (drawing && this.delayedTrigger === null &&
- !this.handler.freehandMode(this.handler.evt)) {
+ if (drawing && !this.handler.freehandMode(this.handler.evt)) {
+ this.cancelDelay();
this.measure(feature.geometry, "measurepartial");
}
},
diff --git a/lib/OpenLayers/Control/ModifyFeature.js b/lib/OpenLayers/Control/ModifyFeature.js
index 6e78184efc..30d6fad0cd 100644
--- a/lib/OpenLayers/Control/ModifyFeature.js
+++ b/lib/OpenLayers/Control/ModifyFeature.js
@@ -246,7 +246,6 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
// configure the drag control
var dragOptions = {
geometryTypes: ["OpenLayers.Geometry.Point"],
- snappingOptions: this.snappingOptions,
onStart: function(feature, pixel) {
control.dragStart.apply(control, [feature, pixel]);
},
diff --git a/lib/OpenLayers/Control/Panel.js b/lib/OpenLayers/Control/Panel.js
index b04f6c3863..f141671445 100644
--- a/lib/OpenLayers/Control/Panel.js
+++ b/lib/OpenLayers/Control/Panel.js
@@ -245,26 +245,58 @@ OpenLayers.Control.Panel = OpenLayers.Class(OpenLayers.Control, {
controls = [controls];
}
this.controls = this.controls.concat(controls);
-
- // Give each control a panel_div which will be used later.
- // Access to this div is via the panel_div attribute of the
- // control added to the panel.
- // Also, stop mousedowns and clicks, but don't stop mouseup,
- // since they need to pass through.
+
for (var i=0, len=controls.length; i} The control to create the HTML
+ * markup for.
+ *
+ * Returns:
+ * {DOMElement} The markup.
+ */
+ createControlMarkup: function(control) {
+ return document.createElement("div");
+ },
/**
* Method: addControlsToMap
diff --git a/lib/OpenLayers/Control/Permalink.js b/lib/OpenLayers/Control/Permalink.js
index 5686f1f8b6..4a2112c552 100644
--- a/lib/OpenLayers/Control/Permalink.js
+++ b/lib/OpenLayers/Control/Permalink.js
@@ -94,12 +94,13 @@ OpenLayers.Control.Permalink = OpenLayers.Class(OpenLayers.Control, {
* APIMethod: destroy
*/
destroy: function() {
- if (this.element.parentNode == this.div) {
+ if (this.element && this.element.parentNode == this.div) {
this.div.removeChild(this.element);
+ this.element = null;
+ }
+ if (this.map) {
+ this.map.events.unregister('moveend', this, this.updateLink);
}
- this.element = null;
-
- this.map.events.unregister('moveend', this, this.updateLink);
OpenLayers.Control.prototype.destroy.apply(this, arguments);
},
diff --git a/lib/OpenLayers/Control/WMSGetFeatureInfo.js b/lib/OpenLayers/Control/WMSGetFeatureInfo.js
index 9348a9d542..86e9423060 100644
--- a/lib/OpenLayers/Control/WMSGetFeatureInfo.js
+++ b/lib/OpenLayers/Control/WMSGetFeatureInfo.js
@@ -341,6 +341,7 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
service: "WMS",
version: firstLayer.params.VERSION,
request: "GetFeatureInfo",
+ exceptions: firstLayer.params.EXCEPTIONS,
bbox: this.map.getExtent().toBBOX(null,
firstLayer.reverseAxisOrder()),
feature_count: this.maxFeatures,
diff --git a/lib/OpenLayers/Control/Zoom.js b/lib/OpenLayers/Control/Zoom.js
new file mode 100644
index 0000000000..eb212eeb83
--- /dev/null
+++ b/lib/OpenLayers/Control/Zoom.js
@@ -0,0 +1,139 @@
+/* Copyright (c) 2006-2012 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/Events/buttonclick.js
+ */
+
+/**
+ * Class: OpenLayers.Control.Zoom
+ * The Zoom control is a pair of +/- links for zooming in and out.
+ *
+ * Inherits from:
+ * -
+ */
+OpenLayers.Control.Zoom = OpenLayers.Class(OpenLayers.Control, {
+
+ /**
+ * APIProperty: zoomInText
+ * {String}
+ * Text for zoom-in link. Default is "+".
+ */
+ zoomInText: "+",
+
+ /**
+ * APIProperty: zoomInId
+ * {String}
+ * Instead of having the control create a zoom in link, you can provide
+ * the identifier for an anchor element already added to the document.
+ * By default, an element with id "olZoomInLink" will be searched for
+ * and used if it exists.
+ */
+ zoomInId: "olZoomInLink",
+
+ /**
+ * APIProperty: zoomOutText
+ * {String}
+ * Text for zoom-out link. Default is "-".
+ */
+ zoomOutText: "-",
+
+ /**
+ * APIProperty: zoomOutId
+ * {String}
+ * Instead of having the control create a zoom out link, you can provide
+ * the identifier for an anchor element already added to the document.
+ * By default, an element with id "olZoomOutLink" will be searched for
+ * and used if it exists.
+ */
+ zoomOutId: "olZoomOutLink",
+
+ /**
+ * Method: draw
+ *
+ * Returns:
+ * {DOMElement} A reference to the DOMElement containing the zoom links.
+ */
+ draw: function() {
+ var div = OpenLayers.Control.prototype.draw.apply(this),
+ links = this.getOrCreateLinks(div),
+ zoomIn = links.zoomIn,
+ zoomOut = links.zoomOut,
+ bind = OpenLayers.Function.bind,
+ eventsInstance = this.map.events;
+
+ if (zoomOut.parentNode !== div) {
+ eventsInstance = this.events;
+ eventsInstance.attachToElement(zoomOut.parentNode);
+ }
+ eventsInstance.register("buttonclick", this, this.onZoomClick);
+
+ this.zoomInLink = zoomIn;
+ this.zoomOutLink = zoomOut;
+ return div;
+ },
+
+ /**
+ * Method: getOrCreateLinks
+ *
+ * Parameters:
+ * el - {DOMElement}
+ *
+ * Return:
+ * {Object} Object with zoomIn and zoomOut properties referencing links.
+ */
+ getOrCreateLinks: function(el) {
+ var zoomIn = document.getElementById(this.zoomInId),
+ zoomOut = document.getElementById(this.zoomOutId);
+ if (!zoomIn) {
+ zoomIn = document.createElement("a");
+ zoomIn.href = "#zoomIn";
+ zoomIn.appendChild(document.createTextNode(this.zoomInText));
+ zoomIn.className = "olControlZoomIn";
+ el.appendChild(zoomIn);
+ }
+ OpenLayers.Element.addClass(zoomIn, "olButton");
+ if (!zoomOut) {
+ zoomOut = document.createElement("a");
+ zoomOut.href = "#zoomOut";
+ zoomOut.appendChild(document.createTextNode(this.zoomOutText));
+ zoomOut.className = "olControlZoomOut";
+ el.appendChild(zoomOut);
+ }
+ OpenLayers.Element.addClass(zoomOut, "olButton");
+ return {
+ zoomIn: zoomIn, zoomOut: zoomOut
+ };
+ },
+
+ /**
+ * Method: onZoomClick
+ * Called when zoomin/out link is clicked.
+ */
+ onZoomClick: function(evt) {
+ var button = evt.buttonElement;
+ if (button === this.zoomInLink) {
+ this.map.zoomIn();
+ } else if (button === this.zoomOutLink) {
+ this.map.zoomOut();
+ }
+ },
+
+ /**
+ * Method: destroy
+ * Clean up.
+ */
+ destroy: function() {
+ if (this.map) {
+ this.map.events.unregister("buttonclick", this, this.onZoomClick);
+ }
+ delete this.zoomInLink;
+ delete this.zoomOutLink;
+ OpenLayers.Control.prototype.destroy.apply(this);
+ },
+
+ CLASS_NAME: "OpenLayers.Control.Zoom"
+});
diff --git a/lib/OpenLayers/Events.js b/lib/OpenLayers/Events.js
index 907ced8109..ea46bf3cba 100644
--- a/lib/OpenLayers/Events.js
+++ b/lib/OpenLayers/Events.js
@@ -20,6 +20,12 @@ OpenLayers.Event = {
* element._eventCacheID
*/
observers: false,
+
+ /**
+ * Constant: KEY_SPACE
+ * {int}
+ */
+ KEY_SPACE: 32,
/**
* Constant: KEY_BACKSPACE
@@ -388,7 +394,8 @@ OpenLayers.Events = OpenLayers.Class({
"mousedown", "mouseup", "mousemove",
"click", "dblclick", "rightclick", "dblrightclick",
"resize", "focus", "blur",
- "touchstart", "touchmove", "touchend"
+ "touchstart", "touchmove", "touchend",
+ "keydown"
],
/**
diff --git a/lib/OpenLayers/Events/buttonclick.js b/lib/OpenLayers/Events/buttonclick.js
index 351248bf0c..6520b83a0d 100644
--- a/lib/OpenLayers/Events/buttonclick.js
+++ b/lib/OpenLayers/Events/buttonclick.js
@@ -39,7 +39,7 @@ OpenLayers.Events.buttonclick = OpenLayers.Class({
*/
events: [
'mousedown', 'mouseup', 'click', 'dblclick',
- 'touchstart', 'touchmove', 'touchend'
+ 'touchstart', 'touchmove', 'touchend', 'keydown'
],
/**
@@ -97,6 +97,31 @@ OpenLayers.Events.buttonclick = OpenLayers.Class({
delete this.target;
},
+ /**
+ * Method: getPressedButton
+ * Get the pressed button, if any. Returns undefined if no button
+ * was pressed.
+ *
+ * Arguments:
+ * element - {DOMElement} The event target.
+ *
+ * Returns:
+ * {DOMElement} The button element, or undefined.
+ */
+ getPressedButton: function(element) {
+ var depth = 3, // limit the search depth
+ button;
+ do {
+ if(OpenLayers.Element.hasClass(element, "olButton")) {
+ // hit!
+ button = element;
+ break;
+ }
+ element = element.parentNode;
+ } while(--depth > 0 && element);
+ return button;
+ },
+
/**
* Method: buttonClick
* Check if a button was clicked, and fire the buttonclick event
@@ -108,15 +133,25 @@ OpenLayers.Events.buttonclick = OpenLayers.Class({
var propagate = true,
element = OpenLayers.Event.element(evt);
if (element && (OpenLayers.Event.isLeftClick(evt) || !~evt.type.indexOf("mouse"))) {
- if (element.nodeType === 3 || OpenLayers.Element.hasClass(element, "olAlphaImg")) {
- element = element.parentNode;
- }
- if (OpenLayers.Element.hasClass(element, "olButton")) {
- if (this.startEvt) {
+ // was a button pressed?
+ var button = this.getPressedButton(element);
+ if (button) {
+ if (evt.type === "keydown") {
+ switch (evt.keyCode) {
+ case OpenLayers.Event.KEY_RETURN:
+ case OpenLayers.Event.KEY_SPACE:
+ this.target.triggerEvent("buttonclick", {
+ buttonElement: button
+ });
+ OpenLayers.Event.stop(evt);
+ propagate = false;
+ break;
+ }
+ } else if (this.startEvt) {
if (this.completeRegEx.test(evt.type)) {
- var pos = OpenLayers.Util.pagePosition(element);
+ var pos = OpenLayers.Util.pagePosition(button);
this.target.triggerEvent("buttonclick", {
- buttonElement: element,
+ buttonElement: button,
buttonXY: {
x: this.startEvt.clientX - pos[0],
y: this.startEvt.clientY - pos[1]
diff --git a/lib/OpenLayers/Format/KML.js b/lib/OpenLayers/Format/KML.js
index 1754fd8eb5..b814eece5a 100644
--- a/lib/OpenLayers/Format/KML.js
+++ b/lib/OpenLayers/Format/KML.js
@@ -64,9 +64,25 @@ OpenLayers.Format.KML = OpenLayers.Class(OpenLayers.Format.XML, {
* APIProperty: extractAttributes
* {Boolean} Extract attributes from KML. Default is true.
* Extracting styleUrls requires this to be set to true
+ * Note that currently only Data and SimpleData
+ * elements are handled.
*/
extractAttributes: true,
+ /**
+ * APIProperty: kvpAttributes
+ * {Boolean} Only used if extractAttributes is true.
+ * If set to true, attributes will be simple
+ * key-value pairs, compatible with other formats,
+ * Any displayName elements will be ignored.
+ * If set to false, attributes will be objects,
+ * retaining any displayName elements, but not
+ * compatible with other formats. Any CDATA in
+ * displayName will be read in as a string value.
+ * Default is false.
+ */
+ kvpAttributes: false,
+
/**
* Property: extractStyles
* {Boolean} Extract styles from KML. Default is false.
@@ -1078,12 +1094,16 @@ OpenLayers.Format.KML = OpenLayers.Class(OpenLayers.Format.XML, {
var valueNode = data.getElementsByTagName("value");
if (valueNode.length) {
ed['value'] = this.getChildValue(valueNode[0]);
- }
- var nameNode = data.getElementsByTagName("displayName");
- if (nameNode.length) {
- ed['displayName'] = this.getChildValue(nameNode[0]);
}
- attributes[key] = ed;
+ if (this.kvpAttributes) {
+ attributes[key] = ed['value'];
+ } else {
+ var nameNode = data.getElementsByTagName("displayName");
+ if (nameNode.length) {
+ ed['displayName'] = this.getChildValue(nameNode[0]);
+ }
+ attributes[key] = ed;
+ }
}
var simpleDataNodes = node.getElementsByTagName("SimpleData");
for (i = 0, len = simpleDataNodes.length; i < len; i++) {
@@ -1091,8 +1111,12 @@ OpenLayers.Format.KML = OpenLayers.Class(OpenLayers.Format.XML, {
data = simpleDataNodes[i];
key = data.getAttribute("name");
ed['value'] = this.getChildValue(data);
- ed['displayName'] = key;
- attributes[key] = ed;
+ if (this.kvpAttributes) {
+ attributes[key] = ed['value'];
+ } else {
+ ed['displayName'] = key;
+ attributes[key] = ed;
+ }
}
return attributes;
@@ -1209,7 +1233,14 @@ OpenLayers.Format.KML = OpenLayers.Class(OpenLayers.Format.XML, {
var geometryNode = this.buildGeometryNode(feature.geometry);
placemarkNode.appendChild(geometryNode);
- // TBD - deal with remaining (non name/description) attributes.
+ // output attributes as extendedData
+ if (feature.attributes) {
+ var edNode = this.buildExtendedData(feature.attributes);
+ if (edNode) {
+ placemarkNode.appendChild(edNode);
+ }
+ }
+
return placemarkNode;
},
@@ -1440,5 +1471,48 @@ OpenLayers.Format.KML = OpenLayers.Class(OpenLayers.Format.XML, {
return point.x + "," + point.y;
},
+ /**
+ * Method: buildExtendedData
+ *
+ * Parameters:
+ * attributes - {Object}
+ *
+ * Returns
+ * {DOMElement} A KML ExtendedData node or {null} if no attributes.
+ */
+ buildExtendedData: function(attributes) {
+ var extendedData = this.createElementNS(this.kmlns, "ExtendedData");
+ for (var attributeName in attributes) {
+ // empty, name, description, styleUrl attributes ignored
+ if (attributes[attributeName] && attributeName != "name" && attributeName != "description" && attributeName != "styleUrl") {
+ var data = this.createElementNS(this.kmlns, "Data");
+ data.setAttribute("name", attributeName);
+ var value = this.createElementNS(this.kmlns, "value");
+ if (typeof attributes[attributeName] == "object") {
+ // cater for object attributes with 'value' properties
+ // other object properties will output an empty node
+ if (attributes[attributeName].value) {
+ value.appendChild(this.createTextNode(attributes[attributeName].value));
+ }
+ if (attributes[attributeName].displayName) {
+ var displayName = this.createElementNS(this.kmlns, "displayName");
+ // displayName always written as CDATA
+ displayName.appendChild(this.getXMLDoc().createCDATASection(attributes[attributeName].displayName));
+ data.appendChild(displayName);
+ }
+ } else {
+ value.appendChild(this.createTextNode(attributes[attributeName]));
+ }
+ data.appendChild(value);
+ extendedData.appendChild(data);
+ }
+ }
+ if (this.isSimpleContent(extendedData)) {
+ return null;
+ } else {
+ return extendedData;
+ }
+ },
+
CLASS_NAME: "OpenLayers.Format.KML"
});
diff --git a/lib/OpenLayers/Format/SLD/v1.js b/lib/OpenLayers/Format/SLD/v1.js
index a6fe969c4a..71855cbee0 100644
--- a/lib/OpenLayers/Format/SLD/v1.js
+++ b/lib/OpenLayers/Format/SLD/v1.js
@@ -220,6 +220,78 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
);
}
},
+ "LabelPlacement": function(node, symbolizer) {
+ this.readChildNodes(node, symbolizer);
+ },
+ "PointPlacement": function(node, symbolizer) {
+ var config = {};
+ this.readChildNodes(node, config);
+ config.labelRotation = config.rotation;
+ delete config.rotation;
+ var labelAlign,
+ x = symbolizer.labelAnchorPointX,
+ y = symbolizer.labelAnchorPointY;
+ if (x <= 1/3) {
+ labelAlign = 'l';
+ } else if (x > 1/3 && x < 2/3) {
+ labelAlign = 'c';
+ } else if (x >= 2/3) {
+ labelAlign = 'r';
+ }
+ if (y <= 1/3) {
+ labelAlign += 'b';
+ } else if (y > 1/3 && y < 2/3) {
+ labelAlign += 'm';
+ } else if (y >= 2/3) {
+ labelAlign += 't';
+ }
+ config.labelAlign = labelAlign;
+ OpenLayers.Util.applyDefaults(symbolizer, config);
+ },
+ "AnchorPoint": function(node, symbolizer) {
+ this.readChildNodes(node, symbolizer);
+ },
+ "AnchorPointX": function(node, symbolizer) {
+ var labelAnchorPointX = this.readers.ogc._expression.call(this, node);
+ // always string, could be empty string
+ if(labelAnchorPointX) {
+ symbolizer.labelAnchorPointX = labelAnchorPointX;
+ }
+ },
+ "AnchorPointY": function(node, symbolizer) {
+ var labelAnchorPointY = this.readers.ogc._expression.call(this, node);
+ // always string, could be empty string
+ if(labelAnchorPointY) {
+ symbolizer.labelAnchorPointY = labelAnchorPointY;
+ }
+ },
+ "Displacement": function(node, symbolizer) {
+ this.readChildNodes(node, symbolizer);
+ },
+ "DisplacementX": function(node, symbolizer) {
+ var labelXOffset = this.readers.ogc._expression.call(this, node);
+ // always string, could be empty string
+ if(labelXOffset) {
+ symbolizer.labelXOffset = labelXOffset;
+ }
+ },
+ "DisplacementY": function(node, symbolizer) {
+ var labelYOffset = this.readers.ogc._expression.call(this, node);
+ // always string, could be empty string
+ if(labelYOffset) {
+ symbolizer.labelYOffset = labelYOffset;
+ }
+ },
+ "LinePlacement": function(node, symbolizer) {
+ this.readChildNodes(node, symbolizer);
+ },
+ "PerpendicularOffset": function(node, symbolizer) {
+ var labelPerpendicularOffset = this.readers.ogc._expression.call(this, node);
+ // always string, could be empty string
+ if(labelPerpendicularOffset) {
+ symbolizer.labelPerpendicularOffset = labelPerpendicularOffset;
+ }
+ },
"Label": function(node, symbolizer) {
var value = this.readers.ogc._expression.call(this, node);
if (value) {
@@ -481,7 +553,7 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
* Method: getGraphicFormat
* Given a href for an external graphic, try to determine the mime-type.
* This method doesn't try too hard, and will fall back to
- * if one of the known is not
+ * if one of the known is not
* the file extension of the provided href.
*
* Parameters:
@@ -498,7 +570,7 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
break;
}
}
- return format || this.defautlGraphicFormat;
+ return format || this.defaultGraphicFormat;
},
/**
@@ -885,16 +957,26 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
}
// add in optional Font
if(symbolizer.fontFamily != null ||
- symbolizer.fontSize != null ||
- symbolizer.fontWeight != null ||
- symbolizer.fontStyle != null) {
- this.writeNode("Font", symbolizer, node);
+ symbolizer.fontSize != null ||
+ symbolizer.fontWeight != null ||
+ symbolizer.fontStyle != null) {
+ this.writeNode("Font", symbolizer, node);
+ }
+ // add in optional LabelPlacement
+ if (symbolizer.labelAnchorPointX != null ||
+ symbolizer.labelAnchorPointY != null ||
+ symbolizer.labelAlign != null ||
+ symbolizer.labelXOffset != null ||
+ symbolizer.labelYOffset != null ||
+ symbolizer.labelRotation != null ||
+ symbolizer.labelPerpendicularOffset != null) {
+ this.writeNode("LabelPlacement", symbolizer, node);
}
// add in optional Halo
if(symbolizer.haloRadius != null ||
- symbolizer.haloColor != null ||
- symbolizer.haloOpacity != null) {
- this.writeNode("Halo", symbolizer, node);
+ symbolizer.haloColor != null ||
+ symbolizer.haloOpacity != null) {
+ this.writeNode("Halo", symbolizer, node);
}
// add in optional Fill
if(symbolizer.fontColor != null ||
@@ -906,6 +988,111 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
}
return node;
},
+ "LabelPlacement": function(symbolizer) {
+ var node = this.createElementNSPlus("sld:LabelPlacement");
+ // PointPlacement and LinePlacement are choices, so don't output both
+ if ((symbolizer.labelAnchorPointX != null ||
+ symbolizer.labelAnchorPointY != null ||
+ symbolizer.labelAlign != null ||
+ symbolizer.labelXOffset != null ||
+ symbolizer.labelYOffset != null ||
+ symbolizer.labelRotation != null) &&
+ symbolizer.labelPerpendicularOffset == null) {
+ this.writeNode("PointPlacement", symbolizer, node);
+ }
+ if (symbolizer.labelPerpendicularOffset != null) {
+ this.writeNode("LinePlacement", symbolizer, node);
+ }
+ return node;
+ },
+ "LinePlacement": function(symbolizer) {
+ var node = this.createElementNSPlus("sld:LinePlacement");
+ this.writeNode("PerpendicularOffset", symbolizer.labelPerpendicularOffset, node);
+ return node;
+ },
+ "PerpendicularOffset": function(value) {
+ return this.createElementNSPlus("sld:PerpendicularOffset", {
+ value: value
+ });
+ },
+ "PointPlacement": function(symbolizer) {
+ var node = this.createElementNSPlus("sld:PointPlacement");
+ if (symbolizer.labelAnchorPointX != null ||
+ symbolizer.labelAnchorPointY != null ||
+ symbolizer.labelAlign != null) {
+ this.writeNode("AnchorPoint", symbolizer, node);
+ }
+ if (symbolizer.labelXOffset != null ||
+ symbolizer.labelYOffset != null) {
+ this.writeNode("Displacement", symbolizer, node);
+ }
+ if (symbolizer.labelRotation != null) {
+ this.writeNode("Rotation", symbolizer.labelRotation, node);
+ }
+ return node;
+ },
+ "AnchorPoint": function(symbolizer) {
+ var node = this.createElementNSPlus("sld:AnchorPoint");
+ var x = symbolizer.labelAnchorPointX,
+ y = symbolizer.labelAnchorPointY;
+ if (x != null) {
+ this.writeNode("AnchorPointX", x, node);
+ }
+ if (y != null) {
+ this.writeNode("AnchorPointY", y, node);
+ }
+ if (x == null && y == null) {
+ var xAlign = symbolizer.labelAlign.substr(0, 1),
+ yAlign = symbolizer.labelAlign.substr(1, 1);
+ if (xAlign === "l") {
+ x = 0;
+ } else if (xAlign === "c") {
+ x = 0.5;
+ } else if (xAlign === "r") {
+ x = 1;
+ }
+ if (yAlign === "b") {
+ y = 0;
+ } else if (yAlign === "m") {
+ y = 0.5;
+ } else if (yAlign === "t") {
+ y = 1;
+ }
+ this.writeNode("AnchorPointX", x, node);
+ this.writeNode("AnchorPointY", y, node);
+ }
+ return node;
+ },
+ "AnchorPointX": function(value) {
+ return this.createElementNSPlus("sld:AnchorPointX", {
+ value: value
+ });
+ },
+ "AnchorPointY": function(value) {
+ return this.createElementNSPlus("sld:AnchorPointY", {
+ value: value
+ });
+ },
+ "Displacement": function(symbolizer) {
+ var node = this.createElementNSPlus("sld:Displacement");
+ if (symbolizer.labelXOffset != null) {
+ this.writeNode("DisplacementX", symbolizer.labelXOffset, node);
+ }
+ if (symbolizer.labelYOffset != null) {
+ this.writeNode("DisplacementY", symbolizer.labelYOffset, node);
+ }
+ return node;
+ },
+ "DisplacementX": function(value) {
+ return this.createElementNSPlus("sld:DisplacementX", {
+ value: value
+ });
+ },
+ "DisplacementY": function(value) {
+ return this.createElementNSPlus("sld:DisplacementY", {
+ value: value
+ });
+ },
"Font": function(symbolizer) {
var node = this.createElementNSPlus("sld:Font");
// add in CssParameters
diff --git a/lib/OpenLayers/Format/SLD/v1_0_0_GeoServer.js b/lib/OpenLayers/Format/SLD/v1_0_0_GeoServer.js
index 49596be1c4..bee661311b 100644
--- a/lib/OpenLayers/Format/SLD/v1_0_0_GeoServer.js
+++ b/lib/OpenLayers/Format/SLD/v1_0_0_GeoServer.js
@@ -58,12 +58,9 @@ OpenLayers.Format.SLD.v1_0_0_GeoServer = OpenLayers.Class(
},
"VendorOption": function(node, obj) {
if (!obj.vendorOptions) {
- obj.vendorOptions = [];
+ obj.vendorOptions = {};
}
- obj.vendorOptions.push({
- name: node.getAttribute("name"),
- value: this.getChildValue(node)
- });
+ obj.vendorOptions[node.getAttribute("name")] = this.getChildValue(node);
}
}, OpenLayers.Format.SLD.v1_0_0.prototype.readers["sld"])
}, OpenLayers.Format.SLD.v1_0_0.prototype.readers),
@@ -130,8 +127,11 @@ OpenLayers.Format.SLD.v1_0_0_GeoServer = OpenLayers.Class(
addVendorOptions: function(node, symbolizer) {
var options = symbolizer.vendorOptions;
if (options) {
- for (var i=0, ii=options.length; i
*/
OpenLayers.Format.WFSCapabilities.v1 = OpenLayers.Class(
- OpenLayers.Format.WFSCapabilities, {
+ OpenLayers.Format.XML, {
+
+ /**
+ * Property: namespaces
+ * {Object} Mapping of namespace aliases to namespace URIs.
+ */
+ namespaces: {
+ wfs: "http://www.opengis.net/wfs",
+ xlink: "http://www.w3.org/1999/xlink",
+ xsi: "http://www.w3.org/2001/XMLSchema-instance",
+ ows: "http://www.opengis.net/ows"
+ },
+
+ /**
+ * Property: defaultPrefix
+ */
+ defaultPrefix: "wfs",
/**
* Constructor: OpenLayers.Format.WFSCapabilities.v1_1
@@ -25,10 +41,6 @@ OpenLayers.Format.WFSCapabilities.v1 = OpenLayers.Class(
* options - {Object} An optional object whose properties will be set on
* this instance.
*/
- initialize: function(options) {
- OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);
- this.options = options;
- },
/**
* APIMethod: read
@@ -44,83 +56,64 @@ OpenLayers.Format.WFSCapabilities.v1 = OpenLayers.Class(
if(typeof data == "string") {
data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);
}
+ var raw = data;
+ if(data && data.nodeType == 9) {
+ data = data.documentElement;
+ }
var capabilities = {};
- var root = data.documentElement;
- this.runChildNodes(capabilities, root);
+ this.readNode(data, capabilities);
return capabilities;
},
-
+
/**
- * Method: runChildNodes
+ * Property: readers
+ * Contains public functions, grouped by namespace prefix, that will
+ * be applied when a namespaced node is found matching the function
+ * name. The function will be applied in the scope of this parser
+ * with two arguments: the node being read and a context object passed
+ * from the parent.
*/
- runChildNodes: function(obj, node) {
- var children = node.childNodes;
- var childNode, processor;
- for(var i=0; i 0) {
+ obj.featureNS = this.lookupNamespaceURI(node, parts[0]);
+ }
+ }
+ },
+ "Title": function(node, obj) {
+ var title = this.getChildValue(node);
+ if(title) {
+ obj.title = title;
+ }
+ },
+ "Abstract": function(node, obj) {
+ var abst = this.getChildValue(node);
+ if(abst) {
+ obj["abstract"] = abst;
}
}
}
},
-
- /**
- * Method: read_cap_FeatureTypeList
- */
- read_cap_FeatureTypeList: function(request, node) {
- var featureTypeList = {
- featureTypes: []
- };
- this.runChildNodes(featureTypeList, node);
- request.featureTypeList = featureTypeList;
- },
-
- /**
- * Method: read_cap_FeatureType
- */
- read_cap_FeatureType: function(featureTypeList, node, parentLayer) {
- var featureType = {};
- this.runChildNodes(featureType, node);
- featureTypeList.featureTypes.push(featureType);
- },
-
- /**
- * Method: read_cap_Name
- */
- read_cap_Name: function(obj, node) {
- var name = this.getChildValue(node);
- if(name) {
- var parts = name.split(":");
- obj.name = parts.pop();
- if(parts.length > 0) {
- obj.featureNS = this.lookupNamespaceURI(node, parts[0]);
- }
- }
- },
-
- /**
- * Method: read_cap_Title
- */
- read_cap_Title: function(obj, node) {
- var title = this.getChildValue(node);
- if(title) {
- obj.title = title;
- }
- },
- /**
- * Method: read_cap_Abstract
- */
- read_cap_Abstract: function(obj, node) {
- var abst = this.getChildValue(node);
- if(abst) {
- obj["abstract"] = abst;
- }
- },
-
CLASS_NAME: "OpenLayers.Format.WFSCapabilities.v1"
});
diff --git a/lib/OpenLayers/Format/WFSCapabilities/v1_0_0.js b/lib/OpenLayers/Format/WFSCapabilities/v1_0_0.js
index 8b86487b65..0dc41f67fb 100644
--- a/lib/OpenLayers/Format/WFSCapabilities/v1_0_0.js
+++ b/lib/OpenLayers/Format/WFSCapabilities/v1_0_0.js
@@ -25,136 +25,89 @@ OpenLayers.Format.WFSCapabilities.v1_0_0 = OpenLayers.Class(
* options - {Object} An optional object whose properties will be set on
* this instance.
*/
-
- /**
- * Method: read_cap_Service
- */
- read_cap_Service: function(capabilities, node) {
- var service = {};
- this.runChildNodes(service, node);
- capabilities.service = service;
- },
/**
- * Method: read_cap_Fees
- */
- read_cap_Fees: function(service, node) {
- var fees = this.getChildValue(node);
- if (fees && fees.toLowerCase() != "none") {
- service.fees = fees;
- }
- },
-
- /**
- * Method: read_cap_AccessConstraints
- */
- read_cap_AccessConstraints: function(service, node) {
- var constraints = this.getChildValue(node);
- if (constraints && constraints.toLowerCase() != "none") {
- service.accessConstraints = constraints;
- }
- },
-
- /**
- * Method: read_cap_OnlineResource
- */
- read_cap_OnlineResource: function(service, node) {
- var onlineResource = this.getChildValue(node);
- if (onlineResource && onlineResource.toLowerCase() != "none") {
- service.onlineResource = onlineResource;
- }
- },
-
- /**
- * Method: read_cap_Keywords
- */
- read_cap_Keywords: function(service, node) {
- var keywords = this.getChildValue(node);
- if (keywords && keywords.toLowerCase() != "none") {
- service.keywords = keywords.split(', ');
- }
- },
-
- /**
- * Method: read_cap_Capability
- */
- read_cap_Capability: function(capabilities, node) {
- var capability = {};
- this.runChildNodes(capability, node);
- capabilities.capability = capability;
- },
-
- /**
- * Method: read_cap_Request
- */
- read_cap_Request: function(obj, node) {
- var request = {};
- this.runChildNodes(request, node);
- obj.request = request;
- },
-
- /**
- * Method: read_cap_GetFeature
+ * Property: readers
+ * Contains public functions, grouped by namespace prefix, that will
+ * be applied when a namespaced node is found matching the function
+ * name. The function will be applied in the scope of this parser
+ * with two arguments: the node being read and a context object passed
+ * from the parent.
*/
- read_cap_GetFeature: function(request, node) {
- var getfeature = {
- href: {}, // DCPType
- formats: [] // ResultFormat
- };
- this.runChildNodes(getfeature, node);
- request.getfeature = getfeature;
- },
-
- /**
- * Method: read_cap_ResultFormat
- */
- read_cap_ResultFormat: function(obj, node) {
- var children = node.childNodes;
- var childNode;
- for(var i=0; i} For layers with a gutter, the image offset
- * represents displacement due to the gutter.
- */
- imageOffset: null,
-
// OPTIONS
/**
@@ -693,7 +686,7 @@ OpenLayers.Layer = OpenLayers.Class({
/**
* APIMethod: setTileSize
* Set the tile size based on the map size. This also sets layer.imageSize
- * and layer.imageOffset for use by Tile.Image.
+ * or use by Tile.Image.
*
* Parameters:
* size - {}
@@ -710,8 +703,6 @@ OpenLayers.Layer = OpenLayers.Class({
// 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));
}
diff --git a/lib/OpenLayers/Layer/ArcGISCache.js b/lib/OpenLayers/Layer/ArcGISCache.js
index 9c500e4533..27173392c4 100644
--- a/lib/OpenLayers/Layer/ArcGISCache.js
+++ b/lib/OpenLayers/Layer/ArcGISCache.js
@@ -452,7 +452,9 @@ OpenLayers.Layer.ArcGISCache = OpenLayers.Class(OpenLayers.Layer.XYZ, {
// Write the values into our formatted url
url = OpenLayers.String.format(url, {'x': x, 'y': y, 'z': z});
- return url;
+ return OpenLayers.Util.urlAppend(
+ url, OpenLayers.Util.getParameterString(this.params)
+ );
},
/**
diff --git a/lib/OpenLayers/Layer/Grid.js b/lib/OpenLayers/Layer/Grid.js
index 1e767f75dd..e84411cee9 100644
--- a/lib/OpenLayers/Layer/Grid.js
+++ b/lib/OpenLayers/Layer/Grid.js
@@ -202,6 +202,10 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* track of the loading progress. Listeners are called with an object
* with a tile property as first argument, making the loded tile
* available to the listener.
+ * tileerror - Triggered before the tileloaded event (i.e. when the tile is
+ * still hidden) if a tile failed to load. Listeners receive an object
+ * as first argument, which has a tile property that references the
+ * tile that could not be loaded.
*/
/**
@@ -969,7 +973,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
}
this.numLoadingTiles++;
};
- tile.events.register("loadstart", this, tile.onLoadStart);
tile.onLoadEnd = function() {
this.numLoadingTiles--;
@@ -987,8 +990,18 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
}
}
};
- tile.events.register("loadend", this, tile.onLoadEnd);
- tile.events.register("unload", this, tile.onLoadEnd);
+
+ tile.onLoadError = function() {
+ this.events.triggerEvent("tileerror", {tile: tile});
+ };
+
+ tile.events.on({
+ "loadstart": tile.onLoadStart,
+ "loadend": tile.onLoadEnd,
+ "unload": tile.onLoadEnd,
+ "loaderror": tile.onLoadError,
+ scope: this
+ });
},
/**
@@ -1005,6 +1018,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
"loadstart": tile.onLoadStart,
"loadend": tile.onLoadEnd,
"unload": tile.onLoadEnd,
+ "loaderror": tile.onLoadError,
scope: this
});
},
diff --git a/lib/OpenLayers/Layer/HTTPRequest.js b/lib/OpenLayers/Layer/HTTPRequest.js
index 7855cb6b03..d1e9bf2219 100644
--- a/lib/OpenLayers/Layer/HTTPRequest.js
+++ b/lib/OpenLayers/Layer/HTTPRequest.js
@@ -60,7 +60,9 @@ OpenLayers.Layer.HTTPRequest = OpenLayers.Class(OpenLayers.Layer, {
initialize: function(name, url, params, options) {
OpenLayers.Layer.prototype.initialize.apply(this, [name, options]);
this.url = url;
- this.params = OpenLayers.Util.extend( {}, params);
+ if (!this.params) {
+ this.params = OpenLayers.Util.extend({}, params);
+ }
},
/**
diff --git a/lib/OpenLayers/Layer/OSM.js b/lib/OpenLayers/Layer/OSM.js
index 04e7b04454..264687644f 100644
--- a/lib/OpenLayers/Layer/OSM.js
+++ b/lib/OpenLayers/Layer/OSM.js
@@ -34,7 +34,7 @@ OpenLayers.Layer.OSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
/**
* APIProperty: url
* {String} The tileset URL scheme. Defaults to
- * : http://tile.openstreetmap.org/${z}/${x}/${y}.png
+ * : http://[a|b|c].tile.openstreetmap.org/${z}/${x}/${y}.png
* (the official OSM tileset) if the second argument to the constructor
* is null or undefined. To use another tileset you can have something
* like this:
@@ -43,7 +43,11 @@ OpenLayers.Layer.OSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
* "http://tah.openstreetmap.org/Tiles/tile/${z}/${x}/${y}.png");
* (end)
*/
- url: 'http://tile.openstreetmap.org/${z}/${x}/${y}.png',
+ url: [
+ 'http://a.tile.openstreetmap.org/${z}/${x}/${y}.png',
+ 'http://b.tile.openstreetmap.org/${z}/${x}/${y}.png',
+ 'http://c.tile.openstreetmap.org/${z}/${x}/${y}.png'
+ ],
/**
* Property: attribution
diff --git a/lib/OpenLayers/Map.js b/lib/OpenLayers/Map.js
index 15b3bb03dd..016c4110b8 100644
--- a/lib/OpenLayers/Map.js
+++ b/lib/OpenLayers/Map.js
@@ -239,6 +239,12 @@ OpenLayers.Map = OpenLayers.Class({
*/
panRatio: 1.5,
+ /**
+ * APIProperty: options
+ * {Object} The options object passed to the class constructor. Read-only.
+ */
+ options: null,
+
// Options
/**
@@ -480,6 +486,9 @@ OpenLayers.Map = OpenLayers.Class({
this.theme = OpenLayers._getScriptLocation() +
'theme/default/style.css';
+ // backup original options
+ this.options = OpenLayers.Util.extend({}, options);
+
// now override default options
OpenLayers.Util.extend(this, options);
@@ -487,13 +496,16 @@ OpenLayers.Map = OpenLayers.Class({
this.projection.projCode : this.projection;
OpenLayers.Util.applyDefaults(this, OpenLayers.Projection.defaults[projCode]);
- // allow extents to be arrays
+ // allow extents and center to be arrays
if (this.maxExtent && !(this.maxExtent instanceof OpenLayers.Bounds)) {
this.maxExtent = new OpenLayers.Bounds(this.maxExtent);
}
if (this.restrictedExtent && !(this.restrictedExtent instanceof OpenLayers.Bounds)) {
this.restrictedExtent = new OpenLayers.Bounds(this.restrictedExtent);
}
+ if (this.center && !(this.center instanceof OpenLayers.LonLat)) {
+ this.center = new OpenLayers.LonLat(this.center);
+ }
// initialize layers array
this.layers = [];
@@ -616,9 +628,9 @@ OpenLayers.Map = OpenLayers.Class({
* be properly set below.
*/
delete this.center;
- this.addLayers(options.layers);
+ this.addLayers(options.layers);
// set center (and optionally zoom)
- if (options.center) {
+ if (options.center && !this.getCenter()) {
// zoom can be undefined here
this.setCenter(options.center, options.zoom);
}
@@ -731,6 +743,7 @@ OpenLayers.Map = OpenLayers.Class({
this.events.destroy();
this.events = null;
+ this.options = null;
},
/**
diff --git a/lib/OpenLayers/Popup.js b/lib/OpenLayers/Popup.js
index 36f666e73f..774ecb8c03 100644
--- a/lib/OpenLayers/Popup.js
+++ b/lib/OpenLayers/Popup.js
@@ -685,7 +685,9 @@ OpenLayers.Popup = OpenLayers.Class({
// 'img' properties in the context.
//
var onImgLoad = function() {
-
+ if (this.popup.id === null) { // this.popup has been destroyed!
+ return;
+ }
this.popup.updateSize();
if ( this.popup.visible() && this.popup.panMapIfOutOfView ) {
diff --git a/lib/OpenLayers/Protocol/HTTP.js b/lib/OpenLayers/Protocol/HTTP.js
index ebfacac705..d5c822c7d2 100644
--- a/lib/OpenLayers/Protocol/HTTP.js
+++ b/lib/OpenLayers/Protocol/HTTP.js
@@ -62,12 +62,27 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {
scope: null,
/**
- * Property: readWithPOST
+ * APIProperty: readWithPOST
* {Boolean} true if read operations are done with POST requests
* instead of GET, defaults to false.
*/
readWithPOST: false,
+ /**
+ * APIProperty: updateWithPOST
+ * {Boolean} true if update operations are done with POST requests
+ * defaults to false.
+ */
+ updateWithPOST: false,
+
+ /**
+ * APIProperty: deleteWithPOST
+ * {Boolean} true if delete operations are done with POST requests
+ * defaults to false.
+ * if true, POST data is set to output of format.write().
+ */
+ deleteWithPOST: false,
+
/**
* Property: wildcarded.
* {Boolean} If true percent signs are added around values
@@ -99,7 +114,7 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {
* Valid options include:
* url - {String}
* headers - {Object}
- * params - {Object}
+ * params - {Object} URL parameters for GET requests
* format - {}
* callback - {Function}
* scope - {Object}
@@ -293,7 +308,8 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {
requestType: "update"
});
- resp.priv = OpenLayers.Request.PUT({
+ var method = this.updateWithPOST ? "POST" : "PUT";
+ resp.priv = OpenLayers.Request[method]({
url: url,
callback: this.createCallback(this.handleUpdate, resp, options),
headers: options.headers,
@@ -344,11 +360,16 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {
requestType: "delete"
});
- resp.priv = OpenLayers.Request.DELETE({
+ var method = this.deleteWithPOST ? "POST" : "DELETE";
+ var requestOptions = {
url: url,
callback: this.createCallback(this.handleDelete, resp, options),
headers: options.headers
- });
+ };
+ if (this.deleteWithPOST) {
+ requestOptions.data = this.format.write(feature);
+ }
+ resp.priv = OpenLayers.Request[method](requestOptions);
return resp;
},
diff --git a/lib/OpenLayers/Protocol/Script.js b/lib/OpenLayers/Protocol/Script.js
index 49e332b7f0..62f7840bb4 100644
--- a/lib/OpenLayers/Protocol/Script.js
+++ b/lib/OpenLayers/Protocol/Script.js
@@ -54,20 +54,12 @@ OpenLayers.Protocol.Script = OpenLayers.Class(OpenLayers.Protocol, {
callback: null,
/**
- * APIProperty: scope
- * {Object} Optional ``this`` object for the callback. Read-only, set
- * through the options passed to the constructor.
+ * APIProperty: callbackTemplate
+ * {String} Template for creating a unique callback function name
+ * for the registry. Should include ${id}.
+ * Default is "OpenLayers.Protocol.Script.registry[${id}]".
*/
- scope: null,
-
- /**
- * APIProperty: format
- * {} Format for parsing features. Default is an
- * format. If an alternative is provided,
- * the format's read method must take an object and return an array
- * of features.
- */
- format: null,
+ callbackTemplate: "OpenLayers.Protocol.Script.registry[${id}]",
/**
* APIProperty: callbackKey
@@ -88,6 +80,22 @@ OpenLayers.Protocol.Script = OpenLayers.Class(OpenLayers.Protocol, {
*/
callbackPrefix: "",
+ /**
+ * APIProperty: scope
+ * {Object} Optional ``this`` object for the callback. Read-only, set
+ * through the options passed to the constructor.
+ */
+ scope: null,
+
+ /**
+ * APIProperty: format
+ * {} Format for parsing features. Default is an
+ * format. If an alternative is provided,
+ * the format's read method must take an object and return an array
+ * of features.
+ */
+ format: null,
+
/**
* Property: pendingRequests
* {Object} References all pending requests. Property names are script
@@ -135,7 +143,7 @@ OpenLayers.Protocol.Script = OpenLayers.Class(OpenLayers.Protocol, {
});
this.filterToParams = function(filter, params) {
return format.write(filter, params);
- }
+ };
}
},
@@ -212,7 +220,7 @@ OpenLayers.Protocol.Script = OpenLayers.Class(OpenLayers.Protocol, {
*/
createRequest: function(url, params, callback) {
var id = OpenLayers.Protocol.Script.register(callback);
- var name = "OpenLayers.Protocol.Script.registry[" + id + "]";
+ var name = OpenLayers.String.format(this.callbackTemplate, {id: id});
params = OpenLayers.Util.extend({}, params);
params[this.callbackKey] = this.callbackPrefix + name;
url = OpenLayers.Util.urlAppend(
@@ -333,7 +341,7 @@ OpenLayers.Protocol.Script = OpenLayers.Class(OpenLayers.Protocol, {
(function() {
var o = OpenLayers.Protocol.Script;
var counter = 0;
- o.registry = [];
+ o.registry = {};
/**
* Function: OpenLayers.Protocol.Script.register
@@ -345,12 +353,11 @@ OpenLayers.Protocol.Script = OpenLayers.Class(OpenLayers.Protocol, {
* that is the JSON returned by the service.
*
* Returns:
- * {Number} An identifier for retreiving the registered callback.
+ * {Number} An identifier for retrieving the registered callback.
*/
o.register = function(callback) {
- var id = ++counter;
+ var id = "c"+(++counter);
o.registry[id] = function() {
- o.unregister(id);
callback.apply(this, arguments);
};
return id;
diff --git a/lib/OpenLayers/Renderer.js b/lib/OpenLayers/Renderer.js
index 45de3a6f3f..3d7ffa1596 100644
--- a/lib/OpenLayers/Renderer.js
+++ b/lib/OpenLayers/Renderer.js
@@ -415,3 +415,18 @@ OpenLayers.Renderer.defaultSymbolizer = {
labelAlign: 'cm'
};
+
+
+/**
+ * Constant: OpenLayers.Renderer.symbol
+ * Coordinate arrays for well known (named) symbols.
+ */
+OpenLayers.Renderer.symbol = {
+ "star": [350,75, 379,161, 469,161, 397,215, 423,301, 350,250, 277,301,
+ 303,215, 231,161, 321,161, 350,75],
+ "cross": [4,0, 6,0, 6,4, 10,4, 10,6, 6,6, 6,10, 4,10, 4,6, 0,6, 0,4, 4,4,
+ 4,0],
+ "x": [0,0, 25,0, 50,35, 75,0, 100,0, 65,50, 100,100, 75,100, 50,65, 25,100, 0,100, 35,50, 0,0],
+ "square": [0,0, 0,1, 1,1, 1,0, 0,0],
+ "triangle": [0,10, 10,10, 5,0, 0,10]
+};
\ No newline at end of file
diff --git a/lib/OpenLayers/Renderer/Canvas.js b/lib/OpenLayers/Renderer/Canvas.js
index 35939afdd2..74ae40b768 100644
--- a/lib/OpenLayers/Renderer/Canvas.js
+++ b/lib/OpenLayers/Renderer/Canvas.js
@@ -434,28 +434,6 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
}
},
- /**
- * Method: setCanvasStyle
- * Prepare the canvas for drawing by setting various global settings.
- *
- * Parameters:
- * type - {String} one of 'stroke', 'fill', or 'reset'
- * style - {Object} Symbolizer hash
- */
- setCanvasStyle: function(type, style) {
- if (type === "fill") {
- this.canvas.globalAlpha = style['fillOpacity'];
- this.canvas.fillStyle = style['fillColor'];
- } else if (type === "stroke") {
- this.canvas.globalAlpha = style['strokeOpacity'];
- this.canvas.strokeStyle = style['strokeColor'];
- this.canvas.lineWidth = style['strokeWidth'];
- } else {
- this.canvas.globalAlpha = 0;
- this.canvas.lineWidth = 1;
- }
- },
-
/**
* Method: featureIdToHex
* Convert a feature ID string into an RGB hex string.
@@ -787,7 +765,8 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
*/
getFeatureIdFromEvent: function(evt) {
var featureId, feature;
- if (this.hitDetection) {
+
+ if (this.hitDetection && this.root.style.display !== "none") {
// this dragging check should go in the feature handler
if (!this.map.dragging) {
var xy = evt.xy;
diff --git a/lib/OpenLayers/Renderer/Elements.js b/lib/OpenLayers/Renderer/Elements.js
index 7e1d89e5b1..11735f4eeb 100644
--- a/lib/OpenLayers/Renderer/Elements.js
+++ b/lib/OpenLayers/Renderer/Elements.js
@@ -1051,17 +1051,3 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, {
CLASS_NAME: "OpenLayers.Renderer.Elements"
});
-
-/**
- * Constant: OpenLayers.Renderer.symbol
- * Coordinate arrays for well known (named) symbols.
- */
-OpenLayers.Renderer.symbol = {
- "star": [350,75, 379,161, 469,161, 397,215, 423,301, 350,250, 277,301,
- 303,215, 231,161, 321,161, 350,75],
- "cross": [4,0, 6,0, 6,4, 10,4, 10,6, 6,6, 6,10, 4,10, 4,6, 0,6, 0,4, 4,4,
- 4,0],
- "x": [0,0, 25,0, 50,35, 75,0, 100,0, 65,50, 100,100, 75,100, 50,65, 25,100, 0,100, 35,50, 0,0],
- "square": [0,0, 0,1, 1,1, 1,0, 0,0],
- "triangle": [0,10, 10,10, 5,0, 0,10]
-};
diff --git a/lib/OpenLayers/Spherical.js b/lib/OpenLayers/Spherical.js
index 4a8956a5b7..b3957d4910 100644
--- a/lib/OpenLayers/Spherical.js
+++ b/lib/OpenLayers/Spherical.js
@@ -3,6 +3,10 @@
* See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
+/**
+ * @requires OpenLayers/SingleFile.js
+ */
+
/**
* Namespace: Spherical
* The OpenLayers.Spherical namespace includes utility functions for
diff --git a/lib/OpenLayers/Tile.js b/lib/OpenLayers/Tile.js
index d1d11eef8f..56c49c6320 100644
--- a/lib/OpenLayers/Tile.js
+++ b/lib/OpenLayers/Tile.js
@@ -40,6 +40,8 @@ OpenLayers.Tile = OpenLayers.Class({
* to call (true) to actually draw the tile.
* loadstart - Triggered when tile loading starts.
* loadend - Triggered when tile loading ends.
+ * loaderror - Triggered before the loadend event (i.e. when the tile is
+ * still hidden) if the tile could not be loaded.
* reload - Triggered when an already loading tile is reloaded.
* unload - Triggered before a tile is unloaded.
*/
diff --git a/lib/OpenLayers/Tile/Image.js b/lib/OpenLayers/Tile/Image.js
index 5332c1581d..778ececc92 100644
--- a/lib/OpenLayers/Tile/Image.js
+++ b/lib/OpenLayers/Tile/Image.js
@@ -208,11 +208,12 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
* code.
*/
positionTile: function() {
- var style = this.getTile().style;
+ var style = this.getTile().style,
+ size = this.layer.getImageSize(this.bounds);
style.left = this.position.x + "%";
style.top = this.position.y + "%";
- style.width = this.size.w + "%";
- style.height = this.size.h + "%";
+ style.width = size.w + "%";
+ style.height = size.h + "%";
},
/**
@@ -256,11 +257,6 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
var top = this.layer.gutter / this.layer.tileSize.h * 100;
style.left = -left + "%";
style.top = -top + "%";
- style.width = (2 * left + 100) + "%";
- style.height = (2 * top + 100) + "%";
- } else {
- style.width = "100%";
- style.height = "100%";
}
style.visibility = "hidden";
style.opacity = 0;
@@ -429,6 +425,7 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
this.setImgSrc(this.layer.getURL(this.bounds));
} else {
OpenLayers.Element.addClass(img, "olImageLoadError");
+ this.events.triggerEvent("loaderror");
this.onImageLoad();
}
}
diff --git a/lib/OpenLayers/Tile/Image/IFrame.js b/lib/OpenLayers/Tile/Image/IFrame.js
index eefa7bbe91..b29798cccc 100644
--- a/lib/OpenLayers/Tile/Image/IFrame.js
+++ b/lib/OpenLayers/Tile/Image/IFrame.js
@@ -65,7 +65,11 @@ OpenLayers.Tile.Image.IFrame = {
// And if we had an iframe we also remove the event pane.
if(fromIFrame) {
+ this.blankImageUrl = this._blankImageUrl;
this.frame.removeChild(this.frame.firstChild);
+ } else {
+ this._blankImageUrl = this.blankImageUrl;
+ this.blankImageUrl = "about:blank";
}
}
}
@@ -85,7 +89,7 @@ OpenLayers.Tile.Image.IFrame = {
style.width = "100%";
style.height = "100%";
style.zIndex = 1;
- style.backgroundImage = "url(" + this.blankImageUrl + ")";
+ style.backgroundImage = "url(" + this._blankImageUrl + ")";
this.frame.appendChild(eventPane);
}
@@ -133,7 +137,7 @@ OpenLayers.Tile.Image.IFrame = {
return OpenLayers.Tile.Image.prototype.getImage.apply(this, arguments);
}
},
-
+
/**
* Method: createRequestForm
* Create the html