diff --git a/build.py b/build.py
index f3bdd9b16a..abcda2669d 100755
--- a/build.py
+++ b/build.py
@@ -673,8 +673,11 @@ def host_examples(t):
t.rm_rf('build/hosted/%(BRANCH)s/ol')
t.makedirs('build/hosted/%(BRANCH)s/ol')
t.cp_r('src/ol', 'build/hosted/%(BRANCH)s/ol/ol')
+ t.rm_rf('build/hosted/%(BRANCH)s/ol.ext')
+ t.cp_r('build/ol.ext', 'build/hosted/%(BRANCH)s/ol.ext')
t.run('%(PYTHON)s', closure_lib_path + '/closure/bin/build/depswriter.py',
'--root_with_prefix', 'src ../../../ol',
+ '--root_with_prefix', 'build/ol.ext ../../../ol.ext',
'--root', 'build/hosted/%(BRANCH)s/closure-library/closure/goog',
'--root_with_prefix', 'build/hosted/%(BRANCH)s/closure-library/'
'third_party ../../third_party',
diff --git a/config/jsdoc/api/template/static/scripts/main.js b/config/jsdoc/api/template/static/scripts/main.js
index 9a368453c6..d57e4b9395 100644
--- a/config/jsdoc/api/template/static/scripts/main.js
+++ b/config/jsdoc/api/template/static/scripts/main.js
@@ -54,11 +54,25 @@ $(function () {
_onResize();
// show/hide unstable items
+ var links = $('a[href^="ol."]');
var unstable = $('.unstable');
var stabilityToggle = $('#stability-toggle');
stabilityToggle.change(function() {
unstable.toggleClass('hidden', this.checked);
+ var search = this.checked ? '' : '?unstable=true';
+ links.each(function(i, el) {
+ this.href = this.pathname + search + this.hash;
+ });
+ if (history.replaceState) {
+ var url = window.location.pathname + search + window.location.hash;
+ history.replaceState({}, '', url);
+ }
return false;
});
+ var search = window.location.search;
+ links.each(function(i, el) {
+ this.href = this.pathname + search + this.hash;
+ });
+ stabilityToggle.prop('checked', search !== '?unstable=true');
unstable.toggleClass('hidden', stabilityToggle[0].checked);
});
diff --git a/css/ol.css b/css/ol.css
index 4b87bdbfe8..f860f08934 100644
--- a/css/ol.css
+++ b/css/ol.css
@@ -99,7 +99,6 @@
}
.ol-compass {
display: block;
- font-family: Arial;
font-weight: normal;
font-size: 1.2em;
}
@@ -222,12 +221,6 @@ button.ol-full-screen-true:after {
width: 1.8em;
}
-.ol-control button,
-.ol-attribution,
-.ol-scale-line-inner {
- font-family: 'Lucida Grande',Verdana,Geneva,Lucida,Arial,Helvetica,sans-serif;
-}
-
.ol-overviewmap {
position: absolute;
left: 0.5em;
diff --git a/examples/epsg-4326.js b/examples/epsg-4326.js
index a5b8bcf6ec..d5ee910855 100644
--- a/examples/epsg-4326.js
+++ b/examples/epsg-4326.js
@@ -9,7 +9,7 @@ goog.require('ol.source.TileWMS');
var layers = [
new ol.layer.Tile({
source: new ol.source.TileWMS({
- url: 'http://demo.opengeo.org/geoserver/wms',
+ url: 'http://demo.boundlessgeo.com/geoserver/wms',
params: {
'LAYERS': 'ne:NE1_HR_LC_SR_W_DR'
}
diff --git a/examples/getfeatureinfo-image.js b/examples/getfeatureinfo-image.js
index 8a284aaeda..1806cae784 100644
--- a/examples/getfeatureinfo-image.js
+++ b/examples/getfeatureinfo-image.js
@@ -5,7 +5,7 @@ goog.require('ol.source.ImageWMS');
var wmsSource = new ol.source.ImageWMS({
- url: 'http://demo.opengeo.org/geoserver/wms',
+ url: 'http://demo.boundlessgeo.com/geoserver/wms',
params: {'LAYERS': 'ne:ne'},
serverType: 'geoserver'
});
diff --git a/examples/getfeatureinfo-tile.js b/examples/getfeatureinfo-tile.js
index f928d83ac2..70704a7b8f 100644
--- a/examples/getfeatureinfo-tile.js
+++ b/examples/getfeatureinfo-tile.js
@@ -5,7 +5,7 @@ goog.require('ol.source.TileWMS');
var wmsSource = new ol.source.TileWMS({
- url: 'http://demo.opengeo.org/geoserver/wms',
+ url: 'http://demo.boundlessgeo.com/geoserver/wms',
params: {'LAYERS': 'ne:ne'},
serverType: 'geoserver'
});
diff --git a/examples/layer-extent.html b/examples/layer-extent.html
new file mode 100644
index 0000000000..95bc7d041c
--- /dev/null
+++ b/examples/layer-extent.html
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+ Limited Layer Extent
+
+
+
+
+
+
+
+
+
+
+
+
+
Limited layer extent
+
Restricting layer rendering to a limited extent.
+
+
+ This example uses the layer.setExtent() method to
+ modify the extent of the overlay layer. Use the controls below
+ to limit rendering based on an extent.
+
+
+
+ northwest
+ northeast
+ southeast
+ southwest
+ world
+
+
+
+ See the layer-extent.js
+ source for details on how this is done.
+
+
+
extent, tilejson
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/layer-extent.js b/examples/layer-extent.js
new file mode 100644
index 0000000000..fca59929fa
--- /dev/null
+++ b/examples/layer-extent.js
@@ -0,0 +1,50 @@
+goog.require('ol.Map');
+goog.require('ol.View');
+goog.require('ol.layer.Tile');
+goog.require('ol.proj');
+goog.require('ol.source.TileJSON');
+
+function transform(extent) {
+ return ol.proj.transformExtent(extent, 'EPSG:4326', 'EPSG:3857');
+}
+
+var extents = {
+ northwest: transform([-180, 0, 0, 85]),
+ northeast: transform([0, 0, 180, 85]),
+ southeast: transform([0, -85, 180, 0]),
+ southwest: transform([-180, -85, 0, 0]),
+ world: transform([-180, -85, 180, 85])
+};
+
+var base = new ol.layer.Tile({
+ source: new ol.source.TileJSON({
+ url: 'http://api.tiles.mapbox.com/v3/' +
+ 'mapbox.world-black.jsonp',
+ crossOrigin: 'anonymous'
+ })
+});
+
+var overlay = new ol.layer.Tile({
+ extent: extents.northwest,
+ source: new ol.source.TileJSON({
+ url: 'http://api.tiles.mapbox.com/v3/' +
+ 'mapbox.world-glass.jsonp',
+ crossOrigin: 'anonymous'
+ })
+});
+
+var map = new ol.Map({
+ layers: [base, overlay],
+ renderer: exampleNS.getRendererFromQueryString(),
+ target: 'map',
+ view: new ol.View({
+ center: [0, 0],
+ zoom: 1
+ })
+});
+
+for (var key in extents) {
+ document.getElementById(key).onclick = function(event) {
+ overlay.setExtent(extents[event.target.id]);
+ };
+}
diff --git a/examples/regularshape.html b/examples/regularshape.html
new file mode 100644
index 0000000000..2b1ecfcc34
--- /dev/null
+++ b/examples/regularshape.html
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+ Regular Shape example
+
+
+
+
+
+
+
+
+
+
+
+
+
Regular Shape example
+
Example of some Regular Shape styles.
+
+
vector, symbol, regularshape, style, square, cross, star, triangle, x
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/regularshape.js b/examples/regularshape.js
new file mode 100644
index 0000000000..141f07280b
--- /dev/null
+++ b/examples/regularshape.js
@@ -0,0 +1,100 @@
+goog.require('ol.Feature');
+goog.require('ol.Map');
+goog.require('ol.View');
+goog.require('ol.geom.Point');
+goog.require('ol.layer.Vector');
+goog.require('ol.source.Vector');
+goog.require('ol.style.Fill');
+goog.require('ol.style.RegularShape');
+goog.require('ol.style.Stroke');
+goog.require('ol.style.Style');
+
+
+var stroke = new ol.style.Stroke({color: 'black', width: 2});
+var fill = new ol.style.Fill({color: 'red'});
+
+var styles = {
+ 'square': [new ol.style.Style({
+ image: new ol.style.RegularShape(
+ /** @type {olx.style.RegularShapeOptions} */({
+ fill: fill,
+ stroke: stroke,
+ points: 4,
+ radius: 10,
+ angle: Math.PI / 4
+ }))
+ })],
+ 'triangle': [new ol.style.Style({
+ image: new ol.style.RegularShape(
+ /** @type {olx.style.RegularShapeOptions} */({
+ fill: fill,
+ stroke: stroke,
+ points: 3,
+ radius: 10,
+ angle: 0
+ }))
+ })],
+ 'star': [new ol.style.Style({
+ image: new ol.style.RegularShape(
+ /** @type {olx.style.RegularShapeOptions} */({
+ fill: fill,
+ stroke: stroke,
+ points: 5,
+ radius: 10,
+ radius2: 4,
+ angle: 0
+ }))
+ })],
+ 'cross': [new ol.style.Style({
+ image: new ol.style.RegularShape(
+ /** @type {olx.style.RegularShapeOptions} */({
+ fill: fill,
+ stroke: stroke,
+ points: 4,
+ radius: 10,
+ radius2: 0,
+ angle: 0
+ }))
+ })],
+ 'x': [new ol.style.Style({
+ image: new ol.style.RegularShape(
+ /** @type {olx.style.RegularShapeOptions} */({
+ fill: fill,
+ stroke: stroke,
+ points: 4,
+ radius: 10,
+ radius2: 0,
+ angle: Math.PI / 4
+ }))
+ })]
+};
+
+
+var styleKeys = ['x', 'cross', 'star', 'triangle', 'square'];
+var count = 250;
+var features = new Array(count);
+var e = 4500000;
+for (var i = 0; i < count; ++i) {
+ var coordinates = [2 * e * Math.random() - e, 2 * e * Math.random() - e];
+ features[i] = new ol.Feature(new ol.geom.Point(coordinates));
+ features[i].setStyle(styles[styleKeys[Math.floor(Math.random() * 5)]]);
+}
+
+var source = new ol.source.Vector({
+ features: features
+});
+
+var vectorLayer = new ol.layer.Vector({
+ source: source
+});
+
+var map = new ol.Map({
+ layers: [
+ vectorLayer
+ ],
+ target: 'map',
+ view: new ol.View({
+ center: [0, 0],
+ zoom: 2
+ })
+});
diff --git a/examples/tissot.js b/examples/tissot.js
index af92b5cb32..3aee7ce8dd 100644
--- a/examples/tissot.js
+++ b/examples/tissot.js
@@ -20,7 +20,7 @@ var map4326 = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.TileWMS({
- url: 'http://demo.opengeo.org/geoserver/wms',
+ url: 'http://demo.boundlessgeo.com/geoserver/wms',
params: {
'LAYERS': 'ne:NE1_HR_LC_SR_W_DR'
}
@@ -41,7 +41,7 @@ var map3857 = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.TileWMS({
- url: 'http://demo.opengeo.org/geoserver/wms',
+ url: 'http://demo.boundlessgeo.com/geoserver/wms',
params: {
'LAYERS': 'ne:NE1_HR_LC_SR_W_DR'
}
diff --git a/examples/vector-wfs.js b/examples/vector-wfs.js
index 1ca1d6438a..30c2b9d2ef 100644
--- a/examples/vector-wfs.js
+++ b/examples/vector-wfs.js
@@ -13,7 +13,7 @@ goog.require('ol.tilegrid.XYZ');
var vectorSource = new ol.source.ServerVector({
format: new ol.format.GeoJSON(),
loader: function(extent, resolution, projection) {
- var url = 'http://demo.opengeo.org/geoserver/wfs?service=WFS&' +
+ var url = 'http://demo.boundlessgeo.com/geoserver/wfs?service=WFS&' +
'version=1.1.0&request=GetFeature&typename=osm:water_areas&' +
'outputFormat=text/javascript&format_options=callback:loadFeatures' +
'&srsname=EPSG:3857&bbox=' + extent.join(',') + ',EPSG:3857';
diff --git a/examples/wms-image.js b/examples/wms-image.js
index adcb74dcf9..328b5170bf 100644
--- a/examples/wms-image.js
+++ b/examples/wms-image.js
@@ -13,7 +13,7 @@ var layers = [
new ol.layer.Image({
extent: [-13884991, 2870341, -7455066, 6338219],
source: new ol.source.ImageWMS({
- url: 'http://demo.opengeo.org/geoserver/wms',
+ url: 'http://demo.boundlessgeo.com/geoserver/wms',
params: {'LAYERS': 'topp:states'},
serverType: 'geoserver'
})
diff --git a/examples/wms-tiled.js b/examples/wms-tiled.js
index 9815eb8d17..abd603cafd 100644
--- a/examples/wms-tiled.js
+++ b/examples/wms-tiled.js
@@ -12,7 +12,7 @@ var layers = [
new ol.layer.Tile({
extent: [-13884991, 2870341, -7455066, 6338219],
source: new ol.source.TileWMS(/** @type {olx.source.TileWMSOptions} */ ({
- url: 'http://demo.opengeo.org/geoserver/wms',
+ url: 'http://demo.boundlessgeo.com/geoserver/wms',
params: {'LAYERS': 'topp:states', 'TILED': true},
serverType: 'geoserver'
}))
diff --git a/externs/oli.js b/externs/oli.js
index cf6c31f5a1..16f5a8a201 100644
--- a/externs/oli.js
+++ b/externs/oli.js
@@ -149,7 +149,8 @@ oli.interaction.Interaction = function() {};
* through the chain of interactions. `false` means stop, `true`
* means continue.
*/
-oli.interaction.Interaction.prototype.handleMapBrowserEvent = function(e) {};
+oli.interaction.Interaction.prototype.handleMapBrowserEvent =
+ function(mapBrowserEvent) {};
/**
diff --git a/externs/olx.js b/externs/olx.js
index 4df39a1c48..05013fc9b4 100644
--- a/externs/olx.js
+++ b/externs/olx.js
@@ -3569,7 +3569,11 @@ olx.source.TileImageOptions.prototype.attributions;
/**
- * crossOrigin setting for image requests. Default is `null`.
+ * The `crossOrigin` attribute for loaded images. Note that you must provide a
+ * `crossOrigin` value if you are using the WebGL renderer or if you want to
+ * access pixel data with the Canvas renderer. See
+ * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image}
+ * for more detail.
* @type {null|string|undefined}
* @api
*/
@@ -4120,7 +4124,13 @@ olx.source.OSMOptions.prototype.attributions;
/**
- * crossOrigin setting for image requests. Default is `anonymous`.
+ * The `crossOrigin` attribute for loaded images. Note that you must provide a
+ * `crossOrigin` value if you are using the WebGL renderer or if you want to
+ * access pixel data with the Canvas renderer. See
+ * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image}
+ * for more detail.
+ *
+ * Default is `anonymous`.
* @type {null|string|undefined}
* @api stable
*/
@@ -4406,7 +4416,11 @@ olx.source.ImageWMSOptions.prototype.attributions;
/**
- * crossOrigin setting for image requests.
+ * The `crossOrigin` attribute for loaded images. Note that you must provide a
+ * `crossOrigin` value if you are using the WebGL renderer or if you want to
+ * access pixel data with the Canvas renderer. See
+ * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image}
+ * for more detail.
* @type {null|string|undefined}
* @api stable
*/
@@ -4573,7 +4587,11 @@ olx.source.ImageStaticOptions.prototype.attributions;
/**
- * crossOrigin setting for image requests.
+ * The `crossOrigin` attribute for loaded images. Note that you must provide a
+ * `crossOrigin` value if you are using the WebGL renderer or if you want to
+ * access pixel data with the Canvas renderer. See
+ * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image}
+ * for more detail.
* @type {null|string|undefined}
* @api stable
*/
@@ -4581,7 +4599,8 @@ olx.source.ImageStaticOptions.prototype.crossOrigin;
/**
- * Extent of the image.
+ * Extent of the image in map coordinates. This is the [left, bottom, right,
+ * top] map coordinates of your image.
* @type {ol.Extent}
* @api stable
*/
@@ -4589,7 +4608,7 @@ olx.source.ImageStaticOptions.prototype.imageExtent;
/**
- * Size of the image.
+ * Size of the image in pixels.
* @type {ol.Size|undefined}
* @api stable
*/
@@ -4605,7 +4624,7 @@ olx.source.ImageStaticOptions.prototype.imageLoadFunction;
/**
- * Logo.
+ * Optional logo.
* @type {string|olx.LogoOptions|undefined}
* @api stable
*/
@@ -4621,7 +4640,7 @@ olx.source.ImageStaticOptions.prototype.projection;
/**
- * Url.
+ * Image URL.
* @type {string}
* @api stable
*/
@@ -4700,7 +4719,11 @@ olx.source.TileJSONOptions;
/**
- * crossOrigin setting for image requests.
+ * The `crossOrigin` attribute for loaded images. Note that you must provide a
+ * `crossOrigin` value if you are using the WebGL renderer or if you want to
+ * access pixel data with the Canvas renderer. See
+ * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image}
+ * for more detail.
* @type {null|string|undefined}
* @api stable
*/
@@ -4769,7 +4792,11 @@ olx.source.TileWMSOptions.prototype.params;
/**
- * crossOrigin setting for image requests.
+ * The `crossOrigin` attribute for loaded images. Note that you must provide a
+ * `crossOrigin` value if you are using the WebGL renderer or if you want to
+ * access pixel data with the Canvas renderer. See
+ * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image}
+ * for more detail.
* @type {null|string|undefined}
* @api stable
*/
@@ -5061,7 +5088,11 @@ olx.source.WMTSOptions.prototype.attributions;
/**
- * crossOrigin setting for image requests.
+ * The `crossOrigin` attribute for loaded images. Note that you must provide a
+ * `crossOrigin` value if you are using the WebGL renderer or if you want to
+ * access pixel data with the Canvas renderer. See
+ * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image}
+ * for more detail.
* @type {string|null|undefined}
* @api
*/
@@ -5229,7 +5260,11 @@ olx.source.XYZOptions.prototype.attributions;
/**
- * Cross origin setting for image requests.
+ * The `crossOrigin` attribute for loaded images. Note that you must provide a
+ * `crossOrigin` value if you are using the WebGL renderer or if you want to
+ * access pixel data with the Canvas renderer. See
+ * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image}
+ * for more detail.
* @type {null|string|undefined}
* @api stable
*/
@@ -5349,7 +5384,11 @@ olx.source.ZoomifyOptions.prototype.attributions;
/**
- * Cross origin setting for image requests.
+ * The `crossOrigin` attribute for loaded images. Note that you must provide a
+ * `crossOrigin` value if you are using the WebGL renderer or if you want to
+ * access pixel data with the Canvas renderer. See
+ * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image}
+ * for more detail.
* @type {null|string|undefined}
* @api stable
*/
@@ -5528,7 +5567,11 @@ olx.style.IconOptions.prototype.anchorYUnits;
/**
- * crossOrigin setting for image.
+ * The `crossOrigin` attribute for loaded images. Note that you must provide a
+ * `crossOrigin` value if you are using the WebGL renderer or if you want to
+ * access pixel data with the Canvas renderer. See
+ * {@link https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image}
+ * for more detail.
* @type {null|string|undefined}
* @api
*/
@@ -5621,11 +5664,13 @@ olx.style.IconOptions.prototype.src;
/**
+ * Specify radius for regular polygons, or radius1 and radius2 for stars.
* @typedef {{fill: (ol.style.Fill|undefined),
* points: number,
- * radius: number,
- * radius2: number,
- * angle: number,
+ * radius: (number|undefined),
+ * radius1: (number|undefined),
+ * radius2: (number|undefined),
+ * angle: (number|undefined),
* snapToPixel: (boolean|undefined),
* stroke: (ol.style.Stroke|undefined),
* atlasManager: (ol.style.AtlasManager|undefined)}}
@@ -5652,18 +5697,24 @@ olx.style.RegularShapeOptions.prototype.points;
/**
- * Shape radius.
- * @type {number}
+ * Radius of a regular polygon.
+ * @type {number|undefined}
* @api
*/
olx.style.RegularShapeOptions.prototype.radius;
/**
- * Shape secondary radius for drawing stars. If radius 2 is equal to radius,
- * the regular shape will be a regular polygon instead of a star.
- * Default value is equal to radius.
- * @type {number}
+* Inner radius of a star.
+* @type {number|undefined}
+* @api
+*/
+olx.style.RegularShapeOptions.prototype.radius1;
+
+
+/**
+ * Outer radius of a star.
+ * @type {number|undefined}
* @api
*/
olx.style.RegularShapeOptions.prototype.radius2;
@@ -5673,7 +5724,7 @@ olx.style.RegularShapeOptions.prototype.radius2;
* Shape's rotation in radians. A value of 0 will have one of the shape's point
* facing up.
* Default value is 0.
- * @type {number}
+ * @type {number|undefined}
* @api
*/
olx.style.RegularShapeOptions.prototype.angle;
@@ -6100,7 +6151,6 @@ olx.tilegrid.XYZOptions.prototype.tileSize;
/**
* @typedef {{resolutions: !Array.}}
* @api
- * @api
*/
olx.tilegrid.ZoomifyOptions;
diff --git a/resources/layout.css b/resources/layout.css
index abb8df1672..f4d25d5391 100644
--- a/resources/layout.css
+++ b/resources/layout.css
@@ -11,6 +11,10 @@ body {
.ol-attribution {
max-width: calc(100% - 3em);
}
+.ol-control button, .ol-attribution, .ol-scale-line-inner {
+ font-family: 'Lucida Grande',Verdana,Geneva,Lucida,Arial,Helvetica,sans-serif;
+}
+
#tags {
display: none;
}
diff --git a/src/ol/color/color.js b/src/ol/color/color.js
index 6f7f44fff4..a857308d57 100644
--- a/src/ol/color/color.js
+++ b/src/ol/color/color.js
@@ -94,6 +94,8 @@ ol.color.blend = function(dst, src, opt_color) {
/**
+ * Return the color as an array. This function maintains a cache of calculated
+ * arrays which means the result should not be modified.
* @param {ol.Color|string} color Color.
* @return {ol.Color} Color.
* @api
@@ -109,6 +111,7 @@ ol.color.asArray = function(color) {
/**
+ * Return the color as an rgba string.
* @param {ol.Color|string} color Color.
* @return {string} Rgba string.
* @api
@@ -137,12 +140,11 @@ ol.color.equals = function(color1, color2) {
/**
* @param {string} s String.
- * @param {ol.Color=} opt_color Color.
* @return {ol.Color} Color.
*/
ol.color.fromString = (
/**
- * @return {function(string, ol.Color=): ol.Color}
+ * @return {function(string): ol.Color}
*/
function() {
@@ -169,10 +171,9 @@ ol.color.fromString = (
return (
/**
* @param {string} s String.
- * @param {ol.Color=} opt_color Color.
* @return {ol.Color} Color.
*/
- function(s, opt_color) {
+ function(s) {
var color;
if (cache.hasOwnProperty(s)) {
color = cache[s];
@@ -191,7 +192,7 @@ ol.color.fromString = (
cache[s] = color;
++cacheSize;
}
- return ol.color.returnOrUpdate(color, opt_color);
+ return color;
});
})();
@@ -275,24 +276,6 @@ ol.color.normalize = function(color, opt_color) {
};
-/**
- * @param {ol.Color} color Color.
- * @param {ol.Color=} opt_color Color.
- * @return {ol.Color} Color.
- */
-ol.color.returnOrUpdate = function(color, opt_color) {
- if (goog.isDef(opt_color)) {
- opt_color[0] = color[0];
- opt_color[1] = color[1];
- opt_color[2] = color[2];
- opt_color[3] = color[3];
- return opt_color;
- } else {
- return color;
- }
-};
-
-
/**
* @param {ol.Color} color Color.
* @return {string} String.
diff --git a/src/ol/control/mousepositioncontrol.js b/src/ol/control/mousepositioncontrol.js
index 03264ef6f8..110f59a58e 100644
--- a/src/ol/control/mousepositioncontrol.js
+++ b/src/ol/control/mousepositioncontrol.js
@@ -6,7 +6,6 @@ goog.require('goog.dom');
goog.require('goog.dom.TagName');
goog.require('goog.events');
goog.require('goog.events.EventType');
-goog.require('goog.style');
goog.require('ol.CoordinateFormatType');
goog.require('ol.Object');
goog.require('ol.Pixel');
@@ -162,9 +161,7 @@ goog.exportProperty(
*/
ol.control.MousePosition.prototype.handleMouseMove = function(browserEvent) {
var map = this.getMap();
- var eventPosition = goog.style.getRelativePosition(
- browserEvent, map.getViewport());
- this.lastMouseMovePixel_ = [eventPosition.x, eventPosition.y];
+ this.lastMouseMovePixel_ = map.getEventPixel(browserEvent.getBrowserEvent());
this.updateHTML_(this.lastMouseMovePixel_);
};
diff --git a/src/ol/format/gml/gmlbase.js b/src/ol/format/gml/gmlbase.js
index 5133badd8c..1e1e9dcfc7 100644
--- a/src/ol/format/gml/gmlbase.js
+++ b/src/ol/format/gml/gmlbase.js
@@ -100,8 +100,8 @@ ol.format.GMLBase.prototype.readFeatures_ = function(node, objectStack) {
var parsers = {};
var parsersNS = {};
parsers[featureType] = (localName == 'featureMembers') ?
- ol.xml.makeArrayPusher(this.readFeature_, this) :
- ol.xml.makeReplacer(this.readFeature_, this);
+ ol.xml.makeArrayPusher(this.readFeatureElement, this) :
+ ol.xml.makeReplacer(this.readFeatureElement, this);
parsersNS[goog.object.get(context, 'featureNS')] = parsers;
features = ol.xml.pushParseAndPop([], parsersNS, node, objectStack);
}
@@ -150,9 +150,8 @@ ol.format.GMLBase.prototype.readGeometryElement = function(node, objectStack) {
* @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack.
* @return {ol.Feature} Feature.
- * @private
*/
-ol.format.GMLBase.prototype.readFeature_ = function(node, objectStack) {
+ol.format.GMLBase.prototype.readFeatureElement = function(node, objectStack) {
var n;
var fid = node.getAttribute('fid') ||
ol.xml.getAttributeNS(node, 'http://www.opengis.net/gml', 'id');
diff --git a/src/ol/format/wktformat.js b/src/ol/format/wktformat.js
index e4dd17d239..40fc27601c 100644
--- a/src/ol/format/wktformat.js
+++ b/src/ol/format/wktformat.js
@@ -582,7 +582,7 @@ ol.format.WKT.Parser.prototype.parse = function() {
/**
- * @return {!ol.geom.Geometry|!ol.geom.GeometryCollection} The geometry.
+ * @return {!(ol.geom.Geometry|ol.geom.GeometryCollection)} The geometry.
* @private
*/
ol.format.WKT.Parser.prototype.parseGeometry_ = function() {
diff --git a/src/ol/format/wmsgetfeatureinfoformat.js b/src/ol/format/wmsgetfeatureinfoformat.js
new file mode 100644
index 0000000000..0d928189e4
--- /dev/null
+++ b/src/ol/format/wmsgetfeatureinfoformat.js
@@ -0,0 +1,146 @@
+goog.provide('ol.format.WMSGetFeatureInfo');
+
+goog.require('goog.array');
+goog.require('goog.asserts');
+goog.require('goog.dom');
+goog.require('goog.dom.NodeType');
+goog.require('goog.object');
+goog.require('goog.string');
+goog.require('ol.format.GML');
+goog.require('ol.format.GML2');
+goog.require('ol.format.XMLFeature');
+goog.require('ol.xml');
+
+
+
+/**
+ * @classdesc
+ * Format for reading WMSGetFeatureInfo format. It uses
+ * {@link ol.format.GML2} to read features.
+ *
+ * @constructor
+ * @extends {ol.format.XMLFeature}
+ * @api
+ */
+ol.format.WMSGetFeatureInfo = function() {
+
+ /**
+ * @private
+ * @type {string}
+ */
+ this.featureNS_ = 'http://mapserver.gis.umn.edu/mapserver';
+
+
+ /**
+ * @private
+ * @type {ol.format.GML2}
+ */
+ this.gmlFormat_ = new ol.format.GML2();
+
+ goog.base(this);
+};
+goog.inherits(ol.format.WMSGetFeatureInfo, ol.format.XMLFeature);
+
+
+/**
+ * @const
+ * @type {string}
+ * @private
+ */
+ol.format.WMSGetFeatureInfo.featureIdentifier_ = '_feature';
+
+
+/**
+ * @const
+ * @type {string}
+ * @private
+ */
+ol.format.WMSGetFeatureInfo.layerIdentifier_ = '_layer';
+
+
+/**
+ * @param {Node} node Node.
+ * @param {Array.<*>} objectStack Object stack.
+ * @return {Array.} Features.
+ * @private
+ */
+ol.format.WMSGetFeatureInfo.prototype.readFeatures_ =
+ function(node, objectStack) {
+
+ node.namespaceURI = this.featureNS_;
+ goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT);
+ var localName = ol.xml.getLocalName(node);
+ /** @type {Array.} */
+ var features = [];
+ if (node.childNodes.length === 0) {
+ return features;
+ }
+ if (localName == 'msGMLOutput') {
+ goog.array.forEach(node.childNodes, function(layer) {
+ if (layer.nodeType !== goog.dom.NodeType.ELEMENT) {
+ return;
+ }
+ var context = objectStack[0];
+ goog.asserts.assert(goog.isObject(context));
+
+ goog.asserts.assert(layer.localName.indexOf(
+ ol.format.WMSGetFeatureInfo.layerIdentifier_) >= 0);
+
+ var featureType = goog.string.remove(layer.localName,
+ ol.format.WMSGetFeatureInfo.layerIdentifier_) +
+ ol.format.WMSGetFeatureInfo.featureIdentifier_;
+
+ goog.object.set(context, 'featureType', featureType);
+ goog.object.set(context, 'featureNS', this.featureNS_);
+
+ var parsers = {};
+ parsers[featureType] = ol.xml.makeArrayPusher(
+ this.gmlFormat_.readFeatureElement, this.gmlFormat_);
+ var parsersNS = ol.xml.makeParsersNS(
+ [goog.object.get(context, 'featureNS'), null], parsers);
+ layer.namespaceURI = this.featureNS_;
+ var layerFeatures = ol.xml.pushParseAndPop(
+ [], parsersNS, layer, objectStack, this.gmlFormat_);
+ if (goog.isDef(layerFeatures)) {
+ goog.array.extend(features, layerFeatures);
+ }
+ }, this);
+ }
+ if (localName == 'FeatureCollection') {
+ var gmlFeatures = ol.xml.pushParseAndPop([],
+ this.gmlFormat_.FEATURE_COLLECTION_PARSERS, node,
+ [{}], this.gmlFormat_);
+ if (goog.isDef(gmlFeatures)) {
+ features = gmlFeatures;
+ }
+ }
+ return features;
+};
+
+
+/**
+ * Read all features from a WMSGetFeatureInfo response.
+ *
+ * @function
+ * @param {ArrayBuffer|Document|Node|Object|string} source Source.
+ * @param {olx.format.ReadOptions=} opt_options Options.
+ * @return {Array.} Features.
+ * @api stable
+ */
+ol.format.WMSGetFeatureInfo.prototype.readFeatures;
+
+
+/**
+ * @inheritDoc
+ */
+ol.format.WMSGetFeatureInfo.prototype.readFeaturesFromNode =
+ function(node, opt_options) {
+ var options = {
+ 'featureType': this.featureType,
+ 'featureNS': this.featureNS
+ };
+ if (goog.isDef(opt_options)) {
+ goog.object.extend(options, this.getReadOptions(node, opt_options));
+ }
+ return this.readFeatures_(node, [options]);
+};
diff --git a/src/ol/geom/geometrycollection.js b/src/ol/geom/geometrycollection.js
index e6130bd673..0ccdd1887a 100644
--- a/src/ol/geom/geometrycollection.js
+++ b/src/ol/geom/geometrycollection.js
@@ -265,6 +265,7 @@ ol.geom.GeometryCollection.prototype.setGeometriesArray = function(geometries) {
/**
* @inheritDoc
+ * @api stable
*/
ol.geom.GeometryCollection.prototype.applyTransform = function(transformFn) {
var geometries = this.geometries_;
diff --git a/src/ol/geom/simplegeometry.js b/src/ol/geom/simplegeometry.js
index 847cd292fb..89449a1527 100644
--- a/src/ol/geom/simplegeometry.js
+++ b/src/ol/geom/simplegeometry.js
@@ -245,6 +245,7 @@ ol.geom.SimpleGeometry.prototype.setLayout =
/**
* @inheritDoc
+ * @api stable
*/
ol.geom.SimpleGeometry.prototype.applyTransform = function(transformFn) {
if (!goog.isNull(this.flatCoordinates)) {
diff --git a/src/ol/interaction/selectinteraction.js b/src/ol/interaction/selectinteraction.js
index 5c4067e3db..86f322f1ef 100644
--- a/src/ol/interaction/selectinteraction.js
+++ b/src/ol/interaction/selectinteraction.js
@@ -154,7 +154,7 @@ ol.interaction.Select.prototype.handleMapBrowserEvent =
}
} else {
// Modify the currently selected feature(s).
- var /** @type {Array.} */ deselected = [];
+ var /** @type {Array.} */ deselected = [];
var /** @type {Array.} */ selected = [];
map.forEachFeatureAtPixel(mapBrowserEvent.pixel,
/**
@@ -169,17 +169,17 @@ ol.interaction.Select.prototype.handleMapBrowserEvent =
}
} else {
if (remove || toggle) {
- deselected.push(index);
+ deselected.push(feature);
}
}
}, undefined, this.layerFilter_);
var i;
for (i = deselected.length - 1; i >= 0; --i) {
- features.removeAt(deselected[i]);
+ features.remove(deselected[i]);
}
features.extend(selected);
}
- return false;
+ return this.condition_ == ol.events.condition.mouseMove;
};
diff --git a/src/ol/layer/layergroup.js b/src/ol/layer/layergroup.js
index 86dc1042f5..dcb420fc5f 100644
--- a/src/ol/layer/layergroup.js
+++ b/src/ol/layer/layergroup.js
@@ -214,9 +214,13 @@ ol.layer.Group.prototype.getLayerStatesArray = function(opt_states) {
layerState.maxResolution, ownLayerState.maxResolution);
layerState.minResolution = Math.max(
layerState.minResolution, ownLayerState.minResolution);
- if (goog.isDef(ownLayerState.extent) && goog.isDef(layerState.extent)) {
- layerState.extent = ol.extent.getIntersection(
- layerState.extent, ownLayerState.extent);
+ if (goog.isDef(ownLayerState.extent)) {
+ if (goog.isDef(layerState.extent)) {
+ layerState.extent = ol.extent.getIntersection(
+ layerState.extent, ownLayerState.extent);
+ } else {
+ layerState.extent = ownLayerState.extent;
+ }
}
}
diff --git a/src/ol/map.js b/src/ol/map.js
index 95e4acfca4..6905e65eae 100644
--- a/src/ol/map.js
+++ b/src/ol/map.js
@@ -265,7 +265,7 @@ ol.Map = function(options) {
goog.events.EventType.TOUCHSTART,
goog.events.EventType.MSPOINTERDOWN,
ol.MapBrowserEvent.EventType.POINTERDOWN,
- goog.events.EventType.MOUSEWHEEL
+ goog.userAgent.GECKO ? 'DOMMouseScroll' : 'mousewheel'
], goog.events.Event.stopPropagation);
goog.dom.appendChild(this.viewport_, this.overlayContainerStopEvent_);
@@ -592,18 +592,25 @@ ol.Map.prototype.getEventCoordinate = function(event) {
/**
- * Returns the map pixel position for a browser event.
+ * Returns the map pixel position for a browser event relative to the viewport.
* @param {Event} event Event.
* @return {ol.Pixel} Pixel.
* @api stable
*/
ol.Map.prototype.getEventPixel = function(event) {
- // goog.style.getRelativePosition is based on event.targetTouches,
- // but touchend and touchcancel events have no targetTouches when
- // the last finger is removed from the screen.
- // So we ourselves compute the position of touch events.
- // See https://github.com/google/closure-library/pull/323
- if (goog.isDef(event.changedTouches)) {
+ // Use the offsetX and offsetY values if available.
+ // See http://www.w3.org/TR/cssom-view/#dom-mouseevent-offsetx and
+ // http://www.w3.org/TR/cssom-view/#dom-mouseevent-offsety
+ if (goog.isDef(event.offsetX) && goog.isDef(event.offsetY)) {
+ return [event.offsetX, event.offsetY];
+ } else if (goog.isDef(event.changedTouches)) {
+ // offsetX and offsetY are not defined for Touch Event
+ //
+ // goog.style.getRelativePosition is based on event.targetTouches,
+ // but touchend and touchcancel events have no targetTouches when
+ // the last finger is removed from the screen.
+ // So we ourselves compute the position of touch events.
+ // See https://github.com/google/closure-library/pull/323
var touch = event.changedTouches[0];
var viewportPosition = goog.style.getClientPosition(this.viewport_);
return [
@@ -611,6 +618,8 @@ ol.Map.prototype.getEventPixel = function(event) {
touch.clientY - viewportPosition.y
];
} else {
+ // Compute offsetX and offsetY values for browsers that don't implement
+ // cssom-view specification
var eventPosition = goog.style.getRelativePosition(event, this.viewport_);
return [eventPosition.x, eventPosition.y];
}
diff --git a/src/ol/proj/epsg3857projection.js b/src/ol/proj/epsg3857projection.js
index 3186b43a3c..e5ed7c0598 100644
--- a/src/ol/proj/epsg3857projection.js
+++ b/src/ol/proj/epsg3857projection.js
@@ -80,6 +80,7 @@ ol.proj.EPSG3857.CODES = [
'EPSG:102113',
'EPSG:900913',
'urn:ogc:def:crs:EPSG:6.18:3:3857',
+ 'urn:ogc:def:crs:EPSG::3857',
'http://www.opengis.net/gml/srs/epsg.xml#3857'
];
diff --git a/src/ol/proj/epsg4326projection.js b/src/ol/proj/epsg4326projection.js
index 09fb570d87..cbbf571d8e 100644
--- a/src/ol/proj/epsg4326projection.js
+++ b/src/ol/proj/epsg4326projection.js
@@ -59,6 +59,7 @@ ol.proj.EPSG4326.EXTENT = [-180, -90, 180, 90];
ol.proj.EPSG4326.PROJECTIONS = [
new ol.proj.EPSG4326_('CRS:84'),
new ol.proj.EPSG4326_('EPSG:4326', 'neu'),
+ new ol.proj.EPSG4326_('urn:ogc:def:crs:EPSG::4326', 'neu'),
new ol.proj.EPSG4326_('urn:ogc:def:crs:EPSG:6.6:4326', 'neu'),
new ol.proj.EPSG4326_('urn:ogc:def:crs:OGC:1.3:CRS84'),
new ol.proj.EPSG4326_('urn:ogc:def:crs:OGC:2:84'),
diff --git a/src/ol/renderer/canvas/canvasimagelayerrenderer.js b/src/ol/renderer/canvas/canvasimagelayerrenderer.js
index c223d84f1c..6fad17913b 100644
--- a/src/ol/renderer/canvas/canvasimagelayerrenderer.js
+++ b/src/ol/renderer/canvas/canvasimagelayerrenderer.js
@@ -9,6 +9,7 @@ goog.require('ol.ImageState');
goog.require('ol.ViewHint');
goog.require('ol.extent');
goog.require('ol.layer.Image');
+goog.require('ol.proj');
goog.require('ol.renderer.Map');
goog.require('ol.renderer.canvas.Layer');
goog.require('ol.vec.Mat4');
@@ -108,8 +109,14 @@ ol.renderer.canvas.ImageLayer.prototype.prepareFrame =
if (!hints[ol.ViewHint.ANIMATING] && !hints[ol.ViewHint.INTERACTING] &&
!ol.extent.isEmpty(renderedExtent)) {
+ var projection = viewState.projection;
+ var sourceProjection = imageSource.getProjection();
+ if (!goog.isNull(sourceProjection)) {
+ goog.asserts.assert(ol.proj.equivalent(projection, sourceProjection));
+ projection = sourceProjection;
+ }
image = imageSource.getImage(
- renderedExtent, viewResolution, pixelRatio, viewState.projection);
+ renderedExtent, viewResolution, pixelRatio, projection);
if (!goog.isNull(image)) {
var imageState = image.getState();
if (imageState == ol.ImageState.IDLE) {
diff --git a/src/ol/renderer/canvas/canvaslayerrenderer.js b/src/ol/renderer/canvas/canvaslayerrenderer.js
index f48f64eb7a..74bca84a42 100644
--- a/src/ol/renderer/canvas/canvaslayerrenderer.js
+++ b/src/ol/renderer/canvas/canvaslayerrenderer.js
@@ -1,8 +1,10 @@
goog.provide('ol.renderer.canvas.Layer');
goog.require('goog.array');
+goog.require('goog.asserts');
goog.require('goog.vec.Mat4');
goog.require('ol.dom');
+goog.require('ol.extent');
goog.require('ol.layer.Layer');
goog.require('ol.render.Event');
goog.require('ol.render.EventType');
@@ -44,6 +46,35 @@ ol.renderer.canvas.Layer.prototype.composeFrame =
var image = this.getImage();
if (!goog.isNull(image)) {
+
+ // clipped rendering if layer extent is set
+ var extent = layerState.extent;
+ var clipped = goog.isDef(extent);
+ if (clipped) {
+ goog.asserts.assert(goog.isDef(extent));
+ var topLeft = ol.extent.getTopLeft(extent);
+ var topRight = ol.extent.getTopRight(extent);
+ var bottomRight = ol.extent.getBottomRight(extent);
+ var bottomLeft = ol.extent.getBottomLeft(extent);
+
+ ol.vec.Mat4.multVec2(frameState.coordinateToPixelMatrix,
+ topLeft, topLeft);
+ ol.vec.Mat4.multVec2(frameState.coordinateToPixelMatrix,
+ topRight, topRight);
+ ol.vec.Mat4.multVec2(frameState.coordinateToPixelMatrix,
+ bottomRight, bottomRight);
+ ol.vec.Mat4.multVec2(frameState.coordinateToPixelMatrix,
+ bottomLeft, bottomLeft);
+
+ context.save();
+ context.beginPath();
+ context.moveTo(topLeft[0], topLeft[1]);
+ context.lineTo(topRight[0], topRight[1]);
+ context.lineTo(bottomRight[0], bottomRight[1]);
+ context.lineTo(bottomLeft[0], bottomLeft[1]);
+ context.clip();
+ }
+
var imageTransform = this.getImageTransform();
// for performance reasons, context.save / context.restore is not used
// to save and restore the transformation matrix and the opacity.
@@ -72,6 +103,10 @@ ol.renderer.canvas.Layer.prototype.composeFrame =
context.setTransform(1, 0, 0, 1, 0, 0);
}
context.globalAlpha = alpha;
+
+ if (clipped) {
+ context.restore();
+ }
}
this.dispatchPostComposeEvent(context, frameState);
diff --git a/src/ol/renderer/canvas/canvastilelayerrenderer.js b/src/ol/renderer/canvas/canvastilelayerrenderer.js
index 8ccc72d1ac..978aa41aa4 100644
--- a/src/ol/renderer/canvas/canvastilelayerrenderer.js
+++ b/src/ol/renderer/canvas/canvastilelayerrenderer.js
@@ -5,16 +5,13 @@ goog.provide('ol.renderer.canvas.TileLayer');
goog.require('goog.array');
goog.require('goog.asserts');
-goog.require('goog.events');
goog.require('goog.object');
goog.require('goog.vec.Mat4');
-goog.require('ol.Object');
goog.require('ol.Size');
goog.require('ol.TileRange');
goog.require('ol.TileState');
goog.require('ol.dom');
goog.require('ol.extent');
-goog.require('ol.layer.LayerProperty');
goog.require('ol.layer.Tile');
goog.require('ol.renderer.Map');
goog.require('ol.renderer.canvas.Layer');
@@ -81,32 +78,10 @@ ol.renderer.canvas.TileLayer = function(mapRenderer, tileLayer) {
*/
this.renderedTiles_ = null;
- /**
- * @private
- * @type {Array.}
- */
- this.eventKeys_ = [
- goog.events.listen(
- tileLayer, ol.Object.getChangeEventType(ol.layer.LayerProperty.EXTENT),
- this.handleLayerExtentChanged_, false, this)
- ];
-
};
goog.inherits(ol.renderer.canvas.TileLayer, ol.renderer.canvas.Layer);
-/**
- * @inheritDoc
- */
-ol.renderer.canvas.TileLayer.prototype.disposeInternal = function() {
- for (var i = 0, ii = this.eventKeys_.length; i < ii; ++i) {
- goog.events.unlistenByKey(this.eventKeys_[i]);
- }
- this.eventKeys_.length = 0;
- goog.base(this, 'disposeInternal');
-};
-
-
/**
* @inheritDoc
*/
@@ -123,19 +98,6 @@ ol.renderer.canvas.TileLayer.prototype.getImageTransform = function() {
};
-/**
- * Handle layer extent changes. We clear the canvas any time the layer extent
- * changes.
- * @private
- */
-ol.renderer.canvas.TileLayer.prototype.handleLayerExtentChanged_ = function() {
- if (!goog.isNull(this.context_)) {
- this.context_.clearRect(0, 0, this.canvasSize_[0], this.canvasSize_[1]);
- this.renderedCanvasZ_ = NaN;
- }
-};
-
-
/**
* @inheritDoc
*/
@@ -278,11 +240,6 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
if (z != this.renderedCanvasZ_ ||
!this.renderedCanvasTileRange_.containsTileRange(tileRange)) {
this.renderedCanvasTileRange_ = null;
- // Due to limited layer extent, we may be rendering tiles on a small
- // portion of the canvas.
- if (z < this.renderedCanvasZ_) {
- this.context_.clearRect(0, 0, canvasWidth, canvasHeight);
- }
}
}
}
diff --git a/src/ol/renderer/dom/domimagelayerrenderer.js b/src/ol/renderer/dom/domimagelayerrenderer.js
index ce2ca367c7..0a8f59388b 100644
--- a/src/ol/renderer/dom/domimagelayerrenderer.js
+++ b/src/ol/renderer/dom/domimagelayerrenderer.js
@@ -12,6 +12,7 @@ goog.require('ol.ViewHint');
goog.require('ol.dom');
goog.require('ol.extent');
goog.require('ol.layer.Image');
+goog.require('ol.proj');
goog.require('ol.renderer.dom.Layer');
goog.require('ol.vec.Mat4');
@@ -104,8 +105,14 @@ ol.renderer.dom.ImageLayer.prototype.prepareFrame =
if (!hints[ol.ViewHint.ANIMATING] && !hints[ol.ViewHint.INTERACTING] &&
!ol.extent.isEmpty(renderedExtent)) {
+ var projection = viewState.projection;
+ var sourceProjection = imageSource.getProjection();
+ if (!goog.isNull(sourceProjection)) {
+ goog.asserts.assert(ol.proj.equivalent(projection, sourceProjection));
+ projection = sourceProjection;
+ }
var image_ = imageSource.getImage(renderedExtent, viewResolution,
- frameState.pixelRatio, viewState.projection);
+ frameState.pixelRatio, projection);
if (!goog.isNull(image_)) {
var imageState = image_.getState();
if (imageState == ol.ImageState.IDLE) {
diff --git a/src/ol/renderer/webgl/webglimagelayerrenderer.js b/src/ol/renderer/webgl/webglimagelayerrenderer.js
index a29cbd0d4d..6f31e1cf42 100644
--- a/src/ol/renderer/webgl/webglimagelayerrenderer.js
+++ b/src/ol/renderer/webgl/webglimagelayerrenderer.js
@@ -12,6 +12,7 @@ goog.require('ol.ImageState');
goog.require('ol.ViewHint');
goog.require('ol.extent');
goog.require('ol.layer.Image');
+goog.require('ol.proj');
goog.require('ol.renderer.webgl.Layer');
@@ -124,8 +125,14 @@ ol.renderer.webgl.ImageLayer.prototype.prepareFrame =
}
if (!hints[ol.ViewHint.ANIMATING] && !hints[ol.ViewHint.INTERACTING] &&
!ol.extent.isEmpty(renderedExtent)) {
+ var projection = viewState.projection;
+ var sourceProjection = imageSource.getProjection();
+ if (!goog.isNull(sourceProjection)) {
+ goog.asserts.assert(ol.proj.equivalent(projection, sourceProjection));
+ projection = sourceProjection;
+ }
var image_ = imageSource.getImage(renderedExtent, viewResolution,
- frameState.pixelRatio, viewState.projection);
+ frameState.pixelRatio, projection);
if (!goog.isNull(image_)) {
var imageState = image_.getState();
if (imageState == ol.ImageState.IDLE) {
diff --git a/src/ol/source/formatvectorsource.js b/src/ol/source/formatvectorsource.js
index 1ceba4d297..7c94bf5fa2 100644
--- a/src/ol/source/formatvectorsource.js
+++ b/src/ol/source/formatvectorsource.js
@@ -48,12 +48,14 @@ goog.inherits(ol.source.FormatVector, ol.source.Vector);
/**
* @param {goog.Uri|string} url URL.
- * @param {function(this: T, Array.)} callback Callback.
- * @param {T} thisArg Value to use as `this` when executing `callback`.
+ * @param {function(this: T, Array.)} success Success Callback.
+ * @param {function(this: T)} error Error callback.
+ * @param {T} thisArg Value to use as `this` when executing `success` or
+ * `error`.
* @template T
*/
ol.source.FormatVector.prototype.loadFeaturesFromURL =
- function(url, callback, thisArg) {
+ function(url, success, error, thisArg) {
var xhrIo = new goog.net.XhrIo();
var type = this.format.getType();
var responseType;
@@ -97,13 +99,13 @@ ol.source.FormatVector.prototype.loadFeaturesFromURL =
goog.asserts.fail();
}
if (goog.isDefAndNotNull(source)) {
- callback.call(thisArg, this.readFeatures(source));
+ success.call(thisArg, this.readFeatures(source));
} else {
this.setState(ol.source.State.ERROR);
goog.asserts.fail();
}
} else {
- this.setState(ol.source.State.ERROR);
+ error.call(thisArg);
}
goog.dispose(xhrIo);
}, false, this);
diff --git a/src/ol/source/imagestaticsource.js b/src/ol/source/imagestaticsource.js
index bdc4e14d07..04fa00fa78 100644
--- a/src/ol/source/imagestaticsource.js
+++ b/src/ol/source/imagestaticsource.js
@@ -10,8 +10,7 @@ goog.require('ol.source.Image');
/**
* @classdesc
- * An image source for 'static', that is, non-georeferenced, images.
- * See examples/static-image for example.
+ * A layer source for displaying a single, static image.
*
* @constructor
* @extends {ol.source.Image}
diff --git a/src/ol/source/mapquestsource.js b/src/ol/source/mapquestsource.js
index 6b9f7f59f3..743bddb1ae 100644
--- a/src/ol/source/mapquestsource.js
+++ b/src/ol/source/mapquestsource.js
@@ -56,7 +56,7 @@ ol.source.MapQuest.TILE_ATTRIBUTION = new ol.Attribution({
*/
ol.source.MapQuestConfig = {
'osm': {
- maxZoom: 28,
+ maxZoom: 19,
attributions: [
ol.source.MapQuest.TILE_ATTRIBUTION,
ol.source.OSM.ATTRIBUTION
diff --git a/src/ol/source/staticvectorsource.js b/src/ol/source/staticvectorsource.js
index ca5c5362c6..30b5e330e7 100644
--- a/src/ol/source/staticvectorsource.js
+++ b/src/ol/source/staticvectorsource.js
@@ -48,13 +48,15 @@ ol.source.StaticVector = function(options) {
if (goog.isDef(options.url) || goog.isDef(options.urls)) {
this.setState(ol.source.State.LOADING);
if (goog.isDef(options.url)) {
- this.loadFeaturesFromURL(options.url, this.onFeaturesLoaded_, this);
+ this.loadFeaturesFromURL(options.url,
+ this.onFeaturesLoadedSuccess_, this.onFeaturesLoadedError_, this);
}
if (goog.isDef(options.urls)) {
var urls = options.urls;
var i, ii;
for (i = 0, ii = urls.length; i < ii; ++i) {
- this.loadFeaturesFromURL(urls[i], this.onFeaturesLoaded_, this);
+ this.loadFeaturesFromURL(urls[i],
+ this.onFeaturesLoadedSuccess_, this.onFeaturesLoadedError_, this);
}
}
}
@@ -63,11 +65,19 @@ ol.source.StaticVector = function(options) {
goog.inherits(ol.source.StaticVector, ol.source.FormatVector);
+/**
+ * @private
+ */
+ol.source.StaticVector.prototype.onFeaturesLoadedError_ = function() {
+ this.setState(ol.source.State.ERROR);
+};
+
+
/**
* @param {Array.} features Features.
* @private
*/
-ol.source.StaticVector.prototype.onFeaturesLoaded_ = function(features) {
+ol.source.StaticVector.prototype.onFeaturesLoadedSuccess_ = function(features) {
this.addFeaturesInternal(features);
this.setState(ol.source.State.READY);
};
diff --git a/src/ol/source/tilevectorsource.js b/src/ol/source/tilevectorsource.js
index 1dc0ed79db..84eea90faa 100644
--- a/src/ol/source/tilevectorsource.js
+++ b/src/ol/source/tilevectorsource.js
@@ -1,6 +1,7 @@
goog.provide('ol.source.TileVector');
goog.require('goog.array');
+goog.require('goog.asserts');
goog.require('goog.object');
goog.require('ol.TileCoord');
goog.require('ol.TileUrlFunction');
@@ -91,6 +92,48 @@ ol.source.TileVector.prototype.clear = function() {
ol.source.TileVector.prototype.forEachFeature = goog.abstractMethod;
+/**
+ * Iterate through all features whose geometries contain the provided
+ * coordinate at the provided resolution, calling the callback with each
+ * feature. If the callback returns a "truthy" value, iteration will stop and
+ * the function will return the same value.
+ *
+ * @param {ol.Coordinate} coordinate Coordinate.
+ * @param {number} resolution Resolution.
+ * @param {function(this: T, ol.Feature): S} callback Called with each feature
+ * whose goemetry contains the provided coordinate.
+ * @param {T=} opt_this The object to use as `this` in the callback.
+ * @return {S|undefined} The return value from the last call to the callback.
+ * @template T,S
+ */
+ol.source.TileVector.prototype.forEachFeatureAtCoordinateAndResolution =
+ function(coordinate, resolution, callback, opt_this) {
+
+ var tileGrid = this.tileGrid_;
+ var tiles = this.tiles_;
+ var tileCoord = tileGrid.getTileCoordForCoordAndResolution(coordinate,
+ resolution);
+
+ var tileKey = this.getTileKeyZXY_(tileCoord[0], tileCoord[1], tileCoord[2]);
+ var features = tiles[tileKey];
+ if (goog.isDef(features)) {
+ var i, ii;
+ for (i = 0, ii = features.length; i < ii; ++i) {
+ var feature = features[i];
+ var geometry = feature.getGeometry();
+ goog.asserts.assert(goog.isDefAndNotNull(geometry));
+ if (geometry.containsCoordinate(coordinate)) {
+ var result = callback.call(opt_this, feature);
+ if (result) {
+ return result;
+ }
+ }
+ }
+ }
+ return undefined;
+};
+
+
/**
* @inheritDoc
*/
@@ -141,6 +184,7 @@ ol.source.TileVector.prototype.getExtent = goog.abstractMethod;
/**
* @inheritDoc
+ * @api
*/
ol.source.TileVector.prototype.getFeatures = function() {
var tiles = this.tiles_;
@@ -153,6 +197,28 @@ ol.source.TileVector.prototype.getFeatures = function() {
};
+/**
+ * Get all features whose geometry intersects the provided coordinate for the
+ * provided resolution.
+ * @param {ol.Coordinate} coordinate Coordinate.
+ * @param {number} resolution Resolution.
+ * @return {Array.} Features.
+ * @api
+ */
+ol.source.TileVector.prototype.getFeaturesAtCoordinateAndResolution =
+ function(coordinate, resolution) {
+ var features = [];
+ this.forEachFeatureAtCoordinateAndResolution(coordinate, resolution,
+ /**
+ * @param {ol.Feature} feature Feature.
+ */
+ function(feature) {
+ features.push(feature);
+ });
+ return features;
+};
+
+
/**
* @inheritDoc
*/
@@ -184,6 +250,15 @@ ol.source.TileVector.prototype.loadFeatures =
var tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);
var tileCoord = [z, 0, 0];
var x, y;
+ /**
+ * @param {string} tileKey Tile key.
+ * @param {Array.} features Features.
+ * @this {ol.source.TileVector}
+ */
+ function success(tileKey, features) {
+ tiles[tileKey] = features;
+ this.setState(ol.source.State.READY);
+ }
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
var tileKey = this.getTileKeyZXY_(z, x, y);
@@ -195,16 +270,8 @@ ol.source.TileVector.prototype.loadFeatures =
var url = tileUrlFunction(tileCoord, 1, projection);
if (goog.isDef(url)) {
tiles[tileKey] = [];
- this.loadFeaturesFromURL(url, goog.partial(
- /**
- * @param {string} tileKey Tile key.
- * @param {Array.} features Features.
- * @this {ol.source.TileVector}
- */
- function(tileKey, features) {
- tiles[tileKey] = features;
- this.setState(ol.source.State.READY);
- }, tileKey), this);
+ this.loadFeaturesFromURL(url, goog.partial(success, tileKey),
+ goog.nullFunction, this);
}
}
}
diff --git a/src/ol/source/wmtssource.js b/src/ol/source/wmtssource.js
index 8581772b72..ad458804c9 100644
--- a/src/ol/source/wmtssource.js
+++ b/src/ol/source/wmtssource.js
@@ -68,7 +68,6 @@ ol.source.WMTS = function(options) {
var context = {
'Layer': options.layer,
- 'style': options.style,
'Style': options.style,
'TileMatrixSet': options.matrixSet
};
diff --git a/src/ol/style/circlestyle.js b/src/ol/style/circlestyle.js
index 1c1742811d..96632d06aa 100644
--- a/src/ol/style/circlestyle.js
+++ b/src/ol/style/circlestyle.js
@@ -4,6 +4,7 @@ goog.require('goog.asserts');
goog.require('goog.dom');
goog.require('goog.dom.TagName');
goog.require('ol.color');
+goog.require('ol.has');
goog.require('ol.render.canvas');
goog.require('ol.structs.IHasChecksum');
goog.require('ol.style.Fill');
@@ -243,7 +244,7 @@ ol.style.Circle.prototype.unlistenImageChange = goog.nullFunction;
/**
* @typedef {{strokeStyle: (string|undefined), strokeWidth: number,
- * size: number}}
+ * size: number, lineDash: Array.}}
*/
ol.style.Circle.RenderOptions;
@@ -253,7 +254,10 @@ ol.style.Circle.RenderOptions;
* @param {ol.style.AtlasManager|undefined} atlasManager
*/
ol.style.Circle.prototype.render_ = function(atlasManager) {
- var strokeStyle, strokeWidth = 0, imageSize;
+ var imageSize;
+ var lineDash = null;
+ var strokeStyle;
+ var strokeWidth = 0;
if (!goog.isNull(this.stroke_)) {
strokeStyle = ol.color.asString(this.stroke_.getColor());
@@ -261,15 +265,21 @@ ol.style.Circle.prototype.render_ = function(atlasManager) {
if (!goog.isDef(strokeWidth)) {
strokeWidth = ol.render.canvas.defaultLineWidth;
}
+ lineDash = this.stroke_.getLineDash();
+ if (!ol.has.CANVAS_LINE_DASH) {
+ lineDash = null;
+ }
}
+
var size = 2 * (this.radius_ + strokeWidth) + 1;
/** @type {ol.style.Circle.RenderOptions} */
var renderOptions = {
strokeStyle: strokeStyle,
strokeWidth: strokeWidth,
- size: size
+ size: size,
+ lineDash: lineDash
};
if (!goog.isDef(atlasManager)) {
@@ -355,6 +365,9 @@ ol.style.Circle.prototype.draw_ = function(renderOptions, context, x, y) {
if (!goog.isNull(this.stroke_)) {
context.strokeStyle = renderOptions.strokeStyle;
context.lineWidth = renderOptions.strokeWidth;
+ if (!goog.isNull(renderOptions.lineDash)) {
+ context.setLineDash(renderOptions.lineDash);
+ }
context.stroke();
}
context.closePath();
@@ -412,6 +425,9 @@ ol.style.Circle.prototype.drawHitDetectionCanvas_ =
if (!goog.isNull(this.stroke_)) {
context.strokeStyle = renderOptions.strokeStyle;
context.lineWidth = renderOptions.strokeWidth;
+ if (!goog.isNull(renderOptions.lineDash)) {
+ context.setLineDash(renderOptions.lineDash);
+ }
context.stroke();
}
context.closePath();
diff --git a/src/ol/style/regularshapestyle.js b/src/ol/style/regularshapestyle.js
index 24f35ef5f4..f7744cc3ff 100644
--- a/src/ol/style/regularshapestyle.js
+++ b/src/ol/style/regularshapestyle.js
@@ -4,6 +4,7 @@ goog.require('goog.asserts');
goog.require('goog.dom');
goog.require('goog.dom.TagName');
goog.require('ol.color');
+goog.require('ol.has');
goog.require('ol.render.canvas');
goog.require('ol.style.Fill');
goog.require('ol.style.Image');
@@ -14,7 +15,9 @@ goog.require('ol.style.Stroke');
/**
* @classdesc
- * Set regular shape style for vector features.
+ * Set regular shape style for vector features. The resulting shape will be
+ * a regular polygon when `radius` is provided, or a star when `radius1` and
+ * `radius2` are provided.
*
* @constructor
* @param {olx.style.RegularShapeOptions=} opt_options Options.
@@ -68,18 +71,22 @@ ol.style.RegularShape = function(opt_options) {
*/
this.points_ = options.points;
+ goog.asserts.assert(goog.isDef(options.radius) ||
+ goog.isDef(options.radius1));
+
/**
* @private
* @type {number}
*/
- this.radius_ = options.radius;
+ this.radius_ = /** @type {number} */ (goog.isDef(options.radius) ?
+ options.radius : options.radius1);
/**
* @private
* @type {number}
*/
this.radius2_ =
- goog.isDef(options.radius2) ? options.radius2 : options.radius;
+ goog.isDef(options.radius2) ? options.radius2 : this.radius_;
/**
* @private
@@ -222,6 +229,15 @@ ol.style.RegularShape.prototype.getRadius = function() {
};
+/**
+ * @return {number} Radius2.
+ * @api
+ */
+ol.style.RegularShape.prototype.getRadius2 = function() {
+ return this.radius2_;
+};
+
+
/**
* @inheritDoc
* @api
@@ -260,7 +276,7 @@ ol.style.RegularShape.prototype.unlistenImageChange = goog.nullFunction;
/**
* @typedef {{strokeStyle: (string|undefined), strokeWidth: number,
- * size: number}}
+ * size: number, lineDash: Array.}}
*/
ol.style.RegularShape.RenderOptions;
@@ -270,7 +286,10 @@ ol.style.RegularShape.RenderOptions;
* @param {ol.style.AtlasManager|undefined} atlasManager
*/
ol.style.RegularShape.prototype.render_ = function(atlasManager) {
- var strokeStyle, strokeWidth = 0, imageSize;
+ var imageSize;
+ var lineDash = null;
+ var strokeStyle;
+ var strokeWidth = 0;
if (!goog.isNull(this.stroke_)) {
strokeStyle = ol.color.asString(this.stroke_.getColor());
@@ -278,6 +297,10 @@ ol.style.RegularShape.prototype.render_ = function(atlasManager) {
if (!goog.isDef(strokeWidth)) {
strokeWidth = ol.render.canvas.defaultLineWidth;
}
+ lineDash = this.stroke_.getLineDash();
+ if (!ol.has.CANVAS_LINE_DASH) {
+ lineDash = null;
+ }
}
var size = 2 * (this.radius_ + strokeWidth) + 1;
@@ -286,7 +309,8 @@ ol.style.RegularShape.prototype.render_ = function(atlasManager) {
var renderOptions = {
strokeStyle: strokeStyle,
strokeWidth: strokeWidth,
- size: size
+ size: size,
+ lineDash: lineDash
};
if (!goog.isDef(atlasManager)) {
@@ -379,6 +403,9 @@ ol.style.RegularShape.prototype.draw_ = function(renderOptions, context, x, y) {
if (!goog.isNull(this.stroke_)) {
context.strokeStyle = renderOptions.strokeStyle;
context.lineWidth = renderOptions.strokeWidth;
+ if (!goog.isNull(renderOptions.lineDash)) {
+ context.setLineDash(renderOptions.lineDash);
+ }
context.stroke();
}
context.closePath();
@@ -444,6 +471,9 @@ ol.style.RegularShape.prototype.drawHitDetectionCanvas_ =
if (!goog.isNull(this.stroke_)) {
context.strokeStyle = renderOptions.strokeStyle;
context.lineWidth = renderOptions.strokeWidth;
+ if (!goog.isNull(renderOptions.lineDash)) {
+ context.setLineDash(renderOptions.lineDash);
+ }
context.stroke();
}
context.closePath();
diff --git a/src/ol/tilegrid/tilegrid.js b/src/ol/tilegrid/tilegrid.js
index d0b63a6975..e24e8e02b4 100644
--- a/src/ol/tilegrid/tilegrid.js
+++ b/src/ol/tilegrid/tilegrid.js
@@ -2,6 +2,7 @@ goog.provide('ol.tilegrid.TileGrid');
goog.require('goog.array');
goog.require('goog.asserts');
+goog.require('goog.functions');
goog.require('ol');
goog.require('ol.Coordinate');
goog.require('ol.TileCoord');
@@ -101,12 +102,16 @@ ol.tilegrid.TileGrid.tmpTileCoord_ = [0, 0, 0];
/**
+ * Returns the identity function. May be overridden in subclasses.
* @param {{extent: (ol.Extent|undefined),
* wrapX: (boolean|undefined)}=} opt_options Options.
* @return {function(ol.TileCoord, ol.proj.Projection, ol.TileCoord=):
* ol.TileCoord} Tile coordinate transform.
*/
-ol.tilegrid.TileGrid.prototype.createTileCoordTransform = goog.abstractMethod;
+ol.tilegrid.TileGrid.prototype.createTileCoordTransform =
+ function(opt_options) {
+ return goog.functions.identity;
+};
/**
@@ -300,6 +305,7 @@ ol.tilegrid.TileGrid.prototype.getTileCoordExtent =
* @param {number} resolution Resolution.
* @param {ol.TileCoord=} opt_tileCoord Destination ol.TileCoord object.
* @return {ol.TileCoord} Tile coordinate.
+ * @api
*/
ol.tilegrid.TileGrid.prototype.getTileCoordForCoordAndResolution = function(
coordinate, resolution, opt_tileCoord) {
@@ -346,6 +352,7 @@ ol.tilegrid.TileGrid.prototype.getTileCoordForXYAndResolution_ = function(
* @param {number} z Z.
* @param {ol.TileCoord=} opt_tileCoord Destination ol.TileCoord object.
* @return {ol.TileCoord} Tile coordinate.
+ * @api
*/
ol.tilegrid.TileGrid.prototype.getTileCoordForCoordAndZ =
function(coordinate, z, opt_tileCoord) {
diff --git a/test/spec/ol/format/wms/getfeatureinfo.xml b/test/spec/ol/format/wms/getfeatureinfo.xml
new file mode 100644
index 0000000000..f00c6c4f93
--- /dev/null
+++ b/test/spec/ol/format/wms/getfeatureinfo.xml
@@ -0,0 +1,45 @@
+
+
+
+ ADCP de coque 2001
+
+
+
+ -531138.686422,5386348.414671 -117252.819653,6144475.186022
+
+
+ 1071
+ 1020050
+ ITSAS II
+ http://www.ifremer.fr/sismerData/jsp/visualisationMetadata2.jsp?strPortail=ifremer&langue=FR&pageOrigine=CAM&cle1=FI352001020050
+ ITSASII_BB150_0_osite.nc
+ http://www.ifremer.fr/sismerData/jsp/visualisationMetadata3.jsp?strPortail=ifremer&langue=FR&pageOrigine=CS&cle1=71053_1&cle2=ADCP01
+
+
+
+
+ -531138.686422,5386348.414671 -117252.819653,6144475.186022
+
+
+ 22431
+ 1020050
+ ITSAS II
+ http://www.ifremer.fr/sismerData/jsp/visualisationMetadata2.jsp?strPortail=ifremer&langue=FR&pageOrigine=CAM&cle1=FI352001020050
+ ITSASII_BB150_figures.tar
+ http://www.ifremer.fr/sismerData/jsp/visualisationMetadata3.jsp?strPortail=ifremer&langue=FR&pageOrigine=CS&cle1=108842_2&cle2=ADCP01
+
+
+
+
+ -531138.686422,5386348.414671 -117252.819653,6144475.186022
+
+
+ 22432
+ 1020050
+ ITSAS II
+ http://www.ifremer.fr/sismerData/jsp/visualisationMetadata2.jsp?strPortail=ifremer&langue=FR&pageOrigine=CAM&cle1=FI352001020050
+ ITSASII_BB150_0_fhv12.nc
+ http://www.ifremer.fr/sismerData/jsp/visualisationMetadata3.jsp?strPortail=ifremer&langue=FR&pageOrigine=CS&cle1=108842_3&cle2=ADCP01
+
+
+
diff --git a/test/spec/ol/format/wmsgetfeatureinfoformat.test.js b/test/spec/ol/format/wmsgetfeatureinfoformat.test.js
new file mode 100644
index 0000000000..aff68e2dc0
--- /dev/null
+++ b/test/spec/ol/format/wmsgetfeatureinfoformat.test.js
@@ -0,0 +1,207 @@
+goog.provide('ol.test.format.WMSGetFeatureInfo');
+
+describe('ol.format.WMSGetFeatureInfo', function() {
+
+ describe('#readFormat', function() {
+
+ describe('read Features', function() {
+
+ var features;
+
+ before(function(done) {
+ proj4.defs('urn:x-ogc:def:crs:EPSG:4326', proj4.defs('EPSG:4326'));
+ afterLoadText('spec/ol/format/wms/getfeatureinfo.xml', function(data) {
+ try {
+ features = new ol.format.WMSGetFeatureInfo().readFeatures(data);
+ } catch (e) {
+ done(e);
+ }
+ done();
+ });
+ });
+
+ after(function() {
+ proj4.defs('urn:x-ogc:def:crs:EPSG:4326', undefined);
+ });
+
+ it('creates 3 features', function() {
+ expect(features).to.have.length(3);
+ });
+
+ it('creates a feature for 1071', function() {
+ var feature = features[0];
+ expect(feature.getId()).to.be(undefined);
+ expect(feature.get('FID')).to.equal('1071');
+ expect(feature.get('NO_CAMPAGNE')).to.equal('1020050');
+ });
+
+ it('read boundedBy but no geometry', function() {
+ var feature = features[0];
+ expect(feature.getGeometry()).to.be(undefined);
+ expect(feature.get('boundedBy')).to.eql(
+ [-531138.686422, 5386348.414671, -117252.819653, 6144475.186022]);
+ });
+
+ it('read empty response', function() {
+ // read empty response
+ var text = '' +
+ '' +
+ ' ' +
+ ' ' +
+ ' ';
+ var features = new ol.format.WMSGetFeatureInfo().readFeatures(text);
+ expect(features.length).to.be(0);
+ });
+
+ it('read empty attributes', function() {
+ text =
+ '' +
+ '' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' 107397.266000,460681.063000 116568.188000,480609.250000' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' bar ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ';
+ var features = new ol.format.WMSGetFeatureInfo().readFeatures(text);
+ expect(features.length).to.be(1);
+ expect(features[0].get('FOO')).to.be('bar');
+ // FIXME is that really wanted ?
+ expect(features[0].get('EMPTY')).to.be(undefined);
+ });
+
+ it('read features from multiple layers', function() {
+ text =
+ '' +
+ '' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' 129799.109000,467950.250000 133199.906000,468904.063000' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' 287 ' +
+ ' N403 ' +
+ ' #N403 ' +
+ ' 1 ' +
+ ' P ' +
+ ' 4091.25 ' +
+ ' <shape> ' +
+ ' <null> ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' 129936.000000,468362.000000 131686.000000,473119.000000' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' 1251 ' +
+ ' 1515 ' +
+ ' 00:00:00 01/01/1998 ' +
+ ' 1472 ' +
+ ' 1309 ' +
+ ' D ' +
+ ' 227 ' +
+ ' Vecht ' +
+ ' 2 ' +
+ ' Vecht ' +
+ ' 18.25 ' +
+ ' 23.995 ' +
+ ' 5745.09 ' +
+ ' <shape> ' +
+ ' <null> ' +
+ ' ' +
+ ' ' +
+ ' ';
+ var features = new ol.format.WMSGetFeatureInfo().readFeatures(text);
+ expect(features.length).to.be(2);
+ expect(features[0].get('OBJECTID')).to.be('287');
+ expect(features[1].get('OBJECTID')).to.be('1251');
+ });
+
+ it('read geoserver’s response', function() {
+ text =
+ '' +
+ '' +
+ ' ' +
+ ' ' +
+ ' ' +
+ '591943.9375,4925605 593045.625,4925845' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' 3 ' +
+ ' secondary highway, hard surface' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ '593045.60746465,4925605.0059156 593024.32382915,4925606.79305411' +
+ ' 592907.54863574,4925624.85647524 592687.35111096,' +
+ '4925670.76834012 592430.76279218,4925678.79393165' +
+ ' 592285.97636109,4925715.70811767 592173.39165655,' +
+ '4925761.83511156 592071.1753393,4925793.95523514' +
+ ' 591985.96972625,4925831.59842486' +
+ ' 591943.98769455,4925844.93220071' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ' +
+ ' ';
+ var features = new ol.format.WMSGetFeatureInfo().readFeatures(text);
+ expect(features.length).to.be(1);
+ expect(features[0].get('cat')).to.be('3');
+ expect(features[0].getGeometry().getType()).to.be('MultiLineString');
+ });
+
+ });
+ });
+});
+
+
+goog.require('goog.dom');
+goog.require('ol.format.WMSGetFeatureInfo');
diff --git a/test/spec/ol/layer/layergroup.test.js b/test/spec/ol/layer/layergroup.test.js
index b9c6918842..3430969c33 100644
--- a/test/spec/ol/layer/layergroup.test.js
+++ b/test/spec/ol/layer/layergroup.test.js
@@ -382,6 +382,12 @@ describe('ol.layer.Group', function() {
maxResolution: 500,
minResolution: 0.25
});
+ var layer3 = new ol.layer.Layer({
+ source: new ol.source.Source({
+ projection: 'EPSG:4326'
+ }),
+ extent: [-5, -2, 5, 2]
+ });
it('does not transform layerStates by default', function() {
var layerGroup = new ol.layer.Group({
@@ -405,6 +411,29 @@ describe('ol.layer.Group', function() {
goog.dispose(layerGroup);
});
+ it('uses the layer group extent if layer has no extent', function() {
+ var groupExtent = [-10, -5, 10, 5];
+ var layerGroup = new ol.layer.Group({
+ extent: groupExtent,
+ layers: [layer1]
+ });
+ var layerStatesArray = layerGroup.getLayerStatesArray();
+ expect(layerStatesArray[0].extent).to.eql(groupExtent);
+ goog.dispose(layerGroup);
+ });
+
+ it('uses the intersection of group and child extent', function() {
+ var groupExtent = [-10, -5, 10, 5];
+ var layerGroup = new ol.layer.Group({
+ extent: groupExtent,
+ layers: [layer3]
+ });
+ var layerStatesArray = layerGroup.getLayerStatesArray();
+ expect(layerStatesArray[0].extent).to.eql(
+ ol.extent.getIntersection(layer3.getExtent(), groupExtent));
+ goog.dispose(layerGroup);
+ });
+
it('transforms layerStates correctly', function() {
var layerGroup = new ol.layer.Group({
layers: [layer1, layer2],
@@ -451,6 +480,7 @@ describe('ol.layer.Group', function() {
goog.dispose(layer1);
goog.dispose(layer2);
+ goog.dispose(layer3);
});
@@ -460,6 +490,7 @@ goog.require('goog.dispose');
goog.require('goog.events.EventType');
goog.require('goog.object');
goog.require('ol.ObjectEventType');
+goog.require('ol.extent');
goog.require('ol.layer.Layer');
goog.require('ol.layer.Group');
goog.require('ol.source.Source');
diff --git a/test/spec/ol/style/regularshapestyle.test.js b/test/spec/ol/style/regularshapestyle.test.js
index 1d8290b61d..f972ae7fc6 100644
--- a/test/spec/ol/style/regularshapestyle.test.js
+++ b/test/spec/ol/style/regularshapestyle.test.js
@@ -1,10 +1,43 @@
goog.provide('ol.test.style.RegularShape');
-
describe('ol.style.RegularShape', function() {
describe('#constructor', function() {
+ it('can use radius', function() {
+ var style = new ol.style.RegularShape({
+ radius: 5,
+ radius2: 10
+ });
+ expect(style.getRadius()).to.eql(5);
+ expect(style.getRadius2()).to.eql(10);
+ });
+
+ it('can use radius1 as an alias for radius', function() {
+ var style = new ol.style.RegularShape({
+ radius1: 5,
+ radius2: 10
+ });
+ expect(style.getRadius()).to.eql(5);
+ expect(style.getRadius2()).to.eql(10);
+ });
+
+ it('will use radius for radius2 if radius2 not defined', function() {
+ var style = new ol.style.RegularShape({
+ radius: 5
+ });
+ expect(style.getRadius()).to.eql(5);
+ expect(style.getRadius2()).to.eql(5);
+ });
+
+ it('will use radius1 for radius2 if radius2 not defined', function() {
+ var style = new ol.style.RegularShape({
+ radius1: 5
+ });
+ expect(style.getRadius()).to.eql(5);
+ expect(style.getRadius2()).to.eql(5);
+ });
+
it('creates a canvas if no atlas is used (no fill-style)', function() {
var style = new ol.style.RegularShape({radius: 10});
expect(style.getImage()).to.be.an(HTMLCanvasElement);
@@ -79,18 +112,26 @@ describe('ol.style.RegularShape', function() {
describe('#getChecksum', function() {
- it('calculates the same hash code for default options', function() {
- var style1 = new ol.style.RegularShape();
- var style2 = new ol.style.RegularShape();
- expect(style1.getChecksum()).to.eql(style2.getChecksum());
- });
-
it('calculates not the same hash code (radius)', function() {
var style1 = new ol.style.RegularShape({
+ radius: 4,
radius2: 5
});
var style2 = new ol.style.RegularShape({
- radius: 5
+ radius: 3,
+ radius2: 5
+ });
+ expect(style1.getChecksum()).to.not.eql(style2.getChecksum());
+ });
+
+ it('calculates not the same hash code (radius2)', function() {
+ var style1 = new ol.style.RegularShape({
+ radius: 4,
+ radius2: 5
+ });
+ var style2 = new ol.style.RegularShape({
+ radius: 4,
+ radius2: 6
});
expect(style1.getChecksum()).to.not.eql(style2.getChecksum());
});