Compare commits
100 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e406c9633 | ||
|
|
9f4112a8f9 | ||
|
|
30ddbad4fe | ||
|
|
efd1caf00f | ||
|
|
488a55c83c | ||
|
|
1dc6c99328 | ||
|
|
405d5666e2 | ||
|
|
bad5a97d20 | ||
|
|
9a9b838235 | ||
|
|
5bdfc35d35 | ||
|
|
361d83dc73 | ||
|
|
8f2cfe9420 | ||
|
|
5d9708be11 | ||
|
|
ea7879f616 | ||
|
|
682c816b9b | ||
|
|
b1289dbae7 | ||
|
|
cf99bcbba1 | ||
|
|
5ae2521724 | ||
|
|
81b13f295b | ||
|
|
e43573bcf2 | ||
|
|
894be51b36 | ||
|
|
b06f3457da | ||
|
|
7f1053d2cd | ||
|
|
96741e1f0b | ||
|
|
f5cd9a3eba | ||
|
|
4196e34c73 | ||
|
|
22bed40f5c | ||
|
|
a33008be9e | ||
|
|
746116d266 | ||
|
|
1f6d2eff96 | ||
|
|
764f821a70 | ||
|
|
41596d808b | ||
|
|
ec208916d2 | ||
|
|
78dcbe6b8e | ||
|
|
074941bf1f | ||
|
|
824a77e41b | ||
|
|
e766d00e7b | ||
|
|
2e2d08f552 | ||
|
|
9870fe58e0 | ||
|
|
80efbb60d0 | ||
|
|
111e6db8c8 | ||
|
|
f40aa54c18 | ||
|
|
531b35d7c2 | ||
|
|
879307da1b | ||
|
|
acb0a8da53 | ||
|
|
e87b616de8 | ||
|
|
a3f9b3ba43 | ||
|
|
680f140858 | ||
|
|
b6a4188ce4 | ||
|
|
4be106d014 | ||
|
|
100020fd59 | ||
|
|
3580cdc823 | ||
|
|
f0720b2f97 | ||
|
|
e578f98c73 | ||
|
|
1dbf8cd4d6 | ||
|
|
0f36d1a7c2 | ||
|
|
2b76bc05a5 | ||
|
|
1ac41c7403 | ||
|
|
96550c8fcf | ||
|
|
26f1062dbf | ||
|
|
26ad3fe6b1 | ||
|
|
34986b0870 | ||
|
|
19c91235ce | ||
|
|
901a0f6d8e | ||
|
|
250221cded | ||
|
|
4e94908440 | ||
|
|
23b207dae4 | ||
|
|
16c4082898 | ||
|
|
51c8bcae57 | ||
|
|
b606f4996b | ||
|
|
7dc2a2b97e | ||
|
|
a243149d02 | ||
|
|
a314813511 | ||
|
|
fe79389fd3 | ||
|
|
d5c69b2e5e | ||
|
|
2724292de1 | ||
|
|
829337c219 | ||
|
|
549d0a7601 | ||
|
|
b602285992 | ||
|
|
82b1355591 | ||
|
|
249f432b2e | ||
|
|
45a5b1d24e | ||
|
|
c5b788f370 | ||
|
|
ebded733f7 | ||
|
|
e4e91b82d6 | ||
|
|
8f9cde0595 | ||
|
|
f47d873ae5 | ||
|
|
492a3c8f7a | ||
|
|
0bf70489b6 | ||
|
|
32efd99397 | ||
|
|
0650a97371 | ||
|
|
b05193fa45 | ||
|
|
a116878a57 | ||
|
|
700903ca5c | ||
|
|
4192092dcf | ||
|
|
c0d9a822f8 | ||
|
|
bb6192bc10 | ||
|
|
56e8575e41 | ||
|
|
762bb0f055 | ||
|
|
dd07fd7977 |
@@ -329,3 +329,33 @@ Occasionally other changes to `master` might mean that your pull request cannot
|
||||
be merged automatically. In this case you may need to rebase your branch on a
|
||||
more recent `master`, resolve any conflicts, and `git push --force` to update
|
||||
your branch so that it can be merged automatically.
|
||||
|
||||
## Building on Windows
|
||||
|
||||
Most developers build on Linux. Building on Windows is possible under Cygwin.
|
||||
When installing Cygwin from https://www.cygwin.com/, include the developer
|
||||
tools to get GNU make.
|
||||
|
||||
First (before npm install), to avoid file permission problems between Windows
|
||||
and Cygwin, edit Cygwin's /etc/fstab file to disable ACLs like this
|
||||
`none /cygdrive cygdrive binary,noacl,posix=0,user 0 0`
|
||||
|
||||
Python is normally installed with Cygwin so need not be installed separately.
|
||||
By default Cygwin will use its own version of Python rather than Window's,
|
||||
so the Python modules should be installed for Cygwin's Python.
|
||||
|
||||
The build targets `check-deps`, `serve`, `lint`, `build`, `test`, `check` and
|
||||
`host-examples` described above should all work. `host-examples` takes quite a
|
||||
while to run. If a target does not run properly first time, try it again.
|
||||
|
||||
Currently, Firefox fails to run http://localhost:3000/build/examples
|
||||
from make serve, but Chrome and Internet Explorer will.
|
||||
|
||||
Microsoft Visual Studio's javascript debugger may be used to debug the
|
||||
build/hosted/your-branch/examples. It will be convenient to set
|
||||
build/hosted/your-branch/examples/index.html as the startup page.
|
||||
|
||||
Your ol3 source tree need not be under the Cygwin root.
|
||||
if you checkout to c:/ol3 then you can build under Cygwin at /cygdrive/c/ol3 .
|
||||
However, keep the path to the ol3 files short otherwise you may see
|
||||
`ENAMETOOLONG` errors.
|
||||
|
||||
6
Makefile
6
Makefile
@@ -23,7 +23,11 @@ CHECK_EXAMPLE_TIMESTAMPS = $(patsubst examples/%.html,build/timestamps/check-%-t
|
||||
|
||||
TASKS_JS := $(shell find tasks -name '*.js')
|
||||
|
||||
CLOSURE_LIB = $(shell node -e 'process.stdout.write(require("closure-util").getLibraryPath())')
|
||||
ifeq (CYGWIN,$(findstring CYGWIN,$(OS)))
|
||||
CLOSURE_LIB = $(shell cygpath -u $(shell node -e 'process.stdout.write(require("closure-util").getLibraryPath())'))
|
||||
else
|
||||
CLOSURE_LIB = $(shell node -e 'process.stdout.write(require("closure-util").getLibraryPath())')
|
||||
endif
|
||||
|
||||
ifeq ($(OS),Darwin)
|
||||
STAT_COMPRESSED = stat -f ' compressed: %z bytes'
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
## Getting Started
|
||||
|
||||
- Download the [latest release](https://github.com/openlayers/ol3/releases/tag/v3.4.0)
|
||||
- Download the [latest release](http://openlayers.org/download/)
|
||||
- Install with npm: `npm install openlayers`
|
||||
- Clone the repo: `git clone git@github.com:openlayers/ol3.git`
|
||||
|
||||
|
||||
@@ -1,5 +1,20 @@
|
||||
## Upgrade notes
|
||||
|
||||
### v3.6.0
|
||||
|
||||
#### `ol.interaction.Draw` changes
|
||||
|
||||
* The `minPointsPerRing` config option has been renamed to `minPoints`. It is now also available for linestring drawing, not only for polygons.
|
||||
* The `ol.DrawEvent` and `ol.DrawEventType` types were renamed to `ol.interaction.DrawEvent` and `ol.interaction.DrawEventType`. This has an impact on your code only if your code is compiled together with ol3.
|
||||
|
||||
#### `ol.tilegrid` changes
|
||||
|
||||
* The `ol.tilegrid.XYZ` constructor has been replaced by a static `ol.tilegrid.createXYZ()` function. The `ol.tilegrid.createXYZ()` function takes the same arguments as the previous `ol.tilegrid.XYZ` constructor, but returns an `ol.tilegrid.TileGrid` instance.
|
||||
* The internal tile coordinate scheme for XYZ sources has been changed. Previously, the `y` of tile coordinates was transformed to the coordinates used by sources by calculating `-y-1`. Now, it is transformed by calculating `height-y-1`, where height is the number of rows of the tile grid at the zoom level of the tile coordinate.
|
||||
* The `widths` constructor option of `ol.tilegrid.TileGrid` and subclasses is no longer available, and it is no longer necessary to get proper wrapping at the 180° meridian. However, for `ol.tilegrid.WMTS`, there is a new option `sizes`, where each entry is an `ol.Size` with the `width` ('TileMatrixWidth' in WMTS capabilities) as first and the `height` ('TileMatrixHeight') as second entry of the array. For other tile grids, users can
|
||||
now specify an `extent` instead of `widths`. These settings are used to restrict the range of tiles that sources will request.
|
||||
* For `ol.source.TileWMS`, the default value of `warpX` used to be `undefined`, meaning that WMS requests with out-of-extent tile BBOXes would be sent. Now `wrapX` can only be `true` or `false`, and the new default is `true`. No application code changes should be required, but the resulting WMS requests for out-of-extent tiles will no longer use out-of-extent BBOXes, but ones that are shifted to real-world coordinates.
|
||||
|
||||
### v3.5.0
|
||||
|
||||
#### `ol.Object` and `bindTo`
|
||||
|
||||
64
changelog/v3.6.0.md
Normal file
64
changelog/v3.6.0.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# v3.6.0
|
||||
|
||||
## Summary
|
||||
|
||||
The v3.6.0 release includes features and fixes from 40 pull requests since v3.5.0. To simplify the code base, there were some changes to "experimental" features. Please follow the upgrade notes to make your applications work with the latest release.
|
||||
|
||||
## Upgrade notes
|
||||
|
||||
### `ol.interaction.Draw` changes
|
||||
|
||||
* The `minPointsPerRing` config option has been renamed to `minPoints`. It is now also available for linestring drawing, not only for polygons.
|
||||
* The `ol.DrawEvent` and `ol.DrawEventType` types were renamed to `ol.interaction.DrawEvent` and `ol.interaction.DrawEventType`. This has an impact on your code only if your code is compiled together with ol3.
|
||||
|
||||
### `ol.tilegrid` changes
|
||||
|
||||
* The `ol.tilegrid.XYZ` constructor has been replaced by a static `ol.tilegrid.createXYZ()` function. The `ol.tilegrid.createXYZ()` function takes the same arguments as the previous `ol.tilegrid.XYZ` constructor, but returns an `ol.tilegrid.TileGrid` instance.
|
||||
* The internal tile coordinate scheme for XYZ sources has been changed. Previously, the `y` of tile coordinates was transformed to the coordinates used by sources by calculating `-y-1`. Now, it is transformed by calculating `height-y-1`, where height is the number of rows of the tile grid at the zoom level of the tile coordinate.
|
||||
* The `widths` constructor option of `ol.tilegrid.TileGrid` and subclasses is no longer available, and it is no longer necessary to get proper wrapping at the 180° meridian. However, for `ol.tilegrid.WMTS`, there is a new option `sizes`, where each entry is an `ol.Size` with the `width` ('TileMatrixWidth' in WMTS capabilities) as first and the `height` ('TileMatrixHeight') as second entry of the array. For other tile grids, users can
|
||||
now specify an `extent` instead of `widths`. These settings are used to restrict the range of tiles that sources will request.
|
||||
* For `ol.source.TileWMS`, the default value of `warpX` used to be `undefined`, meaning that WMS requests with out-of-extent tile BBOXes would be sent. Now `wrapX` can only be `true` or `false`, and the new default is `true`. No application code changes should be required, but the resulting WMS requests for out-of-extent tiles will no longer use out-of-extent BBOXes, but ones that are shifted to real-world coordinates.
|
||||
|
||||
## New features and fixes
|
||||
|
||||
* [#3764](https://github.com/openlayers/ol3/pull/3764) - Add tests and implementation for intersectsExtent (ol.geom.Geometry) ([@alvinlindstam](https://github.com/alvinlindstam))
|
||||
* [#3757](https://github.com/openlayers/ol3/pull/3757) - Add mapBrowserEvent as a member of ol.SelectEvent ([@bjornharrtell](https://github.com/bjornharrtell))
|
||||
* [#3759](https://github.com/openlayers/ol3/pull/3759) - Mark tilegrid.createTileCoordTransform() @api ([@gberaudo](https://github.com/gberaudo))
|
||||
* [#3747](https://github.com/openlayers/ol3/pull/3747) - Make tileCoordTransform a member again ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#3751](https://github.com/openlayers/ol3/pull/3751) - Do not rely on remote services for tests ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#3749](https://github.com/openlayers/ol3/pull/3749) - Fix typo in API docs ([@marcjansen](https://github.com/marcjansen))
|
||||
* [#3739](https://github.com/openlayers/ol3/pull/3739) - Simplify detection of scientific notation in WKT format ([@marcjansen](https://github.com/marcjansen))
|
||||
* [#3741](https://github.com/openlayers/ol3/pull/3741) - Enhance docs of arguments and return values of callbacks / filters ([@marcjansen](https://github.com/marcjansen))
|
||||
* [#3740](https://github.com/openlayers/ol3/pull/3740) - Add @fires to select interaction ([@probins](https://github.com/probins))
|
||||
* [#3738](https://github.com/openlayers/ol3/pull/3738) - Improve doucmentation for ol.TileUrlFunctionType ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#3736](https://github.com/openlayers/ol3/pull/3736) - Fix invalid example HTML markup ([@fredj](https://github.com/fredj))
|
||||
* [#3735](https://github.com/openlayers/ol3/pull/3735) - Snap example: remove featureoverlay from tags ([@probins](https://github.com/probins))
|
||||
* [#3732](https://github.com/openlayers/ol3/pull/3732) - Add a method to bind button bluring on mouseout/focusout ([@marcjansen](https://github.com/marcjansen))
|
||||
* [#3659](https://github.com/openlayers/ol3/pull/3659) - Revert "Implement ol.renderer.Layer#forEachFeatureAtCoordinate" ([@fredj](https://github.com/fredj))
|
||||
* [#3683](https://github.com/openlayers/ol3/pull/3683) - Improve Map docs for layers and layergroups ([@probins](https://github.com/probins))
|
||||
* [#3720](https://github.com/openlayers/ol3/pull/3720) - Add missing goog.provides in drawinteraction.js ([@elemoine](https://github.com/elemoine))
|
||||
* [#3725](https://github.com/openlayers/ol3/pull/3725) - Document default value for olx.interaction.ModifyOptions#pixelTolerance ([@fredj](https://github.com/fredj))
|
||||
* [#3722](https://github.com/openlayers/ol3/pull/3722) - Use the correct TileCoord transform function ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#3692](https://github.com/openlayers/ol3/pull/3692) - Updates for building on Windows using Cygwin. ([@bill-chadwick](https://github.com/bill-chadwick))
|
||||
* [#3718](https://github.com/openlayers/ol3/pull/3718) - Add a assertion for renderOrder ([@tsauerwein](https://github.com/tsauerwein))
|
||||
* [#3711](https://github.com/openlayers/ol3/pull/3711) - Fix and test ol.color.blend ([@marcjansen](https://github.com/marcjansen))
|
||||
* [#3673](https://github.com/openlayers/ol3/pull/3673) - More control over ol.interaction.Draw, to allow e.g. square drawing ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#3710](https://github.com/openlayers/ol3/pull/3710) - Add more tests for ol.extent ([@marcjansen](https://github.com/marcjansen))
|
||||
* [#3709](https://github.com/openlayers/ol3/pull/3709) - vector-wfs example does not work in JSFiddle ([@bartvde](https://github.com/bartvde))
|
||||
* [#3699](https://github.com/openlayers/ol3/pull/3699) - Add support for scientific notation to WKT format ([@marcjansen](https://github.com/marcjansen))
|
||||
* [#3696](https://github.com/openlayers/ol3/pull/3696) - Add an example for various blend modes ([@marcjansen](https://github.com/marcjansen))
|
||||
* [#3697](https://github.com/openlayers/ol3/pull/3697) - Use a valid SPDX license expression ([@marcjansen](https://github.com/marcjansen))
|
||||
* [#3694](https://github.com/openlayers/ol3/pull/3694) - Correct typo in upgrade-notes ([@probins](https://github.com/probins))
|
||||
* [#3693](https://github.com/openlayers/ol3/pull/3693) - Fix ol.extent.containsExtent documentation ([@tremby](https://github.com/tremby))
|
||||
* [#3689](https://github.com/openlayers/ol3/pull/3689) - Fix WMTS.optionsFromCapabilities if no OperationsMetadata section ([@probins](https://github.com/probins))
|
||||
* [#3688](https://github.com/openlayers/ol3/pull/3688) - Add two missing properties to extern of WebGLContextAttributes ([@fredj](https://github.com/fredj))
|
||||
* [#3682](https://github.com/openlayers/ol3/pull/3682) - Add a note about using the collection in addLayer ([@bartvde](https://github.com/bartvde))
|
||||
* [#3649](https://github.com/openlayers/ol3/pull/3649) - More specific regex in serve.js ([@elemoine](https://github.com/elemoine))
|
||||
* [#3677](https://github.com/openlayers/ol3/pull/3677) - Add metadata to examples, ([@tschaub](https://github.com/tschaub))
|
||||
* [#3672](https://github.com/openlayers/ol3/pull/3672) - Add link to FAQ-document and fix internal links ([@marcjansen](https://github.com/marcjansen))
|
||||
* [#3665](https://github.com/openlayers/ol3/pull/3665) - Add proj4js and projection definition files to example resources ([@marcjansen](https://github.com/marcjansen))
|
||||
* [#3662](https://github.com/openlayers/ol3/pull/3662) - Clarify docs for renderBuffer option ([@tsauerwein](https://github.com/tsauerwein))
|
||||
* [#3664](https://github.com/openlayers/ol3/pull/3664) - Link to download page. ([@tschaub](https://github.com/tschaub))
|
||||
* [#3639](https://github.com/openlayers/ol3/pull/3639) - Add extent support to ol.tilegrid.TileGrid ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#3663](https://github.com/openlayers/ol3/pull/3663) - Readme should not include the version number. ([@tschaub](https://github.com/tschaub))
|
||||
* [#3637](https://github.com/openlayers/ol3/pull/3637) - Implement ol.renderer.Layer#forEachFeatureAtCoordinate ([@fredj](https://github.com/fredj))
|
||||
@@ -73,7 +73,7 @@
|
||||
</script>
|
||||
</body>
|
||||
</html></code></pre>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
24
doc/faq.md
24
doc/faq.md
@@ -14,15 +14,16 @@ free to ping us or to send a pull request enhancing this document.
|
||||
|
||||
Table of contents:
|
||||
|
||||
* [What projection is OpenLayers using?](#what-projection-is-openlayers-using)
|
||||
* [How do I change the projection of my map?](#how-do-i-change-the-projection-of-my-map)
|
||||
* [Why is my map centered on the gulf of guinea (or africa, the ocean, null-island)?](#why-is-my-map-centered-on-the-gulf-of-guinea-or-africa-the-ocean-null-island)
|
||||
* [Why is the order of a coordinate [lon,lat], and not [lat,lon]?](#why-is-the-order-of-a-coordinate-lonlat-and-not-latlon)
|
||||
* [Why aren't there any features in my source?](#why-arent-there-any-features-in-my-source)
|
||||
* [How do I force a re-render of the map?](#how-do-i-force-a-re-render-of-the-map)
|
||||
* [How do I create a custom build of OpenLayers?](#how-do-i-create-a-custom-build-of-openlayers)
|
||||
* [Do I need to write my own code using Closure library?](#do-i-need-to-write-my-own-code-using-closure-library)
|
||||
* [Do I need to compress my code with Closure compiler?](#do-i-need-to-compress-my-code-with-closure-compiler)
|
||||
* [What projection is OpenLayers using?](#what-projection-is-openlayers-using-)
|
||||
* [How do I change the projection of my map?](#how-do-i-change-the-projection-of-my-map-)
|
||||
* [Why is my map centered on the gulf of guinea (or africa, the ocean, null-island)?](#why-is-my-map-centered-on-the-gulf-of-guinea-or-africa-the-ocean-null-island-)
|
||||
* [Why is the order of a coordinate [lon,lat], and not [lat,lon]?](#why-is-the-order-of-a-coordinate-lon-lat-and-not-lat-lon-)
|
||||
* [Why aren't there any features in my source?](#why-aren-t-there-any-features-in-my-source-)
|
||||
* [How do I force a re-render of the map?](#how-do-i-force-a-re-render-of-the-map-)
|
||||
* [How do I create a custom build of OpenLayers?](#how-do-i-create-a-custom-build-of-openlayers-)
|
||||
* [Do I need to write my own code using Closure library?](#do-i-need-to-write-my-own-code-using-closure-library-)
|
||||
* [Do I need to compress my code with Closure compiler?](#do-i-need-to-compress-my-code-with-closure-compiler-)
|
||||
|
||||
|
||||
## What projection is OpenLayers using?
|
||||
|
||||
@@ -302,7 +303,7 @@ map.renderSync();
|
||||
|
||||
## How do I create a custom build of OpenLayers?
|
||||
|
||||
Please refer to [this blog post](http://boundlessgeo.com/2014/10/openlayers-custom-builds-revisited/)
|
||||
Please refer to the [official create custom builds tutorial](tutorials/custom-builds.html)
|
||||
which explains how to create a custom build of OpenLayers with just those parts
|
||||
included that you want.
|
||||
|
||||
@@ -326,7 +327,8 @@ compiler](https://developers.google.com/closure/compiler/).
|
||||
It may be a good choice though, because when your application code and the
|
||||
OpenLayers source code is compiled together using closure compiler, the
|
||||
resulting build will most probably be the smallest in terms of byte-size. For
|
||||
more details refer to [this tutorial](compile-application.md).
|
||||
more details refer to the
|
||||
[compile application and OpenLayers together tutorial](tutorials/closure.html).
|
||||
|
||||
If you don't want to use the closure compiler, or you can't, you are not at all
|
||||
forced to use it.
|
||||
|
||||
@@ -13,6 +13,10 @@ Make sure to also check out the [OpenLayers 3 workshop](../../../ol3-workshop/).
|
||||
|
||||
Find additional reference material in the [API docs](../apidoc).
|
||||
|
||||
# Questions
|
||||
# Frequently Asked Questions (FAQ)
|
||||
|
||||
If you cannot find an answer in the documentation, you can ask your question on [stackoverflow using the tag 'openlayers-3'](http://stackoverflow.com/questions/tagged/openlayers-3).
|
||||
We have put together a document that lists [Frequently Asked Questions (FAQ)](faq.html) and our answers. Common problems that may arise when using OpenLayers 3 are explained there, and chances are you'll find an appropriate solution in this document.
|
||||
|
||||
# More questions?
|
||||
|
||||
If you cannot find an answer in the documentation or the FAQ, you can ask your question on [stackoverflow using the tag 'openlayers-3'](http://stackoverflow.com/questions/tagged/openlayers-3).
|
||||
|
||||
4
examples/blend-modes.css
Normal file
4
examples/blend-modes.css
Normal file
@@ -0,0 +1,4 @@
|
||||
.map{
|
||||
background-repeat: repeat;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAApSURBVBiVY7x///5/BjSgqKjIiC7GhC6ACwygQgxHMzAwMGDz4FDwDAD5/wevjSk4mwAAAABJRU5ErkJggg==);
|
||||
}
|
||||
76
examples/blend-modes.html
Normal file
76
examples/blend-modes.html
Normal file
@@ -0,0 +1,76 @@
|
||||
---
|
||||
template: example.html
|
||||
title: Blend modes example
|
||||
shortdesc: Shows how to change the canvas compositing / blending mode in post- and precompose eventhandlers.
|
||||
docs: >
|
||||
<p>This example shows how to change the canvas compositing / blending mode in
|
||||
post- and precompose event handlers. The Canvas 2D API provides the property
|
||||
<code>globalCompositeOperation</code> with which one can influence which
|
||||
composition operation will be used when drawing on the canvas. The various
|
||||
options are well described on the <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation">MDN
|
||||
documentation page</a>.</p>
|
||||
|
||||
<p>In this example three circles on the corners of an equilateral triangle are
|
||||
drawn with red, green or blue styles respectively. By setting the
|
||||
<code>globalCompositeOperation</code> you can change how these colors turn out
|
||||
when they are combined on the map.</p>
|
||||
|
||||
<p>You can select an operation in the select-field and you can also control
|
||||
which layers will be affected by the chosen operation through the layer
|
||||
checkboxes.</p>
|
||||
tags: "blendmode, blend-mode, blend mode, blendingmode, blending-mode, blending mode, composition, compositing, canvas, vector"
|
||||
---
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
<div id="map" class="map"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
<form class="form-horizontal">
|
||||
<label>
|
||||
<select id="blend-mode" class="form-control">
|
||||
<option value="source-over">source-over (default)</option>
|
||||
<option>source-in</option>
|
||||
<option>source-out</option>
|
||||
<option>source-atop</option>
|
||||
<option>destination-over</option>
|
||||
<option>destination-in</option>
|
||||
<option>destination-out</option>
|
||||
<option>destination-atop</option>
|
||||
<option>lighter</option>
|
||||
<option>copy</option>
|
||||
<option>xor</option>
|
||||
<option>multiply</option>
|
||||
<option>screen</option>
|
||||
<option>overlay</option>
|
||||
<option>darken</option>
|
||||
<option>lighten</option>
|
||||
<option>color-dodge</option>
|
||||
<option>color-burn</option>
|
||||
<option>hard-light</option>
|
||||
<option>soft-light</option>
|
||||
<option selected>difference</option>
|
||||
<option>exclusion</option>
|
||||
<option>hue</option>
|
||||
<option>saturation</option>
|
||||
<option>color</option>
|
||||
<option>luminosity</option>
|
||||
</select>
|
||||
Canvas compositing / blending mode
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" id="affect-red" checked>
|
||||
Red circle affected
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" id="affect-green" checked>
|
||||
Green circle affected
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" id="affect-blue" checked>
|
||||
Blue circle affected
|
||||
</label>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
177
examples/blend-modes.js
Normal file
177
examples/blend-modes.js
Normal file
@@ -0,0 +1,177 @@
|
||||
goog.require('ol.Feature');
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.style.Circle');
|
||||
goog.require('ol.style.Fill');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
|
||||
|
||||
// Create separate layers for red, green an blue circles.
|
||||
//
|
||||
// Every layer has one feature that is styled with a circle, together the
|
||||
// features form the corners of an equilateral triangle and their styles overlap
|
||||
var redLayer = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({
|
||||
features: [new ol.Feature(new ol.geom.Point([0, 0]))]
|
||||
}),
|
||||
style: new ol.style.Style({
|
||||
image: new ol.style.Circle({
|
||||
fill: new ol.style.Fill({
|
||||
color: 'rgba(255,0,0,0.8)'
|
||||
}),
|
||||
stroke: new ol.style.Stroke({
|
||||
color: 'rgb(255,0,0)',
|
||||
width: 15
|
||||
}),
|
||||
radius: 120
|
||||
})
|
||||
})
|
||||
});
|
||||
var greenLayer = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({
|
||||
// 433.013 is roughly 250 * Math.sqrt(3)
|
||||
features: [new ol.Feature(new ol.geom.Point([250, 433.013]))]
|
||||
}),
|
||||
style: new ol.style.Style({
|
||||
image: new ol.style.Circle({
|
||||
fill: new ol.style.Fill({
|
||||
color: 'rgba(0,255,0,0.8)'
|
||||
}),
|
||||
stroke: new ol.style.Stroke({
|
||||
color: 'rgb(0,255,0)',
|
||||
width: 15
|
||||
}),
|
||||
radius: 120
|
||||
})
|
||||
})
|
||||
});
|
||||
var blueLayer = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({
|
||||
features: [new ol.Feature(new ol.geom.Point([500, 0]))]
|
||||
}),
|
||||
style: new ol.style.Style({
|
||||
image: new ol.style.Circle({
|
||||
fill: new ol.style.Fill({
|
||||
color: 'rgba(0,0,255,0.8)'
|
||||
}),
|
||||
stroke: new ol.style.Stroke({
|
||||
color: 'rgb(0,0,255)',
|
||||
width: 15
|
||||
}),
|
||||
radius: 120
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
// Create the map, the view is centered on the triangle. Zooming and panning is
|
||||
// restricted to a sane area
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
redLayer,
|
||||
greenLayer,
|
||||
blueLayer
|
||||
],
|
||||
target: 'map',
|
||||
view: new ol.View({
|
||||
center: [250, 220],
|
||||
extent: [0, 0, 500, 500],
|
||||
resolution: 4,
|
||||
minResolution: 2,
|
||||
maxResolution: 32
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
// Various helper methods and event handlers
|
||||
/**
|
||||
* This method sets the globalCompositeOperation to the value of the select
|
||||
* field and it is bound to the precompose event of the layers.
|
||||
*
|
||||
* @param {ol.render.Event} evt The render event.
|
||||
*/
|
||||
var setBlendModeFromSelect = function(evt) {
|
||||
evt.context.globalCompositeOperation = select.value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This method resets the globalCompositeOperation to the default value of
|
||||
* 'source-over' and it is bound to the postcompose event of the layers.
|
||||
*
|
||||
* @param {ol.render.Event} evt The render event.
|
||||
*/
|
||||
var resetBlendModeFromSelect = function(evt) {
|
||||
evt.context.globalCompositeOperation = 'source-over';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Bind the pre- and postcompose handlers to the passed layer.
|
||||
*
|
||||
* @param {ol.layer.Vector} layer The layer to bind the handlers to.
|
||||
*/
|
||||
var bindLayerListeners = function(layer) {
|
||||
layer.on('precompose', setBlendModeFromSelect);
|
||||
layer.on('postcompose', resetBlendModeFromSelect);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Unind the pre- and postcompose handlers to the passed layers.
|
||||
*
|
||||
* @param {ol.layer.Vector} layer The layer to unbind the handlers from.
|
||||
*/
|
||||
var unbindLayerListeners = function(layer) {
|
||||
layer.un('precompose', setBlendModeFromSelect);
|
||||
layer.un('postcompose', resetBlendModeFromSelect);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handler for the click event of the 'affect-XXX' checkboxes.
|
||||
*
|
||||
* @this {HTMLInputElement}
|
||||
*/
|
||||
var affectLayerClicked = function() {
|
||||
var layer;
|
||||
if (this.id == 'affect-red') {
|
||||
layer = redLayer;
|
||||
} else if (this.id == 'affect-green') {
|
||||
layer = greenLayer;
|
||||
} else {
|
||||
layer = blueLayer;
|
||||
}
|
||||
if (this.checked) {
|
||||
bindLayerListeners(layer);
|
||||
} else {
|
||||
unbindLayerListeners(layer);
|
||||
}
|
||||
map.render();
|
||||
};
|
||||
|
||||
|
||||
// Get the form elements and bind the listeners
|
||||
var select = document.getElementById('blend-mode');
|
||||
var affectRed = document.getElementById('affect-red');
|
||||
var affectGreen = document.getElementById('affect-green');
|
||||
var affectBlue = document.getElementById('affect-blue');
|
||||
|
||||
// Rerender map when blend mode changes
|
||||
select.addEventListener('change', function() {
|
||||
map.render();
|
||||
});
|
||||
|
||||
// Unbind / bind listeners depending on the checked state when the checkboxes
|
||||
// are clicked
|
||||
affectRed.addEventListener('click', affectLayerClicked);
|
||||
affectGreen.addEventListener('click', affectLayerClicked);
|
||||
affectBlue.addEventListener('click', affectLayerClicked);
|
||||
|
||||
// Initially bind listeners
|
||||
bindLayerListeners(redLayer);
|
||||
bindLayerListeners(greenLayer);
|
||||
bindLayerListeners(blueLayer);
|
||||
@@ -5,7 +5,6 @@ goog.require('ol.layer.Tile');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.source.OSM');
|
||||
goog.require('ol.source.TileDebug');
|
||||
goog.require('ol.tilegrid.XYZ');
|
||||
|
||||
|
||||
var map = new ol.Map({
|
||||
@@ -16,9 +15,7 @@ var map = new ol.Map({
|
||||
new ol.layer.Tile({
|
||||
source: new ol.source.TileDebug({
|
||||
projection: 'EPSG:3857',
|
||||
tileGrid: new ol.tilegrid.XYZ({
|
||||
maxZoom: 22
|
||||
})
|
||||
tileGrid: ol.tilegrid.createXYZ({maxZoom: 22})
|
||||
})
|
||||
})
|
||||
],
|
||||
|
||||
@@ -6,7 +6,10 @@ docs: >
|
||||
Example of using the Draw interaction. Select a geometry type from the
|
||||
dropdown above to start drawing. To finish drawing, click the last
|
||||
point. To activate freehand drawing for lines and polygons, hold the `Shift`
|
||||
key.
|
||||
key. Square drawing is achieved by using Circle mode with a `geometryFunction`
|
||||
that creates a 4-sided regular polygon instead of a circle. Box drawing uses a
|
||||
custom `geometryFunction` that takes start and end point of a line with 2
|
||||
points and creates a rectangular box.
|
||||
tags: "draw, edit, freehand, vector"
|
||||
---
|
||||
<div class="row-fluid">
|
||||
@@ -20,6 +23,8 @@ tags: "draw, edit, freehand, vector"
|
||||
<option value="LineString">LineString</option>
|
||||
<option value="Polygon">Polygon</option>
|
||||
<option value="Circle">Circle</option>
|
||||
<option value="Square">Square</option>
|
||||
<option value="Box">Box</option>
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.geom.Polygon');
|
||||
goog.require('ol.interaction.Draw');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.layer.Vector');
|
||||
@@ -51,9 +52,30 @@ var draw; // global so we can remove it later
|
||||
function addInteraction() {
|
||||
var value = typeSelect.value;
|
||||
if (value !== 'None') {
|
||||
var geometryFunction, maxPoints;
|
||||
if (value === 'Square') {
|
||||
value = 'Circle';
|
||||
geometryFunction = ol.interaction.Draw.createRegularPolygon(4);
|
||||
} else if (value === 'Box') {
|
||||
value = 'LineString';
|
||||
maxPoints = 2;
|
||||
geometryFunction = function(coordinates, geometry) {
|
||||
if (!geometry) {
|
||||
geometry = new ol.geom.Polygon(null);
|
||||
}
|
||||
var start = coordinates[0];
|
||||
var end = coordinates[1];
|
||||
geometry.setCoordinates([
|
||||
[start, [start[0], end[1]], end, [end[0], start[1]], start]
|
||||
]);
|
||||
return geometry;
|
||||
};
|
||||
}
|
||||
draw = new ol.interaction.Draw({
|
||||
source: source,
|
||||
type: /** @type {ol.geom.GeometryType} */ (value)
|
||||
type: /** @type {ol.geom.GeometryType} */ (value),
|
||||
geometryFunction: geometryFunction,
|
||||
maxPoints: maxPoints
|
||||
});
|
||||
map.addInteraction(draw);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
---
|
||||
template: "example-verbatim.html"
|
||||
template: example-verbatim.html
|
||||
title: Geolocation Tracking with Orientation
|
||||
shortdesc: Example of a geolocated and oriented map.
|
||||
tags: "fullscreen, geolocation, orientation, mobile"
|
||||
---
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
@@ -41,15 +44,8 @@ template: "example-verbatim.html"
|
||||
<button id="geolocate">Geolocate Me!</button>
|
||||
<button id="simulate">Simulate</button>
|
||||
</div>
|
||||
|
||||
<script src="http://code.jquery.com/jquery-1.9.1.min.js" type="text/javascript"></script>
|
||||
<script src="./resources/common.js" type="text/javascript"></script>
|
||||
<script src="loader.js?id=geolocation-orientation" type="text/javascript"></script>
|
||||
|
||||
<div style="display: none;">
|
||||
<div id="title">Geolocation tracking with orientation example</div>
|
||||
<div id="shortdesc">Example of a geolocated and oriented map.</div>
|
||||
<div id="tags">fullscreen, geolocation, orientation, mobile</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
---
|
||||
template: "example-verbatim.html"
|
||||
template: example-verbatim.html
|
||||
title: Full-Screen Mobile
|
||||
shortdesc: Example of a full screen map.
|
||||
tags: "fullscreen, geolocation, mobile"
|
||||
---
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
@@ -23,11 +26,5 @@ template: "example-verbatim.html"
|
||||
<script src="./resources/common.js" type="text/javascript"></script>
|
||||
<script src="http://cdnjs.cloudflare.com/ajax/libs/fastclick/1.0.6/fastclick.min.js" type="text/javascript"></script>
|
||||
<script src="loader.js?id=mobile-full-screen" type="text/javascript"></script>
|
||||
|
||||
<div style="display: none;">
|
||||
<div id="title">Mobile full screen example</div>
|
||||
<div id="shortdesc">Example of a full screen map.</div>
|
||||
<div id="tags">fullscreen, bing, geolocation, mobile</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -29,7 +29,7 @@ docs: >
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
tags: "draw, edit, modify, vector, featureoverlay, snap"
|
||||
tags: "draw, edit, modify, vector, snap"
|
||||
---
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
|
||||
@@ -7,13 +7,12 @@ goog.require('ol.source.TileVector');
|
||||
goog.require('ol.style.Fill');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
goog.require('ol.tilegrid.XYZ');
|
||||
|
||||
var waterLayer = new ol.layer.Vector({
|
||||
source: new ol.source.TileVector({
|
||||
format: new ol.format.TopoJSON(),
|
||||
projection: 'EPSG:3857',
|
||||
tileGrid: new ol.tilegrid.XYZ({
|
||||
tileGrid: ol.tilegrid.createXYZ({
|
||||
maxZoom: 19
|
||||
}),
|
||||
url: 'http://{a-c}.tile.openstreetmap.us/' +
|
||||
@@ -31,7 +30,7 @@ var roadLayer = new ol.layer.Vector({
|
||||
source: new ol.source.TileVector({
|
||||
format: new ol.format.TopoJSON(),
|
||||
projection: 'EPSG:3857',
|
||||
tileGrid: new ol.tilegrid.XYZ({
|
||||
tileGrid: ol.tilegrid.createXYZ({
|
||||
maxZoom: 19
|
||||
}),
|
||||
url: 'http://{a-c}.tile.openstreetmap.us/' +
|
||||
@@ -87,7 +86,7 @@ var buildingLayer = new ol.layer.Vector({
|
||||
defaultProjection: 'EPSG:4326'
|
||||
}),
|
||||
projection: 'EPSG:3857',
|
||||
tileGrid: new ol.tilegrid.XYZ({
|
||||
tileGrid: ol.tilegrid.createXYZ({
|
||||
maxZoom: 19
|
||||
}),
|
||||
url: 'http://{a-c}.tile.openstreetmap.us/' +
|
||||
@@ -106,7 +105,7 @@ var landuseLayer = new ol.layer.Vector({
|
||||
defaultProjection: 'EPSG:4326'
|
||||
}),
|
||||
projection: 'EPSG:3857',
|
||||
tileGrid: new ol.tilegrid.XYZ({
|
||||
tileGrid: ol.tilegrid.createXYZ({
|
||||
maxZoom: 19
|
||||
}),
|
||||
url: 'http://{a-c}.tile.openstreetmap.us/' +
|
||||
|
||||
@@ -12,7 +12,6 @@ goog.require('ol.loadingstrategy');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.source.XYZ');
|
||||
goog.require('ol.tilegrid.XYZ');
|
||||
|
||||
|
||||
var serviceUrl = 'http://services.arcgis.com/rOo16HdIMeOBI4Mb/arcgis/rest/' +
|
||||
@@ -45,7 +44,7 @@ var vectorSource = new ol.source.Vector({
|
||||
}
|
||||
}});
|
||||
},
|
||||
strategy: ol.loadingstrategy.tile(new ol.tilegrid.XYZ({
|
||||
strategy: ol.loadingstrategy.tile(ol.tilegrid.createXYZ({
|
||||
tileSize: 512
|
||||
}))
|
||||
});
|
||||
|
||||
@@ -11,7 +11,6 @@ goog.require('ol.source.XYZ');
|
||||
goog.require('ol.style.Fill');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
goog.require('ol.tilegrid.XYZ');
|
||||
|
||||
|
||||
var serviceUrl = 'http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/' +
|
||||
@@ -91,7 +90,7 @@ var vectorSource = new ol.source.Vector({
|
||||
}
|
||||
}});
|
||||
},
|
||||
strategy: ol.loadingstrategy.tile(new ol.tilegrid.XYZ({
|
||||
strategy: ol.loadingstrategy.tile(ol.tilegrid.createXYZ({
|
||||
tileSize: 512
|
||||
}))
|
||||
});
|
||||
|
||||
@@ -12,7 +12,6 @@ goog.require('ol.style.Circle');
|
||||
goog.require('ol.style.Fill');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
goog.require('ol.tilegrid.XYZ');
|
||||
|
||||
var styles = {
|
||||
'amenity': {
|
||||
@@ -102,7 +101,7 @@ var vectorSource = new ol.source.Vector({
|
||||
vectorSource.addFeatures(features);
|
||||
});
|
||||
},
|
||||
strategy: ol.loadingstrategy.tile(new ol.tilegrid.XYZ({
|
||||
strategy: ol.loadingstrategy.tile(ol.tilegrid.createXYZ({
|
||||
maxZoom: 19
|
||||
}))
|
||||
});
|
||||
|
||||
@@ -8,7 +8,6 @@ goog.require('ol.source.BingMaps');
|
||||
goog.require('ol.source.Vector');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Style');
|
||||
goog.require('ol.tilegrid.XYZ');
|
||||
|
||||
|
||||
// format used to parse WFS GetFeature responses
|
||||
@@ -24,14 +23,17 @@ var vectorSource = new ol.source.Vector({
|
||||
// parameter to the URL
|
||||
$.ajax({url: url, dataType: 'jsonp', jsonp: false});
|
||||
},
|
||||
strategy: ol.loadingstrategy.tile(new ol.tilegrid.XYZ({
|
||||
strategy: ol.loadingstrategy.tile(ol.tilegrid.createXYZ({
|
||||
maxZoom: 19
|
||||
}))
|
||||
});
|
||||
|
||||
// the global function whose name is specified in the URL of JSONP WFS
|
||||
// GetFeature requests
|
||||
var loadFeatures = function(response) {
|
||||
|
||||
/**
|
||||
* JSONP WFS callback function.
|
||||
* @param {Object} response The response object.
|
||||
*/
|
||||
window.loadFeatures = function(response) {
|
||||
vectorSource.addFeatures(geojsonFormat.readFeatures(response));
|
||||
};
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ for (var i = 0, ii = resolutions.length; i < ii; ++i) {
|
||||
resolutions[i] = startResolution / Math.pow(2, i);
|
||||
}
|
||||
var tileGrid = new ol.tilegrid.TileGrid({
|
||||
origin: ol.extent.getBottomLeft(projExtent),
|
||||
extent: [-13884991, 2870341, -7455066, 6338219],
|
||||
resolutions: resolutions,
|
||||
tileSize: [512, 256]
|
||||
});
|
||||
@@ -25,7 +25,6 @@ var layers = [
|
||||
source: new ol.source.MapQuest({layer: 'sat'})
|
||||
}),
|
||||
new ol.layer.Tile({
|
||||
extent: [-13884991, 2870341, -7455066, 6338219],
|
||||
source: new ol.source.TileWMS({
|
||||
url: 'http://demo.boundlessgeo.com/geoserver/wms',
|
||||
params: {'LAYERS': 'topp:states', 'TILED': true},
|
||||
|
||||
@@ -5,6 +5,9 @@ shortdesc: Example of integrating Proj4js for coordinate transforms.
|
||||
docs: >
|
||||
With transparent [Proj4js](http://proj4js.org/) integration, OpenLayers can transform coordinates between arbitrary projections.
|
||||
tags: "wms, single image, proj4js, projection"
|
||||
resources:
|
||||
- http://cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.6/proj4.js
|
||||
- http://epsg.io/21781-1753.js
|
||||
---
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
|
||||
@@ -13,8 +13,7 @@ var layers = [
|
||||
source: new ol.source.TileWMS({
|
||||
url: 'http://demo.boundlessgeo.com/geoserver/ne/wms',
|
||||
params: {'LAYERS': 'ne:ne_10m_admin_0_countries', 'TILED': true},
|
||||
serverType: 'geoserver',
|
||||
wrapX: true
|
||||
serverType: 'geoserver'
|
||||
})
|
||||
})
|
||||
];
|
||||
|
||||
@@ -35,7 +35,7 @@ var map = new ol.Map({
|
||||
target: 'map',
|
||||
layers: [
|
||||
new ol.layer.Tile({
|
||||
/* ol.source.XYZ and ol.tilegrid.XYZ have no resolutions config */
|
||||
/* ol.source.XYZ and ol.tilegrid.TileGrid have no resolutions config */
|
||||
source: new ol.source.TileImage({
|
||||
attributions: [attribution],
|
||||
tileUrlFunction: function(tileCoord, pixelRatio, projection) {
|
||||
|
||||
@@ -30,3 +30,15 @@ Touch.prototype.webkitRadiusX;
|
||||
|
||||
/** @type {number} */
|
||||
Touch.prototype.webkitRadiusY;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
WebGLContextAttributes.prototype.preferLowPowerToHighPerformance;
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
WebGLContextAttributes.prototype.failIfMajorPerformanceCaveat;
|
||||
|
||||
@@ -120,21 +120,27 @@ oli.MapEvent.prototype.frameState;
|
||||
/**
|
||||
* @interface
|
||||
*/
|
||||
oli.SelectEvent = function() {};
|
||||
oli.SelectEvent = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.Feature>}
|
||||
*/
|
||||
/**
|
||||
* @type {Array.<ol.Feature>}
|
||||
*/
|
||||
oli.SelectEvent.prototype.deselected;
|
||||
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.Feature>}
|
||||
*/
|
||||
/**
|
||||
* @type {Array.<ol.Feature>}
|
||||
*/
|
||||
oli.SelectEvent.prototype.selected;
|
||||
|
||||
|
||||
/**
|
||||
* @type {ol.MapBrowserEvent}
|
||||
*/
|
||||
oli.SelectEvent.prototype.mapBrowserEvent;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @type {Object}
|
||||
|
||||
134
externs/olx.js
134
externs/olx.js
@@ -226,7 +226,10 @@ olx.MapOptions.prototype.keyboardEventTarget;
|
||||
|
||||
|
||||
/**
|
||||
* Layers. If this is not defined, a map with no layers will be rendered.
|
||||
* Layers. If this is not defined, a map with no layers will be rendered. Note
|
||||
* that layers are rendered in the order supplied, so if you want, for example,
|
||||
* a vector layer to appear on top of a tile layer, it must come after the tile
|
||||
* layer.
|
||||
* @type {Array.<ol.layer.Base>|ol.Collection.<ol.layer.Base>|undefined}
|
||||
* @api stable
|
||||
*/
|
||||
@@ -2357,8 +2360,10 @@ olx.interaction.DragZoomOptions.prototype.style;
|
||||
* source: (ol.source.Vector|undefined),
|
||||
* snapTolerance: (number|undefined),
|
||||
* type: ol.geom.GeometryType,
|
||||
* minPointsPerRing: (number|undefined),
|
||||
* maxPoints: (number|undefined),
|
||||
* minPoints: (number|undefined),
|
||||
* style: (ol.style.Style|Array.<ol.style.Style>|ol.style.StyleFunction|undefined),
|
||||
* geometryFunction: (ol.interaction.DrawGeometryFunctionType|undefined),
|
||||
* geometryName: (string|undefined),
|
||||
* condition: (ol.events.ConditionType|undefined),
|
||||
* freehandCondition: (ol.events.ConditionType|undefined)}}
|
||||
@@ -2393,7 +2398,7 @@ olx.interaction.DrawOptions.prototype.snapTolerance;
|
||||
|
||||
/**
|
||||
* Drawing type ('Point', 'LineString', 'Polygon', 'MultiPoint',
|
||||
* 'MultiLineString', or 'MultiPolygon').
|
||||
* 'MultiLineString', 'MultiPolygon' or 'Circle').
|
||||
* @type {ol.geom.GeometryType}
|
||||
* @api
|
||||
*/
|
||||
@@ -2401,12 +2406,21 @@ olx.interaction.DrawOptions.prototype.type;
|
||||
|
||||
|
||||
/**
|
||||
* The number of points that must be drawn before a polygon ring can be finished.
|
||||
* Default is `3`.
|
||||
* The number of points that can be drawn before a polygon ring or line string
|
||||
* is finished. The default is no restriction.
|
||||
* @type {number|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.interaction.DrawOptions.prototype.minPointsPerRing;
|
||||
olx.interaction.DrawOptions.prototype.maxPoints;
|
||||
|
||||
|
||||
/**
|
||||
* The number of points that must be drawn before a polygon ring or line string
|
||||
* can be finished. Default is `3` for polygon rings and `2` for line strings.
|
||||
* @type {number|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.interaction.DrawOptions.prototype.minPoints;
|
||||
|
||||
|
||||
/**
|
||||
@@ -2417,6 +2431,14 @@ olx.interaction.DrawOptions.prototype.minPointsPerRing;
|
||||
olx.interaction.DrawOptions.prototype.style;
|
||||
|
||||
|
||||
/**
|
||||
* Function that is called when a geometry's coordinates are updated.
|
||||
* @type {ol.interaction.DrawGeometryFunctionType|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.interaction.DrawOptions.prototype.geometryFunction;
|
||||
|
||||
|
||||
/**
|
||||
* Geometry name to use for features created by the draw interaction.
|
||||
* @type {string|undefined}
|
||||
@@ -2542,7 +2564,7 @@ olx.interaction.ModifyOptions.prototype.deleteCondition;
|
||||
|
||||
/**
|
||||
* Pixel tolerance for considering the pointer close enough to a segment or
|
||||
* vertex for editing.
|
||||
* vertex for editing. Default is `10`.
|
||||
* @type {number|undefined}
|
||||
* @api
|
||||
*/
|
||||
@@ -3556,8 +3578,9 @@ olx.layer.VectorOptions.prototype.opacity;
|
||||
|
||||
/**
|
||||
* The buffer around the viewport extent used by the renderer when getting
|
||||
* features from the vector source. Recommended value: the size of the
|
||||
* largest symbol or line width. Default is 100 pixels.
|
||||
* features from the vector source for the rendering or hit-detection.
|
||||
* Recommended value: the size of the largest symbol, line width or label.
|
||||
* Default is 100 pixels.
|
||||
* @type {number|undefined}
|
||||
* @api
|
||||
*/
|
||||
@@ -4942,11 +4965,10 @@ olx.source.TileWMSOptions.prototype.urls;
|
||||
|
||||
|
||||
/**
|
||||
* Whether to wrap the world horizontally. The default, `undefined`, is to
|
||||
* request out-of-bounds tiles from the server. This works well in e.g.
|
||||
* GeoServer. When set to `false`, only one world will be rendered. When set to
|
||||
* `true`, tiles will be requested for one world only, but they will be wrapped
|
||||
* horizontally to render multiple worlds.
|
||||
* Whether to wrap the world horizontally. When set to `false`, only one world
|
||||
* will be rendered. When `true`, tiles will be requested for one world only,
|
||||
* but they will be wrapped horizontally to render multiple worlds. The default
|
||||
* is `true`.
|
||||
* @type {boolean|undefined}
|
||||
* @api
|
||||
*/
|
||||
@@ -6014,18 +6036,31 @@ olx.tilegrid;
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{minZoom: (number|undefined),
|
||||
* @typedef {{createTileCoordTransform: (undefined|function({extent: (ol.Extent|undefined)}):function(ol.TileCoord, ol.proj.Projection, ol.TileCoord=):ol.TileCoord),
|
||||
* extent: (ol.Extent|undefined),
|
||||
* minZoom: (number|undefined),
|
||||
* origin: (ol.Coordinate|undefined),
|
||||
* origins: (Array.<ol.Coordinate>|undefined),
|
||||
* resolutions: !Array.<number>,
|
||||
* sizes: (Array.<ol.Size>|undefined),
|
||||
* tileSize: (number|ol.Size|undefined),
|
||||
* tileSizes: (Array.<number|ol.Size>|undefined),
|
||||
* widths: (Array.<number>|undefined)}}
|
||||
* tileSizes: (Array.<number|ol.Size>|undefined)}}
|
||||
* @api
|
||||
*/
|
||||
olx.tilegrid.TileGridOptions;
|
||||
|
||||
|
||||
/**
|
||||
* Extent for the tile grid. No tiles outside this extent will be requested by
|
||||
* {@link ol.source.Tile} sources. When no `origin` or `origins` are
|
||||
* configured, the `origin` will be set to the bottom-left corner of the extent.
|
||||
* When no `sizes` are configured, they will be calculated from the extent.
|
||||
* @type {ol.Extent|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.tilegrid.TileGridOptions.prototype.extent;
|
||||
|
||||
|
||||
/**
|
||||
* Minimum zoom. Default is 0.
|
||||
* @type {number|undefined}
|
||||
@@ -6035,7 +6070,7 @@ olx.tilegrid.TileGridOptions.prototype.minZoom;
|
||||
|
||||
|
||||
/**
|
||||
* Origin. Default is null.
|
||||
* Origin, i.e. the bottom-left corner of the grid. Default is null.
|
||||
* @type {ol.Coordinate|undefined}
|
||||
* @api stable
|
||||
*/
|
||||
@@ -6043,8 +6078,9 @@ olx.tilegrid.TileGridOptions.prototype.origin;
|
||||
|
||||
|
||||
/**
|
||||
* Origins. If given, the array length should match the length of the
|
||||
* `resolutions` array, i.e. each resolution can have a different origin.
|
||||
* Origins, i.e. the bottom-left corners of the grid for each zoom level. If
|
||||
* given, the array length should match the length of the `resolutions` array,
|
||||
* i.e. each resolution can have a different origin.
|
||||
* @type {Array.<ol.Coordinate>|undefined}
|
||||
* @api stable
|
||||
*/
|
||||
@@ -6061,6 +6097,17 @@ olx.tilegrid.TileGridOptions.prototype.origins;
|
||||
olx.tilegrid.TileGridOptions.prototype.resolutions;
|
||||
|
||||
|
||||
/**
|
||||
* Number of tile rows and columns of the grid for each zoom level. This setting
|
||||
* is only needed for tile coordinate transforms that need to work with origins
|
||||
* other than the bottom-left corner of the grid. No tiles outside this range
|
||||
* will be requested by sources. If an `extent` is also configured, it takes
|
||||
* precedence.
|
||||
* @type {Array.<ol.Size>|undefined}
|
||||
*/
|
||||
olx.tilegrid.TileGridOptions.prototype.sizes;
|
||||
|
||||
|
||||
/**
|
||||
* Tile size. Default is `[256, 256]`.
|
||||
* @type {number|ol.Size|undefined}
|
||||
@@ -6079,32 +6126,32 @@ olx.tilegrid.TileGridOptions.prototype.tileSizes;
|
||||
|
||||
|
||||
/**
|
||||
* Number of tile columns that cover the grid's extent for each zoom level. Only
|
||||
* required when used with a source that has `wrapX` set to `true`, and only
|
||||
* when the grid's origin differs from the one of the projection's extent. The
|
||||
* array length has to match the length of the `resolutions` array, i.e. each
|
||||
* resolution will have a matching entry here.
|
||||
* @type {Array.<number>|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.tilegrid.TileGridOptions.prototype.widths;
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{origin: (ol.Coordinate|undefined),
|
||||
* @typedef {{extent: (ol.Extent|undefined),
|
||||
* origin: (ol.Coordinate|undefined),
|
||||
* origins: (Array.<ol.Coordinate>|undefined),
|
||||
* resolutions: !Array.<number>,
|
||||
* matrixIds: !Array.<string>,
|
||||
* sizes: (Array.<ol.Size>|undefined),
|
||||
* tileSize: (number|ol.Size|undefined),
|
||||
* tileSizes: (Array.<number|ol.Size>|undefined),
|
||||
* widths: (Array.<number>|undefined)}}
|
||||
* tileSizes: (Array.<number|ol.Size>|undefined)}}
|
||||
* @api
|
||||
*/
|
||||
olx.tilegrid.WMTSOptions;
|
||||
|
||||
|
||||
/**
|
||||
* Origin.
|
||||
* Extent for the tile grid. No tiles outside this extent will be requested by
|
||||
* {@link ol.source.WMTS} sources. When no `origin` or `origins` are
|
||||
* configured, the `origin` will be calculated from the extent.
|
||||
* When no `sizes` are configured, they will be calculated from the extent.
|
||||
* @type {ol.Extent|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.tilegrid.WMTSOptions.prototype.extent;
|
||||
|
||||
|
||||
/**
|
||||
* Origin, i.e. the top-left corner of the grid.
|
||||
* @type {ol.Coordinate|undefined}
|
||||
* @api
|
||||
*/
|
||||
@@ -6112,7 +6159,8 @@ olx.tilegrid.WMTSOptions.prototype.origin;
|
||||
|
||||
|
||||
/**
|
||||
* Origins. The length of this array needs to match the length of the
|
||||
* Origins, i.e. the top-left corners of the grid for each zoom level. The
|
||||
* length of this array needs to match the length of the
|
||||
* `resolutions` array.
|
||||
* @type {Array.<ol.Coordinate>|undefined}
|
||||
* @api
|
||||
@@ -6139,6 +6187,18 @@ olx.tilegrid.WMTSOptions.prototype.resolutions;
|
||||
olx.tilegrid.WMTSOptions.prototype.matrixIds;
|
||||
|
||||
|
||||
/**
|
||||
* Number of tile rows and columns of the grid for each zoom level. The values
|
||||
* here are the `TileMatrixWidth` and `TileMatrixHeight` advertised in the
|
||||
* GetCapabilities response of the WMTS, and define the grid's extent together
|
||||
* with the `origin`. An `extent` can be configured in addition, and will
|
||||
* further limit the extent for which tile requests are made by sources.
|
||||
* @type {Array.<ol.Size>|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.tilegrid.WMTSOptions.prototype.sizes;
|
||||
|
||||
|
||||
/**
|
||||
* Tile size.
|
||||
* @type {number|ol.Size|undefined}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "openlayers",
|
||||
"version": "3.5.0",
|
||||
"version": "3.6.0",
|
||||
"description": "Build tools and sources for developing OpenLayers based mapping applications",
|
||||
"keywords": [
|
||||
"map",
|
||||
@@ -19,7 +19,7 @@
|
||||
"type": "git",
|
||||
"url": "git://github.com/openlayers/ol3.git"
|
||||
},
|
||||
"license": "BSD",
|
||||
"license": "BSD-2-Clause",
|
||||
"bugs": {
|
||||
"url": "https://github.com/openlayers/ol3/issues"
|
||||
},
|
||||
|
||||
@@ -78,8 +78,8 @@ ol.Attribution.prototype.intersectsAnyTileRange =
|
||||
if (testTileRange.intersects(tileRange)) {
|
||||
return true;
|
||||
}
|
||||
var extentTileRange = tileGrid.getTileRange(
|
||||
parseInt(zKey, 10), projection);
|
||||
var extentTileRange = tileGrid.getTileRangeForExtentAndZ(
|
||||
projection.getExtent(), parseInt(zKey, 10));
|
||||
var width = extentTileRange.getWidth();
|
||||
if (tileRange.minX < extentTileRange.minX ||
|
||||
tileRange.maxX > extentTileRange.maxX) {
|
||||
|
||||
@@ -64,12 +64,12 @@ ol.color.blend = function(dst, src, opt_color) {
|
||||
// FIXME do we need to scale by 255?
|
||||
var out = goog.isDef(opt_color) ? opt_color : [];
|
||||
var dstA = dst[3];
|
||||
var srcA = dst[3];
|
||||
var srcA = src[3];
|
||||
if (dstA == 1) {
|
||||
out[0] = (src[0] * srcA + dst[0] * (1 - srcA) + 0.5) | 0;
|
||||
out[1] = (src[1] * srcA + dst[1] * (1 - srcA) + 0.5) | 0;
|
||||
out[2] = (src[2] * srcA + dst[2] * (1 - srcA) + 0.5) | 0;
|
||||
out[4] = 1;
|
||||
out[3] = 1;
|
||||
} else if (srcA === 0) {
|
||||
out[0] = dst[0];
|
||||
out[1] = dst[1];
|
||||
|
||||
@@ -3,6 +3,7 @@ goog.provide('ol.control.Control');
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('ol.MapEventType');
|
||||
goog.require('ol.Object');
|
||||
|
||||
@@ -78,6 +79,24 @@ ol.control.Control = function(options) {
|
||||
goog.inherits(ol.control.Control, ol.Object);
|
||||
|
||||
|
||||
/**
|
||||
* Bind a listener that blurs the passed element on any mouseout- or
|
||||
* focusout-event.
|
||||
*
|
||||
* @param {!Element} button The button which shall blur on mouseout- or
|
||||
* focusout-event.
|
||||
* @protected
|
||||
*/
|
||||
ol.control.Control.bindMouseOutFocusOutBlur = function(button) {
|
||||
goog.events.listen(button, [
|
||||
goog.events.EventType.MOUSEOUT,
|
||||
goog.events.EventType.FOCUSOUT
|
||||
], /** @this {Element} */ function() {
|
||||
this.blur();
|
||||
}, false);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
|
||||
@@ -67,12 +67,7 @@ ol.control.FullScreen = function(opt_options) {
|
||||
goog.events.listen(button, goog.events.EventType.CLICK,
|
||||
this.handleClick_, false, this);
|
||||
|
||||
goog.events.listen(button, [
|
||||
goog.events.EventType.MOUSEOUT,
|
||||
goog.events.EventType.FOCUSOUT
|
||||
], function() {
|
||||
this.blur();
|
||||
}, false);
|
||||
ol.control.Control.bindMouseOutFocusOutBlur(button);
|
||||
|
||||
goog.events.listen(goog.global.document,
|
||||
goog.dom.fullscreen.EventType.CHANGE,
|
||||
|
||||
@@ -90,12 +90,7 @@ ol.control.OverviewMap = function(opt_options) {
|
||||
goog.events.listen(button, goog.events.EventType.CLICK,
|
||||
this.handleClick_, false, this);
|
||||
|
||||
goog.events.listen(button, [
|
||||
goog.events.EventType.MOUSEOUT,
|
||||
goog.events.EventType.FOCUSOUT
|
||||
], function() {
|
||||
this.blur();
|
||||
}, false);
|
||||
ol.control.Control.bindMouseOutFocusOutBlur(button);
|
||||
|
||||
var ovmapDiv = goog.dom.createDom(goog.dom.TagName.DIV, 'ol-overviewmap-map');
|
||||
|
||||
|
||||
@@ -60,12 +60,7 @@ ol.control.Rotate = function(opt_options) {
|
||||
goog.events.listen(button, goog.events.EventType.CLICK,
|
||||
ol.control.Rotate.prototype.handleClick_, false, this);
|
||||
|
||||
goog.events.listen(button, [
|
||||
goog.events.EventType.MOUSEOUT,
|
||||
goog.events.EventType.FOCUSOUT
|
||||
], function() {
|
||||
this.blur();
|
||||
}, false);
|
||||
ol.control.Control.bindMouseOutFocusOutBlur(button);
|
||||
|
||||
var cssClasses = className + ' ' + ol.css.CLASS_UNSELECTABLE + ' ' +
|
||||
ol.css.CLASS_CONTROL;
|
||||
|
||||
@@ -50,12 +50,7 @@ ol.control.Zoom = function(opt_options) {
|
||||
goog.events.EventType.CLICK, goog.partial(
|
||||
ol.control.Zoom.prototype.handleClick_, delta), false, this);
|
||||
|
||||
goog.events.listen(inElement, [
|
||||
goog.events.EventType.MOUSEOUT,
|
||||
goog.events.EventType.FOCUSOUT
|
||||
], function() {
|
||||
this.blur();
|
||||
}, false);
|
||||
ol.control.Control.bindMouseOutFocusOutBlur(inElement);
|
||||
|
||||
var outElement = goog.dom.createDom(goog.dom.TagName.BUTTON, {
|
||||
'class': className + '-out',
|
||||
|
||||
@@ -43,12 +43,7 @@ ol.control.ZoomToExtent = function(opt_options) {
|
||||
goog.events.listen(button, goog.events.EventType.CLICK,
|
||||
this.handleClick_, false, this);
|
||||
|
||||
goog.events.listen(button, [
|
||||
goog.events.EventType.MOUSEOUT,
|
||||
goog.events.EventType.FOCUSOUT
|
||||
], function() {
|
||||
this.blur();
|
||||
}, false);
|
||||
ol.control.Control.bindMouseOutFocusOutBlur(button);
|
||||
|
||||
var cssClasses = className + ' ' + ol.css.CLASS_UNSELECTABLE + ' ' +
|
||||
ol.css.CLASS_CONTROL;
|
||||
|
||||
@@ -164,12 +164,15 @@ ol.extent.containsCoordinate = function(extent, coordinate) {
|
||||
|
||||
|
||||
/**
|
||||
* Check if one extent is contained by or on the edge of another.
|
||||
* Check if one extent contains another.
|
||||
*
|
||||
* An extent is deemed contained if it lies completely within the other extent,
|
||||
* including if they share one or more edges.
|
||||
*
|
||||
* @param {ol.Extent} extent1 Extent 1.
|
||||
* @param {ol.Extent} extent2 Extent 2.
|
||||
* @return {boolean} The first extent is contained by or on the edge of the
|
||||
* second.
|
||||
* @return {boolean} The second extent is contained by or on the edge of the
|
||||
* first.
|
||||
* @api stable
|
||||
*/
|
||||
ol.extent.containsExtent = function(extent1, extent2) {
|
||||
|
||||
@@ -491,12 +491,23 @@ ol.format.WKT.Lexer.prototype.nextToken = function() {
|
||||
ol.format.WKT.Lexer.prototype.readNumber_ = function() {
|
||||
var c, index = this.index_;
|
||||
var decimal = false;
|
||||
var scientificNotation = false;
|
||||
do {
|
||||
if (c == '.') {
|
||||
decimal = true;
|
||||
} else if (c == 'e' || c == 'E') {
|
||||
scientificNotation = true;
|
||||
}
|
||||
c = this.nextChar_();
|
||||
} while (this.isNumeric_(c, decimal));
|
||||
} while (
|
||||
this.isNumeric_(c, decimal) ||
|
||||
// if we haven't detected a scientific number before, 'e' or 'E'
|
||||
// hint that we should continue to read
|
||||
!scientificNotation && (c == 'e' || c == 'E') ||
|
||||
// once we know that we have a scientific number, both '-' and '+'
|
||||
// are allowed
|
||||
scientificNotation && (c == '-' || c == '+')
|
||||
);
|
||||
return parseFloat(this.wkt.substring(index, this.index_--));
|
||||
};
|
||||
|
||||
|
||||
@@ -137,6 +137,29 @@ ol.geom.Circle.prototype.getType = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @api stable
|
||||
*/
|
||||
ol.geom.Circle.prototype.intersectsExtent = function(extent) {
|
||||
var circleExtent = this.getExtent();
|
||||
if (ol.extent.intersects(extent, circleExtent)) {
|
||||
var center = this.getCenter();
|
||||
|
||||
if (extent[0] <= center[0] && extent[2] >= center[0]) {
|
||||
return true;
|
||||
}
|
||||
if (extent[1] <= center[1] && extent[3] >= center[1]) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return ol.extent.forEachCorner(extent, this.containsCoordinate, this);
|
||||
}
|
||||
return false;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Set the center of the circle as {@link ol.Coordinate coordinate}.
|
||||
* @param {ol.Coordinate} center Center.
|
||||
|
||||
@@ -2,6 +2,7 @@ goog.provide('ol.geom.Polygon');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.math');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.geom.GeometryLayout');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
@@ -422,3 +423,53 @@ ol.geom.Polygon.fromExtent = function(extent) {
|
||||
ol.geom.GeometryLayout.XY, flatCoordinates, [flatCoordinates.length]);
|
||||
return polygon;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create a regular polygon from a circle.
|
||||
* @param {ol.geom.Circle} circle Circle geometry.
|
||||
* @param {number=} opt_sides Number of sides of the polygon. Default is 32.
|
||||
* @param {number=} opt_angle Start angle for the first vertex of the polygon in
|
||||
* radians. Default is 0.
|
||||
* @return {ol.geom.Polygon} Polygon geometry.
|
||||
* @api
|
||||
*/
|
||||
ol.geom.Polygon.fromCircle = function(circle, opt_sides, opt_angle) {
|
||||
var sides = goog.isDef(opt_sides) ? opt_sides : 32;
|
||||
var stride = circle.getStride();
|
||||
var layout = circle.getLayout();
|
||||
var polygon = new ol.geom.Polygon(null, layout);
|
||||
var flatCoordinates = goog.array.repeat(0, stride * (sides + 1));
|
||||
var ends = [flatCoordinates.length];
|
||||
polygon.setFlatCoordinates(layout, flatCoordinates, ends);
|
||||
ol.geom.Polygon.makeRegular(
|
||||
polygon, circle.getCenter(), circle.getRadius(), opt_angle);
|
||||
return polygon;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Modify the coordinates of a polygon to make it a regular polygon.
|
||||
* @param {ol.geom.Polygon} polygon Polygon geometry.
|
||||
* @param {ol.Coordinate} center Center of the regular polygon.
|
||||
* @param {number} radius Radius of the regular polygon.
|
||||
* @param {number=} opt_angle Start angle for the first vertex of the polygon in
|
||||
* radians. Default is 0.
|
||||
*/
|
||||
ol.geom.Polygon.makeRegular = function(polygon, center, radius, opt_angle) {
|
||||
var flatCoordinates = polygon.getFlatCoordinates();
|
||||
var layout = polygon.getLayout();
|
||||
var stride = polygon.getStride();
|
||||
var ends = polygon.getEnds();
|
||||
goog.asserts.assert(ends.length === 1, 'only 1 ring is supported');
|
||||
var sides = flatCoordinates.length / stride - 1;
|
||||
var startAngle = goog.isDef(opt_angle) ? opt_angle : 0;
|
||||
var angle, coord, offset;
|
||||
for (var i = 0; i <= sides; ++i) {
|
||||
offset = i * stride;
|
||||
angle = startAngle + (goog.math.modulo(i, sides) * 2 * Math.PI / sides);
|
||||
flatCoordinates[offset] = center[0] + (radius * Math.cos(angle));
|
||||
flatCoordinates[offset + 1] = center[1] + (radius * Math.sin(angle));
|
||||
}
|
||||
polygon.setFlatCoordinates(layout, flatCoordinates, ends);
|
||||
};
|
||||
|
||||
@@ -98,6 +98,12 @@ ol.geom.SimpleGeometry.prototype.computeExtent = function(extent) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Array} Coordinates.
|
||||
*/
|
||||
ol.geom.SimpleGeometry.prototype.getCoordinates = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* Return the first coordinate of the geometry.
|
||||
* @return {ol.Coordinate} First coordinate.
|
||||
@@ -209,6 +215,13 @@ ol.geom.SimpleGeometry.prototype.setFlatCoordinatesInternal =
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Array} coordinates Coordinates.
|
||||
* @param {ol.geom.GeometryLayout=} opt_layout Layout.
|
||||
*/
|
||||
ol.geom.SimpleGeometry.prototype.setCoordinates = goog.abstractMethod;
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.geom.GeometryLayout|undefined} layout Layout.
|
||||
* @param {Array} coordinates Coordinates.
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
goog.provide('ol.DrawEvent');
|
||||
goog.provide('ol.DrawEventType');
|
||||
goog.provide('ol.interaction.Draw');
|
||||
goog.provide('ol.interaction.DrawEvent');
|
||||
goog.provide('ol.interaction.DrawEventType');
|
||||
goog.provide('ol.interaction.DrawGeometryFunctionType');
|
||||
goog.provide('ol.interaction.DrawMode');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.events');
|
||||
@@ -12,6 +14,7 @@ goog.require('ol.FeatureOverlay');
|
||||
goog.require('ol.MapBrowserEvent');
|
||||
goog.require('ol.MapBrowserEvent.EventType');
|
||||
goog.require('ol.Object');
|
||||
goog.require('ol.coordinate');
|
||||
goog.require('ol.events.condition');
|
||||
goog.require('ol.geom.Circle');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
@@ -21,6 +24,7 @@ goog.require('ol.geom.MultiPoint');
|
||||
goog.require('ol.geom.MultiPolygon');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.geom.Polygon');
|
||||
goog.require('ol.geom.SimpleGeometry');
|
||||
goog.require('ol.interaction.InteractionProperty');
|
||||
goog.require('ol.interaction.Pointer');
|
||||
goog.require('ol.source.Vector');
|
||||
@@ -30,16 +34,16 @@ goog.require('ol.style.Style');
|
||||
/**
|
||||
* @enum {string}
|
||||
*/
|
||||
ol.DrawEventType = {
|
||||
ol.interaction.DrawEventType = {
|
||||
/**
|
||||
* Triggered upon feature draw start
|
||||
* @event ol.DrawEvent#drawstart
|
||||
* @event ol.interaction.DrawEvent#drawstart
|
||||
* @api stable
|
||||
*/
|
||||
DRAWSTART: 'drawstart',
|
||||
/**
|
||||
* Triggered upon feature draw end
|
||||
* @event ol.DrawEvent#drawend
|
||||
* @event ol.interaction.DrawEvent#drawend
|
||||
* @api stable
|
||||
*/
|
||||
DRAWEND: 'drawend'
|
||||
@@ -55,10 +59,10 @@ ol.DrawEventType = {
|
||||
* @constructor
|
||||
* @extends {goog.events.Event}
|
||||
* @implements {oli.DrawEvent}
|
||||
* @param {ol.DrawEventType} type Type.
|
||||
* @param {ol.interaction.DrawEventType} type Type.
|
||||
* @param {ol.Feature} feature The feature drawn.
|
||||
*/
|
||||
ol.DrawEvent = function(type, feature) {
|
||||
ol.interaction.DrawEvent = function(type, feature) {
|
||||
|
||||
goog.base(this, type);
|
||||
|
||||
@@ -70,7 +74,7 @@ ol.DrawEvent = function(type, feature) {
|
||||
this.feature = feature;
|
||||
|
||||
};
|
||||
goog.inherits(ol.DrawEvent, goog.events.Event);
|
||||
goog.inherits(ol.interaction.DrawEvent, goog.events.Event);
|
||||
|
||||
|
||||
|
||||
@@ -80,7 +84,7 @@ goog.inherits(ol.DrawEvent, goog.events.Event);
|
||||
*
|
||||
* @constructor
|
||||
* @extends {ol.interaction.Pointer}
|
||||
* @fires ol.DrawEvent
|
||||
* @fires ol.interaction.DrawEvent
|
||||
* @param {olx.interaction.DrawOptions} options Options.
|
||||
* @api stable
|
||||
*/
|
||||
@@ -126,15 +130,6 @@ ol.interaction.Draw = function(options) {
|
||||
this.snapTolerance_ = goog.isDef(options.snapTolerance) ?
|
||||
options.snapTolerance : 12;
|
||||
|
||||
/**
|
||||
* The number of points that must be drawn before a polygon ring can be
|
||||
* finished. The default is 3.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.minPointsPerRing_ = goog.isDef(options.minPointsPerRing) ?
|
||||
options.minPointsPerRing : 3;
|
||||
|
||||
/**
|
||||
* Geometry type.
|
||||
* @type {ol.geom.GeometryType}
|
||||
@@ -149,6 +144,77 @@ ol.interaction.Draw = function(options) {
|
||||
*/
|
||||
this.mode_ = ol.interaction.Draw.getMode_(this.type_);
|
||||
|
||||
/**
|
||||
* The number of points that must be drawn before a polygon ring or line
|
||||
* string can be finished. The default is 3 for polygon rings and 2 for
|
||||
* line strings.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.minPoints_ = goog.isDef(options.minPoints) ?
|
||||
options.minPoints :
|
||||
(this.mode_ === ol.interaction.DrawMode.POLYGON ? 3 : 2);
|
||||
|
||||
/**
|
||||
* The number of points that can be drawn before a polygon ring or line string
|
||||
* is finished. The default is no restriction.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.maxPoints_ = goog.isDef(options.maxPoints) ?
|
||||
options.maxPoints : Infinity;
|
||||
|
||||
var geometryFunction = options.geometryFunction;
|
||||
if (!goog.isDef(geometryFunction)) {
|
||||
if (this.type_ === ol.geom.GeometryType.CIRCLE) {
|
||||
/**
|
||||
* @param {ol.Coordinate|Array.<ol.Coordinate>|Array.<Array.<ol.Coordinate>>} coordinates
|
||||
* @param {ol.geom.SimpleGeometry=} opt_geometry
|
||||
* @return {ol.geom.SimpleGeometry}
|
||||
*/
|
||||
geometryFunction = function(coordinates, opt_geometry) {
|
||||
var circle = goog.isDef(opt_geometry) ? opt_geometry :
|
||||
new ol.geom.Circle([NaN, NaN]);
|
||||
goog.asserts.assertInstanceof(circle, ol.geom.Circle,
|
||||
'geometry must be an ol.geom.Circle');
|
||||
var squaredLength = ol.coordinate.squaredDistance(
|
||||
coordinates[0], coordinates[1]);
|
||||
circle.setCenterAndRadius(coordinates[0], Math.sqrt(squaredLength));
|
||||
return circle;
|
||||
};
|
||||
} else {
|
||||
var Constructor;
|
||||
var mode = this.mode_;
|
||||
if (mode === ol.interaction.DrawMode.POINT) {
|
||||
Constructor = ol.geom.Point;
|
||||
} else if (mode === ol.interaction.DrawMode.LINE_STRING) {
|
||||
Constructor = ol.geom.LineString;
|
||||
} else if (mode === ol.interaction.DrawMode.POLYGON) {
|
||||
Constructor = ol.geom.Polygon;
|
||||
}
|
||||
/**
|
||||
* @param {ol.Coordinate|Array.<ol.Coordinate>|Array.<Array.<ol.Coordinate>>} coordinates
|
||||
* @param {ol.geom.SimpleGeometry=} opt_geometry
|
||||
* @return {ol.geom.SimpleGeometry}
|
||||
*/
|
||||
geometryFunction = function(coordinates, opt_geometry) {
|
||||
var geometry = opt_geometry;
|
||||
if (goog.isDef(geometry)) {
|
||||
geometry.setCoordinates(coordinates);
|
||||
} else {
|
||||
geometry = new Constructor(coordinates);
|
||||
}
|
||||
return geometry;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {ol.interaction.DrawGeometryFunctionType}
|
||||
* @private
|
||||
*/
|
||||
this.geometryFunction_ = geometryFunction;
|
||||
|
||||
/**
|
||||
* Finish coordinate for the feature (first point for polygons, last point for
|
||||
* linestrings).
|
||||
@@ -171,6 +237,13 @@ ol.interaction.Draw = function(options) {
|
||||
*/
|
||||
this.sketchPoint_ = null;
|
||||
|
||||
/**
|
||||
* Sketch coordinates. Used when drawing a line or polygon.
|
||||
* @type {ol.Coordinate|Array.<ol.Coordinate>|Array.<Array.<ol.Coordinate>>}
|
||||
* @private
|
||||
*/
|
||||
this.sketchCoords_ = null;
|
||||
|
||||
/**
|
||||
* Sketch line. Used when drawing polygon.
|
||||
* @type {ol.Feature}
|
||||
@@ -179,11 +252,11 @@ ol.interaction.Draw = function(options) {
|
||||
this.sketchLine_ = null;
|
||||
|
||||
/**
|
||||
* Sketch polygon. Used when drawing polygon.
|
||||
* @type {Array.<Array.<ol.Coordinate>>}
|
||||
* Sketch line coordinates. Used when drawing a polygon or circle.
|
||||
* @type {Array.<ol.Coordinate>}
|
||||
* @private
|
||||
*/
|
||||
this.sketchPolygonCoords_ = null;
|
||||
this.sketchLineCoords_ = null;
|
||||
|
||||
/**
|
||||
* Squared tolerance for handling up events. If the squared distance
|
||||
@@ -362,20 +435,15 @@ ol.interaction.Draw.prototype.handlePointerMove_ = function(event) {
|
||||
ol.interaction.Draw.prototype.atFinish_ = function(event) {
|
||||
var at = false;
|
||||
if (!goog.isNull(this.sketchFeature_)) {
|
||||
var geometry = this.sketchFeature_.getGeometry();
|
||||
var potentiallyDone = false;
|
||||
var potentiallyFinishCoordinates = [this.finishCoordinate_];
|
||||
if (this.mode_ === ol.interaction.DrawMode.LINE_STRING) {
|
||||
goog.asserts.assertInstanceof(geometry, ol.geom.LineString,
|
||||
'geometry should be an ol.geom.LineString');
|
||||
potentiallyDone = geometry.getCoordinates().length > 2;
|
||||
potentiallyDone = this.sketchCoords_.length > this.minPoints_;
|
||||
} else if (this.mode_ === ol.interaction.DrawMode.POLYGON) {
|
||||
goog.asserts.assertInstanceof(geometry, ol.geom.Polygon,
|
||||
'geometry should be an ol.geom.Polygon');
|
||||
potentiallyDone = geometry.getCoordinates()[0].length >
|
||||
this.minPointsPerRing_;
|
||||
potentiallyFinishCoordinates = [this.sketchPolygonCoords_[0][0],
|
||||
this.sketchPolygonCoords_[0][this.sketchPolygonCoords_[0].length - 2]];
|
||||
potentiallyDone = this.sketchCoords_[0].length >
|
||||
this.minPoints_;
|
||||
potentiallyFinishCoordinates = [this.sketchCoords_[0][0],
|
||||
this.sketchCoords_[0][this.sketchCoords_[0].length - 2]];
|
||||
}
|
||||
if (potentiallyDone) {
|
||||
var map = event.map;
|
||||
@@ -425,23 +493,22 @@ ol.interaction.Draw.prototype.createOrUpdateSketchPoint_ = function(event) {
|
||||
ol.interaction.Draw.prototype.startDrawing_ = function(event) {
|
||||
var start = event.coordinate;
|
||||
this.finishCoordinate_ = start;
|
||||
var geometry;
|
||||
if (this.mode_ === ol.interaction.DrawMode.POINT) {
|
||||
geometry = new ol.geom.Point(start.slice());
|
||||
this.sketchCoords_ = start.slice();
|
||||
} else if (this.mode_ === ol.interaction.DrawMode.POLYGON) {
|
||||
this.sketchCoords_ = [[start.slice(), start.slice()]];
|
||||
this.sketchLineCoords_ = this.sketchCoords_[0];
|
||||
} else {
|
||||
if (this.mode_ === ol.interaction.DrawMode.LINE_STRING) {
|
||||
geometry = new ol.geom.LineString([start.slice(), start.slice()]);
|
||||
} else if (this.mode_ === ol.interaction.DrawMode.POLYGON) {
|
||||
this.sketchLine_ = new ol.Feature(new ol.geom.LineString([start.slice(),
|
||||
start.slice()]));
|
||||
this.sketchPolygonCoords_ = [[start.slice(), start.slice()]];
|
||||
geometry = new ol.geom.Polygon(this.sketchPolygonCoords_);
|
||||
} else if (this.mode_ === ol.interaction.DrawMode.CIRCLE) {
|
||||
geometry = new ol.geom.Circle(start.slice(), 0);
|
||||
this.sketchLine_ = new ol.Feature(new ol.geom.LineString([start.slice(),
|
||||
start.slice()]));
|
||||
this.sketchCoords_ = [start.slice(), start.slice()];
|
||||
if (this.mode_ === ol.interaction.DrawMode.CIRCLE) {
|
||||
this.sketchLineCoords_ = this.sketchCoords_;
|
||||
}
|
||||
}
|
||||
if (!goog.isNull(this.sketchLineCoords_)) {
|
||||
this.sketchLine_ = new ol.Feature(
|
||||
new ol.geom.LineString(this.sketchLineCoords_));
|
||||
}
|
||||
var geometry = this.geometryFunction_(this.sketchCoords_);
|
||||
goog.asserts.assert(goog.isDef(geometry), 'geometry should be defined');
|
||||
this.sketchFeature_ = new ol.Feature();
|
||||
if (goog.isDef(this.geometryName_)) {
|
||||
@@ -449,8 +516,8 @@ ol.interaction.Draw.prototype.startDrawing_ = function(event) {
|
||||
}
|
||||
this.sketchFeature_.setGeometry(geometry);
|
||||
this.updateSketchFeatures_();
|
||||
this.dispatchEvent(new ol.DrawEvent(ol.DrawEventType.DRAWSTART,
|
||||
this.sketchFeature_));
|
||||
this.dispatchEvent(new ol.interaction.DrawEvent(
|
||||
ol.interaction.DrawEventType.DRAWSTART, this.sketchFeature_));
|
||||
};
|
||||
|
||||
|
||||
@@ -462,60 +529,50 @@ ol.interaction.Draw.prototype.startDrawing_ = function(event) {
|
||||
ol.interaction.Draw.prototype.modifyDrawing_ = function(event) {
|
||||
var coordinate = event.coordinate;
|
||||
var geometry = this.sketchFeature_.getGeometry();
|
||||
var coordinates, last, sketchLineGeom;
|
||||
goog.asserts.assertInstanceof(geometry, ol.geom.SimpleGeometry,
|
||||
'geometry should be ol.geom.SimpleGeometry or subclass');
|
||||
var coordinates, last;
|
||||
if (this.mode_ === ol.interaction.DrawMode.POINT) {
|
||||
goog.asserts.assertInstanceof(geometry, ol.geom.Point,
|
||||
'geometry should be an ol.geom.Point');
|
||||
last = geometry.getCoordinates();
|
||||
last[0] = coordinate[0];
|
||||
last[1] = coordinate[1];
|
||||
geometry.setCoordinates(last);
|
||||
} else {
|
||||
if (this.mode_ === ol.interaction.DrawMode.LINE_STRING) {
|
||||
goog.asserts.assertInstanceof(geometry, ol.geom.LineString,
|
||||
'geometry should be an ol.geom.LineString');
|
||||
coordinates = geometry.getCoordinates();
|
||||
} else if (this.mode_ === ol.interaction.DrawMode.POLYGON) {
|
||||
goog.asserts.assertInstanceof(geometry, ol.geom.Polygon,
|
||||
'geometry should be an ol.geom.Polygon');
|
||||
coordinates = this.sketchPolygonCoords_[0];
|
||||
} else if (this.mode_ === ol.interaction.DrawMode.CIRCLE) {
|
||||
goog.asserts.assertInstanceof(geometry, ol.geom.Circle,
|
||||
'geometry should be an ol.geom.Circle');
|
||||
coordinates = geometry.getCenter();
|
||||
}
|
||||
last = this.sketchCoords_;
|
||||
} else if (this.mode_ === ol.interaction.DrawMode.POLYGON) {
|
||||
coordinates = this.sketchCoords_[0];
|
||||
last = coordinates[coordinates.length - 1];
|
||||
if (this.atFinish_(event)) {
|
||||
// snap to finish
|
||||
coordinate = this.finishCoordinate_.slice();
|
||||
}
|
||||
} else {
|
||||
coordinates = this.sketchCoords_;
|
||||
last = coordinates[coordinates.length - 1];
|
||||
}
|
||||
last[0] = coordinate[0];
|
||||
last[1] = coordinate[1];
|
||||
goog.asserts.assert(!goog.isNull(this.sketchCoords_),
|
||||
'sketchCoords_ must not be null');
|
||||
this.geometryFunction_(this.sketchCoords_, geometry);
|
||||
if (!goog.isNull(this.sketchPoint_)) {
|
||||
var sketchPointGeom = this.sketchPoint_.getGeometry();
|
||||
goog.asserts.assertInstanceof(sketchPointGeom, ol.geom.Point,
|
||||
'sketchPointGeom should be an ol.geom.Point');
|
||||
sketchPointGeom.setCoordinates(coordinate);
|
||||
last = coordinates[coordinates.length - 1];
|
||||
last[0] = coordinate[0];
|
||||
last[1] = coordinate[1];
|
||||
if (this.mode_ === ol.interaction.DrawMode.LINE_STRING) {
|
||||
goog.asserts.assertInstanceof(geometry, ol.geom.LineString,
|
||||
'geometry should be an ol.geom.LineString');
|
||||
geometry.setCoordinates(coordinates);
|
||||
} else if (this.mode_ === ol.interaction.DrawMode.POLYGON) {
|
||||
sketchLineGeom = this.sketchLine_.getGeometry();
|
||||
goog.asserts.assertInstanceof(sketchLineGeom, ol.geom.LineString,
|
||||
'sketchLineGeom should be an ol.geom.LineString');
|
||||
sketchLineGeom.setCoordinates(coordinates);
|
||||
goog.asserts.assertInstanceof(geometry, ol.geom.Polygon,
|
||||
'geometry should be an ol.geom.Polygon');
|
||||
geometry.setCoordinates(this.sketchPolygonCoords_);
|
||||
} else if (this.mode_ === ol.interaction.DrawMode.CIRCLE) {
|
||||
goog.asserts.assertInstanceof(geometry, ol.geom.Circle,
|
||||
'geometry should be an ol.geom.Circle');
|
||||
sketchLineGeom = this.sketchLine_.getGeometry();
|
||||
goog.asserts.assertInstanceof(sketchLineGeom, ol.geom.LineString,
|
||||
'sketchLineGeom should be an ol.geom.LineString');
|
||||
sketchLineGeom.setCoordinates([geometry.getCenter(), coordinate]);
|
||||
geometry.setRadius(sketchLineGeom.getLength());
|
||||
}
|
||||
var sketchLineGeom;
|
||||
if (geometry instanceof ol.geom.Polygon &&
|
||||
this.mode_ !== ol.interaction.DrawMode.POLYGON) {
|
||||
if (goog.isNull(this.sketchLine_)) {
|
||||
this.sketchLine_ = new ol.Feature(new ol.geom.LineString(null));
|
||||
}
|
||||
var ring = geometry.getLinearRing(0);
|
||||
sketchLineGeom = this.sketchLine_.getGeometry();
|
||||
goog.asserts.assertInstanceof(sketchLineGeom, ol.geom.LineString,
|
||||
'sketchLineGeom must be an ol.geom.LineString');
|
||||
sketchLineGeom.setFlatCoordinates(
|
||||
ring.getLayout(), ring.getFlatCoordinates());
|
||||
} else if (!goog.isNull(this.sketchLineCoords_)) {
|
||||
sketchLineGeom = this.sketchLine_.getGeometry();
|
||||
goog.asserts.assertInstanceof(sketchLineGeom, ol.geom.LineString,
|
||||
'sketchLineGeom must be an ol.geom.LineString');
|
||||
sketchLineGeom.setCoordinates(this.sketchLineCoords_);
|
||||
}
|
||||
this.updateSketchFeatures_();
|
||||
};
|
||||
@@ -529,57 +586,57 @@ ol.interaction.Draw.prototype.modifyDrawing_ = function(event) {
|
||||
ol.interaction.Draw.prototype.addToDrawing_ = function(event) {
|
||||
var coordinate = event.coordinate;
|
||||
var geometry = this.sketchFeature_.getGeometry();
|
||||
goog.asserts.assertInstanceof(geometry, ol.geom.SimpleGeometry,
|
||||
'geometry must be an ol.geom.SimpleGeometry');
|
||||
var done;
|
||||
var coordinates;
|
||||
if (this.mode_ === ol.interaction.DrawMode.LINE_STRING) {
|
||||
this.finishCoordinate_ = coordinate.slice();
|
||||
goog.asserts.assertInstanceof(geometry, ol.geom.LineString,
|
||||
'geometry should be an ol.geom.LineString');
|
||||
coordinates = geometry.getCoordinates();
|
||||
coordinates = this.sketchCoords_;
|
||||
coordinates.push(coordinate.slice());
|
||||
geometry.setCoordinates(coordinates);
|
||||
done = coordinates.length > this.maxPoints_;
|
||||
this.geometryFunction_(coordinates, geometry);
|
||||
} else if (this.mode_ === ol.interaction.DrawMode.POLYGON) {
|
||||
this.sketchPolygonCoords_[0].push(coordinate.slice());
|
||||
goog.asserts.assertInstanceof(geometry, ol.geom.Polygon,
|
||||
'geometry should be an ol.geom.Polygon');
|
||||
geometry.setCoordinates(this.sketchPolygonCoords_);
|
||||
coordinates = this.sketchCoords_[0];
|
||||
coordinates.push(coordinate.slice());
|
||||
done = coordinates.length > this.maxPoints_;
|
||||
if (done) {
|
||||
this.finishCoordinate_ = coordinates[0];
|
||||
}
|
||||
this.geometryFunction_(this.sketchCoords_, geometry);
|
||||
}
|
||||
this.updateSketchFeatures_();
|
||||
if (done) {
|
||||
this.finishDrawing();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Stop drawing and add the sketch feature to the target layer.
|
||||
* The {@link ol.DrawEventType.DRAWEND} event is dispatched before inserting
|
||||
* the feature.
|
||||
* The {@link ol.interaction.DrawEventType.DRAWEND} event is dispatched before
|
||||
* inserting the feature.
|
||||
* @api
|
||||
*/
|
||||
ol.interaction.Draw.prototype.finishDrawing = function() {
|
||||
var sketchFeature = this.abortDrawing_();
|
||||
goog.asserts.assert(!goog.isNull(sketchFeature),
|
||||
'sketchFeature should not be null');
|
||||
var coordinates;
|
||||
var coordinates = this.sketchCoords_;
|
||||
var geometry = sketchFeature.getGeometry();
|
||||
if (this.mode_ === ol.interaction.DrawMode.POINT) {
|
||||
goog.asserts.assertInstanceof(geometry, ol.geom.Point,
|
||||
'geometry should be an ol.geom.Point');
|
||||
coordinates = geometry.getCoordinates();
|
||||
} else if (this.mode_ === ol.interaction.DrawMode.LINE_STRING) {
|
||||
goog.asserts.assertInstanceof(geometry, ol.geom.LineString,
|
||||
'geometry should be an ol.geom.LineString');
|
||||
coordinates = geometry.getCoordinates();
|
||||
goog.asserts.assertInstanceof(geometry, ol.geom.SimpleGeometry,
|
||||
'geometry must be an ol.geom.SimpleGeometry');
|
||||
if (this.mode_ === ol.interaction.DrawMode.LINE_STRING) {
|
||||
// remove the redundant last point
|
||||
coordinates.pop();
|
||||
geometry.setCoordinates(coordinates);
|
||||
this.geometryFunction_(coordinates, geometry);
|
||||
} else if (this.mode_ === ol.interaction.DrawMode.POLYGON) {
|
||||
goog.asserts.assertInstanceof(geometry, ol.geom.Polygon,
|
||||
'geometry should be an ol.geom.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
|
||||
this.sketchPolygonCoords_[0].pop();
|
||||
this.sketchPolygonCoords_[0].push(this.sketchPolygonCoords_[0][0]);
|
||||
geometry.setCoordinates(this.sketchPolygonCoords_);
|
||||
coordinates = geometry.getCoordinates();
|
||||
coordinates[0].pop();
|
||||
coordinates[0].push(coordinates[0][0]);
|
||||
this.geometryFunction_(coordinates, geometry);
|
||||
}
|
||||
|
||||
// cast multi-part geometries
|
||||
@@ -592,7 +649,8 @@ ol.interaction.Draw.prototype.finishDrawing = function() {
|
||||
}
|
||||
|
||||
// First dispatch event to allow full set up of feature
|
||||
this.dispatchEvent(new ol.DrawEvent(ol.DrawEventType.DRAWEND, sketchFeature));
|
||||
this.dispatchEvent(new ol.interaction.DrawEvent(
|
||||
ol.interaction.DrawEventType.DRAWEND, sketchFeature));
|
||||
|
||||
// Then insert feature
|
||||
if (!goog.isNull(this.features_)) {
|
||||
@@ -660,6 +718,44 @@ ol.interaction.Draw.prototype.updateState_ = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create a `geometryFunction` for `mode: 'Circle'` that will create a regular
|
||||
* polygon with a user specified number of sides and start angle instead of an
|
||||
* `ol.geom.Circle` geometry.
|
||||
* @param {number=} opt_sides Number of sides of the regular polygon. Default is
|
||||
* 32.
|
||||
* @param {number=} opt_angle Angle of the first point in radians. 0 means East.
|
||||
* Default is the angle defined by the heading from the center of the
|
||||
* regular polygon to the current pointer position.
|
||||
* @return {ol.interaction.DrawGeometryFunctionType} Function that draws a
|
||||
* polygon.
|
||||
* @api
|
||||
*/
|
||||
ol.interaction.Draw.createRegularPolygon = function(opt_sides, opt_angle) {
|
||||
return (
|
||||
/**
|
||||
* @param {ol.Coordinate|Array.<ol.Coordinate>|Array.<Array.<ol.Coordinate>>} coordinates
|
||||
* @param {ol.geom.SimpleGeometry=} opt_geometry
|
||||
* @return {ol.geom.SimpleGeometry}
|
||||
*/
|
||||
function(coordinates, opt_geometry) {
|
||||
var center = coordinates[0];
|
||||
var end = coordinates[1];
|
||||
var radius = Math.sqrt(
|
||||
ol.coordinate.squaredDistance(center, end));
|
||||
var geometry = goog.isDef(opt_geometry) ? opt_geometry :
|
||||
ol.geom.Polygon.fromCircle(new ol.geom.Circle(center), opt_sides);
|
||||
goog.asserts.assertInstanceof(geometry, ol.geom.Polygon,
|
||||
'geometry must be a polygon');
|
||||
var angle = goog.isDef(opt_angle) ? opt_angle :
|
||||
Math.atan((end[1] - center[1]) / (end[0] - center[0]));
|
||||
ol.geom.Polygon.makeRegular(geometry, center, radius, angle);
|
||||
return geometry;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the drawing mode. The mode for mult-part geometries is the same as for
|
||||
* their single-part cousins.
|
||||
@@ -686,6 +782,19 @@ ol.interaction.Draw.getMode_ = function(type) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Function that takes coordinates and an optional existing geometry as
|
||||
* arguments, and returns a geometry. The optional existing geometry is the
|
||||
* geometry that is returned when the function is called without a second
|
||||
* argument.
|
||||
* @typedef {function(!(ol.Coordinate|Array.<ol.Coordinate>|
|
||||
* Array.<Array.<ol.Coordinate>>), ol.geom.SimpleGeometry=):
|
||||
* ol.geom.SimpleGeometry}
|
||||
* @api
|
||||
*/
|
||||
ol.interaction.DrawGeometryFunctionType;
|
||||
|
||||
|
||||
/**
|
||||
* Draw mode. This collapses multi-part geometry types with their single-part
|
||||
* cousins.
|
||||
|
||||
@@ -46,11 +46,13 @@ ol.interaction.SelectFilterFunction;
|
||||
* @param {string} type The event type.
|
||||
* @param {Array.<ol.Feature>} selected Selected features.
|
||||
* @param {Array.<ol.Feature>} deselected Deselected features.
|
||||
* @param {ol.MapBrowserEvent} mapBrowserEvent Associated
|
||||
* {@link ol.MapBrowserEvent}.
|
||||
* @implements {oli.SelectEvent}
|
||||
* @extends {goog.events.Event}
|
||||
* @constructor
|
||||
*/
|
||||
ol.SelectEvent = function(type, selected, deselected) {
|
||||
ol.SelectEvent = function(type, selected, deselected, mapBrowserEvent) {
|
||||
goog.base(this, type);
|
||||
|
||||
/**
|
||||
@@ -66,6 +68,13 @@ ol.SelectEvent = function(type, selected, deselected) {
|
||||
* @api
|
||||
*/
|
||||
this.deselected = deselected;
|
||||
|
||||
/**
|
||||
* Associated {@link ol.MapBrowserEvent}.
|
||||
* @type {ol.MapBrowserEvent}
|
||||
* @api
|
||||
*/
|
||||
this.mapBrowserEvent = mapBrowserEvent;
|
||||
};
|
||||
goog.inherits(ol.SelectEvent, goog.events.Event);
|
||||
|
||||
@@ -81,6 +90,7 @@ goog.inherits(ol.SelectEvent, goog.events.Event);
|
||||
* @constructor
|
||||
* @extends {ol.interaction.Interaction}
|
||||
* @param {olx.interaction.SelectOptions=} opt_options Options.
|
||||
* @fires ol.SelectEvent
|
||||
* @api stable
|
||||
*/
|
||||
ol.interaction.Select = function(opt_options) {
|
||||
@@ -265,7 +275,8 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) {
|
||||
}
|
||||
if (change) {
|
||||
this.dispatchEvent(
|
||||
new ol.SelectEvent(ol.SelectEventType.SELECT, selected, deselected));
|
||||
new ol.SelectEvent(ol.SelectEventType.SELECT, selected, deselected,
|
||||
mapBrowserEvent));
|
||||
}
|
||||
return ol.events.condition.pointerMove(mapBrowserEvent);
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
goog.provide('ol.layer.Vector');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.object');
|
||||
goog.require('ol.layer.Layer');
|
||||
goog.require('ol.style.Style');
|
||||
@@ -32,6 +33,11 @@ ol.layer.Vector = function(opt_options) {
|
||||
var options = goog.isDef(opt_options) ?
|
||||
opt_options : /** @type {olx.layer.VectorOptions} */ ({});
|
||||
|
||||
goog.asserts.assert(
|
||||
!goog.isDef(options.renderOrder) || goog.isNull(options.renderOrder) ||
|
||||
goog.isFunction(options.renderOrder),
|
||||
'renderOrder must be a comparator function');
|
||||
|
||||
var baseOptions = goog.object.clone(options);
|
||||
|
||||
delete baseOptions.style;
|
||||
@@ -153,6 +159,10 @@ ol.layer.Vector.prototype.getUpdateWhileInteracting = function() {
|
||||
* Render order.
|
||||
*/
|
||||
ol.layer.Vector.prototype.setRenderOrder = function(renderOrder) {
|
||||
goog.asserts.assert(
|
||||
!goog.isDef(renderOrder) || goog.isNull(renderOrder) ||
|
||||
goog.isFunction(renderOrder),
|
||||
'renderOrder must be a comparator function');
|
||||
this.set(ol.layer.VectorProperty.RENDER_ORDER, renderOrder);
|
||||
};
|
||||
|
||||
|
||||
@@ -151,6 +151,15 @@ ol.MapProperty = {
|
||||
* a further element within the viewport, either DOM or Canvas, depending on the
|
||||
* renderer.
|
||||
*
|
||||
* Layers are stored as a `ol.Collection` in layerGroups. A top-level group is
|
||||
* provided by the library. This is what is accessed by `getLayerGroup` and
|
||||
* `setLayerGroup`. Layers entered in the options are added to this group, and
|
||||
* `addLayer` and `removeLayer` change the layer collection in the group.
|
||||
* `getLayers` is a convenience function for `getLayerGroup().getLayers()`.
|
||||
* Note that `ol.layer.Group` is a subclass of `ol.layer.Base`, so layers
|
||||
* entered in the options or added with `addLayer` can be groups, which can
|
||||
* contain further groups, and so on.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {ol.Object}
|
||||
* @param {olx.MapOptions} options Map options.
|
||||
@@ -503,7 +512,9 @@ ol.Map.prototype.addInteraction = function(interaction) {
|
||||
|
||||
|
||||
/**
|
||||
* Adds the given layer to the top of this map.
|
||||
* Adds the given layer to the top of this map. If you want to add a layer
|
||||
* elsewhere in the stack, use `getLayers()` and the methods available on
|
||||
* {@link ol.Collection}.
|
||||
* @param {ol.layer.Base} layer Layer.
|
||||
* @api stable
|
||||
*/
|
||||
@@ -564,15 +575,19 @@ ol.Map.prototype.disposeInternal = function() {
|
||||
* included in the detection.
|
||||
* @param {ol.Pixel} pixel Pixel.
|
||||
* @param {function(this: S, ol.Feature, ol.layer.Layer): T} callback Feature
|
||||
* callback. If the detected feature is not on a layer, but on a
|
||||
* {@link ol.FeatureOverlay}, then the 2nd argument to this function will
|
||||
* be `null`. To stop detection, callback functions can return a truthy
|
||||
* value.
|
||||
* callback. The callback will be called with two arguments. The first
|
||||
* argument is one {@link ol.Feature feature} at the pixel, the second is
|
||||
* the {@link ol.layer.Layer layer} of the feature. If the detected feature
|
||||
* is not on a layer, but on a {@link ol.FeatureOverlay}, then the second
|
||||
* argument to this function will be `null`. To stop detection, callback
|
||||
* functions can return a truthy value.
|
||||
* @param {S=} opt_this Value to use as `this` when executing `callback`.
|
||||
* @param {(function(this: U, ol.layer.Layer): boolean)=} opt_layerFilter Layer
|
||||
* filter function, only layers which are visible and for which this
|
||||
* function returns `true` will be tested for features. By default, all
|
||||
* visible layers will be tested. Feature overlays will always be tested.
|
||||
* filter function. The filter function will receive one argument, the
|
||||
* {@link ol.layer.Layer layer-candidate} and it should return a boolean
|
||||
* value. Only layers which are visible and for which this function returns
|
||||
* `true` will be tested for features. By default, all visible layers will
|
||||
* be tested. Feature overlays will always be tested.
|
||||
* @param {U=} opt_this2 Value to use as `this` when executing `layerFilter`.
|
||||
* @return {T|undefined} Callback result, i.e. the return value of last
|
||||
* callback execution, or the first truthy callback return value.
|
||||
@@ -602,15 +617,18 @@ ol.Map.prototype.forEachFeatureAtPixel =
|
||||
* always be included in the detection.
|
||||
* @param {ol.Pixel} pixel Pixel.
|
||||
* @param {function(this: S, ol.layer.Layer): T} callback Layer
|
||||
* callback. If the detected feature is not on a layer, but on a
|
||||
* {@link ol.FeatureOverlay}, then the argument to this function will
|
||||
* be `null`. To stop detection, callback functions can return a truthy
|
||||
* value.
|
||||
* callback. Will receive one argument, the {@link ol.layer.Layer layer}
|
||||
* that contains the color pixel. If the detected color value is not from a
|
||||
* layer, but from a {@link ol.FeatureOverlay}, then the argument to this
|
||||
* function will be `null`. To stop detection, callback functions can return
|
||||
* a truthy value.
|
||||
* @param {S=} opt_this Value to use as `this` when executing `callback`.
|
||||
* @param {(function(this: U, ol.layer.Layer): boolean)=} opt_layerFilter Layer
|
||||
* filter function, only layers which are visible and for which this
|
||||
* function returns `true` will be tested for features. By default, all
|
||||
* visible layers will be tested. Feature overlays will always be tested.
|
||||
* filter function. The filter function will receive one argument, the
|
||||
* {@link ol.layer.Layer layer-candidate} and it should return a boolean
|
||||
* value. Only layers which are visible and for which this function returns
|
||||
* `true` will be tested for features. By default, all visible layers will
|
||||
* be tested. Feature overlays will always be tested.
|
||||
* @param {U=} opt_this2 Value to use as `this` when executing `layerFilter`.
|
||||
* @return {T|undefined} Callback result, i.e. the return value of last
|
||||
* callback execution, or the first truthy callback return value.
|
||||
@@ -638,9 +656,11 @@ ol.Map.prototype.forEachLayerAtPixel =
|
||||
* always be included in the detection.
|
||||
* @param {ol.Pixel} pixel Pixel.
|
||||
* @param {(function(this: U, ol.layer.Layer): boolean)=} opt_layerFilter Layer
|
||||
* filter function, only layers which are visible and for which this
|
||||
* function returns `true` will be tested for features. By default, all
|
||||
* visible layers will be tested. Feature overlays will always be tested.
|
||||
* filter function. The filter function will receive one argument, the
|
||||
* {@link ol.layer.Layer layer-candidate} and it should return a boolean
|
||||
* value. Only layers which are visible and for which this function returns
|
||||
* `true` will be tested for features. By default, all visible layers will
|
||||
* be tested. Feature overlays will always be tested.
|
||||
* @param {U=} opt_this Value to use as `this` when executing `layerFilter`.
|
||||
* @return {boolean} Is there a feature at the given pixel?
|
||||
* @template U
|
||||
|
||||
@@ -12,7 +12,6 @@ goog.require('ol.proj');
|
||||
goog.require('ol.source.State');
|
||||
goog.require('ol.source.TileImage');
|
||||
goog.require('ol.tilecoord');
|
||||
goog.require('ol.tilegrid.XYZ');
|
||||
|
||||
|
||||
|
||||
@@ -103,12 +102,14 @@ ol.source.BingMaps.prototype.handleImageryMetadataResponse =
|
||||
var maxZoom = this.maxZoom_ == -1 ? resource.zoomMax : this.maxZoom_;
|
||||
|
||||
var sourceProjection = this.getProjection();
|
||||
var tileGrid = new ol.tilegrid.XYZ({
|
||||
extent: ol.tilegrid.extentFromProjection(sourceProjection),
|
||||
var extent = ol.tilegrid.extentFromProjection(sourceProjection);
|
||||
var tileSize = resource.imageWidth == resource.imageHeight ?
|
||||
resource.imageWidth : [resource.imageWidth, resource.imageHeight];
|
||||
var tileGrid = ol.tilegrid.createXYZ({
|
||||
extent: extent,
|
||||
minZoom: resource.zoomMin,
|
||||
maxZoom: maxZoom,
|
||||
tileSize: resource.imageWidth == resource.imageHeight ?
|
||||
resource.imageWidth : [resource.imageWidth, resource.imageHeight]
|
||||
tileSize: tileSize
|
||||
});
|
||||
this.tileGrid = tileGrid;
|
||||
|
||||
|
||||
@@ -75,9 +75,9 @@ ol.source.Source = function(options) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean|undefined}
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.wrapX_ = options.wrapX;
|
||||
this.wrapX_ = goog.isDef(options.wrapX) ? options.wrapX : false;
|
||||
|
||||
};
|
||||
goog.inherits(ol.source.Source, ol.Object);
|
||||
|
||||
@@ -93,7 +93,8 @@ ol.source.TileImage.prototype.getTile =
|
||||
} else {
|
||||
goog.asserts.assert(projection, 'argument projection is truthy');
|
||||
var tileCoord = [z, x, y];
|
||||
var urlTileCoord = this.getWrapXTileCoord(tileCoord, projection);
|
||||
var urlTileCoord = this.getTileCoordForTileUrlFunction(
|
||||
tileCoord, projection);
|
||||
var tileUrl = goog.isNull(urlTileCoord) ? undefined :
|
||||
this.tileUrlFunction(urlTileCoord, pixelRatio, projection);
|
||||
var tile = new this.tileClass(
|
||||
|
||||
@@ -17,7 +17,6 @@ goog.require('ol.extent');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.source.State');
|
||||
goog.require('ol.source.TileImage');
|
||||
goog.require('ol.tilegrid.XYZ');
|
||||
|
||||
|
||||
|
||||
@@ -69,7 +68,7 @@ ol.source.TileJSON.prototype.handleTileJSONResponse = function(tileJSON) {
|
||||
}
|
||||
var minZoom = tileJSON.minzoom || 0;
|
||||
var maxZoom = tileJSON.maxzoom || 22;
|
||||
var tileGrid = new ol.tilegrid.XYZ({
|
||||
var tileGrid = ol.tilegrid.createXYZ({
|
||||
extent: ol.tilegrid.extentFromProjection(sourceProjection),
|
||||
maxZoom: maxZoom,
|
||||
minZoom: minZoom
|
||||
@@ -77,7 +76,7 @@ ol.source.TileJSON.prototype.handleTileJSONResponse = function(tileJSON) {
|
||||
this.tileGrid = tileGrid;
|
||||
|
||||
this.tileUrlFunction = ol.TileUrlFunction.withTileCoordTransform(
|
||||
tileGrid.createTileCoordTransform({extent: extent}),
|
||||
tileGrid.createTileCoordTransform(),
|
||||
ol.TileUrlFunction.createFromTemplates(tileJSON.tiles));
|
||||
|
||||
if (goog.isDef(tileJSON.attribution) &&
|
||||
|
||||
@@ -2,6 +2,7 @@ goog.provide('ol.source.Tile');
|
||||
goog.provide('ol.source.TileEvent');
|
||||
goog.provide('ol.source.TileOptions');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.events.Event');
|
||||
goog.require('ol.Attribution');
|
||||
goog.require('ol.Extent');
|
||||
@@ -216,28 +217,23 @@ ol.source.Tile.prototype.getTilePixelSize =
|
||||
|
||||
|
||||
/**
|
||||
* Handles x-axis wrapping. When `wrapX` is `undefined` or the projection is not
|
||||
* a global projection, `tileCoord` will be returned unaltered. When `wrapX` is
|
||||
* `true`, the tile coordinate will be wrapped horizontally.
|
||||
* When `wrapX` is `false`, `null` will be returned for tiles that are
|
||||
* outside the projection extent.
|
||||
* Handles x-axis wrapping and returns a tile coordinate when it is within
|
||||
* the resolution and extent range.
|
||||
* @param {ol.TileCoord} tileCoord Tile coordinate.
|
||||
* @param {ol.proj.Projection=} opt_projection Projection.
|
||||
* @return {ol.TileCoord} Tile coordinate.
|
||||
* @return {ol.TileCoord} Tile coordinate to be passed to the tileUrlFunction or
|
||||
* null if no tile URL should be created for the passed `tileCoord`.
|
||||
*/
|
||||
ol.source.Tile.prototype.getWrapXTileCoord =
|
||||
ol.source.Tile.prototype.getTileCoordForTileUrlFunction =
|
||||
function(tileCoord, opt_projection) {
|
||||
var projection = goog.isDef(opt_projection) ?
|
||||
opt_projection : this.getProjection();
|
||||
var tileGrid = this.getTileGridForProjection(projection);
|
||||
var wrapX = this.getWrapX();
|
||||
if (goog.isDef(wrapX) && tileGrid.isGlobal(tileCoord[0], projection)) {
|
||||
return wrapX ?
|
||||
ol.tilecoord.wrapX(tileCoord, tileGrid, projection) :
|
||||
ol.tilecoord.clipX(tileCoord, tileGrid, projection);
|
||||
} else {
|
||||
return tileCoord;
|
||||
goog.asserts.assert(!goog.isNull(tileGrid), 'tile grid needed');
|
||||
if (this.getWrapX()) {
|
||||
tileCoord = ol.tilecoord.wrapX(tileCoord, tileGrid, projection);
|
||||
}
|
||||
return ol.tilecoord.restrictByExtentAndZ(tileCoord, tileGrid);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ goog.require('ol.extent');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.source.State');
|
||||
goog.require('ol.source.Tile');
|
||||
goog.require('ol.tilegrid.XYZ');
|
||||
|
||||
|
||||
|
||||
@@ -122,7 +121,7 @@ ol.source.TileUTFGrid.prototype.handleTileJSONResponse = function(tileJSON) {
|
||||
}
|
||||
var minZoom = tileJSON.minzoom || 0;
|
||||
var maxZoom = tileJSON.maxzoom || 22;
|
||||
var tileGrid = new ol.tilegrid.XYZ({
|
||||
var tileGrid = ol.tilegrid.createXYZ({
|
||||
extent: ol.tilegrid.extentFromProjection(sourceProjection),
|
||||
maxZoom: maxZoom,
|
||||
minZoom: minZoom
|
||||
@@ -138,9 +137,7 @@ ol.source.TileUTFGrid.prototype.handleTileJSONResponse = function(tileJSON) {
|
||||
}
|
||||
|
||||
this.tileUrlFunction_ = ol.TileUrlFunction.withTileCoordTransform(
|
||||
tileGrid.createTileCoordTransform({
|
||||
extent: extent
|
||||
}),
|
||||
tileGrid.createTileCoordTransform(),
|
||||
ol.TileUrlFunction.createFromTemplates(grids));
|
||||
|
||||
if (goog.isDef(tileJSON.attribution)) {
|
||||
|
||||
@@ -49,7 +49,7 @@ ol.source.TileWMS = function(opt_options) {
|
||||
tileGrid: options.tileGrid,
|
||||
tileLoadFunction: options.tileLoadFunction,
|
||||
tileUrlFunction: goog.bind(this.tileUrlFunction_, this),
|
||||
wrapX: options.wrapX
|
||||
wrapX: goog.isDef(options.wrapX) ? options.wrapX : true
|
||||
});
|
||||
|
||||
var urls = options.urls;
|
||||
|
||||
@@ -11,7 +11,6 @@ goog.require('ol.TileUrlFunctionType');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.source.TileImage');
|
||||
goog.require('ol.tilecoord');
|
||||
goog.require('ol.tilegrid.WMTS');
|
||||
|
||||
|
||||
@@ -181,31 +180,8 @@ ol.source.WMTS = function(options) {
|
||||
goog.array.map(this.urls_, createFromWMTSTemplate)) :
|
||||
ol.TileUrlFunction.nullTileUrlFunction;
|
||||
|
||||
var tmpExtent = ol.extent.createEmpty();
|
||||
tileUrlFunction = ol.TileUrlFunction.withTileCoordTransform(
|
||||
/**
|
||||
* @param {ol.TileCoord} tileCoord Tile coordinate.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @param {ol.TileCoord=} opt_tileCoord Tile coordinate.
|
||||
* @return {ol.TileCoord} Tile coordinate.
|
||||
*/
|
||||
function(tileCoord, projection, opt_tileCoord) {
|
||||
goog.asserts.assert(!goog.isNull(tileGrid),
|
||||
'tileGrid must not be null');
|
||||
if (tileGrid.getResolutions().length <= tileCoord[0]) {
|
||||
return null;
|
||||
}
|
||||
var x = tileCoord[1];
|
||||
var y = -tileCoord[2] - 1;
|
||||
var tileExtent = tileGrid.getTileCoordExtent(tileCoord, tmpExtent);
|
||||
var extent = projection.getExtent();
|
||||
|
||||
if (!ol.extent.intersects(tileExtent, extent) ||
|
||||
ol.extent.touches(tileExtent, extent)) {
|
||||
return null;
|
||||
}
|
||||
return ol.tilecoord.createOrUpdate(tileCoord[0], x, y, opt_tileCoord);
|
||||
},
|
||||
ol.tilegrid.createOriginTopLeftTileCoordTransform(tileGrid),
|
||||
tileUrlFunction);
|
||||
|
||||
goog.base(this, {
|
||||
@@ -379,7 +355,7 @@ ol.source.WMTS.optionsFromCapabilities = function(wmtsCap, config) {
|
||||
|
||||
goog.asserts.assert(l['TileMatrixSetLink'].length > 0,
|
||||
'layer has TileMatrixSetLink');
|
||||
var idx, matrixSet, wrapX;
|
||||
var idx, matrixSet;
|
||||
if (l['TileMatrixSetLink'].length > 1) {
|
||||
idx = goog.array.findIndex(l['TileMatrixSetLink'],
|
||||
function(elt, index, array) {
|
||||
@@ -404,13 +380,6 @@ ol.source.WMTS.optionsFromCapabilities = function(wmtsCap, config) {
|
||||
goog.asserts.assert(!goog.isNull(matrixSet),
|
||||
'TileMatrixSet must not be null');
|
||||
|
||||
var wgs84BoundingBox = l['WGS84BoundingBox'];
|
||||
if (goog.isDef(wgs84BoundingBox)) {
|
||||
var wgs84ProjectionExtent = ol.proj.get('EPSG:4326').getExtent();
|
||||
wrapX = (wgs84BoundingBox[0] == wgs84ProjectionExtent[0] &&
|
||||
wgs84BoundingBox[2] == wgs84ProjectionExtent[2]);
|
||||
}
|
||||
|
||||
var format = /** @type {string} */ (l['Format'][0]);
|
||||
if (goog.isDef(config['format'])) {
|
||||
format = config['format'];
|
||||
@@ -450,9 +419,6 @@ ol.source.WMTS.optionsFromCapabilities = function(wmtsCap, config) {
|
||||
goog.asserts.assert(!goog.isNull(matrixSetObj),
|
||||
'found matrixSet in Contents/TileMatrixSet');
|
||||
|
||||
var tileGrid = ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet(
|
||||
matrixSetObj);
|
||||
|
||||
var projection;
|
||||
if (goog.isDef(config['projection'])) {
|
||||
projection = ol.proj.get(config['projection']);
|
||||
@@ -461,6 +427,27 @@ ol.source.WMTS.optionsFromCapabilities = function(wmtsCap, config) {
|
||||
/urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/, '$1:$3'));
|
||||
}
|
||||
|
||||
var wgs84BoundingBox = l['WGS84BoundingBox'];
|
||||
var extent, wrapX;
|
||||
if (goog.isDef(wgs84BoundingBox)) {
|
||||
var wgs84ProjectionExtent = ol.proj.get('EPSG:4326').getExtent();
|
||||
wrapX = (wgs84BoundingBox[0] == wgs84ProjectionExtent[0] &&
|
||||
wgs84BoundingBox[2] == wgs84ProjectionExtent[2]);
|
||||
extent = ol.proj.transformExtent(
|
||||
wgs84BoundingBox, 'EPSG:4326', projection);
|
||||
var projectionExtent = projection.getExtent();
|
||||
if (!goog.isNull(projectionExtent)) {
|
||||
// If possible, do a sanity check on the extent - it should never be
|
||||
// bigger than the validity extent of the projection of a matrix set.
|
||||
if (!ol.extent.containsExtent(projectionExtent, extent)) {
|
||||
extent = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var tileGrid = ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet(
|
||||
matrixSetObj, extent);
|
||||
|
||||
/** @type {!Array.<string>} */
|
||||
var urls = [];
|
||||
var requestEncoding = config['requestEncoding'];
|
||||
@@ -471,7 +458,8 @@ ol.source.WMTS.optionsFromCapabilities = function(wmtsCap, config) {
|
||||
'requestEncoding (%s) is one of "REST", "RESTful", "KVP" or ""',
|
||||
requestEncoding);
|
||||
|
||||
if (!wmtsCap['OperationsMetadata'].hasOwnProperty('GetTile') ||
|
||||
if (!wmtsCap.hasOwnProperty('OperationsMetadata') ||
|
||||
!wmtsCap['OperationsMetadata'].hasOwnProperty('GetTile') ||
|
||||
goog.string.startsWith(requestEncoding, 'REST')) {
|
||||
// Add REST tile resource url
|
||||
requestEncoding = ol.source.WMTSRequestEncoding.REST;
|
||||
|
||||
@@ -3,7 +3,6 @@ goog.provide('ol.source.XYZ');
|
||||
goog.require('ol.Attribution');
|
||||
goog.require('ol.TileUrlFunction');
|
||||
goog.require('ol.source.TileImage');
|
||||
goog.require('ol.tilegrid.XYZ');
|
||||
|
||||
|
||||
|
||||
@@ -20,7 +19,7 @@ ol.source.XYZ = function(options) {
|
||||
var projection = goog.isDef(options.projection) ?
|
||||
options.projection : 'EPSG:3857';
|
||||
|
||||
var tileGrid = new ol.tilegrid.XYZ({
|
||||
var tileGrid = ol.tilegrid.createXYZ({
|
||||
extent: ol.tilegrid.extentFromProjection(projection),
|
||||
maxZoom: options.maxZoom,
|
||||
tileSize: options.tileSize
|
||||
|
||||
@@ -3,7 +3,7 @@ goog.provide('ol.tilecoord');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.math');
|
||||
goog.require('ol.extent');
|
||||
|
||||
|
||||
/**
|
||||
@@ -149,25 +149,42 @@ ol.tilecoord.toString = function(tileCoord) {
|
||||
*/
|
||||
ol.tilecoord.wrapX = function(tileCoord, tileGrid, projection) {
|
||||
var z = tileCoord[0];
|
||||
var x = tileCoord[1];
|
||||
var tileRange = tileGrid.getTileRange(z, projection);
|
||||
if (x < tileRange.minX || x > tileRange.maxX) {
|
||||
x = goog.math.modulo(x, tileRange.getWidth());
|
||||
return [z, x, tileCoord[2]];
|
||||
var center = tileGrid.getTileCoordCenter(tileCoord);
|
||||
var projectionExtent = ol.tilegrid.extentFromProjection(projection);
|
||||
if (!ol.extent.containsCoordinate(projectionExtent, center)) {
|
||||
var worldWidth = ol.extent.getWidth(projectionExtent);
|
||||
var worldsAway = Math.ceil((projectionExtent[0] - center[0]) / worldWidth);
|
||||
center[0] += worldWidth * worldsAway;
|
||||
return tileGrid.getTileCoordForCoordAndZ(center, z);
|
||||
} else {
|
||||
return tileCoord;
|
||||
}
|
||||
return tileCoord;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.TileCoord} tileCoord Tile coordinate.
|
||||
* @param {ol.tilegrid.TileGrid} tileGrid Tile grid.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @param {!ol.tilegrid.TileGrid} tileGrid Tile grid.
|
||||
* @return {ol.TileCoord} Tile coordinate.
|
||||
*/
|
||||
ol.tilecoord.clipX = function(tileCoord, tileGrid, projection) {
|
||||
ol.tilecoord.restrictByExtentAndZ = function(tileCoord, tileGrid) {
|
||||
var z = tileCoord[0];
|
||||
var x = tileCoord[1];
|
||||
var tileRange = tileGrid.getTileRange(z, projection);
|
||||
return (x < tileRange.minX || x > tileRange.maxX) ? null : tileCoord;
|
||||
var y = tileCoord[2];
|
||||
|
||||
if (tileGrid.getMinZoom() > z || z > tileGrid.getMaxZoom()) {
|
||||
return null;
|
||||
}
|
||||
var extent = tileGrid.getExtent();
|
||||
var tileRange;
|
||||
if (goog.isNull(extent)) {
|
||||
tileRange = tileGrid.getFullTileRange(z);
|
||||
} else {
|
||||
tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);
|
||||
}
|
||||
if (goog.isNull(tileRange)) {
|
||||
return tileCoord;
|
||||
} else {
|
||||
return tileRange.containsXY(x, y) ? tileCoord : null;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -4,6 +4,7 @@ goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.functions');
|
||||
goog.require('goog.math');
|
||||
goog.require('goog.object');
|
||||
goog.require('ol');
|
||||
goog.require('ol.Coordinate');
|
||||
goog.require('ol.TileCoord');
|
||||
@@ -69,6 +70,14 @@ ol.tilegrid.TileGrid = function(options) {
|
||||
goog.asserts.assert(this.origins_.length == this.resolutions_.length,
|
||||
'number of origins and resolutions must be equal');
|
||||
}
|
||||
|
||||
var extent = options.extent;
|
||||
|
||||
if (goog.isDef(extent) &&
|
||||
goog.isNull(this.origin_) && goog.isNull(this.origins_)) {
|
||||
this.origin_ = ol.extent.getBottomLeft(extent);
|
||||
}
|
||||
|
||||
goog.asserts.assert(
|
||||
(goog.isNull(this.origin_) && !goog.isNull(this.origins_)) ||
|
||||
(!goog.isNull(this.origin_) && goog.isNull(this.origins_)),
|
||||
@@ -97,6 +106,56 @@ ol.tilegrid.TileGrid = function(options) {
|
||||
(!goog.isNull(this.tileSize_) && goog.isNull(this.tileSizes_)),
|
||||
'either tileSize or tileSizes must be configured, never both');
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Extent}
|
||||
*/
|
||||
this.extent_ = goog.isDef(extent) ? extent : null;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a TileCoord transform function for use with this tile grid.
|
||||
* Transforms the internal tile coordinates with bottom-left origin to
|
||||
* the tile coordinates used by the {@link ol.TileUrlFunction}.
|
||||
* The returned function expects an {@link ol.TileCoord} as first and an
|
||||
* {@link ol.proj.Projection} as second argument and returns a transformed
|
||||
* {@link ol.TileCoord}.
|
||||
* @param {{extent: (ol.Extent|undefined)}=} opt_options Options.
|
||||
* @return {function(ol.TileCoord, ol.proj.Projection, ol.TileCoord=):
|
||||
* ol.TileCoord} Tile coordinate transform.
|
||||
* @api
|
||||
*/
|
||||
this.createTileCoordTransform = goog.isDef(options.createTileCoordTransform) ?
|
||||
options.createTileCoordTransform :
|
||||
goog.functions.identity;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<ol.TileRange>}
|
||||
*/
|
||||
this.fullTileRanges_ = null;
|
||||
|
||||
if (goog.isDef(options.sizes)) {
|
||||
goog.asserts.assert(options.sizes.length == this.resolutions_.length,
|
||||
'number of sizes and resolutions must be equal');
|
||||
this.fullTileRanges_ = goog.array.map(options.sizes, function(size, z) {
|
||||
goog.asserts.assert(size[0] > 0, 'width must be > 0');
|
||||
goog.asserts.assert(size[1] !== 0, 'height must not be 0');
|
||||
var tileRange = new ol.TileRange(0, size[0] - 1, 0, size[1] - 1);
|
||||
if (tileRange.maxY < tileRange.minY) {
|
||||
tileRange.minY = size[1];
|
||||
tileRange.maxY = -1;
|
||||
}
|
||||
if (this.minZoom <= z && z <= this.maxZoom && goog.isDef(extent)) {
|
||||
goog.asserts.assert(tileRange.containsTileRange(
|
||||
this.getTileRangeForExtentAndZ(extent, z)),
|
||||
'extent tile range must not exceed tilegrid width and height');
|
||||
}
|
||||
return tileRange;
|
||||
}, this);
|
||||
} else if (goog.isDefAndNotNull(extent)) {
|
||||
this.calculateTileRanges_(extent);
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -104,17 +163,6 @@ ol.tilegrid.TileGrid = function(options) {
|
||||
*/
|
||||
this.tmpSize_ = [0, 0];
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<number>}
|
||||
*/
|
||||
this.widths_ = null;
|
||||
if (goog.isDef(options.widths)) {
|
||||
this.widths_ = options.widths;
|
||||
goog.asserts.assert(this.widths_.length == this.resolutions_.length,
|
||||
'number of widths and resolutions must be equal');
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -125,18 +173,6 @@ ol.tilegrid.TileGrid = function(options) {
|
||||
ol.tilegrid.TileGrid.tmpTileCoord_ = [0, 0, 0];
|
||||
|
||||
|
||||
/**
|
||||
* Returns the identity function. May be overridden in subclasses.
|
||||
* @param {{extent: (ol.Extent|undefined)}=} opt_options Options.
|
||||
* @return {function(ol.TileCoord, ol.proj.Projection, ol.TileCoord=):
|
||||
* ol.TileCoord} Tile coordinate transform.
|
||||
*/
|
||||
ol.tilegrid.TileGrid.prototype.createTileCoordTransform =
|
||||
function(opt_options) {
|
||||
return goog.functions.identity;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.TileCoord} tileCoord Tile coordinate.
|
||||
* @param {function(this: T, number, ol.TileRange): boolean} callback Callback.
|
||||
@@ -161,6 +197,15 @@ ol.tilegrid.TileGrid.prototype.forEachTileCoordParentTileRange =
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the extent for this tile grid, if it was configured.
|
||||
* @return {ol.Extent} Extent.
|
||||
*/
|
||||
ol.tilegrid.TileGrid.prototype.getExtent = function() {
|
||||
return this.extent_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the maximum zoom level for the grid.
|
||||
* @return {number} Max zoom.
|
||||
@@ -365,8 +410,11 @@ ol.tilegrid.TileGrid.prototype.getTileCoordForXYAndResolution_ = function(
|
||||
var origin = this.getOrigin(z);
|
||||
var tileSize = ol.size.toSize(this.getTileSize(z), this.tmpSize_);
|
||||
|
||||
var tileCoordX = scale * (x - origin[0]) / (resolution * tileSize[0]);
|
||||
var tileCoordY = scale * (y - origin[1]) / (resolution * tileSize[1]);
|
||||
var adjust = reverseIntersectionPolicy ? 0.5 : 0;
|
||||
var xFromOrigin = ((x - origin[0]) / resolution + adjust) | 0;
|
||||
var yFromOrigin = ((y - origin[1]) / resolution + adjust) | 0;
|
||||
var tileCoordX = scale * xFromOrigin / tileSize[0];
|
||||
var tileCoordY = scale * yFromOrigin / tileSize[1];
|
||||
|
||||
if (reverseIntersectionPolicy) {
|
||||
tileCoordX = Math.ceil(tileCoordX) - 1;
|
||||
@@ -409,25 +457,6 @@ ol.tilegrid.TileGrid.prototype.getTileCoordResolution = function(tileCoord) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} z Zoom level.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @param {ol.TileRange=} opt_tileRange Tile range.
|
||||
* @return {ol.TileRange} Tile range.
|
||||
*/
|
||||
ol.tilegrid.TileGrid.prototype.getTileRange =
|
||||
function(z, projection, opt_tileRange) {
|
||||
var projectionExtentTileRange = this.getTileRangeForExtentAndZ(
|
||||
ol.tilegrid.extentFromProjection(projection), z);
|
||||
var width = this.getWidth(z);
|
||||
if (!goog.isDef(width)) {
|
||||
width = projectionExtentTileRange.getWidth();
|
||||
}
|
||||
return ol.TileRange.createOrUpdate(
|
||||
0, width - 1, 0, projectionExtentTileRange.getHeight(), opt_tileRange);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the tile size for a zoom level. The type of the return value matches the
|
||||
* `tileSize` or `tileSizes` that the tile grid was configured with. To always
|
||||
@@ -452,15 +481,16 @@ ol.tilegrid.TileGrid.prototype.getTileSize = function(z) {
|
||||
|
||||
/**
|
||||
* @param {number} z Zoom level.
|
||||
* @return {number|undefined} Width for the specified zoom level or `undefined`
|
||||
* if unknown.
|
||||
* @return {ol.TileRange} Extent tile range for the specified zoom level.
|
||||
*/
|
||||
ol.tilegrid.TileGrid.prototype.getWidth = function(z) {
|
||||
if (!goog.isNull(this.widths_)) {
|
||||
ol.tilegrid.TileGrid.prototype.getFullTileRange = function(z) {
|
||||
if (goog.isNull(this.fullTileRanges_)) {
|
||||
return null;
|
||||
} else {
|
||||
goog.asserts.assert(this.minZoom <= z && z <= this.maxZoom,
|
||||
'z is not in allowed range (%s <= %s <= %s',
|
||||
this.minZoom, z, this.maxZoom);
|
||||
return this.widths_[z];
|
||||
return this.fullTileRanges_[z];
|
||||
}
|
||||
};
|
||||
|
||||
@@ -476,22 +506,21 @@ ol.tilegrid.TileGrid.prototype.getZForResolution = function(resolution) {
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} z Zoom level.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @return {boolean} Whether the tile grid is defined for the whole globe when
|
||||
* used with the provided `projection` at zoom level `z`.
|
||||
* @param {!ol.Extent} extent Extent for this tile grid.
|
||||
* @private
|
||||
*/
|
||||
ol.tilegrid.TileGrid.prototype.isGlobal = function(z, projection) {
|
||||
var width = this.getWidth(z);
|
||||
if (goog.isDef(width)) {
|
||||
var projTileGrid = ol.tilegrid.getForProjection(projection);
|
||||
var projExtent = projection.getExtent();
|
||||
return ol.size.toSize(this.getTileSize(z), this.tmpSize_)[0] * width ==
|
||||
projTileGrid.getTileSize(z) *
|
||||
projTileGrid.getTileRangeForExtentAndZ(projExtent, z).getWidth();
|
||||
} else {
|
||||
return projection.isGlobal();
|
||||
ol.tilegrid.TileGrid.prototype.calculateTileRanges_ = function(extent) {
|
||||
var extentWidth = ol.extent.getWidth(extent);
|
||||
var extentHeight = ol.extent.getHeight(extent);
|
||||
var fullTileRanges = new Array(this.resolutions_.length);
|
||||
var tileSize;
|
||||
for (var z = 0, zz = fullTileRanges.length; z < zz; ++z) {
|
||||
tileSize = ol.size.toSize(this.getTileSize(z), this.tmpSize_);
|
||||
fullTileRanges[z] = new ol.TileRange(
|
||||
0, Math.ceil(extentWidth / tileSize[0] / this.resolutions_[z]) - 1,
|
||||
0, Math.ceil(extentHeight / tileSize[1] / this.resolutions_[z]) - 1);
|
||||
}
|
||||
this.fullTileRanges_ = fullTileRanges;
|
||||
};
|
||||
|
||||
|
||||
@@ -521,36 +550,59 @@ ol.tilegrid.getForProjection = function(projection) {
|
||||
*/
|
||||
ol.tilegrid.createForExtent =
|
||||
function(extent, opt_maxZoom, opt_tileSize, opt_corner) {
|
||||
var tileSize = goog.isDef(opt_tileSize) ?
|
||||
ol.size.toSize(opt_tileSize) : ol.size.toSize(ol.DEFAULT_TILE_SIZE);
|
||||
|
||||
var corner = goog.isDef(opt_corner) ?
|
||||
opt_corner : ol.extent.Corner.BOTTOM_LEFT;
|
||||
|
||||
var resolutions = ol.tilegrid.resolutionsFromExtent(
|
||||
extent, opt_maxZoom, ol.size.toSize(tileSize));
|
||||
|
||||
var widths = new Array(resolutions.length);
|
||||
var extentWidth = ol.extent.getWidth(extent);
|
||||
for (var z = resolutions.length - 1; z >= 0; --z) {
|
||||
widths[z] = extentWidth / tileSize[0] / resolutions[z];
|
||||
}
|
||||
extent, opt_maxZoom, opt_tileSize);
|
||||
|
||||
return new ol.tilegrid.TileGrid({
|
||||
extent: extent,
|
||||
origin: ol.extent.getCorner(extent, corner),
|
||||
resolutions: resolutions,
|
||||
tileSize: goog.isDef(opt_tileSize) ? opt_tileSize : ol.DEFAULT_TILE_SIZE,
|
||||
widths: widths
|
||||
tileSize: opt_tileSize
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a tile grid with a standard XYZ tiling scheme.
|
||||
* @param {olx.tilegrid.XYZOptions=} opt_options Tile grid options.
|
||||
* @return {ol.tilegrid.TileGrid} Tile grid instance.
|
||||
* @api
|
||||
*/
|
||||
ol.tilegrid.createXYZ = function(opt_options) {
|
||||
var options = /** @type {olx.tilegrid.TileGridOptions} */ ({});
|
||||
goog.object.extend(options, goog.isDef(opt_options) ?
|
||||
opt_options : /** @type {olx.tilegrid.XYZOptions} */ ({}));
|
||||
if (!goog.isDef(options.extent)) {
|
||||
options.extent = ol.proj.get('EPSG:3857').getExtent();
|
||||
}
|
||||
options.resolutions = ol.tilegrid.resolutionsFromExtent(
|
||||
options.extent, options.maxZoom, options.tileSize);
|
||||
delete options.maxZoom;
|
||||
|
||||
/**
|
||||
* @param {{extent: (ol.Extent|undefined)}=} opt_options Options.
|
||||
* @return {function(ol.TileCoord, ol.proj.Projection, ol.TileCoord=):
|
||||
* ol.TileCoord} Tile coordinate transform.
|
||||
* @this {ol.tilegrid.TileGrid}
|
||||
*/
|
||||
options.createTileCoordTransform = function(opt_options) {
|
||||
return ol.tilegrid.createOriginTopLeftTileCoordTransform(this);
|
||||
};
|
||||
|
||||
return new ol.tilegrid.TileGrid(options);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create a resolutions array from an extent. A zoom factor of 2 is assumed.
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {number=} opt_maxZoom Maximum zoom level (default is
|
||||
* ol.DEFAULT_MAX_ZOOM).
|
||||
* @param {ol.Size=} opt_tileSize Tile size (default uses ol.DEFAULT_TILE_SIZE).
|
||||
* @param {number|ol.Size=} opt_tileSize Tile size (default uses
|
||||
* ol.DEFAULT_TILE_SIZE).
|
||||
* @return {!Array.<number>} Resolutions array.
|
||||
*/
|
||||
ol.tilegrid.resolutionsFromExtent =
|
||||
@@ -561,8 +613,8 @@ ol.tilegrid.resolutionsFromExtent =
|
||||
var height = ol.extent.getHeight(extent);
|
||||
var width = ol.extent.getWidth(extent);
|
||||
|
||||
var tileSize = goog.isDef(opt_tileSize) ?
|
||||
opt_tileSize : ol.size.toSize(ol.DEFAULT_TILE_SIZE);
|
||||
var tileSize = ol.size.toSize(goog.isDef(opt_tileSize) ?
|
||||
opt_tileSize : ol.DEFAULT_TILE_SIZE);
|
||||
var maxResolution = Math.max(
|
||||
width / tileSize[0], height / tileSize[1]);
|
||||
|
||||
@@ -608,3 +660,32 @@ ol.tilegrid.extentFromProjection = function(projection) {
|
||||
}
|
||||
return extent;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.tilegrid.TileGrid} tileGrid Tile grid.
|
||||
* @return {function(ol.TileCoord, ol.proj.Projection, ol.TileCoord=):
|
||||
* ol.TileCoord} Tile coordinate transform.
|
||||
*/
|
||||
ol.tilegrid.createOriginTopLeftTileCoordTransform = function(tileGrid) {
|
||||
goog.asserts.assert(!goog.isNull(tileGrid), 'tileGrid required');
|
||||
return (
|
||||
/**
|
||||
* @param {ol.TileCoord} tileCoord Tile coordinate.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @param {ol.TileCoord=} opt_tileCoord Destination tile coordinate.
|
||||
* @return {ol.TileCoord} Tile coordinate.
|
||||
*/
|
||||
function(tileCoord, projection, opt_tileCoord) {
|
||||
if (goog.isNull(tileCoord)) {
|
||||
return null;
|
||||
}
|
||||
var z = tileCoord[0];
|
||||
var fullTileRange = tileGrid.getFullTileRange(z);
|
||||
var height = (goog.isNull(fullTileRange) || fullTileRange.minY < 0) ?
|
||||
0 : fullTileRange.getHeight();
|
||||
return ol.tilecoord.createOrUpdate(
|
||||
z, tileCoord[1], height - tileCoord[2] - 1, opt_tileCoord);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
@@ -32,12 +32,13 @@ ol.tilegrid.WMTS = function(options) {
|
||||
// FIXME: should the matrixIds become optionnal?
|
||||
|
||||
goog.base(this, {
|
||||
extent: options.extent,
|
||||
origin: options.origin,
|
||||
origins: options.origins,
|
||||
resolutions: options.resolutions,
|
||||
tileSize: options.tileSize,
|
||||
tileSizes: options.tileSizes,
|
||||
widths: options.widths
|
||||
sizes: options.sizes
|
||||
});
|
||||
|
||||
};
|
||||
@@ -69,11 +70,13 @@ ol.tilegrid.WMTS.prototype.getMatrixIds = function() {
|
||||
* Create a tile grid from a WMTS capabilities matrix set.
|
||||
* @param {Object} matrixSet An object representing a matrixSet in the
|
||||
* capabilities document.
|
||||
* @param {ol.Extent=} opt_extent An optional extent to restrict the tile
|
||||
* ranges the server provides.
|
||||
* @return {ol.tilegrid.WMTS} WMTS tileGrid instance.
|
||||
* @api
|
||||
*/
|
||||
ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet =
|
||||
function(matrixSet) {
|
||||
function(matrixSet, opt_extent) {
|
||||
|
||||
/** @type {!Array.<number>} */
|
||||
var resolutions = [];
|
||||
@@ -83,8 +86,8 @@ ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet =
|
||||
var origins = [];
|
||||
/** @type {!Array.<ol.Size>} */
|
||||
var tileSizes = [];
|
||||
/** @type {!Array.<number>} */
|
||||
var widths = [];
|
||||
/** @type {!Array.<ol.Size>} */
|
||||
var sizes = [];
|
||||
|
||||
var supportedCRSPropName = 'SupportedCRS';
|
||||
var matrixIdsPropName = 'TileMatrix';
|
||||
@@ -108,26 +111,30 @@ ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet =
|
||||
goog.array.forEach(matrixSet[matrixIdsPropName],
|
||||
function(elt, index, array) {
|
||||
matrixIds.push(elt[identifierPropName]);
|
||||
var resolution = elt[scaleDenominatorPropName] * 0.28E-3 /
|
||||
metersPerUnit;
|
||||
var tileWidth = elt[tileWidthPropName];
|
||||
var tileHeight = elt[tileHeightPropName];
|
||||
var matrixHeight = elt['MatrixHeight'];
|
||||
if (switchOriginXY) {
|
||||
origins.push([elt[topLeftCornerPropName][1],
|
||||
elt[topLeftCornerPropName][0]]);
|
||||
} else {
|
||||
origins.push(elt[topLeftCornerPropName]);
|
||||
}
|
||||
resolutions.push(elt[scaleDenominatorPropName] * 0.28E-3 /
|
||||
metersPerUnit);
|
||||
var tileWidth = elt[tileWidthPropName];
|
||||
var tileHeight = elt[tileHeightPropName];
|
||||
resolutions.push(resolution);
|
||||
tileSizes.push(tileWidth == tileHeight ?
|
||||
tileWidth : [tileWidth, tileHeight]);
|
||||
widths.push(elt['MatrixWidth']);
|
||||
// top-left origin, so height is negative
|
||||
sizes.push([elt['MatrixWidth'], -matrixHeight]);
|
||||
});
|
||||
|
||||
return new ol.tilegrid.WMTS({
|
||||
extent: opt_extent,
|
||||
origins: origins,
|
||||
resolutions: resolutions,
|
||||
matrixIds: matrixIds,
|
||||
tileSizes: tileSizes,
|
||||
widths: widths
|
||||
sizes: sizes
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
goog.provide('ol.tilegrid.XYZ');
|
||||
|
||||
goog.require('goog.math');
|
||||
goog.require('ol');
|
||||
goog.require('ol.TileCoord');
|
||||
goog.require('ol.TileRange');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.extent.Corner');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.proj.EPSG3857');
|
||||
goog.require('ol.size');
|
||||
goog.require('ol.tilecoord');
|
||||
goog.require('ol.tilegrid.TileGrid');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Set the grid pattern for sources accessing XYZ tiled-image servers.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {ol.tilegrid.TileGrid}
|
||||
* @param {olx.tilegrid.XYZOptions} options XYZ options.
|
||||
* @struct
|
||||
* @api
|
||||
*/
|
||||
ol.tilegrid.XYZ = function(options) {
|
||||
var extent = goog.isDef(options.extent) ?
|
||||
options.extent : ol.proj.EPSG3857.EXTENT;
|
||||
var tileSize;
|
||||
if (goog.isDef(options.tileSize)) {
|
||||
tileSize = ol.size.toSize(options.tileSize);
|
||||
}
|
||||
var resolutions = ol.tilegrid.resolutionsFromExtent(
|
||||
extent, options.maxZoom, tileSize);
|
||||
|
||||
goog.base(this, {
|
||||
minZoom: options.minZoom,
|
||||
origin: ol.extent.getCorner(extent, ol.extent.Corner.TOP_LEFT),
|
||||
resolutions: resolutions,
|
||||
tileSize: options.tileSize
|
||||
});
|
||||
|
||||
};
|
||||
goog.inherits(ol.tilegrid.XYZ, ol.tilegrid.TileGrid);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.tilegrid.XYZ.prototype.createTileCoordTransform = function(opt_options) {
|
||||
var options = goog.isDef(opt_options) ? opt_options : {};
|
||||
var minZ = this.minZoom;
|
||||
var maxZ = this.maxZoom;
|
||||
/** @type {Array.<ol.TileRange>} */
|
||||
var tileRangeByZ = null;
|
||||
if (goog.isDef(options.extent)) {
|
||||
tileRangeByZ = new Array(maxZ + 1);
|
||||
var z;
|
||||
for (z = 0; z <= maxZ; ++z) {
|
||||
if (z < minZ) {
|
||||
tileRangeByZ[z] = null;
|
||||
} else {
|
||||
tileRangeByZ[z] = this.getTileRangeForExtentAndZ(options.extent, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (
|
||||
/**
|
||||
* @param {ol.TileCoord} tileCoord Tile coordinate.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @param {ol.TileCoord=} opt_tileCoord Destination tile coordinate.
|
||||
* @return {ol.TileCoord} Tile coordinate.
|
||||
*/
|
||||
function(tileCoord, projection, opt_tileCoord) {
|
||||
var z = tileCoord[0];
|
||||
if (z < minZ || maxZ < z) {
|
||||
return null;
|
||||
}
|
||||
var n = Math.pow(2, z);
|
||||
var x = tileCoord[1];
|
||||
var y = tileCoord[2];
|
||||
if (y < -n || -1 < y) {
|
||||
return null;
|
||||
}
|
||||
if (!goog.isNull(tileRangeByZ)) {
|
||||
if (!tileRangeByZ[z].containsXY(x, y)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return ol.tilecoord.createOrUpdate(z, x, -y - 1, opt_tileCoord);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.tilegrid.XYZ.prototype.getTileCoordChildTileRange =
|
||||
function(tileCoord, opt_tileRange) {
|
||||
if (tileCoord[0] < this.maxZoom) {
|
||||
var doubleX = 2 * tileCoord[1];
|
||||
var doubleY = 2 * tileCoord[2];
|
||||
return ol.TileRange.createOrUpdate(
|
||||
doubleX, doubleX + 1,
|
||||
doubleY, doubleY + 1,
|
||||
opt_tileRange);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.tilegrid.XYZ.prototype.forEachTileCoordParentTileRange =
|
||||
function(tileCoord, callback, opt_this, opt_tileRange) {
|
||||
var tileRange = ol.TileRange.createOrUpdate(
|
||||
0, tileCoord[1], 0, tileCoord[2], opt_tileRange);
|
||||
var z;
|
||||
for (z = tileCoord[0] - 1; z >= this.minZoom; --z) {
|
||||
tileRange.minX = tileRange.maxX >>= 1;
|
||||
tileRange.minY = tileRange.maxY >>= 1;
|
||||
if (callback.call(opt_this, z, tileRange)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
@@ -19,61 +19,65 @@ goog.require('ol.tilegrid.TileGrid');
|
||||
*/
|
||||
ol.tilegrid.Zoomify = function(opt_options) {
|
||||
var options = goog.isDef(opt_options) ? opt_options : options;
|
||||
|
||||
/**
|
||||
* @param {{extent: (ol.Extent|undefined)}=} opt_options Options.
|
||||
* @return {function(ol.TileCoord, ol.proj.Projection, ol.TileCoord=):
|
||||
* ol.TileCoord} Tile coordinate transform.
|
||||
* @this {ol.tilegrid.Zoomify}
|
||||
*/
|
||||
var createTileCoordTransform = function(opt_options) {
|
||||
var options = goog.isDef(opt_options) ? opt_options : {};
|
||||
var minZ = this.minZoom;
|
||||
var maxZ = this.maxZoom;
|
||||
/** @type {Array.<ol.TileRange>} */
|
||||
var tileRangeByZ = null;
|
||||
if (goog.isDef(options.extent)) {
|
||||
tileRangeByZ = new Array(maxZ + 1);
|
||||
var z;
|
||||
for (z = 0; z <= maxZ; ++z) {
|
||||
if (z < minZ) {
|
||||
tileRangeByZ[z] = null;
|
||||
} else {
|
||||
tileRangeByZ[z] = this.getTileRangeForExtentAndZ(options.extent, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (
|
||||
/**
|
||||
* @param {ol.TileCoord} tileCoord Tile coordinate.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @param {ol.TileCoord=} opt_tileCoord Destination tile coordinate.
|
||||
* @return {ol.TileCoord} Tile coordinate.
|
||||
*/
|
||||
function(tileCoord, projection, opt_tileCoord) {
|
||||
var z = tileCoord[0];
|
||||
if (z < minZ || maxZ < z) {
|
||||
return null;
|
||||
}
|
||||
var n = Math.pow(2, z);
|
||||
var x = tileCoord[1];
|
||||
if (x < 0 || n <= x) {
|
||||
return null;
|
||||
}
|
||||
var y = tileCoord[2];
|
||||
if (y < -n || -1 < y) {
|
||||
return null;
|
||||
}
|
||||
if (!goog.isNull(tileRangeByZ)) {
|
||||
if (!tileRangeByZ[z].containsXY(x, -y - 1)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return ol.tilecoord.createOrUpdate(z, x, -y - 1, opt_tileCoord);
|
||||
});
|
||||
};
|
||||
|
||||
goog.base(this, {
|
||||
createTileCoordTransform: createTileCoordTransform,
|
||||
origin: [0, 0],
|
||||
resolutions: options.resolutions
|
||||
});
|
||||
|
||||
};
|
||||
goog.inherits(ol.tilegrid.Zoomify, ol.tilegrid.TileGrid);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.tilegrid.Zoomify.prototype.createTileCoordTransform = function(opt_options) {
|
||||
var options = goog.isDef(opt_options) ? opt_options : {};
|
||||
var minZ = this.minZoom;
|
||||
var maxZ = this.maxZoom;
|
||||
/** @type {Array.<ol.TileRange>} */
|
||||
var tileRangeByZ = null;
|
||||
if (goog.isDef(options.extent)) {
|
||||
tileRangeByZ = new Array(maxZ + 1);
|
||||
var z;
|
||||
for (z = 0; z <= maxZ; ++z) {
|
||||
if (z < minZ) {
|
||||
tileRangeByZ[z] = null;
|
||||
} else {
|
||||
tileRangeByZ[z] = this.getTileRangeForExtentAndZ(options.extent, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
return (
|
||||
/**
|
||||
* @param {ol.TileCoord} tileCoord Tile coordinate.
|
||||
* @param {ol.proj.Projection} projection Projection.
|
||||
* @param {ol.TileCoord=} opt_tileCoord Destination tile coordinate.
|
||||
* @return {ol.TileCoord} Tile coordinate.
|
||||
*/
|
||||
function(tileCoord, projection, opt_tileCoord) {
|
||||
var z = tileCoord[0];
|
||||
if (z < minZ || maxZ < z) {
|
||||
return null;
|
||||
}
|
||||
var n = Math.pow(2, z);
|
||||
var x = tileCoord[1];
|
||||
if (x < 0 || n <= x) {
|
||||
return null;
|
||||
}
|
||||
var y = tileCoord[2];
|
||||
if (y < -n || -1 < y) {
|
||||
return null;
|
||||
}
|
||||
if (!goog.isNull(tileRangeByZ)) {
|
||||
if (!tileRangeByZ[z].containsXY(x, -y - 1)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return ol.tilecoord.createOrUpdate(z, x, -y - 1, opt_tileCoord);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -14,6 +14,28 @@ goog.require('ol.tilecoord');
|
||||
* for the projection as arguments and returns a `{string}` or
|
||||
* undefined representing the tile URL.
|
||||
*
|
||||
* The {@link ol.TileCoord}'s `x` value
|
||||
* increases from left to right, `y` increases from bottom to top. At the
|
||||
* bottom left corner, `x` and `y` are `0`. To convert `y` to increase from
|
||||
* top to bottom, use the following code:
|
||||
* ```js
|
||||
* var tileGrid = new ol.tilegrid.TileGrid({
|
||||
* extent: extent,
|
||||
* resolutions: resolutions,
|
||||
* tileSize: tileSize
|
||||
* });
|
||||
*
|
||||
* function calculateY(tileCoord) {
|
||||
* var z = tileCoord[0];
|
||||
* var yFromBottom = tileCoord[2];
|
||||
* var resolution = tileGrid.getResolution(z);
|
||||
* var tileHeight = ol.size.toSize(tileSize)[1];
|
||||
* var matrixHeight =
|
||||
* Math.floor(ol.extent.getHeight(extent) / tileHeight / resolution);
|
||||
* return matrixHeight - yFromBottom - 1;
|
||||
* };
|
||||
* ```
|
||||
*
|
||||
* @typedef {function(ol.TileCoord, number,
|
||||
* ol.proj.Projection): (string|undefined)}
|
||||
* @api
|
||||
|
||||
@@ -5,6 +5,7 @@ var spawn = require('child_process').spawn;
|
||||
var async = require('async');
|
||||
var fse = require('fs-extra');
|
||||
var walk = require('walk').walk;
|
||||
var isWindows = process.platform.indexOf('win') === 0;
|
||||
|
||||
var sourceDir = path.join(__dirname, '..', 'src');
|
||||
var externsDir = path.join(__dirname, '..', 'externs');
|
||||
@@ -14,6 +15,12 @@ var externsPaths = [
|
||||
];
|
||||
var infoPath = path.join(__dirname, '..', 'build', 'info.json');
|
||||
var jsdoc = path.join(__dirname, '..', 'node_modules', '.bin', 'jsdoc');
|
||||
|
||||
// on Windows, use jsdoc.cmd
|
||||
if (isWindows) {
|
||||
jsdoc += '.cmd';
|
||||
}
|
||||
|
||||
var jsdocConfig = path.join(
|
||||
__dirname, '..', 'config', 'jsdoc', 'info', 'conf.json');
|
||||
|
||||
@@ -92,6 +99,17 @@ function getNewer(date, newer, callback) {
|
||||
callback(new Error('Trouble walking ' + sourceDir));
|
||||
});
|
||||
walker.on('end', function() {
|
||||
|
||||
/**
|
||||
* Windows has restrictions on length of command line, so passing all the
|
||||
* changed paths to a task will fail if this limit is exceeded.
|
||||
* To get round this, if this is Windows and there are newer files, just
|
||||
* pass the sourceDir to the task so it can do the walking.
|
||||
*/
|
||||
if (isWindows) {
|
||||
paths = [sourceDir].concat(externsPaths);
|
||||
}
|
||||
|
||||
callback(null, newer ? paths : []);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ var createServer = exports.createServer = function(callback) {
|
||||
manager.on('ready', function() {
|
||||
server = new closure.Server({
|
||||
manager: manager,
|
||||
loader: /^.*\/loader\.js/,
|
||||
loader: /^\/(?:(?:build\/examples)|(?:test(?:_rendering)?))\/loader\.js/,
|
||||
getMain: function(req) {
|
||||
var main;
|
||||
var query = url.parse(req.url, true).query;
|
||||
|
||||
@@ -3,6 +3,33 @@ goog.provide('ol.test.color');
|
||||
|
||||
describe('ol.color', function() {
|
||||
|
||||
describe('ol.color.blend', function() {
|
||||
it('blends red (a=1) and blue (a=1) to blue (a=1)', function() {
|
||||
var red = [255, 0, 0, 1];
|
||||
var blue = [0, 0, 255, 1];
|
||||
var blended = ol.color.blend(red, blue);
|
||||
expect(blended).to.eql([0, 0, 255, 1]);
|
||||
});
|
||||
it('blends red (a=1) and blue (a=0) to red (a=1)', function() {
|
||||
var red = [255, 0, 0, 1];
|
||||
var blue = [0, 0, 255, 0];
|
||||
var blended = ol.color.blend(red, blue);
|
||||
expect(blended).to.eql([255, 0, 0, 1]);
|
||||
});
|
||||
it('blends red (a=0.5) and blue (a=0.5) to purple (a=0.75)', function() {
|
||||
var red = [255, 0, 0, 0.5];
|
||||
var blue = [0, 0, 255, 0.5];
|
||||
var blended = ol.color.blend(red, blue);
|
||||
expect(blended).to.eql([85, 0, 170, 0.75]);
|
||||
});
|
||||
it('blends red (a=0.5) and blue (a=0) to red (a=0.5)', function() {
|
||||
var red = [255, 0, 0, 0.5];
|
||||
var blue = [0, 0, 255, 0];
|
||||
var blended = ol.color.blend(red, blue);
|
||||
expect(blended).to.eql([255, 0, 0, 0.5]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ol.color.fromString', function() {
|
||||
|
||||
before(function() {
|
||||
|
||||
1
test/spec/ol/data/tilejson.json
Normal file
1
test/spec/ol/data/tilejson.json
Normal file
File diff suppressed because one or more lines are too long
@@ -24,6 +24,267 @@ describe('ol.extent', function() {
|
||||
|
||||
});
|
||||
|
||||
describe('closestSquaredDistanceXY', function() {
|
||||
|
||||
it('returns correct result when x left of extent', function() {
|
||||
var extent = ol.extent.createOrUpdate(0, 0, 1, 1);
|
||||
var x = -2;
|
||||
var y = 0;
|
||||
expect(ol.extent.closestSquaredDistanceXY(extent, x, y)).to.be(4);
|
||||
});
|
||||
|
||||
it('returns correct result when x right of extent', function() {
|
||||
var extent = ol.extent.createOrUpdate(0, 0, 1, 1);
|
||||
var x = 3;
|
||||
var y = 0;
|
||||
expect(ol.extent.closestSquaredDistanceXY(extent, x, y)).to.be(4);
|
||||
});
|
||||
|
||||
it('returns correct result for other x values', function() {
|
||||
var extent = ol.extent.createOrUpdate(0, 0, 1, 1);
|
||||
var x = 0.5;
|
||||
var y = 3;
|
||||
expect(ol.extent.closestSquaredDistanceXY(extent, x, y)).to.be(4);
|
||||
});
|
||||
|
||||
it('returns correct result when y below extent', function() {
|
||||
var extent = ol.extent.createOrUpdate(0, 0, 1, 1);
|
||||
var x = 0;
|
||||
var y = -2;
|
||||
expect(ol.extent.closestSquaredDistanceXY(extent, x, y)).to.be(4);
|
||||
});
|
||||
|
||||
it('returns correct result when y above extent', function() {
|
||||
var extent = ol.extent.createOrUpdate(0, 0, 1, 1);
|
||||
var x = 0;
|
||||
var y = 3;
|
||||
expect(ol.extent.closestSquaredDistanceXY(extent, x, y)).to.be(4);
|
||||
});
|
||||
|
||||
it('returns correct result for other y values', function() {
|
||||
var extent = ol.extent.createOrUpdate(0, 0, 1, 1);
|
||||
var x = 3;
|
||||
var y = 0.5;
|
||||
expect(ol.extent.closestSquaredDistanceXY(extent, x, y)).to.be(4);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('createOrUpdateFromCoordinate', function() {
|
||||
|
||||
it('works when no extent passed', function() {
|
||||
var coords = [0, 1];
|
||||
var expected = [0, 1, 0, 1];
|
||||
var got = ol.extent.createOrUpdateFromCoordinate(coords);
|
||||
expect(got).to.eql(expected);
|
||||
});
|
||||
|
||||
it('updates a passed extent', function() {
|
||||
var extent = ol.extent.createOrUpdate(-4, -7, -3, -6);
|
||||
var coords = [0, 1];
|
||||
var expected = [0, 1, 0, 1];
|
||||
ol.extent.createOrUpdateFromCoordinate(coords, extent);
|
||||
expect(extent).to.eql(expected);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('createOrUpdateFromCoordinates', function() {
|
||||
|
||||
it('works when single coordinate and no extent passed', function() {
|
||||
var coords = [[0, 1]];
|
||||
var expected = [0, 1, 0, 1];
|
||||
var got = ol.extent.createOrUpdateFromCoordinates(coords);
|
||||
expect(got).to.eql(expected);
|
||||
});
|
||||
|
||||
it('changes the passed extent when single coordinate', function() {
|
||||
var extent = ol.extent.createOrUpdate(-4, -7, -3, -6);
|
||||
var coords = [[0, 1]];
|
||||
var expected = [0, 1, 0, 1];
|
||||
ol.extent.createOrUpdateFromCoordinates(coords, extent);
|
||||
expect(extent).to.eql(expected);
|
||||
});
|
||||
|
||||
it('works when multiple coordinates and no extent passed', function() {
|
||||
var coords = [[0, 1], [2, 3]];
|
||||
var expected = [0, 1, 2, 3];
|
||||
var got = ol.extent.createOrUpdateFromCoordinates(coords);
|
||||
expect(got).to.eql(expected);
|
||||
});
|
||||
|
||||
it('changes the passed extent when multiple coordinates given', function() {
|
||||
var extent = ol.extent.createOrUpdate(-4, -7, -3, -6);
|
||||
var coords = [[0, 1], [-2, -1]];
|
||||
var expected = [-2, -1, 0, 1];
|
||||
ol.extent.createOrUpdateFromCoordinates(coords, extent);
|
||||
expect(extent).to.eql(expected);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('createOrUpdateFromRings', function() {
|
||||
|
||||
it('works when single ring and no extent passed', function() {
|
||||
var ring = [[0, 0], [0, 2], [2, 2], [2, 0], [0, 0]];
|
||||
var rings = [ring];
|
||||
var expected = [0, 0, 2, 2];
|
||||
var got = ol.extent.createOrUpdateFromRings(rings);
|
||||
expect(got).to.eql(expected);
|
||||
});
|
||||
|
||||
it('changes the passed extent when single ring given', function() {
|
||||
var ring = [[0, 0], [0, 2], [2, 2], [2, 0], [0, 0]];
|
||||
var rings = [ring];
|
||||
var extent = [1, 1, 4, 7];
|
||||
var expected = [0, 0, 2, 2];
|
||||
ol.extent.createOrUpdateFromRings(rings, extent);
|
||||
expect(extent).to.eql(expected);
|
||||
});
|
||||
|
||||
it('works when multiple rings and no extent passed', function() {
|
||||
var ring1 = [[0, 0], [0, 2], [2, 2], [2, 0], [0, 0]];
|
||||
var ring2 = [[1, 1], [1, 3], [3, 3], [3, 1], [1, 1]];
|
||||
var rings = [ring1, ring2];
|
||||
var expected = [0, 0, 3, 3];
|
||||
var got = ol.extent.createOrUpdateFromRings(rings);
|
||||
expect(got).to.eql(expected);
|
||||
});
|
||||
|
||||
it('changes the passed extent when multiple rings given', function() {
|
||||
var ring1 = [[0, 0], [0, 2], [2, 2], [2, 0], [0, 0]];
|
||||
var ring2 = [[1, 1], [1, 3], [3, 3], [3, 1], [1, 1]];
|
||||
var rings = [ring1, ring2];
|
||||
var extent = [1, 1, 4, 7];
|
||||
var expected = [0, 0, 3, 3];
|
||||
ol.extent.createOrUpdateFromRings(rings, extent);
|
||||
expect(extent).to.eql(expected);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
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;
|
||||
var callbackTrue;
|
||||
beforeEach(function() {
|
||||
callbackFalse = sinon.spy(function() {
|
||||
return false;
|
||||
});
|
||||
callbackTrue = sinon.spy(function() {
|
||||
return true;
|
||||
});
|
||||
});
|
||||
|
||||
it('calls the passed callback for each corner', function() {
|
||||
var extent = [1, 2, 3, 4];
|
||||
ol.extent.forEachCorner(extent, callbackFalse);
|
||||
expect(callbackFalse.callCount).to.be(4);
|
||||
});
|
||||
|
||||
it('calls the passed callback with each corner', function() {
|
||||
var extent = [1, 2, 3, 4];
|
||||
ol.extent.forEachCorner(extent, callbackFalse);
|
||||
var firstCallFirstArg = callbackFalse.args[0][0];
|
||||
var secondCallFirstArg = callbackFalse.args[1][0];
|
||||
var thirdCallFirstArg = callbackFalse.args[2][0];
|
||||
var fourthCallFirstArg = callbackFalse.args[3][0];
|
||||
expect(firstCallFirstArg).to.eql([1, 2]); // bl
|
||||
expect(secondCallFirstArg).to.eql([3, 2]); // br
|
||||
expect(thirdCallFirstArg).to.eql([3, 4]); // tr
|
||||
expect(fourthCallFirstArg).to.eql([1, 4]); // tl
|
||||
});
|
||||
|
||||
it('calls a truthy callback only once', function() {
|
||||
var extent = [1, 2, 3, 4];
|
||||
ol.extent.forEachCorner(extent, callbackTrue);
|
||||
expect(callbackTrue.callCount).to.be(1);
|
||||
});
|
||||
|
||||
it('ensures that any corner can cancel the callback execution', function() {
|
||||
var extent = [1, 2, 3, 4];
|
||||
var bottomLeftSpy = sinon.spy(function(corner) {
|
||||
return (corner[0] === 1 && corner[1] === 2) ? true : false;
|
||||
});
|
||||
var bottomRightSpy = sinon.spy(function(corner) {
|
||||
return (corner[0] === 3 && corner[1] === 2) ? true : false;
|
||||
});
|
||||
var topRightSpy = sinon.spy(function(corner) {
|
||||
return (corner[0] === 3 && corner[1] === 4) ? true : false;
|
||||
});
|
||||
var topLeftSpy = sinon.spy(function(corner) {
|
||||
return (corner[0] === 1 && corner[1] === 4) ? true : false;
|
||||
});
|
||||
|
||||
ol.extent.forEachCorner(extent, bottomLeftSpy);
|
||||
ol.extent.forEachCorner(extent, bottomRightSpy);
|
||||
ol.extent.forEachCorner(extent, topRightSpy);
|
||||
ol.extent.forEachCorner(extent, topLeftSpy);
|
||||
|
||||
expect(bottomLeftSpy.callCount).to.be(1);
|
||||
expect(bottomRightSpy.callCount).to.be(2);
|
||||
expect(topRightSpy.callCount).to.be(3);
|
||||
expect(topLeftSpy.callCount).to.be(4);
|
||||
});
|
||||
|
||||
it('returns false eventually, if no invocation returned a truthy value',
|
||||
function() {
|
||||
var extent = [1, 2, 3, 4];
|
||||
var spy = sinon.spy(); // will return undefined for each corner
|
||||
var got = ol.extent.forEachCorner(extent, spy);
|
||||
expect(spy.callCount).to.be(4);
|
||||
expect(got).to.be(false);
|
||||
}
|
||||
);
|
||||
|
||||
it('calls the callback with given scope', function() {
|
||||
var extent = [1, 2, 3, 4];
|
||||
var scope = {humpty: 'dumpty'};
|
||||
ol.extent.forEachCorner(extent, callbackTrue, scope);
|
||||
expect(callbackTrue.calledOn(scope)).to.be(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('getArea', function() {
|
||||
it('returns zero for empty extents', function() {
|
||||
var emptyExtent = ol.extent.createEmpty();
|
||||
var areaEmpty = ol.extent.getArea(emptyExtent);
|
||||
expect(areaEmpty).to.be(0);
|
||||
|
||||
var extentDeltaXZero = [45, 67, 45, 78];
|
||||
var areaDeltaXZero = ol.extent.getArea(extentDeltaXZero);
|
||||
expect(areaDeltaXZero).to.be(0);
|
||||
|
||||
var extentDeltaYZero = [11, 67, 45, 67];
|
||||
var areaDeltaYZero = ol.extent.getArea(extentDeltaYZero);
|
||||
expect(areaDeltaYZero).to.be(0);
|
||||
});
|
||||
it('calculates correct area for other extents', function() {
|
||||
var extent = [0, 0, 10, 10];
|
||||
var area = ol.extent.getArea(extent);
|
||||
expect(area).to.be(100);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getIntersection()', function() {
|
||||
it('returns the intersection of two extents', function() {
|
||||
var world = [-180, -90, 180, 90];
|
||||
@@ -175,6 +436,12 @@ describe('ol.extent', function() {
|
||||
expect(center[0]).to.eql(2);
|
||||
expect(center[1]).to.eql(3);
|
||||
});
|
||||
it('returns [NaN, NaN] for empty extents', function() {
|
||||
var extent = ol.extent.createEmpty();
|
||||
var center = ol.extent.getCenter(extent);
|
||||
expect('' + center[0]).to.be('NaN');
|
||||
expect('' + center[1]).to.be('NaN');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getCorner', function() {
|
||||
@@ -200,6 +467,21 @@ describe('ol.extent', function() {
|
||||
expect(ol.extent.getCorner(extent, corner)).to.eql([3, 4]);
|
||||
});
|
||||
|
||||
it('throws exception for unexpected corner', function() {
|
||||
expect(function() {
|
||||
ol.extent.getCorner(extent, 'foobar');
|
||||
}).to.throwException();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('getEnlargedArea', function() {
|
||||
it('returns enlarged area of two extents', function() {
|
||||
var extent1 = [-1, -1, 0, 0];
|
||||
var extent2 = [0, 0, 1, 1];
|
||||
var enlargedArea = ol.extent.getEnlargedArea(extent1, extent2);
|
||||
expect(enlargedArea).to.be(4);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getForViewAndSize', function() {
|
||||
@@ -259,6 +541,28 @@ describe('ol.extent', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getIntersectionArea', function() {
|
||||
it('returns correct area when extents intersect', function() {
|
||||
var extent1 = [0, 0, 2, 2];
|
||||
var extent2 = [1, 1, 3, 3];
|
||||
var intersectionArea = ol.extent.getIntersectionArea(extent1, extent2);
|
||||
expect(intersectionArea).to.be(1);
|
||||
});
|
||||
it('returns 0 when extents do not intersect', function() {
|
||||
var extent1 = [0, 0, 1, 1];
|
||||
var extent2 = [2, 2, 3, 3];
|
||||
var intersectionArea = ol.extent.getIntersectionArea(extent1, extent2);
|
||||
expect(intersectionArea).to.be(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getMargin', function() {
|
||||
it('returns the correct margin (sum of width and height)', function() {
|
||||
var extent = [1, 2, 3, 4];
|
||||
expect(ol.extent.getMargin(extent)).to.be(4);
|
||||
});
|
||||
});
|
||||
|
||||
describe('intersects', function() {
|
||||
|
||||
it('returns the expected value', function() {
|
||||
@@ -294,6 +598,29 @@ 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() {
|
||||
|
||||
@@ -369,6 +369,63 @@ describe('ol.format.WKT', function() {
|
||||
expect(format.writeFeatures(features)).to.eql(wkt);
|
||||
});
|
||||
|
||||
describe('scientific notation supported', function() {
|
||||
|
||||
it('handles scientific notation correctly', function() {
|
||||
var wkt = 'POINT(3e1 1e1)';
|
||||
var geom = format.readGeometry(wkt);
|
||||
expect(geom.getCoordinates()).to.eql([30, 10]);
|
||||
expect(format.writeGeometry(geom)).to.eql('POINT(30 10)');
|
||||
});
|
||||
|
||||
it('works with with negative exponent', function() {
|
||||
var wkt = 'POINT(3e-1 1e-1)';
|
||||
var geom = format.readGeometry(wkt);
|
||||
expect(geom.getCoordinates()).to.eql([0.3, 0.1]);
|
||||
expect(format.writeGeometry(geom)).to.eql('POINT(0.3 0.1)');
|
||||
});
|
||||
|
||||
it('works with with explicitly positive exponent', function() {
|
||||
var wkt = 'POINT(3e+1 1e+1)';
|
||||
var geom = format.readGeometry(wkt);
|
||||
expect(geom.getCoordinates()).to.eql([30, 10]);
|
||||
expect(format.writeGeometry(geom)).to.eql('POINT(30 10)');
|
||||
});
|
||||
|
||||
it('handles very small numbers in scientific notation', function() {
|
||||
// very small numbers keep the scientific notation, both when reading and
|
||||
// writing
|
||||
var wkt = 'POINT(3e-9 1e-9)';
|
||||
var geom = format.readGeometry(wkt);
|
||||
expect(geom.getCoordinates()).to.eql([3e-9, 1e-9]);
|
||||
expect(format.writeGeometry(geom)).to.eql('POINT(3e-9 1e-9)');
|
||||
});
|
||||
|
||||
it('handles very big numbers in scientific notation', function() {
|
||||
// very big numbers keep the scientific notation, both when reading and
|
||||
// writing
|
||||
var wkt = 'POINT(3e25 1e25)';
|
||||
var geom = format.readGeometry(wkt);
|
||||
expect(geom.getCoordinates()).to.eql([3e25, 1e25]);
|
||||
expect(format.writeGeometry(geom)).to.eql('POINT(3e+25 1e+25)');
|
||||
});
|
||||
|
||||
it('works case insensitively (e / E)', function() {
|
||||
var wkt = 'POINT(3E1 1E1)';
|
||||
var geom = format.readGeometry(wkt);
|
||||
expect(geom.getCoordinates()).to.eql([30, 10]);
|
||||
expect(format.writeGeometry(geom)).to.eql('POINT(30 10)');
|
||||
});
|
||||
|
||||
it('detects invalid scientific notation', function() {
|
||||
expect(function() {
|
||||
// note the double 'e'
|
||||
format.readGeometry('POINT(3ee1 10)');
|
||||
}).to.throwException();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.Feature');
|
||||
|
||||
@@ -203,6 +203,73 @@ describe('ol.geom.Circle', function() {
|
||||
|
||||
});
|
||||
|
||||
describe('#intersectsExtent', function() {
|
||||
|
||||
it('returns false for non-intersecting extents (wide outside own bbox)',
|
||||
function() {
|
||||
var wideOutsideLeftTop = [-3, 2, -2, 3];
|
||||
var wideOutsideRightTop = [2, 2, 3, 3];
|
||||
var wideOutsideRightBottom = [2, -3, 3, -2];
|
||||
var wideOutsideLeftBottom = [-3, -3, -2, -2];
|
||||
expect(circle.intersectsExtent(wideOutsideLeftTop)).to.be(false);
|
||||
expect(circle.intersectsExtent(wideOutsideRightTop)).to.be(false);
|
||||
expect(circle.intersectsExtent(wideOutsideRightBottom)).to.be(false);
|
||||
expect(circle.intersectsExtent(wideOutsideLeftBottom)).to.be(false);
|
||||
}
|
||||
);
|
||||
|
||||
it('returns false for non-intersecting extents (inside own bbox)',
|
||||
function() {
|
||||
var nearOutsideLeftTop = [-1, 0.9, -0.9, 1];
|
||||
var nearOutsideRightTop = [0.9, 0.9, 1, 1];
|
||||
var nearOutsideRightBottom = [0.9, -1, 1, -0.9];
|
||||
var nearOutsideLeftBottom = [-1, -1, -0.9, -0.9];
|
||||
expect(circle.intersectsExtent(nearOutsideLeftTop)).to.be(false);
|
||||
expect(circle.intersectsExtent(nearOutsideRightTop)).to.be(false);
|
||||
expect(circle.intersectsExtent(nearOutsideRightBottom)).to.be(false);
|
||||
expect(circle.intersectsExtent(nearOutsideLeftBottom)).to.be(false);
|
||||
}
|
||||
);
|
||||
|
||||
it('returns true for extents that intersect clearly', function() {
|
||||
var intersectingLeftTop = [-1.5, 0.5, -0.5, 1.5];
|
||||
var intersectingRightTop = [0.5, 0.5, 1.5, 1.5];
|
||||
var intersectingRightBottom = [0.5, -1.5, 1.5, -0.5];
|
||||
var intersectingLeftBottom = [-1.5, -1.5, -0.5, -0.5];
|
||||
expect(circle.intersectsExtent(intersectingLeftTop)).to.be(true);
|
||||
expect(circle.intersectsExtent(intersectingRightTop)).to.be(true);
|
||||
expect(circle.intersectsExtent(intersectingRightBottom)).to.be(true);
|
||||
expect(circle.intersectsExtent(intersectingLeftBottom)).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true for extents that touch the circumference', function() {
|
||||
var touchCircumferenceLeft = [-2, 0, -1, 1];
|
||||
var touchCircumferenceTop = [0, 1, 1, 2];
|
||||
var touchCircumferenceRight = [1, -1, 2, 0];
|
||||
var touchCircumferenceBottom = [-1, -2, 0, -1];
|
||||
expect(circle.intersectsExtent(touchCircumferenceLeft)).to.be(true);
|
||||
expect(circle.intersectsExtent(touchCircumferenceTop)).to.be(true);
|
||||
expect(circle.intersectsExtent(touchCircumferenceRight)).to.be(true);
|
||||
expect(circle.intersectsExtent(touchCircumferenceBottom)).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true for a contained extent', function() {
|
||||
var containedExtent = [-0.5, -0.5, 0.5, 0.5];
|
||||
expect(circle.intersectsExtent(containedExtent)).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true for a covering extent', function() {
|
||||
var bigCoveringExtent = [-5, -5, 5, 5];
|
||||
expect(circle.intersectsExtent(bigCoveringExtent)).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true for the geom\'s own extent', function() {
|
||||
var circleExtent = circle.getExtent();
|
||||
expect(circle.intersectsExtent(circleExtent)).to.be(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
goog.provide('ol.test.geom.GeometryCollection');
|
||||
|
||||
goog.require('ol.extent');
|
||||
|
||||
describe('ol.geom.GeometryCollection', function() {
|
||||
|
||||
@@ -114,6 +115,35 @@ describe('ol.geom.GeometryCollection', function() {
|
||||
|
||||
});
|
||||
|
||||
describe('#intersectsExtent()', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
point = new ol.geom.Point([5, 20]);
|
||||
line = new ol.geom.LineString([[10, 20], [30, 40]]);
|
||||
poly = new ol.geom.Polygon([outer, inner1, inner2]);
|
||||
multi = new ol.geom.GeometryCollection([point, line, poly]);
|
||||
});
|
||||
|
||||
it('returns true for intersecting point', function() {
|
||||
expect(multi.intersectsExtent([5, 20, 5, 20])).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true for intersecting part of lineString', function() {
|
||||
expect(multi.intersectsExtent([25, 35, 30, 40])).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true for intersecting part of polygon', function() {
|
||||
expect(multi.intersectsExtent([0, 0, 5, 5])).to.be(true);
|
||||
});
|
||||
|
||||
|
||||
it('returns false for non-matching extent within own extent', function() {
|
||||
var extent = [0, 35, 5, 40];
|
||||
expect(poly.intersectsExtent(extent)).to.be(false);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#setGeometries', function() {
|
||||
|
||||
var line, multi, point, poly;
|
||||
|
||||
@@ -73,6 +73,22 @@ describe('ol.geom.LineString', function() {
|
||||
expect(lineString.getStride()).to.be(2);
|
||||
});
|
||||
|
||||
describe('#intersectsExtent', function() {
|
||||
|
||||
it('return false for non matching extent', function() {
|
||||
expect(lineString.intersectsExtent([1, 3, 1.9, 4])).to.be(false);
|
||||
});
|
||||
|
||||
it('return true for extent on midpoint', function() {
|
||||
expect(lineString.intersectsExtent([2, 3, 4, 3])).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true for the geom\'s own extent', function() {
|
||||
expect(lineString.intersectsExtent(lineString.getExtent())).to.be(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('construct with 3D coordinates', function() {
|
||||
@@ -102,6 +118,22 @@ describe('ol.geom.LineString', function() {
|
||||
expect(lineString.getStride()).to.be(3);
|
||||
});
|
||||
|
||||
describe('#intersectsExtent', function() {
|
||||
|
||||
it('return false for non matching extent', function() {
|
||||
expect(lineString.intersectsExtent([1, 3, 1.9, 4])).to.be(false);
|
||||
});
|
||||
|
||||
it('return true for extent on midpoint', function() {
|
||||
expect(lineString.intersectsExtent([2, 3, 4, 3])).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true for the geom\'s own extent', function() {
|
||||
expect(lineString.intersectsExtent(lineString.getExtent())).to.be(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('construct with 3D coordinates and layout XYM', function() {
|
||||
@@ -132,6 +164,22 @@ describe('ol.geom.LineString', function() {
|
||||
expect(lineString.getStride()).to.be(3);
|
||||
});
|
||||
|
||||
describe('#intersectsExtent', function() {
|
||||
|
||||
it('return false for non matching extent', function() {
|
||||
expect(lineString.intersectsExtent([1, 3, 1.9, 4])).to.be(false);
|
||||
});
|
||||
|
||||
it('return true for extent on midpoint', function() {
|
||||
expect(lineString.intersectsExtent([2, 3, 4, 3])).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true for the geom\'s own extent', function() {
|
||||
expect(lineString.intersectsExtent(lineString.getExtent())).to.be(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('construct with 4D coordinates', function() {
|
||||
@@ -161,6 +209,22 @@ describe('ol.geom.LineString', function() {
|
||||
expect(lineString.getStride()).to.be(4);
|
||||
});
|
||||
|
||||
describe('#intersectsExtent', function() {
|
||||
|
||||
it('return false for non matching extent', function() {
|
||||
expect(lineString.intersectsExtent([1, 3, 1.9, 4])).to.be(false);
|
||||
});
|
||||
|
||||
it('return true for extent on midpoint', function() {
|
||||
expect(lineString.intersectsExtent([2, 3, 4, 3])).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true for the geom\'s own extent', function() {
|
||||
expect(lineString.intersectsExtent(lineString.getExtent())).to.be(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('with a simple line string', function() {
|
||||
|
||||
@@ -88,6 +88,18 @@ describe('ol.geom.MultiLineString', function() {
|
||||
|
||||
});
|
||||
|
||||
describe('#intersectsExtent()', function() {
|
||||
|
||||
it('returns true for intersecting part of lineString', function() {
|
||||
expect(multiLineString.intersectsExtent([1, 2, 2, 3])).to.be(true);
|
||||
});
|
||||
|
||||
it('returns false for non-matching extent within own extent', function() {
|
||||
expect(multiLineString.intersectsExtent([1, 7, 2, 8])).to.be(false);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('construct with 3D coordinates', function() {
|
||||
|
||||
@@ -73,6 +73,18 @@ describe('ol.geom.MultiPoint', function() {
|
||||
expect(multiPoint.getStride()).to.be(2);
|
||||
});
|
||||
|
||||
describe('#intersectsExtent()', function() {
|
||||
|
||||
it('returns true for extent covering a point', function() {
|
||||
expect(multiPoint.intersectsExtent([1, 2, 2, 2])).to.be(true);
|
||||
});
|
||||
|
||||
it('returns false for non-matching extent within own extent', function() {
|
||||
expect(multiPoint.intersectsExtent([2, 3, 2, 4])).to.be(false);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('construct with 3D coordinates', function() {
|
||||
|
||||
@@ -115,6 +115,14 @@ describe('ol.geom.MultiPolygon', function() {
|
||||
|
||||
});
|
||||
|
||||
describe('#getExtent()', function() {
|
||||
|
||||
it('returns expected result', function() {
|
||||
expect(multiPolygon.getExtent()).to.eql([0, 0, 5, 2]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getSimplifiedGeometry', function() {
|
||||
|
||||
it('returns the expected result', function() {
|
||||
@@ -127,6 +135,22 @@ describe('ol.geom.MultiPolygon', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#intersectsExtent()', function() {
|
||||
|
||||
it('returns true for extent of of each polygon', function() {
|
||||
var polygons = multiPolygon.getPolygons();
|
||||
for (var i = 0; i < polygons.length; i++) {
|
||||
expect(multiPolygon.intersectsExtent(
|
||||
polygons[i].getExtent())).to.be(true);
|
||||
}
|
||||
});
|
||||
|
||||
it('returns false for non-matching extent within own extent', function() {
|
||||
expect(multiPolygon.intersectsExtent([2.1, 0, 2.9, 2])).to.be(false);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -37,6 +37,14 @@ describe('ol.geom.Point', function() {
|
||||
expect(point.getStride()).to.be(2);
|
||||
});
|
||||
|
||||
it('does not intersect non matching extent', function() {
|
||||
expect(point.intersectsExtent([0, 0, 10, 0.5])).to.be(false);
|
||||
});
|
||||
|
||||
it('does intersect it\'s extent', function() {
|
||||
expect(point.intersectsExtent(point.getExtent())).to.be(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('construct with 3D coordinates and layout XYM', function() {
|
||||
@@ -66,6 +74,14 @@ describe('ol.geom.Point', function() {
|
||||
expect(point.getStride()).to.be(3);
|
||||
});
|
||||
|
||||
it('does not intersect non matching extent', function() {
|
||||
expect(point.intersectsExtent([0, 0, 10, 0.5])).to.be(false);
|
||||
});
|
||||
|
||||
it('does intersect it\'s extent', function() {
|
||||
expect(point.intersectsExtent(point.getExtent())).to.be(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('construct with 4D coordinates', function() {
|
||||
@@ -95,6 +111,14 @@ describe('ol.geom.Point', function() {
|
||||
expect(point.getStride()).to.be(4);
|
||||
});
|
||||
|
||||
it('does not intersect non matching extent', function() {
|
||||
expect(point.intersectsExtent([0, 0, 10, 0.5])).to.be(false);
|
||||
});
|
||||
|
||||
it('does intersect it\'s extent', function() {
|
||||
expect(point.intersectsExtent(point.getExtent())).to.be(true);
|
||||
});
|
||||
|
||||
describe('#getClosestPoint', function() {
|
||||
|
||||
it('preseves extra dimensions', function() {
|
||||
|
||||
@@ -215,6 +215,33 @@ describe('ol.geom.Polygon', function() {
|
||||
expect(polygon.containsCoordinate(insideInner)).to.be(false);
|
||||
});
|
||||
|
||||
describe('#intersectsExtent', function() {
|
||||
|
||||
it('does not intersect outside extent', function() {
|
||||
expect(polygon.intersectsExtent(
|
||||
ol.extent.boundingExtent([outsideOuter]))).to.be(false);
|
||||
});
|
||||
|
||||
it('does intersect inside extent', function() {
|
||||
expect(polygon.intersectsExtent(
|
||||
ol.extent.boundingExtent([inside]))).to.be(true);
|
||||
});
|
||||
|
||||
it('does intersect boundary extent', function() {
|
||||
var firstMidX = (outerRing[0][0] + outerRing[1][0]) / 2;
|
||||
var firstMidY = (outerRing[0][1] + outerRing[1][1]) / 2;
|
||||
|
||||
expect(polygon.intersectsExtent(ol.extent.boundingExtent([[firstMidX,
|
||||
firstMidY]]))).to.be(true);
|
||||
});
|
||||
|
||||
it('does not intersect extent fully contained by inner ring', function() {
|
||||
expect(polygon.intersectsExtent(
|
||||
ol.extent.boundingExtent([insideInner]))).to.be(false);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getOrientedFlatCoordinates', function() {
|
||||
|
||||
it('reverses the outer ring if necessary', function() {
|
||||
@@ -287,6 +314,33 @@ describe('ol.geom.Polygon', function() {
|
||||
expect(polygon.containsCoordinate(insideInner)).to.be(false);
|
||||
});
|
||||
|
||||
describe('#intersectsExtent', function() {
|
||||
|
||||
it('does not intersect outside extent', function() {
|
||||
expect(polygon.intersectsExtent(
|
||||
ol.extent.boundingExtent([outsideOuter]))).to.be(false);
|
||||
});
|
||||
|
||||
it('does intersect inside extent', function() {
|
||||
expect(polygon.intersectsExtent(
|
||||
ol.extent.boundingExtent([inside]))).to.be(true);
|
||||
});
|
||||
|
||||
it('does intersect boundary extent', function() {
|
||||
var firstMidX = (outerRing[0][0] + outerRing[1][0]) / 2;
|
||||
var firstMidY = (outerRing[0][1] + outerRing[1][1]) / 2;
|
||||
|
||||
expect(polygon.intersectsExtent(ol.extent.boundingExtent([[firstMidX,
|
||||
firstMidY]]))).to.be(true);
|
||||
});
|
||||
|
||||
it('does not intersect extent fully contained by inner ring', function() {
|
||||
expect(polygon.intersectsExtent(
|
||||
ol.extent.boundingExtent([insideInner]))).to.be(false);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getOrientedFlatCoordinates', function() {
|
||||
|
||||
it('reverses the outer ring if necessary', function() {
|
||||
@@ -367,6 +421,35 @@ describe('ol.geom.Polygon', function() {
|
||||
expect(polygon.containsCoordinate(insideInner2)).to.be(false);
|
||||
});
|
||||
|
||||
describe('#intersectsExtent', function() {
|
||||
|
||||
it('does not intersect outside extent', function() {
|
||||
expect(polygon.intersectsExtent(
|
||||
ol.extent.boundingExtent([outsideOuter]))).to.be(false);
|
||||
});
|
||||
|
||||
it('does intersect inside extent', function() {
|
||||
expect(polygon.intersectsExtent(
|
||||
ol.extent.boundingExtent([inside]))).to.be(true);
|
||||
});
|
||||
|
||||
it('does intersect boundary extent', function() {
|
||||
var firstMidX = (outerRing[0][0] + outerRing[1][0]) / 2;
|
||||
var firstMidY = (outerRing[0][1] + outerRing[1][1]) / 2;
|
||||
|
||||
expect(polygon.intersectsExtent(ol.extent.boundingExtent([[firstMidX,
|
||||
firstMidY]]))).to.be(true);
|
||||
});
|
||||
|
||||
it('does not intersect extent fully contained by inner ring', function() {
|
||||
expect(polygon.intersectsExtent(
|
||||
ol.extent.boundingExtent([insideInner1]))).to.be(false);
|
||||
expect(polygon.intersectsExtent(
|
||||
ol.extent.boundingExtent([insideInner2]))).to.be(false);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getOrientedFlatCoordinates', function() {
|
||||
|
||||
it('reverses the outer ring if necessary', function() {
|
||||
@@ -436,10 +519,44 @@ describe('ol.geom.Polygon', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('ol.geom.Polygon.fromCircle', function() {
|
||||
|
||||
it('creates a regular polygon', function() {
|
||||
var circle = new ol.geom.Circle([0, 0, 0], 1, ol.geom.GeometryLayout.XYZ);
|
||||
var polygon = ol.geom.Polygon.fromCircle(circle);
|
||||
var coordinates = polygon.getLinearRing(0).getCoordinates();
|
||||
expect(coordinates[0].length).to.eql(3);
|
||||
expect(coordinates[0][2]).to.eql(0);
|
||||
expect(coordinates[32]).to.eql(coordinates[0]);
|
||||
// east
|
||||
expect(coordinates[0][0]).to.roughlyEqual(1, 1e-9);
|
||||
expect(coordinates[0][1]).to.roughlyEqual(0, 1e-9);
|
||||
// south
|
||||
expect(coordinates[8][0]).to.roughlyEqual(0, 1e-9);
|
||||
expect(coordinates[8][1]).to.roughlyEqual(1, 1e-9);
|
||||
// west
|
||||
expect(coordinates[16][0]).to.roughlyEqual(-1, 1e-9);
|
||||
expect(coordinates[16][1]).to.roughlyEqual(0, 1e-9);
|
||||
// north
|
||||
expect(coordinates[24][0]).to.roughlyEqual(0, 1e-9);
|
||||
expect(coordinates[24][1]).to.roughlyEqual(-1, 1e-9);
|
||||
});
|
||||
|
||||
it('creates a regular polygon with custom sides and angle', function() {
|
||||
var circle = new ol.geom.Circle([0, 0], 1);
|
||||
var polygon = ol.geom.Polygon.fromCircle(circle, 4, Math.PI / 2);
|
||||
var coordinates = polygon.getLinearRing(0).getCoordinates();
|
||||
expect(coordinates[4]).to.eql(coordinates[0]);
|
||||
expect(coordinates[0][0]).to.roughlyEqual(0, 1e-9);
|
||||
expect(coordinates[0][1]).to.roughlyEqual(1, 1e-9);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.geom.Circle');
|
||||
goog.require('ol.geom.GeometryLayout');
|
||||
goog.require('ol.geom.LinearRing');
|
||||
goog.require('ol.geom.Polygon');
|
||||
|
||||
@@ -136,8 +136,8 @@ describe('ol.interaction.Draw', function() {
|
||||
it('triggers draw events', function() {
|
||||
var ds = sinon.spy();
|
||||
var de = sinon.spy();
|
||||
goog.events.listen(draw, ol.DrawEventType.DRAWSTART, ds);
|
||||
goog.events.listen(draw, ol.DrawEventType.DRAWEND, de);
|
||||
goog.events.listen(draw, ol.interaction.DrawEventType.DRAWSTART, ds);
|
||||
goog.events.listen(draw, ol.interaction.DrawEventType.DRAWEND, de);
|
||||
simulateEvent('pointermove', 10, 20);
|
||||
simulateEvent('pointerdown', 10, 20);
|
||||
simulateEvent('pointerup', 10, 20);
|
||||
@@ -151,11 +151,12 @@ describe('ol.interaction.Draw', function() {
|
||||
end: 0,
|
||||
addfeature: 0
|
||||
};
|
||||
goog.events.listen(draw, ol.DrawEventType.DRAWEND, function() {
|
||||
expect(receivedEvents.end).to.be(0);
|
||||
expect(receivedEvents.addfeature).to.be(0);
|
||||
++receivedEvents.end;
|
||||
});
|
||||
goog.events.listen(draw, ol.interaction.DrawEventType.DRAWEND,
|
||||
function() {
|
||||
expect(receivedEvents.end).to.be(0);
|
||||
expect(receivedEvents.addfeature).to.be(0);
|
||||
++receivedEvents.end;
|
||||
});
|
||||
source.on(ol.source.VectorEventType.ADDFEATURE, function() {
|
||||
expect(receivedEvents.end).to.be(1);
|
||||
expect(receivedEvents.addfeature).to.be(0);
|
||||
@@ -279,8 +280,8 @@ describe('ol.interaction.Draw', function() {
|
||||
it('triggers draw events', function() {
|
||||
var ds = sinon.spy();
|
||||
var de = sinon.spy();
|
||||
goog.events.listen(draw, ol.DrawEventType.DRAWSTART, ds);
|
||||
goog.events.listen(draw, ol.DrawEventType.DRAWEND, de);
|
||||
goog.events.listen(draw, ol.interaction.DrawEventType.DRAWSTART, ds);
|
||||
goog.events.listen(draw, ol.interaction.DrawEventType.DRAWEND, de);
|
||||
|
||||
// first point
|
||||
simulateEvent('pointermove', 10, 20);
|
||||
@@ -435,8 +436,8 @@ describe('ol.interaction.Draw', function() {
|
||||
it('triggers draw events', function() {
|
||||
var ds = sinon.spy();
|
||||
var de = sinon.spy();
|
||||
goog.events.listen(draw, ol.DrawEventType.DRAWSTART, ds);
|
||||
goog.events.listen(draw, ol.DrawEventType.DRAWEND, de);
|
||||
goog.events.listen(draw, ol.interaction.DrawEventType.DRAWSTART, ds);
|
||||
goog.events.listen(draw, ol.interaction.DrawEventType.DRAWEND, de);
|
||||
|
||||
// first point
|
||||
simulateEvent('pointermove', 10, 20);
|
||||
@@ -573,8 +574,8 @@ describe('ol.interaction.Draw', function() {
|
||||
it('triggers draw events', function() {
|
||||
var ds = sinon.spy();
|
||||
var de = sinon.spy();
|
||||
goog.events.listen(draw, ol.DrawEventType.DRAWSTART, ds);
|
||||
goog.events.listen(draw, ol.DrawEventType.DRAWEND, de);
|
||||
goog.events.listen(draw, ol.interaction.DrawEventType.DRAWSTART, ds);
|
||||
goog.events.listen(draw, ol.interaction.DrawEventType.DRAWEND, de);
|
||||
|
||||
// first point
|
||||
simulateEvent('pointermove', 10, 20);
|
||||
@@ -708,13 +709,42 @@ describe('ol.interaction.Draw', function() {
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('ol.interaction.Draw.createRegularPolygon', function() {
|
||||
it('creates a regular polygon in Circle mode', function() {
|
||||
var draw = new ol.interaction.Draw({
|
||||
source: source,
|
||||
type: ol.geom.GeometryType.CIRCLE,
|
||||
geometryFunction:
|
||||
ol.interaction.Draw.createRegularPolygon(4, Math.PI / 4)
|
||||
});
|
||||
map.addInteraction(draw);
|
||||
|
||||
// first point
|
||||
simulateEvent('pointermove', 0, 0);
|
||||
simulateEvent('pointerdown', 0, 0);
|
||||
simulateEvent('pointerup', 0, 0);
|
||||
|
||||
// finish on second point
|
||||
simulateEvent('pointermove', 20, 20);
|
||||
simulateEvent('pointerdown', 20, 20);
|
||||
simulateEvent('pointerup', 20, 20);
|
||||
|
||||
var features = source.getFeatures();
|
||||
var geometry = features[0].getGeometry();
|
||||
expect(geometry).to.be.a(ol.geom.Polygon);
|
||||
var coordinates = geometry.getCoordinates();
|
||||
expect(coordinates[0].length).to.eql(5);
|
||||
expect(coordinates[0][0][0]).to.roughlyEqual(20, 1e-9);
|
||||
expect(coordinates[0][0][1]).to.roughlyEqual(20, 1e-9);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
goog.require('goog.dispose');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.events.BrowserEvent');
|
||||
goog.require('goog.style');
|
||||
goog.require('ol.DrawEventType');
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.MapBrowserPointerEvent');
|
||||
goog.require('ol.View');
|
||||
@@ -727,6 +757,7 @@ goog.require('ol.geom.MultiPolygon');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.geom.Polygon');
|
||||
goog.require('ol.interaction.Draw');
|
||||
goog.require('ol.interaction.DrawEventType');
|
||||
goog.require('ol.interaction.Interaction');
|
||||
goog.require('ol.layer.Vector');
|
||||
goog.require('ol.pointer.PointerEvent');
|
||||
|
||||
78
test/spec/ol/source/tilejsonsource.test.js
Normal file
78
test/spec/ol/source/tilejsonsource.test.js
Normal file
@@ -0,0 +1,78 @@
|
||||
goog.provide('ol.test.source.TileJSON');
|
||||
|
||||
|
||||
describe('ol.source.TileJSON', function() {
|
||||
|
||||
describe('tileUrlFunction', function() {
|
||||
|
||||
var source, tileGrid;
|
||||
|
||||
beforeEach(function(done) {
|
||||
var googNetJsonp = goog.net.Jsonp;
|
||||
// mock goog.net.Jsonp (used in the ol.source.TileJSON constructor)
|
||||
goog.net.Jsonp = function() {
|
||||
this.send = function() {
|
||||
var callback = arguments[1];
|
||||
var client = new XMLHttpRequest();
|
||||
client.open('GET', 'spec/ol/data/tilejson.json', true);
|
||||
client.onload = function() {
|
||||
callback(JSON.parse(client.responseText));
|
||||
};
|
||||
client.send();
|
||||
};
|
||||
};
|
||||
source = new ol.source.TileJSON({
|
||||
url: 'http://api.tiles.mapbox.com/v3/mapbox.geography-class.jsonp'
|
||||
});
|
||||
goog.net.Jsonp = googNetJsonp;
|
||||
var key = source.on('change', function() {
|
||||
if (source.getState() === 'ready') {
|
||||
source.unByKey(key);
|
||||
tileGrid = source.getTileGrid();
|
||||
done();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('uses the correct tile coordinates', function() {
|
||||
|
||||
var coordinate = [829330.2064098881, 5933916.615134273];
|
||||
var regex = /\/([0-9]*\/[0-9]*\/[0-9]*)\.png$/;
|
||||
var tileUrl;
|
||||
|
||||
tileUrl = source.tileUrlFunction(
|
||||
tileGrid.getTileCoordForCoordAndZ(coordinate, 0));
|
||||
expect(tileUrl.match(regex)[1]).to.eql('0/0/0');
|
||||
|
||||
tileUrl = source.tileUrlFunction(
|
||||
tileGrid.getTileCoordForCoordAndZ(coordinate, 1));
|
||||
expect(tileUrl.match(regex)[1]).to.eql('1/1/0');
|
||||
|
||||
tileUrl = source.tileUrlFunction(
|
||||
tileGrid.getTileCoordForCoordAndZ(coordinate, 2));
|
||||
expect(tileUrl.match(regex)[1]).to.eql('2/2/1');
|
||||
|
||||
tileUrl = source.tileUrlFunction(
|
||||
tileGrid.getTileCoordForCoordAndZ(coordinate, 3));
|
||||
expect(tileUrl.match(regex)[1]).to.eql('3/4/2');
|
||||
|
||||
tileUrl = source.tileUrlFunction(
|
||||
tileGrid.getTileCoordForCoordAndZ(coordinate, 4));
|
||||
expect(tileUrl.match(regex)[1]).to.eql('4/8/5');
|
||||
|
||||
tileUrl = source.tileUrlFunction(
|
||||
tileGrid.getTileCoordForCoordAndZ(coordinate, 5));
|
||||
expect(tileUrl.match(regex)[1]).to.eql('5/16/11');
|
||||
|
||||
tileUrl = source.tileUrlFunction(
|
||||
tileGrid.getTileCoordForCoordAndZ(coordinate, 6));
|
||||
expect(tileUrl.match(regex)[1]).to.eql('6/33/22');
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('goog.net.Jsonp');
|
||||
goog.require('ol.source.TileJSON');
|
||||
@@ -115,22 +115,7 @@ describe('ol.source.Tile', function() {
|
||||
|
||||
});
|
||||
|
||||
describe('#getWrapXTileCoord()', function() {
|
||||
|
||||
it('returns the expected tile coordinate - {wrapX: undefined}', function() {
|
||||
var tileSource = new ol.source.Tile({
|
||||
projection: 'EPSG:3857'
|
||||
});
|
||||
|
||||
var tileCoord = tileSource.getWrapXTileCoord([6, -31, 22]);
|
||||
expect(tileCoord).to.eql([6, -31, 22]);
|
||||
|
||||
tileCoord = tileSource.getWrapXTileCoord([6, 33, 22]);
|
||||
expect(tileCoord).to.eql([6, 33, 22]);
|
||||
|
||||
tileCoord = tileSource.getWrapXTileCoord([6, 97, 22]);
|
||||
expect(tileCoord).to.eql([6, 97, 22]);
|
||||
});
|
||||
describe('#getTileCoordForTileUrlFunction()', function() {
|
||||
|
||||
it('returns the expected tile coordinate - {wrapX: true}', function() {
|
||||
var tileSource = new ol.source.Tile({
|
||||
@@ -138,13 +123,13 @@ describe('ol.source.Tile', function() {
|
||||
wrapX: true
|
||||
});
|
||||
|
||||
var tileCoord = tileSource.getWrapXTileCoord([6, -31, 22]);
|
||||
var tileCoord = tileSource.getTileCoordForTileUrlFunction([6, -31, 22]);
|
||||
expect(tileCoord).to.eql([6, 33, 22]);
|
||||
|
||||
tileCoord = tileSource.getWrapXTileCoord([6, 33, 22]);
|
||||
tileCoord = tileSource.getTileCoordForTileUrlFunction([6, 33, 22]);
|
||||
expect(tileCoord).to.eql([6, 33, 22]);
|
||||
|
||||
tileCoord = tileSource.getWrapXTileCoord([6, 97, 22]);
|
||||
tileCoord = tileSource.getTileCoordForTileUrlFunction([6, 97, 22]);
|
||||
expect(tileCoord).to.eql([6, 33, 22]);
|
||||
});
|
||||
|
||||
@@ -154,13 +139,13 @@ describe('ol.source.Tile', function() {
|
||||
wrapX: false
|
||||
});
|
||||
|
||||
var tileCoord = tileSource.getWrapXTileCoord([6, -31, 22]);
|
||||
var tileCoord = tileSource.getTileCoordForTileUrlFunction([6, -31, 22]);
|
||||
expect(tileCoord).to.eql(null);
|
||||
|
||||
tileCoord = tileSource.getWrapXTileCoord([6, 33, 22]);
|
||||
tileCoord = tileSource.getTileCoordForTileUrlFunction([6, 33, 22]);
|
||||
expect(tileCoord).to.eql([6, 33, 22]);
|
||||
|
||||
tileCoord = tileSource.getWrapXTileCoord([6, 97, 22]);
|
||||
tileCoord = tileSource.getTileCoordForTileUrlFunction([6, 97, 22]);
|
||||
expect(tileCoord).to.eql(null);
|
||||
});
|
||||
});
|
||||
|
||||
35
test/spec/ol/source/tilevectorsource.test.js
Normal file
35
test/spec/ol/source/tilevectorsource.test.js
Normal file
@@ -0,0 +1,35 @@
|
||||
goog.provide('ol.test.source.TileVector');
|
||||
|
||||
|
||||
describe('ol.source.TileVector', function() {
|
||||
|
||||
describe('#loadFeatures()', function() {
|
||||
|
||||
it('calls tileUrlFunction with correct tile coords', function() {
|
||||
var tileCoords = [];
|
||||
var source = new ol.source.TileVector({
|
||||
format: new ol.format.TopoJSON(),
|
||||
projection: 'EPSG:3857',
|
||||
tileGrid: ol.tilegrid.createXYZ({
|
||||
maxZoom: 19
|
||||
}),
|
||||
tileUrlFunction: function(tileCoord) {
|
||||
tileCoords.push(tileCoord.slice());
|
||||
return null;
|
||||
}
|
||||
});
|
||||
source.loadFeatures(
|
||||
[-8238854, 4969777, -8237854, 4970777], 4.8, source.getProjection());
|
||||
expect(tileCoords[0]).to.eql([15, 9647, 12320]);
|
||||
expect(tileCoords[1]).to.eql([15, 9647, 12319]);
|
||||
expect(tileCoords[2]).to.eql([15, 9648, 12320]);
|
||||
expect(tileCoords[3]).to.eql([15, 9648, 12319]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
goog.require('ol.format.TopoJSON');
|
||||
goog.require('ol.source.TileVector');
|
||||
@@ -66,15 +66,18 @@ describe('ol.source.XYZ', function() {
|
||||
it('returns the expected URL', function() {
|
||||
var projection = xyzTileSource.getProjection();
|
||||
var tileUrl = xyzTileSource.tileUrlFunction(
|
||||
xyzTileSource.getWrapXTileCoord([6, -31, -23], projection));
|
||||
xyzTileSource.getTileCoordForTileUrlFunction(
|
||||
[6, -31, 41], projection));
|
||||
expect(tileUrl).to.eql('6/33/22');
|
||||
|
||||
tileUrl = xyzTileSource.tileUrlFunction(
|
||||
xyzTileSource.getWrapXTileCoord([6, 33, -23], projection));
|
||||
xyzTileSource.getTileCoordForTileUrlFunction(
|
||||
[6, 33, 41], projection));
|
||||
expect(tileUrl).to.eql('6/33/22');
|
||||
|
||||
tileUrl = xyzTileSource.tileUrlFunction(
|
||||
xyzTileSource.getWrapXTileCoord([6, 97, -23], projection));
|
||||
xyzTileSource.getTileCoordForTileUrlFunction(
|
||||
[6, 97, 41], projection));
|
||||
expect(tileUrl).to.eql('6/33/22');
|
||||
});
|
||||
|
||||
@@ -83,14 +86,20 @@ describe('ol.source.XYZ', function() {
|
||||
describe('crop y', function() {
|
||||
|
||||
it('returns the expected URL', function() {
|
||||
var projection = xyzTileSource.getProjection();
|
||||
var tileUrl = xyzTileSource.tileUrlFunction(
|
||||
[6, 33, -87]);
|
||||
xyzTileSource.getTileCoordForTileUrlFunction(
|
||||
[6, 33, 150], projection));
|
||||
expect(tileUrl).to.be(undefined);
|
||||
|
||||
tileUrl = xyzTileSource.tileUrlFunction([6, 33, -23]);
|
||||
tileUrl = xyzTileSource.tileUrlFunction(
|
||||
xyzTileSource.getTileCoordForTileUrlFunction(
|
||||
[6, 33, 41], projection));
|
||||
expect(tileUrl).to.eql('6/33/22');
|
||||
|
||||
tileUrl = xyzTileSource.tileUrlFunction([6, 33, 41]);
|
||||
tileUrl = xyzTileSource.tileUrlFunction(
|
||||
xyzTileSource.getTileCoordForTileUrlFunction(
|
||||
[6, 33, -23], projection));
|
||||
expect(tileUrl).to.be(undefined);
|
||||
});
|
||||
|
||||
|
||||
@@ -46,7 +46,79 @@ describe('ol.TileCoord', function() {
|
||||
ol.tilecoord.hash(tileCoord2));
|
||||
});
|
||||
});
|
||||
|
||||
describe('restrictByExtentAndZ', function() {
|
||||
|
||||
it('restricts by z', function() {
|
||||
var tileGrid = new ol.tilegrid.TileGrid({
|
||||
extent: [10, 20, 30, 40],
|
||||
tileSize: 10,
|
||||
resolutions: [2, 1],
|
||||
minZoom: 1
|
||||
});
|
||||
expect(ol.tilecoord.restrictByExtentAndZ([0, 0, 0], tileGrid))
|
||||
.to.equal(null);
|
||||
expect(ol.tilecoord.restrictByExtentAndZ([1, 0, 0], tileGrid))
|
||||
.to.eql([1, 0, 0]);
|
||||
expect(ol.tilecoord.restrictByExtentAndZ([2, 0, 0], tileGrid))
|
||||
.to.equal(null);
|
||||
});
|
||||
|
||||
it('restricts by extent when extent defines tile ranges', function() {
|
||||
var tileGrid = new ol.tilegrid.TileGrid({
|
||||
extent: [10, 20, 30, 40],
|
||||
sizes: [[3, 3]],
|
||||
tileSize: 10,
|
||||
resolutions: [1]
|
||||
});
|
||||
expect(ol.tilecoord.restrictByExtentAndZ([0, 1, 1], tileGrid))
|
||||
.to.eql([0, 1, 1]);
|
||||
expect(ol.tilecoord.restrictByExtentAndZ([0, 2, 0], tileGrid))
|
||||
.to.equal(null);
|
||||
expect(ol.tilecoord.restrictByExtentAndZ([0, 0, 2], tileGrid))
|
||||
.to.equal(null);
|
||||
});
|
||||
|
||||
it('restricts by extent when sizes define tile ranges', function() {
|
||||
var tileGrid = new ol.tilegrid.TileGrid({
|
||||
origin: [10, 20],
|
||||
sizes: [[3, 3]],
|
||||
tileSize: 10,
|
||||
resolutions: [1]
|
||||
});
|
||||
expect(ol.tilecoord.restrictByExtentAndZ([0, 0, 0], tileGrid))
|
||||
.to.eql([0, 0, 0]);
|
||||
expect(ol.tilecoord.restrictByExtentAndZ([0, -1, 0], tileGrid))
|
||||
.to.equal(null);
|
||||
expect(ol.tilecoord.restrictByExtentAndZ([0, 0, -1], tileGrid))
|
||||
.to.equal(null);
|
||||
expect(ol.tilecoord.restrictByExtentAndZ([0, 2, 2], tileGrid))
|
||||
.to.eql([0, 2, 2]);
|
||||
expect(ol.tilecoord.restrictByExtentAndZ([0, 3, 0], tileGrid))
|
||||
.to.equal(null);
|
||||
expect(ol.tilecoord.restrictByExtentAndZ([0, 0, 3], tileGrid))
|
||||
.to.equal(null);
|
||||
});
|
||||
|
||||
it('does not restrict by extent with no extent or sizes', function() {
|
||||
var tileGrid = new ol.tilegrid.TileGrid({
|
||||
origin: [10, 20],
|
||||
tileSize: 10,
|
||||
resolutions: [1]
|
||||
});
|
||||
expect(ol.tilecoord.restrictByExtentAndZ([0, Infinity, 0], tileGrid))
|
||||
.to.eql([0, Infinity, 0]);
|
||||
expect(ol.tilecoord.restrictByExtentAndZ([0, 0, Infinity], tileGrid))
|
||||
.to.eql([0, 0, Infinity]);
|
||||
expect(ol.tilecoord.restrictByExtentAndZ([0, -Infinity, 0], tileGrid))
|
||||
.to.eql([0, -Infinity, 0]);
|
||||
expect(ol.tilecoord.restrictByExtentAndZ([0, 0, Infinity], tileGrid))
|
||||
.to.eql([0, 0, Infinity]);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
goog.require('ol.TileCoord');
|
||||
goog.require('ol.tilecoord');
|
||||
goog.require('ol.tilegrid.TileGrid');
|
||||
|
||||
@@ -150,6 +150,129 @@ describe('ol.tilegrid.TileGrid', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('create with extent exceeding tile ranges', function() {
|
||||
it('throws an exception', function() {
|
||||
expect(function() {
|
||||
return new ol.tilegrid.TileGrid({
|
||||
extent: [10, 20, 30, 40],
|
||||
sizes: [[1, 1]],
|
||||
tileSize: 10,
|
||||
resolutions: [1]
|
||||
});
|
||||
}).to.throwException();
|
||||
expect(function() {
|
||||
return new ol.tilegrid.TileGrid({
|
||||
extent: [10, 20, 30, 40],
|
||||
origin: [10, 40], // top-left origin
|
||||
sizes: [[3, 3]], // would have to be [[3, -3]] for this to not throw
|
||||
tileSize: 10,
|
||||
resolutions: [1]
|
||||
});
|
||||
}).to.throwException();
|
||||
});
|
||||
});
|
||||
|
||||
describe('create with origin', function() {
|
||||
var tileGrid;
|
||||
beforeEach(function() {
|
||||
tileGrid = new ol.tilegrid.TileGrid({
|
||||
origin: [10, 20],
|
||||
tileSize: 10,
|
||||
resolutions: [1]
|
||||
});
|
||||
});
|
||||
|
||||
it('returns the configured origin', function() {
|
||||
expect(tileGrid.getOrigin()).to.eql([10, 20]);
|
||||
});
|
||||
|
||||
it('returns null for an unknown extent', function() {
|
||||
expect(tileGrid.getExtent()).to.equal(null);
|
||||
});
|
||||
|
||||
it('returns null for an unknown full tile range', function() {
|
||||
expect(tileGrid.getFullTileRange(0)).to.equal(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('create with extent', function() {
|
||||
var tileGrid;
|
||||
beforeEach(function() {
|
||||
tileGrid = new ol.tilegrid.TileGrid({
|
||||
extent: [10, 20, 30, 40],
|
||||
tileSize: 10,
|
||||
resolutions: [1]
|
||||
});
|
||||
});
|
||||
|
||||
it('assumes bottom left corner of extent as origin', function() {
|
||||
expect(tileGrid.getOrigin()).to.eql([10, 20]);
|
||||
});
|
||||
|
||||
it('calculates full tile ranges from extent', function() {
|
||||
var fullTileRange = tileGrid.getFullTileRange(0);
|
||||
expect(fullTileRange.minX).to.equal(0);
|
||||
expect(fullTileRange.maxX).to.equal(1);
|
||||
expect(fullTileRange.minY).to.equal(0);
|
||||
expect(fullTileRange.maxY).to.equal(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('create with extent and sizes', function() {
|
||||
var tileGrid;
|
||||
beforeEach(function() {
|
||||
tileGrid = new ol.tilegrid.TileGrid({
|
||||
extent: [10, 20, 30, 40],
|
||||
sizes: [[3, 3]],
|
||||
tileSize: 10,
|
||||
resolutions: [1]
|
||||
});
|
||||
});
|
||||
|
||||
it('returns the configured extent', function() {
|
||||
expect(tileGrid.getExtent()).to.eql([10, 20, 30, 40]);
|
||||
});
|
||||
|
||||
it('calculates full tile ranges from sizes', function() {
|
||||
var fullTileRange = tileGrid.getFullTileRange(0);
|
||||
expect(fullTileRange.minX).to.equal(0);
|
||||
expect(fullTileRange.maxX).to.equal(2);
|
||||
expect(fullTileRange.minY).to.equal(0);
|
||||
expect(fullTileRange.maxY).to.equal(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('create with top-left origin and sizes', function() {
|
||||
var tileGrid;
|
||||
beforeEach(function() {
|
||||
tileGrid = new ol.tilegrid.TileGrid({
|
||||
origin: [10, 40],
|
||||
sizes: [[3, -3]],
|
||||
tileSize: 10,
|
||||
resolutions: [1]
|
||||
});
|
||||
});
|
||||
|
||||
it('calculates correct minX and maxX for negative heights', function() {
|
||||
var fullTileRange = tileGrid.getFullTileRange(0);
|
||||
expect(fullTileRange.minY).to.equal(-3);
|
||||
expect(fullTileRange.maxY).to.equal(-1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('create with extent and origin', function() {
|
||||
it('uses both origin and extent', function() {
|
||||
var tileGrid = new ol.tilegrid.TileGrid({
|
||||
origin: [0, 0],
|
||||
extent: [10, 20, 30, 40],
|
||||
tileSize: 10,
|
||||
resolutions: [1]
|
||||
});
|
||||
expect(tileGrid.getOrigin()).to.eql([0, 0]);
|
||||
expect(tileGrid.getExtent()).to.eql([10, 20, 30, 40]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createForExtent', function() {
|
||||
it('allows creation of tile grid from extent', function() {
|
||||
var extent = ol.extent.createOrUpdate(-100, -100, 100, 100);
|
||||
@@ -247,6 +370,104 @@ describe('ol.tilegrid.TileGrid', function() {
|
||||
|
||||
});
|
||||
|
||||
describe('createOriginTopLeftTileCoordTransform', function() {
|
||||
|
||||
it('transforms y to -y-1 for top-left origins', function() {
|
||||
var tileGrid = new ol.tilegrid.TileGrid({
|
||||
origin: [10, 40],
|
||||
sizes: [[2, -2], [4, -4]],
|
||||
resolutions: [1, 0.5],
|
||||
tileSize: 10
|
||||
});
|
||||
var transformFn =
|
||||
ol.tilegrid.createOriginTopLeftTileCoordTransform(tileGrid);
|
||||
expect(transformFn([0, 0, -2])).to.eql([0, 0, 1]);
|
||||
expect(transformFn([0, 0, -1])).to.eql([0, 0, 0]);
|
||||
expect(transformFn([1, 0, -4])).to.eql([1, 0, 3]);
|
||||
expect(transformFn([1, 0, -1])).to.eql([1, 0, 0]);
|
||||
});
|
||||
|
||||
it('transforms y to -y-1 when origin corner is not specified', function() {
|
||||
var tileGrid1 = new ol.tilegrid.TileGrid({
|
||||
origin: [10, 20],
|
||||
resolutions: [1, 0.5],
|
||||
tileSize: 10
|
||||
});
|
||||
var tileGrid = new ol.tilegrid.TileGrid({
|
||||
origin: [10, 40],
|
||||
resolutions: [1, 0.5],
|
||||
tileSize: 10
|
||||
});
|
||||
var transformFn1 =
|
||||
ol.tilegrid.createOriginTopLeftTileCoordTransform(tileGrid);
|
||||
var transformFn2 =
|
||||
ol.tilegrid.createOriginTopLeftTileCoordTransform(tileGrid1);
|
||||
expect(transformFn1([0, 0, -2])).to.eql([0, 0, 1]);
|
||||
expect(transformFn2([0, 0, -2])).to.eql([0, 0, 1]);
|
||||
expect(transformFn1([0, 0, -1])).to.eql([0, 0, 0]);
|
||||
expect(transformFn2([0, 0, -1])).to.eql([0, 0, 0]);
|
||||
expect(transformFn1([1, 0, -4])).to.eql([1, 0, 3]);
|
||||
expect(transformFn2([1, 0, -4])).to.eql([1, 0, 3]);
|
||||
expect(transformFn1([1, 0, -1])).to.eql([1, 0, 0]);
|
||||
expect(transformFn2([1, 0, -1])).to.eql([1, 0, 0]);
|
||||
});
|
||||
|
||||
it('transforms y to height-y-1 for bottom-left origins', function() {
|
||||
var tileGrid1 = new ol.tilegrid.TileGrid({
|
||||
extent: [10, 20, 30, 40],
|
||||
resolutions: [1, 0.5],
|
||||
tileSize: 10
|
||||
});
|
||||
var tileGrid2 = new ol.tilegrid.TileGrid({
|
||||
origin: [10, 20],
|
||||
sizes: [[2, 2], [4, 4]],
|
||||
resolutions: [1, 0.5],
|
||||
tileSize: 10
|
||||
});
|
||||
var transformFn1 =
|
||||
ol.tilegrid.createOriginTopLeftTileCoordTransform(tileGrid1);
|
||||
var transformFn2 =
|
||||
ol.tilegrid.createOriginTopLeftTileCoordTransform(tileGrid2);
|
||||
expect(tileGrid1.getFullTileRange(0).getHeight()).to.equal(2);
|
||||
expect(transformFn1([0, 0, 0])).to.eql([0, 0, 1]);
|
||||
expect(transformFn2([0, 0, 0])).to.eql([0, 0, 1]);
|
||||
expect(transformFn1([0, 0, 1])).to.eql([0, 0, 0]);
|
||||
expect(transformFn2([0, 0, 1])).to.eql([0, 0, 0]);
|
||||
expect(tileGrid1.getFullTileRange(1).getHeight()).to.equal(4);
|
||||
expect(transformFn1([1, 0, 0])).to.eql([1, 0, 3]);
|
||||
expect(transformFn2([1, 0, 0])).to.eql([1, 0, 3]);
|
||||
expect(transformFn1([1, 0, 3])).to.eql([1, 0, 0]);
|
||||
expect(transformFn2([1, 0, 3])).to.eql([1, 0, 0]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('createXYZ()', function() {
|
||||
|
||||
it('uses defaults', function() {
|
||||
var tileGrid = ol.tilegrid.createXYZ();
|
||||
expect(tileGrid.getExtent()).to.eql(
|
||||
ol.proj.get('EPSG:3857').getExtent());
|
||||
expect(tileGrid.getMinZoom()).to.equal(0);
|
||||
expect(tileGrid.getMaxZoom()).to.equal(ol.DEFAULT_MAX_ZOOM);
|
||||
expect(tileGrid.getTileSize()).to.equal(ol.DEFAULT_TILE_SIZE);
|
||||
});
|
||||
|
||||
it('respects configuration options', function() {
|
||||
var tileGrid = ol.tilegrid.createXYZ({
|
||||
extent: [10, 20, 30, 40],
|
||||
minZoom: 1,
|
||||
maxZoom: 2,
|
||||
tileSize: 128
|
||||
});
|
||||
expect(tileGrid.getExtent()).to.eql([10, 20, 30, 40]);
|
||||
expect(tileGrid.getMinZoom()).to.equal(1);
|
||||
expect(tileGrid.getMaxZoom()).to.equal(2);
|
||||
expect(tileGrid.getTileSize()).to.equal(128);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('getForProjection', function() {
|
||||
|
||||
it('gets the default tile grid for a projection', function() {
|
||||
@@ -269,7 +490,150 @@ describe('ol.tilegrid.TileGrid', function() {
|
||||
|
||||
});
|
||||
|
||||
describe('getTileCoordFromCoordAndZ', function() {
|
||||
describe('#getTileCoordChildTileRange()', function() {
|
||||
|
||||
var tileGrid;
|
||||
beforeEach(function() {
|
||||
tileGrid = ol.tilegrid.createForExtent(
|
||||
ol.proj.get('EPSG:3857').getExtent(), 22);
|
||||
});
|
||||
|
||||
it('returns the tile range for one zoom level deeper', function() {
|
||||
var range;
|
||||
|
||||
range = tileGrid.getTileCoordChildTileRange([0, 0, 0]);
|
||||
expect(range.minX).to.be(0);
|
||||
expect(range.maxX).to.be(1);
|
||||
expect(range.minY).to.be(0);
|
||||
expect(range.maxY).to.be(1);
|
||||
|
||||
range = tileGrid.getTileCoordChildTileRange([0, 1, 0]);
|
||||
expect(range.minX).to.be(2);
|
||||
expect(range.maxX).to.be(3);
|
||||
expect(range.minY).to.be(0);
|
||||
expect(range.maxY).to.be(1);
|
||||
|
||||
range = tileGrid.getTileCoordChildTileRange([0, 0, 1]);
|
||||
expect(range.minX).to.be(0);
|
||||
expect(range.maxX).to.be(1);
|
||||
expect(range.minY).to.be(2);
|
||||
expect(range.maxY).to.be(3);
|
||||
|
||||
range = tileGrid.getTileCoordChildTileRange([0, -1, 0]);
|
||||
expect(range.minX).to.be(-2);
|
||||
expect(range.maxX).to.be(-1);
|
||||
expect(range.minY).to.be(0);
|
||||
expect(range.maxY).to.be(1);
|
||||
|
||||
range = tileGrid.getTileCoordChildTileRange([0, 0, -1]);
|
||||
expect(range.minX).to.be(0);
|
||||
expect(range.maxX).to.be(1);
|
||||
expect(range.minY).to.be(-2);
|
||||
expect(range.maxY).to.be(-1);
|
||||
});
|
||||
|
||||
it('returns null for z > maxZoom', function() {
|
||||
var max = tileGrid.maxZoom;
|
||||
var range = tileGrid.getTileCoordChildTileRange([max + 1, 0, 0]);
|
||||
expect(range).to.be(null);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#forEachTileCoordParentTileRange()', function() {
|
||||
|
||||
var tileGrid;
|
||||
beforeEach(function() {
|
||||
tileGrid = ol.tilegrid.createForExtent(
|
||||
ol.proj.get('EPSG:3857').getExtent(), 22);
|
||||
});
|
||||
|
||||
it('iterates as expected', function() {
|
||||
|
||||
var tileCoord = [5, 11, 21];
|
||||
var zs = [], tileRanges = [];
|
||||
tileGrid.forEachTileCoordParentTileRange(
|
||||
tileCoord,
|
||||
function(z, tileRange) {
|
||||
zs.push(z);
|
||||
tileRanges.push(new ol.TileRange(
|
||||
tileRange.minX, tileRange.maxX,
|
||||
tileRange.minY, tileRange.maxY));
|
||||
return false;
|
||||
});
|
||||
|
||||
expect(zs.length).to.eql(5);
|
||||
expect(tileRanges.length).to.eql(5);
|
||||
|
||||
expect(zs[0]).to.eql(4);
|
||||
expect(tileRanges[0].minX).to.eql(5);
|
||||
expect(tileRanges[0].maxX).to.eql(5);
|
||||
expect(tileRanges[0].minY).to.eql(10);
|
||||
expect(tileRanges[0].maxY).to.eql(10);
|
||||
|
||||
expect(zs[1]).to.eql(3);
|
||||
expect(tileRanges[1].minX).to.eql(2);
|
||||
expect(tileRanges[1].maxX).to.eql(2);
|
||||
expect(tileRanges[1].minY).to.eql(5);
|
||||
expect(tileRanges[1].maxY).to.eql(5);
|
||||
|
||||
expect(zs[2]).to.eql(2);
|
||||
expect(tileRanges[2].minX).to.eql(1);
|
||||
expect(tileRanges[2].maxX).to.eql(1);
|
||||
expect(tileRanges[2].minY).to.eql(2);
|
||||
expect(tileRanges[2].maxY).to.eql(2);
|
||||
|
||||
expect(zs[3]).to.eql(1);
|
||||
expect(tileRanges[3].minX).to.eql(0);
|
||||
expect(tileRanges[3].maxX).to.eql(0);
|
||||
expect(tileRanges[3].minY).to.eql(1);
|
||||
expect(tileRanges[3].maxY).to.eql(1);
|
||||
|
||||
expect(zs[4]).to.eql(0);
|
||||
expect(tileRanges[4].minX).to.eql(0);
|
||||
expect(tileRanges[4].maxX).to.eql(0);
|
||||
expect(tileRanges[4].minY).to.eql(0);
|
||||
expect(tileRanges[4].maxY).to.eql(0);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('getResolution', function() {
|
||||
|
||||
var tileGrid;
|
||||
beforeEach(function() {
|
||||
tileGrid = ol.tilegrid.createForExtent(
|
||||
ol.proj.get('EPSG:3857').getExtent(), 22);
|
||||
});
|
||||
|
||||
it('returns the correct resolution at the equator', function() {
|
||||
// @see http://msdn.microsoft.com/en-us/library/aa940990.aspx
|
||||
expect(tileGrid.getResolution(0)).to.roughlyEqual(156543.04, 1e-2);
|
||||
expect(tileGrid.getResolution(1)).to.roughlyEqual(78271.52, 1e-2);
|
||||
expect(tileGrid.getResolution(2)).to.roughlyEqual(39135.76, 1e-2);
|
||||
expect(tileGrid.getResolution(3)).to.roughlyEqual(19567.88, 1e-2);
|
||||
expect(tileGrid.getResolution(4)).to.roughlyEqual(9783.94, 1e-2);
|
||||
expect(tileGrid.getResolution(5)).to.roughlyEqual(4891.97, 1e-2);
|
||||
expect(tileGrid.getResolution(6)).to.roughlyEqual(2445.98, 1e-2);
|
||||
expect(tileGrid.getResolution(7)).to.roughlyEqual(1222.99, 1e-2);
|
||||
expect(tileGrid.getResolution(8)).to.roughlyEqual(611.50, 1e-2);
|
||||
expect(tileGrid.getResolution(9)).to.roughlyEqual(305.75, 1e-2);
|
||||
expect(tileGrid.getResolution(10)).to.roughlyEqual(152.87, 1e-2);
|
||||
expect(tileGrid.getResolution(11)).to.roughlyEqual(76.44, 1e-2);
|
||||
expect(tileGrid.getResolution(12)).to.roughlyEqual(38.22, 1e-2);
|
||||
expect(tileGrid.getResolution(13)).to.roughlyEqual(19.11, 1e-2);
|
||||
expect(tileGrid.getResolution(14)).to.roughlyEqual(9.55, 1e-2);
|
||||
expect(tileGrid.getResolution(15)).to.roughlyEqual(4.78, 1e-2);
|
||||
expect(tileGrid.getResolution(16)).to.roughlyEqual(2.39, 1e-2);
|
||||
expect(tileGrid.getResolution(17)).to.roughlyEqual(1.19, 1e-2);
|
||||
expect(tileGrid.getResolution(18)).to.roughlyEqual(0.60, 1e-2);
|
||||
expect(tileGrid.getResolution(19)).to.roughlyEqual(0.30, 1e-2);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#getTileCoordFromCoordAndZ()', function() {
|
||||
|
||||
describe('Y North, X East', function() {
|
||||
it('returns the expected TileCoord', function() {
|
||||
@@ -696,7 +1060,7 @@ describe('ol.tilegrid.TileGrid', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getZForResolution (approcimate)', function() {
|
||||
describe('getZForResolution (approximate)', function() {
|
||||
it('returns the expected z value', function() {
|
||||
var tileGrid = new ol.tilegrid.TileGrid({
|
||||
resolutions: resolutions,
|
||||
@@ -731,4 +1095,5 @@ goog.require('ol.proj');
|
||||
goog.require('ol.proj.EPSG3857');
|
||||
goog.require('ol.proj.Projection');
|
||||
goog.require('ol.proj.Units');
|
||||
goog.require('ol.TileRange');
|
||||
goog.require('ol.tilegrid.TileGrid');
|
||||
|
||||
@@ -42,27 +42,17 @@ describe('ol.tilegrid.WMTS', function() {
|
||||
expect(tileGrid.origins_).to.be.an('array');
|
||||
expect(tileGrid.origins_).to.have.length(20);
|
||||
expect(tileGrid.origins_).to.eql(
|
||||
[[-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
|
||||
[-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
|
||||
[-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
|
||||
[-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
|
||||
[-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
|
||||
[-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
|
||||
[-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
|
||||
[-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
|
||||
[-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
|
||||
[-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428]
|
||||
]);
|
||||
goog.array.repeat([-20037508.3428, 20037508.3428], 20));
|
||||
|
||||
expect(tileGrid.tileSizes_).to.be.an('array');
|
||||
expect(tileGrid.tileSizes_).to.have.length(20);
|
||||
expect(tileGrid.tileSizes_).to.eql(
|
||||
[256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
|
||||
256, 256, 256, 256, 256, 256, 256, 256, 256, 256]);
|
||||
goog.array.repeat(256, 20));
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('ol.format.WMTSCapabilities');
|
||||
goog.require('ol.tilegrid.WMTS');
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
goog.provide('ol.test.tilegrid.XYZ');
|
||||
|
||||
|
||||
describe('ol.tilegrid.XYZ', function() {
|
||||
|
||||
var xyzTileGrid;
|
||||
beforeEach(function() {
|
||||
xyzTileGrid = new ol.tilegrid.XYZ({
|
||||
maxZoom: 22
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getTileCoordChildTileRange()', function() {
|
||||
|
||||
it('returns the tile range for one zoom level deeper', function() {
|
||||
var range;
|
||||
|
||||
range = xyzTileGrid.getTileCoordChildTileRange([0, 0, 0]);
|
||||
expect(range.minX).to.be(0);
|
||||
expect(range.maxX).to.be(1);
|
||||
expect(range.minY).to.be(0);
|
||||
expect(range.maxY).to.be(1);
|
||||
|
||||
range = xyzTileGrid.getTileCoordChildTileRange([0, 1, 0]);
|
||||
expect(range.minX).to.be(2);
|
||||
expect(range.maxX).to.be(3);
|
||||
expect(range.minY).to.be(0);
|
||||
expect(range.maxY).to.be(1);
|
||||
|
||||
range = xyzTileGrid.getTileCoordChildTileRange([0, 0, 1]);
|
||||
expect(range.minX).to.be(0);
|
||||
expect(range.maxX).to.be(1);
|
||||
expect(range.minY).to.be(2);
|
||||
expect(range.maxY).to.be(3);
|
||||
|
||||
range = xyzTileGrid.getTileCoordChildTileRange([0, -1, 0]);
|
||||
expect(range.minX).to.be(-2);
|
||||
expect(range.maxX).to.be(-1);
|
||||
expect(range.minY).to.be(0);
|
||||
expect(range.maxY).to.be(1);
|
||||
|
||||
range = xyzTileGrid.getTileCoordChildTileRange([0, 0, -1]);
|
||||
expect(range.minX).to.be(0);
|
||||
expect(range.maxX).to.be(1);
|
||||
expect(range.minY).to.be(-2);
|
||||
expect(range.maxY).to.be(-1);
|
||||
});
|
||||
|
||||
it('returns null for z > maxZoom', function() {
|
||||
var max = xyzTileGrid.maxZoom;
|
||||
var range = xyzTileGrid.getTileCoordChildTileRange([max + 1, 0, 0]);
|
||||
expect(range).to.be(null);
|
||||
});
|
||||
|
||||
it('is like ol.tilegrid.TileGrid#getTileCoordChildTileRange()', function() {
|
||||
var superMethod = ol.tilegrid.TileGrid.prototype
|
||||
.getTileCoordChildTileRange.bind(xyzTileGrid);
|
||||
|
||||
var coord, selfRange, superRange;
|
||||
|
||||
coord = [0, 0, 0];
|
||||
selfRange = xyzTileGrid.getTileCoordChildTileRange(coord);
|
||||
superRange = superMethod(coord);
|
||||
expect(selfRange.minX).to.be(superRange.minX);
|
||||
expect(selfRange.maxX).to.be(superRange.maxX);
|
||||
expect(selfRange.minY).to.be(superRange.minY);
|
||||
expect(selfRange.maxY).to.be(superRange.maxY);
|
||||
|
||||
coord = [1, 2, 3];
|
||||
selfRange = xyzTileGrid.getTileCoordChildTileRange(coord);
|
||||
superRange = superMethod(coord);
|
||||
expect(selfRange.minX).to.be(superRange.minX);
|
||||
expect(selfRange.maxX).to.be(superRange.maxX);
|
||||
expect(selfRange.minY).to.be(superRange.minY);
|
||||
expect(selfRange.maxY).to.be(superRange.maxY);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('forEachTileCoordParentTileRange', function() {
|
||||
|
||||
it('iterates as expected', function() {
|
||||
|
||||
var tileCoord = [5, 11, 21];
|
||||
var zs = [], tileRanges = [];
|
||||
xyzTileGrid.forEachTileCoordParentTileRange(
|
||||
tileCoord,
|
||||
function(z, tileRange) {
|
||||
zs.push(z);
|
||||
tileRanges.push(new ol.TileRange(
|
||||
tileRange.minX, tileRange.maxX,
|
||||
tileRange.minY, tileRange.maxY));
|
||||
return false;
|
||||
});
|
||||
|
||||
expect(zs.length).to.eql(5);
|
||||
expect(tileRanges.length).to.eql(5);
|
||||
|
||||
expect(zs[0]).to.eql(4);
|
||||
expect(tileRanges[0].minX).to.eql(5);
|
||||
expect(tileRanges[0].maxX).to.eql(5);
|
||||
expect(tileRanges[0].minY).to.eql(10);
|
||||
expect(tileRanges[0].maxY).to.eql(10);
|
||||
|
||||
expect(zs[1]).to.eql(3);
|
||||
expect(tileRanges[1].minX).to.eql(2);
|
||||
expect(tileRanges[1].maxX).to.eql(2);
|
||||
expect(tileRanges[1].minY).to.eql(5);
|
||||
expect(tileRanges[1].maxY).to.eql(5);
|
||||
|
||||
expect(zs[2]).to.eql(2);
|
||||
expect(tileRanges[2].minX).to.eql(1);
|
||||
expect(tileRanges[2].maxX).to.eql(1);
|
||||
expect(tileRanges[2].minY).to.eql(2);
|
||||
expect(tileRanges[2].maxY).to.eql(2);
|
||||
|
||||
expect(zs[3]).to.eql(1);
|
||||
expect(tileRanges[3].minX).to.eql(0);
|
||||
expect(tileRanges[3].maxX).to.eql(0);
|
||||
expect(tileRanges[3].minY).to.eql(1);
|
||||
expect(tileRanges[3].maxY).to.eql(1);
|
||||
|
||||
expect(zs[4]).to.eql(0);
|
||||
expect(tileRanges[4].minX).to.eql(0);
|
||||
expect(tileRanges[4].maxX).to.eql(0);
|
||||
expect(tileRanges[4].minY).to.eql(0);
|
||||
expect(tileRanges[4].maxY).to.eql(0);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('getResolution', function() {
|
||||
|
||||
it('returns the correct resolution at the equator', function() {
|
||||
// @see http://msdn.microsoft.com/en-us/library/aa940990.aspx
|
||||
expect(xyzTileGrid.getResolution(0)).to.roughlyEqual(156543.04, 1e-2);
|
||||
expect(xyzTileGrid.getResolution(1)).to.roughlyEqual(78271.52, 1e-2);
|
||||
expect(xyzTileGrid.getResolution(2)).to.roughlyEqual(39135.76, 1e-2);
|
||||
expect(xyzTileGrid.getResolution(3)).to.roughlyEqual(19567.88, 1e-2);
|
||||
expect(xyzTileGrid.getResolution(4)).to.roughlyEqual(9783.94, 1e-2);
|
||||
expect(xyzTileGrid.getResolution(5)).to.roughlyEqual(4891.97, 1e-2);
|
||||
expect(xyzTileGrid.getResolution(6)).to.roughlyEqual(2445.98, 1e-2);
|
||||
expect(xyzTileGrid.getResolution(7)).to.roughlyEqual(1222.99, 1e-2);
|
||||
expect(xyzTileGrid.getResolution(8)).to.roughlyEqual(611.50, 1e-2);
|
||||
expect(xyzTileGrid.getResolution(9)).to.roughlyEqual(305.75, 1e-2);
|
||||
expect(xyzTileGrid.getResolution(10)).to.roughlyEqual(152.87, 1e-2);
|
||||
expect(xyzTileGrid.getResolution(11)).to.roughlyEqual(76.44, 1e-2);
|
||||
expect(xyzTileGrid.getResolution(12)).to.roughlyEqual(38.22, 1e-2);
|
||||
expect(xyzTileGrid.getResolution(13)).to.roughlyEqual(19.11, 1e-2);
|
||||
expect(xyzTileGrid.getResolution(14)).to.roughlyEqual(9.55, 1e-2);
|
||||
expect(xyzTileGrid.getResolution(15)).to.roughlyEqual(4.78, 1e-2);
|
||||
expect(xyzTileGrid.getResolution(16)).to.roughlyEqual(2.39, 1e-2);
|
||||
expect(xyzTileGrid.getResolution(17)).to.roughlyEqual(1.19, 1e-2);
|
||||
expect(xyzTileGrid.getResolution(18)).to.roughlyEqual(0.60, 1e-2);
|
||||
expect(xyzTileGrid.getResolution(19)).to.roughlyEqual(0.30, 1e-2);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
goog.require('ol.TileCoord');
|
||||
goog.require('ol.TileRange');
|
||||
goog.require('ol.tilegrid.TileGrid');
|
||||
goog.require('ol.tilegrid.XYZ');
|
||||
@@ -55,8 +55,8 @@ describe('ol.rendering.layer.Image', function() {
|
||||
beforeEach(function() {
|
||||
source = new ol.source.ImageStatic({
|
||||
url: 'spec/ol/data/tiles/osm/5/5/12.png',
|
||||
imageExtent: new ol.tilegrid.XYZ({}).getTileCoordExtent(
|
||||
[5, 5, -12 - 1]),
|
||||
imageExtent: ol.tilegrid.createXYZ().getTileCoordExtent(
|
||||
[5, 5, 32 - 12 - 1]),
|
||||
projection: ol.proj.get('EPSG:3857')
|
||||
});
|
||||
});
|
||||
@@ -91,4 +91,3 @@ goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.layer.Image');
|
||||
goog.require('ol.source.ImageStatic');
|
||||
goog.require('ol.tilegrid.XYZ');
|
||||
|
||||
Reference in New Issue
Block a user