merge with trunk

This commit is contained in:
Bart van den Eijnden
2012-02-28 13:31:14 +01:00
119 changed files with 2543 additions and 855 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: Tween (no auto-title, OpenLayers/Tween.js)
File: Util (no auto-title, OpenLayers/Util.js) File: Util (no auto-title, OpenLayers/Util.js)
File: Spherical (no auto-title, OpenLayers/Spherical.js)
File: Deprecated (no auto-title, deprecated.js) File: Deprecated (no auto-title, deprecated.js)
} # Group: OpenLayers } # Group: OpenLayers

View File

@@ -0,0 +1,69 @@
<!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>Accessible Custom Click Control</title>
<link rel="stylesheet" href="../theme/default/style.css" type="text/css">
<link rel="stylesheet" href="style.css" type="text/css">
<style type="text/css">
<style type="text/css">
a {
text-decoration: none;
font-size: 1.2em;
}
a em {
font-style: normal;
font-weight: normal;
text-decoration: underline;
}
a:hover {
text-decoration: underline;
}
a.api {
font-size:1em;
text-decoration:underline;
}
a.accesskey {
color: white;
}
a.accesskey:focus {
color: #436976;
}
a.zoom {
padding-right: 20px;
}
</style>
<script src="../lib/Firebug/firebug.js"></script>
<script src="../lib/OpenLayers.js"></script>
<script src="accessible-click-control.js"></script>
</head>
<body onload="init()">
<h1 id="title">An accessible click control implementation</h1>
<div id="tags">
click, control, accessibility
</div>
<a class="accesskey"
href=""
accesskey="1"
onclick="document.getElementById('map').focus();return false;">
Jump to map
</a>
<div id="map" class="smallmap" tabindex="0"></div>
<p id="desc">
Demonstrate the KeyboardDefaults control as well as a control that
allows clicking on the map using the keyboard.
First focus the map (using tab key or mouse), then press the 'i'
key to activate the query control. You can then move the point
using arrow keys. Press 'RETURN' to get the coordinate. Press 'i'
again to deactivate the control.
</p>
</body>
</html>

View File

@@ -0,0 +1,199 @@
var map, navigationControl, queryControl;
function init(){
map = new OpenLayers.Map('map', {controls: []});
var layer = new OpenLayers.Layer.WMS(
"OpenLayers WMS",
"http://vmap0.tiles.osgeo.org/wms/vmap0",
{layers: 'basic'}
);
map.addLayers([layer]);
navigationControl = new OpenLayers.Control.KeyboardDefaults({
observeElement: 'map'
});
map.addControl(navigationControl);
queryControl = new OpenLayers.Control.KeyboardClick({
observeElement: 'map'
});
map.addControl(queryControl);
map.zoomToMaxExtent();
}
/**
* Class: OpenLayers.Control.KeyboardClick
*
* A custom control that (a) adds a vector point that can be moved using the
* arrow keys of the keyboard, and (b) displays a browser alert window when the
* RETURN key is pressed. The control can be activated/deactivated using the
* "i" key. When activated the control deactivates any KeyboardDefaults control
* in the map so that the map is not moved when the arrow keys are pressed.
*
* This control relies on the OpenLayers.Handler.KeyboardPoint custom handler.
*/
OpenLayers.Control.KeyboardClick = OpenLayers.Class(OpenLayers.Control, {
initialize: function(options) {
OpenLayers.Control.prototype.initialize.apply(this, [options]);
var observeElement = this.observeElement || document;
this.handler = new OpenLayers.Handler.KeyboardPoint(this, {
done: this.onClick,
cancel: this.deactivate
}, {
observeElement: observeElement
});
OpenLayers.Event.observe(
observeElement,
"keydown",
OpenLayers.Function.bindAsEventListener(
function(evt) {
if (evt.keyCode == 73) { // "i"
if (this.active) {
this.deactivate();
} else {
this.activate();
}
}
},
this
)
);
},
onClick: function(geometry) {
alert("You clicked near " + geometry.x + " N, " +
geometry.y + " E");
},
activate: function() {
if(!OpenLayers.Control.prototype.activate.apply(this, arguments)) {
return false;
}
// deactivate any KeyboardDefaults control
var keyboardDefaults = this.map.getControlsByClass(
'OpenLayers.Control.KeyboardDefaults')[0];
if (keyboardDefaults) {
keyboardDefaults.deactivate();
}
return true;
},
deactivate: function() {
if(!OpenLayers.Control.prototype.deactivate.apply(this, arguments)) {
return false;
}
// reactivate any KeyboardDefaults control
var keyboardDefaults = this.map.getControlsByClass(
'OpenLayers.Control.KeyboardDefaults')[0];
if (keyboardDefaults) {
keyboardDefaults.activate();
}
return true;
}
});
/**
* Class: OpenLayers.Handler.KeyboardPoint
*
* A custom handler that displays a vector point that can be moved
* using the arrow keys of the keyboard.
*/
OpenLayers.Handler.KeyboardPoint = OpenLayers.Class(OpenLayers.Handler, {
KEY_EVENTS: ["keydown"],
initialize: function(control, callbacks, options) {
OpenLayers.Handler.prototype.initialize.apply(this, arguments);
// cache the bound event listener method so it can be unobserved later
this.eventListener = OpenLayers.Function.bindAsEventListener(
this.handleKeyEvent, this
);
},
activate: function() {
if(!OpenLayers.Handler.prototype.activate.apply(this, arguments)) {
return false;
}
this.layer = new OpenLayers.Layer.Vector(this.CLASS_NAME);
this.map.addLayer(this.layer);
this.observeElement = this.observeElement || document;
for (var i=0, len=this.KEY_EVENTS.length; i<len; i++) {
OpenLayers.Event.observe(
this.observeElement, this.KEY_EVENTS[i], this.eventListener);
}
if(!this.point) {
this.createFeature();
}
return true;
},
deactivate: function() {
if (!OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {
return false;
}
for (var i=0, len=this.KEY_EVENTS.length; i<len; i++) {
OpenLayers.Event.stopObserving(
this.observeElement, this.KEY_EVENTS[i], this.eventListener);
}
this.map.removeLayer(this.layer);
this.destroyFeature();
return true;
},
handleKeyEvent: function (evt) {
switch(evt.keyCode) {
case OpenLayers.Event.KEY_LEFT:
this.modifyFeature(-3, 0);
break;
case OpenLayers.Event.KEY_RIGHT:
this.modifyFeature(3, 0);
break;
case OpenLayers.Event.KEY_UP:
this.modifyFeature(0, 3);
break;
case OpenLayers.Event.KEY_DOWN:
this.modifyFeature(0, -3);
break;
case OpenLayers.Event.KEY_RETURN:
this.callback('done', [this.point.geometry.clone()]);
break;
case OpenLayers.Event.KEY_ESC:
this.callback('cancel');
break;
}
},
modifyFeature: function(lon, lat) {
if(!this.point) {
this.createFeature();
}
var resolution = this.map.getResolution();
this.point.geometry.x = this.point.geometry.x + lon * resolution;
this.point.geometry.y = this.point.geometry.y + lat * resolution;
this.callback("modify", [this.point.geometry, this.point, false]);
this.point.geometry.clearBounds();
this.drawFeature();
},
createFeature: function() {
var center = this.map.getCenter();
var geometry = new OpenLayers.Geometry.Point(
center.lon, center.lat
);
this.point = new OpenLayers.Feature.Vector(geometry);
this.callback("create", [this.point.geometry, this.point]);
this.point.geometry.clearBounds();
this.layer.addFeatures([this.point], {silent: true});
},
destroyFeature: function() {
this.layer.destroyFeatures([this.point]);
this.point = null;
},
drawFeature: function() {
this.layer.drawFeature(this.point, this.style);
}
});

View File

@@ -31,13 +31,26 @@
font-size:1em; font-size:1em;
text-decoration:underline; text-decoration:underline;
} }
a.accesskey {
color: white;
}
a.accesskey:focus {
color: #436976;
}
a.zoom {
padding-right: 20px;
}
</style> </style>
<script src="../lib/OpenLayers.js"></script> <script src="../lib/OpenLayers.js"></script>
<script type="text/javascript"> <script type="text/javascript">
var map = null; var map = null;
function init(){ function init(){
var options = { var options = {
controls: [new OpenLayers.Control.KeyboardDefaults()] controls: [
new OpenLayers.Control.KeyboardDefaults({
observeElement: 'map'
})
]
}; };
map = new OpenLayers.Map('map', options); map = new OpenLayers.Map('map', options);
var wms = new OpenLayers.Layer.WMS( var wms = new OpenLayers.Layer.WMS(
@@ -57,31 +70,37 @@
keyboard, pan, panning, zoom, zooming, accesskey keyboard, pan, panning, zoom, zooming, accesskey
</div> </div>
<a class="accesskey"
href=""
accesskey="1"
onclick="document.getElementById('map').focus(); return false;">
Go to map
</a>
<p id="shortdesc"> <p id="shortdesc">
Demonstrate how to use the KeyboardDefaults option parameter for layer types. Demonstrate the KeyboardDefaults control and how to use links
with Access Keys to navigate the map with the keyboard.
</p> </p>
<a class="zoom"
href="javascript: void map.zoomIn();"
accesskey="i">
zoom <em>i</em>n</a>
<a class="zoom"
href="javascript: void map.zoomOut();"
accesskey="o">
zoom <em>o</em>ut</a>
<table> <table>
<tbody> <tbody>
<tr> <tr>
<td> <td>&nbsp;</td>
<a href="javascript: void map.zoomOut();"
accesskey="o">
zoom <em>o</em>ut
</a>
</td>
<td> <td>
<a href="javascript: void map.pan(0, -map.getSize().h / 4);" <a href="javascript: void map.pan(0, -map.getSize().h / 4);"
accesskey="n"> accesskey="n">
pan <em>n</em>orth pan <em>n</em>orth
</a> </a>
</td> </td>
<td>
<a href="javascript: void map.zoomIn();"
accesskey="i">
zoom <em>i</em>n
</a>
</td>
</tr> </tr>
<tr> <tr>
<td> <td>
@@ -90,7 +109,7 @@
pan <em>w</em>est pan <em>w</em>est
</a> </a>
</td> </td>
<td id="map" class="smallmap"></td> <td id="map" class="smallmap" tabindex="0"></td>
<td> <td>
<a href="javascript: void map.pan(map.getSize().w / 4, 0);" <a href="javascript: void map.pan(map.getSize().w / 4, 0);"
accesskey="e"> accesskey="e">
@@ -113,9 +132,9 @@
<div id="docs"> <div id="docs">
<p>Navigate the map in one of three ways:</p> <p>Navigate the map in one of three ways:</p>
<ul> <ol>
<li>Click on the named links to zoom and pan</li> <li>Use Access Key "1" (alt + 1) to focus the map element, and
<li>Use following keys to pan and zoom: use following keys to pan and zoom:
<ul> <ul>
<li>+ (zoom in)</li> <li>+ (zoom in)</li>
<li>- (zoom out)</li> <li>- (zoom out)</li>
@@ -124,8 +143,12 @@
<li>left-arrow (pan east)</li> <li>left-arrow (pan east)</li>
<li>right-arrow (pan west)</li> <li>right-arrow (pan west)</li>
</ul> </ul>
See <a href=http://en.wikipedia.org/wiki/Access_key>wikipedia</a> for
more detail about Access Keys.
</li> </li>
<li>If access keys work for links in your browser, use: <li>Navigate to pan and zoom links using the "tab" key, and
press "enter" to pan and zoom</li>
<li>If Access Keys work for links in your browser, use:
<ul> <ul>
<li>i (zoom in)</li> <li>i (zoom in)</li>
<li>o (zoom out)</li> <li>o (zoom out)</li>
@@ -135,7 +158,7 @@
<li>w (pan west)</li> <li>w (pan west)</li>
</ul> </ul>
</li> </li>
</ul> </ol>
<p> <p>
This is an example of using alternate methods to control panning and zooming. This approach uses map.pan() and map.zoom(). You'll note that to pan, additional math is necessary along with map.size() in order to set the distance to pan. This is an example of using alternate methods to control panning and zooming. This approach uses map.pan() and map.zoom(). You'll note that to pan, additional math is necessary along with map.size() in order to set the distance to pan.

View File

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

View File

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

View File

@@ -33,8 +33,9 @@
var pointLayer = new OpenLayers.Layer.Vector("Point Layer"); var pointLayer = new OpenLayers.Layer.Vector("Point Layer");
var lineLayer = new OpenLayers.Layer.Vector("Line Layer"); var lineLayer = new OpenLayers.Layer.Vector("Line Layer");
var polygonLayer = new OpenLayers.Layer.Vector("Polygon 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.LayerSwitcher());
map.addControl(new OpenLayers.Control.MousePosition()); map.addControl(new OpenLayers.Control.MousePosition());
@@ -44,7 +45,15 @@
line: new OpenLayers.Control.DrawFeature(lineLayer, line: new OpenLayers.Control.DrawFeature(lineLayer,
OpenLayers.Handler.Path), OpenLayers.Handler.Path),
polygon: new OpenLayers.Control.DrawFeature(polygonLayer, 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) { for(var key in drawControls) {
@@ -80,11 +89,11 @@
<h1 id="title">OpenLayers Draw Feature Example</h1> <h1 id="title">OpenLayers Draw Feature Example</h1>
<div id="tags"> <div id="tags">
point, line, linestring, polygon, digitizing, geometry, draw, drag point, line, linestring, polygon, box, digitizing, geometry, draw, drag
</div> </div>
<p id="shortdesc"> <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> </p>
<div id="map" class="smallmap"></div> <div id="map" class="smallmap"></div>
@@ -107,6 +116,10 @@
<input type="radio" name="type" value="polygon" id="polygonToggle" onclick="toggleControl(this);" /> <input type="radio" name="type" value="polygon" id="polygonToggle" onclick="toggleControl(this);" />
<label for="polygonToggle">draw polygon</label> <label for="polygonToggle">draw polygon</label>
</li> </li>
<li>
<input type="radio" name="type" value="box" id="boxToggle" onclick="toggleControl(this);" />
<label for="boxToggle">draw box</label>
</li>
<li> <li>
<input type="checkbox" name="allow-pan" value="allow-pan" id="allowPanCheckbox" checked=true onclick="allowPan(this);" /> <input type="checkbox" name="allow-pan" value="allow-pan" id="allowPanCheckbox" checked=true onclick="allowPan(this);" />
<label for="allowPanCheckbox">allow pan while drawing</label> <label for="allowPanCheckbox">allow pan while drawing</label>
@@ -119,6 +132,8 @@
Double-click to finish drawing.</p> 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 <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> 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 <p>With any drawing control active, paning the map can still be achieved. Drag the map as
usual for that.</p> usual for that.</p>
<p>Hold down the shift key while drawing to activate freehand mode. While drawing lines or polygons <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/style.css" type="text/css">
<link rel="stylesheet" href="../theme/default/google.css" type="text/css"> <link rel="stylesheet" href="../theme/default/google.css" type="text/css">
<link rel="stylesheet" href="style.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="../lib/OpenLayers.js"></script>
<script src="google-v3-alloverlays.js"></script> <script src="google-v3-alloverlays.js"></script>
</head> </head>

View File

@@ -45,7 +45,7 @@
"http://demo.opengeo.org/geoserver/wms", "http://demo.opengeo.org/geoserver/wms",
{layers: 'topp:states'}, {layers: 'topp:states'},
{gutter: 15}); {gutter: 15});
var states = new OpenLayers.Layer.WMS( "Roads (no gutter)", var states = new OpenLayers.Layer.WMS( "States (no gutter)",
"http://demo.opengeo.org/geoserver/wms", "http://demo.opengeo.org/geoserver/wms",
{layers: 'topp:states'}); {layers: 'topp:states'});
map.addLayers([states, states15]); map.addLayers([states, states15]);

View File

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

View File

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

View File

@@ -7,7 +7,7 @@
<meta name="apple-mobile-web-app-capable" content="yes"> <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"> <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/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.css" type="text/css">
<link rel="stylesheet" href="style.mobile-jq.css" type="text/css"> <link rel="stylesheet" href="style.mobile-jq.css" type="text/css">
<script src="../lib/OpenLayers.js?mobile"></script> <script src="../lib/OpenLayers.js?mobile"></script>

View File

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

View File

@@ -9,6 +9,12 @@ html, body, #map {
#title, #tags, #shortdesc { #title, #tags, #shortdesc {
display: none; 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 { div.olControlAttribution {
position: absolute; position: absolute;
font-size: 10px; font-size: 10px;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -4,12 +4,7 @@ function init() {
map = new OpenLayers.Map({ map = new OpenLayers.Map({
div: "map", div: "map",
projection: "EPSG:900913", projection: "EPSG:900913"
units: "m",
maxExtent: new OpenLayers.Bounds(
-20037508.34, -20037508.34, 20037508.34, 20037508.34
),
maxResolution: 156543.0339
}); });
var osm = new OpenLayers.Layer.OSM(); 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); var layerExtent = new OpenLayers.Bounds( -13758743.4295939, 5591455.28887228, -13531302.3472101 , 5757360.4178881);
map = new OpenLayers.Map( 'map', {'restrictedExtent': layerExtent} ); map = new OpenLayers.Map( 'map', {'restrictedExtent': layerExtent} );
layer = new OpenLayers.Layer.XYZ( "ESRI", 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} ); {sphericalMercator: true} );
map.addLayer(layer); map.addLayer(layer);
map.zoomToExtent(map.restrictedExtent); map.zoomToExtent(map.restrictedExtent);
@@ -33,7 +33,7 @@
XYZ, layer, tile XYZ, layer, tile
</div> </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> <div id="map" class="smallmap"></div>

View File

@@ -291,6 +291,11 @@
"OpenLayers/Format/SLD.js", "OpenLayers/Format/SLD.js",
"OpenLayers/Format/SLD/v1.js", "OpenLayers/Format/SLD/v1.js",
"OpenLayers/Format/SLD/v1_0_0.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",
"OpenLayers/Format/OWSCommon/v1_1_0.js",
"OpenLayers/Format/CSWGetDomain.js", "OpenLayers/Format/CSWGetDomain.js",
"OpenLayers/Format/CSWGetDomain/v2_0_2.js", "OpenLayers/Format/CSWGetDomain/v2_0_2.js",
"OpenLayers/Format/CSWGetRecords.js", "OpenLayers/Format/CSWGetRecords.js",
@@ -348,7 +353,8 @@
"OpenLayers/Symbolizer/Text.js", "OpenLayers/Symbolizer/Text.js",
"OpenLayers/Symbolizer/Raster.js", "OpenLayers/Symbolizer/Raster.js",
"OpenLayers/Lang.js", "OpenLayers/Lang.js",
"OpenLayers/Lang/en.js" "OpenLayers/Lang/en.js",
"OpenLayers/Spherical.js"
]; // etc. ]; // etc.
} }

View File

@@ -15,6 +15,16 @@
*/ */
OpenLayers.Animation = (function(window) { 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 * Function: requestFrame
* Schedule a function to be called at the next available animation frame. * Schedule a function to be called at the next available animation frame.
@@ -89,6 +99,7 @@ OpenLayers.Animation = (function(window) {
} }
return { return {
isNative: isNative,
requestFrame: requestFrame, requestFrame: requestFrame,
start: start, start: start,
stop: stop stop: stop

View File

@@ -60,28 +60,6 @@ OpenLayers.String = {
return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
}, },
/**
* APIFunction: camelize
* Camel-case a hyphenated string.
* Ex. "chicken-head" becomes "chickenHead", and
* "-chicken-head" becomes "ChickenHead".
*
* Parameters:
* str - {String} The string to be camelized. The original is not modified.
*
* Returns:
* {String} The string, camelized
*/
camelize: function(str) {
var oStringList = str.split('-');
var camelizedString = oStringList[0];
for (var i=1, len=oStringList.length; i<len; i++) {
var s = oStringList[i];
camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
}
return camelizedString;
},
/** /**
* APIFunction: format * APIFunction: format
* Given a string with tokens in the form ${token}, return a string * Given a string with tokens in the form ${token}, return a string

View File

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

View File

@@ -163,7 +163,7 @@ OpenLayers.Element = {
var value = null; var value = null;
if (element && element.style) { if (element && element.style) {
value = element.style[OpenLayers.String.camelize(style)]; value = element.style[style];
if (!value) { if (!value) {
if (document.defaultView && if (document.defaultView &&
document.defaultView.getComputedStyle) { document.defaultView.getComputedStyle) {
@@ -171,7 +171,7 @@ OpenLayers.Element = {
var css = document.defaultView.getComputedStyle(element, null); var css = document.defaultView.getComputedStyle(element, null);
value = css ? css.getPropertyValue(style) : null; value = css ? css.getPropertyValue(style) : null;
} else if (element.currentStyle) { } else if (element.currentStyle) {
value = element.currentStyle[OpenLayers.String.camelize(style)]; value = element.currentStyle[style];
} }
} }

View File

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

View File

@@ -24,6 +24,14 @@ OpenLayers.Control.Attribution =
*/ */
separator: ", ", 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 * 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, 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 * featureadded - Triggered when a feature is added
*/ */

View File

@@ -23,13 +23,22 @@
OpenLayers.Control.Geolocate = OpenLayers.Class(OpenLayers.Control, { OpenLayers.Control.Geolocate = OpenLayers.Class(OpenLayers.Control, {
/** /**
* Supported event types: * APIProperty: events
* - *locationupdated* Triggered when browser return a new position. Listeners will * {<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 * 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 * native object, as well as a 'point' property which is the location transformed in the
* current map projection. * current map projection.
* - *locationfailed* Triggered when geolocation has failed * locationfailed - Triggered when geolocation has failed
* - *locationuncapable* Triggered when control is activated on a browser * locationuncapable - Triggered when control is activated on a browser
* which doesn't support geolocation * which doesn't support geolocation
*/ */

View File

@@ -170,7 +170,16 @@ OpenLayers.Control.GetFeature = OpenLayers.Class(OpenLayers.Control, {
filterType: OpenLayers.Filter.Spatial.BBOX, 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 * beforefeatureselected - Triggered when <click> is true before a
* feature is selected. The event object has a feature property with * feature is selected. The event object has a feature property with
* the feature about to select * the feature about to select

View File

@@ -34,6 +34,15 @@ OpenLayers.Control.KeyboardDefaults = OpenLayers.Class(OpenLayers.Control, {
*/ */
slideFactor: 75, slideFactor: 75,
/**
* APIProperty: observeElement
* {DOMelement|String} The DOM element to handle keys for. You
* can use the map div here, to have the navigation keys
* work when the map div has the focus. If undefined the
* document is used.
*/
observeElement: null,
/** /**
* Constructor: OpenLayers.Control.KeyboardDefaults * Constructor: OpenLayers.Control.KeyboardDefaults
*/ */
@@ -43,8 +52,11 @@ OpenLayers.Control.KeyboardDefaults = OpenLayers.Class(OpenLayers.Control, {
* Create handler. * Create handler.
*/ */
draw: function() { draw: function() {
this.handler = new OpenLayers.Handler.Keyboard( this, { var observeElement = this.observeElement || document;
"keydown": this.defaultKeyPress }); this.handler = new OpenLayers.Handler.Keyboard( this,
{"keydown": this.defaultKeyPress},
{observeElement: observeElement}
);
}, },
/** /**
@@ -62,7 +74,7 @@ OpenLayers.Control.KeyboardDefaults = OpenLayers.Class(OpenLayers.Control, {
* evt - {Event} * evt - {Event}
*/ */
defaultKeyPress: function (evt) { defaultKeyPress: function (evt) {
var size; var size, handled = true;
switch(evt.keyCode) { switch(evt.keyCode) {
case OpenLayers.Event.KEY_LEFT: case OpenLayers.Event.KEY_LEFT:
this.map.pan(-this.slideFactor, 0); this.map.pan(-this.slideFactor, 0);
@@ -106,6 +118,13 @@ OpenLayers.Control.KeyboardDefaults = OpenLayers.Class(OpenLayers.Control, {
case 95: // -/_ (some ASCII) case 95: // -/_ (some ASCII)
this.map.zoomOut(); this.map.zoomOut();
break; break;
default:
handled = false;
}
if (handled) {
// prevent browser default not to move the page
// when moving the page with the keyboard
OpenLayers.Event.stop(evt);
} }
}, },

View File

@@ -197,11 +197,25 @@ OpenLayers.Control.LayerSwitcher =
* evt - {Event} * evt - {Event}
*/ */
onButtonClick: function(evt) { onButtonClick: function(evt) {
if (evt.buttonElement === this.minimizeDiv) { var button = evt.buttonElement;
if (button === this.minimizeDiv) {
this.minimizeControl(); this.minimizeControl();
} else if (evt.buttonElement === this.maximizeDiv) { } else if (button === this.maximizeDiv) {
this.maximizeControl(); 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} * layersType - {String}
*/ */
clearLayersArray: function(layersType) { 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 + "LayersDiv"].innerHTML = "";
this[layersType + "Layers"] = []; this[layersType + "Layers"] = [];
}, },
@@ -320,32 +326,26 @@ OpenLayers.Control.LayerSwitcher =
inputElem.value = layer.name; inputElem.value = layer.name;
inputElem.checked = checked; inputElem.checked = checked;
inputElem.defaultChecked = checked; inputElem.defaultChecked = checked;
inputElem.className = "olButton";
inputElem._layer = layer.id;
inputElem._layerSwitcher = this.id;
if (!baseLayer && !layer.inRange) { if (!baseLayer && !layer.inRange) {
inputElem.disabled = true; 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 // create span
var labelSpan = document.createElement("span"); var labelSpan = document.createElement("label");
OpenLayers.Element.addClass(labelSpan, "labelSpan"); labelSpan["for"] = inputElem.id;
OpenLayers.Element.addClass(labelSpan, "labelSpan olButton");
labelSpan._layer = layer.id;
labelSpan._layerSwitcher = this.id;
if (!baseLayer && !layer.inRange) { if (!baseLayer && !layer.inRange) {
labelSpan.style.color = "gray"; labelSpan.style.color = "gray";
} }
labelSpan.innerHTML = layer.name; labelSpan.innerHTML = layer.name;
labelSpan.style.verticalAlign = (baseLayer) ? "bottom" labelSpan.style.verticalAlign = (baseLayer) ? "bottom"
: "baseline"; : "baseline";
OpenLayers.Event.observe(labelSpan, "click", onInputClick);
OpenLayers.Event.observe(labelSpan, "touchstart", onInputClick);
// create line break // create line break
var br = document.createElement("br"); var br = document.createElement("br");
@@ -376,49 +376,6 @@ OpenLayers.Control.LayerSwitcher =
return this.div; 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 * Method: updateMap
* Cycles through the loaded data and base layer input arrays and makes * 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, { 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: * Register a listener for a particular event with the following syntax:
* (code) * (code)
* control.events.register(type, obj, listener); * control.events.register(type, obj, listener);
* (end) * (end)
* *
* Listeners will be called with a reference to an event object. The * Supported event types (in addition to those from <OpenLayers.Control.events>):
* properties of this event depends on exactly what happened.
*
* Supported control event types (in addition to those from <OpenLayers.Control>):
* measure - Triggered when a measurement sketch is complete. Listeners * measure - Triggered when a measurement sketch is complete. Listeners
* will receive an event with measure, units, order, and geometry * will receive an event with measure, units, order, and geometry
* properties. * properties.

View File

@@ -137,6 +137,13 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
*/ */
mode: null, 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 * Property: modified
* {Boolean} The currently selected feature has been 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 // 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) { for(i=0, len=geometry.components.length; i<len-1; ++i) {
var prevVertex = geometry.components[i]; var prevVertex = geometry.components[i];
var nextVertex = geometry.components[i + 1]; var nextVertex = geometry.components[i + 1];

View File

@@ -493,14 +493,14 @@ OpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, {
this.ovmap.zoomToMaxExtent(); this.ovmap.zoomToMaxExtent();
// check extent rectangle border width // check extent rectangle border width
this.wComp = parseInt(OpenLayers.Element.getStyle(this.extentRectangle, this.wComp = parseInt(OpenLayers.Element.getStyle(this.extentRectangle,
'border-left-width')) + 'borderLeftWidth')) +
parseInt(OpenLayers.Element.getStyle(this.extentRectangle, parseInt(OpenLayers.Element.getStyle(this.extentRectangle,
'border-right-width')); 'borderRightWidth'));
this.wComp = (this.wComp) ? this.wComp : 2; this.wComp = (this.wComp) ? this.wComp : 2;
this.hComp = parseInt(OpenLayers.Element.getStyle(this.extentRectangle, this.hComp = parseInt(OpenLayers.Element.getStyle(this.extentRectangle,
'border-top-width')) + 'border-top-width')) +
parseInt(OpenLayers.Element.getStyle(this.extentRectangle, parseInt(OpenLayers.Element.getStyle(this.extentRectangle,
'border-bottom-width')); 'borderBottomWidth'));
this.hComp = (this.hComp) ? this.hComp : 2; this.hComp = (this.hComp) ? this.hComp : 2;
this.handlers.drag = new OpenLayers.Handler.Drag( this.handlers.drag = new OpenLayers.Handler.Drag(

View File

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

View File

@@ -22,12 +22,21 @@
OpenLayers.Control.SelectFeature = OpenLayers.Class(OpenLayers.Control, { OpenLayers.Control.SelectFeature = OpenLayers.Class(OpenLayers.Control, {
/** /**
* Supported event types: * APIProperty: events
* - *beforefeaturehighlighted* Triggered before a feature is highlighted * {<OpenLayers.Events>} Events instance for listeners and triggering
* - *featurehighlighted* Triggered when a feature is highlighted * control specific events.
* - *featureunhighlighted* Triggered when a feature is unhighlighted *
* - *boxselectionstart* Triggered before box selection starts * Register a listener for a particular event with the following syntax:
* - *boxselectionend* Triggered after box selection ends * (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, { 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: * Register a listener for a particular event with the following syntax:
* (code) * (code)
* control.events.register(type, obj, listener); * control.events.register(type, obj, listener);
* (end) * (end)
* *
* Listeners will be called with a reference to an event object. The * Supported event types (in addition to those from <OpenLayers.Control.events>):
* properties of this event depends on exactly what happened.
*
* Supported control event types (in addition to those from <OpenLayers.Control>):
* beforesnap - Triggered before a snap occurs. Listeners receive an * beforesnap - Triggered before a snap occurs. Listeners receive an
* event object with *point*, *x*, *y*, *distance*, *layer*, and * event object with *point*, *x*, *y*, *distance*, *layer*, and
* *snapType* properties. The point property will be original point * *snapType* properties. The point property will be original point

View File

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

View File

@@ -22,31 +22,40 @@
OpenLayers.Control.TransformFeature = OpenLayers.Class(OpenLayers.Control, { OpenLayers.Control.TransformFeature = OpenLayers.Class(OpenLayers.Control, {
/** /**
* Supported event types: * APIProperty: events
* - *beforesetfeature* Triggered before a feature is set for * {<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 * tranformation. The feature will not be set if a listener returns
* false. Listeners receive a *feature* property, with the feature * false. Listeners receive a *feature* property, with the feature
* that will be set for transformation. Listeners are allowed to * that will be set for transformation. Listeners are allowed to
* set the control's *scale*, *ratio* and *rotation* properties, * set the control's *scale*, *ratio* and *rotation* properties,
* which will set the initial scale, ratio and rotation of the * which will set the initial scale, ratio and rotation of the
* feature, like the <setFeature> method's initialParams argument. * 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 * Listeners receive a *feature* property, with the feature that
* is now set for transformation. * 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 * transformed. The feature will not be transformed if a listener
* returns false (but the box still will). Listeners receive one or * returns false (but the box still will). Listeners receive one or
* more of *center*, *scale*, *ratio* and *rotation*. The *center* * more of *center*, *scale*, *ratio* and *rotation*. The *center*
* property is an <OpenLayers.Geometry.Point> object with the new * property is an <OpenLayers.Geometry.Point> object with the new
* center of the transformed feature, the others are Floats with the * center of the transformed feature, the others are Floats with the
* scale, ratio or rotation change since the last transformation. * 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*, * 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 * <OpenLayers.Geometry.Point> object with the new center of the
* transformed feature, the others are Floats with the scale, ratio * transformed feature, the others are Floats with the scale, ratio
* or rotation change of the feature since the last transformation. * 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*. * an event object with the transformed *feature*.
*/ */

View File

@@ -155,7 +155,16 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
hoverRequest: null, 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. * beforegetfeatureinfo - Triggered before the request is sent.
* The event object has an *xy* property with the position of the * The event object has an *xy* property with the position of the
* mouse click or hover event that triggers the request. * mouse click or hover event that triggers the request.

View File

@@ -136,7 +136,16 @@ OpenLayers.Control.WMTSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
hoverRequest: null, 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. * beforegetfeatureinfo - Triggered before each request is sent.
* The event object has an *xy* property with the position of the * The event object has an *xy* property with the position of the
* mouse click or hover event that triggers the request and a *layer* * 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, var propagate = true,
element = OpenLayers.Event.element(evt); element = OpenLayers.Event.element(evt);
if (element && (OpenLayers.Event.isLeftClick(evt) || !~evt.type.indexOf("mouse"))) { 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; element = element.parentNode;
} }
if (OpenLayers.Element.hasClass(element, "olButton")) { if (OpenLayers.Element.hasClass(element, "olButton")) {

View File

@@ -72,6 +72,13 @@ OpenLayers.Format.GPX = OpenLayers.Class(OpenLayers.Format.XML, {
*/ */
schemaLocation: "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 * Constructor: OpenLayers.Format.GPX
* Create a new parser for GPX. * Create a new parser for GPX.
@@ -190,7 +197,7 @@ OpenLayers.Format.GPX = OpenLayers.Class(OpenLayers.Format.XML, {
var attributes = {}; var attributes = {};
var attrNode = node.firstChild, value, name; var attrNode = node.firstChild, value, name;
while(attrNode) { while(attrNode) {
if(attrNode.nodeType == 1) { if(attrNode.nodeType == 1 && attrNode.firstChild) {
value = attrNode.firstChild; value = attrNode.firstChild;
if(value.nodeType == 3 || value.nodeType == 4) { if(value.nodeType == 3 || value.nodeType == 4) {
name = (attrNode.prefix) ? name = (attrNode.prefix) ?
@@ -218,8 +225,9 @@ OpenLayers.Format.GPX = OpenLayers.Class(OpenLayers.Format.XML, {
write: function(features, metadata) { write: function(features, metadata) {
features = OpenLayers.Util.isArray(features) ? features = OpenLayers.Util.isArray(features) ?
features : [features]; features : [features];
var gpx = this.createElementNSPlus("gpx:gpx"); var gpx = this.createElementNS(this.namespaces.gpx, "gpx");
gpx.setAttribute("version", "1.1"); gpx.setAttribute("version", "1.1");
gpx.setAttribute("creator", this.creator);
this.setAttributes(gpx, { this.setAttributes(gpx, {
"xsi:schemaLocation": this.schemaLocation "xsi:schemaLocation": this.schemaLocation
}); });

View File

@@ -23,6 +23,15 @@
*/ */
OpenLayers.Format.SLD = OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC, { 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 * APIProperty: defaultVersion
* {String} Version number to assume if none found. Default is "1.0.0". * {String} Version number to assume if none found. Default is "1.0.0".

View File

@@ -220,6 +220,78 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
); );
} }
}, },
"LabelPlacement": function(node, symbolizer) {
this.readChildNodes(node, symbolizer);
},
"PointPlacement": function(node, symbolizer) {
var config = {};
this.readChildNodes(node, config);
config.labelRotation = config.rotation;
delete config.rotation;
var labelAlign,
x = symbolizer.labelAnchorPointX,
y = symbolizer.labelAnchorPointY;
if (x <= 1/3) {
labelAlign = 'l';
} else if (x > 1/3 && x < 2/3) {
labelAlign = 'c';
} else if (x >= 2/3) {
labelAlign = 'r';
}
if (y <= 1/3) {
labelAlign += 'b';
} else if (y > 1/3 && y < 2/3) {
labelAlign += 'm';
} else if (y >= 2/3) {
labelAlign += 't';
}
config.labelAlign = labelAlign;
OpenLayers.Util.applyDefaults(symbolizer, config);
},
"AnchorPoint": function(node, symbolizer) {
this.readChildNodes(node, symbolizer);
},
"AnchorPointX": function(node, symbolizer) {
var labelAnchorPointX = this.readers.ogc._expression.call(this, node);
// always string, could be empty string
if(labelAnchorPointX) {
symbolizer.labelAnchorPointX = labelAnchorPointX;
}
},
"AnchorPointY": function(node, symbolizer) {
var labelAnchorPointY = this.readers.ogc._expression.call(this, node);
// always string, could be empty string
if(labelAnchorPointY) {
symbolizer.labelAnchorPointY = labelAnchorPointY;
}
},
"Displacement": function(node, symbolizer) {
this.readChildNodes(node, symbolizer);
},
"DisplacementX": function(node, symbolizer) {
var labelXOffset = this.readers.ogc._expression.call(this, node);
// always string, could be empty string
if(labelXOffset) {
symbolizer.labelXOffset = labelXOffset;
}
},
"DisplacementY": function(node, symbolizer) {
var labelYOffset = this.readers.ogc._expression.call(this, node);
// always string, could be empty string
if(labelYOffset) {
symbolizer.labelYOffset = labelYOffset;
}
},
"LinePlacement": function(node, symbolizer) {
this.readChildNodes(node, symbolizer);
},
"PerpendicularOffset": function(node, symbolizer) {
var labelPerpendicularOffset = this.readers.ogc._expression.call(this, node);
// always string, could be empty string
if(labelPerpendicularOffset) {
symbolizer.labelPerpendicularOffset = labelPerpendicularOffset;
}
},
"Label": function(node, symbolizer) { "Label": function(node, symbolizer) {
var value = this.readers.ogc._expression.call(this, node); var value = this.readers.ogc._expression.call(this, node);
if (value) { if (value) {
@@ -338,6 +410,15 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
"CssParameter": function(node, symbolizer) { "CssParameter": function(node, symbolizer) {
var cssProperty = node.getAttribute("name"); var cssProperty = node.getAttribute("name");
var symProperty = this.cssMap[cssProperty]; 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) { if(symProperty) {
// Limited support for parsing of OGC expressions // Limited support for parsing of OGC expressions
var value = this.readers.ogc._expression.call(this, node); var value = this.readers.ogc._expression.call(this, node);
@@ -881,6 +962,16 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
symbolizer.fontStyle != null) { symbolizer.fontStyle != null) {
this.writeNode("Font", symbolizer, node); this.writeNode("Font", symbolizer, node);
} }
// add in optional LabelPlacement
if (symbolizer.labelAnchorPointX != null ||
symbolizer.labelAnchorPointY != null ||
symbolizer.labelAlign != null ||
symbolizer.labelXOffset != null ||
symbolizer.labelYOffset != null ||
symbolizer.labelRotation != null ||
symbolizer.labelPerpendicularOffset != null) {
this.writeNode("LabelPlacement", symbolizer, node);
}
// add in optional Halo // add in optional Halo
if(symbolizer.haloRadius != null || if(symbolizer.haloRadius != null ||
symbolizer.haloColor != null || symbolizer.haloColor != null ||
@@ -888,12 +979,118 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
this.writeNode("Halo", symbolizer, node); this.writeNode("Halo", symbolizer, node);
} }
// add in optional Fill // add in optional Fill
if(symbolizer.fillColor != null || if(symbolizer.fontColor != null ||
symbolizer.fillOpacity != null) { symbolizer.fontOpacity != null) {
this.writeNode("Fill", symbolizer, node); this.writeNode("Fill", {
fillColor: symbolizer.fontColor,
fillOpacity: symbolizer.fontOpacity
}, node);
} }
return node; return node;
}, },
"LabelPlacement": function(symbolizer) {
var node = this.createElementNSPlus("sld:LabelPlacement");
if (symbolizer.labelAnchorPointX != null ||
symbolizer.labelAnchorPointY != null ||
symbolizer.labelAlign != null ||
symbolizer.labelXOffset != null ||
symbolizer.labelYOffset != null ||
symbolizer.labelRotation != null) {
this.writeNode("PointPlacement", symbolizer, node);
}
if (symbolizer.labelPerpendicularOffset != null) {
this.writeNode("LinePlacement", symbolizer, node);
}
return node;
},
"LinePlacement": function(symbolizer) {
var node = this.createElementNSPlus("sld:LinePlacement");
this.writeNode("PerpendicularOffset", symbolizer.labelPerpendicularOffset, node);
return node;
},
"PerpendicularOffset": function(value) {
return this.createElementNSPlus("sld:PerpendicularOffset", {
value: value
});
},
"PointPlacement": function(symbolizer) {
var node = this.createElementNSPlus("sld:PointPlacement");
if (symbolizer.labelAnchorPointX != null ||
symbolizer.labelAnchorPointY != null ||
symbolizer.labelAlign != null) {
this.writeNode("AnchorPoint", symbolizer, node);
}
if (symbolizer.labelXOffset != null ||
symbolizer.labelYOffset != null) {
this.writeNode("Displacement", symbolizer, node);
}
if (symbolizer.labelRotation != null) {
this.writeNode("Rotation", symbolizer.labelRotation, node);
}
return node;
},
"AnchorPoint": function(symbolizer) {
var node = this.createElementNSPlus("sld:AnchorPoint");
var x = symbolizer.labelAnchorPointX,
y = symbolizer.labelAnchorPointY;
if (x != null) {
this.writeNode("AnchorPointX", x, node);
}
if (y != null) {
this.writeNode("AnchorPointY", y, node);
}
if (x == null && y == null) {
var xAlign = symbolizer.labelAlign.substr(0, 1),
yAlign = symbolizer.labelAlign.substr(1, 1);
if (xAlign === "l") {
x = 0;
} else if (xAlign === "c") {
x = 0.5;
} else if (xAlign === "r") {
x = 1;
}
if (yAlign === "b") {
y = 0;
} else if (yAlign === "m") {
y = 0.5;
} else if (yAlign === "t") {
y = 1;
}
this.writeNode("AnchorPointX", x, node);
this.writeNode("AnchorPointY", y, node);
}
return node;
},
"AnchorPointX": function(value) {
return this.createElementNSPlus("sld:AnchorPointX", {
value: value
});
},
"AnchorPointY": function(value) {
return this.createElementNSPlus("sld:AnchorPointY", {
value: value
});
},
"Displacement": function(symbolizer) {
var node = this.createElementNSPlus("sld:Displacement");
if (symbolizer.labelXOffset != null) {
this.writeNode("DisplacementX", symbolizer.labelXOffset, node);
}
if (symbolizer.labelYOffset != null) {
this.writeNode("DisplacementY", symbolizer.labelYOffset, node);
}
return node;
},
"DisplacementX": function(value) {
return this.createElementNSPlus("sld:DisplacementX", {
value: value
});
},
"DisplacementY": function(value) {
return this.createElementNSPlus("sld:DisplacementY", {
value: value
});
},
"Font": function(symbolizer) { "Font": function(symbolizer) {
var node = this.createElementNSPlus("sld:Font"); var node = this.createElementNSPlus("sld:Font");
// add in CssParameters // add in CssParameters

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

@@ -221,13 +221,13 @@ OpenLayers.Handler.Box = OpenLayers.Class(OpenLayers.Handler, {
document.body.removeChild(testDiv); document.body.removeChild(testDiv);
var left = parseInt(OpenLayers.Element.getStyle(this.zoomBox, var left = parseInt(OpenLayers.Element.getStyle(this.zoomBox,
"border-left-width")); "borderLeftWidth"));
var right = parseInt(OpenLayers.Element.getStyle( var right = parseInt(OpenLayers.Element.getStyle(
this.zoomBox, "border-right-width")); this.zoomBox, "borderRightWidth"));
var top = parseInt(OpenLayers.Element.getStyle(this.zoomBox, var top = parseInt(OpenLayers.Element.getStyle(this.zoomBox,
"border-top-width")); "borderTopWidth"));
var bottom = parseInt(OpenLayers.Element.getStyle( var bottom = parseInt(OpenLayers.Element.getStyle(
this.zoomBox, "border-bottom-width")); this.zoomBox, "borderBottomWidth"));
this.boxOffsets = { this.boxOffsets = {
left: left, left: left,
right: right, right: right,

View File

@@ -33,6 +33,13 @@ OpenLayers.Handler.Keyboard = OpenLayers.Class(OpenLayers.Handler, {
*/ */
eventListener: null, eventListener: null,
/**
* Property: observeElement
* {DOMElement|String} The DOM element on which we listen for
* key events. Default to the document.
*/
observeElement: null,
/** /**
* Constructor: OpenLayers.Handler.Keyboard * Constructor: OpenLayers.Handler.Keyboard
* Returns a new keyboard handler. * Returns a new keyboard handler.
@@ -71,9 +78,10 @@ OpenLayers.Handler.Keyboard = OpenLayers.Class(OpenLayers.Handler, {
*/ */
activate: function() { activate: function() {
if (OpenLayers.Handler.prototype.activate.apply(this, arguments)) { if (OpenLayers.Handler.prototype.activate.apply(this, arguments)) {
this.observeElement = this.observeElement || document;
for (var i=0, len=this.KEY_EVENTS.length; i<len; i++) { for (var i=0, len=this.KEY_EVENTS.length; i<len; i++) {
OpenLayers.Event.observe( OpenLayers.Event.observe(
document, this.KEY_EVENTS[i], this.eventListener); this.observeElement, this.KEY_EVENTS[i], this.eventListener);
} }
return true; return true;
} else { } else {
@@ -89,7 +97,7 @@ OpenLayers.Handler.Keyboard = OpenLayers.Class(OpenLayers.Handler, {
if (OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) { if (OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {
for (var i=0, len=this.KEY_EVENTS.length; i<len; i++) { for (var i=0, len=this.KEY_EVENTS.length; i<len; i++) {
OpenLayers.Event.stopObserving( OpenLayers.Event.stopObserving(
document, this.KEY_EVENTS[i], this.eventListener); this.observeElement, this.KEY_EVENTS[i], this.eventListener);
} }
deactivated = true; deactivated = true;
} }

View File

@@ -1,8 +1,9 @@
/* Copyright (c) 2006-2012 by OpenLayers Contributors (see authors.txt for /* Copyright (c) 2006-2012 by OpenLayers Contributors (see authors.txt for
* full list of contributors). Published under the Clear BSD license. * full list of contributors). Published under the Clear BSD license.
* See http://svn.openlayers.org/trunk/openlayers/license.txt for the * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. * full text of the license. */
*
/**
* @requires OpenLayers/BaseTypes/Class.js * @requires OpenLayers/BaseTypes/Class.js
* @requires OpenLayers/Animation.js * @requires OpenLayers/Animation.js
*/ */

View File

@@ -58,6 +58,21 @@ OpenLayers.Layer = OpenLayers.Class({
alwaysInRange: null, 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: * Register a listener for a particular event with the following syntax:
* (code) * (code)
* layer.events.register(type, obj, listener); * 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 * will receive an object with a *map* property referencing the map and
* a *layer* property referencing the layer. * 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, events: null,
/** /**
@@ -161,13 +159,6 @@ OpenLayers.Layer = OpenLayers.Class({
*/ */
imageSize: null, imageSize: null,
/**
* Property: imageOffset
* {<OpenLayers.Pixel>} For layers with a gutter, the image offset
* represents displacement due to the gutter.
*/
imageOffset: null,
// OPTIONS // OPTIONS
/** /**
@@ -255,8 +246,8 @@ OpenLayers.Layer = OpenLayers.Class({
* APIProperty: maxResolution * APIProperty: maxResolution
* {Float} Default max is 360 deg / 256 px, which corresponds to * {Float} Default max is 360 deg / 256 px, which corresponds to
* zoom level 0 on gmaps. Specify a different value in the layer * zoom level 0 on gmaps. Specify a different value in the layer
* options if you are not using a geographic projection and * options if you are not using the default <OpenLayers.Map.tileSize>
* displaying the whole world. * and displaying the whole world.
*/ */
maxResolution: null, maxResolution: null,
@@ -361,10 +352,6 @@ OpenLayers.Layer = OpenLayers.Class({
} }
} }
if (this.wrapDateLine) {
this.displayOutsideMaxExtent = true;
}
}, },
/** /**
@@ -477,8 +464,18 @@ OpenLayers.Layer = OpenLayers.Class({
this.options = {}; this.options = {};
} }
// allow array for extents
if (newOptions) { 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)) { if (newOptions.maxExtent && !(newOptions.maxExtent instanceof OpenLayers.Bounds)) {
newOptions.maxExtent = new OpenLayers.Bounds(newOptions.maxExtent); newOptions.maxExtent = new OpenLayers.Bounds(newOptions.maxExtent);
} }
@@ -493,11 +490,6 @@ OpenLayers.Layer = OpenLayers.Class({
// add new options to this // add new options to this
OpenLayers.Util.extend(this, newOptions); 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 // get the units from the projection, if we have a projection
// and it it has units // and it it has units
if(this.projection && this.projection.getUnits()) { if(this.projection && this.projection.getUnits()) {
@@ -694,7 +686,7 @@ OpenLayers.Layer = OpenLayers.Class({
/** /**
* APIMethod: setTileSize * APIMethod: setTileSize
* Set the tile size based on the map size. This also sets layer.imageSize * Set the tile size based on the map size. This also sets layer.imageSize
* and layer.imageOffset for use by Tile.Image. * or use by Tile.Image.
* *
* Parameters: * Parameters:
* size - {<OpenLayers.Size>} * size - {<OpenLayers.Size>}
@@ -711,8 +703,6 @@ OpenLayers.Layer = OpenLayers.Class({
// this.name + ": layers with " + // this.name + ": layers with " +
// "gutters need non-null tile sizes"); // "gutters need non-null tile sizes");
//} //}
this.imageOffset = new OpenLayers.Pixel(-this.gutter,
-this.gutter);
this.imageSize = new OpenLayers.Size(tileSize.w + (2*this.gutter), this.imageSize = new OpenLayers.Size(tileSize.w + (2*this.gutter),
tileSize.h + (2*this.gutter)); tileSize.h + (2*this.gutter));
} }
@@ -889,6 +879,16 @@ OpenLayers.Layer = OpenLayers.Class({
props.resolutions = this.resolutionsFromScales(props.scales); props.resolutions = this.resolutionsFromScales(props.scales);
} }
if(props.resolutions == null) { 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); props.resolutions = this.calculateResolutions(props);
} }
} }

View File

@@ -29,12 +29,6 @@ OpenLayers.Layer.ArcIMS = OpenLayers.Class(OpenLayers.Layer.Grid, {
ServiceName: '' ServiceName: ''
}, },
/**
* APIProperty: tileSize
* {<OpenLayers.Size>} Size for tiles. Default is 512x512.
*/
tileSize: null,
/** /**
* APIProperty: featureCoordSys * APIProperty: featureCoordSys
* {String} Code for feature coordinate system. Default is "4326". * {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", 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 * APIProperty: metadataParams
* {Object} Optional url parameters for the Get Imagery Metadata request * {Object} Optional url parameters for the Get Imagery Metadata request
@@ -74,6 +81,16 @@ OpenLayers.Layer.Bing = OpenLayers.Class(OpenLayers.Layer.XYZ, {
*/ */
metadataParams: null, 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 * Constructor: OpenLayers.Layer.Bing
* Create a new Bing layer. * Create a new Bing layer.
@@ -107,6 +124,9 @@ OpenLayers.Layer.Bing = OpenLayers.Class(OpenLayers.Layer.XYZ, {
var newArgs = [name, null, options]; var newArgs = [name, null, options];
OpenLayers.Layer.XYZ.prototype.initialize.apply(this, newArgs); OpenLayers.Layer.XYZ.prototype.initialize.apply(this, newArgs);
this.tileOptions = OpenLayers.Util.extend({
crossOriginKeyword: 'anonymous'
}, this.options.tileOptions);
this.loadMetadata(); this.loadMetadata();
}, },
@@ -142,13 +162,15 @@ OpenLayers.Layer.Bing = OpenLayers.Class(OpenLayers.Layer.XYZ, {
initLayer: function() { initLayer: function() {
var res = this.metadata.resourceSets[0].resources[0]; var res = this.metadata.resourceSets[0].resources[0];
var url = res.imageUrl.replace("{quadkey}", "${quadkey}"); var url = res.imageUrl.replace("{quadkey}", "${quadkey}");
url = url.replace("{culture}", this.culture);
this.url = []; this.url = [];
for (var i=0; i<res.imageUrlSubdomains.length; ++i) { for (var i=0; i<res.imageUrlSubdomains.length; ++i) {
this.url.push(url.replace("{subdomain}", res.imageUrlSubdomains[i])); this.url.push(url.replace("{subdomain}", res.imageUrlSubdomains[i]));
} }
this.addOptions({ this.addOptions({
maxResolution: Math.min( maxResolution: Math.min(
this.serverResolutions[res.zoomMin], this.maxResolution this.serverResolutions[res.zoomMin],
this.maxResolution || Number.POSITIVE_INFINITY
), ),
numZoomLevels: Math.min( numZoomLevels: Math.min(
res.zoomMax + 1 - res.zoomMin, this.numZoomLevels res.zoomMax + 1 - res.zoomMin, this.numZoomLevels

View File

@@ -11,10 +11,15 @@
/** /**
* Constant: OpenLayers.Layer.Google.v3 * Constant: OpenLayers.Layer.Google.v3
* *
* Mixin providing functionality specific to the Google Maps API v3. Note that * Mixin providing functionality specific to the Google Maps API v3 <= v3.6.
* this layer configures the google.maps.map object with the "disableDefaultUI" * Note that this layer configures the google.maps.map object with the
* option set to true. Using UI controls that the Google Maps API provides is * "disableDefaultUI" option set to true. Using UI controls that the Google
* not supported by the OpenLayers API. * 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 = { OpenLayers.Layer.Google.v3 = {
@@ -25,29 +30,13 @@ OpenLayers.Layer.Google.v3 = {
* *
* (code) * (code)
* { * {
* maxExtent: new OpenLayers.Bounds(
* -128 * 156543.03390625,
* -128 * 156543.03390625,
* 128 * 156543.03390625,
* 128 * 156543.03390625
* ),
* sphericalMercator: true, * sphericalMercator: true,
* maxResolution: 156543.03390625,
* units: "m",
* projection: "EPSG:900913" * projection: "EPSG:900913"
* } * }
* (end) * (end)
*/ */
DEFAULTS: { DEFAULTS: {
maxExtent: new OpenLayers.Bounds(
-128 * 156543.03390625,
-128 * 156543.03390625,
128 * 156543.03390625,
128 * 156543.03390625
),
sphericalMercator: true, sphericalMercator: true,
maxResolution: 156543.03390625,
units: "m",
projection: "EPSG:900913" projection: "EPSG:900913"
}, },

View File

@@ -99,10 +99,11 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
/** /**
* APIProperty: tileLoadingDelay * APIProperty: tileLoadingDelay
* {Integer} - Number of milliseconds before we shift and load * {Integer} Number of milliseconds before we shift and load
* tiles. Default is 100. * tiles when panning. Ignored if <OpenLayers.Animation.isNative> is
* true. Default is 85.
*/ */
tileLoadingDelay: 100, tileLoadingDelay: 85,
/** /**
* Property: serverResolutions * Property: serverResolutions
@@ -112,10 +113,30 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
serverResolutions: null, serverResolutions: null,
/** /**
* Property: timerId * Property: moveTimerId
* {Number} - The id of the tileLoadingDelay timer. * {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 * Property: backBuffer
@@ -153,6 +174,14 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
*/ */
backBufferTimerId: null, 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: * Register a listener for a particular event with the following syntax:
* (code) * (code)
@@ -170,7 +199,9 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* tileloaded - Triggered when each new tile is * tileloaded - Triggered when each new tile is
* loaded, as a means of progress update to listeners. * loaded, as a means of progress update to listeners.
* listeners can access 'numLoadingTiles' if they wish to keep * 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, OpenLayers.Layer.HTTPRequest.prototype.initialize.apply(this,
arguments); arguments);
this.grid = []; this.grid = [];
this.tileQueue = [];
this._moveGriddedTiles = OpenLayers.Function.bind( if (!OpenLayers.Animation.isNative) {
this.moveGriddedTiles, this 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. * map - {<OpenLayers.Map>} The map.
*/ */
removeMap: function(map) { removeMap: function(map) {
if(this.timerId != null) { if (this.moveTimerId !== null) {
window.clearTimeout(this.timerId); window.clearTimeout(this.moveTimerId);
this.timerId = null; this.moveTimerId = null;
} }
this.clearTileQueue();
if(this.backBufferTimerId !== null) { if(this.backBufferTimerId !== null) {
window.clearTimeout(this.backBufferTimerId); window.clearTimeout(this.backBufferTimerId);
this.backBufferTimerId = null; this.backBufferTimerId = null;
@@ -230,13 +266,13 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* destroy() on each of them to kill circular references * destroy() on each of them to kill circular references
*/ */
clearGrid:function() { clearGrid:function() {
this.clearTileQueue();
if (this.grid) { if (this.grid) {
for(var iRow=0, len=this.grid.length; iRow<len; iRow++) { for(var iRow=0, len=this.grid.length; iRow<len; iRow++) {
var row = this.grid[iRow]; var row = this.grid[iRow];
for(var iCol=0, clen=row.length; iCol<clen; iCol++) { for(var iCol=0, clen=row.length; iCol<clen; iCol++) {
var tile = row[iCol]; var tile = row[iCol];
this.removeTileMonitoringHooks(tile); this.destroyTile(tile);
tile.destroy();
} }
} }
this.grid = []; this.grid = [];
@@ -371,12 +407,67 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
} }
this.initGriddedTiles(bounds); this.initGriddedTiles(bounds);
} else { } 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 * Method: getServerResolution
* Return the closest highest server-supported resolution. Throw an * 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) { moveByPx: function(dx, dy) {
if (!this.singleTile) { 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 * APIMethod: setTileSize
* Check if we are in singleTile mode and if so, set the size as a ratio * 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>} * bounds - {<OpenLayers.Bounds>}
*/ */
initSingleTile: function(bounds) { initSingleTile: function(bounds) {
this.clearTileQueue();
//determine new tile bounds //determine new tile bounds
var center = bounds.getCenterLonLat(); var center = bounds.getCenterLonLat();
@@ -744,6 +822,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* bounds - {<OpenLayers.Bounds>} * bounds - {<OpenLayers.Bounds>}
*/ */
initGriddedTiles:function(bounds) { initGriddedTiles:function(bounds) {
this.clearTileQueue();
// work out mininum number of rows and columns; this is the number of // 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 // 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 layerContainerDivLeft = parseInt(this.map.layerContainerDiv.style.left);
var layerContainerDivTop = parseInt(this.map.layerContainerDiv.style.top); var layerContainerDivTop = parseInt(this.map.layerContainerDiv.style.top);
var tileData = [], center = this.map.getCenter();
do { do {
var row = this.grid[rowidx++]; var row = this.grid[rowidx++];
if (!row) { if (!row) {
@@ -810,6 +889,12 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
} else { } else {
tile.moveTo(tileBounds, px, false); 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; tileoffsetlon += tilelon;
tileoffsetx += this.tileSize.w; tileoffsetx += this.tileSize.w;
@@ -828,7 +913,12 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
this.gridResolution = this.getServerResolution(); this.gridResolution = this.getServerResolution();
//now actually draw the tiles //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; 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 * APIMethod: addTile
* Create a tile, initialize it, and add it to the layer div. * 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 * {<OpenLayers.Tile>} The added OpenLayers.Tile
*/ */
addTile: function(bounds, position) { addTile: function(bounds, position) {
return new this.tileClass(this, position, bounds, null, var tile = new this.tileClass(
this.tileSize, this.tileOptions); 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() { tile.onLoadEnd = function() {
this.numLoadingTiles--; 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 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"); this.events.triggerEvent("loadend");
if(this.backBuffer) { if(this.backBuffer) {
// the removal of the back buffer is delayed to prevent flash // the removal of the back buffer is delayed to prevent flash
// effects due to the animation of tile displaying // effects due to the animation of tile displaying
this.backBufferTimerId = window.setTimeout( this.backBufferTimerId = window.setTimeout(
OpenLayers.Function.bind(this.removeBackBuffer, this), OpenLayers.Function.bind(this.removeBackBuffer, this),
2500 this.removeBackBufferDelay
); );
} }
} }
@@ -991,19 +1011,32 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
/** /**
* Method: moveGriddedTiles * Method: moveGriddedTiles
*
* Parameter:
* deferred - {Boolean} true if this is a deferred call that should not
* be delayed.
*/ */
moveGriddedTiles: function() { moveGriddedTiles: function(deferred) {
var shifted = true; 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 buffer = this.buffer || 1;
var scale = this.getResolutionScale(); var scale = this.getResolutionScale();
var tlLayer = this.grid[0][0].position.clone(); while(true) {
tlLayer.x *= scale; var tlViewPort = {
tlLayer.y *= scale; x: (this.grid[0][0].position.x * scale) +
tlLayer = tlLayer.add(parseInt(this.div.style.left, 10), parseInt(this.div.style.left, 10) +
parseInt(this.div.style.top, 10)); parseInt(this.map.layerContainerDiv.style.left),
var offsetX = parseInt(this.map.layerContainerDiv.style.left); y: (this.grid[0][0].position.y * scale) +
var offsetY = parseInt(this.map.layerContainerDiv.style.top); parseInt(this.div.style.top, 10) +
var tlViewPort = tlLayer.add(offsetX, offsetY); parseInt(this.map.layerContainerDiv.style.top)
};
var tileSize = { var tileSize = {
w: this.tileSize.w * scale, w: this.tileSize.w * scale,
h: this.tileSize.h * 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) { } else if (tlViewPort.y < -tileSize.h * buffer) {
this.shiftRow(false); this.shiftRow(false);
} else { } 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(); var row = this.grid.pop();
for (var i=0, l=row.length; i<l; i++) { for (var i=0, l=row.length; i<l; i++) {
var tile = row[i]; var tile = row[i];
this.removeTileMonitoringHooks(tile); this.destroyTile(tile);
tile.destroy();
} }
} }
@@ -1123,8 +1150,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
for (var i=0, l=this.grid.length; i<l; i++) { for (var i=0, l=this.grid.length; i<l; i++) {
var row = this.grid[i]; var row = this.grid[i];
var tile = row.pop(); var tile = row.pop();
this.removeTileMonitoringHooks(tile); this.destroyTile(tile);
tile.destroy();
} }
} }
}, },

View File

@@ -63,6 +63,25 @@ OpenLayers.Layer.OSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {
*/ */
wrapDateLine: true, 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 * 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. * layer option can be set in this object (e.g.
* <OpenLayers.Layer.Grid.buffer>). * <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 * Method: clone

View File

@@ -24,6 +24,9 @@
OpenLayers.Layer.Vector = OpenLayers.Class(OpenLayers.Layer, { OpenLayers.Layer.Vector = OpenLayers.Class(OpenLayers.Layer, {
/** /**
* APIProperty: events
* {<OpenLayers.Events>}
*
* Register a listener for a particular event with the following syntax: * Register a listener for a particular event with the following syntax:
* (code) * (code)
* layer.events.register(type, obj, listener); * 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. * object - {Object} A reference to layer.events.object.
* element - {DOMElement} A reference to layer.events.element. * 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 * beforefeatureadded - Triggered before a feature is added. Listeners
* will receive an object with a *feature* property referencing the * will receive an object with a *feature* property referencing the
* feature to be added. To stop the feature from being added, a * 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 * Property: yx
* {Object} Keys in this object are EPSG codes for which the axis order * {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 * 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 * 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. * {Boolean} true if the axis order is reversed, false otherwise.
*/ */
reverseAxisOrder: function() { reverseAxisOrder: function() {
return (parseFloat(this.params.VERSION) >= 1.3 && var projCode = this.projection.getCode();
!!this.yx[this.map.getProjectionObject().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) { initialize: function(name, url, options) {
if (options && options.sphericalMercator || this.sphericalMercator) { if (options && options.sphericalMercator || this.sphericalMercator) {
options = OpenLayers.Util.extend({ options = OpenLayers.Util.extend({
maxExtent: new OpenLayers.Bounds( projection: "EPSG:900913",
-128 * 156543.03390625, numZoomLevels: 19
-128 * 156543.03390625,
128 * 156543.03390625,
128 * 156543.03390625
),
maxResolution: 156543.03390625,
numZoomLevels: 19,
units: "m",
projection: "EPSG:900913"
}, options); }, options);
} }
url = url || this.url; OpenLayers.Layer.Grid.prototype.initialize.apply(this, [
name = name || this.name; name || this.name, url || this.url, {}, options
var newArguments = [name, url, {}, options]; ]);
OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);
}, },
/** /**
@@ -157,9 +148,8 @@ OpenLayers.Layer.XYZ = OpenLayers.Class(OpenLayers.Layer.Grid, {
OpenLayers.Util.indexOf(resolutions, res) : OpenLayers.Util.indexOf(resolutions, res) :
this.getServerZoom() + this.zoomOffset; this.getServerZoom() + this.zoomOffset;
if (this.wrapDateLine) {
var limit = Math.pow(2, z); var limit = Math.pow(2, z);
if (this.wrapDateLine)
{
x = ((x % limit) + limit) % limit; 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 // initilize the Zoomify pyramid for given size
this.initializeZoomify(size); this.initializeZoomify(size);
var newArguments = []; OpenLayers.Layer.Grid.prototype.initialize.apply(this, [
newArguments.push(name, url, size, {}, options); name, url, size, {}, options
]);
OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);
}, },
/** /**

View File

@@ -8,6 +8,7 @@
* @requires OpenLayers/Util.js * @requires OpenLayers/Util.js
* @requires OpenLayers/Events.js * @requires OpenLayers/Events.js
* @requires OpenLayers/Tween.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: * Register a listener for a particular event with the following syntax:
* (code) * (code)
* map.events.register(type, obj, listener); * map.events.register(type, obj, listener);
@@ -43,43 +47,42 @@ OpenLayers.Map = OpenLayers.Class({
* properties of this event depends on exactly what happened. * properties of this event depends on exactly what happened.
* *
* All event objects have at least the following properties: * All event objects have at least the following properties:
* - *object* {Object} A reference to map.events.object. * object - {Object} A reference to map.events.object.
* - *element* {DOMElement} A reference to map.events.element. * element - {DOMElement} A reference to map.events.element.
* *
* Browser events have the following additional properties: * 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). * to the the map viewport).
* - other properties that come with browser events
* *
* Supported map event types: * 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 * object will include a *layer* property that references the layer
* to be added. When a listener returns "false" the adding will be * to be added. When a listener returns "false" the adding will be
* aborted. * 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. * 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 * object will include a *layer* property that references the layer
* to be removed. When a listener returns "false" the removal will be * to be removed. When a listener returns "false" the removal will be
* aborted. * 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 * object will include a *layer* property that references the removed
* layer. * 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 * opacity change, params change, visibility change (due to resolution
* thresholds) or attribution change (due to extent change). Listeners * thresholds) or attribution change (due to extent change). Listeners
* will receive an event object with *layer* and *property* properties. * will receive an event object with *layer* and *property* properties.
* The *layer* property will be a reference to the changed layer. The * The *layer* property will be a reference to the changed layer. The
* *property* property will be a key to the changed property (name, * *property* property will be a key to the changed property (name,
* order, opacity, params, visibility or attribution). * order, opacity, params, visibility or attribution).
* - *movestart* triggered after the start of a drag, pan, or zoom * movestart - triggered after the start of a drag, pan, or zoom
* - *move* triggered after each drag, pan, or zoom * move - triggered after each drag, pan, or zoom
* - *moveend* triggered after a drag, pan, or zoom completes * moveend - triggered after a drag, pan, or zoom completes
* - *zoomend* triggered after a zoom completes * zoomend - triggered after a zoom completes
* - *mouseover* triggered after mouseover the map * mouseover - triggered after mouseover the map
* - *mouseout* triggered after mouseout the map * mouseout - triggered after mouseout the map
* - *mousemove* triggered after mousemove the map * mousemove - triggered after mousemove the map
* - *changebaselayer* triggered after the base layer changes * changebaselayer - triggered after the base layer changes
*/ */
/** /**
@@ -248,17 +251,19 @@ OpenLayers.Map = OpenLayers.Class({
/** /**
* APIProperty: projection * APIProperty: projection
* {String} Set in the map options to override the default projection * {String} Set in the map options to override the default projection
* string this map - also set maxExtent, maxResolution, and * string this map. When using a projection other than EPSG:4326
* units if appropriate. Default is "EPSG:4326". * (CRS:84, Geographic) or EPSG:3857 (EPSG:900913, Web Mercator),
* also set maxExtent and maxResolution. Default is "EPSG:4326".
*/ */
projection: "EPSG:4326", projection: "EPSG:4326",
/** /**
* APIProperty: units * APIProperty: units
* {String} The map units. Defaults to 'degrees'. Possible values are * {String} The map units. Possible values are 'degrees' (or 'dd'), 'm',
* 'degrees' (or 'dd'), 'm', 'ft', 'km', 'mi', 'inches'. * 'ft', 'km', 'mi', 'inches'. Only required if the projection default
* should be overridden.
*/ */
units: 'degrees', units: null,
/** /**
* APIProperty: resolutions * APIProperty: resolutions
@@ -271,12 +276,10 @@ OpenLayers.Map = OpenLayers.Class({
/** /**
* APIProperty: maxResolution * APIProperty: maxResolution
* {Float} Default max is 360 deg / 256 px, which corresponds to * {Float} Required if you are not displaying the whole world on a tile
* zoom level 0 on gmaps. Specify a different value in the map * with the size specified in <tileSize>.
* options if you are not using a geographic projection and
* displaying the whole world.
*/ */
maxResolution: 1.40625, maxResolution: null,
/** /**
* APIProperty: minResolution * APIProperty: minResolution
@@ -342,7 +345,8 @@ OpenLayers.Map = OpenLayers.Class({
/** /**
* APIProperty: displayProjection * 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, * several controls to display data to user. If this property is set,
* it will be set on any control which has a null displayProjection * it will be set on any control which has a null displayProjection
* property at the time the control is added to the map. * property at the time the control is added to the map.
@@ -471,8 +475,6 @@ OpenLayers.Map = OpenLayers.Class({
this.tileSize = new OpenLayers.Size(OpenLayers.Map.TILE_WIDTH, this.tileSize = new OpenLayers.Size(OpenLayers.Map.TILE_WIDTH,
OpenLayers.Map.TILE_HEIGHT); OpenLayers.Map.TILE_HEIGHT);
this.maxExtent = new OpenLayers.Bounds(-180, -90, 180, 90);
this.paddingForPopups = new OpenLayers.Bounds(15, 15, 15, 15); this.paddingForPopups = new OpenLayers.Bounds(15, 15, 15, 15);
this.theme = OpenLayers._getScriptLocation() + this.theme = OpenLayers._getScriptLocation() +
@@ -481,6 +483,10 @@ OpenLayers.Map = OpenLayers.Class({
// now override default options // now override default options
OpenLayers.Util.extend(this, 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 // allow extents to be arrays
if (this.maxExtent && !(this.maxExtent instanceof OpenLayers.Bounds)) { if (this.maxExtent && !(this.maxExtent instanceof OpenLayers.Bounds)) {
this.maxExtent = new OpenLayers.Bounds(this.maxExtent); this.maxExtent = new OpenLayers.Bounds(this.maxExtent);
@@ -571,14 +577,20 @@ OpenLayers.Map = OpenLayers.Class({
} }
if (this.controls == null) { 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 = []; 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())
}
} }
} }

View File

@@ -845,10 +845,10 @@ OpenLayers.Popup = OpenLayers.Class({
//read the padding settings from css, put them in an OL.Bounds //read the padding settings from css, put them in an OL.Bounds
contentDivPadding = new OpenLayers.Bounds( contentDivPadding = new OpenLayers.Bounds(
OpenLayers.Element.getStyle(this.contentDiv, "padding-left"), OpenLayers.Element.getStyle(this.contentDiv, "paddingLeft"),
OpenLayers.Element.getStyle(this.contentDiv, "padding-bottom"), OpenLayers.Element.getStyle(this.contentDiv, "paddingBottom"),
OpenLayers.Element.getStyle(this.contentDiv, "padding-right"), OpenLayers.Element.getStyle(this.contentDiv, "paddingRight"),
OpenLayers.Element.getStyle(this.contentDiv, "padding-top") OpenLayers.Element.getStyle(this.contentDiv, "paddingTop")
); );
//cache the value //cache the value

View File

@@ -142,7 +142,7 @@ OpenLayers.Projection = OpenLayers.Class({
/** /**
* Property: transforms * 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 * have a to property. This allows you to define projections without
* requiring support for proj4js to be included. * requiring support for proj4js to be included.
* *
@@ -162,6 +162,30 @@ OpenLayers.Projection = OpenLayers.Class({
*/ */
OpenLayers.Projection.transforms = {}; 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 * APIMethod: addTransform
* Set a custom transform method between two projections. Use this method in * 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. * in place. The original point should be modified.
*/ */
OpenLayers.Projection.addTransform = function(from, to, method) { 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]) { if(!OpenLayers.Projection.transforms[from]) {
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 recognizes EPSG:3857, EPSG:900913, EPSG:102113 and EPSG:102100.
* OpenLayers originally started referring to EPSG:900913 as web mercator. * OpenLayers originally started referring to EPSG:900913 as web mercator.
* The EPSG has declared EPSG:3857 to be web mercator. * The EPSG has declared EPSG:3857 to be web mercator.
* ArcGIS 10 recognizes the EPSG:3857, EPSG:102113, and EPSG:102100 as * 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() { (function() {
@@ -258,22 +291,31 @@ OpenLayers.Projection.nullTransform = function(point) {
return xy; return xy;
} }
// list of equivalent codes for web mercator function map(base, codes) {
var codes = ["EPSG:900913", "EPSG:3857", "EPSG:102113", "EPSG:102100"];
var add = OpenLayers.Projection.addTransform; var add = OpenLayers.Projection.addTransform;
var same = OpenLayers.Projection.nullTransform; var same = OpenLayers.Projection.nullTransform;
var i, len, code, other, j; var i, len, code, other, j;
for (i=0, len=codes.length; i<len; ++i) { for (i=0, len=codes.length; i<len; ++i) {
code = codes[i]; code = codes[i];
add("EPSG:4326", code, forwardMercator); add(base, code, forwardMercator);
add(code, "EPSG:4326", inverseMercator); add(code, base, inverseMercator);
for (j=i+1; j<len; ++j) { for (j=i+1; j<len; ++j) {
other = codes[j]; other = codes[j];
add(code, other, same); add(code, other, same);
add(other, code, 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

@@ -62,12 +62,27 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {
scope: null, scope: null,
/** /**
* Property: readWithPOST * APIProperty: readWithPOST
* {Boolean} true if read operations are done with POST requests * {Boolean} true if read operations are done with POST requests
* instead of GET, defaults to false. * instead of GET, defaults to false.
*/ */
readWithPOST: false, readWithPOST: false,
/**
* APIProperty: updateWithPOST
* {Boolean} true if update operations are done with POST requests
* defaults to false.
*/
updateWithPOST: false,
/**
* APIProperty: deleteWithPOST
* {Boolean} true if delete operations are done with POST requests
* defaults to false.
* if true, POST data is set to output of format.write().
*/
deleteWithPOST: false,
/** /**
* Property: wildcarded. * Property: wildcarded.
* {Boolean} If true percent signs are added around values * {Boolean} If true percent signs are added around values
@@ -293,7 +308,8 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {
requestType: "update" requestType: "update"
}); });
resp.priv = OpenLayers.Request.PUT({ var method = this.updateWithPOST ? "POST" : "PUT";
resp.priv = OpenLayers.Request[method]({
url: url, url: url,
callback: this.createCallback(this.handleUpdate, resp, options), callback: this.createCallback(this.handleUpdate, resp, options),
headers: options.headers, headers: options.headers,
@@ -344,11 +360,16 @@ OpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {
requestType: "delete" requestType: "delete"
}); });
resp.priv = OpenLayers.Request.DELETE({ var method = this.deleteWithPOST ? "POST" : "DELETE";
var requestOptions = {
url: url, url: url,
callback: this.createCallback(this.handleDelete, resp, options), callback: this.createCallback(this.handleDelete, resp, options),
headers: options.headers headers: options.headers
}); };
if (this.deleteWithPOST) {
requestOptions.data = this.format.write(feature);
}
resp.priv = OpenLayers.Request[method](requestOptions);
return resp; return resp;
}, },

View File

@@ -415,3 +415,18 @@ OpenLayers.Renderer.defaultSymbolizer = {
labelAlign: 'cm' labelAlign: 'cm'
}; };
/**
* Constant: OpenLayers.Renderer.symbol
* Coordinate arrays for well known (named) symbols.
*/
OpenLayers.Renderer.symbol = {
"star": [350,75, 379,161, 469,161, 397,215, 423,301, 350,250, 277,301,
303,215, 231,161, 321,161, 350,75],
"cross": [4,0, 6,0, 6,4, 10,4, 10,6, 6,6, 6,10, 4,10, 4,6, 0,6, 0,4, 4,4,
4,0],
"x": [0,0, 25,0, 50,35, 75,0, 100,0, 65,50, 100,100, 75,100, 50,65, 25,100, 0,100, 35,50, 0,0],
"square": [0,0, 0,1, 1,1, 1,0, 0,0],
"triangle": [0,10, 10,10, 5,0, 0,10]
};

View File

@@ -51,6 +51,12 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
*/ */
pendingRedraw: false, pendingRedraw: false,
/**
* Property: cachedSymbolBounds
* {Object} Internal cache of calculated symbol extents.
*/
cachedSymbolBounds: {},
/** /**
* Constructor: OpenLayers.Renderer.Canvas * 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 * {Boolean} Whether or not the browser supports the renderer class
*/ */
supported: function() { supported: function() {
var canvas = document.createElement("canvas"); return OpenLayers.CANVAS_SUPPORTED;
return !!canvas.getContext;
}, },
/** /**
@@ -284,6 +289,151 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
img.src = style.externalGraphic; 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 * Method: setCanvasStyle
* Prepare the canvas for drawing by setting various global settings. * 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.graphic !== false) {
if(style.externalGraphic) { if(style.externalGraphic) {
this.drawExternalGraphic(geometry, style, featureId); this.drawExternalGraphic(geometry, style, featureId);
} else if (style.graphicName && (style.graphicName != "circle")) {
this.drawNamedSymbol(geometry, style, featureId);
} else { } else {
var pt = this.getLocalXY(geometry); var pt = this.getLocalXY(geometry);
var p0 = pt[0]; var p0 = pt[0];
@@ -634,8 +786,9 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
* layer. * layer.
*/ */
getFeatureIdFromEvent: function(evt) { getFeatureIdFromEvent: function(evt) {
var feature; var featureId, feature;
if (this.hitDetection) {
if (this.hitDetection && this.root.style.display !== "none") {
// this dragging check should go in the feature handler // this dragging check should go in the feature handler
if (!this.map.dragging) { if (!this.map.dragging) {
var xy = evt.xy; var xy = evt.xy;
@@ -645,7 +798,14 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
if (data[3] === 255) { // antialiased if (data[3] === 255) { // antialiased
var id = data[2] + (256 * (data[1] + (256 * data[0]))); var id = data[2] + (256 * (data[1] + (256 * data[0])));
if (id) { 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

@@ -1051,17 +1051,3 @@ OpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, {
CLASS_NAME: "OpenLayers.Renderer.Elements" CLASS_NAME: "OpenLayers.Renderer.Elements"
}); });
/**
* Constant: OpenLayers.Renderer.symbol
* Coordinate arrays for well known (named) symbols.
*/
OpenLayers.Renderer.symbol = {
"star": [350,75, 379,161, 469,161, 397,215, 423,301, 350,250, 277,301,
303,215, 231,161, 321,161, 350,75],
"cross": [4,0, 6,0, 6,4, 10,4, 10,6, 6,6, 6,10, 4,10, 4,6, 0,6, 0,4, 4,4,
4,0],
"x": [0,0, 25,0, 50,35, 75,0, 100,0, 65,50, 100,100, 75,100, 50,65, 25,100, 0,100, 35,50, 0,0],
"square": [0,0, 0,1, 1,1, 1,0, 0,0],
"triangle": [0,10, 10,10, 5,0, 0,10]
};

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

View File

@@ -20,15 +20,19 @@
OpenLayers.Strategy.Save = OpenLayers.Class(OpenLayers.Strategy, { 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: * Register a listener for a particular event with the following syntax:
* (code) * (code)
* strategy.events.register(type, obj, listener); * strategy.events.register(type, obj, listener);
* (end) * (end)
* *
* Supported event types: * Supported event types:
* - *start* Triggered before saving * start - Triggered before saving
* - *success* Triggered after a successful transaction * success - Triggered after a successful transaction
* - *fail* Triggered after a failed transaction * fail - Triggered after a failed transaction
* *
*/ */

View File

@@ -23,18 +23,25 @@
*/ */
OpenLayers.Tile = OpenLayers.Class({ 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 * APIProperty: events
* {<OpenLayers.Events>} An events object that handles all * {<OpenLayers.Events>} An events object that handles all
* events on the tile. * 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, events: null,
@@ -181,14 +188,25 @@ OpenLayers.Tile = OpenLayers.Class({
* that can be overridden by subclasses. The minimum thing to do here * that can be overridden by subclasses. The minimum thing to do here
* is to call <clear> and return the result from <shouldDraw>. * 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: * Returns:
* {Boolean} Whether or not the tile should actually be drawn. * {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 //clear tile's contents and mark as not drawn
this.clear(); 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 * Method: clear
* Clear the tile of any bounds/position-related data so that it can * Clear the tile of any bounds/position-related data so that it can
* be reused in a new location. To be implemented by subclasses. * be reused in a new location.
*/ */
clear: function(draw) { clear: function(draw) {
// to be implemented by subclasses // to be extended by subclasses
}, },
CLASS_NAME: "OpenLayers.Tile" CLASS_NAME: "OpenLayers.Tile"

View File

@@ -6,6 +6,7 @@
/** /**
* @requires OpenLayers/Tile.js * @requires OpenLayers/Tile.js
* @requires OpenLayers/Animation.js
*/ */
/** /**
@@ -81,6 +82,23 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
*/ */
maxGetUrlLength: null, 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 /** TBD 3.0 - reorder the parameters to the init function to remove
* URL. the getUrl() function on the layer gets called on * URL. the getUrl() function on the layer gets called on
* each draw(), so no need to specify it here. * each draw(), so no need to specify it here.
@@ -190,11 +208,12 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
* code. * code.
*/ */
positionTile: function() { positionTile: function() {
var style = this.getTile().style; var style = this.getTile().style,
size = this.layer.getImageSize(this.bounds);
style.left = this.position.x + "%"; style.left = this.position.x + "%";
style.top = this.position.y + "%"; style.top = this.position.y + "%";
style.width = this.size.w + "%"; style.width = size.w + "%";
style.height = this.size.h + "%"; style.height = size.h + "%";
}, },
/** /**
@@ -203,6 +222,7 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
* it can be reused in a new location. * it can be reused in a new location.
*/ */
clear: function() { clear: function() {
OpenLayers.Tile.prototype.clear.apply(this, arguments);
var img = this.imgDiv; var img = this.imgDiv;
if (img) { if (img) {
OpenLayers.Event.stopObservingElement(img); OpenLayers.Event.stopObservingElement(img);
@@ -216,6 +236,7 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
} }
OpenLayers.Element.removeClass(img, "olImageLoadError"); OpenLayers.Element.removeClass(img, "olImageLoadError");
} }
this.canvasContext = null;
}, },
/** /**
@@ -236,11 +257,6 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
var top = this.layer.gutter / this.layer.tileSize.h * 100; var top = this.layer.gutter / this.layer.tileSize.h * 100;
style.left = -left + "%"; style.left = -left + "%";
style.top = -top + "%"; style.top = -top + "%";
style.width = (2 * left + 100) + "%";
style.height = (2 * top + 100) + "%";
} else {
style.width = "100%";
style.height = "100%";
} }
style.visibility = "hidden"; style.visibility = "hidden";
style.opacity = 0; style.opacity = 0;
@@ -297,6 +313,9 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
} else { } else {
OpenLayers.Event.observe(img, "load", load); OpenLayers.Event.observe(img, "load", load);
OpenLayers.Event.observe(img, "error", load); OpenLayers.Event.observe(img, "error", load);
if (img.crossOrigin) {
img.crossOrigin = null;
}
img.src = this.blankImageUrl; img.src = this.blankImageUrl;
} }
} }
@@ -314,6 +333,10 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
img.style.visibility = 'hidden'; img.style.visibility = 'hidden';
img.style.opacity = 0; img.style.opacity = 0;
if (url) { 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; img.src = url;
} }
}, },
@@ -366,6 +389,7 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
img.style.opacity = this.layer.opacity; img.style.opacity = this.layer.opacity;
this.isLoading = false; this.isLoading = false;
this.canvasContext = null;
this.events.triggerEvent("loadend"); this.events.triggerEvent("loadend");
// IE<7 needs a reflow when the tiles are loaded because of the // IE<7 needs a reflow when the tiles are loaded because of the
@@ -406,6 +430,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" CLASS_NAME: "OpenLayers.Tile.Image"
}); });

View File

@@ -65,7 +65,11 @@ OpenLayers.Tile.Image.IFrame = {
// And if we had an iframe we also remove the event pane. // And if we had an iframe we also remove the event pane.
if(fromIFrame) { if(fromIFrame) {
this.blankImageUrl = this._blankImageUrl;
this.frame.removeChild(this.frame.firstChild); this.frame.removeChild(this.frame.firstChild);
} else {
this._blankImageUrl = this.blankImageUrl;
this.blankImageUrl = "about:blank";
} }
} }
} }
@@ -85,7 +89,7 @@ OpenLayers.Tile.Image.IFrame = {
style.width = "100%"; style.width = "100%";
style.height = "100%"; style.height = "100%";
style.zIndex = 1; style.zIndex = 1;
style.backgroundImage = "url(" + this.blankImageUrl + ")"; style.backgroundImage = "url(" + this._blankImageUrl + ")";
this.frame.appendChild(eventPane); this.frame.appendChild(eventPane);
} }

View File

@@ -1,8 +1,9 @@
/* Copyright (c) 2006-2012 by OpenLayers Contributors (see authors.txt for /* Copyright (c) 2006-2012 by OpenLayers Contributors (see authors.txt for
* full list of contributors). Published under the Clear BSD license. * full list of contributors). Published under the Clear BSD license.
* See http://svn.openlayers.org/trunk/openlayers/license.txt for the * See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. * full text of the license. */
*
/**
* @requires OpenLayers/BaseTypes/Class.js * @requires OpenLayers/BaseTypes/Class.js
* @requires OpenLayers/Animation.js * @requires OpenLayers/Animation.js
*/ */

View File

@@ -1435,6 +1435,15 @@ OpenLayers.IS_GECKO = (function() {
return ua.indexOf("webkit") == -1 && ua.indexOf("gecko") != -1; 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 * Constant: BROWSER_NAME
* {String} * {String}

View File

@@ -105,6 +105,30 @@ OpenLayers.Util.clearArray = function(array) {
array.length = 0; array.length = 0;
}; };
/**
* APIFunction: camelize
* Camel-case a hyphenated string.
* Ex. "chicken-head" becomes "chickenHead", and
* "-chicken-head" becomes "ChickenHead".
*
* Parameters:
* str - {String} The string to be camelized. The original is not modified.
*
* Returns:
* {String} The string, camelized
*/
OpenLayers.String.camelize = function(str) {
var oStringList = str.split('-');
var camelizedString = oStringList[0];
for (var i=1, len=oStringList.length; i<len; i++) {
var s = oStringList[i];
camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
}
return camelizedString;
};
/** /**
* Function: setOpacity * Function: setOpacity
* *Deprecated*. This function has been deprecated. Instead, please use * *Deprecated*. This function has been deprecated. Instead, please use

View File

@@ -62,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: 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; border-radius: 10px 0 0 10px;
} }
@@ -76,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. 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) `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 ## 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. 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.
@@ -105,6 +109,7 @@ A number of properties, methods, and constructors have been marked as deprecated
* OpenLayers.Util.setOpacity * OpenLayers.Util.setOpacity
* OpenLayers.Util.safeStopPropagation * OpenLayers.Util.safeStopPropagation
* OpenLayers.Util.getArgs * OpenLayers.Util.getArgs
* OpenLayers.Sring.camelize
* OpenLayers.nullHandler * OpenLayers.nullHandler
* OpenLayers.loadURL * OpenLayers.loadURL
* OpenLayers.parseXMLString * OpenLayers.parseXMLString

View File

@@ -15,7 +15,8 @@
<script> <script>
function test_all(t) { 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) { t.open_window("Animation.html", function(win) {
win.requestFrame(t); win.requestFrame(t);
win.start(t); win.start(t);

View File

@@ -60,33 +60,6 @@
t.eq(OpenLayers.String.trim(str), "", "whitespace string is trimmed correctly"); t.eq(OpenLayers.String.trim(str), "", "whitespace string is trimmed correctly");
} }
function test_String_camelize(t) {
t.plan(7);
var str = "chickenhead";
t.eq(OpenLayers.String.camelize(str), "chickenhead", "string with no hyphens is left alone");
str = "chicken-head";
t.eq(OpenLayers.String.camelize(str), "chickenHead", "string with one middle hyphen is camelized correctly");
str = "chicken-head-man";
t.eq(OpenLayers.String.camelize(str), "chickenHeadMan", "string with multiple middle hyphens is camelized correctly");
str = "-chickenhead";
t.eq(OpenLayers.String.camelize(str), "Chickenhead", "string with starting hyphen is camelized correctly (capitalized)");
str = "-chicken-head-man";
t.eq(OpenLayers.String.camelize(str), "ChickenHeadMan", "string with starting hypen and multiple middle hyphens is camelized correctly");
str = "chicken-";
t.eq(OpenLayers.String.camelize(str), "chicken", "string ending in hyphen is camelized correctly (hyphen dropped)");
str = "chicken-head-man-";
t.eq(OpenLayers.String.camelize(str), "chickenHeadMan", "string with multiple middle hyphens and end hyphen is camelized correctly (end hyphen dropped)");
}
function test_String_format(t) { function test_String_format(t) {
var unchanged = [ var unchanged = [
"", "${ ", "${", " ${", "${${", "${}", "${${}}", " ${ ${", "", "${ ", "${", " ${", "${${", "${}", "${${}}", " ${ ${",

View File

@@ -30,8 +30,9 @@
map.addLayer(new OpenLayers.Layer("name", {'attribution':'My layer 2!'})); 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."); t.eq(control.div.innerHTML, 'My layer!, My layer 2!', "Attribution correct with two layers.");
control.separator = '|'; control.separator = '|';
control.template = "Map Copyright (c) 2012 by Foo Bar; ${layers}";
map.addLayer(new OpenLayers.Layer("name",{'attribution':'My layer 3!'})); 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 src="../OLLoader.js"></script>
<script type="text/javascript"> <script type="text/javascript">
function test_initialze(t) { function test_initialize(t) {
t.plan(1); 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"); 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> </script>
</head> </head>
<body> <body>

View File

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

View File

@@ -46,7 +46,7 @@
new OpenLayers.Feature.Vector(point2, {name: 'foo', description: 'bar'}) new OpenLayers.Feature.Vector(point2, {name: 'foo', description: 'bar'})
]; ];
var data = parser.write(features); var data = parser.write(features);
t.xml_eq(data, '<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" 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'); 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) { function test_Format_GPX_serialize_line(t) {
t.plan(1); t.plan(1);
@@ -58,7 +58,7 @@
var line = new OpenLayers.Geometry.LineString([point, point2]); var line = new OpenLayers.Geometry.LineString([point, point2]);
var f = new OpenLayers.Feature.Vector(line, {name: 'foo', description: 'bar'}); var f = new OpenLayers.Feature.Vector(line, {name: 'foo', description: 'bar'});
var data = parser.write(f); var data = parser.write(f);
t.xml_eq(data, '<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" 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'); 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) { function test_Format_GPX_serialize_lines(t) {
t.plan(1); t.plan(1);
@@ -74,7 +74,7 @@
var f = new OpenLayers.Feature.Vector(line, {name: 'foo', description: 'bar'}); var f = new OpenLayers.Feature.Vector(line, {name: 'foo', description: 'bar'});
var f2 = new OpenLayers.Feature.Vector(line2, {name: 'dude', description: 'truite'}); var f2 = new OpenLayers.Feature.Vector(line2, {name: 'dude', description: 'truite'});
var data = parser.write([f, f2]); var data = parser.write([f, f2]);
t.xml_eq(data, '<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" 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'); 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) { function test_Format_GPX_serialize_multiline(t) {
t.plan(1); t.plan(1);
@@ -90,7 +90,7 @@
var multiline = new OpenLayers.Geometry.MultiLineString([line, line2]); var multiline = new OpenLayers.Geometry.MultiLineString([line, line2]);
var f = new OpenLayers.Feature.Vector(multiline, {name: 'foo', description: 'bar'}); var f = new OpenLayers.Feature.Vector(multiline, {name: 'foo', description: 'bar'});
var data = parser.write([f]); var data = parser.write([f]);
t.xml_eq(data, '<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" 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'); 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) { function test_Format_GPX_serialize_polygon(t) {
t.plan(1); t.plan(1);
@@ -103,7 +103,7 @@
var polygon = new OpenLayers.Geometry.Polygon([linearRing]); var polygon = new OpenLayers.Geometry.Polygon([linearRing]);
var f = new OpenLayers.Feature.Vector(polygon, {name: 'foo', description: 'bar'}); var f = new OpenLayers.Feature.Vector(polygon, {name: 'foo', description: 'bar'});
var data = parser.write([f]); var data = parser.write([f]);
t.xml_eq(data, '<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" 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'); 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) { function test_Format_GPX_serialize_metadata(t) {
t.plan(1); t.plan(1);
@@ -111,7 +111,7 @@
var parser = new OpenLayers.Format.GPX(); var parser = new OpenLayers.Format.GPX();
var data = parser.write([], {name: 'foo', desc: 'bar'}); var data = parser.write([], {name: 'foo', desc: 'bar'});
t.xml_eq(data, '<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" 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'); 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> </script>
</head> </head>

View File

@@ -47,6 +47,19 @@
'<CssParameter name="font-weight">bold</CssParameter>' + '<CssParameter name="font-weight">bold</CssParameter>' +
'<CssParameter name="font-style">normal</CssParameter>' + '<CssParameter name="font-style">normal</CssParameter>' +
'</Font>' + '</Font>' +
'<LabelPlacement>' +
'<PointPlacement>' +
'<AnchorPoint>' +
'<AnchorPointX>0.5</AnchorPointX>' +
'<AnchorPointY>0.5</AnchorPointY>' +
'</AnchorPoint>' +
'<Displacement>' +
'<DisplacementX>5</DisplacementX>' +
'<DisplacementY>5</DisplacementY>' +
'</Displacement>' +
'<Rotation>45</Rotation>' +
'</PointPlacement>' +
'</LabelPlacement>' +
'<Halo>' + '<Halo>' +
'<Radius>3</Radius>' + '<Radius>3</Radius>' +
'<Fill>' + '<Fill>' +
@@ -177,7 +190,7 @@
t.eq(text.label, "A ${FOO} label", "(AAA161) first rule has proper text label"); 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(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.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.haloRadius, "3", "(AAA161) first rule has proper halo radius");
t.eq(text.haloColor, "#ffffff", "(AAA161) first rule has proper halo color"); t.eq(text.haloColor, "#ffffff", "(AAA161) first rule has proper halo color");
@@ -347,7 +360,7 @@
"label": "This is the ${city} in ${state}.", "label": "This is the ${city} in ${state}.",
"fontFamily": "Arial", "fontFamily": "Arial",
"fontSize": 10, "fontSize": 10,
"fillColor": "blue", "fontColor": "blue",
"fontWeight": "bold", "fontWeight": "bold",
"fontStyle": "normal", "fontStyle": "normal",
"haloRadius": 2, "haloRadius": 2,
@@ -510,6 +523,54 @@
} }
function test_label_LinePlacement(t) {
t.plan(1);
var format = new OpenLayers.Format.SLD.v1_0_0({
multipleSymbolizers: true
});
var style = new OpenLayers.Style2({
rules: [
new OpenLayers.Rule({
symbolizers: [
new OpenLayers.Symbolizer.Line({
strokeColor: "red",
strokeWidth: 3
}),
new OpenLayers.Symbolizer.Text({
label: "${FOO}",
labelPerpendicularOffset: 10
})
]
})
]
});
var got = format.writeNode("sld:UserStyle", style);
var exp = readXML("label_lineplacement_test.sld").documentElement;
t.xml_eq(got, exp, "LinePlacement written out correctly");
}
function test_labelAlignToAnchorPosition(t) {
t.plan(1);
var format = new OpenLayers.Format.SLD.v1_0_0({
multipleSymbolizers: true
});
var style = new OpenLayers.Style2({
rules: [
new OpenLayers.Rule({
symbolizers: [
new OpenLayers.Symbolizer.Text({
label: "${FOO}",
labelAlign: "rb"
})
]
})
]
});
var got = format.writeNode("sld:UserStyle", style);
var exp = readXML("label_pointplacement_test.sld").documentElement;
t.xml_eq(got, exp, "PointPlacement with labelAlign written out correctly");
}
function test_read_FeatureTypeStyles(t) { function test_read_FeatureTypeStyles(t) {
t.plan(13); t.plan(13);
@@ -585,7 +646,6 @@
doc = readXML("polygon_labelhalo.sld"); doc = readXML("polygon_labelhalo.sld");
out = format.write(format.read(doc)); out = format.write(format.read(doc));
t.xml_eq(out, doc.documentElement, "round-tripped polygon_labelhalo.sld"); t.xml_eq(out, doc.documentElement, "round-tripped polygon_labelhalo.sld");
} }
</script> </script>
@@ -867,5 +927,46 @@
</sld:FeatureTypeStyle> </sld:FeatureTypeStyle>
</sld:UserStyle> </sld:UserStyle>
--></div> --></div>
<div id="label_lineplacement_test.sld"><!--
<sld:UserStyle xmlns:sld="http://www.opengis.net/sld">
<sld:FeatureTypeStyle>
<sld:Rule>
<sld:LineSymbolizer>
<sld:Stroke>
<sld:CssParameter name="stroke">red</sld:CssParameter>
<sld:CssParameter name="stroke-width">3</sld:CssParameter>
</sld:Stroke>
</sld:LineSymbolizer>
<sld:TextSymbolizer>
<sld:Label><ogc:PropertyName xmlns:ogc="http://www.opengis.net/ogc">FOO</ogc:PropertyName></sld:Label>
<sld:LabelPlacement>
<sld:LinePlacement>
<sld:PerpendicularOffset>10</sld:PerpendicularOffset>
</sld:LinePlacement>
</sld:LabelPlacement>
</sld:TextSymbolizer>
</sld:Rule>
</sld:FeatureTypeStyle>
</sld:UserStyle>
--></div>
<div id="label_pointplacement_test.sld"><!--
<sld:UserStyle xmlns:sld="http://www.opengis.net/sld">
<sld:FeatureTypeStyle>
<sld:Rule>
<sld:TextSymbolizer>
<sld:Label><ogc:PropertyName xmlns:ogc="http://www.opengis.net/ogc">FOO</ogc:PropertyName></sld:Label>
<sld:LabelPlacement>
<sld:PointPlacement>
<sld:AnchorPoint>
<sld:AnchorPointX>1</sld:AnchorPointX>
<sld:AnchorPointY>0</sld:AnchorPointY>
</sld:AnchorPoint>
</sld:PointPlacement>
</sld:LabelPlacement>
</sld:TextSymbolizer>
</sld:Rule>
</sld:FeatureTypeStyle>
</sld:UserStyle>
--></div>
</body> </body>
</html> </html>

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

@@ -41,7 +41,7 @@
// Chromium 10: left is 0 // Chromium 10: left is 0
var testdiv = OpenLayers.Util.createDiv('testdiv', new OpenLayers.Pixel(5, 5)); var testdiv = OpenLayers.Util.createDiv('testdiv', new OpenLayers.Pixel(5, 5));
map.div.appendChild(testdiv); map.div.appendChild(testdiv);
var left = parseInt(OpenLayers.Element.getStyle(testdiv, 'border-left-width')); var left = parseInt(OpenLayers.Element.getStyle(testdiv, 'borderLeftWidth'));
map.div.removeChild(testdiv); map.div.removeChild(testdiv);
var testAll = !isNaN(left); var testAll = !isNaN(left);

View File

@@ -42,59 +42,103 @@
} }
function test_Handler_Keyboard_activate(t) { function test_Handler_Keyboard_activate(t) {
t.plan(8); t.plan(15);
var log;
var map = new OpenLayers.Map('map'); var map = new OpenLayers.Map('map');
var control = new OpenLayers.Control(); var control = new OpenLayers.Control();
map.addControl(control); map.addControl(control);
var handler = new OpenLayers.Handler.Keyboard(control); var handler = new OpenLayers.Handler.Keyboard(control);
handler.active = true;
var activated = handler.activate(); // mock OpenLayers.Event.observe
t.ok(!activated,
"activate returns false if the handler was already active");
handler.active = false;
handler.dragging = true;
var old = OpenLayers.Event.stopObserving; var old = OpenLayers.Event.stopObserving;
var types = ["keydown", "keyup"];
OpenLayers.Event.observe = function(obj, type, method) { OpenLayers.Event.observe = function(obj, type, method) {
t.ok(obj == document, log[type] = obj;
"activate calls observing with correct object"); var validType = OpenLayers.Util.indexOf(["keydown", "keyup"], type) != -1;
var validType = (OpenLayers.Util.indexOf(types, type) != -1);
t.ok(validType, "activate calls observe for " + type); t.ok(validType, "activate calls observe for " + type);
t.ok(method == handler.eventListener, t.ok(method == handler.eventListener,
"activate calls observing with correct method"); "activate calls observing with correct method");
}; };
handler.active = true;
var activated = handler.activate();
t.ok(!activated,
"activate returns false if the handler was already active");
log = {};
handler.active = false;
handler.observeElement = map.div;
activated = handler.activate(); activated = handler.activate();
t.ok(log['keydown'] == map.div,
"activate calls observing for keydown with correct object");
t.ok(log['keyup'] == map.div,
"activate calls observing for keyup with correct object");
t.ok(activated, t.ok(activated,
"activate returns true if the handler was not already active"); "activate returns true if the handler was not already active");
OpenLayers.Event.observe = old;
log = {};
handler.active = false;
handler.observeElement = null;
activated = handler.activate();
t.ok(log['keydown'] == document,
"activate calls observing for keydown with correct object");
t.ok(log['keyup'] == document,
"activate calls observing for keyup with correct object");
t.ok(activated,
"activate returns true if the handler was not already active");
OpenLayers.Event.observe = old;
map.destroy();
} }
function test_Handler_Keyboard_deactivate(t) { function test_Handler_Keyboard_deactivate(t) {
t.plan(8); t.plan(15);
var log;
var map = new OpenLayers.Map('map'); var map = new OpenLayers.Map('map');
var control = new OpenLayers.Control(); var control = new OpenLayers.Control();
map.addControl(control); map.addControl(control);
var handler = new OpenLayers.Handler.Keyboard(control); var handler = new OpenLayers.Handler.Keyboard(control);
handler.active = false;
var deactivated = handler.deactivate(); // mock OpenLayers.Event.stopObserving
t.ok(!deactivated,
"deactivate returns false if the handler was not already active");
handler.active = true;
var old = OpenLayers.Event.stopObserving; var old = OpenLayers.Event.stopObserving;
var types = ["keydown", "keyup"];
OpenLayers.Event.stopObserving = function(obj, type, method) { OpenLayers.Event.stopObserving = function(obj, type, method) {
t.ok(obj == document, log[type] = obj;
"deactivate calls stopObserving with correct object"); var validType = OpenLayers.Util.indexOf(["keydown", "keyup"], type) != -1;
var validType = (OpenLayers.Util.indexOf(types, type) != -1);
t.ok(validType, "deactivate calls stopObserving for " + type); t.ok(validType, "deactivate calls stopObserving for " + type);
t.ok(method == handler.eventListener, t.ok(method == handler.eventListener,
"deactivate calls stopObserving with correct method"); "deactivate calls stopObserving with correct method");
}; };
handler.active = false;
var deactivated = handler.deactivate();
t.ok(!deactivated,
"deactivate returns false if the handler was not already active");
log = {};
handler.active = true;
handler.observeElement = map.div;
deactivated = handler.deactivate(); deactivated = handler.deactivate();
t.ok(log['keydown'] == map.div,
"deactivate calls stopObserving for keydown with correct object");
t.ok(log['keyup'] == map.div,
"deactivate calls stopObserving for keyup with correct object");
t.ok(deactivated, t.ok(deactivated,
"deactivate returns true if the handler was active already"); "deactivate returns true if the handler was active already");
log = {};
handler.active = true;
handler.observeElement = document;
deactivated = handler.deactivate();
t.ok(log['keydown'] == document,
"deactivate calls stopObserving for keydown with correct object");
t.ok(log['keyup'] == document,
"deactivate calls stopObserving for keyup with correct object");
t.ok(deactivated,
"deactivate returns true if the handler was active already");
OpenLayers.Event.stopObserving = old; OpenLayers.Event.stopObserving = old;
map.destroy();
} }

View File

@@ -268,10 +268,10 @@
map.destroy(); map.destroy();
map = new OpenLayers.Map("map"); map = new OpenLayers.Map("map");
layer = new OpenLayers.Layer("test", {projection: "EPSG:4326"}); layer = new OpenLayers.Layer("test", {projection: "unknown"});
map.addLayer(layer); map.addLayer(layer);
t.eq(layer.alwaysInRange, true, t.eq(layer.alwaysInRange, true,
"alwaysInRange true if only get projection."); "alwaysInRange true if unknown projection is set.");
map.destroy(); map.destroy();
map = new OpenLayers.Map("map"); map = new OpenLayers.Map("map");
@@ -764,7 +764,7 @@
} }
function test_layer_setTileSize(t) { function test_layer_setTileSize(t) {
t.plan(6); t.plan(4);
layer = new OpenLayers.Layer(); layer = new OpenLayers.Layer();
@@ -784,7 +784,6 @@
var size = new OpenLayers.Size(2,2); var size = new OpenLayers.Size(2,2);
layer.setTileSize(size); layer.setTileSize(size);
t.ok(layer.tileSize.equals(size), "size paramater set correctly to layer's tile size"); t.ok(layer.tileSize.equals(size), "size paramater set correctly to layer's tile size");
t.ok(layer.imageOffset == null, "imageOffset and imageSize null when no gutters")
//set on layer //set on layer
layer.tileSize = layerTileSize; layer.tileSize = layerTileSize;
@@ -803,10 +802,8 @@
size = new OpenLayers.Size(10,100); size = new OpenLayers.Size(10,100);
layer.setTileSize(size); layer.setTileSize(size);
var desiredImageOffset = new OpenLayers.Pixel(-15, -15);
var desiredImageSize = new OpenLayers.Size(40, 130); var desiredImageSize = new OpenLayers.Size(40, 130);
t.ok(layer.imageOffset.equals(desiredImageOffset), "image offset correctly calculated");
t.ok(layer.imageSize.equals(desiredImageSize), "image size correctly calculated"); t.ok(layer.imageSize.equals(desiredImageSize), "image size correctly calculated");
} }

View File

@@ -4,6 +4,9 @@
<script type="text/javascript">window.alert = oldAlert;</script> <script type="text/javascript">window.alert = oldAlert;</script>
<script src="../OLLoader.js"></script> <script src="../OLLoader.js"></script>
<script type="text/javascript"> <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 isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
var layer; var layer;

Some files were not shown because too many files have changed in this diff Show More