From 08c6e601b8143cc3b5441f0538a0b7f62c8b3f53 Mon Sep 17 00:00:00 2001 From: kalinbas Date: Thu, 30 Oct 2014 13:23:09 +0100 Subject: [PATCH 01/47] Update wmtssource.js - "duplicated" style parameter is not supported by Intergraph GeoMedia - Uppercase Parameter is needed by ARCGis - are there other constraints? --- src/ol/source/wmtssource.js | 1 - 1 file changed, 1 deletion(-) 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 }; From d4bd5f24c6e9900608af5bf60e66cfb1bd52c647 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Thu, 30 Oct 2014 12:44:47 +0100 Subject: [PATCH 02/47] Move font-family customization to layout.css --- css/ol.css | 7 ------- resources/layout.css | 4 ++++ 2 files changed, 4 insertions(+), 7 deletions(-) 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/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; } From 759386e37e419c1302b89f908949eb5336273246 Mon Sep 17 00:00:00 2001 From: Florent gravin Date: Fri, 3 Oct 2014 16:17:09 +0200 Subject: [PATCH 03/47] Add WMS GetFeatureInfo reader format --- src/ol/format/getfeatureinfoformat.js | 122 ++++++++++++++++++++++++++ src/ol/format/gml/gmlbase.js | 7 +- 2 files changed, 125 insertions(+), 4 deletions(-) create mode 100644 src/ol/format/getfeatureinfoformat.js diff --git a/src/ol/format/getfeatureinfoformat.js b/src/ol/format/getfeatureinfoformat.js new file mode 100644 index 0000000000..709fe891c9 --- /dev/null +++ b/src/ol/format/getfeatureinfoformat.js @@ -0,0 +1,122 @@ +goog.provide('ol.format.GetFeatureInfo'); + +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.GMLBase'); +goog.require('ol.format.XMLFeature'); +goog.require('ol.xml'); + + + +/** + * @classdesc + * Format for reading MapServer GetFeatureInfo format.It uses + * ol.format.GML2 to read features. + * + * @constructor + * @param {olx.format.GMLOptions=} opt_options + * Optional configuration object. + * @extends {ol.format.XMLFeature} + * @api + */ +ol.format.GetFeatureInfo = function(opt_options) { + + /** + * @private + * @type {string} + */ + this.featureNS_ = 'http://mapserver.gis.umn.edu/mapserver'; + + + /** + * @private + * @type {string} + */ + this.featureIdentifier_ = '_feature'; + + + /** + * @private + * @type {string} + */ + this.layerIdentifier_ = '_layer'; + + + /** + * @private + * @type {ol.format.GMLBase} + */ + this.gmlFormat_ = new ol.format.GML2(); + + goog.base(this); +}; +goog.inherits(ol.format.GetFeatureInfo, ol.format.XMLFeature); + + +/** + * @const + * @type {string} + * @private + */ +ol.format.GetFeatureInfo.schemaLocation_ = ''; + + +/** + * @param {Node} node Node. + * @param {Array.<*>} objectStack Object stack. + * @return {Array.} Features. + * @private + */ +ol.format.GetFeatureInfo.prototype.readFeatures_ = function(node, objectStack) { + + node.namespaceURI = this.featureNS_; + goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); + var localName = ol.xml.getLocalName(node); + var features; + if (localName == 'msGMLOutput') { + var context = objectStack[0]; + goog.asserts.assert(goog.isObject(context)); + + var layer = node.firstElementChild; + goog.asserts.assert(layer.localName.indexOf(this.layerIdentifier_) >= 0); + + var featureType = goog.string.remove(layer.localName, + this.layerIdentifier_) + this.featureIdentifier_; + + goog.object.set(context, 'featureType', featureType); + goog.object.set(context, 'featureNS', this.featureNS_); + + var parsers = {}; + var parsersNS = {}; + parsers[featureType] = ol.xml.makeArrayPusher( + this.gmlFormat_.readFeatureElement, this.gmlFormat_); + parsersNS[goog.object.get(context, 'featureNS')] = parsers; + features = ol.xml.pushParseAndPop([], parsersNS, layer, objectStack, + this.gmlFormat_); + } + if (!goog.isDef(features)) { + features = []; + } + return features; +}; + + +/** + * @inheritDoc + */ +ol.format.GetFeatureInfo.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/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'); From d0d6215550953c8894e7e3321cb26db865b1c56f Mon Sep 17 00:00:00 2001 From: Florent gravin Date: Fri, 3 Oct 2014 16:20:33 +0200 Subject: [PATCH 04/47] Add tests suite for GetFeatureInfo format --- .../ol/format/getfeatureinfoformat.test.js | 46 +++++++++++++++++++ test/spec/ol/format/wms/getfeatureinfo.xml | 45 ++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 test/spec/ol/format/getfeatureinfoformat.test.js create mode 100644 test/spec/ol/format/wms/getfeatureinfo.xml diff --git a/test/spec/ol/format/getfeatureinfoformat.test.js b/test/spec/ol/format/getfeatureinfoformat.test.js new file mode 100644 index 0000000000..647df35c2d --- /dev/null +++ b/test/spec/ol/format/getfeatureinfoformat.test.js @@ -0,0 +1,46 @@ +goog.provide('ol.test.format.GetFeatureInfo'); + +describe('ol.format.GetFeatureInfo', 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.GetFeatureInfo().readFeatures(data); + } catch (e) { + done(e); + } + done(); + }); + }); + + 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]); + }); + }); + }); +}); + + +goog.require('goog.dom'); +goog.require('ol.format.GetFeatureInfo'); diff --git a/test/spec/ol/format/wms/getfeatureinfo.xml b/test/spec/ol/format/wms/getfeatureinfo.xml new file mode 100644 index 0000000000..f431b15ad3 --- /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 + + + \ No newline at end of file From c0f2187310bec332a87b950aa938833b40b9085f Mon Sep 17 00:00:00 2001 From: Antoine Abt Date: Fri, 10 Oct 2014 13:19:03 +0200 Subject: [PATCH 05/47] Make GetFeatureInfo format pass ol2 test suite --- src/ol/format/getfeatureinfoformat.js | 51 ++++-- .../ol/format/getfeatureinfoformat.test.js | 157 ++++++++++++++++++ test/spec/ol/format/wms/getfeatureinfo.xml | 4 +- 3 files changed, 193 insertions(+), 19 deletions(-) diff --git a/src/ol/format/getfeatureinfoformat.js b/src/ol/format/getfeatureinfoformat.js index 709fe891c9..d8a726cf94 100644 --- a/src/ol/format/getfeatureinfoformat.js +++ b/src/ol/format/getfeatureinfoformat.js @@ -1,5 +1,6 @@ goog.provide('ol.format.GetFeatureInfo'); +goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.dom'); goog.require('goog.dom.NodeType'); @@ -15,7 +16,7 @@ goog.require('ol.xml'); /** * @classdesc - * Format for reading MapServer GetFeatureInfo format.It uses + * Format for reading GetFeatureInfo format.It uses * ol.format.GML2 to read features. * * @constructor @@ -77,27 +78,43 @@ ol.format.GetFeatureInfo.prototype.readFeatures_ = function(node, objectStack) { node.namespaceURI = this.featureNS_; goog.asserts.assert(node.nodeType == goog.dom.NodeType.ELEMENT); var localName = ol.xml.getLocalName(node); - var features; + var features = []; + if (node.childNodes.length === 0) { + return features; + } if (localName == 'msGMLOutput') { - var context = objectStack[0]; - goog.asserts.assert(goog.isObject(context)); + 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)); - var layer = node.firstElementChild; - goog.asserts.assert(layer.localName.indexOf(this.layerIdentifier_) >= 0); + goog.asserts.assert(layer.localName.indexOf(this.layerIdentifier_) >= 0); - var featureType = goog.string.remove(layer.localName, - this.layerIdentifier_) + this.featureIdentifier_; + var featureType = goog.string.remove(layer.localName, + this.layerIdentifier_) + this.featureIdentifier_; - goog.object.set(context, 'featureType', featureType); - goog.object.set(context, 'featureNS', this.featureNS_); + goog.object.set(context, 'featureType', featureType); + goog.object.set(context, 'featureNS', this.featureNS_); - var parsers = {}; - var parsersNS = {}; - parsers[featureType] = ol.xml.makeArrayPusher( - this.gmlFormat_.readFeatureElement, this.gmlFormat_); - parsersNS[goog.object.get(context, 'featureNS')] = parsers; - features = ol.xml.pushParseAndPop([], parsersNS, layer, objectStack, - this.gmlFormat_); + 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(/** @type {Array} */ (features), layerFeatures); + } + }, this); + } + if (localName == 'FeatureCollection') { + features = ol.xml.pushParseAndPop([], + this.gmlFormat_.FEATURE_COLLECTION_PARSERS, node, + [{}], this.gmlFormat_); } if (!goog.isDef(features)) { features = []; diff --git a/test/spec/ol/format/getfeatureinfoformat.test.js b/test/spec/ol/format/getfeatureinfoformat.test.js index 647df35c2d..1b9acd2333 100644 --- a/test/spec/ol/format/getfeatureinfoformat.test.js +++ b/test/spec/ol/format/getfeatureinfoformat.test.js @@ -37,6 +37,163 @@ describe('ol.format.GetFeatureInfo', function() { 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.GetFeatureInfo().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.GetFeatureInfo().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.GetFeatureInfo().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.GetFeatureInfo().readFeatures(text); + expect(features.length).to.be(1); + expect(features[0].get('cat')).to.be('3'); + expect(features[0].getGeometry().getType()).to.be('MultiLineString'); + }); + }); }); }); diff --git a/test/spec/ol/format/wms/getfeatureinfo.xml b/test/spec/ol/format/wms/getfeatureinfo.xml index f431b15ad3..f00c6c4f93 100644 --- a/test/spec/ol/format/wms/getfeatureinfo.xml +++ b/test/spec/ol/format/wms/getfeatureinfo.xml @@ -1,5 +1,5 @@ - + ADCP de coque 2001 @@ -42,4 +42,4 @@ http://www.ifremer.fr/sismerData/jsp/visualisationMetadata3.jsp?strPortail=ifremer&langue=FR&pageOrigine=CS&cle1=108842_3&cle2=ADCP01 - \ No newline at end of file + From 0f99f113e3700f0126a2a41a0f23f19ff5c58032 Mon Sep 17 00:00:00 2001 From: Florent gravin Date: Tue, 4 Nov 2014 09:39:19 +0100 Subject: [PATCH 06/47] Change format name to WMSGetFeatureInfo --- .../{getfeatureinfoformat.js => wmsgetfeatureinfoformat.js} | 2 +- ...reinfoformat.test.js => wmsgetfeatureinfoformat.test.js} | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/ol/format/{getfeatureinfoformat.js => wmsgetfeatureinfoformat.js} (98%) rename test/spec/ol/format/{getfeatureinfoformat.test.js => wmsgetfeatureinfoformat.test.js} (98%) diff --git a/src/ol/format/getfeatureinfoformat.js b/src/ol/format/wmsgetfeatureinfoformat.js similarity index 98% rename from src/ol/format/getfeatureinfoformat.js rename to src/ol/format/wmsgetfeatureinfoformat.js index d8a726cf94..916ae7790c 100644 --- a/src/ol/format/getfeatureinfoformat.js +++ b/src/ol/format/wmsgetfeatureinfoformat.js @@ -1,4 +1,4 @@ -goog.provide('ol.format.GetFeatureInfo'); +goog.provide('ol.format.WMSGetFeatureInfo'); goog.require('goog.array'); goog.require('goog.asserts'); diff --git a/test/spec/ol/format/getfeatureinfoformat.test.js b/test/spec/ol/format/wmsgetfeatureinfoformat.test.js similarity index 98% rename from test/spec/ol/format/getfeatureinfoformat.test.js rename to test/spec/ol/format/wmsgetfeatureinfoformat.test.js index 1b9acd2333..d402d37161 100644 --- a/test/spec/ol/format/getfeatureinfoformat.test.js +++ b/test/spec/ol/format/wmsgetfeatureinfoformat.test.js @@ -1,6 +1,6 @@ -goog.provide('ol.test.format.GetFeatureInfo'); +goog.provide('ol.test.format.WMSGetFeatureInfo'); -describe('ol.format.GetFeatureInfo', function() { +describe('ol.format.WMSGetFeatureInfo', function() { describe('#readFormat', function() { @@ -200,4 +200,4 @@ describe('ol.format.GetFeatureInfo', function() { goog.require('goog.dom'); -goog.require('ol.format.GetFeatureInfo'); +goog.require('ol.format.WMSGetFeatureInfo'); From 344658edb0c4b226bb52dfaae145d7fe4844ace0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Mon, 10 Nov 2014 17:24:29 +0100 Subject: [PATCH 07/47] Fix compile warning --- externs/oli.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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) {}; /** From 89248cf60a5c1855bb40ece835e8d92449b8622b Mon Sep 17 00:00:00 2001 From: paulsimon Date: Mon, 10 Nov 2014 20:49:20 +0100 Subject: [PATCH 08/47] Fix jsdoc comment --- src/ol/format/wktformat.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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() { From 08aa6ee82d2c263688261e1dc5a6a073c89394d6 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Tue, 11 Nov 2014 12:35:19 +0100 Subject: [PATCH 09/47] Do not rely on unstable index --- src/ol/interaction/selectinteraction.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ol/interaction/selectinteraction.js b/src/ol/interaction/selectinteraction.js index 5c4067e3db..3f690e2189 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, /** @@ -175,7 +175,7 @@ ol.interaction.Select.prototype.handleMapBrowserEvent = }, undefined, this.layerFilter_); var i; for (i = deselected.length - 1; i >= 0; --i) { - features.removeAt(deselected[i]); + features.remove(deselected[i]); } features.extend(selected); } From 50c0bc6879d38f2a6da0057b919069d6ad3bfb12 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Tue, 11 Nov 2014 08:54:10 -0800 Subject: [PATCH 10/47] Clip rendering to layer extent --- src/ol/renderer/canvas/canvaslayerrenderer.js | 35 +++++++++++++++ .../canvas/canvastilelayerrenderer.js | 43 ------------------- 2 files changed, 35 insertions(+), 43 deletions(-) diff --git a/src/ol/renderer/canvas/canvaslayerrenderer.js b/src/ol/renderer/canvas/canvaslayerrenderer.js index 65fa90866e..25538ddf56 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); - } } } } From 36856261872216ca39c9bbc922e60691ec295c2d Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Tue, 11 Nov 2014 09:00:20 -0800 Subject: [PATCH 11/47] Example demonstrating limited layer extent --- examples/layer-extent.html | 68 ++++++++++++++++++++++++++++++++++++++ examples/layer-extent.js | 50 ++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 examples/layer-extent.html create mode 100644 examples/layer-extent.js 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]); + }; +} From 96729baa9f3684075835cbbb8ebc17eaf32fa1e2 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Tue, 11 Nov 2014 20:09:24 +0100 Subject: [PATCH 12/47] Push the feature, not the index --- src/ol/interaction/selectinteraction.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ol/interaction/selectinteraction.js b/src/ol/interaction/selectinteraction.js index 3f690e2189..1a32311390 100644 --- a/src/ol/interaction/selectinteraction.js +++ b/src/ol/interaction/selectinteraction.js @@ -169,7 +169,7 @@ ol.interaction.Select.prototype.handleMapBrowserEvent = } } else { if (remove || toggle) { - deselected.push(index); + deselected.push(feature); } } }, undefined, this.layerFilter_); From b2691612764c6eec4ba4173fd5bcf5c9f921862c Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Tue, 11 Nov 2014 19:01:05 -0800 Subject: [PATCH 13/47] A bit more static image doc --- externs/olx.js | 15 ++++++++++----- src/ol/source/imagestaticsource.js | 3 +-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/externs/olx.js b/externs/olx.js index ff38c14653..8b2dff1f5e 100644 --- a/externs/olx.js +++ b/externs/olx.js @@ -4573,7 +4573,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 +4585,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 +4594,7 @@ olx.source.ImageStaticOptions.prototype.imageExtent; /** - * Size of the image. + * Size of the image in pixels. * @type {ol.Size|undefined} * @api stable */ @@ -4605,7 +4610,7 @@ olx.source.ImageStaticOptions.prototype.imageLoadFunction; /** - * Logo. + * Optional logo. * @type {string|olx.LogoOptions|undefined} * @api stable */ @@ -4621,7 +4626,7 @@ olx.source.ImageStaticOptions.prototype.projection; /** - * Url. + * Image URL. * @type {string} * @api stable */ 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} From b991895c61dcc1cd7fb6f33c3f78405aa7c9b670 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Tue, 11 Nov 2014 19:04:25 -0800 Subject: [PATCH 14/47] Similar detail for all crossOrigin options --- externs/olx.js | 56 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 9 deletions(-) diff --git a/externs/olx.js b/externs/olx.js index 8b2dff1f5e..ea8c57a169 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 */ @@ -4705,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 */ @@ -4774,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 */ @@ -5066,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 */ @@ -5234,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 */ @@ -5354,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 */ @@ -5522,7 +5556,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 */ From 39010238b9c6d4ceec80740e8df8ce92b4e86c07 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Tue, 11 Nov 2014 20:06:26 -0800 Subject: [PATCH 15/47] Make stability checkbox sticky --- config/jsdoc/api/template/static/scripts/main.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/config/jsdoc/api/template/static/scripts/main.js b/config/jsdoc/api/template/static/scripts/main.js index 9a368453c6..637f6d7e65 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); }); From c701ad6749ffb8f9d232d28ba4e7cd8f2de9121c Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Thu, 13 Nov 2014 10:46:06 +0100 Subject: [PATCH 16/47] Mark applyTransform api stable --- src/ol/geom/geometrycollection.js | 1 + src/ol/geom/simplegeometry.js | 1 + 2 files changed, 2 insertions(+) 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)) { From 2b2f74524862b6d5e2c1deb760289bdab6ed6921 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Fri, 14 Nov 2014 00:16:28 +0100 Subject: [PATCH 17/47] Add ol.ext to hosted dir --- build.py | 3 +++ 1 file changed, 3 insertions(+) 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', From 552f9483cb28ac088701facb338b265a91545376 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Mon, 17 Nov 2014 10:10:04 +0100 Subject: [PATCH 18/47] Revert "Remove mousewheel event name workaround" This reverts commit 20ce6640688ade1398f15f1ebca299859d497c8b. Reverted upstream: https://github.com/google/closure-library/commit/4ee0daca0ec1bea486ab670310a6e9bdbaaad720 --- src/ol/map.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ol/map.js b/src/ol/map.js index 95e4acfca4..f7621f3ca8 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_); From 4714c9b3806b95d11ea92bbf87889e8cc83ce5c3 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Tue, 18 Nov 2014 16:37:18 +0100 Subject: [PATCH 19/47] Fix typo in selector --- config/jsdoc/api/template/static/scripts/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/jsdoc/api/template/static/scripts/main.js b/config/jsdoc/api/template/static/scripts/main.js index 637f6d7e65..d57e4b9395 100644 --- a/config/jsdoc/api/template/static/scripts/main.js +++ b/config/jsdoc/api/template/static/scripts/main.js @@ -54,7 +54,7 @@ $(function () { _onResize(); // show/hide unstable items - var links = $('a[href^="ol."'); + var links = $('a[href^="ol."]'); var unstable = $('.unstable'); var stabilityToggle = $('#stability-toggle'); stabilityToggle.change(function() { From 3db26f1d2b2b3f0035ee4c262f5f5e64d1c035cb Mon Sep 17 00:00:00 2001 From: Bart van den Eijnden Date: Tue, 18 Nov 2014 19:55:23 +0100 Subject: [PATCH 20/47] Use the layergroup's extent if no extent provided --- src/ol/layer/layergroup.js | 10 ++++++--- test/spec/ol/layer/layergroup.test.js | 31 +++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) 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/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'); From 374f02c725afafacf25fa3d2f38e53d643d9fc78 Mon Sep 17 00:00:00 2001 From: Antoine Abt Date: Fri, 21 Nov 2014 11:23:06 +0100 Subject: [PATCH 21/47] Fix pan with select interaction in mousemove mode. --- src/ol/interaction/selectinteraction.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ol/interaction/selectinteraction.js b/src/ol/interaction/selectinteraction.js index 1a32311390..86f322f1ef 100644 --- a/src/ol/interaction/selectinteraction.js +++ b/src/ol/interaction/selectinteraction.js @@ -179,7 +179,7 @@ ol.interaction.Select.prototype.handleMapBrowserEvent = } features.extend(selected); } - return false; + return this.condition_ == ol.events.condition.mouseMove; }; From 8ba830f91fa2a191e58bc782b575a337209f18ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Mon, 24 Nov 2014 14:42:21 +0100 Subject: [PATCH 22/47] Make loadFeaturesFromUrl accept an error callback --- src/ol/source/formatvectorsource.js | 12 +++++++----- src/ol/source/staticvectorsource.js | 16 +++++++++++++--- src/ol/source/tilevectorsource.js | 21 +++++++++++---------- 3 files changed, 31 insertions(+), 18 deletions(-) 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/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..b0da2796aa 100644 --- a/src/ol/source/tilevectorsource.js +++ b/src/ol/source/tilevectorsource.js @@ -184,6 +184,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 +204,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); } } } From ec01aa45b948c063271c57d0e811141c3272d669 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Mon, 24 Nov 2014 14:55:49 +0100 Subject: [PATCH 23/47] Make createTileCoordTransform return identity func This makes ol.tilegrid.TileGrid#createTileCoordTransform return the identity function. This makes it possible to use ol.source.TileVector with an ol.tilegrid.TileGrid (as opposed to an ol.tilegrid.XYZ). --- src/ol/tilegrid/tilegrid.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ol/tilegrid/tilegrid.js b/src/ol/tilegrid/tilegrid.js index d0b63a6975..a91a78fc02 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; +}; /** From fc16c4500d070c901c762a7ee4dbc16cb0748616 Mon Sep 17 00:00:00 2001 From: Antoine Abt Date: Tue, 25 Nov 2014 16:24:32 +0100 Subject: [PATCH 24/47] Renaming & better typing --- src/ol/format/wmsgetfeatureinfoformat.js | 59 +++++++++---------- .../ol/format/wmsgetfeatureinfoformat.test.js | 10 ++-- 2 files changed, 32 insertions(+), 37 deletions(-) diff --git a/src/ol/format/wmsgetfeatureinfoformat.js b/src/ol/format/wmsgetfeatureinfoformat.js index 916ae7790c..6f3178339f 100644 --- a/src/ol/format/wmsgetfeatureinfoformat.js +++ b/src/ol/format/wmsgetfeatureinfoformat.js @@ -8,7 +8,6 @@ goog.require('goog.object'); goog.require('goog.string'); goog.require('ol.format.GML'); goog.require('ol.format.GML2'); -goog.require('ol.format.GMLBase'); goog.require('ol.format.XMLFeature'); goog.require('ol.xml'); @@ -16,16 +15,14 @@ goog.require('ol.xml'); /** * @classdesc - * Format for reading GetFeatureInfo format.It uses - * ol.format.GML2 to read features. + * Format for reading WMSGetFeatureInfo format. It uses + * {@link ol.format.GML2} to read features. * * @constructor - * @param {olx.format.GMLOptions=} opt_options - * Optional configuration object. * @extends {ol.format.XMLFeature} * @api */ -ol.format.GetFeatureInfo = function(opt_options) { +ol.format.WMSGetFeatureInfo = function() { /** * @private @@ -36,27 +33,13 @@ ol.format.GetFeatureInfo = function(opt_options) { /** * @private - * @type {string} - */ - this.featureIdentifier_ = '_feature'; - - - /** - * @private - * @type {string} - */ - this.layerIdentifier_ = '_layer'; - - - /** - * @private - * @type {ol.format.GMLBase} + * @type {ol.format.GML2} */ this.gmlFormat_ = new ol.format.GML2(); goog.base(this); }; -goog.inherits(ol.format.GetFeatureInfo, ol.format.XMLFeature); +goog.inherits(ol.format.WMSGetFeatureInfo, ol.format.XMLFeature); /** @@ -64,7 +47,15 @@ goog.inherits(ol.format.GetFeatureInfo, ol.format.XMLFeature); * @type {string} * @private */ -ol.format.GetFeatureInfo.schemaLocation_ = ''; +ol.format.WMSGetFeatureInfo.featureIdentifier_ = '_feature'; + + +/** + * @const + * @type {string} + * @private + */ +ol.format.WMSGetFeatureInfo.layerIdentifier_ = '_layer'; /** @@ -73,11 +64,13 @@ ol.format.GetFeatureInfo.schemaLocation_ = ''; * @return {Array.} Features. * @private */ -ol.format.GetFeatureInfo.prototype.readFeatures_ = function(node, objectStack) { +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; @@ -90,10 +83,12 @@ ol.format.GetFeatureInfo.prototype.readFeatures_ = function(node, objectStack) { var context = objectStack[0]; goog.asserts.assert(goog.isObject(context)); - goog.asserts.assert(layer.localName.indexOf(this.layerIdentifier_) >= 0); + goog.asserts.assert(layer.localName.indexOf( + ol.format.WMSGetFeatureInfo.layerIdentifier_) >= 0); var featureType = goog.string.remove(layer.localName, - this.layerIdentifier_) + this.featureIdentifier_; + ol.format.WMSGetFeatureInfo.layerIdentifier_) + + ol.format.WMSGetFeatureInfo.featureIdentifier_; goog.object.set(context, 'featureType', featureType); goog.object.set(context, 'featureNS', this.featureNS_); @@ -107,17 +102,17 @@ ol.format.GetFeatureInfo.prototype.readFeatures_ = function(node, objectStack) { var layerFeatures = ol.xml.pushParseAndPop( [], parsersNS, layer, objectStack, this.gmlFormat_); if (goog.isDef(layerFeatures)) { - goog.array.extend(/** @type {Array} */ (features), layerFeatures); + goog.array.extend(features, layerFeatures); } }, this); } if (localName == 'FeatureCollection') { - features = ol.xml.pushParseAndPop([], + var gmlFeatures = ol.xml.pushParseAndPop([], this.gmlFormat_.FEATURE_COLLECTION_PARSERS, node, [{}], this.gmlFormat_); - } - if (!goog.isDef(features)) { - features = []; + if (goog.isDef(gmlFeatures)) { + features = gmlFeatures; + } } return features; }; @@ -126,7 +121,7 @@ ol.format.GetFeatureInfo.prototype.readFeatures_ = function(node, objectStack) { /** * @inheritDoc */ -ol.format.GetFeatureInfo.prototype.readFeaturesFromNode = +ol.format.WMSGetFeatureInfo.prototype.readFeaturesFromNode = function(node, opt_options) { var options = { 'featureType': this.featureType, diff --git a/test/spec/ol/format/wmsgetfeatureinfoformat.test.js b/test/spec/ol/format/wmsgetfeatureinfoformat.test.js index d402d37161..f4ec041a59 100644 --- a/test/spec/ol/format/wmsgetfeatureinfoformat.test.js +++ b/test/spec/ol/format/wmsgetfeatureinfoformat.test.js @@ -12,7 +12,7 @@ describe('ol.format.WMSGetFeatureInfo', function() { 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.GetFeatureInfo().readFeatures(data); + features = new ol.format.WMSGetFeatureInfo().readFeatures(data); } catch (e) { done(e); } @@ -47,7 +47,7 @@ describe('ol.format.WMSGetFeatureInfo', function() { ' ' + ' ' + ''; - var features = new ol.format.GetFeatureInfo().readFeatures(text); + var features = new ol.format.WMSGetFeatureInfo().readFeatures(text); expect(features.length).to.be(0); }); @@ -72,7 +72,7 @@ describe('ol.format.WMSGetFeatureInfo', function() { ' ' + ' ' + ''; - var features = new ol.format.GetFeatureInfo().readFeatures(text); + 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 ? @@ -132,7 +132,7 @@ describe('ol.format.WMSGetFeatureInfo', function() { ' ' + ' ' + ''; - var features = new ol.format.GetFeatureInfo().readFeatures(text); + 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'); @@ -188,7 +188,7 @@ describe('ol.format.WMSGetFeatureInfo', function() { ' ' + ' ' + ''; - var features = new ol.format.GetFeatureInfo().readFeatures(text); + 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'); From 638f8275aac89952bdc396937c92f50dfd8f81aa Mon Sep 17 00:00:00 2001 From: Antoine Abt Date: Tue, 25 Nov 2014 16:24:51 +0100 Subject: [PATCH 25/47] Export readFeatures method --- src/ol/format/wmsgetfeatureinfoformat.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/ol/format/wmsgetfeatureinfoformat.js b/src/ol/format/wmsgetfeatureinfoformat.js index 6f3178339f..0d928189e4 100644 --- a/src/ol/format/wmsgetfeatureinfoformat.js +++ b/src/ol/format/wmsgetfeatureinfoformat.js @@ -118,6 +118,18 @@ ol.format.WMSGetFeatureInfo.prototype.readFeatures_ = }; +/** + * 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 */ From 22491601ba12d403ccba5944cd9c707b53b945ae Mon Sep 17 00:00:00 2001 From: Antoine Abt Date: Tue, 25 Nov 2014 17:38:06 +0100 Subject: [PATCH 26/47] Restore proj4 state after tests --- test/spec/ol/format/wmsgetfeatureinfoformat.test.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/spec/ol/format/wmsgetfeatureinfoformat.test.js b/test/spec/ol/format/wmsgetfeatureinfoformat.test.js index f4ec041a59..aff68e2dc0 100644 --- a/test/spec/ol/format/wmsgetfeatureinfoformat.test.js +++ b/test/spec/ol/format/wmsgetfeatureinfoformat.test.js @@ -20,6 +20,10 @@ describe('ol.format.WMSGetFeatureInfo', function() { }); }); + after(function() { + proj4.defs('urn:x-ogc:def:crs:EPSG:4326', undefined); + }); + it('creates 3 features', function() { expect(features).to.have.length(3); }); From b72fddf7f47ce9daefb8b9893dc142bb919b823a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poul=20Kjeldager=20S=C3=B8rensen?= Date: Wed, 26 Nov 2014 01:24:00 +0100 Subject: [PATCH 27/47] Making GetTileCoordFor methods public avaible I am using tilegrid to request elevation data tiles side by side of a raster layer. It would be nice if these two method was public avaible such I could use the tilegrid to convert mouse coordinates to tile coordinates to request backend tiles. The elevation tiles are not shown as a layer directly but rather used to compute and show information in relationship to mouse curser or map view. This would save me the time of adding another tilegrid implementation in my application specific context. --- src/ol/tilegrid/tilegrid.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ol/tilegrid/tilegrid.js b/src/ol/tilegrid/tilegrid.js index d0b63a6975..65f08193ce 100644 --- a/src/ol/tilegrid/tilegrid.js +++ b/src/ol/tilegrid/tilegrid.js @@ -300,6 +300,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 stable */ ol.tilegrid.TileGrid.prototype.getTileCoordForCoordAndResolution = function( coordinate, resolution, opt_tileCoord) { @@ -346,6 +347,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 stable */ ol.tilegrid.TileGrid.prototype.getTileCoordForCoordAndZ = function(coordinate, z, opt_tileCoord) { From 5155e7a6ac0571a482757bbcb6a0810054246f3b Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Thu, 27 Nov 2014 19:13:02 +0100 Subject: [PATCH 28/47] Fix zoom levels for the MapQuest Street layer A typo in 65b8e0f91576e521606d906ecdfa9dffd2159dcb introduced this bug. Before that, 18 zoom levels were used. Now we're using 19, which appears to be available with full world coverage. --- src/ol/source/mapquestsource.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 890b96f1e97f98a8c07d4885e96053c9970f4e08 Mon Sep 17 00:00:00 2001 From: Bart van den Eijnden Date: Thu, 27 Nov 2014 20:01:53 +0100 Subject: [PATCH 29/47] Support OGC srs urns without an EPSG database version --- src/ol/proj/epsg3857projection.js | 1 + src/ol/proj/epsg4326projection.js | 1 + 2 files changed, 2 insertions(+) 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'), From 34e82de8c8ea3b00fd56c6e7209da5aaaf32c85a Mon Sep 17 00:00:00 2001 From: Pierre GIRAUD Date: Fri, 28 Nov 2014 11:54:35 +0100 Subject: [PATCH 30/47] Export ol.source.TileVector#getFeatures in built mode --- src/ol/source/tilevectorsource.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ol/source/tilevectorsource.js b/src/ol/source/tilevectorsource.js index 1dc0ed79db..17ec6a86b6 100644 --- a/src/ol/source/tilevectorsource.js +++ b/src/ol/source/tilevectorsource.js @@ -141,6 +141,7 @@ ol.source.TileVector.prototype.getExtent = goog.abstractMethod; /** * @inheritDoc + * @api */ ol.source.TileVector.prototype.getFeatures = function() { var tiles = this.tiles_; From 2d74a6b10f02090d8111b5db27fccb29d858c116 Mon Sep 17 00:00:00 2001 From: Bart van den Eijnden Date: Fri, 28 Nov 2014 12:56:14 +0100 Subject: [PATCH 31/47] Use lineDash in ol.style.Circle's and ol.style.RegularShape's stroke --- src/ol/style/circlestyle.js | 11 ++++++++++- src/ol/style/regularshapestyle.js | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/ol/style/circlestyle.js b/src/ol/style/circlestyle.js index 0d209ba876..8901d8362b 100644 --- a/src/ol/style/circlestyle.js +++ b/src/ol/style/circlestyle.js @@ -3,6 +3,7 @@ goog.provide('ol.style.Circle'); 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'); @@ -197,7 +198,7 @@ ol.style.Circle.prototype.unlistenImageChange = goog.nullFunction; */ ol.style.Circle.prototype.render_ = function() { var canvas = this.canvas_; - var strokeStyle, strokeWidth; + var strokeStyle, strokeWidth, lineDash; if (goog.isNull(this.stroke_)) { strokeWidth = 0; @@ -229,6 +230,10 @@ ol.style.Circle.prototype.render_ = function() { } if (!goog.isNull(this.stroke_)) { context.strokeStyle = strokeStyle; + lineDash = this.stroke_.getLineDash(); + if (ol.has.CANVAS_LINE_DASH && !goog.isNull(lineDash)) { + context.setLineDash(lineDash); + } context.lineWidth = strokeWidth; context.stroke(); } @@ -253,6 +258,10 @@ ol.style.Circle.prototype.render_ = function() { context.fill(); if (!goog.isNull(this.stroke_)) { context.strokeStyle = strokeStyle; + lineDash = this.stroke_.getLineDash(); + if (ol.has.CANVAS_LINE_DASH && !goog.isNull(lineDash)) { + context.setLineDash(lineDash); + } context.lineWidth = strokeWidth; context.stroke(); } diff --git a/src/ol/style/regularshapestyle.js b/src/ol/style/regularshapestyle.js index 74850f1225..c699fcadfe 100644 --- a/src/ol/style/regularshapestyle.js +++ b/src/ol/style/regularshapestyle.js @@ -3,6 +3,7 @@ goog.provide('ol.style.RegularShape'); 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'); @@ -215,7 +216,7 @@ ol.style.RegularShape.prototype.unlistenImageChange = goog.nullFunction; */ ol.style.RegularShape.prototype.render_ = function() { var canvas = this.canvas_; - var strokeStyle, strokeWidth; + var strokeStyle, strokeWidth, lineDash; if (goog.isNull(this.stroke_)) { strokeWidth = 0; @@ -257,6 +258,10 @@ ol.style.RegularShape.prototype.render_ = function() { } if (!goog.isNull(this.stroke_)) { context.strokeStyle = strokeStyle; + lineDash = this.stroke_.getLineDash(); + if (ol.has.CANVAS_LINE_DASH && !goog.isNull(lineDash)) { + context.setLineDash(lineDash); + } context.lineWidth = strokeWidth; context.stroke(); } @@ -290,6 +295,10 @@ ol.style.RegularShape.prototype.render_ = function() { context.fill(); if (!goog.isNull(this.stroke_)) { context.strokeStyle = strokeStyle; + lineDash = this.stroke_.getLineDash(); + if (ol.has.CANVAS_LINE_DASH && !goog.isNull(lineDash)) { + context.setLineDash(lineDash); + } context.lineWidth = strokeWidth; context.stroke(); } From 5878e7f83935b47ce367d8b0f81ffb65170e4930 Mon Sep 17 00:00:00 2001 From: Pierre GIRAUD Date: Fri, 28 Nov 2014 16:17:39 +0100 Subject: [PATCH 32/47] Adding getFeaturesAtCoordinateAtResolution in ol.source.TileVector --- src/ol/source/tilevectorsource.js | 65 +++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/src/ol/source/tilevectorsource.js b/src/ol/source/tilevectorsource.js index b0da2796aa..b5f96e081b 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.forEachFeatureAtCoordinateAtResolution = + 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 */ @@ -153,6 +196,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 stable + */ +ol.source.TileVector.prototype.getFeaturesAtCoordinateAtResolution = + function(coordinate, resolution) { + var features = []; + this.forEachFeatureAtCoordinateAtResolution(coordinate, resolution, + /** + * @param {ol.Feature} feature Feature. + */ + function(feature) { + features.push(feature); + }); + return features; +}; + + /** * @inheritDoc */ From da39e9f96aa950aae4dbb7ce38837390e7e7210e Mon Sep 17 00:00:00 2001 From: Bart van den Eijnden Date: Fri, 28 Nov 2014 14:22:02 +0100 Subject: [PATCH 33/47] For stars, use radius1 and radius2 in ol.style.RegularShape --- externs/olx.js | 17 ++++++--- src/ol/style/regularshapestyle.js | 17 +++++++-- test/spec/ol/style/regularshapestyle.test.js | 36 ++++++++++++++++++++ 3 files changed, 62 insertions(+), 8 deletions(-) create mode 100644 test/spec/ol/style/regularshapestyle.test.js diff --git a/externs/olx.js b/externs/olx.js index ea8c57a169..5b871832f1 100644 --- a/externs/olx.js +++ b/externs/olx.js @@ -5653,9 +5653,11 @@ 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, + * radius1: number, * radius2: number, * angle: number, * snapToPixel: (boolean|undefined), @@ -5683,7 +5685,7 @@ olx.style.RegularShapeOptions.prototype.points; /** - * Shape radius. + * Radius of a regular polygon. * @type {number} * @api */ @@ -5691,9 +5693,15 @@ 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. +* Inner radius of a star. +* @type {number} +* @api +*/ +olx.style.RegularShapeOptions.prototype.radius1; + + +/** + * Outer radius of a star. * @type {number} * @api */ @@ -6121,7 +6129,6 @@ olx.tilegrid.XYZOptions.prototype.tileSize; /** * @typedef {{resolutions: !Array.}} * @api - * @api */ olx.tilegrid.ZoomifyOptions; diff --git a/src/ol/style/regularshapestyle.js b/src/ol/style/regularshapestyle.js index 74850f1225..a8ff33a939 100644 --- a/src/ol/style/regularshapestyle.js +++ b/src/ol/style/regularshapestyle.js @@ -13,7 +13,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. @@ -59,14 +61,14 @@ ol.style.RegularShape = function(opt_options) { * @private * @type {number} */ - this.radius_ = options.radius; + this.radius_ = 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 @@ -173,6 +175,15 @@ ol.style.RegularShape.prototype.getRadius = function() { }; +/** + * @return {number} Radius2. + * @api + */ +ol.style.RegularShape.prototype.getRadius2 = function() { + return this.radius2_; +}; + + /** * @inheritDoc * @api diff --git a/test/spec/ol/style/regularshapestyle.test.js b/test/spec/ol/style/regularshapestyle.test.js new file mode 100644 index 0000000000..c515670056 --- /dev/null +++ b/test/spec/ol/style/regularshapestyle.test.js @@ -0,0 +1,36 @@ +goog.provide('ol.test.style.RegularShape'); + +describe('ol.style.RegularShape', 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); + }); +}); + +goog.require('ol.style.RegularShape'); From c42ec27a4a3ae1e335fba2e03c99c71fa758bd2e Mon Sep 17 00:00:00 2001 From: Thomas Hirsch Date: Fri, 28 Nov 2014 22:09:45 +0100 Subject: [PATCH 34/47] image layer renderers use source projection if given and equivalent --- src/ol/renderer/canvas/canvasimagelayerrenderer.js | 8 +++++++- src/ol/renderer/dom/domimagelayerrenderer.js | 8 +++++++- src/ol/renderer/webgl/webglimagelayerrenderer.js | 8 +++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/ol/renderer/canvas/canvasimagelayerrenderer.js b/src/ol/renderer/canvas/canvasimagelayerrenderer.js index c223d84f1c..290f641a1d 100644 --- a/src/ol/renderer/canvas/canvasimagelayerrenderer.js +++ b/src/ol/renderer/canvas/canvasimagelayerrenderer.js @@ -108,8 +108,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.isDefAndNotNull(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/dom/domimagelayerrenderer.js b/src/ol/renderer/dom/domimagelayerrenderer.js index ce2ca367c7..5cd126f67c 100644 --- a/src/ol/renderer/dom/domimagelayerrenderer.js +++ b/src/ol/renderer/dom/domimagelayerrenderer.js @@ -104,8 +104,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.isDefAndNotNull(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 8579d2cc9c..39df83f58d 100644 --- a/src/ol/renderer/webgl/webglimagelayerrenderer.js +++ b/src/ol/renderer/webgl/webglimagelayerrenderer.js @@ -124,8 +124,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.isDefAndNotNull(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) { From 6cd1f3f2627d73662b20ace846894c7fb72e1586 Mon Sep 17 00:00:00 2001 From: Bart van den Eijnden Date: Sat, 29 Nov 2014 12:31:33 +0100 Subject: [PATCH 35/47] Correct olx.style.RegularShapeOptions definition --- externs/olx.js | 16 ++++++++-------- src/ol/style/regularshapestyle.js | 7 ++++++- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/externs/olx.js b/externs/olx.js index 5b871832f1..e850627709 100644 --- a/externs/olx.js +++ b/externs/olx.js @@ -5656,10 +5656,10 @@ 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, - * radius1: 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)}} * @api @@ -5686,7 +5686,7 @@ olx.style.RegularShapeOptions.prototype.points; /** * Radius of a regular polygon. - * @type {number} + * @type {number|undefined} * @api */ olx.style.RegularShapeOptions.prototype.radius; @@ -5694,7 +5694,7 @@ olx.style.RegularShapeOptions.prototype.radius; /** * Inner radius of a star. -* @type {number} +* @type {number|undefined} * @api */ olx.style.RegularShapeOptions.prototype.radius1; @@ -5702,7 +5702,7 @@ olx.style.RegularShapeOptions.prototype.radius1; /** * Outer radius of a star. - * @type {number} + * @type {number|undefined} * @api */ olx.style.RegularShapeOptions.prototype.radius2; @@ -5712,7 +5712,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; diff --git a/src/ol/style/regularshapestyle.js b/src/ol/style/regularshapestyle.js index 07028e1f77..579e71f6f7 100644 --- a/src/ol/style/regularshapestyle.js +++ b/src/ol/style/regularshapestyle.js @@ -1,5 +1,6 @@ goog.provide('ol.style.RegularShape'); +goog.require('goog.asserts'); goog.require('goog.dom'); goog.require('goog.dom.TagName'); goog.require('ol.color'); @@ -58,11 +59,15 @@ 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_ = goog.isDef(options.radius) ? options.radius : options.radius1; + this.radius_ = /** @type {number} */ (goog.isDef(options.radius) ? + options.radius : options.radius1); /** * @private From e385e81a202a00bf1271be1aaafaf06972c8d7eb Mon Sep 17 00:00:00 2001 From: Thomas Hirsch Date: Sun, 30 Nov 2014 10:08:41 +0100 Subject: [PATCH 36/47] linting --- src/ol/renderer/canvas/canvasimagelayerrenderer.js | 2 +- src/ol/renderer/dom/domimagelayerrenderer.js | 2 +- src/ol/renderer/webgl/webglimagelayerrenderer.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ol/renderer/canvas/canvasimagelayerrenderer.js b/src/ol/renderer/canvas/canvasimagelayerrenderer.js index 290f641a1d..d26155fb62 100644 --- a/src/ol/renderer/canvas/canvasimagelayerrenderer.js +++ b/src/ol/renderer/canvas/canvasimagelayerrenderer.js @@ -109,7 +109,7 @@ 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() + var sourceProjection = imageSource.getProjection(); if (goog.isDefAndNotNull(sourceProjection)) { goog.asserts.assert(ol.proj.equivalent(projection, sourceProjection)); projection = sourceProjection; diff --git a/src/ol/renderer/dom/domimagelayerrenderer.js b/src/ol/renderer/dom/domimagelayerrenderer.js index 5cd126f67c..1d5953ac0f 100644 --- a/src/ol/renderer/dom/domimagelayerrenderer.js +++ b/src/ol/renderer/dom/domimagelayerrenderer.js @@ -105,7 +105,7 @@ 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() + var sourceProjection = imageSource.getProjection(); if (goog.isDefAndNotNull(sourceProjection)) { goog.asserts.assert(ol.proj.equivalent(projection, sourceProjection)); projection = sourceProjection; diff --git a/src/ol/renderer/webgl/webglimagelayerrenderer.js b/src/ol/renderer/webgl/webglimagelayerrenderer.js index 39df83f58d..dfd1ee88c8 100644 --- a/src/ol/renderer/webgl/webglimagelayerrenderer.js +++ b/src/ol/renderer/webgl/webglimagelayerrenderer.js @@ -125,7 +125,7 @@ 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() + var sourceProjection = imageSource.getProjection(); if (goog.isDefAndNotNull(sourceProjection)) { goog.asserts.assert(ol.proj.equivalent(projection, sourceProjection)); projection = sourceProjection; From 1d7bae6b2607019b20e9effe85086887c509b16c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Poul=20Kjeldager=20S=C3=B8rensen?= Date: Sun, 30 Nov 2014 21:53:42 +0100 Subject: [PATCH 37/47] Update tilegrid.js --- src/ol/tilegrid/tilegrid.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ol/tilegrid/tilegrid.js b/src/ol/tilegrid/tilegrid.js index 65f08193ce..f4926be9af 100644 --- a/src/ol/tilegrid/tilegrid.js +++ b/src/ol/tilegrid/tilegrid.js @@ -300,7 +300,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 stable + * @api */ ol.tilegrid.TileGrid.prototype.getTileCoordForCoordAndResolution = function( coordinate, resolution, opt_tileCoord) { @@ -347,7 +347,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 stable + * @api */ ol.tilegrid.TileGrid.prototype.getTileCoordForCoordAndZ = function(coordinate, z, opt_tileCoord) { From ce4ecb711b461db54f9464640d037a004a5896bd Mon Sep 17 00:00:00 2001 From: Pierre GIRAUD Date: Mon, 1 Dec 2014 09:49:02 +0100 Subject: [PATCH 38/47] getFeaturesAtCoordinateAtResolution is not stable yet --- src/ol/source/tilevectorsource.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ol/source/tilevectorsource.js b/src/ol/source/tilevectorsource.js index b766b408c4..24581f46ca 100644 --- a/src/ol/source/tilevectorsource.js +++ b/src/ol/source/tilevectorsource.js @@ -203,7 +203,7 @@ ol.source.TileVector.prototype.getFeatures = function() { * @param {ol.Coordinate} coordinate Coordinate. * @param {number} resolution Resolution. * @return {Array.} Features. - * @api stable + * @api */ ol.source.TileVector.prototype.getFeaturesAtCoordinateAtResolution = function(coordinate, resolution) { From d5bafc5e9f365b2efbe829fdb8c02a3b30145187 Mon Sep 17 00:00:00 2001 From: Thomas Hirsch Date: Mon, 1 Dec 2014 10:53:36 +0100 Subject: [PATCH 39/47] linting --- src/ol/renderer/canvas/canvasimagelayerrenderer.js | 1 + src/ol/renderer/dom/domimagelayerrenderer.js | 1 + src/ol/renderer/webgl/webglimagelayerrenderer.js | 1 + 3 files changed, 3 insertions(+) diff --git a/src/ol/renderer/canvas/canvasimagelayerrenderer.js b/src/ol/renderer/canvas/canvasimagelayerrenderer.js index d26155fb62..afbaebfbf4 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'); diff --git a/src/ol/renderer/dom/domimagelayerrenderer.js b/src/ol/renderer/dom/domimagelayerrenderer.js index 1d5953ac0f..fabf03ea8c 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'); diff --git a/src/ol/renderer/webgl/webglimagelayerrenderer.js b/src/ol/renderer/webgl/webglimagelayerrenderer.js index dfd1ee88c8..07721bcb10 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'); From 26ce8032eb2c3410a34596bb334de9acd04378c3 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Thu, 27 Nov 2014 10:16:55 +0100 Subject: [PATCH 40/47] Use ol.Map#getEventPixel in mouse position control --- src/ol/control/mousepositioncontrol.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) 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_); }; From fabf05977a7bd025ba68f53aa1a41dcdabe06925 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Thu, 27 Nov 2014 10:17:09 +0100 Subject: [PATCH 41/47] Use offsetX and offsetY if available --- src/ol/map.js | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/ol/map.js b/src/ol/map.js index f7621f3ca8..6905e65eae 100644 --- a/src/ol/map.js +++ b/src/ol/map.js @@ -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]; } From 8e4d7c0715ffcaf011e6c7b3b2dc77c0ab3bceca Mon Sep 17 00:00:00 2001 From: Thomas Hirsch Date: Mon, 1 Dec 2014 12:57:35 +0100 Subject: [PATCH 42/47] isDefAndNotNull -> !isNull --- src/ol/renderer/canvas/canvasimagelayerrenderer.js | 2 +- src/ol/renderer/dom/domimagelayerrenderer.js | 2 +- src/ol/renderer/webgl/webglimagelayerrenderer.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ol/renderer/canvas/canvasimagelayerrenderer.js b/src/ol/renderer/canvas/canvasimagelayerrenderer.js index afbaebfbf4..6fad17913b 100644 --- a/src/ol/renderer/canvas/canvasimagelayerrenderer.js +++ b/src/ol/renderer/canvas/canvasimagelayerrenderer.js @@ -111,7 +111,7 @@ ol.renderer.canvas.ImageLayer.prototype.prepareFrame = !ol.extent.isEmpty(renderedExtent)) { var projection = viewState.projection; var sourceProjection = imageSource.getProjection(); - if (goog.isDefAndNotNull(sourceProjection)) { + if (!goog.isNull(sourceProjection)) { goog.asserts.assert(ol.proj.equivalent(projection, sourceProjection)); projection = sourceProjection; } diff --git a/src/ol/renderer/dom/domimagelayerrenderer.js b/src/ol/renderer/dom/domimagelayerrenderer.js index fabf03ea8c..0a8f59388b 100644 --- a/src/ol/renderer/dom/domimagelayerrenderer.js +++ b/src/ol/renderer/dom/domimagelayerrenderer.js @@ -107,7 +107,7 @@ ol.renderer.dom.ImageLayer.prototype.prepareFrame = !ol.extent.isEmpty(renderedExtent)) { var projection = viewState.projection; var sourceProjection = imageSource.getProjection(); - if (goog.isDefAndNotNull(sourceProjection)) { + if (!goog.isNull(sourceProjection)) { goog.asserts.assert(ol.proj.equivalent(projection, sourceProjection)); projection = sourceProjection; } diff --git a/src/ol/renderer/webgl/webglimagelayerrenderer.js b/src/ol/renderer/webgl/webglimagelayerrenderer.js index 07721bcb10..b8ce5a1fa0 100644 --- a/src/ol/renderer/webgl/webglimagelayerrenderer.js +++ b/src/ol/renderer/webgl/webglimagelayerrenderer.js @@ -127,7 +127,7 @@ ol.renderer.webgl.ImageLayer.prototype.prepareFrame = !ol.extent.isEmpty(renderedExtent)) { var projection = viewState.projection; var sourceProjection = imageSource.getProjection(); - if (goog.isDefAndNotNull(sourceProjection)) { + if (!goog.isNull(sourceProjection)) { goog.asserts.assert(ol.proj.equivalent(projection, sourceProjection)); projection = sourceProjection; } From 9f725f99ca5a5eff2c6d8bd3fd9d89eb4a435ef8 Mon Sep 17 00:00:00 2001 From: Pierre GIRAUD Date: Mon, 1 Dec 2014 14:22:03 +0100 Subject: [PATCH 43/47] Rename methods --- src/ol/source/tilevectorsource.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ol/source/tilevectorsource.js b/src/ol/source/tilevectorsource.js index 24581f46ca..84eea90faa 100644 --- a/src/ol/source/tilevectorsource.js +++ b/src/ol/source/tilevectorsource.js @@ -106,7 +106,7 @@ ol.source.TileVector.prototype.forEachFeature = goog.abstractMethod; * @return {S|undefined} The return value from the last call to the callback. * @template T,S */ -ol.source.TileVector.prototype.forEachFeatureAtCoordinateAtResolution = +ol.source.TileVector.prototype.forEachFeatureAtCoordinateAndResolution = function(coordinate, resolution, callback, opt_this) { var tileGrid = this.tileGrid_; @@ -205,10 +205,10 @@ ol.source.TileVector.prototype.getFeatures = function() { * @return {Array.} Features. * @api */ -ol.source.TileVector.prototype.getFeaturesAtCoordinateAtResolution = +ol.source.TileVector.prototype.getFeaturesAtCoordinateAndResolution = function(coordinate, resolution) { var features = []; - this.forEachFeatureAtCoordinateAtResolution(coordinate, resolution, + this.forEachFeatureAtCoordinateAndResolution(coordinate, resolution, /** * @param {ol.Feature} feature Feature. */ From 4a07327dabf5c4aa6adb642e6552af159471053d Mon Sep 17 00:00:00 2001 From: Bart van den Eijnden Date: Thu, 27 Nov 2014 13:33:33 +0100 Subject: [PATCH 44/47] Add an example to show off ol.style.RegularShape (see #2706) --- examples/regularshape.html | 51 +++++++++++++++++++ examples/regularshape.js | 100 +++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 examples/regularshape.html create mode 100644 examples/regularshape.js 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 + }) +}); From 0d16e0f0c8401dfe71cec324196bc08d4d81b367 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Wed, 3 Dec 2014 14:13:36 +0100 Subject: [PATCH 45/47] Use new demo GeoServer location demo.opengeo.org currently redirects to demo.boundlessgeo.com, so this change makes it so the new location is used directly. --- examples/epsg-4326.js | 2 +- examples/getfeatureinfo-image.js | 2 +- examples/getfeatureinfo-tile.js | 2 +- examples/tissot.js | 4 ++-- examples/vector-wfs.js | 2 +- examples/wms-image.js | 2 +- examples/wms-tiled.js | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) 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/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' })) From 22e33519c8c54e6ab8e7c68bb35f4471cc4247d2 Mon Sep 17 00:00:00 2001 From: Bart van den Eijnden Date: Thu, 4 Dec 2014 09:07:21 +0100 Subject: [PATCH 46/47] Explain that return of ol.color.asArray should not be modified --- src/ol/color/color.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ol/color/color.js b/src/ol/color/color.js index 6f7f44fff4..712323f370 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 From ccc7c1b9b7041f484fe71cec24c36e6484ad588f Mon Sep 17 00:00:00 2001 From: Bart van den Eijnden Date: Thu, 4 Dec 2014 09:24:18 +0100 Subject: [PATCH 47/47] Remove code that suggests that color arrays may be modified --- src/ol/color/color.js | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/src/ol/color/color.js b/src/ol/color/color.js index 712323f370..a857308d57 100644 --- a/src/ol/color/color.js +++ b/src/ol/color/color.js @@ -140,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() { @@ -172,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]; @@ -194,7 +192,7 @@ ol.color.fromString = ( cache[s] = color; ++cacheSize; } - return ol.color.returnOrUpdate(color, opt_color); + return color; }); })(); @@ -278,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.