diff --git a/.gitignore b/.gitignore index 2f70f4f045..7c37802ad3 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,7 @@ /build/gh-pages /build/check-requires-timestamp /build/jsdoc-*-timestamp -/build/lint-spec-timestamp -/build/lint-src-timestamp +/build/lint-timestamp /build/ol.css /build/ol.js /build/ol-all.js diff --git a/build.py b/build.py index f584c4c97a..c0e7e7c1b8 100755 --- a/build.py +++ b/build.py @@ -229,15 +229,15 @@ def serve_precommit(t): t.run('%(JAVA)s', '-jar', PLOVR_JAR, 'serve', 'build/ol-all.json', 'test/test.json') -virtual('lint', 'build/lint-src-timestamp', 'build/lint-spec-timestamp', 'build/check-requires-timestamp') +virtual('lint', 'build/lint-timestamp', 'build/check-requires-timestamp') -@target('build/lint-src-timestamp', SRC, INTERNAL_SRC, EXTERNAL_SRC, EXAMPLES_SRC, precious=True) +@target('build/lint-timestamp', SRC, INTERNAL_SRC, EXTERNAL_SRC, EXAMPLES_SRC, SPEC, precious=True) def build_lint_src_timestamp(t): limited_doc_files = [path for path in ifind('externs', 'build/src/external/externs') if path.endswith('.js')] - t.run('%(GJSLINT)s', '--strict', '--limited_doc_files=%s' % (','.join(limited_doc_files),), t.newer(SRC, INTERNAL_SRC, EXTERNAL_SRC, EXAMPLES_SRC)) + t.run('%(GJSLINT)s', '--strict', '--limited_doc_files=%s' % (','.join(limited_doc_files),), t.newer(t.dependencies)) t.touch() @@ -263,7 +263,7 @@ def _strip_comments(lines): yield line -@target('build/check-requires-timestamp', SRC, INTERNAL_SRC, EXTERNAL_SRC, EXAMPLES_SRC) +@target('build/check-requires-timestamp', SRC, INTERNAL_SRC, EXTERNAL_SRC, EXAMPLES_SRC, SPEC) def build_check_requires_timestamp(t): unused_count = 0 all_provides = set() @@ -273,7 +273,8 @@ def build_check_requires_timestamp(t): require_linenos = {} uses = set() lineno = 0 - for line in open(filename): + lines = open(filename).readlines() + for line in lines: lineno += 1 m = re.match(r'goog.provide\(\'(.*)\'\);', line) if m: @@ -283,6 +284,7 @@ def build_check_requires_timestamp(t): if m: require_linenos[m.group(1)] = lineno continue + for line in lines: for require in require_linenos.iterkeys(): if require in line: uses.add(require) @@ -329,12 +331,6 @@ def build_check_requires_timestamp(t): t.touch() -@target('build/lint-spec-timestamp', SPEC, precious=True) -def build_lint_spec_timestamp(t): - t.run('%(GJSLINT)s', t.newer(SPEC)) - t.touch() - - virtual('plovr', PLOVR_JAR) diff --git a/css/ol.css b/css/ol.css index 197439505e..1a2ede8923 100644 --- a/css/ol.css +++ b/css/ol.css @@ -28,6 +28,24 @@ width: 100%; height: 100%; } +.ol-scale-line { + background: rgba(0,60,136,0.3); + border-radius: 4px; + bottom: 8px; + left: 8px; + padding: 2px; + position: absolute; +} +.ol-scale-line-inner { + border: 1px solid #eeeeee; + border-top: none; + color: #eeeeee; + font-size: 10px; + font-family: 'Lucida Grande',Verdana,Geneva,Lucida,Arial,Helvetica,sans-serif; + text-align: center; + margin: 1px; + padding: 0px 2px; +} .ol-viewport .ol-unselectable { -webkit-touch-callout: none; -webkit-user-select: none; diff --git a/examples/canvas-tiles.html b/examples/canvas-tiles.html index 7340cdc3fc..5dbdde1af5 100644 --- a/examples/canvas-tiles.html +++ b/examples/canvas-tiles.html @@ -21,10 +21,12 @@ DOM WebGL + Canvas
+
diff --git a/examples/canvas-tiles.js b/examples/canvas-tiles.js index 31cd1515d9..ecec31b88b 100644 --- a/examples/canvas-tiles.js +++ b/examples/canvas-tiles.js @@ -41,3 +41,10 @@ var domMap = new ol.Map({ }); domMap.bindTo('layers', webglMap); domMap.bindTo('view', webglMap); + +var canvasMap = new ol.Map({ + renderer: ol.RendererHint.DOM, + target: 'canvasMap' +}); +canvasMap.bindTo('layers', webglMap); +canvasMap.bindTo('view', webglMap); diff --git a/examples/epsg-4326.js b/examples/epsg-4326.js index 9acf4517f8..ba95c06146 100644 --- a/examples/epsg-4326.js +++ b/examples/epsg-4326.js @@ -3,6 +3,7 @@ goog.require('ol.Coordinate'); goog.require('ol.Map'); goog.require('ol.RendererHint'); goog.require('ol.View2D'); +goog.require('ol.control.ScaleLineUnits'); goog.require('ol.layer.TileLayer'); goog.require('ol.projection'); goog.require('ol.source.TiledWMS'); @@ -39,6 +40,8 @@ var map = new ol.Map({ layers: layers, // The OSgeo server does not set cross origin headers, so we cannot use WebGL renderers: [ol.RendererHint.CANVAS, ol.RendererHint.DOM], + scaleLineControl: true, + scaleLineUnits: ol.control.ScaleLineUnits.DEGREES, target: 'map', view: new ol.View2D({ projection: epsg4326, diff --git a/examples/full-screen.js b/examples/full-screen.js index e696c2fea1..8ab4ca96ea 100644 --- a/examples/full-screen.js +++ b/examples/full-screen.js @@ -15,6 +15,7 @@ var layer = new ol.layer.TileLayer({ var map = new ol.Map({ layers: new ol.Collection([layer]), renderers: ol.RendererHints.createFromQueryData(), + scaleLineControl: true, target: 'map', view: new ol.View2D({ center: new ol.Coordinate(0, 0), diff --git a/examples/two-layers.js b/examples/two-layers.js index 78451c0669..e325376b7f 100644 --- a/examples/two-layers.js +++ b/examples/two-layers.js @@ -1,4 +1,3 @@ -goog.require('ol.BingMapsStyle'); goog.require('ol.Collection'); goog.require('ol.Coordinate'); goog.require('ol.Map'); @@ -14,7 +13,7 @@ var layers = new ol.Collection([ new ol.layer.TileLayer({ source: new ol.source.BingMaps({ key: 'AgtFlPYDnymLEe9zJ5PCkghbNiFZE9aAtTy3mPaEnEBXqLHtFuTcKoZ-miMC3w7R', - style: ol.BingMapsStyle.AERIAL + style: 'Aerial' }) }), new ol.layer.TileLayer({ diff --git a/readme.md b/readme.md index 85925eddb5..b94f437aa9 100644 --- a/readme.md +++ b/readme.md @@ -5,7 +5,13 @@ ## Hosted Examples -The examples are hosted on GitHub (as GitHub pages). See http://openlayers.github.com/ol3/master/examples/. +The examples are hosted on GitHub (as GitHub pages): http://openlayers.github.com/ol3/master/examples/. + +By default the examples use the `ol.js` script, which is compiled using Closure Compiler's ADVANVCED mode. +By appending `?mode=simple` or `?mode=whitespace` to the URL you can make the example page load `ol-simple.js` +or `ol-whitespace.js` instead of `ol.js`. As their names suggest it, `ol-simple.js` and `ol-whitespace.js` +are compiled using the SIMPLE and WHITESPACE modes, respectively. For example: +http://openlayers.github.com/ol3/master/examples/full-screen.html?mode=simple. ## Build OpenLayers 3 @@ -15,7 +21,7 @@ Run build.py: Windows users should run `build` instead. -## Run examples locally +## Run Examples locally Run the [Plovr](http://plovr.com/) web server with: @@ -33,18 +39,20 @@ and explore the `examples/` directory, for example by opening You can turn off compilation by appending `?mode=RAW` to the URL, for example . (By default mode is `ADVANCED`.) +Run examples without Plovr: + The examples can also be run against the `ol.js` standalone lib, without Plovr, just like the examples [hosted](http://openlayers.github.com/ol3/master/examples/) -on GitHub. You will want to run the examples against the standalone lib to verify -that will work correctly when copied on GitHub (as GitHub pages). Start by executing -the `hostexamples` build target: +on GitHub. Start by executing the `hostexamples` build target: $ ./build.py hostexamples -This will build `ol.js` and `ol.css`, creates the examples index page, and copy everything to -`build/gh-pages//`, where `` is the name of the local checked -out Git branch. You can now open the `build/gh-pages/examples` directory -in the browser, for example: . +This will build `ol.js`, `ol-simple.js`, `ol-whitespace.js`, and `ol.css`, create the examples index page, +and copy everything to `build/gh-pages//`, where `` is the name of the local +checked out Git branch. You can now open the examples index page in the browser, for example: +. To make an example use `ol-simple.js` or +`ol-whitespace.js` instead of `ol.js` append `?mode=simple` or `?mode=whitespace` to the example +URL. ## Run tests diff --git a/src/objectliterals.exports b/src/objectliterals.exports index 351ef6bdcd..3f0a1e984d 100644 --- a/src/objectliterals.exports +++ b/src/objectliterals.exports @@ -10,6 +10,8 @@ @exportObjectLiteralProperty ol.MapOptions.mouseWheelZoomDelta number|undefined @exportObjectLiteralProperty ol.MapOptions.renderer ol.RendererHint|undefined @exportObjectLiteralProperty ol.MapOptions.renderers Array.|undefined +@exportObjectLiteralProperty ol.MapOptions.scaleLineControl boolean|undefined +@exportObjectLiteralProperty ol.MapOptions.scaleLineUnits ol.control.ScaleLineUnits|undefined @exportObjectLiteralProperty ol.MapOptions.shiftDragZoom boolean|undefined @exportObjectLiteralProperty ol.MapOptions.target Element|string @exportObjectLiteralProperty ol.MapOptions.touchPan boolean|undefined @@ -58,6 +60,12 @@ @exportObjectLiteralProperty ol.control.AttributionOptions.map ol.Map|undefined @exportObjectLiteralProperty ol.control.AttributionOptions.target Element|undefined +@exportObjectLiteral ol.control.ScaleLineOptions +@exportObjectLiteralProperty ol.control.ScaleLineOptions.map ol.Map|undefined +@exportObjectLiteralProperty ol.control.ScaleLineOptions.minWidth number|undefined +@exportObjectLiteralProperty ol.control.ScaleLineOptions.target Element|undefined +@exportObjectLiteralProperty ol.control.ScaleLineOptions.units ol.control.ScaleLineUnits|undefined + @exportObjectLiteral ol.control.MousePositionOptions @exportObjectLiteralProperty ol.control.MousePositionOptions.coordinateFormat ol.CoordinateFormatType|undefined @exportObjectLiteralProperty ol.control.MousePositionOptions.map ol.Map|undefined @@ -88,7 +96,7 @@ @exportObjectLiteral ol.source.BingMapsOptions @exportObjectLiteralProperty ol.source.BingMapsOptions.culture string|undefined @exportObjectLiteralProperty ol.source.BingMapsOptions.key string -@exportObjectLiteralProperty ol.source.BingMapsOptions.style ol.BingMapsStyle +@exportObjectLiteralProperty ol.source.BingMapsOptions.style string @exportObjectLiteral ol.source.DebugTileSourceOptions @exportObjectLiteralProperty ol.source.DebugTileSourceOptions.extent ol.Extent|undefined @@ -125,6 +133,7 @@ @exportObjectLiteralProperty ol.source.TiledWMSOptions.crossOrigin null|string|undefined @exportObjectLiteralProperty ol.source.TiledWMSOptions.extent ol.Extent|undefined @exportObjectLiteralProperty ol.source.TiledWMSOptions.tileGrid ol.tilegrid.TileGrid|undefined +@exportObjectLiteralProperty ol.source.TiledWMSOptions.transparent boolean|undefined @exportObjectLiteralProperty ol.source.TiledWMSOptions.maxZoom number|undefined @exportObjectLiteralProperty ol.source.TiledWMSOptions.projection ol.Projection|undefined @exportObjectLiteralProperty ol.source.TiledWMSOptions.url string|undefined diff --git a/src/ol/control/scaleline.exports b/src/ol/control/scaleline.exports new file mode 100644 index 0000000000..6d0cbe1cd1 --- /dev/null +++ b/src/ol/control/scaleline.exports @@ -0,0 +1,9 @@ +@exportClass ol.control.ScaleLine ol.control.ScaleLineOptions +@exportProperty ol.control.ScaleLine.prototype.setMap + +@exportSymbol ol.control.ScaleLineUnits +@exportProperty ol.control.ScaleLineUnits.DEGREES +@exportProperty ol.control.ScaleLineUnits.IMPERIAL +@exportProperty ol.control.ScaleLineUnits.NAUTICAL +@exportProperty ol.control.ScaleLineUnits.METRIC +@exportProperty ol.control.ScaleLineUnits.US diff --git a/src/ol/control/scalelinecontrol.js b/src/ol/control/scalelinecontrol.js new file mode 100644 index 0000000000..a2144e502c --- /dev/null +++ b/src/ol/control/scalelinecontrol.js @@ -0,0 +1,277 @@ +goog.provide('ol.control.ScaleLine'); +goog.provide('ol.control.ScaleLineUnits'); + +goog.require('goog.dom'); +goog.require('goog.style'); +goog.require('ol.FrameState'); +goog.require('ol.MapEvent'); +goog.require('ol.MapEventType'); +goog.require('ol.ProjectionUnits'); +goog.require('ol.TransformFunction'); +goog.require('ol.control.Control'); +goog.require('ol.projection'); +goog.require('ol.sphere.NORMAL'); + + +/** + * @enum {string} + */ +ol.control.ScaleLineUnits = { + DEGREES: 'degrees', + IMPERIAL: 'imperial', + NAUTICAL: 'nautical', + METRIC: 'metric', + US: 'us' +}; + + + +/** + * @constructor + * @extends {ol.control.Control} + * @param {ol.control.ScaleLineOptions=} opt_options Options. + */ +ol.control.ScaleLine = function(opt_options) { + + var options = opt_options || {}; + + /** + * @private + * @type {Element} + */ + this.innerElement_ = goog.dom.createDom(goog.dom.TagName.DIV, { + 'class': 'ol-scale-line-inner' + }); + + /** + * @private + * @type {Element} + */ + this.element_ = goog.dom.createDom(goog.dom.TagName.DIV, { + 'class': 'ol-scale-line ol-unselectable' + }, this.innerElement_); + + /** + * @private + * @type {number} + */ + this.minWidth_ = goog.isDef(options.minWidth) ? options.minWidth : 64; + + /** + * @private + * @type {ol.control.ScaleLineUnits} + */ + this.units_ = goog.isDef(options.units) ? + options.units : ol.control.ScaleLineUnits.METRIC; + + /** + * @private + * @type {Array.} + */ + this.listenerKeys_ = null; + + /** + * @private + * @type {boolean} + */ + this.renderedVisible_ = false; + + /** + * @private + * @type {number|undefined} + */ + this.renderedWidth_; + + /** + * @private + * @type {string} + */ + this.renderedHTML_ = ''; + + /** + * @private + * @type {?ol.TransformFunction} + */ + this.toEPSG4326_ = null; + + goog.base(this, { + element: this.element_, + map: options.map, + target: options.target + }); + +}; +goog.inherits(ol.control.ScaleLine, ol.control.Control); + + +/** + * @const + * @type {Array.} + */ +ol.control.ScaleLine.LEADING_DIGITS = [1, 2, 5]; + + +/** + * @param {ol.MapEvent} mapEvent Map event. + */ +ol.control.ScaleLine.prototype.handleMapPostrender = function(mapEvent) { + var frameState = mapEvent.frameState; + this.updateElement_(mapEvent.frameState); +}; + + +/** + * @inheritDoc + */ +ol.control.ScaleLine.prototype.setMap = function(map) { + if (!goog.isNull(this.listenerKeys_)) { + goog.array.forEach(this.listenerKeys_, goog.events.unlistenByKey); + this.listenerKeys_ = null; + } + goog.base(this, 'setMap', map); + if (!goog.isNull(map)) { + this.listenerKeys_ = [ + goog.events.listen(map, ol.MapEventType.POSTRENDER, + this.handleMapPostrender, false, this) + ]; + } +}; + + +/** + * @param {?ol.FrameState} frameState Frame state. + * @private + */ +ol.control.ScaleLine.prototype.updateElement_ = function(frameState) { + + if (goog.isNull(frameState)) { + if (this.renderedVisible_) { + goog.style.showElement(this.element_, false); + this.renderedVisible_ = false; + } + return; + } + + var view2DState = frameState.view2DState; + var center = view2DState.center; + var projection = view2DState.projection; + var pointResolution = + projection.getPointResolution(view2DState.resolution, center); + var projectionUnits = projection.getUnits(); + + var cosLatitude; + if (projectionUnits == ol.ProjectionUnits.DEGREES && + (this.units_ == ol.control.ScaleLineUnits.METRIC || + this.units_ == ol.control.ScaleLineUnits.IMPERIAL)) { + + // Convert pointResolution from degrees to meters + this.toEPSG4326_ = null; + cosLatitude = Math.cos(goog.math.toRadians(center.y)); + pointResolution *= Math.PI * cosLatitude * ol.sphere.NORMAL.radius / 180; + + } else if (projectionUnits == ol.ProjectionUnits.METERS && + this.units_ == ol.control.ScaleLineUnits.DEGREES) { + + // Convert pointResolution from meters to degrees + if (goog.isNull(this.toEPSG4326_)) { + this.toEPSG4326_ = ol.projection.getTransform( + projection, ol.projection.getFromCode('EPSG:4326')); + } + var vertex = [center.x, center.y]; + vertex = this.toEPSG4326_(vertex, vertex, 2); + cosLatitude = Math.cos(goog.math.toRadians(vertex[1])); + pointResolution *= 180 / (Math.PI * cosLatitude * ol.sphere.NORMAL.radius); + + } else { + + this.toEPSG4326_ = null; + goog.asserts.assert( + ((this.units_ == ol.control.ScaleLineUnits.METRIC || + this.units_ == ol.control.ScaleLineUnits.IMPERIAL) && + projectionUnits == ol.ProjectionUnits.METERS) || + (this.units_ == ol.control.ScaleLineUnits.DEGREES && + projectionUnits == ol.ProjectionUnits.DEGREES)); + + } + + var nominalCount = this.minWidth_ * pointResolution; + var suffix = ''; + if (this.units_ == ol.control.ScaleLineUnits.DEGREES) { + if (nominalCount < 1 / 60) { + suffix = '\u2033'; // seconds + pointResolution *= 3600; + } else if (nominalCount < 1) { + suffix = '\u2032'; // minutes + pointResolution *= 60; + } else { + suffix = '\u00b0'; // degrees + } + } else if (this.units_ == ol.control.ScaleLineUnits.IMPERIAL) { + if (nominalCount < 0.9144) { + suffix = 'in'; + pointResolution /= 0.0254; + } else if (nominalCount < 1609.344) { + suffix = 'ft'; + pointResolution /= 0.3048; + } else { + suffix = 'mi'; + pointResolution /= 1609.344; + } + } else if (this.units_ == ol.control.ScaleLineUnits.NAUTICAL) { + pointResolution /= 1852; + suffix = 'nm'; + } else if (this.units_ == ol.control.ScaleLineUnits.METRIC) { + if (nominalCount < 1) { + suffix = 'mm'; + pointResolution *= 1000; + } else if (nominalCount < 1000) { + suffix = 'm'; + } else { + suffix = 'km'; + pointResolution /= 1000; + } + } else if (this.units_ == ol.control.ScaleLineUnits.US) { + if (nominalCount < 0.9144) { + suffix = 'in'; + pointResolution *= 39.37; + } else if (nominalCount < 1609.344) { + suffix = 'ft'; + pointResolution /= 0.30480061; + } else { + suffix = 'mi'; + pointResolution /= 1609.3472; + } + } else { + goog.asserts.assert(false); + } + + var i = 3 * Math.floor( + Math.log(this.minWidth_ * pointResolution) / Math.log(10)); + var count, width; + while (true) { + count = ol.control.ScaleLine.LEADING_DIGITS[i % 3] * + Math.pow(10, Math.floor(i / 3)); + width = Math.round(count / pointResolution); + if (width >= this.minWidth_) { + break; + } + ++i; + } + + var html = count + suffix; + if (this.renderedHTML_ != html) { + this.innerElement_.innerHTML = html; + this.renderedHTML_ = html; + } + + if (this.renderedWidth_ != width) { + this.innerElement_.style.width = width + 'px'; + this.renderedWidth_ = width; + } + + if (!this.renderedVisible_) { + goog.style.showElement(this.element_, true); + this.renderedVisible_ = true; + } + +}; diff --git a/src/ol/map.js b/src/ol/map.js index f25b7908da..9dfcee6d75 100644 --- a/src/ol/map.js +++ b/src/ol/map.js @@ -45,6 +45,7 @@ goog.require('ol.View'); goog.require('ol.View2D'); goog.require('ol.control.Attribution'); goog.require('ol.control.Control'); +goog.require('ol.control.ScaleLine'); goog.require('ol.control.Zoom'); goog.require('ol.interaction.DblClickZoom'); goog.require('ol.interaction.DragPan'); @@ -926,6 +927,16 @@ ol.Map.createControls_ = function(mapOptions) { controls.push(new ol.control.Attribution({})); } + var scaleLineControl = goog.isDef(mapOptions.scaleLineControl) ? + mapOptions.scaleLineControl : false; + if (scaleLineControl) { + var scaleLineUnits = goog.isDef(mapOptions.scaleLineUnits) ? + mapOptions.scaleLineUnits : undefined; + controls.push(new ol.control.ScaleLine({ + units: scaleLineUnits + })); + } + var zoomControl = goog.isDef(mapOptions.zoomControl) ? mapOptions.zoomControl : true; if (zoomControl) { diff --git a/src/ol/parser/ogc/wmtscapabilities_v1_0_0.js b/src/ol/parser/ogc/wmtscapabilities_v1_0_0.js index 1d1390248a..9260038a63 100644 --- a/src/ol/parser/ogc/wmtscapabilities_v1_0_0.js +++ b/src/ol/parser/ogc/wmtscapabilities_v1_0_0.js @@ -94,17 +94,19 @@ ol.parser.ogc.WMTSCapabilities_v1_0_0 = function() { obj['matrixHeight'] = parseInt(this.getChildValue(node), 10); }, 'ResourceURL': function(node, obj) { - obj['resourceUrl'] = obj['resourceUrl'] || {}; var resourceType = node.getAttribute('resourceType'); + var format = node.getAttribute('format'); + var template = node.getAttribute('template'); if (!obj['resourceUrls']) { - obj['resourceUrls'] = []; + obj['resourceUrls'] = {}; } - var resourceUrl = obj['resourceUrl'][resourceType] = { - 'format': node.getAttribute('format'), - 'template': node.getAttribute('template'), - 'resourceType': resourceType - }; - obj['resourceUrls'].push(resourceUrl); + if (!obj['resourceUrls'][resourceType]) { + obj['resourceUrls'][resourceType] = {}; + } + if (!obj['resourceUrls'][resourceType][format]) { + obj['resourceUrls'][resourceType][format] = []; + } + obj['resourceUrls'][resourceType][format].push(template); }, 'WSDL': function(node, obj) { obj['wsdl'] = {}; diff --git a/src/ol/renderer/canvas/canvastilelayerrenderer.js b/src/ol/renderer/canvas/canvastilelayerrenderer.js index 2c3a9882ec..1374457df6 100644 --- a/src/ol/renderer/canvas/canvastilelayerrenderer.js +++ b/src/ol/renderer/canvas/canvastilelayerrenderer.js @@ -1,4 +1,3 @@ -// FIXME don't redraw tiles if not needed // FIXME find correct globalCompositeOperation // FIXME optimize :-) @@ -51,6 +50,12 @@ ol.renderer.canvas.TileLayer = function(mapRenderer, tileLayer) { */ this.transform_ = goog.vec.Mat4.createNumber(); + /** + * @private + * @type {Array.} + */ + this.renderedTiles_ = null; + }; goog.inherits(ol.renderer.canvas.TileLayer, ol.renderer.canvas.Layer); @@ -100,10 +105,11 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame = var tileResolution = tileGrid.getResolution(z); var tileRange = tileGrid.getTileRangeForExtentAndResolution( frameState.extent, tileResolution); + var tileRangeWidth = tileRange.getWidth(); + var tileRangeHeight = tileRange.getHeight(); var canvasSize = new ol.Size( - tileSize.width * tileRange.getWidth(), - tileSize.height * tileRange.getHeight()); + tileSize.width * tileRangeWidth, tileSize.height * tileRangeHeight); var canvas, context; if (goog.isNull(this.canvas_)) { @@ -115,6 +121,7 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame = this.canvas_ = canvas; this.canvasSize_ = canvasSize; this.context_ = context; + this.renderedTiles_ = new Array(tileRangeWidth * tileRangeHeight); } else { canvas = this.canvas_; context = this.context_; @@ -122,11 +129,10 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame = canvas.width = canvasSize.width; canvas.height = canvasSize.height; this.canvasSize_ = canvasSize; + this.renderedTiles_ = new Array(tileRangeWidth * tileRangeHeight); } } - context.clearRect(0, 0, canvasSize.width, canvasSize.height); - /** * @type {Object.>} */ @@ -173,9 +179,12 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame = /** @type {Array.} */ var zs = goog.array.map(goog.object.getKeys(tilesToDrawByZ), Number); goog.array.sort(zs); + var opaque = tileSource.getOpaque(); var origin = tileGrid.getTileCoordExtent( new ol.TileCoord(z, tileRange.minX, tileRange.maxY)).getTopLeft(); - var currentZ, i, scale, tileCoordKey, tileExtent, tilesToDraw; + var currentZ, i, index, scale, tileCoordKey, tileExtent, tilesToDraw; + var ix, iy, interimTileExtent, interimTileRange, maxX, maxY, minX, minY; + var height, width; for (i = 0; i < zs.length; ++i) { currentZ = zs[i]; tileSize = tileGrid.getTileSize(currentZ); @@ -183,22 +192,44 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame = if (currentZ == z) { for (tileCoordKey in tilesToDraw) { tile = tilesToDraw[tileCoordKey]; - context.drawImage( - tile.getImage(), - tileSize.width * (tile.tileCoord.x - tileRange.minX), - tileSize.height * (tileRange.maxY - tile.tileCoord.y)); + tileCoord = tile.tileCoord; + index = (tileCoord.y - tileRange.minY) * tileRangeWidth + + (tileCoord.x - tileRange.minX); + if (this.renderedTiles_[index] != tile) { + x = tileSize.width * (tile.tileCoord.x - tileRange.minX); + y = tileSize.height * (tileRange.maxY - tile.tileCoord.y); + if (!opaque) { + context.clearRect(x, y, tileSize.width, tileSize.height); + } + context.drawImage(tile.getImage(), x, y); + this.renderedTiles_[index] = tile; + } } } else { scale = tileGrid.getResolution(currentZ) / tileResolution; for (tileCoordKey in tilesToDraw) { tile = tilesToDraw[tileCoordKey]; tileExtent = tileGrid.getTileCoordExtent(tile.tileCoord); - context.drawImage( - tile.getImage(), - (tileExtent.minX - origin.x) / tileResolution, - (origin.y - tileExtent.maxY) / tileResolution, - scale * tileSize.width, - scale * tileSize.height); + x = (tileExtent.minX - origin.x) / tileResolution; + y = (origin.y - tileExtent.maxY) / tileResolution; + width = scale * tileSize.width; + height = scale * tileSize.height; + if (!opaque) { + context.clearRect(x, y, width, height); + } + context.drawImage(tile.getImage(), x, y, width, height); + interimTileRange = + tileGrid.getTileRangeForExtentAndZ(tileExtent, z); + minX = Math.max(interimTileRange.minX, tileRange.minX); + maxX = Math.min(interimTileRange.maxX, tileRange.maxX); + minY = Math.max(interimTileRange.minY, tileRange.minY); + maxY = Math.min(interimTileRange.maxY, tileRange.maxY); + for (ix = minX; ix <= maxX; ++ix) { + for (iy = minY; iy <= maxY; ++iy) { + this.renderedTiles_[(iy - tileRange.minY) * tileRangeWidth + + (ix - tileRange.minX)] = undefined; + } + } } } } diff --git a/src/ol/renderer/webgl/webglimagelayerrenderer.js b/src/ol/renderer/webgl/webglimagelayerrenderer.js index 12d5b86603..46d2246c85 100644 --- a/src/ol/renderer/webgl/webglimagelayerrenderer.js +++ b/src/ol/renderer/webgl/webglimagelayerrenderer.js @@ -45,7 +45,7 @@ ol.renderer.webgl.ImageLayer = function(mapRenderer, imageLayer) { * @private * @type {!goog.vec.Mat4.Number} */ - this.vertexCoordMatrix_ = goog.vec.Mat4.createNumber(); + this.projectionMatrix_ = goog.vec.Mat4.createNumber(); }; goog.inherits(ol.renderer.webgl.ImageLayer, ol.renderer.webgl.Layer); @@ -118,8 +118,8 @@ ol.renderer.webgl.ImageLayer.prototype.getTexture = function() { /** * @inheritDoc */ -ol.renderer.webgl.ImageLayer.prototype.getVertexCoordMatrix = function() { - return this.vertexCoordMatrix_; +ol.renderer.webgl.ImageLayer.prototype.getProjectionMatrix = function() { + return this.projectionMatrix_; }; @@ -188,7 +188,7 @@ ol.renderer.webgl.ImageLayer.prototype.renderFrame = var canvas = this.getMapRenderer().getCanvas(); - this.updateVertexCoordMatrix_(canvas.width, canvas.height, + this.updateProjectionMatrix_(canvas.width, canvas.height, viewCenter, viewResolution, viewRotation, image.getExtent()); // Translate and scale to flip the Y coord. @@ -214,24 +214,24 @@ ol.renderer.webgl.ImageLayer.prototype.renderFrame = * @param {number} viewRotation View rotation. * @param {ol.Extent} imageExtent Image extent. */ -ol.renderer.webgl.ImageLayer.prototype.updateVertexCoordMatrix_ = +ol.renderer.webgl.ImageLayer.prototype.updateProjectionMatrix_ = function(canvasWidth, canvasHeight, viewCenter, viewResolution, viewRotation, imageExtent) { var canvasExtentWidth = canvasWidth * viewResolution; var canvasExtentHeight = canvasHeight * viewResolution; - var vertexCoordMatrix = this.vertexCoordMatrix_; - goog.vec.Mat4.makeIdentity(vertexCoordMatrix); - goog.vec.Mat4.scale(vertexCoordMatrix, + var projectionMatrix = this.projectionMatrix_; + goog.vec.Mat4.makeIdentity(projectionMatrix); + goog.vec.Mat4.scale(projectionMatrix, 2 / canvasExtentWidth, 2 / canvasExtentHeight, 1); - goog.vec.Mat4.rotateZ(vertexCoordMatrix, -viewRotation); - goog.vec.Mat4.translate(vertexCoordMatrix, + goog.vec.Mat4.rotateZ(projectionMatrix, -viewRotation); + goog.vec.Mat4.translate(projectionMatrix, imageExtent.minX - viewCenter.x, imageExtent.minY - viewCenter.y, 0); - goog.vec.Mat4.scale(vertexCoordMatrix, + goog.vec.Mat4.scale(projectionMatrix, imageExtent.getWidth() / 2, imageExtent.getHeight() / 2, 1); - goog.vec.Mat4.translate(vertexCoordMatrix, 1, 1, 0); + goog.vec.Mat4.translate(projectionMatrix, 1, 1, 0); }; diff --git a/src/ol/renderer/webgl/webgllayerrenderer.js b/src/ol/renderer/webgl/webgllayerrenderer.js index 067a4e054c..7199246d4b 100644 --- a/src/ol/renderer/webgl/webgllayerrenderer.js +++ b/src/ol/renderer/webgl/webgllayerrenderer.js @@ -100,7 +100,7 @@ ol.renderer.webgl.Layer.prototype.getTexture = goog.abstractMethod; /** * @return {!goog.vec.Mat4.Number} Matrix. */ -ol.renderer.webgl.Layer.prototype.getVertexCoordMatrix = goog.abstractMethod; +ol.renderer.webgl.Layer.prototype.getProjectionMatrix = goog.abstractMethod; /** diff --git a/src/ol/renderer/webgl/webglmaprenderer.js b/src/ol/renderer/webgl/webglmaprenderer.js index 62b03fc489..0870c376db 100644 --- a/src/ol/renderer/webgl/webglmaprenderer.js +++ b/src/ol/renderer/webgl/webglmaprenderer.js @@ -48,17 +48,17 @@ ol.renderer.webgl.map.shader.Fragment = function() { goog.base(this, [ 'precision mediump float;', '', - 'uniform mat4 uColorMatrix;', - 'uniform float uOpacity;', - 'uniform sampler2D uTexture;', + 'uniform mat4 u_colorMatrix;', + 'uniform float u_opacity;', + 'uniform sampler2D u_texture;', '', - 'varying vec2 vTexCoord;', + 'varying vec2 v_texCoord;', '', 'void main(void) {', '', - ' vec4 texColor = texture2D(uTexture, vTexCoord);', - ' vec4 color = uColorMatrix * vec4(texColor.rgb, 1.);', - ' color.a = texColor.a * uOpacity;', + ' vec4 texColor = texture2D(u_texture, v_texCoord);', + ' vec4 color = u_colorMatrix * vec4(texColor.rgb, 1.);', + ' color.a = texColor.a * u_opacity;', '', ' gl_FragColor = color;', '', @@ -77,17 +77,17 @@ goog.addSingletonGetter(ol.renderer.webgl.map.shader.Fragment); */ ol.renderer.webgl.map.shader.Vertex = function() { goog.base(this, [ - 'attribute vec2 aPosition;', - 'attribute vec2 aTexCoord;', + 'attribute vec2 a_position;', + 'attribute vec2 a_texCoord;', '', - 'uniform mat4 uTexCoordMatrix;', - 'uniform mat4 uVertexCoordMatrix;', + 'uniform mat4 u_texCoordMatrix;', + 'uniform mat4 u_projectionMatrix;', '', - 'varying vec2 vTexCoord;', + 'varying vec2 v_texCoord;', '', 'void main(void) {', - ' gl_Position = uVertexCoordMatrix * vec4(aPosition, 0., 1.);', - ' vTexCoord = (uTexCoordMatrix * vec4(aTexCoord, 0., 1.)).st;', + ' gl_Position = u_projectionMatrix * vec4(a_position, 0., 1.);', + ' v_texCoord = (u_texCoordMatrix * vec4(a_texCoord, 0., 1.)).st;', '}' ].join('\n')); }; @@ -157,13 +157,13 @@ ol.renderer.webgl.Map = function(container, map) { /** * @private - * @type {{aPosition: number, - * aTexCoord: number, - * uColorMatrix: WebGLUniformLocation, - * uOpacity: WebGLUniformLocation, - * uTexture: WebGLUniformLocation, - * uTexCoordMatrix: WebGLUniformLocation, - * uVertexCoordMatrix: WebGLUniformLocation}|null} + * @type {{a_position: number, + * a_texCoord: number, + * u_colorMatrix: WebGLUniformLocation, + * u_opacity: WebGLUniformLocation, + * u_texture: WebGLUniformLocation, + * u_texCoordMatrix: WebGLUniformLocation, + * u_projectionMatrix: WebGLUniformLocation}|null} */ this.locations_ = null; @@ -522,13 +522,13 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) { gl.useProgram(program); if (goog.isNull(this.locations_)) { this.locations_ = { - aPosition: gl.getAttribLocation(program, 'aPosition'), - aTexCoord: gl.getAttribLocation(program, 'aTexCoord'), - uColorMatrix: gl.getUniformLocation(program, 'uColorMatrix'), - uTexCoordMatrix: gl.getUniformLocation(program, 'uTexCoordMatrix'), - uVertexCoordMatrix: gl.getUniformLocation(program, 'uVertexCoordMatrix'), - uOpacity: gl.getUniformLocation(program, 'uOpacity'), - uTexture: gl.getUniformLocation(program, 'uTexture') + a_position: gl.getAttribLocation(program, 'a_position'), + a_texCoord: gl.getAttribLocation(program, 'a_texCoord'), + u_colorMatrix: gl.getUniformLocation(program, 'u_colorMatrix'), + u_texCoordMatrix: gl.getUniformLocation(program, 'u_texCoordMatrix'), + u_projectionMatrix: gl.getUniformLocation(program, 'u_projectionMatrix'), + u_opacity: gl.getUniformLocation(program, 'u_opacity'), + u_texture: gl.getUniformLocation(program, 'u_texture') }; } @@ -546,13 +546,13 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) { gl.bindBuffer(goog.webgl.ARRAY_BUFFER, this.arrayBuffer_); } - gl.enableVertexAttribArray(this.locations_.aPosition); + gl.enableVertexAttribArray(this.locations_.a_position); gl.vertexAttribPointer( - this.locations_.aPosition, 2, goog.webgl.FLOAT, false, 16, 0); - gl.enableVertexAttribArray(this.locations_.aTexCoord); + this.locations_.a_position, 2, goog.webgl.FLOAT, false, 16, 0); + gl.enableVertexAttribArray(this.locations_.a_texCoord); gl.vertexAttribPointer( - this.locations_.aTexCoord, 2, goog.webgl.FLOAT, false, 16, 8); - gl.uniform1i(this.locations_.uTexture, 0); + this.locations_.a_texCoord, 2, goog.webgl.FLOAT, false, 16, 8); + gl.uniform1i(this.locations_.u_texture, 0); goog.array.forEach(frameState.layersArray, function(layer) { var layerState = frameState.layerStates[goog.getUid(layer)]; @@ -561,14 +561,14 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) { } var layerRenderer = this.getLayerRenderer(layer); gl.uniformMatrix4fv( - this.locations_.uTexCoordMatrix, false, + this.locations_.u_texCoordMatrix, false, layerRenderer.getTexCoordMatrix()); gl.uniformMatrix4fv( - this.locations_.uVertexCoordMatrix, false, - layerRenderer.getVertexCoordMatrix()); + this.locations_.u_projectionMatrix, false, + layerRenderer.getProjectionMatrix()); gl.uniformMatrix4fv( - this.locations_.uColorMatrix, false, layerRenderer.getColorMatrix()); - gl.uniform1f(this.locations_.uOpacity, layer.getOpacity()); + this.locations_.u_colorMatrix, false, layerRenderer.getColorMatrix()); + gl.uniform1f(this.locations_.u_opacity, layer.getOpacity()); gl.bindTexture(goog.webgl.TEXTURE_2D, layerRenderer.getTexture()); gl.drawArrays(goog.webgl.TRIANGLE_STRIP, 0, 4); }, this); diff --git a/src/ol/renderer/webgl/webgltilelayerrenderer.js b/src/ol/renderer/webgl/webgltilelayerrenderer.js index 7f89cfca89..4059509e0a 100644 --- a/src/ol/renderer/webgl/webgltilelayerrenderer.js +++ b/src/ol/renderer/webgl/webgltilelayerrenderer.js @@ -145,7 +145,7 @@ ol.renderer.webgl.TileLayer = function(mapRenderer, tileLayer) { * @private * @type {!goog.vec.Mat4.Number} */ - this.vertexCoordMatrix_ = goog.vec.Mat4.createNumberIdentity(); + this.projectionMatrix_ = goog.vec.Mat4.createNumberIdentity(); /** * @private @@ -246,8 +246,8 @@ ol.renderer.webgl.TileLayer.prototype.getTexture = function() { /** * @inheritDoc */ -ol.renderer.webgl.TileLayer.prototype.getVertexCoordMatrix = function() { - return this.vertexCoordMatrix_; +ol.renderer.webgl.TileLayer.prototype.getProjectionMatrix = function() { + return this.projectionMatrix_; }; diff --git a/src/ol/source/bingmaps.exports b/src/ol/source/bingmaps.exports index 516bf8777c..8f2a2384f2 100644 --- a/src/ol/source/bingmaps.exports +++ b/src/ol/source/bingmaps.exports @@ -1,7 +1 @@ @exportSymbol ol.source.BingMaps -@exportSymbol ol.BingMapsStyle -@exportProperty ol.BingMapsStyle.AERIAL -@exportProperty ol.BingMapsStyle.AERIAL_WITH_LABELS -@exportProperty ol.BingMapsStyle.ROAD -@exportProperty ol.BingMapsStyle.ORDNANCE_SURVEY -@exportProperty ol.BingMapsStyle.COLLINS_BART diff --git a/src/ol/source/bingmapssource.js b/src/ol/source/bingmapssource.js index 1e5355904c..430e548a1b 100644 --- a/src/ol/source/bingmapssource.js +++ b/src/ol/source/bingmapssource.js @@ -1,4 +1,3 @@ -goog.provide('ol.BingMapsStyle'); goog.provide('ol.source.BingMaps'); goog.require('goog.Uri'); @@ -15,18 +14,6 @@ goog.require('ol.source.ImageTileSource'); goog.require('ol.tilegrid.XYZ'); -/** - * @enum {string} - */ -ol.BingMapsStyle = { - AERIAL: 'Aerial', - AERIAL_WITH_LABELS: 'AerialWithLabels', - ROAD: 'Road', - ORDNANCE_SURVEY: 'OrdnanceSurvey', - COLLINS_BART: 'CollinsBart' -}; - - /** * @constructor @@ -36,6 +23,7 @@ ol.BingMapsStyle = { ol.source.BingMaps = function(bingMapsOptions) { goog.base(this, { + opaque: true, projection: ol.projection.getFromCode('EPSG:3857') }); diff --git a/src/ol/source/debugtilesource.js b/src/ol/source/debugtilesource.js index e553081ae3..d9ab21ad80 100644 --- a/src/ol/source/debugtilesource.js +++ b/src/ol/source/debugtilesource.js @@ -90,6 +90,7 @@ ol.source.DebugTileSource = function(options) { goog.base(this, { extent: options.extent, + opaque: false, projection: options.projection, tileGrid: options.tileGrid }); diff --git a/src/ol/source/imagetilesource.js b/src/ol/source/imagetilesource.js index 15f2cc4f04..b9fd30f9ea 100644 --- a/src/ol/source/imagetilesource.js +++ b/src/ol/source/imagetilesource.js @@ -17,6 +17,7 @@ goog.require('ol.tilegrid.TileGrid'); * @typedef {{attributions: (Array.|undefined), * crossOrigin: (null|string|undefined), * extent: (ol.Extent|undefined), + * opaque: (boolean|undefined), * projection: (ol.Projection|undefined), * tileGrid: (ol.tilegrid.TileGrid|undefined), * tileUrlFunction: (ol.TileUrlFunctionType|undefined)}} @@ -35,6 +36,7 @@ ol.source.ImageTileSource = function(options) { goog.base(this, { attributions: options.attributions, extent: options.extent, + opaque: options.opaque, projection: options.projection, tileGrid: options.tileGrid }); diff --git a/src/ol/source/mapquestsource.js b/src/ol/source/mapquestsource.js index 08fb316632..ae12b33a25 100644 --- a/src/ol/source/mapquestsource.js +++ b/src/ol/source/mapquestsource.js @@ -26,6 +26,7 @@ ol.source.MapQuestOSM = function() { goog.base(this, { attributions: attributions, + opaque: true, maxZoom: 28, url: 'http://otile{1-4}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.jpg' }); @@ -54,6 +55,7 @@ ol.source.MapQuestOpenAerial = function() { goog.base(this, { attributions: attributions, maxZoom: 18, + opaque: true, url: 'http://oatile{1-4}.mqcdn.com/tiles/1.0.0/sat/{z}/{x}/{y}.jpg' }); diff --git a/src/ol/source/openstreetmapsource.js b/src/ol/source/openstreetmapsource.js index 8bbfaf5742..258fe22637 100644 --- a/src/ol/source/openstreetmapsource.js +++ b/src/ol/source/openstreetmapsource.js @@ -18,6 +18,7 @@ ol.source.OpenStreetMap = function() { goog.base(this, { attributions: [attribution], + opaque: true, maxZoom: 18, url: 'http://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png' }); diff --git a/src/ol/source/stamensource.js b/src/ol/source/stamensource.js index 46f87d83df..90355bf1e5 100644 --- a/src/ol/source/stamensource.js +++ b/src/ol/source/stamensource.js @@ -85,6 +85,7 @@ ol.source.Stamen = function(stamenOptions) { goog.base(this, { attributions: [attribution], maxZoom: config.maxZoom, + opaque: false, url: 'http://{a-d}.tile.stamen.com/' + layer + '/{z}/{x}/{y}.' + config.type }); diff --git a/src/ol/source/tiledwmssource.js b/src/ol/source/tiledwmssource.js index 405735b52b..7ba0401cdd 100644 --- a/src/ol/source/tiledwmssource.js +++ b/src/ol/source/tiledwmssource.js @@ -38,7 +38,8 @@ ol.source.TiledWMS = function(tiledWMSOptions) { } else { tileUrlFunction = ol.TileUrlFunction.nullTileUrlFunction; } - + var transparent = goog.isDef(tiledWMSOptions.transparent) ? + tiledWMSOptions.transparent : true; var extent = tiledWMSOptions.extent; var tileCoordTransform = function(tileCoord, tileGrid, projection) { @@ -70,6 +71,7 @@ ol.source.TiledWMS = function(tiledWMSOptions) { crossOrigin: tiledWMSOptions.crossOrigin, extent: extent, tileGrid: tiledWMSOptions.tileGrid, + opaque: !transparent, projection: tiledWMSOptions.projection, tileUrlFunction: ol.TileUrlFunction.withTileCoordTransform( tileCoordTransform, tileUrlFunction) diff --git a/src/ol/source/tilesource.js b/src/ol/source/tilesource.js index 34e0d13ba4..92bd61caf3 100644 --- a/src/ol/source/tilesource.js +++ b/src/ol/source/tilesource.js @@ -15,6 +15,7 @@ goog.require('ol.tilegrid.TileGrid'); /** * @typedef {{attributions: (Array.|undefined), * extent: (ol.Extent|undefined), + * opaque: (boolean|undefined), * projection: (ol.Projection|undefined), * tileGrid: (ol.tilegrid.TileGrid|undefined)}} */ @@ -35,6 +36,13 @@ ol.source.TileSource = function(tileSourceOptions) { projection: tileSourceOptions.projection }); + /** + * @private + * @type {boolean} + */ + this.opaque_ = goog.isDef(tileSourceOptions.opaque) ? + tileSourceOptions.opaque : false; + /** * @protected * @type {ol.tilegrid.TileGrid} @@ -98,6 +106,14 @@ ol.source.TileSource.prototype.findLoadedTiles = function(loadedTilesByZ, }; +/** + * @return {boolean} Opaque. + */ +ol.source.TileSource.prototype.getOpaque = function() { + return this.opaque_; +}; + + /** * @inheritDoc */ diff --git a/test/spec/ol/color.test.js b/test/spec/ol/color.test.js index 3daeb97b0c..1e79f7f7f7 100644 --- a/test/spec/ol/color.test.js +++ b/test/spec/ol/color.test.js @@ -71,3 +71,5 @@ describe('ol.Color', function() { }); }); + +goog.require('ol.Color'); diff --git a/test/spec/ol/ellipsoid.test.js b/test/spec/ol/ellipsoid.test.js index cf65f8d23f..6dd8310d93 100644 --- a/test/spec/ol/ellipsoid.test.js +++ b/test/spec/ol/ellipsoid.test.js @@ -325,15 +325,16 @@ describe('ol.Ellipsoid', function() { it('returns the same distances as Chris Veness\'s reference implementation', function() { - var e, i, v; - for (i = 0; i < expected.length; ++i) { - e = expected[i]; - v = ol.ellipsoid.WGS84.vincenty(e.c1, e.c2, 1e-12, 100); - expect(v.distance).toRoughlyEqual(e.vincentyDistance, 1e-8); - expect(v.finalBearing).toRoughlyEqual(e.vincentyFinalBearing, 1e-9); - expect(v.initialBearing).toRoughlyEqual(e.vincentyInitialBearing, 1e-9); - } - }); + var e, i, v; + for (i = 0; i < expected.length; ++i) { + e = expected[i]; + v = ol.ellipsoid.WGS84.vincenty(e.c1, e.c2, 1e-12, 100); + expect(v.distance).toRoughlyEqual(e.vincentyDistance, 1e-8); + expect(v.finalBearing).toRoughlyEqual(e.vincentyFinalBearing, 1e-9); + expect(v.initialBearing).toRoughlyEqual( + e.vincentyInitialBearing, 1e-9); + } + }); }); @@ -341,14 +342,14 @@ describe('ol.Ellipsoid', function() { it('returns the same distances as Chris Veness\'s reference implementation', function() { - var e, i, vincentyDistance; - for (i = 0; i < expected.length; ++i) { - e = expected[i]; - vincentyDistance = - ol.ellipsoid.WGS84.vincentyDistance(e.c1, e.c2, 1e-12, 100); - expect(vincentyDistance).toRoughlyEqual(e.vincentyDistance, 1e-8); - } - }); + var e, i, vincentyDistance; + for (i = 0; i < expected.length; ++i) { + e = expected[i]; + vincentyDistance = + ol.ellipsoid.WGS84.vincentyDistance(e.c1, e.c2, 1e-12, 100); + expect(vincentyDistance).toRoughlyEqual(e.vincentyDistance, 1e-8); + } + }); }); @@ -356,15 +357,15 @@ describe('ol.Ellipsoid', function() { it('returns the same distances as Chris Veness\'s reference implementation', function() { - var e, i, vincentyFinalBearing; - for (i = 0; i < expected.length; ++i) { - e = expected[i]; - vincentyFinalBearing = - ol.ellipsoid.WGS84.vincentyFinalBearing(e.c1, e.c2, 1e-12, 100); - expect(vincentyFinalBearing).toRoughlyEqual( - e.vincentyFinalBearing, 1e-9); - } - }); + var e, i, vincentyFinalBearing; + for (i = 0; i < expected.length; ++i) { + e = expected[i]; + vincentyFinalBearing = + ol.ellipsoid.WGS84.vincentyFinalBearing(e.c1, e.c2, 1e-12, 100); + expect(vincentyFinalBearing).toRoughlyEqual( + e.vincentyFinalBearing, 1e-9); + } + }); }); @@ -372,15 +373,15 @@ describe('ol.Ellipsoid', function() { it('returns the same distances as Chris Veness\'s reference implementation', function() { - var e, i, vincentyInitialBearing; - for (i = 0; i < expected.length; ++i) { - e = expected[i]; - vincentyInitialBearing = - ol.ellipsoid.WGS84.vincentyInitialBearing(e.c1, e.c2, 1e-12, 100); - expect(vincentyInitialBearing).toRoughlyEqual( - e.vincentyInitialBearing, 1e-9); - } - }); + var e, i, vincentyInitialBearing; + for (i = 0; i < expected.length; ++i) { + e = expected[i]; + vincentyInitialBearing = ol.ellipsoid.WGS84.vincentyInitialBearing( + e.c1, e.c2, 1e-12, 100); + expect(vincentyInitialBearing).toRoughlyEqual( + e.vincentyInitialBearing, 1e-9); + } + }); }); @@ -388,4 +389,5 @@ describe('ol.Ellipsoid', function() { goog.require('ol.Coordinate'); +goog.require('ol.Ellipsoid'); goog.require('ol.ellipsoid.WGS84'); diff --git a/test/spec/ol/extent.test.js b/test/spec/ol/extent.test.js index 9cd1ba3c40..9737ab9334 100644 --- a/test/spec/ol/extent.test.js +++ b/test/spec/ol/extent.test.js @@ -100,5 +100,6 @@ describe('ol.Extent', function() { }); }); +goog.require('ol.Coordinate'); goog.require('ol.Extent'); goog.require('ol.projection'); diff --git a/test/spec/ol/layer/layer.test.js b/test/spec/ol/layer/layer.test.js index 299279a1ee..2b5c567162 100644 --- a/test/spec/ol/layer/layer.test.js +++ b/test/spec/ol/layer/layer.test.js @@ -276,4 +276,6 @@ describe('ol.layer.Layer', function() { }); +goog.require('ol.layer.Layer'); goog.require('ol.projection'); +goog.require('ol.source.Source'); diff --git a/test/spec/ol/lrucache.test.js b/test/spec/ol/lrucache.test.js index 587724e36a..6cf2768a69 100644 --- a/test/spec/ol/lrucache.test.js +++ b/test/spec/ol/lrucache.test.js @@ -187,3 +187,5 @@ describe('ol.structs.LRUCache', function() { }); }); + +goog.require('ol.structs.LRUCache'); diff --git a/test/spec/ol/map.test.js b/test/spec/ol/map.test.js index 43cda9f703..776d268400 100644 --- a/test/spec/ol/map.test.js +++ b/test/spec/ol/map.test.js @@ -246,6 +246,9 @@ goog.require('ol.Collection'); goog.require('ol.Coordinate'); goog.require('ol.Map'); goog.require('ol.RendererHint'); +goog.require('ol.RendererHints'); goog.require('ol.View2D'); +goog.require('ol.interaction.DblClickZoom'); +goog.require('ol.interaction.MouseWheelZoom'); goog.require('ol.layer.TileLayer'); goog.require('ol.source.XYZ'); diff --git a/test/spec/ol/parser/ogc/wmscapabilities.test.js b/test/spec/ol/parser/ogc/wmscapabilities.test.js index 579898a1f4..a69ac29e87 100644 --- a/test/spec/ol/parser/ogc/wmscapabilities.test.js +++ b/test/spec/ol/parser/ogc/wmscapabilities.test.js @@ -3,10 +3,10 @@ goog.provide('ol.test.parser.ogc.WMSCapabilities'); describe('test WMSCapabilities', function() { describe('test getVersion', function() { var snippet = '' + - ''; + 'xmlns="http://www.opengis.net/wms">' + + ''; var snippet2 = '' + - ''; + ''; it('Version taken from document', function() { var parser = new ol.parser.ogc.WMSCapabilities(); var data = parser.read(snippet); @@ -28,7 +28,7 @@ describe('test WMSCapabilities', function() { expect(version).toEqual('1.3.0'); }); var msg = 'defaultVersion returned if no version specified in options ' + - 'and no version on the format'; + 'and no version on the format'; it(msg, function() { var version = parser.getVersion(null); expect(version).toEqual('1.1.1'); diff --git a/test/spec/ol/parser/ogc/wmscapabilities_v1_1_1.test.js b/test/spec/ol/parser/ogc/wmscapabilities_v1_1_1.test.js index 7d91002fbb..fd2f05c1eb 100644 --- a/test/spec/ol/parser/ogc/wmscapabilities_v1_1_1.test.js +++ b/test/spec/ol/parser/ogc/wmscapabilities_v1_1_1.test.js @@ -57,8 +57,8 @@ describe('ol.parser.ogc.wmscapabilities_v1_1_1', function() { expect(getfeatureinfo.post.href).toEqual(post); expect(capability.layers).toBeTruthy(); expect(capability.layers.length).toEqual(22); - var infoFormats = ['text/plain', 'text/html', - 'application/vnd.ogc.gml']; + var infoFormats = + ['text/plain', 'text/html', 'application/vnd.ogc.gml']; expect(layer.infoFormats).toEqual(infoFormats); expect(layer.name).toEqual('tiger:tiger_roads'); expect(layer.prefix).toEqual('tiger'); @@ -66,13 +66,13 @@ describe('ol.parser.ogc.wmscapabilities_v1_1_1', function() { var abstr = 'Highly simplified road layout of Manhattan in New York..'; expect(layer['abstract']).toEqual(abstr); var bbox = [-74.08769307536667, 40.660618924633326, - -73.84653192463333, 40.90178007536667]; + -73.84653192463333, 40.90178007536667]; expect(layer.llbbox).toEqual(bbox); expect(layer.styles.length).toEqual(1); expect(layer.styles[0].name).toEqual('tiger_roads'); var legend = 'http://publicus.opengeo.org:80/geoserver/wms/' + - 'GetLegendGraphic?VERSION=1.0.0&FORMAT=image/png&WIDTH=20&' + - 'HEIGHT=20&LAYER=tiger:tiger_roads'; + 'GetLegendGraphic?VERSION=1.0.0&FORMAT=image/png&WIDTH=20&' + + 'HEIGHT=20&LAYER=tiger:tiger_roads'; expect(layer.styles[0].legend.href).toEqual(legend); expect(layer.styles[0].legend.format).toEqual('image/png'); expect(layer.queryable).toBeTruthy(); @@ -168,28 +168,28 @@ describe('ol.parser.ogc.wmscapabilities_v1_1_1', function() { expect(elevation['default']).toEqual('0'); expect(elevation.nearestVal).toBeTruthy(); expect(elevation.multipleVal).toBeFalsy(); - expect(elevation.values).toEqual(['0', '1000', '3000', '5000', - '10000']); + expect(elevation.values).toEqual( + ['0', '1000', '3000', '5000', '10000']); }); }); }); describe('test contact info', function() { - it('Test contact info', function() { - var obj, service, contactinfo, personPrimary, addr; - runs(function() { - var url = 'spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/' + - 'ogcsample.xml'; - goog.net.XhrIo.send(url, function(e) { - var xhr = e.target; - obj = parser.read(xhr.getResponseXml()); - service = obj.service; - contactinfo = service.contactInformation; - personPrimary = contactinfo.personPrimary; - addr = contactinfo.contactAddress; - }); - }); - waitsFor(function() { + it('Test contact info', function() { + var obj, service, contactinfo, personPrimary, addr; + runs(function() { + var url = 'spec/ol/parser/ogc/xml/wmscapabilities_v1_1_1/' + + 'ogcsample.xml'; + goog.net.XhrIo.send(url, function(e) { + var xhr = e.target; + obj = parser.read(xhr.getResponseXml()); + service = obj.service; + contactinfo = service.contactInformation; + personPrimary = contactinfo.personPrimary; + addr = contactinfo.contactAddress; + }); + }); + waitsFor(function() { return (obj !== undefined); }, 'XHR timeout', 1000); runs(function() { diff --git a/test/spec/ol/parser/ogc/wmscapabilities_v1_1_1_WMSC.test.js b/test/spec/ol/parser/ogc/wmscapabilities_v1_1_1_WMSC.test.js index 517daa762c..d2d1faf355 100644 --- a/test/spec/ol/parser/ogc/wmscapabilities_v1_1_1_WMSC.test.js +++ b/test/spec/ol/parser/ogc/wmscapabilities_v1_1_1_WMSC.test.js @@ -25,7 +25,7 @@ describe('ol.parser.ogc.wmscapabilities_v1_1_1_wmsc', function() { runs(function() { expect(tilesets.length).toEqual(2); var bbox = [-13697515.466796875, 5165920.118906248, - -13619243.94984375, 5244191.635859374]; + -13619243.94984375, 5244191.635859374]; expect(tileset.bbox['EPSG:900913'].bbox).toEqual(bbox); expect(tileset.format).toEqual('image/png'); expect(tileset.height).toEqual(256); @@ -33,14 +33,14 @@ describe('ol.parser.ogc.wmscapabilities_v1_1_1_wmsc', function() { expect(tileset.layers).toEqual('medford:hydro'); expect(tileset.srs['EPSG:900913']).toBeTruthy(); var resolutions = [156543.03390625, 78271.516953125, 39135.7584765625, - 19567.87923828125, 9783.939619140625, 4891.9698095703125, - 2445.9849047851562, 1222.9924523925781, 611.4962261962891, - 305.74811309814453, 152.87405654907226, 76.43702827453613, - 38.218514137268066, 19.109257068634033, 9.554628534317017, - 4.777314267158508, 2.388657133579254, 1.194328566789627, - 0.5971642833948135, 0.29858214169740677, 0.14929107084870338, - 0.07464553542435169, 0.037322767712175846, 0.018661383856087923, - 0.009330691928043961, 0.004665345964021981]; + 19567.87923828125, 9783.939619140625, 4891.9698095703125, + 2445.9849047851562, 1222.9924523925781, 611.4962261962891, + 305.74811309814453, 152.87405654907226, 76.43702827453613, + 38.218514137268066, 19.109257068634033, 9.554628534317017, + 4.777314267158508, 2.388657133579254, 1.194328566789627, + 0.5971642833948135, 0.29858214169740677, 0.14929107084870338, + 0.07464553542435169, 0.037322767712175846, 0.018661383856087923, + 0.009330691928043961, 0.004665345964021981]; expect(tileset.resolutions).toEqual(resolutions); expect(tileset.styles).toEqual(''); }); diff --git a/test/spec/ol/parser/ogc/wmscapabilities_v1_3_0.test.js b/test/spec/ol/parser/ogc/wmscapabilities_v1_3_0.test.js index 8ddac8875a..b73ff2ff8f 100644 --- a/test/spec/ol/parser/ogc/wmscapabilities_v1_3_0.test.js +++ b/test/spec/ol/parser/ogc/wmscapabilities_v1_3_0.test.js @@ -100,8 +100,8 @@ describe('ol.parser.ogc.wmscapabilities_v1_3_0', function() { expect(elevation['default']).toEqual('0'); expect(elevation.nearestVal).toBeTruthy(); expect(elevation.multipleVal).toBeFalsy(); - expect(elevation.values).toEqual(['0', '1000', '3000', '5000', - '10000']); + expect(elevation.values).toEqual( + ['0', '1000', '3000', '5000', '10000']); expect(contactinfo).toBeTruthy(); expect(personPrimary).toBeTruthy(); expect(personPrimary.person).toEqual('Jeff Smith'); diff --git a/test/spec/ol/parser/ogc/wmtscapabilities_v1_0_0.test.js b/test/spec/ol/parser/ogc/wmtscapabilities_v1_0_0.test.js index af7b43cd8d..57077d340e 100644 --- a/test/spec/ol/parser/ogc/wmtscapabilities_v1_0_0.test.js +++ b/test/spec/ol/parser/ogc/wmtscapabilities_v1_0_0.test.js @@ -105,26 +105,24 @@ describe('ol.parser.ogc.wmtscapabilities_v1_0_0', function() { expect(wgs84Bbox.maxX).toEqual(180.0); expect(wgs84Bbox.minY).toEqual(-90.0); expect(wgs84Bbox.maxY).toEqual(90.0); - expect(layer.resourceUrl.tile.format).toEqual('image/png'); - var tpl = 'http://www.example.com/wmts/coastlines/{TileMatrix}/' + + expect(layer.resourceUrls.hasOwnProperty('tile')).toBeTruthy(); + var format = 'image/png'; + expect(layer.resourceUrls.tile.hasOwnProperty(format)).toBeTruthy(); + expect(layer.resourceUrls.tile[format].length).toEqual(2); + var tpl = 'http://a.example.com/wmts/coastlines/{TileMatrix}/' + '{TileRow}/{TileCol}.png'; - expect(layer.resourceUrl.tile.template).toEqual(tpl); - var format = 'application/gml+xml; version=3.1'; - expect(layer.resourceUrl.FeatureInfo.format).toEqual(format); - tpl = 'http://www.example.com/wmts/coastlines/{TileMatrixSet}/' + - '{TileMatrix}/{TileRow}/{TileCol}/{J}/{I}.xml'; - expect(layer.resourceUrl.FeatureInfo.template).toEqual(tpl); - expect(layer.resourceUrls[0].format).toEqual('image/png'); - expect(layer.resourceUrls[0].resourceType).toEqual('tile'); - tpl = 'http://www.example.com/wmts/coastlines/{TileMatrix}/' + - '{TileRow}/{TileCol}.png'; - expect(layer.resourceUrls[0].template).toEqual(tpl); + expect(layer.resourceUrls.tile[format][0]).toEqual(tpl); + tpl = 'http://b.example.com/wmts/coastlines/{TileMatrix}/' + + '{TileRow}/{TileCol}.png'; + expect(layer.resourceUrls.tile[format][1]).toEqual(tpl); + expect(layer.resourceUrls.hasOwnProperty('FeatureInfo')).toBeTruthy(); format = 'application/gml+xml; version=3.1'; - expect(layer.resourceUrls[1].format).toEqual(format); - expect(layer.resourceUrls[1].resourceType).toEqual('FeatureInfo'); + expect(layer.resourceUrls.FeatureInfo.hasOwnProperty(format)) + .toBeTruthy(); + expect(layer.resourceUrls.FeatureInfo[format].length).toEqual(1); tpl = 'http://www.example.com/wmts/coastlines/{TileMatrixSet}/' + - '{TileMatrix}/{TileRow}/{TileCol}/{J}/{I}.xml'; - expect(layer.resourceUrls[1].template).toEqual(tpl); + '{TileMatrix}/{TileRow}/{TileCol}/{J}/{I}.xml'; + expect(layer.resourceUrls.FeatureInfo[format][0]).toEqual(tpl); expect(dimensions.length).toEqual(1); expect(dimensions[0].title).toEqual('Time'); expect(dimensions[0]['abstract']).toEqual('Monthly datasets'); @@ -180,4 +178,5 @@ describe('ol.parser.ogc.wmtscapabilities_v1_0_0', function() { }); goog.require('goog.net.XhrIo'); +goog.require('ol.Extent'); goog.require('ol.parser.ogc.WMTSCapabilities'); diff --git a/test/spec/ol/parser/ogc/xml/wmtscapabilities_v1_0_0/ogcsample.xml b/test/spec/ol/parser/ogc/xml/wmtscapabilities_v1_0_0/ogcsample.xml index 9f0f1bc690..0421214ffc 100644 --- a/test/spec/ol/parser/ogc/xml/wmtscapabilities_v1_0_0/ogcsample.xml +++ b/test/spec/ol/parser/ogc/xml/wmtscapabilities_v1_0_0/ogcsample.xml @@ -74,7 +74,9 @@ coastlines + template="http://a.example.com/wmts/coastlines/{TileMatrix}/{TileRow}/{TileCol}.png" /> +