Compare commits

..

252 Commits

Author SHA1 Message Date
Tim Schaub
b64b8af2ea Changes for v6.7.0 2021-09-09 11:24:29 -06:00
Tim Schaub
be312c1616 Merge pull request #12727 from simonseyock/patch-3
Add missing 'boxstart' event to OnSignature
2021-09-09 09:54:08 -06:00
Simon Seyock
c27974b3da Add missing 'boxstart' event to OnSignature
Fixes #12725
2021-09-09 16:48:23 +02:00
Tim Schaub
d7f7cbbc75 Merge pull request #12718 from tschaub/wms-caps
Rename function to avoid minification failure
2021-09-07 14:40:49 -06:00
Tim Schaub
c0546c5f07 Rename function to avoid minification failure 2021-09-07 14:18:52 -06:00
Andreas Hocevar
1f3e3efe5d Merge pull request #12712 from ahocevar/read-rgb
Add convertToRGB option to GeoTIFF source
2021-09-07 17:23:32 +02:00
Andreas Hocevar
cde6417d62 Add convertToRGB option to GeoTIFF source 2021-09-07 17:19:34 +02:00
Frédéric Junod
4c673ce846 Merge pull request #12716 from fredj/spelling
Spelling fix
2021-09-07 14:15:50 +02:00
Tim Schaub
3a869ba7f6 Merge pull request #12715 from tschaub/proj-units
Try harder to get the projection from GeoTIFF headers
2021-09-07 06:12:19 -06:00
Frederic Junod
5c212008de Spelling fix 2021-09-07 09:47:47 +02:00
Tim Schaub
be51d0480c Try harder to get the projection from GeoTIFF headers 2021-09-06 16:55:16 -06:00
Tim Schaub
e89b6c0a3f Merge pull request #12714 from tschaub/simpler-examples
Avoid creating duplicate projections in COG examples
2021-09-06 16:54:16 -06:00
Tim Schaub
4b340fc9bc Avoid creating duplicate projections in COG examples 2021-09-06 16:08:10 -06:00
Tim Schaub
81fdcd5a38 Merge pull request #12713 from tschaub/geotiff-crs
Check for GeoTIFF CRS starting with last image
2021-09-06 16:05:02 -06:00
Tim Schaub
cbfbe08aaa Merge pull request #12709 from tschaub/unreferenced-geotiff
Support rendering of GeoTIFF images in pixel coordinates
2021-09-06 15:30:35 -06:00
Tim Schaub
fce42dc80f Check for crs starting with last image 2021-09-06 15:26:19 -06:00
Tim Schaub
9ddca3739b Merge pull request #12711 from tschaub/band-number
Use band numbers starting with one
2021-09-06 12:50:17 -06:00
Tim Schaub
83375e735c Merge pull request #12710 from tschaub/doc-typo
Spelling fix in GeoTIFF docs
2021-09-06 12:00:48 -06:00
Tim Schaub
0e4c40e315 Use band numbers starting with one 2021-09-06 11:31:08 -06:00
Tim Schaub
39f62f1fa2 Spelling fix 2021-09-06 11:06:46 -06:00
Tim Schaub
eab8dcf7ba Support rendering of GeoTIFF images in pixel coordinates 2021-09-06 09:14:50 -06:00
Andreas Hocevar
8a67c5dbe6 Merge pull request #12703 from openlayers/dependabot/npm_and_yarn/terser-webpack-plugin-5.2.3
Bump terser-webpack-plugin from 5.1.4 to 5.2.3
2021-09-06 12:45:22 +02:00
Andreas Hocevar
72ad10887e Merge pull request #12704 from openlayers/dependabot/npm_and_yarn/babel/eslint-parser-7.15.4
Bump @babel/eslint-parser from 7.15.0 to 7.15.4
2021-09-06 12:45:01 +02:00
Andreas Hocevar
8c96fc8120 Merge pull request #12705 from openlayers/dependabot/npm_and_yarn/webpack-5.52.0
Bump webpack from 5.51.1 to 5.52.0
2021-09-06 12:44:22 +02:00
Andreas Hocevar
348a1d1a13 Merge pull request #12706 from openlayers/dependabot/npm_and_yarn/webpack-dev-server-4.1.0
Bump webpack-dev-server from 4.0.0 to 4.1.0
2021-09-06 12:44:01 +02:00
Andreas Hocevar
0b0d6ba637 Merge pull request #12707 from openlayers/dependabot/npm_and_yarn/babel/core-7.15.5
Bump @babel/core from 7.15.0 to 7.15.5
2021-09-06 12:43:34 +02:00
Andreas Hocevar
6173b3259d Merge pull request #12702 from openlayers/dependabot/npm_and_yarn/babel/preset-env-7.15.4
Bump @babel/preset-env from 7.15.0 to 7.15.4
2021-09-06 12:43:14 +02:00
dependabot[bot]
02f2cb8a65 Bump @babel/core from 7.15.0 to 7.15.5
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.15.0 to 7.15.5.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.15.5/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-06 10:02:38 +00:00
dependabot[bot]
3a4fdbdf6b Bump webpack-dev-server from 4.0.0 to 4.1.0
Bumps [webpack-dev-server](https://github.com/webpack/webpack-dev-server) from 4.0.0 to 4.1.0.
- [Release notes](https://github.com/webpack/webpack-dev-server/releases)
- [Changelog](https://github.com/webpack/webpack-dev-server/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack-dev-server/compare/v4.0.0...v4.1.0)

---
updated-dependencies:
- dependency-name: webpack-dev-server
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-06 10:02:15 +00:00
dependabot[bot]
593ea6706a Bump webpack from 5.51.1 to 5.52.0
Bumps [webpack](https://github.com/webpack/webpack) from 5.51.1 to 5.52.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.51.1...v5.52.0)

---
updated-dependencies:
- dependency-name: webpack
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-06 10:02:04 +00:00
dependabot[bot]
0ac661bed1 Bump @babel/eslint-parser from 7.15.0 to 7.15.4
Bumps [@babel/eslint-parser](https://github.com/babel/babel/tree/HEAD/eslint/babel-eslint-parser) from 7.15.0 to 7.15.4.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.15.4/eslint/babel-eslint-parser)

---
updated-dependencies:
- dependency-name: "@babel/eslint-parser"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-06 10:01:51 +00:00
dependabot[bot]
aa7ab1ba65 Bump terser-webpack-plugin from 5.1.4 to 5.2.3
Bumps [terser-webpack-plugin](https://github.com/webpack-contrib/terser-webpack-plugin) from 5.1.4 to 5.2.3.
- [Release notes](https://github.com/webpack-contrib/terser-webpack-plugin/releases)
- [Changelog](https://github.com/webpack-contrib/terser-webpack-plugin/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack-contrib/terser-webpack-plugin/compare/v5.1.4...v5.2.3)

---
updated-dependencies:
- dependency-name: terser-webpack-plugin
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-06 10:01:30 +00:00
dependabot[bot]
d63728d3d4 Bump @babel/preset-env from 7.15.0 to 7.15.4
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.15.0 to 7.15.4.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.15.4/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-06 10:01:14 +00:00
Tim Schaub
c9ec6138ba Merge pull request #12697 from tschaub/doc-warning
Move description above type tag
2021-09-05 12:27:48 -06:00
Tim Schaub
c0bfcfb7ba Move description above type tag 2021-09-05 11:29:15 -06:00
Tim Schaub
69ec9871e2 Merge pull request #12695 from mike-000/KML
Update Google KML icon anchors and correct icon scaling
2021-09-05 08:51:06 -06:00
Andreas Hocevar
1f40bcd633 Merge pull request #12642 from ahocevar/mapbox-style-fullscreen
Fix fullscreen in mapbox-style example
2021-09-05 09:30:33 +02:00
Andreas Hocevar
5901751f43 Merge pull request #12624 from ahocevar/apidoc-undefined
Improve API docs for optional properties
2021-09-05 09:30:04 +02:00
mike-000
7b8d6c817b Ensure scale used in calculations is numeric 2021-09-05 00:04:14 +01:00
mike-000
0c912b6c29 Test load icon image and reset the scale 2021-09-04 23:12:40 +01:00
Tim Schaub
3004f5707f Merge pull request #10963 from tschaub/ogc-tiles
OGC map and vector tile sources
2021-09-04 11:20:42 -06:00
Tim Schaub
c8067bebbb Add supported media type list to feature formats 2021-09-04 11:17:41 -06:00
mike-000
35ed7d4358 Update expected scales 2021-09-04 18:10:01 +01:00
mike-000
c76e78d0b3 Update Google default icon hotspot anchors
Update Google default icon hotspot anchors
Correct icon scaling
Include icon anchor in textOffset calculation
2021-09-04 17:38:36 +01:00
Tim Schaub
ac4e472353 Use union type for corner of origin 2021-09-04 10:31:36 -06:00
Tim Schaub
7168a26cab Use union types
Co-authored-by: Andreas Hocevar <andreas.hocevar@gmail.com>
2021-09-04 10:21:36 -06:00
Tim Schaub
12795e3923 Slightly smaller functions 2021-09-03 14:21:22 -06:00
Tim Schaub
d8baa87e25 Respect tile matrix set limits 2021-09-03 14:13:06 -06:00
Tim Schaub
58cf9f5f6d Leave as experimental until spec is finalized 2021-09-03 12:28:27 -06:00
Tim Schaub
4099f60779 OGC vector tile source 2021-09-03 12:28:27 -06:00
Tim Schaub
791add0d73 OGC map tile source 2021-09-03 12:28:27 -06:00
Andreas Hocevar
d7af546ad3 Merge pull request #12690 from ahocevar/foreachsegment-stride
Fix return stride of forEachSegment
2021-09-02 16:20:23 +02:00
Andreas Hocevar
d17c7ad31e Fix return stride of forEachSegment 2021-09-02 09:44:33 +02:00
Andreas Hocevar
95bfe85dd5 Merge pull request #12684 from mike-000/patch-12
Fix view resolutions in example
2021-08-31 13:11:02 +02:00
mike-000
167d852e02 Fix view resolutions 2021-08-31 11:27:18 +01:00
Andreas Hocevar
7bb5211fc0 Merge pull request #12683 from ahocevar/icon-sprite-offset-pixelratio
Fix sprite offset for pixel ratio !== 1
2021-08-31 09:47:47 +02:00
Tim Schaub
04da7d568f Merge pull request #12677 from openlayers/dependabot/npm_and_yarn/marked-3.0.2
Bump marked from 3.0.0 to 3.0.2
2021-08-30 16:50:23 -06:00
Andreas Hocevar
df493725c6 Fix sprite offset for pixel ratio !== 1 2021-08-30 22:05:34 +02:00
dependabot[bot]
25c1fe7d57 Bump marked from 3.0.0 to 3.0.2
Bumps [marked](https://github.com/markedjs/marked) from 3.0.0 to 3.0.2.
- [Release notes](https://github.com/markedjs/marked/releases)
- [Changelog](https://github.com/markedjs/marked/blob/master/release.config.js)
- [Commits](https://github.com/markedjs/marked/compare/v3.0.0...v3.0.2)

---
updated-dependencies:
- dependency-name: marked
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-30 15:48:50 +00:00
Tim Schaub
706955dfd9 Merge pull request #12678 from openlayers/dependabot/npm_and_yarn/globby-12.0.2
Bump globby from 12.0.1 to 12.0.2
2021-08-30 09:48:23 -06:00
Tim Schaub
611c0e5d6b Merge pull request #12679 from openlayers/dependabot/npm_and_yarn/mocha-9.1.1
Bump mocha from 9.1.0 to 9.1.1
2021-08-30 09:47:58 -06:00
dependabot[bot]
ae38ef32df Bump mocha from 9.1.0 to 9.1.1
Bumps [mocha](https://github.com/mochajs/mocha) from 9.1.0 to 9.1.1.
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v9.1.0...v9.1.1)

---
updated-dependencies:
- dependency-name: mocha
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-30 10:01:33 +00:00
dependabot[bot]
f5fc891ae0 Bump globby from 12.0.1 to 12.0.2
Bumps [globby](https://github.com/sindresorhus/globby) from 12.0.1 to 12.0.2.
- [Release notes](https://github.com/sindresorhus/globby/releases)
- [Commits](https://github.com/sindresorhus/globby/compare/v12.0.1...v12.0.2)

---
updated-dependencies:
- dependency-name: globby
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-30 10:01:17 +00:00
Tim Schaub
1601d6b859 Merge pull request #12671 from tschaub/cacheless
Configure cache on the layer instead of the source
2021-08-28 15:01:01 -06:00
Andreas Hocevar
9c5d0b54e3 Merge pull request #12669 from ahocevar/geotiff-options
Add opaque and transition options to GeoTIFF source
2021-08-28 19:54:12 +02:00
Tim Schaub
d37e3e3134 Configure cache on the layer instead of the source 2021-08-27 18:04:00 -06:00
Andreas Hocevar
14371a5462 Add opaque and transition options to GeoTIFF source 2021-08-27 19:46:49 +02:00
Tim Schaub
5e6e2f0fb6 Merge pull request #12667 from tschaub/raster-updates
Additional docs and type checking for raster source
2021-08-26 16:44:21 -06:00
Andreas Hocevar
64ea2a56da Merge pull request #12666 from ahocevar/pluggablemap-events
Re-add accidently removed events
2021-08-26 19:29:20 +02:00
Andreas Hocevar
b588ec8c7f Re-add accidently removed events 2021-08-26 19:05:27 +02:00
Tim Schaub
de9ff20f65 Additional docs and type checking for raster source 2021-08-26 11:04:07 -06:00
Andreas Hocevar
3b6bf14cdc Merge pull request #12657 from openlayers/dependabot/npm_and_yarn/mocha-9.1.0
Bump mocha from 9.0.3 to 9.1.0
2021-08-23 14:06:32 +02:00
dependabot[bot]
d58a1b7d09 Bump mocha from 9.0.3 to 9.1.0
Bumps [mocha](https://github.com/mochajs/mocha) from 9.0.3 to 9.1.0.
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v9.0.3...v9.1.0)

---
updated-dependencies:
- dependency-name: mocha
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-23 10:01:11 +00:00
Andreas Hocevar
0fcaad321c Merge pull request #12650 from openlayers/dependabot/npm_and_yarn/webpack-5.51.1
Bump webpack from 5.50.0 to 5.51.1
2021-08-23 10:42:25 +02:00
dependabot[bot]
fe9a8d2c74 Bump webpack from 5.50.0 to 5.51.1
Bumps [webpack](https://github.com/webpack/webpack) from 5.50.0 to 5.51.1.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.50.0...v5.51.1)

---
updated-dependencies:
- dependency-name: webpack
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-23 08:34:09 +00:00
Andreas Hocevar
64fff348fd Merge pull request #12654 from openlayers/dependabot/npm_and_yarn/webpack-dev-server-4.0.0
Bump webpack-dev-server from 4.0.0-rc.0 to 4.0.0
2021-08-23 10:32:49 +02:00
Andreas Hocevar
88810afac6 Merge pull request #12653 from openlayers/dependabot/npm_and_yarn/globby-12.0.1
Bump globby from 12.0.0 to 12.0.1
2021-08-23 10:29:01 +02:00
Andreas Hocevar
1723bea12c Merge pull request #12652 from openlayers/dependabot/npm_and_yarn/loglevelnext-5.0.6
Bump loglevelnext from 5.0.5 to 5.0.6
2021-08-23 10:22:29 +02:00
Andreas Hocevar
fbded2a504 Merge pull request #12651 from openlayers/dependabot/npm_and_yarn/rollup-2.56.3
Bump rollup from 2.56.2 to 2.56.3
2021-08-23 10:18:09 +02:00
dependabot[bot]
9ea56cf9c7 Bump webpack-dev-server from 4.0.0-rc.0 to 4.0.0
Bumps [webpack-dev-server](https://github.com/webpack/webpack-dev-server) from 4.0.0-rc.0 to 4.0.0.
- [Release notes](https://github.com/webpack/webpack-dev-server/releases)
- [Changelog](https://github.com/webpack/webpack-dev-server/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack-dev-server/compare/v4.0.0-rc.0...v4.0.0)

---
updated-dependencies:
- dependency-name: webpack-dev-server
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-23 08:14:04 +00:00
dependabot[bot]
674ed45888 Bump globby from 12.0.0 to 12.0.1
Bumps [globby](https://github.com/sindresorhus/globby) from 12.0.0 to 12.0.1.
- [Release notes](https://github.com/sindresorhus/globby/releases)
- [Commits](https://github.com/sindresorhus/globby/compare/v12.0.0...v12.0.1)

---
updated-dependencies:
- dependency-name: globby
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-23 08:13:04 +00:00
dependabot[bot]
8674c46899 Bump loglevelnext from 5.0.5 to 5.0.6
Bumps [loglevelnext](https://github.com/shellscape/loglevelnext) from 5.0.5 to 5.0.6.
- [Release notes](https://github.com/shellscape/loglevelnext/releases)
- [Commits](https://github.com/shellscape/loglevelnext/compare/v5.0.5...v5.0.6)

---
updated-dependencies:
- dependency-name: loglevelnext
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-23 08:12:33 +00:00
dependabot[bot]
0a7c90acdd Bump rollup from 2.56.2 to 2.56.3
Bumps [rollup](https://github.com/rollup/rollup) from 2.56.2 to 2.56.3.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v2.56.2...v2.56.3)

---
updated-dependencies:
- dependency-name: rollup
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-23 08:12:01 +00:00
Andreas Hocevar
b71667c386 Merge pull request #12647 from mike-000/patch-11
Remove Translate option conflicts and update documentation
2021-08-22 12:29:27 +02:00
mike-000
d85990436d fix typo 2021-08-21 15:13:38 +01:00
mike-000
3c1e3dcfd5 Document (existing) multiple feature behaviour 2021-08-21 15:11:57 +01:00
mike-000
207fc99295 Remove option conflicts and update documentation 2021-08-21 14:57:11 +01:00
Tim Schaub
72d153696a Merge pull request #12008 from tschaub/gl
Rendering raster tiles with WebGL
2021-08-20 10:14:48 -06:00
Andreas Hocevar
a0b75268ee Fix fullscreen in mapbox-style example 2021-08-20 09:28:22 +02:00
Tim Schaub
42970915ea Extract nodata values from metadata when possible 2021-08-19 10:40:59 -06:00
Tim Schaub
8954f001fa Modify the source extent 2021-08-19 09:19:53 -06:00
Tim Schaub
b8c52b4298 Update aspect calculation for GLSL atan implementation 2021-08-18 18:25:38 -06:00
Andreas Hocevar
10989f96bf Fix aspect calculation in shaded-relief example 2021-08-18 21:30:53 +02:00
Andreas Hocevar
814d70b1cc Add more tests 2021-08-18 17:54:48 +02:00
Andreas Hocevar
7acd5338c9 Allow sampling data from neighboring pixels 2021-08-18 11:24:37 +02:00
Andreas Hocevar
324148c606 Add more docs 2021-08-18 11:24:37 +02:00
Andreas Hocevar
7a8c1f309b Use geotiff v1.0.4 2021-08-18 11:24:36 +02:00
Andreas Hocevar
011c14c7df Load layers for pyramid on demand 2021-08-18 11:24:35 +02:00
Andreas Hocevar
283aed2dc9 Better docs 2021-08-18 11:24:34 +02:00
Andreas Hocevar
4526f2ef34 Properly handle alt tiles of transparent images 2021-08-18 11:24:34 +02:00
Andreas Hocevar
efae01e71f Add COG tile pyramid example 2021-08-18 11:24:33 +02:00
Andreas Hocevar
394873013c Do not render layer when outside extent 2021-08-18 11:24:32 +02:00
Andreas Hocevar
e7dfcc77ae Fix source key handling for interim tiles 2021-08-18 11:24:32 +02:00
Andreas Hocevar
e8ead306ff Remove multi-source restrictions and fix alpha 2021-08-18 11:24:31 +02:00
Tim Schaub
7f3f4e6cdd Set tile after creating helper
Co-authored-by: MoonE <maxi_kroeg@web.de>
2021-08-18 11:24:30 +02:00
Andreas Hocevar
79b3bc4244 Add multi-source cog example 2021-08-18 11:24:29 +02:00
Andreas Hocevar
05e0fb1bf7 Mix Geotiffs with arbitrary bands and resolutions 2021-08-18 11:24:29 +02:00
Andreas Hocevar
f0cac76718 Add expression for Math.abs 2021-08-18 11:24:28 +02:00
Andreas Hocevar
05eac3e384 Use worker for GeoTIFF decoding 2021-08-18 11:24:27 +02:00
Andreas Hocevar
311247265b Add interim tiles handling 2021-08-18 11:24:26 +02:00
Andreas Hocevar
fd43b00118 Premultiply alpha for transparent tile sources 2021-08-18 11:24:25 +02:00
Andreas Hocevar
976f1b694a Fix legacy build to work with geotiff 2021-08-18 11:24:24 +02:00
Andreas Hocevar
429a8fbc1a Remove lint after dependency updates 2021-08-18 11:24:24 +02:00
Tim Schaub
af80477c1d Rendering raster tiles with WebGL 2021-08-18 11:24:23 +02:00
Andreas Hocevar
2dd212cdac Merge pull request #12627 from openlayers/dependabot/npm_and_yarn/webpack-cli-4.8.0
Bump webpack-cli from 4.7.2 to 4.8.0
2021-08-17 11:48:33 +02:00
Andreas Hocevar
6df5ff8d2b Merge pull request #12632 from mike-000/patch-10
Only warn of zero size when map should be visible
2021-08-17 10:27:35 +02:00
mike-000
0f56eed272 only warn of zero size when map should be visible 2021-08-16 23:43:43 +01:00
Andreas Hocevar
b41abcb08e Merge pull request #12631 from openlayers/dependabot/npm_and_yarn/marked-3.0.0
Bump marked from 2.1.3 to 3.0.0
2021-08-16 14:03:47 +02:00
Andreas Hocevar
e9607acacb Merge pull request #12630 from openlayers/dependabot/npm_and_yarn/webpack-5.50.0
Bump webpack from 5.49.0 to 5.50.0
2021-08-16 14:02:55 +02:00
Andreas Hocevar
c155850395 Merge pull request #12629 from openlayers/dependabot/npm_and_yarn/yargs-17.1.1
Bump yargs from 17.1.0 to 17.1.1
2021-08-16 14:02:15 +02:00
Andreas Hocevar
b068284d8f Merge pull request #12628 from openlayers/dependabot/npm_and_yarn/rollup-2.56.2
Bump rollup from 2.56.1 to 2.56.2
2021-08-16 14:01:47 +02:00
Andreas Hocevar
2332acc4e4 Merge pull request #12626 from mike-000/patch-9
Set canvas style to override problem 3rd party css
2021-08-16 12:15:07 +02:00
dependabot[bot]
d6a1f83b0e Bump marked from 2.1.3 to 3.0.0
Bumps [marked](https://github.com/markedjs/marked) from 2.1.3 to 3.0.0.
- [Release notes](https://github.com/markedjs/marked/releases)
- [Changelog](https://github.com/markedjs/marked/blob/master/release.config.js)
- [Commits](https://github.com/markedjs/marked/compare/v2.1.3...v3.0.0)

---
updated-dependencies:
- dependency-name: marked
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-16 10:02:10 +00:00
dependabot[bot]
492fa3d9f7 Bump webpack from 5.49.0 to 5.50.0
Bumps [webpack](https://github.com/webpack/webpack) from 5.49.0 to 5.50.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.49.0...v5.50.0)

---
updated-dependencies:
- dependency-name: webpack
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-16 10:01:56 +00:00
dependabot[bot]
2c0fc5eded Bump yargs from 17.1.0 to 17.1.1
Bumps [yargs](https://github.com/yargs/yargs) from 17.1.0 to 17.1.1.
- [Release notes](https://github.com/yargs/yargs/releases)
- [Changelog](https://github.com/yargs/yargs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yargs/yargs/compare/v17.1.0...v17.1.1)

---
updated-dependencies:
- dependency-name: yargs
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-16 10:01:25 +00:00
dependabot[bot]
82e17ca11b Bump rollup from 2.56.1 to 2.56.2
Bumps [rollup](https://github.com/rollup/rollup) from 2.56.1 to 2.56.2.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v2.56.1...v2.56.2)

---
updated-dependencies:
- dependency-name: rollup
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-16 10:01:13 +00:00
dependabot[bot]
f5fd052aee Bump webpack-cli from 4.7.2 to 4.8.0
Bumps [webpack-cli](https://github.com/webpack/webpack-cli) from 4.7.2 to 4.8.0.
- [Release notes](https://github.com/webpack/webpack-cli/releases)
- [Changelog](https://github.com/webpack/webpack-cli/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack-cli/compare/webpack-cli@4.7.2...webpack-cli@4.8.0)

---
updated-dependencies:
- dependency-name: webpack-cli
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-16 10:00:59 +00:00
mike-000
d824475305 set initial style after document.createElement 2021-08-16 10:27:41 +01:00
mike-000
78c105e838 set canvas style to override problem 3rd party css
move typecast for simplicity
2021-08-15 23:14:41 +01:00
Andreas Hocevar
000461993b Add undefined as type when optional and no default 2021-08-12 12:18:51 +02:00
Andreas Hocevar
44ec78749f Merge pull request #12616 from openlayers/dependabot/npm_and_yarn/webpack-5.49.0
Bump webpack from 5.47.1 to 5.49.0
2021-08-09 14:22:51 +02:00
Andreas Hocevar
0649f613ad Merge pull request #12617 from openlayers/dependabot/npm_and_yarn/babel/eslint-parser-7.15.0
Bump @babel/eslint-parser from 7.14.9 to 7.15.0
2021-08-09 14:22:18 +02:00
Andreas Hocevar
6ee0da2d76 Merge pull request #12615 from openlayers/dependabot/npm_and_yarn/rollup-2.56.1
Bump rollup from 2.56.0 to 2.56.1
2021-08-09 14:21:45 +02:00
Andreas Hocevar
d86cc70e46 Merge pull request #12614 from openlayers/dependabot/npm_and_yarn/puppeteer-10.2.0
Bump puppeteer from 10.1.0 to 10.2.0
2021-08-09 14:21:16 +02:00
Andreas Hocevar
91a24d45bd Merge pull request #12613 from openlayers/dependabot/npm_and_yarn/yargs-17.1.0
Bump yargs from 17.0.1 to 17.1.0
2021-08-09 14:18:44 +02:00
Andreas Hocevar
99fe1d1f8b Merge pull request #12612 from openlayers/dependabot/npm_and_yarn/babel/core-7.15.0
Bump @babel/core from 7.14.8 to 7.15.0
2021-08-09 14:18:13 +02:00
dependabot[bot]
5e50a23bc7 Bump webpack from 5.47.1 to 5.49.0
Bumps [webpack](https://github.com/webpack/webpack) from 5.47.1 to 5.49.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.47.1...v5.49.0)

---
updated-dependencies:
- dependency-name: webpack
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-09 12:12:37 +00:00
dependabot[bot]
9f7b8b955f Bump @babel/core from 7.14.8 to 7.15.0
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.14.8 to 7.15.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.15.0/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-09 12:12:35 +00:00
Andreas Hocevar
c328d47074 Merge pull request #12611 from openlayers/dependabot/npm_and_yarn/babel/preset-env-7.15.0
Bump @babel/preset-env from 7.14.9 to 7.15.0
2021-08-09 14:11:43 +02:00
Andreas Hocevar
3420eeca1c Merge pull request #12610 from openlayers/dependabot/npm_and_yarn/clean-css-cli-5.3.3
Bump clean-css-cli from 5.3.2 to 5.3.3
2021-08-09 14:11:09 +02:00
dependabot[bot]
1eb2f36deb Bump @babel/eslint-parser from 7.14.9 to 7.15.0
Bumps [@babel/eslint-parser](https://github.com/babel/babel/tree/HEAD/eslint/babel-eslint-parser) from 7.14.9 to 7.15.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.15.0/eslint/babel-eslint-parser)

---
updated-dependencies:
- dependency-name: "@babel/eslint-parser"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-09 10:02:31 +00:00
dependabot[bot]
1feae26489 Bump rollup from 2.56.0 to 2.56.1
Bumps [rollup](https://github.com/rollup/rollup) from 2.56.0 to 2.56.1.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v2.56.0...v2.56.1)

---
updated-dependencies:
- dependency-name: rollup
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-09 10:01:59 +00:00
dependabot[bot]
3ad04d09cc Bump puppeteer from 10.1.0 to 10.2.0
Bumps [puppeteer](https://github.com/puppeteer/puppeteer) from 10.1.0 to 10.2.0.
- [Release notes](https://github.com/puppeteer/puppeteer/releases)
- [Changelog](https://github.com/puppeteer/puppeteer/blob/main/CHANGELOG.md)
- [Commits](https://github.com/puppeteer/puppeteer/compare/v10.1.0...v10.2.0)

---
updated-dependencies:
- dependency-name: puppeteer
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-09 10:01:40 +00:00
dependabot[bot]
acd6f9b5d7 Bump yargs from 17.0.1 to 17.1.0
Bumps [yargs](https://github.com/yargs/yargs) from 17.0.1 to 17.1.0.
- [Release notes](https://github.com/yargs/yargs/releases)
- [Changelog](https://github.com/yargs/yargs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yargs/yargs/compare/v17.0.1...v17.1.0)

---
updated-dependencies:
- dependency-name: yargs
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-09 10:01:26 +00:00
dependabot[bot]
f166629dd5 Bump @babel/preset-env from 7.14.9 to 7.15.0
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.14.9 to 7.15.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.15.0/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-09 10:01:00 +00:00
dependabot[bot]
0d3526976d Bump clean-css-cli from 5.3.2 to 5.3.3
Bumps [clean-css-cli](https://github.com/clean-css/clean-css-cli) from 5.3.2 to 5.3.3.
- [Release notes](https://github.com/clean-css/clean-css-cli/releases)
- [Changelog](https://github.com/clean-css/clean-css-cli/blob/master/History.md)
- [Commits](https://github.com/clean-css/clean-css-cli/compare/v5.3.2...v5.3.3)

---
updated-dependencies:
- dependency-name: clean-css-cli
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-09 10:00:43 +00:00
Tim Schaub
3bff0f23ca Merge pull request #12608 from tschaub/more-proj-ids
Support more OGC CRS identifiers
2021-08-08 15:58:07 -06:00
Tim Schaub
08583b4a41 Add more alternative identifiers for EPSG:4326 2021-08-08 12:15:52 -06:00
Tim Schaub
73bb89f196 Add another alternative identifier for EPSG:3857 2021-08-08 12:13:19 -06:00
MoonE
22a48fe939 Merge pull request #12607 from MoonE/expression-no-color-equal-operator
Don't add color as possible type if it was not set
2021-08-08 15:40:55 +02:00
Maximilian Krög
2bcd57193d Don't add color as possible type if it was not set 2021-08-08 15:30:57 +02:00
Tim Schaub
c1f4749e4d Merge pull request #12605 from simonseyock/typings
Some typing improvements
2021-08-06 11:57:34 -06:00
Tim Schaub
687219a089 Merge pull request #12600 from simonseyock/attributions-public
Make attribution getters public.
2021-08-06 11:50:12 -06:00
Simon Seyock
f636d68cce Fix typing errors. 2021-08-06 17:14:17 +02:00
Simon Seyock
d6e0eb75fa Use Source as default parameter for Layer. 2021-08-06 17:14:17 +02:00
Simon Seyock
d7b443bf44 Make constructor pick up geometry type from properties object. 2021-08-06 17:14:17 +02:00
Simon Seyock
cebaa546b7 Feature.clone returns correct type. 2021-08-06 17:14:17 +02:00
Andreas Hocevar
f8ac74fa1b Merge pull request #12597 from mwerlitz/12596_rastersource_does_not_end_tile_transition
#12596 fix RasterSource does not end Tile transition
2021-08-05 15:19:16 +02:00
mwerlitz
aea11b773c fix whitespace error
Co-authored-by: Andreas Hocevar <andreas.hocevar@gmail.com>
2021-08-05 13:02:26 +02:00
Andreas Hocevar
022928eaa1 Merge pull request #12602 from openlayers/dependabot/npm_and_yarn/rollup-2.56.0
Bump rollup from 2.54.0 to 2.56.0
2021-08-05 12:40:17 +02:00
dependabot[bot]
dbcb5d1582 Bump rollup from 2.54.0 to 2.56.0
Bumps [rollup](https://github.com/rollup/rollup) from 2.54.0 to 2.56.0.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v2.54.0...v2.56.0)

---
updated-dependencies:
- dependency-name: rollup
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-05 10:18:03 +00:00
Simon Seyock
6ce7b58020 Make attribution getters public. 2021-08-05 11:04:33 +02:00
Andreas Hocevar
7a2b0cd2d9 Merge pull request #12583 from openlayers/dependabot/npm_and_yarn/webpack-sources-3.2.0
Bump webpack-sources from 2.3.1 to 3.2.0
2021-08-05 10:23:24 +02:00
dependabot[bot]
d938a75b53 Bump webpack-sources from 2.3.1 to 3.2.0
Bumps [webpack-sources](https://github.com/webpack/webpack-sources) from 2.3.1 to 3.2.0.
- [Release notes](https://github.com/webpack/webpack-sources/releases)
- [Commits](https://github.com/webpack/webpack-sources/compare/v2.3.1...v3.2.0)

---
updated-dependencies:
- dependency-name: webpack-sources
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-05 07:26:17 +00:00
Andreas Hocevar
7bb35422a0 Merge pull request #12599 from ahocevar/reference-image-again
Replace reference image to match that of the CI
2021-08-05 09:24:59 +02:00
Andreas Hocevar
27d915aefa Replace reference image to match that of the CI 2021-08-05 09:17:29 +02:00
Andreas Hocevar
4f38dd2c66 Merge pull request #12595 from ahocevar/null-types
Generate correct type definitions with null
2021-08-05 07:57:28 +02:00
Andreas Hocevar
e9791cf4d3 Generate correct type definitions with null 2021-08-04 14:32:36 +02:00
Andreas Hocevar
40f7140348 Merge pull request #12578 from ahocevar/update-reference-image
Update rendering test reference image
2021-08-04 13:47:04 +02:00
Mathias Werlitz
c72a31a226 #12596 fix RasterSource does not end Tile transition 2021-08-04 12:20:42 +02:00
Tim Schaub
f0bbe366f5 Merge pull request #12581 from openlayers/dependabot/npm_and_yarn/rollup/plugin-commonjs-20.0.0
Bump @rollup/plugin-commonjs from 19.0.1 to 20.0.0
2021-08-02 22:30:22 -06:00
Tim Schaub
68871eae86 Merge pull request #12582 from openlayers/dependabot/npm_and_yarn/babel/preset-env-7.14.9
Bump @babel/preset-env from 7.14.8 to 7.14.9
2021-08-02 22:24:05 -06:00
Tim Schaub
632053a4f4 Merge pull request #12585 from openlayers/dependabot/npm_and_yarn/clean-css-cli-5.3.2
Bump clean-css-cli from 5.3.0 to 5.3.2
2021-08-02 22:23:32 -06:00
Tim Schaub
c197e80bd4 Merge pull request #12584 from openlayers/dependabot/npm_and_yarn/webpack-5.47.1
Bump webpack from 5.46.0 to 5.47.1
2021-08-02 22:22:22 -06:00
Tim Schaub
470b0df16a Merge pull request #12586 from openlayers/dependabot/npm_and_yarn/babel/eslint-parser-7.14.9
Bump @babel/eslint-parser from 7.14.7 to 7.14.9
2021-08-02 22:21:17 -06:00
Tim Schaub
43a2ae29f0 Merge pull request #12588 from openlayers/dependabot/npm_and_yarn/sinon-11.1.2
Bump sinon from 11.1.1 to 11.1.2
2021-08-02 22:20:30 -06:00
Tim Schaub
e3777edac2 Merge pull request #12589 from openlayers/dependabot/npm_and_yarn/eslint-7.32.0
Bump eslint from 7.31.0 to 7.32.0
2021-08-02 22:19:56 -06:00
dependabot[bot]
7fd51b3195 Bump eslint from 7.31.0 to 7.32.0
Bumps [eslint](https://github.com/eslint/eslint) from 7.31.0 to 7.32.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v7.31.0...v7.32.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-02 10:02:55 +00:00
dependabot[bot]
444da4ab39 Bump sinon from 11.1.1 to 11.1.2
Bumps [sinon](https://github.com/sinonjs/sinon) from 11.1.1 to 11.1.2.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/master/CHANGELOG.md)
- [Commits](https://github.com/sinonjs/sinon/commits)

---
updated-dependencies:
- dependency-name: sinon
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-02 10:02:40 +00:00
dependabot[bot]
4bdd40b7e1 Bump @babel/eslint-parser from 7.14.7 to 7.14.9
Bumps [@babel/eslint-parser](https://github.com/babel/babel/tree/HEAD/eslint/babel-eslint-parser) from 7.14.7 to 7.14.9.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.14.9/eslint/babel-eslint-parser)

---
updated-dependencies:
- dependency-name: "@babel/eslint-parser"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-02 10:02:13 +00:00
dependabot[bot]
8dc9ecd4b5 Bump clean-css-cli from 5.3.0 to 5.3.2
Bumps [clean-css-cli](https://github.com/jakubpawlowicz/clean-css-cli) from 5.3.0 to 5.3.2.
- [Release notes](https://github.com/jakubpawlowicz/clean-css-cli/releases)
- [Changelog](https://github.com/clean-css/clean-css-cli/blob/master/History.md)
- [Commits](https://github.com/jakubpawlowicz/clean-css-cli/commits)

---
updated-dependencies:
- dependency-name: clean-css-cli
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-02 10:01:51 +00:00
dependabot[bot]
0c919784ae Bump webpack from 5.46.0 to 5.47.1
Bumps [webpack](https://github.com/webpack/webpack) from 5.46.0 to 5.47.1.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.46.0...v5.47.1)

---
updated-dependencies:
- dependency-name: webpack
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-02 10:01:34 +00:00
dependabot[bot]
a8e890ca3f Bump @babel/preset-env from 7.14.8 to 7.14.9
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.14.8 to 7.14.9.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.14.9/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-02 10:01:09 +00:00
dependabot[bot]
9f92628212 Bump @rollup/plugin-commonjs from 19.0.1 to 20.0.0
Bumps [@rollup/plugin-commonjs](https://github.com/rollup/plugins/tree/HEAD/packages/commonjs) from 19.0.1 to 20.0.0.
- [Release notes](https://github.com/rollup/plugins/releases)
- [Changelog](https://github.com/rollup/plugins/blob/master/packages/commonjs/CHANGELOG.md)
- [Commits](https://github.com/rollup/plugins/commits/commonjs-v20.0.0/packages/commonjs)

---
updated-dependencies:
- dependency-name: "@rollup/plugin-commonjs"
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-08-02 10:00:52 +00:00
Andreas Hocevar
36fc2c042a Update rendering test reference image 2021-08-01 11:03:47 +02:00
MoonE
f701f20eae Merge pull request #12577 from MoonE/fix-buid-site-on-windows-cmd
Use shx for the build-site script, clean before run
2021-08-01 10:36:53 +02:00
Andreas Hocevar
6bc60f9911 Merge pull request #12575 from ahocevar/raster-events
Add on(), un() and once() signatures for ol/source/Raster
2021-08-01 10:33:19 +02:00
Andreas Hocevar
ea9b2c4c41 Merge pull request #12565 from sebakerckhof/fix/12564
Handle named colors as string in equal operator
2021-08-01 10:32:06 +02:00
Andreas Hocevar
2038a93880 Add on(), un() and once() signatures for ol/source/Raster 2021-08-01 10:28:02 +02:00
Maximilian Krög
0f894a28df Use shx for the build-site script, clean before run 2021-08-01 09:55:30 +02:00
MoonE
0cc533e5d8 Merge pull request #12576 from MoonE/fix-example-and-legacy-build-with-nodejs-16-6
Fix example and legacy build with nodejs 16.6
2021-08-01 09:51:25 +02:00
Maximilian Krög
687b131714 Fix example and legacy build with nodejs 16.6 2021-08-01 01:13:26 +02:00
Seba Kerckhof
fec6fee83c Remove color from value type in equal operator 2021-07-28 09:26:29 +02:00
Seba Kerckhof
25af938a83 Update test/browser/spec/ol/style/expressions.test.js
Co-authored-by: Andreas Hocevar <andreas.hocevar@gmail.com>
2021-07-28 09:17:10 +02:00
Seba Kerckhof
db57d9bf89 Handle named colors as string in equal operator 2021-07-27 18:54:08 +02:00
Andreas Hocevar
1dc336e459 Merge pull request #12559 from openlayers/dependabot/npm_and_yarn/rollup-2.54.0
Bump rollup from 2.53.2 to 2.54.0
2021-07-26 13:26:02 +02:00
Andreas Hocevar
7749eaf953 Merge pull request #12560 from openlayers/dependabot/npm_and_yarn/babel/core-7.14.8
Bump @babel/core from 7.14.6 to 7.14.8
2021-07-26 13:25:35 +02:00
Andreas Hocevar
f9362a0825 Merge pull request #12558 from openlayers/dependabot/npm_and_yarn/webpack-dev-server-4.0.0-rc.0
Bump webpack-dev-server from 4.0.0-beta.3 to 4.0.0-rc.0
2021-07-26 13:25:00 +02:00
Andreas Hocevar
9a38a91816 Merge pull request #12556 from openlayers/dependabot/npm_and_yarn/globby-12.0.0
Bump globby from 11.0.4 to 12.0.0
2021-07-26 13:18:19 +02:00
Andreas Hocevar
de460cfb09 Change import 2021-07-26 13:13:54 +02:00
Andreas Hocevar
20240c549f Merge pull request #12555 from openlayers/dependabot/npm_and_yarn/webpack-5.46.0
Bump webpack from 5.45.1 to 5.46.0
2021-07-26 13:10:59 +02:00
dependabot[bot]
9986e6d0c0 Bump webpack from 5.45.1 to 5.46.0
Bumps [webpack](https://github.com/webpack/webpack) from 5.45.1 to 5.46.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.45.1...v5.46.0)

---
updated-dependencies:
- dependency-name: webpack
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-26 10:19:25 +00:00
dependabot[bot]
310eeea207 Bump rollup from 2.53.2 to 2.54.0
Bumps [rollup](https://github.com/rollup/rollup) from 2.53.2 to 2.54.0.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v2.53.2...v2.54.0)

---
updated-dependencies:
- dependency-name: rollup
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-26 10:18:44 +00:00
Andreas Hocevar
498721ff57 Merge pull request #12554 from openlayers/dependabot/npm_and_yarn/mocha-9.0.3
Bump mocha from 9.0.2 to 9.0.3
2021-07-26 12:12:54 +02:00
Andreas Hocevar
a86cfcc3be Merge pull request #12553 from openlayers/dependabot/npm_and_yarn/babel/preset-env-7.14.8
Bump @babel/preset-env from 7.14.7 to 7.14.8
2021-07-26 12:12:23 +02:00
Andreas Hocevar
2c3851b541 Merge pull request #12552 from openlayers/dependabot/npm_and_yarn/rollup/plugin-node-resolve-13.0.4
Bump @rollup/plugin-node-resolve from 13.0.2 to 13.0.4
2021-07-26 12:11:53 +02:00
Andreas Hocevar
55fb897f88 Merge pull request #12551 from M393/add-wkb-to-ol-format
Add WKB to the exports of ol/format
2021-07-26 12:10:46 +02:00
dependabot[bot]
8baba070d5 Bump @babel/core from 7.14.6 to 7.14.8
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.14.6 to 7.14.8.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.14.8/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-26 10:03:08 +00:00
dependabot[bot]
14eaaac976 Bump webpack-dev-server from 4.0.0-beta.3 to 4.0.0-rc.0
Bumps [webpack-dev-server](https://github.com/webpack/webpack-dev-server) from 4.0.0-beta.3 to 4.0.0-rc.0.
- [Release notes](https://github.com/webpack/webpack-dev-server/releases)
- [Changelog](https://github.com/webpack/webpack-dev-server/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack-dev-server/compare/v4.0.0-beta.3...v4.0.0-rc.0)

---
updated-dependencies:
- dependency-name: webpack-dev-server
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-26 10:02:18 +00:00
dependabot[bot]
16f8e1be7a Bump globby from 11.0.4 to 12.0.0
Bumps [globby](https://github.com/sindresorhus/globby) from 11.0.4 to 12.0.0.
- [Release notes](https://github.com/sindresorhus/globby/releases)
- [Commits](https://github.com/sindresorhus/globby/compare/v11.0.4...v12.0.0)

---
updated-dependencies:
- dependency-name: globby
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-26 10:01:41 +00:00
dependabot[bot]
9a883f5a73 Bump mocha from 9.0.2 to 9.0.3
Bumps [mocha](https://github.com/mochajs/mocha) from 9.0.2 to 9.0.3.
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v9.0.2...v9.0.3)

---
updated-dependencies:
- dependency-name: mocha
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-26 10:01:12 +00:00
dependabot[bot]
a9b9bb34fa Bump @babel/preset-env from 7.14.7 to 7.14.8
Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.14.7 to 7.14.8.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.14.8/packages/babel-preset-env)

---
updated-dependencies:
- dependency-name: "@babel/preset-env"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-26 10:01:00 +00:00
dependabot[bot]
b05d4d9cad Bump @rollup/plugin-node-resolve from 13.0.2 to 13.0.4
Bumps [@rollup/plugin-node-resolve](https://github.com/rollup/plugins/tree/HEAD/packages/node-resolve) from 13.0.2 to 13.0.4.
- [Release notes](https://github.com/rollup/plugins/releases)
- [Changelog](https://github.com/rollup/plugins/blob/master/packages/node-resolve/CHANGELOG.md)
- [Commits](https://github.com/rollup/plugins/commits/node-resolve-v13.0.4/packages/node-resolve)

---
updated-dependencies:
- dependency-name: "@rollup/plugin-node-resolve"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-26 10:00:45 +00:00
Maximilian Krög
e50d5a2197 Add WKB to the exports of ol/format 2021-07-26 09:24:52 +02:00
Andreas Hocevar
0b941e01d9 Merge pull request #12550 from simonseyock/example-grid-tag
Add `grid` tag to examples.
2021-07-23 14:13:42 +02:00
Andreas Hocevar
65742a22f9 Merge pull request #12549 from simonseyock/group-layer-event
Add `change:layers` event.
2021-07-23 14:12:52 +02:00
Simon Seyock
2e054aea4d Add grid tag to examples. 2021-07-23 13:15:51 +02:00
Simon Seyock
bf9ca7f3d1 Add change:layers event. 2021-07-23 13:03:57 +02:00
Andreas Hocevar
82956aaf5e Merge pull request #12545 from ahocevar/proj4-axis
Restore simple axis order handling with fixed proj4
2021-07-22 18:46:20 +02:00
Andreas Hocevar
eb39f59713 Merge pull request #12544 from ahocevar/raster-image-generics
Make Raster source work as generics type for Image layer
2021-07-22 18:45:36 +02:00
Andreas Hocevar
a5a156525f Restore simple axis order handling with fixed proj4 2021-07-22 14:20:55 +02:00
Andreas Hocevar
a26fe5f31b Make Raster source work as generics type for Image layer 2021-07-22 12:57:39 +02:00
Andreas Hocevar
8004e0faad Merge pull request #12527 from mike-000/patch-1
Treat custom loaders without success/fail handling as if they were a void loader
2021-07-22 12:39:21 +02:00
Tim Schaub
c640457501 Merge pull request #12538 from tschaub/lazy-doc
Avoid creating context until needed
2021-07-21 07:41:26 -06:00
Tim Schaub
adff6f0e77 Avoid creating context until needed 2021-07-19 09:08:21 -06:00
Tim Schaub
58b7faed55 Merge pull request #12536 from openlayers/dependabot/npm_and_yarn/rollup-2.53.2
Bump rollup from 2.53.1 to 2.53.2
2021-07-19 09:08:10 -06:00
dependabot[bot]
48321a47d7 Bump rollup from 2.53.1 to 2.53.2
Bumps [rollup](https://github.com/rollup/rollup) from 2.53.1 to 2.53.2.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rollup/rollup/compare/v2.53.1...v2.53.2)

---
updated-dependencies:
- dependency-name: rollup
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-19 14:59:00 +00:00
Tim Schaub
dc93933973 Merge pull request #12537 from openlayers/dependabot/npm_and_yarn/rollup/plugin-node-resolve-13.0.2
Bump @rollup/plugin-node-resolve from 13.0.0 to 13.0.2
2021-07-19 08:58:14 -06:00
Tim Schaub
695fee9d3c Merge pull request #12535 from openlayers/dependabot/npm_and_yarn/webpack-5.45.1
Bump webpack from 5.44.0 to 5.45.1
2021-07-19 08:57:40 -06:00
Tim Schaub
9c2852bb7c Merge pull request #12534 from openlayers/dependabot/npm_and_yarn/eslint-7.31.0
Bump eslint from 7.30.0 to 7.31.0
2021-07-19 08:56:46 -06:00
Tim Schaub
408dace5c9 Merge pull request #12533 from openlayers/dependabot/npm_and_yarn/rollup/plugin-commonjs-19.0.1
Bump @rollup/plugin-commonjs from 19.0.0 to 19.0.1
2021-07-19 08:55:38 -06:00
dependabot[bot]
a32113afbf Bump @rollup/plugin-node-resolve from 13.0.0 to 13.0.2
Bumps [@rollup/plugin-node-resolve](https://github.com/rollup/plugins/tree/HEAD/packages/node-resolve) from 13.0.0 to 13.0.2.
- [Release notes](https://github.com/rollup/plugins/releases)
- [Changelog](https://github.com/rollup/plugins/blob/master/packages/node-resolve/CHANGELOG.md)
- [Commits](https://github.com/rollup/plugins/commits/node-resolve-v13.0.2/packages/node-resolve)

---
updated-dependencies:
- dependency-name: "@rollup/plugin-node-resolve"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-19 10:02:13 +00:00
dependabot[bot]
a81a2120e3 Bump webpack from 5.44.0 to 5.45.1
Bumps [webpack](https://github.com/webpack/webpack) from 5.44.0 to 5.45.1.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.44.0...v5.45.1)

---
updated-dependencies:
- dependency-name: webpack
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-19 10:01:31 +00:00
dependabot[bot]
8b3494a585 Bump eslint from 7.30.0 to 7.31.0
Bumps [eslint](https://github.com/eslint/eslint) from 7.30.0 to 7.31.0.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/eslint/eslint/compare/v7.30.0...v7.31.0)

---
updated-dependencies:
- dependency-name: eslint
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-19 10:01:14 +00:00
dependabot[bot]
822b967a9c Bump @rollup/plugin-commonjs from 19.0.0 to 19.0.1
Bumps [@rollup/plugin-commonjs](https://github.com/rollup/plugins/tree/HEAD/packages/commonjs) from 19.0.0 to 19.0.1.
- [Release notes](https://github.com/rollup/plugins/releases)
- [Changelog](https://github.com/rollup/plugins/blob/master/packages/commonjs/CHANGELOG.md)
- [Commits](https://github.com/rollup/plugins/commits/commonjs-v19.0.1/packages/commonjs)

---
updated-dependencies:
- dependency-name: "@rollup/plugin-commonjs"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-07-19 10:00:50 +00:00
MoonE
f1530364dd Merge pull request #12528 from MoonE/hit-detect-priority-test
Convert the hit tolerance priority example into a test
2021-07-17 17:49:21 +02:00
Maximilian Krög
19fb51183e Convert hit detect priority example to test 2021-07-17 15:09:38 +02:00
mike-000
6c862df03f include custom loader in rendercomplete test
include a VectorSource with custom loader (no success/fail handling) in rendercomplete test
2021-07-17 12:56:33 +01:00
mike-000
431beed45f Handle custom loaders without success/fail
Treat custom loaders without success/fail handling as if the were VOID
2021-07-16 20:44:03 +01:00
Tim Schaub
e8047f6d08 Merge pull request #12522 from tschaub/create-cluster
Shorter name for the option to create a custom cluster
2021-07-16 10:47:31 -06:00
Tim Schaub
1b9329ea91 Shorter name for the option to create a custom cluster 2021-07-15 21:35:59 -06:00
Andreas Hocevar
a617ef3caf Merge pull request #12506 from M393/fix-ol-ext-bar
Fix adding controls with map config
2021-07-15 18:33:26 +02:00
Maximilian Krög
8f8027c33a Fix adding controls with map config
If a control like ol.control.Bar adds sub controls when added to a map
it fails during map creating because the listeners are added after the control
was added to the map.
2021-07-15 14:19:08 +02:00
Maximilian Krög
5d7f7dbf51 Add test for subcontrol added during map contruction 2021-07-15 14:19:08 +02:00
Andreas Hocevar
10e38947cc Merge pull request #12487 from Razi91/cluster-feature-fn
Custom cluster feature creation function
2021-07-15 11:30:46 +02:00
Andreas Hocevar
94d0b85fde Merge pull request #12520 from ahocevar/release-notes-typo
Fix typo in changelog
2021-07-15 11:25:11 +02:00
Andreas Hocevar
5dd9836546 Fix typo in changelog 2021-07-15 11:24:32 +02:00
Andreas Hocevar
9f5da8cd76 Merge pull request #12519 from openlayers/release-v6.6.1
Release v6.6.1
2021-07-15 11:21:52 +02:00
Andreas Hocevar
1b2512d013 Develop on 6.6.2-dev 2021-07-15 11:16:58 +02:00
jkonieczny
e1b161bbbe remove setter/getter 2021-07-15 09:06:13 +02:00
jkonieczny
a8f7d955af rename to createClusterFeature 2021-07-13 17:27:32 +02:00
jkonieczny
9fd25dddbf allow hydrating clustered features 2021-07-12 19:28:00 +02:00
133 changed files with 7466 additions and 1265 deletions

View File

@@ -1,6 +1,8 @@
## Upgrade notes
### Next version
### v6.7.0
There should be nothing special required when upgrading from v6.6 to v6.7.
### v6.6.0

View File

@@ -1,4 +1,4 @@
# 6.4.1
# 6.6.1
This is a bugfix release which brings improvements to the included TypeScript types, and fixes two minor issues with the Draw interaction and hit detection of regular shape symbols.

121
changelog/v6.7.0.md Normal file
View File

@@ -0,0 +1,121 @@
# 6.7.0
The 6.7 release includes a great batch of usability improvements, fixes, and new features. See the full list of changes from 100 pull requests below, but here are some highlights:
* New GeoTIFF source! With parsing support from the awesome [geotiff.js](https://geotiffjs.github.io/) library, you can now render layers from hosted GeoTIFF imagery. The GeoTIFF source gives you the ability to pull from multiple GeoTIFF images, read from arbitrary bands, run band math expressions, and style the imagery to your liking.
* New WebGL tile renderer. The GeoTIFF source is rendered with a new WebGL-based tile renderer. In addition to GeoTIFFs, the renderer supports layers with a generic DataTile source  these can be used to render aribtrary raster data and leverage the same style expressions as described above.
* More type checking. We continue to make improvements to the TypeScript definitions included in the `ol` package.
* New sources supporting the draft [OGC API - Tiles](https://ogcapi.ogc.org/tiles/) specification. The OGCMapTile and OGCVectorTile sources allow you to render data from services that implement the draft OGC tiles spec. Since the specification is not yet final, these sources are not yet part of the stable OpenLayers API and should be considered experimental.
* Custom cluster creation support, improved KML icon rendering, lots of fixes, and more. See below for all the detail.
## List of all changes
* [#12727](https://github.com/openlayers/openlayers/pull/12727) - Add missing 'boxstart' event to OnSignature ([@simonseyock](https://github.com/simonseyock))
* [#12718](https://github.com/openlayers/openlayers/pull/12718) - Rename function to avoid minification failure ([@tschaub](https://github.com/tschaub))
* [#12712](https://github.com/openlayers/openlayers/pull/12712) - Add convertToRGB option to GeoTIFF source ([@ahocevar](https://github.com/ahocevar))
* [#12716](https://github.com/openlayers/openlayers/pull/12716) - Spelling fix ([@fredj](https://github.com/fredj))
* [#12715](https://github.com/openlayers/openlayers/pull/12715) - Try harder to get the projection from GeoTIFF headers ([@tschaub](https://github.com/tschaub))
* [#12714](https://github.com/openlayers/openlayers/pull/12714) - Avoid creating duplicate projections in COG examples ([@tschaub](https://github.com/tschaub))
* [#12713](https://github.com/openlayers/openlayers/pull/12713) - Check for GeoTIFF CRS starting with last image ([@tschaub](https://github.com/tschaub))
* [#12709](https://github.com/openlayers/openlayers/pull/12709) - Support rendering of GeoTIFF images in pixel coordinates ([@tschaub](https://github.com/tschaub))
* [#12711](https://github.com/openlayers/openlayers/pull/12711) - Use band numbers starting with one ([@tschaub](https://github.com/tschaub))
* [#12710](https://github.com/openlayers/openlayers/pull/12710) - Spelling fix in GeoTIFF docs ([@tschaub](https://github.com/tschaub))
* [#12697](https://github.com/openlayers/openlayers/pull/12697) - Move description above type tag ([@tschaub](https://github.com/tschaub))
* [#12695](https://github.com/openlayers/openlayers/pull/12695) - Update Google KML icon anchors and correct icon scaling ([@mike-000](https://github.com/mike-000))
* [#12642](https://github.com/openlayers/openlayers/pull/12642) - Fix fullscreen in mapbox-style example ([@ahocevar](https://github.com/ahocevar))
* [#12624](https://github.com/openlayers/openlayers/pull/12624) - Improve API docs for optional properties ([@ahocevar](https://github.com/ahocevar))
* [#10963](https://github.com/openlayers/openlayers/pull/10963) - OGC map and vector tile sources ([@tschaub](https://github.com/tschaub))
* [#12690](https://github.com/openlayers/openlayers/pull/12690) - Fix return stride of forEachSegment ([@ahocevar](https://github.com/ahocevar))
* [#12684](https://github.com/openlayers/openlayers/pull/12684) - Fix view resolutions in example ([@mike-000](https://github.com/mike-000))
* [#12683](https://github.com/openlayers/openlayers/pull/12683) - Fix sprite offset for pixel ratio !== 1 ([@ahocevar](https://github.com/ahocevar))
* [#12671](https://github.com/openlayers/openlayers/pull/12671) - Configure cache on the layer instead of the source ([@tschaub](https://github.com/tschaub))
* [#12669](https://github.com/openlayers/openlayers/pull/12669) - Add opaque and transition options to GeoTIFF source ([@ahocevar](https://github.com/ahocevar))
* [#12667](https://github.com/openlayers/openlayers/pull/12667) - Additional docs and type checking for raster source ([@tschaub](https://github.com/tschaub))
* [#12666](https://github.com/openlayers/openlayers/pull/12666) - Re-add accidently removed events ([@ahocevar](https://github.com/ahocevar))
* [#12647](https://github.com/openlayers/openlayers/pull/12647) - Remove Translate option conflicts and update documentation ([@mike-000](https://github.com/mike-000))
* [#12008](https://github.com/openlayers/openlayers/pull/12008) - Rendering raster tiles with WebGL ([@tschaub](https://github.com/tschaub))
* [#12632](https://github.com/openlayers/openlayers/pull/12632) - Only warn of zero size when map should be visible ([@mike-000](https://github.com/mike-000))
* [#12626](https://github.com/openlayers/openlayers/pull/12626) - Set canvas style to override problem 3rd party css ([@mike-000](https://github.com/mike-000))
* [#12608](https://github.com/openlayers/openlayers/pull/12608) - Support more OGC CRS identifiers ([@tschaub](https://github.com/tschaub))
* [#12607](https://github.com/openlayers/openlayers/pull/12607) - Don't add color as possible type if it was not set ([@MoonE](https://github.com/MoonE))
* [#12605](https://github.com/openlayers/openlayers/pull/12605) - Some typing improvements ([@simonseyock](https://github.com/simonseyock))
* [#12600](https://github.com/openlayers/openlayers/pull/12600) - Make attribution getters public. ([@simonseyock](https://github.com/simonseyock))
* [#12597](https://github.com/openlayers/openlayers/pull/12597) - #12596 fix RasterSource does not end Tile transition ([@mwerlitz](https://github.com/mwerlitz))
* [#12599](https://github.com/openlayers/openlayers/pull/12599) - Replace reference image to match that of the CI ([@ahocevar](https://github.com/ahocevar))
* [#12595](https://github.com/openlayers/openlayers/pull/12595) - Generate correct type definitions with null ([@ahocevar](https://github.com/ahocevar))
* [#12578](https://github.com/openlayers/openlayers/pull/12578) - Update rendering test reference image ([@ahocevar](https://github.com/ahocevar))
* [#12577](https://github.com/openlayers/openlayers/pull/12577) - Use shx for the build-site script, clean before run ([@MoonE](https://github.com/MoonE))
* [#12575](https://github.com/openlayers/openlayers/pull/12575) - Add on(), un() and once() signatures for ol/source/Raster ([@ahocevar](https://github.com/ahocevar))
* [#12565](https://github.com/openlayers/openlayers/pull/12565) - Handle named colors as string in equal operator ([@sebakerckhof](https://github.com/sebakerckhof))
* [#12576](https://github.com/openlayers/openlayers/pull/12576) - Fix example and legacy build with nodejs 16.6 ([@MoonE](https://github.com/MoonE))
* [#12551](https://github.com/openlayers/openlayers/pull/12551) - Add WKB to the exports of ol/format ([@M393](https://github.com/M393))
* [#12550](https://github.com/openlayers/openlayers/pull/12550) - Add `grid` tag to examples. ([@simonseyock](https://github.com/simonseyock))
* [#12549](https://github.com/openlayers/openlayers/pull/12549) - Add `change:layers` event. ([@simonseyock](https://github.com/simonseyock))
* [#12545](https://github.com/openlayers/openlayers/pull/12545) - Restore simple axis order handling with fixed proj4 ([@ahocevar](https://github.com/ahocevar))
* [#12544](https://github.com/openlayers/openlayers/pull/12544) - Make Raster source work as generics type for Image layer ([@ahocevar](https://github.com/ahocevar))
* [#12527](https://github.com/openlayers/openlayers/pull/12527) - Treat custom loaders without success/fail handling as if they were a void loader ([@mike-000](https://github.com/mike-000))
* [#12538](https://github.com/openlayers/openlayers/pull/12538) - Avoid creating context until needed ([@tschaub](https://github.com/tschaub))
* [#12528](https://github.com/openlayers/openlayers/pull/12528) - Convert the hit tolerance priority example into a test ([@MoonE](https://github.com/MoonE))
* [#12522](https://github.com/openlayers/openlayers/pull/12522) - Shorter name for the option to create a custom cluster ([@tschaub](https://github.com/tschaub))
* [#12506](https://github.com/openlayers/openlayers/pull/12506) - Fix adding controls with map config ([@M393](https://github.com/M393))
* [#12487](https://github.com/openlayers/openlayers/pull/12487) - Custom cluster feature creation function ([@Razi91](https://github.com/Razi91))
* [#12520](https://github.com/openlayers/openlayers/pull/12520) - Fix typo in changelog ([@ahocevar](https://github.com/ahocevar))
* [#12519](https://github.com/openlayers/openlayers/pull/12519) - Release v6.6.1 ([@openlayers](https://github.com/openlayers))
<details>
<summary>Dependency Updates</summary>
* [#12703](https://github.com/openlayers/openlayers/pull/12703) - Bump terser-webpack-plugin from 5.1.4 to 5.2.3 ([@openlayers](https://github.com/openlayers))
* [#12704](https://github.com/openlayers/openlayers/pull/12704) - Bump @babel/eslint-parser from 7.15.0 to 7.15.4 ([@openlayers](https://github.com/openlayers))
* [#12705](https://github.com/openlayers/openlayers/pull/12705) - Bump webpack from 5.51.1 to 5.52.0 ([@openlayers](https://github.com/openlayers))
* [#12706](https://github.com/openlayers/openlayers/pull/12706) - Bump webpack-dev-server from 4.0.0 to 4.1.0 ([@openlayers](https://github.com/openlayers))
* [#12707](https://github.com/openlayers/openlayers/pull/12707) - Bump @babel/core from 7.15.0 to 7.15.5 ([@openlayers](https://github.com/openlayers))
* [#12702](https://github.com/openlayers/openlayers/pull/12702) - Bump @babel/preset-env from 7.15.0 to 7.15.4 ([@openlayers](https://github.com/openlayers))
* [#12677](https://github.com/openlayers/openlayers/pull/12677) - Bump marked from 3.0.0 to 3.0.2 ([@openlayers](https://github.com/openlayers))
* [#12678](https://github.com/openlayers/openlayers/pull/12678) - Bump globby from 12.0.1 to 12.0.2 ([@openlayers](https://github.com/openlayers))
* [#12679](https://github.com/openlayers/openlayers/pull/12679) - Bump mocha from 9.1.0 to 9.1.1 ([@openlayers](https://github.com/openlayers))
* [#12657](https://github.com/openlayers/openlayers/pull/12657) - Bump mocha from 9.0.3 to 9.1.0 ([@openlayers](https://github.com/openlayers))
* [#12650](https://github.com/openlayers/openlayers/pull/12650) - Bump webpack from 5.50.0 to 5.51.1 ([@openlayers](https://github.com/openlayers))
* [#12654](https://github.com/openlayers/openlayers/pull/12654) - Bump webpack-dev-server from 4.0.0-rc.0 to 4.0.0 ([@openlayers](https://github.com/openlayers))
* [#12653](https://github.com/openlayers/openlayers/pull/12653) - Bump globby from 12.0.0 to 12.0.1 ([@openlayers](https://github.com/openlayers))
* [#12652](https://github.com/openlayers/openlayers/pull/12652) - Bump loglevelnext from 5.0.5 to 5.0.6 ([@openlayers](https://github.com/openlayers))
* [#12651](https://github.com/openlayers/openlayers/pull/12651) - Bump rollup from 2.56.2 to 2.56.3 ([@openlayers](https://github.com/openlayers))
* [#12627](https://github.com/openlayers/openlayers/pull/12627) - Bump webpack-cli from 4.7.2 to 4.8.0 ([@openlayers](https://github.com/openlayers))
* [#12631](https://github.com/openlayers/openlayers/pull/12631) - Bump marked from 2.1.3 to 3.0.0 ([@openlayers](https://github.com/openlayers))
* [#12630](https://github.com/openlayers/openlayers/pull/12630) - Bump webpack from 5.49.0 to 5.50.0 ([@openlayers](https://github.com/openlayers))
* [#12629](https://github.com/openlayers/openlayers/pull/12629) - Bump yargs from 17.1.0 to 17.1.1 ([@openlayers](https://github.com/openlayers))
* [#12628](https://github.com/openlayers/openlayers/pull/12628) - Bump rollup from 2.56.1 to 2.56.2 ([@openlayers](https://github.com/openlayers))
* [#12616](https://github.com/openlayers/openlayers/pull/12616) - Bump webpack from 5.47.1 to 5.49.0 ([@openlayers](https://github.com/openlayers))
* [#12617](https://github.com/openlayers/openlayers/pull/12617) - Bump @babel/eslint-parser from 7.14.9 to 7.15.0 ([@openlayers](https://github.com/openlayers))
* [#12615](https://github.com/openlayers/openlayers/pull/12615) - Bump rollup from 2.56.0 to 2.56.1 ([@openlayers](https://github.com/openlayers))
* [#12614](https://github.com/openlayers/openlayers/pull/12614) - Bump puppeteer from 10.1.0 to 10.2.0 ([@openlayers](https://github.com/openlayers))
* [#12613](https://github.com/openlayers/openlayers/pull/12613) - Bump yargs from 17.0.1 to 17.1.0 ([@openlayers](https://github.com/openlayers))
* [#12612](https://github.com/openlayers/openlayers/pull/12612) - Bump @babel/core from 7.14.8 to 7.15.0 ([@openlayers](https://github.com/openlayers))
* [#12611](https://github.com/openlayers/openlayers/pull/12611) - Bump @babel/preset-env from 7.14.9 to 7.15.0 ([@openlayers](https://github.com/openlayers))
* [#12610](https://github.com/openlayers/openlayers/pull/12610) - Bump clean-css-cli from 5.3.2 to 5.3.3 ([@openlayers](https://github.com/openlayers))
* [#12602](https://github.com/openlayers/openlayers/pull/12602) - Bump rollup from 2.54.0 to 2.56.0 ([@openlayers](https://github.com/openlayers))
* [#12583](https://github.com/openlayers/openlayers/pull/12583) - Bump webpack-sources from 2.3.1 to 3.2.0 ([@openlayers](https://github.com/openlayers))
* [#12581](https://github.com/openlayers/openlayers/pull/12581) - Bump @rollup/plugin-commonjs from 19.0.1 to 20.0.0 ([@openlayers](https://github.com/openlayers))
* [#12582](https://github.com/openlayers/openlayers/pull/12582) - Bump @babel/preset-env from 7.14.8 to 7.14.9 ([@openlayers](https://github.com/openlayers))
* [#12585](https://github.com/openlayers/openlayers/pull/12585) - Bump clean-css-cli from 5.3.0 to 5.3.2 ([@openlayers](https://github.com/openlayers))
* [#12584](https://github.com/openlayers/openlayers/pull/12584) - Bump webpack from 5.46.0 to 5.47.1 ([@openlayers](https://github.com/openlayers))
* [#12586](https://github.com/openlayers/openlayers/pull/12586) - Bump @babel/eslint-parser from 7.14.7 to 7.14.9 ([@openlayers](https://github.com/openlayers))
* [#12588](https://github.com/openlayers/openlayers/pull/12588) - Bump sinon from 11.1.1 to 11.1.2 ([@openlayers](https://github.com/openlayers))
* [#12589](https://github.com/openlayers/openlayers/pull/12589) - Bump eslint from 7.31.0 to 7.32.0 ([@openlayers](https://github.com/openlayers))
* [#12559](https://github.com/openlayers/openlayers/pull/12559) - Bump rollup from 2.53.2 to 2.54.0 ([@openlayers](https://github.com/openlayers))
* [#12560](https://github.com/openlayers/openlayers/pull/12560) - Bump @babel/core from 7.14.6 to 7.14.8 ([@openlayers](https://github.com/openlayers))
* [#12558](https://github.com/openlayers/openlayers/pull/12558) - Bump webpack-dev-server from 4.0.0-beta.3 to 4.0.0-rc.0 ([@openlayers](https://github.com/openlayers))
* [#12556](https://github.com/openlayers/openlayers/pull/12556) - Bump globby from 11.0.4 to 12.0.0 ([@openlayers](https://github.com/openlayers))
* [#12555](https://github.com/openlayers/openlayers/pull/12555) - Bump webpack from 5.45.1 to 5.46.0 ([@openlayers](https://github.com/openlayers))
* [#12554](https://github.com/openlayers/openlayers/pull/12554) - Bump mocha from 9.0.2 to 9.0.3 ([@openlayers](https://github.com/openlayers))
* [#12553](https://github.com/openlayers/openlayers/pull/12553) - Bump @babel/preset-env from 7.14.7 to 7.14.8 ([@openlayers](https://github.com/openlayers))
* [#12552](https://github.com/openlayers/openlayers/pull/12552) - Bump @rollup/plugin-node-resolve from 13.0.2 to 13.0.4 ([@openlayers](https://github.com/openlayers))
* [#12536](https://github.com/openlayers/openlayers/pull/12536) - Bump rollup from 2.53.1 to 2.53.2 ([@openlayers](https://github.com/openlayers))
* [#12537](https://github.com/openlayers/openlayers/pull/12537) - Bump @rollup/plugin-node-resolve from 13.0.0 to 13.0.2 ([@openlayers](https://github.com/openlayers))
* [#12535](https://github.com/openlayers/openlayers/pull/12535) - Bump webpack from 5.44.0 to 5.45.1 ([@openlayers](https://github.com/openlayers))
* [#12534](https://github.com/openlayers/openlayers/pull/12534) - Bump eslint from 7.30.0 to 7.31.0 ([@openlayers](https://github.com/openlayers))
* [#12533](https://github.com/openlayers/openlayers/pull/12533) - Bump @rollup/plugin-commonjs from 19.0.0 to 19.0.1 ([@openlayers](https://github.com/openlayers))
</details>

View File

@@ -27,7 +27,8 @@
<a href="module-ol_layer_Tile-TileLayer.html">ol/layer/Tile</a><br>
<a href="module-ol_layer_Image-ImageLayer.html">ol/layer/Image</a><br>
<a href="module-ol_layer_Vector-VectorLayer.html">ol/layer/Vector</a><br>
<a href="module-ol_layer_VectorTile-VectorTileLayer.html">ol/layer/VectorTile</a>
<a href="module-ol_layer_VectorTile-VectorTileLayer.html">ol/layer/VectorTile</a><br>
<a href="module-ol_layer_WebGLTile-WebGLTileLayer.html">ol/layer/WebGLTile</a>
</div>
</div>
</div>
@@ -58,7 +59,7 @@
<div class="card h-100 bg-light">
<div class="card-body">
<h4 class="card-title">Sources and formats</h4>
<a href="module-ol_source_Tile-TileSource.html">Tile sources</a> for <a href="module-ol_layer_Tile-TileLayer.html">ol/layer/Tile</a>
<a href="module-ol_source_Tile-TileSource.html">Tile sources</a> for <a href="module-ol_layer_Tile-TileLayer.html">ol/layer/Tile</a> or <a href="module-ol_layer_WebGLTile-WebGLTileLayer.html">ol/layer/WebGLTile</a>
<br><a href="module-ol_source_Image-ImageSource.html">Image sources</a> for <a href="module-ol_layer_Image-ImageLayer.html">ol/layer/Image</a>
<br><a href="module-ol_source_Vector-VectorSource.html">Vector sources</a> for <a href="module-ol_layer_Vector-VectorLayer.html">ol/layer/Vector</a>
<br><a href="module-ol_source_VectorTile-VectorTile.html">Vector tile sources</a> for <a href="module-ol_layer_VectorTile-VectorTileLayer.html">ol/layer/VectorTile</a>
@@ -71,7 +72,7 @@
<div class="card h-100 bg-light">
<div class="card-body">
<h4 class="card-title">Projections</h4>
<p>All coordinates and extents need to be provided in view projection (default: EPSG:3857). To transform, use <a href="module-ol_proj.html#.transform">ol/proj#transform()</a> and <a href="module-ol_proj.html#.transformExtent">ol/proj#transformExtent()</a>.</p>
<p>All coordinates and extents need to be provided in view projection (default: EPSG:3857). To transform coordinates from and to geographic, use <a href="module-ol_proj.html#.fromLonLat">ol/proj#fromLonLat()</a> and <a href="module-ol_proj.html#.toLonLat">ol/proj#toLonLat()</a>. For extents and other projections, use <a href="module-ol_proj.html#.transformExtent">ol/proj#transformExtent()</a> and <a href="module-ol_proj.html#.transform">ol/proj#transform()</a>.<p>
<a href="module-ol_proj.html">ol/proj</a>
</div>
</div>

View File

@@ -70,7 +70,7 @@
<?js if (!param.subparams) {?>
<td class="type">
<?js if (param.type && param.type.names) {?>
<?js= self.partial('type.tmpl', param.type.names) ?>
<?js= self.partial('type.tmpl', param.type.names) + (param.optional && typeof param.defaultvalue === 'undefined' && param.type.names.indexOf('undefined') === -1 ? ' | undefined' : '') ?>
<?js if (typeof param.defaultvalue !== 'undefined') { ?>
(defaults to <?js= self.htmlsafe(param.defaultvalue) ?>)
<?js } ?>

View File

@@ -23,7 +23,7 @@
/* Strict Type-Checking Options */
"strict": false, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
"strictNullChecks": true, /* Enable strict null checks. */
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */

View File

@@ -32,6 +32,11 @@ export default {
],
},
resolve: {
fallback: {
fs: false,
http: false,
https: false,
},
alias: {
ol: path.resolve('./build/ol'),
},

View File

@@ -0,0 +1,13 @@
---
layout: example.html
title: NDVI+NDWI from two 16-bit COGs
shortdesc: Calculating NDVI+NDWI as green and blue values.
docs: >
The GeoTIFF layer in this example calculates the Normalized Difference Vegetation Index (NDVI)
and Normalized Difference Water Index (NDWI) from two cloud-optimized Sentinel 2 GeoTIFFs: one
with 10 m resolution and red and a near infrared bands, and one with 60 m resolution and a short
wave infrared channel. The NDVI is shown as green, the NDWI as blue. The 4th band is the alpha
band, which gets added when a source has a `nodata` value configured.
tags: "cog, ndvi, ndwi, sentinel, geotiff"
---
<div id="map" class="map"></div>

View File

@@ -0,0 +1,65 @@
import GeoTIFF from '../src/ol/source/GeoTIFF.js';
import Map from '../src/ol/Map.js';
import TileLayer from '../src/ol/layer/WebGLTile.js';
import View from '../src/ol/View.js';
const source = new GeoTIFF({
sources: [
{
url: 'https://s2downloads.eox.at/demo/Sentinel-2/3857/R10m.tif',
bands: [3, 4],
min: 0,
nodata: 0,
max: 65535,
},
{
url: 'https://s2downloads.eox.at/demo/Sentinel-2/3857/R60m.tif',
bands: [9],
min: 0,
nodata: 0,
max: 65535,
},
],
});
source.setAttributions(
"<a href='https://s2maps.eu'>Sentinel-2 cloudless</a> by <a href='https://eox.at/'>EOX IT Services GmbH</a> (Contains modified Copernicus Sentinel data 2019)"
);
const ndvi = [
'/',
['-', ['band', 2], ['band', 1]],
['+', ['band', 2], ['band', 1]],
];
const ndwi = [
'/',
['-', ['band', 3], ['band', 1]],
['+', ['band', 3], ['band', 1]],
];
const map = new Map({
target: 'map',
layers: [
new TileLayer({
style: {
color: [
'color',
// red: | NDVI - NDWI |
['*', 255, ['abs', ['-', ndvi, ndwi]]],
// green: NDVI
['*', 255, ndvi],
// blue: NDWI
['*', 255, ndwi],
// alpha
['band', 4],
],
},
source,
}),
],
view: new View({
center: [1900000, 6100000],
zoom: 13,
minZoom: 10,
}),
});

11
examples/cog-math.html Normal file
View File

@@ -0,0 +1,11 @@
---
layout: example.html
title: NDVI from a Sentinel 2 COG
shortdesc: Calculating NDVI and applying a custom color map.
docs: >
The GeoTIFF layer in this example draws from two Sentinel 2 sources: a red band and a near infrared band.
The layer style includes a `color` expression that calculates the Normalized Difference Vegetation Index (NDVI)
from values in the two bands. The `interpolate` expression is used to map NDVI values to colors.
tags: "cog, ndvi"
---
<div id="map" class="map"></div>

95
examples/cog-math.js Normal file
View File

@@ -0,0 +1,95 @@
import GeoTIFF from '../src/ol/source/GeoTIFF.js';
import Map from '../src/ol/Map.js';
import TileLayer from '../src/ol/layer/WebGLTile.js';
import View from '../src/ol/View.js';
import proj4 from 'proj4';
import {getCenter} from '../src/ol/extent.js';
import {register} from '../src/ol/proj/proj4.js';
proj4.defs('EPSG:32636', '+proj=utm +zone=36 +datum=WGS84 +units=m +no_defs');
register(proj4);
// metadata from https://s3.us-west-2.amazonaws.com/sentinel-cogs/sentinel-s2-l2a-cogs/2020/S2A_36QWD_20200701_0_L2A/S2A_36QWD_20200701_0_L2A.json
const sourceExtent = [499980, 1790220, 609780, 1900020];
const map = new Map({
target: 'map',
layers: [
new TileLayer({
style: {
color: [
'interpolate',
['linear'],
// calculate NDVI, bands come from the sources below
[
'/',
['-', ['band', 2], ['band', 1]],
['+', ['band', 2], ['band', 1]],
],
// color ramp for NDVI values, ranging from -1 to 1
-0.2,
[191, 191, 191],
-0.1,
[219, 219, 219],
0,
[255, 255, 224],
0.025,
[255, 250, 204],
0.05,
[237, 232, 181],
0.075,
[222, 217, 156],
0.1,
[204, 199, 130],
0.125,
[189, 184, 107],
0.15,
[176, 194, 97],
0.175,
[163, 204, 89],
0.2,
[145, 191, 82],
0.25,
[128, 179, 71],
0.3,
[112, 163, 64],
0.35,
[97, 150, 54],
0.4,
[79, 138, 46],
0.45,
[64, 125, 36],
0.5,
[48, 110, 28],
0.55,
[33, 97, 18],
0.6,
[15, 84, 10],
0.65,
[0, 69, 0],
],
},
source: new GeoTIFF({
sources: [
{
// visible red, band 1 in the style expression above
url: 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/2020/S2A_36QWD_20200701_0_L2A/B04.tif',
max: 10000,
},
{
// near infrared, band 2 in the style expression above
url: 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/2020/S2A_36QWD_20200701_0_L2A/B08.tif',
max: 10000,
},
],
}),
extent: sourceExtent,
}),
],
view: new View({
projection: 'EPSG:32636',
center: getCenter(sourceExtent),
extent: sourceExtent,
zoom: 9,
}),
});

View File

@@ -0,0 +1,12 @@
---
layout: example.html
title: GeoTIFF with Overviews
shortdesc: Rendering a GeoTIFF with external overviews as a layer.
docs: >
In some cases, a GeoTIFF may have external overviews. This example uses the
`overviews` property to provide URLs for the external overviews. The example
composes a false color composite using shortwave infrared (B6), near infrared (B5),
and visible green (B3) bands from a Landsat 8 image.
tags: "cog"
---
<div id="map" class="map"></div>

62
examples/cog-overviews.js Normal file
View File

@@ -0,0 +1,62 @@
import GeoTIFF from '../src/ol/source/GeoTIFF.js';
import Map from '../src/ol/Map.js';
import TileLayer from '../src/ol/layer/WebGLTile.js';
import View from '../src/ol/View.js';
import proj4 from 'proj4';
import {getCenter} from '../src/ol/extent.js';
import {register} from '../src/ol/proj/proj4.js';
proj4.defs('EPSG:32645', '+proj=utm +zone=45 +datum=WGS84 +units=m +no_defs');
register(proj4);
const sourceExtent = [382200, 2279370, 610530, 2512500];
const base =
'https://landsat-pds.s3.amazonaws.com/c1/L8/139/045/LC08_L1TP_139045_20170304_20170316_01_T1/LC08_L1TP_139045_20170304_20170316_01_T1';
// scale values in this range to 0 - 1
const min = 10000;
const max = 15000;
const map = new Map({
target: 'map',
layers: [
new TileLayer({
extent: sourceExtent,
style: {
saturation: -0.3,
},
source: new GeoTIFF({
sources: [
{
url: `${base}_B6.TIF`,
overviews: [`${base}_B6.TIF.ovr`],
min: min,
max: max,
nodata: 0,
},
{
url: `${base}_B5.TIF`,
overviews: [`${base}_B5.TIF.ovr`],
min: min,
max: max,
nodata: 0,
},
{
url: `${base}_B3.TIF`,
overviews: [`${base}_B3.TIF.ovr`],
min: min,
max: max,
nodata: 0,
},
],
}),
}),
],
view: new View({
projection: 'EPSG:32645',
center: getCenter(sourceExtent),
extent: sourceExtent,
zoom: 8,
}),
});

12
examples/cog-pyramid.html Normal file
View File

@@ -0,0 +1,12 @@
---
layout: example.html
title: GeoTIFF tile pyramid
shortdesc: Rendering a COG tile pyramid as layer group.
docs: >
Data from a Cloud Optimized GeoTIFF (COG) tile pyramid can be rendered as a set of layers. In this
example, a pyramid of 3-band GeoTIFFs is used to render RGB data. For each tile of the pyramid, a
separate layer is created on demand. The lowest resolution layer serves as preview while higher resolutions are
loading.
tags: "cog, tilepyramid, stac"
---
<div id="map" class="map"></div>

71
examples/cog-pyramid.js Normal file
View File

@@ -0,0 +1,71 @@
import GeoTIFF from '../src/ol/source/GeoTIFF.js';
import LayerGroup from '../src/ol/layer/Group.js';
import Map from '../src/ol/Map.js';
import TileGrid from '../src/ol/tilegrid/TileGrid.js';
import View from '../src/ol/View.js';
import WebGLTileLayer from '../src/ol/layer/WebGLTile.js';
import {getIntersection} from '../src/ol/extent.js';
// Metadata from https://s2downloads.eox.at/demo/EOxCloudless/2019/rgb/2019_EOxCloudless_rgb.json
// Tile grid of the GeoTIFF pyramid layout
const tileGrid = new TileGrid({
origin: [-180, 90],
resolutions: [0.703125, 0.3515625, 0.17578125, 8.7890625e-2, 4.39453125e-2],
tileSizes: [
[512, 256],
[1024, 512],
[2048, 1024],
[4096, 2048],
[4096, 4096],
],
});
const pyramid = new LayerGroup();
const layerForUrl = {};
const zs = tileGrid.getResolutions().length;
function useLayer(z, x, y) {
const url = `https://s2downloads.eox.at/demo/EOxCloudless/2019/rgb/${z}/${y}/${x}.tif`;
if (!(url in layerForUrl)) {
pyramid.getLayers().push(
new WebGLTileLayer({
minZoom: z,
maxZoom: z === 0 || z === zs - 1 ? undefined : z + 1,
extent: tileGrid.getTileCoordExtent([z, x, y]),
source: new GeoTIFF({
sources: [
{
url: url,
},
],
}),
})
);
layerForUrl[url] = true;
}
}
const map = new Map({
target: 'map',
layers: [pyramid],
view: new View({
projection: 'EPSG:4326',
center: [0, 0],
zoom: 0,
showFullExtent: true,
}),
});
// Add overview layer
useLayer(0, 0, 0);
// Add layer for specific extent on demand
map.on('moveend', () => {
const view = map.getView();
tileGrid.forEachTileCoord(
getIntersection([-180, -90, 180, 90], view.calculateExtent()),
tileGrid.getZForResolution(view.getResolution()),
([z, x, y]) => useLayer(z, x, y)
);
});

10
examples/cog.html Normal file
View File

@@ -0,0 +1,10 @@
---
layout: example.html
title: Cloud Optimized GeoTIFF (COG)
shortdesc: Rendering a COG as a tiled layer.
docs: >
Tiled data from a Cloud Optimized GeoTIFF (COG) can be rendered as a layer. In this
example, a single 3-band GeoTIFF is used to render RGB data.
tags: "cog"
---
<div id="map" class="map"></div>

35
examples/cog.js Normal file
View File

@@ -0,0 +1,35 @@
import GeoTIFF from '../src/ol/source/GeoTIFF.js';
import Map from '../src/ol/Map.js';
import TileLayer from '../src/ol/layer/WebGLTile.js';
import View from '../src/ol/View.js';
import proj4 from 'proj4';
import {getCenter} from '../src/ol/extent.js';
import {register} from '../src/ol/proj/proj4.js';
proj4.defs('EPSG:32636', '+proj=utm +zone=36 +datum=WGS84 +units=m +no_defs');
register(proj4);
// metadata from https://s3.us-west-2.amazonaws.com/sentinel-cogs/sentinel-s2-l2a-cogs/2020/S2A_36QWD_20200701_0_L2A/S2A_36QWD_20200701_0_L2A.json
const sourceExtent = [499980, 1790220, 609780, 1900020];
const map = new Map({
target: 'map',
layers: [
new TileLayer({
source: new GeoTIFF({
sources: [
{
url: 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/2020/S2A_36QWD_20200701_0_L2A/TCI.tif',
},
],
}),
extent: sourceExtent,
}),
],
view: new View({
projection: 'EPSG:32636',
center: getCenter(sourceExtent),
extent: sourceExtent,
zoom: 9,
}),
});

9
examples/data-tiles.html Normal file
View File

@@ -0,0 +1,9 @@
---
layout: example.html
title: Data Tiles
shortdesc: Generating tile data from scratch.
docs: >
This example generates RGBA tile data from scratch.
tags: "data tiles"
---
<div id="map" class="map"></div>

45
examples/data-tiles.js Normal file
View File

@@ -0,0 +1,45 @@
import DataTile from '../src/ol/source/DataTile.js';
import Map from '../src/ol/Map.js';
import TileLayer from '../src/ol/layer/WebGLTile.js';
import View from '../src/ol/View.js';
const size = 256;
const canvas = document.createElement('canvas');
canvas.width = size;
canvas.height = size;
const context = canvas.getContext('2d');
context.strokeStyle = 'white';
context.textAlign = 'center';
context.font = '24px sans-serif';
const lineHeight = 30;
const map = new Map({
target: 'map',
layers: [
new TileLayer({
source: new DataTile({
loader: function (z, x, y) {
const half = size / 2;
context.clearRect(0, 0, size, size);
context.fillStyle = 'rgba(100, 100, 100, 0.5)';
context.fillRect(0, 0, size, size);
context.fillStyle = 'black';
context.fillText(`z: ${z}`, half, half - lineHeight);
context.fillText(`x: ${x}`, half, half);
context.fillText(`y: ${y}`, half, half + lineHeight);
context.strokeRect(0, 0, size, size);
const data = context.getImageData(0, 0, size, size).data;
return Promise.resolve(data);
},
// disable opacity transition to avoid overlapping labels during tile loading
transition: 0,
}),
}),
],
view: new View({
center: [0, 0],
zoom: 0,
}),
});

View File

@@ -1,9 +0,0 @@
---
layout: example.html
title: Hit tolerance priority
shortdesc: Shows bad behavior of hit detection with hit tolerance.
docs: >
Hover over the map and observe how the small circles get a black outline as you hover over them. Is the expected feature getting highlighted?
tags: "simple, openstreetmap"
---
<div id="map" class="map"></div>

View File

@@ -1,84 +0,0 @@
import CircleStyle from '../src/ol/style/Circle.js';
import Feature from '../src/ol/Feature.js';
import Map from '../src/ol/Map.js';
import VectorLayer from '../src/ol/layer/Vector.js';
import VectorSource from '../src/ol/source/Vector.js';
import View from '../src/ol/View.js';
import {Fill, Stroke, Style} from '../src/ol/style.js';
import {Point} from '../src/ol/geom.js';
const map = new Map({
target: 'map',
view: new View({
center: [0, 0],
resolution: 1,
resolutions: [1],
}),
});
const vectorLayer = new VectorLayer({
source: new VectorSource({
features: [
new Feature({
geometry: new Point([0, 0]),
color: 'white',
}),
new Feature({
geometry: new Point([-10, 0]),
color: 'fuchsia',
}),
new Feature({
geometry: new Point([-10, -10]),
color: 'orange',
}),
new Feature({
geometry: new Point([-10, 10]),
color: 'cyan',
}),
],
}),
style: (feature) => {
return new Style({
image: new CircleStyle({
radius: 5,
fill: new Fill({
color: feature.get('color'),
}),
stroke: new Stroke({
color: 'gray',
width: 1,
}),
}),
});
},
});
map.addLayer(vectorLayer);
const highlightFeature = new Feature(new Point([NaN, NaN]));
highlightFeature.setStyle(
new Style({
image: new CircleStyle({
radius: 5,
stroke: new Stroke({
color: 'black',
width: 2,
}),
}),
})
);
vectorLayer.getSource().addFeature(highlightFeature);
map.on('pointermove', (e) => {
const hit = map.forEachFeatureAtPixel(
e.pixel,
(feature) => {
highlightFeature.setGeometry(feature.getGeometry().clone());
return true;
},
{
hitTolerance: 10,
}
);
if (!hit) {
highlightFeature.setGeometry(new Point([NaN, NaN]));
}
});

View File

@@ -4,3 +4,13 @@
top: auto;
right: auto;
}
.map:-webkit-full-screen {
height: 100%;
margin: 0;
}
.map:-ms-fullscreen {
height: 100%;
}
.map:fullscreen {
height: 100%;
}

View File

@@ -4,7 +4,7 @@ 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 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"
tags: "mapbox, vector, tiles, mobile, grid"
resources:
- resources/mapbox-streets-v6-style.js
cloak:

View File

@@ -92,7 +92,7 @@ const map = new Map({
],
target: 'map',
view: new View({
resolutions: createXYZ({tileSize: 512}).getResolutions89,
resolutions: createXYZ({tileSize: 512}).getResolutions(),
center: [0, 0],
zoom: 2,
}),

View File

@@ -0,0 +1,11 @@
---
layout: example.html
title: OGC Map Tiles (Geographic)
shortdesc: Rendering map tiles from an OGC API Tiles service.
docs: >
The <a href="https://ogcapi.ogc.org/tiles/">OGC API Tiles</a> specification describes how a service can provide map tiles. Because the specification
has not yet been finalized, the <code>OGCMapTile</code> source is not yet part of the stable API.
tags: "ogc"
experimental: true
---
<div id="map" class="map"></div>

View File

@@ -0,0 +1,20 @@
import Map from '../src/ol/Map.js';
import OGCMapTile from '../src/ol/source/OGCMapTile.js';
import TileLayer from '../src/ol/layer/Tile.js';
import View from '../src/ol/View.js';
const map = new Map({
target: 'map',
layers: [
new TileLayer({
source: new OGCMapTile({
url: 'https://maps.ecere.com/ogcapi/collections/blueMarble/map/tiles/WorldCRS84Quad',
}),
}),
],
view: new View({
projection: 'EPSG:4326',
center: [0, 0],
zoom: 1,
}),
});

View File

@@ -0,0 +1,11 @@
---
layout: example.html
title: OGC Map Tiles
shortdesc: Rendering map tiles from an OGC API Tiles service.
docs: >
The <a href="https://ogcapi.ogc.org/tiles/">OGC API Tiles</a> specification describes how a service can provide map tiles. Because the specification
has not yet been finalized, the <code>OGCMapTile</code> source is not yet part of the stable API.
tags: "ogc"
experimental: true
---
<div id="map" class="map"></div>

19
examples/ogc-map-tiles.js Normal file
View File

@@ -0,0 +1,19 @@
import Map from '../src/ol/Map.js';
import OGCMapTile from '../src/ol/source/OGCMapTile.js';
import TileLayer from '../src/ol/layer/Tile.js';
import View from '../src/ol/View.js';
const map = new Map({
target: 'map',
layers: [
new TileLayer({
source: new OGCMapTile({
url: 'https://maps.ecere.com/ogcapi/collections/blueMarble/map/tiles/WebMercatorQuad',
}),
}),
],
view: new View({
center: [0, 0],
zoom: 1,
}),
});

View File

@@ -0,0 +1,11 @@
---
layout: example.html
title: OGC Vector Tiles
shortdesc: Rendering vector tiles from an OGC API Tiles service.
docs: >
The <a href="https://ogcapi.ogc.org/tiles/">OGC API Tiles</a> specification describes how a service can provide vector tiles. Because the specification
has not yet been finalized, the <code>OGCVectorTile</code> source is not yet part of the stable API.
tags: "ogc, vector"
experimental: true
---
<div id="map" class="map"></div>

View File

@@ -0,0 +1,21 @@
import MVT from '../src/ol/format/MVT.js';
import Map from '../src/ol/Map.js';
import OGCVectorTile from '../src/ol/source/OGCVectorTile.js';
import VectorTileLayer from '../src/ol/layer/VectorTile.js';
import View from '../src/ol/View.js';
const map = new Map({
target: 'map',
layers: [
new VectorTileLayer({
source: new OGCVectorTile({
url: 'https://maps.ecere.com/ogcapi/collections/NaturalEarth:cultural:ne_10m_admin_0_countries/tiles/WebMercatorQuad',
format: new MVT(),
}),
}),
],
view: new View({
center: [0, 0],
zoom: 1,
}),
});

View File

@@ -8,7 +8,7 @@ docs: >
Unlike the <a href="export-pdf.html">Export PDF example</a> the on screen map is only used to set the center and rotation.
The extent printed depends on the scale and page size. To print the scale bar and attributions the example uses the
<a href="https://html2canvas.hertzen.com/" target="_blank">html2canvas</a> library.
tags: "print, printing, scale, scaleline, export, pdf"
tags: "print, printing, scale, scaleline, export, pdf, grid"
resources:
- https://html2canvas.hertzen.com/dist/html2canvas.min.js
- https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.3.1/jspdf.umd.min.js

View File

@@ -5,7 +5,7 @@ import XYZ from '../src/ol/source/XYZ.js';
import {Image as ImageLayer, Tile as TileLayer} from '../src/ol/layer.js';
const minVgi = 0;
const maxVgi = 0.25;
const maxVgi = 0.5;
const bins = 10;
/**
@@ -87,7 +87,7 @@ const raster = new RasterSource({
summarize: summarize,
},
});
raster.set('threshold', 0.1);
raster.set('threshold', 0.25);
function createCounts(min, max, num) {
const values = new Array(num);

View File

@@ -4,7 +4,7 @@ title: Raster Reprojection
shortdesc: Demonstrates client-side raster reprojection between various projections.
docs: >
This example shows client-side raster reprojection between various projections.
tags: "reprojection, projection, proj4js, osm, wms, wmts, hidpi"
tags: "reprojection, projection, proj4js, osm, wms, wmts, hidpi, grid"
---
<div id="map" class="map"></div>
<form class="form-inline">

View File

@@ -3,7 +3,7 @@ layout: example.html
title: Select Features
shortdesc: Example of using the Select interaction.
docs: >
Choose between <code>Single-click</code>, <code>Click</code>, <code>Hover</code> and <code>Alt+Click</code> as the event type for selection in the combobox below. When using <code>Single-click</code> or <code>Click</code> you can hold do <code>Shift</code> key to toggle the feature in the selection.</p>
Choose between <code>Single-click</code>, <code>Click</code>, <code>Hover</code> and <code>Alt+Click</code> as the event type for selection in the combobox below. When using <code>Single-click</code> or <code>Click</code> you can hold the <code>Shift</code> key to toggle the feature in the selection.</p>
<p>Note: when <code>Single-click</code> is used double-clicks won't select features. This in contrast to <code>Click</code>, where a double-click will both select the feature and zoom the map (because of the <code>DoubleClickZoom</code> interaction). Note that <code>Single-click</code> is less responsive than <code>Click</code> because of the delay it uses to detect double-clicks.</p>
<p>In this example, a listener is registered for the Select interaction's <code>select</code> event in order to update the selection status above.
tags: "select, vector"

View File

@@ -3,7 +3,9 @@ layout: example.html
title: Translate Features
shortdesc: Example of a translate features interaction.
docs: >
This example demonstrates how the translate and select interactions can be used together. Zoom in to an area of interest and click to select a feature. Then drag the feature around to move it elsewhere on the map.
This example demonstrates how the translate and select interactions can be used together.
Zoom in to an area of interest and click to select a feature or hold the <code>Shift</code> key and select multiple features.
Then drag the features around to move them elsewhere on the map.
tags: "drag, translate, feature, vector, editing"
---
<div id="map" class="map"></div>

View File

@@ -5,7 +5,7 @@ shortdesc: Example showing vector tiles in EPSG:4326 (styled using ol-mapbox-sty
docs: >
Example showing vector tiles in EPSG:4326 (styled using `ol-mapbox-style`) loaded from maptiler.com.
**Note**: Make sure to get your own API key at https://www.maptiler.com/cloud/ when using this example. No map will be visible when the API key has expired.
tags: "vector tiles, epsg4326, mapbox style, ol-mapbox-style, maptiler"
tags: "vector tiles, epsg4326, mapbox style, ol-mapbox-style, maptiler, grid"
cloak:
- key: get_your_own_D6rA4zTHduk6KOKTXzGB
value: Get your own API key at https://www.maptiler.com/cloud/

View File

@@ -0,0 +1,13 @@
#level {
display: inline-block;
width: 150px;
vertical-align: text-bottom;
}
a.location {
cursor: pointer;
}
#map {
background: #8bd4ff;
}

View File

@@ -0,0 +1,37 @@
---
layout: example.html
title: Sea Level (with WebGL)
shortdesc: Render sea level at different elevations
docs: >
<p>
The <code>style</code> property of a WebGL tile layer accepts a <code>color</code> expression that
can be used to modify pixel values before rendering. Here, RGB tiles representing elevation
data are loaded and rendered so that values at or below sea level are blue, and values
above sea level are transparent. The <code>color</code> expression operates on normalized pixel
values ranging from 0 to 1. The <code>band</code> operator is used to select normalized values
from a single band.
</p><p>
After converting the normalized RGB values to elevation, the <code>interpolate</code> expression
is used to pick colors to apply at a given elevation. Instead of using constant
numeric values as the stops in the colors array, the <code>var</code> operator allows you to
use a value that can be modified by your application. When the user drags the
sea level slider, the <code>layer.updateStyleVariables()</code> function is called to update
the <code>level</code> style variable with the value from the slider.
</p>
tags: "webgl, math, flood"
cloak:
- key: get_your_own_D6rA4zTHduk6KOKTXzGB
value: Get your own API key at https://www.maptiler.com/cloud/
---
<div id="map" class="map"></div>
<label>
Sea level
<input id="level" type="range" min="0" max="100" value="1"/>
+<span id="output"></span> m
</label>
<br>
Go to
<a class="location" data-center="-122.3267,37.8377" data-zoom="11">San Francisco</a>,
<a class="location" data-center="-73.9338,40.6861" data-zoom="11">New York</a>,
<a class="location" data-center="72.9481,18.9929" data-zoom="11">Mumbai</a>, or
<a class="location" data-center="120.831,31.160" data-zoom="9">Shanghai</a>

View File

@@ -0,0 +1,90 @@
import Map from '../src/ol/Map.js';
import TileLayer from '../src/ol/layer/WebGLTile.js';
import View from '../src/ol/View.js';
import XYZ from '../src/ol/source/XYZ.js';
import {fromLonLat} from '../src/ol/proj.js';
const key = 'get_your_own_D6rA4zTHduk6KOKTXzGB';
const attributions =
'<a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> ' +
'<a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>';
const elevation = new TileLayer({
opacity: 0.6,
source: new XYZ({
url:
'https://api.maptiler.com/tiles/terrain-rgb/{z}/{x}/{y}.png?key=' + key,
maxZoom: 10,
tileSize: 512,
crossOrigin: 'anonymous',
}),
style: {
variables: {
level: 0,
},
color: [
'interpolate',
['linear'],
// band math operates on normalized values from 0-1
// so we scale by 255 to align with the elevation formula
// from https://cloud.maptiler.com/tiles/terrain-rgb/
[
'+',
-10000,
[
'*',
0.1 * 255,
[
'+',
['*', 256 * 256, ['band', 1]],
['+', ['*', 256, ['band', 2]], ['band', 3]],
],
],
],
// use the `level` style variable as a stop in the color ramp
['var', 'level'],
[139, 212, 255, 1],
['+', 0.01, ['var', 'level']],
[139, 212, 255, 0],
],
},
});
const map = new Map({
target: 'map',
layers: [
new TileLayer({
source: new XYZ({
url: 'https://api.maptiler.com/maps/streets/{z}/{x}/{y}.png?key=' + key,
attributions: attributions,
crossOrigin: 'anonymous',
tileSize: 512,
}),
}),
elevation,
],
view: new View({
center: fromLonLat([-122.3267, 37.8377]),
zoom: 11,
}),
});
const control = document.getElementById('level');
const output = document.getElementById('output');
control.addEventListener('input', function () {
output.innerText = control.value;
elevation.updateStyleVariables({level: parseFloat(control.value)});
});
output.innerText = control.value;
const locations = document.getElementsByClassName('location');
for (let i = 0, ii = locations.length; i < ii; ++i) {
locations[i].addEventListener('click', relocate);
}
function relocate(event) {
const data = event.target.dataset;
const view = map.getView();
view.setCenter(fromLonLat(data.center.split(',').map(Number)));
view.setZoom(Number(data.zoom));
}

View File

@@ -0,0 +1,7 @@
table.controls td {
padding: 2px 5px;
}
table.controls td:nth-child(3) {
text-align: right;
min-width: 3em;
}

View File

@@ -0,0 +1,32 @@
---
layout: example.html
title: Shaded Relief (with WebGL)
shortdesc: Calculate shaded relief from elevation data
docs: >
<p>
For the shaded relief, a single tiled source of elevation data is used as input.
The shaded relief is calculated by the layer's <code>style</code> with a <code>color</code>
expression. The style variables are updated when the user drags one of the sliders. The
<code>band</code> operator is used to sample data from neighboring pixels for calculating slope and
aspect, which is done with the <code>['band', bandIndex, xOffset, yOffset]</code> syntax.
</p>
tags: "webgl, shaded relief"
---
<div id="map" class="map"></div>
<table class="controls">
<tr>
<td><label for="vert">vertical exaggeration:</label></td>
<td><input id="vert" type="range" min="1" max="5" value="1"/></td>
<td><span id="vertOut"></span> x</td>
</tr>
<tr>
<td><label for="sunEl">sun elevation:</label></td>
<td><input id="sunEl" type="range" min="0" max="90" value="45"/></td>
<td><span id="sunElOut"></span> °</td>
</tr>
<tr>
<td><label for="sunAz">sun azimuth:</label></td>
<td><input id="sunAz" type="range" min="0" max="360" value="45"/></td>
<td><span id="sunAzOut"></span> °</td>
</tr>
</table>

View File

@@ -0,0 +1,91 @@
import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js';
import {OSM, XYZ} from '../src/ol/source.js';
import {WebGLTile as TileLayer} from '../src/ol/layer.js';
const variables = {};
// The method used to extract elevations from the DEM.
// In this case the format used is
// red + green * 2 + blue * 3
//
// Other frequently used methods include the Mapbox format
// (red * 256 * 256 + green * 256 + blue) * 0.1 - 10000
// and the Terrarium format
// (red * 256 + green + blue / 256) - 32768
function elevation(xOffset, yOffset) {
return [
'+',
['*', 256, ['band', 1, xOffset, yOffset]],
[
'+',
['*', 2 * 256, ['band', 2, xOffset, yOffset]],
['*', 3 * 256, ['band', 3, xOffset, yOffset]],
],
];
}
// Generates a shaded relief image given elevation data. Uses a 3x3
// neighborhood for determining slope and aspect.
const dp = ['*', 2, ['resolution']];
const z0x = ['*', ['var', 'vert'], elevation(-1, 0)];
const z1x = ['*', ['var', 'vert'], elevation(1, 0)];
const dzdx = ['/', ['-', z1x, z0x], dp];
const z0y = ['*', ['var', 'vert'], elevation(0, -1)];
const z1y = ['*', ['var', 'vert'], elevation(0, 1)];
const dzdy = ['/', ['-', z1y, z0y], dp];
const slope = ['atan', ['^', ['+', ['^', dzdx, 2], ['^', dzdy, 2]], 0.5]];
const aspect = ['clamp', ['atan', ['-', 0, dzdx], dzdy], -Math.PI, Math.PI];
const sunEl = ['*', Math.PI / 180, ['var', 'sunEl']];
const sunAz = ['*', Math.PI / 180, ['var', 'sunAz']];
const cosIncidence = [
'+',
['*', ['sin', sunEl], ['cos', slope]],
['*', ['*', ['cos', sunEl], ['sin', slope]], ['cos', ['-', sunAz, aspect]]],
];
const scaled = ['*', 255, cosIncidence];
const shadedRelief = new TileLayer({
opacity: 0.3,
source: new XYZ({
url: 'https://{a-d}.tiles.mapbox.com/v3/aj.sf-dem/{z}/{x}/{y}.png',
crossOrigin: 'anonymous',
}),
style: {
variables: variables,
color: ['color', scaled, scaled, scaled],
},
});
const controlIds = ['vert', 'sunEl', 'sunAz'];
controlIds.forEach(function (id) {
const control = document.getElementById(id);
const output = document.getElementById(id + 'Out');
function updateValues() {
output.innerText = control.value;
variables[id] = Number(control.value);
}
updateValues();
control.addEventListener('input', () => {
updateValues();
shadedRelief.updateStyleVariables(variables);
});
});
const map = new Map({
target: 'map',
layers: [
new TileLayer({
source: new OSM(),
}),
shadedRelief,
],
view: new View({
extent: [-13675026, 4439648, -13580856, 4580292],
center: [-13615645, 4497969],
minZoom: 10,
maxZoom: 16,
zoom: 13,
}),
});

View File

@@ -0,0 +1,4 @@
#controls {
display: flex;
justify-content: space-around;
}

View File

@@ -0,0 +1,31 @@
---
layout: example.html
title: WebGL Tile Layer Styles
shortdesc: Styling raster tiles with WebGL.
docs: >
The `style` property of a WebGL tile layer can be used to adjust properties like
`exposure`, `contrast`, and `saturation`. Typically those values would be set to
numeric constants to apply a filter to imagery. In this example, the style properties
are set to variables that can be updated based on application state. Adjusting the
sliders results in a call to `layer.updateStyleVariables()` to use new values for the
associated style properties.
tags: "webgl, style"
cloak:
- key: get_your_own_D6rA4zTHduk6KOKTXzGB
value: Get your own API key at https://www.maptiler.com/cloud/
---
<div id="map" class="map"></div>
<div id="controls">
<label>
<input id="exposure" type="range" min="-0.5" max="0.5" step="0.01">
<br>exposure <span id="exposure-value"></span>
</label>
<label>
<input id="contrast" type="range" min="-0.5" max="0.5" step="0.01">
<br>contrast <span id="contrast-value"></span>
</label>
<label>
<input id="saturation" type="range" min="-0.5" max="0.5" step="0.01">
<br>saturation <span id="saturation-value"></span>
</label>
</div>

View File

@@ -0,0 +1,55 @@
import Map from '../src/ol/Map.js';
import TileLayer from '../src/ol/layer/WebGLTile.js';
import View from '../src/ol/View.js';
import XYZ from '../src/ol/source/XYZ.js';
const key = 'get_your_own_D6rA4zTHduk6KOKTXzGB';
const attributions =
'<a href="https://www.maptiler.com/copyright/" target="_blank">&copy; MapTiler</a> ' +
'<a href="https://www.openstreetmap.org/copyright" target="_blank">&copy; OpenStreetMap contributors</a>';
const variables = {
exposure: 0,
contrast: 0,
saturation: 0,
};
const layer = new TileLayer({
style: {
exposure: ['var', 'exposure'],
contrast: ['var', 'contrast'],
saturation: ['var', 'saturation'],
variables: variables,
},
source: new XYZ({
crossOrigin: 'anonymous', // TODO: determine if we can avoid this
attributions: attributions,
url: 'https://api.maptiler.com/tiles/satellite/{z}/{x}/{y}.jpg?key=' + key,
maxZoom: 20,
}),
});
const map = new Map({
target: 'map',
layers: [layer],
view: new View({
center: [0, 0],
zoom: 0,
}),
});
for (const name in variables) {
const element = document.getElementById(name);
const value = variables[name];
element.value = value.toString();
document.getElementById(`${name}-value`).innerText = `(${value})`;
element.addEventListener('input', function (event) {
const value = parseFloat(event.target.value);
document.getElementById(`${name}-value`).innerText = `(${value})`;
const updates = {};
updates[name] = value;
layer.updateStyleVariables(updates);
});
}

View File

@@ -0,0 +1,9 @@
---
layout: example.html
title: WebGL Tiles
shortdesc: Rendering raster data with WebGL.
docs: >
This example uses WebGL to raster tiles on a map.
tags: "webgl, osm"
---
<div id="map" class="map"></div>

17
examples/webgl-tiles.js Normal file
View File

@@ -0,0 +1,17 @@
import Map from '../src/ol/Map.js';
import OSM from '../src/ol/source/OSM.js';
import TileLayer from '../src/ol/layer/WebGLTile.js';
import View from '../src/ol/View.js';
const map = new Map({
target: 'map',
layers: [
new TileLayer({
source: new OSM(),
}),
],
view: new View({
center: [0, 0],
zoom: 0,
}),
});

View File

@@ -101,6 +101,8 @@ export default {
resolve: {
fallback: {
fs: false,
http: false,
https: false,
},
alias: {
// allow imports from 'ol/module' instead of specifiying the source path

View File

@@ -9,7 +9,12 @@ module.exports = function loader() {
build(this.resource, {minify})
.then((chunk) => {
for (const filePath in chunk.modules) {
this.addDependency(filePath);
try {
const dependency = require.resolve(filePath);
this.addDependency(dependency);
} catch (e) {
// empty catch block
}
}
callback(null, chunk.code);
})

View File

@@ -1,9 +1,9 @@
---
layout: example.html
title: WMS 512x256 Tiles
shortdesc: Example of a WMS layer with 512x256px tiles.
shortdesc: Example of a WMS layer with a custom grid with 512x256px tiles.
docs: >
WMS can serve arbitrary tile sizes. This example uses a custom tile grid with non-square tiles.
tags: "wms, tile, non-square"
tags: "wms, tile, non-square, grid"
---
<div id="map" class="map"></div>

View File

@@ -4,7 +4,7 @@ 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 continuously. The demonstration layer is a global sea-level computation (flooding computation from <a href="https://scalgo.com/">SCALGO</a>, underlying data from <a href="https://cgiarcsi.community/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"
tags: "wmts, parameter, transition, grid"
---
<div id="map" class="map"></div>
<label>

View File

@@ -9,6 +9,6 @@ docs: >
and
[Documentation de loffre de données et services de lIGN](https://geoservices.ign.fr/documentation/diffusion/documentation-offre.html)
(french).
tags: "french, ign, geoportail, wmts"
tags: "french, ign, geoportail, wmts, grid"
---
<div id="map" class="map"></div>

View File

@@ -4,6 +4,6 @@ title: WMTS
shortdesc: Example of a WMTS source.
docs: >
This example shows how to manually create the configuration for accessing a WMTS. The [WMTS Layer from capabilities example](wmts-layer-from-capabilities.html) shows how to create the configuration from a GetCapabilities response.
tags: "wmts"
tags: "wmts, grid"
---
<div id="map" class="map"></div>

2095
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "ol",
"version": "6.6.1",
"version": "6.7.0",
"description": "OpenLayers mapping library",
"keywords": [
"map",
@@ -18,12 +18,12 @@
"test": "npm run test-browser && npm run test-node && npm run test-rendering -- --force",
"karma": "karma start test/browser/karma.config.cjs",
"start": "npm run serve-examples",
"serve-examples": "webpack serve --config examples/webpack/config.js --mode development",
"build-examples": "webpack --config examples/webpack/config.js --mode production",
"serve-examples": "webpack serve --config examples/webpack/config.mjs --mode development",
"build-examples": "webpack --config examples/webpack/config.mjs --mode production",
"build-package": "npm run transpile && npm run copy-css && npm run generate-types && node tasks/prepare-package.js",
"build-index": "shx rm -f build/index.js && npm run build-package && node tasks/generate-index.js",
"build-legacy": "shx rm -rf build/legacy && npm run build-index && webpack --config config/webpack-config-legacy-build.js && cleancss --source-map src/ol/ol.css -o build/legacy/ol.css",
"build-site": "npm run build-examples && npm run apidoc && mkdir -p build/site && cp site/index.html build/site && mv build/apidoc build/site/apidoc && mv build/examples build/site/examples",
"build-legacy": "shx rm -rf build/legacy && npm run build-index && webpack --config config/webpack-config-legacy-build.mjs && cleancss --source-map src/ol/ol.css -o build/legacy/ol.css",
"build-site": "shx rm -rf build/site && npm run build-examples && npm run apidoc && shx mkdir -p build/site && shx cp site/index.html build/site/ && shx mv build/apidoc build/examples build/site/",
"copy-css": "shx cp src/ol/ol.css build/ol/ol.css",
"generate-types": "npx --package=typescript@3.8.3 -y -- tsc --project config/tsconfig-build.json --declaration --declarationMap --emitDeclarationOnly --outdir build/ol",
"transpile": "shx rm -rf build/ol && shx mkdir -p build/ol && shx cp -rf src/ol build/ol/src && node tasks/serialize-workers.cjs && npx --package=typescript@4.3.5 -y -- tsc --project config/tsconfig-build.json",
@@ -45,6 +45,7 @@
"url": "https://opencollective.com/openlayers"
},
"dependencies": {
"geotiff": "^1.0.5",
"ol-mapbox-style": "^6.4.1",
"pbf": "3.2.1",
"rbush": "^3.0.1"
@@ -55,7 +56,7 @@
"@babel/preset-env": "^7.4.4",
"@openlayers/eslint-plugin": "^4.0.0",
"@rollup/plugin-babel": "^5.3.0",
"@rollup/plugin-commonjs": "^19.0.0",
"@rollup/plugin-commonjs": "^20.0.0",
"@rollup/plugin-node-resolve": "^13.0.0",
"@types/arcgis-rest-api": "^10.4.4",
"@types/geojson": "^7946.0.7",
@@ -65,7 +66,7 @@
"buble": "^0.20.0",
"buble-loader": "^0.5.1",
"chaikin-smooth": "^1.0.4",
"clean-css-cli": "5.3.0",
"clean-css-cli": "5.3.3",
"copy-webpack-plugin": "^9.0.0",
"coverage-istanbul-loader": "^3.0.5",
"coveralls": "3.1.1",
@@ -77,7 +78,7 @@
"front-matter": "^4.0.0",
"fs-extra": "^10.0.0",
"glob": "^7.1.5",
"globby": "^11.0.0",
"globby": "^12.0.0",
"handlebars": "4.7.7",
"istanbul": "0.4.5",
"jquery": "3.6.0",
@@ -92,12 +93,13 @@
"karma-sourcemap-loader": "^0.3.8",
"karma-webpack": "^5.0.0",
"loglevelnext": "^5.0.5",
"marked": "2.1.3",
"mocha": "9.0.2",
"marked": "3.0.2",
"mocha": "9.1.1",
"pixelmatch": "^5.1.0",
"pngjs": "^6.0.0",
"proj4": "2.7.4",
"puppeteer": "10.1.0",
"proj4": "^2.7.5",
"puppeteer": "10.2.0",
"regenerator-runtime": "^0.13.9",
"rollup": "^2.42.3",
"rollup-plugin-terser": "^7.0.2",
"serve-static": "^1.14.0",
@@ -110,7 +112,7 @@
"webpack-cli": "^4.5.0",
"webpack-dev-middleware": "^5.0.0",
"webpack-dev-server": "^4.0.0-beta.2",
"webpack-sources": "^2.2.0",
"webpack-sources": "^3.2.0",
"worker-loader": "^3.0.8",
"yargs": "^17.0.0"
},

76
src/ol/DataTile.js Normal file
View File

@@ -0,0 +1,76 @@
/**
* @module ol/DataTile
*/
import Tile from './Tile.js';
import TileState from './TileState.js';
/**
* Data that can be used with a DataTile.
* @typedef {Uint8Array|Uint8ClampedArray|DataView} Data
*/
/**
* @typedef {Object} Options
* @property {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.
* @property {function() : Promise<Data>} loader Data loader.
* @property {number} [transition=250] A duration for tile opacity
* transitions in milliseconds. A duration of 0 disables the opacity transition.
* @api
*/
class DataTile extends Tile {
/**
* @param {Options} options Tile options.
*/
constructor(options) {
const state = TileState.IDLE;
super(options.tileCoord, state, {transition: options.transition});
this.loader_ = options.loader;
this.data_ = null;
this.error_ = null;
}
/**
* Get the data for the tile.
* @return {Data} Tile data.
* @api
*/
getData() {
return this.data_;
}
/**
* Get any loading error.
* @return {Error} Loading error.
* @api
*/
getError() {
return this.error_;
}
/**
* Load not yet loaded URI.
* @api
*/
load() {
this.state = TileState.LOADING;
this.changed();
const self = this;
this.loader_()
.then(function (data) {
self.data_ = data;
self.state = TileState.LOADED;
self.changed();
})
.catch(function (error) {
self.error_ = error;
self.state = TileState.ERROR;
self.changed();
});
}
}
export default DataTile;

View File

@@ -11,7 +11,7 @@ import {listen, unlistenByKey} from './events.js';
*/
/**
* @typedef {Feature|import("./render/Feature.js").default} FeatureLike
* @typedef {Feature<import("./geom/Geometry.js").default>|import("./render/Feature.js").default} FeatureLike
*/
/***
@@ -22,6 +22,11 @@ import {listen, unlistenByKey} from './events.js';
* |'change:geometry', Return>} FeatureOnSignature
*/
/***
* @template Geometry
* @typedef {Object<string, *> & { geometry?: Geometry }} ObjectWithGeometry
*/
/**
* @classdesc
* A vector object for geographic features with a geometry and other
@@ -69,7 +74,7 @@ import {listen, unlistenByKey} from './events.js';
*/
class Feature extends BaseObject {
/**
* @param {Geometry|Object<string, *>} [opt_geometryOrProperties]
* @param {Geometry|ObjectWithGeometry<Geometry>} [opt_geometryOrProperties]
* You may pass a Geometry object directly, or an object literal containing
* properties. If you pass an object literal, you may include a Geometry
* associated with a `geometry` key.
@@ -144,17 +149,17 @@ class Feature extends BaseObject {
/**
* Clone this feature. If the original feature has a geometry it
* is also cloned. The feature id is not set in the clone.
* @return {Feature} The clone.
* @return {Feature<Geometry>} The clone.
* @api
*/
clone() {
const clone = new Feature(
this.hasProperties() ? this.getProperties() : null
const clone = /** @type {Feature<Geometry>} */ (
new Feature(this.hasProperties() ? this.getProperties() : null)
);
clone.setGeometryName(this.getGeometryName());
const geometry = this.getGeometry();
if (geometry) {
clone.setGeometry(geometry.clone());
clone.setGeometry(/** @type {Geometry} */ (geometry.clone()));
}
const style = this.getStyle();
if (style) {

View File

@@ -66,7 +66,7 @@ import {removeNode} from './dom.js';
/**
* @typedef {Object} AtPixelOptions
* @property {undefined|function(import("./layer/Layer.js").default): boolean} [layerFilter] Layer filter
* @property {undefined|function(import("./layer/Layer.js").default<import("./source/Source").default>): boolean} [layerFilter] Layer filter
* function. The filter function will receive one argument, the
* {@link module:ol/layer/Layer layer-candidate} and it should return a boolean value.
* Only layers which are visible and for which this function returns `true`
@@ -143,6 +143,11 @@ import {removeNode} from './dom.js';
*/
/**
* @fires import("./MapBrowserEvent.js").MapBrowserEvent
* @fires import("./MapEvent.js").MapEvent
* @fires import("./render/Event.js").default#precompose
* @fires import("./render/Event.js").default#postcompose
* @fires import("./render/Event.js").default#rendercomplete
* @api
*/
class PluggableMap extends BaseObject {
@@ -383,16 +388,6 @@ class PluggableMap extends BaseObject {
// is "defined" already.
this.setProperties(optionsInternal.values);
this.controls.forEach(
/**
* @param {import("./control/Control.js").default} control Control.
* @this {PluggableMap}
*/
function (control) {
control.setMap(this);
}.bind(this)
);
this.controls.addEventListener(
CollectionEventType.ADD,
/**
@@ -413,16 +408,6 @@ class PluggableMap extends BaseObject {
}.bind(this)
);
this.interactions.forEach(
/**
* @param {import("./interaction/Interaction.js").default} interaction Interaction.
* @this {PluggableMap}
*/
function (interaction) {
interaction.setMap(this);
}.bind(this)
);
this.interactions.addEventListener(
CollectionEventType.ADD,
/**
@@ -443,8 +428,6 @@ class PluggableMap extends BaseObject {
}.bind(this)
);
this.overlays_.forEach(this.addOverlayInternal_.bind(this));
this.overlays_.addEventListener(
CollectionEventType.ADD,
/**
@@ -473,6 +456,28 @@ class PluggableMap extends BaseObject {
event.element.setMap(null);
}.bind(this)
);
this.controls.forEach(
/**
* @param {import("./control/Control.js").default} control Control.
* @this {PluggableMap}
*/
function (control) {
control.setMap(this);
}.bind(this)
);
this.interactions.forEach(
/**
* @param {import("./interaction/Interaction.js").default} interaction Interaction.
* @this {PluggableMap}
*/
function (interaction) {
interaction.setMap(this);
}.bind(this)
);
this.overlays_.forEach(this.addOverlayInternal_.bind(this));
}
/**
@@ -553,7 +558,7 @@ class PluggableMap extends BaseObject {
* callback with each intersecting feature. Layers included in the detection can
* be configured through the `layerFilter` option in `opt_options`.
* @param {import("./pixel.js").Pixel} pixel Pixel.
* @param {function(import("./Feature.js").FeatureLike, import("./layer/Layer.js").default, import("./geom/SimpleGeometry.js").default): T} callback Feature callback. The callback will be
* @param {function(import("./Feature.js").FeatureLike, import("./layer/Layer.js").default<import("./source/Source").default>, import("./geom/SimpleGeometry.js").default): T} callback Feature callback. The callback will be
* called with two arguments. The first argument is one
* {@link module:ol/Feature feature} or
* {@link module:ol/render/Feature render feature} at the pixel, the second is
@@ -563,7 +568,7 @@ class PluggableMap extends BaseObject {
* @param {AtPixelOptions} [opt_options] Optional options.
* @return {T|undefined} Callback result, i.e. the return value of last
* callback execution, or the first truthy callback return value.
* @template S,T
* @template T
* @api
*/
forEachFeatureAtPixel(pixel, callback, opt_options) {
@@ -1524,7 +1529,14 @@ class PluggableMap extends BaseObject {
parseFloat(computedStyle['borderBottomWidth']);
if (!isNaN(width) && !isNaN(height)) {
size = [width, height];
if (!hasArea(size)) {
if (
!hasArea(size) &&
!!(
targetElement.offsetWidth ||
targetElement.offsetHeight ||
targetElement.getClientRects().length
)
) {
// eslint-disable-next-line
console.warn(
"No map visible because the map container's width or height are 0."

View File

@@ -74,7 +74,7 @@ export function includes(arr, obj) {
*/
/**
* @param {Array<number>} arr Array in desccending order.
* @param {Array<number>} arr Array in descending order.
* @param {number} target Target.
* @param {number|NearestDirectionFunction} direction
* 0 means return the nearest,
@@ -206,7 +206,7 @@ export function equals(arr1, arr2) {
}
/**
* Sort the passed array such that the relative order of equal elements is preverved.
* Sort the passed array such that the relative order of equal elements is preserved.
* See https://en.wikipedia.org/wiki/Sorting_algorithm#Stability for details.
* @param {Array<*>} arr The array to sort (modifies original).
* @param {!function(*, *): number} compareFnc Comparison function.

View File

@@ -104,8 +104,8 @@ class MousePosition extends Control {
}
/**
* @type {boolean}
* Change this to `false` when removing the deprecated `undefinedHTML` option.
* @type {boolean}
*/
let renderOnMouseOut = true;

View File

@@ -19,12 +19,16 @@ export function createCanvasContext2D(
opt_canvasPool,
opt_Context2DSettings
) {
const canvas =
opt_canvasPool && opt_canvasPool.length
? opt_canvasPool.shift()
: WORKER_OFFSCREEN_CANVAS
? new OffscreenCanvas(opt_width || 300, opt_height || 300)
: document.createElement('canvas');
/** @type {HTMLCanvasElement|OffscreenCanvas} */
let canvas;
if (opt_canvasPool && opt_canvasPool.length) {
canvas = opt_canvasPool.shift();
} else if (WORKER_OFFSCREEN_CANVAS) {
canvas = new OffscreenCanvas(opt_width || 300, opt_height || 300);
} else {
canvas = document.createElement('canvas');
canvas.style.all = 'initial';
}
if (opt_width) {
canvas.width = opt_width;
}

View File

@@ -14,6 +14,7 @@ export {default as OWS} from './format/OWS.js';
export {default as Polyline} from './format/Polyline.js';
export {default as TopoJSON} from './format/TopoJSON.js';
export {default as WFS} from './format/WFS.js';
export {default as WKB} from './format/WKB.js';
export {default as WKT} from './format/WKT.js';
export {default as WMSCapabilities} from './format/WMSCapabilities.js';
export {default as WMSGetFeatureInfo} from './format/WMSGetFeatureInfo.js';

View File

@@ -76,6 +76,12 @@ class FeatureFormat {
* @type {import("../proj/Projection.js").default|undefined}
*/
this.defaultFeatureProjection = undefined;
/**
* A list media types supported by the format in descending order of preference.
* @type {Array<string>}
*/
this.supportedMediaTypes = null;
}
/**

View File

@@ -132,6 +132,8 @@ class GMLBase extends XMLFeature {
'featureMember': makeArrayPusher(this.readFeaturesInternal),
'featureMembers': makeReplacer(this.readFeaturesInternal),
};
this.supportedMediaTypes = ['application/gml+xml'];
}
/**

View File

@@ -28,7 +28,7 @@ import {includes} from '../array.js';
import {
readDateTime,
readDecimal,
readNonNegativeInteger,
readPositiveInteger,
readString,
writeDateTimeTextNode,
writeDecimalTextNode,
@@ -262,7 +262,7 @@ const RTE_PARSERS = makeStructureNS(NAMESPACE_URIS, {
'desc': makeObjectPropertySetter(readString),
'src': makeObjectPropertySetter(readString),
'link': parseLink,
'number': makeObjectPropertySetter(readNonNegativeInteger),
'number': makeObjectPropertySetter(readPositiveInteger),
'extensions': parseExtensions,
'type': makeObjectPropertySetter(readString),
'rtept': parseRtePt,
@@ -289,7 +289,7 @@ const TRK_PARSERS = makeStructureNS(NAMESPACE_URIS, {
'desc': makeObjectPropertySetter(readString),
'src': makeObjectPropertySetter(readString),
'link': parseLink,
'number': makeObjectPropertySetter(readNonNegativeInteger),
'number': makeObjectPropertySetter(readPositiveInteger),
'type': makeObjectPropertySetter(readString),
'extensions': parseExtensions,
'trkseg': parseTrkSeg,
@@ -332,12 +332,12 @@ const WPT_PARSERS = makeStructureNS(NAMESPACE_URIS, {
'sym': makeObjectPropertySetter(readString),
'type': makeObjectPropertySetter(readString),
'fix': makeObjectPropertySetter(readString),
'sat': makeObjectPropertySetter(readNonNegativeInteger),
'sat': makeObjectPropertySetter(readPositiveInteger),
'hdop': makeObjectPropertySetter(readDecimal),
'vdop': makeObjectPropertySetter(readDecimal),
'pdop': makeObjectPropertySetter(readDecimal),
'ageofdgpsdata': makeObjectPropertySetter(readDecimal),
'dgpsid': makeObjectPropertySetter(readNonNegativeInteger),
'dgpsid': makeObjectPropertySetter(readPositiveInteger),
'extensions': parseExtensions,
});

View File

@@ -82,6 +82,11 @@ class GeoJSON extends JSONFeature {
* @private
*/
this.extractGeometryName_ = options.extractGeometryName;
this.supportedMediaTypes = [
'application/geo+json',
'application/vnd.geo+json',
];
}
/**

View File

@@ -9,6 +9,7 @@ import GeometryType from '../geom/GeometryType.js';
import Icon from '../style/Icon.js';
import IconAnchorUnits from '../style/IconAnchorUnits.js';
import IconOrigin from '../style/IconOrigin.js';
import ImageState from '../ImageState.js';
import LineString from '../geom/LineString.js';
import MultiLineString from '../geom/MultiLineString.js';
import MultiPoint from '../geom/MultiPoint.js';
@@ -231,11 +232,6 @@ let DEFAULT_IMAGE_STYLE_SIZE;
*/
let DEFAULT_IMAGE_STYLE_SRC;
/**
* @type {number}
*/
let DEFAULT_IMAGE_SCALE_MULTIPLIER;
/**
* @type {import("../style/Image.js").default}
*/
@@ -311,6 +307,15 @@ export function getDefaultStyleArray() {
return DEFAULT_STYLE_ARRAY;
}
/**
* Function that returns the scale needed to normalize an icon image to 32 pixels.
* @param {import("../size.js").Size} size Image size.
* @return {number} Scale.
*/
function scaleForSize(size) {
return 32 / Math.min(size[0], size[1]);
}
function createStyleDefaults() {
DEFAULT_COLOR = [255, 255, 255, 1];
@@ -318,7 +323,7 @@ function createStyleDefaults() {
color: DEFAULT_COLOR,
});
DEFAULT_IMAGE_STYLE_ANCHOR = [20, 2]; // FIXME maybe [8, 32] ?
DEFAULT_IMAGE_STYLE_ANCHOR = [20, 2];
DEFAULT_IMAGE_STYLE_ANCHOR_X_UNITS = IconAnchorUnits.PIXELS;
@@ -329,8 +334,6 @@ function createStyleDefaults() {
DEFAULT_IMAGE_STYLE_SRC =
'https://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png';
DEFAULT_IMAGE_SCALE_MULTIPLIER = 0.5;
DEFAULT_IMAGE_STYLE = new Icon({
anchor: DEFAULT_IMAGE_STYLE_ANCHOR,
anchorOrigin: IconOrigin.BOTTOM_LEFT,
@@ -338,7 +341,7 @@ function createStyleDefaults() {
anchorYUnits: DEFAULT_IMAGE_STYLE_ANCHOR_Y_UNITS,
crossOrigin: 'anonymous',
rotation: 0,
scale: DEFAULT_IMAGE_SCALE_MULTIPLIER,
scale: scaleForSize(DEFAULT_IMAGE_STYLE_SIZE),
size: DEFAULT_IMAGE_STYLE_SIZE,
src: DEFAULT_IMAGE_STYLE_SRC,
});
@@ -489,6 +492,8 @@ class KML extends XMLFeature {
this.iconUrlFunction_ = options.iconUrlFunction
? options.iconUrlFunction
: defaultIconUrlFunction;
this.supportedMediaTypes = ['application/vnd.google-earth.kml+xml'];
}
/**
@@ -939,16 +944,14 @@ function createNameStyleFunction(foundStyle, name) {
let textAlign = 'start';
const imageStyle = foundStyle.getImage();
if (imageStyle) {
let imageSize = imageStyle.getImageSize();
if (imageSize === null) {
imageSize = DEFAULT_IMAGE_STYLE_SIZE;
}
if (imageSize.length == 2) {
const imageSize = imageStyle.getSize();
if (imageSize && imageSize.length == 2) {
const imageScale = imageStyle.getScaleArray();
const anchor = imageStyle.getAnchor();
// Offset the label to be centered to the right of the icon,
// if there is one.
textOffset[0] = (imageScale[0] * imageSize[0]) / 2;
textOffset[1] = (-imageScale[1] * imageSize[1]) / 2;
textOffset[0] = imageScale[0] * (imageSize[0] - anchor[0]);
textOffset[1] = imageScale[1] * (imageSize[1] / 2 - anchor[1]);
textAlign = 'left';
}
}
@@ -1276,14 +1279,21 @@ function iconStyleParser(node, objectStack) {
anchorXUnits = hotSpot.xunits;
anchorYUnits = hotSpot.yunits;
anchorOrigin = hotSpot.origin;
} else if (src === DEFAULT_IMAGE_STYLE_SRC) {
anchor = DEFAULT_IMAGE_STYLE_ANCHOR;
anchorXUnits = DEFAULT_IMAGE_STYLE_ANCHOR_X_UNITS;
anchorYUnits = DEFAULT_IMAGE_STYLE_ANCHOR_Y_UNITS;
} else if (/^http:\/\/maps\.(?:google|gstatic)\.com\//.test(src)) {
anchor = [0.5, 0];
anchorXUnits = IconAnchorUnits.FRACTION;
anchorYUnits = IconAnchorUnits.FRACTION;
// Google hotspots from https://kml4earth.appspot.com/icons.html#notes
if (/pushpin/.test(src)) {
anchor = DEFAULT_IMAGE_STYLE_ANCHOR;
anchorXUnits = DEFAULT_IMAGE_STYLE_ANCHOR_X_UNITS;
anchorYUnits = DEFAULT_IMAGE_STYLE_ANCHOR_Y_UNITS;
} else if (/arrow-reverse/.test(src)) {
anchor = [54, 42];
anchorXUnits = DEFAULT_IMAGE_STYLE_ANCHOR_X_UNITS;
anchorYUnits = DEFAULT_IMAGE_STYLE_ANCHOR_Y_UNITS;
} else if (/paddle/.test(src)) {
anchor = [32, 1];
anchorXUnits = DEFAULT_IMAGE_STYLE_ANCHOR_X_UNITS;
anchorYUnits = DEFAULT_IMAGE_STYLE_ANCHOR_Y_UNITS;
}
}
let offset;
@@ -1306,16 +1316,13 @@ function iconStyleParser(node, objectStack) {
rotation = toRadians(heading);
}
let scale = /** @type {number|undefined} */ (object['scale']);
const scale = /** @type {number|undefined} */ (object['scale']);
const color = /** @type {Array<number>|undefined} */ (object['color']);
if (drawIcon) {
if (src == DEFAULT_IMAGE_STYLE_SRC) {
size = DEFAULT_IMAGE_STYLE_SIZE;
if (scale === undefined) {
scale = DEFAULT_IMAGE_SCALE_MULTIPLIER;
}
}
const imageStyle = new Icon({
@@ -1332,6 +1339,37 @@ function iconStyleParser(node, objectStack) {
src: this.iconUrlFunction_(src),
color: color,
});
const imageScale = imageStyle.getScaleArray()[0];
const imageSize = imageStyle.getSize();
if (imageSize === null) {
const imageState = imageStyle.getImageState();
if (imageState === ImageState.IDLE || imageState === ImageState.LOADING) {
const listener = function () {
const imageState = imageStyle.getImageState();
if (
!(
imageState === ImageState.IDLE ||
imageState === ImageState.LOADING
)
) {
const imageSize = imageStyle.getSize();
if (imageSize && imageSize.length == 2) {
const resizeScale = scaleForSize(imageSize);
imageStyle.setScale(imageScale * resizeScale);
}
imageStyle.unlistenImageChange(listener);
}
};
imageStyle.listenImageChange(listener);
if (imageState === ImageState.IDLE) {
imageStyle.load();
}
}
} else if (imageSize.length == 2) {
const resizeScale = scaleForSize(imageSize);
imageStyle.setScale(imageScale * resizeScale);
}
styleObject['imageStyle'] = imageStyle;
} else {
// handle the case when we explicitly want to draw no icon.
@@ -1882,8 +1920,12 @@ function readStyle(node, objectStack) {
const geometry = feature.getGeometry();
const type = geometry.getType();
if (type === GeometryType.GEOMETRY_COLLECTION) {
const collection =
/** @type {import("../geom/GeometryCollection").default} */ (
geometry
);
return new GeometryCollection(
geometry
collection
.getGeometriesArrayRecursive()
.filter(function (geometry) {
const type = geometry.getType();
@@ -1911,8 +1953,12 @@ function readStyle(node, objectStack) {
const geometry = feature.getGeometry();
const type = geometry.getType();
if (type === GeometryType.GEOMETRY_COLLECTION) {
const collection =
/** @type {import("../geom/GeometryCollection").default} */ (
geometry
);
return new GeometryCollection(
geometry
collection
.getGeometriesArrayRecursive()
.filter(function (geometry) {
const type = geometry.getType();
@@ -2609,7 +2655,15 @@ function writeIconStyle(node, style, objectStack) {
properties['Icon'] = iconProperties;
const scale = style.getScale();
let scale = style.getScaleArray()[0];
let imageSize = size;
if (imageSize === null) {
imageSize = DEFAULT_IMAGE_STYLE_SIZE;
}
if (imageSize.length == 2) {
const resizeScale = scaleForSize(imageSize);
scale = scale / resizeScale;
}
if (scale !== 1) {
properties['scale'] = scale;
}

View File

@@ -89,6 +89,11 @@ class MVT extends FeatureFormat {
* @type {string}
*/
this.idProperty_ = options.idProperty;
this.supportedMediaTypes = [
'application/vnd.mapbox-vector-tile',
'application/x-protobuf',
];
}
/**

View File

@@ -24,8 +24,8 @@ import {assert} from '../asserts.js';
import {assign} from '../obj.js';
import {get as getProjection} from '../proj.js';
import {
readNonNegativeInteger,
readNonNegativeIntegerString,
readPositiveInteger,
writeStringTextNode,
} from './xsd.js';
@@ -51,14 +51,14 @@ const FEATURE_COLLECTION_PARSERS = {
*/
const TRANSACTION_SUMMARY_PARSERS = {
'http://www.opengis.net/wfs': {
'totalInserted': makeObjectPropertySetter(readNonNegativeInteger),
'totalUpdated': makeObjectPropertySetter(readNonNegativeInteger),
'totalDeleted': makeObjectPropertySetter(readNonNegativeInteger),
'totalInserted': makeObjectPropertySetter(readPositiveInteger),
'totalUpdated': makeObjectPropertySetter(readPositiveInteger),
'totalDeleted': makeObjectPropertySetter(readPositiveInteger),
},
'http://www.opengis.net/wfs/2.0': {
'totalInserted': makeObjectPropertySetter(readNonNegativeInteger),
'totalUpdated': makeObjectPropertySetter(readNonNegativeInteger),
'totalDeleted': makeObjectPropertySetter(readNonNegativeInteger),
'totalInserted': makeObjectPropertySetter(readPositiveInteger),
'totalUpdated': makeObjectPropertySetter(readPositiveInteger),
'totalDeleted': makeObjectPropertySetter(readPositiveInteger),
},
};

View File

@@ -13,8 +13,8 @@ import {
readBooleanString,
readDecimal,
readDecimalString,
readNonNegativeInteger,
readNonNegativeIntegerString,
readPositiveInteger,
readString,
} from './xsd.js';
import {readHref} from './xlink.js';
@@ -94,9 +94,9 @@ const SERVICE_PARSERS = makeStructureNS(NAMESPACE_URIS, {
'ContactInformation': makeObjectPropertySetter(readContactInformation),
'Fees': makeObjectPropertySetter(readString),
'AccessConstraints': makeObjectPropertySetter(readString),
'LayerLimit': makeObjectPropertySetter(readNonNegativeInteger),
'MaxWidth': makeObjectPropertySetter(readNonNegativeInteger),
'MaxHeight': makeObjectPropertySetter(readNonNegativeInteger),
'LayerLimit': makeObjectPropertySetter(readPositiveInteger),
'MaxWidth': makeObjectPropertySetter(readPositiveInteger),
'MaxHeight': makeObjectPropertySetter(readPositiveInteger),
});
/**

View File

@@ -11,7 +11,7 @@ import {
makeStructureNS,
pushParseAndPop,
} from '../xml.js';
import {readDecimal, readNonNegativeInteger, readString} from './xsd.js';
import {readDecimal, readPositiveInteger, readString} from './xsd.js';
import {readHref} from './xlink.js';
/**
@@ -150,10 +150,10 @@ const TMS_LIMITS_LIST_PARSERS = makeStructureNS(NAMESPACE_URIS, {
// @ts-ignore
const TMS_LIMITS_PARSERS = makeStructureNS(NAMESPACE_URIS, {
'TileMatrix': makeObjectPropertySetter(readString),
'MinTileRow': makeObjectPropertySetter(readNonNegativeInteger),
'MaxTileRow': makeObjectPropertySetter(readNonNegativeInteger),
'MinTileCol': makeObjectPropertySetter(readNonNegativeInteger),
'MaxTileCol': makeObjectPropertySetter(readNonNegativeInteger),
'MinTileRow': makeObjectPropertySetter(readPositiveInteger),
'MaxTileRow': makeObjectPropertySetter(readPositiveInteger),
'MinTileCol': makeObjectPropertySetter(readPositiveInteger),
'MaxTileCol': makeObjectPropertySetter(readPositiveInteger),
});
/**
@@ -210,10 +210,10 @@ const TM_PARSERS = makeStructureNS(
{
'TopLeftCorner': makeObjectPropertySetter(readCoordinates),
'ScaleDenominator': makeObjectPropertySetter(readDecimal),
'TileWidth': makeObjectPropertySetter(readNonNegativeInteger),
'TileHeight': makeObjectPropertySetter(readNonNegativeInteger),
'MatrixWidth': makeObjectPropertySetter(readNonNegativeInteger),
'MatrixHeight': makeObjectPropertySetter(readNonNegativeInteger),
'TileWidth': makeObjectPropertySetter(readPositiveInteger),
'TileHeight': makeObjectPropertySetter(readPositiveInteger),
'MatrixWidth': makeObjectPropertySetter(readPositiveInteger),
'MatrixHeight': makeObjectPropertySetter(readPositiveInteger),
},
makeStructureNS(OWS_NAMESPACE_URIS, {
'Identifier': makeObjectPropertySetter(readString),

View File

@@ -63,7 +63,7 @@ export function readDecimalString(string) {
* @param {Node} node Node.
* @return {number|undefined} Non negative integer.
*/
export function readNonNegativeInteger(node) {
export function readPositiveInteger(node) {
const s = getAllTextContent(node, false);
return readNonNegativeIntegerString(s);
}

View File

@@ -16,18 +16,16 @@
* @template T
*/
export function forEach(flatCoordinates, offset, end, stride, callback) {
const point1 = [flatCoordinates[offset], flatCoordinates[offset + 1]];
const point2 = [];
let ret;
for (; offset + stride < end; offset += stride) {
point2[0] = flatCoordinates[offset + stride];
point2[1] = flatCoordinates[offset + stride + 1];
ret = callback(point1, point2);
offset += stride;
for (; offset < end; offset += stride) {
ret = callback(
flatCoordinates.slice(offset - stride, offset),
flatCoordinates.slice(offset, offset + stride)
);
if (ret) {
return ret;
}
point1[0] = point2[0];
point1[1] = point2[1];
}
return false;
}

View File

@@ -98,7 +98,7 @@ export class DragBoxEvent extends Event {
* @typedef {import("../Observable").OnSignature<import("../Observable").EventTypes, import("../events/Event.js").default, Return> &
* import("../Observable").OnSignature<import("../ObjectEventType").Types|
* 'change:active', import("../Object").ObjectEvent, Return> &
* import("../Observable").OnSignature<'boxcancel'|'boxdrag'|'boxend', DragBoxEvent, Return> &
* import("../Observable").OnSignature<'boxcancel'|'boxdrag'|'boxend'|'boxstart', DragBoxEvent, Return> &
* import("../Observable").CombinedOnSignature<import("../Observable").EventTypes|import("../ObjectEventType").Types|
* 'change:active'|'boxcancel'|'boxdrag'|'boxend', Return>} DragBoxOnSignature
*/

View File

@@ -1247,7 +1247,7 @@ export function createBox() {
}
/**
* Get the drawing mode. The mode for mult-part geometries is the same as for
* Get the drawing mode. The mode for multi-part geometries is the same as for
* their single-part cousins.
* @param {import("../geom/GeometryType.js").default} type Geometry type.
* @return {Mode} Drawing mode.

View File

@@ -1167,7 +1167,11 @@ class Modify extends PointerInteraction {
map.forEachFeatureAtPixel(
pixel,
(feature, layer, geometry) => {
geometry = geometry || feature.getGeometry();
geometry =
geometry ||
/** @type {import("../geom/SimpleGeometry").default} */ (
feature.getGeometry()
);
if (
geometry.getType() === GeometryType.POINT &&
includes(this.features_.getArray(), feature)

View File

@@ -30,7 +30,7 @@ const SelectEventType = {
* {@link module:ol/render/Feature} and an
* {@link module:ol/layer/Layer} and returns `true` if the feature may be
* selected or `false` otherwise.
* @typedef {function(import("../Feature.js").FeatureLike, import("../layer/Layer.js").default):boolean} FilterFunction
* @typedef {function(import("../Feature.js").FeatureLike, import("../layer/Layer.js").default<import("../source/Source").default>):boolean} FilterFunction
*/
/**
@@ -49,7 +49,7 @@ const SelectEventType = {
* feature removes all from the selection.
* See `toggle`, `add`, `remove` options for adding/removing extra features to/
* from the selection.
* @property {Array<import("../layer/Layer.js").default>|function(import("../layer/Layer.js").default): boolean} [layers]
* @property {Array<import("../layer/Layer.js").default>|function(import("../layer/Layer.js").default<import("../source/Source").default>): boolean} [layers]
* A list of layers from which features should be selected. Alternatively, a
* filter function can be provided. The function will be called for each layer
* in the map and should return `true` for layers that you want to be
@@ -252,7 +252,7 @@ class Select extends Interaction {
*/
this.features_ = options.features || new Collection();
/** @type {function(import("../layer/Layer.js").default): boolean} */
/** @type {function(import("../layer/Layer.js").default<import("../source/Source").default>): boolean} */
let layerFilter;
if (options.layers) {
if (typeof options.layers === 'function') {
@@ -269,7 +269,7 @@ class Select extends Interaction {
/**
* @private
* @type {function(import("../layer/Layer.js").default): boolean}
* @type {function(import("../layer/Layer.js").default<import("../source/Source").default>): boolean}
*/
this.layerFilter_ = layerFilter;

View File

@@ -38,7 +38,7 @@ const TranslateEventType = {
* {@link module:ol/render/Feature} and an
* {@link module:ol/layer/Layer} and returns `true` if the feature may be
* translated or `false` otherwise.
* @typedef {function(import("../Feature.js").FeatureLike, import("../layer/Layer.js").default):boolean} FilterFunction
* @typedef {function(import("../Feature.js").FeatureLike, import("../layer/Layer.js").default<import("../source/Source").default>):boolean} FilterFunction
*/
/**
@@ -47,17 +47,17 @@ const TranslateEventType = {
* takes an {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a
* boolean to indicate whether that event should be handled.
* Default is {@link module:ol/events/condition.always}.
* @property {Collection<import("../Feature.js").default>} [features] Only features contained in this collection will be able to be translated. If
* not specified, all features on the map will be able to be translated.
* @property {Array<import("../layer/Layer.js").default>|function(import("../layer/Layer.js").default): boolean} [layers] A list of layers from which features should be
* @property {Collection<import("../Feature.js").default>} [features] Features contained in this collection will be able to be translated together.
* @property {Array<import("../layer/Layer.js").default>|function(import("../layer/Layer.js").default<import("../source/Source").default>): boolean} [layers] A list of layers from which features should be
* translated. Alternatively, a filter function can be provided. The
* function will be called for each layer in the map and should return
* `true` for layers that you want to be translatable. If the option is
* absent, all visible layers will be considered translatable.
* Not used if `features` is provided.
* @property {FilterFunction} [filter] A function
* that takes an {@link module:ol/Feature} and an
* {@link module:ol/layer/Layer} and returns `true` if the feature may be
* translated or `false` otherwise.
* translated or `false` otherwise. Not used if `features` is provided.
* @property {number} [hitTolerance=0] Hit-detection tolerance. Pixels inside the radius around the given position
* will be checked for features.
*/
@@ -123,6 +123,9 @@ export class TranslateEvent extends Event {
/**
* @classdesc
* Interaction for translating (moving) features.
* If you want to translate multiple features in a single action (for example,
* the collection used by a select interaction), construct the interaction with
* the `features` option.
*
* @fires TranslateEvent
* @api
@@ -171,9 +174,9 @@ class Translate extends PointerInteraction {
*/
this.features_ = options.features !== undefined ? options.features : null;
/** @type {function(import("../layer/Layer.js").default): boolean} */
/** @type {function(import("../layer/Layer.js").default<import("../source/Source").default>): boolean} */
let layerFilter;
if (options.layers) {
if (options.layers && !this.features_) {
if (typeof options.layers === 'function') {
layerFilter = options.layers;
} else {
@@ -188,7 +191,7 @@ class Translate extends PointerInteraction {
/**
* @private
* @type {function(import("../layer/Layer.js").default): boolean}
* @type {function(import("../layer/Layer.js").default<import("../source/Source").default>): boolean}
*/
this.layerFilter_ = layerFilter;
@@ -196,7 +199,7 @@ class Translate extends PointerInteraction {
* @private
* @type {FilterFunction}
*/
this.filter_ = options.filter ? options.filter : TRUE;
this.filter_ = options.filter && !this.features_ ? options.filter : TRUE;
/**
* @private

View File

@@ -13,3 +13,4 @@ export {default as Vector} from './layer/Vector.js';
export {default as VectorImage} from './layer/VectorImage.js';
export {default as VectorTile} from './layer/VectorTile.js';
export {default as WebGLPoints} from './layer/WebGLPoints.js';
export {default as WebGLTile} from './layer/WebGLTile.js';

View File

@@ -13,6 +13,14 @@ import {getIntersection} from '../extent.js';
import {getUid} from '../util.js';
import {listen, unlistenByKey} from '../events.js';
/***
* @template Return
* @typedef {import("../Observable").OnSignature<import("../Observable").EventTypes, import("../events/Event.js").default, Return> &
* import("../Observable").OnSignature<import("./Base").BaseLayerObjectEventTypes|
* 'change:layers', import("../Object").ObjectEvent, Return> &
* import("../Observable").CombinedOnSignature<import("../Observable").EventTypes|import("./Base").BaseLayerObjectEventTypes|'change:layers', Return>} GroupOnSignature
*/
/**
* @typedef {Object} Options
* @property {number} [opacity=1] Opacity (0, 1).
@@ -64,6 +72,21 @@ class LayerGroup extends BaseLayer {
super(baseOptions);
/***
* @type {GroupOnSignature<import("../Observable.js").OnReturn>}
*/
this.on;
/***
* @type {GroupOnSignature<import("../Observable.js").OnReturn>}
*/
this.once;
/***
* @type {GroupOnSignature<void>}
*/
this.un;
/**
* @private
* @type {Array<import("../events.js").EventsKey>}

323
src/ol/layer/WebGLTile.js Normal file
View File

@@ -0,0 +1,323 @@
/**
* @module ol/layer/WebGLTile
*/
import BaseTileLayer from './BaseTile.js';
import WebGLTileLayerRenderer, {
Attributes,
Uniforms,
} from '../renderer/webgl/TileLayer.js';
import {
ValueTypes,
expressionToGlsl,
getStringNumberEquivalent,
uniformNameForVariable,
} from '../style/expressions.js';
import {assign} from '../obj.js';
/**
* @typedef {Object} Style
* Translates tile data to rendered pixels.
*
* @property {Object<string, number>} [variables] Style variables. Each variable must hold a number. These
* variables can be used in the `color`, `brightness`, `contrast`, `exposure`, `saturation` and `gamma`
* {@link import("../style/expressions.js").ExpressionValue expressions}, using the `['var', 'varName']` operator.
* To update style variables, use the {@link import("./WebGLTile.js").default#updateStyleVariables} method.
* @property {import("../style/expressions.js").ExpressionValue} [color] An expression applied to color values.
* @property {import("../style/expressions.js").ExpressionValue} [brightness=0] Value used to decrease or increase
* the layer brightness. Values range from -1 to 1.
* @property {import("../style/expressions.js").ExpressionValue} [contrast=0] Value used to decrease or increase
* the layer contrast. Values range from -1 to 1.
* @property {import("../style/expressions.js").ExpressionValue} [exposure=0] Value used to decrease or increase
* the layer exposure. Values range from -1 to 1.
* @property {import("../style/expressions.js").ExpressionValue} [saturation=0] Value used to decrease or increase
* the layer saturation. Values range from -1 to 1.
* @property {import("../style/expressions.js").ExpressionValue} [gamma=1] Apply a gamma correction to the layer.
* Values range from 0 to infinity.
*/
/**
* @typedef {Object} Options
* @property {Style} [style] Style to apply to the layer.
* @property {string} [className='ol-layer'] A CSS class name to set to the layer element.
* @property {number} [opacity=1] Opacity (0, 1).
* @property {boolean} [visible=true] Visibility.
* @property {import("../extent.js").Extent} [extent] The bounding extent for layer rendering. The layer will not be
* rendered outside of this extent.
* @property {number} [zIndex] The z-index for layer rendering. At rendering time, the layers
* will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed
* for layers that are added to the map's `layers` collection, or `Infinity` when the layer's `setMap()`
* method was used.
* @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be
* visible.
* @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will
* be visible.
* @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be
* visible.
* @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will
* be visible.
* @property {number} [preload=0] Preload. Load low-resolution tiles up to `preload` levels. `0`
* means no preloading.
* @property {import("../source/Tile.js").default} [source] Source for this layer.
* @property {import("../PluggableMap.js").default} [map] Sets the layer as overlay on a map. The map will not manage
* this layer in its layers collection, and the layer will be rendered on top. This is useful for
* temporary layers. The standard way to add a layer to a map and have it managed by the map is to
* use {@link module:ol/Map#addLayer}.
* @property {boolean} [useInterimTilesOnError=true] Use interim tiles on error.
* @property {number} [cacheSize=512] The internal texture cache size. This needs to be large enough to render
* two zoom levels worth of tiles.
*/
/**
* @typedef {Object} ParsedStyle
* @property {string} vertexShader The vertex shader.
* @property {string} fragmentShader The fragment shader.
* @property {Object<string,import("../webgl/Helper.js").UniformValue>} uniforms Uniform definitions.
*/
/**
* @param {Style} style The layer style.
* @param {number} [bandCount] The number of bands.
* @return {ParsedStyle} Shaders and uniforms generated from the style.
*/
function parseStyle(style, bandCount) {
const vertexShader = `
attribute vec2 ${Attributes.TEXTURE_COORD};
uniform mat4 ${Uniforms.TILE_TRANSFORM};
uniform float ${Uniforms.DEPTH};
varying vec2 v_textureCoord;
void main() {
v_textureCoord = ${Attributes.TEXTURE_COORD};
gl_Position = ${Uniforms.TILE_TRANSFORM} * vec4(${Attributes.TEXTURE_COORD}, ${Uniforms.DEPTH}, 1.0);
}
`;
/**
* @type {import("../style/expressions.js").ParsingContext}
*/
const context = {
inFragmentShader: true,
variables: [],
attributes: [],
stringLiteralsMap: {},
bandCount: bandCount,
};
const pipeline = [];
if (style.color !== undefined) {
const color = expressionToGlsl(context, style.color, ValueTypes.COLOR);
pipeline.push(`color = ${color};`);
}
if (style.contrast !== undefined) {
const contrast = expressionToGlsl(
context,
style.contrast,
ValueTypes.NUMBER
);
pipeline.push(
`color.rgb = clamp((${contrast} + 1.0) * color.rgb - (${contrast} / 2.0), vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0));`
);
}
if (style.exposure !== undefined) {
const exposure = expressionToGlsl(
context,
style.exposure,
ValueTypes.NUMBER
);
pipeline.push(
`color.rgb = clamp((${exposure} + 1.0) * color.rgb, vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0));`
);
}
if (style.saturation !== undefined) {
const saturation = expressionToGlsl(
context,
style.saturation,
ValueTypes.NUMBER
);
pipeline.push(`
float saturation = ${saturation} + 1.0;
float sr = (1.0 - saturation) * 0.2126;
float sg = (1.0 - saturation) * 0.7152;
float sb = (1.0 - saturation) * 0.0722;
mat3 saturationMatrix = mat3(
sr + saturation, sr, sr,
sg, sg + saturation, sg,
sb, sb, sb + saturation
);
color.rgb = clamp(saturationMatrix * color.rgb, vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0));
`);
}
if (style.gamma !== undefined) {
const gamma = expressionToGlsl(context, style.gamma, ValueTypes.NUMBER);
pipeline.push(`color.rgb = pow(color.rgb, vec3(1.0 / ${gamma}));`);
}
if (style.brightness !== undefined) {
const brightness = expressionToGlsl(
context,
style.brightness,
ValueTypes.NUMBER
);
pipeline.push(
`color.rgb = clamp(color.rgb + ${brightness}, vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0));`
);
}
/** @type {Object<string,import("../webgl/Helper").UniformValue>} */
const uniforms = {};
const numVariables = context.variables.length;
if (numVariables > 1 && !style.variables) {
throw new Error(
`Missing variables in style (expected ${context.variables})`
);
}
for (let i = 0; i < numVariables; ++i) {
const variableName = context.variables[i];
if (!(variableName in style.variables)) {
throw new Error(`Missing '${variableName}' in style variables`);
}
const uniformName = uniformNameForVariable(variableName);
uniforms[uniformName] = function () {
let value = style.variables[variableName];
if (typeof value === 'string') {
value = getStringNumberEquivalent(context, value);
}
return value !== undefined ? value : -9999999; // to avoid matching with the first string literal
};
}
const uniformDeclarations = Object.keys(uniforms).map(function (name) {
return `uniform float ${name};`;
});
const textureCount = Math.ceil(bandCount / 4);
const colorAssignments = new Array(textureCount);
for (let textureIndex = 0; textureIndex < textureCount; ++textureIndex) {
const uniformName = Uniforms.TILE_TEXTURE_PREFIX + textureIndex;
uniformDeclarations.push(`uniform sampler2D ${uniformName};`);
colorAssignments[
textureIndex
] = `vec4 color${textureIndex} = texture2D(${uniformName}, v_textureCoord);`;
}
const fragmentShader = `
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
varying vec2 v_textureCoord;
uniform float ${Uniforms.TRANSITION_ALPHA};
uniform float ${Uniforms.TEXTURE_PIXEL_WIDTH};
uniform float ${Uniforms.TEXTURE_PIXEL_HEIGHT};
uniform float ${Uniforms.RESOLUTION};
uniform float ${Uniforms.ZOOM};
${uniformDeclarations.join('\n')}
void main() {
${colorAssignments.join('\n')}
vec4 color = color0;
${pipeline.join('\n')}
if (color.a == 0.0) {
discard;
}
gl_FragColor = color;
gl_FragColor.rgb *= gl_FragColor.a;
gl_FragColor *= ${Uniforms.TRANSITION_ALPHA};
}`;
return {
vertexShader: vertexShader,
fragmentShader: fragmentShader,
uniforms: uniforms,
};
}
/**
* @classdesc
* For layer sources that provide pre-rendered, tiled images in grids that are
* organized by zoom levels for specific resolutions.
* Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}
* property on the layer object; for example, setting `title: 'My Title'` in the
* options means that `title` is observable, and has get/set accessors.
*
* @extends BaseTileLayer<import("../source/DataTile.js").default|import("../source/TileImage.js").default>
* @api
*/
class WebGLTileLayer extends BaseTileLayer {
/**
* @param {Options} opt_options Tile layer options.
*/
constructor(opt_options) {
const options = opt_options ? assign({}, opt_options) : {};
const style = options.style || {};
delete options.style;
const cacheSize = options.cacheSize;
delete options.cacheSize;
super(options);
/**
* @type {Style}
* @private
*/
this.style_ = style;
/**
* @type {number}
* @private
*/
this.cacheSize_ = cacheSize;
}
/**
* Create a renderer for this layer.
* @return {import("../renderer/Layer.js").default} A layer renderer.
* @protected
*/
createRenderer() {
const source = this.getSource();
const parsedStyle = parseStyle(
this.style_,
'bandCount' in source ? source.bandCount : 4
);
this.styleVariables_ = this.style_.variables || {};
return new WebGLTileLayerRenderer(this, {
vertexShader: parsedStyle.vertexShader,
fragmentShader: parsedStyle.fragmentShader,
uniforms: parsedStyle.uniforms,
className: this.getClassName(),
cacheSize: this.cacheSize_,
});
}
/**
* Update any variables used by the layer style and trigger a re-render.
* @param {Object<string, number>} variables Variables to update.
* @api
*/
updateStyleVariables(variables) {
assign(this.styleVariables_, variables);
this.changed();
}
}
export default WebGLTileLayer;

View File

@@ -41,3 +41,110 @@ export function jsonp(url, callback, opt_errback, opt_callbackParam) {
};
document.getElementsByTagName('head')[0].appendChild(script);
}
export class ResponseError extends Error {
/**
* @param {XMLHttpRequest} response The XHR object.
*/
constructor(response) {
const message = 'Unexpected response status: ' + response.status;
super(message);
/**
* @type {string}
*/
this.name = 'ResponseError';
/**
* @type {XMLHttpRequest}
*/
this.response = response;
}
}
export class ClientError extends Error {
/**
* @param {XMLHttpRequest} client The XHR object.
*/
constructor(client) {
super('Failed to issue request');
/**
* @type {string}
*/
this.name = 'ClientError';
/**
* @type {XMLHttpRequest}
*/
this.client = client;
}
}
/**
* @param {string} url The URL.
* @return {Promise<Object>} A promise that resolves to the JSON response.
*/
export function getJSON(url) {
return new Promise(function (resolve, reject) {
/**
* @param {ProgressEvent<XMLHttpRequest>} event The load event.
*/
function onLoad(event) {
const client = event.target;
// status will be 0 for file:// urls
if (!client.status || (client.status >= 200 && client.status < 300)) {
let data;
try {
data = JSON.parse(client.responseText);
} catch (err) {
const message = 'Error parsing response text as JSON: ' + err.message;
reject(new Error(message));
return;
}
resolve(data);
return;
}
reject(new ResponseError(client));
}
/**
* @param {ProgressEvent<XMLHttpRequest>} event The error event.
*/
function onError(event) {
reject(new ClientError(event.target));
}
const client = new XMLHttpRequest();
client.addEventListener('load', onLoad);
client.addEventListener('error', onError);
client.open('GET', url);
client.setRequestHeader('Accept', 'application/json');
client.send();
});
}
/**
* @param {string} base The base URL.
* @param {string} url The potentially relative URL.
* @return {string} The full URL.
*/
export function resolveUrl(base, url) {
if (url.indexOf('://') >= 0) {
return url;
}
return new URL(url, base).href;
}
let originalXHR;
export function overrideXHR(xhr) {
if (typeof XMLHttpRequest !== 'undefined') {
originalXHR = XMLHttpRequest;
}
global.XMLHttpRequest = xhr;
}
export function restoreXHR() {
global.XMLHttpRequest = originalXHR;
}

View File

@@ -8,6 +8,11 @@
* @enum {string}
*/
const Units = {
/**
* Radians
* @api
*/
RADIANS: 'radians',
/**
* Degrees
* @api
@@ -40,6 +45,26 @@ const Units = {
USFEET: 'us-ft',
};
/**
* See http://duff.ess.washington.edu/data/raster/drg/docs/geotiff.txt
* @type {Object<number, Units>}
*/
const unitByCode = {
'9001': Units.METERS,
'9002': Units.FEET,
'9003': Units.USFEET,
'9101': Units.RADIANS,
'9102': Units.DEGREES,
};
/**
* @param {number} code Unit code.
* @return {Units} Units.
*/
export function fromCode(code) {
return unitByCode[code];
}
/**
* Meters per unit lookup table.
* @const
@@ -48,6 +73,7 @@ const Units = {
*/
export const METERS_PER_UNIT = {};
// use the radius of the Normal sphere
METERS_PER_UNIT[Units.RADIANS] = 6370997 / (2 * Math.PI);
METERS_PER_UNIT[Units.DEGREES] = (2 * Math.PI * 6370997) / 360;
METERS_PER_UNIT[Units.FEET] = 0.3048;
METERS_PER_UNIT[Units.METERS] = 1;

View File

@@ -71,6 +71,7 @@ export const PROJECTIONS = [
new EPSG3857Projection('EPSG:102100'),
new EPSG3857Projection('EPSG:102113'),
new EPSG3857Projection('EPSG:900913'),
new EPSG3857Projection('http://www.opengis.net/def/crs/EPSG/0/3857'),
new EPSG3857Projection('http://www.opengis.net/gml/srs/epsg.xml#3857'),
];

View File

@@ -63,5 +63,7 @@ export const PROJECTIONS = [
new EPSG4326Projection('EPSG:4326', 'neu'),
new EPSG4326Projection('urn:ogc:def:crs:OGC:1.3:CRS84'),
new EPSG4326Projection('urn:ogc:def:crs:OGC:2:84'),
new EPSG4326Projection('http://www.opengis.net/def/crs/OGC/1.3/CRS84', 'neu'),
new EPSG4326Projection('http://www.opengis.net/gml/srs/epsg.xml#4326', 'neu'),
new EPSG4326Projection('http://www.opengis.net/def/crs/EPSG/0/4326', 'neu'),
];

View File

@@ -10,7 +10,6 @@ import {
createSafeCoordinateTransform,
get,
} from '../proj.js';
import {assign} from '../obj.js';
import {get as getTransform} from './transforms.js';
/**
@@ -53,16 +52,10 @@ export function register(proj4) {
const code2 = projCodes[j];
const proj2 = get(code2);
if (!getTransform(code1, code2)) {
const def1 = proj4.defs(code1);
const def2 = proj4.defs(code2);
if (def1 === def2) {
if (proj4.defs[code1] === proj4.defs[code2]) {
addEquivalentProjections([proj1, proj2]);
} else {
// Reset axis because OpenLayers always uses x, y axis order
const transform = proj4(
assign({}, def1, {axis: undefined}),
assign({}, def2, {axis: undefined})
);
const transform = proj4(code1, code2);
addCoordinateTransforms(
proj1,
proj2,

View File

@@ -249,8 +249,8 @@ class CanvasImageBuilder extends CanvasBuilder {
this.image_ = image;
this.height_ = size[1];
this.opacity_ = imageStyle.getOpacity();
this.originX_ = origin[0];
this.originY_ = origin[1];
this.originX_ = origin[0] * this.imagePixelRatio_;
this.originY_ = origin[1] * this.imagePixelRatio_;
this.rotateWithView_ = imageStyle.getRotateWithView();
this.rotation_ = imageStyle.getRotation();
this.scale_ = imageStyle.getScaleArray();

View File

@@ -153,9 +153,9 @@ class CompositeMapRenderer extends MapRenderer {
* @param {import("../pixel.js").Pixel} pixel Pixel.
* @param {import("../PluggableMap.js").FrameState} frameState FrameState.
* @param {number} hitTolerance Hit tolerance in pixels.
* @param {function(import("../layer/Layer.js").default, (Uint8ClampedArray|Uint8Array)): T} callback Layer
* @param {function(import("../layer/Layer.js").default<import("../source/Source").default>, (Uint8ClampedArray|Uint8Array)): T} callback Layer
* callback.
* @param {function(import("../layer/Layer.js").default): boolean} layerFilter Layer filter
* @param {function(import("../layer/Layer.js").default<import("../source/Source").default>): boolean} layerFilter Layer filter
* function, only layers which are visible and for which this function
* returns `true` will be tested for features. By default, all visible
* layers will be tested.

View File

@@ -175,9 +175,9 @@ class MapRenderer extends Disposable {
* @param {import("../pixel.js").Pixel} pixel Pixel.
* @param {import("../PluggableMap.js").FrameState} frameState FrameState.
* @param {number} hitTolerance Hit tolerance in pixels.
* @param {function(import("../layer/Layer.js").default, (Uint8ClampedArray|Uint8Array)): T} callback Layer
* @param {function(import("../layer/Layer.js").default<import("../source/Source").default>, (Uint8ClampedArray|Uint8Array)): T} callback Layer
* callback.
* @param {function(import("../layer/Layer.js").default): boolean} layerFilter Layer filter
* @param {function(import("../layer/Layer.js").default<import("../source/Source").default>): boolean} layerFilter Layer filter
* function, only layers which are visible and for which this function
* returns `true` will be tested for features. By default, all visible
* layers will be tested.

View File

@@ -13,7 +13,7 @@ import {getUid} from '../util.js';
* unmanaged layers. The third is the {@link module:ol/geom/SimpleGeometry} of the feature. For features
* with a GeometryCollection geometry, it will be the first detected geometry from the collection.
* @template T
* @typedef {function(import("../Feature.js").FeatureLike, import("../layer/Layer.js").default, import("../geom/SimpleGeometry.js").default): T} FeatureCallback
* @typedef {function(import("../Feature.js").FeatureLike, import("../layer/Layer.js").default<import("../source/Source").default>, import("../geom/SimpleGeometry.js").default): T} FeatureCallback
*/
/**

View File

@@ -0,0 +1,541 @@
/**
* @module ol/renderer/webgl/TileLayer
*/
import LRUCache from '../../structs/LRUCache.js';
import State from '../../source/State.js';
import TileRange from '../../TileRange.js';
import TileState from '../../TileState.js';
import TileTexture from '../../webgl/TileTexture.js';
import WebGLArrayBuffer from '../../webgl/Buffer.js';
import WebGLLayerRenderer from './Layer.js';
import {AttributeType} from '../../webgl/Helper.js';
import {ELEMENT_ARRAY_BUFFER, STATIC_DRAW} from '../../webgl.js';
import {
compose as composeTransform,
create as createTransform,
} from '../../transform.js';
import {
create as createMat4,
fromTransform as mat4FromTransform,
} from '../../vec/mat4.js';
import {
createOrUpdate as createTileCoord,
getKeyZXY,
getKey as getTileCoordKey,
} from '../../tilecoord.js';
import {fromUserExtent} from '../../proj.js';
import {getIntersection} from '../../extent.js';
import {getUid} from '../../util.js';
import {isEmpty} from '../../extent.js';
import {numberSafeCompareFunction} from '../../array.js';
import {toSize} from '../../size.js';
export const Uniforms = {
TILE_TEXTURE_PREFIX: 'u_tileTexture',
TILE_TRANSFORM: 'u_tileTransform',
TRANSITION_ALPHA: 'u_transitionAlpha',
DEPTH: 'u_depth',
TEXTURE_PIXEL_WIDTH: 'u_texturePixelWidth',
TEXTURE_PIXEL_HEIGHT: 'u_texturePixelHeight',
RESOLUTION: 'u_resolution',
ZOOM: 'u_zoom',
};
export const Attributes = {
TEXTURE_COORD: 'a_textureCoord',
};
/**
* @type {Array<import('../../webgl/Helper.js').AttributeDescription>}
*/
const attributeDescriptions = [
{
name: Attributes.TEXTURE_COORD,
size: 2,
type: AttributeType.FLOAT,
},
];
const empty = {};
/**
* Transform a zoom level into a depth value ranging from -1 to 1.
* @param {number} z A zoom level.
* @return {number} A depth value.
*/
function depthForZ(z) {
return 2 * (1 - 1 / (z + 1)) - 1;
}
/**
* Add a tile texture to the lookup.
* @param {Object<string, Array<import("../../webgl/TileTexture.js").default>>} tileTexturesByZ Lookup of
* tile textures by zoom level.
* @param {import("../../webgl/TileTexture.js").default} tileTexture A tile texture.
* @param {number} z The zoom level.
*/
function addTileTextureToLookup(tileTexturesByZ, tileTexture, z) {
if (!(z in tileTexturesByZ)) {
tileTexturesByZ[z] = [];
}
tileTexturesByZ[z].push(tileTexture);
}
/**
*
* @param {import("../../PluggableMap.js").FrameState} frameState Frame state.
* @return {import("../../extent.js").Extent} Extent.
*/
function getRenderExtent(frameState) {
const layerState = frameState.layerStatesArray[frameState.layerIndex];
let extent = frameState.extent;
if (layerState.extent) {
extent = getIntersection(
extent,
fromUserExtent(layerState.extent, frameState.viewState.projection)
);
}
return extent;
}
/**
* @typedef {Object} Options
* @property {string} vertexShader Vertex shader source.
* @property {string} fragmentShader Fragment shader source.
* @property {Object<string, import("../../webgl/Helper").UniformValue>} [uniforms] Additional uniforms
* made available to shaders.
* @property {string} [className='ol-layer'] A CSS class name to set to the canvas element.
* @property {number} [cacheSize=512] The texture cache size.
*/
/**
* @classdesc
* WebGL renderer for tile layers.
* @api
*/
class WebGLTileLayerRenderer extends WebGLLayerRenderer {
/**
* @param {import("../../layer/WebGLTile.js").default} tileLayer Tile layer.
* @param {Options} options Options.
*/
constructor(tileLayer, options) {
super(tileLayer, {
uniforms: options.uniforms,
className: options.className,
});
/**
* This transform converts tile i, j coordinates to screen coordinates.
* @type {import("../../transform.js").Transform}
* @private
*/
this.tileTransform_ = createTransform();
/**
* @type {Array<number>}
* @private
*/
this.tempMat4_ = createMat4();
/**
* @type {import("../../TileRange.js").default}
* @private
*/
this.tempTileRange_ = new TileRange(0, 0, 0, 0);
/**
* @type {import("../../tilecoord.js").TileCoord}
* @private
*/
this.tempTileCoord_ = createTileCoord(0, 0, 0);
/**
* @type {import("../../size.js").Size}
* @private
*/
this.tempSize_ = [0, 0];
this.program_ = this.helper.getProgram(
options.fragmentShader,
options.vertexShader
);
/**
* Tiles are rendered as a quad with the following structure:
*
* [P3]---------[P2]
* |` |
* | ` B |
* | ` |
* | ` |
* | A ` |
* | ` |
* [P0]---------[P1]
*
* Triangle A: P0, P1, P3
* Triangle B: P1, P2, P3
*/
const indices = new WebGLArrayBuffer(ELEMENT_ARRAY_BUFFER, STATIC_DRAW);
indices.fromArray([0, 1, 3, 1, 2, 3]);
this.helper.flushBufferData(indices);
this.indices_ = indices;
const cacheSize = options.cacheSize !== undefined ? options.cacheSize : 512;
this.tileTextureCache_ = new LRUCache(cacheSize);
this.renderedOpacity_ = NaN;
}
/**
* @protected
* @param {import("../../Tile.js").default} tile Tile.
* @return {boolean} Tile is drawable.
*/
isDrawableTile(tile) {
const tileLayer = this.getLayer();
const tileState = tile.getState();
const useInterimTilesOnError = tileLayer.getUseInterimTilesOnError();
return (
tileState == TileState.LOADED ||
tileState == TileState.EMPTY ||
(tileState == TileState.ERROR && !useInterimTilesOnError)
);
}
/**
* Determine whether render should be called.
* @param {import("../../PluggableMap.js").FrameState} frameState Frame state.
* @return {boolean} Layer is ready to be rendered.
*/
prepareFrame(frameState) {
if (isEmpty(getRenderExtent(frameState))) {
return false;
}
const source = this.getLayer().getSource();
if (!source) {
return false;
}
return source.getState() === State.READY;
}
/**
* Render the layer.
* @param {import("../../PluggableMap.js").FrameState} frameState Frame state.
* @return {HTMLElement} The rendered element.
*/
renderFrame(frameState) {
this.preRender(frameState);
const viewState = frameState.viewState;
const layerState = frameState.layerStatesArray[frameState.layerIndex];
const extent = getRenderExtent(frameState);
const tileLayer = this.getLayer();
const tileSource = tileLayer.getSource();
const tileGrid = tileSource.getTileGridForProjection(viewState.projection);
const z = tileGrid.getZForResolution(
viewState.resolution,
tileSource.zDirection
);
/**
* @type {Object<string, Array<import("../../webgl/TileTexture.js").default>>}
*/
const tileTexturesByZ = {};
const tileTextureCache = this.tileTextureCache_;
const tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);
const tileSourceKey = getUid(tileSource);
if (!(tileSourceKey in frameState.wantedTiles)) {
frameState.wantedTiles[tileSourceKey] = {};
}
const wantedTiles = frameState.wantedTiles[tileSourceKey];
const tileResolution = tileGrid.getResolution(z);
for (let x = tileRange.minX; x <= tileRange.maxX; ++x) {
for (let y = tileRange.minY; y <= tileRange.maxY; ++y) {
const tileCoord = createTileCoord(z, x, y, this.tempTileCoord_);
const tileCoordKey = getTileCoordKey(tileCoord);
let tileTexture, tile;
if (tileTextureCache.containsKey(tileCoordKey)) {
tileTexture = tileTextureCache.get(tileCoordKey);
tile = tileTexture.tile;
}
if (!tileTexture || tileTexture.tile.key !== tileSource.getKey()) {
tile = tileSource.getTile(
z,
x,
y,
frameState.pixelRatio,
viewState.projection
);
if (!tileTexture) {
tileTexture = new TileTexture(tile, tileGrid, this.helper);
tileTextureCache.set(tileCoordKey, tileTexture);
} else {
tileTexture.setTile(
this.isDrawableTile(tile) ? tile : tile.getInterimTile()
);
}
}
addTileTextureToLookup(tileTexturesByZ, tileTexture, z);
const tileQueueKey = tile.getKey();
wantedTiles[tileQueueKey] = true;
if (tile.getState() === TileState.IDLE) {
if (!frameState.tileQueue.isKeyQueued(tileQueueKey)) {
frameState.tileQueue.enqueue([
tile,
tileSourceKey,
tileGrid.getTileCoordCenter(tileCoord),
tileResolution,
]);
}
}
}
}
/**
* A lookup of alpha values for tiles at the target rendering resolution
* for tiles that are in transition. If a tile coord key is absent from
* this lookup, the tile should be rendered at alpha 1.
* @type {Object<string, number>}
*/
const alphaLookup = {};
const uid = getUid(this);
const time = frameState.time;
let blend = false;
// look for cached tiles to use if a target tile is not ready
const tileTextures = tileTexturesByZ[z];
for (let i = 0, ii = tileTextures.length; i < ii; ++i) {
const tileTexture = tileTextures[i];
const tile = tileTexture.tile;
const tileCoord = tile.tileCoord;
if (tileTexture.loaded) {
const alpha = tile.getAlpha(uid, time);
if (alpha === 1) {
// no need to look for alt tiles
tile.endTransition(uid);
continue;
}
blend = true;
const tileCoordKey = getTileCoordKey(tileCoord);
alphaLookup[tileCoordKey] = alpha;
}
// first look for child tiles (at z + 1)
const coveredByChildren = this.findAltTiles_(
tileGrid,
tileCoord,
z + 1,
tileTexturesByZ
);
if (coveredByChildren) {
continue;
}
// next look for parent tiles
for (let parentZ = z - 1; parentZ >= tileGrid.minZoom; --parentZ) {
const coveredByParent = this.findAltTiles_(
tileGrid,
tileCoord,
parentZ,
tileTexturesByZ
);
if (coveredByParent) {
break;
}
}
}
this.helper.useProgram(this.program_);
this.helper.prepareDraw(frameState, !blend);
const zs = Object.keys(tileTexturesByZ)
.map(Number)
.sort(numberSafeCompareFunction);
const gl = this.helper.getGL();
const centerX = viewState.center[0];
const centerY = viewState.center[1];
for (let j = 0, jj = zs.length; j < jj; ++j) {
const tileZ = zs[j];
const tileResolution = tileGrid.getResolution(tileZ);
const tileSize = toSize(tileGrid.getTileSize(tileZ), this.tempSize_);
const tileOrigin = tileGrid.getOrigin(tileZ);
const centerI =
(centerX - tileOrigin[0]) / (tileSize[0] * tileResolution);
const centerJ =
(tileOrigin[1] - centerY) / (tileSize[1] * tileResolution);
const tileScale = viewState.resolution / tileResolution;
const depth = depthForZ(tileZ);
const tileTextures = tileTexturesByZ[tileZ];
for (let i = 0, ii = tileTextures.length; i < ii; ++i) {
const tileTexture = tileTextures[i];
if (!tileTexture.loaded) {
continue;
}
const tile = tileTexture.tile;
const tileCoord = tile.tileCoord;
const tileCoordKey = getTileCoordKey(tileCoord);
const tileCenterI = tileCoord[1];
const tileCenterJ = tileCoord[2];
composeTransform(
this.tileTransform_,
0,
0,
2 / ((frameState.size[0] * tileScale) / tileSize[0]),
-2 / ((frameState.size[1] * tileScale) / tileSize[1]),
viewState.rotation,
-(centerI - tileCenterI),
-(centerJ - tileCenterJ)
);
this.helper.setUniformMatrixValue(
Uniforms.TILE_TRANSFORM,
mat4FromTransform(this.tempMat4_, this.tileTransform_)
);
this.helper.bindBuffer(tileTexture.coords);
this.helper.bindBuffer(this.indices_);
this.helper.enableAttributes(attributeDescriptions);
for (
let textureIndex = 0;
textureIndex < tileTexture.textures.length;
++textureIndex
) {
const textureProperty = 'TEXTURE' + textureIndex;
const uniformName = Uniforms.TILE_TEXTURE_PREFIX + textureIndex;
gl.activeTexture(gl[textureProperty]);
gl.bindTexture(gl.TEXTURE_2D, tileTexture.textures[textureIndex]);
gl.uniform1i(this.helper.getUniformLocation(uniformName), 0);
}
const alpha =
tileCoordKey in alphaLookup ? alphaLookup[tileCoordKey] : 1;
if (alpha < 1) {
frameState.animate = true;
}
this.helper.setUniformFloatValue(Uniforms.TRANSITION_ALPHA, alpha);
this.helper.setUniformFloatValue(Uniforms.DEPTH, depth);
this.helper.setUniformFloatValue(
Uniforms.TEXTURE_PIXEL_WIDTH,
tileSize[0]
);
this.helper.setUniformFloatValue(
Uniforms.TEXTURE_PIXEL_HEIGHT,
tileSize[1]
);
this.helper.setUniformFloatValue(
Uniforms.RESOLUTION,
viewState.resolution
);
this.helper.setUniformFloatValue(Uniforms.ZOOM, viewState.zoom);
this.helper.drawElements(0, this.indices_.getSize());
}
}
this.helper.finalizeDraw(frameState);
const canvas = this.helper.getCanvas();
const opacity = layerState.opacity;
if (this.renderedOpacity_ !== opacity) {
canvas.style.opacity = String(opacity);
this.renderedOpacity_ = opacity;
}
while (tileTextureCache.canExpireCache()) {
const tileTexture = tileTextureCache.pop();
tileTexture.dispose();
}
// TODO: let the renderers manage their own cache instead of managing the source cache
/**
* Here we unconditionally expire the source cache since the renderer maintains
* its own cache.
* @param {import("../../PluggableMap.js").default} map Map.
* @param {import("../../PluggableMap.js").FrameState} frameState Frame state.
*/
const postRenderFunction = function (map, frameState) {
tileSource.expireCache(tileSource.getProjection(), empty);
};
frameState.postRenderFunctions.push(postRenderFunction);
this.postRender(frameState);
return canvas;
}
/**
* Look for tiles covering the provided tile coordinate at an alternate
* zoom level. Loaded tiles will be added to the provided tile texture lookup.
* @param {import("../../tilegrid/TileGrid.js").default} tileGrid The tile grid.
* @param {import("../../tilecoord.js").TileCoord} tileCoord The target tile coordinate.
* @param {number} altZ The alternate zoom level.
* @param {Object<string, Array<import("../../webgl/TileTexture.js").default>>} tileTexturesByZ Lookup of
* tile textures by zoom level.
* @return {boolean} The tile coordinate is covered by loaded tiles at the alternate zoom level.
* @private
*/
findAltTiles_(tileGrid, tileCoord, altZ, tileTexturesByZ) {
const tileRange = tileGrid.getTileRangeForTileCoordAndZ(
tileCoord,
altZ,
this.tempTileRange_
);
if (!tileRange) {
return false;
}
let covered = true;
const tileTextureCache = this.tileTextureCache_;
for (let x = tileRange.minX; x <= tileRange.maxX; ++x) {
for (let y = tileRange.minY; y <= tileRange.maxY; ++y) {
const cacheKey = getKeyZXY(altZ, x, y);
let loaded = false;
if (tileTextureCache.containsKey(cacheKey)) {
const tileTexture = tileTextureCache.get(cacheKey);
if (tileTexture.loaded) {
addTileTextureToLookup(tileTexturesByZ, tileTexture, altZ);
loaded = true;
}
}
if (!loaded) {
covered = false;
}
}
}
return covered;
}
}
/**
* @function
* @return {import("../../layer/WebGLTile.js").default}
*/
WebGLTileLayerRenderer.prototype.getLayer;
export default WebGLTileLayerRenderer;

View File

@@ -5,6 +5,8 @@
export {default as BingMaps} from './source/BingMaps.js';
export {default as CartoDB} from './source/CartoDB.js';
export {default as Cluster} from './source/Cluster.js';
export {default as DataTile} from './source/DataTile.js';
export {default as GeoTIFF} from './source/GeoTIFF.js';
export {default as IIIF} from './source/IIIF.js';
export {default as Image} from './source/Image.js';
export {default as ImageArcGISRest} from './source/ImageArcGISRest.js';

View File

@@ -40,6 +40,18 @@ import {getUid} from '../util.js';
* ```
* See {@link module:ol/geom/Polygon~Polygon#getInteriorPoint} for a way to get a cluster
* calculation point for polygons.
* @property {function(Point, Array<Feature>):Feature} [createCluster]
* Function that takes the cluster's center {@link module:ol/geom/Point} and an array
* of {@link module:ol/Feature} included in this cluster. Must return a
* {@link module:ol/Feature} that will be used to render. Default implementation is:
* ```js
* function(point, features) {
* return new Feature({
* geometry: point,
* features: features
* });
* }
* ```
* @property {VectorSource} [source] Source.
* @property {boolean} [wrapX=true] Whether to wrap the world horizontally.
*/
@@ -108,6 +120,12 @@ class Cluster extends VectorSource {
return geometry;
};
/**
* @type {function(Point, Array<Feature>):Feature}
* @private
*/
this.createCustomCluster_ = options.createCluster;
/**
* @type {VectorSource}
* @protected
@@ -294,9 +312,14 @@ class Cluster extends VectorSource {
centroid[0] * (1 - ratio) + searchCenter[0] * ratio,
centroid[1] * (1 - ratio) + searchCenter[1] * ratio,
]);
const cluster = new Feature(geometry);
cluster.set('features', features, true);
return cluster;
if (this.createCustomCluster_) {
return this.createCustomCluster_(geometry, features);
} else {
return new Feature({
geometry,
features,
});
}
}
}

152
src/ol/source/DataTile.js Normal file
View File

@@ -0,0 +1,152 @@
/**
* @module ol/source/DataTile
*/
import DataTile from '../DataTile.js';
import EventType from '../events/EventType.js';
import TileEventType from './TileEventType.js';
import TileSource, {TileSourceEvent} from './Tile.js';
import TileState from '../TileState.js';
import {assign} from '../obj.js';
import {createXYZ, extentFromProjection} from '../tilegrid.js';
import {getKeyZXY} from '../tilecoord.js';
import {getUid} from '../util.js';
/**
* @typedef {Object} Options
* @property {function(number, number, number) : Promise<import("../DataTile.js").Data>} [loader] Data loader. Called with z, x, and y tile coordinates.
* Returns a promise that resolves to a {@link import("../DataTile.js").Data}.
* @property {number} [maxZoom=42] Optional max zoom level. Not used if `tileGrid` is provided.
* @property {number} [minZoom=0] Optional min zoom level. Not used if `tileGrid` is provided.
* @property {number|import("../size.js").Size} [tileSize=[256, 256]] The pixel width and height of the tiles.
* @property {number} [maxResolution] Optional tile grid resolution at level zero. Not used if `tileGrid` is provided.
* @property {import("../proj.js").ProjectionLike} [projection='EPSG:3857'] Tile projection.
* @property {import("../tilegrid/TileGrid.js").default} [tileGrid] Tile grid.
* @property {boolean} [opaque=false] Whether the layer is opaque.
* @property {import("./State.js").default} [state] The source state.
* @property {number} [tilePixelRatio] Tile pixel ratio.
* @property {boolean} [wrapX=true] Render tiles beyond the antimeridian.
* @property {number} [transition] Transition time when fading in new tiles (in miliseconds).
*/
/**
* @classdesc
* Base class for sources providing tiles divided into a tile grid.
*
* @fires import("./Tile.js").TileSourceEvent
* @api
*/
class DataTileSource extends TileSource {
/**
* @param {Options} options Image tile options.
*/
constructor(options) {
const projection =
options.projection === undefined ? 'EPSG:3857' : options.projection;
let tileGrid = options.tileGrid;
if (tileGrid === undefined && projection) {
tileGrid = createXYZ({
extent: extentFromProjection(projection),
maxResolution: options.maxResolution,
maxZoom: options.maxZoom,
minZoom: options.minZoom,
tileSize: options.tileSize,
});
}
super({
cacheSize: 0.1, // don't cache on the source
projection: projection,
tileGrid: tileGrid,
opaque: options.opaque,
state: options.state,
tilePixelRatio: options.tilePixelRatio,
wrapX: options.wrapX,
transition: options.transition,
});
/**
* @private
* @type {!Object<string, boolean>}
*/
this.tileLoadingKeys_ = {};
/**
* @private
*/
this.loader_ = options.loader;
this.handleTileChange_ = this.handleTileChange_.bind(this);
/**
* @type {number}
*/
this.bandCount = 4; // assume RGBA
}
/**
* @param {function(number, number, number) : Promise<import("../DataTile.js").Data>} loader The data loader.
* @protected
*/
setLoader(loader) {
this.loader_ = loader;
}
/**
* @abstract
* @param {number} z Tile coordinate z.
* @param {number} x Tile coordinate x.
* @param {number} y Tile coordinate y.
* @param {number} pixelRatio Pixel ratio.
* @param {import("../proj/Projection.js").default} projection Projection.
* @return {!DataTile} Tile.
*/
getTile(z, x, y, pixelRatio, projection) {
const tileCoordKey = getKeyZXY(z, x, y);
if (this.tileCache.containsKey(tileCoordKey)) {
return this.tileCache.get(tileCoordKey);
}
const sourceLoader = this.loader_;
function loader() {
return sourceLoader(z, x, y);
}
const tile = new DataTile(
assign({tileCoord: [z, x, y], loader: loader}, this.tileOptions)
);
tile.key = this.getKey();
tile.addEventListener(EventType.CHANGE, this.handleTileChange_);
this.tileCache.set(tileCoordKey, tile);
return tile;
}
/**
* Handle tile change events.
* @param {import("../events/Event.js").default} event Event.
*/
handleTileChange_(event) {
const tile = /** @type {import("../Tile.js").default} */ (event.target);
const uid = getUid(tile);
const tileState = tile.getState();
let type;
if (tileState == TileState.LOADING) {
this.tileLoadingKeys_[uid] = true;
type = TileEventType.TILELOADSTART;
} else if (uid in this.tileLoadingKeys_) {
delete this.tileLoadingKeys_[uid];
type =
tileState == TileState.ERROR
? TileEventType.TILELOADERROR
: tileState == TileState.LOADED
? TileEventType.TILELOADEND
: undefined;
}
if (type) {
this.dispatchEvent(new TileSourceEvent(type, tile));
}
}
}
export default DataTileSource;

652
src/ol/source/GeoTIFF.js Normal file
View File

@@ -0,0 +1,652 @@
/**
* @module ol/source/GeoTIFF
*/
import DataTile from './DataTile.js';
import State from './State.js';
import TileGrid from '../tilegrid/TileGrid.js';
import {Pool, fromUrl as tiffFromUrl, fromUrls as tiffFromUrls} from 'geotiff';
import {Projection, get as getCachedProjection} from '../proj.js';
import {create as createDecoderWorker} from '../worker/geotiff-decoder.js';
import {getIntersection} from '../extent.js';
import {toSize} from '../size.js';
import {fromCode as unitsFromCode} from '../proj/Units.js';
/**
* @typedef {Object} SourceInfo
* @property {string} url URL for the source GeoTIFF.
* @property {Array<string>} [overviews] List of any overview URLs.
* @property {number} [min=0] The minimum source data value. Rendered values are scaled from 0 to 1 based on
* the configured min and max.
* @property {number} [max] The maximum source data value. Rendered values are scaled from 0 to 1 based on
* the configured min and max.
* @property {number} [nodata] Values to discard. When provided, an additional band (alpha) will be added
* to the data.
* @property {Array<number>} [bands] Band numbers to be read from (where the first band is `1`). If not provided, all bands will
* be read. For example, if a GeoTIFF has blue (1), green (2), red (3), and near-infrared (4) bands, and you only need the
* near-infrared band, configure `bands: [4]`.
*/
/**
* @typedef {Object} GeoKeys
* @property {number} GTModelTypeGeoKey Model type.
* @property {number} GTRasterTypeGeoKey Raster type.
* @property {number} GeogAngularUnitsGeoKey Angular units.
* @property {number} GeogInvFlatteningGeoKey Inverse flattening.
* @property {number} GeogSemiMajorAxisGeoKey Semi-major axis.
* @property {number} GeographicTypeGeoKey Geographic coordinate system code.
* @property {number} ProjLinearUnitsGeoKey Projected linear unit code.
* @property {number} ProjectedCSTypeGeoKey Projected coordinate system code.
*/
/**
* @typedef {Object} GeoTIFFImage
* @property {Object} fileDirectory The file directory.
* @property {GeoKeys} geoKeys The parsed geo-keys.
* @property {boolean} littleEndian Uses little endian byte order.
* @property {Object} tiles The tile cache.
* @property {boolean} isTiled The image is tiled.
* @property {function():Array<number>} getBoundingBox Get the image bounding box.
* @property {function():Array<number>} getOrigin Get the image origin.
* @property {function(GeoTIFFImage):Array<number>} getResolution Get the image resolution.
*/
let workerPool;
function getWorkerPool() {
if (!workerPool) {
workerPool = new Pool(undefined, createDecoderWorker());
}
return workerPool;
}
/**
* Get the bounding box of an image. If the image does not have an affine transform,
* the pixel bounds are returned.
* @param {GeoTIFFImage} image The image.
* @return {Array<number>} The image bounding box.
*/
function getBoundingBox(image) {
try {
return image.getBoundingBox();
} catch (_) {
const fileDirectory = image.fileDirectory;
return [0, 0, fileDirectory.ImageWidth, fileDirectory.ImageLength];
}
}
/**
* Get the origin of an image. If the image does not have an affine transform,
* the top-left corner of the pixel bounds is returned.
* @param {GeoTIFFImage} image The image.
* @return {Array<number>} The image origin.
*/
function getOrigin(image) {
try {
return image.getOrigin().slice(0, 2);
} catch (_) {
return [0, image.fileDirectory.ImageLength];
}
}
/**
* Get the resolution of an image. If the image does not have an affine transform,
* the width of the image is compared with the reference image.
* @param {GeoTIFFImage} image The image.
* @param {GeoTIFFImage} referenceImage The reference image.
* @return {number} The image resolution.
*/
function getResolution(image, referenceImage) {
try {
return image.getResolution(referenceImage)[0];
} catch (_) {
return (
referenceImage.fileDirectory.ImageWidth / image.fileDirectory.ImageWidth
);
}
}
/**
* @param {GeoTIFFImage} image A GeoTIFF.
* @return {import("../proj/Projection.js").default} The image projection.
*/
function getProjection(image) {
const geoKeys = image.geoKeys;
if (!geoKeys) {
return null;
}
if (geoKeys.ProjectedCSTypeGeoKey) {
const code = 'EPSG:' + geoKeys.ProjectedCSTypeGeoKey;
let projection = getCachedProjection(code);
if (!projection) {
const units = unitsFromCode(geoKeys.ProjLinearUnitsGeoKey);
if (units) {
projection = new Projection({
code: code,
units: units,
});
}
}
return projection;
}
if (geoKeys.GeographicTypeGeoKey) {
const code = 'EPSG:' + geoKeys.GeographicTypeGeoKey;
let projection = getCachedProjection(code);
if (!projection) {
const units = unitsFromCode(geoKeys.GeogAngularUnitsGeoKey);
if (units) {
projection = new Projection({
code: code,
units: units,
});
}
}
return projection;
}
return null;
}
/**
* @param {import("geotiff/src/geotiff.js").GeoTIFF|import("geotiff/src/geotiff.js").MultiGeoTIFF} tiff A GeoTIFF.
* @return {Promise<Array<import("geotiff/src/geotiffimage.js").GeoTIFFImage>>} Resolves to a list of images.
*/
function getImagesForTIFF(tiff) {
return tiff.getImageCount().then(function (count) {
const requests = new Array(count);
for (let i = 0; i < count; ++i) {
requests[i] = tiff.getImage(i);
}
return Promise.all(requests);
});
}
/**
* @param {SourceInfo} source The GeoTIFF source.
* @return {Promise<Array<import("geotiff/src/geotiffimage.js").GeoTIFFImage>>} Resolves to a list of images.
*/
function getImagesForSource(source) {
let request;
if (source.overviews) {
request = tiffFromUrls(source.url, source.overviews);
} else {
request = tiffFromUrl(source.url);
}
return request.then(getImagesForTIFF);
}
/**
* @param {number|Array<number>|Array<Array<number>>} expected Expected value.
* @param {number|Array<number>|Array<Array<number>>} got Actual value.
* @param {number} tolerance Accepted tolerance in fraction of expected between expected and got.
* @param {string} message The error message.
*/
function assertEqual(expected, got, tolerance, message) {
if (Array.isArray(expected)) {
const length = expected.length;
if (!Array.isArray(got) || length != got.length) {
throw new Error(message);
}
for (let i = 0; i < length; ++i) {
assertEqual(expected[i], got[i], tolerance, message);
}
return;
}
got = /** @type {number} */ (got);
if (Math.abs(expected - got) > tolerance * expected) {
throw new Error(message);
}
}
/**
* @param {Array} array The data array.
* @return {number} The minimum value.
*/
function getMinForDataType(array) {
if (array instanceof Int8Array) {
return -128;
}
if (array instanceof Int16Array) {
return -32768;
}
if (array instanceof Int32Array) {
return -2147483648;
}
if (array instanceof Float32Array) {
return 1.2e-38;
}
return 0;
}
/**
* @param {Array} array The data array.
* @return {number} The maximum value.
*/
function getMaxForDataType(array) {
if (array instanceof Int8Array) {
return 127;
}
if (array instanceof Uint8Array) {
return 255;
}
if (array instanceof Uint8ClampedArray) {
return 255;
}
if (array instanceof Int16Array) {
return 32767;
}
if (array instanceof Uint16Array) {
return 65535;
}
if (array instanceof Int32Array) {
return 2147483647;
}
if (array instanceof Uint32Array) {
return 4294967295;
}
if (array instanceof Float32Array) {
return 3.4e38;
}
return 255;
}
/**
* @typedef {Object} Options
* @property {Array<SourceInfo>} sources List of information about GeoTIFF sources.
* Multiple sources can be combined when their resolution sets are equal after applying a scale.
* The list of sources defines a mapping between input bands as they are read from each GeoTIFF and
* the output bands that are provided by data tiles. To control which bands to read from each GeoTIFF,
* use the {@link import("./GeoTIFF.js").SourceInfo bands} property. If, for example, you specify two
* sources, one with 3 bands and {@link import("./GeoTIFF.js").SourceInfo nodata} configured, and
* another with 1 band, the resulting data tiles will have 5 bands: 3 from the first source, 1 alpha
* band from the first source, and 1 band from the second source.
* @property {boolean} [convertToRGB = false] By default, bands from the sources are read as-is. When
* reading GeoTIFFs with the purpose of displaying them as RGB images, setting this to `true` will
* convert other color spaces (YCbCr, CMYK) to RGB.
* @property {boolean} [opaque=false] Whether the layer is opaque.
* @property {number} [transition=250] Duration of the opacity transition for rendering.
* To disable the opacity transition, pass `transition: 0`.
*/
/**
* @classdesc
* A source for working with GeoTIFF data.
* @api
*/
class GeoTIFFSource extends DataTile {
/**
* @param {Options} options Data tile options.
*/
constructor(options) {
super({
state: State.LOADING,
tileGrid: null,
projection: null,
opaque: options.opaque,
transition: options.transition,
});
/**
* @type {Array<SourceInfo>}
* @private
*/
this.sourceInfo_ = options.sources;
const numSources = this.sourceInfo_.length;
/**
* @type {Array<Array<import("geotiff/src/geotiffimage.js").GeoTIFFImage>>}
* @private
*/
this.sourceImagery_ = new Array(numSources);
/**
* @type {Array<number>}
* @private
*/
this.resolutionFactors_ = new Array(numSources);
/**
* @type {Array<number>}
* @private
*/
this.samplesPerPixel_;
/**
* @type {Array<Array<number>>}
* @private
*/
this.nodataValues_;
/**
* @type {boolean}
* @private
*/
this.addAlpha_ = false;
/**
* @type {Error}
* @private
*/
this.error_ = null;
/**
* @type {'readRasters' | 'readRGB'}
*/
this.readMethod_ = options.convertToRGB ? 'readRGB' : 'readRasters';
this.setKey(this.sourceInfo_.map((source) => source.url).join(','));
const self = this;
const requests = new Array(numSources);
for (let i = 0; i < numSources; ++i) {
requests[i] = getImagesForSource(this.sourceInfo_[i]);
}
Promise.all(requests)
.then(function (sources) {
self.configure_(sources);
})
.catch(function (error) {
console.error(error); // eslint-disable-line no-console
self.error_ = error;
self.setState(State.ERROR);
});
}
/**
* @return {Error} A source loading error. When the source state is `error`, use this function
* to get more information about the error. To debug a faulty configuration, you may want to use
* a listener like
* ```js
* geotiffSource.on('change', () => {
* if (geotiffSource.getState() === 'error') {
* console.error(geotiffSource.getError());
* }
* });
* ```
*/
getError() {
return this.error_;
}
/**
* Configure the tile grid based on images within the source GeoTIFFs. Each GeoTIFF
* must have the same internal tiled structure.
* @param {Array<Array<import("geotiff/src/geotiffimage.js").GeoTIFFImage>>} sources Each source is a list of images
* from a single GeoTIFF.
* @private
*/
configure_(sources) {
let extent;
let origin;
let tileSizes;
let resolutions;
const samplesPerPixel = new Array(sources.length);
const nodataValues = new Array(sources.length);
let minZoom = 0;
const sourceCount = sources.length;
for (let sourceIndex = 0; sourceIndex < sourceCount; ++sourceIndex) {
const images = sources[sourceIndex];
const imageCount = images.length;
let sourceExtent;
let sourceOrigin;
const sourceTileSizes = new Array(imageCount);
const sourceResolutions = new Array(imageCount);
nodataValues[sourceIndex] = new Array(imageCount);
for (let imageIndex = 0; imageIndex < imageCount; ++imageIndex) {
const image = images[imageIndex];
const nodataValue = image.getGDALNoData();
nodataValues[sourceIndex][imageIndex] =
nodataValue === null ? NaN : nodataValue;
const wantedSamples = this.sourceInfo_[sourceIndex].bands;
samplesPerPixel[sourceIndex] = wantedSamples
? wantedSamples.length
: image.getSamplesPerPixel();
const level = imageCount - (imageIndex + 1);
if (!sourceExtent) {
sourceExtent = getBoundingBox(image);
}
if (!sourceOrigin) {
sourceOrigin = getOrigin(image);
}
sourceResolutions[level] = getResolution(image, images[0]);
sourceTileSizes[level] = [image.getTileWidth(), image.getTileHeight()];
}
if (!extent) {
extent = sourceExtent;
} else {
getIntersection(extent, sourceExtent, extent);
}
if (!origin) {
origin = sourceOrigin;
} else {
const message = `Origin mismatch for source ${sourceIndex}, got [${sourceOrigin}] but expected [${origin}]`;
assertEqual(origin, sourceOrigin, 0, message);
}
if (!resolutions) {
resolutions = sourceResolutions;
this.resolutionFactors_[sourceIndex] = 1;
} else {
if (resolutions.length - minZoom > sourceResolutions.length) {
minZoom = resolutions.length - sourceResolutions.length;
}
const resolutionFactor =
resolutions[resolutions.length - 1] /
sourceResolutions[sourceResolutions.length - 1];
this.resolutionFactors_[sourceIndex] = resolutionFactor;
const scaledSourceResolutions = sourceResolutions.map(
(resolution) => (resolution *= resolutionFactor)
);
const message = `Resolution mismatch for source ${sourceIndex}, got [${scaledSourceResolutions}] but expected [${resolutions}]`;
assertEqual(
resolutions.slice(minZoom, resolutions.length),
scaledSourceResolutions,
0.005,
message
);
}
if (!tileSizes) {
tileSizes = sourceTileSizes;
} else {
assertEqual(
tileSizes.slice(minZoom, tileSizes.length),
sourceTileSizes,
0,
`Tile size mismatch for source ${sourceIndex}`
);
}
this.sourceImagery_[sourceIndex] = images.reverse();
}
for (let i = 0, ii = this.sourceImagery_.length; i < ii; ++i) {
const sourceImagery = this.sourceImagery_[i];
while (sourceImagery.length < resolutions.length) {
sourceImagery.unshift(undefined);
}
}
if (!this.getProjection()) {
const firstSource = sources[0];
for (let i = firstSource.length - 1; i >= 0; --i) {
const image = firstSource[i];
const projection = getProjection(image);
if (projection) {
this.projection = projection;
break;
}
}
}
this.samplesPerPixel_ = samplesPerPixel;
this.nodataValues_ = nodataValues;
// decide if we need to add an alpha band to handle nodata
outer: for (let sourceIndex = 0; sourceIndex < sourceCount; ++sourceIndex) {
// option 1: source is configured with a nodata value
if (this.sourceInfo_[sourceIndex].nodata !== undefined) {
this.addAlpha_ = true;
break;
}
const values = nodataValues[sourceIndex];
// option 2: check image metadata for limited bands
const bands = this.sourceInfo_[sourceIndex].bands;
if (bands) {
for (let i = 0; i < bands.length; ++i) {
if (!isNaN(values[bands[i] - 1])) {
this.addAlpha_ = true;
break outer;
}
}
continue;
}
// option 3: check image metadata for all bands
for (let imageIndex = 0; imageIndex < values.length; ++imageIndex) {
if (!isNaN(values[imageIndex])) {
this.addAlpha_ = true;
break outer;
}
}
}
const additionalBands = this.addAlpha_ ? 1 : 0;
this.bandCount =
samplesPerPixel.reduce((accumulator, value) => {
accumulator += value;
return accumulator;
}, 0) + additionalBands;
const tileGrid = new TileGrid({
extent: extent,
minZoom: minZoom,
origin: origin,
resolutions: resolutions,
tileSizes: tileSizes,
});
this.tileGrid = tileGrid;
this.setLoader(this.loadTile_.bind(this));
this.setState(State.READY);
}
loadTile_(z, x, y) {
const size = toSize(this.tileGrid.getTileSize(z));
const sourceCount = this.sourceImagery_.length;
const requests = new Array(sourceCount);
const addAlpha = this.addAlpha_;
const bandCount = this.bandCount;
const samplesPerPixel = this.samplesPerPixel_;
const sourceInfo = this.sourceInfo_;
for (let sourceIndex = 0; sourceIndex < sourceCount; ++sourceIndex) {
const source = sourceInfo[sourceIndex];
const resolutionFactor = this.resolutionFactors_[sourceIndex];
const pixelBounds = [
Math.round(x * (size[0] * resolutionFactor)),
Math.round(y * (size[1] * resolutionFactor)),
Math.round((x + 1) * (size[0] * resolutionFactor)),
Math.round((y + 1) * (size[1] * resolutionFactor)),
];
const image = this.sourceImagery_[sourceIndex][z];
let samples;
if (source.bands) {
samples = source.bands.map(function (bandNumber) {
return bandNumber - 1;
});
}
requests[sourceIndex] = image[this.readMethod_]({
window: pixelBounds,
width: size[0],
height: size[1],
samples: samples,
fillValue: source.nodata,
pool: getWorkerPool(),
interleave: false,
});
}
const pixelCount = size[0] * size[1];
const dataLength = pixelCount * bandCount;
const nodataValues = this.nodataValues_;
return Promise.all(requests).then(function (sourceSamples) {
const data = new Uint8ClampedArray(dataLength);
let dataIndex = 0;
for (let pixelIndex = 0; pixelIndex < pixelCount; ++pixelIndex) {
let transparent = addAlpha;
for (let sourceIndex = 0; sourceIndex < sourceCount; ++sourceIndex) {
const source = sourceInfo[sourceIndex];
let min = source.min;
if (min === undefined) {
min = getMinForDataType(sourceSamples[sourceIndex][0]);
}
let max = source.max;
if (max === undefined) {
max = getMaxForDataType(sourceSamples[sourceIndex][0]);
}
const gain = 255 / (max - min);
const bias = -min * gain;
for (
let sampleIndex = 0;
sampleIndex < samplesPerPixel[sourceIndex];
++sampleIndex
) {
const sourceValue =
sourceSamples[sourceIndex][sampleIndex][pixelIndex];
const value = gain * sourceValue + bias;
if (!addAlpha) {
data[dataIndex] = value;
} else {
let nodata = source.nodata;
if (nodata === undefined) {
let bandIndex;
if (source.bands) {
bandIndex = source.bands[sampleIndex] - 1;
} else {
bandIndex = sampleIndex;
}
nodata = nodataValues[sourceIndex][bandIndex];
}
if (sourceValue !== nodata) {
transparent = false;
data[dataIndex] = value;
}
}
dataIndex++;
}
}
if (addAlpha) {
if (!transparent) {
data[dataIndex] = 255;
}
dataIndex++;
}
}
return data;
});
}
}
export default GeoTIFFSource;

View File

@@ -0,0 +1,93 @@
/**
* @module ol/source/OGCMapTile
*/
import SourceState from './State.js';
import TileImage from './TileImage.js';
import {getTileSetInfo} from './ogcTileUtil.js';
/**
* @typedef {Object} Options
* @property {string} url URL to the OGC Map Tileset endpoint.
* @property {Object} [context] A lookup of values to use in the tile URL template. The `{tileMatrix}`
* (zoom level), `{tileRow}`, and `{tileCol}` variables in the URL will always be provided by the source.
* @property {string} [mediaType] The content type for the tiles (e.g. "image/png"). If not provided,
* the source will try to find a link with rel="item" that uses a supported image type.
* @property {import("../proj.js").ProjectionLike} [projection] Projection. By default, the projection
* will be derived from the `crs` of the `tileMatrixSet`. You can override this by supplying
* a projection to the constructor.
* @property {import("./Source.js").AttributionLike} [attributions] Attributions.
* @property {number} [cacheSize] Tile cache size. The default depends on the screen size. Will be ignored if too small.
* @property {null|string} [crossOrigin] The `crossOrigin` attribute for loaded images. Note that
* you must provide a `crossOrigin` value if you want to access pixel data with the Canvas renderer.
* See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.
* @property {boolean} [imageSmoothing=true] Enable image smoothing.
* @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).
* Higher values can increase reprojection performance, but decrease precision.
* @property {import("../Tile.js").LoadFunction} [tileLoadFunction] Optional function to load a tile given a URL. The default is
* ```js
* function(tile, src) {
* tile.getImage().src = src;
* };
* ```
* @property {boolean} [wrapX=true] Whether to wrap the world horizontally.
* @property {number} [transition] Duration of the opacity transition for rendering.
* To disable the opacity transition, pass `transition: 0`.
*/
/**
* @classdesc
* Layer source for map tiles from an [OGC API - Tiles](https://ogcapi.ogc.org/tiles/) service that provides "map" type tiles.
* The service must conform to at least the core (http://www.opengis.net/spec/ogcapi-tiles-1/1.0/conf/core)
* and tileset (http://www.opengis.net/spec/ogcapi-tiles-1/1.0/conf/tileset) conformance classes.
*/
class OGCMapTile extends TileImage {
/**
* @param {Options} options OGC map tile options.
*/
constructor(options) {
super({
attributions: options.attributions,
cacheSize: options.cacheSize,
crossOrigin: options.crossOrigin,
imageSmoothing: options.imageSmoothing,
projection: options.projection,
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
state: SourceState.LOADING,
tileLoadFunction: options.tileLoadFunction,
wrapX: options.wrapX !== undefined ? options.wrapX : true,
transition: options.transition,
});
const sourceInfo = {
url: options.url,
projection: this.getProjection(),
mediaType: options.mediaType,
context: options.context || null,
};
getTileSetInfo(sourceInfo)
.then(this.handleTileSetInfo_.bind(this))
.catch(this.handleError_.bind(this));
}
/**
* @param {import("./ogcTileUtil.js").TileSetInfo} tileSetInfo Tile set info.
* @private
*/
handleTileSetInfo_(tileSetInfo) {
this.tileGrid = tileSetInfo.grid;
this.setTileUrlFunction(tileSetInfo.urlFunction, tileSetInfo.urlTemplate);
this.setState(SourceState.READY);
}
/**
* @private
* @param {Error} error The error.
*/
handleError_(error) {
console.error(error); // eslint-disable-line no-console
this.setState(SourceState.ERROR);
}
}
export default OGCMapTile;

View File

@@ -0,0 +1,100 @@
/**
* @module ol/source/OGCVectorTile
*/
import SourceState from './State.js';
import VectorTile from './VectorTile.js';
import {getTileSetInfo} from './ogcTileUtil.js';
/**
* @typedef {Object} Options
* @property {string} url URL to the OGC Vector Tileset endpoint.
* @property {Object} [context] A lookup of values to use in the tile URL template. The `{tileMatrix}`
* (zoom level), `{tileRow}`, and `{tileCol}` variables in the URL will always be provided by the source.
* @property {import("../format/Feature.js").default} format Feature parser for tiles.
* @property {string} [mediaType] The content type for the tiles (e.g. "application/vnd.mapbox-vector-tile"). If not provided,
* the source will try to find a link with rel="item" that uses a vector type supported by the configured format.
* @property {import("./Source.js").AttributionLike} [attributions] Attributions.
* @property {boolean} [attributionsCollapsible=true] Attributions are collapsible.
* @property {number} [cacheSize] Initial tile cache size. Will auto-grow to hold at least twice the number of tiles in the viewport.
* @property {boolean} [overlaps=true] This source may have overlapping geometries. Setting this
* to `false` (e.g. for sources with polygons that represent administrative
* boundaries or TopoJSON sources) allows the renderer to optimise fill and
* stroke operations.
* @property {import("../proj.js").ProjectionLike} [projection='EPSG:3857'] Projection of the tile grid.
* @property {typeof import("../VectorTile.js").default} [tileClass] Class used to instantiate image tiles.
* Default is {@link module:ol/VectorTile}.
* @property {number} [transition] A duration for tile opacity
* transitions in milliseconds. A duration of 0 disables the opacity transition.
* @property {boolean} [wrapX=true] Whether to wrap the world horizontally.
* When set to `false`, only one world
* will be rendered. When set to `true`, tiles will be wrapped horizontally to
* render multiple worlds.
* @property {number|import("../array.js").NearestDirectionFunction} [zDirection=1]
* Choose whether to use tiles with a higher or lower zoom level when between integer
* zoom levels. See {@link module:ol/tilegrid/TileGrid~TileGrid#getZForResolution}.
*/
/**
* @classdesc
* Layer source for map tiles from an [OGC API - Tiles](https://ogcapi.ogc.org/tiles/) service that provides "vector" type tiles.
* The service must conform to at least the core (http://www.opengis.net/spec/ogcapi-tiles-1/1.0/conf/core)
* and tileset (http://www.opengis.net/spec/ogcapi-tiles-1/1.0/conf/tileset) conformance classes.
*
* Vector tile sets may come in a variety of formats (e.g. GeoJSON, MVT). The `format` option is used to determine
* which of the advertised media types is used. If you need to force the use of a particular media type, you can
* provide the `mediaType` option.
*/
class OGCVectorTile extends VectorTile {
/**
* @param {Options} options OGC vector tile options.
*/
constructor(options) {
super({
attributions: options.attributions,
attributionsCollapsible: options.attributionsCollapsible,
cacheSize: options.cacheSize,
format: options.format,
overlaps: options.overlaps,
projection: options.projection,
tileClass: options.tileClass,
transition: options.transition,
wrapX: options.wrapX,
zDirection: options.zDirection,
state: SourceState.LOADING,
});
const sourceInfo = {
url: options.url,
projection: this.getProjection(),
mediaType: options.mediaType,
supportedMediaTypes: options.format.supportedMediaTypes,
context: options.context || null,
};
getTileSetInfo(sourceInfo)
.then(this.handleTileSetInfo_.bind(this))
.catch(this.handleError_.bind(this));
}
/**
* @param {import("./ogcTileUtil.js").TileSetInfo} tileSetInfo Tile set info.
* @private
*/
handleTileSetInfo_(tileSetInfo) {
this.tileGrid = tileSetInfo.grid;
this.setTileUrlFunction(tileSetInfo.urlFunction, tileSetInfo.urlTemplate);
this.setState(SourceState.READY);
}
/**
* @private
* @param {Error} error The error.
*/
handleError_(error) {
console.error(error); // eslint-disable-line no-console
this.setState(SourceState.ERROR);
}
}
export default OGCVectorTile;

View File

@@ -24,7 +24,8 @@ try {
hasImageData = false;
}
const context = document.createElement('canvas').getContext('2d');
/** @type {CanvasRenderingContext2D} */
let context;
/**
* @param {Uint8ClampedArray} data Image data.
@@ -35,19 +36,31 @@ const context = document.createElement('canvas').getContext('2d');
export function newImageData(data, width, height) {
if (hasImageData) {
return new ImageData(data, width, height);
} else {
const imageData = context.createImageData(width, height);
imageData.data.set(data);
return imageData;
}
if (!context) {
context = document.createElement('canvas').getContext('2d');
}
const imageData = context.createImageData(width, height);
imageData.data.set(data);
return imageData;
}
/**
* @typedef {Object} MinionData
* @property {Array<ArrayBuffer>} buffers Array of buffers.
* @property {Object} meta Operation metadata.
* @property {boolean} imageOps The operation is an image operation.
* @property {number} width The width of the image.
* @property {number} height The height of the image.
*/
/* istanbul ignore next */
/**
* Create a function for running operations. This function is serialized for
* use in a worker.
* @param {function(Array, Object):*} operation The operation.
* @return {function(Object):ArrayBuffer} A function that takes an object with
* @return {function(MinionData):ArrayBuffer} A function that takes an object with
* buffers, meta, imageOps, width, and height properties and returns an array
* buffer.
*/
@@ -77,40 +90,40 @@ function createMinion(operation) {
const numBuffers = buffers.length;
const numBytes = buffers[0].byteLength;
let output, b;
if (imageOps) {
const images = new Array(numBuffers);
for (b = 0; b < numBuffers; ++b) {
for (let b = 0; b < numBuffers; ++b) {
images[b] = newWorkerImageData(
new Uint8ClampedArray(buffers[b]),
width,
height
);
}
output = operation(images, meta).data;
} else {
output = new Uint8ClampedArray(numBytes);
const arrays = new Array(numBuffers);
const pixels = new Array(numBuffers);
for (b = 0; b < numBuffers; ++b) {
arrays[b] = new Uint8ClampedArray(buffers[b]);
pixels[b] = [0, 0, 0, 0];
}
for (let i = 0; i < numBytes; i += 4) {
for (let j = 0; j < numBuffers; ++j) {
const array = arrays[j];
pixels[j][0] = array[i];
pixels[j][1] = array[i + 1];
pixels[j][2] = array[i + 2];
pixels[j][3] = array[i + 3];
}
const pixel = operation(pixels, meta);
output[i] = pixel[0];
output[i + 1] = pixel[1];
output[i + 2] = pixel[2];
output[i + 3] = pixel[3];
const output = operation(images, meta).data;
return output.buffer;
}
const output = new Uint8ClampedArray(numBytes);
const arrays = new Array(numBuffers);
const pixels = new Array(numBuffers);
for (let b = 0; b < numBuffers; ++b) {
arrays[b] = new Uint8ClampedArray(buffers[b]);
pixels[b] = [0, 0, 0, 0];
}
for (let i = 0; i < numBytes; i += 4) {
for (let j = 0; j < numBuffers; ++j) {
const array = arrays[j];
pixels[j][0] = array[i];
pixels[j][1] = array[i + 1];
pixels[j][2] = array[i + 2];
pixels[j][3] = array[i + 3];
}
const pixel = operation(pixels, meta);
output[i] = pixel[0];
output[i + 1] = pixel[1];
output[i + 2] = pixel[2];
output[i + 3] = pixel[3];
}
return output.buffer;
};
@@ -118,7 +131,7 @@ function createMinion(operation) {
/**
* Create a worker for running operations.
* @param {Object} config Configuration.
* @param {ProcessorOptions} config Processor options.
* @param {function(MessageEvent): void} onMessage Called with a message event.
* @return {Worker} The worker.
*/
@@ -173,11 +186,22 @@ function createFauxWorker(config, onMessage) {
};
}
/**
* @typedef {function(Error, ImageData, (Object|Array<Object>)): void} JobCallback
*/
/**
* @typedef {Object} Job
* @property {Object} meta Job metadata.
* @property {Array<ImageData>} inputs Array of input data.
* @property {JobCallback} callback Called when the job is complete.
*/
/**
* @typedef {Object} ProcessorOptions
* @property {number} threads Number of workers to spawn.
* @property {function(Array, Object):*} operation The operation.
* @property {Object} [lib] Functions that will be made available to operations run in a worker.
* @property {Operation} operation The operation.
* @property {Object<string, Function>} [lib] Functions that will be made available to operations run in a worker.
* @property {number} queue The number of queued jobs to allow.
* @property {boolean} [imageOps=false] Pass all the image data to the operation instead of a single pixel.
*/
@@ -202,7 +226,11 @@ export class Processor extends Disposable {
} else {
threads = config.threads || 1;
}
const workers = [];
/**
* @type {Array<Worker>}
*/
const workers = new Array(threads);
if (threads) {
for (let i = 0; i < threads; ++i) {
workers[i] = createWorker(config, this._onWorkerMessage.bind(this, i));
@@ -214,17 +242,32 @@ export class Processor extends Disposable {
);
}
this._workers = workers;
/**
* @type {Array<Job>}
* @private
*/
this._queue = [];
this._maxQueueLength = config.queue || Infinity;
this._running = 0;
/**
* @type {Object<number, any>}
* @private
*/
this._dataLookup = {};
/**
* @type {Job}
* @private
*/
this._job = null;
}
/**
* Run operation on input data.
* @param {Array<Array|ImageData>} inputs Array of pixels or image data
* (depending on the operation type).
* @param {Array<ImageData>} inputs Array of image data.
* @param {Object} meta A user data object. This is passed to all operations
* and must be serializable.
* @param {function(Error, ImageData, Object): void} callback Called when work
@@ -242,7 +285,7 @@ export class Processor extends Disposable {
/**
* Add a job to the queue.
* @param {Object} job The job.
* @param {Job} job The job.
*/
_enqueue(job) {
this._queue.push(job);
@@ -255,48 +298,51 @@ export class Processor extends Disposable {
* Dispatch a job.
*/
_dispatch() {
if (this._running === 0 && this._queue.length > 0) {
const job = this._queue.shift();
this._job = job;
const width = job.inputs[0].width;
const height = job.inputs[0].height;
const buffers = job.inputs.map(function (input) {
return input.data.buffer;
});
const threads = this._workers.length;
this._running = threads;
if (threads === 1) {
this._workers[0].postMessage(
{
buffers: buffers,
meta: job.meta,
imageOps: this._imageOps,
width: width,
height: height,
},
buffers
);
} else {
const length = job.inputs[0].data.length;
const segmentLength = 4 * Math.ceil(length / 4 / threads);
for (let i = 0; i < threads; ++i) {
const offset = i * segmentLength;
const slices = [];
for (let j = 0, jj = buffers.length; j < jj; ++j) {
slices.push(buffers[j].slice(offset, offset + segmentLength));
}
this._workers[i].postMessage(
{
buffers: slices,
meta: job.meta,
imageOps: this._imageOps,
width: width,
height: height,
},
slices
);
}
if (this._running || this._queue.length === 0) {
return;
}
const job = this._queue.shift();
this._job = job;
const width = job.inputs[0].width;
const height = job.inputs[0].height;
const buffers = job.inputs.map(function (input) {
return input.data.buffer;
});
const threads = this._workers.length;
this._running = threads;
if (threads === 1) {
this._workers[0].postMessage(
{
buffers: buffers,
meta: job.meta,
imageOps: this._imageOps,
width: width,
height: height,
},
buffers
);
return;
}
const length = job.inputs[0].data.length;
const segmentLength = 4 * Math.ceil(length / 4 / threads);
for (let i = 0; i < threads; ++i) {
const offset = i * segmentLength;
const slices = [];
for (let j = 0, jj = buffers.length; j < jj; ++j) {
slices.push(buffers[j].slice(offset, offset + segmentLength));
}
this._workers[i].postMessage(
{
buffers: slices,
meta: job.meta,
imageOps: this._imageOps,
width: width,
height: height,
},
slices
);
}
}
@@ -330,7 +376,7 @@ export class Processor extends Disposable {
} else {
const length = job.inputs[0].data.length;
data = new Uint8ClampedArray(length);
meta = new Array(length);
meta = new Array(threads);
const segmentLength = 4 * Math.ceil(length / 4 / threads);
for (let i = 0; i < threads; ++i) {
const buffer = this._dataLookup[i]['buffer'];
@@ -384,14 +430,17 @@ export class Processor extends Disposable {
*/
const RasterEventType = {
/**
* Triggered before operations are run.
* Triggered before operations are run. Listeners will receive an event object with
* a `data` property that can be used to make data available to operations.
* @event module:ol/source/Raster.RasterSourceEvent#beforeoperations
* @api
*/
BEFOREOPERATIONS: 'beforeoperations',
/**
* Triggered after operations are run.
* Triggered after operations are run. Listeners will receive an event object with
* a `data` property. If more than one thread is used, `data` will be an array of
* objects. If a single thread is used, `data` will be a single object.
* @event module:ol/source/Raster.RasterSourceEvent#afteroperations
* @api
*/
@@ -407,6 +456,10 @@ const RasterOperationType = {
IMAGE: 'image',
};
/**
* @typedef {import("./Image.js").ImageSourceEventTypes|'beforeoperations'|'afteroperations'} RasterSourceEventTypes
*/
/**
* @classdesc
* Events emitted by {@link module:ol/source/Raster} instances are instances of this
@@ -416,7 +469,8 @@ export class RasterSourceEvent extends Event {
/**
* @param {string} type Type.
* @param {import("../PluggableMap.js").FrameState} frameState The frame state.
* @param {Object} data An object made available to operations.
* @param {Object|Array<Object>} data An object made available to operations. For "afteroperations" evenets
* this will be an array of objects if more than one thread is used.
*/
constructor(type, frameState, data) {
super(type);
@@ -465,6 +519,16 @@ export class RasterSourceEvent extends Event {
* be called with an array of ImageData objects from input sources.
*/
/***
* @template Return
* @typedef {import("../Observable").OnSignature<import("../Observable").EventTypes, import("../events/Event.js").default, Return> &
* import("../Observable").OnSignature<import("../ObjectEventType").Types, import("../Object").ObjectEvent, Return> &
* import("../Observable").OnSignature<import("./Image.js").ImageSourceEventTypes, import("./Image.js").ImageSourceEvent, Return> &
* import("../Observable").OnSignature<RasterSourceEventTypes, RasterSourceEvent, Return> &
* import("../Observable").CombinedOnSignature<import("../Observable").EventTypes|import("../ObjectEventType").Types
* |RasterSourceEventTypes, Return>} RasterSourceOnSignature
*/
/**
* @classdesc
* A source that transforms data from any number of input sources using an
@@ -483,6 +547,21 @@ class RasterSource extends ImageSource {
projection: null,
});
/***
* @type {RasterSourceOnSignature<import("../Observable.js").OnReturn>}
*/
this.on;
/***
* @type {RasterSourceOnSignature<import("../Observable.js").OnReturn>}
*/
this.once;
/***
* @type {RasterSourceOnSignature<void>}
*/
this.un;
/**
* @private
* @type {Processor}
@@ -639,7 +718,7 @@ class RasterSource extends ImageSource {
frameState.extent = extent.slice();
frameState.size[0] = Math.round(getWidth(extent) / resolution);
frameState.size[1] = Math.round(getHeight(extent) / resolution);
frameState.time = Infinity;
frameState.time = Date.now();
const viewState = frameState.viewState;
viewState.center = center;
@@ -743,7 +822,7 @@ class RasterSource extends ImageSource {
* @param {import("../PluggableMap.js").FrameState} frameState The frame state.
* @param {Error} err Any error during processing.
* @param {ImageData} output The output image data.
* @param {Object} data The user data.
* @param {Object|Array<Object>} data The user data (or an array if more than one thread).
* @private
*/
onWorkerComplete_(frameState, err, output, data) {
@@ -783,13 +862,7 @@ class RasterSource extends ImageSource {
this.dispatchEvent(
new RasterSourceEvent(RasterEventType.AFTEROPERATIONS, frameState, data)
);
}
/**
* @return {null} not implemented
*/
getImageInternal() {
return null; // not implemented
requestAnimationFrame(this.changed.bind(this));
}
disposeInternal() {

View File

@@ -95,6 +95,7 @@ class Source extends BaseObject {
/**
* Get the attribution function for the source.
* @return {?Attribution} Attribution function.
* @api
*/
getAttributions() {
return this.attributions_;
@@ -102,6 +103,7 @@ class Source extends BaseObject {
/**
* @return {boolean} Attributions are collapsible.
* @api
*/
getAttributionsCollapsible() {
return this.attributionsCollapsible_;

View File

@@ -983,7 +983,7 @@ class VectorSource extends Source {
}
}
this.loading =
this.loader_ === VOID ? false : this.loadingExtentsCount_ > 0;
this.loader_.length < 4 ? false : this.loadingExtentsCount_ > 0;
}
refresh() {

Some files were not shown because too many files have changed in this diff Show More