Merge branch 'master' into fixed-strategy

This commit is contained in:
friedjoff
2013-04-30 12:44:17 +02:00
330 changed files with 3632 additions and 1924 deletions

View File

@@ -379,7 +379,6 @@ Group: OpenLayers {
File: Popup (no auto-title, OpenLayers/Popup.js)
File: Anchored (no auto-title, OpenLayers/Popup/Anchored.js)
File: AnchoredBubble (no auto-title, OpenLayers/Popup/AnchoredBubble.js)
File: Framed (no auto-title, OpenLayers/Popup/Framed.js)
File: FramedCloud (no auto-title, OpenLayers/Popup/FramedCloud.js)
} # Group: Popup

View File

@@ -32,6 +32,13 @@ def build(config_file = None, output_file = None, options = None):
except ImportError:
print "No minimize"
try:
import uglify_js
uglify_js.check_available()
have_compressor.append("uglify-js")
except Exception, E:
print "No uglify-js (%s)" % E
use_compressor = None
if options.compressor and options.compressor in have_compressor:
use_compressor = options.compressor
@@ -52,7 +59,7 @@ def build(config_file = None, output_file = None, options = None):
print "Merging libraries."
try:
if use_compressor == "closure":
if use_compressor == "closure" or use_compressor == 'uglify-js':
sourceFiles = mergejs.getNames(sourceDirectory, configFilename)
else:
merged = mergejs.run(sourceDirectory, None, configFilename)
@@ -107,6 +114,14 @@ def build(config_file = None, output_file = None, options = None):
print "\nAbnormal termination due to compilation errors."
sys.exit("ERROR: Closure Compilation failed! See compilation errors.")
print "Closure Compilation has completed successfully."
elif use_compressor == "uglify-js":
minimized = uglify_js.compile(sourceFiles)
if minimized is None:
print "\nAbnormal termination due to compilation errors."
sys.exit("ERROR: Uglify JS compilation failed! See compilation errors.")
print "Uglify JS compilation has completed successfully."
else: # fallback
minimized = merged

View File

@@ -29,6 +29,7 @@ OpenLayers/Protocol/HTTP.js
OpenLayers/Protocol/WFS.js
OpenLayers/Protocol/WFS/v1_0_0.js
OpenLayers/Strategy/Fixed.js
OpenLayers/TileManager.js
[exclude]

View File

@@ -379,7 +379,6 @@ Group: OpenLayers {
File: Popup (no auto-title, OpenLayers/Popup.js)
File: Anchored (no auto-title, OpenLayers/Popup/Anchored.js)
File: AnchoredBubble (no auto-title, OpenLayers/Popup/AnchoredBubble.js)
File: Framed (no auto-title, OpenLayers/Popup/Framed.js)
File: FramedCloud (no auto-title, OpenLayers/Popup/FramedCloud.js)
} # Group: Popup

View File

@@ -1,35 +1,21 @@
var streets = new OpenLayers.Layer.XYZ(
"MapBox Streets",
var earth = new OpenLayers.Layer.XYZ(
"Natural Earth",
[
"http://a.tiles.mapbox.com/v3/mapbox.mapbox-streets/${z}/${x}/${y}.png",
"http://b.tiles.mapbox.com/v3/mapbox.mapbox-streets/${z}/${x}/${y}.png",
"http://c.tiles.mapbox.com/v3/mapbox.mapbox-streets/${z}/${x}/${y}.png",
"http://d.tiles.mapbox.com/v3/mapbox.mapbox-streets/${z}/${x}/${y}.png"
"http://a.tiles.mapbox.com/v3/mapbox.natural-earth-hypso-bathy/${z}/${x}/${y}.png",
"http://b.tiles.mapbox.com/v3/mapbox.natural-earth-hypso-bathy/${z}/${x}/${y}.png",
"http://c.tiles.mapbox.com/v3/mapbox.natural-earth-hypso-bathy/${z}/${x}/${y}.png",
"http://d.tiles.mapbox.com/v3/mapbox.natural-earth-hypso-bathy/${z}/${x}/${y}.png"
], {
attribution: "Tiles &copy; <a href='http://mapbox.com/'>MapBox</a> | " +
"Data &copy; <a href='http://www.openstreetmap.org/'>OpenStreetMap</a> " +
"and contributors, CC-BY-SA",
attribution: "Tiles &copy; <a href='http://mapbox.com/'>MapBox</a>",
sphericalMercator: true,
wrapDateLine: true,
transitionEffect: "resize",
buffer: 1,
numZoomLevels: 17
numZoomLevels: 5
}
);
var map = new OpenLayers.Map({
div: "map",
layers: [streets],
controls: [
new OpenLayers.Control.Attribution(),
new OpenLayers.Control.Navigation({
dragPanOptions: {
enableKinetic: true
}
}),
new OpenLayers.Control.Zoom(),
new OpenLayers.Control.Permalink({anchor: true})
],
layers: [earth],
center: [0, 0],
zoom: 1
});

View File

@@ -5,10 +5,10 @@ var map = new OpenLayers.Map({
new OpenLayers.Layer.XYZ(
"OpenStreetMap",
[
"http://otile1.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png",
"http://otile2.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png",
"http://otile3.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png",
"http://otile4.mqcdn.com/tiles/1.0.0/osm/${z}/${x}/${y}.png"
"http://otile1.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.png",
"http://otile2.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.png",
"http://otile3.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.png",
"http://otile4.mqcdn.com/tiles/1.0.0/map/${z}/${x}/${y}.png"
],
{
attribution: "Data, imagery and map information provided by <a href='http://www.mapquest.com/' target='_blank'>MapQuest</a>, <a href='http://www.openstreetmap.org/' target='_blank'>Open Street Map</a> and contributors, <a href='http://creativecommons.org/licenses/by-sa/2.0/' target='_blank'>CC-BY-SA</a> <img src='http://developer.mapquest.com/content/osm/mq_logo.png' border='0'>",
@@ -18,10 +18,10 @@ var map = new OpenLayers.Map({
new OpenLayers.Layer.XYZ(
"Imagery",
[
"http://oatile1.mqcdn.com/naip/${z}/${x}/${y}.png",
"http://oatile2.mqcdn.com/naip/${z}/${x}/${y}.png",
"http://oatile3.mqcdn.com/naip/${z}/${x}/${y}.png",
"http://oatile4.mqcdn.com/naip/${z}/${x}/${y}.png"
"http://otile1.mqcdn.com/tiles/1.0.0/sat/${z}/${x}/${y}.png",
"http://otile2.mqcdn.com/tiles/1.0.0/sat/${z}/${x}/${y}.png",
"http://otile3.mqcdn.com/tiles/1.0.0/sat/${z}/${x}/${y}.png",
"http://otile4.mqcdn.com/tiles/1.0.0/sat/${z}/${x}/${y}.png"
],
{
attribution: "Tiles Courtesy of <a href='http://open.mapquest.co.uk/' target='_blank'>MapQuest</a>. Portions Courtesy NASA/JPL-Caltech and U.S. Depart. of Agriculture, Farm Service Agency. <img src='http://developer.mapquest.com/content/osm/mq_logo.png' border='0'>",

View File

@@ -5,7 +5,15 @@ function init() {
styleMap: new OpenLayers.StyleMap({
temporary: OpenLayers.Util.applyDefaults({
pointRadius: 16
}, OpenLayers.Feature.Vector.style.temporary)
}, OpenLayers.Feature.Vector.style.temporary),
'default': OpenLayers.Util.applyDefaults({
pointRadius: 16,
strokeWidth: 3,
}, OpenLayers.Feature.Vector.style['default']),
select: OpenLayers.Util.applyDefaults({
pointRadius: 16,
strokeWidth: 3
}, OpenLayers.Feature.Vector.style.select)
})
});

View File

@@ -12,14 +12,48 @@ html, body, #map {
#title, #tags, #shortdesc {
display: none;
}
div.olMapViewport {
-ms-touch-action: none;
}
/* Turn on GPU support where available */
.olTileImage {
-webkit-transform: translateZ(0);
-moz-transform: translateZ(0);
-o-transform: translateZ(0);
-ms-transform: translateZ(0);
transform: translateZ(0);
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-ms-backface-visibility: hidden;
backface-visibility: hidden;
-webkit-perspective: 1000;
-moz-perspective: 1000;
-ms-perspective: 1000;
perspective: 1000;
}
/* Tile fade animation */
.olLayerGrid .olTileImage {
-webkit-transition: opacity 0.2s linear;
-moz-transition: opacity 0.2s linear;
-o-transition: opacity 0.2s linear;
transition: opacity 0.2s linear;
/* workaround for strange border tile squeezing on Android 4.x */
-webkit-transform: scale(1.001);
}
/* Zoom Box */
.olHandlerBoxZoomBox {
border: 2px solid red;
position: absolute;
background-color: white;
opacity: 0.50;
font-size: 1px;
filter: alpha(opacity=50);
}
.olDrawBox {
cursor: crosshair;
}
div.olControlAttribution {
position: absolute;
font-size: 10px;

View File

@@ -46,9 +46,10 @@ var map;
// Geolocate control for the Locate button - the locationupdated handler
// draws a cross at the location and a circle showing the accuracy radius.
zoomPanel.addControls([
new OpenLayers.Control.Geolocate({
var geolocate = new OpenLayers.Control.Geolocate({
type: OpenLayers.Control.TYPE_TOGGLE,
bind: false,
watch: true,
geolocationOptions: {
enableHighAccuracy: false,
maximumAge: 0,
@@ -87,8 +88,11 @@ var map;
map.zoomToExtent(vector.getDataExtent());
}
}
})
]);
});
zoomPanel.addControls([geolocate]);
// Fallback layer when outside Vienna
var osm = new OpenLayers.Layer.OSM();
// Map with navigation controls optimized for touch devices
map = new OpenLayers.Map({
@@ -96,23 +100,11 @@ var map;
theme: null,
projection: "EPSG:3857",
units: "m",
maxExtent: [-20037508.34, -20037508.34, 20037508.34, 20037508.34],
maxResolution: 156543.0339,
numZoomLevels: 20,
maxResolution: 38.21851413574219,
numZoomLevels: 8,
tileManager: new OpenLayers.TileManager(),
controls: [
new OpenLayers.Control.Navigation({
mouseWheelOptions: {
cumulative: false,
interval: 20
},
dragPanOptions: {
enableKinetic: {
deceleration: 0.02
}
},
zoomBoxEnabled: false
}),
new OpenLayers.Control.Navigation(),
new OpenLayers.Control.Attribution(),
zoomPanel,
layerPanel
@@ -122,6 +114,15 @@ var map;
// update anchor for permalinks
var ctr = map.getCenter();
window.location.hash = "x="+ctr.lon+"&y="+ctr.lat+"&z="+map.getZoom();
// switch to OSM when outside Vienna
if (!map.getExtent().intersectsBounds(fmzk.tileFullExtent)) {
if (map.baseLayer !== osm) {
map.addLayer(osm);
map.setBaseLayer(osm);
}
} else if (map.baseLayer === osm) {
map.removeLayer(osm);
}
}
}
});
@@ -133,6 +134,7 @@ var map;
// Defaults for the WMTS layers
var defaults = {
zoomOffset: 12,
requestEncoding: "REST",
matrixSet: "google3857",
attribution: 'Datenquelle: Stadt Wien - <a href="http://data.wien.gv.at">data.wien.gv.at</a>'
@@ -160,13 +162,13 @@ var map;
var doc = request.responseText,
caps = format.read(doc);
fmzk = format.createLayer(caps, OpenLayers.Util.applyDefaults(
{layer:"fmzk", transitionEffect:"resize"}, defaults
{layer:"fmzk"}, defaults
));
aerial = format.createLayer(caps, OpenLayers.Util.applyDefaults(
{layer:"lb", transitionEffect:"resize"}, defaults
{layer:"lb"}, defaults
));
labels = format.createLayer(caps, OpenLayers.Util.applyDefaults(
{layer:"beschriftung", isBaseLayer: false},
{layer:"beschriftung", isBaseLayer: false, transitionEffect: 'map-resize'},
defaults
));
map.addLayers([fmzk, aerial, labels]);
@@ -182,25 +184,41 @@ var map;
var extent = new OpenLayers.Bounds(1799448.394855, 6124949.74777, 1848250.442089, 6162571.828177);
defaults.tileFullExtent = extent;
fmzk = new OpenLayers.Layer.WMTS(OpenLayers.Util.applyDefaults({
url: "http://maps.wien.gv.at/wmts/fmzk/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpeg",
url: [
"http://maps.wien.gv.at/wmts/fmzk/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpeg",
"http://maps1.wien.gv.at/wmts/fmzk/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpeg",
"http://maps2.wien.gv.at/wmts/fmzk/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpeg",
"http://maps3.wien.gv.at/wmts/fmzk/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpeg",
"http://maps4.wien.gv.at/wmts/fmzk/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpeg"
],
layer: "fmzk",
style: "pastell",
transitionEffect: "resize"
style: "pastell"
},
defaults));
aerial = new OpenLayers.Layer.WMTS(OpenLayers.Util.applyDefaults({
url: "http://maps.wien.gv.at/wmts/lb/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpeg",
url: [
"http://maps.wien.gv.at/wmts/lb/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpeg",
"http://maps1.wien.gv.at/wmts/lb/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpeg",
"http://maps2.wien.gv.at/wmts/lb/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpeg",
"http://maps3.wien.gv.at/wmts/lb/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpeg",
"http://maps4.wien.gv.at/wmts/lb/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpeg"
],
layer: "lb",
style: "farbe",
transitionEffect: "resize"
style: "farbe"
},
defaults));
labels = new OpenLayers.Layer.WMTS(OpenLayers.Util.applyDefaults({
url: "http://maps.wien.gv.at/wmts/beschriftung/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png",
url: [
"http://maps.wien.gv.at/wmts/beschriftung/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png",
"http://maps1.wien.gv.at/wmts/beschriftung/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png",
"http://maps2.wien.gv.at/wmts/beschriftung/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png",
"http://maps3.wien.gv.at/wmts/beschriftung/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png",
"http://maps4.wien.gv.at/wmts/beschriftung/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png"
],
layer: "beschriftung",
style: "normal",
transitionEffect: null,
isBaseLayer: false
isBaseLayer: false,
transitionEffect: 'map-resize'
},
defaults));
map.addLayers([fmzk, aerial, labels]);

View File

@@ -0,0 +1,41 @@
<!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>Switch between polar projections</title>
<link rel="stylesheet" href="../theme/default/style.css" type="text/css">
<link rel="stylesheet" href="style.css" type="text/css">
<script type="text/javascript" src="http://svn.osgeo.org/metacrs/proj4js/trunk/lib/proj4js-compressed.js"></script>
<script type="text/javascript" src="http://spatialreference.org/ref/epsg/3574/proj4js/"></script>
<script type="text/javascript" src="http://spatialreference.org/ref/epsg/3576/proj4js/"></script>
<script type="text/javascript" src="http://spatialreference.org/ref/epsg/3571/proj4js/"></script>
<script type="text/javascript" src="http://spatialreference.org/ref/epsg/3573/proj4js/"></script>
<script type="text/javascript" src="../lib/OpenLayers.js"></script>
<script type="text/javascript" src="polar-projections.js"></script>
</head>
<body onload="init()">
<h1 id="title">Polar Projections WMS Example</h1>
<div id="tags">
switch projections polar
</div>
<div id="shortdesc">Switch between different projections</div>
<div id="map" class="smallmap" style="height:512px"></div>
<button id='epsg3574'>EPSG:3574</button>
<button id='epsg3576'>EPSG:3576</button>
<button id='epsg3571'>EPSG:3571</button>
<button id='epsg3573'>EPSG:3573</button>
<div id="docs">
<p>This example shows how to switch between different projections,
maintaining the center and resolution.</p>
<p>Click the buttons above to try it, and see
<a href='polar-projections.js'>polar-projections.js</a> for the
source code.</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,84 @@
var map, layer, overlay;
var projectionOptions = {
'EPSG:3574': {
projection: new OpenLayers.Projection('EPSG:3574'),
units: 'm',
maxExtent: new OpenLayers.Bounds(-5505054, -5505054, 5505054, 5505054),
maxResolution: 5505054 / 128,
numZoomLevels: 18
},
'EPSG:3576': {
projection: new OpenLayers.Projection('EPSG:3576'),
units: 'm',
maxExtent: new OpenLayers.Bounds(-5505054, -5505054, 5505054, 5505054),
maxResolution: 5505054 / 128,
numZoomLevels: 18
},
'EPSG:3571': {
projection: new OpenLayers.Projection('EPSG:3571'),
units: 'm',
maxExtent: new OpenLayers.Bounds(-5505054, -5505054, 5505054, 5505054),
maxResolution: 5505054 / 128,
numZoomLevels: 18
},
'EPSG:3573': {
projection: new OpenLayers.Projection('EPSG:3573'),
units: 'm',
maxExtent: new OpenLayers.Bounds(-5505054, -5505054, 5505054, 5505054),
maxResolution: 5505054 / 128,
numZoomLevels: 18
}
};
function setProjection() {
projCode = this.innerHTML;
var oldExtent = map.getExtent();
var oldCenter = map.getCenter();
var oldProjection = map.getProjectionObject();
// map projection is controlled by the base layer
map.baseLayer.addOptions(projectionOptions[projCode]);
// with the base layer updated, the map has the new projection now
var newProjection = map.getProjectionObject();
// transform the center of the old projection, not the extent
map.setCenter(
oldCenter.transform(oldProjection, newProjection,
map.getZoomForExtent(oldExtent.transform(oldProjection, newProjection))
));
for (var i=map.layers.length-1; i>=0; --i) {
// update grid settings
map.layers[i].addOptions(projectionOptions[projCode]);
// redraw layer - just in case center and zoom are the same in old and
// new projection
map.layers[i].redraw();
}
}
function init() {
map = new OpenLayers.Map('map');
layer = new OpenLayers.Layer.WMS(
'world',
'http://v2.suite.opengeo.org/geoserver/wms',
{layers: 'world', version: '1.1.1'},
projectionOptions['EPSG:3574']
);
overlay = new OpenLayers.Layer.WMS(
'world',
'http://v2.suite.opengeo.org/geoserver/wms',
{transparent: 'true', layers: 'world:borders', styles: 'line'},
projectionOptions['EPSG:3574']
);
overlay.isBaseLayer = false;
map.addLayers([layer, overlay]);
map.zoomToMaxExtent();
// add behaviour to dom elements
document.getElementById('epsg3574').onclick = setProjection;
document.getElementById('epsg3576').onclick = setProjection;
document.getElementById('epsg3571').onclick = setProjection;
document.getElementById('epsg3573').onclick = setProjection;
}

View File

@@ -144,8 +144,6 @@
"OpenLayers/Console.js",
"OpenLayers/Tween.js",
"OpenLayers/Kinetic.js",
"Rico/Corner.js",
"Rico/Color.js",
"OpenLayers/Events.js",
"OpenLayers/Events/buttonclick.js",
"OpenLayers/Request.js",
@@ -191,7 +189,6 @@
"OpenLayers/Layer/Zoomify.js",
"OpenLayers/Layer/ArcGISCache.js",
"OpenLayers/Popup/Anchored.js",
"OpenLayers/Popup/AnchoredBubble.js",
"OpenLayers/Popup/Framed.js",
"OpenLayers/Popup/FramedCloud.js",
"OpenLayers/Feature.js",

View File

@@ -1,9 +1,9 @@
/**
* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
* full list of contributors). Published under the 2-clause BSD license.
* See license.txt in the OpenLayers distribution or repository for the
* full text of the license.
*
* full text of the license. */
/**
* @requires OpenLayers/SingleFile.js
* @requires OpenLayers/Util/vendorPrefix.js
*/

View File

@@ -127,7 +127,9 @@ OpenLayers.String = {
if (i == 0) {
replacement = context;
}
if (replacement === undefined) {
break;
}
replacement = replacement[subs[i]];
}
@@ -295,6 +297,24 @@ OpenLayers.Number = {
str = integer + dsep + rem;
}
return str;
},
/**
* Method: zeroPad
* Create a zero padded string optionally with a radix for casting numbers.
*
* Parameters:
* num - {Number} The number to be zero padded.
* len - {Number} The length of the string to be returned.
* radix - {Number} An integer between 2 and 36 specifying the base to use
* for representing numeric values.
*/
zeroPad: function(num, len, radix) {
var str = num.toString(radix || 10);
while (str.length < len) {
str = "0" + str;
}
return str;
}
};

View File

@@ -63,7 +63,7 @@ OpenLayers.Bounds = OpenLayers.Class({
* left - {Number} The left bounds of the box. Note that for width
* calculations, this is assumed to be less than the right value.
* bottom - {Number} The bottom bounds of the box. Note that for height
* calculations, this is assumed to be more than the top value.
* calculations, this is assumed to be less than the top value.
* right - {Number} The right bounds.
* top - {Number} The top bounds.
*
@@ -355,39 +355,59 @@ OpenLayers.Bounds = OpenLayers.Class({
* object.
*/
extend:function(object) {
var bounds = null;
if (object) {
// clear cached center location
switch(object.CLASS_NAME) {
case "OpenLayers.LonLat":
bounds = new OpenLayers.Bounds(object.lon, object.lat,
object.lon, object.lat);
this.extendXY(object.lon, object.lat);
break;
case "OpenLayers.Geometry.Point":
bounds = new OpenLayers.Bounds(object.x, object.y,
object.x, object.y);
this.extendXY(object.x, object.y);
break;
case "OpenLayers.Bounds":
bounds = object;
// clear cached center location
this.centerLonLat = null;
if ( (this.left == null) || (object.left < this.left)) {
this.left = object.left;
}
if ( (this.bottom == null) || (object.bottom < this.bottom) ) {
this.bottom = object.bottom;
}
if ( (this.right == null) || (object.right > this.right) ) {
this.right = object.right;
}
if ( (this.top == null) || (object.top > this.top) ) {
this.top = object.top;
}
break;
}
}
},
if (bounds) {
/**
* APIMethod: extendXY
* Extend the bounds to include the XY coordinate specified.
*
* Parameters:
* x - {number} The X part of the the coordinate.
* y - {number} The Y part of the the coordinate.
*/
extendXY:function(x, y) {
// clear cached center location
this.centerLonLat = null;
if ( (this.left == null) || (bounds.left < this.left)) {
this.left = bounds.left;
if ((this.left == null) || (x < this.left)) {
this.left = x;
}
if ( (this.bottom == null) || (bounds.bottom < this.bottom) ) {
this.bottom = bounds.bottom;
}
if ( (this.right == null) || (bounds.right > this.right) ) {
this.right = bounds.right;
}
if ( (this.top == null) || (bounds.top > this.top) ) {
this.top = bounds.top;
if ((this.bottom == null) || (y < this.bottom)) {
this.bottom = y;
}
if ((this.right == null) || (x > this.right)) {
this.right = x;
}
if ((this.top == null) || (y > this.top)) {
this.top = y;
}
},

View File

@@ -49,13 +49,6 @@ OpenLayers.Date = {
return date.toISOString();
};
} else {
function pad(num, len) {
var str = num + "";
while (str.length < len) {
str = "0" + str;
}
return str;
}
return function(date) {
var str;
if (isNaN(date.getTime())) {
@@ -65,12 +58,12 @@ OpenLayers.Date = {
} else {
str =
date.getUTCFullYear() + "-" +
pad(date.getUTCMonth() + 1, 2) + "-" +
pad(date.getUTCDate(), 2) + "T" +
pad(date.getUTCHours(), 2) + ":" +
pad(date.getUTCMinutes(), 2) + ":" +
pad(date.getUTCSeconds(), 2) + "." +
pad(date.getUTCMilliseconds(), 3) + "Z";
OpenLayers.Number.zeroPad(date.getUTCMonth() + 1, 2) + "-" +
OpenLayers.Number.zeroPad(date.getUTCDate(), 2) + "T" +
OpenLayers.Number.zeroPad(date.getUTCHours(), 2) + ":" +
OpenLayers.Number.zeroPad(date.getUTCMinutes(), 2) + ":" +
OpenLayers.Number.zeroPad(date.getUTCSeconds(), 2) + "." +
OpenLayers.Number.zeroPad(date.getUTCMilliseconds(), 3) + "Z";
}
return str;
};

View File

@@ -56,11 +56,11 @@ OpenLayers.Control.DragPan = OpenLayers.Class(OpenLayers.Control, {
* {Boolean} Set this option to enable "kinetic dragging". Can be
* set to true or to an object. If set to an object this
* object will be passed to the {<OpenLayers.Kinetic>}
* constructor. Defaults to false.
* If you set this property, you should ensure that
* OpenLayers/Kinetic.js is included in your build config
* constructor. Defaults to true.
* To get kinetic dragging, ensure that OpenLayers/Kinetic.js is
* included in your build config.
*/
enableKinetic: false,
enableKinetic: true,
/**
* APIProperty: kineticInterval
@@ -77,7 +77,7 @@ OpenLayers.Control.DragPan = OpenLayers.Class(OpenLayers.Control, {
* <panMapDone> as callbacks.
*/
draw: function() {
if(this.enableKinetic) {
if (this.enableKinetic && OpenLayers.Kinetic) {
var config = {interval: this.kineticInterval};
if(typeof this.enableKinetic === "object") {
config = OpenLayers.Util.extend(config, this.enableKinetic);

View File

@@ -45,8 +45,15 @@ OpenLayers.Control.Geolocate = OpenLayers.Class(OpenLayers.Control, {
/**
* Property: geolocation
* {Object} The geolocation engine, as a property to be possibly mocked.
* This is set lazily to avoid a memory leak in IE9.
*/
geolocation: navigator.geolocation,
geolocation: null,
/**
* Property: available
* {Boolean} The navigator.geolocation object is available.
*/
available: ('geolocation' in navigator),
/**
* APIProperty: bind
@@ -90,6 +97,10 @@ OpenLayers.Control.Geolocate = OpenLayers.Class(OpenLayers.Control, {
* {Boolean} The control was effectively activated.
*/
activate: function () {
if (this.available && !this.geolocation) {
// set lazily to avoid IE9 memory leak
this.geolocation = navigator.geolocation;
}
if (!this.geolocation) {
this.events.triggerEvent("locationuncapable");
return false;

View File

@@ -6,7 +6,7 @@
/**
* @requires OpenLayers/Control.js
* @requires OpenLayers/Lang.js
* @requires OpenLayers/Console.js
* @requires OpenLayers/Util.js
* @requires OpenLayers/Events/buttonclick.js
*/
@@ -23,26 +23,7 @@
* Inherits from:
* - <OpenLayers.Control>
*/
OpenLayers.Control.LayerSwitcher =
OpenLayers.Class(OpenLayers.Control, {
/**
* APIProperty: roundedCorner
* {Boolean} If true the Rico library is used for rounding the corners
* of the layer switcher div, defaults to false. *Deprecated*. Use
* CSS3's border-radius instead. If this option is set to true the
* Rico/Corner.js script must be loaded in the page, and therefore
* listed in the build profile.
*
*/
roundedCorner: false,
/**
* APIProperty: roundedCornerColor
* {String} The color of the rounded corners, only applies if roundedCorner
* is true, defaults to "darkblue".
*/
roundedCornerColor: "darkblue",
OpenLayers.Control.LayerSwitcher = OpenLayers.Class(OpenLayers.Control, {
/**
* Property: layerStates
@@ -52,7 +33,6 @@ OpenLayers.Control.LayerSwitcher =
*/
layerStates: null,
// DOM Elements
/**
@@ -120,10 +100,6 @@ OpenLayers.Control.LayerSwitcher =
initialize: function(options) {
OpenLayers.Control.prototype.initialize.apply(this, arguments);
this.layerStates = [];
if(this.roundedCorner) {
OpenLayers.Console.warn('roundedCorner option is deprecated');
}
},
/**
@@ -246,24 +222,23 @@ OpenLayers.Control.LayerSwitcher =
* {Boolean} The layer state changed since the last redraw() call.
*/
checkRedraw: function() {
var redraw = false;
if ( !this.layerStates.length ||
(this.map.layers.length != this.layerStates.length) ) {
redraw = true;
} else {
for (var i=0, len=this.layerStates.length; i<len; i++) {
return true;
}
for (var i = 0, len = this.layerStates.length; i < len; i++) {
var layerState = this.layerStates[i];
var layer = this.map.layers[i];
if ( (layerState.name != layer.name) ||
(layerState.inRange != layer.inRange) ||
(layerState.id != layer.id) ||
(layerState.visibility != layer.visibility) ) {
redraw = true;
break;
return true;
}
}
}
return redraw;
return false;
},
/**
@@ -325,8 +300,14 @@ OpenLayers.Control.LayerSwitcher =
: layer.getVisibility();
// create input element
var inputElem = document.createElement("input");
inputElem.id = this.id + "_input_" + layer.name;
var inputElem = document.createElement("input"),
// The input shall have an id attribute so we can use
// labels to interact with them.
inputId = OpenLayers.Util.createUniqueID(
this.id + "_input_"
);
inputElem.id = inputId;
inputElem.name = (baseLayer) ? this.id + "_baseLayers" : layer.name;
inputElem.type = (baseLayer) ? "radio" : "checkbox";
inputElem.value = layer.name;
@@ -342,6 +323,8 @@ OpenLayers.Control.LayerSwitcher =
// create span
var labelSpan = document.createElement("label");
// this isn't the DOM attribute 'for', but an arbitrary name we
// use to find the appropriate input element in <onButtonClick>
labelSpan["for"] = inputElem.id;
OpenLayers.Element.addClass(labelSpan, "labelSpan olButton");
labelSpan._layer = layer.id;
@@ -507,16 +490,6 @@ OpenLayers.Control.LayerSwitcher =
this.div.appendChild(this.layersDiv);
if(this.roundedCorner) {
OpenLayers.Rico.Corner.round(this.div, {
corners: "tl bl",
bgColor: "transparent",
color: this.roundedCornerColor,
blend: false
});
OpenLayers.Rico.Corner.changeOpacity(this.layersDiv, 0.75);
}
// maximize button div
var img = OpenLayers.Util.getImageLocation('layer-switcher-maximize.png');
this.maximizeDiv = OpenLayers.Util.createAlphaImageDiv(

View File

@@ -49,14 +49,14 @@ OpenLayers.Control.Measure = OpenLayers.Class(OpenLayers.Control, {
callbacks: null,
/**
* Property: displaySystem
* APIProperty: displaySystem
* {String} Display system for output measurements. Supported values
* are 'english', 'metric', and 'geographic'. Default is 'metric'.
*/
displaySystem: 'metric',
/**
* Property: geodesic
* APIProperty: geodesic
* {Boolean} Calculate geodesic metrics instead of planar metrics. This
* requires that geometries can be transformed into Geographic/WGS84
* (if that is not already the map projection). Default is false.
@@ -226,8 +226,10 @@ OpenLayers.Control.Measure = OpenLayers.Class(OpenLayers.Control, {
* Method: measureImmediate
* Called each time the measurement sketch is modified.
*
* Parameters: point - {<OpenLayers.Geometry.Point>} The point at the
* mouseposition. feature - {<OpenLayers.Feature.Vector>} The sketch feature.
* Parameters:
* point - {<OpenLayers.Geometry.Point>} The point at the mouse position.
* feature - {<OpenLayers.Feature.Vector>} The sketch feature.
* drawing - {Boolean} Indicates whether we're currently drawing.
*/
measureImmediate : function(point, feature, drawing) {
if (drawing && !this.handler.freehandMode(this.handler.evt)) {

View File

@@ -4,8 +4,7 @@
* full text of the license. */
/**
* @requires OpenLayers/Control/DragFeature.js
* @requires OpenLayers/Control/SelectFeature.js
* @requires OpenLayers/Handler/Drag.js
* @requires OpenLayers/Handler/Keyboard.js
*/
@@ -74,6 +73,12 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
*/
feature: null,
/**
* Property: vertex
* {<OpenLayers.Feature.Vector>} Vertex currently being modified.
*/
vertex: null,
/**
* Property: vertices
* {Array(<OpenLayers.Feature.Vector>)} Verticies currently available
@@ -88,18 +93,6 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
*/
virtualVertices: null,
/**
* Property: selectControl
* {<OpenLayers.Control.SelectFeature>}
*/
selectControl: null,
/**
* Property: dragControl
* {<OpenLayers.Control.DragFeature>}
*/
dragControl: null,
/**
* Property: handlers
* {Object}
@@ -232,64 +225,50 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
if(!(OpenLayers.Util.isArray(this.deleteCodes))) {
this.deleteCodes = [this.deleteCodes];
}
var control = this;
// configure the select control
var selectOptions = {
geometryTypes: this.geometryTypes,
clickout: this.clickout,
toggle: this.toggle,
onBeforeSelect: this.beforeSelectFeature,
onSelect: this.selectFeature,
onUnselect: this.unselectFeature,
scope: this
};
if(this.standalone === false) {
this.selectControl = new OpenLayers.Control.SelectFeature(
layer, selectOptions
);
// configure the drag handler
var dragCallbacks = {
down: function(pixel) {
this.vertex = null;
var feature = this.layer.getFeatureFromEvent(
this.handlers.drag.evt);
if (feature) {
this.dragStart(feature);
} else if (this.feature && this.clickout) {
this.unselectFeature(this.feature);
}
// configure the drag control
},
move: function(pixel) {
delete this._unselect;
if (this.vertex) {
this.dragVertex(this.vertex, pixel);
}
},
up: function() {
this.handlers.drag.stopDown = false;
if (this._unselect) {
this.unselectFeature(this._unselect);
delete this._unselect;
}
},
done: function(pixel) {
if (this.vertex) {
this.dragComplete(this.vertex);
}
}
};
var dragOptions = {
documentDrag: this.documentDrag,
geometryTypes: ["OpenLayers.Geometry.Point"],
onStart: function(feature, pixel) {
control.dragStart.apply(control, [feature, pixel]);
},
onDrag: function(feature, pixel) {
control.dragVertex.apply(control, [feature, pixel]);
},
onComplete: function(feature) {
control.dragComplete.apply(control, [feature]);
},
featureCallbacks: {
over: function(feature) {
/**
* In normal mode, the feature handler is set up to allow
* dragging of all points. In standalone mode, we only
* want to allow dragging of sketch vertices and virtual
* vertices - or, in the case of a modifiable point, the
* point itself.
*/
if(control.standalone !== true || feature._sketch ||
control.feature === feature) {
control.dragControl.overFeature.apply(
control.dragControl, [feature]);
}
}
}
stopDown: false
};
this.dragControl = new OpenLayers.Control.DragFeature(
layer, dragOptions
);
// configure the keyboard handler
var keyboardOptions = {
keydown: this.handleKeypress
};
this.handlers = {
keyboard: new OpenLayers.Handler.Keyboard(this, keyboardOptions)
keyboard: new OpenLayers.Handler.Keyboard(this, keyboardOptions),
drag: new OpenLayers.Handler.Drag(this, dragCallbacks, dragOptions)
};
},
@@ -298,9 +277,14 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
* Take care of things that are not handled in superclass.
*/
destroy: function() {
if (this.map) {
this.map.events.un({
"removelayer": this.handleMapEvents,
"changelayer": this.handleMapEvents,
scope: this
});
}
this.layer = null;
this.standalone || this.selectControl.destroy();
this.dragControl.destroy();
OpenLayers.Control.prototype.destroy.apply(this, []);
},
@@ -312,8 +296,14 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
* {Boolean} Successfully activated the control.
*/
activate: function() {
return ((this.standalone || this.selectControl.activate()) &&
this.handlers.keyboard.activate() &&
this.moveLayerToTop();
this.map.events.on({
"removelayer": this.handleMapEvents,
"changelayer": this.handleMapEvents,
scope: this
});
return (this.handlers.keyboard.activate() &&
this.handlers.drag.activate() &&
OpenLayers.Control.prototype.activate.apply(this, arguments));
},
@@ -328,24 +318,21 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
var deactivated = false;
// the return from the controls is unimportant in this case
if(OpenLayers.Control.prototype.deactivate.apply(this, arguments)) {
this.moveLayerBack();
this.map.events.un({
"removelayer": this.handleMapEvents,
"changelayer": this.handleMapEvents,
scope: this
});
this.layer.removeFeatures(this.vertices, {silent: true});
this.layer.removeFeatures(this.virtualVertices, {silent: true});
this.vertices = [];
this.dragControl.deactivate();
this.handlers.drag.deactivate();
this.handlers.keyboard.deactivate();
var feature = this.feature;
var valid = feature && feature.geometry && feature.layer;
if(this.standalone === false) {
if(valid) {
this.selectControl.unselect.apply(this.selectControl,
[feature]);
}
this.selectControl.deactivate();
} else {
if(valid) {
if (feature && feature.geometry && feature.layer) {
this.unselectFeature(feature);
}
}
this.handlers.keyboard.deactivate();
deactivated = true;
}
return deactivated;
@@ -367,19 +354,27 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
/**
* APIMethod: selectFeature
* Select a feature for modification in standalone mode. In non-standalone
* mode, this method is called when the select feature control selects a
* feature. Register a listener to the beforefeaturemodified event and
* return false to prevent feature modification.
* mode, this method is called when a feature is selected by clicking.
* Register a listener to the beforefeaturemodified event and return false
* to prevent feature modification.
*
* Parameters:
* feature - {<OpenLayers.Feature.Vector>} the selected feature.
*/
selectFeature: function(feature) {
if (!this.standalone || this.beforeSelectFeature(feature) !== false) {
if (this.geometryTypes && OpenLayers.Util.indexOf(this.geometryTypes,
feature.geometry.CLASS_NAME) == -1) {
return;
}
if (this.beforeSelectFeature(feature) !== false) {
if (this.feature) {
this.unselectFeature(this.feature);
}
this.feature = feature;
this.layer.selectedFeatures.push(feature);
this.layer.drawFeature(feature, 'select');
this.modified = false;
this.resetVertices();
this.dragControl.activate();
this.onModificationStart(this.feature);
}
// keep track of geometry modifications
@@ -409,8 +404,9 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
this.layer.destroyFeatures([this.radiusHandle], {silent: true});
delete this.radiusHandle;
}
this.layer.drawFeature(this.feature, 'default');
this.feature = null;
this.dragControl.deactivate();
OpenLayers.Util.removeItem(this.layer.selectedFeatures, feature);
this.onModificationEnd(feature);
this.layer.events.triggerEvent("afterfeaturemodified", {
feature: feature,
@@ -419,63 +415,47 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
this.modified = false;
},
/**
* Method: dragStart
* Called by the drag feature control with before a feature is dragged.
* This method is used to differentiate between points and vertices
* of higher order geometries. This respects the <geometryTypes>
* property and forces a select of points when the drag control is
* already active (and stops events from propagating to the select
* control).
* Called by the drag handler before a feature is dragged. This method is
* used to differentiate between points and vertices
* of higher order geometries.
*
* Parameters:
* feature - {<OpenLayers.Feature.Vector>} The point or vertex about to be
* dragged.
* pixel - {<OpenLayers.Pixel>} Pixel location of the mouse event.
*/
dragStart: function(feature, pixel) {
// only change behavior if the feature is not in the vertices array
if(feature != this.feature && !feature.geometry.parent &&
feature != this.dragHandle && feature != this.radiusHandle) {
if(this.standalone === false && this.feature) {
// unselect the currently selected feature
this.selectControl.clickFeature.apply(this.selectControl,
[this.feature]);
dragStart: function(feature) {
var isPoint = feature.geometry.CLASS_NAME ==
'OpenLayers.Geometry.Point';
if (!this.standalone &&
((!feature._sketch && isPoint) || !feature._sketch)) {
if (this.toggle && this.feature === feature) {
// mark feature for unselection
this._unselect = feature;
}
// check any constraints on the geometry type
if(this.geometryTypes == null ||
OpenLayers.Util.indexOf(this.geometryTypes,
feature.geometry.CLASS_NAME) != -1) {
// select the point
this.standalone || this.selectControl.clickFeature.apply(
this.selectControl, [feature]);
/**
* TBD: These lines improve workflow by letting the user
* immediately start dragging after the mouse down.
* However, it is very ugly to be messing with controls
* and their handlers in this way. I'd like a better
* solution if the workflow change is necessary.
*/
// prepare the point for dragging
this.dragControl.overFeature.apply(this.dragControl,
[feature]);
this.dragControl.lastPixel = pixel;
this.dragControl.handlers.drag.started = true;
this.dragControl.handlers.drag.start = pixel;
this.dragControl.handlers.drag.last = pixel;
this.selectFeature(feature);
}
if (feature._sketch || isPoint) {
// feature is a drag or virtual handle or point
this.vertex = feature;
this.handlers.drag.stopDown = true;
}
},
/**
* Method: dragVertex
* Called by the drag feature control with each drag move of a vertex.
* Called by the drag handler with each drag move of a vertex.
*
* Parameters:
* vertex - {<OpenLayers.Feature.Vector>} The vertex being dragged.
* pixel - {<OpenLayers.Pixel>} Pixel location of the mouse event.
*/
dragVertex: function(vertex, pixel) {
var pos = this.map.getLonLatFromViewPortPx(pixel);
var geom = vertex.geometry;
geom.move(pos.lon - geom.x, pos.lat - geom.y);
this.modified = true;
/**
* Five cases:
@@ -487,9 +467,6 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
*/
if(this.feature.geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
// dragging a simple point
if(this.feature != vertex) {
this.feature = vertex;
}
this.layer.events.triggerEvent("vertexmodified", {
vertex: vertex.geometry,
feature: this.feature,
@@ -526,7 +503,7 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
this.virtualVertices = [];
}
this.layer.drawFeature(this.feature, this.standalone ? undefined :
this.selectControl.renderIntent);
'select');
}
// keep the vertex on top so it gets the mouseout after dragging
// this should be removed in favor of an option to draw under or
@@ -536,7 +513,7 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
/**
* Method: dragComplete
* Called by the drag feature control when the feature dragging is complete.
* Called by the drag handler when the feature dragging is complete.
*
* Parameters:
* vertex - {<OpenLayers.Feature.Vector>} The vertex being dragged.
@@ -572,16 +549,6 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
* Method: resetVertices
*/
resetVertices: function() {
// if coming from a drag complete we're about to destroy the vertex
// that was just dragged. For that reason, the drag feature control
// will never detect a mouse-out on that vertex, meaning that the drag
// handler won't be deactivated. This can cause errors because the drag
// feature control still has a feature to drag but that feature is
// destroyed. To prevent this, we call outFeature on the drag feature
// control if the control actually has a feature to drag.
if(this.dragControl.feature) {
this.dragControl.outFeature(this.dragControl.feature);
}
if(this.vertices.length > 0) {
this.layer.removeFeatures(this.vertices, {silent: true});
this.vertices = [];
@@ -632,11 +599,10 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
// check for delete key
if(this.feature &&
OpenLayers.Util.indexOf(this.deleteCodes, code) != -1) {
var vertex = this.dragControl.feature;
if(vertex &&
var vertex = this.layer.getFeatureFromEvent(this.handlers.drag.evt);
if (vertex &&
OpenLayers.Util.indexOf(this.vertices, vertex) != -1 &&
!this.dragControl.handlers.drag.dragging &&
vertex.geometry.parent) {
!this.handlers.drag.dragging && vertex.geometry.parent) {
// remove the vertex
vertex.geometry.parent.removeComponent(vertex.geometry);
this.layer.events.triggerEvent("vertexremoved", {
@@ -645,8 +611,7 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
pixel: evt.xy
});
this.layer.drawFeature(this.feature, this.standalone ?
undefined :
this.selectControl.renderIntent);
undefined : 'select');
this.modified = true;
this.resetVertices();
this.setFeatureState();
@@ -800,11 +765,49 @@ OpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {
* map - {<OpenLayers.Map>} The control's map.
*/
setMap: function(map) {
this.standalone || this.selectControl.setMap(map);
this.dragControl.setMap(map);
this.handlers.drag.setMap(map);
OpenLayers.Control.prototype.setMap.apply(this, arguments);
},
/**
* Method: handleMapEvents
*
* Parameters:
* evt - {Object}
*/
handleMapEvents: function(evt) {
if (evt.type == "removelayer" || evt.property == "order") {
this.moveLayerToTop();
}
},
/**
* Method: moveLayerToTop
* Moves the layer for this handler to the top, so mouse events can reach
* it.
*/
moveLayerToTop: function() {
var index = Math.max(this.map.Z_INDEX_BASE['Feature'] - 1,
this.layer.getZIndex()) + 1;
this.layer.setZIndex(index);
},
/**
* Method: moveLayerBack
* Moves the layer back to the position determined by the map's layers
* array.
*/
moveLayerBack: function() {
var index = this.layer.getZIndex() - 1;
if (index >= this.map.Z_INDEX_BASE['Feature']) {
this.layer.setZIndex(index);
} else {
this.map.setLayerZIndex(this.layer,
this.map.getLayerIndex(this.layer));
}
},
CLASS_NAME: "OpenLayers.Control.ModifyFeature"
});

View File

@@ -77,7 +77,9 @@ OpenLayers.Control.Navigation = OpenLayers.Class(OpenLayers.Control, {
/**
* Property: mouseWheelOptions
* {Object} Options passed to the MouseWheel control (only useful if
* <zoomWheelEnabled> is set to true)
* <zoomWheelEnabled> is set to true). Default is no options for maps
* with fractionalZoom set to true, otherwise
* {cumulative: false, interval: 50, maxDelta: 6}
*/
mouseWheelOptions: null,
@@ -208,10 +210,15 @@ OpenLayers.Control.Navigation = OpenLayers.Class(OpenLayers.Control, {
{map: this.map, keyMask: this.zoomBoxKeyMask});
this.dragPan.draw();
this.zoomBox.draw();
var wheelOptions = this.map.fractionalZoom ? {} : {
cumulative: false,
interval: 50,
maxDelta: 6
};
this.handlers.wheel = new OpenLayers.Handler.MouseWheel(
this, {"up" : this.wheelUp,
"down": this.wheelDown},
this.mouseWheelOptions );
this, {up : this.wheelUp, down: this.wheelDown},
OpenLayers.Util.extend(wheelOptions, this.mouseWheelOptions)
);
if (OpenLayers.Control.PinchZoom) {
this.pinchZoom = new OpenLayers.Control.PinchZoom(
OpenLayers.Util.extend(
@@ -238,8 +245,7 @@ OpenLayers.Control.Navigation = OpenLayers.Class(OpenLayers.Control, {
* evt - {Event}
*/
defaultDblClick: function (evt) {
var newCenter = this.map.getLonLatFromViewPortPx( evt.xy );
this.map.setCenter(newCenter, this.map.zoom + 1);
this.map.zoomTo(this.map.zoom + 1, evt.xy);
},
/**
@@ -249,8 +255,7 @@ OpenLayers.Control.Navigation = OpenLayers.Class(OpenLayers.Control, {
* evt - {Event}
*/
defaultDblRightClick: function (evt) {
var newCenter = this.map.getLonLatFromViewPortPx( evt.xy );
this.map.setCenter(newCenter, this.map.zoom - 1);
this.map.zoomTo(this.map.zoom - 1, evt.xy);
},
/**
@@ -264,22 +269,14 @@ OpenLayers.Control.Navigation = OpenLayers.Class(OpenLayers.Control, {
if (!this.map.fractionalZoom) {
deltaZ = Math.round(deltaZ);
}
var currentZoom = this.map.getZoom();
var newZoom = this.map.getZoom() + deltaZ;
var currentZoom = this.map.getZoom(),
newZoom = currentZoom + deltaZ;
newZoom = Math.max(newZoom, 0);
newZoom = Math.min(newZoom, this.map.getNumZoomLevels());
if (newZoom === currentZoom) {
return;
}
var size = this.map.getSize();
var deltaX = size.w/2 - evt.xy.x;
var deltaY = evt.xy.y - size.h/2;
var newRes = this.map.baseLayer.getResolutionForZoom(newZoom);
var zoomPoint = this.map.getLonLatFromPixel(evt.xy);
var newCenter = new OpenLayers.LonLat(
zoomPoint.lon + deltaX * newRes,
zoomPoint.lat + deltaY * newRes );
this.map.setCenter( newCenter, newZoom );
this.map.zoomTo(newZoom, evt.xy);
},
/**

View File

@@ -4,7 +4,6 @@
* full text of the license. */
/**
* @requires OpenLayers/Util/vendorPrefix.js
* @requires OpenLayers/Handler/Pinch.js
*/
@@ -105,27 +104,13 @@ OpenLayers.Control.PinchZoom = OpenLayers.Class(OpenLayers.Control, {
var current = (this.preserveCenter) ?
this.map.getPixelFromLonLat(this.map.getCenter()) : evt.xy;
var dx = Math.round((current.x - pinchOrigin.x) + (scale - 1) * (containerOrigin.x - pinchOrigin.x));
var dy = Math.round((current.y - pinchOrigin.y) + (scale - 1) * (containerOrigin.y - pinchOrigin.y));
var dx = Math.round((containerOrigin.x + current.x - pinchOrigin.x) + (scale - 1) * (containerOrigin.x - pinchOrigin.x));
var dy = Math.round((containerOrigin.y + current.y - pinchOrigin.y) + (scale - 1) * (containerOrigin.y - pinchOrigin.y));
this.applyTransform(
"translate(" + dx + "px, " + dy + "px) scale(" + scale + ")"
);
this.map.applyTransform(dx, dy, scale);
this.currentCenter = current;
},
/**
* Method: applyTransform
* Applies the given transform to layers.
*/
applyTransform: function(transform) {
var style = this.map.layerContainerDiv.style;
var transformProperty = OpenLayers.Util.vendorPrefix.style("transform");
if (transformProperty) {
style[transformProperty] = transform;
}
},
/**
* Method: pinchDone
*
@@ -137,7 +122,7 @@ OpenLayers.Control.PinchZoom = OpenLayers.Class(OpenLayers.Control, {
* of the pinch gesture. This give us the final scale of the pinch.
*/
pinchDone: function(evt, start, last) {
this.applyTransform("");
this.map.applyTransform();
var zoom = this.map.getZoomForResolution(this.map.getResolution() / last.scale, true);
if (zoom !== this.map.getZoom() || !this.currentCenter.equals(this.pinchOrigin)) {
var resolution = this.map.getResolutionForZoom(zoom);

View File

@@ -175,8 +175,7 @@ OpenLayers.Control.TouchNavigation = OpenLayers.Class(OpenLayers.Control, {
* evt - {Event}
*/
defaultDblClick: function (evt) {
var newCenter = this.map.getLonLatFromViewPortPx(evt.xy);
this.map.setCenter(newCenter, this.map.zoom + 1);
this.map.zoomTo(this.map.zoom + 1, evt.xy);
},
CLASS_NAME: "OpenLayers.Control.TouchNavigation"

View File

@@ -49,23 +49,25 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
*/
maxFeatures: 10,
/** APIProperty: clickCallback
/**
* APIProperty: clickCallback
* {String} The click callback to register in the
* {<OpenLayers.Handler.Click>} object created when the hover
* option is set to false. Default is "click".
*/
clickCallback: "click",
/** APIProperty: output
* {String} Either "features" or "object". When triggering a
* getfeatureinfo request should we pass on an array of features
* or an object with with a "features" property and other properties
* (such as the url of the WMS). Default is "features".
/**
* APIProperty: output
* {String} Either "features" or "object". When triggering a getfeatureinfo
* request should we pass on an array of features or an object with with
* a "features" property and other properties (such as the url of the
* WMS). Default is "features".
*/
output: "features",
/**
* Property: layers
* APIProperty: layers
* {Array(<OpenLayers.Layer.WMS>)} The layers to query for feature info.
* If omitted, all map WMS layers with a url that matches this <url> or
* <layerUrls> will be considered.
@@ -73,21 +75,21 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
layers: null,
/**
* Property: queryVisible
* APIProperty: queryVisible
* {Boolean} If true, filter out hidden layers when searching the map for
* layers to query. Default is false.
*/
queryVisible: false,
/**
* Property: url
* APIProperty: url
* {String} The URL of the WMS service to use. If not provided, the url
* of the first eligible layer will be used.
*/
url: null,
/**
* Property: layerUrls
* APIProperty: layerUrls
* {Array(String)} Optional list of urls for layers that should be queried.
* This can be used when the layer url differs from the url used for
* making GetFeatureInfo requests (in the case of a layer using cached
@@ -96,7 +98,7 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
layerUrls: null,
/**
* Property: infoFormat
* APIProperty: infoFormat
* {String} The mimetype to request from the server. If you are using
* drillDown mode and have multiple servers that do not share a common
* infoFormat, you can override the control's infoFormat by providing an
@@ -105,7 +107,7 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
infoFormat: 'text/html',
/**
* Property: vendorParams
* APIProperty: vendorParams
* {Object} Additional parameters that will be added to the request, for
* WMS implementations that support them. This could e.g. look like
* (start code)
@@ -117,14 +119,14 @@ OpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {
vendorParams: {},
/**
* Property: format
* APIProperty: format
* {<OpenLayers.Format>} A format for parsing GetFeatureInfo responses.
* Default is <OpenLayers.Format.WMSGetFeatureInfo>.
*/
format: null,
/**
* Property: formatOptions
* APIProperty: formatOptions
* {Object} Optional properties to set on the format (if one is not provided
* in the <format> property.
*/

View File

@@ -69,7 +69,8 @@ OpenLayers.Control.ZoomBox = OpenLayers.Class(OpenLayers.Control, {
*/
zoomBox: function (position) {
if (position instanceof OpenLayers.Bounds) {
var bounds;
var bounds,
targetCenterPx = position.getCenterPixel();
if (!this.out) {
var minXY = this.map.getLonLatFromPixel({
x: position.left,
@@ -82,13 +83,12 @@ OpenLayers.Control.ZoomBox = OpenLayers.Class(OpenLayers.Control, {
bounds = new OpenLayers.Bounds(minXY.lon, minXY.lat,
maxXY.lon, maxXY.lat);
} else {
var pixWidth = Math.abs(position.right-position.left);
var pixHeight = Math.abs(position.top-position.bottom);
var pixWidth = position.right - position.left;
var pixHeight = position.bottom - position.top;
var zoomFactor = Math.min((this.map.size.h / pixHeight),
(this.map.size.w / pixWidth));
var extent = this.map.getExtent();
var center = this.map.getLonLatFromPixel(
position.getCenterPixel());
var center = this.map.getLonLatFromPixel(targetCenterPx);
var xmin = center.lon - (extent.getWidth()/2)*zoomFactor;
var xmax = center.lon + (extent.getWidth()/2)*zoomFactor;
var ymin = center.lat - (extent.getHeight()/2)*zoomFactor;
@@ -96,18 +96,27 @@ OpenLayers.Control.ZoomBox = OpenLayers.Class(OpenLayers.Control, {
bounds = new OpenLayers.Bounds(xmin, ymin, xmax, ymax);
}
// always zoom in/out
var lastZoom = this.map.getZoom();
this.map.zoomToExtent(bounds);
var lastZoom = this.map.getZoom(),
size = this.map.getSize(),
centerPx = {x: size.w / 2, y: size.h / 2},
zoom = this.map.getZoomForExtent(bounds),
oldRes = this.map.getResolution(),
newRes = this.map.getResolutionForZoom(zoom),
zoomOriginPx = {
x: (oldRes * targetCenterPx.x - newRes * centerPx.x) /
(oldRes - newRes),
y: (oldRes * targetCenterPx.y - newRes * centerPx.y) /
(oldRes - newRes)
};
this.map.zoomTo(zoom, zoomOriginPx);
if (lastZoom == this.map.getZoom() && this.alwaysZoom == true){
this.map.zoomTo(lastZoom + (this.out ? -1 : 1));
}
} else if (this.zoomOnClick) { // it's a pixel
if (!this.out) {
this.map.setCenter(this.map.getLonLatFromPixel(position),
this.map.getZoom() + 1);
this.map.zoomTo(this.map.getZoom() + 1, position);
} else {
this.map.setCenter(this.map.getLonLatFromPixel(position),
this.map.getZoom() - 1);
this.map.zoomTo(this.map.getZoom() - 1, position);
}
}
},

View File

@@ -566,6 +566,7 @@ OpenLayers.Events = OpenLayers.Class({
this.listeners = {};
this.extensions = {};
this.extensionCount = {};
this._msTouches = [];
// if a dom element is specified, add a listeners list
// for browser events on the element and register them
@@ -632,11 +633,16 @@ OpenLayers.Events = OpenLayers.Class({
);
}
this.element = element;
var msTouch = !!window.navigator.msMaxTouchPoints;
var type;
for (var i = 0, len = this.BROWSER_EVENTS.length; i < len; i++) {
type = this.BROWSER_EVENTS[i];
// register the event cross-browser
OpenLayers.Event.observe(
element, this.BROWSER_EVENTS[i], this.eventHandler
OpenLayers.Event.observe(element, type, this.eventHandler
);
if (msTouch && type.indexOf('touch') === 0) {
this.addMsTouchListener(element, type, this.eventHandler);
}
}
// disable dragstart in IE so that mousedown/move/up works normally
OpenLayers.Event.observe(element, "dragstart", OpenLayers.Event.stop);
@@ -1014,5 +1020,151 @@ OpenLayers.Events = OpenLayers.Class({
);
},
/**
* Method: addMsTouchListener
*
* Parameters:
* element - {DOMElement} The DOM element to register the listener on
* type - {String} The event type
* handler - {Function} the handler
*/
addMsTouchListener: function (element, type, handler) {
var eventHandler = this.eventHandler;
var touches = this._msTouches;
function msHandler(evt) {
handler(OpenLayers.Util.applyDefaults({
stopPropagation: function() {
for (var i=touches.length-1; i>=0; --i) {
touches[i].stopPropagation();
}
},
preventDefault: function() {
for (var i=touches.length-1; i>=0; --i) {
touches[i].preventDefault();
}
},
type: type
}, evt));
}
switch (type) {
case 'touchstart':
return this.addMsTouchListenerStart(element, type, msHandler);
case 'touchend':
return this.addMsTouchListenerEnd(element, type, msHandler);
case 'touchmove':
return this.addMsTouchListenerMove(element, type, msHandler);
default:
throw 'Unknown touch event type';
}
},
/**
* Method: addMsTouchListenerStart
*
* Parameters:
* element - {DOMElement} The DOM element to register the listener on
* type - {String} The event type
* handler - {Function} the handler
*/
addMsTouchListenerStart: function(element, type, handler) {
var touches = this._msTouches;
var cb = function(e) {
var alreadyInArray = false;
for (var i=0, ii=touches.length; i<ii; ++i) {
if (touches[i].pointerId == e.pointerId) {
alreadyInArray = true;
break;
}
}
if (!alreadyInArray) {
touches.push(e);
}
e.touches = touches.slice();
handler(e);
};
OpenLayers.Event.observe(element, 'MSPointerDown', cb);
// Need to also listen for end events to keep the _msTouches list
// accurate
var internalCb = function(e) {
for (var i=0, ii=touches.length; i<ii; ++i) {
if (touches[i].pointerId == e.pointerId) {
touches.splice(i, 1);
break;
}
}
};
OpenLayers.Event.observe(element, 'MSPointerUp', internalCb);
},
/**
* Method: addMsTouchListenerMove
*
* Parameters:
* element - {DOMElement} The DOM element to register the listener on
* type - {String} The event type
* handler - {Function} the handler
*/
addMsTouchListenerMove: function (element, type, handler) {
var touches = this._msTouches;
var cb = function(e) {
//Don't fire touch moves when mouse isn't down
if (e.pointerType == e.MSPOINTER_TYPE_MOUSE && e.buttons == 0) {
return;
}
if (touches.length == 1 && touches[0].pageX == e.pageX &&
touches[0].pageY == e.pageY) {
// don't trigger event when pointer has not moved
return;
}
for (var i=0, ii=touches.length; i<ii; ++i) {
if (touches[i].pointerId == e.pointerId) {
touches[i] = e;
break;
}
}
e.touches = touches.slice();
handler(e);
};
OpenLayers.Event.observe(element, 'MSPointerMove', cb);
},
/**
* Method: addMsTouchListenerEnd
*
* Parameters:
* element - {DOMElement} The DOM element to register the listener on
* type - {String} The event type
* handler - {Function} the handler
*/
addMsTouchListenerEnd: function (element, type, handler) {
var touches = this._msTouches;
var cb = function(e) {
for (var i=0, ii=touches.length; i<ii; ++i) {
if (touches[i].pointerId == e.pointerId) {
touches.splice(i, 1);
break;
}
}
e.touches = touches.slice();
handler(e);
};
OpenLayers.Event.observe(element, 'MSPointerUp', cb);
},
CLASS_NAME: "OpenLayers.Events"
});

View File

@@ -170,6 +170,12 @@ OpenLayers.Events.buttonclick = OpenLayers.Class({
} else if (this.startEvt) {
if (this.completeRegEx.test(evt.type)) {
var pos = OpenLayers.Util.pagePosition(button);
var viewportElement = OpenLayers.Util.getViewportElement();
var scrollTop = window.pageYOffset || viewportElement.scrollTop;
var scrollLeft = window.pageXOffset || viewportElement.scrollLeft;
pos[0] = pos[0] - scrollLeft;
pos[1] = pos[1] - scrollTop;
this.target.triggerEvent("buttonclick", {
buttonElement: button,
buttonXY: {

View File

@@ -422,7 +422,8 @@ OpenLayers.Feature.Vector = OpenLayers.Class(OpenLayers.Feature, {
* labelSelect - {Boolean} If set to true, labels will be selectable using SelectFeature or similar controls.
* Default is false.
* labelOutlineColor - {String} The color of the label outline. Default is 'white'. Only supported by the canvas & SVG renderers.
* labelOutlineWidth - {Number} The width of the label outline. Default is 3, set to 0 or null to disable. Only supported by the canvas & SVG renderers.
* labelOutlineWidth - {Number} The width of the label outline. Default is 3, set to 0 or null to disable. Only supported by the SVG renderers.
* labelOutlineOpacity - {Number} The opacity (0-1) of the label outline. Default is fontOpacity. Only supported by the canvas & SVG renderers.
* fontColor - {String} The font color for the label, to be provided like CSS.
* fontOpacity - {Number} Opacity (0-1) for the label
* fontFamily - {String} The font family for the label, to be provided like in CSS.

View File

@@ -62,15 +62,16 @@ OpenLayers.Format.EncodedPolyline = OpenLayers.Class(OpenLayers.Format, {
else if (this.geometryType != "point" && this.geometryType != "polygon")
return null;
var points = this.decode(encoded, 2);
var pointGeometries = new Array();
for (var i in points) {
var point = points[i];
pointGeometries.push(
new OpenLayers.Geometry.Point(point[1] * 1e-5, point[0] * 1e-5)
);
var flatPoints = this.decodeDeltas(encoded, 2);
var flatPointsLength = flatPoints.length;
var pointGeometries = [];
for (var i = 0; i + 1 < flatPointsLength;) {
var y = flatPoints[i++], x = flatPoints[i++];
pointGeometries.push(new OpenLayers.Geometry.Point(x, y));
}
if (this.geometryType == "point")
return new OpenLayers.Feature.Vector(
pointGeometries[0]
@@ -102,29 +103,18 @@ OpenLayers.Format.EncodedPolyline = OpenLayers.Class(OpenLayers.Format, {
* coordinates.
*/
decode: function(encoded, dims) {
var points = new Array();
var point = new Array(dims);
var flatPoints = this.decodeDeltas(encoded, dims, 1);
var flatPointsLength = flatPoints.length;
// Reset the point array
for (var i = 0; i < point.length; ++i)
point[i] = 0;
var points = [];
for (var i = 0; i + (dims - 1) < flatPointsLength;) {
var point = [];
for (var i = 0; i < encoded.length;) {
for (var dim = 0; dim < dims; ++dim) {
var result = 0;
var shift = 0;
var b;
do {
b = encoded.charCodeAt(i++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
point[dim] += ((result & 1) ? ~(result >> 1) : (result >> 1));
point.push(flatPoints[i++])
}
points.push(point.slice(0));
points.push(point);
}
return points;
@@ -163,16 +153,16 @@ OpenLayers.Format.EncodedPolyline = OpenLayers.Class(OpenLayers.Format, {
else
return null;
var points = new Array();
for (var i in pointGeometries) {
var flatPoints = [];
var pointGeometriesLength = pointGeometries.length;
for (var i = 0; i < pointGeometriesLength; ++i) {
var pointGeometry = pointGeometries[i];
var point = [Math.round(pointGeometry.y * 1e5),
Math.round(pointGeometry.x * 1e5)];
points.push(point);
flatPoints.push(pointGeometry.y);
flatPoints.push(pointGeometry.x);
}
var result = this.encode(points, 2);
return result;
return this.encodeDeltas(flatPoints, 2);
},
/**
@@ -188,66 +178,377 @@ OpenLayers.Format.EncodedPolyline = OpenLayers.Class(OpenLayers.Format, {
* {String} An encoded string
*/
encode: function (points, dims) {
var encoded_points = "";
var flatPoints = [];
var lastPoint = new Array(dims);
for (var i = 0; i < lastPoint.length; ++i)
lastPoint[i] = 0;
for (var i = 0; i < points.length; i++) {
var pointsLength = points.length;
for (var i = 0; i < pointsLength; ++i) {
var point = points[i];
for (var dim = 0; dim < lastPoint.length; ++dim) {
var delta = point[dim] - lastPoint[dim];
encoded_points += this.encodeSignedNumber(delta);
for (var dim = 0; dim < dims; ++dim) {
flatPoints.push(point[dim]);
}
}
lastPoint = point;
}
return encoded_points;
return this.encodeDeltas(flatPoints, dims, 1);
},
/**
* Method: encodeSignedNumber
* APIMethod: encodeDeltas
* Encode a list of n-dimensional points and return an encoded string
*
* Attention: This function will modify the passed array!
*
* Parameters:
* numbers - {Array.<number>} A list of n-dimensional points.
* dimension - {number} The dimension of the points in the list.
* opt_factor - {number=} The factor by which the numbers will be
* multiplied. The remaining decimal places will get rounded away.
*
* Returns:
* {string} The encoded string.
*/
encodeDeltas: function(numbers, dimension, opt_factor) {
var factor = opt_factor || 1e5;
var d;
var lastNumbers = new Array(dimension);
for (d = 0; d < dimension; ++d) {
lastNumbers[d] = 0;
}
var numbersLength = numbers.length;
for (var i = 0; i < numbersLength;) {
for (d = 0; d < dimension; ++d, ++i) {
var num = numbers[i];
var delta = num - lastNumbers[d];
lastNumbers[d] = num;
numbers[i] = delta;
}
}
return this.encodeFloats(numbers, factor);
},
/**
* APIMethod: decodeDeltas
* Decode a list of n-dimensional points from an encoded string
*
* Parameters:
* encoded - {string} An encoded string.
* dimension - {number} The dimension of the points in the encoded string.
* opt_factor - {number=} The factor by which the resulting numbers will
* be divided.
*
* Returns:
* {Array.<number>} A list of n-dimensional points.
*/
decodeDeltas: function(encoded, dimension, opt_factor) {
var factor = opt_factor || 1e5;
var d;
var lastNumbers = new Array(dimension);
for (d = 0; d < dimension; ++d) {
lastNumbers[d] = 0;
}
var numbers = this.decodeFloats(encoded, factor);
var numbersLength = numbers.length;
for (var i = 0; i < numbersLength;) {
for (d = 0; d < dimension; ++d, ++i) {
lastNumbers[d] += numbers[i];
numbers[i] = lastNumbers[d];
}
}
return numbers;
},
/**
* APIMethod: encodeFloats
* Encode a list of floating point numbers and return an encoded string
*
* Attention: This function will modify the passed array!
*
* Parameters:
* numbers - {Array.<number>} A list of floating point numbers.
* opt_factor - {number=} The factor by which the numbers will be
* multiplied. The remaining decimal places will get rounded away.
*
* Returns:
* {string} The encoded string.
*/
encodeFloats: function(numbers, opt_factor) {
var factor = opt_factor || 1e5;
var numbersLength = numbers.length;
for (var i = 0; i < numbersLength; ++i) {
numbers[i] = Math.round(numbers[i] * factor);
}
return this.encodeSignedIntegers(numbers);
},
/**
* APIMethod: decodeFloats
* Decode a list of floating point numbers from an encoded string
*
* Parameters:
* encoded - {string} An encoded string.
* opt_factor - {number=} The factor by which the result will be divided.
*
* Returns:
* {Array.<number>} A list of floating point numbers.
*/
decodeFloats: function(encoded, opt_factor) {
var factor = opt_factor || 1e5;
var numbers = this.decodeSignedIntegers(encoded);
var numbersLength = numbers.length;
for (var i = 0; i < numbersLength; ++i) {
numbers[i] /= factor;
}
return numbers;
},
/**
* APIMethod: encodeSignedIntegers
* Encode a list of signed integers and return an encoded string
*
* Attention: This function will modify the passed array!
*
* Parameters:
* numbers - {Array.<number>} A list of signed integers.
*
* Returns:
* {string} The encoded string.
*/
encodeSignedIntegers: function(numbers) {
var numbersLength = numbers.length;
for (var i = 0; i < numbersLength; ++i) {
var num = numbers[i];
var signedNum = num << 1;
if (num < 0) {
signedNum = ~(signedNum);
}
numbers[i] = signedNum;
}
return this.encodeUnsignedIntegers(numbers);
},
/**
* APIMethod: decodeSignedIntegers
* Decode a list of signed integers from an encoded string
*
* Parameters:
* encoded - {string} An encoded string.
*
* Returns:
* {Array.<number>} A list of signed integers.
*/
decodeSignedIntegers: function(encoded) {
var numbers = this.decodeUnsignedIntegers(encoded);
var numbersLength = numbers.length;
for (var i = 0; i < numbersLength; ++i) {
var num = numbers[i];
numbers[i] = (num & 1) ? ~(num >> 1) : (num >> 1);
}
return numbers;
},
/**
* APIMethod: encodeUnsignedIntegers
* Encode a list of unsigned integers and return an encoded string
*
* Parameters:
* numbers - {Array.<number>} A list of unsigned integers.
*
* Returns:
* {string} The encoded string.
*/
encodeUnsignedIntegers: function(numbers) {
var encoded = '';
var numbersLength = numbers.length;
for (var i = 0; i < numbersLength; ++i) {
encoded += this.encodeUnsignedInteger(numbers[i]);
}
return encoded;
},
/**
* APIMethod: decodeUnsignedIntegers
* Decode a list of unsigned integers from an encoded string
*
* Parameters:
* encoded - {string} An encoded string.
*
* Returns:
* {Array.<number>} A list of unsigned integers.
*/
decodeUnsignedIntegers: function(encoded) {
var numbers = [];
var current = 0;
var shift = 0;
var encodedLength = encoded.length;
for (var i = 0; i < encodedLength; ++i) {
var b = encoded.charCodeAt(i) - 63;
current |= (b & 0x1f) << shift;
if (b < 0x20) {
numbers.push(current);
current = 0;
shift = 0;
} else {
shift += 5;
}
}
return numbers;
},
/**
* Method: encodeFloat
* Encode one single floating point number and return an encoded string
*
* Parameters:
* num - {number} Floating point number that should be encoded.
* opt_factor - {number=} The factor by which num will be multiplied.
* The remaining decimal places will get rounded away.
*
* Returns:
* {string} The encoded string.
*/
encodeFloat: function(num, opt_factor) {
num = Math.round(num * (opt_factor || 1e5));
return this.encodeSignedInteger(num);
},
/**
* Method: decodeFloat
* Decode one single floating point number from an encoded string
*
* Parameters:
* encoded - {string} An encoded string.
* opt_factor - {number=} The factor by which the result will be divided.
*
* Returns:
* {number} The decoded floating point number.
*/
decodeFloat: function(encoded, opt_factor) {
var result = this.decodeSignedInteger(encoded);
return result / (opt_factor || 1e5);
},
/**
* Method: encodeSignedInteger
* Encode one single signed integer and return an encoded string
*
* Parameters:
* num - {int} A signed integer that should be encoded
* num - {number} Signed integer that should be encoded.
*
* Returns:
* {String} An encoded string
* {string} The encoded string.
*/
encodeSignedNumber: function (num) {
var sgn_num = num << 1;
if (num < 0)
sgn_num = ~(sgn_num);
encodeSignedInteger: function(num) {
var signedNum = num << 1;
if (num < 0) {
signedNum = ~(signedNum);
}
return this.encodeNumber(sgn_num);
return this.encodeUnsignedInteger(signedNum);
},
/**
* Method: encodeNumber
* Encode one single unsigned integer and return an encoded string
*
* encodeSignedNumber should be used instead of using this method directly!
* Method: decodeSignedInteger
* Decode one single signed integer from an encoded string
*
* Parameters:
* num - {int} An unsigned integer that should be encoded
* encoded - {string} An encoded string.
*
* Returns:
* {String} An encoded string
* {number} The decoded signed integer.
*/
encodeNumber: function (num) {
var encodeString = "";
var value;
decodeSignedInteger: function(encoded) {
var result = this.decodeUnsignedInteger(encoded);
return ((result & 1) ? ~(result >> 1) : (result >> 1));
},
/**
* Method: encodeUnsignedInteger
* Encode one single unsigned integer and return an encoded string
*
* Parameters:
* num - {number} Unsigned integer that should be encoded.
*
* Returns:
* {string} The encoded string.
*/
encodeUnsignedInteger: function(num) {
var value, encoded = '';
while (num >= 0x20) {
value = (0x20 | (num & 0x1f)) + 63;
encodeString += (String.fromCharCode(value));
encoded += (String.fromCharCode(value));
num >>= 5;
}
value = num + 63;
encodeString += (String.fromCharCode(value));
return encodeString;
encoded += (String.fromCharCode(value));
return encoded;
},
/**
* Method: decodeUnsignedInteger
* Decode one single unsigned integer from an encoded string
*
* Parameters:
* encoded - {string} An encoded string.
*
* Returns:
* {number} The decoded unsigned integer.
*/
decodeUnsignedInteger: function(encoded) {
var result = 0;
var shift = 0;
var encodedLength = encoded.length;
for (var i = 0; i < encodedLength; ++i) {
var b = encoded.charCodeAt(i) - 63;
result |= (b & 0x1f) << shift;
if (b < 0x20)
break;
shift += 5;
}
return result;
},
CLASS_NAME: "OpenLayers.Format.EncodedPolyline"

View File

@@ -250,11 +250,11 @@ OpenLayers.Format.GPX = OpenLayers.Class(OpenLayers.Format.XML, {
*/
buildMetadataNode: function(metadata) {
var types = ['name', 'desc', 'author'],
node = this.createElementNSPlus('gpx:metadata');
node = this.createElementNS(this.namespaces.gpx, 'metadata');
for (var i=0; i < types.length; i++) {
var type = types[i];
if (metadata[type]) {
var n = this.createElementNSPlus("gpx:" + type);
var n = this.createElementNS(this.namespaces.gpx, type);
n.appendChild(this.createTextNode(metadata[type]));
node.appendChild(n);
}
@@ -284,7 +284,7 @@ OpenLayers.Format.GPX = OpenLayers.Class(OpenLayers.Format.XML, {
this.appendAttributesNode(wpt, feature);
return wpt;
} else {
var trkNode = this.createElementNSPlus("gpx:trk");
var trkNode = this.createElementNS(this.namespaces.gpx, "trk");
this.appendAttributesNode(trkNode, feature);
var trkSegNodes = this.buildTrkSegNode(geometry);
trkSegNodes = OpenLayers.Util.isArray(trkSegNodes) ?
@@ -312,7 +312,7 @@ OpenLayers.Format.GPX = OpenLayers.Class(OpenLayers.Format.XML, {
nodes;
if (geometry.CLASS_NAME == "OpenLayers.Geometry.LineString" ||
geometry.CLASS_NAME == "OpenLayers.Geometry.LinearRing") {
node = this.createElementNSPlus("gpx:trkseg");
node = this.createElementNS(this.namespaces.gpx, "trkseg");
for (i = 0, len=geometry.components.length; i < len; i++) {
point = geometry.components[i];
node.appendChild(this.buildTrkPtNode(point));
@@ -338,7 +338,7 @@ OpenLayers.Format.GPX = OpenLayers.Class(OpenLayers.Format.XML, {
* {DOMElement} A trkpt node
*/
buildTrkPtNode: function(point) {
var node = this.createElementNSPlus("gpx:trkpt");
var node = this.createElementNS(this.namespaces.gpx, "trkpt");
node.setAttribute("lon", point.x);
node.setAttribute("lat", point.y);
return node;
@@ -355,7 +355,7 @@ OpenLayers.Format.GPX = OpenLayers.Class(OpenLayers.Format.XML, {
* {DOMElement} A wpt node
*/
buildWptNode: function(geometry) {
var node = this.createElementNSPlus("gpx:wpt");
var node = this.createElementNS(this.namespaces.gpx, "wpt");
node.setAttribute("lon", geometry.x);
node.setAttribute("lat", geometry.y);
return node;
@@ -370,11 +370,11 @@ OpenLayers.Format.GPX = OpenLayers.Class(OpenLayers.Format.XML, {
* feature - {<OpenLayers.Feature.Vector>}
*/
appendAttributesNode: function(node, feature) {
var name = this.createElementNSPlus('gpx:name');
var name = this.createElementNS(this.namespaces.gpx, 'name');
name.appendChild(this.createTextNode(
feature.attributes.name || feature.id));
node.appendChild(name);
var desc = this.createElementNSPlus('gpx:desc');
var desc = this.createElementNS(this.namespaces.gpx, 'desc');
desc.appendChild(this.createTextNode(
feature.attributes.description || this.defaultDesc));
node.appendChild(desc);

View File

@@ -6,6 +6,12 @@
/**
* @requires OpenLayers/Format.js
* @requires OpenLayers/Feature/Vector.js
* @requires OpenLayers/Geometry/Point.js
* @requires OpenLayers/Geometry/MultiPoint.js
* @requires OpenLayers/Geometry/LineString.js
* @requires OpenLayers/Geometry/MultiLineString.js
* @requires OpenLayers/Geometry/Polygon.js
* @requires OpenLayers/Geometry/MultiPolygon.js
*/
/**

View File

@@ -438,12 +438,39 @@ OpenLayers.Geometry.segmentsIntersect = function(seg1, seg2, options) {
* representing endpoint coordinates.
*
* Returns:
* {Object} An object with distance, x, and y properties. The distance
* {Object} An object with distance, along, x, and y properties. The distance
* will be the shortest distance between the input point and segment.
* The x and y properties represent the coordinates along the segment
* where the shortest distance meets the segment.
* where the shortest distance meets the segment. The along attribute
* describes how far between the two segment points the given point is.
*/
OpenLayers.Geometry.distanceToSegment = function(point, segment) {
var result = OpenLayers.Geometry.distanceSquaredToSegment(point, segment);
result.distance = Math.sqrt(result.distance);
return result;
};
/**
* Function: OpenLayers.Geometry.distanceSquaredToSegment
*
* Usually the distanceToSegment function should be used. This variant however
* can be used for comparisons where the exact distance is not important.
*
* Parameters:
* point - {Object} An object with x and y properties representing the
* point coordinates.
* segment - {Object} An object with x1, y1, x2, and y2 properties
* representing endpoint coordinates.
*
* Returns:
* {Object} An object with squared distance, along, x, and y properties.
* The distance will be the shortest distance between the input point and
* segment. The x and y properties represent the coordinates along the
* segment where the shortest distance meets the segment. The along
* attribute describes how far between the two segment points the given
* point is.
*/
OpenLayers.Geometry.distanceSquaredToSegment = function(point, segment) {
var x0 = point.x;
var y0 = point.y;
var x1 = segment.x1;
@@ -466,7 +493,8 @@ OpenLayers.Geometry.distanceToSegment = function(point, segment) {
y = y1 + along * dy;
}
return {
distance: Math.sqrt(Math.pow(x - x0, 2) + Math.pow(y - y0, 2)),
x: x, y: y
distance: Math.pow(x - x0, 2) + Math.pow(y - y0, 2),
x: x, y: y,
along: along
};
};

View File

@@ -86,6 +86,14 @@ OpenLayers.Handler = OpenLayers.Class({
*/
evt: null,
/**
* Property: touch
* {Boolean} Indicates the support of touch events. When touch events are
* started touch will be true and all mouse related listeners will do
* nothing.
*/
touch: false,
/**
* Constructor: OpenLayers.Handler
* Construct a handler.
@@ -187,10 +195,32 @@ OpenLayers.Handler = OpenLayers.Class({
this.unregister(events[i], this[events[i]]);
}
}
this.touch = false;
this.active = false;
return true;
},
/**
* Method: startTouch
* Start touch events, this method must be called by subclasses in
* "touchstart" method. When touch events are started <touch> will be
* true and all mouse related listeners will do nothing.
*/
startTouch: function() {
if (!this.touch) {
this.touch = true;
var events = [
"mousedown", "mouseup", "mousemove", "click", "dblclick",
"mouseout"
];
for (var i=0, len=events.length; i<len; i++) {
if (this[events[i]]) {
this.unregister(events[i], this[events[i]]);
}
}
}
},
/**
* Method: callback
* Trigger the control's named callback with the given arguments

View File

@@ -91,13 +91,6 @@ OpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, {
*/
timerId: null,
/**
* Property: touch
* {Boolean} When a touchstart event is fired, touch will be true and all
* mouse related listeners will do nothing.
*/
touch: false,
/**
* Property: down
* {Object} Object that store relevant information about the last
@@ -155,10 +148,7 @@ OpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, {
* {Boolean} Continue propagating this event.
*/
touchstart: function(evt) {
if (!this.touch) {
this.unregisterMouseListeners();
this.touch = true;
}
this.startTouch();
this.down = this.getEventInfo(evt);
this.last = this.getEventInfo(evt);
return true;
@@ -196,20 +186,6 @@ OpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, {
return true;
},
/**
* Method: unregisterMouseListeners
* In a touch environment, we don't want to handle mouse events.
*/
unregisterMouseListeners: function() {
this.map.events.un({
mousedown: this.mousedown,
mouseup: this.mouseup,
click: this.click,
dblclick: this.dblclick,
scope: this
});
},
/**
* Method: mousedown
* Handle mousedown.
@@ -352,7 +328,7 @@ OpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, {
// touch device, no dblclick event - this may be a double
if (this["double"]) {
// on Android don't let the browser zoom on the page
OpenLayers.Event.stop(evt);
OpenLayers.Event.preventDefault(evt);
}
this.handleDouble(evt);
}
@@ -520,7 +496,6 @@ OpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, {
this.down = null;
this.first = null;
this.last = null;
this.touch = false;
deactivated = true;
}
return deactivated;

View File

@@ -50,13 +50,6 @@ OpenLayers.Handler.Drag = OpenLayers.Class(OpenLayers.Handler, {
*/
dragging: false,
/**
* Property: touch
* {Boolean} When a touchstart event is fired, touch will be true and all
* mouse related listeners will do nothing.
*/
touch: false,
/**
* Property: last
* {<OpenLayers.Pixel>} The last pixel location of the drag.
@@ -345,17 +338,7 @@ OpenLayers.Handler.Drag = OpenLayers.Class(OpenLayers.Handler, {
* {Boolean} Let the event propagate.
*/
touchstart: function(evt) {
if (!this.touch) {
this.touch = true;
// unregister mouse listeners
this.map.events.un({
mousedown: this.mousedown,
mouseup: this.mouseup,
mousemove: this.mousemove,
click: this.click,
scope: this
});
}
this.startTouch();
return this.dragstart(evt);
},
@@ -509,7 +492,6 @@ OpenLayers.Handler.Drag = OpenLayers.Class(OpenLayers.Handler, {
deactivate: function() {
var deactivated = false;
if(OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {
this.touch = false;
this.started = false;
this.dragging = false;
this.start = null;

View File

@@ -60,13 +60,6 @@ OpenLayers.Handler.Feature = OpenLayers.Class(OpenLayers.Handler, {
*/
up: null,
/**
* Property: touch
* {Boolean} When a touchstart event is fired, touch will be true and all
* mouse related listeners will do nothing.
*/
touch: false,
/**
* Property: clickTolerance
* {Number} The number of pixels the mouse can move between mousedown
@@ -139,17 +132,7 @@ OpenLayers.Handler.Feature = OpenLayers.Class(OpenLayers.Handler, {
* {Boolean} Let the event propagate.
*/
touchstart: function(evt) {
if(!this.touch) {
this.touch = true;
this.map.events.un({
mousedown: this.mousedown,
mouseup: this.mouseup,
mousemove: this.mousemove,
click: this.click,
dblclick: this.dblclick,
scope: this
});
}
this.startTouch();
return OpenLayers.Event.isMultiTouch(evt) ?
true : this.mousedown(evt);
},
@@ -351,6 +334,11 @@ OpenLayers.Handler.Feature = OpenLayers.Class(OpenLayers.Handler, {
if(dpx <= this.clickTolerance) {
this.callback(key, args);
}
// we're done with this set of events now: clear the cached
// positions so we can't trip over them later (this can occur
// if one of the up/down events gets eaten before it gets to us
// but we still get the click)
this.up = this.down = null;
} else {
this.callback(key, args);
}
@@ -393,7 +381,6 @@ OpenLayers.Handler.Feature = OpenLayers.Class(OpenLayers.Handler, {
this.lastFeature = null;
this.down = null;
this.up = null;
this.touch = false;
this.map.events.un({
"removelayer": this.handleMapEvents,
"changelayer": this.handleMapEvents,

View File

@@ -31,6 +31,14 @@ OpenLayers.Handler.MouseWheel = OpenLayers.Class(OpenLayers.Handler, {
*/
interval: 0,
/**
* Property: maxDelta
* {Integer} Maximum delta to collect before breaking from the current
* interval. In cumulative mode, this also limits the maximum delta
* returned from the handler. Default is Number.POSITIVE_INFINITY.
*/
maxDelta: Number.POSITIVE_INFINITY,
/**
* Property: delta
* {Integer} When interval is set, delta collects the mousewheel z-deltas
@@ -176,10 +184,10 @@ OpenLayers.Handler.MouseWheel = OpenLayers.Class(OpenLayers.Handler, {
// so force delta 1 / -1
delta = - (e.detail / Math.abs(e.detail));
}
this.delta = this.delta + delta;
this.delta += delta;
if(this.interval) {
window.clearTimeout(this._timeoutId);
if(this.interval && Math.abs(this.delta) < this.maxDelta) {
// store e because window.event might change during delay
var evt = OpenLayers.Util.extend({}, e);
this._timeoutId = window.setTimeout(
@@ -211,9 +219,11 @@ OpenLayers.Handler.MouseWheel = OpenLayers.Class(OpenLayers.Handler, {
if (delta) {
e.xy = this.map.events.getMousePosition(e);
if (delta < 0) {
this.callback("down", [e, this.cumulative ? delta : -1]);
this.callback("down",
[e, this.cumulative ? Math.max(-this.maxDelta, delta) : -1]);
} else {
this.callback("up", [e, this.cumulative ? delta : 1]);
this.callback("up",
[e, this.cumulative ? Math.min(this.maxDelta, delta) : 1]);
}
}
},

View File

@@ -271,6 +271,16 @@ OpenLayers.Handler.Path = OpenLayers.Class(OpenLayers.Handler.Point, {
var target = components[index];
var undone = geometry.removeComponent(target);
if (undone) {
// On touch devices, set the current ("mouse location") point to
// match the last digitized point.
if (this.touch && index > 0) {
components = geometry.components; // safety
var lastpt = components[index - 1];
var curptidx = this.getCurrentPointIndex();
var curpt = components[curptidx];
curpt.x = lastpt.x;
curpt.y = lastpt.y;
}
if (!this.redoStack) {
this.redoStack = [];
}

View File

@@ -113,12 +113,6 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, {
*/
pixelTolerance: 5,
/**
* Property: touch
* {Boolean} Indcates the support of touch events.
*/
touch: false,
/**
* Property: lastTouchPx
* {<OpenLayers.Pixel>} The last pixel used to know the distance between
@@ -216,7 +210,6 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, {
this.layer.destroy(false);
}
this.layer = null;
this.touch = false;
return true;
},
@@ -383,18 +376,7 @@ OpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, {
* {Boolean} Allow event propagation
*/
touchstart: function(evt) {
if (!this.touch) {
this.touch = true;
// unregister mouse listeners
this.map.events.un({
mousedown: this.mousedown,
mouseup: this.mouseup,
mousemove: this.mousemove,
click: this.click,
dblclick: this.dblclick,
scope: this
});
}
this.startTouch();
this.lastTouchPx = evt.xy;
return this.down(evt);
},

View File

@@ -13,7 +13,7 @@
* <OpenLayers.Lang.translate>. Entry bodies are normal strings or
* strings formatted for use with <OpenLayers.String.format> calls.
*/
OpenLayers.Lang["pt-br"] = OpenLayers.Util.applyDefaults({
OpenLayers.Lang["pt-BR"] = OpenLayers.Util.applyDefaults({
'unhandledRequest': "A requisição retornou um erro não tratado: ${statusText}",

69
lib/OpenLayers/Lang/ro.js Normal file
View File

@@ -0,0 +1,69 @@
/**
* @requires OpenLayers/Lang.js
*/
/**
* Namespace: OpenLayers.Lang["ro"]
* Dictionary for Romanian. Keys for entries are used in calls to
* <OpenLayers.Lang.translate>. Entry bodies are normal strings or
* strings formatted for use with <OpenLayers.String.format> calls.
*/
OpenLayers.Lang.ro = {
'unhandledRequest': "Cerere nesoluționată return ${statusText}",
'Permalink': "Legatură permanentă",
'Overlays': "Straturi vector",
'Base Layer': "Straturi de bază",
'noFID': "Nu pot actualiza un feature pentru care nu există FID.",
'browserNotSupported':
"Browserul tău nu suportă afișarea vectorilor. Supoetul curent pentru randare:\n${renderers}",
// console message
'minZoomLevelError':
"Proprietatea minZoomLevel este doar pentru a fi folosită " +
"cu straturile FixedZoomLevels-descendent. De aceea acest " +
"strat wfs verifică dacă minZoomLevel este o relicvă" +
". Nu îl putem , oricum, înlătura fără " +
"a afecta aplicațiile Openlayers care depind de ea." +
" De aceea considerăm depreciat -- minZoomLevel " +
"și îl vom înlătura în 3.0. Folosește " +
"min/max resolution cum este descrisă aici: " +
"http://trac.openlayers.org/wiki/SettingZoomLevels",
'commitSuccess': "Tranzacție WFS: SUCCES ${response}",
'commitFailed': "Tranzacție WFS : EȘEC ${response}",
'googleWarning':
"Stratul Google nu a putut fi încărcat corect.<br><br>" +
"Pentru a elimina acest mesaj, selectează un nou strat de bază " +
"în Layerswitcher din colțul dreata-sus.<br><br>" +
"Asta datorită, faptului că Google Maps library " +
"script nu este inclus, sau nu conține " +
"cheia API corectă pentru situl tău.<br><br>" +
"Developeri: Pentru ajutor, " +
"<a href='http://trac.openlayers.org/wiki/Google' " +
"target='_blank'>apăsați aici</a>",
'getLayerWarning':
"Stratul ${layerType} nu a putut fi încărcat corect.<br><br>" +
"pentru a înlătura acest mesaj, selectează un nou strat de bază " +
"Acesta eroare apare de obicei când ${layerLib} library " +
"script nu a fost încărcat corect.<br><br>" +
"Developeri: Pentru ajutor privind utilizarea corectă, " +
"<a href='http://trac.openlayers.org/wiki/${layerLib}' " +
"target='_blank'>apasă aici</a>",
'Scale = 1 : ${scaleDenom}': "Scara = 1 : ${scaleDenom}",
//labels for the graticule control
'W': 'V',
'E': 'E',
'N': 'N',
'S': 'S',
'Graticule': 'Graticule',
// console message
'reprojectDeprecated':
"folosești opțiunea 'reproject' " +
"pentru stratul ${layerName} . Această opțiune este depreciată: " +
"a fost utilizată pentru afișarea straturilor de bază comerciale " +
"Mai multe informații despre proiecția Mercator sunt disponibile aici " +
"http://trac.openlayers.org/wiki/SphericalMercator.",
// console message
'methodDeprecated':
"Această metodă este depreciată și va fi înlăturată in versiunea 3.0. " +
"folosește metoda ${newMethod}.",
// **** end ****
'end': ''
};

View File

@@ -93,7 +93,11 @@ OpenLayers.Layer = OpenLayers.Class({
* loadend - Triggered when layer loading ends. When using a Vector layer
* with a Fixed or BBOX strategy, the event object includes a
* *response* property holding an OpenLayers.Protocol.Response object.
* visibilitychanged - Triggered when layer visibility is changed.
* visibilitychanged - Triggered when the layer's visibility property is
* changed, e.g. by turning the layer on or off in the layer switcher.
* Note that the actual visibility of the layer can also change if it
* gets out of range (see <calculateInRange>). If you also want to catch
* these cases, register for the map's 'changelayer' event instead.
* move - Triggered when layer moves (triggered with every mousemove
* during a drag).
* moveend - Triggered when layer is done moving, object passed as

View File

@@ -3,7 +3,6 @@
* See license.txt in the OpenLayers distribution or repository for the
* full text of the license. */
/**
* @requires OpenLayers/Layer/Grid.js
*/

View File

@@ -1,3 +1,8 @@
/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
* full list of contributors). Published under the 2-clause BSD license.
* See license.txt in the OpenLayers distribution or repository for the
* full text of the license. */
/**
* @requires OpenLayers/Layer/XYZ.js
*/
@@ -457,9 +462,9 @@ OpenLayers.Layer.ArcGISCache = OpenLayers.Class(OpenLayers.Layer.XYZ, {
url = url + '/tile/${z}/${y}/${x}';
} else {
// The tile images are stored using hex values on disk.
x = 'C' + this.zeroPad(x, 8, 16);
y = 'R' + this.zeroPad(y, 8, 16);
z = 'L' + this.zeroPad(z, 2, 16);
x = 'C' + OpenLayers.Number.zeroPad(x, 8, 16);
y = 'R' + OpenLayers.Number.zeroPad(y, 8, 16);
z = 'L' + OpenLayers.Number.zeroPad(z, 2, 10);
url = url + '/${z}/${y}/${x}.' + this.type;
}
@@ -471,23 +476,5 @@ OpenLayers.Layer.ArcGISCache = OpenLayers.Class(OpenLayers.Layer.XYZ, {
);
},
/**
* Method: zeroPad
* Create a zero padded string optionally with a radix for casting numbers.
*
* Parameters:
* num - {Number} The number to be zero padded.
* len - {Number} The length of the string to be returned.
* radix - {Number} An integer between 2 and 36 specifying the base to use
* for representing numeric values.
*/
zeroPad: function(num, len, radix) {
var str = num.toString(radix || 10);
while (str.length < len) {
str = "0" + str;
}
return str;
},
CLASS_NAME: 'OpenLayers.Layer.ArcGISCache'
});

View File

@@ -248,7 +248,7 @@ OpenLayers.Layer.Bing = OpenLayers.Class(OpenLayers.Layer.XYZ, {
this.map.getProjectionObject(),
new OpenLayers.Projection("EPSG:4326")
);
var providers = res.imageryProviders,
var providers = res.imageryProviders || [],
zoom = OpenLayers.Util.indexOf(this.serverResolutions,
this.getServerResolution()),
copyrights = "", provider, i, ii, j, jj, bbox, coverage;

View File

@@ -92,6 +92,7 @@ OpenLayers.Layer.Google.v3 = {
googleControl.style.width = '100%';
googleControl.style.height = '100%';
mapObject.controls[google.maps.ControlPosition.TOP_LEFT].push(googleControl);
this.map.div.appendChild(container);
// cache elements for use by any other google layers added to
// this same map
@@ -140,26 +141,13 @@ OpenLayers.Layer.Google.v3 = {
}
var container = this.mapObject.getDiv();
if (visible === true) {
if (container.parentNode !== map.div) {
map.div.appendChild(container);
if (!cache.rendered) {
google.maps.event.addListenerOnce(this.mapObject, 'tilesloaded', function() {
container.style.display = '';
cache.googleControl.appendChild(map.viewPortDiv);
cache.rendered = true;
});
} else {
cache.googleControl.appendChild(map.viewPortDiv);
}
google.maps.event.trigger(this.mapObject, 'resize');
}
this.mapObject.setMapTypeId(type);
cache.displayed = this.id;
} else {
if (cache.googleControl.hasChildNodes()) {
map.div.appendChild(map.viewPortDiv);
map.div.removeChild(container);
}
delete cache.displayed;
container.style.display = 'none';
}
}
},

View File

@@ -77,6 +77,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
/** APIProperty: ratio
* {Float} Used only when in single-tile mode, this specifies the
* ratio of the size of the single tile to the size of the map.
* Default value is 1.5.
*/
ratio: 1.5,
@@ -96,16 +97,21 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* {String} The transition effect to use when the map is zoomed.
* Two posible values:
*
* null - No transition effect (the default).
* "resize" - Existing tiles are resized on zoom to provide a visual
* effect of the zoom having taken place immediately. As the
* new tiles become available, they are drawn over top of the
* resized tiles.
* new tiles become available, they are drawn on top of the
* resized tiles (this is the default setting).
* "map-resize" - Existing tiles are resized on zoom and placed below the
* base layer. New tiles for the base layer will cover existing tiles.
* This setting is recommended when having an overlay duplicated during
* the transition is undesirable (e.g. street labels or big transparent
* fills).
* null - No transition effect.
*
* Using "resize" on non-opaque layers can cause undesired visual
* effects. This is therefore discouraged.
* effects. Set transitionEffect to null in this case.
*/
transitionEffect: null,
transitionEffect: "resize",
/**
* APIProperty: numLoadingTiles
@@ -428,6 +434,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
obj.backBuffer = null;
obj.backBufferTimerId = null;
obj.loading = false;
obj.numLoadingTiles = 0;
return obj;
},
@@ -649,7 +656,11 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
if(!backBuffer) {
return;
}
if (resolution === this.gridResolution) {
this.div.insertBefore(backBuffer, this.div.firstChild);
} else {
this.map.baseLayer.div.parentNode.insertBefore(backBuffer, this.map.baseLayer.div);
}
this.backBuffer = backBuffer;
// set some information in the instance for subsequent
@@ -699,6 +710,12 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
backBuffer.id = this.div.id + '_bb';
backBuffer.className = 'olBackBuffer';
backBuffer.style.position = 'absolute';
var map = this.map;
backBuffer.style.zIndex = this.transitionEffect === 'resize' ?
this.getZIndex() - 1 :
// 'map-resize':
map.Z_INDEX_BASE.BaseLayer -
(map.getNumLayers() - map.getLayerIndex(this));
for(var i=0, lenI=this.grid.length; i<lenI; i++) {
for(var j=0, lenJ=this.grid[i].length; j<lenJ; j++) {
var tile = this.grid[i][j],
@@ -730,7 +747,9 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
delete this._transitionElement;
}
if(this.backBuffer) {
this.div.removeChild(this.backBuffer);
if (this.backBuffer.parentNode) {
this.backBuffer.parentNode.removeChild(this.backBuffer);
}
this.backBuffer = null;
this.backBufferResolution = null;
if(this.backBufferTimerId !== null) {
@@ -1080,7 +1099,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
}
this.events.triggerEvent("tileloadstart", {tile: tile});
this.numLoadingTiles++;
if (this.backBuffer && this.gridResolution === this.backBufferResolution) {
if (!this.singleTile && this.backBuffer && this.gridResolution === this.backBufferResolution) {
OpenLayers.Element.addClass(tile.imgDiv, replacingCls);
}
};
@@ -1092,7 +1111,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
tile: tile,
aborted: aborted
});
if (!aborted && this.backBuffer && this.gridResolution === this.backBufferResolution) {
if (!this.singleTile && !aborted && this.backBuffer && this.gridResolution === this.backBufferResolution) {
if (OpenLayers.Element.getStyle(tile.imgDiv, 'display') === 'none') {
var bufferTile = document.getElementById(tile.id + '_bb');
if (bufferTile) {
@@ -1103,13 +1122,18 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
}
//if that was the last tile, then trigger a 'loadend' on the layer
if (this.numLoadingTiles === 0) {
this.loading = false;
this.events.triggerEvent("loadend");
if(this.backBuffer) {
this._transitionElement = tile.imgDiv;
for (var i=this.transitionendEvents.length-1; i>=0; --i) {
if (this.backBuffer) {
if (this.backBuffer.childNodes.length === 0) {
// no tiles transitioning, remove immediately
this.removeBackBuffer();
} else {
// wait until transition has ended or delay has passed
this._transitionElement = aborted ?
this.div.lastChild : tile.imgDiv;
var transitionendEvents = this.transitionendEvents;
for (var i=transitionendEvents.length-1; i>=0; --i) {
OpenLayers.Event.observe(this._transitionElement,
this.transitionendEvents[i],
transitionendEvents[i],
this._removeBackBuffer);
}
// the removal of the back buffer is delayed to prevent
@@ -1119,6 +1143,9 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
);
}
}
this.loading = false;
this.events.triggerEvent("loadend");
}
};
tile.onLoadError = function() {

View File

@@ -116,31 +116,16 @@ OpenLayers.Layer.TileCache = OpenLayers.Class(OpenLayers.Layer.Grid, {
var tileZ = this.serverResolutions != null ?
OpenLayers.Util.indexOf(this.serverResolutions, res) :
this.map.getZoom();
/**
* Zero-pad a positive integer.
* number - {Int}
* length - {Int}
*
* Returns:
* {String} A zero-padded string
*/
function zeroPad(number, length) {
number = String(number);
var zeros = [];
for(var i=0; i<length; ++i) {
zeros.push('0');
}
return zeros.join('').substring(0, length - number.length) + number;
}
var components = [
this.layername,
zeroPad(tileZ, 2),
zeroPad(parseInt(tileX / 1000000), 3),
zeroPad((parseInt(tileX / 1000) % 1000), 3),
zeroPad((parseInt(tileX) % 1000), 3),
zeroPad(parseInt(tileY / 1000000), 3),
zeroPad((parseInt(tileY / 1000) % 1000), 3),
zeroPad((parseInt(tileY) % 1000), 3) + '.' + this.extension
OpenLayers.Number.zeroPad(tileZ, 2),
OpenLayers.Number.zeroPad(parseInt(tileX / 1000000), 3),
OpenLayers.Number.zeroPad((parseInt(tileX / 1000) % 1000), 3),
OpenLayers.Number.zeroPad((parseInt(tileX) % 1000), 3),
OpenLayers.Number.zeroPad(parseInt(tileY / 1000000), 3),
OpenLayers.Number.zeroPad((parseInt(tileY / 1000) % 1000), 3),
OpenLayers.Number.zeroPad((parseInt(tileY) % 1000), 3) + '.' + this.extension
];
var path = components.join('/');
var url = this.url;

View File

@@ -42,7 +42,7 @@ OpenLayers.Layer.UTFGrid = OpenLayers.Class(OpenLayers.Layer.XYZ, {
/**
* APIProperty: isBaseLayer
* Default is true, as this is designed to be a base tile source.
* Default is false, as UTFGrids are designed to be a transparent overlay layer.
*/
isBaseLayer: false,
@@ -110,6 +110,12 @@ OpenLayers.Layer.UTFGrid = OpenLayers.Class(OpenLayers.Layer.XYZ, {
}, this.tileOptions);
},
/**
* Method: createBackBuffer
* The UTFGrid cannot create a back buffer, so this method is overriden.
*/
createBackBuffer: function() {},
/**
* APIMethod: clone
* Create a clone of this layer
@@ -148,7 +154,7 @@ OpenLayers.Layer.UTFGrid = OpenLayers.Class(OpenLayers.Layer.XYZ, {
getFeatureInfo: function(location) {
var info = null;
var tileInfo = this.getTileData(location);
if (tileInfo.tile) {
if (tileInfo && tileInfo.tile) {
info = tileInfo.tile.getFeatureInfo(tileInfo.i, tileInfo.j);
}
return info;

View File

@@ -264,7 +264,6 @@ OpenLayers.Layer.WMTS = OpenLayers.Class(OpenLayers.Layer.Grid, {
*/
setMap: function() {
OpenLayers.Layer.Grid.prototype.setMap.apply(this, arguments);
this.updateMatrixProperties();
},
/**

View File

@@ -6,6 +6,7 @@
/**
* @requires OpenLayers/BaseTypes/Class.js
* @requires OpenLayers/Util.js
* @requires OpenLayers/Util/vendorPrefix.js
* @requires OpenLayers/Events.js
* @requires OpenLayers/Tween.js
* @requires OpenLayers/Projection.js
@@ -69,12 +70,13 @@ OpenLayers.Map = OpenLayers.Class({
* object will include a *layer* property that references the removed
* layer.
* changelayer - triggered after a layer name change, order change,
* opacity change, params change, visibility change (due to resolution
* thresholds) or attribution change (due to extent change). Listeners
* will receive an event object with *layer* and *property* properties.
* The *layer* property will be a reference to the changed layer. The
* *property* property will be a key to the changed property (name,
* order, opacity, params, visibility or attribution).
* opacity change, params change, visibility change (actual visibility,
* not the layer's visibility property) or attribution change (due to
* extent change). Listeners will receive an event object with *layer*
* and *property* properties. The *layer* property will be a reference
* to the changed layer. The *property* property will be a key to the
* changed property (name, order, opacity, params, visibility or
* attribution).
* movestart - triggered after the start of a drag, pan, or zoom. The event
* object may include a *zoomChanged* property that tells whether the
* zoom has changed.
@@ -375,7 +377,8 @@ OpenLayers.Map = OpenLayers.Class({
* APIProperty: tileManager
* {<OpenLayers.TileManager>} If configured at construction time, the map
* will use the TileManager to queue image requests and to cache tile image
* elements.
* elements. Note: make sure that OpenLayers/TileManager.js is included in
* your build profile.
*/
tileManager: null,
@@ -383,9 +386,9 @@ OpenLayers.Map = OpenLayers.Class({
* APIProperty: fallThrough
* {Boolean} Should OpenLayers allow events on the map to fall through to
* other elements on the page, or should it swallow them? (#457)
* Default is to fall through.
* Default is to swallow.
*/
fallThrough: true,
fallThrough: false,
/**
* APIProperty: autoUpdateSize
@@ -394,12 +397,6 @@ OpenLayers.Map = OpenLayers.Class({
*/
autoUpdateSize: true,
/**
* Property: panTween
* {<OpenLayers.Tween>} Animated panning tween object, see panTo()
*/
panTween: null,
/**
* APIProperty: eventListeners
* {Object} If set as an option at construction, the eventListeners
@@ -409,6 +406,12 @@ OpenLayers.Map = OpenLayers.Class({
*/
eventListeners: null,
/**
* Property: panTween
* {<OpenLayers.Tween>} Animated panning tween object, see panTo()
*/
panTween: null,
/**
* APIProperty: panMethod
* {Function} The Easing function to be used for tweening. Default is
@@ -426,6 +429,28 @@ OpenLayers.Map = OpenLayers.Class({
*/
panDuration: 50,
/**
* Property: zoomTween
* {<OpenLayers.Tween>} Animated zooming tween object, see zoomTo()
*/
zoomTween: null,
/**
* APIProperty: zoomMethod
* {Function} The Easing function to be used for tweening. Default is
* OpenLayers.Easing.Quad.easeOut. Setting this to 'null' turns off
* animated zooming.
*/
zoomMethod: OpenLayers.Easing.Quad.easeOut,
/**
* Property: zoomDuration
* {Integer} The number of steps to be passed to the
* OpenLayers.Tween.start() method when the map is zoomed.
* Default is 20.
*/
zoomDuration: 20,
/**
* Property: paddingForPopups
* {<OpenLayers.Bounds>} Outside margin of the popup. Used to prevent
@@ -597,6 +622,7 @@ OpenLayers.Map = OpenLayers.Class({
this.layerContainerDiv = OpenLayers.Util.createDiv(id);
this.layerContainerDiv.style.zIndex=this.Z_INDEX_BASE['Popup']-1;
this.layerContainerOriginPx = {x: 0, y: 0};
this.applyTransform();
this.viewPortDiv.appendChild(this.layerContainerDiv);
@@ -692,6 +718,13 @@ OpenLayers.Map = OpenLayers.Class({
this.setCenter(options.center, options.zoom);
}
}
if (this.panMethod) {
this.panTween = new OpenLayers.Tween(this.panMethod);
}
if (this.zoomMethod && this.applyTransform.transform) {
this.zoomTween = new OpenLayers.Tween(this.zoomMethod);
}
},
/**
@@ -760,6 +793,11 @@ OpenLayers.Map = OpenLayers.Class({
this.panTween.stop();
this.panTween = null;
}
// make sure zooming doesn't continue after destruction
if(this.zoomTween) {
this.zoomTween.stop();
this.zoomTween = null;
}
// map has been destroyed. dont do it again!
OpenLayers.Event.stopObserving(window, 'unload', this.unloadDestroy);
@@ -1680,10 +1718,7 @@ OpenLayers.Map = OpenLayers.Class({
* lonlat - {<OpenLayers.LonLat>}
*/
panTo: function(lonlat) {
if (this.panMethod && this.getExtent().scale(this.panRatio).containsLonLat(lonlat)) {
if (!this.panTween) {
this.panTween = new OpenLayers.Tween(this.panMethod);
}
if (this.panTween && this.getExtent().scale(this.panRatio).containsLonLat(lonlat)) {
var center = this.getCachedCenter();
// center will not change, don't do nothing
@@ -1734,7 +1769,12 @@ OpenLayers.Map = OpenLayers.Class({
* TBD: reconsider forceZoomChange in 3.0
*/
setCenter: function(lonlat, zoom, dragging, forceZoomChange) {
this.panTween && this.panTween.stop();
if (this.panTween) {
this.panTween.stop();
}
if (this.zoomTween) {
this.zoomTween.stop();
}
this.moveTo(lonlat, zoom, {
'dragging': dragging,
'forceZoomChange': forceZoomChange
@@ -1775,17 +1815,16 @@ OpenLayers.Map = OpenLayers.Class({
}
this.center = null;
if (dx) {
this.layerContainerDiv.style.left =
(this.layerContainerOriginPx.x -= dx) + "px";
this.layerContainerOriginPx.x -= dx;
this.minPx.x -= dx;
this.maxPx.x -= dx;
}
if (dy) {
this.layerContainerDiv.style.top =
(this.layerContainerOriginPx.y -= dy) + "px";
this.layerContainerOriginPx.y -= dy;
this.minPx.y -= dy;
this.maxPx.y -= dy;
}
this.applyTransform();
var layer, i, len;
for (i=0, len=this.layers.length; i<len; ++i) {
layer = this.layers[i];
@@ -1945,11 +1984,9 @@ OpenLayers.Map = OpenLayers.Class({
// (re)set the layerContainerDiv's location
if (zoomChanged || this.layerContainerOrigin == null) {
this.layerContainerOrigin = this.getCachedCenter();
var style = this.layerContainerDiv.style;
style.left = "0px";
style.top = "0px";
this.layerContainerOriginPx.x = 0;
this.layerContainerOriginPx.y = 0;
this.applyTransform();
var maxExtent = this.getMaxExtent({restricted: true});
var maxExtentCenter = maxExtent.getCenterLonLat();
var lonDelta = this.center.lon - maxExtentCenter.lon;
@@ -2037,10 +2074,9 @@ OpenLayers.Map = OpenLayers.Class({
var oldTop = this.layerContainerOriginPx.y;
var newLeft = Math.round(originPx.x - newPx.x);
var newTop = Math.round(originPx.y - newPx.y);
this.layerContainerDiv.style.left =
(this.layerContainerOriginPx.x = newLeft) + "px";
this.layerContainerDiv.style.top =
(this.layerContainerOriginPx.y = newTop) + "px";
this.applyTransform(
(this.layerContainerOriginPx.x = newLeft),
(this.layerContainerOriginPx.y = newTop));
var dx = oldLeft - newLeft;
var dy = oldTop - newTop;
this.minPx.x -= dx;
@@ -2339,14 +2375,62 @@ OpenLayers.Map = OpenLayers.Class({
/**
* APIMethod: zoomTo
* Zoom to a specific zoom level
* Zoom to a specific zoom level. Zooming will be animated unless the map
* is configured with {zoomMethod: null}. To zoom without animation, use
* <setCenter> without a lonlat argument.
*
* Parameters:
* zoom - {Integer}
*/
zoomTo: function(zoom) {
if (this.isValidZoomLevel(zoom)) {
this.setCenter(null, zoom);
zoomTo: function(zoom, xy) {
// non-API arguments:
// xy - {<OpenLayers.Pixel>} optional zoom origin
var map = this;
if (map.isValidZoomLevel(zoom)) {
if (map.baseLayer.wrapDateLine) {
zoom = map.adjustZoom(zoom);
}
if (map.zoomTween) {
var currentRes = map.getResolution(),
targetRes = map.getResolutionForZoom(zoom),
start = {scale: 1},
end = {scale: currentRes / targetRes};
if (map.zoomTween.playing && map.zoomTween.duration < 3 * map.zoomDuration) {
// update the end scale, and reuse the running zoomTween
map.zoomTween.finish = {
scale: map.zoomTween.finish.scale * end.scale
};
} else {
if (!xy) {
var size = map.getSize();
xy = {x: size.w / 2, y: size.h / 2};
}
map.zoomTween.start(start, end, map.zoomDuration, {
minFrameRate: 50, // don't spend much time zooming
callbacks: {
eachStep: function(data) {
var containerOrigin = map.layerContainerOriginPx,
scale = data.scale,
dx = ((scale - 1) * (containerOrigin.x - xy.x)) | 0,
dy = ((scale - 1) * (containerOrigin.y - xy.y)) | 0;
map.applyTransform(containerOrigin.x + dx, containerOrigin.y + dy, scale);
},
done: function(data) {
map.applyTransform();
var resolution = map.getResolution() / data.scale,
zoom = map.getZoomForResolution(resolution, true)
map.moveTo(map.getZoomTargetCenter(xy, resolution), zoom, true);
}
}
});
}
} else {
var center = xy ?
map.getZoomTargetCenter(xy, map.getResolutionForZoom(zoom)) :
null;
map.setCenter(center, zoom);
}
}
},
@@ -2507,6 +2591,31 @@ OpenLayers.Map = OpenLayers.Class({
return px;
},
/**
* Method: getZoomTargetCenter
*
* Parameters:
* xy - {<OpenLayers.Pixel>} The zoom origin pixel location on the screen
* resolution - {Float} The resolution we want to get the center for
*
* Returns:
* {<OpenLayers.LonLat>} The location of the map center after the
* transformation described by the origin xy and the target resolution.
*/
getZoomTargetCenter: function (xy, resolution) {
var lonlat = null,
size = this.getSize(),
deltaX = size.w/2 - xy.x,
deltaY = xy.y - size.h/2,
zoomPoint = this.getLonLatFromPixel(xy);
if (zoomPoint) {
lonlat = new OpenLayers.LonLat(
zoomPoint.lon + deltaX * resolution,
zoomPoint.lat + deltaY * resolution
);
}
return lonlat;
},
//
// CONVENIENCE TRANSLATION FUNCTIONS FOR API
@@ -2667,6 +2776,76 @@ OpenLayers.Map = OpenLayers.Class({
return this.getLayerPxFromViewPortPx(px);
},
/**
* Method: applyTransform
* Applies the given transform to the <layerContainerDiv>. This method has
* a 2-stage fallback from translate3d/scale3d via translate/scale to plain
* style.left/style.top, in which case no scaling is supported.
*
* Parameters:
* x - {Number} x parameter for the translation. Defaults to the x value of
* the map's <layerContainerOriginPx>
* y - {Number} y parameter for the translation. Defaults to the y value of
* the map's <layerContainerOriginPx>
* scale - {Number} scale. Defaults to 1 if not provided.
*/
applyTransform: function(x, y, scale) {
scale = scale || 1;
var origin = this.layerContainerOriginPx,
needTransform = scale !== 1;
x = x || origin.x;
y = y || origin.y;
var style = this.layerContainerDiv.style,
transform = this.applyTransform.transform,
template = this.applyTransform.template;
if (transform === undefined) {
transform = OpenLayers.Util.vendorPrefix.style('transform');
this.applyTransform.transform = transform;
if (transform) {
// Try translate3d, but only if the viewPortDiv has a transform
// defined in a stylesheet
var computedStyle = OpenLayers.Element.getStyle(this.viewPortDiv,
OpenLayers.Util.vendorPrefix.css('transform'));
if (!computedStyle || computedStyle !== 'none') {
template = ['translate3d(', ',0) ', 'scale3d(', ',1)'];
style[transform] = [template[0], '0,0', template[1]].join('');
}
// If no transform is defined in the stylesheet or translate3d
// does not stick, use translate and scale
if (!template || !~style[transform].indexOf(template[0])) {
template = ['translate(', ') ', 'scale(', ')'];
}
this.applyTransform.template = template;
}
}
// If we do 3d transforms, we always want to use them. If we do 2d
// transforms, we only use them when we need to.
if (transform !== null && (template[0] === 'translate3d(' || needTransform === true)) {
// Our 2d transforms are combined with style.left and style.top, so
// adjust x and y values and set the origin as left and top
if (needTransform === true && template[0] === 'translate(') {
x -= origin.x;
y -= origin.y;
style.left = origin.x + 'px';
style.top = origin.y + 'px';
}
style[transform] = [
template[0], x, 'px,', y, 'px', template[1],
template[2], scale, ',', scale, template[3]
].join('');
} else {
style.left = x + 'px';
style.top = y + 'px';
// We previously might have had needTransform, so remove transform
if (transform !== null) {
style[transform] = '';
}
}
},
CLASS_NAME: "OpenLayers.Map"
});

View File

@@ -81,7 +81,7 @@ OpenLayers.Marker.Box = OpenLayers.Class(OpenLayers.Marker, {
* sz - {<OpenLayers.Size>}
*
* Returns:
* {DOMElement} A new DOM Image with this marker<EFBFBD>s icon set at the
* {DOMElement} A new DOM Image with this marker's icon set at the
* location passed-in
*/
draw: function(px, sz) {

View File

@@ -1,196 +0,0 @@
/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
* full list of contributors). Published under the 2-clause BSD license.
* See license.txt in the OpenLayers distribution or repository for the
* full text of the license. */
/**
* @requires OpenLayers/Popup/Anchored.js
* @requires OpenLayers/Console.js
* @requires Rico/Corner.js
*/
/**
* Class: OpenLayers.Popup.AnchoredBubble
* This class is *deprecated*. Use {<OpenLayers.Popup.Anchored>} and
* round corners using CSS3's border-radius property.
*
* Inherits from:
* - <OpenLayers.Popup.Anchored>
*/
OpenLayers.Popup.AnchoredBubble =
OpenLayers.Class(OpenLayers.Popup.Anchored, {
/**
* Property: rounded
* {Boolean} Has the popup been rounded yet?
*/
rounded: false,
/**
* Constructor: OpenLayers.Popup.AnchoredBubble
*
* Parameters:
* id - {String}
* lonlat - {<OpenLayers.LonLat>}
* contentSize - {<OpenLayers.Size>}
* contentHTML - {String}
* anchor - {Object} Object to which we'll anchor the popup. Must expose
* a 'size' (<OpenLayers.Size>) and 'offset' (<OpenLayers.Pixel>)
* (Note that this is generally an <OpenLayers.Icon>).
* closeBox - {Boolean}
* closeBoxCallback - {Function} Function to be called on closeBox click.
*/
initialize:function(id, lonlat, contentSize, contentHTML, anchor, closeBox,
closeBoxCallback) {
OpenLayers.Console.warn('AnchoredBubble is deprecated');
this.padding = new OpenLayers.Bounds(
0, OpenLayers.Popup.AnchoredBubble.CORNER_SIZE,
0, OpenLayers.Popup.AnchoredBubble.CORNER_SIZE
);
OpenLayers.Popup.Anchored.prototype.initialize.apply(this, arguments);
},
/**
* Method: draw
*
* Parameters:
* px - {<OpenLayers.Pixel>}
*
* Returns:
* {DOMElement} Reference to a div that contains the drawn popup.
*/
draw: function(px) {
OpenLayers.Popup.Anchored.prototype.draw.apply(this, arguments);
this.setContentHTML();
//set the popup color and opacity
this.setBackgroundColor();
this.setOpacity();
return this.div;
},
/**
* Method: updateRelativePosition
* The popup has been moved to a new relative location, in which case
* we will want to re-do the rico corners.
*/
updateRelativePosition: function() {
this.setRicoCorners();
},
/**
* APIMethod: setSize
*
* Parameters:
* contentSize - {<OpenLayers.Size>} the new size for the popup's
* contents div (in pixels).
*/
setSize:function(contentSize) {
OpenLayers.Popup.Anchored.prototype.setSize.apply(this, arguments);
this.setRicoCorners();
},
/**
* APIMethod: setBackgroundColor
*
* Parameters:
* color - {String}
*/
setBackgroundColor:function(color) {
if (color != undefined) {
this.backgroundColor = color;
}
if (this.div != null) {
if (this.contentDiv != null) {
this.div.style.background = "transparent";
OpenLayers.Rico.Corner.changeColor(this.groupDiv,
this.backgroundColor);
}
}
},
/**
* APIMethod: setOpacity
*
* Parameters:
* opacity - {float}
*/
setOpacity:function(opacity) {
OpenLayers.Popup.Anchored.prototype.setOpacity.call(this, opacity);
if (this.div != null) {
if (this.groupDiv != null) {
OpenLayers.Rico.Corner.changeOpacity(this.groupDiv,
this.opacity);
}
}
},
/**
* Method: setBorder
* Always sets border to 0. Bubble Popups can not have a border.
*
* Parameters:
* border - {Integer}
*/
setBorder:function(border) {
this.border = 0;
},
/**
* Method: setRicoCorners
* Update RICO corners according to the popup's current relative postion.
*/
setRicoCorners:function() {
var corners = this.getCornersToRound(this.relativePosition);
var options = {corners: corners,
color: this.backgroundColor,
bgColor: "transparent",
blend: false};
if (!this.rounded) {
OpenLayers.Rico.Corner.round(this.div, options);
this.rounded = true;
} else {
OpenLayers.Rico.Corner.reRound(this.groupDiv, options);
//set the popup color and opacity
this.setBackgroundColor();
this.setOpacity();
}
},
/**
* Method: getCornersToRound
*
* Returns:
* {String} The proper corners string ("tr tl bl br") for rico to round.
*/
getCornersToRound:function() {
var corners = ['tl', 'tr', 'bl', 'br'];
//we want to round all the corners _except_ the opposite one.
var corner = OpenLayers.Bounds.oppositeQuadrant(this.relativePosition);
OpenLayers.Util.removeItem(corners, corner);
return corners.join(" ");
},
CLASS_NAME: "OpenLayers.Popup.AnchoredBubble"
});
/**
* Constant: CORNER_SIZE
* {Integer} 5. Border space for the RICO corners.
*/
OpenLayers.Popup.AnchoredBubble.CORNER_SIZE = 5;

View File

@@ -712,6 +712,7 @@ OpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {
for (var i = 0; i < numRows; i++) {
if (style.labelOutlineWidth) {
this.canvas.save();
this.canvas.globalAlpha = style.labelOutlineOpacity || style.fontOpacity || 1.0;
this.canvas.strokeStyle = style.labelOutlineColor;
this.canvas.lineWidth = style.labelOutlineWidth;
this.canvas.strokeText(labelRows[i], pt[0], pt[1] + (lineHeight*i) + 1);

View File

@@ -655,6 +655,9 @@ OpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {
outlineStyle.fontColor = outlineStyle.labelOutlineColor;
outlineStyle.fontStrokeColor = outlineStyle.labelOutlineColor;
outlineStyle.fontStrokeWidth = style.labelOutlineWidth;
if (style.labelOutlineOpacity) {
outlineStyle.fontOpacity = style.labelOutlineOpacity;
}
delete outlineStyle.labelOutlineWidth;
this.drawText(featureId, outlineStyle, location);
}

View File

@@ -79,6 +79,10 @@ OpenLayers.Strategy.Refresh = OpenLayers.Class(OpenLayers.Strategy, {
var deactivated = OpenLayers.Strategy.prototype.deactivate.call(this);
if(deactivated) {
this.stop();
this.layer.events.un({
"visibilitychanged": this.reset,
scope: this
});
}
return deactivated;
},

View File

@@ -7,6 +7,7 @@
/**
* @requires OpenLayers/Tile.js
* @requires OpenLayers/Animation.js
* @requires OpenLayers/Util.js
*/
/**
@@ -317,7 +318,7 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
this.layer.div.appendChild(this.getTile());
this.events.triggerEvent(this._loadEvent);
var img = this.getImage();
if (this.url && img.getAttribute("src") == this.url) {
if (this.url && OpenLayers.Util.isEquivalentUrl(img.src, this.url)) {
this._loadTimeout = window.setTimeout(
OpenLayers.Function.bind(this.onImageLoad, this), 0
);

View File

@@ -114,6 +114,7 @@ OpenLayers.TileManager = OpenLayers.Class({
map.events.on({
move: this.move,
zoomend: this.zoomEnd,
changelayer: this.changeLayer,
addlayer: this.addLayer,
preremovelayer: this.removeLayer,
scope: this
@@ -141,6 +142,7 @@ OpenLayers.TileManager = OpenLayers.Class({
map.events.un({
move: this.move,
zoomend: this.zoomEnd,
changelayer: this.changeLayer,
addlayer: this.addLayer,
preremovelayer: this.removeLayer,
scope: this
@@ -173,6 +175,19 @@ OpenLayers.TileManager = OpenLayers.Class({
this.updateTimeout(evt.object, this.zoomDelay);
},
/**
* Method: changeLayer
* Handles the map's changeLayer event
*
* Parameters:
* evt - {Object} Listener argument
*/
changeLayer: function(evt) {
if (evt.property === 'visibility' || evt.property === 'params') {
this.updateTimeout(evt.object, 0);
}
},
/**
* Method: addLayer
* Handles the map's addlayer event
@@ -300,9 +315,16 @@ OpenLayers.TileManager = OpenLayers.Class({
var tile = evt.object;
var queued = false;
var layer = tile.layer;
var url = layer.getURL(tile.bounds);
var img = this.tileCache[url];
if (img && img.className !== 'olTileImage') {
// cached image no longer valid, e.g. because we're olTileReplacing
delete this.tileCache[url];
OpenLayers.Util.removeItem(this.tileCacheIndex, url);
img = null;
}
// queue only if image with same url not cached already
if (layer.url && (layer.async ||
!this.tileCache[layer.getURL(tile.bounds)])) {
if (layer.url && (layer.async || !img)) {
// add to queue only if not in queue already
var tileQueue = this.tileQueue[layer.map.id];
if (!~OpenLayers.Util.indexOf(tileQueue, tile)) {
@@ -341,6 +363,8 @@ OpenLayers.TileManager = OpenLayers.Class({
img.style.opacity = 0;
img.style.visibility = 'hidden';
}
// Only backbuffer tiles have an id, so we don't want one here
img.id = null;
tile.setImage(img);
// LRU - move tile to the end of the array to mark it as the most
// recently used

View File

@@ -1,9 +1,9 @@
/**
* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
* full list of contributors). Published under the 2-clause BSD license.
* See license.txt in the OpenLayers distribution or repository for the
* full text of the license.
*
* full text of the license. */
/**
* @requires OpenLayers/SingleFile.js
*/

View File

@@ -1,9 +1,9 @@
/**
* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
* full list of contributors). Published under the 2-clause BSD license.
* See license.txt in the OpenLayers distribution or repository for the
* full text of the license.
*
* full text of the license. */
/**
* @requires OpenLayers/SingleFile.js
*/

View File

@@ -1,9 +1,9 @@
/**
* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
* full list of contributors). Published under the 2-clause BSD license.
* See license.txt in the OpenLayers distribution or repository for the
* full text of the license.
*
* full text of the license. */
/**
* @requires OpenLayers/SingleFile.js
*/

View File

@@ -22,6 +22,8 @@
* @requires OpenLayers/Format/XML.js
* @requires OpenLayers/Geometry.js
* @requires OpenLayers/Renderer/Elements.js
* @requires OpenLayers/Popup/Anchored.js
* @requires Rico/Corner.js
*/
/**
@@ -5657,3 +5659,184 @@ OpenLayers.Renderer.SVG2.LABEL_VFACTOR = {
OpenLayers.Renderer.SVG2.preventDefault = function(e) {
e.preventDefault && e.preventDefault();
};
/**
* Class: OpenLayers.Popup.AnchoredBubble
* This class is *deprecated*. Use {<OpenLayers.Popup.Anchored>} and
* round corners using CSS3's border-radius property.
*
* Inherits from:
* - <OpenLayers.Popup.Anchored>
*/
OpenLayers.Popup.AnchoredBubble = OpenLayers.Class(OpenLayers.Popup.Anchored, {
/**
* Property: rounded
* {Boolean} Has the popup been rounded yet?
*/
rounded: false,
/**
* Constructor: OpenLayers.Popup.AnchoredBubble
*
* Parameters:
* id - {String}
* lonlat - {<OpenLayers.LonLat>}
* contentSize - {<OpenLayers.Size>}
* contentHTML - {String}
* anchor - {Object} Object to which we'll anchor the popup. Must expose
* a 'size' (<OpenLayers.Size>) and 'offset' (<OpenLayers.Pixel>)
* (Note that this is generally an <OpenLayers.Icon>).
* closeBox - {Boolean}
* closeBoxCallback - {Function} Function to be called on closeBox click.
*/
initialize:function(id, lonlat, contentSize, contentHTML, anchor, closeBox,
closeBoxCallback) {
this.padding = new OpenLayers.Bounds(
0, OpenLayers.Popup.AnchoredBubble.CORNER_SIZE,
0, OpenLayers.Popup.AnchoredBubble.CORNER_SIZE
);
OpenLayers.Popup.Anchored.prototype.initialize.apply(this, arguments);
},
/**
* Method: draw
*
* Parameters:
* px - {<OpenLayers.Pixel>}
*
* Returns:
* {DOMElement} Reference to a div that contains the drawn popup.
*/
draw: function(px) {
OpenLayers.Popup.Anchored.prototype.draw.apply(this, arguments);
this.setContentHTML();
//set the popup color and opacity
this.setBackgroundColor();
this.setOpacity();
return this.div;
},
/**
* Method: updateRelativePosition
* The popup has been moved to a new relative location, in which case
* we will want to re-do the rico corners.
*/
updateRelativePosition: function() {
this.setRicoCorners();
},
/**
* APIMethod: setSize
*
* Parameters:
* contentSize - {<OpenLayers.Size>} the new size for the popup's
* contents div (in pixels).
*/
setSize:function(contentSize) {
OpenLayers.Popup.Anchored.prototype.setSize.apply(this, arguments);
this.setRicoCorners();
},
/**
* APIMethod: setBackgroundColor
*
* Parameters:
* color - {String}
*/
setBackgroundColor:function(color) {
if (color != undefined) {
this.backgroundColor = color;
}
if (this.div != null) {
if (this.contentDiv != null) {
this.div.style.background = "transparent";
OpenLayers.Rico.Corner.changeColor(this.groupDiv,
this.backgroundColor);
}
}
},
/**
* APIMethod: setOpacity
*
* Parameters:
* opacity - {float}
*/
setOpacity:function(opacity) {
OpenLayers.Popup.Anchored.prototype.setOpacity.call(this, opacity);
if (this.div != null) {
if (this.groupDiv != null) {
OpenLayers.Rico.Corner.changeOpacity(this.groupDiv,
this.opacity);
}
}
},
/**
* Method: setBorder
* Always sets border to 0. Bubble Popups can not have a border.
*
* Parameters:
* border - {Integer}
*/
setBorder:function(border) {
this.border = 0;
},
/**
* Method: setRicoCorners
* Update RICO corners according to the popup's current relative postion.
*/
setRicoCorners:function() {
var corners = this.getCornersToRound(this.relativePosition);
var options = {corners: corners,
color: this.backgroundColor,
bgColor: "transparent",
blend: false};
if (!this.rounded) {
OpenLayers.Rico.Corner.round(this.div, options);
this.rounded = true;
} else {
OpenLayers.Rico.Corner.reRound(this.groupDiv, options);
//set the popup color and opacity
this.setBackgroundColor();
this.setOpacity();
}
},
/**
* Method: getCornersToRound
*
* Returns:
* {String} The proper corners string ("tr tl bl br") for rico to round.
*/
getCornersToRound:function() {
var corners = ['tl', 'tr', 'bl', 'br'];
//we want to round all the corners _except_ the opposite one.
var corner = OpenLayers.Bounds.oppositeQuadrant(this.relativePosition);
OpenLayers.Util.removeItem(corners, corner);
return corners.join(" ");
},
CLASS_NAME: "OpenLayers.Popup.AnchoredBubble"
});
/**
* Constant: CORNER_SIZE
* {Integer} 5. Border space for the RICO corners.
*/
OpenLayers.Popup.AnchoredBubble.CORNER_SIZE = 5;

View File

@@ -37,6 +37,27 @@ Corresponding issues/pull requests:
# Behavior Changes from Past Releases
## Control.DragPan: Kinetic by default
The `enableKinetic` property for the DragPan control has been changed to true by default. This will enable kinetic panning only if the `OpenLayers/Kinetic.js` file is included in your build.
## Control.ModifyFeature: no more built-in SelectFeature control
The ModifyFeature control is now much leaner, making it more reliable when combined with other controls. The most noticable change is that it has no
`selectControl` member any more. Users who previously relied on this built-in SelectFeature control will now have to create both a SelectFeature and a ModifyFeature control and configure the ModifyFeature control with `standalone: true`. To get features selected, call the `selectFeature` method e.g. from a `featureselected` listener on the vector layer.
## Format.GPX: No more prefixes
No `gpx:` prefix is added in the XML tags anymore when writing GPX from `OpenLayers` features. It seems like it is not supported by most of the tools that are able to read GPX.
## Different return type for OpenLayers.Format.WMSDescribeLayer
The return type of WMSDescribeLayer format's `read` method was different from the one of the VersionedOGC format superclass. So it was changed from an array to an object with a layerDescriptions property that holds the array. For backwards compatibility, the object still has a length property and 0, ..., n properties with the previous array values.
## Moved errorProperty from the base class to the parser in Format.OWSCommon
This was necessary for WCS support because there are no properties in common between versions 1.0.0 and 1.1.0 that were appropriate for checking. The only existing code that this affected was WFS parsing.
## Layer.Grid: Tile queue and tileLoadingDelay changes
With the introduction of OpenLayers.TileManager, tile queueing has become optional. The default behavior is back to how it was in OpenLayers 2.11. To use a tile queue in 2.13, the map needs to be configured with a tileManager, e.g.:
@@ -51,6 +72,40 @@ The `moveDelay` is the replacement for the `tileLoadingDelay` layer config optio
In general, when targeting mobile devices or when using slow servers or connections for tiled layers, it is recommended to configure the map with a TileManager.
## Layer.Grid: Resize transitions by default
The `transitionEffect` property for grid layers has been changed to "resize" by default. This allows smooth transitions with animated zooming (also enabled by default). If resize transitions are not wanted for individual layers, set `transitionEffect` to `null`.
## Map: Animated zooming and GPU support
OpenLayers now has animated zooming, which is enabled by default. To turn it off, configure the map with `zoomMethod: null`.
To make the zoom animation smooth, GPU support is active by default for rendering tiles. This may interer with UI widgets that overlay the map. In this case, it may be necessary to turn GPU support off, which is done with the following css declaration:
img.olTileImage {
-webkit-transform: inherit;
-moz-transform: inherit;
-o-transform: inherit;
-ms-transform: inherit;
transform: inherit;
-webkit-backface-visibility: inherit;
-moz-backface-visibility: inherit;
-ms-backface-visibility: inherit;
backface-visibility: inherit;
-webkit-perspective: inherit;
-moz-perspective: inherit;
-ms-perspective: inherit;
perspective: inherit;
}
## Map property fallThrough defaults to false
The behaviour controlled by map property fallThrough wasn't consistent (some events were swallowed even with fallThrough set to true) and changes have been made to fix that. Defaulting fallThrough to false after this change is sensible in most situations and will probably be what most applications expect, but if you previously relied on pointer or keyboard events being passed through you will probably want to set fallThrough to true.
Behavioural change was made in this commit:
* https://github.com/openlayers/openlayers/commit/a6119f6a7528e013b922fd0d997a07df13f6bd6e
## window.$ is no longer an alias for OpenLayers.Util.getElement
We do no longer create a global variable '$' when such a symbol isn't already
@@ -79,10 +134,23 @@ Corresponding issue/pull requests:
* https://github.com/openlayers/openlayers/pull/528
# Different return type for OpenLayers.Format.WMSDescribeLayer
## Deprecated Components
A number of properties, methods, and constructors have been marked as
deprecated for multiple releases in the 2.x series.
For the 2.13 release this deprecated functionality has been moved to a
separate deprecated.js file. If you use any of the constructors or
methods below, you will have to explicitly include the deprecated.js
file in your build (or add it in a separate `<script>` tag after
OpenLayers.js).
The return type of WMSDescribeLayer format's `read` method was different from the one of the VersionedOGC format superclass. So it was changed from an array to an object with a layerDescriptions property that holds the array. For backwards compatibility, the object still has a length property and 0, ..., n properties with the previous array values.
* OpenLayers.Layer.Popup.AnchoredBubble
# Moved errorProperty from the base class to the parser
Because the Rico library is now only used by deprecated components, the
files have been removed from the debug loader in lib/OpenLayers.js;
the files have now to be explicitly loaded in a script tag.
This was necessary for WCS support because there are no properties in common between versions 1.0.0 and 1.1.0 that were appropriate for checking. The only existing code that this affected was WFS parsing.
## LayerSwitcher rounded corner removal
The deprecated `roundedCorner` and `roundedCornerColor` options have
been removed from the `OpenLayers.Control.LayerSwitcher` control. Use
CSS3's border-radius instead.

View File

@@ -155,8 +155,8 @@
}
};
t.eq(
format("${a.b.c} ${a.b.e} ${a.b.q} ${a} ${a...b...c}", context),
"d f undefined [object Object] d",
format("${a.b.c} ${a.b.e} ${a.b.q} ${a} ${a...b...c} ${aa.b} ${a.bb.c}", context),
"d f undefined [object Object] d undefined undefined",
"attribute values that are objects are supported"
);
@@ -279,6 +279,17 @@
t.eq(format(num, 3), "12.345,679", "changing thousands/decimal separator globally works");
}
function test_Number_zeroPad(t) {
t.plan(6);
var pad = OpenLayers.Number.zeroPad;
t.eq(pad(15, 4), "0015", "left padding works");
t.eq(pad(15, 2), "15", "no left padding when equal to number of digits");
t.eq(pad(15, 1), "15", "no left padding when less than number of digits");
t.eq(pad(10, 5, 2), "01010", "radix modified and padding works");
t.eq(pad(10, 5, 8), "00012", "radix modified and padding works");
t.eq(pad(10, 5, 36), "0000a", "radix modified and padding works");
}
function test_Function_bind(t) {
t.plan(12);

View File

@@ -444,37 +444,36 @@
function test_Bounds_extend(t) {
t.plan( 9 );
// null bounds to start
var originalBounds = new OpenLayers.Bounds();
var bounds = originalBounds.clone();
//null bounds to start
bounds.extend(new OpenLayers.LonLat(4,5));
t.ok(bounds.equals(new OpenLayers.Bounds(4,5,4,5)), "uninitialized bounds can be safely extended");
// extend with null obj
originalBounds = new OpenLayers.Bounds(10,20,50,80);
bounds = originalBounds.clone();
//null obj
bounds.extend(null);
t.ok(bounds.equals(originalBounds), "null to extend does not crash or change original bounds");
//obj with no classname
// obj with no classname
var object = {};
bounds.extend(object);
t.ok(bounds.equals(originalBounds), "extend() passing object with no classname does not crash or change original bounds")
//obj is bounds
//pushing all limits with bounds obj
// obj is bounds
// pushing all limits with bounds obj
var testBounds = new OpenLayers.Bounds(5, 10, 60, 90);
object = testBounds.clone();
bounds.extend(object);
t.ok(bounds.equals(testBounds), "extend by valid bounds, pushing all limits, correctly extends bounds");
//pushing no limits with bounds obj
// pushing no limits with bounds obj
bounds = originalBounds.clone();
testBounds = new OpenLayers.Bounds(15, 30, 40, 70);
@@ -483,9 +482,10 @@
bounds.extend(object);
t.ok(bounds.equals(originalBounds), "extend by valid bounds, pushing no limits, correctly does not extend bounds");
// obj is lonlat
//left, bottom
// left, bottom
bounds = originalBounds.clone();
object = new OpenLayers.LonLat(5, 10);
@@ -495,9 +495,9 @@
t.ok( ((bounds.left == object.lon) &&
(bounds.bottom == object.lat) &&
(bounds.right == originalBounds.right) &&
(bounds.top == originalBounds.top)), "obj lonlat to extends correclty modifies left and bottom");
(bounds.top == originalBounds.top)), "obj lonlat to extends correctly modifies left and bottom");
//right, top
// right, top
bounds = originalBounds.clone();
object = new OpenLayers.LonLat(60,90);
@@ -507,11 +507,12 @@
t.ok( ((bounds.left == originalBounds.left) &&
(bounds.bottom == originalBounds.bottom) &&
(bounds.right == object.lon) &&
(bounds.top == object.lat)), "obj lonlat to extends correclty modifies right and top");
(bounds.top == object.lat)), "obj lonlat to extends correctly modifies right and top");
// obj is point
//left, bottom
// left, bottom
bounds = originalBounds.clone();
object = new OpenLayers.Geometry.Point(5, 10);
@@ -521,9 +522,9 @@
t.ok( ((bounds.left == object.x) &&
(bounds.bottom == object.y) &&
(bounds.right == originalBounds.right) &&
(bounds.top == originalBounds.top)), "obj Point to extends correclty modifies left and bottom");
(bounds.top == originalBounds.top)), "obj Point to extends correctly modifies left and bottom");
//right, top
// right, top
bounds = originalBounds.clone();
object = new OpenLayers.Geometry.Point(60,90);
@@ -533,11 +534,44 @@
t.ok( ((bounds.left == originalBounds.left) &&
(bounds.bottom == originalBounds.bottom) &&
(bounds.right == object.x) &&
(bounds.top == object.y)), "obj Point to extends correclty modifies right and top");
(bounds.top == object.y)), "obj Point to extends correctly modifies right and top");
}
function test_Bounds_extendXY(t) {
t.plan(3);
// null bounds to start
var originalBounds = new OpenLayers.Bounds();
var bounds = originalBounds.clone();
bounds.extendXY(4, 5);
t.ok(bounds.equals(new OpenLayers.Bounds(4,5,4,5)), "uninitialized bounds can be safely extended");
// left, bottom
originalBounds = new OpenLayers.Bounds(10,20,50,80);
bounds = originalBounds.clone();
bounds.extendXY(5, 10);
t.ok( ((bounds.left == 5) &&
(bounds.bottom == 10) &&
(bounds.right == originalBounds.right) &&
(bounds.top == originalBounds.top)), "extendXY correctly modifies left and bottom");
// right, top
bounds = originalBounds.clone();
bounds.extendXY(60, 90);
t.ok( ((bounds.left == originalBounds.left) &&
(bounds.bottom == originalBounds.bottom) &&
(bounds.right == 60) &&
(bounds.top == 90)), "extendXY correctly modifies right and top");
}
function test_Bounds_wrapDateLine(t) {
t.plan( 13 );

View File

@@ -101,18 +101,6 @@
map.removeControl(control);
map.setCenter(centerLL);
}
function test_uncapable(t) {
t.plan(1);
var control = new OpenLayers.Control.Geolocate({
geolocation: null,
bind: false
});
control.events.register('locationuncapable', null, function() {
t.ok(true,'uncapable browser fired locationuncapable event');
});
map.addControl(control);
control.activate();
}
function test_destroy(t) {
t.plan(1);
var control = new OpenLayers.Control.Geolocate({

View File

@@ -88,13 +88,13 @@
control = new OpenLayers.Control.LayerSwitcher();
map.addControl(control);
var wmsInput = OpenLayers.Util.getElement(control.id + "_input_" + layer.name);
var wmsInput = control.div.childNodes[0].childNodes[1].childNodes[0];
t.ok(wmsInput != null, "correctly makes an input for wms layer");
t.eq(wmsInput.type, "radio", "wms correctly made a radio button");
t.eq(wmsInput.name, control.id + "_baseLayers", "wms correctly named");
t.eq(wmsInput.value, layer.name, "wms correctly valued");
var markersInput = OpenLayers.Util.getElement(control.id + "_input_" + markers.name);
var markersInput = control.div.childNodes[0].childNodes[3].childNodes[0];
t.ok(markersInput != null, "correctly makes an input for markers layer");
t.eq(markersInput.type, "checkbox", "wms correctly made a radio button");
t.eq(markersInput.name, markers.name, "wms correctly named");
@@ -191,7 +191,54 @@
t.eq(control.div.childNodes[0].childNodes[0].style.display, "" , "Base layer display on when visble base layer");
}
// See e.g. https://github.com/openlayers/openlayers/issues/866
function test_Control_LayerSwitcher_validIds(t){
t.plan(2);
// setup
var layername = "Name with spaces & illegal characters * + ~ ` ' ? )",
map = new OpenLayers.Map("map", {
controls: [
new OpenLayers.Control.LayerSwitcher()
],
layers: [
new OpenLayers.Layer.WMS(
layername,
"../../img/blank.gif"
),
// add another layer with the same name, the generated id
// must be different
new OpenLayers.Layer.WMS(
layername,
"../../img/blank.gif"
)
]
});
var baselayerDiv = map.controls[0].div.childNodes[0].childNodes[1],
firstGeneratedInputId = baselayerDiv.childNodes[0].id,
secondGeneratedInputId = baselayerDiv.childNodes[1].id,
// legal ids start with a letter and are followed only by word
// characters (letters, digits, and underscores) plus the dash (-)
// This is only a subset of all allowed charcters inside of ids.
allowedIdChars = (/^[a-zA-Z]{1}[\w-]*$/g);
// tests
// validity
t.ok(
allowedIdChars.test(firstGeneratedInputId),
"id only contains letters, digits, underscores and dashes. It " +
"starts with a letter."
);
// uniqueness
t.ok(
firstGeneratedInputId !== secondGeneratedInputId,
"generated ids are different even for equal layernames"
);
// teardown
map.destroy();
}
</script>
</head>

View File

@@ -13,34 +13,27 @@
}
};
var options = {
geometryTypes: "bar"
documentDrag: true
};
var control = new OpenLayers.Control.ModifyFeature(layer, options);
t.ok(control.layer == layer,
"constructor sets layer correctly");
t.eq(control.selectControl.geometryTypes, "bar",
"constructor sets options correctly on feature handler");
t.eq(control.handlers.drag.documentDrag, true,
"constructor sets options correctly on drag handler");
t.eq(control.mode, OpenLayers.Control.ModifyFeature.RESHAPE,
"constructor initializes modification mode correctly");
control.destroy();
}
function test_destroy(t) {
t.plan(2);
t.plan(1);
var map = new OpenLayers.Map("map");
var layer = new OpenLayers.Layer.Vector();
map.addLayer(layer);
var control = new OpenLayers.Control.ModifyFeature(layer);
control.selectControl.destroy = function() {
t.ok(true,
"control.destroy calls destroy on select control");
}
control.dragControl.destroy = function() {
t.ok(true,
"control.destroy calls destroy on feature handler");
}
control.destroy();
t.eq(control.layer, null, "Layer reference removed on destroy.");
map.destroy();
}
@@ -51,11 +44,11 @@
map.addLayer(layer);
var control = new OpenLayers.Control.ModifyFeature(layer);
map.addControl(control);
t.ok(!control.selectControl.active,
"select control is not active prior to activating control");
t.ok(!control.handlers.drag.active,
"drag handler is not active prior to activating control");
control.activate();
t.ok(control.selectControl.active,
"select control is active after activating control");
t.ok(control.handlers.drag.active,
"drag handler is active after activating control");
map.destroy();
}
@@ -99,7 +92,8 @@
);
// mock up vertex deletion
control.dragControl.feature = point;
var origGetFeatureFromEvent = layer.getFeatureFromEvent;
layer.getFeatureFromEvent = function() { return point; };
control.feature = poly;
// we cannot use selectFeature since the control is not part of a map
control._originalGeometry = poly.geometry.clone();
@@ -139,17 +133,18 @@
t.eq(control.feature.state, OpenLayers.State.UPDATE, "feature state set to update");
// now make sure nothing happens if the vertex is mid-drag
control.dragControl.handlers.drag.dragging = true;
control.handlers.drag.dragging = true;
control.handleKeypress({keyCode:delKey});
// clean up
layer.getFeatureFromEvent = origGetFeatureFromEvent;
control.destroy();
layer.destroy();
}
function test_onUnSelect(t) {
t.plan(6);
t.plan(5);
var layer = new OpenLayers.Layer.Vector();
var control = new OpenLayers.Control.ModifyFeature(layer);
var fakeFeature = {'id':'myid'};
@@ -159,7 +154,6 @@
layer.events.on({"afterfeaturemodified": function(event) {
t.eq(event.feature, fakeFeature, "afterfeaturemodified triggered");
}});
control.dragControl.deactivate = function() { t.ok(true, "Deactivate called on drag control"); }
control.onModificationEnd = function (feature) { t.eq(feature.id, fakeFeature.id, "onModificationEnd got feature.") }
layer.removeFeatures = function(verts) {
t.ok(verts == 'a', "Normal verts removed correctly");
@@ -190,10 +184,6 @@
// If a feature is to be modified, control.selectFeature gets called.
// We want this test to fail if selectFeature gets called.
var modified = false;
var _ = OpenLayers.Control.ModifyFeature.prototype.selectFeature;
OpenLayers.Control.ModifyFeature.prototype.selectFeature = function() {
modified = true;
}
var control = new OpenLayers.Control.ModifyFeature(layer);
map.addControl(control);
@@ -202,17 +192,15 @@
// register a listener that will stop feature modification
layer.events.on({"beforefeaturemodified": function() {return false}});
// we can initiate feature modification by selecting a feature with
// the control's select feature control
control.selectControl.select(feature);
// we can initiate feature modification by programmatically selecting
// a feature
control.selectFeature(feature);
if(modified) {
t.fail("selectFeature called, prepping feature for modification");
} else {
t.ok(true, "the beforefeaturemodified listener stopped feature modification");
}
OpenLayers.Control.ModifyFeature.prototype.selectFeature = _;
}
function test_selectFeature(t) {
@@ -228,7 +216,6 @@
t.ok(obj.feature == fakeFeature, "beforefeaturemodified triggered");
};
layer.events.on({"beforefeaturemodified": callback});
control.dragControl.activate = function() { t.ok(true, "drag Control activated"); }
control.onModificationStart = function(feature) { t.eq(feature.id, fakeFeature.id, "On Modification Start called with correct feature."); }
// Start of testing
@@ -262,7 +249,7 @@
control.selectFeature(fakeFeature);
control.vertices = ['a'];
control.virtualVertices = ['b'];
control.virtualVertices = [{destroy: function() {}}];
layer.addFeatures = function(features) {}
@@ -283,7 +270,7 @@
}
function test_resetVertices(t) {
t.plan(21);
t.plan(20);
var layer = new OpenLayers.Layer.Vector();
var control = new OpenLayers.Control.ModifyFeature(layer);
var point = new OpenLayers.Geometry.Point(5,6);
@@ -340,18 +327,6 @@
t.eq(control.vertices.length, 0, "No vertices when both resizing and reshaping (RESIZE|RESHAPE)");
t.eq(control.virtualVertices.length, 0, "No virtual vertices when both resizing and reshaping (RESIZE|RESHAPE)");
control.dragControl.feature = new OpenLayers.Feature.Vector(polygon);
control.dragControl.map = {};
control.dragControl.map.div = {};
control.dragControl.map.div.style = {};
control.dragControl.map.viewPortDiv = "foo";
control.dragControl.handlers.drag.deactivate = function() {
this.active = false;
}
control.resetVertices();
t.ok(!control.dragControl.handlers.drag.active, "resetVertices deactivates drag handler");
control.dragControl.map = null;
control.destroy();
layer.destroy();
}
@@ -512,17 +487,19 @@
var control = new OpenLayers.Control.ModifyFeature(layer);
map.addControl(control);
control.selectControl.deactivate = function() {
control.handlers.keyboard.deactivate = function() {
t.ok(true,
"control.deactivate calls deactivate on select control");
"control.deactivate calls deactivate on keyboard handler");
}
control.dragControl.deactivate = function() {
control.handlers.drag.deactivate = function() {
t.ok(true,
"control.deactivate calls deactivate on drag control");
"control.deactivate calls deactivate on drag handler");
}
control.active = true;
control.deactivate();
control.handlers.keyboard.deactivate = OpenLayers.Handler.Keyboard.prototype.deactivate;
control.handlers.drag.deactivate = OpenLayers.Handler.Drag.prototype.deactivate;
map.destroy();
}
@@ -609,14 +586,17 @@
layer.events.on({"featuremodified": function(event) {
t.eq(event.feature.id, poly.id, "featuremodified triggered");
}});
control.onModification = function(feature) {
t.eq(feature.id, poly.id,
"onModification called with the right feature on vertex delete");
};
point.geometry.parent = poly.geometry;
control.dragControl.feature = point;
origGetFeatureFromEvent = layer.getFeatureFromEvent;
layer.getFeatureFromEvent = function() { return point; };
control.handleKeypress({keyCode:46});
layer.drawFeature = oldDraw;
layer.getFeatureFromEvent = origGetFeatureFromEvent;
map.destroy();
}
@@ -694,7 +674,7 @@
function test_standalone(t) {
t.plan(18);
t.plan(17);
var map = new OpenLayers.Map("map");
var layer = new OpenLayers.Layer.Vector();
@@ -733,7 +713,6 @@
// activate control
control.activate();
t.eq(control.active, true, "[activate] control activated");
t.eq(control.selectControl, null, "[activate] no select control");
// manually select feature for editing
control.selectFeature(f1);
@@ -761,22 +740,19 @@
t.ok(log[0].feature === f2, "[deactivate] correct feature");
t.eq(log[0].modified, false, "[deactivate] feature not actually modified");
// reactivate control and select a point feature to see if we can drag
// another point feature;
control.activate();
control.selectFeature(f3);
control.dragControl.handlers.feature.triggerCallback("mousemove", "in", [f4]);
t.eq(control.dragControl.handlers.drag.active, false, "cannot drag unselected feature f4");
control.dragControl.handlers.feature.triggerCallback("mousemove", "in", [f3]);
t.eq(control.dragControl.handlers.drag.active, true, "can drag selected feature f3");
// select the polygon feature to make sure that we can drag vertices and
// virtual vertices
control.selectFeature(f2);
control.dragControl.handlers.feature.triggerCallback("mousemove", "in", [control.vertices[0]]);
t.eq(control.dragControl.handlers.drag.active, true, "can drag vertex of feature f2");
control.dragControl.handlers.feature.triggerCallback("mousemove", "in", [control.virtualVertices[0]]);
t.eq(control.dragControl.handlers.drag.active, true, "can drag virtual vertex of feature f2");
var origGetFeatureFromEvent = layer.getFeatureFromEvent;
layer.getFeatureFromEvent = function() { return control.vertices[0]; };
control.handlers.drag.callbacks.down.call(control, new OpenLayers.Pixel(0,0));
t.ok(control.vertex === control.vertices[0], "can drag vertex of feature f2");
t.ok(control.feature === f2, "dragging a vertex does not change the selected feature");
layer.getFeatureFromEvent = function() { return control.virtualVertices[0]; };
control.handlers.drag.callbacks.down.call(control, new OpenLayers.Pixel(0,0));
t.ok(control.vertex === control.virtualVertices[0], "can drag virtual vertex of feature f2");
t.ok(control.feature === f2, "dragging a vertex does not change the selected feature");
layer.getFeatureFromEvent = origGetFeatureFromEvent;
control.deactivate();
map.destroy();
@@ -826,6 +802,20 @@
control.destroy();
}
function test_moveLayerToTop_moveLayerBack(t) {
t.plan(2);
var map = new OpenLayers.Map("map");
var layer1 = new OpenLayers.Layer.Vector();
var layer2 = new OpenLayers.Layer.Vector();
map.addLayers([layer1, layer2]);
var control = new OpenLayers.Control.ModifyFeature(layer1);
map.addControl(control);
control.activate();
t.ok(layer1.div.style.zIndex > layer2.div.style.zIndex, "layer raised so events don't get swallowed");
control.deactivate();
t.ok(layer1.div.style.zIndex < layer2.div.style.zIndex, 'layer order restored on deactivation');
}
</script>
</head>
<body>

View File

@@ -148,6 +148,7 @@
var nav = new OpenLayers.Control.Navigation({zoomWheelEnabled: false});
var map = new OpenLayers.Map({
div: "map",
zoomMethod: null,
controls: [nav],
layers: [
new OpenLayers.Layer(null, {isBaseLayer: true})

View File

@@ -170,7 +170,7 @@
function test_clear(t) {
t.plan(7);
var map = new OpenLayers.Map("map");
var map = new OpenLayers.Map("map", {zoomMethod: null});
var layer = new OpenLayers.Layer(
"test", {isBaseLayer: true}
);

View File

@@ -77,7 +77,7 @@
function test_Control_PanZoomBar_onButtonClick (t) {
t.plan(2);
map = new OpenLayers.Map('map', {controls:[]});
map = new OpenLayers.Map('map', {controls:[], zoomMethod: null});
var layer = new OpenLayers.Layer.WMS("Test Layer",
"http://octo.metacarta.com/cgi-bin/mapserv?",
{map: "/mapdata/vmap_wms.map", layers: "basic"});
@@ -97,7 +97,8 @@
t.plan(1);
map = new OpenLayers.Map('map', {
controls: [],
fractionalZoom: true
fractionalZoom: true,
zoomMethod: null
});
var layer = new OpenLayers.Layer.WMS("Test Layer", "http://octo.metacarta.com/cgi-bin/mapserv?", {
map: "/mapdata/vmap_wms.map",
@@ -127,7 +128,8 @@
var map = new OpenLayers.Map('map', {
controls: [],
fractionalZoom: true
fractionalZoom: true,
zoomMethod: null
});
var layer = new OpenLayers.Layer.WMS("Test Layer", "http://octo.metacarta.com/cgi-bin/mapserv?", {
map: "/mapdata/vmap_wms.map",

View File

@@ -45,8 +45,8 @@
});
var log = [];
control.applyTransform = function(transform) {
log.push(transform);
map.applyTransform = function(x, y, scale) {
log.push([x, y, scale]);
}
map.layerContainerOriginPx = {
@@ -58,12 +58,12 @@
};
var cases = [
{x: 100, y: 60, scale: 1, transform: "translate(0px, 10px) scale(1)"},
{x: 150, y: 60, scale: 1, transform: "translate(50px, 10px) scale(1)"},
{x: 150, y: 60, scale: 2, transform: "translate(-100px, -90px) scale(2)"},
{x: 50, y: 20, scale: 2.5, transform: "translate(-275px, -180px) scale(2.5)"},
{x: 150, y: 60, scale: 2, transform: "translate(-100px, -90px) scale(2)"},
{x: 50, y: 20, scale: 0.25, transform: "translate(63px, 45px) scale(0.25)"}
{x: 100, y: 60, scale: 1, transform: [-50, -40, 1]},
{x: 150, y: 60, scale: 1, transform: [0, -40, 1]},
{x: 150, y: 60, scale: 2, transform: [-150, -140, 2]},
{x: 50, y: 20, scale: 2.5, transform: [-325, -230, 2.5]},
{x: 150, y: 60, scale: 2, transform: [-150, -140, 2]},
{x: 50, y: 20, scale: 0.25, transform: [13, -5, 0.25]}
];
var len = cases.length;
@@ -95,23 +95,23 @@
var centerPx = map.getPixelFromLonLat(map.getCenter());
control.pinchStart = function(evt, pinchData) {
t.eq(control.pinchOrigin, centerPx, "center preserved");
t.eq(control.currentCenter, centerPx, "center preserved");
t.eq(map.layerContainerOriginPx, {x: 0, y: 0}, "center preserved");
t.eq(map.getPixelFromLonLat(map.getCenter()), centerPx, "center preserved");
}
control.pinchStart(null);
var log = [];
control.applyTransform = function(transform) {
log.push(transform);
map.applyTransform = function(x, y, scale) {
log.push([x, y, scale]);
}
control.pinchOrigin = map.getPixelFromLonLat(map.getCenter());
var cases = [
{scale: 1, transform: "translate(0px, 0px) scale(1)"},
{scale: 2, transform: "translate(-128px, -128px) scale(2)"},
{scale: 2.5, transform: "translate(-192px, -192px) scale(2.5)"},
{scale: 0.25, transform: "translate(96px, 96px) scale(0.25)"}
{scale: 1, transform: [0, 0, 1]},
{scale: 2, transform: [-128, -128, 2]},
{scale: 2.5, transform: [-192, -192, 2.5]},
{scale: 0.25, transform: [96, 96, 0.25]}
];
var len = cases.length;

View File

@@ -22,7 +22,7 @@
control = new OpenLayers.Control.Scale('scale');
t.ok( control instanceof OpenLayers.Control.Scale, "new OpenLayers.Control returns object" );
map = new OpenLayers.Map('map');
map = new OpenLayers.Map('map', {zoomMethod: null});
layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});
map.addLayer(layer);
map.zoomTo(0);
@@ -38,7 +38,7 @@
t.plan(2);
control = new OpenLayers.Control.Scale();
t.ok( control instanceof OpenLayers.Control.Scale, "new OpenLayers.Control returns object" );
map = new OpenLayers.Map('map');
map = new OpenLayers.Map('map', {zoomMethod: null});
layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});
map.addLayer(layer);
map.zoomTo(0);

View File

@@ -128,27 +128,28 @@
function test_zoomOut(t) {
t.plan(1);
var map = new OpenLayers.Map(document.body);
var map = new OpenLayers.Map('map', {zoomMethod: null});
var layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
"http://labs.metacarta.com/wms/vmap0",
{layers: 'basic'} );
map.addLayer(layer);
map.setCenter(new OpenLayers.LonLat(0, 0), 5);
var origSetTimeout = window.setTimeout;
window.setTimeout = function(fn) { fn(); return 'id'; };
var control = new OpenLayers.Control.TouchNavigation();
map.addControl(control);
var handler = control.handlers.click;
handler.touchstart({xy: new OpenLayers.Pixel(1 ,1), touches: ["foo", "bar"]});
handler.touchend({});
t.delay_call(1, function() {
t.eq(map.getZoom(), 4, "Did we zoom out?");
// tear down
map.destroy();
});
window.setTimeout = origSetTimeout;
}
</script>
</head>
<body>
<div id="map" style="width:512px;height:256px"></div>
</body>
</html>

View File

@@ -43,7 +43,8 @@
var map = new OpenLayers.Map({
div: "map",
layers: [new OpenLayers.Layer(null, {isBaseLayer: true})]
layers: [new OpenLayers.Layer(null, {isBaseLayer: true})],
zoomMethod: null
});
var control = new OpenLayers.Control.Zoom();
map.addControl(control);
@@ -60,7 +61,8 @@
var map = new OpenLayers.Map({
div: "map",
layers: [new OpenLayers.Layer(null, {isBaseLayer: true})]
layers: [new OpenLayers.Layer(null, {isBaseLayer: true})],
zoomMethod: null
});
var control = new OpenLayers.Control.Zoom();
map.addControl(control);

View File

@@ -23,6 +23,7 @@
function test_zoomBox(t) {
t.plan(4);
var map = new OpenLayers.Map("map", {
zoomMethod: null,
layers: [new OpenLayers.Layer("", {isBaseLayer: true})],
center: [0, 0],
zoom: 1
@@ -37,7 +38,8 @@
t.eq(map.getZoom(), 2, "not zoomed with zoomOnClick set to false");
map.zoomToMaxExtent();
control.zoomBox(new OpenLayers.Bounds(128, 64, 256, 128));
// pixel bounds bottom > top
control.zoomBox(new OpenLayers.Bounds(128, 128, 256, 64));
t.eq(map.getCenter().toShortString(), "-45, 22.5", "centered to box center");
t.eq(map.getZoom(), 3, "zoomed to box extent");

View File

@@ -3,6 +3,27 @@
<script src="../OLLoader.js"></script>
<script type="text/javascript">
var flatPoints;
var floats, smallFloats, encodedFloats;
var signedIntegers, encodedSignedIntegers;
var unsignedIntegers, encodedUnsignedIntegers;
function resetTestingData() {
flatPoints = [38.50000, -120.20000,
40.70000, -120.95000,
43.25200, -126.45300];
floats = [0.00, 0.15, -0.01, -0.16, 0.16, 0.01];
smallFloats = [0.00000, 0.00015, -0.00001, -0.00016, 0.00016, 0.00001];
encodedFloats = '?]@^_@A';
signedIntegers = [0, 15, -1, -16, 16, 1];
encodedSignedIntegers = '?]@^_@A';
unsignedIntegers = [0, 30, 1, 31, 32, 2, 174];
encodedUnsignedIntegers = '?]@^_@AmD';
}
var basePoints = new Array(
new Array(3850000, -12020000),
new Array(4070000, -12095000),
@@ -10,12 +31,9 @@
);
var points = [
new OpenLayers.Geometry.Point(basePoints[0][1] * 1e-5,
basePoints[0][0] * 1e-5),
new OpenLayers.Geometry.Point(basePoints[1][1] * 1e-5,
basePoints[1][0] * 1e-5),
new OpenLayers.Geometry.Point(basePoints[2][1] * 1e-5,
basePoints[2][0] * 1e-5)
new OpenLayers.Geometry.Point(-120.200, 38.500),
new OpenLayers.Geometry.Point(-120.950, 40.700),
new OpenLayers.Geometry.Point(-126.453, 43.252)
];
var singlePoint = new OpenLayers.Feature.Vector(points[0]);
@@ -126,6 +144,227 @@
t.eq(format.encode(basePoints, 2), encoded);
}
function test_encodeDeltas_returns_expected_value(t) {
t.plan(1);
resetTestingData();
var format = new OpenLayers.Format.EncodedPolyline();
t.eq(format.encodeDeltas(flatPoints, 2), encoded);
}
function test_decodeDeltas_returns_expected_value(t) {
t.plan(1);
resetTestingData();
var format = new OpenLayers.Format.EncodedPolyline();
t.eq(format.decodeDeltas(encoded, 2), flatPoints);
}
function test_encodeFloats_returns_expected_value(t) {
t.plan(3);
resetTestingData();
var format = new OpenLayers.Format.EncodedPolyline();
t.eq(format.encodeFloats(smallFloats), encodedFloats);
resetTestingData();
t.eq(format.encodeFloats(smallFloats, 1e5), encodedFloats);
t.eq(format.encodeFloats(floats, 1e2), encodedFloats);
}
function test_decodeFloats_returns_expected_value(t) {
t.plan(3);
resetTestingData();
var format = new OpenLayers.Format.EncodedPolyline();
t.eq(format.decodeFloats(encodedFloats), smallFloats);
t.eq(format.decodeFloats(encodedFloats, 1e5), smallFloats);
t.eq(format.decodeFloats(encodedFloats, 1e2), floats);
}
function test_encodeSignedIntegers_returns_expected_value(t) {
t.plan(1);
resetTestingData();
var format = new OpenLayers.Format.EncodedPolyline();
t.eq(format.encodeSignedIntegers(
signedIntegers), encodedSignedIntegers);
}
function test_decodeSignedIntegers_returns_expected_value(t) {
t.plan(1);
resetTestingData();
var format = new OpenLayers.Format.EncodedPolyline();
t.eq(format.decodeSignedIntegers(
encodedSignedIntegers), signedIntegers);
}
function test_encodeUnsignedIntegers_returns_expected_value(t) {
t.plan(1);
resetTestingData();
var format = new OpenLayers.Format.EncodedPolyline();
t.eq(format.encodeUnsignedIntegers(
unsignedIntegers), encodedUnsignedIntegers);
}
function test_decodeUnsignedIntegers_returns_expected_value(t) {
t.plan(1);
resetTestingData();
var format = new OpenLayers.Format.EncodedPolyline();
t.eq(format.decodeUnsignedIntegers(
encodedUnsignedIntegers), unsignedIntegers);
}
function test_encodeFloat_returns_expected_value(t) {
t.plan(12);
resetTestingData();
var format = new OpenLayers.Format.EncodedPolyline();
t.eq(format.encodeFloat(0.00000), '?');
t.eq(format.encodeFloat(-0.00001), '@');
t.eq(format.encodeFloat(0.00001), 'A');
t.eq(format.encodeFloat(-0.00002), 'B');
t.eq(format.encodeFloat(0.00002), 'C');
t.eq(format.encodeFloat(0.00015), ']');
t.eq(format.encodeFloat(-0.00016), '^');
t.eq(format.encodeFloat(-0.1, 10), '@');
t.eq(format.encodeFloat(0.1, 10), 'A');
t.eq(format.encodeFloat(16 * 32 / 1e5), '__@');
t.eq(format.encodeFloat(16 * 32 * 32 / 1e5), '___@');
// from the "Encoded Polyline Algorithm Format" page at Google
t.eq(format.encodeFloat(-179.9832104), '`~oia@');
}
function test_decodeFloat_returns_expected_value(t) {
t.plan(12);
resetTestingData();
var format = new OpenLayers.Format.EncodedPolyline();
t.eq(format.decodeFloat('?'), 0.00000);
t.eq(format.decodeFloat('@'), -0.00001);
t.eq(format.decodeFloat('A'), 0.00001);
t.eq(format.decodeFloat('B'), -0.00002);
t.eq(format.decodeFloat('C'), 0.00002);
t.eq(format.decodeFloat(']'), 0.00015);
t.eq(format.decodeFloat('^'), -0.00016);
t.eq(format.decodeFloat('@', 10), -0.1);
t.eq(format.decodeFloat('A', 10), 0.1);
t.eq(format.decodeFloat('__@'), 16 * 32 / 1e5);
t.eq(format.decodeFloat('___@'), 16 * 32 * 32 / 1e5);
// from the "Encoded Polyline Algorithm Format" page at Google
t.eq(format.decodeFloat('`~oia@'), -179.98321);
}
function test_encodeSignedInteger_returns_expected_value(t) {
t.plan(10);
resetTestingData();
var format = new OpenLayers.Format.EncodedPolyline();
t.eq(format.encodeSignedInteger(0), '?');
t.eq(format.encodeSignedInteger(-1), '@');
t.eq(format.encodeSignedInteger(1), 'A');
t.eq(format.encodeSignedInteger(-2), 'B');
t.eq(format.encodeSignedInteger(2), 'C');
t.eq(format.encodeSignedInteger(15), ']');
t.eq(format.encodeSignedInteger(-16), '^');
t.eq(format.encodeSignedInteger(16), '_@');
t.eq(format.encodeSignedInteger(16 * 32), '__@');
t.eq(format.encodeSignedInteger(16 * 32 * 32), '___@');
}
function test_decodeSignedInteger_returns_expected_value(t) {
t.plan(10);
resetTestingData();
var format = new OpenLayers.Format.EncodedPolyline();
t.eq(format.decodeSignedInteger('?'), 0);
t.eq(format.decodeSignedInteger('@'), -1);
t.eq(format.decodeSignedInteger('A'), 1);
t.eq(format.decodeSignedInteger('B'), -2);
t.eq(format.decodeSignedInteger('C'), 2);
t.eq(format.decodeSignedInteger(']'), 15);
t.eq(format.decodeSignedInteger('^'), -16);
t.eq(format.decodeSignedInteger('__@'), 16 * 32);
t.eq(format.decodeSignedInteger('___@'), 16 * 32 * 32);
t.eq(format.decodeSignedInteger('_@'), 16);
}
function test_encodeUnsignedInteger_returns_expected_value(t) {
t.plan(10);
var format = new OpenLayers.Format.EncodedPolyline();
t.eq(format.encodeUnsignedInteger(0), '?');
t.eq(format.encodeUnsignedInteger(1), '@');
t.eq(format.encodeUnsignedInteger(2), 'A');
t.eq(format.encodeUnsignedInteger(30), ']');
t.eq(format.encodeUnsignedInteger(31), '^');
t.eq(format.encodeUnsignedInteger(32), '_@');
t.eq(format.encodeUnsignedInteger(32 * 32), '__@');
t.eq(format.encodeUnsignedInteger(5 * 32 * 32), '__D');
t.eq(format.encodeUnsignedInteger(32 * 32 * 32), '___@');
// from the "Encoded Polyline Algorithm Format" page at Google
t.eq(format.encodeUnsignedInteger(174), 'mD');
}
function test_decodeUnsignedInteger_returns_expected_value(t) {
t.plan(10);
var format = new OpenLayers.Format.EncodedPolyline();
t.eq(format.decodeUnsignedInteger('?'), 0);
t.eq(format.decodeUnsignedInteger('@'), 1);
t.eq(format.decodeUnsignedInteger('A'), 2);
t.eq(format.decodeUnsignedInteger(']'), 30);
t.eq(format.decodeUnsignedInteger('^'), 31);
t.eq(format.decodeUnsignedInteger('_@'), 32);
t.eq(format.decodeUnsignedInteger('__@'), 32 * 32);
t.eq(format.decodeUnsignedInteger('__D'), 5 * 32 * 32);
t.eq(format.decodeUnsignedInteger('___@'), 32 * 32 * 32);
// from the "Encoded Polyline Algorithm Format" page at Google
t.eq(format.decodeUnsignedInteger('mD'), 174);
}
</script>
</head>
<body>

View File

@@ -49,8 +49,8 @@
function test_read_exception(t) {
t.plan(1);
var text = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' +
'<!DOCTYPE ServiceExceptionReport SYSTEM "http://mapstory.dev.opengeo.org:80/geoserver/schemas/wms/1.1.1/WMS_exception_1_1_1.dtd">' +
'<ServiceExceptionReport version="1.1.1" > <ServiceException code="LayerNotDefined" locator="MapLayerInfoKvpParser">' +
'<!DOCTYPE ServiceExceptionReport SYSTEM "http://schemas.opengis.net/wms/1.1.1/WMS_exception_1_1_1.dtd">' +
'<ServiceExceptionReport version="1.1.1" > <ServiceException code="LayerNotDefined">' +
'geonode:_map_107_annotations: no such layer on this server' +
'</ServiceException></ServiceExceptionReport>';
var format = new OpenLayers.Format.WMSDescribeLayer();

View File

@@ -257,24 +257,23 @@
var cases = [{
got: dist({x: 0, y: 0}, {x1: 0, y1: 1, x2: 1, y2: 1}),
expected: {distance: 1, x: 0, y: 1}
expected: {distance: 1, x: 0, y: 1, along: 0}
}, {
got: dist({x: 0, y: 0}, {x1: -1, y1: -1, x2: 0, y2: -1}),
expected: {distance: 1, x: 0, y: -1}
expected: {distance: 1, x: 0, y: -1, along: 1}
}, {
got: dist({x: 0, y: 0}, {x1: -1, y1: -1, x2: 1, y2: 1}),
expected: {distance: 0, x: 0, y: 0}
expected: {distance: 0, x: 0, y: 0, along: 0.5}
}, {
got: dist({x: 1, y: 1}, {x1: 2, y1: 0, x2: 2, y2: 3}),
expected: {distance: 1, x: 2, y: 1}
expected: {distance: 1, x: 2, y: 1, along: 1/3.}
}, {
got: dist({x: -1, y: -1}, {x1: -2, y1: -2, x2: -1, y2: -3}),
expected: {distance: Math.sqrt(2), x: -2, y: -2}
expected: {distance: Math.sqrt(2), x: -2, y: -2, along: 0}
}, {
got: dist({x: -1, y: 1}, {x1: -3, y1: 1, x2: -1, y2: 3}),
expected: {distance: Math.sqrt(2), x: -2, y: 2}
expected: {distance: Math.sqrt(2), x: -2, y: 2, along: 0.5}
}];
t.plan(cases.length);
for(var i=0; i<cases.length; ++i) {
t.eq(cases[i].got, cases[i].expected, "case " + i);

View File

@@ -669,6 +669,64 @@
map.destroy();
}
function test_touchstart(t) {
// a test to verify that the touchstart function does
// unregister the mouse listeners when it's called the
// first time
t.plan(7);
// set up
var map = new OpenLayers.Map("map", {
controls: []
});
var control = new OpenLayers.Control({});
var handler = new OpenLayers.Handler.Click(control, {});
control.handler = handler;
map.addControl(control);
handler.activate();
function allRegistered() {
var eventTypes = ['mousedown', 'mouseup', 'click', 'dblclick'],
eventType,
listeners,
listener,
flag;
for(var i=0, ilen=eventTypes.length; i<ilen; i++) {
flag = false;
eventType = eventTypes[i];
listeners = map.events.listeners[eventType];
for(var j=0, jlen=listeners.length; j<jlen; j++) {
listener = listeners[j];
if(listener.func === handler[eventType] && listener.obj === handler) {
flag = true;
break;
}
}
if(!flag) {
return false;
}
}
return true;
}
// test
t.ok(allRegistered(), 'mouse listeners are registered');
handler.touchstart({xy: new OpenLayers.Pixel(0, 0)});
t.eq(map.events.listeners.mousedown.length, 0,"mousedown is not registered");
t.eq(map.events.listeners.mouseup.length, 0,"mouseup is not registered");
t.eq(map.events.listeners.click.length, 0,"click is not registered");
t.eq(map.events.listeners.dblclick.length, 0,"dblclick is not registered");
t.ok(handler.touch, 'handler.touch is set');
handler.deactivate();
t.ok(!handler.touch, 'handler.touch is not set');
map.destroy();
}
</script>
</head>
<body>

View File

@@ -288,7 +288,7 @@
// "touchend" events set expected states in the drag handler.
// We also verify that we prevent the default as appropriate.
t.plan(14);
t.plan(19);
// set up
@@ -318,6 +318,11 @@
t.eq(h.start.y, 0, '[touchstart] start.y is correct');
t.eq(log.length, 1, '[touchstart] one item in log');
t.ok(log[0] === e, "touchstart", '[touchstart] event is stopped');
t.eq(m.events.listeners.mousedown.length, 0,"mousedown is not registered");
t.eq(m.events.listeners.mouseup.length, 0,"mouseup is not registered");
t.eq(m.events.listeners.mousemove.length, 0,"mousemove is not registered");
t.eq(m.events.listeners.click.length, 0,"click is not registered");
t.eq(m.events.listeners.mouseout.length, 0,"mouseout is not registered");
e = {xy: new Px(1, 1)};
m.events.triggerEvent('touchmove', e);

View File

@@ -280,9 +280,10 @@
handler.mousedown = function() {}; // mock mousedown
handler.activate();
var eventTypes = ['mousedown', 'mouseup', 'mousemove', 'click', 'dblclick'];
function allRegistered() {
var eventTypes = ['mousedown', 'mouseup', 'mousemove', 'click', 'dblclick'],
eventType,
var eventType,
listeners,
listener,
flag;
@@ -305,21 +306,18 @@
}
function noneRegistered() {
var eventTypes = ['mousedown', 'mouseup', 'mousemove', 'click', 'dblclick'],
eventType,
listeners,
listener;
var eventType,
times,
flag = false;
for(var i=0, ilen=eventTypes.length; i<ilen; i++) {
eventType = eventTypes[i];
listeners = map.events.listeners[eventType];
for(var j=0, jlen=listeners.length; j<jlen; j++) {
listener = listeners[j];
if(listener.func === handler[eventType] && listener.obj === handler) {
return false;
times = map.events.listeners[eventType].length;
if (times != 0) {
t.fail(eventType + " is registered " + times + " times");
flag = true;
}
}
}
return true;
return !flag;
}
// test
@@ -564,10 +562,10 @@
handler = new OpenLayers.Handler.Feature(
control, layer, callbacks, {clickTolerance: 4});
handler.activate();
handler.down = {x: 0, y: 0};
// distance between down and up is 1, which is
// lower than clickTolerance so "click" should trigger
handler.down = {x: 0, y: 0};
handler.up = {x: 1, y: 0};
clicks = 0;
map.events.triggerEvent("click", evtPx);
@@ -575,6 +573,7 @@
// distance between down and up is 4, which is
// equal to clickTolerance so "click" should trigger
handler.down = {x: 0, y: 0}; // cached handler.down cleared (#857)
handler.up = {x: 0, y: 4};
clicks = 0;
map.events.triggerEvent("click", evtPx);
@@ -582,6 +581,7 @@
// distance between down and up is 5, which is
// greater than clickTolerance so "click" should not trigger
handler.down = {x: 0, y: 0}; // cached handler.down cleared (#857)
handler.up = {x: 5, y: 0};
clicks = 0;
map.events.triggerEvent("click", evtPx);
@@ -660,6 +660,36 @@
}
function test_clear_event_position_cache(t) {
t.plan(2);
var map, control, layer, feature, evtPx;
map = new OpenLayers.Map('map', {controls: []});
control = new OpenLayers.Control();
map.addControl(control);
layer = new OpenLayers.Layer();
layer.getFeatureFromEvent = function(evt) { return feature; };
map.addLayer(layer);
feature = new OpenLayers.Feature.Vector();
feature.layer = layer;
evtPx = {
xy: new OpenLayers.Pixel(Math.random(), Math.random()),
type: "click"
};
handler = new OpenLayers.Handler.Feature(
control, layer, {}, {});
handler.activate();
handler.down = {x: 0, y: 0};
handler.up = {x: 1, y: 0};
map.events.triggerEvent("click", evtPx);
t.eq(handler.down, null, "cached mousedown position is cleared after handling click");
t.eq(handler.up, null, "cached mouseup position is cleared after handling click")
}
</script>
</head>
<body>

View File

@@ -115,12 +115,13 @@
}
function test_Handler_MouseWheel_cumulative(t) {
t.plan(1);
t.plan(2);
var deltaUp = 0;
var deltaUp = 0, ticks = 0;
var callbacks = {
up: function(evt, delta) {
deltaUp += delta;
ticks++;
}
};
@@ -131,7 +132,8 @@
map.addControl(control);
var handler = new OpenLayers.Handler.MouseWheel(control, callbacks, {
interval: 150,
cumulative: false
cumulative: false,
maxDelta: 6
});
var delta = 120;
@@ -140,8 +142,9 @@
handler.onWheelEvent({'target':map.layers[0].div, wheelDelta: delta});
}
t.delay_call(1, function() {
t.eq(deltaUp, 1, "Non cumulative mode works");
t.delay_call(2, function() {
t.eq(deltaUp / ticks, 1, "Cumulative mode works");
t.eq(ticks, 4, "up called 4x with maxDelta of 6");
});
}

View File

@@ -601,6 +601,12 @@
handler.mousedown({type: "mousedown", xy: px});
handler.mouseup({type: "mouseup", xy: px});
}
function userTap(handler, x, y) {
var px = new OpenLayers.Pixel(x, y);
handler.touchstart({xy: px});
handler.touchmove({xy: px});
handler.touchend({});
}
/**
* Editing method tests: insertXY, insertDeltaXY, insertDirectionXY,
@@ -720,7 +726,7 @@
}
function test_undoredo1(t) {
t.plan(4);
t.plan(5);
var obj = editingMethodsSetup();
var map = obj.map;
var handler = obj.handler;
@@ -747,6 +753,17 @@
handler.redo();
t.geom_eq(original, handler.line.geometry, "one redo undoes one undo");
// add point via touch
userTap(handler, 10, 50);
handler.undo();
currentLen = handler.line.geometry.components.length;
t.geom_eq(
handler.line.geometry.components[currentLen-1],
handler.line.geometry.components[currentLen-2],
"current point (mouse position) is set to the last digitized " +
"point after undo on touch devices"
);
// cleanup
map.destroy();
}

View File

@@ -97,7 +97,7 @@
function test_callbacks(t) {
t.plan(32);
var map = new OpenLayers.Map('map', {controls: []});
var map = new OpenLayers.Map('map', {controls: [], fallThrough: true});
var control = new OpenLayers.Control();
map.addControl(control);

View File

@@ -407,7 +407,8 @@
// set up
var map = new OpenLayers.Map("map", {
resolutions: [1]
resolutions: [1],
controls: []
});
var layer = new OpenLayers.Layer.Vector("foo", {
maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),
@@ -421,9 +422,11 @@
map.setCenter(new OpenLayers.LonLat(0, 0), 0);
handler.activate();
var eventTypes = ['mousedown', 'mouseup', 'mousemove', 'click', 'dblclick',
'mouseout'];
function allRegistered() {
var eventTypes = ['mousedown', 'mouseup', 'mousemove', 'click', 'dblclick'],
eventType,
var eventType,
listeners,
listener,
flag;
@@ -446,22 +449,20 @@
}
function noneRegistered() {
var eventTypes = ['mousedown', 'mouseup', 'mousemove', 'click', 'dblclick'],
eventType,
listeners,
listener;
var eventType,
times,
flag = false;
for(var i=0, ilen=eventTypes.length; i<ilen; i++) {
eventType = eventTypes[i];
listeners = map.events.listeners[eventType];
for(var j=0, jlen=listeners.length; j<jlen; j++) {
listener = listeners[j];
if(listener.func === handler[eventType] && listener.obj === handler) {
return false;
times = map.events.listeners[eventType].length;
if (times != 0) {
t.fail(eventType + " is registered " + times + " times");
flag = true;
}
}
return !flag;
}
return true;
}
// test

View File

@@ -187,7 +187,9 @@
}
/**
* Check our utility function for generating tile indexes against a file cache
* Check the utility function for generating tile indexes against a file cache
* This is already tested in BaseTypes test, but these are specific,
* common conversions that this class will rely on, so the tests are retained
*/
function test_Layer_ARCGISCACHE_zeroPad(t) {
t.plan(4);
@@ -195,10 +197,10 @@
var layer = new OpenLayers.Layer.ArcGISCache('test', null, { });
//some tile examples
t.ok('00000001' == layer.zeroPad(1, 8, 16), 'zeroPad should generate tile indexes properly ');
t.ok('00000020' == layer.zeroPad(32, 8, 16), 'zeroPad should generate tile indexes properly ');
t.ok('00000100' == layer.zeroPad(256, 8, 16), 'zeroPad should generate tile indexes properly ');
t.ok('00001000' == layer.zeroPad(4096, 8, 16), 'zeroPad should generate tile indexes properly ');
t.ok('00000001' == OpenLayers.Number.zeroPad(1, 8, 16), 'zeroPad should generate tile indexes properly ');
t.ok('00000020' == OpenLayers.Number.zeroPad(32, 8, 16), 'zeroPad should generate tile indexes properly ');
t.ok('00000100' == OpenLayers.Number.zeroPad(256, 8, 16), 'zeroPad should generate tile indexes properly ');
t.ok('00001000' == OpenLayers.Number.zeroPad(4096, 8, 16), 'zeroPad should generate tile indexes properly ');
}
/**

View File

@@ -237,7 +237,7 @@
}
function test_setOpacity(t) {
if(validkey) {
t.plan(6);
var map = new OpenLayers.Map("map");
@@ -283,7 +283,11 @@
t.ok(opacityCheck(0.5), "container opacity set to layer opacity");
map.destroy();
} else {
t.plan(0);
t.debug_print("Google tests can't be run from " +
window.location.host);
}
}
function test_Layer_Google_setGMapVisibility(t) {
@@ -322,6 +326,7 @@
function test_sphericalMercator(t) {
if (validkey) {
t.plan(4);
var map, layer;
@@ -348,7 +353,11 @@
map.addLayer(layer);
t.eq(map.getProjection(), "EPSG:102113", "custom code respected with sphericalMercator");
map.destroy();
} else {
t.plan(0);
t.debug_print("Google tests can't be run from " +
window.location.host);
}
}

View File

@@ -22,7 +22,7 @@
function test_constructor (t) {
t.plan( 8 );
t.plan( 7 );
layer = new OpenLayers.Layer.Grid(name, url, params, null);
t.ok( layer instanceof OpenLayers.Layer.Grid, "returns OpenLayers.Layer.Grid object" );
@@ -31,7 +31,6 @@
t.eq( layer.numLoadingTiles, 0, "numLoadingTiles starts at 0");
t.ok( layer.tileClass === OpenLayers.Tile.Image, "tileClass default is OpenLayers.Tile.Image");
t.eq( layer.className, 'olLayerGrid', "className default is olLayerGrid");
t.eq( layer.removeBackBufferDelay, 2500, "removeBackBufferDelay default is 2500");
var obj = {};
var func = function() {};
@@ -390,7 +389,7 @@
*/
function test_Layer_Grid_clone(t) {
t.plan(6);
t.plan(7);
var options = {tileSize: new OpenLayers.Size(500,50)};
var map = new OpenLayers.Map('map', options);
@@ -400,8 +399,10 @@
layer.grid = [ [6, 7],
[8, 9]];
// if we clone when tiles are still loading, this should not influence the clone
layer.numLoadingTiles = 1;
var clone = layer.clone();
t.eq( clone.numLoadingTiles, 0, "numLoadingTiles should be reset");
t.ok( clone.grid != layer.grid, "clone does not copy grid");
t.ok( clone.grid.length == 0, "clone creates a new array instead");
@@ -625,7 +626,7 @@
}
function test_Layer_Grid_getTileBounds(t) {
t.plan(2);
var map = new OpenLayers.Map("map2");
var map = new OpenLayers.Map("map2", {zoomMethod: null});
var url = "http://octo.metacarta.com/cgi-bin/mapserv";
layer = new OpenLayers.Layer.WMS(name, url, params);
@@ -822,7 +823,8 @@
t.plan(11);
var map = new OpenLayers.Map('map', {
resolutions: [32, 16, 8, 4, 2, 1]
resolutions: [32, 16, 8, 4, 2, 1],
zoomMethod: null
});
var layer = new OpenLayers.Layer.WMS('', '', {}, {
isBaseLayer: true,
@@ -883,7 +885,8 @@
t.plan(4);
var map = new OpenLayers.Map('map', {
resolutions: [1, 0.5, 0.025]
resolutions: [1, 0.5, 0.025],
zoomMethod: null
});
var resolution;
var layer = new OpenLayers.Layer.WMS('', '', {}, {
@@ -927,7 +930,8 @@
t.plan(4);
var map = new OpenLayers.Map('map', {
resolutions: [1, 0.5, 0.025]
resolutions: [1, 0.5, 0.025],
zoomMethod: null
});
var resolution;
var layer = new OpenLayers.Layer.WMS('', '', {}, {
@@ -996,7 +1000,7 @@
layer.applyBackBuffer(2);
t.ok(layer.backBuffer === backBuffer,
'back buffer set in layer');
t.ok(layer.div.firstChild === backBuffer,
t.ok(map.layerContainerDiv.firstChild === backBuffer,
'back buffer inserted as first child');
t.eq(layer.backBuffer.style.left, '250px',
'back buffer has correct left');
@@ -1016,7 +1020,7 @@
layer.applyBackBuffer(2);
t.ok(layer.backBuffer === backBuffer,
'back buffer set in layer');
t.ok(layer.div.firstChild === backBuffer,
t.ok(map.layerContainerDiv.firstChild === backBuffer,
'back buffer inserted as first child');
t.eq(layer.backBuffer.style.left, '230px',
'back buffer has correct left');
@@ -1031,12 +1035,12 @@
return;
};
backBuffer = document.createElement('div');
layer.div.insertBefore(backBuffer, layer.div.firstChild);
map.layerContainerDiv.insertBefore(backBuffer, map.baseLayer.div);
layer.backBuffer = backBuffer;
layer.backBufferTimerId = 'fake';
layer.applyBackBuffer(2);
t.ok(backBuffer.parentNode !== layer.div,
'back buffer is not child node of layer div');
t.ok(backBuffer !== map.layerContainerDiv.firstChild,
'back buffer is not first child of layer container div');
t.eq(layer.backBuffer, null,
'back buffer not set in layer');
t.eq(layer.backBufferTimerId, null,
@@ -1045,7 +1049,7 @@
}
function test_createBackBuffer(t) {
t.plan(7);
t.plan(9);
var map = new OpenLayers.Map('map');
var layer = new OpenLayers.Layer.WMS('', '', {}, {
@@ -1070,7 +1074,16 @@
OpenLayers.Tile.Image.prototype.createBackBuffer = function() {
return document.createElement('div');
};
layer.transitionEffect = 'map-resize';
backBuffer = layer.createBackBuffer();
t.ok(backBuffer.style.zIndex == 99, 'z-index of backbuffer correct for "map-resize".');
layer.removeBackBuffer();
layer.transitionEffect = 'resize';
backBuffer = layer.createBackBuffer();
t.ok(backBuffer.style.zIndex == layer.getZIndex() - 1, 'z-index of backbuffer correct for "resize",');
layer.backBufferResolution = 1;
layer.gridResolution = 1;
layer.backBuffer = backBuffer;
@@ -1093,7 +1106,7 @@
}
function test_removeBackBuffer(t) {
t.plan(4);
t.plan(3);
var map = new OpenLayers.Map('map');
var layer = new OpenLayers.Layer.WMS('', '', {}, {isBaseLayer: true});
@@ -1105,17 +1118,12 @@
layer.div.appendChild(backBuffer);
layer.backBufferResolution = 32;
// add a fake back buffer removal timer
layer.backBufferTimerId = 'fake';
layer.removeBackBuffer();
t.eq(layer.backBuffer, null, 'backBuffer set to null in layer');
t.eq(layer.backBufferResolution, null,
'backBufferResolution set to null in layer');
t.ok(backBuffer.parentNode !== layer.div,
'back buffer removed from layer');
t.eq(layer.backBufferTimerId, null,
'backBufferTimerId set to null in layer');
map.destroy();
}
@@ -1150,6 +1158,23 @@
});
}
function test_backbuffer_replace_singleTile(t) {
t.plan(1);
var map = new OpenLayers.Map('map');
var layer = new OpenLayers.Layer.WMS('', '../../img/blank.gif', null, {
singleTile: true,
transitionEffect: 'resize'
});
map.addLayer(layer);
map.zoomToMaxExtent();
t.delay_call(1, function() {
map.zoomIn();
var tile = layer.grid[0][0];
t.ok(!OpenLayers.Element.hasClass(tile.imgDiv, 'olTileReplacing'), 'tile is not marked for being replaced for singleTile layers');
});
}
function test_singleTile_move_and_zoom(t) {
//
@@ -1162,9 +1187,10 @@
t.plan(4);
var map = new OpenLayers.Map('map');
var map = new OpenLayers.Map('map', {zoomMethod: null});
var layer = new OpenLayers.Layer.WMS('', '', {}, {
isBaseLayer: true,
transitionEffect: null,
singleTile: true,
ratio: 1.1
});
@@ -1193,7 +1219,8 @@
//
var map = new OpenLayers.Map('map', {
resolutions: [32, 16, 8, 4, 2, 1]
resolutions: [32, 16, 8, 4, 2, 1],
zoomMethod: null
});
var layer = new OpenLayers.Layer.WMS(
"WMS",
@@ -1289,6 +1316,7 @@
OpenLayers.Tile.Image.prototype.createBackBuffer = origCreateBackBuffer
}
function test_delayed_back_buffer_removal(t) {
//
// Test that the delaying of the back buffer removal behaves
@@ -1300,7 +1328,8 @@
// set up
var map = new OpenLayers.Map('map', {
resolutions: [32, 16, 8, 4, 2, 1]
resolutions: [32, 16, 8, 4, 2, 1],
zoomMethod: null
});
var layer = new OpenLayers.Layer.WMS('', '', {}, {
isBaseLayer: true,
@@ -1311,11 +1340,14 @@
map.zoomTo(1);
// Mark one tile loaded, to see if back buffer removal gets scheduled.
t.ok(layer.backBuffer === map.layerContainerDiv.firstChild,
'[a] back buffer is first child of layer container div');
// Mark one tile loaded and add an element to the backbuffer, to see if
// backbuffer removal gets scheduled.
layer.backBuffer.appendChild(document.createElement('img'));
layer.grid[1][1].onImageLoad();
t.ok(layer.backBuffer.parentNode === layer.div,
'[a] back buffer is a child of layer div');
t.ok(layer.backBufferTimerId !== null,
'[a] back buffer scheduled for removal');
@@ -1325,8 +1357,8 @@
t.ok(layer.backBuffer !== backBuffer,
'[b] a new back buffer was created');
t.ok(layer.backBuffer.parentNode === layer.div,
'[b] back buffer is a child of layer div');
t.ok(layer.backBuffer === map.layerContainerDiv.firstChild,
'[b] back buffer is first child of layer container div');
t.ok(layer.backBufferTimerId === null,
'[b] back buffer no longer scheduled for removal');

View File

@@ -233,7 +233,7 @@
}
function test_Layer_KaMap_getTileBounds(t) {
t.plan(2);
var map = new OpenLayers.Map("map");
var map = new OpenLayers.Map("map", {zoomMethod: null});
var url = "http://octo.metacarta.com/cgi-bin/mapserv";
layer = new OpenLayers.Layer.KaMap(name, url, params);

View File

@@ -59,7 +59,7 @@
t.plan(6);
var map = new OpenLayers.Map("map");
var map = new OpenLayers.Map("map", {zoomMethod: null});
var layer = new OpenLayers.Layer.Markers("Base", {isBaseLayer: true});
map.addLayer(layer);
map.setCenter(new OpenLayers.LonLat(0, 0), 1);

View File

@@ -211,7 +211,8 @@
div: "map",
layers: [layer],
center: new OpenLayers.LonLat(0, 0),
zoom: 1
zoom: 1,
zoomMethod: null
});
t.eq(layer.features.length, 50, "50 features at zoom 1");

View File

@@ -59,6 +59,21 @@
}
function test_createBackBuffer(t) {
t.plan(1);
setUp();
var got;
try {
got = layer.createBackBuffer();
} catch (e) {
got = e;
} finally {
tearDown();
}
t.eq(got, undefined, "createBackBuffer returns undefined");
}
function test_clone(t) {
t.plan(3);
setUp();

View File

@@ -557,7 +557,7 @@
function test_tileBounds(t) {
t.plan(3);
var map = new OpenLayers.Map("map", {projection: "EPSG:3857"});
var map = new OpenLayers.Map("map", {projection: "EPSG:3857", zoomMethod: null});
var layer = new OpenLayers.Layer.WMS("wms", "../../img/blank.gif");
map.addLayer(layer);
map.setCenter([0, 0], 1);

View File

@@ -245,7 +245,8 @@
layers: [layer],
projection: "EPSG:4326",
maxResolution: 0.3515625,
maxExtent: new OpenLayers.Bounds(-180, -90, 180, 90)
maxExtent: new OpenLayers.Bounds(-180, -90, 180, 90),
zoomMethod: null
});
map.setCenter(new OpenLayers.LonLat(-97.0, 38.0), 1);
t.eq(layer.getURL(new OpenLayers.Bounds(-135.0, 0.0, -90.0, 45.0)),

View File

@@ -216,6 +216,7 @@
t.plan(14);
var log = [];
map = new OpenLayers.Map('map', {
zoomMethod: null,
eventListeners: {
"movestart": function() {log.push("movestart");},
"move": function() {log.push("move");},
@@ -268,7 +269,7 @@
function test_Map_zoomend_event (t) {
t.plan(2);
map = new OpenLayers.Map('map');
map = new OpenLayers.Map('map', {zoomMethod: null});
var baseLayer = new OpenLayers.Layer.WMS("Test Layer",
"http://octo.metacarta.com/cgi-bin/mapserv?",
{map: "/mapdata/vmap_wms.map", layers: "basic"});
@@ -928,8 +929,13 @@
map.setBaseLayer(tmsLayer);
map.zoomIn();
map.pan(0, -200, {animate:false});
var log = [];
map.applyTransform = function(x, y, scale) {
log.push([x || map.layerContainerOriginPx.x, y || map.layerContainerOriginPx.y, scale]);
OpenLayers.Map.prototype.applyTransform.apply(this, arguments);
};
map.setBaseLayer(wmsLayer);
t.eq(map.layerContainerDiv.style.top, "0px", "layerContainer is recentered after setBaseLayer");
t.eq(log[0][0], 0, "layerContainer is recentered after setBaseLayer");
map.destroy();
}
@@ -1287,7 +1293,8 @@
extent = new OpenLayers.Bounds(8, 44.5, 19, 50);
var options = {
restrictedExtent: extent
restrictedExtent: extent,
zoomMethod: null
};
map = new OpenLayers.Map('map', options);
@@ -1325,7 +1332,7 @@
function test_zoomTo(t) {
t.plan(8);
var map = new OpenLayers.Map("map");
var map = new OpenLayers.Map("map", {zoomMethod: null});
map.addLayer(new OpenLayers.Layer(null, {
isBaseLayer: true
}));
@@ -1362,6 +1369,38 @@
map.destroy();
}
function test_zoomTo_animated(t) {
t.plan(2);
var map = new OpenLayers.Map("map");
map.addLayer(new OpenLayers.Layer(null, {
isBaseLayer: true
}));
map.zoomToMaxExtent();
map.zoomTo(2);
map.zoomIn();
map.zoomOut();
map.zoomIn();
t.delay_call(2, function() {
t.eq(map.getZoom(), 3, '[fractionalZoom: false] zoomTo(2) - zoomIn() - zoomOut() - zoomIn()');
// now allow fractional zoom
map.fractionalZoom = true;
map.zoomTo(2.6);
map.zoomIn();
map.zoomOut();
map.zoomIn();
});
t.delay_call(4, function() {
t.eq(map.getZoom(), 3.6, '[fractionalZoom: true] zoomTo(2) - zoomIn() - zoomOut() - zoomIn()');
map.destroy();
});
}
function test_Map_getUnits(t) {
t.plan(2);
var map = new OpenLayers.Map("map");
@@ -1959,7 +1998,7 @@
}
function test_moveByPx(t) {
t.plan(16);
t.plan(14);
var moved;
var Layer = OpenLayers.Class(OpenLayers.Layer, {
@@ -1979,14 +2018,19 @@
{isBaseLayer: false, minResolution:2})
]
});
var log = [];
map.applyTransform = function(x, y, scale) {
log.push([x || map.layerContainerOriginPx.x, y || map.layerContainerOriginPx.y, scale]);
OpenLayers.Map.prototype.applyTransform.apply(this, arguments);
};
moved = {};
map.zoomToExtent(new OpenLayers.Bounds(-1, -1, 1, 1));
// check initial state
t.eq(map.layerContainerDiv.style.left, '0px',
t.eq(log[0][0], 0,
'[initial state] layer container left correct');
t.eq(map.layerContainerDiv.style.top, '0px',
t.eq(log[0][1], 0,
'[initial state] layer container top correct');
t.eq(moved['base'], undefined,
'[initial state] base layer not moved');
@@ -1996,9 +2040,9 @@
// move to a valid position
moved = {};
map.moveByPx(-455, 455);
t.eq(map.layerContainerDiv.style.left, '455px',
t.eq(log[1][0], 455,
'[valid position] layer container left correct');
t.eq(map.layerContainerDiv.style.top, '-455px',
t.eq(log[1][1], -455,
'[valid position] layer container top correct');
t.eq(moved['base'], true,
'[valid position] base layer moved');
@@ -2008,10 +2052,8 @@
// move outside the max extent
moved = {};
map.moveByPx(-4500, 4500);
t.eq(map.layerContainerDiv.style.left, '455px',
'[outside max extent] layer container left correct');
t.eq(map.layerContainerDiv.style.top, '-455px',
'[outside max extent] layer container top correct');
t.eq(log.length, 2,
'[outside max extent] layer container offset unchanged');
t.eq(moved['base'], undefined,
'[outside max extent] base layer not moved');
t.eq(moved['outofrange'], undefined,
@@ -2020,10 +2062,8 @@
// move outside the restricted extent
moved = {};
map.moveByPx(-500, 500);
t.eq(map.layerContainerDiv.style.left, '455px',
'[outside restricted extent] layer container left correct');
t.eq(map.layerContainerDiv.style.top, '-455px',
'[outside restricted extent] layer container top correct');
t.eq(log.length, 2,
'[outside restricted extent] layer container offset unchanged');
t.eq(moved['base'], undefined,
'[outside restricted extent] base layer not moved');
t.eq(moved['outofrange'], undefined,
@@ -2047,9 +2087,59 @@
map.zoomToExtent(new OpenLayers.Bounds(-11.25, 0, 11.25, 11.25));
var log = [];
map.applyTransform = function(x, y, scale) {
log.push([x || map.layerContainerOriginPx.x, y || map.layerContainerOriginPx.y, scale]);
OpenLayers.Map.prototype.applyTransform.apply(this, arguments);
};
map.moveByPx(-10, -10);
t.eq(map.layerContainerDiv.style.left, '10px', 'layer container left correct');
t.eq(map.layerContainerDiv.style.top, '0px', 'layer container top correct');
t.eq(log[0][0], 10, 'layer container left correct');
t.eq(log[0][1], 0, 'layer container top correct');
}
function test_applyTransform(t) {
t.plan(10);
var origStylePrefix = OpenLayers.Util.vendorPrefix.style;
OpenLayers.Util.vendorPrefix.style =
OpenLayers.Util.vendorPrefix.css =
function(key) { return 'transform'; };
var map = new OpenLayers.Map('map');
map.layerContainerDiv = {style: {}};
delete map.applyTransform.transform;
delete map.applyTransform.template;
var origGetStyle = OpenLayers.Element.getStyle;
OpenLayers.Element.getStyle = function() { return 'foo'; }
map.applyTransform(1, 2, 3);
OpenLayers.Element.getStyle = origGetStyle;
t.eq(map.layerContainerDiv.style.transform, 'translate3d(1px,2px,0) scale3d(3,3,1)', '3d transform and scale used when available');
delete map.applyTransform.transform;
delete map.applyTransform.template;
var origIndexOf = String.prototype.indexOf;
String.prototype.indexOf = function() { return -1; };
map.layerContainerOriginPx = {x: -3, y: 2};
map.applyTransform(1, 2, 3);
String.prototype.indexOf = origIndexOf;
t.eq(map.layerContainerDiv.style.transform, 'translate(4px,0px) scale(3,3)', '2d translate and scale correct');
t.eq(map.layerContainerDiv.style.left, '-3px', 'container origin x set as style.left');
t.eq(map.layerContainerDiv.style.top, '2px', 'container origin y set as style.top');
map.applyTransform(1, 2);
t.ok(!map.layerContainerDiv.style.transform, 'no transform set when no transform needed');
t.eq(map.layerContainerDiv.style.left, '1px', 'style.left correct when no transform needed');
t.eq(map.layerContainerDiv.style.top, '2px', 'style.top correct when no transform needed');
map.applyTransform.transform = null;
map.applyTransform(4, 5, 6);
t.eq(map.layerContainerDiv.style.left, '4px', 'style.left set when transform not available')
t.eq(map.layerContainerDiv.style.top, '5px', 'style.top set when transform not available')
t.ok(!map.layerContainerDiv.style.transform, 'no transform set, because not supported');
map.destroy();
delete map.applyTransform.transform;
delete map.applyTransform.template;
OpenLayers.Util.vendorPrefix.style = origStylePrefix;
}
function test_options(t) {
@@ -2113,6 +2203,24 @@
t.ok(center.equals(new OpenLayers.LonLat(-13.25, 56)), "Center is correct and not equal to maxExtent's center");
}
function test_getZoomTargetCenter(t) {
t.plan(1);
var map = new OpenLayers.Map({
div: 'map',
layers: [
new OpenLayers.Layer('', {isBaseLayer: true})
],
center: [0, 0],
zoom: 1
});
var ll = map.getZoomTargetCenter({x: 44, y: 22}, map.getMaxResolution());
t.eq(ll.toShortString(), "180, -90", "getZoomTargetCenter works.");
map.destroy();
}
function test_autoUpdateSize(t) {
t.plan(1);
OpenLayers.Event.unloadCache();

View File

@@ -168,8 +168,7 @@
var bColor = popup.div.style.backgroundColor;
var goodColor = ( (bColor == color) || (bColor == hexColor));
t.ok(goodColor, "good default popup.backgroundColor");
if (navigator.appName.indexOf("Microsoft") == -1) {
if (navigator.appName.indexOf("Microsoft") == -1 || new RegExp(/msie 10/).test(navigator.userAgent.toLowerCase())) {
t.eq(parseFloat(popup.div.style.opacity), opacity, "good default popup.opacity");
} else {
t.eq(popup.div.style.filter, "alpha(opacity=" + opacity*100 + ")", "good default popup.opacity");

View File

@@ -321,9 +321,9 @@
var cases = [{
msg: "center of point", x: -100, y: 0, id: layer.features[0].id
}, {
msg: "edge of point", x: -103, y: 3, id: layer.features[0].id
msg: "edge of point", x: -106, y: 0, id: layer.features[0].id
}, {
msg: "outside point", x: -110, y: 3, id: null
msg: "outside point", x: -110, y: 0, id: null
}, {
msg: "center of line", x: 0, y: 0, id: layer.features[1].id
}, {

View File

@@ -51,7 +51,7 @@
});
// create a map with the layers and a center
var map = new OpenLayers.Map("map");
var map = new OpenLayers.Map("map", {zoomMethod: null});
map.addLayers([dummy, layer]);
map.zoomToMaxExtent();
@@ -206,7 +206,7 @@
function test_resFactor(t) {
t.plan(2);
var map = new OpenLayers.Map("map");
var map = new OpenLayers.Map("map", {zoomMethod: null});
var bbox = new OpenLayers.Strategy.BBOX();
var fakeProtocol = new OpenLayers.Protocol({
'read': function() {

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