Compare commits
328 Commits
v4.1.1
...
v4.3.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1cf01037aa | ||
|
|
89ec2dacad | ||
|
|
b97439cf8e | ||
|
|
b7b2ee0c57 | ||
|
|
fe39b5da1b | ||
|
|
bc0bc3f8a9 | ||
|
|
9c0d0c5681 | ||
|
|
b97daf844b | ||
|
|
f8237c9cd2 | ||
|
|
b317a4474e | ||
|
|
b1772dae44 | ||
|
|
c33383d248 | ||
|
|
645e359cde | ||
|
|
fa71593a2a | ||
|
|
2e903c0293 | ||
|
|
aced192bcd | ||
|
|
19b0b956f7 | ||
|
|
9f9355ac46 | ||
|
|
f28e6c2d95 | ||
|
|
e633380221 | ||
|
|
5f6f757bd0 | ||
|
|
b29fc52842 | ||
|
|
791ffaabeb | ||
|
|
c31d67fe57 | ||
|
|
a1710be335 | ||
|
|
2260d92436 | ||
|
|
4d0e106d98 | ||
|
|
8bc4bde5c3 | ||
|
|
429e2982d0 | ||
|
|
23f8540b4c | ||
|
|
59d8d749e3 | ||
|
|
cff9ef5e63 | ||
|
|
e6e0109a1b | ||
|
|
7739239e89 | ||
|
|
eb8d5bcade | ||
|
|
ff242ef28c | ||
|
|
4a0f97ac6a | ||
|
|
a0e0e76995 | ||
|
|
b5f9b88d0e | ||
|
|
339f048826 | ||
|
|
4f0bfbc1db | ||
|
|
db63cc1b23 | ||
|
|
f88d8b8a7d | ||
|
|
991328904d | ||
|
|
9d3539b3cb | ||
|
|
bd143c0ad1 | ||
|
|
970265acb0 | ||
|
|
36c80f61bc | ||
|
|
d86c7c22dc | ||
|
|
71b334d49c | ||
|
|
ee0eb8b1a0 | ||
|
|
cd4ed759ed | ||
|
|
c0e4da6d8c | ||
|
|
72f5ff917f | ||
|
|
4c9c9fa719 | ||
|
|
163e01a2dc | ||
|
|
79862ca8c2 | ||
|
|
aa8d7b0b36 | ||
|
|
8d0857fd7a | ||
|
|
67f69a32bb | ||
|
|
382674975e | ||
|
|
eaaa895b0a | ||
|
|
70b971d3a4 | ||
|
|
3ddb8712a3 | ||
|
|
533ca8b9fe | ||
|
|
0fc710bc48 | ||
|
|
fe18636ff9 | ||
|
|
c299bfcd0f | ||
|
|
3f5a6bca26 | ||
|
|
a6b35e7d8a | ||
|
|
619e85e737 | ||
|
|
b3407b0554 | ||
|
|
a4c421e699 | ||
|
|
a3a443324d | ||
|
|
7b9833fdce | ||
|
|
bd87ec7c83 | ||
|
|
26bfa7a172 | ||
|
|
f82bc15013 | ||
|
|
da60b96445 | ||
|
|
2ed5abed07 | ||
|
|
49dcda7794 | ||
|
|
9fc0fb5e74 | ||
|
|
d32006b324 | ||
|
|
feabb6440d | ||
|
|
87e9c9ad46 | ||
|
|
7d6929c710 | ||
|
|
887642e69c | ||
|
|
b9e6619b2d | ||
|
|
78b5fe5f8c | ||
|
|
72e9b74b3e | ||
|
|
c6aeda1511 | ||
|
|
eb501e1244 | ||
|
|
1f51c14e7e | ||
|
|
dee3ebdc54 | ||
|
|
d0ef05977b | ||
|
|
a17db4f45c | ||
|
|
20974fea55 | ||
|
|
416df98505 | ||
|
|
fb5891cd48 | ||
|
|
1d4a482c1a | ||
|
|
8d57a879ce | ||
|
|
3e7aecd094 | ||
|
|
c46bc1f02a | ||
|
|
0d0ed6c130 | ||
|
|
0045bed6e7 | ||
|
|
0982dc0551 | ||
|
|
e38efc7cbe | ||
|
|
ea4e5f2293 | ||
|
|
29d1590bc6 | ||
|
|
e14ee2ea72 | ||
|
|
68ca4b3c2a | ||
|
|
4ad85e52e2 | ||
|
|
4255e81b93 | ||
|
|
81e8cdc7ab | ||
|
|
b1b5b54fd0 | ||
|
|
109362f147 | ||
|
|
b5038c18e2 | ||
|
|
87d889f96c | ||
|
|
9b41ea4017 | ||
|
|
51658a0d7c | ||
|
|
2f45e14bea | ||
|
|
aa56afdab7 | ||
|
|
9fda131d37 | ||
|
|
b3ddcd4ed9 | ||
|
|
107792635d | ||
|
|
7ea8cf5fb3 | ||
|
|
1d6ce6db35 | ||
|
|
4e44a09072 | ||
|
|
dc6d0c091a | ||
|
|
af6aaf4bab | ||
|
|
e822731f8c | ||
|
|
a23246aca1 | ||
|
|
f31e45d7d2 | ||
|
|
34e61da366 | ||
|
|
451aef200f | ||
|
|
bb8a1b061c | ||
|
|
d4367cdd7d | ||
|
|
3b15bb80b9 | ||
|
|
399e11edf7 | ||
|
|
f97f370e5b | ||
|
|
070f2e181c | ||
|
|
9d9da4feb9 | ||
|
|
ce858a80ed | ||
|
|
4898c83590 | ||
|
|
d8ed2eb1be | ||
|
|
00c8a5845e | ||
|
|
d8dba61b0a | ||
|
|
b8117b3931 | ||
|
|
aface2f43e | ||
|
|
9691130b83 | ||
|
|
1fbf3caa50 | ||
|
|
e3128c204e | ||
|
|
1e6b27d42a | ||
|
|
c24bd209e6 | ||
|
|
df96cc6e56 | ||
|
|
641549c9ed | ||
|
|
66e0308028 | ||
|
|
22939abb0d | ||
|
|
dfc4bff579 | ||
|
|
588223915c | ||
|
|
5702670bd3 | ||
|
|
d79760e9dd | ||
|
|
21011d00ea | ||
|
|
23cb98272c | ||
|
|
b8b2712f73 | ||
|
|
8b6a29decf | ||
|
|
5475841ca0 | ||
|
|
e8a2ad1d1b | ||
|
|
54a62ea78d | ||
|
|
bcda41b508 | ||
|
|
c0fac0f5ca | ||
|
|
0faf0dd2a1 | ||
|
|
9a698ce1e8 | ||
|
|
a7683c60c9 | ||
|
|
9412b770bf | ||
|
|
29a6473c3d | ||
|
|
7ceed1f42d | ||
|
|
959367629e | ||
|
|
aeed1f79bb | ||
|
|
278d3a0313 | ||
|
|
5af9f71d38 | ||
|
|
b6f446e909 | ||
|
|
7804a2db86 | ||
|
|
0e4d2b50b4 | ||
|
|
b594cf0d74 | ||
|
|
074fdeb212 | ||
|
|
a1355ee766 | ||
|
|
c3e1bb40f4 | ||
|
|
661410a96e | ||
|
|
e272eced94 | ||
|
|
4ab901ed43 | ||
|
|
c1abe4a550 | ||
|
|
3fc76f9c10 | ||
|
|
1e304f56cb | ||
|
|
5929826c5f | ||
|
|
9dad36b117 | ||
|
|
8b9f994cea | ||
|
|
7ecb2c0185 | ||
|
|
342c49f0bb | ||
|
|
bb220b5c3b | ||
|
|
3455f00d23 | ||
|
|
992ab7120c | ||
|
|
5215722c78 | ||
|
|
56b3203fa9 | ||
|
|
3cc4a0c6e3 | ||
|
|
556ede5960 | ||
|
|
46c610f35e | ||
|
|
18357be938 | ||
|
|
a9f369479f | ||
|
|
8c00bbc91d | ||
|
|
9af01c515f | ||
|
|
567cc304ed | ||
|
|
98a1654b47 | ||
|
|
ddbe1986ad | ||
|
|
ac19d4d19c | ||
|
|
142f16afe4 | ||
|
|
07810818cc | ||
|
|
4664a19718 | ||
|
|
46f59acdce | ||
|
|
c61189121e | ||
|
|
8c14262efc | ||
|
|
fa398766d9 | ||
|
|
026fcc66c9 | ||
|
|
7c5a3ae311 | ||
|
|
feacf7614e | ||
|
|
8609e65fc2 | ||
|
|
3ff33699c8 | ||
|
|
df72d7b20f | ||
|
|
1d7144564c | ||
|
|
aced2e4e94 | ||
|
|
9b9ac03760 | ||
|
|
c052de2bbc | ||
|
|
85d0e9797c | ||
|
|
f975319d02 | ||
|
|
b8164df349 | ||
|
|
1458d77844 | ||
|
|
052f2ac321 | ||
|
|
4a6945ac17 | ||
|
|
c9ca9737a7 | ||
|
|
2e1495fc07 | ||
|
|
55de3020d3 | ||
|
|
366bf46ca1 | ||
|
|
50615557d9 | ||
|
|
1c0f891427 | ||
|
|
0c6c0ef6d5 | ||
|
|
ff91974345 | ||
|
|
e7dc09cf9f | ||
|
|
fcf9649ef9 | ||
|
|
55e3746554 | ||
|
|
a59a147dbd | ||
|
|
355ce9f679 | ||
|
|
785e7135a7 | ||
|
|
735ab45480 | ||
|
|
55c2adc503 | ||
|
|
2486b25e5e | ||
|
|
020a8da9bb | ||
|
|
d559037f31 | ||
|
|
cce81bcefb | ||
|
|
fc73c4b1fd | ||
|
|
588efb1427 | ||
|
|
2d46c83149 | ||
|
|
3c62396533 | ||
|
|
22f55a7aeb | ||
|
|
3d7bd00abf | ||
|
|
7b1ed14e4e | ||
|
|
3c88e04d4c | ||
|
|
9adab910f4 | ||
|
|
d7969931e8 | ||
|
|
94b6f27937 | ||
|
|
8690bb7c12 | ||
|
|
49b5bbc964 | ||
|
|
479d98212b | ||
|
|
3f973e6fa3 | ||
|
|
584d4f67bd | ||
|
|
642ed5f46e | ||
|
|
9a9e6e94ff | ||
|
|
88b028e4a5 | ||
|
|
fb07d2dad6 | ||
|
|
b4f68ef021 | ||
|
|
403214f569 | ||
|
|
944f0df981 | ||
|
|
97b3ff0499 | ||
|
|
4507fb9368 | ||
|
|
cdd44c4db8 | ||
|
|
983fe5e086 | ||
|
|
f4686adced | ||
|
|
25aeb58c87 | ||
|
|
dd73ac8892 | ||
|
|
16f97a74d7 | ||
|
|
242c55dcff | ||
|
|
1f87dcc6b8 | ||
|
|
dafe3a0811 | ||
|
|
9ac4d137ff | ||
|
|
3cb3113705 | ||
|
|
239f9e817d | ||
|
|
b9f42ddc0f | ||
|
|
c437afc15b | ||
|
|
41812172a7 | ||
|
|
11e682e061 | ||
|
|
821cf24c5b | ||
|
|
14f29e95a7 | ||
|
|
8aa30ee8f6 | ||
|
|
c9303f5889 | ||
|
|
b1f38ea0e8 | ||
|
|
3e9cbade45 | ||
|
|
52af66e0f9 | ||
|
|
c1911994ea | ||
|
|
af62ef736d | ||
|
|
4a6f427df7 | ||
|
|
00a2d7b1cb | ||
|
|
e2af6b9d04 | ||
|
|
4955097a52 | ||
|
|
870bc51ad9 | ||
|
|
ea54543602 | ||
|
|
bb278df881 | ||
|
|
46fde0e439 | ||
|
|
e3d895be4c | ||
|
|
dd8d4b5ad8 | ||
|
|
d956a3bdb3 | ||
|
|
66930ab303 | ||
|
|
0f032a1388 | ||
|
|
5ce54c9e0d | ||
|
|
b86950da6f | ||
|
|
f7c71bdaac | ||
|
|
ee2aa91d97 | ||
|
|
c353455b83 | ||
|
|
530419a839 | ||
|
|
c027b4d127 |
@@ -1,2 +1,3 @@
|
||||
examples/Jugl.js
|
||||
examples/resources/
|
||||
build/package/**/*webgl*
|
||||
|
||||
5
Makefile
5
Makefile
@@ -86,7 +86,7 @@ check-deps:
|
||||
done ;\
|
||||
|
||||
.PHONY: ci
|
||||
ci: lint build test test-rendering compile-examples check-examples apidoc
|
||||
ci: lint build test test-rendering package compile-examples check-examples apidoc
|
||||
|
||||
.PHONY: compile-examples
|
||||
compile-examples: build/compiled-examples/all.combined.js
|
||||
@@ -253,7 +253,7 @@ build/timestamps/eslint-timestamp: $(SRC_JS) $(SPEC_JS) $(SPEC_RENDERING_JS) \
|
||||
build/timestamps/node-modules-timestamp
|
||||
@mkdir -p $(@D)
|
||||
@echo "Running eslint..."
|
||||
@./node_modules/.bin/eslint --quiet tasks test test_rendering src examples
|
||||
@./node_modules/.bin/eslint tasks test test_rendering src examples
|
||||
@touch $@
|
||||
|
||||
build/timestamps/node-modules-timestamp: package.json
|
||||
@@ -310,3 +310,4 @@ package:
|
||||
@rm build/package/typedefs.js
|
||||
@cp css/ol.css build/package
|
||||
./node_modules/.bin/jscodeshift --transform transforms/module.js build/package
|
||||
npm run lint-package
|
||||
|
||||
@@ -2,6 +2,36 @@
|
||||
|
||||
### Next release
|
||||
|
||||
#### `ol.animate` now takes the shortest arc for rotation animation
|
||||
|
||||
Usually rotation animations should animate along the shortest arc. There are rare occasions where a spinning animation effect is desired. So if you previously had something like
|
||||
```js
|
||||
map.getView().animate({
|
||||
rotation: 2 * Math.PI,
|
||||
duration: 2000
|
||||
});
|
||||
```
|
||||
we recommend to split the animation into two parts and use different easing functions. The code below results in the same effect as the snippet above did with previous versions:
|
||||
```js
|
||||
map.getView().animate({
|
||||
rotation: Math.PI,
|
||||
easing: ol.easing.easeIn
|
||||
}, {
|
||||
rotation: 2 * Math.PI,
|
||||
easing: ol.easing.easeOut
|
||||
});
|
||||
```
|
||||
|
||||
### v4.2.0
|
||||
|
||||
#### Return values of two `ol.style.RegularShape` getters have changed
|
||||
|
||||
To provide a more consistent behaviour the following getters now return the same value that was given to constructor:
|
||||
|
||||
`ol.style.RegularShape#getPoints` does not return the double amount of points anymore if a radius2 is set.
|
||||
|
||||
`ol.style.RegularShape#getRadius2` will return `undefined` if no radius2 is set.
|
||||
|
||||
### v4.1.0
|
||||
|
||||
#### Adding duplicate layers to a map throws
|
||||
|
||||
151
changelog/v4.2.0.md
Normal file
151
changelog/v4.2.0.md
Normal file
@@ -0,0 +1,151 @@
|
||||
# 4.2.0
|
||||
|
||||
## Summary
|
||||
|
||||
The v4.2.0 release includes features and fixes from 87 pull requests.
|
||||
|
||||
#### New `movestart` event on `ol.Map`
|
||||
|
||||
The map now has a `movestart` event, as countarpart to the already existing `moveend` event.
|
||||
|
||||
#### New `moveTolerance` option in `ol.Map`
|
||||
|
||||
Some touch devices do not play well with OpenLayers's way of detecting clicks. To overcome this, a new `moveTolerance` option was introduced, so users can override the 1 pixel threshold above which a touch-release sequence won't be considered a click any more.
|
||||
|
||||
#### Support for multiple layers in `ol.format.TopoJSON`
|
||||
|
||||
With the new `layerName` and `layers` options, applications can extract the layer as additional attribute for vector features from `ol.format.TopoJSON`. This can especially be useful for styling vector tile layers.
|
||||
|
||||
#### New `tileJSON` option for `ol.source.TileJSON`
|
||||
|
||||
Like `ol.source.TileUTFGrid`, `ol.source.TileJSON` now also has a `tileJSON` option to configue it with inline TileJSON instead of a TileJSON URL.
|
||||
|
||||
#### New `ol.format.filter.during` filter
|
||||
|
||||
Although OpenLayers has no support for WFS v2.0, we added `ol.format.filter.during` for the `During` temporal operator.
|
||||
|
||||
#### Improved vector tile rendering at non-native resolutions
|
||||
|
||||
The vector tile renderer now uses an internal tile grid for all resolutions to cache pre-rendered tiles, even if the tile source does not have tiles for the viewed resolution. This improves rendering quality and performance.
|
||||
|
||||
#### New `insertVertexCondition` for `ol.interaction.Modify`
|
||||
|
||||
Applications can now control whether a vertex will be inserted into the modified geometry. This makes it easier to modify custom geometries.
|
||||
|
||||
#### New `callback` option for `ol.View#fit()`
|
||||
|
||||
To allow applications to perform custom actions when an animation associated with `ol.View#fit()` is completed, that method now has a new `callback` option.
|
||||
|
||||
#### New `ol.View#getInteracting()` getter
|
||||
|
||||
Like `ol.View#getAnimating()` returns `true` during a view animation, `ol.View#getInteracting()` returns `true` while users are interacting with the view.
|
||||
|
||||
#### New `hasZ` option for `ol.format.WFS#writeTransaction()`
|
||||
|
||||
When the new `hasZ` option is set to `true`, 3D coordinates will be preserved and encoded when writing a WFS transaction.
|
||||
|
||||
#### New `wrapX` option for `ol.source.Stamen`
|
||||
|
||||
Like other tile sources, `ol.source.Stamen` now also has a `wrapX` option, which allows applications to turn off wrapping the world in x direction.
|
||||
|
||||
#### Label support for `ol.Graticule`
|
||||
|
||||
The `ol.Graticule` component has several new options to add and control the output of labels. To turn on labelling, configure `ol.Graticule` with `showLabels: true`. The new options to control label formatting are `lonLabelFormatter`, `latLabelFormatter`, `lonLabelPosition` and `latLabelPosition`.
|
||||
|
||||
#### Return values of two `ol.style.RegularShape` getters have changed
|
||||
|
||||
To provide a more consistent behaviour the following getters now return the same value that was given to constructor:
|
||||
|
||||
`ol.style.RegularShape#getPoints` does not return the double amount of points anymore if a radius2 is set.
|
||||
|
||||
`ol.style.RegularShape#getRadius2` will return `undefined` if no radius2 is set.
|
||||
|
||||
## Detailed changes
|
||||
|
||||
* [#6912](https://github.com/openlayers/openlayers/pull/6912) - Use class instead of style for Translate cursor ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#6858](https://github.com/openlayers/openlayers/pull/6858) - Webgl vector improvements ([@GaborFarkas](https://github.com/GaborFarkas))
|
||||
* [#6890](https://github.com/openlayers/openlayers/pull/6890) - Add a movestart event ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#6910](https://github.com/openlayers/openlayers/pull/6910) - Avoid duplicates in Observables list ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#6902](https://github.com/openlayers/openlayers/pull/6902) - Require minimum duration for kinetic animation ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#6904](https://github.com/openlayers/openlayers/pull/6904) - chore(package): update sinon to version 2.3.4 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6901](https://github.com/openlayers/openlayers/pull/6901) - Added release note for changed methods of ol.style.regularShape ([@KlausBenndorf](https://github.com/KlausBenndorf))
|
||||
* [#6886](https://github.com/openlayers/openlayers/pull/6886) - Make ol.source.Cluster extensible ([@gberaudo](https://github.com/gberaudo))
|
||||
* [#6887](https://github.com/openlayers/openlayers/pull/6887) - Disable rotation for views with enableRotation: false ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#6900](https://github.com/openlayers/openlayers/pull/6900) - Update clean-css-cli to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6897](https://github.com/openlayers/openlayers/pull/6897) - ProjectionLike in proj.getPointResolution ([@probins](https://github.com/probins))
|
||||
* [#6888](https://github.com/openlayers/openlayers/pull/6888) - Add note about custom functions to getPointResolution ([@probins](https://github.com/probins))
|
||||
* [#6893](https://github.com/openlayers/openlayers/pull/6893) - Fix decimals options when writing features ([@tchandelle](https://github.com/tchandelle))
|
||||
* [#6759](https://github.com/openlayers/openlayers/pull/6759) - Regular shape points ([@KlausBenndorf](https://github.com/KlausBenndorf))
|
||||
* [#6892](https://github.com/openlayers/openlayers/pull/6892) - Accept a ol.ProjectionLike instead of ol.proj.Projection ([@fredj](https://github.com/fredj))
|
||||
* [#6883](https://github.com/openlayers/openlayers/pull/6883) - Remove unused ol.pointer.EventSource#getMapping function ([@fredj](https://github.com/fredj))
|
||||
* [#6870](https://github.com/openlayers/openlayers/pull/6870) - Center map on proper earth, not one to the left ([@kannes](https://github.com/kannes))
|
||||
* [#6872](https://github.com/openlayers/openlayers/pull/6872) - Update rollup to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6876](https://github.com/openlayers/openlayers/pull/6876) - Only test ol.interaction.DragAndDrop if FileReader is supported ([@fredj](https://github.com/fredj))
|
||||
* [#6874](https://github.com/openlayers/openlayers/pull/6874) - Remove unused var from ol.proj ([@probins](https://github.com/probins))
|
||||
* [#6875](https://github.com/openlayers/openlayers/pull/6875) - chore(package): update sinon to version 2.3.2 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6867](https://github.com/openlayers/openlayers/pull/6867) - add getArea to api ([@cs09g](https://github.com/cs09g))
|
||||
* [#6863](https://github.com/openlayers/openlayers/pull/6863) - change size to optional ([@cs09g](https://github.com/cs09g))
|
||||
* [#6864](https://github.com/openlayers/openlayers/pull/6864) - fix(package): update closure-util to version 1.21.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6834](https://github.com/openlayers/openlayers/pull/6834) - Move tolerance option ([@notnotse](https://github.com/notnotse))
|
||||
* [#6856](https://github.com/openlayers/openlayers/pull/6856) - Fix creation of new URL in readSharedStyle_ and readSharedStyleMap_ ([@oterral](https://github.com/oterral))
|
||||
* [#6852](https://github.com/openlayers/openlayers/pull/6852) - Update mocha to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6851](https://github.com/openlayers/openlayers/pull/6851) - Register/unregister listeners in setActive ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#6832](https://github.com/openlayers/openlayers/pull/6832) - Force state of error tiles when usInterimTilesOnError is false ([@oterral](https://github.com/oterral))
|
||||
* [#6849](https://github.com/openlayers/openlayers/pull/6849) - Create URL object only when we can ([@oterral](https://github.com/oterral))
|
||||
* [#6845](https://github.com/openlayers/openlayers/pull/6845) - Snap on circles ([@tchandelle](https://github.com/tchandelle))
|
||||
* [#6842](https://github.com/openlayers/openlayers/pull/6842) - add condition to check if active ([@cs09g](https://github.com/cs09g))
|
||||
* [#6844](https://github.com/openlayers/openlayers/pull/6844) - Update sinon to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6841](https://github.com/openlayers/openlayers/pull/6841) - Update sinon to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6839](https://github.com/openlayers/openlayers/pull/6839) - Update async to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6838](https://github.com/openlayers/openlayers/pull/6838) - fix(package): update handlebars to version 4.0.10 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6817](https://github.com/openlayers/openlayers/pull/6817) - Multiple layers in TopoJSON vector tiles ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#6833](https://github.com/openlayers/openlayers/pull/6833) - Fix geojson-vt example for line and point geometries ([@oterral](https://github.com/oterral))
|
||||
* [#6829](https://github.com/openlayers/openlayers/pull/6829) - Update clean-css-cli to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6819](https://github.com/openlayers/openlayers/pull/6819) - Adjust/fix API for working with vector tile features ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#6818](https://github.com/openlayers/openlayers/pull/6818) - Add tileJSON option to ol.source.TileJSON ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#6805](https://github.com/openlayers/openlayers/pull/6805) - Display country name on click select ([@fredj](https://github.com/fredj))
|
||||
* [#6813](https://github.com/openlayers/openlayers/pull/6813) - Prepend the version with a v ([@tschaub](https://github.com/tschaub))
|
||||
* [#6814](https://github.com/openlayers/openlayers/pull/6814) - Re-add ol.render.Feature#getGeometry() ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#6812](https://github.com/openlayers/openlayers/pull/6812) - Update mocha to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6786](https://github.com/openlayers/openlayers/pull/6786) - Add ol.format.filter.during ([@fredj](https://github.com/fredj))
|
||||
* [#6806](https://github.com/openlayers/openlayers/pull/6806) - Add note about features with the same id ([@drnextgis](https://github.com/drnextgis))
|
||||
* [#6802](https://github.com/openlayers/openlayers/pull/6802) - Remove unused setFeatures and getFormat methods ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#6801](https://github.com/openlayers/openlayers/pull/6801) - Add getId method for ol.render.Feature ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#6778](https://github.com/openlayers/openlayers/pull/6778) - Add a small tolerance when testing pointer event positions ([@fredj](https://github.com/fredj))
|
||||
* [#6796](https://github.com/openlayers/openlayers/pull/6796) - Re-add accidently dropped condition ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#6798](https://github.com/openlayers/openlayers/pull/6798) - chore(package): update clean-css-cli to version 4.1.2 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6795](https://github.com/openlayers/openlayers/pull/6795) - Fix ol.DrawGeometryFunctionType coordinates argument type ([@fredj](https://github.com/fredj))
|
||||
* [#6797](https://github.com/openlayers/openlayers/pull/6797) - Update clean-css-cli to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6779](https://github.com/openlayers/openlayers/pull/6779) - Decouple source and rendered tile grid of vector tile sources ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#6785](https://github.com/openlayers/openlayers/pull/6785) - Add insertVertexCondition to ol.interaction.Modify options ([@fredj](https://github.com/fredj))
|
||||
* [#6792](https://github.com/openlayers/openlayers/pull/6792) - Create intermediate canvas when resolutions have changed ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#6790](https://github.com/openlayers/openlayers/pull/6790) - Update resemblejs to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6784](https://github.com/openlayers/openlayers/pull/6784) - chore(package): update clean-css-cli to version 4.1.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6556](https://github.com/openlayers/openlayers/pull/6556) - Reading kml xunits/yunits insetPixels ([@KlausBenndorf](https://github.com/KlausBenndorf))
|
||||
* [#6775](https://github.com/openlayers/openlayers/pull/6775) - Update closure-util to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6774](https://github.com/openlayers/openlayers/pull/6774) - Update fs-extra to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6770](https://github.com/openlayers/openlayers/pull/6770) - Enforce the "no missing requires" rule ([@tschaub](https://github.com/tschaub))
|
||||
* [#6772](https://github.com/openlayers/openlayers/pull/6772) - Remove html tag from shortdesc ([@fredj](https://github.com/fredj))
|
||||
* [#6769](https://github.com/openlayers/openlayers/pull/6769) - Update handlebars to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6757](https://github.com/openlayers/openlayers/pull/6757) - Fix crashing on creation of snap-interaction, if Circle is among the features to snap to. ([@hajjimurad](https://github.com/hajjimurad))
|
||||
* [#6766](https://github.com/openlayers/openlayers/pull/6766) - Update sinon to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6765](https://github.com/openlayers/openlayers/pull/6765) - Add new callback function to view.FitOptions ([@fredj](https://github.com/fredj))
|
||||
* [#6764](https://github.com/openlayers/openlayers/pull/6764) - Added View#getInteracting() to the api ([@mblinsitu](https://github.com/mblinsitu))
|
||||
* [#6760](https://github.com/openlayers/openlayers/pull/6760) - Update handlebars to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6761](https://github.com/openlayers/openlayers/pull/6761) - Update async to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6755](https://github.com/openlayers/openlayers/pull/6755) - Add missing goog.require ([@fredj](https://github.com/fredj))
|
||||
* [#6751](https://github.com/openlayers/openlayers/pull/6751) - Update coveralls to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6750](https://github.com/openlayers/openlayers/pull/6750) - Update fs-extra to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6741](https://github.com/openlayers/openlayers/pull/6741) - Allow user selection in overlay container ([@fredj](https://github.com/fredj))
|
||||
* [#6744](https://github.com/openlayers/openlayers/pull/6744) - Update mocha to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6737](https://github.com/openlayers/openlayers/pull/6737) - Graticule labels ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#6740](https://github.com/openlayers/openlayers/pull/6740) - Fix spelling ([@fredj](https://github.com/fredj))
|
||||
* [#6730](https://github.com/openlayers/openlayers/pull/6730) - Update metalsmith-layouts to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6732](https://github.com/openlayers/openlayers/pull/6732) - Use firefox < 53 in travis ([@fredj](https://github.com/fredj))
|
||||
* [#6677](https://github.com/openlayers/openlayers/pull/6677) - Add an option to writeTransaction to support 3D geometries ([@Jenselme](https://github.com/Jenselme))
|
||||
* [#6524](https://github.com/openlayers/openlayers/pull/6524) - Don't append feature prefix twice in WFS requests ([@Jenselme](https://github.com/Jenselme))
|
||||
* [#6727](https://github.com/openlayers/openlayers/pull/6727) - Add default value in doc for the hitTolerance option ([@fredj](https://github.com/fredj))
|
||||
* [#6724](https://github.com/openlayers/openlayers/pull/6724) - Add wrapX option to Stamen source ([@fredj](https://github.com/fredj))
|
||||
* [#6728](https://github.com/openlayers/openlayers/pull/6728) - Fix tissot examples docs ([@fredj](https://github.com/fredj))
|
||||
* [#6725](https://github.com/openlayers/openlayers/pull/6725) - Update dependencies to enable Greenkeeper 🌴 ([@openlayers](https://github.com/openlayers))
|
||||
* [#6711](https://github.com/openlayers/openlayers/pull/6711) - Correct path to cleancss ([@tschaub](https://github.com/tschaub))
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"opts": {
|
||||
"recurse": true,
|
||||
"template": "config/jsdoc/api/template"
|
||||
"template": "../../config/jsdoc/api/template"
|
||||
},
|
||||
"tags": {
|
||||
"allowUnknownTags": true
|
||||
@@ -16,12 +16,12 @@
|
||||
]
|
||||
},
|
||||
"plugins": [
|
||||
"node_modules/jsdoc/plugins/markdown",
|
||||
"config/jsdoc/api/plugins/inheritdoc",
|
||||
"config/jsdoc/api/plugins/typedefs",
|
||||
"config/jsdoc/api/plugins/events",
|
||||
"config/jsdoc/api/plugins/observable",
|
||||
"config/jsdoc/api/plugins/api"
|
||||
"plugins/markdown",
|
||||
"../../config/jsdoc/api/plugins/inheritdoc",
|
||||
"../../config/jsdoc/api/plugins/typedefs",
|
||||
"../../config/jsdoc/api/plugins/events",
|
||||
"../../config/jsdoc/api/plugins/observable",
|
||||
"../../config/jsdoc/api/plugins/api"
|
||||
],
|
||||
"markdown": {
|
||||
"parser": "gfm"
|
||||
|
||||
@@ -41,7 +41,7 @@ exports.handlers = {
|
||||
cls.observables = [];
|
||||
}
|
||||
observable = observables[doclet.observable];
|
||||
if (cls.observables.indexOf(observable) == -1) {
|
||||
if (observable.type && cls.observables.indexOf(observable) == -1) {
|
||||
cls.observables.push(observable);
|
||||
}
|
||||
if (!cls.fires) {
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
<tbody>
|
||||
<?js
|
||||
var self = this;
|
||||
var propsByName = {};
|
||||
props.forEach(function(prop) {
|
||||
if (!prop) { return; }
|
||||
if (!prop || propsByName[prop.name]) { return; }
|
||||
propsByName[prop.name] = prop;
|
||||
var setter = prop.readonly ? 'no' : 'yes';
|
||||
?>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"opts": {
|
||||
"recurse": true,
|
||||
"template": "config/jsdoc/info"
|
||||
"template": "../../config/jsdoc/info"
|
||||
},
|
||||
"tags": {
|
||||
"allowUnknownTags": true
|
||||
@@ -10,8 +10,8 @@
|
||||
"includePattern": "\\.js$"
|
||||
},
|
||||
"plugins": [
|
||||
"config/jsdoc/info/api-plugin",
|
||||
"config/jsdoc/info/define-plugin",
|
||||
"config/jsdoc/info/virtual-plugin"
|
||||
"../../config/jsdoc/info/api-plugin",
|
||||
"../../config/jsdoc/info/define-plugin",
|
||||
"../../config/jsdoc/info/virtual-plugin"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
* an api tag) and boolean defines (with a define tag and a default value).
|
||||
*/
|
||||
var assert = require('assert');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
|
||||
@@ -89,7 +88,6 @@ exports.publish = function(data, opts) {
|
||||
types: getTypes(doc.type.names)
|
||||
});
|
||||
} else {
|
||||
var types;
|
||||
var symbol = {
|
||||
name: doc.longname,
|
||||
kind: doc.kind,
|
||||
@@ -169,6 +167,7 @@ exports.publish = function(data, opts) {
|
||||
return (symbol.name in augments || symbol.virtual);
|
||||
});
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
process.stdout.write(
|
||||
JSON.stringify({
|
||||
symbols: symbols,
|
||||
@@ -177,5 +176,6 @@ exports.publish = function(data, opts) {
|
||||
externs: externs,
|
||||
base: base
|
||||
}, null, 2));
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
11
css/ol.css
11
css/ol.css
@@ -49,6 +49,17 @@
|
||||
-ms-user-select: auto;
|
||||
user-select: auto;
|
||||
}
|
||||
.ol-grabbing {
|
||||
cursor: -webkit-grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
cursor: grabbing;
|
||||
}
|
||||
.ol-grab {
|
||||
cursor: move;
|
||||
cursor: -webkit-grab;
|
||||
cursor: -moz-grab;
|
||||
cursor: grab;
|
||||
}
|
||||
.ol-control {
|
||||
position: absolute;
|
||||
background-color: rgba(255,255,255,0.4);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.easing');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.source.OSM');
|
||||
@@ -73,9 +74,16 @@ onClick('rotate-right', function() {
|
||||
});
|
||||
|
||||
onClick('rotate-around-rome', function() {
|
||||
// Rotation animation takes the shortest arc, so animate in two parts
|
||||
var rotation = view.getRotation();
|
||||
view.animate({
|
||||
rotation: view.getRotation() + 2 * Math.PI,
|
||||
anchor: rome
|
||||
rotation: rotation + Math.PI,
|
||||
anchor: rome,
|
||||
easing: ol.easing.easeIn
|
||||
}, {
|
||||
rotation: rotation + 2 * Math.PI,
|
||||
anchor: rome,
|
||||
easing: ol.easing.easeOut
|
||||
});
|
||||
});
|
||||
|
||||
@@ -103,10 +111,19 @@ onClick('bounce-to-istanbul', function() {
|
||||
});
|
||||
|
||||
onClick('spin-to-rome', function() {
|
||||
// Rotation animation takes the shortest arc, so animate in two parts
|
||||
var center = view.getCenter();
|
||||
view.animate({
|
||||
center: [
|
||||
center[0] + (rome[0] - center[0]) / 2,
|
||||
center[1] + (rome[1] - center[1]) / 2
|
||||
],
|
||||
rotation: Math.PI,
|
||||
easing: ol.easing.easeIn
|
||||
}, {
|
||||
center: rome,
|
||||
rotation: 2 * Math.PI,
|
||||
duration: 2000
|
||||
easing: ol.easing.easeOut
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@ cloak:
|
||||
<select id="layer-select">
|
||||
<option value="Aerial">Aerial</option>
|
||||
<option value="AerialWithLabels" selected>Aerial with labels</option>
|
||||
<option value="Road">Road</option>
|
||||
<option value="Road">Road (static)</option>
|
||||
<option value="RoadOnDemand">Road (dynamic)</option>
|
||||
<option value="collinsBart">Collins Bart</option>
|
||||
<option value="ordnanceSurvey">Ordnance Survey</option>
|
||||
</select>
|
||||
|
||||
@@ -6,6 +6,7 @@ goog.require('ol.source.BingMaps');
|
||||
|
||||
var styles = [
|
||||
'Road',
|
||||
'RoadOnDemand',
|
||||
'Aerial',
|
||||
'AerialWithLabels',
|
||||
'collinsBart',
|
||||
|
||||
@@ -45,29 +45,29 @@ var dragBox = new ol.interaction.DragBox({
|
||||
|
||||
map.addInteraction(dragBox);
|
||||
|
||||
var infoBox = document.getElementById('info');
|
||||
|
||||
dragBox.on('boxend', function() {
|
||||
// features that intersect the box are added to the collection of
|
||||
// selected features, and their names are displayed in the "info"
|
||||
// div
|
||||
var info = [];
|
||||
// selected features
|
||||
var extent = dragBox.getGeometry().getExtent();
|
||||
vectorSource.forEachFeatureIntersectingExtent(extent, function(feature) {
|
||||
selectedFeatures.push(feature);
|
||||
info.push(feature.get('name'));
|
||||
});
|
||||
if (info.length > 0) {
|
||||
infoBox.innerHTML = info.join(', ');
|
||||
}
|
||||
});
|
||||
|
||||
// clear selection when drawing a new box and when clicking on the map
|
||||
dragBox.on('boxstart', function() {
|
||||
selectedFeatures.clear();
|
||||
infoBox.innerHTML = ' ';
|
||||
});
|
||||
map.on('click', function() {
|
||||
selectedFeatures.clear();
|
||||
infoBox.innerHTML = ' ';
|
||||
|
||||
var infoBox = document.getElementById('info');
|
||||
|
||||
selectedFeatures.on(['add', 'remove'], function() {
|
||||
var names = selectedFeatures.getArray().map(function(feature) {
|
||||
return feature.get('name');
|
||||
});
|
||||
if (names.length > 0) {
|
||||
infoBox.innerHTML = names.join(', ');
|
||||
} else {
|
||||
infoBox.innerHTML = 'No countries selected';
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Clustered Features
|
||||
shortdesc: Example of using <code>ol.source.Cluster</code>.
|
||||
shortdesc: Example of using ol.source.Cluster.
|
||||
docs: >
|
||||
This example shows how to do clustering on point features.
|
||||
tags: "cluster, vector"
|
||||
|
||||
@@ -17,18 +17,30 @@ var replacer = function(key, value) {
|
||||
var geometry = value.geometry;
|
||||
|
||||
if (rawType === 1) {
|
||||
type = geometry.length === 1 ? 'Point' : 'MultiPoint';
|
||||
type = 'MultiPoint';
|
||||
if (geometry.length == 1) {
|
||||
type = 'Point';
|
||||
geometry = geometry[0];
|
||||
}
|
||||
} else if (rawType === 2) {
|
||||
type = geometry.length === 1 ? 'LineString' : 'MultiLineString';
|
||||
type = 'MultiLineString';
|
||||
if (geometry.length == 1) {
|
||||
type = 'LineString';
|
||||
geometry = geometry[0];
|
||||
}
|
||||
} else if (rawType === 3) {
|
||||
type = geometry.length === 1 ? 'Polygon' : 'MultiPolygon';
|
||||
type = 'Polygon';
|
||||
if (geometry.length > 1) {
|
||||
type = 'MultiPolygon';
|
||||
geometry = [geometry];
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
'type': 'Feature',
|
||||
'geometry': {
|
||||
'type': type,
|
||||
'coordinates': geometry.length == 1 ? geometry : [geometry]
|
||||
'coordinates': geometry
|
||||
},
|
||||
'properties': value.tags
|
||||
};
|
||||
|
||||
@@ -27,6 +27,8 @@ var graticule = new ol.Graticule({
|
||||
color: 'rgba(255,120,0,0.9)',
|
||||
width: 2,
|
||||
lineDash: [0.5, 4]
|
||||
})
|
||||
}),
|
||||
showLabels: true
|
||||
});
|
||||
|
||||
graticule.setMap(map);
|
||||
|
||||
@@ -3,7 +3,7 @@ layout: example.html
|
||||
title: Advanced Mapbox Vector Tiles
|
||||
shortdesc: Example of a Mapbox vector tiles map with custom tile grid.
|
||||
docs: >
|
||||
A vector tiles map which reuses the same tiles for subsequent zoom levels to save bandwith on mobile devices. **Note**: No map will be visible when the access token has expired.
|
||||
A vector tiles map which reuses the same source tiles for subsequent zoom levels to save bandwidth on mobile devices. **Note**: No map will be visible when the access token has expired.
|
||||
tags: "mapbox, vector, tiles, mobile"
|
||||
resources:
|
||||
- resources/mapbox-streets-v6-style.js
|
||||
|
||||
@@ -15,25 +15,16 @@ goog.require('ol.tilegrid.TileGrid');
|
||||
|
||||
var key = 'pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiRk1kMWZaSSJ9.E5BkluenyWQMsBLsuByrmg';
|
||||
|
||||
// For how many zoom levels do we want to use the same vector tiles?
|
||||
// 1 means "use tiles from all zoom levels". 2 means "use the same tiles for 2
|
||||
// subsequent zoom levels".
|
||||
var reuseZoomLevels = 2;
|
||||
|
||||
// Offset of loaded tiles from web mercator zoom level 0.
|
||||
// 0 means "At map zoom level 0, use tiles from zoom level 0". 1 means "At map
|
||||
// zoom level 0, use tiles from zoom level 1".
|
||||
var zoomOffset = 1;
|
||||
|
||||
// Calculation of tile urls
|
||||
// Calculation of resolutions that match zoom levels 1, 3, 5, 7, 9, 11, 13, 15.
|
||||
var resolutions = [];
|
||||
for (var z = zoomOffset / reuseZoomLevels; z <= 22 / reuseZoomLevels; ++z) {
|
||||
resolutions.push(156543.03392804097 / Math.pow(2, z * reuseZoomLevels));
|
||||
for (var i = 0; i <= 7; ++i) {
|
||||
resolutions.push(156543.03392804097 / Math.pow(2, i * 2));
|
||||
}
|
||||
// Calculation of tile urls for zoom levels 1, 3, 5, 7, 9, 11, 13, 15.
|
||||
function tileUrlFunction(tileCoord) {
|
||||
return ('https://{a-d}.tiles.mapbox.com/v4/mapbox.mapbox-streets-v6/' +
|
||||
'{z}/{x}/{y}.vector.pbf?access_token=' + key)
|
||||
.replace('{z}', String(tileCoord[0] * reuseZoomLevels + zoomOffset))
|
||||
.replace('{z}', String(tileCoord[0] * 2 - 1))
|
||||
.replace('{x}', String(tileCoord[1]))
|
||||
.replace('{y}', String(-tileCoord[2] - 1))
|
||||
.replace('{a-d}', 'abcd'.substr(
|
||||
@@ -43,8 +34,6 @@ function tileUrlFunction(tileCoord) {
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
new ol.layer.VectorTile({
|
||||
renderMode: 'vector',
|
||||
preload: Infinity,
|
||||
source: new ol.source.VectorTile({
|
||||
attributions: '© <a href="https://www.mapbox.com/map-feedback/">Mapbox</a> ' +
|
||||
'© <a href="https://www.openstreetmap.org/copyright">' +
|
||||
@@ -52,9 +41,10 @@ var map = new ol.Map({
|
||||
format: new ol.format.MVT(),
|
||||
tileGrid: new ol.tilegrid.TileGrid({
|
||||
extent: ol.proj.get('EPSG:3857').getExtent(),
|
||||
resolutions: resolutions
|
||||
resolutions: resolutions,
|
||||
tileSize: 512
|
||||
}),
|
||||
tilePixelRatio: 16,
|
||||
tilePixelRatio: 8,
|
||||
tileUrlFunction: tileUrlFunction
|
||||
}),
|
||||
style: createMapboxStreetsV6Style()
|
||||
|
||||
@@ -222,7 +222,13 @@ var select = new ol.interaction.Select({
|
||||
|
||||
var modify = new ol.interaction.Modify({
|
||||
features: select.getFeatures(),
|
||||
style: overlayStyle
|
||||
style: overlayStyle,
|
||||
insertVertexCondition: function() {
|
||||
// prevent new vertices to be added to the polygons
|
||||
return !this.features_.getArray().every(function(feature) {
|
||||
return feature.getGeometry().getType().match(/Polygon/);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var map = new ol.Map({
|
||||
|
||||
@@ -4,7 +4,6 @@ goog.require('ol.control');
|
||||
goog.require('ol.control.MousePosition');
|
||||
goog.require('ol.coordinate');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.source.OSM');
|
||||
|
||||
var mousePositionControl = new ol.control.MousePosition({
|
||||
@@ -37,7 +36,7 @@ var map = new ol.Map({
|
||||
|
||||
var projectionSelect = document.getElementById('projection');
|
||||
projectionSelect.addEventListener('change', function(event) {
|
||||
mousePositionControl.setProjection(ol.proj.get(event.target.value));
|
||||
mousePositionControl.setProjection(event.target.value);
|
||||
});
|
||||
|
||||
var precisionInput = document.getElementById('precision');
|
||||
|
||||
@@ -3,7 +3,7 @@ layout: example.html
|
||||
title: OSM Vector Tiles
|
||||
shortdesc: Using OpenStreetMap vector tiles.
|
||||
docs: >
|
||||
A simple vector tiles map with Mapzen vector tiles. **Note**: TopoJSON vector tiles are not optimized for rendering - they might clip geometries exactly at the tile boundary instead of adding a buffer, and use geographic coordinates instead of tile relative pixel coordinates in view projection.
|
||||
A simple vector tiles map with Mapzen vector tiles. This example uses the TopoJSON format's `layerName` option to determine the layer ("water", "roads", "buildings") for styling. **Note**: [`ol.format.MVT`](../apidoc/ol.format.MVT.html) is an even more efficient format for vector tiles.
|
||||
tags: "vector, tiles, osm, mapzen"
|
||||
cloak:
|
||||
vector-tiles-5eJz6JX: Your Mapzen API key from https://mapzen.com/developers
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
goog.require('ol.Attribution');
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.format.TopoJSON');
|
||||
@@ -13,11 +12,6 @@ goog.require('ol.tilegrid');
|
||||
|
||||
var key = 'vector-tiles-5eJz6JX';
|
||||
|
||||
var attribution = [new ol.Attribution({
|
||||
html: '© OpenStreetMap contributors, Who’s On First, Natural Earth, and openstreetmapdata.com'
|
||||
})];
|
||||
var format = new ol.format.TopoJSON();
|
||||
var tileGrid = ol.tilegrid.createXYZ({maxZoom: 19});
|
||||
var roadStyleCache = {};
|
||||
var roadColor = {
|
||||
'major_road': '#776',
|
||||
@@ -34,30 +28,12 @@ var buildingStyle = new ol.style.Style({
|
||||
width: 1
|
||||
})
|
||||
});
|
||||
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
new ol.layer.VectorTile({
|
||||
source: new ol.source.VectorTile({
|
||||
attributions: attribution,
|
||||
format: format,
|
||||
tileGrid: tileGrid,
|
||||
url: 'https://tile.mapzen.com/mapzen/vector/v1/water/{z}/{x}/{y}.topojson?api_key=' + key
|
||||
}),
|
||||
style: new ol.style.Style({
|
||||
var waterStyle = new ol.style.Style({
|
||||
fill: new ol.style.Fill({
|
||||
color: '#9db9e8'
|
||||
})
|
||||
})
|
||||
}),
|
||||
new ol.layer.VectorTile({
|
||||
source: new ol.source.VectorTile({
|
||||
attributions: attribution,
|
||||
format: format,
|
||||
tileGrid: tileGrid,
|
||||
url: 'https://tile.mapzen.com/mapzen/vector/v1/roads/{z}/{x}/{y}.topojson?api_key=' + key
|
||||
}),
|
||||
style: function(feature) {
|
||||
});
|
||||
var roadStyle = function(feature) {
|
||||
var kind = feature.get('kind');
|
||||
var railway = feature.get('railway');
|
||||
var sort_key = feature.get('sort_key');
|
||||
@@ -82,17 +58,28 @@ var map = new ol.Map({
|
||||
roadStyleCache[styleKey] = style;
|
||||
}
|
||||
return style;
|
||||
}
|
||||
}),
|
||||
};
|
||||
|
||||
var map = new ol.Map({
|
||||
layers: [
|
||||
new ol.layer.VectorTile({
|
||||
source: new ol.source.VectorTile({
|
||||
attributions: attribution,
|
||||
format: format,
|
||||
tileGrid: tileGrid,
|
||||
url: 'https://tile.mapzen.com/mapzen/vector/v1/buildings/{z}/{x}/{y}.topojson?api_key=' + key
|
||||
attributions: '© OpenStreetMap contributors, Who’s On First, ' +
|
||||
'Natural Earth, and openstreetmapdata.com',
|
||||
format: new ol.format.TopoJSON({
|
||||
layerName: 'layer',
|
||||
layers: ['water', 'roads', 'buildings']
|
||||
}),
|
||||
style: function(f, resolution) {
|
||||
return (resolution < 10) ? buildingStyle : null;
|
||||
tileGrid: ol.tilegrid.createXYZ({maxZoom: 19}),
|
||||
url: 'https://tile.mapzen.com/mapzen/vector/v1/all/{z}/{x}/{y}.topojson?api_key=' + key
|
||||
}),
|
||||
style: function(feature, resolution) {
|
||||
switch (feature.get('layer')) {
|
||||
case 'water': return waterStyle;
|
||||
case 'roads': return roadStyle(feature);
|
||||
case 'buildings': return (resolution < 10) ? buildingStyle : null;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
})
|
||||
],
|
||||
|
||||
@@ -177,7 +177,7 @@ function updateViewProjection() {
|
||||
});
|
||||
map.setView(newView);
|
||||
|
||||
// Example how to prevent double occurence of map by limiting layer extent
|
||||
// Example how to prevent double occurrence of map by limiting layer extent
|
||||
if (newProj == ol.proj.get('EPSG:3857')) {
|
||||
layers['bng'].setExtent([-1057216, 6405988, 404315, 8759696]);
|
||||
} else {
|
||||
|
||||
@@ -18,7 +18,7 @@ var map = new ol.Map({
|
||||
})
|
||||
}),
|
||||
view: new ol.View({
|
||||
center: [-25860000, 4130000],
|
||||
center: [14200000, 4130000],
|
||||
rotation: Math.PI / 6,
|
||||
zoom: 10
|
||||
})
|
||||
|
||||
@@ -29,6 +29,7 @@ tags: "draw, edit, modify, vector, snap"
|
||||
<option value="Point">Point</option>
|
||||
<option value="LineString">LineString</option>
|
||||
<option value="Polygon">Polygon</option>
|
||||
<option value="Circle">Circle</option>
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -81,6 +81,8 @@ var Draw = {
|
||||
this.LineString.setActive(false);
|
||||
map.addInteraction(this.Polygon);
|
||||
this.Polygon.setActive(false);
|
||||
map.addInteraction(this.Circle);
|
||||
this.Circle.setActive(false);
|
||||
},
|
||||
Point: new ol.interaction.Draw({
|
||||
source: vector.getSource(),
|
||||
@@ -94,6 +96,10 @@ var Draw = {
|
||||
source: vector.getSource(),
|
||||
type: /** @type {ol.geom.GeometryType} */ ('Polygon')
|
||||
}),
|
||||
Circle: new ol.interaction.Draw({
|
||||
source: vector.getSource(),
|
||||
type: /** @type {ol.geom.GeometryType} */ ('Circle')
|
||||
}),
|
||||
getActive: function() {
|
||||
return this.activeType ? this[this.activeType].getActive() : false;
|
||||
},
|
||||
|
||||
@@ -29,13 +29,14 @@ var style = new ol.style.Style({
|
||||
var vector = new ol.layer.Vector({
|
||||
source: new ol.source.Vector({
|
||||
url: 'data/topojson/world-110m.json',
|
||||
format: new ol.format.TopoJSON(),
|
||||
format: new ol.format.TopoJSON({
|
||||
// don't want to render the full world polygon (stored as 'land' layer),
|
||||
// which repeats all countries
|
||||
layers: ['countries']
|
||||
}),
|
||||
overlaps: false
|
||||
}),
|
||||
style: function(feature) {
|
||||
// don't want to render the full world polygon, which repeats all countries
|
||||
return feature.getId() !== undefined ? style : null;
|
||||
}
|
||||
style: style
|
||||
});
|
||||
|
||||
var map = new ol.Map({
|
||||
|
||||
@@ -3,7 +3,7 @@ layout: example.html
|
||||
title: WMS Time
|
||||
shortdesc: Example of smooth tile transitions when changing the time dimension of a tiled WMS layer.
|
||||
docs: >
|
||||
Demonstrates smooth reloading of layers when changing the time dimension continously. Data shown: IEM generated CONUS composite of NWS NEXRAD WSR-88D level III base reflectivity.
|
||||
Demonstrates smooth reloading of layers when changing the time dimension continuously. Data shown: IEM generated CONUS composite of NWS NEXRAD WSR-88D level III base reflectivity.
|
||||
tags: "wms, time, dimensions, transition, nexrad"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
|
||||
@@ -3,7 +3,7 @@ layout: example.html
|
||||
title: WMTS Tile Transitions
|
||||
shortdesc: Example of smooth tile transitions when changing the dimension of a WMTS layer.
|
||||
docs: >
|
||||
Demonstrates smooth reloading of layers when changing a dimension continously. The demonstration layer is a global sea-level computation (flooding computation from <a href="http://scalgo.com">SCALGO</a>, underlying data from <a href="http://www.cgiar-csi.org/data/srtm-90m-digital-elevation-database-v4-1">CGIAR-CSI SRTM</a>) where cells that are flooded if the sea-level rises to more than <em>x</em> m are colored blue. The user selects the sea-level dimension using a slider.
|
||||
Demonstrates smooth reloading of layers when changing a dimension continuously. The demonstration layer is a global sea-level computation (flooding computation from <a href="http://scalgo.com">SCALGO</a>, underlying data from <a href="http://www.cgiar-csi.org/data/srtm-90m-digital-elevation-database-v4-1">CGIAR-CSI SRTM</a>) where cells that are flooded if the sea-level rises to more than <em>x</em> m are colored blue. The user selects the sea-level dimension using a slider.
|
||||
tags: "wmts, parameter, transition"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
|
||||
245
externs/olx.js
245
externs/olx.js
@@ -112,7 +112,14 @@ olx.LogoOptions.prototype.src;
|
||||
* @typedef {{map: (ol.Map|undefined),
|
||||
* maxLines: (number|undefined),
|
||||
* strokeStyle: (ol.style.Stroke|undefined),
|
||||
* targetSize: (number|undefined)}}
|
||||
* targetSize: (number|undefined),
|
||||
* showLabels: (boolean|undefined),
|
||||
* lonLabelFormatter: (undefined|function(number):string),
|
||||
* latLabelFormatter: (undefined|function(number):string),
|
||||
* lonLabelPosition: (number|undefined),
|
||||
* latLabelPosition: (number|undefined),
|
||||
* lonLabelStyle: (ol.style.Text|undefined),
|
||||
* latLabelStyle: (ol.style.Text|undefined)}}
|
||||
*/
|
||||
olx.GraticuleOptions;
|
||||
|
||||
@@ -157,6 +164,106 @@ olx.GraticuleOptions.prototype.strokeStyle;
|
||||
olx.GraticuleOptions.prototype.targetSize;
|
||||
|
||||
|
||||
/**
|
||||
* Render a label with the respective latitude/longitude for each graticule
|
||||
* line. Default is false.
|
||||
*
|
||||
* @type {boolean|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.GraticuleOptions.prototype.showLabels;
|
||||
|
||||
|
||||
/**
|
||||
* Label formatter for longitudes. This function is called with the longitude as
|
||||
* argument, and should return a formatted string representing the longitude.
|
||||
* By default, labels are formatted as degrees, minutes, seconds and hemisphere.
|
||||
*
|
||||
* @type {undefined|function(number):string}
|
||||
* @api
|
||||
*/
|
||||
olx.GraticuleOptions.prototype.lonLabelFormatter;
|
||||
|
||||
|
||||
/**
|
||||
* Label formatter for latitudes. This function is called with the latitude as
|
||||
* argument, and should return a formatted string representing the latitude.
|
||||
* By default, labels are formatted as degrees, minutes, seconds and hemisphere.
|
||||
*
|
||||
* @type {undefined|function(number):string}
|
||||
* @api
|
||||
*/
|
||||
olx.GraticuleOptions.prototype.latLabelFormatter;
|
||||
|
||||
|
||||
/**
|
||||
* Longitude label position in fractions (0..1) of view extent. 0 means at the
|
||||
* bottom of the viewport, 1 means at the top. Default is 0.
|
||||
* @type {number|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.GraticuleOptions.prototype.lonLabelPosition;
|
||||
|
||||
|
||||
/**
|
||||
* Latitude label position in fractions (0..1) of view extent. 0 means at the
|
||||
* left of the viewport, 1 means at the right. Default is 1.
|
||||
* @type {number|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.GraticuleOptions.prototype.latLabelPosition;
|
||||
|
||||
|
||||
/**
|
||||
* Longitude label text style. The default is
|
||||
* ```js
|
||||
* new ol.style.Text({
|
||||
* font: '12px Calibri,sans-serif',
|
||||
* textBaseline: 'bottom',
|
||||
* fill: new ol.style.Fill({
|
||||
* color: 'rgba(0,0,0,1)'
|
||||
* }),
|
||||
* stroke: new ol.style.Stroke({
|
||||
* color: 'rgba(255,255,255,1)',
|
||||
* width: 3
|
||||
* })
|
||||
* });
|
||||
* ```
|
||||
* Note that the default's `textBaseline` configuration will not work well for
|
||||
* `lonLabelPosition` configurations that position labels close to the top of
|
||||
* the viewport.
|
||||
*
|
||||
* @type {ol.style.Text|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.GraticuleOptions.prototype.lonLabelStyle;
|
||||
|
||||
|
||||
/**
|
||||
* Latitude label text style. The default is
|
||||
* ```js
|
||||
* new ol.style.Text({
|
||||
* font: '12px Calibri,sans-serif',
|
||||
* textAlign: 'end',
|
||||
* fill: new ol.style.Fill({
|
||||
* color: 'rgba(0,0,0,1)'
|
||||
* }),
|
||||
* stroke: new ol.style.Stroke({
|
||||
* color: 'rgba(255,255,255,1)',
|
||||
* width: 3
|
||||
* })
|
||||
* });
|
||||
* ```
|
||||
* Note that the default's `textAlign` configuration will not work well for
|
||||
* `latLabelPosition` configurations that position labels close to the left of
|
||||
* the viewport.
|
||||
*
|
||||
* @type {ol.style.Text|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.GraticuleOptions.prototype.latLabelStyle;
|
||||
|
||||
|
||||
/**
|
||||
* Object literal with config options for interactions.
|
||||
* @typedef {{handleEvent: function(ol.MapBrowserEvent):boolean}}
|
||||
@@ -185,6 +292,7 @@ olx.interaction.InteractionOptions.prototype.handleEvent;
|
||||
* loadTilesWhileAnimating: (boolean|undefined),
|
||||
* loadTilesWhileInteracting: (boolean|undefined),
|
||||
* logo: (boolean|string|olx.LogoOptions|Element|undefined),
|
||||
* moveTolerance: (number|undefined),
|
||||
* overlays: (ol.Collection.<ol.Overlay>|Array.<ol.Overlay>|undefined),
|
||||
* renderer: (ol.renderer.Type|Array.<ol.renderer.Type>|undefined),
|
||||
* target: (Element|string|undefined),
|
||||
@@ -278,6 +386,17 @@ olx.MapOptions.prototype.loadTilesWhileInteracting;
|
||||
olx.MapOptions.prototype.logo;
|
||||
|
||||
|
||||
/**
|
||||
* The minimum distance in pixels the cursor must move to be detected
|
||||
* as a map move event instead of a click. Increasing this value can make it
|
||||
* easier to click on the map.
|
||||
* Default is `1`.
|
||||
* @type {number|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.MapOptions.prototype.moveTolerance;
|
||||
|
||||
|
||||
/**
|
||||
* Overlays initially added to the map. By default, no overlays are added.
|
||||
* @type {ol.Collection.<ol.Overlay>|Array.<ol.Overlay>|undefined}
|
||||
@@ -561,7 +680,8 @@ olx.ProjectionOptions.prototype.worldExtent;
|
||||
/**
|
||||
* Function to determine resolution at a point. The function is called with a
|
||||
* `{number}` view resolution and an `{ol.Coordinate}` as arguments, and returns
|
||||
* the `{number}` resolution at the passed coordinate.
|
||||
* the `{number}` resolution at the passed coordinate. If this is `undefined`,
|
||||
* the default {@link ol.proj#getPointResolution} function will be used.
|
||||
* @type {(function(number, ol.Coordinate):number|undefined)}
|
||||
* @api
|
||||
*/
|
||||
@@ -1874,9 +1994,9 @@ olx.format.MVTOptions;
|
||||
* {@link ol.Feature} to get full editing and geometry support at the cost of
|
||||
* decreased rendering performance. The default is {@link ol.render.Feature},
|
||||
* which is optimized for rendering and hit detection.
|
||||
* @type {undefined|function((ol.geom.Geometry|Object.<string, *>)=)|
|
||||
* @type {undefined|function((ol.geom.Geometry|Object.<string,*>)=)|
|
||||
* function(ol.geom.GeometryType,Array.<number>,
|
||||
* (Array.<number>|Array.<Array.<number>>),Object.<string, *>)}
|
||||
* (Array.<number>|Array.<Array.<number>>),Object.<string,*>,number)}
|
||||
* @api
|
||||
*/
|
||||
olx.format.MVTOptions.prototype.featureClass;
|
||||
@@ -1933,7 +2053,11 @@ olx.format.PolylineOptions.prototype.geometryLayout;
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{defaultDataProjection: ol.ProjectionLike}}
|
||||
* @typedef {{
|
||||
* defaultDataProjection: ol.ProjectionLike,
|
||||
* layerName: (string|undefined),
|
||||
* layers: (Array.<string>|undefined)
|
||||
* }}
|
||||
*/
|
||||
olx.format.TopoJSONOptions;
|
||||
|
||||
@@ -1946,6 +2070,38 @@ olx.format.TopoJSONOptions;
|
||||
olx.format.TopoJSONOptions.prototype.defaultDataProjection;
|
||||
|
||||
|
||||
/**
|
||||
* Set the name of the TopoJSON topology `objects`'s children as feature
|
||||
* property with the specified name. This means that when set to `'layer'`, a
|
||||
* topology like
|
||||
* ```
|
||||
* {
|
||||
* "type": "Topology",
|
||||
* "objects": {
|
||||
* "example": {
|
||||
* "type": "GeometryCollection",
|
||||
* "geometries": []
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
* will result in features that have a property `'layer'` set to `'example'`.
|
||||
* When not set, no property will be added to features.
|
||||
* @type {string|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.format.TopoJSONOptions.prototype.layerName;
|
||||
|
||||
|
||||
/**
|
||||
* Names of the TopoJSON topology's `objects`'s children to read features from.
|
||||
* If not provided, features will be read from all children.
|
||||
* @type {Array.<string>|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.format.TopoJSONOptions.prototype.layers;
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{altitudeMode: (ol.format.IGCZ|undefined)}}
|
||||
*/
|
||||
@@ -2299,6 +2455,7 @@ olx.format.WFSWriteGetFeatureOptions.prototype.resultType;
|
||||
* featureType: string,
|
||||
* srsName: (string|undefined),
|
||||
* handle: (string|undefined),
|
||||
* hasZ: (boolean|undefined),
|
||||
* nativeElements: Array.<Object>,
|
||||
* gmlOptions: (olx.format.GMLOptions|undefined),
|
||||
* version: (string|undefined)}}
|
||||
@@ -2347,6 +2504,15 @@ olx.format.WFSWriteTransactionOptions.prototype.srsName;
|
||||
olx.format.WFSWriteTransactionOptions.prototype.handle;
|
||||
|
||||
|
||||
/**
|
||||
* Must be set to true if the transaction is for a 3D layer. This will allow
|
||||
* the Z coordinate to be included in the transaction.
|
||||
* @type {boolean|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.format.WFSWriteTransactionOptions.prototype.hasZ;
|
||||
|
||||
|
||||
/**
|
||||
* Native elements. Currently not supported.
|
||||
* @type {Array.<Object>}
|
||||
@@ -2905,7 +3071,7 @@ olx.interaction.DrawOptions.prototype.wrapX;
|
||||
olx.interaction.ExtentOptions;
|
||||
|
||||
/**
|
||||
* Initial extent. Defaults to no inital extent
|
||||
* Initial extent. Defaults to no initial extent
|
||||
* @type {ol.Extent|undefined}
|
||||
* @api
|
||||
*/
|
||||
@@ -2970,7 +3136,7 @@ olx.interaction.TranslateOptions.prototype.layers;
|
||||
/**
|
||||
* Hit-detection tolerance. Pixels inside the radius around the given position
|
||||
* will be checked for features. This only works for the canvas renderer and
|
||||
* not for WebGL.
|
||||
* not for WebGL. Default is `0`.
|
||||
* @type {number|undefined}
|
||||
* @api
|
||||
*/
|
||||
@@ -3047,12 +3213,15 @@ olx.interaction.KeyboardZoomOptions.prototype.delta;
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{condition: (ol.EventsConditionType|undefined),
|
||||
* @typedef {{
|
||||
* condition: (ol.EventsConditionType|undefined),
|
||||
* deleteCondition: (ol.EventsConditionType|undefined),
|
||||
* insertVertexCondition: (ol.EventsConditionType|undefined),
|
||||
* pixelTolerance: (number|undefined),
|
||||
* style: (ol.style.Style|Array.<ol.style.Style>|ol.StyleFunction|undefined),
|
||||
* features: ol.Collection.<ol.Feature>,
|
||||
* wrapX: (boolean|undefined)}}
|
||||
* wrapX: (boolean|undefined)
|
||||
* }}
|
||||
*/
|
||||
olx.interaction.ModifyOptions;
|
||||
|
||||
@@ -3079,6 +3248,16 @@ olx.interaction.ModifyOptions.prototype.condition;
|
||||
olx.interaction.ModifyOptions.prototype.deleteCondition;
|
||||
|
||||
|
||||
/**
|
||||
* A function that takes an {@link ol.MapBrowserEvent} and returns a boolean
|
||||
* to indicate whether a new vertex can be added to the sketch features.
|
||||
* Default is {@link ol.events.condition.always}
|
||||
* @type {ol.EventsConditionType|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.interaction.ModifyOptions.prototype.insertVertexCondition;
|
||||
|
||||
|
||||
/**
|
||||
* Pixel tolerance for considering the pointer close enough to a segment or
|
||||
* vertex for editing. Default is `10`.
|
||||
@@ -3391,7 +3570,7 @@ olx.interaction.SelectOptions.prototype.wrapX;
|
||||
/**
|
||||
* Hit-detection tolerance. Pixels inside the radius around the given position
|
||||
* will be checked for features. This only works for the canvas renderer and
|
||||
* not for WebGL.
|
||||
* not for WebGL. Default is `0`.
|
||||
* @type {number|undefined}
|
||||
* @api
|
||||
*/
|
||||
@@ -4747,7 +4926,7 @@ olx.source.VectorTileOptions.prototype.state;
|
||||
|
||||
|
||||
/**
|
||||
* Class used to instantiate image tiles. Default is {@link ol.VectorTile}.
|
||||
* Class used to instantiate vector tiles. Default is {@link ol.VectorTile}.
|
||||
* @type {function(new: ol.VectorTile, ol.TileCoord,
|
||||
* ol.TileState, string, ol.format.Feature,
|
||||
* ol.TileLoadFunctionType)|undefined}
|
||||
@@ -5558,14 +5737,17 @@ olx.source.ImageWMSOptions.prototype.url;
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{cacheSize: (number|undefined),
|
||||
* @typedef {{
|
||||
* cacheSize: (number|undefined),
|
||||
* layer: string,
|
||||
* minZoom: (number|undefined),
|
||||
* maxZoom: (number|undefined),
|
||||
* opaque: (boolean|undefined),
|
||||
* reprojectionErrorThreshold: (number|undefined),
|
||||
* tileLoadFunction: (ol.TileLoadFunctionType|undefined),
|
||||
* url: (string|undefined)}}
|
||||
* url: (string|undefined),
|
||||
* wrapX: (boolean|undefined)
|
||||
* }}
|
||||
*/
|
||||
olx.source.StamenOptions;
|
||||
|
||||
@@ -5639,6 +5821,14 @@ olx.source.StamenOptions.prototype.tileLoadFunction;
|
||||
olx.source.StamenOptions.prototype.url;
|
||||
|
||||
|
||||
/**
|
||||
* Whether to wrap the world horizontally. Default is `true`.
|
||||
* @type {boolean|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.source.StamenOptions.prototype.wrapX;
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{attributions: (ol.AttributionLike|undefined),
|
||||
* crossOrigin: (null|string|undefined),
|
||||
@@ -5863,8 +6053,9 @@ olx.source.TileArcGISRestOptions.prototype.urls;
|
||||
* crossOrigin: (null|string|undefined),
|
||||
* jsonp: (boolean|undefined),
|
||||
* reprojectionErrorThreshold: (number|undefined),
|
||||
* tileJSON: (TileJSON|undefined),
|
||||
* tileLoadFunction: (ol.TileLoadFunctionType|undefined),
|
||||
* url: string,
|
||||
* url: (string|undefined),
|
||||
* wrapX: (boolean|undefined)}}
|
||||
*/
|
||||
olx.source.TileJSONOptions;
|
||||
@@ -5918,6 +6109,15 @@ olx.source.TileJSONOptions.prototype.jsonp;
|
||||
olx.source.TileJSONOptions.prototype.reprojectionErrorThreshold;
|
||||
|
||||
|
||||
/**
|
||||
* TileJSON configuration for this source. If not provided, `url` must be
|
||||
* configured.
|
||||
* @type {TileJSON|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.source.TileJSONOptions.prototype.tileJSON;
|
||||
|
||||
|
||||
/**
|
||||
* Optional function to load a tile given a URL. The default is
|
||||
* ```js
|
||||
@@ -5932,8 +6132,8 @@ olx.source.TileJSONOptions.prototype.tileLoadFunction;
|
||||
|
||||
|
||||
/**
|
||||
* URL to the TileJSON file.
|
||||
* @type {string}
|
||||
* URL to the TileJSON file. If not provided, `tileJSON` must be configured.
|
||||
* @type {string|undefined}
|
||||
* @api
|
||||
*/
|
||||
olx.source.TileJSONOptions.prototype.url;
|
||||
@@ -7721,7 +7921,8 @@ olx.view;
|
||||
* maxZoom: (number|undefined),
|
||||
* minResolution: (number|undefined),
|
||||
* duration: (number|undefined),
|
||||
* easing: (undefined|function(number):number)
|
||||
* easing: (undefined|function(number):number),
|
||||
* callback: (undefined|function(boolean))
|
||||
* }}
|
||||
*/
|
||||
olx.view.FitOptions;
|
||||
@@ -7799,6 +8000,16 @@ olx.view.FitOptions.prototype.duration;
|
||||
olx.view.FitOptions.prototype.easing;
|
||||
|
||||
|
||||
/**
|
||||
* Optional function called when the view is in it's final position. The callback will be
|
||||
* called with `true` if the animation series completed on its own or `false`
|
||||
* if it was cancelled.
|
||||
* @type {undefined|function(boolean)}
|
||||
* @api
|
||||
*/
|
||||
olx.view.FitOptions.prototype.callback;
|
||||
|
||||
|
||||
/* typedefs for object literals exposed by the library */
|
||||
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
69
package.json
69
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "openlayers",
|
||||
"version": "4.1.1",
|
||||
"version": "4.3.0-beta.2",
|
||||
"description": "Build tools and sources for developing OpenLayers based mapping applications",
|
||||
"keywords": [
|
||||
"map",
|
||||
@@ -13,6 +13,7 @@
|
||||
"postinstall": "closure-util update",
|
||||
"start": "node tasks/serve.js",
|
||||
"pretest": "eslint tasks test test_rendering src examples",
|
||||
"lint-package": "eslint --fix build/package",
|
||||
"test": "node tasks/test.js",
|
||||
"debug-server": "node tasks/serve-lib.js"
|
||||
},
|
||||
@@ -30,30 +31,33 @@
|
||||
"css/ol.css"
|
||||
],
|
||||
"dependencies": {
|
||||
"async": "2.3.0",
|
||||
"browserify": "14.3.0",
|
||||
"closure-util": "1.18.0",
|
||||
"async": "2.5.0",
|
||||
"closure-util": "1.22.0",
|
||||
"derequire": "2.0.6",
|
||||
"fs-extra": "2.1.2",
|
||||
"fs-extra": "4.0.0",
|
||||
"glob": "7.1.1",
|
||||
"handlebars": "4.0.6",
|
||||
"jsdoc": "3.4.3",
|
||||
"handlebars": "4.0.10",
|
||||
"jsdoc": "3.5.3",
|
||||
"marked": "0.3.6",
|
||||
"metalsmith": "2.3.0",
|
||||
"metalsmith-layouts": "1.8.0",
|
||||
"metalsmith-layouts": "1.8.1",
|
||||
"nomnom": "1.8.1",
|
||||
"pbf": "3.0.5",
|
||||
"pixelworks": "1.1.0",
|
||||
"rbush": "2.0.1",
|
||||
"rollup": "^0.45.0",
|
||||
"rollup-plugin-cleanup": "^1.0.0",
|
||||
"rollup-plugin-commonjs": "^8.0.2",
|
||||
"rollup-plugin-node-resolve": "^3.0.0",
|
||||
"temp": "0.8.3",
|
||||
"vector-tile": "1.3.0",
|
||||
"@mapbox/vector-tile": "1.3.0",
|
||||
"walk": "2.3.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"clean-css-cli": "4.0.12",
|
||||
"coveralls": "2.13.0",
|
||||
"clean-css-cli": "4.1.6",
|
||||
"coveralls": "2.13.1",
|
||||
"debounce": "^1.0.0",
|
||||
"eslint": "3.18.0",
|
||||
"eslint": "4.2.0",
|
||||
"eslint-config-openlayers": "7.0.0",
|
||||
"eslint-plugin-openlayers-internal": "^3.1.0",
|
||||
"expect.js": "0.3.1",
|
||||
@@ -61,14 +65,14 @@
|
||||
"istanbul": "0.4.5",
|
||||
"jquery": "3.2.1",
|
||||
"jscodeshift": "^0.3.30",
|
||||
"mocha": "3.2.0",
|
||||
"mocha": "3.4.2",
|
||||
"mocha-phantomjs-core": "^2.1.0",
|
||||
"mustache": "2.3.0",
|
||||
"phantomjs-prebuilt": "2.1.14",
|
||||
"proj4": "2.4.3",
|
||||
"resemblejs": "2.2.3",
|
||||
"resemblejs": "2.2.4",
|
||||
"serve-files": "1.0.1",
|
||||
"sinon": "2.1.0",
|
||||
"sinon": "2.3.8",
|
||||
"slimerjs": "0.10.3"
|
||||
},
|
||||
"eslintConfig": {
|
||||
@@ -91,31 +95,50 @@
|
||||
"no-constant-condition": 0,
|
||||
"openlayers-internal/enum": 2,
|
||||
"openlayers-internal/no-duplicate-requires": 2,
|
||||
"openlayers-internal/no-missing-requires": 1,
|
||||
"openlayers-internal/no-missing-requires": 2,
|
||||
"openlayers-internal/no-unused-requires": 2,
|
||||
"openlayers-internal/one-provide": 2,
|
||||
"openlayers-internal/requires-first": 2,
|
||||
"openlayers-internal/valid-provide": 2,
|
||||
"openlayers-internal/valid-requires": 2
|
||||
"openlayers-internal/valid-requires": 2,
|
||||
"indent": [
|
||||
2,
|
||||
2,
|
||||
{
|
||||
"VariableDeclarator": 2,
|
||||
"SwitchCase": 1,
|
||||
"MemberExpression": 2,
|
||||
"FunctionDeclaration": {
|
||||
"parameters": 2,
|
||||
"body": 1
|
||||
},
|
||||
"FunctionExpression": {
|
||||
"parameters": 2,
|
||||
"body": 1
|
||||
},
|
||||
"CallExpression": {
|
||||
"arguments": 2
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"ext": [
|
||||
{
|
||||
"module": "rbush",
|
||||
"browserify": true
|
||||
"module": "rbush"
|
||||
},
|
||||
{
|
||||
"module": "pbf",
|
||||
"browserify": true
|
||||
"name": "PBF"
|
||||
},
|
||||
{
|
||||
"module": "pixelworks",
|
||||
"browserify": true
|
||||
"import": "Processor"
|
||||
},
|
||||
{
|
||||
"module": "vector-tile",
|
||||
"module": "@mapbox/vector-tile",
|
||||
"name": "vectortile",
|
||||
"browserify": true
|
||||
"import": "VectorTile"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
5
package/.eslintrc
Normal file
5
package/.eslintrc
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"parserOptions": {
|
||||
"sourceType": "module"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ol",
|
||||
"version": "4.1.1",
|
||||
"version": "4.3.0-beta.2",
|
||||
"description": "OpenLayers as ES2015 modules",
|
||||
"main": "index.js",
|
||||
"module": "index.js",
|
||||
@@ -9,7 +9,7 @@
|
||||
"pbf": "3.0.5",
|
||||
"pixelworks": "1.1.0",
|
||||
"rbush": "2.0.1",
|
||||
"vector-tile": "1.3.0"
|
||||
"@mapbox/vector-tile": "1.3.0"
|
||||
},
|
||||
"browserify": {
|
||||
"transform": [
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
goog.provide('ol.Constraints');
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {ol.CenterConstraintType} centerConstraint Center constraint.
|
||||
* @param {ol.ResolutionConstraintType} resolutionConstraint
|
||||
* Resolution constraint.
|
||||
* @param {ol.RotationConstraintType} rotationConstraint
|
||||
* Rotation constraint.
|
||||
*/
|
||||
ol.Constraints = function(centerConstraint, resolutionConstraint, rotationConstraint) {
|
||||
|
||||
/**
|
||||
* @type {ol.CenterConstraintType}
|
||||
*/
|
||||
this.center = centerConstraint;
|
||||
|
||||
/**
|
||||
* @type {ol.ResolutionConstraintType}
|
||||
*/
|
||||
this.resolution = resolutionConstraint;
|
||||
|
||||
/**
|
||||
* @type {ol.RotationConstraintType}
|
||||
*/
|
||||
this.rotation = rotationConstraint;
|
||||
|
||||
};
|
||||
@@ -12,7 +12,7 @@ goog.require('ol.events.EventType');
|
||||
* @classdesc
|
||||
* Provides a button that when clicked fills up the full screen with the map.
|
||||
* The full screen source element is by default the element containing the map viewport unless
|
||||
* overriden by providing the `source` option. In which case, the dom
|
||||
* overridden by providing the `source` option. In which case, the dom
|
||||
* element introduced using this parameter will be displayed in full screen.
|
||||
*
|
||||
* When in full screen mode, a close button is shown to exit full screen mode.
|
||||
|
||||
@@ -47,7 +47,7 @@ ol.control.MousePosition = function(opt_options) {
|
||||
this.setCoordinateFormat(options.coordinateFormat);
|
||||
}
|
||||
if (options.projection) {
|
||||
this.setProjection(ol.proj.get(options.projection));
|
||||
this.setProjection(options.projection);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -192,13 +192,13 @@ ol.control.MousePosition.prototype.setCoordinateFormat = function(format) {
|
||||
|
||||
/**
|
||||
* Set the projection that is used to report the mouse position.
|
||||
* @param {ol.proj.Projection} projection The projection to report mouse
|
||||
* @param {ol.ProjectionLike} projection The projection to report mouse
|
||||
* position in.
|
||||
* @observable
|
||||
* @api
|
||||
*/
|
||||
ol.control.MousePosition.prototype.setProjection = function(projection) {
|
||||
this.set(ol.control.MousePosition.Property_.PROJECTION, projection);
|
||||
this.set(ol.control.MousePosition.Property_.PROJECTION, ol.proj.get(projection));
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -26,6 +26,37 @@ ol.coordinate.add = function(coordinate, delta) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calculates the point closest to the passed coordinate on the passed circle.
|
||||
*
|
||||
* @param {ol.Coordinate} coordinate The coordinate.
|
||||
* @param {ol.geom.Circle} circle The circle.
|
||||
* @return {ol.Coordinate} Closest point on the circumference
|
||||
*/
|
||||
ol.coordinate.closestOnCircle = function(coordinate, circle) {
|
||||
var r = circle.getRadius();
|
||||
var center = circle.getCenter();
|
||||
var x0 = center[0];
|
||||
var y0 = center[1];
|
||||
var x1 = coordinate[0];
|
||||
var y1 = coordinate[1];
|
||||
|
||||
var dx = x1 - x0;
|
||||
var dy = y1 - y0;
|
||||
if (dx === 0 && dy === 0) {
|
||||
dx = 1;
|
||||
}
|
||||
var d = Math.sqrt(dx * dx + dy * dy);
|
||||
|
||||
var x, y;
|
||||
|
||||
x = x0 + r * dx / d;
|
||||
y = y0 + r * dy / d;
|
||||
|
||||
return [x, y];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calculates the point closest to the passed coordinate on the passed segment.
|
||||
* This is the foot of the perpendicular of the coordinate to the segment when
|
||||
@@ -101,14 +132,13 @@ ol.coordinate.createStringXY = function(opt_fractionDigits) {
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {number} degrees Degrees.
|
||||
* @param {string} hemispheres Hemispheres.
|
||||
* @param {number} degrees Degrees.
|
||||
* @param {number=} opt_fractionDigits The number of digits to include
|
||||
* after the decimal point. Default is `0`.
|
||||
* @return {string} String.
|
||||
*/
|
||||
ol.coordinate.degreesToStringHDMS_ = function(degrees, hemispheres, opt_fractionDigits) {
|
||||
ol.coordinate.degreesToStringHDMS = function(hemispheres, degrees, opt_fractionDigits) {
|
||||
var normalizedDegrees = ol.math.modulo(degrees + 180, 360) - 180;
|
||||
var x = Math.abs(3600 * normalizedDegrees);
|
||||
var dflPrecision = opt_fractionDigits || 0;
|
||||
@@ -130,8 +160,8 @@ ol.coordinate.degreesToStringHDMS_ = function(degrees, hemispheres, opt_fraction
|
||||
}
|
||||
|
||||
return deg + '\u00b0 ' + ol.string.padNumber(min, 2) + '\u2032 ' +
|
||||
ol.string.padNumber(sec, 2, dflPrecision) + '\u2033 ' +
|
||||
hemispheres.charAt(normalizedDegrees < 0 ? 1 : 0);
|
||||
ol.string.padNumber(sec, 2, dflPrecision) + '\u2033' +
|
||||
(normalizedDegrees == 0 ? '' : ' ' + hemispheres.charAt(normalizedDegrees < 0 ? 1 : 0));
|
||||
};
|
||||
|
||||
|
||||
@@ -313,8 +343,8 @@ ol.coordinate.squaredDistanceToSegment = function(coordinate, segment) {
|
||||
*/
|
||||
ol.coordinate.toStringHDMS = function(coordinate, opt_fractionDigits) {
|
||||
if (coordinate) {
|
||||
return ol.coordinate.degreesToStringHDMS_(coordinate[1], 'NS', opt_fractionDigits) + ' ' +
|
||||
ol.coordinate.degreesToStringHDMS_(coordinate[0], 'EW', opt_fractionDigits);
|
||||
return ol.coordinate.degreesToStringHDMS('NS', coordinate[1], opt_fractionDigits) + ' ' +
|
||||
ol.coordinate.degreesToStringHDMS('EW', coordinate[0], opt_fractionDigits);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -47,15 +47,15 @@ ol.events.Event = function(type) {
|
||||
*/
|
||||
ol.events.Event.prototype.preventDefault =
|
||||
|
||||
/**
|
||||
/**
|
||||
* Stop event propagation.
|
||||
* @function
|
||||
* @override
|
||||
* @api
|
||||
*/
|
||||
ol.events.Event.prototype.stopPropagation = function() {
|
||||
ol.events.Event.prototype.stopPropagation = function() {
|
||||
this.propagationStopped = true;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -426,8 +426,10 @@ ol.extent.forEachCorner = function(extent, callback, opt_this) {
|
||||
|
||||
|
||||
/**
|
||||
* Get the size of an extent.
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @return {number} Area.
|
||||
* @api
|
||||
*/
|
||||
ol.extent.getArea = function(extent) {
|
||||
var area = 0;
|
||||
|
||||
@@ -121,9 +121,11 @@ ol.format.EsriJSON.convertRings_ = function(rings, layout) {
|
||||
// loop over all outer rings and see if they contain our hole.
|
||||
for (i = outerRings.length - 1; i >= 0; i--) {
|
||||
var outerRing = outerRings[i][0];
|
||||
if (ol.extent.containsExtent(new ol.geom.LinearRing(
|
||||
outerRing).getExtent(),
|
||||
new ol.geom.LinearRing(hole).getExtent())) {
|
||||
var containsHole = ol.extent.containsExtent(
|
||||
new ol.geom.LinearRing(outerRing).getExtent(),
|
||||
new ol.geom.LinearRing(hole).getExtent()
|
||||
);
|
||||
if (containsHole) {
|
||||
// the hole is contained push it into our polygon
|
||||
outerRings[i].push(hole);
|
||||
matched = true;
|
||||
|
||||
@@ -183,14 +183,14 @@ ol.format.Feature.transformWithOptions = function(
|
||||
// FIXME this is necessary because ol.format.GML treats extents
|
||||
// as geometries
|
||||
transformed = ol.proj.transformExtent(
|
||||
write ? geometry.slice() : geometry,
|
||||
write ? featureProjection : dataProjection,
|
||||
write ? dataProjection : featureProjection);
|
||||
geometry,
|
||||
dataProjection,
|
||||
featureProjection);
|
||||
}
|
||||
} else {
|
||||
transformed = geometry;
|
||||
}
|
||||
if (write && opt_options && opt_options.decimals) {
|
||||
if (write && opt_options && opt_options.decimals !== undefined) {
|
||||
var power = Math.pow(10, opt_options.decimals);
|
||||
// if decimals option on write, round each coordinate appropriately
|
||||
/**
|
||||
@@ -203,11 +203,10 @@ ol.format.Feature.transformWithOptions = function(
|
||||
}
|
||||
return coordinates;
|
||||
};
|
||||
if (Array.isArray(transformed)) {
|
||||
transform(transformed);
|
||||
} else {
|
||||
transformed.applyTransform(transform);
|
||||
if (transformed === geometry) {
|
||||
transformed = transformed.clone();
|
||||
}
|
||||
transformed.applyTransform(transform);
|
||||
}
|
||||
return transformed;
|
||||
};
|
||||
|
||||
@@ -2,6 +2,7 @@ goog.provide('ol.format.filter');
|
||||
|
||||
goog.require('ol.format.filter.And');
|
||||
goog.require('ol.format.filter.Bbox');
|
||||
goog.require('ol.format.filter.During');
|
||||
goog.require('ol.format.filter.EqualTo');
|
||||
goog.require('ol.format.filter.GreaterThan');
|
||||
goog.require('ol.format.filter.GreaterThanOrEqualTo');
|
||||
@@ -230,3 +231,17 @@ ol.format.filter.like = function(propertyName, pattern,
|
||||
return new ol.format.filter.IsLike(propertyName, pattern,
|
||||
opt_wildCard, opt_singleChar, opt_escapeChar, opt_matchCase);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create a `<During>` temporal operator.
|
||||
*
|
||||
* @param {!string} propertyName Name of the context property to compare.
|
||||
* @param {!string} begin The begin date in ISO-8601 format.
|
||||
* @param {!string} end The end date in ISO-8601 format.
|
||||
* @returns {!ol.format.filter.During} `<During>` operator.
|
||||
* @api
|
||||
*/
|
||||
ol.format.filter.during = function(propertyName, begin, end) {
|
||||
return new ol.format.filter.During(propertyName, begin, end);
|
||||
};
|
||||
|
||||
33
src/ol/format/filter/during.js
Normal file
33
src/ol/format/filter/during.js
Normal file
@@ -0,0 +1,33 @@
|
||||
goog.provide('ol.format.filter.During');
|
||||
|
||||
goog.require('ol');
|
||||
goog.require('ol.format.filter.Comparison');
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Represents a `<During>` comparison operator.
|
||||
*
|
||||
* @constructor
|
||||
* @param {!string} propertyName Name of the context property to compare.
|
||||
* @param {!string} begin The begin date in ISO-8601 format.
|
||||
* @param {!string} end The end date in ISO-8601 format.
|
||||
* @extends {ol.format.filter.Comparison}
|
||||
* @api
|
||||
*/
|
||||
ol.format.filter.During = function(propertyName, begin, end) {
|
||||
ol.format.filter.Comparison.call(this, 'During', propertyName);
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @type {!string}
|
||||
*/
|
||||
this.begin = begin;
|
||||
|
||||
/**
|
||||
* @public
|
||||
* @type {!string}
|
||||
*/
|
||||
this.end = end;
|
||||
};
|
||||
ol.inherits(ol.format.filter.During, ol.format.filter.Comparison);
|
||||
@@ -329,7 +329,8 @@ ol.format.GeoJSON.GEOMETRY_WRITERS_ = {
|
||||
/**
|
||||
* Read a feature from a GeoJSON Feature source. Only works for Feature or
|
||||
* geometry types. Use {@link ol.format.GeoJSON#readFeatures} to read
|
||||
* FeatureCollection source.
|
||||
* FeatureCollection source. If feature at source has an id, it will be used
|
||||
* as Feature id by calling {@link ol.Feature#setId} internally.
|
||||
*
|
||||
* @function
|
||||
* @param {Document|Node|Object|string} source Source.
|
||||
|
||||
@@ -353,6 +353,7 @@ ol.format.GML2.prototype.createCoordinatesNode_ = function(namespaceURI) {
|
||||
*/
|
||||
ol.format.GML2.prototype.writeCoordinates_ = function(node, value, objectStack) {
|
||||
var context = objectStack[objectStack.length - 1];
|
||||
var hasZ = context['hasZ'];
|
||||
var srsName = context['srsName'];
|
||||
// only 2d for simple features profile
|
||||
var points = value.getCoordinates();
|
||||
@@ -361,7 +362,7 @@ ol.format.GML2.prototype.writeCoordinates_ = function(node, value, objectStack)
|
||||
var point;
|
||||
for (var i = 0; i < len; ++i) {
|
||||
point = points[i];
|
||||
parts[i] = this.getCoords_(point, srsName);
|
||||
parts[i] = this.getCoords_(point, srsName, hasZ);
|
||||
}
|
||||
ol.format.XSD.writeStringTextNode(node, parts.join(' '));
|
||||
};
|
||||
@@ -389,6 +390,7 @@ ol.format.GML2.prototype.writeCurveSegments_ = function(node, line, objectStack)
|
||||
*/
|
||||
ol.format.GML2.prototype.writeSurfaceOrPolygon_ = function(node, geometry, objectStack) {
|
||||
var context = objectStack[objectStack.length - 1];
|
||||
var hasZ = context['hasZ'];
|
||||
var srsName = context['srsName'];
|
||||
if (node.nodeName !== 'PolygonPatch' && srsName) {
|
||||
node.setAttribute('srsName', srsName);
|
||||
@@ -396,7 +398,7 @@ ol.format.GML2.prototype.writeSurfaceOrPolygon_ = function(node, geometry, objec
|
||||
if (node.nodeName === 'Polygon' || node.nodeName === 'PolygonPatch') {
|
||||
var rings = geometry.getLinearRings();
|
||||
ol.xml.pushSerializeAndPop(
|
||||
{node: node, srsName: srsName},
|
||||
{node: node, hasZ: hasZ, srsName: srsName},
|
||||
ol.format.GML2.RING_SERIALIZERS_,
|
||||
this.RING_NODE_FACTORY_,
|
||||
rings, objectStack, undefined, this);
|
||||
@@ -457,17 +459,25 @@ ol.format.GML2.prototype.writeRing_ = function(node, ring, objectStack) {
|
||||
/**
|
||||
* @param {Array.<number>} point Point geometry.
|
||||
* @param {string=} opt_srsName Optional srsName
|
||||
* @param {boolean=} opt_hasZ whether the geometry has a Z coordinate (is 3D) or not.
|
||||
* @return {string} The coords string.
|
||||
* @private
|
||||
*/
|
||||
ol.format.GML2.prototype.getCoords_ = function(point, opt_srsName) {
|
||||
ol.format.GML2.prototype.getCoords_ = function(point, opt_srsName, opt_hasZ) {
|
||||
var axisOrientation = 'enu';
|
||||
if (opt_srsName) {
|
||||
axisOrientation = ol.proj.get(opt_srsName).getAxisOrientation();
|
||||
}
|
||||
return ((axisOrientation.substr(0, 2) === 'en') ?
|
||||
var coords = ((axisOrientation.substr(0, 2) === 'en') ?
|
||||
point[0] + ',' + point[1] :
|
||||
point[1] + ',' + point[0]);
|
||||
if (opt_hasZ) {
|
||||
// For newly created points, Z can be undefined.
|
||||
var z = point[2] || 0;
|
||||
coords += ',' + z;
|
||||
}
|
||||
|
||||
return coords;
|
||||
};
|
||||
|
||||
|
||||
@@ -479,13 +489,14 @@ ol.format.GML2.prototype.getCoords_ = function(point, opt_srsName) {
|
||||
*/
|
||||
ol.format.GML2.prototype.writeMultiCurveOrLineString_ = function(node, geometry, objectStack) {
|
||||
var context = objectStack[objectStack.length - 1];
|
||||
var hasZ = context['hasZ'];
|
||||
var srsName = context['srsName'];
|
||||
var curve = context['curve'];
|
||||
if (srsName) {
|
||||
node.setAttribute('srsName', srsName);
|
||||
}
|
||||
var lines = geometry.getLineStrings();
|
||||
ol.xml.pushSerializeAndPop({node: node, srsName: srsName, curve: curve},
|
||||
ol.xml.pushSerializeAndPop({node: node, hasZ: hasZ, srsName: srsName, curve: curve},
|
||||
ol.format.GML2.LINESTRINGORCURVEMEMBER_SERIALIZERS_,
|
||||
this.MULTIGEOMETRY_MEMBER_NODE_FACTORY_, lines,
|
||||
objectStack, undefined, this);
|
||||
@@ -500,6 +511,7 @@ ol.format.GML2.prototype.writeMultiCurveOrLineString_ = function(node, geometry,
|
||||
*/
|
||||
ol.format.GML2.prototype.writePoint_ = function(node, geometry, objectStack) {
|
||||
var context = objectStack[objectStack.length - 1];
|
||||
var hasZ = context['hasZ'];
|
||||
var srsName = context['srsName'];
|
||||
if (srsName) {
|
||||
node.setAttribute('srsName', srsName);
|
||||
@@ -507,7 +519,7 @@ ol.format.GML2.prototype.writePoint_ = function(node, geometry, objectStack) {
|
||||
var coordinates = this.createCoordinatesNode_(node.namespaceURI);
|
||||
node.appendChild(coordinates);
|
||||
var point = geometry.getCoordinates();
|
||||
var coord = this.getCoords_(point, srsName);
|
||||
var coord = this.getCoords_(point, srsName, hasZ);
|
||||
ol.format.XSD.writeStringTextNode(coordinates, coord);
|
||||
};
|
||||
|
||||
@@ -521,12 +533,13 @@ ol.format.GML2.prototype.writePoint_ = function(node, geometry, objectStack) {
|
||||
ol.format.GML2.prototype.writeMultiPoint_ = function(node, geometry,
|
||||
objectStack) {
|
||||
var context = objectStack[objectStack.length - 1];
|
||||
var hasZ = context['hasZ'];
|
||||
var srsName = context['srsName'];
|
||||
if (srsName) {
|
||||
node.setAttribute('srsName', srsName);
|
||||
}
|
||||
var points = geometry.getPoints();
|
||||
ol.xml.pushSerializeAndPop({node: node, srsName: srsName},
|
||||
ol.xml.pushSerializeAndPop({node: node, hasZ: hasZ, srsName: srsName},
|
||||
ol.format.GML2.POINTMEMBER_SERIALIZERS_,
|
||||
ol.xml.makeSimpleNodeFactory('pointMember'), points,
|
||||
objectStack, undefined, this);
|
||||
@@ -587,13 +600,14 @@ ol.format.GML2.prototype.writeLinearRing_ = function(node, geometry, objectStack
|
||||
*/
|
||||
ol.format.GML2.prototype.writeMultiSurfaceOrPolygon_ = function(node, geometry, objectStack) {
|
||||
var context = objectStack[objectStack.length - 1];
|
||||
var hasZ = context['hasZ'];
|
||||
var srsName = context['srsName'];
|
||||
var surface = context['surface'];
|
||||
if (srsName) {
|
||||
node.setAttribute('srsName', srsName);
|
||||
}
|
||||
var polygons = geometry.getPolygons();
|
||||
ol.xml.pushSerializeAndPop({node: node, srsName: srsName, surface: surface},
|
||||
ol.xml.pushSerializeAndPop({node: node, hasZ: hasZ, srsName: srsName, surface: surface},
|
||||
ol.format.GML2.SURFACEORPOLYGONMEMBER_SERIALIZERS_,
|
||||
this.MULTIGEOMETRY_MEMBER_NODE_FACTORY_, polygons,
|
||||
objectStack, undefined, this);
|
||||
|
||||
@@ -565,6 +565,7 @@ ol.format.GML3.prototype.SEGMENTS_PARSERS_ = {
|
||||
*/
|
||||
ol.format.GML3.prototype.writePos_ = function(node, value, objectStack) {
|
||||
var context = objectStack[objectStack.length - 1];
|
||||
var hasZ = context['hasZ'];
|
||||
var srsName = context['srsName'];
|
||||
var axisOrientation = 'enu';
|
||||
if (srsName) {
|
||||
@@ -578,6 +579,11 @@ ol.format.GML3.prototype.writePos_ = function(node, value, objectStack) {
|
||||
} else {
|
||||
coords = (point[1] + ' ' + point[0]);
|
||||
}
|
||||
if (hasZ) {
|
||||
// For newly created points, Z can be undefined.
|
||||
var z = point[2] || 0;
|
||||
coords += ' ' + z;
|
||||
}
|
||||
ol.format.XSD.writeStringTextNode(node, coords);
|
||||
};
|
||||
|
||||
@@ -585,17 +591,25 @@ ol.format.GML3.prototype.writePos_ = function(node, value, objectStack) {
|
||||
/**
|
||||
* @param {Array.<number>} point Point geometry.
|
||||
* @param {string=} opt_srsName Optional srsName
|
||||
* @param {boolean=} opt_hasZ whether the geometry has a Z coordinate (is 3D) or not.
|
||||
* @return {string} The coords string.
|
||||
* @private
|
||||
*/
|
||||
ol.format.GML3.prototype.getCoords_ = function(point, opt_srsName) {
|
||||
ol.format.GML3.prototype.getCoords_ = function(point, opt_srsName, opt_hasZ) {
|
||||
var axisOrientation = 'enu';
|
||||
if (opt_srsName) {
|
||||
axisOrientation = ol.proj.get(opt_srsName).getAxisOrientation();
|
||||
}
|
||||
return ((axisOrientation.substr(0, 2) === 'en') ?
|
||||
var coords = ((axisOrientation.substr(0, 2) === 'en') ?
|
||||
point[0] + ' ' + point[1] :
|
||||
point[1] + ' ' + point[0]);
|
||||
if (opt_hasZ) {
|
||||
// For newly created points, Z can be undefined.
|
||||
var z = point[2] || 0;
|
||||
coords += ' ' + z;
|
||||
}
|
||||
|
||||
return coords;
|
||||
};
|
||||
|
||||
|
||||
@@ -607,6 +621,7 @@ ol.format.GML3.prototype.getCoords_ = function(point, opt_srsName) {
|
||||
*/
|
||||
ol.format.GML3.prototype.writePosList_ = function(node, value, objectStack) {
|
||||
var context = objectStack[objectStack.length - 1];
|
||||
var hasZ = context['hasZ'];
|
||||
var srsName = context['srsName'];
|
||||
// only 2d for simple features profile
|
||||
var points = value.getCoordinates();
|
||||
@@ -615,7 +630,7 @@ ol.format.GML3.prototype.writePosList_ = function(node, value, objectStack) {
|
||||
var point;
|
||||
for (var i = 0; i < len; ++i) {
|
||||
point = points[i];
|
||||
parts[i] = this.getCoords_(point, srsName);
|
||||
parts[i] = this.getCoords_(point, srsName, hasZ);
|
||||
}
|
||||
ol.format.XSD.writeStringTextNode(node, parts.join(' '));
|
||||
};
|
||||
@@ -717,6 +732,7 @@ ol.format.GML3.prototype.RING_NODE_FACTORY_ = function(value, objectStack, opt_n
|
||||
*/
|
||||
ol.format.GML3.prototype.writeSurfaceOrPolygon_ = function(node, geometry, objectStack) {
|
||||
var context = objectStack[objectStack.length - 1];
|
||||
var hasZ = context['hasZ'];
|
||||
var srsName = context['srsName'];
|
||||
if (node.nodeName !== 'PolygonPatch' && srsName) {
|
||||
node.setAttribute('srsName', srsName);
|
||||
@@ -724,7 +740,7 @@ ol.format.GML3.prototype.writeSurfaceOrPolygon_ = function(node, geometry, objec
|
||||
if (node.nodeName === 'Polygon' || node.nodeName === 'PolygonPatch') {
|
||||
var rings = geometry.getLinearRings();
|
||||
ol.xml.pushSerializeAndPop(
|
||||
{node: node, srsName: srsName},
|
||||
{node: node, hasZ: hasZ, srsName: srsName},
|
||||
ol.format.GML3.RING_SERIALIZERS_,
|
||||
this.RING_NODE_FACTORY_,
|
||||
rings, objectStack, undefined, this);
|
||||
@@ -771,13 +787,14 @@ ol.format.GML3.prototype.writeCurveOrLineString_ = function(node, geometry, obje
|
||||
*/
|
||||
ol.format.GML3.prototype.writeMultiSurfaceOrPolygon_ = function(node, geometry, objectStack) {
|
||||
var context = objectStack[objectStack.length - 1];
|
||||
var hasZ = context['hasZ'];
|
||||
var srsName = context['srsName'];
|
||||
var surface = context['surface'];
|
||||
if (srsName) {
|
||||
node.setAttribute('srsName', srsName);
|
||||
}
|
||||
var polygons = geometry.getPolygons();
|
||||
ol.xml.pushSerializeAndPop({node: node, srsName: srsName, surface: surface},
|
||||
ol.xml.pushSerializeAndPop({node: node, hasZ: hasZ, srsName: srsName, surface: surface},
|
||||
ol.format.GML3.SURFACEORPOLYGONMEMBER_SERIALIZERS_,
|
||||
this.MULTIGEOMETRY_MEMBER_NODE_FACTORY_, polygons,
|
||||
objectStack, undefined, this);
|
||||
@@ -794,11 +811,12 @@ ol.format.GML3.prototype.writeMultiPoint_ = function(node, geometry,
|
||||
objectStack) {
|
||||
var context = objectStack[objectStack.length - 1];
|
||||
var srsName = context['srsName'];
|
||||
var hasZ = context['hasZ'];
|
||||
if (srsName) {
|
||||
node.setAttribute('srsName', srsName);
|
||||
}
|
||||
var points = geometry.getPoints();
|
||||
ol.xml.pushSerializeAndPop({node: node, srsName: srsName},
|
||||
ol.xml.pushSerializeAndPop({node: node, hasZ: hasZ, srsName: srsName},
|
||||
ol.format.GML3.POINTMEMBER_SERIALIZERS_,
|
||||
ol.xml.makeSimpleNodeFactory('pointMember'), points,
|
||||
objectStack, undefined, this);
|
||||
@@ -813,13 +831,14 @@ ol.format.GML3.prototype.writeMultiPoint_ = function(node, geometry,
|
||||
*/
|
||||
ol.format.GML3.prototype.writeMultiCurveOrLineString_ = function(node, geometry, objectStack) {
|
||||
var context = objectStack[objectStack.length - 1];
|
||||
var hasZ = context['hasZ'];
|
||||
var srsName = context['srsName'];
|
||||
var curve = context['curve'];
|
||||
if (srsName) {
|
||||
node.setAttribute('srsName', srsName);
|
||||
}
|
||||
var lines = geometry.getLineStrings();
|
||||
ol.xml.pushSerializeAndPop({node: node, srsName: srsName, curve: curve},
|
||||
ol.xml.pushSerializeAndPop({node: node, hasZ: hasZ, srsName: srsName, curve: curve},
|
||||
ol.format.GML3.LINESTRINGORCURVEMEMBER_SERIALIZERS_,
|
||||
this.MULTIGEOMETRY_MEMBER_NODE_FACTORY_, lines,
|
||||
objectStack, undefined, this);
|
||||
@@ -1168,7 +1187,7 @@ ol.format.GML3.prototype.GEOMETRY_NODE_FACTORY_ = function(value, objectStack, o
|
||||
ol.format.GML3.prototype.writeGeometryNode = function(geometry, opt_options) {
|
||||
opt_options = this.adaptOptions(opt_options);
|
||||
var geom = ol.xml.createElementNS('http://www.opengis.net/gml', 'geom');
|
||||
var context = {node: geom, srsName: this.srsName,
|
||||
var context = {node: geom, hasZ: this.hasZ, srsName: this.srsName,
|
||||
curve: this.curve_, surface: this.surface_,
|
||||
multiSurface: this.multiSurface_, multiCurve: this.multiCurve_};
|
||||
if (opt_options) {
|
||||
@@ -1208,6 +1227,7 @@ ol.format.GML3.prototype.writeFeaturesNode = function(features, opt_options) {
|
||||
'xsi:schemaLocation', this.schemaLocation);
|
||||
var context = {
|
||||
srsName: this.srsName,
|
||||
hasZ: this.hasZ,
|
||||
curve: this.curve_,
|
||||
surface: this.surface_,
|
||||
multiSurface: this.multiSurface_,
|
||||
|
||||
@@ -285,7 +285,8 @@ ol.format.KML.createStyleDefaults_ = function() {
|
||||
*/
|
||||
ol.format.KML.ICON_ANCHOR_UNITS_MAP_ = {
|
||||
'fraction': ol.style.IconAnchorUnits.FRACTION,
|
||||
'pixels': ol.style.IconAnchorUnits.PIXELS
|
||||
'pixels': ol.style.IconAnchorUnits.PIXELS,
|
||||
'insetPixels': ol.style.IconAnchorUnits.PIXELS
|
||||
};
|
||||
|
||||
|
||||
@@ -487,7 +488,7 @@ ol.format.KML.readFlatCoordinates_ = function(node) {
|
||||
*/
|
||||
ol.format.KML.readURI_ = function(node) {
|
||||
var s = ol.xml.getAllTextContent(node, false).trim();
|
||||
if (node.baseURI) {
|
||||
if (node.baseURI && node.baseURI !== 'about:blank') {
|
||||
var url = new URL(s, node.baseURI);
|
||||
return url.href;
|
||||
} else {
|
||||
@@ -504,11 +505,26 @@ ol.format.KML.readURI_ = function(node) {
|
||||
ol.format.KML.readVec2_ = function(node) {
|
||||
var xunits = node.getAttribute('xunits');
|
||||
var yunits = node.getAttribute('yunits');
|
||||
var origin;
|
||||
if (xunits !== 'insetPixels') {
|
||||
if (yunits !== 'insetPixels') {
|
||||
origin = ol.style.IconOrigin.BOTTOM_LEFT;
|
||||
} else {
|
||||
origin = ol.style.IconOrigin.TOP_LEFT;
|
||||
}
|
||||
} else {
|
||||
if (yunits !== 'insetPixels') {
|
||||
origin = ol.style.IconOrigin.BOTTOM_RIGHT;
|
||||
} else {
|
||||
origin = ol.style.IconOrigin.TOP_RIGHT;
|
||||
}
|
||||
}
|
||||
return {
|
||||
x: parseFloat(node.getAttribute('x')),
|
||||
xunits: ol.format.KML.ICON_ANCHOR_UNITS_MAP_[xunits],
|
||||
y: parseFloat(node.getAttribute('y')),
|
||||
yunits: ol.format.KML.ICON_ANCHOR_UNITS_MAP_[yunits]
|
||||
yunits: ol.format.KML.ICON_ANCHOR_UNITS_MAP_[yunits],
|
||||
origin: origin
|
||||
};
|
||||
};
|
||||
|
||||
@@ -533,7 +549,7 @@ ol.format.KML.readStyleMapValue_ = function(node, objectStack) {
|
||||
return ol.xml.pushParseAndPop(undefined,
|
||||
ol.format.KML.STYLE_MAP_PARSERS_, node, objectStack);
|
||||
};
|
||||
/**
|
||||
/**
|
||||
* @param {Node} node Node.
|
||||
* @param {Array.<*>} objectStack Object stack.
|
||||
* @private
|
||||
@@ -562,12 +578,14 @@ ol.format.KML.IconStyleParser_ = function(node, objectStack) {
|
||||
src = ol.format.KML.DEFAULT_IMAGE_STYLE_SRC_;
|
||||
}
|
||||
var anchor, anchorXUnits, anchorYUnits;
|
||||
var anchorOrigin = ol.style.IconOrigin.BOTTOM_LEFT;
|
||||
var hotSpot = /** @type {ol.KMLVec2_|undefined} */
|
||||
(object['hotSpot']);
|
||||
if (hotSpot) {
|
||||
anchor = [hotSpot.x, hotSpot.y];
|
||||
anchorXUnits = hotSpot.xunits;
|
||||
anchorYUnits = hotSpot.yunits;
|
||||
anchorOrigin = hotSpot.origin;
|
||||
} else if (src === ol.format.KML.DEFAULT_IMAGE_STYLE_SRC_) {
|
||||
anchor = ol.format.KML.DEFAULT_IMAGE_STYLE_ANCHOR_;
|
||||
anchorXUnits = ol.format.KML.DEFAULT_IMAGE_STYLE_ANCHOR_X_UNITS_;
|
||||
@@ -616,7 +634,7 @@ ol.format.KML.IconStyleParser_ = function(node, objectStack) {
|
||||
|
||||
var imageStyle = new ol.style.Icon({
|
||||
anchor: anchor,
|
||||
anchorOrigin: ol.style.IconOrigin.BOTTOM_LEFT,
|
||||
anchorOrigin: anchorOrigin,
|
||||
anchorXUnits: anchorXUnits,
|
||||
anchorYUnits: anchorYUnits,
|
||||
crossOrigin: 'anonymous', // FIXME should this be configurable?
|
||||
@@ -1074,13 +1092,13 @@ ol.format.KML.setCommonGeometryProperties_ = function(multiGeometry,
|
||||
ol.format.KML.DataParser_ = function(node, objectStack) {
|
||||
var name = node.getAttribute('name');
|
||||
ol.xml.parseNode(ol.format.KML.DATA_PARSERS_, node, objectStack);
|
||||
var featureObject =
|
||||
/** @type {Object} */ (objectStack[objectStack.length - 1]);
|
||||
var featureObject = /** @type {Object} */ (objectStack[objectStack.length - 1]);
|
||||
if (name !== null) {
|
||||
featureObject[name] = featureObject.value;
|
||||
} else if (featureObject.displayName !== null) {
|
||||
featureObject[featureObject.displayName] = featureObject.value;
|
||||
}
|
||||
delete featureObject['value'];
|
||||
};
|
||||
|
||||
|
||||
@@ -1719,7 +1737,7 @@ ol.format.KML.prototype.readSharedStyle_ = function(node, objectStack) {
|
||||
var style = ol.format.KML.readStyle_(node, objectStack);
|
||||
if (style) {
|
||||
var styleUri;
|
||||
if (node.baseURI) {
|
||||
if (node.baseURI && node.baseURI !== 'about:blank') {
|
||||
var url = new URL('#' + id, node.baseURI);
|
||||
styleUri = url.href;
|
||||
} else {
|
||||
@@ -1746,7 +1764,7 @@ ol.format.KML.prototype.readSharedStyleMap_ = function(node, objectStack) {
|
||||
return;
|
||||
}
|
||||
var styleUri;
|
||||
if (node.baseURI) {
|
||||
if (node.baseURI && node.baseURI !== 'about:blank') {
|
||||
var url = new URL('#' + id, node.baseURI);
|
||||
styleUri = url.href;
|
||||
} else {
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
goog.provide('ol.format.MVT');
|
||||
|
||||
goog.require('ol');
|
||||
goog.require('ol.ext.pbf');
|
||||
goog.require('ol.ext.vectortile');
|
||||
goog.require('ol.ext.PBF');
|
||||
goog.require('ol.ext.vectortile.VectorTile');
|
||||
goog.require('ol.format.Feature');
|
||||
goog.require('ol.format.FormatType');
|
||||
goog.require('ol.geom.GeometryLayout');
|
||||
@@ -44,9 +44,9 @@ ol.format.MVT = function(opt_options) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {function((ol.geom.Geometry|Object.<string, *>)=)|
|
||||
* @type {function((ol.geom.Geometry|Object.<string,*>)=)|
|
||||
* function(ol.geom.GeometryType,Array.<number>,
|
||||
* (Array.<number>|Array.<Array.<number>>),Object.<string, *>)}
|
||||
* (Array.<number>|Array.<Array.<number>>),Object.<string,*>,number)}
|
||||
*/
|
||||
this.featureClass_ = options.featureClass ?
|
||||
options.featureClass : ol.render.Feature;
|
||||
@@ -137,8 +137,9 @@ ol.format.MVT.prototype.readRenderFeature_ = function(rawFeature, layer) {
|
||||
|
||||
var values = rawFeature.properties;
|
||||
values[this.layerName_] = layer;
|
||||
var id = rawFeature.id;
|
||||
|
||||
return new this.featureClass_(geometryType, flatCoordinates, ends, values);
|
||||
return new this.featureClass_(geometryType, flatCoordinates, ends, values, id);
|
||||
};
|
||||
|
||||
|
||||
@@ -149,7 +150,7 @@ ol.format.MVT.prototype.readRenderFeature_ = function(rawFeature, layer) {
|
||||
ol.format.MVT.prototype.readFeatures = function(source, opt_options) {
|
||||
var layers = this.layers_;
|
||||
|
||||
var pbf = new ol.ext.pbf(/** @type {ArrayBuffer} */ (source));
|
||||
var pbf = new ol.ext.PBF(/** @type {ArrayBuffer} */ (source));
|
||||
var tile = new ol.ext.vectortile.VectorTile(pbf);
|
||||
var features = [];
|
||||
var featureClass = this.featureClass_;
|
||||
|
||||
@@ -10,7 +10,6 @@ goog.require('ol.geom.MultiPoint');
|
||||
goog.require('ol.geom.MultiPolygon');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.geom.Polygon');
|
||||
goog.require('ol.obj');
|
||||
goog.require('ol.proj');
|
||||
|
||||
|
||||
@@ -29,6 +28,18 @@ ol.format.TopoJSON = function(opt_options) {
|
||||
|
||||
ol.format.JSONFeature.call(this);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
*/
|
||||
this.layerName_ = options.layerName;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array.<string>}
|
||||
*/
|
||||
this.layers_ = options.layers ? options.layers : null;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@@ -202,18 +213,21 @@ ol.format.TopoJSON.readMultiPolygonGeometry_ = function(object, arcs) {
|
||||
* @param {Array.<Array.<ol.Coordinate>>} arcs Array of arcs.
|
||||
* @param {Array.<number>} scale Scale for each dimension.
|
||||
* @param {Array.<number>} translate Translation for each dimension.
|
||||
* @param {string|undefined} property Property to set the `GeometryCollection`'s parent
|
||||
* object to.
|
||||
* @param {string} name Name of the `Topology`'s child object.
|
||||
* @param {olx.format.ReadOptions=} opt_options Read options.
|
||||
* @return {Array.<ol.Feature>} Array of features.
|
||||
* @private
|
||||
*/
|
||||
ol.format.TopoJSON.readFeaturesFromGeometryCollection_ = function(
|
||||
collection, arcs, scale, translate, opt_options) {
|
||||
collection, arcs, scale, translate, property, name, opt_options) {
|
||||
var geometries = collection.geometries;
|
||||
var features = [];
|
||||
var i, ii;
|
||||
for (i = 0, ii = geometries.length; i < ii; ++i) {
|
||||
features[i] = ol.format.TopoJSON.readFeatureFromGeometry_(
|
||||
geometries[i], arcs, scale, translate, opt_options);
|
||||
geometries[i], arcs, scale, translate, property, name, opt_options);
|
||||
}
|
||||
return features;
|
||||
};
|
||||
@@ -226,12 +240,15 @@ ol.format.TopoJSON.readFeaturesFromGeometryCollection_ = function(
|
||||
* @param {Array.<Array.<ol.Coordinate>>} arcs Array of arcs.
|
||||
* @param {Array.<number>} scale Scale for each dimension.
|
||||
* @param {Array.<number>} translate Translation for each dimension.
|
||||
* @param {string|undefined} property Property to set the `GeometryCollection`'s parent
|
||||
* object to.
|
||||
* @param {string} name Name of the `Topology`'s child object.
|
||||
* @param {olx.format.ReadOptions=} opt_options Read options.
|
||||
* @return {ol.Feature} Feature.
|
||||
* @private
|
||||
*/
|
||||
ol.format.TopoJSON.readFeatureFromGeometry_ = function(object, arcs,
|
||||
scale, translate, opt_options) {
|
||||
scale, translate, property, name, opt_options) {
|
||||
var geometry;
|
||||
var type = object.type;
|
||||
var geometryReader = ol.format.TopoJSON.GEOMETRY_READERS_[type];
|
||||
@@ -246,8 +263,15 @@ ol.format.TopoJSON.readFeatureFromGeometry_ = function(object, arcs,
|
||||
if (object.id !== undefined) {
|
||||
feature.setId(object.id);
|
||||
}
|
||||
if (object.properties) {
|
||||
feature.setProperties(object.properties);
|
||||
var properties = object.properties;
|
||||
if (property) {
|
||||
if (!properties) {
|
||||
properties = {};
|
||||
}
|
||||
properties[property] = name;
|
||||
}
|
||||
if (properties) {
|
||||
feature.setProperties(properties);
|
||||
}
|
||||
return feature;
|
||||
};
|
||||
@@ -283,21 +307,24 @@ ol.format.TopoJSON.prototype.readFeaturesFromObject = function(
|
||||
}
|
||||
/** @type {Array.<ol.Feature>} */
|
||||
var features = [];
|
||||
var topoJSONFeatures = ol.obj.getValues(topoJSONTopology.objects);
|
||||
var i, ii;
|
||||
var feature;
|
||||
for (i = 0, ii = topoJSONFeatures.length; i < ii; ++i) {
|
||||
if (topoJSONFeatures[i].type === 'GeometryCollection') {
|
||||
var topoJSONFeatures = topoJSONTopology.objects;
|
||||
var property = this.layerName_;
|
||||
var objectName, feature;
|
||||
for (objectName in topoJSONFeatures) {
|
||||
if (this.layers_ && this.layers_.indexOf(objectName) == -1) {
|
||||
continue;
|
||||
}
|
||||
if (topoJSONFeatures[objectName].type === 'GeometryCollection') {
|
||||
feature = /** @type {TopoJSONGeometryCollection} */
|
||||
(topoJSONFeatures[i]);
|
||||
(topoJSONFeatures[objectName]);
|
||||
features.push.apply(features,
|
||||
ol.format.TopoJSON.readFeaturesFromGeometryCollection_(
|
||||
feature, arcs, scale, translate, opt_options));
|
||||
feature, arcs, scale, translate, property, objectName, opt_options));
|
||||
} else {
|
||||
feature = /** @type {TopoJSONGeometry} */
|
||||
(topoJSONFeatures[i]);
|
||||
(topoJSONFeatures[objectName]);
|
||||
features.push(ol.format.TopoJSON.readFeatureFromGeometry_(
|
||||
feature, arcs, scale, translate, opt_options));
|
||||
feature, arcs, scale, translate, property, objectName, opt_options));
|
||||
}
|
||||
}
|
||||
return features;
|
||||
|
||||
@@ -90,6 +90,13 @@ ol.format.WFS.OGCNS = 'http://www.opengis.net/ogc';
|
||||
ol.format.WFS.WFSNS = 'http://www.opengis.net/wfs';
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
ol.format.WFS.FESNS = 'http://www.opengis.net/fes';
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {Object.<string, string>}
|
||||
@@ -399,6 +406,25 @@ ol.format.WFS.writeOgcFidFilter_ = function(node, fid, objectStack) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string|undefined} featurePrefix The prefix of the feature.
|
||||
* @param {string} featureType The type of the feature.
|
||||
* @returns {string} The value of the typeName property.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WFS.getTypeName_ = function(featurePrefix, featureType) {
|
||||
featurePrefix = featurePrefix ? featurePrefix :
|
||||
ol.format.WFS.FEATURE_PREFIX;
|
||||
var prefix = featurePrefix + ':';
|
||||
// The featureType already contains the prefix.
|
||||
if (featureType.indexOf(prefix) === 0) {
|
||||
return featureType;
|
||||
} else {
|
||||
return prefix + featureType;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Node} node Node.
|
||||
* @param {ol.Feature} feature Feature.
|
||||
@@ -410,10 +436,9 @@ ol.format.WFS.writeDelete_ = function(node, feature, objectStack) {
|
||||
ol.asserts.assert(feature.getId() !== undefined, 26); // Features must have an id set
|
||||
var featureType = context['featureType'];
|
||||
var featurePrefix = context['featurePrefix'];
|
||||
featurePrefix = featurePrefix ? featurePrefix :
|
||||
ol.format.WFS.FEATURE_PREFIX;
|
||||
var featureNS = context['featureNS'];
|
||||
node.setAttribute('typeName', featurePrefix + ':' + featureType);
|
||||
var typeName = ol.format.WFS.getTypeName_(featurePrefix, featureType);
|
||||
node.setAttribute('typeName', typeName);
|
||||
ol.xml.setAttributeNS(node, ol.format.WFS.XMLNS, 'xmlns:' + featurePrefix,
|
||||
featureNS);
|
||||
var fid = feature.getId();
|
||||
@@ -434,10 +459,9 @@ ol.format.WFS.writeUpdate_ = function(node, feature, objectStack) {
|
||||
ol.asserts.assert(feature.getId() !== undefined, 27); // Features must have an id set
|
||||
var featureType = context['featureType'];
|
||||
var featurePrefix = context['featurePrefix'];
|
||||
featurePrefix = featurePrefix ? featurePrefix :
|
||||
ol.format.WFS.FEATURE_PREFIX;
|
||||
var featureNS = context['featureNS'];
|
||||
node.setAttribute('typeName', featurePrefix + ':' + featureType);
|
||||
var typeName = ol.format.WFS.getTypeName_(featurePrefix, featureType);
|
||||
node.setAttribute('typeName', typeName);
|
||||
ol.xml.setAttributeNS(node, ol.format.WFS.XMLNS, 'xmlns:' + featurePrefix,
|
||||
featureNS);
|
||||
var fid = feature.getId();
|
||||
@@ -452,7 +476,7 @@ ol.format.WFS.writeUpdate_ = function(node, feature, objectStack) {
|
||||
}
|
||||
ol.xml.pushSerializeAndPop(/** @type {ol.XmlNodeStackItem} */ (
|
||||
{'gmlVersion': context['gmlVersion'], node: node,
|
||||
'srsName': context['srsName']}),
|
||||
'hasZ': context['hasZ'], 'srsName': context['srsName']}),
|
||||
ol.format.WFS.TRANSACTION_SERIALIZERS_,
|
||||
ol.xml.makeSimpleNodeFactory('Property'), values,
|
||||
objectStack);
|
||||
@@ -538,8 +562,14 @@ ol.format.WFS.writeQuery_ = function(node, featureType, objectStack) {
|
||||
var featureNS = context['featureNS'];
|
||||
var propertyNames = context['propertyNames'];
|
||||
var srsName = context['srsName'];
|
||||
var prefix = featurePrefix ? featurePrefix + ':' : '';
|
||||
node.setAttribute('typeName', prefix + featureType);
|
||||
var typeName;
|
||||
// If feature prefix is not defined, we must not use the default prefix.
|
||||
if (featurePrefix) {
|
||||
typeName = ol.format.WFS.getTypeName_(featurePrefix, featureType);
|
||||
} else {
|
||||
typeName = featureType;
|
||||
}
|
||||
node.setAttribute('typeName', typeName);
|
||||
if (srsName) {
|
||||
node.setAttribute('srsName', srsName);
|
||||
}
|
||||
@@ -623,6 +653,32 @@ ol.format.WFS.writeWithinFilter_ = function(node, filter, objectStack) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Node} node Node.
|
||||
* @param {ol.format.filter.During} filter Filter.
|
||||
* @param {Array.<*>} objectStack Node stack.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WFS.writeDuringFilter_ = function(node, filter, objectStack) {
|
||||
|
||||
var valueReference = ol.xml.createElementNS(ol.format.WFS.FESNS, 'ValueReference');
|
||||
ol.format.XSD.writeStringTextNode(valueReference, filter.propertyName);
|
||||
node.appendChild(valueReference);
|
||||
|
||||
var timePeriod = ol.xml.createElementNS(ol.format.GMLBase.GMLNS, 'TimePeriod');
|
||||
|
||||
node.appendChild(timePeriod);
|
||||
|
||||
var begin = ol.xml.createElementNS(ol.format.GMLBase.GMLNS, 'begin');
|
||||
timePeriod.appendChild(begin);
|
||||
ol.format.WFS.writeTimeInstant_(begin, filter.begin);
|
||||
|
||||
var end = ol.xml.createElementNS(ol.format.GMLBase.GMLNS, 'end');
|
||||
timePeriod.appendChild(end);
|
||||
ol.format.WFS.writeTimeInstant_(end, filter.end);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Node} node Node.
|
||||
* @param {ol.format.filter.LogicalNary} filter Filter.
|
||||
@@ -754,6 +810,21 @@ ol.format.WFS.writeOgcLiteral_ = function(node, value) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Node} node Node.
|
||||
* @param {string} time PropertyName value.
|
||||
* @private
|
||||
*/
|
||||
ol.format.WFS.writeTimeInstant_ = function(node, time) {
|
||||
var timeInstant = ol.xml.createElementNS(ol.format.GMLBase.GMLNS, 'TimeInstant');
|
||||
node.appendChild(timeInstant);
|
||||
|
||||
var timePosition = ol.xml.createElementNS(ol.format.GMLBase.GMLNS, 'timePosition');
|
||||
timeInstant.appendChild(timePosition);
|
||||
ol.format.XSD.writeStringTextNode(timePosition, time);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @type {Object.<string, Object.<string, ol.XmlSerializer>>}
|
||||
* @private
|
||||
@@ -763,6 +834,7 @@ ol.format.WFS.GETFEATURE_SERIALIZERS_ = {
|
||||
'Query': ol.xml.makeChildAppender(ol.format.WFS.writeQuery_)
|
||||
},
|
||||
'http://www.opengis.net/ogc': {
|
||||
'During': ol.xml.makeChildAppender(ol.format.WFS.writeDuringFilter_),
|
||||
'And': ol.xml.makeChildAppender(ol.format.WFS.writeLogicalFilter_),
|
||||
'Or': ol.xml.makeChildAppender(ol.format.WFS.writeLogicalFilter_),
|
||||
'Not': ol.xml.makeChildAppender(ol.format.WFS.writeNotFilter_),
|
||||
@@ -908,10 +980,11 @@ ol.format.WFS.prototype.writeTransaction = function(inserts, updates, deletes,
|
||||
var schemaLocation = ol.format.WFS.SCHEMA_LOCATIONS[version];
|
||||
ol.xml.setAttributeNS(node, 'http://www.w3.org/2001/XMLSchema-instance',
|
||||
'xsi:schemaLocation', schemaLocation);
|
||||
var featurePrefix = options.featurePrefix ? options.featurePrefix : ol.format.WFS.FEATURE_PREFIX;
|
||||
if (inserts) {
|
||||
obj = {node: node, 'featureNS': options.featureNS,
|
||||
'featureType': options.featureType, 'featurePrefix': options.featurePrefix,
|
||||
'gmlVersion': gmlVersion, 'srsName': options.srsName};
|
||||
'featureType': options.featureType, 'featurePrefix': featurePrefix,
|
||||
'gmlVersion': gmlVersion, 'hasZ': options.hasZ, 'srsName': options.srsName};
|
||||
ol.obj.assign(obj, baseObj);
|
||||
ol.xml.pushSerializeAndPop(obj,
|
||||
ol.format.WFS.TRANSACTION_SERIALIZERS_,
|
||||
@@ -920,8 +993,8 @@ ol.format.WFS.prototype.writeTransaction = function(inserts, updates, deletes,
|
||||
}
|
||||
if (updates) {
|
||||
obj = {node: node, 'featureNS': options.featureNS,
|
||||
'featureType': options.featureType, 'featurePrefix': options.featurePrefix,
|
||||
'gmlVersion': gmlVersion, 'srsName': options.srsName};
|
||||
'featureType': options.featureType, 'featurePrefix': featurePrefix,
|
||||
'gmlVersion': gmlVersion, 'hasZ': options.hasZ, 'srsName': options.srsName};
|
||||
ol.obj.assign(obj, baseObj);
|
||||
ol.xml.pushSerializeAndPop(obj,
|
||||
ol.format.WFS.TRANSACTION_SERIALIZERS_,
|
||||
@@ -930,7 +1003,7 @@ ol.format.WFS.prototype.writeTransaction = function(inserts, updates, deletes,
|
||||
}
|
||||
if (deletes) {
|
||||
ol.xml.pushSerializeAndPop({node: node, 'featureNS': options.featureNS,
|
||||
'featureType': options.featureType, 'featurePrefix': options.featurePrefix,
|
||||
'featureType': options.featureType, 'featurePrefix': featurePrefix,
|
||||
'gmlVersion': gmlVersion, 'srsName': options.srsName},
|
||||
ol.format.WFS.TRANSACTION_SERIALIZERS_,
|
||||
ol.xml.makeSimpleNodeFactory('Delete'), deletes,
|
||||
@@ -938,7 +1011,7 @@ ol.format.WFS.prototype.writeTransaction = function(inserts, updates, deletes,
|
||||
}
|
||||
if (options.nativeElements) {
|
||||
ol.xml.pushSerializeAndPop({node: node, 'featureNS': options.featureNS,
|
||||
'featureType': options.featureType, 'featurePrefix': options.featurePrefix,
|
||||
'featureType': options.featureType, 'featurePrefix': featurePrefix,
|
||||
'gmlVersion': gmlVersion, 'srsName': options.srsName},
|
||||
ol.format.WFS.TRANSACTION_SERIALIZERS_,
|
||||
ol.xml.makeSimpleNodeFactory('Native'), options.nativeElements,
|
||||
|
||||
@@ -3,15 +3,16 @@
|
||||
goog.provide('ol.Geolocation');
|
||||
|
||||
goog.require('ol');
|
||||
goog.require('ol.Object');
|
||||
goog.require('ol.GeolocationProperty');
|
||||
goog.require('ol.Object');
|
||||
goog.require('ol.Sphere');
|
||||
goog.require('ol.events');
|
||||
goog.require('ol.events.EventType');
|
||||
goog.require('ol.geom.Polygon');
|
||||
goog.require('ol.has');
|
||||
goog.require('ol.math');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.sphere.WGS84');
|
||||
goog.require('ol.proj.EPSG4326');
|
||||
|
||||
|
||||
/**
|
||||
@@ -59,6 +60,12 @@ ol.Geolocation = function(opt_options) {
|
||||
*/
|
||||
this.transform_ = ol.proj.identityTransform;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Sphere}
|
||||
*/
|
||||
this.sphere_ = new ol.Sphere(ol.proj.EPSG4326.RADIUS);
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
@@ -73,7 +80,7 @@ ol.Geolocation = function(opt_options) {
|
||||
this.handleTrackingChanged_, this);
|
||||
|
||||
if (options.projection !== undefined) {
|
||||
this.setProjection(ol.proj.get(options.projection));
|
||||
this.setProjection(options.projection);
|
||||
}
|
||||
if (options.trackingOptions !== undefined) {
|
||||
this.setTrackingOptions(options.trackingOptions);
|
||||
@@ -154,7 +161,7 @@ ol.Geolocation.prototype.positionChange_ = function(position) {
|
||||
this.set(ol.GeolocationProperty.SPEED,
|
||||
coords.speed === null ? undefined : coords.speed);
|
||||
var geometry = ol.geom.Polygon.circular(
|
||||
ol.sphere.WGS84, this.position_, coords.accuracy);
|
||||
this.sphere_, this.position_, coords.accuracy);
|
||||
geometry.applyTransform(this.transform_);
|
||||
this.set(ol.GeolocationProperty.ACCURACY_GEOMETRY, geometry);
|
||||
this.changed();
|
||||
@@ -308,13 +315,13 @@ ol.Geolocation.prototype.getTrackingOptions = function() {
|
||||
|
||||
/**
|
||||
* Set the projection to use for transforming the coordinates.
|
||||
* @param {ol.proj.Projection} projection The projection the position is
|
||||
* @param {ol.ProjectionLike} projection The projection the position is
|
||||
* reported in.
|
||||
* @observable
|
||||
* @api
|
||||
*/
|
||||
ol.Geolocation.prototype.setProjection = function(projection) {
|
||||
this.set(ol.GeolocationProperty.PROJECTION, projection);
|
||||
this.set(ol.GeolocationProperty.PROJECTION, ol.proj.get(projection));
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
goog.provide('ol.Graticule');
|
||||
|
||||
goog.require('ol.coordinate');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.geom.GeometryLayout');
|
||||
goog.require('ol.geom.LineString');
|
||||
goog.require('ol.geom.Point');
|
||||
goog.require('ol.geom.flat.geodesic');
|
||||
goog.require('ol.math');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.render.EventType');
|
||||
goog.require('ol.style.Fill');
|
||||
goog.require('ol.style.Stroke');
|
||||
goog.require('ol.style.Text');
|
||||
|
||||
|
||||
/**
|
||||
@@ -129,6 +133,91 @@ ol.Graticule = function(opt_options) {
|
||||
*/
|
||||
this.projectionCenterLonLat_ = null;
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.GraticuleLabelDataType>}
|
||||
* @private
|
||||
*/
|
||||
this.meridiansLabels_ = null;
|
||||
|
||||
/**
|
||||
* @type {Array.<ol.GraticuleLabelDataType>}
|
||||
* @private
|
||||
*/
|
||||
this.parallelsLabels_ = null;
|
||||
|
||||
if (options.showLabels == true) {
|
||||
var degreesToString = ol.coordinate.degreesToStringHDMS;
|
||||
|
||||
/**
|
||||
* @type {null|function(number):string}
|
||||
* @private
|
||||
*/
|
||||
this.lonLabelFormatter_ = options.lonLabelFormatter == undefined ?
|
||||
degreesToString.bind(this, 'EW') : options.lonLabelFormatter;
|
||||
|
||||
/**
|
||||
* @type {function(number):string}
|
||||
* @private
|
||||
*/
|
||||
this.latLabelFormatter_ = options.latLabelFormatter == undefined ?
|
||||
degreesToString.bind(this, 'NS') : options.latLabelFormatter;
|
||||
|
||||
/**
|
||||
* Longitude label position in fractions (0..1) of view extent. 0 means
|
||||
* bottom, 1 means top.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.lonLabelPosition_ = options.lonLabelPosition == undefined ? 0 :
|
||||
options.lonLabelPosition;
|
||||
|
||||
/**
|
||||
* Latitude Label position in fractions (0..1) of view extent. 0 means left, 1
|
||||
* means right.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.latLabelPosition_ = options.latLabelPosition == undefined ? 1 :
|
||||
options.latLabelPosition;
|
||||
|
||||
/**
|
||||
* @type {ol.style.Text}
|
||||
* @private
|
||||
*/
|
||||
this.lonLabelStyle_ = options.lonLabelStyle !== undefined ? options.lonLabelStyle :
|
||||
new ol.style.Text({
|
||||
font: '12px Calibri,sans-serif',
|
||||
textBaseline: 'bottom',
|
||||
fill: new ol.style.Fill({
|
||||
color: 'rgba(0,0,0,1)'
|
||||
}),
|
||||
stroke: new ol.style.Stroke({
|
||||
color: 'rgba(255,255,255,1)',
|
||||
width: 3
|
||||
})
|
||||
});
|
||||
|
||||
/**
|
||||
* @type {ol.style.Text}
|
||||
* @private
|
||||
*/
|
||||
this.latLabelStyle_ = options.latLabelStyle !== undefined ? options.latLabelStyle :
|
||||
new ol.style.Text({
|
||||
font: '12px Calibri,sans-serif',
|
||||
textAlign: 'end',
|
||||
fill: new ol.style.Fill({
|
||||
color: 'rgba(0,0,0,1)'
|
||||
}),
|
||||
stroke: new ol.style.Stroke({
|
||||
color: 'rgba(255,255,255,1)',
|
||||
width: 3
|
||||
})
|
||||
});
|
||||
|
||||
this.meridiansLabels_ = [];
|
||||
this.parallelsLabels_ = [];
|
||||
}
|
||||
|
||||
this.setMap(options.map !== undefined ? options.map : null);
|
||||
};
|
||||
|
||||
@@ -166,11 +255,39 @@ ol.Graticule.prototype.addMeridian_ = function(lon, minLat, maxLat, squaredToler
|
||||
var lineString = this.getMeridian_(lon, minLat, maxLat,
|
||||
squaredTolerance, index);
|
||||
if (ol.extent.intersects(lineString.getExtent(), extent)) {
|
||||
if (this.meridiansLabels_) {
|
||||
var textPoint = this.getMeridianPoint_(lineString, extent, index);
|
||||
this.meridiansLabels_[index] = {
|
||||
geom: textPoint,
|
||||
text: this.lonLabelFormatter_(lon)
|
||||
};
|
||||
}
|
||||
this.meridians_[index++] = lineString;
|
||||
}
|
||||
return index;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {ol.geom.LineString} lineString Meridian
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {number} index Index.
|
||||
* @return {ol.geom.Point} Meridian point.
|
||||
* @private
|
||||
*/
|
||||
ol.Graticule.prototype.getMeridianPoint_ = function(lineString, extent, index) {
|
||||
var flatCoordinates = lineString.getFlatCoordinates();
|
||||
var clampedBottom = Math.max(extent[1], flatCoordinates[1]);
|
||||
var clampedTop = Math.min(extent[3], flatCoordinates[flatCoordinates.length - 1]);
|
||||
var lat = ol.math.clamp(
|
||||
extent[1] + Math.abs(extent[1] - extent[3]) * this.lonLabelPosition_,
|
||||
clampedBottom, clampedTop);
|
||||
var coordinate = [flatCoordinates[0], lat];
|
||||
var point = this.meridiansLabels_[index] !== undefined ?
|
||||
this.meridiansLabels_[index].geom : new ol.geom.Point(null);
|
||||
point.setCoordinates(coordinate);
|
||||
return point;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} lat Latitude.
|
||||
@@ -186,12 +303,41 @@ ol.Graticule.prototype.addParallel_ = function(lat, minLon, maxLon, squaredToler
|
||||
var lineString = this.getParallel_(lat, minLon, maxLon, squaredTolerance,
|
||||
index);
|
||||
if (ol.extent.intersects(lineString.getExtent(), extent)) {
|
||||
if (this.parallelsLabels_) {
|
||||
var textPoint = this.getParallelPoint_(lineString, extent, index);
|
||||
this.parallelsLabels_[index] = {
|
||||
geom: textPoint,
|
||||
text: this.latLabelFormatter_(lat)
|
||||
};
|
||||
}
|
||||
this.parallels_[index++] = lineString;
|
||||
}
|
||||
return index;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.geom.LineString} lineString Parallels.
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {number} index Index.
|
||||
* @return {ol.geom.Point} Parallel point.
|
||||
* @private
|
||||
*/
|
||||
ol.Graticule.prototype.getParallelPoint_ = function(lineString, extent, index) {
|
||||
var flatCoordinates = lineString.getFlatCoordinates();
|
||||
var clampedLeft = Math.max(extent[0], flatCoordinates[0]);
|
||||
var clampedRight = Math.min(extent[2], flatCoordinates[flatCoordinates.length - 2]);
|
||||
var lon = ol.math.clamp(
|
||||
extent[0] + Math.abs(extent[0] - extent[2]) * this.latLabelPosition_,
|
||||
clampedLeft, clampedRight);
|
||||
var coordinate = [lon, flatCoordinates[1]];
|
||||
var point = this.parallelsLabels_[index] !== undefined ?
|
||||
this.parallelsLabels_[index].geom : new ol.geom.Point(null);
|
||||
point.setCoordinates(coordinate);
|
||||
return point;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Extent} extent Extent.
|
||||
* @param {ol.Coordinate} center Center.
|
||||
@@ -204,6 +350,12 @@ ol.Graticule.prototype.createGraticule_ = function(extent, center, resolution, s
|
||||
var interval = this.getInterval_(resolution);
|
||||
if (interval == -1) {
|
||||
this.meridians_.length = this.parallels_.length = 0;
|
||||
if (this.meridiansLabels_) {
|
||||
this.meridiansLabels_.length = 0;
|
||||
}
|
||||
if (this.parallelsLabels_) {
|
||||
this.parallelsLabels_.length = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -249,6 +401,9 @@ ol.Graticule.prototype.createGraticule_ = function(extent, center, resolution, s
|
||||
}
|
||||
|
||||
this.meridians_.length = idx;
|
||||
if (this.meridiansLabels_) {
|
||||
this.meridiansLabels_.length = idx;
|
||||
}
|
||||
|
||||
// Create parallels
|
||||
|
||||
@@ -272,6 +427,9 @@ ol.Graticule.prototype.createGraticule_ = function(extent, center, resolution, s
|
||||
}
|
||||
|
||||
this.parallels_.length = idx;
|
||||
if (this.parallelsLabels_) {
|
||||
this.parallelsLabels_.length = idx;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -370,7 +528,7 @@ ol.Graticule.prototype.getParallel_ = function(lat, minLon, maxLon,
|
||||
|
||||
|
||||
/**
|
||||
* Get the list of parallels. Pallels are lines of equal latitude.
|
||||
* Get the list of parallels. Parallels are lines of equal latitude.
|
||||
* @return {Array.<ol.geom.LineString>} The parallels.
|
||||
* @api
|
||||
*/
|
||||
@@ -426,11 +584,28 @@ ol.Graticule.prototype.handlePostCompose_ = function(e) {
|
||||
var i, l, line;
|
||||
for (i = 0, l = this.meridians_.length; i < l; ++i) {
|
||||
line = this.meridians_[i];
|
||||
vectorContext.drawLineString(line, null);
|
||||
vectorContext.drawGeometry(line);
|
||||
}
|
||||
for (i = 0, l = this.parallels_.length; i < l; ++i) {
|
||||
line = this.parallels_[i];
|
||||
vectorContext.drawLineString(line, null);
|
||||
vectorContext.drawGeometry(line);
|
||||
}
|
||||
var labelData;
|
||||
if (this.meridiansLabels_) {
|
||||
for (i = 0, l = this.meridiansLabels_.length; i < l; ++i) {
|
||||
labelData = this.meridiansLabels_[i];
|
||||
this.lonLabelStyle_.setText(labelData.text);
|
||||
vectorContext.setTextStyle(this.lonLabelStyle_);
|
||||
vectorContext.drawGeometry(labelData.geom);
|
||||
}
|
||||
}
|
||||
if (this.parallelsLabels_) {
|
||||
for (i = 0, l = this.parallelsLabels_.length; i < l; ++i) {
|
||||
labelData = this.parallelsLabels_[i];
|
||||
this.latLabelStyle_.setText(labelData.text);
|
||||
vectorContext.setTextStyle(this.latLabelStyle_);
|
||||
vectorContext.drawGeometry(labelData.geom);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ goog.provide('ol.ImageTile');
|
||||
goog.require('ol');
|
||||
goog.require('ol.Tile');
|
||||
goog.require('ol.TileState');
|
||||
goog.require('ol.dom');
|
||||
goog.require('ol.events');
|
||||
goog.require('ol.events.EventType');
|
||||
|
||||
@@ -30,7 +31,7 @@ ol.ImageTile = function(tileCoord, state, src, crossOrigin, tileLoadFunction) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Image}
|
||||
* @type {Image|HTMLCanvasElement}
|
||||
*/
|
||||
this.image_ = new Image();
|
||||
if (crossOrigin !== null) {
|
||||
@@ -59,6 +60,7 @@ ol.inherits(ol.ImageTile, ol.Tile);
|
||||
ol.ImageTile.prototype.disposeInternal = function() {
|
||||
if (this.state == ol.TileState.LOADING) {
|
||||
this.unlistenImage_();
|
||||
this.image_.src = ol.ImageTile.blankImage.toDataURL('image/png');
|
||||
}
|
||||
if (this.interimTile) {
|
||||
this.interimTile.dispose();
|
||||
@@ -70,8 +72,8 @@ ol.ImageTile.prototype.disposeInternal = function() {
|
||||
|
||||
|
||||
/**
|
||||
* Get the image element for this tile.
|
||||
* @inheritDoc
|
||||
* Get the HTML image element for this tile (may be a Canvas, Image, or Video).
|
||||
* @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.
|
||||
* @api
|
||||
*/
|
||||
ol.ImageTile.prototype.getImage = function() {
|
||||
@@ -95,6 +97,7 @@ ol.ImageTile.prototype.getKey = function() {
|
||||
ol.ImageTile.prototype.handleImageError_ = function() {
|
||||
this.state = ol.TileState.ERROR;
|
||||
this.unlistenImage_();
|
||||
this.image_ = ol.ImageTile.blankImage;
|
||||
this.changed();
|
||||
};
|
||||
|
||||
@@ -143,3 +146,15 @@ ol.ImageTile.prototype.unlistenImage_ = function() {
|
||||
this.imageListenerKeys_.forEach(ol.events.unlistenByKey);
|
||||
this.imageListenerKeys_ = null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A blank image.
|
||||
* @type {HTMLCanvasElement}
|
||||
*/
|
||||
ol.ImageTile.blankImage = (function() {
|
||||
var ctx = ol.dom.createCanvasContext2D(1, 1);
|
||||
ctx.fillStyle = 'rgba(0,0,0,0)';
|
||||
ctx.fillRect(0, 0, 1, 1);
|
||||
return ctx.canvas;
|
||||
})();
|
||||
|
||||
@@ -141,14 +141,10 @@ ol.interaction.DragAndDrop.handleEvent = ol.functions.TRUE;
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* @private
|
||||
*/
|
||||
ol.interaction.DragAndDrop.prototype.setMap = function(map) {
|
||||
if (this.dropListenKeys_) {
|
||||
this.dropListenKeys_.forEach(ol.events.unlistenByKey);
|
||||
this.dropListenKeys_ = null;
|
||||
}
|
||||
ol.interaction.Interaction.prototype.setMap.call(this, map);
|
||||
ol.interaction.DragAndDrop.prototype.registerListeners_ = function() {
|
||||
var map = this.getMap();
|
||||
if (map) {
|
||||
var dropArea = this.target ? this.target : map.getViewport();
|
||||
this.dropListenKeys_ = [
|
||||
@@ -165,6 +161,31 @@ ol.interaction.DragAndDrop.prototype.setMap = function(map) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.interaction.DragAndDrop.prototype.setActive = function(active) {
|
||||
ol.interaction.Interaction.prototype.setActive.call(this, active);
|
||||
if (active) {
|
||||
this.registerListeners_();
|
||||
} else {
|
||||
this.unregisterListeners_();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.interaction.DragAndDrop.prototype.setMap = function(map) {
|
||||
this.unregisterListeners_();
|
||||
ol.interaction.Interaction.prototype.setMap.call(this, map);
|
||||
if (this.getActive()) {
|
||||
this.registerListeners_();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.format.Feature} format Format.
|
||||
* @param {string} text Text.
|
||||
@@ -181,6 +202,17 @@ ol.interaction.DragAndDrop.prototype.tryReadFeatures_ = function(format, text, o
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
ol.interaction.DragAndDrop.prototype.unregisterListeners_ = function() {
|
||||
if (this.dropListenKeys_) {
|
||||
this.dropListenKeys_.forEach(ol.events.unlistenByKey);
|
||||
this.dropListenKeys_ = null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
* @private
|
||||
|
||||
@@ -115,8 +115,8 @@ ol.interaction.DragBox.prototype.getGeometry = function() {
|
||||
|
||||
|
||||
/**
|
||||
* To be overriden by child classes.
|
||||
* FIXME: use constructor option instead of relying on overridding.
|
||||
* To be overridden by child classes.
|
||||
* FIXME: use constructor option instead of relying on overriding.
|
||||
* @param {ol.MapBrowserEvent} mapBrowserEvent Map browser event.
|
||||
* @protected
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
goog.provide('ol.interaction.DragRotate');
|
||||
|
||||
goog.require('ol');
|
||||
goog.require('ol.RotationConstraint');
|
||||
goog.require('ol.ViewHint');
|
||||
goog.require('ol.events.condition');
|
||||
goog.require('ol.functions');
|
||||
@@ -64,13 +65,16 @@ ol.interaction.DragRotate.handleDragEvent_ = function(mapBrowserEvent) {
|
||||
}
|
||||
|
||||
var map = mapBrowserEvent.map;
|
||||
var view = map.getView();
|
||||
if (view.getConstraints().rotation === ol.RotationConstraint.disable) {
|
||||
return;
|
||||
}
|
||||
var size = map.getSize();
|
||||
var offset = mapBrowserEvent.pixel;
|
||||
var theta =
|
||||
Math.atan2(size[1] / 2 - offset[1], offset[0] - size[0] / 2);
|
||||
if (this.lastAngle_ !== undefined) {
|
||||
var delta = theta - this.lastAngle_;
|
||||
var view = map.getView();
|
||||
var rotation = view.getRotation();
|
||||
ol.interaction.Interaction.rotateWithoutConstraints(
|
||||
view, rotation - delta);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
goog.provide('ol.interaction.DragRotateAndZoom');
|
||||
|
||||
goog.require('ol');
|
||||
goog.require('ol.RotationConstraint');
|
||||
goog.require('ol.ViewHint');
|
||||
goog.require('ol.events.condition');
|
||||
goog.require('ol.interaction.Interaction');
|
||||
@@ -85,7 +86,7 @@ ol.interaction.DragRotateAndZoom.handleDragEvent_ = function(mapBrowserEvent) {
|
||||
var theta = Math.atan2(deltaY, deltaX);
|
||||
var magnitude = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
|
||||
var view = map.getView();
|
||||
if (this.lastAngle_ !== undefined) {
|
||||
if (view.getConstraints().rotation !== ol.RotationConstraint.disable && this.lastAngle_ !== undefined) {
|
||||
var angleDelta = theta - this.lastAngle_;
|
||||
ol.interaction.Interaction.rotateWithoutConstraints(
|
||||
view, view.getRotation() - angleDelta);
|
||||
|
||||
@@ -117,7 +117,7 @@ ol.interaction.Draw = function(options) {
|
||||
this.maxPoints_ = options.maxPoints ? options.maxPoints : Infinity;
|
||||
|
||||
/**
|
||||
* A function to decide if a potential finish coordinate is permissable
|
||||
* A function to decide if a potential finish coordinate is permissible
|
||||
* @private
|
||||
* @type {ol.EventsConditionType}
|
||||
*/
|
||||
@@ -127,7 +127,7 @@ ol.interaction.Draw = function(options) {
|
||||
if (!geometryFunction) {
|
||||
if (this.type_ === ol.geom.GeometryType.CIRCLE) {
|
||||
/**
|
||||
* @param {ol.Coordinate|Array.<ol.Coordinate>|Array.<Array.<ol.Coordinate>>} coordinates
|
||||
* @param {!Array.<ol.Coordinate>} coordinates
|
||||
* The coordinates.
|
||||
* @param {ol.geom.SimpleGeometry=} opt_geometry Optional geometry.
|
||||
* @return {ol.geom.SimpleGeometry} A geometry.
|
||||
@@ -151,7 +151,7 @@ ol.interaction.Draw = function(options) {
|
||||
Constructor = ol.geom.Polygon;
|
||||
}
|
||||
/**
|
||||
* @param {ol.Coordinate|Array.<ol.Coordinate>|Array.<Array.<ol.Coordinate>>} coordinates
|
||||
* @param {!Array.<ol.Coordinate>} coordinates
|
||||
* The coordinates.
|
||||
* @param {ol.geom.SimpleGeometry=} opt_geometry Optional geometry.
|
||||
* @return {ol.geom.SimpleGeometry} A geometry.
|
||||
@@ -529,9 +529,7 @@ ol.interaction.Draw.prototype.modifyDrawing_ = function(event) {
|
||||
}
|
||||
last[0] = coordinate[0];
|
||||
last[1] = coordinate[1];
|
||||
this.geometryFunction_(
|
||||
/** @type {!ol.Coordinate|!Array.<ol.Coordinate>|!Array.<Array.<ol.Coordinate>>} */ (this.sketchCoords_),
|
||||
geometry);
|
||||
this.geometryFunction_(/** @type {!Array.<ol.Coordinate>} */ (this.sketchCoords_), geometry);
|
||||
if (this.sketchPoint_) {
|
||||
var sketchPointGeom = /** @type {ol.geom.Point} */ (this.sketchPoint_.getGeometry());
|
||||
sketchPointGeom.setCoordinates(coordinate);
|
||||
@@ -800,7 +798,7 @@ ol.interaction.Draw.createRegularPolygon = function(opt_sides, opt_angle) {
|
||||
ol.interaction.Draw.createBox = function() {
|
||||
return (
|
||||
/**
|
||||
* @param {ol.Coordinate|Array.<ol.Coordinate>|Array.<Array.<ol.Coordinate>>} coordinates
|
||||
* @param {Array.<ol.Coordinate>} coordinates
|
||||
* @param {ol.geom.SimpleGeometry=} opt_geometry
|
||||
* @return {ol.geom.SimpleGeometry}
|
||||
*/
|
||||
|
||||
@@ -67,6 +67,13 @@ ol.interaction.Modify = function(options) {
|
||||
this.deleteCondition_ = options.deleteCondition ?
|
||||
options.deleteCondition : this.defaultDeleteCondition_;
|
||||
|
||||
/**
|
||||
* @type {ol.EventsConditionType}
|
||||
* @private
|
||||
*/
|
||||
this.insertVertexCondition_ = options.insertVertexCondition ?
|
||||
options.insertVertexCondition : ol.events.condition.always;
|
||||
|
||||
/**
|
||||
* Editing vertex.
|
||||
* @type {ol.Feature}
|
||||
@@ -600,7 +607,7 @@ ol.interaction.Modify.handleDownEvent_ = function(evt) {
|
||||
|
||||
this.dragSegments_.push([segmentDataMatch, 1]);
|
||||
componentSegments[uid][1] = segmentDataMatch;
|
||||
} else if (ol.getUid(segment) in this.vertexSegments_ &&
|
||||
} else if (this.insertVertexCondition_(evt) && ol.getUid(segment) in this.vertexSegments_ &&
|
||||
(!componentSegments[uid][0] && !componentSegments[uid][1])) {
|
||||
insertVertices.push([segmentDataMatch, vertex]);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ goog.require('ol.ViewHint');
|
||||
goog.require('ol.functions');
|
||||
goog.require('ol.interaction.Interaction');
|
||||
goog.require('ol.interaction.Pointer');
|
||||
goog.require('ol.RotationConstraint');
|
||||
|
||||
|
||||
/**
|
||||
@@ -95,6 +96,10 @@ ol.interaction.PinchRotate.handleDragEvent_ = function(mapBrowserEvent) {
|
||||
this.lastAngle_ = angle;
|
||||
|
||||
var map = mapBrowserEvent.map;
|
||||
var view = map.getView();
|
||||
if (view.getConstraints().rotation === ol.RotationConstraint.disable) {
|
||||
return;
|
||||
}
|
||||
|
||||
// rotate anchor point.
|
||||
// FIXME: should be the intersection point between the lines:
|
||||
@@ -107,7 +112,6 @@ ol.interaction.PinchRotate.handleDragEvent_ = function(mapBrowserEvent) {
|
||||
|
||||
// rotate
|
||||
if (this.rotating_) {
|
||||
var view = map.getView();
|
||||
var rotation = view.getRotation();
|
||||
map.render();
|
||||
ol.interaction.Interaction.rotateWithoutConstraints(view,
|
||||
|
||||
@@ -217,7 +217,8 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) {
|
||||
// the pixel.
|
||||
ol.obj.clear(this.featureLayerAssociation_);
|
||||
map.forEachFeatureAtPixel(mapBrowserEvent.pixel,
|
||||
(/**
|
||||
(
|
||||
/**
|
||||
* @param {ol.Feature|ol.render.Feature} feature Feature.
|
||||
* @param {ol.layer.Layer} layer Layer.
|
||||
* @return {boolean|undefined} Continue to iterate over the features.
|
||||
@@ -250,7 +251,8 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) {
|
||||
} else {
|
||||
// Modify the currently selected feature(s).
|
||||
map.forEachFeatureAtPixel(mapBrowserEvent.pixel,
|
||||
(/**
|
||||
(
|
||||
/**
|
||||
* @param {ol.Feature|ol.render.Feature} feature Feature.
|
||||
* @param {ol.layer.Layer} layer Layer.
|
||||
* @return {boolean|undefined} Continue to iterate over the features.
|
||||
|
||||
@@ -8,6 +8,8 @@ goog.require('ol.events');
|
||||
goog.require('ol.events.EventType');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.functions');
|
||||
goog.require('ol.geom.GeometryType');
|
||||
goog.require('ol.geom.Polygon');
|
||||
goog.require('ol.interaction.Pointer');
|
||||
goog.require('ol.obj');
|
||||
goog.require('ol.source.Vector');
|
||||
@@ -142,7 +144,8 @@ ol.interaction.Snap = function(opt_options) {
|
||||
'MultiPoint': this.writeMultiPointGeometry_,
|
||||
'MultiLineString': this.writeMultiLineStringGeometry_,
|
||||
'MultiPolygon': this.writeMultiPolygonGeometry_,
|
||||
'GeometryCollection': this.writeGeometryCollectionGeometry_
|
||||
'GeometryCollection': this.writeGeometryCollectionGeometry_,
|
||||
'Circle': this.writeCircleGeometry_
|
||||
};
|
||||
};
|
||||
ol.inherits(ol.interaction.Snap, ol.interaction.Pointer);
|
||||
@@ -345,6 +348,15 @@ ol.interaction.Snap.prototype.snapTo = function(pixel, pixelCoordinate, map) {
|
||||
var box = ol.extent.boundingExtent([lowerLeft, upperRight]);
|
||||
|
||||
var segments = this.rBush_.getInExtent(box);
|
||||
|
||||
// If snapping on vertices only, don't consider circles
|
||||
if (this.vertex_ && !this.edge_) {
|
||||
segments = segments.filter(function(segment) {
|
||||
return segment.feature.getGeometry().getType() !==
|
||||
ol.geom.GeometryType.CIRCLE;
|
||||
});
|
||||
}
|
||||
|
||||
var snappedToVertex = false;
|
||||
var snapped = false;
|
||||
var vertex = null;
|
||||
@@ -354,6 +366,8 @@ ol.interaction.Snap.prototype.snapTo = function(pixel, pixelCoordinate, map) {
|
||||
this.pixelCoordinate_ = pixelCoordinate;
|
||||
segments.sort(this.sortByDistance_);
|
||||
var closestSegment = segments[0].segment;
|
||||
var isCircle = segments[0].feature.getGeometry().getType() ===
|
||||
ol.geom.GeometryType.CIRCLE;
|
||||
if (this.vertex_ && !this.edge_) {
|
||||
pixel1 = map.getPixelFromCoordinate(closestSegment[0]);
|
||||
pixel2 = map.getPixelFromCoordinate(closestSegment[1]);
|
||||
@@ -368,12 +382,17 @@ ol.interaction.Snap.prototype.snapTo = function(pixel, pixelCoordinate, map) {
|
||||
vertexPixel = map.getPixelFromCoordinate(vertex);
|
||||
}
|
||||
} else if (this.edge_) {
|
||||
if (isCircle) {
|
||||
vertex = ol.coordinate.closestOnCircle(pixelCoordinate,
|
||||
/** @type {ol.geom.Circle} */ (segments[0].feature.getGeometry()));
|
||||
} else {
|
||||
vertex = (ol.coordinate.closestOnSegment(pixelCoordinate,
|
||||
closestSegment));
|
||||
}
|
||||
vertexPixel = map.getPixelFromCoordinate(vertex);
|
||||
if (ol.coordinate.distance(pixel, vertexPixel) <= this.pixelTolerance_) {
|
||||
snapped = true;
|
||||
if (this.vertex_) {
|
||||
if (this.vertex_ && !isCircle) {
|
||||
pixel1 = map.getPixelFromCoordinate(closestSegment[0]);
|
||||
pixel2 = map.getPixelFromCoordinate(closestSegment[1]);
|
||||
squaredDist1 = ol.coordinate.squaredDistance(vertexPixel, pixel1);
|
||||
@@ -410,6 +429,26 @@ ol.interaction.Snap.prototype.updateFeature_ = function(feature) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Feature} feature Feature
|
||||
* @param {ol.geom.Circle} geometry Geometry.
|
||||
* @private
|
||||
*/
|
||||
ol.interaction.Snap.prototype.writeCircleGeometry_ = function(feature, geometry) {
|
||||
var polygon = ol.geom.Polygon.fromCircle(geometry);
|
||||
var coordinates = polygon.getCoordinates()[0];
|
||||
var i, ii, segment, segmentData;
|
||||
for (i = 0, ii = coordinates.length - 1; i < ii; ++i) {
|
||||
segment = coordinates.slice(i, i + 2);
|
||||
segmentData = /** @type {ol.SnapSegmentDataType} */ ({
|
||||
feature: feature,
|
||||
segment: segment
|
||||
});
|
||||
this.rBush_.insert(ol.extent.boundingExtent(segment), segmentData);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Feature} feature Feature
|
||||
* @param {ol.geom.GeometryCollection} geometry Geometry.
|
||||
@@ -418,8 +457,10 @@ ol.interaction.Snap.prototype.updateFeature_ = function(feature) {
|
||||
ol.interaction.Snap.prototype.writeGeometryCollectionGeometry_ = function(feature, geometry) {
|
||||
var i, geometries = geometry.getGeometriesArray();
|
||||
for (i = 0; i < geometries.length; ++i) {
|
||||
this.SEGMENT_WRITERS_[geometries[i].getType()].call(
|
||||
this, feature, geometries[i]);
|
||||
var segmentWriter = this.SEGMENT_WRITERS_[geometries[i].getType()];
|
||||
if (segmentWriter) {
|
||||
segmentWriter.call(this, feature, geometries[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -32,13 +32,6 @@ ol.interaction.Translate = function(opt_options) {
|
||||
|
||||
var options = opt_options ? opt_options : {};
|
||||
|
||||
/**
|
||||
* @type {string|undefined}
|
||||
* @private
|
||||
*/
|
||||
this.previousCursor_ = undefined;
|
||||
|
||||
|
||||
/**
|
||||
* The last position we translated to.
|
||||
* @type {ol.Coordinate}
|
||||
@@ -175,23 +168,15 @@ ol.interaction.Translate.handleDragEvent_ = function(event) {
|
||||
* @private
|
||||
*/
|
||||
ol.interaction.Translate.handleMoveEvent_ = function(event) {
|
||||
var elem = event.map.getTargetElement();
|
||||
var elem = event.map.getViewport();
|
||||
|
||||
// Change the cursor to grab/grabbing if hovering any of the features managed
|
||||
// by the interaction
|
||||
if (this.featuresAtPixel_(event.pixel, event.map)) {
|
||||
this.previousCursor_ = this.previousCursor_ !== undefined ?
|
||||
this.previousCursor_ : elem.style.cursor;
|
||||
// WebKit browsers don't support the grab icons without a prefix
|
||||
elem.style.cursor = this.lastCoordinate_ ?
|
||||
'-webkit-grabbing' : '-webkit-grab';
|
||||
|
||||
// Thankfully, attempting to set the standard ones will silently fail,
|
||||
// keeping the prefixed icons
|
||||
elem.style.cursor = this.lastCoordinate_ ? 'grabbing' : 'grab';
|
||||
} else if (this.previousCursor_ !== undefined) {
|
||||
elem.style.cursor = this.previousCursor_;
|
||||
this.previousCursor_ = undefined;
|
||||
elem.classList.remove(this.lastCoordinate_ ? 'ol-grab' : 'ol-grabbing');
|
||||
elem.classList.add(this.lastCoordinate_ ? 'ol-grabbing' : 'ol-grab');
|
||||
} else {
|
||||
elem.classList.remove('ol-grab', 'ol-grabbing');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -266,14 +251,12 @@ ol.interaction.Translate.prototype.handleActiveChanged_ = function() {
|
||||
ol.interaction.Translate.prototype.updateState_ = function(oldMap) {
|
||||
var map = this.getMap();
|
||||
var active = this.getActive();
|
||||
if ((!map || !active) && this.previousCursor_ !== undefined) {
|
||||
if (!map) {
|
||||
map = oldMap;
|
||||
if (!map || !active) {
|
||||
map = map || oldMap;
|
||||
if (map) {
|
||||
var elem = map.getViewport();
|
||||
elem.classList.remove('ol-grab', 'ol-grabbing');
|
||||
}
|
||||
|
||||
var elem = map.getTargetElement();
|
||||
elem.style.cursor = this.previousCursor_;
|
||||
this.previousCursor_ = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -94,7 +94,15 @@ ol.Kinetic.prototype.end = function() {
|
||||
while (firstIndex > 0 && this.points_[firstIndex + 2] > delay) {
|
||||
firstIndex -= 3;
|
||||
}
|
||||
|
||||
var duration = this.points_[lastIndex + 2] - this.points_[firstIndex + 2];
|
||||
// we don't want a duration of 0 (divide by zero)
|
||||
// we also make sure the user panned for a duration of at least one frame
|
||||
// (1/60s) to compute sane displacement values
|
||||
if (duration < 1000 / 60) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var dx = this.points_[lastIndex] - this.points_[firstIndex];
|
||||
var dy = this.points_[lastIndex + 1] - this.points_[firstIndex + 1];
|
||||
this.angle_ = Math.atan2(dy, dx);
|
||||
|
||||
@@ -210,7 +210,7 @@ ol.Map = function(options) {
|
||||
* @private
|
||||
* @type {ol.Extent}
|
||||
*/
|
||||
this.previousExtent_ = ol.extent.createEmpty();
|
||||
this.previousExtent_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -278,7 +278,7 @@ ol.Map = function(options) {
|
||||
* @private
|
||||
* @type {ol.MapBrowserEventHandler}
|
||||
*/
|
||||
this.mapBrowserEventHandler_ = new ol.MapBrowserEventHandler(this);
|
||||
this.mapBrowserEventHandler_ = new ol.MapBrowserEventHandler(this, options.moveTolerance);
|
||||
for (var key in ol.MapBrowserEventType) {
|
||||
ol.events.listen(this.mapBrowserEventHandler_, ol.MapBrowserEventType[key],
|
||||
this.handleMapBrowserEvent, this);
|
||||
@@ -579,7 +579,7 @@ ol.Map.prototype.forEachFeatureAtPixel = function(pixel, callback, opt_options)
|
||||
* detection can be configured through `opt_layerFilter`.
|
||||
* @param {ol.Pixel} pixel Pixel.
|
||||
* @param {function(this: S, ol.layer.Layer, (Uint8ClampedArray|Uint8Array)): T} callback
|
||||
* Layer callback. This callback will recieve two arguments: first is the
|
||||
* Layer callback. This callback will receive two arguments: first is the
|
||||
* {@link ol.layer.Layer layer}, second argument is an array representing
|
||||
* [R, G, B, A] pixel values (0 - 255) and will be `null` for layer types
|
||||
* that do not currently support this argument. To stop detection, callback
|
||||
@@ -1200,6 +1200,7 @@ ol.Map.prototype.renderFrame_ = function(time) {
|
||||
var size = this.getSize();
|
||||
var view = this.getView();
|
||||
var extent = ol.extent.createEmpty();
|
||||
var previousFrameState = this.frameState_;
|
||||
/** @type {?olx.FrameState} */
|
||||
var frameState = null;
|
||||
if (size !== undefined && ol.size.hasArea(size) && view && view.isDef()) {
|
||||
@@ -1249,7 +1250,19 @@ ol.Map.prototype.renderFrame_ = function(time) {
|
||||
Array.prototype.push.apply(
|
||||
this.postRenderFunctions_, frameState.postRenderFunctions);
|
||||
|
||||
var idle = !frameState.viewHints[ol.ViewHint.ANIMATING] &&
|
||||
if (previousFrameState) {
|
||||
var moveStart = !this.previousExtent_ ||
|
||||
(!ol.extent.isEmpty(this.previousExtent_) &&
|
||||
!ol.extent.equals(frameState.extent, this.previousExtent_));
|
||||
if (moveStart) {
|
||||
this.dispatchEvent(
|
||||
new ol.MapEvent(ol.MapEventType.MOVESTART, this, previousFrameState));
|
||||
this.previousExtent_ = ol.extent.createOrUpdateEmpty(this.previousExtent_);
|
||||
}
|
||||
}
|
||||
|
||||
var idle = this.previousExtent_ &&
|
||||
!frameState.viewHints[ol.ViewHint.ANIMATING] &&
|
||||
!frameState.viewHints[ol.ViewHint.INTERACTING] &&
|
||||
!ol.extent.equals(frameState.extent, this.previousExtent_);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
goog.provide('ol.MapBrowserEventHandler');
|
||||
|
||||
goog.require('ol');
|
||||
goog.require('ol.has');
|
||||
goog.require('ol.MapBrowserEventType');
|
||||
goog.require('ol.MapBrowserPointerEvent');
|
||||
goog.require('ol.events');
|
||||
@@ -11,10 +12,11 @@ goog.require('ol.pointer.PointerEventHandler');
|
||||
|
||||
/**
|
||||
* @param {ol.Map} map The map with the viewport to listen to events on.
|
||||
* @param {number|undefined} moveTolerance The minimal distance the pointer must travel to trigger a move.
|
||||
* @constructor
|
||||
* @extends {ol.events.EventTarget}
|
||||
*/
|
||||
ol.MapBrowserEventHandler = function(map) {
|
||||
ol.MapBrowserEventHandler = function(map, moveTolerance) {
|
||||
|
||||
ol.events.EventTarget.call(this);
|
||||
|
||||
@@ -43,6 +45,13 @@ ol.MapBrowserEventHandler = function(map) {
|
||||
*/
|
||||
this.dragListenerKeys_ = [];
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.moveTolerance_ = moveTolerance ?
|
||||
moveTolerance * ol.has.DEVICE_PIXEL_RATIO : ol.has.DEVICE_PIXEL_RATIO;
|
||||
|
||||
/**
|
||||
* The most recent "down" type event (or null if none have occurred).
|
||||
* Set on pointerdown.
|
||||
@@ -241,11 +250,9 @@ ol.MapBrowserEventHandler.prototype.handlePointerDown_ = function(pointerEvent)
|
||||
* @private
|
||||
*/
|
||||
ol.MapBrowserEventHandler.prototype.handlePointerMove_ = function(pointerEvent) {
|
||||
// Fix IE10 on windows Surface : When you tap the tablet, it triggers
|
||||
// multiple pointermove events between pointerdown and pointerup with
|
||||
// the exact same coordinates of the pointerdown event. To avoid a
|
||||
// 'false' touchmove event to be dispatched , we test if the pointer
|
||||
// effectively moved.
|
||||
// Between pointerdown and pointerup, pointermove events are triggered.
|
||||
// To avoid a 'false' touchmove event to be dispatched, we test if the pointer
|
||||
// moved a significant distance.
|
||||
if (this.isMoving_(pointerEvent)) {
|
||||
this.dragging_ = true;
|
||||
var newEvent = new ol.MapBrowserPointerEvent(
|
||||
@@ -281,8 +288,8 @@ ol.MapBrowserEventHandler.prototype.relayEvent_ = function(pointerEvent) {
|
||||
* @private
|
||||
*/
|
||||
ol.MapBrowserEventHandler.prototype.isMoving_ = function(pointerEvent) {
|
||||
return pointerEvent.clientX != this.down_.clientX ||
|
||||
pointerEvent.clientY != this.down_.clientY;
|
||||
return Math.abs(pointerEvent.clientX - this.down_.clientX) > this.moveTolerance_ ||
|
||||
Math.abs(pointerEvent.clientY - this.down_.clientY) > this.moveTolerance_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -12,6 +12,13 @@ ol.MapEventType = {
|
||||
*/
|
||||
POSTRENDER: 'postrender',
|
||||
|
||||
/**
|
||||
* Triggered when the map starts moving.
|
||||
* @event ol.MapEvent#movestart
|
||||
* @api
|
||||
*/
|
||||
MOVESTART: 'movestart',
|
||||
|
||||
/**
|
||||
* Triggered after the map is moved.
|
||||
* @event ol.MapEvent#moveend
|
||||
|
||||
@@ -31,17 +31,6 @@ ol.pointer.EventSource.prototype.getEvents = function() {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a mapping between the supported event types and
|
||||
* the handlers that should handle an event.
|
||||
* @return {Object.<string, function(Event)>}
|
||||
* Event/Handler mapping
|
||||
*/
|
||||
ol.pointer.EventSource.prototype.getMapping = function() {
|
||||
return this.mapping_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the handler that should handle a given event type.
|
||||
* @param {string} eventType The event type.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
goog.provide('ol.proj');
|
||||
|
||||
goog.require('ol');
|
||||
goog.require('ol.Sphere');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.proj.EPSG3857');
|
||||
goog.require('ol.proj.EPSG4326');
|
||||
@@ -9,7 +10,6 @@ goog.require('ol.proj.Units');
|
||||
goog.require('ol.proj.proj4');
|
||||
goog.require('ol.proj.projections');
|
||||
goog.require('ol.proj.transforms');
|
||||
goog.require('ol.sphere.NORMAL');
|
||||
|
||||
|
||||
/**
|
||||
@@ -21,6 +21,14 @@ goog.require('ol.sphere.NORMAL');
|
||||
ol.proj.METERS_PER_UNIT = ol.proj.Units.METERS_PER_UNIT;
|
||||
|
||||
|
||||
/**
|
||||
* A place to store the radius of the Clarke 1866 Authalic Sphere.
|
||||
* @private
|
||||
* @type {ol.Sphere}
|
||||
*/
|
||||
ol.proj.AUTHALIC_SPHERE_ = new ol.Sphere(6370997);
|
||||
|
||||
|
||||
if (ol.ENABLE_PROJ4JS) {
|
||||
/**
|
||||
* Register proj4. If not explicitly registered, it will be assumed that
|
||||
@@ -44,16 +52,22 @@ if (ol.ENABLE_PROJ4JS) {
|
||||
* Get the resolution of the point in degrees or distance units.
|
||||
* For projections with degrees as the unit this will simply return the
|
||||
* provided resolution. For other projections the point resolution is
|
||||
* estimated by transforming the 'point' pixel to EPSG:4326,
|
||||
* by default estimated by transforming the 'point' pixel to EPSG:4326,
|
||||
* measuring its width and height on the normal sphere,
|
||||
* and taking the average of the width and height.
|
||||
* @param {ol.proj.Projection} projection The projection.
|
||||
* A custom function can be provided for a specific projection, either
|
||||
* by setting the `getPointResolution` option in the
|
||||
* {@link ol.proj.Projection} constructor or by using
|
||||
* {@link ol.proj.Projection#setGetPointResolution} to change an existing
|
||||
* projection object.
|
||||
* @param {ol.ProjectionLike} projection The projection.
|
||||
* @param {number} resolution Nominal resolution in projection units.
|
||||
* @param {ol.Coordinate} point Point to find adjusted resolution at.
|
||||
* @return {number} Point resolution at point in projection units.
|
||||
* @api
|
||||
*/
|
||||
ol.proj.getPointResolution = function(projection, resolution, point) {
|
||||
projection = ol.proj.get(projection);
|
||||
var pointResolution;
|
||||
var getter = projection.getPointResolutionFunc();
|
||||
if (getter) {
|
||||
@@ -74,9 +88,9 @@ ol.proj.getPointResolution = function(projection, resolution, point) {
|
||||
point[0], point[1] + resolution / 2
|
||||
];
|
||||
vertices = toEPSG4326(vertices, vertices, 2);
|
||||
var width = ol.sphere.NORMAL.haversineDistance(
|
||||
var width = ol.proj.AUTHALIC_SPHERE_.haversineDistance(
|
||||
vertices.slice(0, 2), vertices.slice(2, 4));
|
||||
var height = ol.sphere.NORMAL.haversineDistance(
|
||||
var height = ol.proj.AUTHALIC_SPHERE_.haversineDistance(
|
||||
vertices.slice(4, 6), vertices.slice(6, 8));
|
||||
pointResolution = (width + height) / 2;
|
||||
var metersPerUnit = projection.getMetersPerUnit();
|
||||
@@ -148,10 +162,7 @@ ol.proj.addProjection = function(projection) {
|
||||
* @param {Array.<ol.proj.Projection>} projections Projections.
|
||||
*/
|
||||
ol.proj.addProjections = function(projections) {
|
||||
var addedProjections = [];
|
||||
projections.forEach(function(projection) {
|
||||
addedProjections.push(ol.proj.addProjection(projection));
|
||||
});
|
||||
projections.forEach(ol.proj.addProjection);
|
||||
};
|
||||
|
||||
|
||||
@@ -288,9 +299,9 @@ ol.proj.get = function(projectionLike) {
|
||||
} else if (typeof projectionLike === 'string') {
|
||||
var code = projectionLike;
|
||||
projection = ol.proj.projections.get(code);
|
||||
if (ol.ENABLE_PROJ4JS) {
|
||||
if (ol.ENABLE_PROJ4JS && !projection) {
|
||||
var proj4js = ol.proj.proj4.get();
|
||||
if (!projection && typeof proj4js == 'function' &&
|
||||
if (typeof proj4js == 'function' &&
|
||||
proj4js.defs(code) !== undefined) {
|
||||
projection = new ol.proj.Projection({code: code});
|
||||
ol.proj.addProjection(projection);
|
||||
|
||||
@@ -31,6 +31,8 @@ ol.inherits(ol.proj.EPSG3857.Projection_, ol.proj.Projection);
|
||||
|
||||
|
||||
/**
|
||||
* Radius of WGS84 sphere
|
||||
*
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
|
||||
@@ -3,7 +3,6 @@ goog.provide('ol.proj.EPSG4326');
|
||||
goog.require('ol');
|
||||
goog.require('ol.proj.Projection');
|
||||
goog.require('ol.proj.Units');
|
||||
goog.require('ol.sphere.WGS84');
|
||||
|
||||
|
||||
/**
|
||||
@@ -34,6 +33,15 @@ ol.proj.EPSG4326.Projection_ = function(code, opt_axisOrientation) {
|
||||
ol.inherits(ol.proj.EPSG4326.Projection_, ol.proj.Projection);
|
||||
|
||||
|
||||
/**
|
||||
* Radius of WGS84 sphere
|
||||
*
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.proj.EPSG4326.RADIUS = 6378137;
|
||||
|
||||
|
||||
/**
|
||||
* Extent of the EPSG:4326 projection which is the whole world.
|
||||
*
|
||||
@@ -47,7 +55,7 @@ ol.proj.EPSG4326.EXTENT = [-180, -90, 180, 90];
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.proj.EPSG4326.METERS_PER_UNIT = Math.PI * ol.sphere.WGS84.radius / 180;
|
||||
ol.proj.EPSG4326.METERS_PER_UNIT = Math.PI * ol.proj.EPSG4326.RADIUS / 180;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -254,7 +254,8 @@ ol.proj.Projection.prototype.setWorldExtent = function(worldExtent) {
|
||||
|
||||
|
||||
/**
|
||||
* Set the getPointResolution function for this projection.
|
||||
* Set the getPointResolution function (see {@link ol.proj#getPointResolution}
|
||||
* for this projection.
|
||||
* @param {function(number, ol.Coordinate):number} func Function
|
||||
* @api
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
goog.provide('ol.proj.Units');
|
||||
|
||||
goog.require('ol.sphere.NORMAL');
|
||||
|
||||
|
||||
/**
|
||||
* Projection units: `'degrees'`, `'ft'`, `'m'`, `'pixels'`, `'tile-pixels'` or
|
||||
@@ -25,8 +23,9 @@ ol.proj.Units = {
|
||||
* @api
|
||||
*/
|
||||
ol.proj.Units.METERS_PER_UNIT = {};
|
||||
// use the radius of the Normal sphere
|
||||
ol.proj.Units.METERS_PER_UNIT[ol.proj.Units.DEGREES] =
|
||||
2 * Math.PI * ol.sphere.NORMAL.radius / 360;
|
||||
2 * Math.PI * 6370997 / 360;
|
||||
ol.proj.Units.METERS_PER_UNIT[ol.proj.Units.FEET] = 0.3048;
|
||||
ol.proj.Units.METERS_PER_UNIT[ol.proj.Units.METERS] = 1;
|
||||
ol.proj.Units.METERS_PER_UNIT[ol.proj.Units.USFEET] = 1200 / 3937;
|
||||
|
||||
@@ -16,14 +16,21 @@ goog.require('ol.geom.GeometryType');
|
||||
* to be right-handed for polygons.
|
||||
* @param {Array.<number>|Array.<Array.<number>>} ends Ends or Endss.
|
||||
* @param {Object.<string, *>} properties Properties.
|
||||
* @param {number|string|undefined} id Feature id.
|
||||
*/
|
||||
ol.render.Feature = function(type, flatCoordinates, ends, properties) {
|
||||
ol.render.Feature = function(type, flatCoordinates, ends, properties, id) {
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.Extent|undefined}
|
||||
*/
|
||||
this.extent_;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|string|undefined}
|
||||
*/
|
||||
this.id_ = id;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.geom.GeometryType}
|
||||
@@ -85,6 +92,16 @@ ol.render.Feature.prototype.getExtent = function() {
|
||||
return this.extent_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the feature identifier. This is a stable identifier for the feature and
|
||||
* is set when reading data from a remote source.
|
||||
* @return {number|string|undefined} Id.
|
||||
* @api
|
||||
*/
|
||||
ol.render.Feature.prototype.getId = function() {
|
||||
return this.id_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Array.<number>} Flat coordinates.
|
||||
@@ -102,7 +119,8 @@ ol.render.Feature.prototype.getFlatCoordinates =
|
||||
|
||||
|
||||
/**
|
||||
* Get the feature for working with its geometry.
|
||||
* For API compatibility with {@link ol.Feature}, this method is useful when
|
||||
* determining the geometry type in style function (see {@link #getType}).
|
||||
* @return {ol.render.Feature} Feature.
|
||||
* @api
|
||||
*/
|
||||
|
||||
@@ -5,12 +5,20 @@ goog.require('ol');
|
||||
|
||||
if (ol.ENABLE_WEBGL) {
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
ol.render.webgl.defaultFont = '10px sans-serif';
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {ol.Color}
|
||||
*/
|
||||
ol.render.webgl.defaultFillStyle = [0.0, 0.0, 0.0, 1.0];
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
@@ -51,6 +59,21 @@ if (ol.ENABLE_WEBGL) {
|
||||
*/
|
||||
ol.render.webgl.defaultStrokeStyle = [0.0, 0.0, 0.0, 1.0];
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.render.webgl.defaultTextAlign = 0.5;
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
*/
|
||||
ol.render.webgl.defaultTextBaseline = 0.5;
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {number}
|
||||
|
||||
@@ -204,8 +204,8 @@ if (ol.ENABLE_WEBGL) {
|
||||
// get the locations
|
||||
var locations;
|
||||
if (!this.defaultLocations_) {
|
||||
locations =
|
||||
new ol.render.webgl.circlereplay.defaultshader.Locations(gl, program);
|
||||
// eslint-disable-next-line openlayers-internal/no-missing-requires
|
||||
locations = new ol.render.webgl.circlereplay.defaultshader.Locations(gl, program);
|
||||
this.defaultLocations_ = locations;
|
||||
} else {
|
||||
locations = this.defaultLocations_;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// This file is automatically generated, do not edit
|
||||
/* eslint openlayers-internal/no-missing-requires: 0 */
|
||||
goog.provide('ol.render.webgl.circlereplay.defaultshader');
|
||||
|
||||
goog.require('ol');
|
||||
|
||||
@@ -1,123 +1,34 @@
|
||||
goog.provide('ol.render.webgl.ImageReplay');
|
||||
|
||||
goog.require('ol');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.obj');
|
||||
goog.require('ol.render.webgl.imagereplay.defaultshader');
|
||||
goog.require('ol.render.webgl.Replay');
|
||||
goog.require('ol.webgl');
|
||||
goog.require('ol.render.webgl.TextureReplay');
|
||||
goog.require('ol.webgl.Buffer');
|
||||
goog.require('ol.webgl.Context');
|
||||
|
||||
|
||||
if (ol.ENABLE_WEBGL) {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.render.webgl.Replay}
|
||||
* @extends {ol.render.webgl.TextureReplay}
|
||||
* @param {number} tolerance Tolerance.
|
||||
* @param {ol.Extent} maxExtent Max extent.
|
||||
* @struct
|
||||
*/
|
||||
ol.render.webgl.ImageReplay = function(tolerance, maxExtent) {
|
||||
ol.render.webgl.Replay.call(this, tolerance, maxExtent);
|
||||
|
||||
/**
|
||||
* @type {number|undefined}
|
||||
* @private
|
||||
*/
|
||||
this.anchorX_ = undefined;
|
||||
|
||||
/**
|
||||
* @type {number|undefined}
|
||||
* @private
|
||||
*/
|
||||
this.anchorY_ = undefined;
|
||||
|
||||
/**
|
||||
* @type {Array.<number>}
|
||||
* @private
|
||||
*/
|
||||
this.groupIndices_ = [];
|
||||
|
||||
/**
|
||||
* @type {Array.<number>}
|
||||
* @private
|
||||
*/
|
||||
this.hitDetectionGroupIndices_ = [];
|
||||
|
||||
/**
|
||||
* @type {number|undefined}
|
||||
* @private
|
||||
*/
|
||||
this.height_ = undefined;
|
||||
ol.render.webgl.TextureReplay.call(this, tolerance, maxExtent);
|
||||
|
||||
/**
|
||||
* @type {Array.<HTMLCanvasElement|HTMLImageElement|HTMLVideoElement>}
|
||||
* @private
|
||||
* @protected
|
||||
*/
|
||||
this.images_ = [];
|
||||
|
||||
/**
|
||||
* @type {Array.<HTMLCanvasElement|HTMLImageElement|HTMLVideoElement>}
|
||||
* @private
|
||||
* @protected
|
||||
*/
|
||||
this.hitDetectionImages_ = [];
|
||||
|
||||
/**
|
||||
* @type {number|undefined}
|
||||
* @private
|
||||
*/
|
||||
this.imageHeight_ = undefined;
|
||||
|
||||
/**
|
||||
* @type {number|undefined}
|
||||
* @private
|
||||
*/
|
||||
this.imageWidth_ = undefined;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.render.webgl.imagereplay.defaultshader.Locations}
|
||||
*/
|
||||
this.defaultLocations_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.opacity_ = undefined;
|
||||
|
||||
/**
|
||||
* @type {number|undefined}
|
||||
* @private
|
||||
*/
|
||||
this.originX_ = undefined;
|
||||
|
||||
/**
|
||||
* @type {number|undefined}
|
||||
* @private
|
||||
*/
|
||||
this.originY_ = undefined;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {boolean|undefined}
|
||||
*/
|
||||
this.rotateWithView_ = undefined;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.rotation_ = undefined;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.scale_ = undefined;
|
||||
|
||||
/**
|
||||
* @type {Array.<WebGLTexture>}
|
||||
* @private
|
||||
@@ -130,141 +41,8 @@ if (ol.ENABLE_WEBGL) {
|
||||
*/
|
||||
this.hitDetectionTextures_ = [];
|
||||
|
||||
/**
|
||||
* @type {number|undefined}
|
||||
* @private
|
||||
*/
|
||||
this.width_ = undefined;
|
||||
};
|
||||
ol.inherits(ol.render.webgl.ImageReplay, ol.render.webgl.Replay);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.ImageReplay.prototype.getDeleteResourcesFunction = function(context) {
|
||||
var verticesBuffer = this.verticesBuffer;
|
||||
var indicesBuffer = this.indicesBuffer;
|
||||
var textures = this.textures_;
|
||||
var hitDetectionTextures = this.hitDetectionTextures_;
|
||||
var gl = context.getGL();
|
||||
return function() {
|
||||
if (!gl.isContextLost()) {
|
||||
var i, ii;
|
||||
for (i = 0, ii = textures.length; i < ii; ++i) {
|
||||
gl.deleteTexture(textures[i]);
|
||||
}
|
||||
for (i = 0, ii = hitDetectionTextures.length; i < ii; ++i) {
|
||||
gl.deleteTexture(hitDetectionTextures[i]);
|
||||
}
|
||||
}
|
||||
context.deleteBuffer(verticesBuffer);
|
||||
context.deleteBuffer(indicesBuffer);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||
* @param {number} offset Offset.
|
||||
* @param {number} end End.
|
||||
* @param {number} stride Stride.
|
||||
* @return {number} My end.
|
||||
* @private
|
||||
*/
|
||||
ol.render.webgl.ImageReplay.prototype.drawCoordinates_ = function(flatCoordinates, offset, end, stride) {
|
||||
var anchorX = /** @type {number} */ (this.anchorX_);
|
||||
var anchorY = /** @type {number} */ (this.anchorY_);
|
||||
var height = /** @type {number} */ (this.height_);
|
||||
var imageHeight = /** @type {number} */ (this.imageHeight_);
|
||||
var imageWidth = /** @type {number} */ (this.imageWidth_);
|
||||
var opacity = /** @type {number} */ (this.opacity_);
|
||||
var originX = /** @type {number} */ (this.originX_);
|
||||
var originY = /** @type {number} */ (this.originY_);
|
||||
var rotateWithView = this.rotateWithView_ ? 1.0 : 0.0;
|
||||
// this.rotation_ is anti-clockwise, but rotation is clockwise
|
||||
var rotation = /** @type {number} */ (-this.rotation_);
|
||||
var scale = /** @type {number} */ (this.scale_);
|
||||
var width = /** @type {number} */ (this.width_);
|
||||
var cos = Math.cos(rotation);
|
||||
var sin = Math.sin(rotation);
|
||||
var numIndices = this.indices.length;
|
||||
var numVertices = this.vertices.length;
|
||||
var i, n, offsetX, offsetY, x, y;
|
||||
for (i = offset; i < end; i += stride) {
|
||||
x = flatCoordinates[i] - this.origin[0];
|
||||
y = flatCoordinates[i + 1] - this.origin[1];
|
||||
|
||||
// There are 4 vertices per [x, y] point, one for each corner of the
|
||||
// rectangle we're going to draw. We'd use 1 vertex per [x, y] point if
|
||||
// WebGL supported Geometry Shaders (which can emit new vertices), but that
|
||||
// is not currently the case.
|
||||
//
|
||||
// And each vertex includes 8 values: the x and y coordinates, the x and
|
||||
// y offsets used to calculate the position of the corner, the u and
|
||||
// v texture coordinates for the corner, the opacity, and whether the
|
||||
// the image should be rotated with the view (rotateWithView).
|
||||
|
||||
n = numVertices / 8;
|
||||
|
||||
// bottom-left corner
|
||||
offsetX = -scale * anchorX;
|
||||
offsetY = -scale * (height - anchorY);
|
||||
this.vertices[numVertices++] = x;
|
||||
this.vertices[numVertices++] = y;
|
||||
this.vertices[numVertices++] = offsetX * cos - offsetY * sin;
|
||||
this.vertices[numVertices++] = offsetX * sin + offsetY * cos;
|
||||
this.vertices[numVertices++] = originX / imageWidth;
|
||||
this.vertices[numVertices++] = (originY + height) / imageHeight;
|
||||
this.vertices[numVertices++] = opacity;
|
||||
this.vertices[numVertices++] = rotateWithView;
|
||||
|
||||
// bottom-right corner
|
||||
offsetX = scale * (width - anchorX);
|
||||
offsetY = -scale * (height - anchorY);
|
||||
this.vertices[numVertices++] = x;
|
||||
this.vertices[numVertices++] = y;
|
||||
this.vertices[numVertices++] = offsetX * cos - offsetY * sin;
|
||||
this.vertices[numVertices++] = offsetX * sin + offsetY * cos;
|
||||
this.vertices[numVertices++] = (originX + width) / imageWidth;
|
||||
this.vertices[numVertices++] = (originY + height) / imageHeight;
|
||||
this.vertices[numVertices++] = opacity;
|
||||
this.vertices[numVertices++] = rotateWithView;
|
||||
|
||||
// top-right corner
|
||||
offsetX = scale * (width - anchorX);
|
||||
offsetY = scale * anchorY;
|
||||
this.vertices[numVertices++] = x;
|
||||
this.vertices[numVertices++] = y;
|
||||
this.vertices[numVertices++] = offsetX * cos - offsetY * sin;
|
||||
this.vertices[numVertices++] = offsetX * sin + offsetY * cos;
|
||||
this.vertices[numVertices++] = (originX + width) / imageWidth;
|
||||
this.vertices[numVertices++] = originY / imageHeight;
|
||||
this.vertices[numVertices++] = opacity;
|
||||
this.vertices[numVertices++] = rotateWithView;
|
||||
|
||||
// top-left corner
|
||||
offsetX = -scale * anchorX;
|
||||
offsetY = scale * anchorY;
|
||||
this.vertices[numVertices++] = x;
|
||||
this.vertices[numVertices++] = y;
|
||||
this.vertices[numVertices++] = offsetX * cos - offsetY * sin;
|
||||
this.vertices[numVertices++] = offsetX * sin + offsetY * cos;
|
||||
this.vertices[numVertices++] = originX / imageWidth;
|
||||
this.vertices[numVertices++] = originY / imageHeight;
|
||||
this.vertices[numVertices++] = opacity;
|
||||
this.vertices[numVertices++] = rotateWithView;
|
||||
|
||||
this.indices[numIndices++] = n;
|
||||
this.indices[numIndices++] = n + 1;
|
||||
this.indices[numIndices++] = n + 2;
|
||||
this.indices[numIndices++] = n;
|
||||
this.indices[numIndices++] = n + 2;
|
||||
this.indices[numIndices++] = n + 3;
|
||||
}
|
||||
|
||||
return numVertices;
|
||||
};
|
||||
ol.inherits(ol.render.webgl.ImageReplay, ol.render.webgl.TextureReplay);
|
||||
|
||||
|
||||
/**
|
||||
@@ -275,7 +53,7 @@ if (ol.ENABLE_WEBGL) {
|
||||
this.startIndicesFeature.push(feature);
|
||||
var flatCoordinates = multiPointGeometry.getFlatCoordinates();
|
||||
var stride = multiPointGeometry.getStride();
|
||||
this.drawCoordinates_(
|
||||
this.drawCoordinates(
|
||||
flatCoordinates, 0, flatCoordinates.length, stride);
|
||||
};
|
||||
|
||||
@@ -288,7 +66,7 @@ if (ol.ENABLE_WEBGL) {
|
||||
this.startIndicesFeature.push(feature);
|
||||
var flatCoordinates = pointGeometry.getFlatCoordinates();
|
||||
var stride = pointGeometry.getStride();
|
||||
this.drawCoordinates_(
|
||||
this.drawCoordinates(
|
||||
flatCoordinates, 0, flatCoordinates.length, stride);
|
||||
};
|
||||
|
||||
@@ -299,8 +77,8 @@ if (ol.ENABLE_WEBGL) {
|
||||
ol.render.webgl.ImageReplay.prototype.finish = function(context) {
|
||||
var gl = context.getGL();
|
||||
|
||||
this.groupIndices_.push(this.indices.length);
|
||||
this.hitDetectionGroupIndices_.push(this.indices.length);
|
||||
this.groupIndices.push(this.indices.length);
|
||||
this.hitDetectionGroupIndices.push(this.indices.length);
|
||||
|
||||
// create, bind, and populate the vertices buffer
|
||||
this.verticesBuffer = new ol.webgl.Buffer(this.vertices);
|
||||
@@ -314,246 +92,14 @@ if (ol.ENABLE_WEBGL) {
|
||||
/** @type {Object.<string, WebGLTexture>} */
|
||||
var texturePerImage = {};
|
||||
|
||||
this.createTextures_(this.textures_, this.images_, texturePerImage, gl);
|
||||
this.createTextures(this.textures_, this.images_, texturePerImage, gl);
|
||||
|
||||
this.createTextures_(this.hitDetectionTextures_, this.hitDetectionImages_,
|
||||
this.createTextures(this.hitDetectionTextures_, this.hitDetectionImages_,
|
||||
texturePerImage, gl);
|
||||
|
||||
this.anchorX_ = undefined;
|
||||
this.anchorY_ = undefined;
|
||||
this.height_ = undefined;
|
||||
this.images_ = null;
|
||||
this.hitDetectionImages_ = null;
|
||||
this.imageHeight_ = undefined;
|
||||
this.imageWidth_ = undefined;
|
||||
this.indices = null;
|
||||
this.opacity_ = undefined;
|
||||
this.originX_ = undefined;
|
||||
this.originY_ = undefined;
|
||||
this.rotateWithView_ = undefined;
|
||||
this.rotation_ = undefined;
|
||||
this.scale_ = undefined;
|
||||
this.vertices = null;
|
||||
this.width_ = undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Array.<WebGLTexture>} textures Textures.
|
||||
* @param {Array.<HTMLCanvasElement|HTMLImageElement|HTMLVideoElement>} images
|
||||
* Images.
|
||||
* @param {Object.<string, WebGLTexture>} texturePerImage Texture cache.
|
||||
* @param {WebGLRenderingContext} gl Gl.
|
||||
*/
|
||||
ol.render.webgl.ImageReplay.prototype.createTextures_ = function(textures, images, texturePerImage, gl) {
|
||||
var texture, image, uid, i;
|
||||
var ii = images.length;
|
||||
for (i = 0; i < ii; ++i) {
|
||||
image = images[i];
|
||||
|
||||
uid = ol.getUid(image).toString();
|
||||
if (uid in texturePerImage) {
|
||||
texture = texturePerImage[uid];
|
||||
} else {
|
||||
texture = ol.webgl.Context.createTexture(
|
||||
gl, image, ol.webgl.CLAMP_TO_EDGE, ol.webgl.CLAMP_TO_EDGE);
|
||||
texturePerImage[uid] = texture;
|
||||
}
|
||||
textures[i] = texture;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.ImageReplay.prototype.setUpProgram = function(gl, context, size, pixelRatio) {
|
||||
// get the program
|
||||
var fragmentShader = ol.render.webgl.imagereplay.defaultshader.fragment;
|
||||
var vertexShader = ol.render.webgl.imagereplay.defaultshader.vertex;
|
||||
var program = context.getProgram(fragmentShader, vertexShader);
|
||||
|
||||
// get the locations
|
||||
var locations;
|
||||
if (!this.defaultLocations_) {
|
||||
locations =
|
||||
new ol.render.webgl.imagereplay.defaultshader.Locations(gl, program);
|
||||
this.defaultLocations_ = locations;
|
||||
} else {
|
||||
locations = this.defaultLocations_;
|
||||
}
|
||||
|
||||
// use the program (FIXME: use the return value)
|
||||
context.useProgram(program);
|
||||
|
||||
// enable the vertex attrib arrays
|
||||
gl.enableVertexAttribArray(locations.a_position);
|
||||
gl.vertexAttribPointer(locations.a_position, 2, ol.webgl.FLOAT,
|
||||
false, 32, 0);
|
||||
|
||||
gl.enableVertexAttribArray(locations.a_offsets);
|
||||
gl.vertexAttribPointer(locations.a_offsets, 2, ol.webgl.FLOAT,
|
||||
false, 32, 8);
|
||||
|
||||
gl.enableVertexAttribArray(locations.a_texCoord);
|
||||
gl.vertexAttribPointer(locations.a_texCoord, 2, ol.webgl.FLOAT,
|
||||
false, 32, 16);
|
||||
|
||||
gl.enableVertexAttribArray(locations.a_opacity);
|
||||
gl.vertexAttribPointer(locations.a_opacity, 1, ol.webgl.FLOAT,
|
||||
false, 32, 24);
|
||||
|
||||
gl.enableVertexAttribArray(locations.a_rotateWithView);
|
||||
gl.vertexAttribPointer(locations.a_rotateWithView, 1, ol.webgl.FLOAT,
|
||||
false, 32, 28);
|
||||
|
||||
return locations;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.ImageReplay.prototype.shutDownProgram = function(gl, locations) {
|
||||
gl.disableVertexAttribArray(locations.a_position);
|
||||
gl.disableVertexAttribArray(locations.a_offsets);
|
||||
gl.disableVertexAttribArray(locations.a_texCoord);
|
||||
gl.disableVertexAttribArray(locations.a_opacity);
|
||||
gl.disableVertexAttribArray(locations.a_rotateWithView);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.ImageReplay.prototype.drawReplay = function(gl, context, skippedFeaturesHash, hitDetection) {
|
||||
var textures = hitDetection ? this.hitDetectionTextures_ : this.textures_;
|
||||
var groupIndices = hitDetection ? this.hitDetectionGroupIndices_ : this.groupIndices_;
|
||||
|
||||
if (!ol.obj.isEmpty(skippedFeaturesHash)) {
|
||||
this.drawReplaySkipping_(
|
||||
gl, context, skippedFeaturesHash, textures, groupIndices);
|
||||
} else {
|
||||
var i, ii, start;
|
||||
for (i = 0, ii = textures.length, start = 0; i < ii; ++i) {
|
||||
gl.bindTexture(ol.webgl.TEXTURE_2D, textures[i]);
|
||||
var end = groupIndices[i];
|
||||
this.drawElements(gl, context, start, end);
|
||||
start = end;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw the replay while paying attention to skipped features.
|
||||
*
|
||||
* This functions creates groups of features that can be drawn to together,
|
||||
* so that the number of `drawElements` calls is minimized.
|
||||
*
|
||||
* For example given the following texture groups:
|
||||
*
|
||||
* Group 1: A B C
|
||||
* Group 2: D [E] F G
|
||||
*
|
||||
* If feature E should be skipped, the following `drawElements` calls will be
|
||||
* made:
|
||||
*
|
||||
* drawElements with feature A, B and C
|
||||
* drawElements with feature D
|
||||
* drawElements with feature F and G
|
||||
*
|
||||
* @private
|
||||
* @param {WebGLRenderingContext} gl gl.
|
||||
* @param {ol.webgl.Context} context Context.
|
||||
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
||||
* to skip.
|
||||
* @param {Array.<WebGLTexture>} textures Textures.
|
||||
* @param {Array.<number>} groupIndices Texture group indices.
|
||||
*/
|
||||
ol.render.webgl.ImageReplay.prototype.drawReplaySkipping_ = function(gl, context, skippedFeaturesHash, textures,
|
||||
groupIndices) {
|
||||
var featureIndex = 0;
|
||||
|
||||
var i, ii;
|
||||
for (i = 0, ii = textures.length; i < ii; ++i) {
|
||||
gl.bindTexture(ol.webgl.TEXTURE_2D, textures[i]);
|
||||
var groupStart = (i > 0) ? groupIndices[i - 1] : 0;
|
||||
var groupEnd = groupIndices[i];
|
||||
|
||||
var start = groupStart;
|
||||
var end = groupStart;
|
||||
while (featureIndex < this.startIndices.length &&
|
||||
this.startIndices[featureIndex] <= groupEnd) {
|
||||
var feature = this.startIndicesFeature[featureIndex];
|
||||
|
||||
var featureUid = ol.getUid(feature).toString();
|
||||
if (skippedFeaturesHash[featureUid] !== undefined) {
|
||||
// feature should be skipped
|
||||
if (start !== end) {
|
||||
// draw the features so far
|
||||
this.drawElements(gl, context, start, end);
|
||||
}
|
||||
// continue with the next feature
|
||||
start = (featureIndex === this.startIndices.length - 1) ?
|
||||
groupEnd : this.startIndices[featureIndex + 1];
|
||||
end = start;
|
||||
} else {
|
||||
// the feature is not skipped, augment the end index
|
||||
end = (featureIndex === this.startIndices.length - 1) ?
|
||||
groupEnd : this.startIndices[featureIndex + 1];
|
||||
}
|
||||
featureIndex++;
|
||||
}
|
||||
|
||||
if (start !== end) {
|
||||
// draw the remaining features (in case there was no skipped feature
|
||||
// in this texture group, all features of a group are drawn together)
|
||||
this.drawElements(gl, context, start, end);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.ImageReplay.prototype.drawHitDetectionReplayOneByOne = function(gl, context, skippedFeaturesHash,
|
||||
featureCallback, opt_hitExtent) {
|
||||
var i, groupStart, start, end, feature, featureUid;
|
||||
var featureIndex = this.startIndices.length - 1;
|
||||
for (i = this.hitDetectionTextures_.length - 1; i >= 0; --i) {
|
||||
gl.bindTexture(ol.webgl.TEXTURE_2D, this.hitDetectionTextures_[i]);
|
||||
groupStart = (i > 0) ? this.hitDetectionGroupIndices_[i - 1] : 0;
|
||||
end = this.hitDetectionGroupIndices_[i];
|
||||
|
||||
// draw all features for this texture group
|
||||
while (featureIndex >= 0 &&
|
||||
this.startIndices[featureIndex] >= groupStart) {
|
||||
start = this.startIndices[featureIndex];
|
||||
feature = this.startIndicesFeature[featureIndex];
|
||||
featureUid = ol.getUid(feature).toString();
|
||||
|
||||
if (skippedFeaturesHash[featureUid] === undefined &&
|
||||
feature.getGeometry() &&
|
||||
(opt_hitExtent === undefined || ol.extent.intersects(
|
||||
/** @type {Array<number>} */ (opt_hitExtent),
|
||||
feature.getGeometry().getExtent()))) {
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
this.drawElements(gl, context, start, end);
|
||||
|
||||
var result = featureCallback(feature);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
end = start;
|
||||
featureIndex--;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
ol.render.webgl.TextureReplay.prototype.finish.call(this, context);
|
||||
};
|
||||
|
||||
|
||||
@@ -578,7 +124,7 @@ if (ol.ENABLE_WEBGL) {
|
||||
} else {
|
||||
currentImage = this.images_[this.images_.length - 1];
|
||||
if (ol.getUid(currentImage) != ol.getUid(image)) {
|
||||
this.groupIndices_.push(this.indices.length);
|
||||
this.groupIndices.push(this.indices.length);
|
||||
this.images_.push(image);
|
||||
}
|
||||
}
|
||||
@@ -589,23 +135,39 @@ if (ol.ENABLE_WEBGL) {
|
||||
currentImage =
|
||||
this.hitDetectionImages_[this.hitDetectionImages_.length - 1];
|
||||
if (ol.getUid(currentImage) != ol.getUid(hitDetectionImage)) {
|
||||
this.hitDetectionGroupIndices_.push(this.indices.length);
|
||||
this.hitDetectionGroupIndices.push(this.indices.length);
|
||||
this.hitDetectionImages_.push(hitDetectionImage);
|
||||
}
|
||||
}
|
||||
|
||||
this.anchorX_ = anchor[0];
|
||||
this.anchorY_ = anchor[1];
|
||||
this.height_ = size[1];
|
||||
this.imageHeight_ = imageSize[1];
|
||||
this.imageWidth_ = imageSize[0];
|
||||
this.opacity_ = opacity;
|
||||
this.originX_ = origin[0];
|
||||
this.originY_ = origin[1];
|
||||
this.rotation_ = rotation;
|
||||
this.rotateWithView_ = rotateWithView;
|
||||
this.scale_ = scale;
|
||||
this.width_ = size[0];
|
||||
this.anchorX = anchor[0];
|
||||
this.anchorY = anchor[1];
|
||||
this.height = size[1];
|
||||
this.imageHeight = imageSize[1];
|
||||
this.imageWidth = imageSize[0];
|
||||
this.opacity = opacity;
|
||||
this.originX = origin[0];
|
||||
this.originY = origin[1];
|
||||
this.rotation = rotation;
|
||||
this.rotateWithView = rotateWithView;
|
||||
this.scale = scale;
|
||||
this.width = size[0];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.ImageReplay.prototype.getTextures = function(opt_all) {
|
||||
return opt_all ? this.textures_.concat(this.hitDetectionTextures_) : this.textures_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.ImageReplay.prototype.getHitDetectionTextures = function() {
|
||||
return this.hitDetectionTextures_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
// This file is automatically generated, do not edit
|
||||
goog.provide('ol.render.webgl.imagereplay.defaultshader');
|
||||
|
||||
goog.require('ol');
|
||||
goog.require('ol.webgl.Fragment');
|
||||
goog.require('ol.webgl.Vertex');
|
||||
|
||||
if (ol.ENABLE_WEBGL) {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.webgl.Fragment}
|
||||
* @struct
|
||||
*/
|
||||
ol.render.webgl.imagereplay.defaultshader.Fragment = function() {
|
||||
ol.webgl.Fragment.call(this, ol.render.webgl.imagereplay.defaultshader.Fragment.SOURCE);
|
||||
};
|
||||
ol.inherits(ol.render.webgl.imagereplay.defaultshader.Fragment, ol.webgl.Fragment);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
ol.render.webgl.imagereplay.defaultshader.Fragment.DEBUG_SOURCE = 'precision mediump float;\nvarying vec2 v_texCoord;\nvarying float v_opacity;\n\nuniform float u_opacity;\nuniform sampler2D u_image;\n\nvoid main(void) {\n vec4 texColor = texture2D(u_image, v_texCoord);\n gl_FragColor.rgb = texColor.rgb;\n float alpha = texColor.a * v_opacity * u_opacity;\n if (alpha == 0.0) {\n discard;\n }\n gl_FragColor.a = alpha;\n}\n';
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
ol.render.webgl.imagereplay.defaultshader.Fragment.OPTIMIZED_SOURCE = 'precision mediump float;varying vec2 a;varying float b;uniform float k;uniform sampler2D l;void main(void){vec4 texColor=texture2D(l,a);gl_FragColor.rgb=texColor.rgb;float alpha=texColor.a*b*k;if(alpha==0.0){discard;}gl_FragColor.a=alpha;}';
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
ol.render.webgl.imagereplay.defaultshader.Fragment.SOURCE = ol.DEBUG_WEBGL ?
|
||||
ol.render.webgl.imagereplay.defaultshader.Fragment.DEBUG_SOURCE :
|
||||
ol.render.webgl.imagereplay.defaultshader.Fragment.OPTIMIZED_SOURCE;
|
||||
|
||||
|
||||
ol.render.webgl.imagereplay.defaultshader.fragment = new ol.render.webgl.imagereplay.defaultshader.Fragment();
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.webgl.Vertex}
|
||||
* @struct
|
||||
*/
|
||||
ol.render.webgl.imagereplay.defaultshader.Vertex = function() {
|
||||
ol.webgl.Vertex.call(this, ol.render.webgl.imagereplay.defaultshader.Vertex.SOURCE);
|
||||
};
|
||||
ol.inherits(ol.render.webgl.imagereplay.defaultshader.Vertex, ol.webgl.Vertex);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
ol.render.webgl.imagereplay.defaultshader.Vertex.DEBUG_SOURCE = 'varying vec2 v_texCoord;\nvarying float v_opacity;\n\nattribute vec2 a_position;\nattribute vec2 a_texCoord;\nattribute vec2 a_offsets;\nattribute float a_opacity;\nattribute float a_rotateWithView;\n\nuniform mat4 u_projectionMatrix;\nuniform mat4 u_offsetScaleMatrix;\nuniform mat4 u_offsetRotateMatrix;\n\nvoid main(void) {\n mat4 offsetMatrix = u_offsetScaleMatrix;\n if (a_rotateWithView == 1.0) {\n offsetMatrix = u_offsetScaleMatrix * u_offsetRotateMatrix;\n }\n vec4 offsets = offsetMatrix * vec4(a_offsets, 0.0, 0.0);\n gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;\n v_texCoord = a_texCoord;\n v_opacity = a_opacity;\n}\n\n\n';
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
ol.render.webgl.imagereplay.defaultshader.Vertex.OPTIMIZED_SOURCE = 'varying vec2 a;varying float b;attribute vec2 c;attribute vec2 d;attribute vec2 e;attribute float f;attribute float g;uniform mat4 h;uniform mat4 i;uniform mat4 j;void main(void){mat4 offsetMatrix=i;if(g==1.0){offsetMatrix=i*j;}vec4 offsets=offsetMatrix*vec4(e,0.0,0.0);gl_Position=h*vec4(c,0.0,1.0)+offsets;a=d;b=f;}';
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
ol.render.webgl.imagereplay.defaultshader.Vertex.SOURCE = ol.DEBUG_WEBGL ?
|
||||
ol.render.webgl.imagereplay.defaultshader.Vertex.DEBUG_SOURCE :
|
||||
ol.render.webgl.imagereplay.defaultshader.Vertex.OPTIMIZED_SOURCE;
|
||||
|
||||
|
||||
ol.render.webgl.imagereplay.defaultshader.vertex = new ol.render.webgl.imagereplay.defaultshader.Vertex();
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {WebGLRenderingContext} gl GL.
|
||||
* @param {WebGLProgram} program Program.
|
||||
* @struct
|
||||
*/
|
||||
ol.render.webgl.imagereplay.defaultshader.Locations = function(gl, program) {
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_image = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_image' : 'l');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_offsetRotateMatrix = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'j');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_offsetScaleMatrix = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'i');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_opacity = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_opacity' : 'k');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_projectionMatrix = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_projectionMatrix' : 'h');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_offsets = gl.getAttribLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'a_offsets' : 'e');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_opacity = gl.getAttribLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'a_opacity' : 'f');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_position = gl.getAttribLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'a_position' : 'c');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_rotateWithView = gl.getAttribLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'a_rotateWithView' : 'g');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_texCoord = gl.getAttribLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'a_texCoord' : 'd');
|
||||
};
|
||||
|
||||
}
|
||||
@@ -324,16 +324,19 @@ if (ol.ENABLE_WEBGL) {
|
||||
*/
|
||||
ol.render.webgl.LineStringReplay.prototype.drawMultiLineString = function(multiLineStringGeometry, feature) {
|
||||
var indexCount = this.indices.length;
|
||||
var lineStringGeometries = multiLineStringGeometry.getLineStrings();
|
||||
var ends = multiLineStringGeometry.getEnds();
|
||||
ends.unshift(0);
|
||||
var flatCoordinates = multiLineStringGeometry.getFlatCoordinates();
|
||||
var stride = multiLineStringGeometry.getStride();
|
||||
var i, ii;
|
||||
for (i = 0, ii = lineStringGeometries.length; i < ii; ++i) {
|
||||
var flatCoordinates = lineStringGeometries[i].getFlatCoordinates();
|
||||
var stride = lineStringGeometries[i].getStride();
|
||||
if (this.isValid_(flatCoordinates, 0, flatCoordinates.length, stride)) {
|
||||
flatCoordinates = ol.geom.flat.transform.translate(flatCoordinates, 0, flatCoordinates.length,
|
||||
if (ends.length > 1) {
|
||||
for (i = 1, ii = ends.length; i < ii; ++i) {
|
||||
if (this.isValid_(flatCoordinates, ends[i - 1], ends[i], stride)) {
|
||||
var lineString = ol.geom.flat.transform.translate(flatCoordinates, ends[i - 1], ends[i],
|
||||
stride, -this.origin[0], -this.origin[1]);
|
||||
this.drawCoordinates_(
|
||||
flatCoordinates, 0, flatCoordinates.length, stride);
|
||||
lineString, 0, lineString.length, stride);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.indices.length > indexCount) {
|
||||
@@ -446,8 +449,8 @@ if (ol.ENABLE_WEBGL) {
|
||||
// get the locations
|
||||
var locations;
|
||||
if (!this.defaultLocations_) {
|
||||
locations =
|
||||
new ol.render.webgl.linestringreplay.defaultshader.Locations(gl, program);
|
||||
// eslint-disable-next-line openlayers-internal/no-missing-requires
|
||||
locations = new ol.render.webgl.linestringreplay.defaultshader.Locations(gl, program);
|
||||
this.defaultLocations_ = locations;
|
||||
} else {
|
||||
locations = this.defaultLocations_;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// This file is automatically generated, do not edit
|
||||
/* eslint openlayers-internal/no-missing-requires: 0 */
|
||||
goog.provide('ol.render.webgl.linestringreplay.defaultshader');
|
||||
|
||||
goog.require('ol');
|
||||
|
||||
@@ -88,20 +88,39 @@ if (ol.ENABLE_WEBGL) {
|
||||
for (i = 0, ii = holeFlatCoordinates.length; i < ii; ++i) {
|
||||
var holeList = {
|
||||
list: new ol.structs.LinkedList(),
|
||||
maxX: undefined
|
||||
maxX: undefined,
|
||||
rtree: new ol.structs.RBush()
|
||||
};
|
||||
holeLists.push(holeList);
|
||||
holeList.maxX = this.processFlatCoordinates_(holeFlatCoordinates[i],
|
||||
stride, holeList.list, rtree, false);
|
||||
stride, holeList.list, holeList.rtree, false);
|
||||
}
|
||||
holeLists.sort(function(a, b) {
|
||||
return b.maxX - a.maxX;
|
||||
return b.maxX[0] === a.maxX[0] ? a.maxX[1] - b.maxX[1] : b.maxX[0] - a.maxX[0];
|
||||
});
|
||||
for (i = 0; i < holeLists.length; ++i) {
|
||||
this.bridgeHole_(holeLists[i].list, holeLists[i].maxX, outerRing, maxX, rtree);
|
||||
}
|
||||
var currList = holeLists[i].list;
|
||||
var start = currList.firstItem();
|
||||
var currItem = start;
|
||||
var intersection;
|
||||
do {
|
||||
if (this.getIntersections_(currItem, rtree).length) {
|
||||
intersection = true;
|
||||
break;
|
||||
}
|
||||
currItem = currList.nextItem();
|
||||
} while (start !== currItem);
|
||||
if (!intersection) {
|
||||
this.classifyPoints_(currList, holeLists[i].rtree, true);
|
||||
if (this.bridgeHole_(currList, holeLists[i].maxX[0], outerRing, maxX[0], rtree)) {
|
||||
rtree.concat(holeLists[i].rtree);
|
||||
this.classifyPoints_(outerRing, rtree, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.classifyPoints_(outerRing, rtree, false);
|
||||
}
|
||||
this.triangulate_(outerRing, rtree);
|
||||
};
|
||||
|
||||
@@ -114,13 +133,13 @@ if (ol.ENABLE_WEBGL) {
|
||||
* @param {ol.structs.LinkedList} list Linked list.
|
||||
* @param {ol.structs.RBush} rtree R-Tree of the polygon.
|
||||
* @param {boolean} clockwise Coordinate order should be clockwise.
|
||||
* @return {number} Maximum X value.
|
||||
* @return {Array.<number>} X and Y coords of maximum X value.
|
||||
*/
|
||||
ol.render.webgl.PolygonReplay.prototype.processFlatCoordinates_ = function(
|
||||
flatCoordinates, stride, list, rtree, clockwise) {
|
||||
var isClockwise = ol.geom.flat.orient.linearRingIsClockwise(flatCoordinates,
|
||||
0, flatCoordinates.length, stride);
|
||||
var i, ii, maxX;
|
||||
var i, ii, maxXX, maxXY;
|
||||
var n = this.vertices.length / 2;
|
||||
/** @type {ol.WebglPolygonVertex} */
|
||||
var start;
|
||||
@@ -133,13 +152,17 @@ if (ol.ENABLE_WEBGL) {
|
||||
if (clockwise === isClockwise) {
|
||||
start = this.createPoint_(flatCoordinates[0], flatCoordinates[1], n++);
|
||||
p0 = start;
|
||||
maxX = flatCoordinates[0];
|
||||
maxXX = flatCoordinates[0];
|
||||
maxXY = flatCoordinates[1];
|
||||
for (i = stride, ii = flatCoordinates.length; i < ii; i += stride) {
|
||||
p1 = this.createPoint_(flatCoordinates[i], flatCoordinates[i + 1], n++);
|
||||
segments.push(this.insertItem_(p0, p1, list));
|
||||
extents.push([Math.min(p0.x, p1.x), Math.min(p0.y, p1.y), Math.max(p0.x, p1.x),
|
||||
Math.max(p0.y, p1.y)]);
|
||||
maxX = flatCoordinates[i] > maxX ? flatCoordinates[i] : maxX;
|
||||
if (flatCoordinates[i] > maxXX) {
|
||||
maxXX = flatCoordinates[i];
|
||||
maxXY = flatCoordinates[i + 1];
|
||||
}
|
||||
p0 = p1;
|
||||
}
|
||||
segments.push(this.insertItem_(p1, start, list));
|
||||
@@ -149,13 +172,17 @@ if (ol.ENABLE_WEBGL) {
|
||||
var end = flatCoordinates.length - stride;
|
||||
start = this.createPoint_(flatCoordinates[end], flatCoordinates[end + 1], n++);
|
||||
p0 = start;
|
||||
maxX = flatCoordinates[end];
|
||||
maxXX = flatCoordinates[end];
|
||||
maxXY = flatCoordinates[end + 1];
|
||||
for (i = end - stride, ii = 0; i >= ii; i -= stride) {
|
||||
p1 = this.createPoint_(flatCoordinates[i], flatCoordinates[i + 1], n++);
|
||||
segments.push(this.insertItem_(p0, p1, list));
|
||||
extents.push([Math.min(p0.x, p1.x), Math.min(p0.y, p1.y), Math.max(p0.x, p1.x),
|
||||
Math.max(p0.y, p1.y)]);
|
||||
maxX = flatCoordinates[i] > maxX ? flatCoordinates[i] : maxX;
|
||||
if (flatCoordinates[i] > maxXX) {
|
||||
maxXX = flatCoordinates[i];
|
||||
maxXY = flatCoordinates[i + 1];
|
||||
}
|
||||
p0 = p1;
|
||||
}
|
||||
segments.push(this.insertItem_(p1, start, list));
|
||||
@@ -164,7 +191,7 @@ if (ol.ENABLE_WEBGL) {
|
||||
}
|
||||
rtree.load(extents, segments);
|
||||
|
||||
return maxX;
|
||||
return [maxXX, maxXY];
|
||||
};
|
||||
|
||||
|
||||
@@ -212,10 +239,10 @@ if (ol.ENABLE_WEBGL) {
|
||||
* @param {ol.structs.LinkedList} list Linked list of the polygon.
|
||||
* @param {number} listMaxX Maximum X value of the polygon.
|
||||
* @param {ol.structs.RBush} rtree R-Tree of the polygon.
|
||||
* @return {boolean} Bridging was successful.
|
||||
*/
|
||||
ol.render.webgl.PolygonReplay.prototype.bridgeHole_ = function(hole, holeMaxX,
|
||||
list, listMaxX, rtree) {
|
||||
this.classifyPoints_(hole, rtree, true);
|
||||
var seg = hole.firstItem();
|
||||
while (seg.p1.x !== holeMaxX) {
|
||||
seg = hole.nextItem();
|
||||
@@ -232,19 +259,18 @@ if (ol.ENABLE_WEBGL) {
|
||||
var intersectingSegments = this.getIntersections_({p0: p1, p1: p2}, rtree, true);
|
||||
for (i = 0, ii = intersectingSegments.length; i < ii; ++i) {
|
||||
var currSeg = intersectingSegments[i];
|
||||
if (currSeg.p0.reflex === undefined) {
|
||||
var intersection = this.calculateIntersection_(p1, p2, currSeg.p0,
|
||||
currSeg.p1, true);
|
||||
var dist = Math.abs(p1.x - intersection[0]);
|
||||
if (dist < minDist) {
|
||||
if (dist < minDist && ol.render.webgl.triangleIsCounterClockwise(p1.x, p1.y,
|
||||
currSeg.p0.x, currSeg.p0.y, currSeg.p1.x, currSeg.p1.y) !== undefined) {
|
||||
minDist = dist;
|
||||
p5 = {x: intersection[0], y: intersection[1], i: -1};
|
||||
seg = currSeg;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (minDist === Infinity) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
bestPoint = seg.p1;
|
||||
|
||||
@@ -264,7 +290,7 @@ if (ol.ENABLE_WEBGL) {
|
||||
}
|
||||
|
||||
seg = list.firstItem();
|
||||
while (seg.p1 !== bestPoint) {
|
||||
while (seg.p1.x !== bestPoint.x || seg.p1.y !== bestPoint.y) {
|
||||
seg = list.nextItem();
|
||||
}
|
||||
|
||||
@@ -278,6 +304,8 @@ if (ol.ENABLE_WEBGL) {
|
||||
seg.p1 = p1Bridge;
|
||||
hole.setFirstItem();
|
||||
list.concat(hole);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
@@ -712,28 +740,33 @@ if (ol.ENABLE_WEBGL) {
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.PolygonReplay.prototype.drawMultiPolygon = function(multiPolygonGeometry, feature) {
|
||||
var polygons = multiPolygonGeometry.getPolygons();
|
||||
var endss = multiPolygonGeometry.getEndss();
|
||||
var stride = multiPolygonGeometry.getStride();
|
||||
var currIndex = this.indices.length;
|
||||
var currLineIndex = this.lineStringReplay.getCurrentIndex();
|
||||
var flatCoordinates = multiPolygonGeometry.getFlatCoordinates();
|
||||
var i, ii, j, jj;
|
||||
for (i = 0, ii = polygons.length; i < ii; ++i) {
|
||||
var linearRings = polygons[i].getLinearRings();
|
||||
if (linearRings.length > 0) {
|
||||
var flatCoordinates = linearRings[0].getFlatCoordinates();
|
||||
flatCoordinates = ol.geom.flat.transform.translate(flatCoordinates, 0, flatCoordinates.length,
|
||||
var start = 0;
|
||||
for (i = 0, ii = endss.length; i < ii; ++i) {
|
||||
var ends = endss[i];
|
||||
if (ends.length > 0) {
|
||||
var outerRing = ol.geom.flat.transform.translate(flatCoordinates, start, ends[0],
|
||||
stride, -this.origin[0], -this.origin[1]);
|
||||
if (outerRing.length) {
|
||||
var holes = [];
|
||||
var holeFlatCoords;
|
||||
for (j = 1, jj = linearRings.length; j < jj; ++j) {
|
||||
holeFlatCoords = linearRings[j].getFlatCoordinates();
|
||||
holeFlatCoords = ol.geom.flat.transform.translate(holeFlatCoords, 0, holeFlatCoords.length,
|
||||
stride, -this.origin[0], -this.origin[1]);
|
||||
for (j = 1, jj = ends.length; j < jj; ++j) {
|
||||
if (ends[j] !== ends[j - 1]) {
|
||||
holeFlatCoords = ol.geom.flat.transform.translate(flatCoordinates, ends[j - 1],
|
||||
ends[j], stride, -this.origin[0], -this.origin[1]);
|
||||
holes.push(holeFlatCoords);
|
||||
}
|
||||
this.lineStringReplay.drawPolygonCoordinates(flatCoordinates, holes, stride);
|
||||
this.drawCoordinates_(flatCoordinates, holes, stride);
|
||||
}
|
||||
this.lineStringReplay.drawPolygonCoordinates(outerRing, holes, stride);
|
||||
this.drawCoordinates_(outerRing, holes, stride);
|
||||
}
|
||||
}
|
||||
start = ends[ends.length - 1];
|
||||
}
|
||||
if (this.indices.length > currIndex) {
|
||||
this.startIndices.push(currIndex);
|
||||
@@ -753,9 +786,23 @@ if (ol.ENABLE_WEBGL) {
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.PolygonReplay.prototype.drawPolygon = function(polygonGeometry, feature) {
|
||||
var linearRings = polygonGeometry.getLinearRings();
|
||||
var ends = polygonGeometry.getEnds();
|
||||
var stride = polygonGeometry.getStride();
|
||||
if (linearRings.length > 0) {
|
||||
if (ends.length > 0) {
|
||||
var flatCoordinates = polygonGeometry.getFlatCoordinates().map(Number);
|
||||
var outerRing = ol.geom.flat.transform.translate(flatCoordinates, 0, ends[0],
|
||||
stride, -this.origin[0], -this.origin[1]);
|
||||
if (outerRing.length) {
|
||||
var holes = [];
|
||||
var i, ii, holeFlatCoords;
|
||||
for (i = 1, ii = ends.length; i < ii; ++i) {
|
||||
if (ends[i] !== ends[i - 1]) {
|
||||
holeFlatCoords = ol.geom.flat.transform.translate(flatCoordinates, ends[i - 1],
|
||||
ends[i], stride, -this.origin[0], -this.origin[1]);
|
||||
holes.push(holeFlatCoords);
|
||||
}
|
||||
}
|
||||
|
||||
this.startIndices.push(this.indices.length);
|
||||
this.startIndicesFeature.push(feature);
|
||||
if (this.state_.changed) {
|
||||
@@ -764,19 +811,9 @@ if (ol.ENABLE_WEBGL) {
|
||||
}
|
||||
this.lineStringReplay.setPolygonStyle(feature);
|
||||
|
||||
var flatCoordinates = linearRings[0].getFlatCoordinates();
|
||||
flatCoordinates = ol.geom.flat.transform.translate(flatCoordinates, 0, flatCoordinates.length,
|
||||
stride, -this.origin[0], -this.origin[1]);
|
||||
var holes = [];
|
||||
var i, ii, holeFlatCoords;
|
||||
for (i = 1, ii = linearRings.length; i < ii; ++i) {
|
||||
holeFlatCoords = linearRings[i].getFlatCoordinates();
|
||||
holeFlatCoords = ol.geom.flat.transform.translate(holeFlatCoords, 0, holeFlatCoords.length,
|
||||
stride, -this.origin[0], -this.origin[1]);
|
||||
holes.push(holeFlatCoords);
|
||||
this.lineStringReplay.drawPolygonCoordinates(outerRing, holes, stride);
|
||||
this.drawCoordinates_(outerRing, holes, stride);
|
||||
}
|
||||
this.lineStringReplay.drawPolygonCoordinates(flatCoordinates, holes, stride);
|
||||
this.drawCoordinates_(flatCoordinates, holes, stride);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -833,8 +870,8 @@ if (ol.ENABLE_WEBGL) {
|
||||
// get the locations
|
||||
var locations;
|
||||
if (!this.defaultLocations_) {
|
||||
locations =
|
||||
new ol.render.webgl.polygonreplay.defaultshader.Locations(gl, program);
|
||||
// eslint-disable-next-line openlayers-internal/no-missing-requires
|
||||
locations = new ol.render.webgl.polygonreplay.defaultshader.Locations(gl, program);
|
||||
this.defaultLocations_ = locations;
|
||||
} else {
|
||||
locations = this.defaultLocations_;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// This file is automatically generated, do not edit
|
||||
/* eslint openlayers-internal/no-missing-requires: 0 */
|
||||
goog.provide('ol.render.webgl.polygonreplay.defaultshader');
|
||||
|
||||
goog.require('ol');
|
||||
|
||||
@@ -140,9 +140,9 @@ if (ol.ENABLE_WEBGL) {
|
||||
* @param {ol.Size} size Size.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @return {ol.render.webgl.circlereplay.defaultshader.Locations|
|
||||
ol.render.webgl.imagereplay.defaultshader.Locations|
|
||||
ol.render.webgl.linestringreplay.defaultshader.Locations|
|
||||
ol.render.webgl.polygonreplay.defaultshader.Locations} Locations.
|
||||
ol.render.webgl.polygonreplay.defaultshader.Locations|
|
||||
ol.render.webgl.texturereplay.defaultshader.Locations} Locations.
|
||||
*/
|
||||
ol.render.webgl.Replay.prototype.setUpProgram = function(gl, context, size, pixelRatio) {};
|
||||
|
||||
@@ -152,9 +152,9 @@ if (ol.ENABLE_WEBGL) {
|
||||
* @protected
|
||||
* @param {WebGLRenderingContext} gl gl.
|
||||
* @param {ol.render.webgl.circlereplay.defaultshader.Locations|
|
||||
ol.render.webgl.imagereplay.defaultshader.Locations|
|
||||
ol.render.webgl.linestringreplay.defaultshader.Locations|
|
||||
ol.render.webgl.polygonreplay.defaultshader.Locations} locations Locations.
|
||||
ol.render.webgl.polygonreplay.defaultshader.Locations|
|
||||
ol.render.webgl.texturereplay.defaultshader.Locations} locations Locations.
|
||||
*/
|
||||
ol.render.webgl.Replay.prototype.shutDownProgram = function(gl, locations) {};
|
||||
|
||||
|
||||
@@ -1,71 +1,455 @@
|
||||
goog.provide('ol.render.webgl.TextReplay');
|
||||
|
||||
goog.require('ol');
|
||||
goog.require('ol.colorlike');
|
||||
goog.require('ol.dom');
|
||||
goog.require('ol.has');
|
||||
goog.require('ol.render.webgl');
|
||||
goog.require('ol.render.webgl.TextureReplay');
|
||||
goog.require('ol.style.AtlasManager');
|
||||
goog.require('ol.webgl.Buffer');
|
||||
|
||||
|
||||
if (ol.ENABLE_WEBGL) {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @abstract
|
||||
* @extends {ol.render.webgl.TextureReplay}
|
||||
* @param {number} tolerance Tolerance.
|
||||
* @param {ol.Extent} maxExtent Max extent.
|
||||
* @struct
|
||||
*/
|
||||
ol.render.webgl.TextReplay = function(tolerance, maxExtent) {};
|
||||
ol.render.webgl.TextReplay = function(tolerance, maxExtent) {
|
||||
ol.render.webgl.TextureReplay.call(this, tolerance, maxExtent);
|
||||
|
||||
/**
|
||||
* @param {ol.style.Text} textStyle Text style.
|
||||
* @private
|
||||
* @type {Array.<HTMLCanvasElement>}
|
||||
*/
|
||||
ol.render.webgl.TextReplay.prototype.setTextStyle = function(textStyle) {};
|
||||
this.images_ = [];
|
||||
|
||||
/**
|
||||
* @param {ol.webgl.Context} context Context.
|
||||
* @param {ol.Coordinate} center Center.
|
||||
* @param {number} resolution Resolution.
|
||||
* @param {number} rotation Rotation.
|
||||
* @param {ol.Size} size Size.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {number} opacity Global opacity.
|
||||
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
||||
* to skip.
|
||||
* @param {function((ol.Feature|ol.render.Feature)): T|undefined} featureCallback Feature callback.
|
||||
* @param {boolean} oneByOne Draw features one-by-one for the hit-detecion.
|
||||
* @param {ol.Extent=} opt_hitExtent Hit extent: Only features intersecting
|
||||
* this extent are checked.
|
||||
* @return {T|undefined} Callback result.
|
||||
* @template T
|
||||
* @private
|
||||
* @type {Array.<WebGLTexture>}
|
||||
*/
|
||||
ol.render.webgl.TextReplay.prototype.replay = function(context,
|
||||
center, resolution, rotation, size, pixelRatio,
|
||||
opacity, skippedFeaturesHash,
|
||||
featureCallback, oneByOne, opt_hitExtent) {
|
||||
return undefined;
|
||||
this.textures_ = [];
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {HTMLCanvasElement}
|
||||
*/
|
||||
this.measureCanvas_ = ol.dom.createCanvasContext2D(0, 0).canvas;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {{strokeColor: (ol.ColorLike|null),
|
||||
* lineCap: (string|undefined),
|
||||
* lineDash: Array.<number>,
|
||||
* lineDashOffset: (number|undefined),
|
||||
* lineJoin: (string|undefined),
|
||||
* lineWidth: number,
|
||||
* miterLimit: (number|undefined),
|
||||
* fillColor: (ol.ColorLike|null),
|
||||
* font: (string|undefined),
|
||||
* scale: (number|undefined)}}
|
||||
*/
|
||||
this.state_ = {
|
||||
strokeColor: null,
|
||||
lineCap: undefined,
|
||||
lineDash: null,
|
||||
lineDashOffset: undefined,
|
||||
lineJoin: undefined,
|
||||
lineWidth: 0,
|
||||
miterLimit: undefined,
|
||||
fillColor: null,
|
||||
font: undefined,
|
||||
scale: undefined
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.text_ = '';
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.textAlign_ = undefined;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.textBaseline_ = undefined;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.offsetX_ = undefined;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.offsetY_ = undefined;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Object.<string, ol.WebglGlyphAtlas>}
|
||||
*/
|
||||
this.atlases_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {ol.WebglGlyphAtlas|undefined}
|
||||
*/
|
||||
this.currAtlas_ = undefined;
|
||||
|
||||
this.scale = 1;
|
||||
|
||||
this.opacity = 1;
|
||||
|
||||
};
|
||||
ol.inherits(ol.render.webgl.TextReplay, ol.render.webgl.TextureReplay);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.TextReplay.prototype.drawText = function(flatCoordinates, offset,
|
||||
end, stride, geometry, feature) {
|
||||
if (this.text_) {
|
||||
this.startIndices.push(this.indices.length);
|
||||
this.startIndicesFeature.push(feature);
|
||||
|
||||
var glyphAtlas = this.currAtlas_;
|
||||
var lines = this.text_.split('\n');
|
||||
var textSize = this.getTextSize_(lines);
|
||||
var i, ii, j, jj, currX, currY, charArr, charInfo;
|
||||
var anchorX = Math.round(textSize[0] * this.textAlign_ + this.offsetX_);
|
||||
var anchorY = Math.round(textSize[1] * this.textBaseline_ + this.offsetY_);
|
||||
var lineWidth = (this.state_.lineWidth / 2) * this.state_.scale;
|
||||
|
||||
for (i = 0, ii = lines.length; i < ii; ++i) {
|
||||
currX = 0;
|
||||
currY = glyphAtlas.height * i;
|
||||
charArr = lines[i].split('');
|
||||
|
||||
for (j = 0, jj = charArr.length; j < jj; ++j) {
|
||||
charInfo = glyphAtlas.atlas.getInfo(charArr[j]);
|
||||
|
||||
if (charInfo) {
|
||||
var image = charInfo.image;
|
||||
|
||||
this.anchorX = anchorX - currX;
|
||||
this.anchorY = anchorY - currY;
|
||||
this.originX = j === 0 ? charInfo.offsetX - lineWidth : charInfo.offsetX;
|
||||
this.originY = charInfo.offsetY;
|
||||
this.height = glyphAtlas.height;
|
||||
this.width = j === 0 || j === charArr.length - 1 ?
|
||||
glyphAtlas.width[charArr[j]] + lineWidth : glyphAtlas.width[charArr[j]];
|
||||
this.imageHeight = image.height;
|
||||
this.imageWidth = image.width;
|
||||
|
||||
var currentImage;
|
||||
if (this.images_.length === 0) {
|
||||
this.images_.push(image);
|
||||
} else {
|
||||
currentImage = this.images_[this.images_.length - 1];
|
||||
if (ol.getUid(currentImage) != ol.getUid(image)) {
|
||||
this.groupIndices.push(this.indices.length);
|
||||
this.images_.push(image);
|
||||
}
|
||||
}
|
||||
|
||||
this.drawText_(flatCoordinates, offset, end, stride);
|
||||
}
|
||||
currX += this.width;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Array.<string>} lines Label to draw split to lines.
|
||||
* @return {Array.<number>} Size of the label in pixels.
|
||||
*/
|
||||
ol.render.webgl.TextReplay.prototype.getTextSize_ = function(lines) {
|
||||
var self = this;
|
||||
var glyphAtlas = this.currAtlas_;
|
||||
var textHeight = lines.length * glyphAtlas.height;
|
||||
//Split every line to an array of chars, sum up their width, and select the longest.
|
||||
var textWidth = lines.map(function(str) {
|
||||
var sum = 0;
|
||||
var i, ii;
|
||||
for (i = 0, ii = str.length; i < ii; ++i) {
|
||||
var curr = str[i];
|
||||
if (!glyphAtlas.width[curr]) {
|
||||
self.addCharToAtlas_(curr);
|
||||
}
|
||||
sum += glyphAtlas.width[curr] ? glyphAtlas.width[curr] : 0;
|
||||
}
|
||||
return sum;
|
||||
}).reduce(function(max, curr) {
|
||||
return Math.max(max, curr);
|
||||
});
|
||||
|
||||
return [textWidth, textHeight];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||
* @param {number} offset Offset.
|
||||
* @param {number} end End.
|
||||
* @param {number} stride Stride.
|
||||
* @param {ol.geom.Geometry|ol.render.Feature} geometry Geometry.
|
||||
* @param {ol.Feature|ol.render.Feature} feature Feature.
|
||||
*/
|
||||
ol.render.webgl.TextReplay.prototype.drawText = function(flatCoordinates, offset,
|
||||
end, stride, geometry, feature) {};
|
||||
ol.render.webgl.TextReplay.prototype.drawText_ = function(flatCoordinates, offset,
|
||||
end, stride) {
|
||||
var i, ii;
|
||||
for (i = offset, ii = end; i < ii; i += stride) {
|
||||
this.drawCoordinates(flatCoordinates, offset, end, stride);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @param {ol.webgl.Context} context Context.
|
||||
* @private
|
||||
* @param {string} char Character.
|
||||
*/
|
||||
ol.render.webgl.TextReplay.prototype.finish = function(context) {};
|
||||
ol.render.webgl.TextReplay.prototype.addCharToAtlas_ = function(char) {
|
||||
if (char.length === 1) {
|
||||
var glyphAtlas = this.currAtlas_;
|
||||
var state = this.state_;
|
||||
var mCtx = this.measureCanvas_.getContext('2d');
|
||||
mCtx.font = state.font;
|
||||
var width = Math.ceil(mCtx.measureText(char).width * state.scale);
|
||||
|
||||
var info = glyphAtlas.atlas.add(char, width, glyphAtlas.height,
|
||||
function(ctx, x, y) {
|
||||
//Parameterize the canvas
|
||||
ctx.font = /** @type {string} */ (state.font);
|
||||
ctx.fillStyle = state.fillColor;
|
||||
ctx.strokeStyle = state.strokeColor;
|
||||
ctx.lineWidth = state.lineWidth;
|
||||
ctx.lineCap = /*** @type {string} */ (state.lineCap);
|
||||
ctx.lineJoin = /** @type {string} */ (state.lineJoin);
|
||||
ctx.miterLimit = /** @type {number} */ (state.miterLimit);
|
||||
ctx.textAlign = 'left';
|
||||
ctx.textBaseline = 'top';
|
||||
if (ol.has.CANVAS_LINE_DASH && state.lineDash) {
|
||||
//FIXME: use pixelRatio
|
||||
ctx.setLineDash(state.lineDash);
|
||||
ctx.lineDashOffset = /** @type {number} */ (state.lineDashOffset);
|
||||
}
|
||||
if (state.scale !== 1) {
|
||||
//FIXME: use pixelRatio
|
||||
ctx.setTransform(/** @type {number} */ (state.scale), 0, 0,
|
||||
/** @type {number} */ (state.scale), 0, 0);
|
||||
}
|
||||
|
||||
//Draw the character on the canvas
|
||||
if (state.strokeColor) {
|
||||
ctx.strokeText(char, x, y);
|
||||
}
|
||||
if (state.fillColor) {
|
||||
ctx.fillText(char, x, y);
|
||||
}
|
||||
});
|
||||
|
||||
if (info) {
|
||||
glyphAtlas.width[char] = width;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.webgl.Context} context WebGL context.
|
||||
* @return {function()} Delete resources function.
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.TextReplay.prototype.getDeleteResourcesFunction = function(context) {
|
||||
return ol.nullFunction;
|
||||
ol.render.webgl.TextReplay.prototype.finish = function(context) {
|
||||
var gl = context.getGL();
|
||||
|
||||
this.groupIndices.push(this.indices.length);
|
||||
this.hitDetectionGroupIndices = this.groupIndices;
|
||||
|
||||
// create, bind, and populate the vertices buffer
|
||||
this.verticesBuffer = new ol.webgl.Buffer(this.vertices);
|
||||
|
||||
// create, bind, and populate the indices buffer
|
||||
this.indicesBuffer = new ol.webgl.Buffer(this.indices);
|
||||
|
||||
// create textures
|
||||
/** @type {Object.<string, WebGLTexture>} */
|
||||
var texturePerImage = {};
|
||||
|
||||
this.createTextures(this.textures_, this.images_, texturePerImage, gl);
|
||||
|
||||
this.state_ = {
|
||||
strokeColor: null,
|
||||
lineCap: undefined,
|
||||
lineDash: null,
|
||||
lineDashOffset: undefined,
|
||||
lineJoin: undefined,
|
||||
lineWidth: 0,
|
||||
miterLimit: undefined,
|
||||
fillColor: null,
|
||||
font: undefined,
|
||||
scale: undefined
|
||||
};
|
||||
this.text_ = '';
|
||||
this.textAlign_ = undefined;
|
||||
this.textBaseline_ = undefined;
|
||||
this.offsetX_ = undefined;
|
||||
this.offsetY_ = undefined;
|
||||
this.images_ = null;
|
||||
this.atlases_ = {};
|
||||
this.currAtlas_ = undefined;
|
||||
ol.render.webgl.TextureReplay.prototype.finish.call(this, context);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.TextReplay.prototype.setTextStyle = function(textStyle) {
|
||||
var state = this.state_;
|
||||
var textFillStyle = textStyle.getFill();
|
||||
var textStrokeStyle = textStyle.getStroke();
|
||||
if (!textStyle || !textStyle.getText() || (!textFillStyle && !textStrokeStyle)) {
|
||||
this.text_ = '';
|
||||
} else {
|
||||
if (!textFillStyle) {
|
||||
state.fillColor = null;
|
||||
} else {
|
||||
var textFillStyleColor = textFillStyle.getColor();
|
||||
state.fillColor = ol.colorlike.asColorLike(textFillStyleColor ?
|
||||
textFillStyleColor : ol.render.webgl.defaultFillStyle);
|
||||
}
|
||||
if (!textStrokeStyle) {
|
||||
state.strokeColor = null;
|
||||
state.lineWidth = 0;
|
||||
} else {
|
||||
var textStrokeStyleColor = textStrokeStyle.getColor();
|
||||
state.strokeColor = ol.colorlike.asColorLike(textStrokeStyleColor ?
|
||||
textStrokeStyleColor : ol.render.webgl.defaultStrokeStyle);
|
||||
state.lineWidth = textStrokeStyle.getWidth() || ol.render.webgl.defaultLineWidth;
|
||||
state.lineCap = textStrokeStyle.getLineCap() || ol.render.webgl.defaultLineCap;
|
||||
state.lineDashOffset = textStrokeStyle.getLineDashOffset() || ol.render.webgl.defaultLineDashOffset;
|
||||
state.lineJoin = textStrokeStyle.getLineJoin() || ol.render.webgl.defaultLineJoin;
|
||||
state.miterLimit = textStrokeStyle.getMiterLimit() || ol.render.webgl.defaultMiterLimit;
|
||||
var lineDash = textStrokeStyle.getLineDash();
|
||||
state.lineDash = lineDash ? lineDash.slice() : ol.render.webgl.defaultLineDash;
|
||||
}
|
||||
state.font = textStyle.getFont() || ol.render.webgl.defaultFont;
|
||||
state.scale = textStyle.getScale() || 1;
|
||||
this.text_ = /** @type {string} */ (textStyle.getText());
|
||||
var textAlign = ol.render.webgl.TextReplay.Align_[textStyle.getTextAlign()];
|
||||
var textBaseline = ol.render.webgl.TextReplay.Align_[textStyle.getTextBaseline()];
|
||||
this.textAlign_ = textAlign === undefined ?
|
||||
ol.render.webgl.defaultTextAlign : textAlign;
|
||||
this.textBaseline_ = textBaseline === undefined ?
|
||||
ol.render.webgl.defaultTextBaseline : textBaseline;
|
||||
this.offsetX_ = textStyle.getOffsetX() || 0;
|
||||
this.offsetY_ = textStyle.getOffsetY() || 0;
|
||||
this.rotateWithView = !!textStyle.getRotateWithView();
|
||||
this.rotation = textStyle.getRotation() || 0;
|
||||
|
||||
this.currAtlas_ = this.getAtlas_(state);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Object} state Font attributes.
|
||||
* @return {ol.WebglGlyphAtlas} Glyph atlas.
|
||||
*/
|
||||
ol.render.webgl.TextReplay.prototype.getAtlas_ = function(state) {
|
||||
var params = [];
|
||||
var i;
|
||||
for (i in state) {
|
||||
if (state[i] || state[i] === 0) {
|
||||
if (Array.isArray(state[i])) {
|
||||
params = params.concat(state[i]);
|
||||
} else {
|
||||
params.push(state[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
var hash = this.calculateHash_(params);
|
||||
if (!this.atlases_[hash]) {
|
||||
var mCtx = this.measureCanvas_.getContext('2d');
|
||||
mCtx.font = state.font;
|
||||
var height = Math.ceil((mCtx.measureText('M').width * 1.5 +
|
||||
state.lineWidth / 2) * state.scale);
|
||||
|
||||
this.atlases_[hash] = {
|
||||
atlas: new ol.style.AtlasManager({
|
||||
space: state.lineWidth + 1
|
||||
}),
|
||||
width: {},
|
||||
height: height
|
||||
};
|
||||
}
|
||||
return this.atlases_[hash];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Array.<string|number>} params Array of parameters.
|
||||
* @return {string} Hash string.
|
||||
*/
|
||||
ol.render.webgl.TextReplay.prototype.calculateHash_ = function(params) {
|
||||
//TODO: Create a more performant, reliable, general hash function.
|
||||
var i, ii;
|
||||
var hash = '';
|
||||
for (i = 0, ii = params.length; i < ii; ++i) {
|
||||
hash += params[i];
|
||||
}
|
||||
return hash;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.TextReplay.prototype.getTextures = function(opt_all) {
|
||||
return this.textures_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.TextReplay.prototype.getHitDetectionTextures = function() {
|
||||
return this.textures_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @enum {number}
|
||||
* @private
|
||||
*/
|
||||
ol.render.webgl.TextReplay.Align_ = {
|
||||
left: 0,
|
||||
end: 0,
|
||||
center: 0.5,
|
||||
right: 1,
|
||||
start: 1,
|
||||
top: 0,
|
||||
middle: 0.5,
|
||||
hanging: 0.2,
|
||||
alphabetic: 0.8,
|
||||
ideographic: 0.8,
|
||||
bottom: 1
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
497
src/ol/render/webgl/texturereplay.js
Normal file
497
src/ol/render/webgl/texturereplay.js
Normal file
@@ -0,0 +1,497 @@
|
||||
goog.provide('ol.render.webgl.TextureReplay');
|
||||
|
||||
goog.require('ol');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.obj');
|
||||
goog.require('ol.render.webgl.texturereplay.defaultshader');
|
||||
goog.require('ol.render.webgl.Replay');
|
||||
goog.require('ol.webgl');
|
||||
goog.require('ol.webgl.Context');
|
||||
|
||||
if (ol.ENABLE_WEBGL) {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @abstract
|
||||
* @extends {ol.render.webgl.Replay}
|
||||
* @param {number} tolerance Tolerance.
|
||||
* @param {ol.Extent} maxExtent Max extent.
|
||||
* @struct
|
||||
*/
|
||||
ol.render.webgl.TextureReplay = function(tolerance, maxExtent) {
|
||||
ol.render.webgl.Replay.call(this, tolerance, maxExtent);
|
||||
|
||||
/**
|
||||
* @type {number|undefined}
|
||||
* @protected
|
||||
*/
|
||||
this.anchorX = undefined;
|
||||
|
||||
/**
|
||||
* @type {number|undefined}
|
||||
* @protected
|
||||
*/
|
||||
this.anchorY = undefined;
|
||||
|
||||
/**
|
||||
* @type {Array.<number>}
|
||||
* @protected
|
||||
*/
|
||||
this.groupIndices = [];
|
||||
|
||||
/**
|
||||
* @type {Array.<number>}
|
||||
* @protected
|
||||
*/
|
||||
this.hitDetectionGroupIndices = [];
|
||||
|
||||
/**
|
||||
* @type {number|undefined}
|
||||
* @protected
|
||||
*/
|
||||
this.height = undefined;
|
||||
|
||||
/**
|
||||
* @type {number|undefined}
|
||||
* @protected
|
||||
*/
|
||||
this.imageHeight = undefined;
|
||||
|
||||
/**
|
||||
* @type {number|undefined}
|
||||
* @protected
|
||||
*/
|
||||
this.imageWidth = undefined;
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @type {ol.render.webgl.texturereplay.defaultshader.Locations}
|
||||
*/
|
||||
this.defaultLocations = null;
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.opacity = undefined;
|
||||
|
||||
/**
|
||||
* @type {number|undefined}
|
||||
* @protected
|
||||
*/
|
||||
this.originX = undefined;
|
||||
|
||||
/**
|
||||
* @type {number|undefined}
|
||||
* @protected
|
||||
*/
|
||||
this.originY = undefined;
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @type {boolean|undefined}
|
||||
*/
|
||||
this.rotateWithView = undefined;
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.rotation = undefined;
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @type {number|undefined}
|
||||
*/
|
||||
this.scale = undefined;
|
||||
|
||||
/**
|
||||
* @type {number|undefined}
|
||||
* @protected
|
||||
*/
|
||||
this.width = undefined;
|
||||
};
|
||||
ol.inherits(ol.render.webgl.TextureReplay, ol.render.webgl.Replay);
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.TextureReplay.prototype.getDeleteResourcesFunction = function(context) {
|
||||
var verticesBuffer = this.verticesBuffer;
|
||||
var indicesBuffer = this.indicesBuffer;
|
||||
var textures = this.getTextures(true);
|
||||
var gl = context.getGL();
|
||||
return function() {
|
||||
if (!gl.isContextLost()) {
|
||||
var i, ii;
|
||||
for (i = 0, ii = textures.length; i < ii; ++i) {
|
||||
gl.deleteTexture(textures[i]);
|
||||
}
|
||||
}
|
||||
context.deleteBuffer(verticesBuffer);
|
||||
context.deleteBuffer(indicesBuffer);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {Array.<number>} flatCoordinates Flat coordinates.
|
||||
* @param {number} offset Offset.
|
||||
* @param {number} end End.
|
||||
* @param {number} stride Stride.
|
||||
* @return {number} My end.
|
||||
* @protected
|
||||
*/
|
||||
ol.render.webgl.TextureReplay.prototype.drawCoordinates = function(flatCoordinates, offset, end, stride) {
|
||||
var anchorX = /** @type {number} */ (this.anchorX);
|
||||
var anchorY = /** @type {number} */ (this.anchorY);
|
||||
var height = /** @type {number} */ (this.height);
|
||||
var imageHeight = /** @type {number} */ (this.imageHeight);
|
||||
var imageWidth = /** @type {number} */ (this.imageWidth);
|
||||
var opacity = /** @type {number} */ (this.opacity);
|
||||
var originX = /** @type {number} */ (this.originX);
|
||||
var originY = /** @type {number} */ (this.originY);
|
||||
var rotateWithView = this.rotateWithView ? 1.0 : 0.0;
|
||||
// this.rotation_ is anti-clockwise, but rotation is clockwise
|
||||
var rotation = /** @type {number} */ (-this.rotation);
|
||||
var scale = /** @type {number} */ (this.scale);
|
||||
var width = /** @type {number} */ (this.width);
|
||||
var cos = Math.cos(rotation);
|
||||
var sin = Math.sin(rotation);
|
||||
var numIndices = this.indices.length;
|
||||
var numVertices = this.vertices.length;
|
||||
var i, n, offsetX, offsetY, x, y;
|
||||
for (i = offset; i < end; i += stride) {
|
||||
x = flatCoordinates[i] - this.origin[0];
|
||||
y = flatCoordinates[i + 1] - this.origin[1];
|
||||
|
||||
// There are 4 vertices per [x, y] point, one for each corner of the
|
||||
// rectangle we're going to draw. We'd use 1 vertex per [x, y] point if
|
||||
// WebGL supported Geometry Shaders (which can emit new vertices), but that
|
||||
// is not currently the case.
|
||||
//
|
||||
// And each vertex includes 8 values: the x and y coordinates, the x and
|
||||
// y offsets used to calculate the position of the corner, the u and
|
||||
// v texture coordinates for the corner, the opacity, and whether the
|
||||
// the image should be rotated with the view (rotateWithView).
|
||||
|
||||
n = numVertices / 8;
|
||||
|
||||
// bottom-left corner
|
||||
offsetX = -scale * anchorX;
|
||||
offsetY = -scale * (height - anchorY);
|
||||
this.vertices[numVertices++] = x;
|
||||
this.vertices[numVertices++] = y;
|
||||
this.vertices[numVertices++] = offsetX * cos - offsetY * sin;
|
||||
this.vertices[numVertices++] = offsetX * sin + offsetY * cos;
|
||||
this.vertices[numVertices++] = originX / imageWidth;
|
||||
this.vertices[numVertices++] = (originY + height) / imageHeight;
|
||||
this.vertices[numVertices++] = opacity;
|
||||
this.vertices[numVertices++] = rotateWithView;
|
||||
|
||||
// bottom-right corner
|
||||
offsetX = scale * (width - anchorX);
|
||||
offsetY = -scale * (height - anchorY);
|
||||
this.vertices[numVertices++] = x;
|
||||
this.vertices[numVertices++] = y;
|
||||
this.vertices[numVertices++] = offsetX * cos - offsetY * sin;
|
||||
this.vertices[numVertices++] = offsetX * sin + offsetY * cos;
|
||||
this.vertices[numVertices++] = (originX + width) / imageWidth;
|
||||
this.vertices[numVertices++] = (originY + height) / imageHeight;
|
||||
this.vertices[numVertices++] = opacity;
|
||||
this.vertices[numVertices++] = rotateWithView;
|
||||
|
||||
// top-right corner
|
||||
offsetX = scale * (width - anchorX);
|
||||
offsetY = scale * anchorY;
|
||||
this.vertices[numVertices++] = x;
|
||||
this.vertices[numVertices++] = y;
|
||||
this.vertices[numVertices++] = offsetX * cos - offsetY * sin;
|
||||
this.vertices[numVertices++] = offsetX * sin + offsetY * cos;
|
||||
this.vertices[numVertices++] = (originX + width) / imageWidth;
|
||||
this.vertices[numVertices++] = originY / imageHeight;
|
||||
this.vertices[numVertices++] = opacity;
|
||||
this.vertices[numVertices++] = rotateWithView;
|
||||
|
||||
// top-left corner
|
||||
offsetX = -scale * anchorX;
|
||||
offsetY = scale * anchorY;
|
||||
this.vertices[numVertices++] = x;
|
||||
this.vertices[numVertices++] = y;
|
||||
this.vertices[numVertices++] = offsetX * cos - offsetY * sin;
|
||||
this.vertices[numVertices++] = offsetX * sin + offsetY * cos;
|
||||
this.vertices[numVertices++] = originX / imageWidth;
|
||||
this.vertices[numVertices++] = originY / imageHeight;
|
||||
this.vertices[numVertices++] = opacity;
|
||||
this.vertices[numVertices++] = rotateWithView;
|
||||
|
||||
this.indices[numIndices++] = n;
|
||||
this.indices[numIndices++] = n + 1;
|
||||
this.indices[numIndices++] = n + 2;
|
||||
this.indices[numIndices++] = n;
|
||||
this.indices[numIndices++] = n + 2;
|
||||
this.indices[numIndices++] = n + 3;
|
||||
}
|
||||
|
||||
return numVertices;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* @param {Array.<WebGLTexture>} textures Textures.
|
||||
* @param {Array.<HTMLCanvasElement|HTMLImageElement|HTMLVideoElement>} images
|
||||
* Images.
|
||||
* @param {Object.<string, WebGLTexture>} texturePerImage Texture cache.
|
||||
* @param {WebGLRenderingContext} gl Gl.
|
||||
*/
|
||||
ol.render.webgl.TextureReplay.prototype.createTextures = function(textures, images, texturePerImage, gl) {
|
||||
var texture, image, uid, i;
|
||||
var ii = images.length;
|
||||
for (i = 0; i < ii; ++i) {
|
||||
image = images[i];
|
||||
|
||||
uid = ol.getUid(image).toString();
|
||||
if (uid in texturePerImage) {
|
||||
texture = texturePerImage[uid];
|
||||
} else {
|
||||
texture = ol.webgl.Context.createTexture(
|
||||
gl, image, ol.webgl.CLAMP_TO_EDGE, ol.webgl.CLAMP_TO_EDGE);
|
||||
texturePerImage[uid] = texture;
|
||||
}
|
||||
textures[i] = texture;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.TextureReplay.prototype.setUpProgram = function(gl, context, size, pixelRatio) {
|
||||
// get the program
|
||||
var fragmentShader = ol.render.webgl.texturereplay.defaultshader.fragment;
|
||||
var vertexShader = ol.render.webgl.texturereplay.defaultshader.vertex;
|
||||
var program = context.getProgram(fragmentShader, vertexShader);
|
||||
|
||||
// get the locations
|
||||
var locations;
|
||||
if (!this.defaultLocations) {
|
||||
// eslint-disable-next-line openlayers-internal/no-missing-requires
|
||||
locations = new ol.render.webgl.texturereplay.defaultshader.Locations(gl, program);
|
||||
this.defaultLocations = locations;
|
||||
} else {
|
||||
locations = this.defaultLocations;
|
||||
}
|
||||
|
||||
// use the program (FIXME: use the return value)
|
||||
context.useProgram(program);
|
||||
|
||||
// enable the vertex attrib arrays
|
||||
gl.enableVertexAttribArray(locations.a_position);
|
||||
gl.vertexAttribPointer(locations.a_position, 2, ol.webgl.FLOAT,
|
||||
false, 32, 0);
|
||||
|
||||
gl.enableVertexAttribArray(locations.a_offsets);
|
||||
gl.vertexAttribPointer(locations.a_offsets, 2, ol.webgl.FLOAT,
|
||||
false, 32, 8);
|
||||
|
||||
gl.enableVertexAttribArray(locations.a_texCoord);
|
||||
gl.vertexAttribPointer(locations.a_texCoord, 2, ol.webgl.FLOAT,
|
||||
false, 32, 16);
|
||||
|
||||
gl.enableVertexAttribArray(locations.a_opacity);
|
||||
gl.vertexAttribPointer(locations.a_opacity, 1, ol.webgl.FLOAT,
|
||||
false, 32, 24);
|
||||
|
||||
gl.enableVertexAttribArray(locations.a_rotateWithView);
|
||||
gl.vertexAttribPointer(locations.a_rotateWithView, 1, ol.webgl.FLOAT,
|
||||
false, 32, 28);
|
||||
|
||||
return locations;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.TextureReplay.prototype.shutDownProgram = function(gl, locations) {
|
||||
gl.disableVertexAttribArray(locations.a_position);
|
||||
gl.disableVertexAttribArray(locations.a_offsets);
|
||||
gl.disableVertexAttribArray(locations.a_texCoord);
|
||||
gl.disableVertexAttribArray(locations.a_opacity);
|
||||
gl.disableVertexAttribArray(locations.a_rotateWithView);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.TextureReplay.prototype.drawReplay = function(gl, context, skippedFeaturesHash, hitDetection) {
|
||||
var textures = hitDetection ? this.getHitDetectionTextures() : this.getTextures();
|
||||
var groupIndices = hitDetection ? this.hitDetectionGroupIndices : this.groupIndices;
|
||||
|
||||
if (!ol.obj.isEmpty(skippedFeaturesHash)) {
|
||||
this.drawReplaySkipping(
|
||||
gl, context, skippedFeaturesHash, textures, groupIndices);
|
||||
} else {
|
||||
var i, ii, start;
|
||||
for (i = 0, ii = textures.length, start = 0; i < ii; ++i) {
|
||||
gl.bindTexture(ol.webgl.TEXTURE_2D, textures[i]);
|
||||
var end = groupIndices[i];
|
||||
this.drawElements(gl, context, start, end);
|
||||
start = end;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Draw the replay while paying attention to skipped features.
|
||||
*
|
||||
* This functions creates groups of features that can be drawn to together,
|
||||
* so that the number of `drawElements` calls is minimized.
|
||||
*
|
||||
* For example given the following texture groups:
|
||||
*
|
||||
* Group 1: A B C
|
||||
* Group 2: D [E] F G
|
||||
*
|
||||
* If feature E should be skipped, the following `drawElements` calls will be
|
||||
* made:
|
||||
*
|
||||
* drawElements with feature A, B and C
|
||||
* drawElements with feature D
|
||||
* drawElements with feature F and G
|
||||
*
|
||||
* @protected
|
||||
* @param {WebGLRenderingContext} gl gl.
|
||||
* @param {ol.webgl.Context} context Context.
|
||||
* @param {Object.<string, boolean>} skippedFeaturesHash Ids of features
|
||||
* to skip.
|
||||
* @param {Array.<WebGLTexture>} textures Textures.
|
||||
* @param {Array.<number>} groupIndices Texture group indices.
|
||||
*/
|
||||
ol.render.webgl.TextureReplay.prototype.drawReplaySkipping = function(gl, context, skippedFeaturesHash, textures,
|
||||
groupIndices) {
|
||||
var featureIndex = 0;
|
||||
|
||||
var i, ii;
|
||||
for (i = 0, ii = textures.length; i < ii; ++i) {
|
||||
gl.bindTexture(ol.webgl.TEXTURE_2D, textures[i]);
|
||||
var groupStart = (i > 0) ? groupIndices[i - 1] : 0;
|
||||
var groupEnd = groupIndices[i];
|
||||
|
||||
var start = groupStart;
|
||||
var end = groupStart;
|
||||
while (featureIndex < this.startIndices.length &&
|
||||
this.startIndices[featureIndex] <= groupEnd) {
|
||||
var feature = this.startIndicesFeature[featureIndex];
|
||||
|
||||
var featureUid = ol.getUid(feature).toString();
|
||||
if (skippedFeaturesHash[featureUid] !== undefined) {
|
||||
// feature should be skipped
|
||||
if (start !== end) {
|
||||
// draw the features so far
|
||||
this.drawElements(gl, context, start, end);
|
||||
}
|
||||
// continue with the next feature
|
||||
start = (featureIndex === this.startIndices.length - 1) ?
|
||||
groupEnd : this.startIndices[featureIndex + 1];
|
||||
end = start;
|
||||
} else {
|
||||
// the feature is not skipped, augment the end index
|
||||
end = (featureIndex === this.startIndices.length - 1) ?
|
||||
groupEnd : this.startIndices[featureIndex + 1];
|
||||
}
|
||||
featureIndex++;
|
||||
}
|
||||
|
||||
if (start !== end) {
|
||||
// draw the remaining features (in case there was no skipped feature
|
||||
// in this texture group, all features of a group are drawn together)
|
||||
this.drawElements(gl, context, start, end);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.TextureReplay.prototype.drawHitDetectionReplayOneByOne = function(gl, context, skippedFeaturesHash,
|
||||
featureCallback, opt_hitExtent) {
|
||||
var i, groupStart, start, end, feature, featureUid;
|
||||
var featureIndex = this.startIndices.length - 1;
|
||||
var hitDetectionTextures = this.getHitDetectionTextures();
|
||||
for (i = hitDetectionTextures.length - 1; i >= 0; --i) {
|
||||
gl.bindTexture(ol.webgl.TEXTURE_2D, hitDetectionTextures[i]);
|
||||
groupStart = (i > 0) ? this.hitDetectionGroupIndices[i - 1] : 0;
|
||||
end = this.hitDetectionGroupIndices[i];
|
||||
|
||||
// draw all features for this texture group
|
||||
while (featureIndex >= 0 &&
|
||||
this.startIndices[featureIndex] >= groupStart) {
|
||||
start = this.startIndices[featureIndex];
|
||||
feature = this.startIndicesFeature[featureIndex];
|
||||
featureUid = ol.getUid(feature).toString();
|
||||
|
||||
if (skippedFeaturesHash[featureUid] === undefined &&
|
||||
feature.getGeometry() &&
|
||||
(opt_hitExtent === undefined || ol.extent.intersects(
|
||||
/** @type {Array<number>} */ (opt_hitExtent),
|
||||
feature.getGeometry().getExtent()))) {
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
this.drawElements(gl, context, start, end);
|
||||
|
||||
var result = featureCallback(feature);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
end = start;
|
||||
featureIndex--;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.render.webgl.TextureReplay.prototype.finish = function(context) {
|
||||
this.anchorX = undefined;
|
||||
this.anchorY = undefined;
|
||||
this.height = undefined;
|
||||
this.imageHeight = undefined;
|
||||
this.imageWidth = undefined;
|
||||
this.indices = null;
|
||||
this.opacity = undefined;
|
||||
this.originX = undefined;
|
||||
this.originY = undefined;
|
||||
this.rotateWithView = undefined;
|
||||
this.rotation = undefined;
|
||||
this.scale = undefined;
|
||||
this.vertices = null;
|
||||
this.width = undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @protected
|
||||
* @param {boolean=} opt_all Return hit detection textures with regular ones.
|
||||
* @returns {Array.<WebGLTexture>} Textures.
|
||||
*/
|
||||
ol.render.webgl.TextureReplay.prototype.getTextures = function(opt_all) {};
|
||||
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @protected
|
||||
* @returns {Array.<WebGLTexture>} Textures.
|
||||
*/
|
||||
ol.render.webgl.TextureReplay.prototype.getHitDetectionTextures = function() {};
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
//! NAMESPACE=ol.render.webgl.imagereplay.defaultshader
|
||||
//! CLASS=ol.render.webgl.imagereplay.defaultshader
|
||||
//! NAMESPACE=ol.render.webgl.texturereplay.defaultshader
|
||||
//! CLASS=ol.render.webgl.texturereplay.defaultshader
|
||||
|
||||
|
||||
//! COMMON
|
||||
154
src/ol/render/webgl/texturereplay/defaultshader.js
Normal file
154
src/ol/render/webgl/texturereplay/defaultshader.js
Normal file
@@ -0,0 +1,154 @@
|
||||
// This file is automatically generated, do not edit
|
||||
/* eslint openlayers-internal/no-missing-requires: 0 */
|
||||
goog.provide('ol.render.webgl.texturereplay.defaultshader');
|
||||
|
||||
goog.require('ol');
|
||||
goog.require('ol.webgl.Fragment');
|
||||
goog.require('ol.webgl.Vertex');
|
||||
|
||||
if (ol.ENABLE_WEBGL) {
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.webgl.Fragment}
|
||||
* @struct
|
||||
*/
|
||||
ol.render.webgl.texturereplay.defaultshader.Fragment = function() {
|
||||
ol.webgl.Fragment.call(this, ol.render.webgl.texturereplay.defaultshader.Fragment.SOURCE);
|
||||
};
|
||||
ol.inherits(ol.render.webgl.texturereplay.defaultshader.Fragment, ol.webgl.Fragment);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
ol.render.webgl.texturereplay.defaultshader.Fragment.DEBUG_SOURCE = 'precision mediump float;\nvarying vec2 v_texCoord;\nvarying float v_opacity;\n\nuniform float u_opacity;\nuniform sampler2D u_image;\n\nvoid main(void) {\n vec4 texColor = texture2D(u_image, v_texCoord);\n gl_FragColor.rgb = texColor.rgb;\n float alpha = texColor.a * v_opacity * u_opacity;\n if (alpha == 0.0) {\n discard;\n }\n gl_FragColor.a = alpha;\n}\n';
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
ol.render.webgl.texturereplay.defaultshader.Fragment.OPTIMIZED_SOURCE = 'precision mediump float;varying vec2 a;varying float b;uniform float k;uniform sampler2D l;void main(void){vec4 texColor=texture2D(l,a);gl_FragColor.rgb=texColor.rgb;float alpha=texColor.a*b*k;if(alpha==0.0){discard;}gl_FragColor.a=alpha;}';
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
ol.render.webgl.texturereplay.defaultshader.Fragment.SOURCE = ol.DEBUG_WEBGL ?
|
||||
ol.render.webgl.texturereplay.defaultshader.Fragment.DEBUG_SOURCE :
|
||||
ol.render.webgl.texturereplay.defaultshader.Fragment.OPTIMIZED_SOURCE;
|
||||
|
||||
|
||||
ol.render.webgl.texturereplay.defaultshader.fragment = new ol.render.webgl.texturereplay.defaultshader.Fragment();
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {ol.webgl.Vertex}
|
||||
* @struct
|
||||
*/
|
||||
ol.render.webgl.texturereplay.defaultshader.Vertex = function() {
|
||||
ol.webgl.Vertex.call(this, ol.render.webgl.texturereplay.defaultshader.Vertex.SOURCE);
|
||||
};
|
||||
ol.inherits(ol.render.webgl.texturereplay.defaultshader.Vertex, ol.webgl.Vertex);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
ol.render.webgl.texturereplay.defaultshader.Vertex.DEBUG_SOURCE = 'varying vec2 v_texCoord;\nvarying float v_opacity;\n\nattribute vec2 a_position;\nattribute vec2 a_texCoord;\nattribute vec2 a_offsets;\nattribute float a_opacity;\nattribute float a_rotateWithView;\n\nuniform mat4 u_projectionMatrix;\nuniform mat4 u_offsetScaleMatrix;\nuniform mat4 u_offsetRotateMatrix;\n\nvoid main(void) {\n mat4 offsetMatrix = u_offsetScaleMatrix;\n if (a_rotateWithView == 1.0) {\n offsetMatrix = u_offsetScaleMatrix * u_offsetRotateMatrix;\n }\n vec4 offsets = offsetMatrix * vec4(a_offsets, 0.0, 0.0);\n gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;\n v_texCoord = a_texCoord;\n v_opacity = a_opacity;\n}\n\n\n';
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
ol.render.webgl.texturereplay.defaultshader.Vertex.OPTIMIZED_SOURCE = 'varying vec2 a;varying float b;attribute vec2 c;attribute vec2 d;attribute vec2 e;attribute float f;attribute float g;uniform mat4 h;uniform mat4 i;uniform mat4 j;void main(void){mat4 offsetMatrix=i;if(g==1.0){offsetMatrix=i*j;}vec4 offsets=offsetMatrix*vec4(e,0.0,0.0);gl_Position=h*vec4(c,0.0,1.0)+offsets;a=d;b=f;}';
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
*/
|
||||
ol.render.webgl.texturereplay.defaultshader.Vertex.SOURCE = ol.DEBUG_WEBGL ?
|
||||
ol.render.webgl.texturereplay.defaultshader.Vertex.DEBUG_SOURCE :
|
||||
ol.render.webgl.texturereplay.defaultshader.Vertex.OPTIMIZED_SOURCE;
|
||||
|
||||
|
||||
ol.render.webgl.texturereplay.defaultshader.vertex = new ol.render.webgl.texturereplay.defaultshader.Vertex();
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {WebGLRenderingContext} gl GL.
|
||||
* @param {WebGLProgram} program Program.
|
||||
* @struct
|
||||
*/
|
||||
ol.render.webgl.texturereplay.defaultshader.Locations = function(gl, program) {
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_image = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_image' : 'l');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_offsetRotateMatrix = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_offsetRotateMatrix' : 'j');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_offsetScaleMatrix = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_offsetScaleMatrix' : 'i');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_opacity = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_opacity' : 'k');
|
||||
|
||||
/**
|
||||
* @type {WebGLUniformLocation}
|
||||
*/
|
||||
this.u_projectionMatrix = gl.getUniformLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'u_projectionMatrix' : 'h');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_offsets = gl.getAttribLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'a_offsets' : 'e');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_opacity = gl.getAttribLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'a_opacity' : 'f');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_position = gl.getAttribLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'a_position' : 'c');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_rotateWithView = gl.getAttribLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'a_rotateWithView' : 'g');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
this.a_texCoord = gl.getAttribLocation(
|
||||
program, ol.DEBUG_WEBGL ? 'a_texCoord' : 'd');
|
||||
};
|
||||
|
||||
}
|
||||
@@ -144,6 +144,15 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame = function(frameState, layer
|
||||
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
||||
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
||||
tile = tileSource.getTile(z, x, y, pixelRatio, projection);
|
||||
if (tile.getState() == ol.TileState.ERROR) {
|
||||
if (!tileLayer.getUseInterimTilesOnError()) {
|
||||
// When useInterimTilesOnError is false, we consider the error tile as loaded.
|
||||
tile.setState(ol.TileState.LOADED);
|
||||
} else if (tileLayer.getPreload() > 0) {
|
||||
// Preloaded tiles for lower resolutions might have finished loading.
|
||||
newTiles = true;
|
||||
}
|
||||
}
|
||||
if (!this.isDrawableTile_(tile)) {
|
||||
tile = tile.getInterimTile();
|
||||
}
|
||||
@@ -170,13 +179,16 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame = function(frameState, layer
|
||||
}
|
||||
}
|
||||
|
||||
var renderedResolution = tileResolution * pixelRatio / tilePixelRatio * oversampling;
|
||||
var hints = frameState.viewHints;
|
||||
if (!(this.renderedResolution && Date.now() - frameState.time > 16 &&
|
||||
(hints[ol.ViewHint.ANIMATING] || hints[ol.ViewHint.INTERACTING])) &&
|
||||
(newTiles || !(this.renderedExtent_ &&
|
||||
ol.extent.containsExtent(this.renderedExtent_, extent)) ||
|
||||
this.renderedRevision != sourceRevision) ||
|
||||
oversampling != this.oversampling_) {
|
||||
var animatingOrInteracting = hints[ol.ViewHint.ANIMATING] || hints[ol.ViewHint.INTERACTING];
|
||||
if (!(this.renderedResolution && Date.now() - frameState.time > 16 && animatingOrInteracting) && (
|
||||
newTiles ||
|
||||
!(this.renderedExtent_ && ol.extent.containsExtent(this.renderedExtent_, extent)) ||
|
||||
this.renderedRevision != sourceRevision ||
|
||||
oversampling != this.oversampling_ ||
|
||||
!animatingOrInteracting && renderedResolution != this.renderedResolution
|
||||
)) {
|
||||
|
||||
var context = this.context;
|
||||
if (context) {
|
||||
@@ -262,7 +274,7 @@ ol.renderer.canvas.TileLayer.prototype.drawTileImage = function(tile, frameState
|
||||
if (!this.getLayer().getSource().getOpaque(frameState.viewState.projection)) {
|
||||
this.context.clearRect(x, y, w, h);
|
||||
}
|
||||
var image = tile.getImage();
|
||||
var image = tile.getImage(this.getLayer());
|
||||
if (image) {
|
||||
this.context.drawImage(image, gutter, gutter,
|
||||
image.width - 2 * gutter, image.height - 2 * gutter, x, y, w, h);
|
||||
|
||||
@@ -97,7 +97,9 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, lay
|
||||
var drawOffsetX = 0;
|
||||
var drawOffsetY = 0;
|
||||
var replayContext;
|
||||
if (layer.hasListener(ol.render.EventType.RENDER)) {
|
||||
var transparentLayer = layerState.opacity !== 1;
|
||||
var hasRenderListeners = layer.hasListener(ol.render.EventType.RENDER);
|
||||
if (transparentLayer || hasRenderListeners) {
|
||||
var drawWidth = context.canvas.width;
|
||||
var drawHeight = context.canvas.height;
|
||||
if (rotation) {
|
||||
@@ -113,11 +115,15 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, lay
|
||||
} else {
|
||||
replayContext = context;
|
||||
}
|
||||
|
||||
var alpha = replayContext.globalAlpha;
|
||||
if (!transparentLayer) {
|
||||
// for performance reasons, context.save / context.restore is not used
|
||||
// to save and restore the transformation matrix and the opacity.
|
||||
// see http://jsperf.com/context-save-restore-versus-variable
|
||||
var alpha = replayContext.globalAlpha;
|
||||
replayContext.globalAlpha = layerState.opacity;
|
||||
}
|
||||
|
||||
if (replayContext != context) {
|
||||
replayContext.translate(drawOffsetX, drawOffsetY);
|
||||
}
|
||||
@@ -159,12 +165,24 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, lay
|
||||
width / 2, height / 2);
|
||||
|
||||
if (replayContext != context) {
|
||||
if (hasRenderListeners) {
|
||||
this.dispatchRenderEvent(replayContext, frameState, transform);
|
||||
}
|
||||
if (transparentLayer) {
|
||||
var mainContextAlpha = context.globalAlpha;
|
||||
context.globalAlpha = layerState.opacity;
|
||||
context.drawImage(replayContext.canvas, -drawOffsetX, -drawOffsetY);
|
||||
context.globalAlpha = mainContextAlpha;
|
||||
} else {
|
||||
context.drawImage(replayContext.canvas, -drawOffsetX, -drawOffsetY);
|
||||
}
|
||||
replayContext.translate(-drawOffsetX, -drawOffsetY);
|
||||
}
|
||||
|
||||
if (!transparentLayer) {
|
||||
replayContext.globalAlpha = alpha;
|
||||
}
|
||||
}
|
||||
|
||||
if (clipped) {
|
||||
context.restore();
|
||||
@@ -277,8 +295,7 @@ ol.renderer.canvas.VectorLayer.prototype.prepareFrame = function(frameState, lay
|
||||
|
||||
this.dirty_ = false;
|
||||
|
||||
var replayGroup =
|
||||
new ol.render.canvas.ReplayGroup(
|
||||
var replayGroup = new ol.render.canvas.ReplayGroup(
|
||||
ol.renderer.vector.getTolerance(resolution, pixelRatio), extent,
|
||||
resolution, vectorSource.getOverlaps(), vectorLayer.getRenderBuffer());
|
||||
vectorSource.loadFeatures(extent, resolution, projection);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
goog.provide('ol.renderer.canvas.VectorTileLayer');
|
||||
|
||||
goog.require('ol');
|
||||
goog.require('ol.TileState');
|
||||
goog.require('ol.dom');
|
||||
goog.require('ol.extent');
|
||||
goog.require('ol.proj');
|
||||
@@ -12,7 +13,6 @@ goog.require('ol.render.canvas.ReplayGroup');
|
||||
goog.require('ol.render.replay');
|
||||
goog.require('ol.renderer.canvas.TileLayer');
|
||||
goog.require('ol.renderer.vector');
|
||||
goog.require('ol.size');
|
||||
goog.require('ol.transform');
|
||||
|
||||
|
||||
@@ -23,6 +23,9 @@ goog.require('ol.transform');
|
||||
*/
|
||||
ol.renderer.canvas.VectorTileLayer = function(layer) {
|
||||
|
||||
/**
|
||||
* @type {CanvasRenderingContext2D}
|
||||
*/
|
||||
this.context = null;
|
||||
|
||||
ol.renderer.canvas.TileLayer.call(this, layer);
|
||||
@@ -95,43 +98,55 @@ ol.renderer.canvas.VectorTileLayer.prototype.prepareFrame = function(frameState,
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.VectorTile} tile Tile.
|
||||
* @param {ol.VectorImageTile} tile Tile.
|
||||
* @param {olx.FrameState} frameState Frame state.
|
||||
* @private
|
||||
*/
|
||||
ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup_ = function(tile,
|
||||
frameState) {
|
||||
ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup_ = function(
|
||||
tile, frameState) {
|
||||
var layer = this.getLayer();
|
||||
var pixelRatio = frameState.pixelRatio;
|
||||
var projection = frameState.viewState.projection;
|
||||
var revision = layer.getRevision();
|
||||
var renderOrder = layer.getRenderOrder() || null;
|
||||
var renderOrder = /** @type {ol.RenderOrderFunction} */
|
||||
(layer.getRenderOrder()) || null;
|
||||
|
||||
var replayState = tile.getReplayState();
|
||||
var replayState = tile.getReplayState(layer);
|
||||
if (!replayState.dirty && replayState.renderedRevision == revision &&
|
||||
replayState.renderedRenderOrder == renderOrder) {
|
||||
return;
|
||||
}
|
||||
|
||||
replayState.replayGroup = null;
|
||||
for (var t = 0, tt = tile.tileKeys.length; t < tt; ++t) {
|
||||
var sourceTile = tile.getTile(tile.tileKeys[t]);
|
||||
replayState.dirty = false;
|
||||
|
||||
var source = /** @type {ol.source.VectorTile} */ (layer.getSource());
|
||||
var tileGrid = source.getTileGrid();
|
||||
var tileCoord = tile.tileCoord;
|
||||
var tileProjection = tile.getProjection();
|
||||
var resolution = tileGrid.getResolution(tileCoord[0]);
|
||||
var sourceTileGrid = source.getTileGrid();
|
||||
var sourceTileCoord = sourceTile.tileCoord;
|
||||
var tileProjection = sourceTile.getProjection();
|
||||
var tileGrid = source.getTileGridForProjection(projection);
|
||||
var resolution = tileGrid.getResolution(tile.tileCoord[0]);
|
||||
var sourceTileResolution = sourceTileGrid.getResolution(sourceTile.tileCoord[0]);
|
||||
var tileExtent = tileGrid.getTileCoordExtent(tile.wrappedTileCoord);
|
||||
var sourceTileExtent = sourceTileGrid.getTileCoordExtent(sourceTileCoord);
|
||||
var sharedExtent = ol.extent.getIntersection(tileExtent, sourceTileExtent);
|
||||
var extent, reproject, tileResolution;
|
||||
if (tileProjection.getUnits() == ol.proj.Units.TILE_PIXELS) {
|
||||
var tilePixelRatio = tileResolution = source.getTilePixelRatio();
|
||||
var tileSize = ol.size.toSize(tileGrid.getTileSize(tileCoord[0]));
|
||||
extent = [0, 0, tileSize[0] * tilePixelRatio, tileSize[1] * tilePixelRatio];
|
||||
var transform = ol.transform.compose(this.tmpTransform_,
|
||||
0, 0,
|
||||
1 / sourceTileResolution * tilePixelRatio, -1 / sourceTileResolution * tilePixelRatio,
|
||||
0,
|
||||
-sourceTileExtent[0], -sourceTileExtent[3]);
|
||||
extent = (ol.transform.apply(transform, [sharedExtent[0], sharedExtent[3]])
|
||||
.concat(ol.transform.apply(transform, [sharedExtent[2], sharedExtent[1]])));
|
||||
} else {
|
||||
tileResolution = resolution;
|
||||
extent = tileGrid.getTileCoordExtent(tileCoord);
|
||||
extent = sharedExtent;
|
||||
if (!ol.proj.equivalent(projection, tileProjection)) {
|
||||
reproject = true;
|
||||
tile.setProjection(projection);
|
||||
sourceTile.setProjection(projection);
|
||||
}
|
||||
}
|
||||
replayState.dirty = false;
|
||||
@@ -144,7 +159,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup_ = function(tile,
|
||||
* @param {ol.Feature|ol.render.Feature} feature Feature.
|
||||
* @this {ol.renderer.canvas.VectorTileLayer}
|
||||
*/
|
||||
function renderFeature(feature) {
|
||||
var renderFeature = function(feature) {
|
||||
var styles;
|
||||
var styleFunction = feature.getStyleFunction();
|
||||
if (styleFunction) {
|
||||
@@ -164,9 +179,9 @@ ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup_ = function(tile,
|
||||
this.dirty_ = this.dirty_ || dirty;
|
||||
replayState.dirty = replayState.dirty || dirty;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var features = tile.getFeatures();
|
||||
var features = sourceTile.getFeatures();
|
||||
if (renderOrder && renderOrder !== replayState.renderedRenderOrder) {
|
||||
features.sort(renderOrder);
|
||||
}
|
||||
@@ -178,13 +193,11 @@ ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup_ = function(tile,
|
||||
}
|
||||
renderFeature.call(this, feature);
|
||||
}
|
||||
|
||||
replayGroup.finish();
|
||||
|
||||
sourceTile.setReplayGroup(layer, tile.tileCoord.toString(), replayGroup);
|
||||
}
|
||||
replayState.renderedRevision = revision;
|
||||
replayState.renderedRenderOrder = renderOrder;
|
||||
replayState.replayGroup = replayGroup;
|
||||
replayState.resolution = NaN;
|
||||
};
|
||||
|
||||
|
||||
@@ -193,10 +206,10 @@ ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup_ = function(tile,
|
||||
*/
|
||||
ol.renderer.canvas.VectorTileLayer.prototype.drawTileImage = function(
|
||||
tile, frameState, layerState, x, y, w, h, gutter) {
|
||||
var vectorTile = /** @type {ol.VectorTile} */ (tile);
|
||||
this.createReplayGroup_(vectorTile, frameState);
|
||||
var vectorImageTile = /** @type {ol.VectorImageTile} */ (tile);
|
||||
this.createReplayGroup_(vectorImageTile, frameState);
|
||||
if (this.context) {
|
||||
this.renderTileImage_(vectorTile, frameState, layerState);
|
||||
this.renderTileImage_(vectorImageTile, frameState, layerState);
|
||||
ol.renderer.canvas.TileLayer.prototype.drawTileImage.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
@@ -213,25 +226,31 @@ ol.renderer.canvas.VectorTileLayer.prototype.forEachFeatureAtCoordinate = functi
|
||||
/** @type {Object.<string, boolean>} */
|
||||
var features = {};
|
||||
|
||||
/** @type {Array.<ol.VectorTile>} */
|
||||
var replayables = this.renderedTiles;
|
||||
/** @type {Array.<ol.VectorImageTile>} */
|
||||
var renderedTiles = this.renderedTiles;
|
||||
|
||||
var source = /** @type {ol.source.VectorTile} */ (layer.getSource());
|
||||
var tileGrid = source.getTileGrid();
|
||||
var found, tileSpaceCoordinate;
|
||||
var tileGrid = source.getTileGridForProjection(frameState.viewState.projection);
|
||||
var sourceTileGrid = source.getTileGrid();
|
||||
var bufferedExtent, found, tileSpaceCoordinate;
|
||||
var i, ii, origin, replayGroup;
|
||||
var tile, tileCoord, tileExtent, tilePixelRatio, tileResolution;
|
||||
for (i = 0, ii = replayables.length; i < ii; ++i) {
|
||||
tile = replayables[i];
|
||||
for (i = 0, ii = renderedTiles.length; i < ii; ++i) {
|
||||
tile = renderedTiles[i];
|
||||
tileCoord = tile.tileCoord;
|
||||
tileExtent = source.getTileGrid().getTileCoordExtent(tileCoord, this.tmpExtent);
|
||||
if (!ol.extent.containsCoordinate(ol.extent.buffer(tileExtent, hitTolerance * resolution), coordinate)) {
|
||||
tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent);
|
||||
bufferedExtent = ol.extent.buffer(tileExtent, hitTolerance * resolution, bufferedExtent);
|
||||
if (!ol.extent.containsCoordinate(bufferedExtent, coordinate)) {
|
||||
continue;
|
||||
}
|
||||
if (tile.getProjection().getUnits() === ol.proj.Units.TILE_PIXELS) {
|
||||
origin = ol.extent.getTopLeft(tileExtent);
|
||||
for (var t = 0, tt = tile.tileKeys.length; t < tt; ++t) {
|
||||
var sourceTile = tile.getTile(tile.tileKeys[t]);
|
||||
if (sourceTile.getProjection().getUnits() === ol.proj.Units.TILE_PIXELS) {
|
||||
var sourceTileCoord = sourceTile.tileCoord;
|
||||
var sourceTileExtent = sourceTileGrid.getTileCoordExtent(sourceTileCoord, this.tmpExtent);
|
||||
origin = ol.extent.getTopLeft(sourceTileExtent);
|
||||
tilePixelRatio = source.getTilePixelRatio();
|
||||
tileResolution = tileGrid.getResolution(tileCoord[0]) / tilePixelRatio;
|
||||
tileResolution = sourceTileGrid.getResolution(sourceTileCoord[0]) / tilePixelRatio;
|
||||
tileSpaceCoordinate = [
|
||||
(coordinate[0] - origin[0]) / tileResolution,
|
||||
(origin[1] - coordinate[1]) / tileResolution
|
||||
@@ -240,7 +259,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.forEachFeatureAtCoordinate = functi
|
||||
} else {
|
||||
tileSpaceCoordinate = coordinate;
|
||||
}
|
||||
replayGroup = tile.getReplayState().replayGroup;
|
||||
replayGroup = sourceTile.getReplayGroup(layer, tile.tileCoord.toString());
|
||||
found = found || replayGroup.forEachFeatureAtCoordinate(
|
||||
tileSpaceCoordinate, resolution, rotation, hitTolerance, {},
|
||||
/**
|
||||
@@ -255,12 +274,13 @@ ol.renderer.canvas.VectorTileLayer.prototype.forEachFeatureAtCoordinate = functi
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return found;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.Tile} tile Tile.
|
||||
* @param {ol.VectorTile} tile Tile.
|
||||
* @param {olx.FrameState} frameState Frame state.
|
||||
* @return {ol.Transform} transform Transform.
|
||||
* @private
|
||||
@@ -308,7 +328,9 @@ ol.renderer.canvas.VectorTileLayer.prototype.handleStyleImageChange_ = function(
|
||||
* @inheritDoc
|
||||
*/
|
||||
ol.renderer.canvas.VectorTileLayer.prototype.postCompose = function(context, frameState, layerState) {
|
||||
var renderMode = this.getLayer().getRenderMode();
|
||||
var layer = this.getLayer();
|
||||
var source = layer.getSource();
|
||||
var renderMode = layer.getRenderMode();
|
||||
var replays = ol.renderer.canvas.VectorTileLayer.VECTOR_REPLAYS[renderMode];
|
||||
if (replays) {
|
||||
var pixelRatio = frameState.pixelRatio;
|
||||
@@ -317,18 +339,32 @@ ol.renderer.canvas.VectorTileLayer.prototype.postCompose = function(context, fra
|
||||
var offsetX = Math.round(pixelRatio * size[0] / 2);
|
||||
var offsetY = Math.round(pixelRatio * size[1] / 2);
|
||||
var tiles = this.renderedTiles;
|
||||
var tilePixelRatio = layer.getSource().getTilePixelRatio();
|
||||
var sourceTileGrid = source.getTileGrid();
|
||||
var tileGrid = source.getTileGridForProjection(frameState.viewState.projection);
|
||||
var clips = [];
|
||||
var zs = [];
|
||||
for (var i = tiles.length - 1; i >= 0; --i) {
|
||||
var tile = /** @type {ol.VectorTile} */ (tiles[i]);
|
||||
// Create a clip mask for regions in this low resolution tile that are
|
||||
// already filled by a higher resolution tile
|
||||
var transform = this.getReplayTransform_(tile, frameState);
|
||||
var currentClip = tile.getReplayState().replayGroup.getClipCoords(transform);
|
||||
var currentZ = tile.tileCoord[0];
|
||||
var tile = /** @type {ol.VectorImageTile} */ (tiles[i]);
|
||||
if (tile.getState() == ol.TileState.ABORT) {
|
||||
continue;
|
||||
}
|
||||
var tileCoord = tile.tileCoord;
|
||||
var worldOffset = tileGrid.getTileCoordExtent(tileCoord)[0] -
|
||||
tileGrid.getTileCoordExtent(tile.wrappedTileCoord)[0];
|
||||
for (var t = 0, tt = tile.tileKeys.length; t < tt; ++t) {
|
||||
var sourceTile = tile.getTile(tile.tileKeys[t]);
|
||||
var currentZ = sourceTile.tileCoord[0];
|
||||
var sourceResolution = sourceTileGrid.getResolution(currentZ);
|
||||
var transform = this.getReplayTransform_(sourceTile, frameState);
|
||||
ol.transform.translate(transform, worldOffset * tilePixelRatio / sourceResolution, 0);
|
||||
var replayGroup = sourceTile.getReplayGroup(layer, tileCoord.toString());
|
||||
var currentClip = replayGroup.getClipCoords(transform);
|
||||
context.save();
|
||||
context.globalAlpha = layerState.opacity;
|
||||
ol.render.canvas.rotateAtOffset(context, -rotation, offsetX, offsetY);
|
||||
// Create a clip mask for regions in this low resolution tile that are
|
||||
// already filled by a higher resolution tile
|
||||
for (var j = 0, jj = clips.length; j < jj; ++j) {
|
||||
var clip = clips[j];
|
||||
if (currentZ < zs[j]) {
|
||||
@@ -346,13 +382,13 @@ ol.renderer.canvas.VectorTileLayer.prototype.postCompose = function(context, fra
|
||||
context.clip();
|
||||
}
|
||||
}
|
||||
var replayGroup = tile.getReplayState().replayGroup;
|
||||
replayGroup.replay(context, pixelRatio, transform, rotation, {}, replays);
|
||||
context.restore();
|
||||
clips.push(currentClip);
|
||||
zs.push(currentZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
ol.renderer.canvas.TileLayer.prototype.postCompose.apply(this, arguments);
|
||||
};
|
||||
|
||||
@@ -386,7 +422,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.renderFeature = function(feature, s
|
||||
|
||||
|
||||
/**
|
||||
* @param {ol.VectorTile} tile Tile.
|
||||
* @param {ol.VectorImageTile} tile Tile.
|
||||
* @param {olx.FrameState} frameState Frame state.
|
||||
* @param {ol.LayerState} layerState Layer state.
|
||||
* @private
|
||||
@@ -394,33 +430,43 @@ ol.renderer.canvas.VectorTileLayer.prototype.renderFeature = function(feature, s
|
||||
ol.renderer.canvas.VectorTileLayer.prototype.renderTileImage_ = function(
|
||||
tile, frameState, layerState) {
|
||||
var layer = this.getLayer();
|
||||
var replayState = tile.getReplayState();
|
||||
var replayState = tile.getReplayState(layer);
|
||||
var revision = layer.getRevision();
|
||||
var replays = ol.renderer.canvas.VectorTileLayer.IMAGE_REPLAYS[layer.getRenderMode()];
|
||||
if (replays && replayState.renderedTileRevision !== revision) {
|
||||
replayState.renderedTileRevision = revision;
|
||||
var tileCoord = tile.tileCoord;
|
||||
var z = tile.tileCoord[0];
|
||||
var tileCoord = tile.wrappedTileCoord;
|
||||
var z = tileCoord[0];
|
||||
var pixelRatio = frameState.pixelRatio;
|
||||
var source = layer.getSource();
|
||||
var tileGrid = source.getTileGrid();
|
||||
var tilePixelRatio = source.getTilePixelRatio();
|
||||
var transform = ol.transform.reset(this.tmpTransform_);
|
||||
if (tile.getProjection().getUnits() == ol.proj.Units.TILE_PIXELS) {
|
||||
var renderPixelRatio = pixelRatio / tilePixelRatio;
|
||||
ol.transform.scale(transform, renderPixelRatio, renderPixelRatio);
|
||||
} else {
|
||||
var sourceTileGrid = source.getTileGrid();
|
||||
var tileGrid = source.getTileGridForProjection(frameState.viewState.projection);
|
||||
var resolution = tileGrid.getResolution(z);
|
||||
var pixelScale = pixelRatio / resolution;
|
||||
var tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent);
|
||||
ol.transform.scale(transform, pixelScale, -pixelScale);
|
||||
ol.transform.translate(transform, -tileExtent[0], -tileExtent[3]);
|
||||
}
|
||||
|
||||
var context = tile.getContext();
|
||||
var tilePixelRatio = source.getTilePixelRatio();
|
||||
var context = tile.getContext(layer);
|
||||
var size = source.getTilePixelSize(z, pixelRatio, frameState.viewState.projection);
|
||||
context.canvas.width = size[0];
|
||||
context.canvas.height = size[1];
|
||||
replayState.replayGroup.replay(context, pixelRatio, transform, 0, {}, replays);
|
||||
var tileExtent = tileGrid.getTileCoordExtent(tileCoord);
|
||||
for (var i = 0, ii = tile.tileKeys.length; i < ii; ++i) {
|
||||
var sourceTile = tile.getTile(tile.tileKeys[i]);
|
||||
var sourceTileCoord = sourceTile.tileCoord;
|
||||
var pixelScale = pixelRatio / resolution;
|
||||
var transform = ol.transform.reset(this.tmpTransform_);
|
||||
if (sourceTile.getProjection().getUnits() == ol.proj.Units.TILE_PIXELS) {
|
||||
var sourceTileExtent = sourceTileGrid.getTileCoordExtent(sourceTileCoord, this.tmpExtent);
|
||||
var sourceResolution = sourceTileGrid.getResolution(sourceTileCoord[0]);
|
||||
var renderPixelRatio = pixelRatio / tilePixelRatio * sourceResolution / resolution;
|
||||
ol.transform.scale(transform, renderPixelRatio, renderPixelRatio);
|
||||
var offsetX = (sourceTileExtent[0] - tileExtent[0]) / sourceResolution * tilePixelRatio;
|
||||
var offsetY = (tileExtent[3] - sourceTileExtent[3]) / sourceResolution * tilePixelRatio;
|
||||
ol.transform.translate(transform, Math.round(offsetX), Math.round(offsetY));
|
||||
} else {
|
||||
ol.transform.scale(transform, pixelScale, -pixelScale);
|
||||
ol.transform.translate(transform, -tileExtent[0], -tileExtent[3]);
|
||||
}
|
||||
var replayGroup = sourceTile.getReplayGroup(layer, tile.tileCoord.toString());
|
||||
replayGroup.replay(context, pixelRatio, transform, 0, {}, replays);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -152,8 +152,10 @@ ol.renderer.Layer.prototype.scheduleExpireCache = function(frameState, tileSourc
|
||||
*/
|
||||
var postRenderFunction = function(tileSource, map, frameState) {
|
||||
var tileSourceKey = ol.getUid(tileSource).toString();
|
||||
if (tileSourceKey in frameState.usedTiles) {
|
||||
tileSource.expireCache(frameState.viewState.projection,
|
||||
frameState.usedTiles[tileSourceKey]);
|
||||
}
|
||||
}.bind(null, tileSource);
|
||||
|
||||
frameState.postRenderFunctions.push(
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// This file is automatically generated, do not edit
|
||||
/* eslint openlayers-internal/no-missing-requires: 0 */
|
||||
goog.provide('ol.renderer.webgl.defaultmapshader');
|
||||
|
||||
goog.require('ol');
|
||||
|
||||
@@ -156,8 +156,8 @@ if (ol.ENABLE_WEBGL) {
|
||||
|
||||
var locations;
|
||||
if (!this.defaultLocations_) {
|
||||
locations =
|
||||
new ol.renderer.webgl.defaultmapshader.Locations(gl, program);
|
||||
// eslint-disable-next-line openlayers-internal/no-missing-requires
|
||||
locations = new ol.renderer.webgl.defaultmapshader.Locations(gl, program);
|
||||
this.defaultLocations_ = locations;
|
||||
} else {
|
||||
locations = this.defaultLocations_;
|
||||
|
||||
@@ -196,8 +196,8 @@ if (ol.ENABLE_WEBGL) {
|
||||
var program = context.getProgram(this.fragmentShader_, this.vertexShader_);
|
||||
context.useProgram(program);
|
||||
if (!this.locations_) {
|
||||
this.locations_ =
|
||||
new ol.renderer.webgl.tilelayershader.Locations(gl, program);
|
||||
// eslint-disable-next-line openlayers-internal/no-missing-requires
|
||||
this.locations_ = new ol.renderer.webgl.tilelayershader.Locations(gl, program);
|
||||
}
|
||||
|
||||
context.bindBuffer(ol.webgl.ARRAY_BUFFER, this.renderArrayBuffer_);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// This file is automatically generated, do not edit
|
||||
/* eslint openlayers-internal/no-missing-requires: 0 */
|
||||
goog.provide('ol.renderer.webgl.tilelayershader');
|
||||
|
||||
goog.require('ol');
|
||||
|
||||
@@ -40,13 +40,15 @@ ol.reproj.calculateSourceResolution = function(sourceProj, targetProj,
|
||||
// coordinates may be slightly different. We need to reverse-compensate this
|
||||
// in order to achieve optimal results.
|
||||
|
||||
var sourceExtent = sourceProj.getExtent();
|
||||
if (!sourceExtent || ol.extent.containsCoordinate(sourceExtent, sourceCenter)) {
|
||||
var compensationFactor =
|
||||
ol.proj.getPointResolution(sourceProj, sourceResolution, sourceCenter) /
|
||||
sourceResolution;
|
||||
|
||||
if (isFinite(compensationFactor) && compensationFactor > 0) {
|
||||
sourceResolution /= compensationFactor;
|
||||
}
|
||||
}
|
||||
|
||||
return sourceResolution;
|
||||
};
|
||||
|
||||
@@ -202,7 +202,8 @@ ol.reproj.Tile.prototype.disposeInternal = function() {
|
||||
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* Get the HTML Canvas element for this tile.
|
||||
* @return {HTMLCanvasElement} Canvas.
|
||||
*/
|
||||
ol.reproj.Tile.prototype.getImage = function() {
|
||||
return this.canvas_;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user