Compare commits

...

51 Commits
ls ... v4.3.3

Author SHA1 Message Date
Tim Schaub
288a284fdd Changes for v4.3.3 2017-09-15 06:15:49 -06:00
Andreas Hocevar
a5b3da1f8a Revert "Merge pull request #7098 from ahocevar/no-math-round"
This reverts commit 5b75666755, reversing
changes made to ff9ef481db.
2017-09-15 06:13:18 -06:00
Tim Schaub
6ed8a9229f Update package version to 4.3.2 2017-08-31 16:25:07 -06:00
Tim Schaub
60b2290add Changelog for v4.3.2 2017-08-31 16:24:14 -06:00
Frederic Junod
afcc86558c Export ol.Sphere.getLength and ol.Sphere.getArea 2017-08-31 16:20:15 -06:00
Tim Schaub
d218c4d454 Merge pull request #7124 from openlayers/release-v4.3.1
Release v4.3.1
2017-08-14 09:51:08 -04:00
Tim Schaub
81f37708c1 Bumping versions to 4.3.1 2017-08-14 09:49:12 -04:00
Tim Schaub
8b0c6196e6 Changelog for v4.3.1 2017-08-14 09:48:22 -04:00
Tim Schaub
93a9799e46 Merge pull request #7122 from tschaub/unanimated
Immediately complete no-op animations
2017-08-14 09:43:39 -04:00
Tim Schaub
7f0c8fe899 Use ol.coordinate.equals 2017-08-14 09:25:41 -04:00
Andreas Hocevar
b06efa387c Merge pull request #7120 from ahocevar/fix-overzoom-hitdetect
Fix hit detection for overzoomed vector tiles
2017-08-14 09:21:04 -04:00
Tim Schaub
48178f0e31 Immediately complete no-op animations 2017-08-14 09:08:50 -04:00
Frédéric Junod
d65cabebd6 Merge pull request #7114 from GaborFarkas/webgl_immediate
Immediate WebGL text renderer and other improvements
2017-08-14 14:33:45 +02:00
Andreas Hocevar
992cf2b2d6 Fix hit detection for overzoomed vector tiles 2017-08-13 22:53:58 -04:00
Tim Schaub
1249b46e5d Merge pull request #7118 from openlayers/release-v4.3.0
Release v4.3.0
2017-08-12 16:47:05 -06:00
Tim Schaub
4733a5d0f9 Bump versions to 4.3.0 2017-08-12 16:33:47 -06:00
Tim Schaub
dfe51e6195 Logging changes 2017-08-12 16:32:53 -06:00
Tim Schaub
24d1f4eac3 Update the readme 2017-08-12 16:12:31 -06:00
Tim Schaub
95bf18f6bd Merge pull request #7117 from tschaub/vector-tilegrid
Sensible default tilegrid for vector tiles
2017-08-12 15:57:16 -06:00
Tim Schaub
8b0ee6023e Merge pull request #7116 from openlayers/greenkeeper/rollup-0.47.2
fix(package): update rollup to version 0.47.2
2017-08-12 15:41:50 -06:00
Tim Schaub
29fcf5f1c2 Take advantage of default tile grid 2017-08-12 15:40:36 -06:00
Andreas Hocevar
952a2cfba3 Merge pull request #7111 from ahocevar/graticule-nowrap
Remove broken wrapX handling from ol.Graticule
2017-08-12 15:36:30 -06:00
Tim Schaub
3b444978a7 Upgrade notes for vector tiles 2017-08-12 15:17:01 -06:00
Tim Schaub
13a761b7e7 Sensible default tilegrid for vector tiles 2017-08-12 15:16:55 -06:00
greenkeeper[bot]
89080cf8dd fix(package): update rollup to version 0.47.2
Closes #7113
2017-08-12 13:54:12 +00:00
GaborFarkas
f1685cbe4f Add immediate WebGL text renderer 2017-08-12 14:52:08 +02:00
GaborFarkas
d3c2c7f96d Fix hole bridging issue freezing the renderer 2017-08-12 14:52:08 +02:00
GaborFarkas
bb593eaac8 Fix WebGL text offset direction 2017-08-12 14:52:08 +02:00
Andreas Hocevar
bfd94445f1 Remove broken wrapX handling from ol.Graticule 2017-08-11 11:00:33 -06:00
Tim Schaub
7c5a208e07 Merge pull request #7107 from openlayers/greenkeeper/rollup-0.46.0
Update rollup to the latest version 🚀
2017-08-11 09:29:47 -06:00
greenkeeper[bot]
b38336b17f fix(package): update rollup to version 0.46.0 2017-08-11 13:50:32 +00:00
Andreas Hocevar
1af4d35713 Merge pull request #7106 from openlayers/greenkeeper/proj4-2.4.4
Update proj4 to the latest version 🚀
2017-08-11 06:53:38 -06:00
Tim Schaub
f2c51cb39e Merge pull request #7105 from tschaub/sphere
Functions for spherical calculations
2017-08-10 20:47:38 -06:00
Tim Schaub
5f794ab562 Make options optional 2017-08-10 20:31:46 -06:00
Andreas Hocevar
f4752cee59 Update proj4 in examples and docs 2017-08-10 20:27:49 -06:00
greenkeeper[bot]
3629a66917 chore(package): update proj4 to version 2.4.4 2017-08-11 02:22:58 +00:00
Tim Schaub
35f79f401b Merge pull request #7104 from openlayers/greenkeeper/sinon-3.2.0
Update sinon to the latest version 🚀
2017-08-10 20:22:16 -06:00
Tim Schaub
a58f162ed9 Update the measure example 2017-08-10 20:20:47 -06:00
Tim Schaub
f3ebbf4b7c Correct units 2017-08-10 18:45:49 -06:00
Tim Schaub
94fb7ca5a6 Function for getting spherical area 2017-08-10 18:30:42 -06:00
Tim Schaub
92c62e5432 Function for getting great circle lengths 2017-08-10 18:05:21 -06:00
GaborFarkas
87391e7795 Fix method name in WebGL polygonreplay 2017-08-10 21:04:53 +02:00
GaborFarkas
87a10200e3 WebGL triangulation performance 2017-08-10 21:04:53 +02:00
Bart van den Eijnden
445c157ee3 Merge pull request #6807 from Jenselme/initialize-hasZ-gml3
Initialize hasZ in the constructor of GML3
2017-08-10 20:02:44 +02:00
Julien Enselme
15ddab7d0a Initialize hasZ in the constructor of GML3 2017-08-10 19:44:20 +02:00
greenkeeper[bot]
3d72cc73b8 chore(package): update sinon to version 3.2.0 2017-08-10 14:37:40 +00:00
Tim Schaub
1b20f89c93 Merge pull request #7102 from tschaub/drag-drop-source
Allow drag and drop interaction to be configured with a source
2017-08-10 07:51:56 -06:00
Tim Schaub
17b6088a79 Allow drag and drop interaction to be configured with a source 2017-08-10 07:10:13 -06:00
Bart van den Eijnden
23405b80a2 Merge pull request #6825 from oterral/tesselate
Read/write Tessellate tag in KML format
2017-08-10 13:27:40 +02:00
oterral
ca90157e9f Write all geometry's properties in KML 2017-05-17 16:58:59 +02:00
oterral
132634f10c Add parsing of Tessellate tag in KML fomat 2017-05-17 14:26:39 +02:00
43 changed files with 1095 additions and 177 deletions

View File

@@ -11,11 +11,14 @@
Use one of the following methods to use OpenLayers in your project:
- For use with mainstream bundlers and minifiers, install the [ol](https://www.npmjs.com/package/ol) npm package: `npm install ol`
- Use `ol.js` and `ol.css` from (cdnjs)[https://cdnjs.com/libraries/openlayers]
- Download the [latest release](https://openlayers.org/download/)
- Clone the repo: `git clone git@github.com:openlayers/openlayers.git`
- For use with Closure Library, install the [openlayers](https://npmjs.com/package/openlayers) npm package and read the [tutorial](http://openlayers.org/en/latest/doc/tutorials/closure.html).
* For use with webpack, Rollup, Browserify, or other module bundlers, install the [`ol` package](https://www.npmjs.com/package/ol):
```
npm install ol
```
* If you just want to add a `<script>` tag to test things out, you can link directly to one of the full builds from [cdnjs](https://cdnjs.com/libraries/openlayers) (not recommended for production)
* For use with Closure Library (rare), install the [`openlayers` package](https://npmjs.com/package/openlayers) and read the [tutorial](http://openlayers.org/en/latest/doc/tutorials/closure.html).
## Supported Browsers

View File

@@ -1,6 +1,29 @@
## Upgrade notes
### Next release
### Next Release
### v4.3.0
#### `ol.source.VectorTile` no longer requires a `tileGrid` option
By default, the `ol.source.VectorTile` constructor creates an XYZ tile grid (in Web Mercator) for 512 pixel tiles and assumes a max zoom level of 22. If you were creating a vector tile source with an explicit `tileGrid` option, you can now remove this.
Before:
```js
var source = new ol.source.VectorTile({
tileGrid: ol.tilegrid.createXYZ({tileSize: 512, maxZoom: 22}),
url: url
});
```
After:
```js
var source = new ol.source.VectorTile({
url: url
});
```
If you need to change the max zoom level, you can pass the source a `maxZoom` option. If you need to change the tile size, you can pass the source a `tileSize` option. If you need a completely custom tile grid, you can still pass the source a `tileGrid` option.
#### `ol.interaction.Modify` deletes with `alt` key only

216
changelog/v4.3.0.md Normal file
View File

@@ -0,0 +1,216 @@
# 4.3.0
## Summary
The v4.3.0 release includes features and fixes from 92 pull requests.
#### New `map.getFeaturesAtPixel()` method
When you want to get all features at a given pixel, use the new `map.getFeaturesAtPixel()` method.
Before:
```js
var features = [];
map.forEachFeatureAtPixel(pixel, function(feature) {
features.push(feature);
});
```
After:
```js
var features = map.getFeaturesAtPixel(pixel);
```
#### `ol.Sphere` functions for spherical measures
The new `ol.Sphere.getArea()` and `ol.Sphere.getLength()` methods can be used to calculate spherical measures on geometries. This is the recommended over using the `geometry.getArea()` or `geometry.getLength()` methods.
Bad:
```js
geometry.getArea();
```
Good:
```js
ol.Sphere.getArea(geometry);
```
#### `ol.interaction.DragAndDrop` can be configured with a vector source
It is now possible to configure the drag and drop interaction with a vector source:
```js
var dragAndDrop = new ol.interaction.DragAndDrop({source: source});
```
Any dropped features will replace all existing features on the source.
#### `ol.interaction.Modify` can be configured with a vector source
It is now possible to configure the modify interaction with a vector source (in addition to a feature collection):
```js
var modify = new ol.interaction.Modify({source: source});
```
With this configuration, all features on the source are eligible for modification while the interaction is active.
#### `ol.interaction.Modify` deletes with `alt` key only
To delete features with the modify interaction, press the `alt` key while clicking on an existing vertex. If you want to configure the modify interaction with a different delete condition, use the `deleteCondition` option. For example, to allow deletion on a single click with no modifier keys, configure the interaction like this:
```js
var interaction = new ol.interaction.Modify({
source: source,
deleteCondition: function(event) {
return ol.events.condition.noModifierKeys(event) && ol.events.condition.singleClick(event);
}
});
```
The motivation for this change is to make the modify, draw, and snap interactions all work well together. Previously, the use of these interactions with the default configuration would make it so you couldn't reliably add new vertices (click with no modifier) and delete existing vertices (click with no modifier).
#### `ol.source.VectorTile` no longer requires a `tileGrid` option
By default, the `ol.source.VectorTile` constructor creates an XYZ tile grid (in Web Mercator) for 512 pixel tiles and assumes a max zoom level of 22. If you were creating a vector tile source with an explicit `tileGrid` option, you can now remove this.
Before:
```js
var source = new ol.source.VectorTile({
tileGrid: ol.tilegrid.createXYZ({tileSize: 512, maxZoom: 22}),
url: url
});
```
After:
```js
var source = new ol.source.VectorTile({
url: url
});
```
If you need to change the max zoom level, you can pass the source a `maxZoom` option. If you need to change the tile size, you can pass the source a `tileSize` option. If you need a completely custom tile grid, you can still pass the source a `tileGrid` option.
#### `ol.source.VectorTile` no longer has a `tilePixelRatio` option
The `tilePixelRatio` option was only used for tiles in projections with `tile-pixels` as units. For tiles read with `ol.format.MVT` and the default tile loader, or tiles with the default pixel size of 4096 pixels, no changes are necessary. For the very rare cases that do not fall under these categories, a custom `tileLoadFunction` now needs to be configured on the `ol.source.VectorTile`. In addition to calling `tile.setFeatures()` and `tile.setProjection()`, it also needs to contain code like the following:
```js
var extent = tile.getFormat() instanceof ol.format.MVT ?
tile.getLastExtent() :
[0, 0, tilePixelRatio * tileSize, tilePixelRatio * tileSize];
tile.setExtent(extent);
```
#### `ol.animate` now takes the shortest arc for rotation animation
Usually rotation animations should animate along the shortest arc. There are rare occasions where a spinning animation effect is desired. So if you previously had something like
```js
map.getView().animate({
rotation: 2 * Math.PI,
duration: 2000
});
```
we recommend to split the animation into two parts and use different easing functions. The code below results in the same effect as the snippet above did with previous versions:
```js
map.getView().animate({
rotation: Math.PI,
easing: ol.easing.easeIn
}, {
rotation: 2 * Math.PI,
easing: ol.easing.easeOut
});
```
## Full List of Changes
* [#7117](https://github.com/openlayers/openlayers/pull/7117) - Sensible default tilegrid for vector tiles ([@tschaub](https://github.com/tschaub))
* [#7116](https://github.com/openlayers/openlayers/pull/7116) - fix(package): update rollup to version 0.47.2 ([@openlayers](https://github.com/openlayers))
* [#7111](https://github.com/openlayers/openlayers/pull/7111) - Remove broken wrapX handling from ol.Graticule ([@ahocevar](https://github.com/ahocevar))
* [#7107](https://github.com/openlayers/openlayers/pull/7107) - Update rollup to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#7106](https://github.com/openlayers/openlayers/pull/7106) - Update proj4 to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#7105](https://github.com/openlayers/openlayers/pull/7105) - Functions for spherical calculations ([@tschaub](https://github.com/tschaub))
* [#7104](https://github.com/openlayers/openlayers/pull/7104) - Update sinon to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#6807](https://github.com/openlayers/openlayers/pull/6807) - Initialize hasZ in the constructor of GML3 ([@Jenselme](https://github.com/Jenselme))
* [#7102](https://github.com/openlayers/openlayers/pull/7102) - Allow drag and drop interaction to be configured with a source ([@tschaub](https://github.com/tschaub))
* [#6825](https://github.com/openlayers/openlayers/pull/6825) - Read/write Tessellate tag in KML format ([@oterral](https://github.com/oterral))
* [#7098](https://github.com/openlayers/openlayers/pull/7098) - Use fractional coordinates for CSS positioning ([@ahocevar](https://github.com/ahocevar))
* [#7064](https://github.com/openlayers/openlayers/pull/7064) - Do not use Array.prototype.forEach when dealing with potentially large arrays ([@ahocevar](https://github.com/ahocevar))
* [#7093](https://github.com/openlayers/openlayers/pull/7093) - Allow modify interaction to be configured with a source ([@tschaub](https://github.com/tschaub))
* [#7096](https://github.com/openlayers/openlayers/pull/7096) - Add new Map#getFeaturesAtPixel method ([@ahocevar](https://github.com/ahocevar))
* [#7094](https://github.com/openlayers/openlayers/pull/7094) - Add missing zIndex options ([@icholy](https://github.com/icholy))
* [#7087](https://github.com/openlayers/openlayers/pull/7087) - Fix scale line for EPSG:4326 maps ([@ahocevar](https://github.com/ahocevar))
* [#7088](https://github.com/openlayers/openlayers/pull/7088) - Update sinon to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#7085](https://github.com/openlayers/openlayers/pull/7085) - Update eslint to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#7084](https://github.com/openlayers/openlayers/pull/7084) - Fix a typo in the street-labels example ([@ahocevar](https://github.com/ahocevar))
* [#7082](https://github.com/openlayers/openlayers/pull/7082) - Update eslint to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#7079](https://github.com/openlayers/openlayers/pull/7079) - Optimize custom renderer code, examples and API ([@ahocevar](https://github.com/ahocevar))
* [#7080](https://github.com/openlayers/openlayers/pull/7080) - Update jsdoc to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#7078](https://github.com/openlayers/openlayers/pull/7078) - Fix return type annotation of ol.layer.VectorTile.getSource ([@geosense](https://github.com/geosense))
* [#7073](https://github.com/openlayers/openlayers/pull/7073) - Make ol.layer.Group change handling consistent ([@gberaudo](https://github.com/gberaudo))
* [#7075](https://github.com/openlayers/openlayers/pull/7075) - Update sinon to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#7072](https://github.com/openlayers/openlayers/pull/7072) - Improve API docs for ol.VectorTile ([@ahocevar](https://github.com/ahocevar))
* [#7070](https://github.com/openlayers/openlayers/pull/7070) - Get tilePixelRatio from MVT tiles ([@ahocevar](https://github.com/ahocevar))
* [#7069](https://github.com/openlayers/openlayers/pull/7069) - Update mocha to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#7068](https://github.com/openlayers/openlayers/pull/7068) - Update fs-extra to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#7066](https://github.com/openlayers/openlayers/pull/7066) - Fix ol.interaction.Extent event type and documentation ([@ahocevar](https://github.com/ahocevar))
* [#7032](https://github.com/openlayers/openlayers/pull/7032) - Fix KML Export Icon Anchor ([@raiyni](https://github.com/raiyni))
* [#7065](https://github.com/openlayers/openlayers/pull/7065) - Only use API functions in example ([@ahocevar](https://github.com/ahocevar))
* [#7022](https://github.com/openlayers/openlayers/pull/7022) - Allow styles to configure a custom renderer ([@ahocevar](https://github.com/ahocevar))
* [#7061](https://github.com/openlayers/openlayers/pull/7061) - Update docs and issue and pull request instructions ([@ahocevar](https://github.com/ahocevar))
* [#7059](https://github.com/openlayers/openlayers/pull/7059) - Allow to configure Extent interaction with an extent ([@ahocevar](https://github.com/ahocevar))
* [#7060](https://github.com/openlayers/openlayers/pull/7060) - Removing invalid urn ([@wnordmann](https://github.com/wnordmann))
* [#7051](https://github.com/openlayers/openlayers/pull/7051) - Changing the EPSG3857.PROJECTION array assignment and adding urn:ogc:… ([@wnordmann](https://github.com/wnordmann))
* [#7045](https://github.com/openlayers/openlayers/pull/7045) - Respect pixelRatio when scaling images ([@ahocevar](https://github.com/ahocevar))
* [#7023](https://github.com/openlayers/openlayers/pull/7023) - Update tile size and resolutions of vector tile examples ([@ahocevar](https://github.com/ahocevar))
* [#7005](https://github.com/openlayers/openlayers/pull/7005) - Add spatial reference inside geometry in EsriFormat ([@Sol1du2](https://github.com/Sol1du2))
* [#7034](https://github.com/openlayers/openlayers/pull/7034) - Move non-build dependencies to devDependencies ([@probins](https://github.com/probins))
* [#7050](https://github.com/openlayers/openlayers/pull/7050) - Update sinon to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#6976](https://github.com/openlayers/openlayers/pull/6976) - Example - Earthquake Clusters - Change evt.type of interaction ([@ehanoj](https://github.com/ehanoj))
* [#7048](https://github.com/openlayers/openlayers/pull/7048) - Update sinon to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#7041](https://github.com/openlayers/openlayers/pull/7041) - Update eslint to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#7042](https://github.com/openlayers/openlayers/pull/7042) - Line dash offset ([@gkresic](https://github.com/gkresic))
* [#6980](https://github.com/openlayers/openlayers/pull/6980) - Added tileClass to TileWMS ([@ZachTRice](https://github.com/ZachTRice))
* [#7028](https://github.com/openlayers/openlayers/pull/7028) - Fix Graticule use of incorrect min/maxLon values ([@greggian](https://github.com/greggian))
* [#7021](https://github.com/openlayers/openlayers/pull/7021) - Update fs-extra to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#7018](https://github.com/openlayers/openlayers/pull/7018) - Update jsdoc to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#7015](https://github.com/openlayers/openlayers/pull/7015) - Update sinon to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#7014](https://github.com/openlayers/openlayers/pull/7014) - Update jsdoc to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#7013](https://github.com/openlayers/openlayers/pull/7013) - Remove ol.sphere.WGS84 and ol.sphere.NORMAL ([@tschaub](https://github.com/tschaub))
* [#6981](https://github.com/openlayers/openlayers/pull/6981) - Render transparent vector layers to an intermediate canvas ([@gberaudo](https://github.com/gberaudo))
* [#6899](https://github.com/openlayers/openlayers/pull/6899) - Use number literal for sphere radius ([@probins](https://github.com/probins))
* [#7011](https://github.com/openlayers/openlayers/pull/7011) - Update jsdoc to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#7008](https://github.com/openlayers/openlayers/pull/7008) - Update sinon to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#7007](https://github.com/openlayers/openlayers/pull/7007) - fix(package): update rollup to version 0.45.0 ([@openlayers](https://github.com/openlayers))
* [#6996](https://github.com/openlayers/openlayers/pull/6996) - 6987: Memory leak with WMS time source with reprojection ([@ch08532](https://github.com/ch08532))
* [#7003](https://github.com/openlayers/openlayers/pull/7003) - Update jsdoc to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#7004](https://github.com/openlayers/openlayers/pull/7004) - Use https for bing and stamen attributions ([@fredj](https://github.com/fredj))
* [#6998](https://github.com/openlayers/openlayers/pull/6998) - Update eslint to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#6999](https://github.com/openlayers/openlayers/pull/6999) - Make VectorTile source work with multiple layers ([@ahocevar](https://github.com/ahocevar))
* [#6988](https://github.com/openlayers/openlayers/pull/6988) - Add missing type annotations ([@ahocevar](https://github.com/ahocevar))
* [#6984](https://github.com/openlayers/openlayers/pull/6984) - Update closure-util to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#6970](https://github.com/openlayers/openlayers/pull/6970) - Fix Bug when adding/removing layer with no cache ([@cmortazavi](https://github.com/cmortazavi))
* [#6972](https://github.com/openlayers/openlayers/pull/6972) - Handle error tiles properly ([@ahocevar](https://github.com/ahocevar))
* [#6973](https://github.com/openlayers/openlayers/pull/6973) - Update clean-css-cli to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#6971](https://github.com/openlayers/openlayers/pull/6971) - Update sinon to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#6968](https://github.com/openlayers/openlayers/pull/6968) - Shortest arc rotation animation improvements and upgrade notes ([@ahocevar](https://github.com/ahocevar))
* [#6966](https://github.com/openlayers/openlayers/pull/6966) - Add getResolutionForZoom method for ol.View ([@ahocevar](https://github.com/ahocevar))
* [#6965](https://github.com/openlayers/openlayers/pull/6965) - Use shortest rotation delta for animation ([@ahocevar](https://github.com/ahocevar))
* [#6967](https://github.com/openlayers/openlayers/pull/6967) - Add RoadOnDemand imagery set to Bing example ([@ahocevar](https://github.com/ahocevar))
* [#6964](https://github.com/openlayers/openlayers/pull/6964) - Fix KML ExtendedData reading ([@fredj](https://github.com/fredj))
* [#6958](https://github.com/openlayers/openlayers/pull/6958) - Remove error tiles after loading is finished ([@ahocevar](https://github.com/ahocevar))
* [#6793](https://github.com/openlayers/openlayers/pull/6793) - Webgl text ([@GaborFarkas](https://github.com/GaborFarkas))
* [#6960](https://github.com/openlayers/openlayers/pull/6960) - Queue tiles before loading ([@tschaub](https://github.com/tschaub))
* [#6957](https://github.com/openlayers/openlayers/pull/6957) - Greenkeeper/eslint 4.1.1 ([@openlayers](https://github.com/openlayers))
* [#6955](https://github.com/openlayers/openlayers/pull/6955) - Update async to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#6916](https://github.com/openlayers/openlayers/pull/6916) - Upgrade eslint to v4.0.0 ([@marcjansen](https://github.com/marcjansen))
* [#6943](https://github.com/openlayers/openlayers/pull/6943) - Update sinon to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#6939](https://github.com/openlayers/openlayers/pull/6939) - Abort loading when tile is disposed ([@ahocevar](https://github.com/ahocevar))
* [#6930](https://github.com/openlayers/openlayers/pull/6930) - Handle setActive(false) on an interaction without map ([@openlayers](https://github.com/openlayers))
* [#6936](https://github.com/openlayers/openlayers/pull/6936) - Do not stop the render loop when all wanted tiles are aborted ([@ahocevar](https://github.com/ahocevar))
* [#6920](https://github.com/openlayers/openlayers/pull/6920) - Fix minor type strength inconsistency ([@klokantech](https://github.com/klokantech))
* [#6935](https://github.com/openlayers/openlayers/pull/6935) - Use transparent image from canvas context ([@ahocevar](https://github.com/ahocevar))
* [#6933](https://github.com/openlayers/openlayers/pull/6933) - Improve proj.get() logic ([@probins](https://github.com/probins))
* [#6931](https://github.com/openlayers/openlayers/pull/6931) - Make sure we use the default featurePrefix ([@bartvde](https://github.com/bartvde))
* [#6928](https://github.com/openlayers/openlayers/pull/6928) - Only adjust resolution when center within projection extent ([@ahocevar](https://github.com/ahocevar))
* [#6923](https://github.com/openlayers/openlayers/pull/6923) - Load tasks/build-ext.js in strict mode ([@fredj](https://github.com/fredj))
* [#6918](https://github.com/openlayers/openlayers/pull/6918) - Remove unnecessary pixelRatio check ([@ahocevar](https://github.com/ahocevar))
* [#6917](https://github.com/openlayers/openlayers/pull/6917) - Correct typo in graticule docs ([@probins](https://github.com/probins))

9
changelog/v4.3.1.md Normal file
View File

@@ -0,0 +1,9 @@
# 4.3.1
The v4.3.1 release includes a few fixes that didn't make it into v4.3.0. No special upgrade considerations.
## Fixes
* [#7122](https://github.com/openlayers/openlayers/pull/7122) - Immediately complete no-op animations ([@tschaub](https://github.com/tschaub))
* [#7120](https://github.com/openlayers/openlayers/pull/7120) - Fix hit detection for overzoomed vector tiles ([@ahocevar](https://github.com/ahocevar))
* [#7114](https://github.com/openlayers/openlayers/pull/7114) - Immediate WebGL text renderer and other improvements ([@GaborFarkas](https://github.com/GaborFarkas))

7
changelog/v4.3.2.md Normal file
View File

@@ -0,0 +1,7 @@
# 4.3.2
The v4.3.2 release includes a single fix.
## Fixes
* [#7140](https://github.com/openlayers/openlayers/pull/7140) - Export ol.Sphere.getLength and ol.Sphere.getArea ([@fredj](https://github.com/fredj))

7
changelog/v4.3.3.md Normal file
View File

@@ -0,0 +1,7 @@
# 4.3.2
The v4.3.3 reverts the fractional pixel positioning of overlays.
## Fixes
* [#7258](https://github.com/openlayers/openlayers/pull/7258) - Revert changes made in #7098 ([@ahocevar](https://github.com/ahocevar))

View File

@@ -45,7 +45,7 @@ The easiest way to use a custom projection is to add the [Proj4js](http://proj4j
Following example shows definition of a [British National Grid](https://epsg.io/27700):
``` html
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.4.3/proj4.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.4.4/proj4.js"></script>
```
``` javascript

View File

@@ -6,7 +6,6 @@ goog.require('ol.source.OSM');
goog.require('ol.source.VectorTile');
goog.require('ol.layer.Tile');
goog.require('ol.layer.VectorTile');
goog.require('ol.tilegrid');
goog.require('ol.proj.Projection');
@@ -77,7 +76,6 @@ fetch(url).then(function(response) {
});
var vectorSource = new ol.source.VectorTile({
format: new ol.format.GeoJSON(),
tileGrid: ol.tilegrid.createXYZ(),
tileLoadFunction: function(tile) {
var format = tile.getFormat();
var tileCoord = tile.getTileCoord();

View File

@@ -10,12 +10,15 @@ goog.require('ol.style.Stroke');
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
source: new ol.source.OSM({
wrapX: false
})
})
],
target: 'map',
view: new ol.View({
center: ol.proj.fromLonLat([4.8, 47.75]),
extent: ol.proj.get('EPSG:3857').getExtent(),
zoom: 5
})
});

View File

@@ -10,7 +10,6 @@ goog.require('ol.style.Icon');
goog.require('ol.style.Stroke');
goog.require('ol.style.Style');
goog.require('ol.style.Text');
goog.require('ol.tilegrid');
var key = 'pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiRk1kMWZaSSJ9.E5BkluenyWQMsBLsuByrmg';
@@ -23,7 +22,6 @@ var map = new ol.Map({
'© <a href="https://www.openstreetmap.org/copyright">' +
'OpenStreetMap contributors</a>',
format: new ol.format.MVT(),
tileGrid: ol.tilegrid.createXYZ({tileSize: 512, maxZoom: 22}),
url: 'https://{a-d}.tiles.mapbox.com/v4/mapbox.mapbox-streets-v6/' +
'{z}/{x}/{y}.vector.pbf?access_token=' + key
}),

View File

@@ -1,20 +1,24 @@
---
layout: example.html
title: Measure
shortdesc: Example of using the ol.interaction.Draw interaction to create a simple measuring application.
shortdesc: Using a draw interaction to measure lengths and areas.
docs: >
<p><i>NOTE: By default, length and area are calculated using the projected coordinates. This is not accurate for projections like Mercator where the projected meters do not correspond to meters on the ground. To get a standarized measurement across all projections, use the geodesic measures.</i></p>
<p>The <code>ol.Sphere.getLength()</code> and <code>ol.Sphere.getArea()</code>
functions calculate spherical lengths and areas for geometries. Lengths are
calculated by assuming great circle segments between geometry coordinates.
Areas are calculated as if edges of polygons were great circle segments.</p>
<p>Note that the <code>geometry.getLength()</code> and <code>geometry.getArea()</code>
methods return measures of projected (planar) geometries. These can be very
different than on-the-ground measures in certain situations — in northern
and southern latitudes using Web Mercator for example. For better results,
use the functions on <code>ol.Sphere</code>.</p>
tags: "draw, edit, measure, vector"
---
<div id="map" class="map"></div>
<form class="form-inline">
<label>Measurement type &nbsp;</label>
<select id="type">
<option value="length">Length (LineString)</option>
<option value="area">Area (Polygon)</option>
</select>
<label class="checkbox">
<input type="checkbox" id="geodesic">
use geodesic measures
</label>
<select id="type">
<option value="length">Length (LineString)</option>
<option value="area">Area (Polygon)</option>
</select>
</form>

View File

@@ -8,7 +8,6 @@ goog.require('ol.geom.Polygon');
goog.require('ol.interaction.Draw');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
goog.require('ol.proj');
goog.require('ol.source.OSM');
goog.require('ol.source.Vector');
goog.require('ol.style.Circle');
@@ -17,8 +16,6 @@ goog.require('ol.style.Stroke');
goog.require('ol.style.Style');
var wgs84Sphere = new ol.Sphere(6378137);
var raster = new ol.layer.Tile({
source: new ol.source.OSM()
});
@@ -137,7 +134,6 @@ map.getViewport().addEventListener('mouseout', function() {
});
var typeSelect = document.getElementById('type');
var geodesicCheckbox = document.getElementById('geodesic');
var draw; // global so we can remove it later
@@ -148,19 +144,7 @@ var draw; // global so we can remove it later
* @return {string} The formatted length.
*/
var formatLength = function(line) {
var length;
if (geodesicCheckbox.checked) {
var coordinates = line.getCoordinates();
length = 0;
var sourceProj = map.getView().getProjection();
for (var i = 0, ii = coordinates.length - 1; i < ii; ++i) {
var c1 = ol.proj.transform(coordinates[i], sourceProj, 'EPSG:4326');
var c2 = ol.proj.transform(coordinates[i + 1], sourceProj, 'EPSG:4326');
length += wgs84Sphere.haversineDistance(c1, c2);
}
} else {
length = Math.round(line.getLength() * 100) / 100;
}
var length = ol.Sphere.getLength(line);
var output;
if (length > 100) {
output = (Math.round(length / 1000 * 100) / 100) +
@@ -179,16 +163,7 @@ var formatLength = function(line) {
* @return {string} Formatted area.
*/
var formatArea = function(polygon) {
var area;
if (geodesicCheckbox.checked) {
var sourceProj = map.getView().getProjection();
var geom = /** @type {ol.geom.Polygon} */(polygon.clone().transform(
sourceProj, 'EPSG:4326'));
var coordinates = geom.getLinearRing(0).getCoordinates();
area = Math.abs(wgs84Sphere.geodesicArea(coordinates));
} else {
area = polygon.getArea();
}
var area = ol.Sphere.getArea(polygon);
var output;
if (area > 10000) {
output = (Math.round(area / 1000000 * 100) / 100) +

View File

@@ -7,8 +7,6 @@ goog.require('ol.source.VectorTile');
goog.require('ol.style.Fill');
goog.require('ol.style.Stroke');
goog.require('ol.style.Style');
goog.require('ol.tilegrid');
var key = 'vector-tiles-5eJz6JX';
@@ -70,7 +68,7 @@ var map = new ol.Map({
layerName: 'layer',
layers: ['water', 'roads', 'buildings']
}),
tileGrid: ol.tilegrid.createXYZ({tileSize: 512, maxZoom: 19}),
maxZoom: 19,
url: 'https://tile.mapzen.com/mapzen/vector/v1/all/{z}/{x}/{y}.topojson?api_key=' + key
}),
style: function(feature, resolution) {

View File

@@ -8,7 +8,7 @@ docs: >
in <a href="https://epsg.io/">EPSG.io</a> database.
tags: "reprojection, projection, proj4js, epsg.io"
resources:
- https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.4.3/proj4.js
- https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.4.4/proj4.js
---
<div id="map" class="map"></div>
<form class="form-inline">

View File

@@ -6,6 +6,6 @@ docs: >
This example shows client-side reprojection of single image source.
tags: "reprojection, projection, proj4js, image, imagestatic"
resources:
- https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.4.3/proj4.js
- https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.4.4/proj4.js
---
<div id="map" class="map"></div>

View File

@@ -6,7 +6,7 @@ docs: >
This example shows client-side raster reprojection between various projections.
tags: "reprojection, projection, proj4js, osm, wms, wmts, hidpi"
resources:
- https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.4.3/proj4.js
- https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.4.4/proj4.js
---
<div id="map" class="map"></div>
<form class="form-inline">

View File

@@ -6,6 +6,6 @@ docs: >
This example shows client-side reprojection of OpenStreetMap to NAD83 Indiana East, including a ScaleLine control with US units.
tags: "reprojection, projection, openstreetmap, nad83, tile, scaleline"
resources:
- https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.4.3/proj4.js
- https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.4.4/proj4.js
---
<div id="map" class="map"></div>

View File

@@ -6,6 +6,6 @@ docs: >
Example of a Sphere Mollweide map with a Graticule component.
tags: "graticule, Mollweide, projection, proj4js"
resources:
- https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.4.3/proj4.js
- https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.4.4/proj4.js
---
<div id="map" class="map"></div>

View File

@@ -6,7 +6,7 @@ docs: >
With [Proj4js](http://proj4js.org/) integration, OpenLayers can transform coordinates between arbitrary projections.
tags: "wms, single image, proj4js, projection"
resources:
- https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.4.3/proj4.js
- https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.4.4/proj4.js
- https://epsg.io/21781-1753.js
---
<div id="map" class="map"></div>

View File

@@ -436,6 +436,33 @@ olx.MapOptions.prototype.target;
olx.MapOptions.prototype.view;
/**
* Object literal with options for the {@link ol.Sphere.getLength} or
* {@link ol.Sphere.getArea} functions.
* @typedef {{projection: (ol.ProjectionLike|undefined),
* radius: (number|undefined)}}
*/
olx.SphereMetricOptions;
/**
* Projection of the geometry. By default, the geometry is assumed to be in
* EPSG:3857 (Web Mercator).
* @type {(ol.ProjectionLike|undefined)}
* @api
*/
olx.SphereMetricOptions.prototype.projection;
/**
* Sphere radius. By default, the radius of the earth is used (Clarke 1866
* Authalic Sphere).
* @type {(number|undefined)}
* @api
*/
olx.SphereMetricOptions.prototype.radius;
/**
* Object literal with options for the {@link ol.Map#forEachFeatureAtPixel} and
* {@link ol.Map#hasFeatureAtPixel} methods.
@@ -2710,6 +2737,7 @@ olx.interaction.DoubleClickZoomOptions.prototype.delta;
/**
* @typedef {{formatConstructors: (Array.<function(new: ol.format.Feature)>|undefined),
* source: (ol.source.Vector|undefined),
* projection: ol.ProjectionLike,
* target: (Element|undefined)}}
*/
@@ -2724,6 +2752,18 @@ olx.interaction.DragAndDropOptions;
olx.interaction.DragAndDropOptions.prototype.formatConstructors;
/**
* Optional vector source where features will be added. If a source is provided
* all existing features will be removed and new features will be added when
* they are dropped on the target. If you want to add features to a vector
* source without removing the existing features (append only), instead of
* providing the source option listen for the "addfeatures" event.
* @type {ol.source.Vector|undefined}
* @api
*/
olx.interaction.DragAndDropOptions.prototype.source;
/**
* Target projection. By default, the map's view's projection is used.
* @type {ol.ProjectionLike}

View File

@@ -1,6 +1,6 @@
{
"name": "openlayers",
"version": "4.2.0",
"version": "4.3.3",
"description": "Build tools and sources for developing OpenLayers based mapping applications",
"keywords": [
"map",
@@ -39,7 +39,7 @@
"pbf": "3.0.5",
"pixelworks": "1.1.0",
"rbush": "2.0.1",
"rollup": "^0.45.0",
"rollup": "^0.47.2",
"rollup-plugin-cleanup": "^1.0.0",
"rollup-plugin-commonjs": "^8.0.2",
"rollup-plugin-node-resolve": "^3.0.0",
@@ -68,10 +68,10 @@
"mocha-phantomjs-core": "^2.1.0",
"mustache": "2.3.0",
"phantomjs-prebuilt": "2.1.14",
"proj4": "2.4.3",
"proj4": "2.4.4",
"resemblejs": "2.2.4",
"serve-files": "1.0.1",
"sinon": "3.1.0",
"sinon": "3.2.0",
"slimerjs": "0.10.3"
},
"eslintConfig": {

View File

@@ -1,6 +1,6 @@
{
"name": "ol",
"version": "4.2.0",
"version": "4.3.3",
"description": "OpenLayers as ES2015 modules",
"main": "index.js",
"module": "index.js",

View File

@@ -67,6 +67,13 @@ ol.format.GML3 = function(opt_options) {
this.schemaLocation = options.schemaLocation ?
options.schemaLocation : ol.format.GML3.schemaLocation_;
/**
* @private
* @type {boolean}
*/
this.hasZ = options.hasZ !== undefined ?
options.hasZ : false;
};
ol.inherits(ol.format.GML3, ol.format.GMLBase);

View File

@@ -1065,19 +1065,25 @@ ol.format.KML.setCommonGeometryProperties_ = function(multiGeometry,
geometries) {
var ii = geometries.length;
var extrudes = new Array(geometries.length);
var tessellates = new Array(geometries.length);
var altitudeModes = new Array(geometries.length);
var geometry, i, hasExtrude, hasAltitudeMode;
hasExtrude = hasAltitudeMode = false;
var geometry, i, hasExtrude, hasTessellate, hasAltitudeMode;
hasExtrude = hasTessellate = hasAltitudeMode = false;
for (i = 0; i < ii; ++i) {
geometry = geometries[i];
extrudes[i] = geometry.get('extrude');
tessellates[i] = geometry.get('tessellate');
altitudeModes[i] = geometry.get('altitudeMode');
hasExtrude = hasExtrude || extrudes[i] !== undefined;
hasTessellate = hasTessellate || tessellates[i] !== undefined;
hasAltitudeMode = hasAltitudeMode || altitudeModes[i];
}
if (hasExtrude) {
multiGeometry.set('extrude', extrudes);
}
if (hasTessellate) {
multiGeometry.set('tessellate', tessellates);
}
if (hasAltitudeMode) {
multiGeometry.set('altitudeMode', altitudeModes);
}
@@ -1371,6 +1377,7 @@ ol.format.KML.LOD_PARSERS_ = ol.xml.makeStructureNS(
ol.format.KML.EXTRUDE_AND_ALTITUDE_MODE_PARSERS_ = ol.xml.makeStructureNS(
ol.format.KML.NAMESPACE_URIS_, {
'extrude': ol.xml.makeObjectPropertySetter(ol.format.XSD.readBoolean),
'tessellate': ol.xml.makeObjectPropertySetter(ol.format.XSD.readBoolean),
'altitudeMode': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString)
});
@@ -2468,10 +2475,16 @@ ol.format.KML.writePrimitiveGeometry_ = function(node, geometry, objectStack) {
var /** @type {ol.XmlNodeStackItem} */ context = {node: node};
context['layout'] = geometry.getLayout();
context['stride'] = geometry.getStride();
ol.xml.pushSerializeAndPop(context,
ol.format.KML.PRIMITIVE_GEOMETRY_SERIALIZERS_,
ol.format.KML.COORDINATES_NODE_FACTORY_,
[flatCoordinates], objectStack);
// serialize properties (properties unknown to KML are not serialized)
var properties = geometry.getProperties();
properties.coordinates = flatCoordinates;
var parentNode = objectStack[objectStack.length - 1].node;
var orderedKeys = ol.format.KML.PRIMITIVE_GEOMETRY_SEQUENCE_[parentNode.namespaceURI];
var values = ol.xml.makeSequence(properties, orderedKeys);
ol.xml.pushSerializeAndPop(context, ol.format.KML.PRIMITIVE_GEOMETRY_SERIALIZERS_,
ol.xml.OBJECT_PROPERTY_NODE_FACTORY, values, objectStack, orderedKeys);
};
@@ -2632,7 +2645,6 @@ ol.format.KML.GEOMETRY_TYPE_TO_NODENAME_ = {
'GeometryCollection': 'MultiGeometry'
};
/**
* @const
* @type {Object.<string, Array.<string>>}
@@ -2808,6 +2820,17 @@ ol.format.KML.PLACEMARK_SERIALIZERS_ = ol.xml.makeStructureNS(
});
/**
* @const
* @type {Object.<string, Array.<string>>}
* @private
*/
ol.format.KML.PRIMITIVE_GEOMETRY_SEQUENCE_ = ol.xml.makeStructureNS(
ol.format.KML.NAMESPACE_URIS_, [
'extrude', 'tessellate', 'altitudeMode', 'coordinates'
]);
/**
* @const
* @type {Object.<string, Object.<string, ol.XmlSerializer>>}
@@ -2815,6 +2838,9 @@ ol.format.KML.PLACEMARK_SERIALIZERS_ = ol.xml.makeStructureNS(
*/
ol.format.KML.PRIMITIVE_GEOMETRY_SERIALIZERS_ = ol.xml.makeStructureNS(
ol.format.KML.NAMESPACE_URIS_, {
'extrude': ol.xml.makeChildAppender(ol.format.XSD.writeBooleanTextNode),
'tessellate': ol.xml.makeChildAppender(ol.format.XSD.writeBooleanTextNode),
'altitudeMode': ol.xml.makeChildAppender(ol.format.XSD.writeStringTextNode),
'coordinates': ol.xml.makeChildAppender(
ol.format.KML.writeCoordinatesTextNode_)
});
@@ -2926,16 +2952,6 @@ ol.format.KML.GEOMETRY_NODE_FACTORY_ = function(value, objectStack,
ol.format.KML.COLOR_NODE_FACTORY_ = ol.xml.makeSimpleNodeFactory('color');
/**
* A factory for creating coordinates nodes.
* @const
* @type {function(*, Array.<*>, string=): (Node|undefined)}
* @private
*/
ol.format.KML.COORDINATES_NODE_FACTORY_ =
ol.xml.makeSimpleNodeFactory('coordinates');
/**
* A factory for creating Data nodes.
* @const

View File

@@ -560,23 +560,6 @@ ol.Graticule.prototype.handlePostCompose_ = function(e) {
this.updateProjectionInfo_(projection);
}
//Fix the extent if wrapped.
//(note: this is the same extent as vectorContext.extent_)
var offsetX = 0;
if (projection.canWrapX()) {
var projectionExtent = projection.getExtent();
var worldWidth = ol.extent.getWidth(projectionExtent);
var x = frameState.focus[0];
if (x < projectionExtent[0] || x > projectionExtent[2]) {
var worldsAway = Math.ceil((projectionExtent[0] - x) / worldWidth);
offsetX = worldWidth * worldsAway;
extent = [
extent[0] + offsetX, extent[1],
extent[2] + offsetX, extent[3]
];
}
}
this.createGraticule_(extent, center, resolution, squaredTolerance);
// Draw the lines

View File

@@ -49,6 +49,12 @@ ol.interaction.DragAndDrop = function(opt_options) {
*/
this.dropListenKeys_ = null;
/**
* @private
* @type {ol.source.Vector}
*/
this.source_ = options.source || null;
/**
* @private
* @type {Element}
@@ -122,6 +128,10 @@ ol.interaction.DragAndDrop.prototype.handleResult_ = function(file, event) {
break;
}
}
if (this.source_) {
this.source_.clear();
this.source_.addFeatures(features);
}
this.dispatchEvent(
new ol.interaction.DragAndDrop.Event(
ol.interaction.DragAndDrop.EventType_.ADD_FEATURES, file,

View File

@@ -475,7 +475,7 @@ ol.Overlay.prototype.updateRenderedPosition = function(pixel, mapSize) {
if (this.rendered_.left_ !== '') {
this.rendered_.left_ = style.left = '';
}
var right = (mapSize[0] - pixel[0] - offsetX) + 'px';
var right = Math.round(mapSize[0] - pixel[0] - offsetX) + 'px';
if (this.rendered_.right_ != right) {
this.rendered_.right_ = style.right = right;
}
@@ -488,7 +488,7 @@ ol.Overlay.prototype.updateRenderedPosition = function(pixel, mapSize) {
positioning == ol.OverlayPositioning.TOP_CENTER) {
offsetX -= this.element_.offsetWidth / 2;
}
var left = (pixel[0] + offsetX) + 'px';
var left = Math.round(pixel[0] + offsetX) + 'px';
if (this.rendered_.left_ != left) {
this.rendered_.left_ = style.left = left;
}
@@ -499,7 +499,7 @@ ol.Overlay.prototype.updateRenderedPosition = function(pixel, mapSize) {
if (this.rendered_.top_ !== '') {
this.rendered_.top_ = style.top = '';
}
var bottom = (mapSize[1] - pixel[1] - offsetY) + 'px';
var bottom = Math.round(mapSize[1] - pixel[1] - offsetY) + 'px';
if (this.rendered_.bottom_ != bottom) {
this.rendered_.bottom_ = style.bottom = bottom;
}
@@ -512,7 +512,7 @@ ol.Overlay.prototype.updateRenderedPosition = function(pixel, mapSize) {
positioning == ol.OverlayPositioning.CENTER_RIGHT) {
offsetY -= this.element_.offsetHeight / 2;
}
var top = (pixel[1] + offsetY) + 'px';
var top = Math.round(pixel[1] + offsetY) + 'px';
if (this.rendered_.top_ != top) {
this.rendered_.top_ = style.top = top;
}

View File

@@ -22,11 +22,11 @@ ol.proj.METERS_PER_UNIT = ol.proj.Units.METERS_PER_UNIT;
/**
* A place to store the radius of the Clarke 1866 Authalic Sphere.
* A place to store the mean radius of the Earth.
* @private
* @type {ol.Sphere}
*/
ol.proj.AUTHALIC_SPHERE_ = new ol.Sphere(6370997);
ol.proj.SPHERE_ = new ol.Sphere(ol.Sphere.DEFAULT_RADIUS);
if (ol.ENABLE_PROJ4JS) {
@@ -90,9 +90,9 @@ ol.proj.getPointResolution = function(projection, resolution, point, opt_units)
point[0], point[1] + resolution / 2
];
vertices = toEPSG4326(vertices, vertices, 2);
var width = ol.proj.AUTHALIC_SPHERE_.haversineDistance(
var width = ol.proj.SPHERE_.haversineDistance(
vertices.slice(0, 2), vertices.slice(2, 4));
var height = ol.proj.AUTHALIC_SPHERE_.haversineDistance(
var height = ol.proj.SPHERE_.haversineDistance(
vertices.slice(4, 6), vertices.slice(6, 8));
pointResolution = (width + height) / 2;
var metersPerUnit = opt_units ?

View File

@@ -78,10 +78,44 @@ if (ol.ENABLE_WEBGL) {
*/
this.strokeStyle_ = null;
/**
* @private
* @type {ol.style.Text}
*/
this.textStyle_ = null;
};
ol.inherits(ol.render.webgl.Immediate, ol.render.VectorContext);
/**
* @param {ol.render.webgl.ReplayGroup} replayGroup Replay group.
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
* @param {number} end End.
* @param {number} stride Stride.
* @private
*/
ol.render.webgl.Immediate.prototype.drawText_ = function(replayGroup,
flatCoordinates, offset, end, stride) {
var context = this.context_;
var replay = /** @type {ol.render.webgl.TextReplay} */ (
replayGroup.getReplay(0, ol.render.ReplayType.TEXT));
replay.setTextStyle(this.textStyle_);
replay.drawText(flatCoordinates, offset, end, stride, null, null);
replay.finish(context);
// default colors
var opacity = 1;
var skippedFeatures = {};
var featureCallback;
var oneByOne = false;
replay.replay(this.context_, this.center_, this.resolution_, this.rotation_,
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
oneByOne);
replay.getDeleteResourcesFunction(context)();
};
/**
* Set the rendering style. Note that since this is an immediate rendering API,
* any `zIndex` on the provided style will be ignored.
@@ -93,6 +127,7 @@ if (ol.ENABLE_WEBGL) {
ol.render.webgl.Immediate.prototype.setStyle = function(style) {
this.setFillStrokeStyle(style.getFill(), style.getStroke());
this.setImageStyle(style.getImage());
this.setTextStyle(style.getText());
};
@@ -184,6 +219,12 @@ if (ol.ENABLE_WEBGL) {
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
oneByOne);
replay.getDeleteResourcesFunction(context)();
if (this.textStyle_) {
var flatCoordinates = geometry.getFlatCoordinates();
var stride = geometry.getStride();
this.drawText_(replayGroup, flatCoordinates, 0, flatCoordinates.length, stride);
}
};
@@ -206,6 +247,12 @@ if (ol.ENABLE_WEBGL) {
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
oneByOne);
replay.getDeleteResourcesFunction(context)();
if (this.textStyle_) {
var flatCoordinates = geometry.getFlatCoordinates();
var stride = geometry.getStride();
this.drawText_(replayGroup, flatCoordinates, 0, flatCoordinates.length, stride);
}
};
@@ -228,6 +275,11 @@ if (ol.ENABLE_WEBGL) {
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
oneByOne);
replay.getDeleteResourcesFunction(context)();
if (this.textStyle_) {
var flatMidpoint = geometry.getFlatMidpoint();
this.drawText_(replayGroup, flatMidpoint, 0, 2, 2);
}
};
@@ -250,6 +302,11 @@ if (ol.ENABLE_WEBGL) {
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
oneByOne);
replay.getDeleteResourcesFunction(context)();
if (this.textStyle_) {
var flatMidpoints = geometry.getFlatMidpoints();
this.drawText_(replayGroup, flatMidpoints, 0, flatMidpoints.length, 2);
}
};
@@ -272,6 +329,11 @@ if (ol.ENABLE_WEBGL) {
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
oneByOne);
replay.getDeleteResourcesFunction(context)();
if (this.textStyle_) {
var flatInteriorPoint = geometry.getFlatInteriorPoint();
this.drawText_(replayGroup, flatInteriorPoint, 0, 2, 2);
}
};
@@ -294,6 +356,11 @@ if (ol.ENABLE_WEBGL) {
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
oneByOne);
replay.getDeleteResourcesFunction(context)();
if (this.textStyle_) {
var flatInteriorPoints = geometry.getFlatInteriorPoints();
this.drawText_(replayGroup, flatInteriorPoints, 0, flatInteriorPoints.length, 2);
}
};
@@ -316,6 +383,10 @@ if (ol.ENABLE_WEBGL) {
this.size_, this.pixelRatio_, opacity, skippedFeatures, featureCallback,
oneByOne);
replay.getDeleteResourcesFunction(context)();
if (this.textStyle_) {
this.drawText_(replayGroup, geometry.getCenter(), 0, 2, 2);
}
};
@@ -335,4 +406,12 @@ if (ol.ENABLE_WEBGL) {
this.strokeStyle_ = strokeStyle;
};
/**
* @inheritDoc
*/
ol.render.webgl.Immediate.prototype.setTextStyle = function(textStyle) {
this.textStyle_ = textStyle;
};
}

View File

@@ -79,7 +79,8 @@ if (ol.ENABLE_WEBGL) {
var outerRing = new ol.structs.LinkedList();
var rtree = new ol.structs.RBush();
// Initialize the outer ring
var maxX = this.processFlatCoordinates_(flatCoordinates, stride, outerRing, rtree, true);
this.processFlatCoordinates_(flatCoordinates, stride, outerRing, rtree, true);
var maxCoords = this.getMaxCoords_(outerRing);
// Eliminate holes, if there are any
if (holeFlatCoordinates.length) {
@@ -88,15 +89,18 @@ if (ol.ENABLE_WEBGL) {
for (i = 0, ii = holeFlatCoordinates.length; i < ii; ++i) {
var holeList = {
list: new ol.structs.LinkedList(),
maxX: undefined,
maxCoords: undefined,
rtree: new ol.structs.RBush()
};
holeLists.push(holeList);
holeList.maxX = this.processFlatCoordinates_(holeFlatCoordinates[i],
this.processFlatCoordinates_(holeFlatCoordinates[i],
stride, holeList.list, holeList.rtree, false);
this.classifyPoints_(holeList.list, holeList.rtree, true);
holeList.maxCoords = this.getMaxCoords_(holeList.list);
}
holeLists.sort(function(a, b) {
return b.maxX[0] === a.maxX[0] ? a.maxX[1] - b.maxX[1] : b.maxX[0] - a.maxX[0];
return b.maxCoords[0] === a.maxCoords[0] ?
a.maxCoords[1] - b.maxCoords[1] : b.maxCoords[0] - a.maxCoords[0];
});
for (i = 0; i < holeLists.length; ++i) {
var currList = holeLists[i].list;
@@ -104,6 +108,7 @@ if (ol.ENABLE_WEBGL) {
var currItem = start;
var intersection;
do {
//TODO: Triangulate holes when they intersect the outer ring.
if (this.getIntersections_(currItem, rtree).length) {
intersection = true;
break;
@@ -111,8 +116,7 @@ if (ol.ENABLE_WEBGL) {
currItem = currList.nextItem();
} while (start !== currItem);
if (!intersection) {
this.classifyPoints_(currList, holeLists[i].rtree, true);
if (this.bridgeHole_(currList, holeLists[i].maxX[0], outerRing, maxX[0], rtree)) {
if (this.bridgeHole_(currList, holeLists[i].maxCoords[0], outerRing, maxCoords[0], rtree)) {
rtree.concat(holeLists[i].rtree);
this.classifyPoints_(outerRing, rtree, false);
}
@@ -133,13 +137,12 @@ if (ol.ENABLE_WEBGL) {
* @param {ol.structs.LinkedList} list Linked list.
* @param {ol.structs.RBush} rtree R-Tree of the polygon.
* @param {boolean} clockwise Coordinate order should be clockwise.
* @return {Array.<number>} X and Y coords of maximum X value.
*/
ol.render.webgl.PolygonReplay.prototype.processFlatCoordinates_ = function(
flatCoordinates, stride, list, rtree, clockwise) {
var isClockwise = ol.geom.flat.orient.linearRingIsClockwise(flatCoordinates,
0, flatCoordinates.length, stride);
var i, ii, maxXX, maxXY;
var i, ii;
var n = this.vertices.length / 2;
/** @type {ol.WebglPolygonVertex} */
var start;
@@ -152,17 +155,11 @@ if (ol.ENABLE_WEBGL) {
if (clockwise === isClockwise) {
start = this.createPoint_(flatCoordinates[0], flatCoordinates[1], n++);
p0 = start;
maxXX = flatCoordinates[0];
maxXY = flatCoordinates[1];
for (i = stride, ii = flatCoordinates.length; i < ii; i += stride) {
p1 = this.createPoint_(flatCoordinates[i], flatCoordinates[i + 1], n++);
segments.push(this.insertItem_(p0, p1, list));
extents.push([Math.min(p0.x, p1.x), Math.min(p0.y, p1.y), Math.max(p0.x, p1.x),
Math.max(p0.y, p1.y)]);
if (flatCoordinates[i] > maxXX) {
maxXX = flatCoordinates[i];
maxXY = flatCoordinates[i + 1];
}
p0 = p1;
}
segments.push(this.insertItem_(p1, start, list));
@@ -172,17 +169,11 @@ if (ol.ENABLE_WEBGL) {
var end = flatCoordinates.length - stride;
start = this.createPoint_(flatCoordinates[end], flatCoordinates[end + 1], n++);
p0 = start;
maxXX = flatCoordinates[end];
maxXY = flatCoordinates[end + 1];
for (i = end - stride, ii = 0; i >= ii; i -= stride) {
p1 = this.createPoint_(flatCoordinates[i], flatCoordinates[i + 1], n++);
segments.push(this.insertItem_(p0, p1, list));
extents.push([Math.min(p0.x, p1.x), Math.min(p0.y, p1.y), Math.max(p0.x, p1.x),
Math.max(p0.y, p1.y)]);
if (flatCoordinates[i] > maxXX) {
maxXX = flatCoordinates[i];
maxXY = flatCoordinates[i + 1];
}
p0 = p1;
}
segments.push(this.insertItem_(p1, start, list));
@@ -190,8 +181,28 @@ if (ol.ENABLE_WEBGL) {
Math.max(p0.y, p1.y)]);
}
rtree.load(extents, segments);
};
return [maxXX, maxXY];
/**
* Returns the rightmost coordinates of a polygon on the X axis.
* @private
* @param {ol.structs.LinkedList} list Polygons ring.
* @return {Array.<number>} Max X coordinates.
*/
ol.render.webgl.PolygonReplay.prototype.getMaxCoords_ = function(list) {
var start = list.firstItem();
var seg = start;
var maxCoords = [seg.p0.x, seg.p0.y];
do {
seg = list.nextItem();
if (seg.p0.x > maxCoords[0]) {
maxCoords = [seg.p0.x, seg.p0.y];
}
} while (seg !== start);
return maxCoords;
};
@@ -325,7 +336,7 @@ if (ol.ENABLE_WEBGL) {
if (!this.classifyPoints_(list, rtree, ccw)) {
// Due to the behavior of OL's PIP algorithm, the ear clipping cannot
// introduce touching segments. However, the original data may have some.
if (!this.resolveLocalSelfIntersections_(list, rtree, true)) {
if (!this.resolveSelfIntersections_(list, rtree, true)) {
break;
}
}
@@ -335,7 +346,7 @@ if (ol.ENABLE_WEBGL) {
// We ran out of ears, try to reclassify.
if (!this.classifyPoints_(list, rtree, ccw)) {
// We have a bad polygon, try to resolve local self-intersections.
if (!this.resolveLocalSelfIntersections_(list, rtree)) {
if (!this.resolveSelfIntersections_(list, rtree)) {
simple = this.isSimple_(list, rtree);
if (!simple) {
// We have a really bad polygon, try more time consuming methods.
@@ -382,10 +393,15 @@ if (ol.ENABLE_WEBGL) {
p2 = s2.p1;
if (p1.reflex === false) {
// We might have a valid ear
var diagonalIsInside = ccw ? this.diagonalIsInside_(s3.p1, p2, p1, p0,
s0.p0) : this.diagonalIsInside_(s0.p0, p0, p1, p2, s3.p1);
var variableCriterion;
if (simple) {
variableCriterion = this.getPointsInTriangle_(p0, p1, p2, rtree, true).length === 0;
} else {
variableCriterion = ccw ? this.diagonalIsInside_(s3.p1, p2, p1, p0,
s0.p0) : this.diagonalIsInside_(s0.p0, p0, p1, p2, s3.p1);
}
if ((simple || this.getIntersections_({p0: p0, p1: p2}, rtree).length === 0) &&
diagonalIsInside && this.getPointsInTriangle_(p0, p1, p2, rtree, true).length === 0) {
variableCriterion) {
//The diagonal is completely inside the polygon
if (simple || p0.reflex === false || p2.reflex === false ||
ol.geom.flat.orient.linearRingIsClockwise([s0.p0.x, s0.p0.y, p0.x,
@@ -420,7 +436,7 @@ if (ol.ENABLE_WEBGL) {
* @param {boolean=} opt_touch Resolve touching segments.
* @return {boolean} There were resolved intersections.
*/
ol.render.webgl.PolygonReplay.prototype.resolveLocalSelfIntersections_ = function(
ol.render.webgl.PolygonReplay.prototype.resolveSelfIntersections_ = function(
list, rtree, opt_touch) {
var start = list.firstItem();
list.nextItem();

View File

@@ -129,8 +129,8 @@ if (ol.ENABLE_WEBGL) {
var lines = this.text_.split('\n');
var textSize = this.getTextSize_(lines);
var i, ii, j, jj, currX, currY, charArr, charInfo;
var anchorX = Math.round(textSize[0] * this.textAlign_ + this.offsetX_);
var anchorY = Math.round(textSize[1] * this.textBaseline_ + this.offsetY_);
var anchorX = Math.round(textSize[0] * this.textAlign_ - this.offsetX_);
var anchorY = Math.round(textSize[1] * this.textBaseline_ - this.offsetY_);
var lineWidth = (this.state_.lineWidth / 2) * this.state_.scale;
for (i = 0, ii = lines.length; i < ii; ++i) {

View File

@@ -238,7 +238,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.forEachFeatureAtCoordinate = functi
var sourceTileGrid = source.getTileGrid();
var bufferedExtent, found, tileSpaceCoordinate;
var i, ii, origin, replayGroup;
var tile, tileCoord, tileExtent, tilePixelRatio, tileResolution;
var tile, tileCoord, tileExtent, tilePixelRatio, tileRenderResolution;
for (i = 0, ii = renderedTiles.length; i < ii; ++i) {
tile = renderedTiles[i];
tileCoord = tile.tileCoord;
@@ -254,12 +254,14 @@ ol.renderer.canvas.VectorTileLayer.prototype.forEachFeatureAtCoordinate = functi
var sourceTileExtent = sourceTileGrid.getTileCoordExtent(sourceTileCoord, this.tmpExtent);
origin = ol.extent.getTopLeft(sourceTileExtent);
tilePixelRatio = this.getTilePixelRatio_(source, sourceTile);
tileResolution = sourceTileGrid.getResolution(sourceTileCoord[0]) / tilePixelRatio;
var sourceTileResolution = sourceTileGrid.getResolution(sourceTileCoord[0]);
tileRenderResolution = sourceTileResolution / tilePixelRatio;
tileSpaceCoordinate = [
(coordinate[0] - origin[0]) / tileResolution,
(origin[1] - coordinate[1]) / tileResolution
(coordinate[0] - origin[0]) / tileRenderResolution,
(origin[1] - coordinate[1]) / tileRenderResolution
];
resolution = tilePixelRatio;
var upscaling = tileGrid.getResolution(tileCoord[0]) / sourceTileResolution;
resolution = tilePixelRatio * upscaling;
} else {
tileSpaceCoordinate = coordinate;
}

View File

@@ -27,16 +27,26 @@ goog.require('ol.source.UrlTile');
* @api
*/
ol.source.VectorTile = function(options) {
var projection = options.projection || 'EPSG:3857';
var extent = options.extent || ol.tilegrid.extentFromProjection(projection);
var tileGrid = options.tileGrid || ol.tilegrid.createXYZ({
extent: extent,
maxZoom: options.maxZoom || 22,
minZoom: options.minZoom,
tileSize: options.tileSize || 512
});
ol.source.UrlTile.call(this, {
attributions: options.attributions,
cacheSize: options.cacheSize !== undefined ? options.cacheSize : 128,
extent: options.extent,
extent: extent,
logo: options.logo,
opaque: false,
projection: options.projection,
projection: projection,
state: options.state,
tileGrid: options.tileGrid,
tileGrid: tileGrid,
tileLoadFunction: options.tileLoadFunction ?
options.tileLoadFunction : ol.VectorImageTile.defaultLoadFunction,
tileUrlFunction: options.tileUrlFunction,

View File

@@ -8,6 +8,7 @@
goog.provide('ol.Sphere');
goog.require('ol.math');
goog.require('ol.geom.GeometryType');
/**
@@ -51,18 +52,7 @@ ol.Sphere = function(radius) {
* @api
*/
ol.Sphere.prototype.geodesicArea = function(coordinates) {
var area = 0, len = coordinates.length;
var x1 = coordinates[len - 1][0];
var y1 = coordinates[len - 1][1];
for (var i = 0; i < len; i++) {
var x2 = coordinates[i][0], y2 = coordinates[i][1];
area += ol.math.toRadians(x2 - x1) *
(2 + Math.sin(ol.math.toRadians(y1)) +
Math.sin(ol.math.toRadians(y2)));
x1 = x2;
y1 = y2;
}
return area * this.radius * this.radius / 2.0;
return ol.Sphere.getArea_(coordinates, this.radius);
};
@@ -75,14 +65,7 @@ ol.Sphere.prototype.geodesicArea = function(coordinates) {
* @api
*/
ol.Sphere.prototype.haversineDistance = function(c1, c2) {
var lat1 = ol.math.toRadians(c1[1]);
var lat2 = ol.math.toRadians(c2[1]);
var deltaLatBy2 = (lat2 - lat1) / 2;
var deltaLonBy2 = ol.math.toRadians(c2[0] - c1[0]) / 2;
var a = Math.sin(deltaLatBy2) * Math.sin(deltaLatBy2) +
Math.sin(deltaLonBy2) * Math.sin(deltaLonBy2) *
Math.cos(lat1) * Math.cos(lat2);
return 2 * this.radius * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return ol.Sphere.getDistance_(c1, c2, this.radius);
};
@@ -107,3 +90,199 @@ ol.Sphere.prototype.offset = function(c1, distance, bearing) {
Math.cos(dByR) - Math.sin(lat1) * Math.sin(lat));
return [ol.math.toDegrees(lon), ol.math.toDegrees(lat)];
};
/**
* The mean Earth radius (1/3 * (2a + b)) for the WGS84 ellipsoid.
* https://en.wikipedia.org/wiki/Earth_radius#Mean_radius
* @type {number}
*/
ol.Sphere.DEFAULT_RADIUS = 6371008.8;
/**
* Get the spherical length of a geometry. This length is the sum of the
* great circle distances between coordinates. For polygons, the length is
* the sum of all rings. For points, the length is zero. For multi-part
* geometries, the length is the sum of the length of each part.
* @param {ol.geom.Geometry} geometry A geometry.
* @param {olx.SphereMetricOptions=} opt_options Options for the length
* calculation. By default, geometries are assumed to be in 'EPSG:3857'.
* You can change this by providing a `projection` option.
* @return {number} The spherical length (in meters).
* @api
*/
ol.Sphere.getLength = function(geometry, opt_options) {
var options = opt_options || {};
var radius = options.radius || ol.Sphere.DEFAULT_RADIUS;
var projection = options.projection || 'EPSG:3857';
geometry = geometry.clone().transform(projection, 'EPSG:4326');
var type = geometry.getType();
var length = 0;
var coordinates, coords, i, ii, j, jj;
switch (type) {
case ol.geom.GeometryType.POINT:
case ol.geom.GeometryType.MULTI_POINT: {
break;
}
case ol.geom.GeometryType.LINE_STRING:
case ol.geom.GeometryType.LINEAR_RING: {
coordinates = /** @type {ol.geom.SimpleGeometry} */ (geometry).getCoordinates();
length = ol.Sphere.getLength_(coordinates, radius);
break;
}
case ol.geom.GeometryType.MULTI_LINE_STRING:
case ol.geom.GeometryType.POLYGON: {
coordinates = /** @type {ol.geom.SimpleGeometry} */ (geometry).getCoordinates();
for (i = 0, ii = coordinates.length; i < ii; ++i) {
length += ol.Sphere.getLength_(coordinates[i], radius);
}
break;
}
case ol.geom.GeometryType.MULTI_POLYGON: {
coordinates = /** @type {ol.geom.SimpleGeometry} */ (geometry).getCoordinates();
for (i = 0, ii = coordinates.length; i < ii; ++i) {
coords = coordinates[i];
for (j = 0, jj = coords.length; j < jj; ++j) {
length += ol.Sphere.getLength_(coords[j], radius);
}
}
break;
}
case ol.geom.GeometryType.GEOMETRY_COLLECTION: {
var geometries = /** @type {ol.geom.GeometryCollection} */ (geometry).getGeometries();
for (i = 0, ii = geometries.length; i < ii; ++i) {
length += ol.Sphere.getLength(geometries[i], opt_options);
}
break;
}
default: {
throw new Error('Unsupported geometry type: ' + type);
}
}
return length;
};
/**
* Get the cumulative great circle length of linestring coordinates (geographic).
* @param {Array} coordinates Linestring coordinates.
* @param {number} radius The sphere radius to use.
* @return {number} The length (in meters).
*/
ol.Sphere.getLength_ = function(coordinates, radius) {
var length = 0;
for (var i = 0, ii = coordinates.length; i < ii - 1; ++i) {
length += ol.Sphere.getDistance_(coordinates[i], coordinates[i + 1], radius);
}
return length;
};
/**
* Get the great circle distance between two geographic coordinates.
* @param {Array} c1 Starting coordinate.
* @param {Array} c2 Ending coordinate.
* @param {number} radius The sphere radius to use.
* @return {number} The great circle distance between the points (in meters).
*/
ol.Sphere.getDistance_ = function(c1, c2, radius) {
var lat1 = ol.math.toRadians(c1[1]);
var lat2 = ol.math.toRadians(c2[1]);
var deltaLatBy2 = (lat2 - lat1) / 2;
var deltaLonBy2 = ol.math.toRadians(c2[0] - c1[0]) / 2;
var a = Math.sin(deltaLatBy2) * Math.sin(deltaLatBy2) +
Math.sin(deltaLonBy2) * Math.sin(deltaLonBy2) *
Math.cos(lat1) * Math.cos(lat2);
return 2 * radius * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
};
/**
* Get the spherical area of a geometry. This is the area (in meters) assuming
* that polygon edges are segments of great circles on a sphere.
* @param {ol.geom.Geometry} geometry A geometry.
* @param {olx.SphereMetricOptions=} opt_options Options for the area
* calculation. By default, geometries are assumed to be in 'EPSG:3857'.
* You can change this by providing a `projection` option.
* @return {number} The spherical area (in square meters).
* @api
*/
ol.Sphere.getArea = function(geometry, opt_options) {
var options = opt_options || {};
var radius = options.radius || ol.Sphere.DEFAULT_RADIUS;
var projection = options.projection || 'EPSG:3857';
geometry = geometry.clone().transform(projection, 'EPSG:4326');
var type = geometry.getType();
var area = 0;
var coordinates, coords, i, ii, j, jj;
switch (type) {
case ol.geom.GeometryType.POINT:
case ol.geom.GeometryType.MULTI_POINT:
case ol.geom.GeometryType.LINE_STRING:
case ol.geom.GeometryType.MULTI_LINE_STRING:
case ol.geom.GeometryType.LINEAR_RING: {
break;
}
case ol.geom.GeometryType.POLYGON: {
coordinates = /** @type {ol.geom.Polygon} */ (geometry).getCoordinates();
area = Math.abs(ol.Sphere.getArea_(coordinates[0], radius));
for (i = 1, ii = coordinates.length; i < ii; ++i) {
area -= Math.abs(ol.Sphere.getArea_(coordinates[i], radius));
}
break;
}
case ol.geom.GeometryType.MULTI_POLYGON: {
coordinates = /** @type {ol.geom.SimpleGeometry} */ (geometry).getCoordinates();
for (i = 0, ii = coordinates.length; i < ii; ++i) {
coords = coordinates[i];
area += Math.abs(ol.Sphere.getArea_(coords[0], radius));
for (j = 1, jj = coords.length; j < jj; ++j) {
area -= Math.abs(ol.Sphere.getArea_(coords[j], radius));
}
}
break;
}
case ol.geom.GeometryType.GEOMETRY_COLLECTION: {
var geometries = /** @type {ol.geom.GeometryCollection} */ (geometry).getGeometries();
for (i = 0, ii = geometries.length; i < ii; ++i) {
area += ol.Sphere.getArea(geometries[i], opt_options);
}
break;
}
default: {
throw new Error('Unsupported geometry type: ' + type);
}
}
return area;
};
/**
* Returns the spherical area for a list of coordinates.
*
* [Reference](https://trs-new.jpl.nasa.gov/handle/2014/40409)
* Robert. G. Chamberlain and William H. Duquette, "Some Algorithms for
* Polygons on a Sphere", JPL Publication 07-03, Jet Propulsion
* Laboratory, Pasadena, CA, June 2007
*
* @param {Array.<ol.Coordinate>} coordinates List of coordinates of a linear
* ring. If the ring is oriented clockwise, the area will be positive,
* otherwise it will be negative.
* @param {number} radius The sphere radius.
* @return {number} Area (in square meters).
*/
ol.Sphere.getArea_ = function(coordinates, radius) {
var area = 0, len = coordinates.length;
var x1 = coordinates[len - 1][0];
var y1 = coordinates[len - 1][1];
for (var i = 0; i < len; i++) {
var x2 = coordinates[i][0], y2 = coordinates[i][1];
area += ol.math.toRadians(x2 - x1) *
(2 + Math.sin(ol.math.toRadians(y1)) +
Math.sin(ol.math.toRadians(y2)));
x1 = x2;
y1 = y2;
}
return area * radius * radius / 2.0;
};

View File

@@ -302,7 +302,14 @@ ol.View.prototype.animate = function(var_args) {
}
animation.callback = callback;
start += animation.duration;
// check if animation is a no-op
if (ol.View.isNoopAnimation(animation)) {
animation.complete = true;
// we still push it onto the series for callback handling
} else {
start += animation.duration;
}
series.push(animation);
}
this.animations_.push(series);
@@ -1158,3 +1165,24 @@ ol.View.createRotationConstraint_ = function(options) {
return ol.RotationConstraint.disable;
}
};
/**
* Determine if an animation involves no view change.
* @param {ol.ViewAnimation} animation The animation.
* @return {boolean} The animation involves no view change.
*/
ol.View.isNoopAnimation = function(animation) {
if (animation.sourceCenter && animation.targetCenter) {
if (!ol.coordinate.equals(animation.sourceCenter, animation.targetCenter)) {
return false;
}
}
if (animation.sourceResolution !== animation.targetResolution) {
return false;
}
if (animation.sourceRotation !== animation.targetRotation) {
return false;
}
return true;
};

View File

@@ -192,6 +192,33 @@ describe('ol.format.KML', function() {
expect(node).to.xmleql(ol.xml.parse(text));
});
it('can write properties', function() {
var lineString = new ol.geom.LineString([[1, 2], [3, 4]]);
lineString.set('extrude', false);
lineString.set('tessellate', true);
lineString.set('altitudeMode', 'clampToGround');
lineString.set('unsupportedProperty', 'foo');
var features = [new ol.Feature(lineString)];
var node = format.writeFeaturesNode(features);
var text =
'<kml xmlns="http://www.opengis.net/kml/2.2"' +
' xmlns:gx="http://www.google.com/kml/ext/2.2"' +
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' +
' xsi:schemaLocation="http://www.opengis.net/kml/2.2' +
' https://developers.google.com/kml/schema/kml22gx.xsd">' +
' <Placemark>' +
' <LineString>' +
' <extrude>0</extrude>' +
' <tessellate>1</tessellate>' +
' <altitudeMode>clampToGround</altitudeMode>' +
' <coordinates>1,2 3,4</coordinates>' +
' </LineString>' +
' </Placemark>' +
'</kml>';
expect(node).to.xmleql(ol.xml.parse(text));
});
it('can read Point geometries', function() {
var text =
'<kml xmlns="http://www.opengis.net/kml/2.2"' +
@@ -412,6 +439,7 @@ describe('ol.format.KML', function() {
' <LineString>' +
' <coordinates>1,2,3 4,5,6</coordinates>' +
' <extrude>0</extrude>' +
' <tessellate>1</tessellate>' +
' <altitudeMode>absolute</altitudeMode>' +
' </LineString>' +
' </Placemark>' +
@@ -424,6 +452,7 @@ describe('ol.format.KML', function() {
expect(g).to.be.an(ol.geom.LineString);
expect(g.getCoordinates()).to.eql([[1, 2, 3], [4, 5, 6]]);
expect(g.get('extrude')).to.be(false);
expect(g.get('tessellate')).to.be(true);
expect(g.get('altitudeMode')).to.be('absolute');
});
@@ -964,6 +993,7 @@ describe('ol.format.KML', function() {
' <MultiGeometry>' +
' <LineString>' +
' <extrude>0</extrude>' +
' <tessellate>0</tessellate>' +
' <altitudeMode>absolute</altitudeMode>' +
' <coordinates>1,2,3 4,5,6</coordinates>' +
' </LineString>' +
@@ -985,6 +1015,10 @@ describe('ol.format.KML', function() {
expect(g.get('extrude')).to.have.length(2);
expect(g.get('extrude')[0]).to.be(false);
expect(g.get('extrude')[1]).to.be(undefined);
expect(g.get('tessellate')).to.be.an('array');
expect(g.get('tessellate')).to.have.length(2);
expect(g.get('tessellate')[0]).to.be(false);
expect(g.get('tessellate')[1]).to.be(undefined);
expect(g.get('altitudeMode')).to.be.an('array');
expect(g.get('altitudeMode')).to.have.length(2);
expect(g.get('altitudeMode')[0]).to.be('absolute');

View File

@@ -6,7 +6,7 @@ goog.require('ol.events.Event');
goog.require('ol.events.EventTarget');
goog.require('ol.format.GeoJSON');
goog.require('ol.interaction.DragAndDrop');
goog.require('ol.source.Vector');
where('FileReader').describe('ol.interaction.DragAndDrop', function() {
var viewport, map, interaction;
@@ -37,6 +37,14 @@ where('FileReader').describe('ol.interaction.DragAndDrop', function() {
expect(interaction.formatConstructors_).to.have.length(1);
});
it('accepts a source option', function() {
var source = new ol.source.Vector();
var drop = new ol.interaction.DragAndDrop({
formatConstructors: [ol.format.GeoJSON],
source: source
});
expect(drop.source_).to.equal(source);
});
});
describe('#setActive()', function() {
@@ -128,6 +136,41 @@ where('FileReader').describe('ol.interaction.DragAndDrop', function() {
expect(event.dataTransfer.dropEffect).to.be('copy');
expect(event.propagationStopped).to.be(true);
});
it('adds dropped features to a source', function(done) {
var source = new ol.source.Vector();
var drop = new ol.interaction.DragAndDrop({
formatConstructors: [ol.format.GeoJSON],
source: source
});
drop.setMap(map);
drop.on('addfeatures', function(evt) {
var features = source.getFeatures();
expect(features.length).to.be(1);
done();
});
var event = new ol.events.Event();
event.dataTransfer = {};
event.type = 'dragenter';
viewport.dispatchEvent(event);
event.type = 'dragover';
viewport.dispatchEvent(event);
event.type = 'drop';
event.dataTransfer.files = {
length: 1,
item: function() {
return JSON.stringify({
type: 'FeatureCollection',
features: [{type: 'Feature', id: '1'}]
});
}
};
viewport.dispatchEvent(event);
expect(event.dataTransfer.dropEffect).to.be('copy');
expect(event.propagationStopped).to.be(true);
});
});
});

View File

@@ -221,21 +221,21 @@ describe('ol.proj', function() {
});
it('returns the correct point resolution for EPSG:4326 with custom units', function() {
var pointResolution = ol.proj.getPointResolution('EPSG:4326', 1, [0, 0], 'm');
expect (pointResolution).to.roughlyEqual(111194.874284, 1e-5);
expect(pointResolution).to.roughlyEqual(111195.0802335329, 1e-5);
pointResolution = ol.proj.getPointResolution('EPSG:4326', 1, [0, 52], 'm');
expect (pointResolution).to.roughlyEqual(89826.367538, 1e-5);
expect(pointResolution).to.roughlyEqual(89826.53390979706, 1e-5);
});
it('returns the correct point resolution for EPSG:3857', function() {
var pointResolution = ol.proj.getPointResolution('EPSG:3857', 1, [0, 0]);
expect (pointResolution).to.be(1);
expect(pointResolution).to.be(1);
pointResolution = ol.proj.getPointResolution('EPSG:3857', 1, ol.proj.fromLonLat([0, 52]));
expect (pointResolution).to.roughlyEqual(0.615661, 1e-5);
expect(pointResolution).to.roughlyEqual(0.615661, 1e-5);
});
it('returns the correct point resolution for EPSG:3857 with custom units', function() {
var pointResolution = ol.proj.getPointResolution('EPSG:3857', 1, [0, 0], 'degrees');
expect (pointResolution).to.be(1);
expect(pointResolution).to.be(1);
pointResolution = ol.proj.getPointResolution('EPSG:4326', 1, ol.proj.fromLonLat([0, 52]), 'degrees');
expect (pointResolution).to.be(1);
expect(pointResolution).to.be(1);
});
});

View File

@@ -154,8 +154,8 @@ describe('ol.render.webgl.TextReplay', function() {
expect(replay.originY).to.be(charInfo.offsetY);
expect(replay.imageHeight).to.be(charInfo.image.height);
expect(replay.imageWidth).to.be(charInfo.image.width);
expect(replay.anchorX).to.be(-widthX + 10);
expect(replay.anchorY).to.be(10);
expect(replay.anchorX).to.be(-widthX - 10);
expect(replay.anchorY).to.be(-10);
});
it('does not draw if text is empty', function() {

View File

@@ -298,6 +298,42 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
expect(spy.callCount).to.be(1);
expect(spy.getCall(0).args[1]).to.equal(layer);
});
});
it('does not give false positives when overzoomed', function(done) {
var target = document.createElement('div');
target.style.width = '100px';
target.style.height = '100px';
document.body.appendChild(target);
var extent = [1824704.739223726, 6141868.096770482, 1827150.7241288517, 6144314.081675608];
var source = new ol.source.VectorTile({
format: new ol.format.MVT(),
url: 'spec/ol/data/14-8938-5680.vector.pbf',
minZoom: 14,
maxZoom: 14
});
var map = new ol.Map({
target: target,
layers: [
new ol.layer.VectorTile({
extent: extent,
source: source
})
],
view: new ol.View({
center: ol.extent.getCenter(extent),
zoom: 19
})
});
source.on('tileloadend', function() {
setTimeout(function() {
var features = map.getFeaturesAtPixel([96, 96]);
document.body.removeChild(target);
map.dispose();
expect(features).to.be(null);
done();
}, 200);
});
});
});
});

View File

@@ -6,13 +6,11 @@ goog.require('ol.proj');
goog.require('ol.source.VectorTile');
goog.require('ol.tilegrid');
describe('ol.source.VectorTile', function() {
var format = new ol.format.MVT();
var source = new ol.source.VectorTile({
format: format,
tileGrid: ol.tilegrid.createXYZ({tileSize: 512}),
tilePixelRatio: 8,
url: 'spec/ol/data/{z}-{x}-{y}.vector.pbf'
});
@@ -22,9 +20,16 @@ describe('ol.source.VectorTile', function() {
it('sets the format on the instance', function() {
expect(source.format_).to.equal(format);
});
it('uses ol.VectorTile as default tileClass', function() {
expect(source.tileClass).to.equal(ol.VectorTile);
});
it('creates a 512 XYZ tilegrid by default', function() {
var tileGrid = ol.tilegrid.createXYZ({tileSize: 512});
expect(source.tileGrid.tileSize_).to.equal(tileGrid.tileSize_);
expect(source.tileGrid.extent_).to.equal(tileGrid.extent_);
});
});
describe('#getTile()', function() {

View File

@@ -108,3 +108,92 @@ describe('ol.Sphere', function() {
});
});
describe('ol.Sphere.getLength()', function() {
var cases = [{
geometry: new ol.geom.Point([0, 0]),
length: 0
}, {
geometry: new ol.geom.MultiPoint([[0, 0], [1, 1]]),
length: 0
}, {
geometry: new ol.geom.LineString([
[12801741.441226462, -3763310.627144653],
[14582853.293918837, -2511525.2348457114],
[15918687.18343812, -2875744.624352243],
[16697923.618991036, -4028802.0261344076]
]),
length: 4407939.124914191
}, {
geometry: new ol.geom.LineString([
[115, -32],
[131, -22],
[143, -25],
[150, -34]
]),
options: {projection: 'EPSG:4326'},
length: 4407939.124914191
}, {
geometry: new ol.geom.MultiLineString([
[
[115, -32],
[131, -22],
[143, -25],
[150, -34]
], [
[115, -32],
[131, -22],
[143, -25],
[150, -34]
]
]),
options: {projection: 'EPSG:4326'},
length: 2 * 4407939.124914191
}, {
geometry: new ol.geom.GeometryCollection([
new ol.geom.LineString([
[115, -32],
[131, -22],
[143, -25],
[150, -34]
]),
new ol.geom.LineString([
[115, -32],
[131, -22],
[143, -25],
[150, -34]
])
]),
options: {projection: 'EPSG:4326'},
length: 2 * 4407939.124914191
}];
cases.forEach(function(c, i) {
it('works for case ' + i, function() {
var c = cases[i];
var length = ol.Sphere.getLength(c.geometry, c.options);
expect(length).to.equal(c.length);
});
});
});
describe('ol.Sphere.getArea()', function() {
var geometry;
before(function(done) {
afterLoadText('spec/ol/format/wkt/illinois.wkt', function(wkt) {
try {
var format = new ol.format.WKT();
geometry = format.readGeometry(wkt);
} catch (e) {
done(e);
}
done();
});
});
it('calculates the area of Ilinois', function() {
var area = ol.Sphere.getArea(geometry, {projection: 'EPSG:4326'});
expect(area).to.equal(145652224192.4434);
});
});

View File

@@ -457,6 +457,20 @@ describe('ol.View', function() {
}, 10);
});
it('immediately completes for no-op animations', function() {
var view = new ol.View({
center: [0, 0],
zoom: 5
});
view.animate({
zoom: 5,
center: [0, 0],
duration: 25
});
expect(view.getAnimating()).to.eql(false);
});
it('prefers zoom over resolution', function(done) {
var view = new ol.View({
center: [0, 0],
@@ -556,6 +570,21 @@ describe('ol.View', function() {
view.setCenter([1, 2]); // interrupt the animation
});
it('calls a callback even if animation is a no-op', function(done) {
var view = new ol.View({
center: [0, 0],
zoom: 0
});
view.animate({
zoom: 0,
duration: 25
}, function(complete) {
expect(complete).to.be(true);
done();
});
});
it('can run multiple animations in series', function(done) {
var view = new ol.View({
center: [0, 0],
@@ -613,7 +642,7 @@ describe('ol.View', function() {
expect(view.getHints()[ol.ViewHint.ANIMATING]).to.be(2);
view.animate({
rotate: Math.PI,
rotation: Math.PI,
duration: 25
}, decrement);
expect(view.getHints()[ol.ViewHint.ANIMATING]).to.be(3);
@@ -640,7 +669,7 @@ describe('ol.View', function() {
expect(view.getHints()[ol.ViewHint.ANIMATING]).to.be(2);
view.animate({
rotate: Math.PI,
rotation: Math.PI,
duration: 25
});
expect(view.getHints()[ol.ViewHint.ANIMATING]).to.be(3);
@@ -1282,3 +1311,74 @@ describe('ol.View', function() {
});
});
});
describe('ol.View.isNoopAnimation()', function() {
var cases = [{
animation: {
sourceCenter: [0, 0], targetCenter: [0, 0],
sourceResolution: 1, targetResolution: 1,
sourceRotation: 0, targetRotation: 0
},
noop: true
}, {
animation: {
sourceCenter: [0, 0], targetCenter: [0, 1],
sourceResolution: 1, targetResolution: 1,
sourceRotation: 0, targetRotation: 0
},
noop: false
}, {
animation: {
sourceCenter: [0, 0], targetCenter: [0, 0],
sourceResolution: 1, targetResolution: 0,
sourceRotation: 0, targetRotation: 0
},
noop: false
}, {
animation: {
sourceCenter: [0, 0], targetCenter: [0, 0],
sourceResolution: 1, targetResolution: 1,
sourceRotation: 0, targetRotation: 1
},
noop: false
}, {
animation: {
sourceCenter: [0, 0], targetCenter: [0, 0]
},
noop: true
}, {
animation: {
sourceCenter: [1, 0], targetCenter: [0, 0]
},
noop: false
}, {
animation: {
sourceResolution: 1, targetResolution: 1
},
noop: true
}, {
animation: {
sourceResolution: 0, targetResolution: 1
},
noop: false
}, {
animation: {
sourceRotation: 10, targetRotation: 10
},
noop: true
}, {
animation: {
sourceRotation: 0, targetRotation: 10
},
noop: false
}];
cases.forEach(function(c, i) {
it('works for case ' + i, function() {
var noop = ol.View.isNoopAnimation(c.animation);
expect(noop).to.equal(c.noop);
});
});
});