Merge branch 'master' into utfgrid

This commit is contained in:
Tim Schaub
2012-02-25 16:08:11 -07:00
100 changed files with 1690 additions and 721 deletions

View File

@@ -1,45 +0,0 @@
# This file includes the OpenLayers code to create a build for everything that
# does not require vector support.
[first]
[last]
[include]
[exclude]
Firebug
OpenLayers.js
OpenLayers/Format/GeoRSS.js
OpenLayers/Format/GML.js
OpenLayers/Format/WKT.js
OpenLayers/Format/KML.js
OpenLayers/Format/WFS.js
OpenLayers/Format.js
OpenLayers/Handler/Path.js
OpenLayers/Handler/Point.js
OpenLayers/Handler/Polygon.js
OpenLayers/Handler/Select.js
OpenLayers/Geometry/Collection.js
OpenLayers/Geometry/Curve.js
OpenLayers/Geometry/LinearRing.js
OpenLayers/Geometry/LineString.js
OpenLayers/Geometry/MultiLineString.js
OpenLayers/Geometry/MultiPoint.js
OpenLayers/Geometry/MultiPolygon.js
OpenLayers/Geometry/Point.js
OpenLayers/Geometry/Polygon.js
OpenLayers/Geometry.js
OpenLayers/Layer/Vector.js
OpenLayers/Control/DrawFeature.js
OpenLayers/Control/EditingToolbar.js
OpenLayers/Control/SelectFeature.js
OpenLayers/Feature/Vector.js
OpenLayers/Renderer
OpenLayers/Renderer/Elements.js
OpenLayers/Renderer/SVG.js
OpenLayers/Renderer/VML.js
OpenLayers/Renderer.js
OpenLayers/Lang

View File

@@ -458,6 +458,7 @@ Group: OpenLayers {
File: Tween (no auto-title, OpenLayers/Tween.js)
File: Util (no auto-title, OpenLayers/Util.js)
File: Spherical (no auto-title, OpenLayers/Spherical.js)
File: Deprecated (no auto-title, deprecated.js)
} # Group: OpenLayers

View File

@@ -5,12 +5,7 @@ function init() {
map = new OpenLayers.Map({
div: "map",
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
units: "m",
maxResolution: 156543.0339,
maxExtent: new OpenLayers.Bounds(
-20037508, -20037508, 20037508, 20037508
)
displayProjection: new OpenLayers.Projection("EPSG:4326")
});
var g = new OpenLayers.Layer.Google("Google Layer", {

View File

@@ -5,10 +5,6 @@ function init() {
map = new OpenLayers.Map({
div: "map",
projection: "EPSG:900913",
units: "m",
maxExtent: new OpenLayers.Bounds(
-20037508.34, -20037508.34, 20037508.34, 20037508.34
),
controls: [],
fractionalZoom: true
});

View File

@@ -33,8 +33,9 @@
var pointLayer = new OpenLayers.Layer.Vector("Point Layer");
var lineLayer = new OpenLayers.Layer.Vector("Line Layer");
var polygonLayer = new OpenLayers.Layer.Vector("Polygon Layer");
var boxLayer = new OpenLayers.Layer.Vector("Box layer");
map.addLayers([wmsLayer, pointLayer, lineLayer, polygonLayer]);
map.addLayers([wmsLayer, pointLayer, lineLayer, polygonLayer, boxLayer]);
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.addControl(new OpenLayers.Control.MousePosition());
@@ -44,7 +45,15 @@
line: new OpenLayers.Control.DrawFeature(lineLayer,
OpenLayers.Handler.Path),
polygon: new OpenLayers.Control.DrawFeature(polygonLayer,
OpenLayers.Handler.Polygon)
OpenLayers.Handler.Polygon),
box: new OpenLayers.Control.DrawFeature(boxLayer,
OpenLayers.Handler.RegularPolygon, {
handlerOptions: {
sides: 4,
irregular: true
}
}
)
};
for(var key in drawControls) {
@@ -80,11 +89,11 @@
<h1 id="title">OpenLayers Draw Feature Example</h1>
<div id="tags">
point, line, linestring, polygon, digitizing, geometry, draw, drag
point, line, linestring, polygon, box, digitizing, geometry, draw, drag
</div>
<p id="shortdesc">
Demonstrate on-screen digitizing tools for point, line, and polygon creation.
Demonstrate on-screen digitizing tools for point, line, polygon and box creation.
</p>
<div id="map" class="smallmap"></div>
@@ -107,6 +116,10 @@
<input type="radio" name="type" value="polygon" id="polygonToggle" onclick="toggleControl(this);" />
<label for="polygonToggle">draw polygon</label>
</li>
<li>
<input type="radio" name="type" value="box" id="boxToggle" onclick="toggleControl(this);" />
<label for="boxToggle">draw box</label>
</li>
<li>
<input type="checkbox" name="allow-pan" value="allow-pan" id="allowPanCheckbox" checked=true onclick="allowPan(this);" />
<label for="allowPanCheckbox">allow pan while drawing</label>
@@ -119,6 +132,8 @@
Double-click to finish drawing.</p>
<p>With the polygon drawing control active, click on the map to add the points that make up your
polygon. Double-click to finish drawing.</p>
<p>With the box drawing control active, click in the map and drag the mouse to get a rectangle. Release
the mouse to finish.</p>
<p>With any drawing control active, paning the map can still be achieved. Drag the map as
usual for that.</p>
<p>Hold down the shift key while drawing to activate freehand mode. While drawing lines or polygons

View File

@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<meta name="apple-mobile-web-app-capable" content="yes">
<title>OpenLayers Google (Static Maps API) Grid Layer Example</title>
<link rel="stylesheet" href="../theme/default/style.css" type="text/css">
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<h1 id="title">Google (Static Maps API) Grid Layer Example</h1>
<div id="tags">
Google, grid, static, GMaps
</div>
<p id="shortdesc">
Using the Google Static Maps API with a Grid Layer.
</p>
<div id="map" class="smallmap"></div>
<div id="docs">
<p>A Grid layer with a custom <code>getURL</code> method can be
used to request static maps for a specific extent and zoom
level. The Google Static Maps API is the most reliable way to
get Google base maps in OpenLayers. Note, however, that the
free version of this is limited to a map size of 640x640 pixels
(1280x1280 if the <code>scale=2</code> url parameter is used)
and 1000 page views per viewer per day. Every map center
or zoom level change increases the page view counter by 1.
</p>
<p>Look at the
<a href="google-static.js" target="_blank">google-static.js
source</a> to see how this is done. See the
<a href="http://code.google.com/apis/maps/documentation/staticmaps/">Static Maps API V2 Developer Guide</a>
for details on the API.
</div>
<script src="../lib/OpenLayers.js"></script>
<script src="google-static.js"></script>
</body>
</html>

61
examples/google-static.js Normal file
View File

@@ -0,0 +1,61 @@
var options = {
singleTile: true,
ratio: 1,
isBaseLayer: true,
wrapDateLine: true,
getURL: function() {
var center = this.map.getCenter().transform("EPSG:3857", "EPSG:4326"),
size = this.map.getSize();
return [
this.url, "&center=", center.lat, ",", center.lon,
"&zoom=", this.map.getZoom(), "&size=", size.w, "x", size.h
].join("");
}
};
var map = new OpenLayers.Map({
div: "map",
projection: "EPSG:3857",
numZoomLevels: 22,
layers: [
new OpenLayers.Layer.Grid(
"Google Physical",
"http://maps.googleapis.com/maps/api/staticmap?sensor=false&maptype=terrain",
null, options
),
new OpenLayers.Layer.Grid(
"Google Streets",
"http://maps.googleapis.com/maps/api/staticmap?sensor=false&maptype=roadmap",
null, options
),
new OpenLayers.Layer.Grid(
"Google Hybrid",
"http://maps.googleapis.com/maps/api/staticmap?sensor=false&maptype=hybrid",
null, options
),
new OpenLayers.Layer.Grid(
"Google Satellite",
"http://maps.googleapis.com/maps/api/staticmap?sensor=false&maptype=satellite",
null, options
),
// the same layer again, but scaled to allow map sizes up to 1280x1280 pixels
new OpenLayers.Layer.Grid(
"Google Satellite (scale=2)",
"http://maps.googleapis.com/maps/api/staticmap?sensor=false&maptype=satellite&scale=2",
null, OpenLayers.Util.applyDefaults({
getURL: function() {
var center = this.map.getCenter().transform("EPSG:3857", "EPSG:4326"),
size = this.map.getSize();
return [
this.url, "&center=", center.lat, ",", center.lon,
"&zoom=", (this.map.getZoom() - 1),
"&size=", Math.floor(size.w / 2), "x", Math.floor(size.h / 2)
].join("");
}
}, options)
),
],
center: new OpenLayers.LonLat(10.2, 48.9).transform("EPSG:4326", "EPSG:3857"),
zoom: 5
});
map.addControl(new OpenLayers.Control.LayerSwitcher());

View File

@@ -8,7 +8,7 @@
<link rel="stylesheet" href="../theme/default/style.css" type="text/css">
<link rel="stylesheet" href="../theme/default/google.css" type="text/css">
<link rel="stylesheet" href="style.css" type="text/css">
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script src="http://maps.google.com/maps/api/js?v=3.6&amp;sensor=false"></script>
<script src="../lib/OpenLayers.js"></script>
<script src="google-v3-alloverlays.js"></script>
</head>

View File

@@ -41,12 +41,7 @@ var init = function (onSelectFeatureFunction) {
div: "map",
theme: null,
projection: sm,
units: "m",
numZoomLevels: 18,
maxResolution: 156543.0339,
maxExtent: new OpenLayers.Bounds(
-20037508.34, -20037508.34, 20037508.34, 20037508.34
),
controls: [
new OpenLayers.Control.Attribution(),
new OpenLayers.Control.TouchNavigation({

View File

@@ -41,12 +41,7 @@ function init() {
map = new OpenLayers.Map({
div: 'map',
projection: 'EPSG:900913',
units: 'm',
numZoomLevels: 18,
maxResolution: 156543.0339,
maxExtent: new OpenLayers.Bounds(
-20037508.34, -20037508.34, 20037508.34, 20037508.34
),
controls: [
new OpenLayers.Control.TouchNavigation({
dragPanOptions: {

View File

@@ -7,7 +7,7 @@
<meta name="apple-mobile-web-app-capable" content="yes">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.css">
<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script src="http://code.jquery.com/mobile/1.0/jquery.mobile-1.0.min.js"></script>
<script src="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js"></script>
<link rel="stylesheet" href="style.mobile.css" type="text/css">
<link rel="stylesheet" href="style.mobile-jq.css" type="text/css">
<script src="../lib/OpenLayers.js?mobile"></script>

View File

@@ -5,12 +5,7 @@ function init() {
div: "map",
theme: null,
projection: new OpenLayers.Projection("EPSG:900913"),
units: "m",
numZoomLevels: 18,
maxResolution: 156543.0339,
maxExtent: new OpenLayers.Bounds(
-20037508.34, -20037508.34, 20037508.34, 20037508.34
),
controls: [
new OpenLayers.Control.TouchNavigation({
dragPanOptions: {

View File

@@ -9,6 +9,12 @@ html, body, #map {
#title, #tags, #shortdesc {
display: none;
}
.olTileImage {
-webkit-transition: opacity 0.2s linear;
-moz-transition: opacity 0.2s linear;
-o-transition: opacity 0.2s linear;
transition: opacity 0.2s linear;
}
div.olControlAttribution {
position: absolute;
font-size: 10px;

View File

@@ -7,7 +7,6 @@
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="stylesheet" href="mobile-wmts-vienna.css" type="text/css">
<script src="../lib/OpenLayers.js"></script>
</head>
<body>
<h1 id="title">City of Vienna WMTS for Desktop and Mobile Devices</h1>
@@ -22,6 +21,7 @@
functionality and uses the Geolocate control.
</p>
<div id="map"></div>
<script src="../lib/OpenLayers.js"></script>
<script src="mobile-wmts-vienna.js"></script>
</body>
</html>

View File

@@ -152,7 +152,6 @@ var map;
var defaults = {
requestEncoding: "REST",
matrixSet: "google3857",
buffer: 4,
attribution: 'Datenquelle: Stadt Wien - <a href="http://data.wien.gv.at">data.wien.gv.at</a>'
};
var doc = request.responseText,
@@ -182,7 +181,6 @@ var map;
requestEncoding: "REST",
matrixSet: "google3857",
tileFullExtent: extent,
buffer: 4,
attribution: 'Datenquelle: Stadt Wien - <a href="http://data.wien.gv.at">data.wien.gv.at</a>'
};
fmzk = new OpenLayers.Layer.WMTS(OpenLayers.Util.applyDefaults({

View File

@@ -96,6 +96,7 @@
if (rotate || drag) {
controls.modify.mode &= ~OpenLayers.Control.ModifyFeature.RESHAPE;
}
controls.modify.createVertices = document.getElementById("createVertices").checked;
var sides = parseInt(document.getElementById("sides").value);
sides = Math.max(3, isNaN(sides) ? 0 : sides);
controls.regular.handler.sides = sides;
@@ -161,6 +162,11 @@
onclick="toggleControl(this);" />
<label for="modifyToggle">modify feature</label>
<ul>
<li>
<input id="createVertices" type="checkbox" checked
name="createVertices" onchange="update()" />
<label for="createVertices">allow vertices creation</label>
</li>
<li>
<input id="rotate" type="checkbox"
name="rotate" onchange="update()" />

View File

@@ -3,12 +3,7 @@ var map;
function init() {
map = new OpenLayers.Map({
div: "map",
projection: new OpenLayers.Projection("EPSG:900913"),
units: "m",
maxResolution: 156543.0339,
maxExtent: new OpenLayers.Bounds(
-20037508, -20037508, 20037508, 20037508.34
)
projection: new OpenLayers.Projection("EPSG:900913")
});
var osm = new OpenLayers.Layer.OSM();

View File

@@ -91,8 +91,7 @@
maxExtent: new OpenLayers.Bounds(-8242894.927728, 4965204.031195,
-8227290.161511, 4994963.723637),
maxResolution: 116.24879860156216,
projection: "EPSG:900913",
units: "m"
projection: "EPSG:900913"
};
var map2 = new OpenLayers.Map('map2', mapOptions);

View File

@@ -12,7 +12,10 @@
<link rel="stylesheet" href="style.css" type="text/css">
<style type="text/css">
.olControlAttribution {
bottom: 0px
bottom: 0px;
left: 2px;
right: inherit;
width: 400px;
}
#map {
height: 512px;
@@ -42,10 +45,7 @@
div: "map",
projection: "EPSG:900913",
displayProjection: "EPSG:4326",
units: "m",
numZoomLevels: 18,
maxResolution: 156543.0339,
maxExtent: [-20037508, -20037508, 20037508, 20037508],
numZoomLevels: 18
});
// create Google Mercator layers

View File

@@ -31,11 +31,7 @@
function init(){
var options = {
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
units: "m",
maxResolution: 156543.0339,
maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34,
20037508.34, 20037508.34)
displayProjection: new OpenLayers.Projection("EPSG:4326")
};
map = new OpenLayers.Map('map', options);
var mapnik = new OpenLayers.Layer.OSM("OpenStreetMap (Mapnik)");

View File

@@ -38,9 +38,6 @@ function init() {
map = new OpenLayers.Map('map', {
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
units: "m",
maxResolution: 20037508.34 / 128,
maxExtent: new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508),
restrictedExtent: extent,
controls: [
new OpenLayers.Control.PanZoom(),

View File

@@ -7,12 +7,7 @@ function init() {
var mercator = new OpenLayers.Projection("EPSG:900913");
map = new OpenLayers.Map('map', {
projection: mercator,
units: "m",
maxResolution: 156543.0339,
maxExtent: new OpenLayers.Bounds(
-20037508, -20037508, 20037508, 20037508
)
projection: mercator
});
var g = new OpenLayers.Layer.Google("Google Layer", {

View File

@@ -47,12 +47,7 @@ function init() {
map = new OpenLayers.Map({
div: "map",
projection: "EPSG:900913",
units: "m",
maxExtent: new OpenLayers.Bounds(
-20037508.34, -20037508.34, 20037508.34, 20037508.34
),
maxResolution: 156543.0339
projection: "EPSG:900913"
});
var osm = new OpenLayers.Layer.OSM();

View File

@@ -5,12 +5,7 @@ function init() {
map = new OpenLayers.Map({
div: "map",
projection: "EPSG:900913",
units: "m",
maxExtent: new OpenLayers.Bounds(
-20037508.34, -20037508.34, 20037508.34, 20037508.34
),
maxResolution: 156543.0339
projection: "EPSG:900913"
});
var osm = new OpenLayers.Layer.OSM();

View File

@@ -4,12 +4,7 @@ function init() {
map = new OpenLayers.Map({
div: "map",
projection: "EPSG:900913",
units: "m",
maxExtent: new OpenLayers.Bounds(
-20037508.34, -20037508.34, 20037508.34, 20037508.34
),
maxResolution: 156543.0339
projection: "EPSG:900913"
});
var osm = new OpenLayers.Layer.OSM();

View File

@@ -19,7 +19,7 @@
var layerExtent = new OpenLayers.Bounds( -13758743.4295939, 5591455.28887228, -13531302.3472101 , 5757360.4178881);
map = new OpenLayers.Map( 'map', {'restrictedExtent': layerExtent} );
layer = new OpenLayers.Layer.XYZ( "ESRI",
"http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Portland/ESRI_LandBase_WebMercator/MapServer/tile/${z}/${y}/${x}",
"http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/${z}/${y}/${x}",
{sphericalMercator: true} );
map.addLayer(layer);
map.zoomToExtent(map.restrictedExtent);
@@ -33,7 +33,7 @@
XYZ, layer, tile
</div>
<div id="shortdesc">Show a Simple ESRI map using the layer from <a href="http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Portland/ESRI_LandBase_WebMercator/MapServer">ESRI's server</a>. </div>
<div id="shortdesc">Show a Simple ESRI map using the layer from <a href="http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer">ESRI's server</a>. </div>
<div id="map" class="smallmap"></div>

View File

@@ -287,6 +287,7 @@
"OpenLayers/Format/SLD.js",
"OpenLayers/Format/SLD/v1.js",
"OpenLayers/Format/SLD/v1_0_0.js",
"OpenLayers/Format/SLD/v1_0_0_GeoServer.js",
"OpenLayers/Format/OWSCommon.js",
"OpenLayers/Format/OWSCommon/v1.js",
"OpenLayers/Format/OWSCommon/v1_0_0.js",
@@ -348,7 +349,8 @@
"OpenLayers/Symbolizer/Text.js",
"OpenLayers/Symbolizer/Raster.js",
"OpenLayers/Lang.js",
"OpenLayers/Lang/en.js"
"OpenLayers/Lang/en.js",
"OpenLayers/Spherical.js"
]; // etc.
}

View File

@@ -15,6 +15,16 @@
*/
OpenLayers.Animation = (function(window) {
/**
* Property: isNative
* {Boolean} true if a native requestAnimationFrame function is available
*/
var isNative = !!(window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame);
/**
* Function: requestFrame
* Schedule a function to be called at the next available animation frame.
@@ -89,6 +99,7 @@ OpenLayers.Animation = (function(window) {
}
return {
isNative: isNative,
requestFrame: requestFrame,
start: start,
stop: stop

View File

@@ -716,7 +716,8 @@ OpenLayers.Bounds.fromArray = function(bbox, reverseAxisOrder) {
* from a size
*
* Parameters:
* size - {<OpenLayers.Size>}
* size - {<OpenLayers.Size>|Object} OpenLayers.Size or an object with
* a 'w' and 'h' properties.
*
* Returns:
* {<OpenLayers.Bounds>} New bounds object built from the passed-in size.

View File

@@ -139,10 +139,7 @@ OpenLayers.Control = OpenLayers.Class({
* APIProperty: events
* {<OpenLayers.Events>} Events instance for listeners and triggering
* control specific events.
*/
events: null,
/**
*
* Register a listener for a particular event with the following syntax:
* (code)
* control.events.register(type, obj, listener);
@@ -161,6 +158,7 @@ OpenLayers.Control = OpenLayers.Class({
* activate - Triggered when activated.
* deactivate - Triggered when deactivated.
*/
events: null,
/**
* Constructor: OpenLayers.Control

View File

@@ -24,6 +24,14 @@ OpenLayers.Control.Attribution =
*/
separator: ", ",
/**
* APIProperty: template
* {String} Template for the attribution. This has to include the substring
* "${layers}", which will be replaced by the layer specific
* attributions, separated by <separator>. The default is "${layers}".
*/
template: "${layers}",
/**
* Constructor: OpenLayers.Control.Attribution
*
@@ -86,7 +94,9 @@ OpenLayers.Control.Attribution =
}
}
}
this.div.innerHTML = attributions.join(this.separator);
this.div.innerHTML = OpenLayers.String.format(this.template, {
layers: attributions.join(this.separator)
});
}
},

View File

@@ -32,7 +32,16 @@ OpenLayers.Control.DrawFeature = OpenLayers.Class(OpenLayers.Control, {
callbacks: null,
/**
* Supported event types:
* APIProperty: events
* {<OpenLayers.Events>} Events instance for listeners and triggering
* control specific events.
*
* Register a listener for a particular event with the following syntax:
* (code)
* control.events.register(type, obj, listener);
* (end)
*
* Supported event types (in addition to those from <OpenLayers.Control.events>):
* featureadded - Triggered when a feature is added
*/

View File

@@ -23,13 +23,22 @@
OpenLayers.Control.Geolocate = OpenLayers.Class(OpenLayers.Control, {
/**
* Supported event types:
* - *locationupdated* Triggered when browser return a new position. Listeners will
* APIProperty: events
* {<OpenLayers.Events>} Events instance for listeners and triggering
* control specific events.
*
* Register a listener for a particular event with the following syntax:
* (code)
* control.events.register(type, obj, listener);
* (end)
*
* Supported event types (in addition to those from <OpenLayers.Control.events>):
* locationupdated - Triggered when browser return a new position. Listeners will
* receive an object with a 'position' property which is the browser.geolocation.position
* native object, as well as a 'point' property which is the location transformed in the
* current map projection.
* - *locationfailed* Triggered when geolocation has failed
* - *locationuncapable* Triggered when control is activated on a browser
* locationfailed - Triggered when geolocation has failed
* locationuncapable - Triggered when control is activated on a browser
* which doesn't support geolocation
*/

View File

@@ -170,7 +170,16 @@ OpenLayers.Control.GetFeature = OpenLayers.Class(OpenLayers.Control, {
filterType: OpenLayers.Filter.Spatial.BBOX,
/**
* Supported event types:
* APIProperty: events
* {<OpenLayers.Events>} Events instance for listeners and triggering
* control specific events.
*
* Register a listener for a particular event with the following syntax:
* (code)
* control.events.register(type, obj, listener);
* (end)
*
* Supported event types (in addition to those from <OpenLayers.Control.events>):
* beforefeatureselected - Triggered when <click> is true before a
* feature is selected. The event object has a feature property with
* the feature about to select

View File

@@ -197,11 +197,25 @@ OpenLayers.Control.LayerSwitcher =
* evt - {Event}
*/
onButtonClick: function(evt) {
if (evt.buttonElement === this.minimizeDiv) {
var button = evt.buttonElement;
if (button === this.minimizeDiv) {
this.minimizeControl();
} else if (evt.buttonElement === this.maximizeDiv) {
} else if (button === this.maximizeDiv) {
this.maximizeControl();
};
} else if (button._layerSwitcher === this.id) {
if (button["for"]) {
button = document.getElementById(button["for"]);
}
if (!button.disabled) {
if (button.type == "radio") {
button.checked = true;
this.map.setBaseLayer(this.map.getLayer(button._layer));
} else {
button.checked = !button.checked;
this.updateMap();
}
}
}
},
/**
@@ -213,14 +227,6 @@ OpenLayers.Control.LayerSwitcher =
* layersType - {String}
*/
clearLayersArray: function(layersType) {
var layers = this[layersType + "Layers"];
if (layers) {
for(var i=0, len=layers.length; i<len ; i++) {
var layer = layers[i];
OpenLayers.Event.stopObservingElement(layer.inputElem);
OpenLayers.Event.stopObservingElement(layer.labelSpan);
}
}
this[layersType + "LayersDiv"].innerHTML = "";
this[layersType + "Layers"] = [];
},
@@ -320,32 +326,26 @@ OpenLayers.Control.LayerSwitcher =
inputElem.value = layer.name;
inputElem.checked = checked;
inputElem.defaultChecked = checked;
inputElem.className = "olButton";
inputElem._layer = layer.id;
inputElem._layerSwitcher = this.id;
if (!baseLayer && !layer.inRange) {
inputElem.disabled = true;
}
var context = {
'inputElem': inputElem,
'layer': layer,
'layerSwitcher': this
};
var onInputClick = OpenLayers.Function.bindAsEventListener(
this.onInputClick, context
);
OpenLayers.Event.observe(inputElem, "mousedown", onInputClick);
OpenLayers.Event.observe(inputElem, "touchstart", onInputClick);
// create span
var labelSpan = document.createElement("span");
OpenLayers.Element.addClass(labelSpan, "labelSpan");
var labelSpan = document.createElement("label");
labelSpan["for"] = inputElem.id;
OpenLayers.Element.addClass(labelSpan, "labelSpan olButton");
labelSpan._layer = layer.id;
labelSpan._layerSwitcher = this.id;
if (!baseLayer && !layer.inRange) {
labelSpan.style.color = "gray";
}
labelSpan.innerHTML = layer.name;
labelSpan.style.verticalAlign = (baseLayer) ? "bottom"
: "baseline";
OpenLayers.Event.observe(labelSpan, "click", onInputClick);
OpenLayers.Event.observe(labelSpan, "touchstart", onInputClick);
// create line break
var br = document.createElement("br");
@@ -376,49 +376,6 @@ OpenLayers.Control.LayerSwitcher =
return this.div;
},
/**
* Method:
* A label has been clicked, check or uncheck its corresponding input
*
* Parameters:
* e - {Event}
*
* Context:
* - {Object}
*
* Object structure:
* inputElem - {DOMElement}
* layerSwitcher - {<OpenLayers.Control.LayerSwitcher>}
* layer - {<OpenLayers.Layer>}
*/
onInputClick: function(e) {
if (!this.inputElem.disabled) {
if (this.inputElem.type == "radio") {
this.inputElem.checked = true;
this.layer.map.setBaseLayer(this.layer);
} else {
this.inputElem.checked = !this.inputElem.checked;
this.layerSwitcher.updateMap();
}
}
OpenLayers.Event.stop(e);
},
/**
* Method: onLayerClick
* Need to update the map accordingly whenever user clicks in either of
* the layers.
*
* Parameters:
* e - {Event}
*/
onLayerClick: function(e) {
this.updateMap();
},
/**
* Method: updateMap
* Cycles through the loaded data and base layer input arrays and makes

View File

@@ -18,15 +18,16 @@
OpenLayers.Control.Measure = OpenLayers.Class(OpenLayers.Control, {
/**
* APIProperty: events
* {<OpenLayers.Events>} Events instance for listeners and triggering
* control specific events.
*
* Register a listener for a particular event with the following syntax:
* (code)
* control.events.register(type, obj, listener);
* (end)
*
* Listeners will be called with a reference to an event object. The
* properties of this event depends on exactly what happened.
*
* Supported control event types (in addition to those from <OpenLayers.Control>):
* Supported event types (in addition to those from <OpenLayers.Control.events>):
* measure - Triggered when a measurement sketch is complete. Listeners
* will receive an event with measure, units, order, and geometry
* properties.

View File

@@ -137,6 +137,13 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
*/
mode: null,
/**
* APIProperty: createVertices
* {Boolean} Create new vertices by dragging the virtual vertices
* in the middle of each edge. Default is true.
*/
createVertices: true,
/**
* Property: modified
* {Boolean} The currently selected feature has been modified.
@@ -677,7 +684,7 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
}
// add virtual vertices in the middle of each edge
if(geometry.CLASS_NAME != "OpenLayers.Geometry.MultiPoint") {
if (control.createVertices && geometry.CLASS_NAME != "OpenLayers.Geometry.MultiPoint") {
for(i=0, len=geometry.components.length; i<len-1; ++i) {
var prevVertex = geometry.components[i];
var nextVertex = geometry.components[i + 1];

View File

@@ -24,16 +24,16 @@
OpenLayers.Control.SLDSelect = OpenLayers.Class(OpenLayers.Control, {
/**
* APIProperty: events
* {<OpenLayers.Events>} Events instance for listeners and triggering
* control specific events.
*
* Register a listener for a particular event with the following syntax:
* (code)
* control.events.register(type, obj, listener);
* (end)
*
* Listeners will be called with a reference to an event object. The
* properties of this event depends on exactly what happened.
*
* Supported control event types (in addition to those from
* <OpenLayers.Control>):
* Supported event types (in addition to those from <OpenLayers.Control.events>):
* selected - Triggered when a selection occurs. Listeners receive an
* event with *filters* and *layer* properties. Filters will be an
* array of OpenLayers.Filter objects created in order to perform

View File

@@ -22,12 +22,21 @@
OpenLayers.Control.SelectFeature = OpenLayers.Class(OpenLayers.Control, {
/**
* Supported event types:
* - *beforefeaturehighlighted* Triggered before a feature is highlighted
* - *featurehighlighted* Triggered when a feature is highlighted
* - *featureunhighlighted* Triggered when a feature is unhighlighted
* - *boxselectionstart* Triggered before box selection starts
* - *boxselectionend* Triggered after box selection ends
* APIProperty: events
* {<OpenLayers.Events>} Events instance for listeners and triggering
* control specific events.
*
* Register a listener for a particular event with the following syntax:
* (code)
* control.events.register(type, obj, listener);
* (end)
*
* Supported event types (in addition to those from <OpenLayers.Control.events>):
* beforefeaturehighlighted - Triggered before a feature is highlighted
* featurehighlighted - Triggered when a feature is highlighted
* featureunhighlighted - Triggered when a feature is unhighlighted
* boxselectionstart - Triggered before box selection starts
* boxselectionend - Triggered after box selection ends
*/
/**

View File

@@ -18,15 +18,16 @@
OpenLayers.Control.Snapping = OpenLayers.Class(OpenLayers.Control, {
/**
* APIProperty: events
* {<OpenLayers.Events>} Events instance for listeners and triggering
* control specific events.
*
* Register a listener for a particular event with the following syntax:
* (code)
* control.events.register(type, obj, listener);
* (end)
*
* Listeners will be called with a reference to an event object. The
* properties of this event depends on exactly what happened.
*
* Supported control event types (in addition to those from <OpenLayers.Control>):
* Supported event types (in addition to those from <OpenLayers.Control.events>):
* beforesnap - Triggered before a snap occurs. Listeners receive an
* event object with *point*, *x*, *y*, *distance*, *layer*, and
* *snapType* properties. The point property will be original point

View File

@@ -19,15 +19,16 @@
OpenLayers.Control.Split = OpenLayers.Class(OpenLayers.Control, {
/**
* APIProperty: events
* {<OpenLayers.Events>} Events instance for listeners and triggering
* control specific events.
*
* Register a listener for a particular event with the following syntax:
* (code)
* control.events.register(type, obj, listener);
* (end)
*
* Listeners will be called with a reference to an event object. The
* properties of this event depends on exactly what happened.
*
* Supported control event types (in addition to those from <OpenLayers.Control>):
* Supported event types (in addition to those from <OpenLayers.Control.events>):
* beforesplit - Triggered before a split occurs. Listeners receive an
* event object with *source* and *target* properties.
* split - Triggered when a split occurs. Listeners receive an event with

View File

@@ -22,31 +22,40 @@
OpenLayers.Control.TransformFeature = OpenLayers.Class(OpenLayers.Control, {
/**
* Supported event types:
* - *beforesetfeature* Triggered before a feature is set for
* APIProperty: events
* {<OpenLayers.Events>} Events instance for listeners and triggering
* control specific events.
*
* Register a listener for a particular event with the following syntax:
* (code)
* control.events.register(type, obj, listener);
* (end)
*
* Supported event types (in addition to those from <OpenLayers.Control.events>):
* beforesetfeature - Triggered before a feature is set for
* tranformation. The feature will not be set if a listener returns
* false. Listeners receive a *feature* property, with the feature
* that will be set for transformation. Listeners are allowed to
* set the control's *scale*, *ratio* and *rotation* properties,
* which will set the initial scale, ratio and rotation of the
* feature, like the <setFeature> method's initialParams argument.
* - *setfeature* Triggered when a feature is set for tranformation.
* setfeature - Triggered when a feature is set for tranformation.
* Listeners receive a *feature* property, with the feature that
* is now set for transformation.
* - *beforetransform* Triggered while dragging, before a feature is
* beforetransform - Triggered while dragging, before a feature is
* transformed. The feature will not be transformed if a listener
* returns false (but the box still will). Listeners receive one or
* more of *center*, *scale*, *ratio* and *rotation*. The *center*
* property is an <OpenLayers.Geometry.Point> object with the new
* center of the transformed feature, the others are Floats with the
* scale, ratio or rotation change since the last transformation.
* - *transform* Triggered while dragging, when a feature is transformed.
* transform - Triggered while dragging, when a feature is transformed.
* Listeners receive an event object with one or more of *center*,
* *scale*, *ratio* and *rotation*. The *center* property is an
* scale*, *ratio* and *rotation*. The *center* property is an
* <OpenLayers.Geometry.Point> object with the new center of the
* transformed feature, the others are Floats with the scale, ratio
* or rotation change of the feature since the last transformation.
* - *transformcomplete* Triggered after dragging. Listeners receive
* transformcomplete - Triggered after dragging. Listeners receive
* an event object with the transformed *feature*.
*/

View File

@@ -155,7 +155,16 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
hoverRequest: null,
/**
* Supported event types (in addition to those from <OpenLayers.Control>):
* APIProperty: events
* {<OpenLayers.Events>} Events instance for listeners and triggering
* control specific events.
*
* Register a listener for a particular event with the following syntax:
* (code)
* control.events.register(type, obj, listener);
* (end)
*
* Supported event types (in addition to those from <OpenLayers.Control.events>):
* beforegetfeatureinfo - Triggered before the request is sent.
* The event object has an *xy* property with the position of the
* mouse click or hover event that triggers the request.

View File

@@ -136,7 +136,16 @@ OpenLayers.Control.WMTSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
hoverRequest: null,
/**
* Supported event types (in addition to those from <OpenLayers.Control>):
* APIProperty: events
* {<OpenLayers.Events>} Events instance for listeners and triggering
* control specific events.
*
* Register a listener for a particular event with the following syntax:
* (code)
* control.events.register(type, obj, listener);
* (end)
*
* Supported event types (in addition to those from <OpenLayers.Control.events>):
* beforegetfeatureinfo - Triggered before each request is sent.
* The event object has an *xy* property with the position of the
* mouse click or hover event that triggers the request and a *layer*

View File

@@ -108,7 +108,7 @@ OpenLayers.Events.buttonclick = OpenLayers.Class({
var propagate = true,
element = OpenLayers.Event.element(evt);
if (element && (OpenLayers.Event.isLeftClick(evt) || !~evt.type.indexOf("mouse"))) {
if (OpenLayers.Element.hasClass(element, "olAlphaImg")) {
if (element.nodeType === 3 || OpenLayers.Element.hasClass(element, "olAlphaImg")) {
element = element.parentNode;
}
if (OpenLayers.Element.hasClass(element, "olButton")) {

View File

@@ -57,11 +57,27 @@ OpenLayers.Format.GPX = OpenLayers.Class(OpenLayers.Format.XML, {
extractAttributes: true,
/**
* APIProperty: gpxns
* {String} GPX namespace to use. Defaults to
* "http://www.topografix.com/GPX/1/1"
* Property: namespaces
* {Object} Mapping of namespace aliases to namespace URIs.
*/
gpxns: "http://www.topografix.com/GPX/1/1",
namespaces: {
gpx: "http://www.topografix.com/GPX/1/1",
xsi: "http://www.w3.org/2001/XMLSchema-instance"
},
/**
* Property: schemaLocation
* {String} Schema location. Defaults to
* "http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"
*/
schemaLocation: "http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd",
/**
* APIProperty: creator
* {String} The creator attribute to be added to the written GPX files.
* Defaults to "OpenLayers"
*/
creator: "OpenLayers",
/**
* Constructor: OpenLayers.Format.GPX
@@ -181,7 +197,7 @@ OpenLayers.Format.GPX = OpenLayers.Class(OpenLayers.Format.XML, {
var attributes = {};
var attrNode = node.firstChild, value, name;
while(attrNode) {
if(attrNode.nodeType == 1) {
if(attrNode.nodeType == 1 && attrNode.firstChild) {
value = attrNode.firstChild;
if(value.nodeType == 3 || value.nodeType == 4) {
name = (attrNode.prefix) ?
@@ -207,17 +223,21 @@ OpenLayers.Format.GPX = OpenLayers.Class(OpenLayers.Format.XML, {
* add to the gpx. Supported keys are 'name', 'desc', 'author'.
*/
write: function(features, metadata) {
var gpx;
features = OpenLayers.Util.isArray(features) ?
features : [features];
gpx = this.createElementNS(this.gpxns, "gpx");
var gpx = this.createElementNS(this.namespaces.gpx, "gpx");
gpx.setAttribute("version", "1.1");
gpx.setAttribute("creator", this.creator);
this.setAttributes(gpx, {
"xsi:schemaLocation": this.schemaLocation
});
for(var i=0, len=features.length; i<len; i++) {
gpx.appendChild(this.buildFeatureNode(features[i]));
}
if (metadata && typeof metadata == 'object') {
gpx.appendChild(this.buildMetadataNode(metadata));
}
for(var i=0, len=features.length; i<len; i++) {
gpx.appendChild(this.buildFeatureNode(features[i]));
}
return OpenLayers.Format.XML.prototype.write.apply(this, [gpx]);
},
@@ -230,11 +250,11 @@ OpenLayers.Format.GPX = OpenLayers.Class(OpenLayers.Format.XML, {
*/
buildMetadataNode: function(metadata) {
var types = ['name', 'desc', 'author'],
node = this.createElementNS(this.gpxns, 'metadata');
node = this.createElementNSPlus('gpx:metadata');
for (var i=0; i < types.length; i++) {
var type = types[i];
if (metadata[type]) {
var n = this.createElementNS(this.gpxns, type);
var n = this.createElementNSPlus("gpx:" + type);
n.appendChild(this.createTextNode(metadata[type]));
node.appendChild(n);
}
@@ -263,7 +283,7 @@ OpenLayers.Format.GPX = OpenLayers.Class(OpenLayers.Format.XML, {
var wpt = this.buildWptNode(feature);
return wpt;
} else {
var trkNode = this.createElementNS(this.gpxns, "trk");
var trkNode = this.createElementNSPlus("gpx:trk");
this.appendAttributesNode(trkNode, feature);
var trkSegNodes = this.buildTrkSegNode(geometry);
trkSegNodes = OpenLayers.Util.isArray(trkSegNodes) ?
@@ -291,7 +311,7 @@ OpenLayers.Format.GPX = OpenLayers.Class(OpenLayers.Format.XML, {
nodes;
if (geometry.CLASS_NAME == "OpenLayers.Geometry.LineString" ||
geometry.CLASS_NAME == "OpenLayers.Geometry.LinearRing") {
node = this.createElementNS(this.gpxns, "trkseg");
node = this.createElementNSPlus("gpx:trkseg");
for (i = 0, len=geometry.components.length; i < len; i++) {
point = geometry.components[i];
node.appendChild(this.buildTrkPtNode(point));
@@ -317,7 +337,7 @@ OpenLayers.Format.GPX = OpenLayers.Class(OpenLayers.Format.XML, {
* {DOMElement} A trkpt node
*/
buildTrkPtNode: function(point) {
var node = this.createElementNS(this.gpxns, "trkpt");
var node = this.createElementNSPlus("gpx:trkpt");
node.setAttribute("lon", point.x);
node.setAttribute("lat", point.y);
return node;
@@ -334,7 +354,7 @@ OpenLayers.Format.GPX = OpenLayers.Class(OpenLayers.Format.XML, {
* {DOMElement} A wpt node
*/
buildWptNode: function(feature) {
var node = this.createElementNS(this.gpxns, "wpt");
var node = this.createElementNSPlus("gpx:wpt");
node.setAttribute("lon", feature.geometry.x);
node.setAttribute("lat", feature.geometry.y);
this.appendAttributesNode(node, feature);
@@ -350,11 +370,11 @@ OpenLayers.Format.GPX = OpenLayers.Class(OpenLayers.Format.XML, {
* feature - {<OpenLayers.Feature.Vector>}
*/
appendAttributesNode: function(node, feature) {
var name = this.createElementNS(this.gpxns, 'name');
var name = this.createElementNSPlus('gpx:name');
name.appendChild(this.createTextNode(
feature.attributes.name || feature.id));
node.appendChild(name);
var desc = this.createElementNS(this.gpxns, 'desc');
var desc = this.createElementNSPlus('gpx:desc');
desc.appendChild(this.createTextNode(
feature.attributes.description || this.defaultDesc));
node.appendChild(desc);

View File

@@ -23,6 +23,15 @@
*/
OpenLayers.Format.SLD = OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC, {
/**
* APIProperty: profile
* {String} If provided, use a custom profile.
*
* Currently supported profiles:
* - GeoServer - parses GeoServer vendor specific capabilities for SLD.
*/
profile: null,
/**
* APIProperty: defaultVersion
* {String} Version number to assume if none found. Default is "1.0.0".

View File

@@ -338,6 +338,15 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
"CssParameter": function(node, symbolizer) {
var cssProperty = node.getAttribute("name");
var symProperty = this.cssMap[cssProperty];
// for labels, fill should map to fontColor and fill-opacity
// to fontOpacity
if (symbolizer.label) {
if (cssProperty === 'fill') {
symProperty = "fontColor";
} else if (cssProperty === 'fill-opacity') {
symProperty = "fontOpacity";
}
}
if(symProperty) {
// Limited support for parsing of OGC expressions
var value = this.readers.ogc._expression.call(this, node);
@@ -888,9 +897,12 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
this.writeNode("Halo", symbolizer, node);
}
// add in optional Fill
if(symbolizer.fillColor != null ||
symbolizer.fillOpacity != null) {
this.writeNode("Fill", symbolizer, node);
if(symbolizer.fontColor != null ||
symbolizer.fontOpacity != null) {
this.writeNode("Fill", {
fillColor: symbolizer.fontColor,
fillOpacity: symbolizer.fontOpacity
}, node);
}
return node;
},

View File

@@ -0,0 +1,142 @@
/* 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/Format/SLD/v1_0_0.js
*/
/**
* Class: OpenLayers.Format.SLD/v1_0_0_GeoServer
* Read and write SLD version 1.0.0 with GeoServer-specific enhanced options.
* See http://svn.osgeo.org/geotools/trunk/modules/extension/xsd/xsd-sld/src/main/resources/org/geotools/sld/bindings/StyledLayerDescriptor.xsd
* for more information.
*
* Inherits from:
* - <OpenLayers.Format.SLD.v1_0_0>
*/
OpenLayers.Format.SLD.v1_0_0_GeoServer = OpenLayers.Class(
OpenLayers.Format.SLD.v1_0_0, {
/**
* Property: version
* {String} The specific parser version.
*/
version: "1.0.0",
/**
* Property: profile
* {String} The specific profile
*/
profile: "GeoServer",
/**
* Constructor: OpenLayers.Format.SLD.v1_0_0_GeoServer
* Create a new parser for GeoServer-enhanced SLD version 1.0.0.
*
* Parameters:
* options - {Object} An optional object whose properties will be set on
* this instance.
*/
/**
* 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.
*/
readers: OpenLayers.Util.applyDefaults({
"sld": OpenLayers.Util.applyDefaults({
"Priority": function(node, obj) {
var value = this.readers.ogc._expression.call(this, node);
if (value) {
obj.priority = value;
}
},
"VendorOption": function(node, obj) {
if (!obj.vendorOptions) {
obj.vendorOptions = [];
}
obj.vendorOptions.push({
name: node.getAttribute("name"),
value: this.getChildValue(node)
});
}
}, OpenLayers.Format.SLD.v1_0_0.prototype.readers["sld"])
}, OpenLayers.Format.SLD.v1_0_0.prototype.readers),
/**
* Property: writers
* As a compliment to the readers property, this structure contains public
* writing functions grouped by namespace alias and named like the
* node names they produce.
*/
writers: OpenLayers.Util.applyDefaults({
"sld": OpenLayers.Util.applyDefaults({
"Priority": function(priority) {
return this.writers.sld._OGCExpression.call(
this, "sld:Priority", priority
);
},
"VendorOption": function(option) {
return this.createElementNSPlus("sld:VendorOption", {
attributes: {name: option.name},
value: option.value
});
},
"TextSymbolizer": function(symbolizer) {
var writers = OpenLayers.Format.SLD.v1_0_0.prototype.writers;
var node = writers["sld"]["TextSymbolizer"].apply(this, arguments);
if (symbolizer.externalGraphic || symbolizer.graphicName) {
this.writeNode("Graphic", symbolizer, node);
}
if ("priority" in symbolizer) {
this.writeNode("Priority", symbolizer.priority, node);
}
return this.addVendorOptions(node, symbolizer);
},
"PointSymbolizer": function(symbolizer) {
var writers = OpenLayers.Format.SLD.v1_0_0.prototype.writers;
var node = writers["sld"]["PointSymbolizer"].apply(this, arguments);
return this.addVendorOptions(node, symbolizer);
},
"LineSymbolizer": function(symbolizer) {
var writers = OpenLayers.Format.SLD.v1_0_0.prototype.writers;
var node = writers["sld"]["LineSymbolizer"].apply(this, arguments);
return this.addVendorOptions(node, symbolizer);
},
"PolygonSymbolizer": function(symbolizer) {
var writers = OpenLayers.Format.SLD.v1_0_0.prototype.writers;
var node = writers["sld"]["PolygonSymbolizer"].apply(this, arguments);
return this.addVendorOptions(node, symbolizer);
}
}, OpenLayers.Format.SLD.v1_0_0.prototype.writers["sld"])
}, OpenLayers.Format.SLD.v1_0_0.prototype.writers),
/**
* Method: addVendorOptions
* Add in the VendorOption tags and return the node again.
*
* Parameters:
* node - {DOMElement} A DOM node.
* symbolizer - {Object}
*
* Returns:
* {DOMElement} A DOM node.
*/
addVendorOptions: function(node, symbolizer) {
var options = symbolizer.vendorOptions;
if (options) {
for (var i=0, ii=options.length; i<ii; ++i) {
this.writeNode("VendorOption", options[i], node);
}
}
return node;
},
CLASS_NAME: "OpenLayers.Format.SLD.v1_0_0_GeoServer"
});

View File

@@ -58,6 +58,21 @@ OpenLayers.Layer = OpenLayers.Class({
alwaysInRange: null,
/**
* 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>}
*
* Register a listener for a particular event with the following syntax:
* (code)
* layer.events.register(type, obj, listener);
@@ -87,23 +102,6 @@ OpenLayers.Layer = OpenLayers.Class({
* will receive an object with a *map* property referencing the map and
* a *layer* property referencing the layer.
*/
/**
* 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>}
*/
events: null,
/**
@@ -255,8 +253,8 @@ OpenLayers.Layer = OpenLayers.Class({
* 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
* displaying the whole world.
* options if you are not using the default <OpenLayers.Map.tileSize>
* and displaying the whole world.
*/
maxResolution: null,
@@ -361,10 +359,6 @@ OpenLayers.Layer = OpenLayers.Class({
}
}
if (this.wrapDateLine) {
this.displayOutsideMaxExtent = true;
}
},
/**
@@ -477,8 +471,18 @@ OpenLayers.Layer = OpenLayers.Class({
this.options = {};
}
// allow array for extents
if (newOptions) {
// make sure this.projection references a projection object
if(typeof newOptions.projection == "string") {
newOptions.projection = new OpenLayers.Projection(newOptions.projection);
}
if (newOptions.projection) {
// get maxResolution, units and maxExtent from projection defaults if
// they are not defined already
OpenLayers.Util.applyDefaults(newOptions,
OpenLayers.Projection.defaults[newOptions.projection.getCode()]);
}
// allow array for extents
if (newOptions.maxExtent && !(newOptions.maxExtent instanceof OpenLayers.Bounds)) {
newOptions.maxExtent = new OpenLayers.Bounds(newOptions.maxExtent);
}
@@ -493,11 +497,6 @@ OpenLayers.Layer = OpenLayers.Class({
// 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()) {
@@ -889,6 +888,16 @@ OpenLayers.Layer = OpenLayers.Class({
props.resolutions = this.resolutionsFromScales(props.scales);
}
if(props.resolutions == null) {
var maxExtent = this.maxExtent;
if (!props.maxResolution && maxExtent) {
// maxResolution for default grid sets assumes that at zoom
// level zero, the whole world fits on one tile.
var tileSize = this.tileSize || this.map.getTileSize();
props.maxResolution = Math.max(
maxExtent.getWidth() / tileSize.w,
maxExtent.getHeight() / tileSize.h
);
}
props.resolutions = this.calculateResolutions(props);
}
}

View File

@@ -29,12 +29,6 @@ OpenLayers.Layer.ArcIMS = OpenLayers.Class(OpenLayers.Layer.Grid, {
ServiceName: ''
},
/**
* APIProperty: tileSize
* {<OpenLayers.Size>} Size for tiles. Default is 512x512.
*/
tileSize: null,
/**
* APIProperty: featureCoordSys
* {String} Code for feature coordinate system. Default is "4326".

View File

@@ -67,6 +67,13 @@ OpenLayers.Layer.Bing = OpenLayers.Class(OpenLayers.Layer.XYZ, {
*/
type: "Road",
/**
* APIProperty: culture
* {String} The culture identifier. See http://msdn.microsoft.com/en-us/library/ff701709.aspx
* for the definition and the possible values. Default is "en-US".
*/
culture: "en-US",
/**
* APIProperty: metadataParams
* {Object} Optional url parameters for the Get Imagery Metadata request
@@ -74,6 +81,16 @@ OpenLayers.Layer.Bing = OpenLayers.Class(OpenLayers.Layer.XYZ, {
*/
metadataParams: null,
/** APIProperty: tileOptions
* {Object} optional configuration options for <OpenLayers.Tile> instances
* created by this Layer. Default is
*
* (code)
* {crossOriginKeyword: 'anonymous'}
* (end)
*/
tileOptions: null,
/**
* Constructor: OpenLayers.Layer.Bing
* Create a new Bing layer.
@@ -107,6 +124,9 @@ OpenLayers.Layer.Bing = OpenLayers.Class(OpenLayers.Layer.XYZ, {
var newArgs = [name, null, options];
OpenLayers.Layer.XYZ.prototype.initialize.apply(this, newArgs);
this.tileOptions = OpenLayers.Util.extend({
crossOriginKeyword: 'anonymous'
}, this.options.tileOptions);
this.loadMetadata();
},
@@ -142,13 +162,15 @@ OpenLayers.Layer.Bing = OpenLayers.Class(OpenLayers.Layer.XYZ, {
initLayer: function() {
var res = this.metadata.resourceSets[0].resources[0];
var url = res.imageUrl.replace("{quadkey}", "${quadkey}");
url = url.replace("{culture}", this.culture);
this.url = [];
for (var i=0; i<res.imageUrlSubdomains.length; ++i) {
this.url.push(url.replace("{subdomain}", res.imageUrlSubdomains[i]));
}
this.addOptions({
maxResolution: Math.min(
this.serverResolutions[res.zoomMin], this.maxResolution
this.serverResolutions[res.zoomMin],
this.maxResolution || Number.POSITIVE_INFINITY
),
numZoomLevels: Math.min(
res.zoomMax + 1 - res.zoomMin, this.numZoomLevels

View File

@@ -11,10 +11,15 @@
/**
* Constant: OpenLayers.Layer.Google.v3
*
* Mixin providing functionality specific to the Google Maps API v3. Note that
* this layer configures the google.maps.map object with the "disableDefaultUI"
* option set to true. Using UI controls that the Google Maps API provides is
* not supported by the OpenLayers API.
* Mixin providing functionality specific to the Google Maps API v3 <= v3.6.
* Note that this layer configures the google.maps.map object with the
* "disableDefaultUI" option set to true. Using UI controls that the Google
* Maps API provides is not supported by the OpenLayers API. To use this layer,
* you must include the GMaps API (<= v3.6) in your html:
*
* (code)
* <script src="http://maps.google.com/maps/api/js?v=3.6&amp;sensor=false"></script>
* (end)
*/
OpenLayers.Layer.Google.v3 = {
@@ -25,29 +30,13 @@ OpenLayers.Layer.Google.v3 = {
*
* (code)
* {
* maxExtent: new OpenLayers.Bounds(
* -128 * 156543.03390625,
* -128 * 156543.03390625,
* 128 * 156543.03390625,
* 128 * 156543.03390625
* ),
* sphericalMercator: true,
* maxResolution: 156543.03390625,
* units: "m",
* projection: "EPSG:900913"
* }
* (end)
*/
DEFAULTS: {
maxExtent: new OpenLayers.Bounds(
-128 * 156543.03390625,
-128 * 156543.03390625,
128 * 156543.03390625,
128 * 156543.03390625
),
sphericalMercator: true,
maxResolution: 156543.03390625,
units: "m",
projection: "EPSG:900913"
},

View File

@@ -99,10 +99,11 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
/**
* APIProperty: tileLoadingDelay
* {Integer} - Number of milliseconds before we shift and load
* tiles. Default is 100.
* {Integer} Number of milliseconds before we shift and load
* tiles when panning. Ignored if <OpenLayers.Animation.isNative> is
* true. Default is 85.
*/
tileLoadingDelay: 100,
tileLoadingDelay: 85,
/**
* Property: serverResolutions
@@ -112,10 +113,30 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
serverResolutions: null,
/**
* Property: timerId
* {Number} - The id of the tileLoadingDelay timer.
* Property: moveTimerId
* {Number} The id of the <deferMoveGriddedTiles> timer.
*/
timerId: null,
moveTimerId: null,
/**
* Property: deferMoveGriddedTiles
* {Function} A function that defers execution of <moveGriddedTiles> by
* <tileLoadingDelay>. If <OpenLayers.Animation.isNative> is true, this
* is null and unused.
*/
deferMoveGriddedTiles: null,
/**
* Property: tileQueueId
* {Number} The id of the <drawTileFromQueue> animation.
*/
tileQueueId: null,
/**
* Property: tileQueue
* {Array(<OpenLayers.Tile>)} Tiles queued for drawing.
*/
tileQueue: null,
/**
* Property: backBuffer
@@ -153,6 +174,14 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
*/
backBufferTimerId: null,
/**
* APIProperty: removeBackBufferDelay
* {Number} Delay for removing the backbuffer when all tiles have finished
* loading. Can be set to 0 when no css opacity transitions for the
* olTileImage class are used. Default is 2500.
*/
removeBackBufferDelay: 2500,
/**
* Register a listener for a particular event with the following syntax:
* (code)
@@ -170,7 +199,9 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* tileloaded - Triggered 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.
* 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.
*/
/**
@@ -187,10 +218,14 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
OpenLayers.Layer.HTTPRequest.prototype.initialize.apply(this,
arguments);
this.grid = [];
this.tileQueue = [];
this._moveGriddedTiles = OpenLayers.Function.bind(
this.moveGriddedTiles, this
);
if (!OpenLayers.Animation.isNative) {
this.deferMoveGriddedTiles = OpenLayers.Function.bind(function() {
this.moveGriddedTiles(true);
this.moveTimerId = null;
}, this);
}
},
/**
@@ -201,10 +236,11 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* map - {<OpenLayers.Map>} The map.
*/
removeMap: function(map) {
if(this.timerId != null) {
window.clearTimeout(this.timerId);
this.timerId = null;
if (this.moveTimerId !== null) {
window.clearTimeout(this.moveTimerId);
this.moveTimerId = null;
}
this.clearTileQueue();
if(this.backBufferTimerId !== null) {
window.clearTimeout(this.backBufferTimerId);
this.backBufferTimerId = null;
@@ -230,13 +266,13 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* destroy() on each of them to kill circular references
*/
clearGrid:function() {
this.clearTileQueue();
if (this.grid) {
for(var iRow=0, len=this.grid.length; iRow<len; iRow++) {
var row = this.grid[iRow];
for(var iCol=0, clen=row.length; iCol<clen; iCol++) {
var tile = row[iCol];
this.removeTileMonitoringHooks(tile);
tile.destroy();
this.destroyTile(tile);
}
}
this.grid = [];
@@ -371,12 +407,67 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
}
this.initGriddedTiles(bounds);
} else {
this.scheduleMoveGriddedTiles();
this.moveGriddedTiles();
}
}
}
},
/**
* Method: queueTileDraw
* Adds a tile to the animation queue that will draw it.
*
* Parameters:
* evt - {Object} Listener argument of the tile's beforedraw event
*/
queueTileDraw: function(evt) {
var tile = evt.object;
if (!~OpenLayers.Util.indexOf(this.tileQueue, tile)) {
// queue only if not in queue already
this.tileQueue.push(tile);
}
if (!this.tileQueueId) {
this.tileQueueId = OpenLayers.Animation.start(
OpenLayers.Function.bind(this.drawTileFromQueue, this),
null, this.div
);
}
return false;
},
/**
* Method: drawTileFromQueue
* Draws the first tile from the tileQueue, and unqueues that tile
*/
drawTileFromQueue: function() {
if (this.tileQueue.length === 0) {
this.clearTileQueue();
} else {
this.tileQueue.shift().draw(true);
}
},
/**
* Method: clearTileQueue
* Clears the animation queue
*/
clearTileQueue: function() {
OpenLayers.Animation.stop(this.tileQueueId);
this.tileQueueId = null;
this.tileQueue = [];
},
/**
* Method: destroyTile
*
* Parameters:
* tile - {<OpenLayers.Tile>}
*/
destroyTile: function(tile) {
this.removeTileMonitoringHooks(tile);
tile.destroy();
},
/**
* Method: getServerResolution
* Return the closest highest server-supported resolution. Throw an
@@ -565,24 +656,10 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
*/
moveByPx: function(dx, dy) {
if (!this.singleTile) {
this.scheduleMoveGriddedTiles();
this.moveGriddedTiles();
}
},
/**
* Method: scheduleMoveGriddedTiles
* Schedule the move of tiles.
*/
scheduleMoveGriddedTiles: function() {
if (this.timerId != null) {
window.clearTimeout(this.timerId);
}
this.timerId = window.setTimeout(
this._moveGriddedTiles,
this.tileLoadingDelay
);
},
/**
* APIMethod: setTileSize
* Check if we are in singleTile mode and if so, set the size as a ratio
@@ -633,6 +710,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* bounds - {<OpenLayers.Bounds>}
*/
initSingleTile: function(bounds) {
this.clearTileQueue();
//determine new tile bounds
var center = bounds.getCenterLonLat();
@@ -744,6 +822,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* bounds - {<OpenLayers.Bounds>}
*/
initGriddedTiles:function(bounds) {
this.clearTileQueue();
// 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
@@ -776,7 +855,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
var layerContainerDivLeft = parseInt(this.map.layerContainerDiv.style.left);
var layerContainerDivTop = parseInt(this.map.layerContainerDiv.style.top);
var tileData = [], center = this.map.getCenter();
do {
var row = this.grid[rowidx++];
if (!row) {
@@ -810,6 +889,12 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
} else {
tile.moveTo(tileBounds, px, false);
}
var tileCenter = tileBounds.getCenterLonLat();
tileData.push({
tile: tile,
distance: Math.pow(tileCenter.lon - center.lon, 2) +
Math.pow(tileCenter.lat - center.lat, 2)
});
tileoffsetlon += tilelon;
tileoffsetx += this.tileSize.w;
@@ -828,7 +913,12 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
this.gridResolution = this.getServerResolution();
//now actually draw the tiles
this.spiralTileLoad();
tileData.sort(function(a, b) {
return a.distance - b.distance;
});
for (var i=0, ii=tileData.length; i<ii; ++i) {
tileData[i].tile.draw();
}
},
/**
@@ -843,79 +933,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
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;
var testCell = iCell;
switch (directions[direction]) {
case "right":
testCell++;
break;
case "down":
testRow++;
break;
case "left":
testCell--;
break;
case "up":
testRow--;
break;
}
// 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;
iCell = testCell;
} else {
//need to try to load a tile in a different direction
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;
}
},
/**
* APIMethod: addTile
* Create a tile, initialize it, and add it to the layer div.
@@ -928,8 +945,11 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* {<OpenLayers.Tile>} The added OpenLayers.Tile
*/
addTile: function(bounds, position) {
return new this.tileClass(this, position, bounds, null,
this.tileSize, this.tileOptions);
var tile = new this.tileClass(
this, position, bounds, null, this.tileSize, this.tileOptions
);
tile.events.register("beforedraw", this, this.queueTileDraw);
return tile;
},
/**
@@ -953,16 +973,16 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
tile.onLoadEnd = function() {
this.numLoadingTiles--;
this.events.triggerEvent("tileloaded");
this.events.triggerEvent("tileloaded", {tile: tile});
//if that was the last tile, then trigger a 'loadend' on the layer
if (this.numLoadingTiles == 0) {
if (this.tileQueue.length === 0 && this.numLoadingTiles === 0) {
this.events.triggerEvent("loadend");
if(this.backBuffer) {
// the removal of the back buffer is delayed to prevent flash
// effects due to the animation of tile displaying
this.backBufferTimerId = window.setTimeout(
OpenLayers.Function.bind(this.removeBackBuffer, this),
2500
this.removeBackBufferDelay
);
}
}
@@ -991,19 +1011,32 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
/**
* Method: moveGriddedTiles
*
* Parameter:
* deferred - {Boolean} true if this is a deferred call that should not
* be delayed.
*/
moveGriddedTiles: function() {
var shifted = true;
moveGriddedTiles: function(deferred) {
if (!deferred && !OpenLayers.Animation.isNative) {
if (this.moveTimerId != null) {
window.clearTimeout(this.moveTimerId);
}
this.moveTimerId = window.setTimeout(
this.deferMoveGriddedTiles, this.tileLoadingDelay
);
return;
}
var buffer = this.buffer || 1;
var scale = this.getResolutionScale();
var tlLayer = this.grid[0][0].position.clone();
tlLayer.x *= scale;
tlLayer.y *= scale;
tlLayer = tlLayer.add(parseInt(this.div.style.left, 10),
parseInt(this.div.style.top, 10));
var offsetX = parseInt(this.map.layerContainerDiv.style.left);
var offsetY = parseInt(this.map.layerContainerDiv.style.top);
var tlViewPort = tlLayer.add(offsetX, offsetY);
while(true) {
var tlViewPort = {
x: (this.grid[0][0].position.x * scale) +
parseInt(this.div.style.left, 10) +
parseInt(this.map.layerContainerDiv.style.left),
y: (this.grid[0][0].position.y * scale) +
parseInt(this.div.style.top, 10) +
parseInt(this.map.layerContainerDiv.style.top)
};
var tileSize = {
w: this.tileSize.w * scale,
h: this.tileSize.h * scale
@@ -1017,13 +1050,8 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
} else if (tlViewPort.y < -tileSize.h * buffer) {
this.shiftRow(false);
} else {
shifted = false;
break;
}
if (shifted) {
// we may have other row or columns to shift, schedule it
// with a setTimeout, to give the user a chance to sneak
// in moveTo's
this.timerId = window.setTimeout(this._moveGriddedTiles, 0);
}
},
@@ -1113,8 +1141,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
var row = this.grid.pop();
for (var i=0, l=row.length; i<l; i++) {
var tile = row[i];
this.removeTileMonitoringHooks(tile);
tile.destroy();
this.destroyTile(tile);
}
}
@@ -1123,8 +1150,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
for (var i=0, l=this.grid.length; i<l; i++) {
var row = this.grid[i];
var tile = row.pop();
this.removeTileMonitoringHooks(tile);
tile.destroy();
this.destroyTile(tile);
}
}
},

View File

@@ -63,6 +63,25 @@ OpenLayers.Layer.OSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
*/
wrapDateLine: true,
/** APIProperty: tileOptions
* {Object} optional configuration options for <OpenLayers.Tile> instances
* created by this Layer. Default is
*
* (code)
* {crossOriginKeyword: 'anonymous'}
* (end)
*
* When using OSM tilesets other than the default ones, it may be
* necessary to set this to
*
* (code)
* {crossOriginKeyword: null}
* (end)
*
* if the server does not send Access-Control-Allow-Origin headers.
*/
tileOptions: null,
/**
* Constructor: OpenLayers.Layer.OSM
*
@@ -73,6 +92,12 @@ OpenLayers.Layer.OSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
* layer option can be set in this object (e.g.
* <OpenLayers.Layer.Grid.buffer>).
*/
initialize: function(name, url, options) {
OpenLayers.Layer.XYZ.prototype.initialize.apply(this, arguments);
this.tileOptions = OpenLayers.Util.extend({
crossOriginKeyword: 'anonymous'
}, this.options && this.options.tileOptions);
},
/**
* Method: clone

View File

@@ -24,6 +24,9 @@
OpenLayers.Layer.Vector = OpenLayers.Class(OpenLayers.Layer, {
/**
* APIProperty: events
* {<OpenLayers.Events>}
*
* Register a listener for a particular event with the following syntax:
* (code)
* layer.events.register(type, obj, listener);
@@ -36,7 +39,7 @@ OpenLayers.Layer.Vector = OpenLayers.Class(OpenLayers.Layer, {
* object - {Object} A reference to layer.events.object.
* element - {DOMElement} A reference to layer.events.element.
*
* Supported map event types (in addition to those from <OpenLayers.Layer>):
* Supported map event types (in addition to those from <OpenLayers.Layer.events>):
* beforefeatureadded - Triggered before a feature is added. Listeners
* will receive an object with a *feature* property referencing the
* feature to be added. To stop the feature from being added, a

View File

@@ -56,9 +56,11 @@ OpenLayers.Layer.WMS = OpenLayers.Class(OpenLayers.Layer.Grid, {
* 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.
* true as value. This is only relevant for WMS versions >= 1.3.0, and
* only if yx is not set in <OpenLayers.Projection.defaults> for the
* used projection.
*/
yx: {'EPSG:4326': true},
yx: {},
/**
* Constructor: OpenLayers.Layer.WMS
@@ -173,8 +175,9 @@ OpenLayers.Layer.WMS = OpenLayers.Class(OpenLayers.Layer.Grid, {
* {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()]);
var projCode = this.projection.getCode();
return parseFloat(this.params.VERSION) >= 1.3 &&
!!(this.yx[projCode] || OpenLayers.Projection.defaults[projCode].yx);
},
/**

View File

@@ -72,22 +72,13 @@ OpenLayers.Layer.XYZ = OpenLayers.Class(OpenLayers.Layer.Grid, {
initialize: function(name, url, options) {
if (options && options.sphericalMercator || this.sphericalMercator) {
options = OpenLayers.Util.extend({
maxExtent: new OpenLayers.Bounds(
-128 * 156543.03390625,
-128 * 156543.03390625,
128 * 156543.03390625,
128 * 156543.03390625
),
maxResolution: 156543.03390625,
numZoomLevels: 19,
units: "m",
projection: "EPSG:900913"
projection: "EPSG:900913",
numZoomLevels: 19
}, options);
}
url = url || this.url;
name = name || this.name;
var newArguments = [name, url, {}, options];
OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);
OpenLayers.Layer.Grid.prototype.initialize.apply(this, [
name || this.name, url || this.url, {}, options
]);
},
/**
@@ -157,9 +148,8 @@ OpenLayers.Layer.XYZ = OpenLayers.Class(OpenLayers.Layer.Grid, {
OpenLayers.Util.indexOf(resolutions, res) :
this.getServerZoom() + this.zoomOffset;
if (this.wrapDateLine) {
var limit = Math.pow(2, z);
if (this.wrapDateLine)
{
x = ((x % limit) + limit) % limit;
}

View File

@@ -89,10 +89,9 @@ OpenLayers.Layer.Zoomify = OpenLayers.Class(OpenLayers.Layer.Grid, {
// initilize the Zoomify pyramid for given size
this.initializeZoomify(size);
var newArguments = [];
newArguments.push(name, url, size, {}, options);
OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);
OpenLayers.Layer.Grid.prototype.initialize.apply(this, [
name, url, size, {}, options
]);
},
/**

View File

@@ -8,6 +8,7 @@
* @requires OpenLayers/Util.js
* @requires OpenLayers/Events.js
* @requires OpenLayers/Tween.js
* @requires OpenLayers/Projection.js
*/
/**
@@ -34,6 +35,9 @@ OpenLayers.Map = OpenLayers.Class({
},
/**
* APIProperty: events
* {<OpenLayers.Events>}
*
* Register a listener for a particular event with the following syntax:
* (code)
* map.events.register(type, obj, listener);
@@ -43,43 +47,42 @@ OpenLayers.Map = OpenLayers.Class({
* properties of this event depends on exactly what happened.
*
* All event objects have at least the following properties:
* - *object* {Object} A reference to map.events.object.
* - *element* {DOMElement} A reference to map.events.element.
* object - {Object} A reference to map.events.object.
* element - {DOMElement} A reference to map.events.element.
*
* Browser events have the following additional properties:
* - *xy* {<OpenLayers.Pixel>} The pixel location of the event (relative
* xy - {<OpenLayers.Pixel>} The pixel location of the event (relative
* to the the map viewport).
* - other properties that come with browser events
*
* Supported map event types:
* - *preaddlayer* triggered before a layer has been added. The event
* preaddlayer - triggered before a layer has been added. The event
* object will include a *layer* property that references the layer
* to be added. When a listener returns "false" the adding will be
* aborted.
* - *addlayer* triggered after a layer has been added. The event object
* addlayer - triggered after a layer has been added. The event object
* will include a *layer* property that references the added layer.
* - *preremovelayer* triggered before a layer has been removed. The event
* preremovelayer - triggered before a layer has been removed. The event
* object will include a *layer* property that references the layer
* to be removed. When a listener returns "false" the removal will be
* aborted.
* - *removelayer* triggered after a layer has been removed. The event
* 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,
* changelayer - triggered after a layer name change, order change,
* opacity change, params change, visibility change (due to resolution
* thresholds) or attribution change (due to extent change). 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, visibility or attribution).
* - *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
* - *mouseover* triggered after mouseover the map
* - *mouseout* triggered after mouseout the map
* - *mousemove* triggered after mousemove the map
* - *changebaselayer* triggered after the base layer changes
* 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
* mouseover - triggered after mouseover the map
* mouseout - triggered after mouseout the map
* mousemove - triggered after mousemove the map
* changebaselayer - triggered after the base layer changes
*/
/**
@@ -248,17 +251,19 @@ OpenLayers.Map = OpenLayers.Class({
/**
* APIProperty: projection
* {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".
* string this map. When using a projection other than EPSG:4326
* (CRS:84, Geographic) or EPSG:3857 (EPSG:900913, Web Mercator),
* also set maxExtent and maxResolution. Default is "EPSG:4326".
*/
projection: "EPSG:4326",
/**
* APIProperty: units
* {String} The map units. Defaults to 'degrees'. Possible values are
* 'degrees' (or 'dd'), 'm', 'ft', 'km', 'mi', 'inches'.
* {String} The map units. Possible values are 'degrees' (or 'dd'), 'm',
* 'ft', 'km', 'mi', 'inches'. Only required if the projection default
* should be overridden.
*/
units: 'degrees',
units: null,
/**
* APIProperty: resolutions
@@ -271,12 +276,10 @@ OpenLayers.Map = OpenLayers.Class({
/**
* 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
* displaying the whole world.
* {Float} Required if you are not displaying the whole world on a tile
* with the size specified in <tileSize>.
*/
maxResolution: 1.40625,
maxResolution: null,
/**
* APIProperty: minResolution
@@ -342,7 +345,8 @@ OpenLayers.Map = OpenLayers.Class({
/**
* APIProperty: displayProjection
* {<OpenLayers.Projection>} Requires proj4js support.Projection used by
* {<OpenLayers.Projection>} Requires proj4js support for projections other
* than EPSG:4326 or EPSG:900913/EPSG:3857. 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.
@@ -471,8 +475,6 @@ OpenLayers.Map = OpenLayers.Class({
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() +
@@ -481,6 +483,10 @@ OpenLayers.Map = OpenLayers.Class({
// now override default options
OpenLayers.Util.extend(this, options);
var projCode = this.projection instanceof OpenLayers.Projection ?
this.projection.projCode : this.projection;
OpenLayers.Util.applyDefaults(this, OpenLayers.Projection.defaults[projCode]);
// allow extents to be arrays
if (this.maxExtent && !(this.maxExtent instanceof OpenLayers.Bounds)) {
this.maxExtent = new OpenLayers.Bounds(this.maxExtent);
@@ -571,14 +577,20 @@ OpenLayers.Map = OpenLayers.Class({
}
if (this.controls == null) {
if (OpenLayers.Control != null) { // running full or lite?
this.controls = [ new OpenLayers.Control.Navigation(),
new OpenLayers.Control.PanZoom(),
new OpenLayers.Control.ArgParser(),
new OpenLayers.Control.Attribution()
];
} else {
this.controls = [];
if (OpenLayers.Control != null) { // running full or lite?
if (OpenLayers.Control.Navigation) {
this.controls.push(new OpenLayers.Control.Navigation())
}
if (OpenLayers.Control.PanZoom) {
this.controls.push(new OpenLayers.Control.PanZoom())
}
if (OpenLayers.Control.ArgParser) {
this.controls.push(new OpenLayers.Control.ArgParser())
}
if (OpenLayers.Control.Attribution) {
this.controls.push(new OpenLayers.Control.Attribution())
}
}
}
@@ -613,6 +625,17 @@ OpenLayers.Map = OpenLayers.Class({
}
},
/**
* APIMethod: getViewport
* Get the DOMElement representing the view port.
*
* Returns:
* {DOMElement}
*/
getViewport: function() {
return this.viewPortDiv;
},
/**
* APIMethod: render
* Render the map to a specified container.

View File

@@ -142,7 +142,7 @@ OpenLayers.Projection = OpenLayers.Class({
/**
* Property: transforms
* Transforms is an object, with from properties, each of which may
* {Object} Transforms is an object, with from properties, each of which may
* have a to property. This allows you to define projections without
* requiring support for proj4js to be included.
*
@@ -162,6 +162,30 @@ OpenLayers.Projection = OpenLayers.Class({
*/
OpenLayers.Projection.transforms = {};
/**
* APIProperty: defaults
* {Object} Defaults for the SRS codes known to OpenLayers (currently
* EPSG:4326, CRS:84, urn:ogc:def:crs:EPSG:6.6:4326, EPSG:900913, EPSG:3857,
* EPSG:102113 and EPSG:102100). Keys are the SRS code, values are units,
* maxExtent (the validity extent for the SRS) and yx (true if this SRS is
* known to have a reverse axis order).
*/
OpenLayers.Projection.defaults = {
"EPSG:4326": {
units: "degrees",
maxExtent: [-180, -90, 180, 90],
yx: true
},
"CRS:84": {
units: "degrees",
maxExtent: [-180, -90, 180, 90]
},
"EPSG:900913": {
units: "m",
maxExtent: [-20037508.34, -20037508.34, 20037508.34, 20037508.34]
}
};
/**
* APIMethod: addTransform
* Set a custom transform method between two projections. Use this method in
@@ -176,6 +200,12 @@ OpenLayers.Projection.transforms = {};
* in place. The original point should be modified.
*/
OpenLayers.Projection.addTransform = function(from, to, method) {
if (method === OpenLayers.Projection.nullTransform) {
var defaults = OpenLayers.Projection.defaults[from];
if (defaults && !OpenLayers.Projection.defaults[to]) {
OpenLayers.Projection.defaults[to] = defaults;
}
}
if(!OpenLayers.Projection.transforms[from]) {
OpenLayers.Projection.transforms[from] = {};
}
@@ -235,12 +265,15 @@ OpenLayers.Projection.nullTransform = function(point) {
};
/**
* Note: Transforms for web mercator <-> EPSG:4326
* Note: Transforms for web mercator <-> geographic
* OpenLayers recognizes EPSG:3857, EPSG:900913, EPSG:102113 and EPSG:102100.
* OpenLayers originally started referring to EPSG:900913 as web mercator.
* The EPSG has declared EPSG:3857 to be web mercator.
* ArcGIS 10 recognizes the EPSG:3857, EPSG:102113, and EPSG:102100 as
* equivalent. See http://blogs.esri.com/Dev/blogs/arcgisserver/archive/2009/11/20/ArcGIS-Online-moving-to-Google-_2F00_-Bing-tiling-scheme_3A00_-What-does-this-mean-for-you_3F00_.aspx#12084
* equivalent. See http://blogs.esri.com/Dev/blogs/arcgisserver/archive/2009/11/20/ArcGIS-Online-moving-to-Google-_2F00_-Bing-tiling-scheme_3A00_-What-does-this-mean-for-you_3F00_.aspx#12084.
* For geographic, OpenLayers recognizes EPSG:4326, CRS:84 and
* urn:ogc:def:crs:EPSG:6.6:4326. OpenLayers also knows about the reverse axis
* order for EPSG:4326.
*/
(function() {
@@ -258,22 +291,31 @@ OpenLayers.Projection.nullTransform = function(point) {
return xy;
}
// list of equivalent codes for web mercator
var codes = ["EPSG:900913", "EPSG:3857", "EPSG:102113", "EPSG:102100"];
function map(base, codes) {
var add = OpenLayers.Projection.addTransform;
var same = OpenLayers.Projection.nullTransform;
var i, len, code, other, j;
for (i=0, len=codes.length; i<len; ++i) {
code = codes[i];
add("EPSG:4326", code, forwardMercator);
add(code, "EPSG:4326", inverseMercator);
add(base, code, forwardMercator);
add(code, base, inverseMercator);
for (j=i+1; j<len; ++j) {
other = codes[j];
add(code, other, same);
add(other, code, same);
}
}
}
// list of equivalent codes for web mercator
var mercator = ["EPSG:900913", "EPSG:3857", "EPSG:102113", "EPSG:102100"],
geographic = ["CRS:84", "urn:ogc:def:crs:EPSG:6.6:4326", "EPSG:4326"],
i;
for (i=mercator.length-1; i>=0; --i) {
map(mercator[i], geographic);
}
for (i=geographic.length-1; i>=0; --i) {
map(geographic[i], mercator);
}
})();

View File

@@ -52,23 +52,6 @@ OpenLayers.Protocol.CSW.v2_0_2 = OpenLayers.Class(OpenLayers.Protocol, {
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);
},
/**
* Method: read
* Construct a request for reading new records from the Catalogue.

View File

@@ -166,7 +166,7 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {
* {<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.
* is then populated with the features received from the server.
*/
read: function(options) {
OpenLayers.Protocol.prototype.read.apply(this, arguments);
@@ -183,13 +183,13 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {
options.readWithPOST : this.readWithPOST;
var resp = new OpenLayers.Protocol.Response({requestType: "read"});
if(readWithPOST) {
var headers = options.headers || {};
headers["Content-Type"] = "application/x-www-form-urlencoded";
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"
}
headers: headers
});
} else {
resp.priv = OpenLayers.Request.GET({

View File

@@ -411,6 +411,7 @@ OpenLayers.Renderer.defaultSymbolizer = {
strokeWidth: 2,
fillOpacity: 1,
strokeOpacity: 1,
pointRadius: 0
pointRadius: 0,
labelAlign: 'cm'
};

View File

@@ -51,6 +51,12 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
*/
pendingRedraw: false,
/**
* Property: cachedSymbolBounds
* {Object} Internal cache of calculated symbol extents.
*/
cachedSymbolBounds: {},
/**
* Constructor: OpenLayers.Renderer.Canvas
*
@@ -110,8 +116,7 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
* {Boolean} Whether or not the browser supports the renderer class
*/
supported: function() {
var canvas = document.createElement("canvas");
return !!canvas.getContext;
return OpenLayers.CANVAS_SUPPORTED;
},
/**
@@ -284,6 +289,151 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
img.src = style.externalGraphic;
},
/**
* Method: drawNamedSymbol
* Called to draw Well Known Graphic Symbol Name.
* This method is only called by the renderer itself.
*
* Parameters:
* geometry - {<OpenLayers.Geometry>}
* style - {Object}
* featureId - {String}
*/
drawNamedSymbol: function(geometry, style, featureId) {
var x, y, cx, cy, i, symbolBounds, scaling, angle;
var unscaledStrokeWidth;
var deg2rad = Math.PI / 180.0;
var symbol = OpenLayers.Renderer.symbol[style.graphicName];
if (!symbol) {
throw new Error(style.graphicName + ' is not a valid symbol name');
}
if (!symbol.length || symbol.length < 2) return;
var pt = this.getLocalXY(geometry);
var p0 = pt[0];
var p1 = pt[1];
if (isNaN(p0) || isNaN(p1)) return;
// Use rounded line caps
this.canvas.lineCap = "round";
this.canvas.lineJoin = "round";
// Scale and rotate symbols, using precalculated bounds whenever possible.
if (style.graphicName in this.cachedSymbolBounds) {
symbolBounds = this.cachedSymbolBounds[style.graphicName];
} else {
symbolBounds = new OpenLayers.Bounds();
for(i = 0; i < symbol.length; i+=2) {
symbolBounds.extend(new OpenLayers.LonLat(symbol[i], symbol[i+1]));
}
this.cachedSymbolBounds[style.graphicName] = symbolBounds;
}
// Push symbol scaling, translation and rotation onto the transformation stack in reverse order.
// Don't forget to apply all canvas transformations to the hitContext canvas as well(!)
this.canvas.save();
if (this.hitDetection) { this.hitContext.save(); }
// Step 3: place symbol at the desired location
this.canvas.translate(p0,p1);
if (this.hitDetection) { this.hitContext.translate(p0,p1); }
// Step 2a. rotate the symbol if necessary
angle = deg2rad * style.rotation; // will be NaN when style.rotation is undefined.
if (!isNaN(angle)) {
this.canvas.rotate(angle);
if (this.hitDetection) { this.hitContext.rotate(angle); }
}
// // Step 2: scale symbol such that pointRadius equals half the maximum symbol dimension.
scaling = 2.0 * style.pointRadius / Math.max(symbolBounds.getWidth(), symbolBounds.getHeight());
this.canvas.scale(scaling,scaling);
if (this.hitDetection) { this.hitContext.scale(scaling,scaling); }
// Step 1: center the symbol at the origin
cx = symbolBounds.getCenterLonLat().lon;
cy = symbolBounds.getCenterLonLat().lat;
this.canvas.translate(-cx,-cy);
if (this.hitDetection) { this.hitContext.translate(-cx,-cy); }
// Don't forget to scale stroke widths, because they are affected by canvas scale transformations as well(!)
// Alternative: scale symbol coordinates manually, so stroke width scaling is not needed anymore.
unscaledStrokeWidth = style.strokeWidth;
style.strokeWidth = unscaledStrokeWidth / scaling;
if (style.fill !== false) {
this.setCanvasStyle("fill", style);
this.canvas.beginPath();
for (i=0; i<symbol.length; i=i+2) {
x = symbol[i];
y = symbol[i+1];
if (i == 0) this.canvas.moveTo(x,y);
this.canvas.lineTo(x,y);
}
this.canvas.closePath();
this.canvas.fill();
if (this.hitDetection) {
this.setHitContextStyle("fill", featureId, style);
this.hitContext.beginPath();
for (i=0; i<symbol.length; i=i+2) {
x = symbol[i];
y = symbol[i+1];
if (i == 0) this.canvas.moveTo(x,y);
this.hitContext.lineTo(x,y);
}
this.hitContext.closePath();
this.hitContext.fill();
}
}
if (style.stroke !== false) {
this.setCanvasStyle("stroke", style);
this.canvas.beginPath();
for (i=0; i<symbol.length; i=i+2) {
x = symbol[i];
y = symbol[i+1];
if (i == 0) this.canvas.moveTo(x,y);
this.canvas.lineTo(x,y);
}
this.canvas.closePath();
this.canvas.stroke();
}
style.strokeWidth = unscaledStrokeWidth;
this.canvas.restore();
if (this.hitDetection) { this.hitContext.restore(); }
this.setCanvasStyle("reset");
},
/**
* 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: setCanvasStyle
* Prepare the canvas for drawing by setting various global settings.
@@ -366,6 +516,8 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
if(style.graphic !== false) {
if(style.externalGraphic) {
this.drawExternalGraphic(geometry, style, featureId);
} else if (style.graphicName && (style.graphicName != "circle")) {
this.drawNamedSymbol(geometry, style, featureId);
} else {
var pt = this.getLocalXY(geometry);
var p0 = pt[0];
@@ -634,7 +786,7 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
* layer.
*/
getFeatureIdFromEvent: function(evt) {
var feature;
var featureId, feature;
if (this.hitDetection) {
// this dragging check should go in the feature handler
if (!this.map.dragging) {
@@ -645,7 +797,14 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
if (data[3] === 255) { // antialiased
var id = data[2] + (256 * (data[1] + (256 * data[0])));
if (id) {
feature = this.features["OpenLayers.Feature.Vector_" + (id - 1 + this.hitOverflow)][0];
featureId = "OpenLayers.Feature.Vector_" + (id - 1 + this.hitOverflow);
try {
feature = this.features[featureId][0];
} catch(err) {
// Because of antialiasing on the canvas, when the hit location is at a point where the edge of
// one symbol intersects the interior of another symbol, a wrong hit color (and therefore id) results.
// todo: set Antialiasing = 'off' on the hitContext as soon as browsers allow it.
}
}
}
}

View File

@@ -696,7 +696,7 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
} else {
label.setAttributeNS(null, "pointer-events", "none");
}
var align = style.labelAlign;
var align = style.labelAlign || OpenLayers.Renderer.defaultSymbolizer.labelAlign;
label.setAttributeNS(null, "text-anchor",
OpenLayers.Renderer.SVG.LABEL_ALIGN[align[0]] || "middle");

View File

@@ -584,7 +584,7 @@ OpenLayers.Renderer.SVG2 = OpenLayers.Class(OpenLayers.Renderer.NG, {
} else {
text.setAttributeNS(null, "pointer-events", "none");
}
var align = style.labelAlign;
var align = style.labelAlign || OpenLayers.Renderer.defaultSymbolizer.labelAlign;
text.setAttributeNS(null, "text-anchor",
OpenLayers.Renderer.SVG2.LABEL_ALIGN[align[0]] || "middle");

View File

@@ -0,0 +1,63 @@
/* 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. */
/**
* Namespace: Spherical
* The OpenLayers.Spherical namespace includes utility functions for
* calculations on the basis of a spherical earth (ignoring ellipsoidal
* effects), which is accurate enough for most purposes.
*
* Relevant links:
* * http://www.movable-type.co.uk/scripts/latlong.html
* * http://code.google.com/apis/maps/documentation/javascript/reference.html#spherical
*/
OpenLayers.Spherical = OpenLayers.Spherical || {};
OpenLayers.Spherical.DEFAULT_RADIUS = 6378137;
/**
* APIFunction: computeDistanceBetween
* Computes the distance between two LonLats.
*
* Parameters:
* from - {<OpenLayers.LonLat>} or {Object} Starting point. A LonLat or
* a JavaScript literal with lon lat properties.
* to - {<OpenLayers.LonLat>} or {Object} Ending point. A LonLat or a
* JavaScript literal with lon lat properties.
* radius - {Float} The radius. Optional. Defaults to 6378137 meters.
*
* Returns:
* {Float} The distance in meters.
*/
OpenLayers.Spherical.computeDistanceBetween = function(from, to, radius) {
var R = radius || OpenLayers.Spherical.DEFAULT_RADIUS;
var sinHalfDeltaLon = Math.sin(Math.PI * (to.lon - from.lon) / 360);
var sinHalfDeltaLat = Math.sin(Math.PI * (to.lat - from.lat) / 360);
var a = sinHalfDeltaLat * sinHalfDeltaLat +
sinHalfDeltaLon * sinHalfDeltaLon * Math.cos(Math.PI * from.lat / 180) * Math.cos(Math.PI * to.lat / 180);
return 2 * R * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
};
/**
* APIFunction: computeHeading
* Computes the heading from one LonLat to another LonLat.
*
* Parameters:
* from - {<OpenLayers.LonLat>} or {Object} Starting point. A LonLat or
* a JavaScript literal with lon lat properties.
* to - {<OpenLayers.LonLat>} or {Object} Ending point. A LonLat or a
* JavaScript literal with lon lat properties.
*
* Returns:
* {Float} The heading in degrees.
*/
OpenLayers.Spherical.computeHeading = function(from, to) {
var y = Math.sin(Math.PI * (from.lon - to.lon) / 180) * Math.cos(Math.PI * to.lat / 180);
var x = Math.cos(Math.PI * from.lat / 180) * Math.sin(Math.PI * to.lat / 180) -
Math.sin(Math.PI * from.lat / 180) * Math.cos(Math.PI * to.lat / 180) * Math.cos(Math.PI * (from.lon - to.lon) / 180);
return 180 * Math.atan2(y, x) / Math.PI;
};

View File

@@ -124,9 +124,12 @@ OpenLayers.Strategy.BBOX = OpenLayers.Class(OpenLayers.Strategy, {
* Callback function called on "moveend" or "refresh" layer events.
*
* Parameters:
* options - {Object} An object with a property named "force", this
* property references a boolean value indicating if new data
* must be incondtionally read.
* options - {Object} Optional object whose properties will determine
* the behaviour of this Strategy
*
* Valid options include:
* force - {Boolean} if true, new data must be unconditionally read.
* noAbort - {Boolean} if true, do not abort previous requests.
*/
update: function(options) {
var mapBounds = this.getMapBounds();
@@ -218,7 +221,7 @@ OpenLayers.Strategy.BBOX = OpenLayers.Class(OpenLayers.Strategy, {
* returned by the layer protocol.
*/
triggerRead: function(options) {
if (this.response) {
if (this.response && !(options && options.noAbort === true)) {
this.layer.protocol.abort(this.response);
this.layer.events.triggerEvent("loadend");
}

View File

@@ -20,15 +20,19 @@
OpenLayers.Strategy.Save = OpenLayers.Class(OpenLayers.Strategy, {
/**
* APIProperty: events
* {<OpenLayers.Events>} An events object that handles all
* events on the strategy object.
*
* Register a listener for a particular event with the following syntax:
* (code)
* strategy.events.register(type, obj, listener);
* (end)
*
* Supported event types:
* - *start* Triggered before saving
* - *success* Triggered after a successful transaction
* - *fail* Triggered after a failed transaction
* start - Triggered before saving
* success - Triggered after a successful transaction
* fail - Triggered after a failed transaction
*
*/

View File

@@ -23,18 +23,25 @@
*/
OpenLayers.Tile = OpenLayers.Class({
/**
* Supported event types:
* - *loadstart* Triggered when tile loading starts.
* - *loadend* Triggered when tile loading ends.
* - *reload* Triggered when an already loading tile is reloaded.
* - *unload* Triggered before a tile is unloaded.
*/
/**
* APIProperty: events
* {<OpenLayers.Events>} An events object that handles all
* events on the tile.
*
* Register a listener for a particular event with the following syntax:
* (code)
* tile.events.register(type, obj, listener);
* (end)
*
* Supported event types:
* beforedraw - Triggered before the tile is drawn. Used to defer
* drawing to an animation queue. To defer drawing, listeners need
* to return false, which will abort drawing. The queue handler needs
* to call <draw>(true) to actually draw the tile.
* loadstart - Triggered when tile loading starts.
* loadend - Triggered when tile loading ends.
* reload - Triggered when an already loading tile is reloaded.
* unload - Triggered before a tile is unloaded.
*/
events: null,
@@ -181,14 +188,25 @@ OpenLayers.Tile = OpenLayers.Class({
* that can be overridden by subclasses. The minimum thing to do here
* is to call <clear> and return the result from <shouldDraw>.
*
* Parameters:
* deferred - {Boolean} When drawing was aborted by returning false from a
* *beforedraw* listener, the queue manager needs to pass true, so the
* tile will not be cleared and immediately be drawn. Otherwise, the
* tile will be cleared and a *beforedraw* event will be fired.
*
* Returns:
* {Boolean} Whether or not the tile should actually be drawn.
*/
draw: function() {
draw: function(deferred) {
if (!deferred) {
//clear tile's contents and mark as not drawn
this.clear();
return this.shouldDraw();
}
var draw = this.shouldDraw();
if (draw && !deferred) {
draw = this.events.triggerEvent("beforedraw") !== false;
}
return draw;
},
/**
@@ -259,10 +277,10 @@ OpenLayers.Tile = OpenLayers.Class({
/**
* Method: clear
* Clear the tile of any bounds/position-related data so that it can
* be reused in a new location. To be implemented by subclasses.
* be reused in a new location.
*/
clear: function(draw) {
// to be implemented by subclasses
// to be extended by subclasses
},
CLASS_NAME: "OpenLayers.Tile"

View File

@@ -6,6 +6,7 @@
/**
* @requires OpenLayers/Tile.js
* @requires OpenLayers/Animation.js
*/
/**
@@ -81,6 +82,23 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
*/
maxGetUrlLength: null,
/**
* Property: canvasContext
* {CanvasRenderingContext2D} A canvas context associated with
* the tile image.
*/
canvasContext: null,
/**
* APIProperty: crossOriginKeyword
* The value of the crossorigin keyword to use when loading images. This is
* only relevant when using <getCanvasContext> for tiles from remote
* origins and should be set to either 'anonymous' or 'use-credentials'
* for servers that send Access-Control-Allow-Origin headers with their
* tiles.
*/
crossOriginKeyword: null,
/** 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.
@@ -203,6 +221,7 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
* it can be reused in a new location.
*/
clear: function() {
OpenLayers.Tile.prototype.clear.apply(this, arguments);
var img = this.imgDiv;
if (img) {
OpenLayers.Event.stopObservingElement(img);
@@ -216,6 +235,7 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
}
OpenLayers.Element.removeClass(img, "olImageLoadError");
}
this.canvasContext = null;
},
/**
@@ -297,6 +317,9 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
} else {
OpenLayers.Event.observe(img, "load", load);
OpenLayers.Event.observe(img, "error", load);
if (img.crossOrigin) {
img.crossOrigin = null;
}
img.src = this.blankImageUrl;
}
}
@@ -314,6 +337,10 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
img.style.visibility = 'hidden';
img.style.opacity = 0;
if (url) {
// don't set crossOrigin if the url is a data URL
if (this.crossOriginKeyword && url.substr(0, 5 !== 'data:')) {
img.crossOrigin = this.crossOriginKeyword;
}
img.src = url;
}
},
@@ -366,6 +393,7 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
img.style.opacity = this.layer.opacity;
this.isLoading = false;
this.canvasContext = null;
this.events.triggerEvent("loadend");
// IE<7 needs a reflow when the tiles are loaded because of the
@@ -406,6 +434,38 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
}
},
/**
* APIMethod: getCanvasContext
* Returns a canvas context associated with the tile image (with
* the image drawn on it).
* Returns undefined if the browser does not support canvas, if
* the tile has no image or if it's currently loading.
*
* The function returns a canvas context instance but the
* underlying canvas is still available in the 'canvas' property:
* (code)
* var context = tile.getCanvasContext();
* if (context) {
* var data = context.canvas.toDataURL('image/jpeg');
* }
* (end)
*
* Returns:
* {Boolean}
*/
getCanvasContext: function() {
if (OpenLayers.CANVAS_SUPPORTED && this.imgDiv && !this.isLoading) {
if (!this.canvasContext) {
var canvas = document.createElement("canvas");
canvas.width = this.size.w;
canvas.height = this.size.h;
this.canvasContext = canvas.getContext("2d");
this.canvasContext.drawImage(this.imgDiv, 0, 0);
}
return this.canvasContext;
}
},
CLASS_NAME: "OpenLayers.Tile.Image"
});

View File

@@ -1435,6 +1435,15 @@ OpenLayers.IS_GECKO = (function() {
return ua.indexOf("webkit") == -1 && ua.indexOf("gecko") != -1;
})();
/**
* Constant: CANVAS_SUPPORTED
* {Boolean} True if canvas 2d is supported.
*/
OpenLayers.CANVAS_SUPPORTED = (function() {
var elem = document.createElement('canvas');
return !!(elem.getContext && elem.getContext('2d'));
})();
/**
* Constant: BROWSER_NAME
* {String}

View File

@@ -22,6 +22,10 @@ People can override this rule to use other transition settings. To remove tile a
# Behavior Changes from Past Releases
## GPX API change
The `gpxns` API property has been removed. The GPX namespace is now defined in the `namespaces` property but is not intended to be overriden.
## Function return values
[Previously][prev] a few functions in the library displayed error messages and returned `undefined`, `null` or `false` if the parameters passed in were bad. In 2.12 these functions now just throw an error/exception. People relying on return values to know if a function call is successful may need to change their code. Here are the modified functions:
@@ -58,7 +62,7 @@ We are deprecating the Rico classes/objects in OpenLayers. This has the followin
The `roundedCorner` option of `Control.LayerSwitcher` is deprecated, and it now defaults to `false`. Setting it to true results in deprecation messages being output on the console. If you still want to set `roundedCorner` to `true` (you should not!) you need to make sure that the Rico/Corner.js and Rico/Color.js scripts are loaded in the page. This can be ensured by adding Rico/Corner.js in the build profile. The controls.html example demonstrates how to use `border-radius` to round corners of a layer switcher:
olControlLayerSwitcher .layersDiv {
.olControlLayerSwitcher .layersDiv {
border-radius: 10px 0 0 10px;
}
@@ -72,10 +76,14 @@ The base `OpenLayers.Geometry` class no longer depends on `OpenLayers.Format.WKT
Without the WKT format included (by default), the `OpenLayers.Geometry::toString` method now returns "[object Object]." Previously, it returned the Well-Known Text representation of the geometry. To maintain the previous behavior, include the OpenLayers/Format/WKT.js file in your build.
## OSM Layer
## OSM and Bing Layers
`Layer.OSM` is now defined in its own script file, namely `OpenLayers/Layer/OSM.js`. So people using `Layer.OSM` should now include `OpenLayers/Layer/OSM.js`, as opposed to `OpenLayers/Layer/XYZ.js`, in their OpenLayers builds. (See https://github.com/openlayers/openlayers/issues/138)
The `OpenLayers.Tile.Image` class now has a method to get a canvas context for processing tiles. Since both OSM and Bing set Access-Control-Allow-Origin headers for their tiles, it is possible to manipulate a canvas that these tiles were rendered to even if the tiles come from a remote origin. Especially when working with custom OSM tilesets from servers that do not send Access-Control-Allow-Origin headers, it is now necessary to configure the layer with
tileOptions: {crossOriginKeyword: null}
## Projection & SphericalMercator
In previous releases, coordinate transforms between EPSG:4326 and EPSG:900913 were defined in the SphericalMercator.js script. In 2.12, these default transforms are included in the Projection.js script. The Projection.js script is included as a dependency in builds with any layer types, so no special build configuration is necessary to get the web mercator transforms.

View File

@@ -15,7 +15,8 @@
<script>
function test_all(t) {
t.plan(7);
t.plan(8);
t.ok(OpenLayers.Animation.isNative !== undefined, "isNative is set.");
t.open_window("Animation.html", function(win) {
win.requestFrame(t);
win.start(t);

View File

@@ -30,8 +30,9 @@
map.addLayer(new OpenLayers.Layer("name", {'attribution':'My layer 2!'}));
t.eq(control.div.innerHTML, 'My layer!, My layer 2!', "Attribution correct with two layers.");
control.separator = '|';
control.template = "Map Copyright (c) 2012 by Foo Bar; ${layers}";
map.addLayer(new OpenLayers.Layer("name",{'attribution':'My layer 3!'}));
t.eq(control.div.innerHTML, 'My layer!|My layer 2!|My layer 3!', "Attribution correct with three layers and diff seperator.");
t.eq(control.div.innerHTML, 'Map Copyright (c) 2012 by Foo Bar; My layer!|My layer 2!|My layer 3!', "Attribution correct with three layers and diff seperator.");
}

View File

@@ -3,7 +3,7 @@
<script src="../OLLoader.js"></script>
<script type="text/javascript">
function test_initialze(t) {
function test_initialize(t) {
t.plan(1);

View File

@@ -807,6 +807,25 @@
t.eq(control._originalGeometry, undefined, "original geometry deleted once it is set on the modified property");
}
function test_createVertices(t) {
t.plan(2);
var layer = new OpenLayers.Layer.Vector();
var control = new OpenLayers.Control.ModifyFeature(layer, {
createVertices: false
});
var line = new OpenLayers.Geometry.LineString([
new OpenLayers.Geometry.Point(5, 6),
new OpenLayers.Geometry.Point(7, 8),
new OpenLayers.Geometry.Point(9, 10)
]);
control.feature = new OpenLayers.Feature.Vector(line);
control.resetVertices();
t.eq(control.vertices.length, 3, "Correct vertices length with createVertices is false");
t.eq(control.virtualVertices.length, 0, "Correct virtual vertices length with createVertices is false");
control.destroy();
}
</script>
</head>
<body>

View File

@@ -291,18 +291,18 @@
t.plan(5);
var map = new OpenLayers.Map("map", {
getExtent: function() {return(new OpenLayers.Bounds(-180,-90,180,90));}
}
);
});
var geographic = new OpenLayers.Projection("EPSG:4326");
var a = new OpenLayers.Layer.WMS("dummy","http://localhost/wms", {
layers: "a,b,c,d",
styles: "a,b,c,d"
});
}, {projection: geographic});
var b = new OpenLayers.Layer.WMS("dummy","http://localhost/wms", {
layers: ["a","b","c","d"],
styles: ["a","b","c","d"]
});
}, {projection: geographic});
var c = new OpenLayers.Layer.WMS("dummy","http://localhost/wms", {
layers: ["a","b","c","d"]
@@ -310,13 +310,13 @@
var d = new OpenLayers.Layer.WMS("dummy","http://localhost/wms", {
layers: "a,b,c,d"
});
}, {projection: geographic});
var click = new OpenLayers.Control.WMSGetFeatureInfo({
featureType: 'type',
featureNS: 'ns',
layers: [a, b, c, d]
});
}, {projection: geographic});
map.addControl(click);
@@ -399,6 +399,7 @@
var c = new OpenLayers.Layer.WMS(
null, ["http://c.mirror/wms", "http://d.mirror/wms"], {layers: "c"}
);
map.addLayers([a, b, c]);
var control = new OpenLayers.Control.WMSGetFeatureInfo({
url: "http://host/wms",

View File

@@ -46,7 +46,7 @@
new OpenLayers.Feature.Vector(point2, {name: 'foo', description: 'bar'})
];
var data = parser.write(features);
t.xml_eq(data, '<?xml version="1.0" encoding="ISO-8859-1"?><gpx xmlns="http://www.topografix.com/GPX/1/1"><wpt lon="-111.04" lat="45.68"><name>foo</name><desc>bar</desc></wpt><wpt lon="-112.04" lat="45.68"><name>foo</name><desc>bar</desc></wpt></gpx>', 'GPX serializes points correctly');
t.xml_eq(data, '<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="OpenLayers" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><wpt lon="-111.04" lat="45.68"><name>foo</name><desc>bar</desc></wpt><wpt lon="-112.04" lat="45.68"><name>foo</name><desc>bar</desc></wpt></gpx>', 'GPX serializes points correctly');
}
function test_Format_GPX_serialize_line(t) {
t.plan(1);
@@ -58,7 +58,7 @@
var line = new OpenLayers.Geometry.LineString([point, point2]);
var f = new OpenLayers.Feature.Vector(line, {name: 'foo', description: 'bar'});
var data = parser.write(f);
t.xml_eq(data, '<?xml version="1.0" encoding="ISO-8859-1"?><gpx xmlns="http://www.topografix.com/GPX/1/1"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon="-111.04" lat="45.68"/><trkpt lon="-112.04" lat="45.68"/></trkseg></trk></gpx>', 'GPX serializes line correctly');
t.xml_eq(data, '<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="OpenLayers" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon="-111.04" lat="45.68"/><trkpt lon="-112.04" lat="45.68"/></trkseg></trk></gpx>', 'GPX serializes line correctly');
}
function test_Format_GPX_serialize_lines(t) {
t.plan(1);
@@ -74,7 +74,7 @@
var f = new OpenLayers.Feature.Vector(line, {name: 'foo', description: 'bar'});
var f2 = new OpenLayers.Feature.Vector(line2, {name: 'dude', description: 'truite'});
var data = parser.write([f, f2]);
t.xml_eq(data, '<?xml version="1.0" encoding="ISO-8859-1"?><gpx xmlns="http://www.topografix.com/GPX/1/1"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon="-111.04" lat="45.68"/><trkpt lon="-112.04" lat="45.68"/></trkseg></trk><trk><name>dude</name><desc>truite</desc><trkseg><trkpt lon="1" lat="2"/><trkpt lon="3" lat="4"/></trkseg></trk></gpx>', 'GPX serializes lines correctly');
t.xml_eq(data, '<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="OpenLayers" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon="-111.04" lat="45.68"/><trkpt lon="-112.04" lat="45.68"/></trkseg></trk><trk><name>dude</name><desc>truite</desc><trkseg><trkpt lon="1" lat="2"/><trkpt lon="3" lat="4"/></trkseg></trk></gpx>', 'GPX serializes lines correctly');
}
function test_Format_GPX_serialize_multiline(t) {
t.plan(1);
@@ -90,7 +90,7 @@
var multiline = new OpenLayers.Geometry.MultiLineString([line, line2]);
var f = new OpenLayers.Feature.Vector(multiline, {name: 'foo', description: 'bar'});
var data = parser.write([f]);
t.xml_eq(data, '<?xml version="1.0" encoding="ISO-8859-1"?><gpx xmlns="http://www.topografix.com/GPX/1/1"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon="-111.04" lat="45.68"/><trkpt lon="-112.04" lat="45.68"/></trkseg><trkseg><trkpt lon="1" lat="2"/><trkpt lon="3" lat="4"/></trkseg></trk></gpx>', 'GPX serializes multiline correctly');
t.xml_eq(data, '<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="OpenLayers" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon="-111.04" lat="45.68"/><trkpt lon="-112.04" lat="45.68"/></trkseg><trkseg><trkpt lon="1" lat="2"/><trkpt lon="3" lat="4"/></trkseg></trk></gpx>', 'GPX serializes multiline correctly');
}
function test_Format_GPX_serialize_polygon(t) {
t.plan(1);
@@ -103,7 +103,7 @@
var polygon = new OpenLayers.Geometry.Polygon([linearRing]);
var f = new OpenLayers.Feature.Vector(polygon, {name: 'foo', description: 'bar'});
var data = parser.write([f]);
t.xml_eq(data, '<?xml version="1.0" encoding="ISO-8859-1"?><gpx xmlns="http://www.topografix.com/GPX/1/1"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon="-111.04" lat="45.68"/><trkpt lon="-112.04" lat="45.68"/><trkpt lon="-111.04" lat="45.68"/></trkseg></trk></gpx>', 'GPX serializes polygon correctly');
t.xml_eq(data, '<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="OpenLayers" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon="-111.04" lat="45.68"/><trkpt lon="-112.04" lat="45.68"/><trkpt lon="-111.04" lat="45.68"/></trkseg></trk></gpx>', 'GPX serializes polygon correctly');
}
function test_Format_GPX_serialize_metadata(t) {
t.plan(1);
@@ -111,7 +111,7 @@
var parser = new OpenLayers.Format.GPX();
var data = parser.write([], {name: 'foo', desc: 'bar'});
t.xml_eq(data, '<?xml version="1.0" encoding="ISO-8859-1"?><gpx xmlns="http://www.topografix.com/GPX/1/1"><metadata><name>foo</name><desc>bar</desc></metadata></gpx>', 'GPX serializes metadata correctly');
t.xml_eq(data, '<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="OpenLayers" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><metadata><name>foo</name><desc>bar</desc></metadata></gpx>', 'GPX serializes metadata correctly');
}
</script>
</head>

View File

@@ -177,7 +177,7 @@
t.eq(text.label, "A ${FOO} label", "(AAA161) first rule has proper text label");
t.eq(layer.userStyles[0].propertyStyles["label"], true, "label added to propertyStyles");
t.eq(text.fontFamily, "Arial", "(AAA161) first rule has proper font family");
t.eq(text.fillColor, "#000000", "(AAA161) first rule has proper text fill");
t.eq(text.fontColor, "#000000", "(AAA161) first rule has proper text fill");
t.eq(text.haloRadius, "3", "(AAA161) first rule has proper halo radius");
t.eq(text.haloColor, "#ffffff", "(AAA161) first rule has proper halo color");
@@ -347,7 +347,7 @@
"label": "This is the ${city} in ${state}.",
"fontFamily": "Arial",
"fontSize": 10,
"fillColor": "blue",
"fontColor": "blue",
"fontWeight": "bold",
"fontStyle": "normal",
"haloRadius": 2,

View File

@@ -0,0 +1,114 @@
<html>
<head>
<script src="../../OLLoader.js"></script>
<script type="text/javascript">
var xml = new OpenLayers.Format.XML();
function readXML(id) {
return xml.read(document.getElementById(id).firstChild.nodeValue);
}
function test_VendorExtensions(t) {
var cases = [
"poly_label.sld"
];
var len = cases.length;
t.plan(len);
var format = new OpenLayers.Format.SLD({
profile: "GeoServer",
multipleSymbolizers: true,
namedLayersAsArray: true,
schemaLocation: "http://www.opengis.net/sld StyledLayerDescriptor.xsd"
});
var c, doc, data, out;
for (var i=0; i<len; ++i) {
c = cases[i];
doc = readXML(c);
data = format.read(doc);
out = format.write(data);
t.xml_eq(out, doc.documentElement, "round-tripped " + c);
}
}
</script>
</head>
<body>
<div id="poly_label.sld"><!--
<StyledLayerDescriptor version="1.0.0"
xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd"
xmlns="http://www.opengis.net/sld"
xmlns:ogc="http://www.opengis.net/ogc"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<NamedLayer>
<Name>Polygon with styled label</Name>
<UserStyle>
<Title>SLD Cook Book: Polygon with styled label</Title>
<FeatureTypeStyle>
<Rule>
<PolygonSymbolizer>
<Fill>
<CssParameter name="fill">#40FF40</CssParameter>
</Fill>
<Stroke>
<CssParameter name="stroke">#FFFFFF</CssParameter>
<CssParameter name="stroke-width">2</CssParameter>
</Stroke>
</PolygonSymbolizer>
<TextSymbolizer>
<Label>
<ogc:PropertyName>name</ogc:PropertyName>
</Label>
<Font>
<CssParameter name="font-family">Arial</CssParameter>
<CssParameter name="font-size">11</CssParameter>
<CssParameter name="font-weight">bold</CssParameter>
<CssParameter name="font-style">normal</CssParameter>
</Font>
<Fill>
<CssParameter name="fill">#000000</CssParameter>
<CssParameter name="fill-opacity">0.5</CssParameter>
</Fill>
<Graphic>
<Mark>
<WellKnownName>square</WellKnownName>
<Fill>
<CssParameter name="fill">#59BF34</CssParameter>
<CssParameter name="fill-opacity">0.8</CssParameter>
</Fill>
<Stroke>
<CssParameter name="stroke">#2D6917</CssParameter>
</Stroke>
</Mark>
<Size>24</Size>
</Graphic>
<Priority>
<ogc:PropertyName>population</ogc:PropertyName>
</Priority>
<VendorOption name="autoWrap">60</VendorOption>
<VendorOption name="followLine">true</VendorOption>
<VendorOption name="repeat">300</VendorOption>
<VendorOption name="maxDisplacement">150</VendorOption>
<VendorOption name="forceLeftToRight">false</VendorOption>
<VendorOption name="graphic-margin">3</VendorOption>
<VendorOption name="graphic-resize">stretch</VendorOption>
<VendorOption name="group">yes</VendorOption>
<VendorOption name="spaceAround">10</VendorOption>
<VendorOption name="labelAllGroup">true</VendorOption>
<VendorOption name="maxAngleDelta">15</VendorOption>
<VendorOption name="conflictResolution">false</VendorOption>
<VendorOption name="goodnessOfFit">0.3</VendorOption>
<VendorOption name="polygonAlign">mbr</VendorOption>
</TextSymbolizer>
</Rule>
</FeatureTypeStyle>
</UserStyle>
</NamedLayer>
</StyledLayerDescriptor>
--></div>
</body>
</html>

View File

@@ -268,10 +268,10 @@
map.destroy();
map = new OpenLayers.Map("map");
layer = new OpenLayers.Layer("test", {projection: "EPSG:4326"});
layer = new OpenLayers.Layer("test", {projection: "unknown"});
map.addLayer(layer);
t.eq(layer.alwaysInRange, true,
"alwaysInRange true if only get projection.");
"alwaysInRange true if unknown projection is set.");
map.destroy();
map = new OpenLayers.Map("map");

View File

@@ -4,6 +4,9 @@
<script type="text/javascript">window.alert = oldAlert;</script>
<script src="../OLLoader.js"></script>
<script type="text/javascript">
// turn off animation frame handling, so we can check img urls in tests
delete OpenLayers.Layer.Grid.prototype.queueTileDraw;
var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
var layer;

View File

@@ -2,6 +2,10 @@
<head>
<script src="../OLLoader.js"></script>
<script type="text/javascript">
// turn off animation frame handling, so we can check img urls in tests
var origQueueTileDraw = OpenLayers.Layer.Grid.prototype.queueTileDraw;
delete OpenLayers.Layer.Grid.prototype.queueTileDraw;
var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
var layer;
@@ -68,6 +72,26 @@
map.destroy();
}
function test_queueTileDraw(t) {
t.plan(3);
OpenLayers.Layer.Grid.prototype.queueTileDraw = origQueueTileDraw;
var map = new OpenLayers.Map('map');
layer = new OpenLayers.Layer.WMS(name, url, params);
map.addLayer(layer);
map.setCenter([0, 0], 3);
var queued = layer.tileQueue.length;
t.ok(layer.tileQueue.length, "Tiles queued for drawing");
map.zoomIn();
t.eq(layer.tileQueue.length, queued, "Tile queue has same length after immediate zoom change");
t.delay_call(1, function() {
t.eq(layer.tileQueue.length, 0, "Tiles from queue processed");
});
map.destroy();
delete OpenLayers.Layer.Grid.prototype.queueTileDraw;
}
function test_Layer_Grid_clearTiles (t) {
t.plan(4);
@@ -189,13 +213,35 @@
function test_Layer_Grid_moveTo(t) {
t.plan(14);
t.plan(17);
var origIsNative = OpenLayers.Animation.isNative;
OpenLayers.Animation.isNative = false;
var map = new OpenLayers.Map('map');
layer = new OpenLayers.Layer.WMS(name, url, params);
layer.destroy = function() {}; //we're going to do funky things with the grid
layer.applyBackBuffer = function() {}; // backbuffering isn't under test here
map.addLayer(layer);
map.setCenter([-10, 0], 5);
var log = [];
layer.deferMoveGriddedTiles = function() {
log.push("deferMoveGriddedTiles");
OpenLayers.Layer.WMS.prototype.deferMoveGriddedTiles.apply(this, arguments);
}
layer.moveGriddedTiles = function() {
log.push("moveGriddedTiles");
OpenLayers.Layer.WMS.prototype.moveGriddedTiles.apply(this, arguments);
}
map.moveTo([5, 0]);
t.eq(log[0], "moveGriddedTiles", "deferred after moveTo");
map.moveTo([0, 0]);
t.eq(log[1], "moveGriddedTiles", "deferred again after another moveTo");
t.eq(log.length, 2, "no tiles loaded yet");
t.delay_call(0.1, function() {
t.eq(log[2], "deferMoveGriddedTiles", "tiles moved after tileLoadingDelay");
});
//make sure null bounds doesnt cause script error.
// no test necessary, just action
@@ -204,7 +250,6 @@
layer.moveTo(); //checks to make sure null bounds doesnt break us
//observing globals
layer.initSingleTile = function(bounds) {
g_WhichFunc = "InitSingle";
@@ -214,10 +259,13 @@
g_WhichFunc = "InitGridded";
g_Bounds = bounds;
};
layer._moveGriddedTiles = function() {
layer.moveGriddedTiles = function() {
g_WhichFunc = "MoveGridded";
g_Bounds = layer.map.getExtent();
};
layer.deferMoveGriddedTiles = function() {
g_WhichFunc = "DeferMoveGridded";
}
var clearTestBounds = function() {
g_WhichFunc = null;
g_Bounds = null;
@@ -307,7 +355,7 @@
//gridded
layer.grid = [ [ {} ] ];
layer.grid = [ [ {position: new OpenLayers.Pixel(0,0)} ] ];
layer.singleTile = false;
//regular move
@@ -315,11 +363,8 @@
tilesBounds = new OpenLayers.Bounds(10,10,120,120);
g_WhichFunc = null;
layer.moveTo(null, zoomChanged);
t.eq(g_WhichFunc, null, "moveGriddedTiles is delayed - not called yet");
t.delay_call(0.2, function() {
t.ok(g_WhichFunc == "MoveGridded", "if tiles not drastically out of bounds, we call moveGriddedTile()");
t.eq(g_WhichFunc, "MoveGridded", "if tiles not drastically out of bounds, we call moveGriddedTile()");
t.ok(g_Bounds.equals(b), "if tiles not drastically out of bounds, we call moveGriddedTile() with correct bounds");
});
// drastic pan
clearTestBounds();
@@ -328,6 +373,7 @@
t.ok(g_WhichFunc == "InitGridded", "if tiles drastically out of bounds, we call initGriddedTile()");
t.ok(g_Bounds.equals(b), "if tiles drastically out of bounds, we call initGriddedTile() with correct bounds");
OpenLayers.Animation.isNative = origIsNative;
}
/** THIS WOULD BE WHERE THE TESTS WOULD GO FOR
@@ -459,12 +505,12 @@
}
function test_Layer_Grid_addTileMonitoringHooks(t) {
t.plan(14);
t.plan(15);
layer = new OpenLayers.Layer.Grid();
layer.events = {
'triggerEvent': function(str) {
g_events.push(str);
'triggerEvent': function(str, evt) {
g_events.push([str, evt]);
}
}
@@ -490,7 +536,7 @@
g_events = [];
tile.onLoadStart.apply(layer);
t.eq(g_events[0], "loadstart", "loadstart event triggered when numLoadingTiles is 0");
t.eq(g_events[0][0], "loadstart", "loadstart event triggered when numLoadingTiles is 0");
t.eq(layer.numLoadingTiles, 1, "numLoadingTiles incremented");
g_events = [];
@@ -507,7 +553,8 @@
layer.numLoadingTiles = 2;
g_events = [];
tile.onLoadEnd.apply(layer);
t.eq(g_events[0], "tileloaded", "tileloaded triggered when numLoadingTiles is > 0");
t.eq(g_events[0][0], "tileloaded", "tileloaded triggered when numLoadingTiles is > 0");
t.ok(g_events[0][1].tile === tile, "tile passed as tile property to event object");
t.eq(g_events.length, 1, "loadend event not triggered when numLoadingTiles is > 0");
t.eq(layer.numLoadingTiles, 1, "numLoadingTiles decremented");
@@ -515,8 +562,8 @@
g_events = [];
layer.grid = [[{}]]; // to prevent error in updateBackBuffer
tile.onLoadEnd.apply(layer);
t.eq(g_events[0], "tileloaded", "tileloaded triggered when numLoadingTiles is 0");
t.eq(g_events[1], "loadend", "loadend event triggered when numLoadingTiles is 0");
t.eq(g_events[0][0], "tileloaded", "tileloaded triggered when numLoadingTiles is 0");
t.eq(g_events[1][0], "loadend", "loadend event triggered when numLoadingTiles is 0");
t.eq(layer.numLoadingTiles, 0, "numLoadingTiles decremented");
}

View File

@@ -6,6 +6,9 @@
<script src="../OLLoader.js"></script>
<script type="text/javascript">
// turn off animation frame handling, so we can check img urls in tests
delete OpenLayers.Layer.Grid.prototype.queueTileDraw;
var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
var layer;

View File

@@ -178,7 +178,7 @@
var map = new OpenLayers.Map({
div: "map",
maxResolution: OpenLayers.Map.prototype.maxResolution / Math.pow(2, offset)
maxResolution: OpenLayers.Projection.defaults["EPSG:4326"].maxResolution / Math.pow(2, offset)
});
var layer = new OpenLayers.Layer.TMS("TMS", "", {
layername: "basic",
@@ -200,7 +200,7 @@
var map = new OpenLayers.Map({
div: "map",
maxResolution: OpenLayers.Map.prototype.maxResolution / Math.pow(2, offset)
maxResolution: OpenLayers.Projection.defaults["EPSG:4326"].maxResolution / Math.pow(2, offset)
});
var layer = new OpenLayers.Layer.TMS("TMS", "", {
layername: "basic",

View File

@@ -5,6 +5,9 @@
<script type="text/javascript">window.alert = oldAlert;</script>
<script src="../OLLoader.js"></script>
<script type="text/javascript">
// turn off animation frame handling, so we can check img urls in tests
delete OpenLayers.Layer.Grid.prototype.queueTileDraw;
var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
var layer;
@@ -385,6 +388,7 @@
var map = new OpenLayers.Map({
div: "map",
maxExtent: new OpenLayers.Bounds(-185, -95, 185, 95),
maxResolution: 1.40625,
layers: [dummy, unconstrained, constrained],
center: new OpenLayers.LonLat(0, 0),
zoom: 1

View File

@@ -137,6 +137,7 @@
style: "blue_marble",
matrixSet: "arcgis_online",
tileSize: new OpenLayers.Size(512, 512),
maxResolution: 1.40625,
requestEncoding: "REST"
});
map.addLayer(layer1);
@@ -157,6 +158,7 @@
style: "blue_marble",
matrixSet: "arcgis_online",
tileSize: new OpenLayers.Size(512, 512),
maxResolution: 1.40625,
requestEncoding: "REST"
});
map.addLayer(layer1);

View File

@@ -2,6 +2,9 @@
<head>
<script src="../OLLoader.js"></script>
<script type="text/javascript">
// turn off animation frame handling, so we can check img urls in tests
delete OpenLayers.Layer.Grid.prototype.queueTileDraw;
var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
var layer;
@@ -127,7 +130,7 @@
}
function test_Layer_WrapDateLine_WMS (t) {
t.plan( 3 );
t.plan( 4 );
var url = "http://octo.metacarta.com/cgi-bin/mapserv";
layer = new OpenLayers.Layer.WMS(name, url, params, {'wrapDateLine':true,encodeBBOX:true, buffer: 2});
@@ -135,13 +138,14 @@
m.addLayer(layer);
m.zoomToMaxExtent();
t.eq(layer.grid[3][0].url, "http://octo.metacarta.com/cgi-bin/mapserv?MAP=%2Fmapdata%2Fvmap_wms.map&LAYERS=basic&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=0%2C-90%2C180%2C90&WIDTH=256&HEIGHT=256", "cell [3][0] is wrapped around the world.");
t.eq(layer.grid[0][0].url, "http://octo.metacarta.com/cgi-bin/mapserv?MAP=%2Fmapdata%2Fvmap_wms.map&LAYERS=basic&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=0%2C450%2C180%2C630&WIDTH=256&HEIGHT=256", "cell [0][0] is wrapped around the world lon, but not lat");
t.eq(layer.grid[0][3].url, "http://octo.metacarta.com/cgi-bin/mapserv?MAP=%2Fmapdata%2Fvmap_wms.map&LAYERS=basic&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=-180%2C450%2C0%2C630&WIDTH=256&HEIGHT=256", "cell [3][0] is not wrapped at all.");
t.eq(layer.grid[3][1].url, "http://octo.metacarta.com/cgi-bin/mapserv?MAP=%2Fmapdata%2Fvmap_wms.map&LAYERS=basic&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=-180%2C-90%2C0%2C90&WIDTH=256&HEIGHT=256", "cell [3][1] is wrapped around the world.");
t.eq(layer.grid[3][2].url, "http://octo.metacarta.com/cgi-bin/mapserv?MAP=%2Fmapdata%2Fvmap_wms.map&LAYERS=basic&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=0%2C-90%2C180%2C90&WIDTH=256&HEIGHT=256", "cell [3][2] is not wrapped at all.");
t.ok(layer.grid[0][2].url == null, "no latitudinal wrapping - tile not loaded if outside maxExtent");
m.destroy();
}
function test_Layer_WrapDateLine_KaMap (t) {
t.plan( 3 );
t.plan( 4 );
var layer = new OpenLayers.Layer.KaMap( "Blue Marble NG",
"http://www.openlayers.org/world/index.php",
@@ -150,13 +154,14 @@
var m = new OpenLayers.Map('map', {adjustZoom: function(z) {return z;}});
m.addLayer(layer);
m.zoomToMaxExtent();
t.eq(layer.grid[0][0].url, "http://www.openlayers.org/world/index.php?g=satellite&map=world&i=jpeg&t=-1280&l=0&s=221471921.25", "grid[0][0] kamap is okay");
t.eq(layer.grid[0][3].url, "http://www.openlayers.org/world/index.php?g=satellite&map=world&i=jpeg&t=-1280&l=-256&s=221471921.25", "grid[0][3] kamap is okay");
t.eq(layer.grid[3][0].url, "http://www.openlayers.org/world/index.php?g=satellite&map=world&i=jpeg&t=-512&l=0&s=221471921.25", "grid[3][0] is okay");
t.eq(layer.grid[5][7].url, "http://www.openlayers.org/world/index.php?g=satellite&map=world&i=jpeg&t=0&l=-256&s=221471921.25", "grid[5][7] kamap is okay");
t.eq(layer.grid[5][6].url, "http://www.openlayers.org/world/index.php?g=satellite&map=world&i=jpeg&t=0&l=0&s=221471921.25", "grid[5][6] kamap is okay");
t.eq(layer.grid[5][5].url, "http://www.openlayers.org/world/index.php?g=satellite&map=world&i=jpeg&t=0&l=-256&s=221471921.25", "grid[5][5] is okay");
t.ok(layer.grid[7][6].url == null, "no latitudinal wrapping - tile not loaded if outside maxExtent");
m.destroy();
}
function test_Layer_WrapDateLine_WMS_Overlay (t) {
t.plan( 3 );
t.plan( 4 );
var url = "http://octo.metacarta.com/cgi-bin/mapserv";
baselayer = new OpenLayers.Layer.WMS(name, url, params, {'wrapDateLine':true, buffer: 2});
var layer = new OpenLayers.Layer.WMS( "DM Solutions Demo",
@@ -168,9 +173,10 @@
var m = new OpenLayers.Map('map', {adjustZoom: function(z) {return z;}});
m.addLayers([baselayer,layer]);
m.zoomToMaxExtent();
t.eq(layer.grid[0][0].url, "http://www2.dmsolutions.ca/cgi-bin/mswms_gmap?LAYERS=bathymetry%2Cland_fn%2Cpark%2Cdrain_fn%2Cdrainage%2Cprov_bound%2Cfedlimit%2Crail%2Croad%2Cpopplace&TRANSPARENT=true&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=0%2C450%2C180%2C630&WIDTH=256&HEIGHT=256", "grid[0][0] wms overlay is okay");
t.eq(layer.grid[0][3].url, "http://www2.dmsolutions.ca/cgi-bin/mswms_gmap?LAYERS=bathymetry%2Cland_fn%2Cpark%2Cdrain_fn%2Cdrainage%2Cprov_bound%2Cfedlimit%2Crail%2Croad%2Cpopplace&TRANSPARENT=true&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=-180%2C450%2C0%2C630&WIDTH=256&HEIGHT=256", "grid[0][3] wms overlay is okay");
t.eq(layer.grid[3][0].url, "http://www2.dmsolutions.ca/cgi-bin/mswms_gmap?LAYERS=bathymetry%2Cland_fn%2Cpark%2Cdrain_fn%2Cdrainage%2Cprov_bound%2Cfedlimit%2Crail%2Croad%2Cpopplace&TRANSPARENT=true&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=0%2C-90%2C180%2C90&WIDTH=256&HEIGHT=256", "grid[3][0] wms overlay okay");
t.eq(layer.grid[3][0].url, "http://www2.dmsolutions.ca/cgi-bin/mswms_gmap?LAYERS=bathymetry%2Cland_fn%2Cpark%2Cdrain_fn%2Cdrainage%2Cprov_bound%2Cfedlimit%2Crail%2Croad%2Cpopplace&TRANSPARENT=true&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=0%2C-90%2C180%2C90&WIDTH=256&HEIGHT=256", "grid[0][0] wms overlay is okay");
t.eq(layer.grid[3][1].url, "http://www2.dmsolutions.ca/cgi-bin/mswms_gmap?LAYERS=bathymetry%2Cland_fn%2Cpark%2Cdrain_fn%2Cdrainage%2Cprov_bound%2Cfedlimit%2Crail%2Croad%2Cpopplace&TRANSPARENT=true&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=-180%2C-90%2C0%2C90&WIDTH=256&HEIGHT=256", "grid[0][3] wms overlay is okay");
t.eq(layer.grid[3][2].url, "http://www2.dmsolutions.ca/cgi-bin/mswms_gmap?LAYERS=bathymetry%2Cland_fn%2Cpark%2Cdrain_fn%2Cdrainage%2Cprov_bound%2Cfedlimit%2Crail%2Croad%2Cpopplace&TRANSPARENT=true&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=0%2C-90%2C180%2C90&WIDTH=256&HEIGHT=256", "grid[3][0] wms overlay okay");
t.ok(layer.grid[0][2].url == null, "no latitudinal wrapping - tile not loaded if outside maxExtent");
m.destroy();
}

View File

@@ -195,7 +195,7 @@
var map = new OpenLayers.Map({
div: "map",
maxResolution: OpenLayers.Map.prototype.maxResolution / Math.pow(2, offset)
maxResolution: 1.40625 / Math.pow(2, offset)
});
var layer = new OpenLayers.Layer.XYZ(name, url, {zoomOffset: offset});
map.addLayer(layer);
@@ -211,7 +211,7 @@
var map = new OpenLayers.Map({
div: "map",
maxResolution: OpenLayers.Map.prototype.maxResolution / Math.pow(2, offset)
maxResolution: 1.40625 / Math.pow(2, offset)
});
var layer = new OpenLayers.Layer.XYZ(name, url, {zoomOffset: offset});
map.addLayer(layer);

View File

@@ -302,7 +302,7 @@
function test_fromWMSLayer(t) {
t.plan(9);
var map = new OpenLayers.Map("map", {
projection: "EPSG:1234"
projection: "CRS:84"
});
var layer = new OpenLayers.Layer.WMS("foo", "htttp://foo/ows",
{layers: "topp:states"}
@@ -312,7 +312,7 @@
t.eq(protocol.url, "htttp://foo/ows", "url taken from wms layer");
t.eq(protocol.featurePrefix, "topp", "feature prefix correctly extracted");
t.eq(protocol.featureType, "states", "typeName correctly extracted");
t.eq(protocol.srsName, "EPSG:1234", "srsName set correctly");
t.eq(protocol.srsName, "CRS:84", "srsName set correctly");
t.eq(protocol.version, "1.1.0", "version set correctly");
t.eq(protocol.format.geometryName, null, "format's geometryName set to null");

View File

@@ -33,7 +33,7 @@
}
function test_update(t) {
t.plan(5);
t.plan(7);
// Create a dummy layer that can act as the map base layer.
// This will be unnecessary if #1921 is addressed (allowing
@@ -43,9 +43,10 @@
var strategy = new OpenLayers.Strategy.BBOX({
ratio: 1 // makes for easier comparison to map bounds
});
var log = [];
var layer = new OpenLayers.Layer.Vector(null, {
isBaseLayer: true,
protocol: new OpenLayers.Protocol(),
protocol: new OpenLayers.Protocol({abort: function(response) { log.push(response); }}),
strategies: [strategy]
});
@@ -61,6 +62,13 @@
* should be removed when the issue(s) described in #1835 are addressed.
*/
strategy.update({force: true});
strategy.response = {};
strategy.update({force: true});
t.eq(log.length, 1, "Response aborted");
log = [];
strategy.update({force: true});
strategy.update({force: true, noAbort: true});
t.eq(log.length, 0, "Response not aborted when noAbort is true");
// test that the strategy bounds were set
t.ok(map.getExtent().equals(strategy.bounds), "[set center] bounds set to map extent");

View File

@@ -60,6 +60,39 @@
}
function test_Tile_draw(t) {
t.plan(6);
setUp();
var position = new OpenLayers.Pixel(10,20);
var bounds = new OpenLayers.Bounds(1,2,3,4);
var url = "bobob";
var size = new OpenLayers.Size(5,6);
tile = new OpenLayers.Tile(layer, position, bounds, url, size);
var log = [];
tile.clear = function() {
log.push("clear");
}
tile.draw();
t.eq(log.length, 1, "Tile cleared before drawing");
log = [];
tile.events.register("beforedraw", this, function() {
log.push("beforedraw");
return false;
});
var drawn = tile.draw();
t.eq(log[0], "clear", "tile cleared");
t.eq(log[1], "beforedraw", "beforedraw event fired");
t.eq(drawn, false, "tile not drawn when beforedraw listener returns false");
drawn = tile.draw(true);
t.eq(log.length, 2, "no beforedraw event fired and tile not cleared when draw called with 'deferred' argument set to true");
t.eq(drawn, true, "tile drawn when draw called with 'deferred' argument set to true");
tearDown();
}
function test_Tile_destroy(t) {
t.plan( 6 );

View File

@@ -2,6 +2,9 @@
<head>
<script src="../OLLoader.js"></script>
<script type="text/javascript">
// turn off animation frame handling, so we can check img urls in tests
delete OpenLayers.Layer.Grid.prototype.queueTileDraw;
var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
var tile;
@@ -400,6 +403,31 @@
});
}
function test_getCanvasContext(t) {
if (!OpenLayers.CANVAS_SUPPORTED) {
t.plan(0);
} else {
t.plan(1);
var map = new OpenLayers.Map('map');
var layer = new OpenLayers.Layer.WMS("OpenLayers WMS",
"http://labs.metacarta.com/wms/vmap0?", {layers: 'basic'});
map.addLayer(layer);
map.setCenter(new OpenLayers.LonLat(0, 0), 5);
t.delay_call(5, function() {
var tile = layer.grid[0][0];
if (tile.isLoading) {
t.ok(false, "test_getCanvasContext timeout");
} else {
t.ok(tile.getCanvasContext() instanceof CanvasRenderingContext2D,
"getCanvasContext() returns CanvasRenderingContext2D instance");
}
map.destroy();
});
}
}
</script>
</head>
<body>

View File

@@ -2,6 +2,9 @@
<head>
<script src="../../OLLoader.js"></script>
<script type="text/javascript">
// turn off animation frame handling, so we can check img urls in tests
delete OpenLayers.Layer.Grid.prototype.queueTileDraw;
var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
var isOpera = (navigator.userAgent.indexOf("Opera") != -1);
var isIE = (navigator.userAgent.indexOf("MSIE") != -1);

View File

@@ -5,6 +5,9 @@
<script src="../../../../lib/deprecated.js"></script>
<script type="text/javascript">
// turn off animation frame handling, so we can check img urls in tests
delete OpenLayers.Layer.Grid.prototype.queueTileDraw;
var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
var layer;

View File

@@ -73,6 +73,7 @@
<li>Format/Text.html</li>
<li>Format/SLD.html</li>
<li>Format/SLD/v1_0_0.html</li>
<li>Format/SLD/v1_0_0_GeoServer.html</li>
<li>Format/Filter.html</li>
<li>Format/Filter/v1.html</li>
<li>Format/Filter/v1_0_0.html</li>

View File

@@ -43,7 +43,7 @@ import sys
SUFFIX_JAVASCRIPT = ".js"
RE_REQUIRE = "@requires?:? (.*)\n" # TODO: Ensure in comment?
RE_REQUIRE = "@requires?:?\s+(\S*)\s*\n" # TODO: Ensure in comment?
class MissingImport(Exception):
"""Exception raised when a listed import is not found in the lib."""