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. +

+

+

+ + + + + +
+

+

+ 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.

+
+

See the regularshape.js source to see how this is done.

+
+
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()); });