Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
48c1d09a95 | ||
|
|
6092e6ecbb | ||
|
|
849b04b882 | ||
|
|
cc0452a2d9 | ||
|
|
cfe78f2766 | ||
|
|
b9fe59c269 | ||
|
|
a3b474623e | ||
|
|
04f070b159 | ||
|
|
14f575f207 | ||
|
|
8a69f1f6ea | ||
|
|
aa7e54833d | ||
|
|
39abb2b143 | ||
|
|
d90bfbde58 | ||
|
|
e0a9910d4e | ||
|
|
7834a95210 | ||
|
|
f4d12ad448 | ||
|
|
5d5d49ad12 | ||
|
|
a2a2a53e08 | ||
|
|
9d5453a927 | ||
|
|
1bd11c1958 | ||
|
|
767bec4dc7 | ||
|
|
70338b928e | ||
|
|
dd6b05b285 | ||
|
|
e59b90377f | ||
|
|
e0a0804040 | ||
|
|
f973eaa24d | ||
|
|
2fe4d63893 | ||
|
|
908f254bd2 | ||
|
|
2132a02f76 | ||
|
|
78f283c32b | ||
|
|
9659d8598c | ||
|
|
42d1c51cbb | ||
|
|
c34f097ffd | ||
|
|
0a2b145fd5 | ||
|
|
0f8d26d829 | ||
|
|
2a1a9ec337 | ||
|
|
5627a467cd |
@@ -1,7 +1,7 @@
|
||||
# OpenLayers 3
|
||||
|
||||
[](http://travis-ci.org/#!/openlayers/ol3)
|
||||
[](https://coveralls.io/r/openlayers/ol3?branch=master)
|
||||
[](https://coveralls.io/github/openlayers/ol3?branch=master)
|
||||
[](http://osgeo.org/)
|
||||
|
||||
[OpenLayers 3](https://openlayers.org/) is a high-performance, feature-packed library for creating interactive maps on the web. It can display map tiles, vector data and markers loaded from any source on any web page. OpenLayers has been developed to further the use of geographic information of all kinds. It is completely free, Open Source JavaScript, released under the 2-clause BSD License (also known as the FreeBSD).
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
## Upgrade notes
|
||||
|
||||
### v3.19.1
|
||||
|
||||
#### `ol.style.Fill` with `CanvasGradient` or `CanvasPattern`
|
||||
|
||||
The origin for gradients and patterns has changed from `[0, 0]` to the top-left
|
||||
corner of the extent of the geometry being filled.
|
||||
|
||||
### v3.19.0
|
||||
|
||||
#### `ol.style.Fill` with `CanvasGradient` or `CanvasPattern`
|
||||
|
||||
22
changelog/v3.19.1.md
Normal file
22
changelog/v3.19.1.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# v3.19.1
|
||||
|
||||
## Summary
|
||||
|
||||
The v3.19.1 release is a patch release that addresses four regressions in the
|
||||
v3.19.0 release. See the
|
||||
[v3.19.0 release notes](https://github.com/openlayers/ol3/releases/tag/v3.19.0)
|
||||
for details on upgrading from v3.18.x.
|
||||
|
||||
## Upgrade notes
|
||||
|
||||
#### `ol.style.Fill` with `CanvasGradient` or `CanvasPattern`
|
||||
|
||||
The origin for gradients and patterns has changed from `[0, 0]` to the top-left
|
||||
corner of the extent of the geometry being filled.
|
||||
|
||||
## Fixes
|
||||
|
||||
* [#6039](https://github.com/openlayers/ol3/pull/6039) - Do not fill when there is no fillStyle ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#6034](https://github.com/openlayers/ol3/pull/6034) - Use geometry extent's top left corner as pattern/gradient origin ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#6027](https://github.com/openlayers/ol3/pull/6027) - Close polygon sketch at all times ([@bjornharrtell](https://github.com/bjornharrtell))
|
||||
* [#6022](https://github.com/openlayers/ol3/pull/6022) - Revert "Merge pull request #5890 from ahocevar/no-white-lines" ([@ahocevar](https://github.com/ahocevar))
|
||||
@@ -9,7 +9,7 @@ If you're eager to get your first OpenLayers 3 map on a page, dive into the [qui
|
||||
|
||||
For a more in-depth overview of OpenLayers 3 core concepts, check out the [tutorials](tutorials/).
|
||||
|
||||
Make sure to also check out the [OpenLayers 3 workshop](/workshop/en/).
|
||||
Make sure to also check out the [OpenLayers 3 workshop](/workshop/).
|
||||
|
||||
Find additional reference material in the [API docs](../apidoc).
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.format.GeoJSON');
|
||||
goog.require('ol.has');
|
||||
goog.require('ol.layer.Vector');
|
||||
@@ -20,11 +21,11 @@ var pixelRatio = ol.has.DEVICE_PIXEL_RATIO;
|
||||
function gradient(feature, resolution) {
|
||||
var extent = feature.getGeometry().getExtent();
|
||||
// Gradient starts on the left edge of each feature, and ends on the right.
|
||||
// Coordinate origin is [0, 0], so we just divide by resolution and multiply
|
||||
// with pixelRatio to match the renderer's pixel coordinate system.
|
||||
var grad = context.createLinearGradient(
|
||||
extent[0] / resolution * pixelRatio, 0,
|
||||
extent[2] / resolution * pixelRatio, 0);
|
||||
// Coordinate origin is the top-left corner of the extent of the geometry, so
|
||||
// we just divide the geometry's extent width by resolution and multiply with
|
||||
// pixelRatio to match the renderer's pixel coordinate system.
|
||||
var grad = context.createLinearGradient(0, 0,
|
||||
ol.extent.getWidth(extent) / resolution * pixelRatio, 0);
|
||||
grad.addColorStop(0, 'red');
|
||||
grad.addColorStop(1 / 6, 'orange');
|
||||
grad.addColorStop(2 / 6, 'yellow');
|
||||
|
||||
@@ -2935,6 +2935,7 @@ olx.interaction.ModifyOptions.prototype.wrapX;
|
||||
|
||||
/**
|
||||
* @typedef {{duration: (number|undefined),
|
||||
* timeout: (number|undefined),
|
||||
* useAnchor: (boolean|undefined)}}
|
||||
*/
|
||||
olx.interaction.MouseWheelZoomOptions;
|
||||
@@ -2948,6 +2949,14 @@ olx.interaction.MouseWheelZoomOptions;
|
||||
olx.interaction.MouseWheelZoomOptions.prototype.duration;
|
||||
|
||||
|
||||
/**
|
||||
* Mouse wheel timeout duration in milliseconds. Default is `80`.
|
||||
* @type {number|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.interaction.MouseWheelZoomOptions.prototype.timeout;
|
||||
|
||||
|
||||
/**
|
||||
* Enable zooming using the mouse's location as the anchor. Default is `true`.
|
||||
* When set to false, zooming in and out will zoom to the center of the screen
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "openlayers",
|
||||
"version": "3.19.0",
|
||||
"version": "3.19.1",
|
||||
"description": "Build tools and sources for developing OpenLayers based mapping applications",
|
||||
"keywords": [
|
||||
"map",
|
||||
@@ -31,7 +31,7 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"async": "2.1.2",
|
||||
"browserify": "13.1.0",
|
||||
"browserify": "13.1.1",
|
||||
"closure-util": "1.15.1",
|
||||
"derequire": "2.0.3",
|
||||
"fs-extra": "0.30.0",
|
||||
@@ -39,7 +39,7 @@
|
||||
"handlebars": "4.0.5",
|
||||
"jsdoc": "3.4.2",
|
||||
"marked": "0.3.6",
|
||||
"metalsmith": "2.2.0",
|
||||
"metalsmith": "2.2.1",
|
||||
"metalsmith-layouts": "1.6.5",
|
||||
"nomnom": "1.8.1",
|
||||
"pbf": "3.0.2",
|
||||
|
||||
@@ -307,18 +307,6 @@ ol.extent.createOrUpdateFromRings = function(rings, opt_extent) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Empty an extent in place.
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @return {ol.Extent} Extent.
|
||||
*/
|
||||
ol.extent.empty = function(extent) {
|
||||
extent[0] = extent[1] = Infinity;
|
||||
extent[2] = extent[3] = -Infinity;
|
||||
return extent;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Determine if two extents are equivalent.
|
||||
* @param {ol.Extent} extent1 Extent 1.
|
||||
@@ -720,29 +708,6 @@ ol.extent.isEmpty = function(extent) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @return {boolean} Is infinite.
|
||||
*/
|
||||
ol.extent.isInfinite = function(extent) {
|
||||
return extent[0] == -Infinity || extent[1] == -Infinity ||
|
||||
extent[2] == Infinity || extent[3] == Infinity;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {ol.Coordinate} coordinate Coordinate.
|
||||
* @return {ol.Coordinate} Coordinate.
|
||||
*/
|
||||
ol.extent.normalize = function(extent, coordinate) {
|
||||
return [
|
||||
(coordinate[0] - extent[0]) / (extent[2] - extent[0]),
|
||||
(coordinate[1] - extent[1]) / (extent[3] - extent[1])
|
||||
];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {ol.Extent=} opt_extent Extent.
|
||||
@@ -831,19 +796,6 @@ ol.extent.intersectsSegment = function(extent, start, end) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Extent} extent1 Extent 1.
|
||||
* @param {ol.Extent} extent2 Extent 2.
|
||||
* @return {boolean} Touches.
|
||||
*/
|
||||
ol.extent.touches = function(extent1, extent2) {
|
||||
var intersects = ol.extent.intersects(extent1, extent2);
|
||||
return intersects &&
|
||||
(extent1[0] == extent2[2] || extent1[2] == extent2[0] ||
|
||||
extent1[1] == extent2[3] || extent1[3] == extent2[1]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Apply a transform function to the extent.
|
||||
* @param {ol.Extent} extent Extent.
|
||||
|
||||
@@ -142,12 +142,6 @@ ol.MAX_ATLAS_SIZE = -1;
|
||||
ol.MOUSEWHEELZOOM_MAXDELTA = 1;
|
||||
|
||||
|
||||
/**
|
||||
* @define {number} Mouse wheel timeout duration.
|
||||
*/
|
||||
ol.MOUSEWHEELZOOM_TIMEOUT_DURATION = 80;
|
||||
|
||||
|
||||
/**
|
||||
* @define {number} Maximum width and/or height extent ratio that determines
|
||||
* when the overview map should be zoomed out.
|
||||
|
||||
@@ -152,7 +152,11 @@ ol.interaction.Draw = function(options) {
|
||||
geometryFunction = function(coordinates, opt_geometry) {
|
||||
var geometry = opt_geometry;
|
||||
if (geometry) {
|
||||
geometry.setCoordinates(coordinates);
|
||||
if (mode === ol.interaction.Draw.Mode.POLYGON) {
|
||||
geometry.setCoordinates([coordinates[0].concat([coordinates[0][0]])]);
|
||||
} else {
|
||||
geometry.setCoordinates(coordinates);
|
||||
}
|
||||
} else {
|
||||
geometry = new Constructor(coordinates);
|
||||
}
|
||||
@@ -617,12 +621,10 @@ ol.interaction.Draw.prototype.finishDrawing = function() {
|
||||
coordinates.pop();
|
||||
this.geometryFunction_(coordinates, geometry);
|
||||
} else if (this.mode_ === ol.interaction.Draw.Mode.POLYGON) {
|
||||
// When we finish drawing a polygon on the last point,
|
||||
// the last coordinate is duplicated as for LineString
|
||||
// we force the replacement by the first point
|
||||
// remove the redundant last point in ring
|
||||
coordinates[0].pop();
|
||||
coordinates[0].push(coordinates[0][0]);
|
||||
this.geometryFunction_(coordinates, geometry);
|
||||
coordinates = geometry.getCoordinates();
|
||||
}
|
||||
|
||||
// cast multi-part geometries
|
||||
|
||||
@@ -36,6 +36,12 @@ ol.interaction.MouseWheelZoom = function(opt_options) {
|
||||
*/
|
||||
this.duration_ = options.duration !== undefined ? options.duration : 250;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.timeout_ = options.timeout !== undefined ? options.timeout : 80;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
@@ -109,8 +115,7 @@ ol.interaction.MouseWheelZoom.handleEvent = function(mapBrowserEvent) {
|
||||
this.startTime_ = Date.now();
|
||||
}
|
||||
|
||||
var duration = ol.MOUSEWHEELZOOM_TIMEOUT_DURATION;
|
||||
var timeLeft = Math.max(duration - (Date.now() - this.startTime_), 0);
|
||||
var timeLeft = Math.max(this.timeout_ - (Date.now() - this.startTime_), 0);
|
||||
|
||||
clearTimeout(this.timeoutId_);
|
||||
this.timeoutId_ = setTimeout(
|
||||
|
||||
@@ -132,7 +132,7 @@ ol.render.canvas.PolygonReplay.prototype.drawCircle = function(circleGeometry, f
|
||||
ol.DEBUG && console.assert(state.lineWidth !== undefined,
|
||||
'state.lineWidth should be defined');
|
||||
}
|
||||
this.setFillStrokeStyles_();
|
||||
this.setFillStrokeStyles_(circleGeometry);
|
||||
this.beginGeometry(circleGeometry, feature);
|
||||
// always fill the circle for hit detection
|
||||
this.hitDetectionInstructions.push(
|
||||
@@ -182,7 +182,7 @@ ol.render.canvas.PolygonReplay.prototype.drawPolygon = function(polygonGeometry,
|
||||
ol.DEBUG && console.assert(state.lineWidth !== undefined,
|
||||
'state.lineWidth should be defined');
|
||||
}
|
||||
this.setFillStrokeStyles_();
|
||||
this.setFillStrokeStyles_(polygonGeometry);
|
||||
this.beginGeometry(polygonGeometry, feature);
|
||||
// always fill the polygon for hit detection
|
||||
this.hitDetectionInstructions.push(
|
||||
@@ -217,7 +217,7 @@ ol.render.canvas.PolygonReplay.prototype.drawMultiPolygon = function(multiPolygo
|
||||
ol.DEBUG && console.assert(state.lineWidth !== undefined,
|
||||
'state.lineWidth should be defined');
|
||||
}
|
||||
this.setFillStrokeStyles_();
|
||||
this.setFillStrokeStyles_(multiPolygonGeometry);
|
||||
this.beginGeometry(multiPolygonGeometry, feature);
|
||||
// always fill the multi-polygon for hit detection
|
||||
this.hitDetectionInstructions.push(
|
||||
@@ -332,8 +332,9 @@ ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyle = function(fillStyle
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {ol.geom.Geometry|ol.render.Feature} geometry Geometry.
|
||||
*/
|
||||
ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyles_ = function() {
|
||||
ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyles_ = function(geometry) {
|
||||
var state = this.state_;
|
||||
var fillStyle = state.fillStyle;
|
||||
var strokeStyle = state.strokeStyle;
|
||||
@@ -342,9 +343,13 @@ ol.render.canvas.PolygonReplay.prototype.setFillStrokeStyles_ = function() {
|
||||
var lineJoin = state.lineJoin;
|
||||
var lineWidth = state.lineWidth;
|
||||
var miterLimit = state.miterLimit;
|
||||
if (fillStyle !== undefined && state.currentFillStyle != fillStyle) {
|
||||
this.instructions.push(
|
||||
[ol.render.canvas.Instruction.SET_FILL_STYLE, fillStyle, typeof fillStyle != 'string']);
|
||||
if (fillStyle !== undefined && (typeof fillStyle !== 'string' || state.currentFillStyle != fillStyle)) {
|
||||
var fillInstruction = [ol.render.canvas.Instruction.SET_FILL_STYLE, fillStyle];
|
||||
if (typeof fillStyle !== 'string') {
|
||||
var fillExtent = geometry.getExtent();
|
||||
fillInstruction.push([fillExtent[0], fillExtent[3]]);
|
||||
}
|
||||
this.instructions.push(fillInstruction);
|
||||
state.currentFillStyle = state.fillStyle;
|
||||
}
|
||||
if (strokeStyle !== undefined) {
|
||||
|
||||
@@ -60,9 +60,9 @@ ol.render.canvas.Replay = function(tolerance, maxExtent, resolution, overlaps) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean}
|
||||
* @type {ol.Coordinate}
|
||||
*/
|
||||
this.alignFill_ = false;
|
||||
this.fillOrigin_;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -194,18 +194,17 @@ ol.render.canvas.Replay.prototype.beginGeometry = function(geometry, feature) {
|
||||
/**
|
||||
* @private
|
||||
* @param {CanvasRenderingContext2D} context Context.
|
||||
* @param {ol.Transform} transform Transform.
|
||||
* @param {number} rotation Rotation.
|
||||
*/
|
||||
ol.render.canvas.Replay.prototype.fill_ = function(context, transform, rotation) {
|
||||
if (this.alignFill_) {
|
||||
context.translate(transform[4], transform[5]);
|
||||
ol.render.canvas.Replay.prototype.fill_ = function(context, rotation) {
|
||||
if (this.fillOrigin_) {
|
||||
var origin = ol.transform.apply(this.renderedTransform_, this.fillOrigin_.slice());
|
||||
context.translate(origin[0], origin[1]);
|
||||
context.rotate(rotation);
|
||||
}
|
||||
context.fill();
|
||||
if (this.alignFill_) {
|
||||
context.rotate(-rotation);
|
||||
context.translate(-transform[4], -transform[5]);
|
||||
if (this.fillOrigin_) {
|
||||
context.setTransform.apply(context, this.resetTransform_);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -275,7 +274,7 @@ ol.render.canvas.Replay.prototype.replay_ = function(
|
||||
break;
|
||||
case ol.render.canvas.Instruction.BEGIN_PATH:
|
||||
if (pendingFill > batchSize) {
|
||||
this.fill_(context, transform, viewRotation);
|
||||
this.fill_(context, viewRotation);
|
||||
pendingFill = 0;
|
||||
}
|
||||
if (pendingStroke > batchSize) {
|
||||
@@ -452,7 +451,7 @@ ol.render.canvas.Replay.prototype.replay_ = function(
|
||||
if (batchSize) {
|
||||
pendingFill++;
|
||||
} else {
|
||||
this.fill_(context, transform, viewRotation);
|
||||
this.fill_(context, viewRotation);
|
||||
}
|
||||
++i;
|
||||
break;
|
||||
@@ -490,10 +489,10 @@ ol.render.canvas.Replay.prototype.replay_ = function(
|
||||
ol.colorlike.isColorLike(instruction[1]),
|
||||
'2nd instruction should be a string, ' +
|
||||
'CanvasPattern, or CanvasGradient');
|
||||
this.alignFill_ = instruction[2];
|
||||
this.fillOrigin_ = instruction[2];
|
||||
|
||||
if (pendingFill) {
|
||||
this.fill_(context, transform, viewRotation);
|
||||
this.fill_(context, viewRotation);
|
||||
pendingFill = 0;
|
||||
}
|
||||
|
||||
@@ -559,7 +558,7 @@ ol.render.canvas.Replay.prototype.replay_ = function(
|
||||
}
|
||||
}
|
||||
if (pendingFill) {
|
||||
this.fill_(context, transform, viewRotation);
|
||||
this.fill_(context, viewRotation);
|
||||
}
|
||||
if (pendingStroke) {
|
||||
context.stroke();
|
||||
|
||||
@@ -12,7 +12,6 @@ goog.require('ol.extent');
|
||||
goog.require('ol.render.canvas');
|
||||
goog.require('ol.render.Event');
|
||||
goog.require('ol.renderer.canvas.Layer');
|
||||
goog.require('ol.size');
|
||||
|
||||
|
||||
/**
|
||||
@@ -216,7 +215,7 @@ ol.renderer.canvas.TileLayer.prototype.forEachLayerAtPixel = function(
|
||||
*/
|
||||
ol.renderer.canvas.TileLayer.prototype.renderTileImages = function(context, frameState, layerState) {
|
||||
var tilesToDraw = this.renderedTiles;
|
||||
if (tilesToDraw.length == 0) {
|
||||
if (tilesToDraw.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -264,17 +263,6 @@ ol.renderer.canvas.TileLayer.prototype.renderTileImages = function(context, fram
|
||||
var alpha = renderContext.globalAlpha;
|
||||
renderContext.globalAlpha = layerState.opacity;
|
||||
|
||||
// Origin of the lowest resolution tile that contains the map center. We will
|
||||
// try to use the same origin for all resolutions for pixel-perfect tile
|
||||
// alignment across resolutions.
|
||||
var lowResTileCoord = tilesToDraw[0].getTileCoord();
|
||||
var minZOrigin = ol.extent.getBottomLeft(tileGrid.getTileCoordExtent(
|
||||
tileGrid.getTileCoordForCoordAndZ(center,
|
||||
lowResTileCoord[0], this.tmpTileCoord_), this.tmpExtent));
|
||||
var maxZ = tilesToDraw[tilesToDraw.length - 1].getTileCoord()[0];
|
||||
var maxZResolution = tileGrid.getResolution(maxZ);
|
||||
var maxZTileSize = ol.size.toSize(tileGrid.getTileSize(maxZ));
|
||||
|
||||
var pixelExtents;
|
||||
var opaque = source.getOpaque(projection) && layerState.opacity == 1;
|
||||
if (!opaque) {
|
||||
@@ -317,23 +305,17 @@ ol.renderer.canvas.TileLayer.prototype.renderTileImages = function(context, fram
|
||||
for (var i = 0, ii = tilesToDraw.length; i < ii; ++i) {
|
||||
var tile = tilesToDraw[i];
|
||||
var tileCoord = tile.getTileCoord();
|
||||
var tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent);
|
||||
var currentZ = tileCoord[0];
|
||||
var tileSize = ol.size.toSize(tileGrid.getTileSize(currentZ));
|
||||
// Calculate all insert points by tile widths from a common origin to avoid
|
||||
// gaps caused by rounding
|
||||
var originTileCoord = tileGrid.getTileCoordForCoordAndZ(minZOrigin, currentZ, this.tmpTileCoord_);
|
||||
var origin = ol.extent.getBottomLeft(tileGrid.getTileCoordExtent(originTileCoord, this.tmpExtent));
|
||||
// Calculate tile width and height by a tile size factor from the highest
|
||||
// resolution tile size to avoid gaps when combining tiles from different
|
||||
// resolutions
|
||||
var resolutionFactor = tileGrid.getResolution(currentZ) / maxZResolution;
|
||||
var tileSizeFactorW = tileSize[0] / maxZTileSize[0] * resolutionFactor;
|
||||
var tileSizeFactorH = tileSize[1] / maxZTileSize[1] * resolutionFactor;
|
||||
var w = Math.round(maxZTileSize[0] / resolution * maxZResolution * pixelRatio * drawScale) * tileSizeFactorW;
|
||||
var h = Math.round(maxZTileSize[1] / resolution * maxZResolution * pixelRatio * drawScale) * tileSizeFactorH;
|
||||
var left = (tileCoord[1] - originTileCoord[1]) * w +
|
||||
var origin = ol.extent.getBottomLeft(tileGrid.getTileCoordExtent(
|
||||
tileGrid.getTileCoordForCoordAndZ(center, currentZ, this.tmpTileCoord_)));
|
||||
var w = Math.round(ol.extent.getWidth(tileExtent) * pixelScale);
|
||||
var h = Math.round(ol.extent.getHeight(tileExtent) * pixelScale);
|
||||
var left = Math.round((tileExtent[0] - origin[0]) * pixelScale / w) * w +
|
||||
offsetX + Math.round((origin[0] - center[0]) * pixelScale);
|
||||
var top = (originTileCoord[2] - tileCoord[2] - 1) * h +
|
||||
var top = Math.round((origin[1] - tileExtent[3]) * pixelScale / h) * h +
|
||||
offsetY + Math.round((center[1] - origin[1]) * pixelScale);
|
||||
if (!opaque) {
|
||||
var pixelExtent = [left, top, left + w, top + h];
|
||||
|
||||
@@ -55,10 +55,25 @@ ol.source.TileArcGISRest = function(opt_options) {
|
||||
*/
|
||||
this.tmpExtent_ = ol.extent.createEmpty();
|
||||
|
||||
this.setKey(this.getKeyForParams_());
|
||||
};
|
||||
ol.inherits(ol.source.TileArcGISRest, ol.source.TileImage);
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @return {string} The key for the current params.
|
||||
*/
|
||||
ol.source.TileArcGISRest.prototype.getKeyForParams_ = function() {
|
||||
var i = 0;
|
||||
var res = [];
|
||||
for (var key in this.params_) {
|
||||
res[i++] = key + '-' + this.params_[key];
|
||||
}
|
||||
return res.join('/');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the user-provided params, i.e. those passed to the constructor through
|
||||
* the "params" option, and possibly updated using the updateParams method.
|
||||
@@ -168,5 +183,5 @@ ol.source.TileArcGISRest.prototype.fixedTileUrlFunction = function(tileCoord, pi
|
||||
*/
|
||||
ol.source.TileArcGISRest.prototype.updateParams = function(params) {
|
||||
ol.obj.assign(this.params_, params);
|
||||
this.changed();
|
||||
this.setKey(this.getKeyForParams_());
|
||||
};
|
||||
|
||||
@@ -121,7 +121,9 @@ ol.Color;
|
||||
/**
|
||||
* A type accepted by CanvasRenderingContext2D.fillStyle
|
||||
* or CanvasRenderingContext2D.strokeStyle.
|
||||
* Represents a color, pattern, or gradient.
|
||||
* Represents a color, pattern, or gradient. The origin for patterns and
|
||||
* gradients as fill style is the top-left corner of the extent of the geometry
|
||||
* being filled.
|
||||
*
|
||||
* @typedef {string|CanvasPattern|CanvasGradient}
|
||||
*/
|
||||
|
||||
@@ -20,6 +20,8 @@ var backupDir = path.join(__dirname, '../src-backup');
|
||||
var instrumentedDir = path.join(__dirname, '../src-instrumented');
|
||||
var coverageDir = path.join(__dirname, '../coverage');
|
||||
|
||||
fs.mkdirSync(coverageDir);
|
||||
|
||||
// The main players in the coverage generation via istanbul
|
||||
var instrumenter = new istanbul.Instrumenter();
|
||||
var reporter = new istanbul.Reporter(false, coverageDir);
|
||||
@@ -76,16 +78,23 @@ var revertBackupAndInstrumentationDir = function() {
|
||||
fs.removeSync(instrumentedDir);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Callback for when runTestsuite() has finished.
|
||||
*/
|
||||
var collectAndWriteCoverageData = function() {
|
||||
log('• collect data from coverage.json');
|
||||
log('• collect data from coverage *.json files');
|
||||
|
||||
var coverageFile = path.join(__dirname,'../coverage/coverage.json');
|
||||
var coverageJson = JSON.parse(fs.readFileSync(coverageFile, 'utf8'));
|
||||
collector.add(coverageJson);
|
||||
var coverageFiles = [
|
||||
path.join(__dirname, '..', 'coverage', 'coverage.json'),
|
||||
path.join(__dirname, '..', 'coverage', 'coverage-rendering.json')
|
||||
];
|
||||
coverageFiles.forEach(function(coverageFile) {
|
||||
if (fs.existsSync(coverageFile)) {
|
||||
log(' • collect data from ' + path.basename(coverageFile));
|
||||
var coverageJson = JSON.parse(fs.readFileSync(coverageFile, 'utf8'));
|
||||
collector.add(coverageJson);
|
||||
}
|
||||
});
|
||||
|
||||
reporter.addAll(['lcovonly','html']);
|
||||
|
||||
@@ -97,6 +106,44 @@ var collectAndWriteCoverageData = function() {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Runs the rendering test by spawning a call to `make test-rendering`. The
|
||||
* `make`-call sets up certain things so that the rendering tests can actually
|
||||
* run, which is why we call it this way.
|
||||
*
|
||||
* @param {Function} callback The callback to invoke once `make` has exited.
|
||||
* Will receive the exit code.
|
||||
*/
|
||||
var runRenderingTestsuite = function(callback) {
|
||||
var spawn = require('child_process').spawn;
|
||||
var child = spawn('make', ['test-rendering'], {stdio: 'inherit'});
|
||||
child.on('exit', function(code) {
|
||||
callback(code);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Derive output file name from input file name, by replacing the *last*
|
||||
* occurence of `/src/` by `/src-instrumented/`
|
||||
*
|
||||
* @param {String} file The input filename.
|
||||
* @return {String} file The output filename.
|
||||
*/
|
||||
var outputFilenameByFilename = function(file) {
|
||||
var search = '/src/';
|
||||
var replace = '/src-instrumented/';
|
||||
var re = new RegExp(search, 'g');
|
||||
var m, match;
|
||||
while ((m = re.exec(file)) !== null) {
|
||||
match = m;
|
||||
}
|
||||
var idx = match.index;
|
||||
var outfile = file.substr(0, idx) + replace +
|
||||
file.substr(idx + search.length);
|
||||
|
||||
return outfile;
|
||||
};
|
||||
|
||||
/**
|
||||
* Will instrument all JavaScript files that are passed as second parameter.
|
||||
* This is the callback to the glob call.
|
||||
@@ -113,15 +160,7 @@ var foundAllJavaScriptSourceFiles = function(err, files) {
|
||||
files.forEach(function(file) {
|
||||
cnt++;
|
||||
var content = fs.readFileSync(file, 'utf-8');
|
||||
// derive output file name from input file name, by replacing the *last*
|
||||
// occurence of /src/ by /src-instrumented/
|
||||
var re = new RegExp('/src/', 'g');
|
||||
var m, match;
|
||||
while ((m = re.exec(file)) !== null) {
|
||||
match = m;
|
||||
}
|
||||
var outfile = file.substr(0, match.index) + '/src-instrumented/' +
|
||||
file.substr(match.index + '/src/'.length);
|
||||
var outfile = outputFilenameByFilename(file);
|
||||
var instrumented = instrumenter.instrumentSync(content, file);
|
||||
fs.writeFileSync(outfile, instrumented);
|
||||
if (cnt % 10 === 0) {
|
||||
@@ -133,8 +172,25 @@ var foundAllJavaScriptSourceFiles = function(err, files) {
|
||||
|
||||
fs.copySync(instrumentedDir, dir, copyOpts);
|
||||
|
||||
log('• run test suite on instrumented code');
|
||||
runTestsuite({coverage: true, reporter: 'dot'}, collectAndWriteCoverageData);
|
||||
log('• run test suites on instrumented code');
|
||||
|
||||
log(' • run rendering test suite');
|
||||
runRenderingTestsuite(function(codeRendering) {
|
||||
if (codeRendering === 0) {
|
||||
log(' • run standard test suite');
|
||||
runTestsuite({coverage: true, reporter: 'dot'}, function(code) {
|
||||
if (code === 0) {
|
||||
collectAndWriteCoverageData();
|
||||
} else {
|
||||
process.stderr.write('Trouble running the standard testsuite\n');
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
process.stderr.write('Trouble running the rendering testsuite\n');
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -167,24 +167,6 @@ describe('ol.extent', function() {
|
||||
|
||||
});
|
||||
|
||||
describe('empty', function() {
|
||||
|
||||
it('returns the empty extent', function() {
|
||||
var extent = [1, 2, 3, 4];
|
||||
var expected = [Infinity, Infinity, -Infinity, -Infinity];
|
||||
var got = ol.extent.empty(extent);
|
||||
expect(got).to.eql(expected);
|
||||
});
|
||||
|
||||
it('empties a passed extent in place', function() {
|
||||
var extent = [1, 2, 3, 4];
|
||||
var expected = [Infinity, Infinity, -Infinity, -Infinity];
|
||||
ol.extent.empty(extent);
|
||||
expect(extent).to.eql(expected);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('forEachCorner', function() {
|
||||
|
||||
var callbackFalse;
|
||||
@@ -602,73 +584,6 @@ describe('ol.extent', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('isInfinite', function() {
|
||||
it('returns true for infinite extents', function() {
|
||||
var extents = [
|
||||
[-Infinity, 0, 0, 0],
|
||||
[0, -Infinity, 0, 0],
|
||||
[0, 0, +Infinity, 0],
|
||||
[0, 0, 0, +Infinity]
|
||||
];
|
||||
expect(ol.extent.isInfinite(extents[0])).to.be(true);
|
||||
expect(ol.extent.isInfinite(extents[1])).to.be(true);
|
||||
expect(ol.extent.isInfinite(extents[2])).to.be(true);
|
||||
expect(ol.extent.isInfinite(extents[3])).to.be(true);
|
||||
});
|
||||
it('returns false for other extents', function() {
|
||||
var extents = [
|
||||
ol.extent.createEmpty(),
|
||||
[1, 2, 3, 4]
|
||||
];
|
||||
expect(ol.extent.isInfinite(extents[0])).to.be(false);
|
||||
expect(ol.extent.isInfinite(extents[1])).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('touches', function() {
|
||||
|
||||
it('returns the expected value', function() {
|
||||
var touches = ol.extent.touches;
|
||||
var extent = [50, 50, 100, 100];
|
||||
expect(touches(extent, [20, 20, 80, 80])).to.be(false);
|
||||
expect(touches(extent, [20, 20, 50, 80])).to.be(true);
|
||||
expect(touches(extent, [20, 20, 50, 40])).to.be(false);
|
||||
expect(touches(extent, [100, 20, 140, 80])).to.be(true);
|
||||
expect(touches(extent, [100, 20, 140, 40])).to.be(false);
|
||||
expect(touches(extent, [20, 20, 80, 50])).to.be(true);
|
||||
expect(touches(extent, [20, 20, 40, 50])).to.be(false);
|
||||
expect(touches(extent, [20, 100, 80, 140])).to.be(true);
|
||||
expect(touches(extent, [20, 100, 40, 140])).to.be(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('normalize', function() {
|
||||
it('returns the expected coordinate', function() {
|
||||
var extent = [0, 1, 2, 3];
|
||||
var coordinate;
|
||||
|
||||
coordinate = ol.extent.normalize(extent, [1, 2]);
|
||||
expect(coordinate[0]).to.eql(0.5);
|
||||
expect(coordinate[1]).to.eql(0.5);
|
||||
|
||||
coordinate = ol.extent.normalize(extent, [0, 3]);
|
||||
expect(coordinate[0]).to.eql(0);
|
||||
expect(coordinate[1]).to.eql(1);
|
||||
|
||||
coordinate = ol.extent.normalize(extent, [2, 1]);
|
||||
expect(coordinate[0]).to.eql(1);
|
||||
expect(coordinate[1]).to.eql(0);
|
||||
|
||||
coordinate = ol.extent.normalize(extent, [0, 0]);
|
||||
expect(coordinate[0]).to.eql(0);
|
||||
expect(coordinate[1]).to.eql(-0.5);
|
||||
|
||||
coordinate = ol.extent.normalize(extent, [-1, 1]);
|
||||
expect(coordinate[0]).to.eql(-0.5);
|
||||
expect(coordinate[1]).to.eql(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('scaleFromCenter', function() {
|
||||
it('scales the extent from its center', function() {
|
||||
var extent = [1, 1, 3, 3];
|
||||
|
||||
@@ -494,21 +494,30 @@ describe('ol.interaction.Draw', function() {
|
||||
map.addInteraction(draw);
|
||||
});
|
||||
|
||||
function isClosed(polygon) {
|
||||
var first = polygon.getFirstCoordinate();
|
||||
var last = polygon.getLastCoordinate();
|
||||
expect(first).to.eql(last);
|
||||
}
|
||||
|
||||
it('draws polygon with clicks, finishing on first point', function() {
|
||||
// first point
|
||||
simulateEvent('pointermove', 10, 20);
|
||||
simulateEvent('pointerdown', 10, 20);
|
||||
simulateEvent('pointerup', 10, 20);
|
||||
isClosed(draw.sketchFeature_.getGeometry());
|
||||
|
||||
// second point
|
||||
simulateEvent('pointermove', 30, 20);
|
||||
simulateEvent('pointerdown', 30, 20);
|
||||
simulateEvent('pointerup', 30, 20);
|
||||
isClosed(draw.sketchFeature_.getGeometry());
|
||||
|
||||
// third point
|
||||
simulateEvent('pointermove', 40, 10);
|
||||
simulateEvent('pointerdown', 40, 10);
|
||||
simulateEvent('pointerup', 40, 10);
|
||||
isClosed(draw.sketchFeature_.getGeometry());
|
||||
|
||||
// finish on first point
|
||||
simulateEvent('pointermove', 10, 20);
|
||||
|
||||
@@ -27,6 +27,36 @@ describe('ol.interaction.MouseWheelZoom', function() {
|
||||
disposeMap(map);
|
||||
});
|
||||
|
||||
describe('timeout duration', function() {
|
||||
var clock;
|
||||
beforeEach(function() {
|
||||
clock = sinon.useFakeTimers();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
it('works with the defaut value', function(done) {
|
||||
var spy = sinon.spy(ol.interaction.Interaction, 'zoomByDelta');
|
||||
var event = new ol.MapBrowserEvent('mousewheel', map, {
|
||||
type: 'mousewheel',
|
||||
target: map.getViewport(),
|
||||
preventDefault: ol.events.Event.prototype.preventDefault
|
||||
});
|
||||
map.handleMapBrowserEvent(event);
|
||||
clock.tick(50);
|
||||
// default timeout is 80 ms, not called yet
|
||||
expect(spy.called).to.be(false);
|
||||
clock.tick(30);
|
||||
expect(spy.called).to.be(true);
|
||||
|
||||
ol.interaction.Interaction.zoomByDelta.restore();
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('handleEvent()', function() {
|
||||
it('[wheel] works on Firefox in DOM_DELTA_PIXEL mode', function(done) {
|
||||
var origHasFirefox = ol.has.FIREFOX;
|
||||
|
||||
@@ -31,6 +31,18 @@ describe('ol.obj.assign()', function() {
|
||||
|
||||
});
|
||||
|
||||
it('throws a TypeError with `undefined` as target', function() {
|
||||
expect(ol.obj.assign).withArgs(undefined).to.throwException(function(e) {
|
||||
expect(e).to.be.a(TypeError);
|
||||
});
|
||||
});
|
||||
|
||||
it('throws a TypeError with `null` as target', function() {
|
||||
expect(ol.obj.assign).withArgs(null).to.throwException(function(e) {
|
||||
expect(e).to.be.a(TypeError);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('ol.obj.clear()', function() {
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
@@ -19,8 +19,23 @@ page.open(url).then(function(status) {
|
||||
}
|
||||
console.error(failedTests.length + ' test(s) failed.');
|
||||
} else {
|
||||
// check for cov here
|
||||
var coverage = page.evaluate(function() {
|
||||
return window.__coverage__;
|
||||
});
|
||||
|
||||
if (coverage) {
|
||||
console.log('Writing coverage to coverage/coverage-rendering.json');
|
||||
var fs = require('fs');
|
||||
fs.write(
|
||||
fs.workingDirectory + '/coverage/coverage-rendering.json',
|
||||
JSON.stringify(coverage),
|
||||
'w'
|
||||
);
|
||||
}
|
||||
console.log('All tests passed.');
|
||||
}
|
||||
|
||||
page.close();
|
||||
phantom.exit(failedTests.length === 0 ? 0 : 1);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user