Compare commits

...

235 Commits

Author SHA1 Message Date
Tim Schaub
0b0d5c63da Merge pull request #8412 from tschaub/release-v5.1.1
Changes for 5.1.1.
2018-07-20 18:38:59 -07:00
Tim Schaub
1ad3e8fe37 Changes for 5.1.1. 2018-07-20 19:33:45 -06:00
Tim Schaub
e5d7b30c31 Merge pull request #8411 from tschaub/release-v5.1.0
Release v5.1.0
2018-07-20 17:40:21 -07:00
Tim Schaub
1b745dc7b7 Update the publish.sh script 2018-07-20 18:31:25 -06:00
Tim Schaub
f8c5a79242 Collapsed dependency updates 2018-07-20 18:22:28 -06:00
Tim Schaub
9061e93c59 Update package version to 5.1.0 2018-07-20 18:20:17 -06:00
Tim Schaub
b04728d907 Changelog for v5.1.0 2018-07-20 18:20:11 -06:00
Tim Schaub
154827c5d5 Merge pull request #8409 from pjeweb/patch-2
Add abstract translate to ol/geom/Geometry
2018-07-20 09:57:06 -07:00
Andreas Hocevar
f1d03702b2 Merge pull request #8410 from openlayers/greenkeeper/rollup-0.63.4
Update rollup to the latest version 🚀
2018-07-20 18:24:18 +02:00
greenkeeper[bot]
23f9110f1f chore(package): update rollup to version 0.63.4 2018-07-20 16:02:19 +00:00
Tim Schaub
d3e221bd10 Merge pull request #8408 from openlayers/greenkeeper/rollup-0.63.3
Update rollup to the latest version 🚀
2018-07-20 07:56:15 -07:00
Paul Golmann
e3e6a28e18 Add abstract translate to ol/geom/Geometry 2018-07-20 15:40:53 +02:00
greenkeeper[bot]
f3089efd19 chore(package): update rollup to version 0.63.3 2018-07-20 12:53:36 +00:00
Tim Schaub
2cfc2fd369 Merge pull request #8405 from tschaub/ts-fixes
Minor type fixes
2018-07-19 15:55:25 -07:00
Tim Schaub
c860aed960 Import inherits, getUid, and VERSION from ol/util 2018-07-19 10:26:17 -06:00
Tim Schaub
83972b00a5 Use single quote instead of backtick 2018-07-19 10:22:10 -06:00
Tim Schaub
cf58ee9bf1 Only use getUid from ol/util 2018-07-19 10:19:41 -06:00
Tim Schaub
e5493d1288 Add ol/pixel module for Pixel type 2018-07-19 10:17:00 -06:00
Andreas Hocevar
f77b6be8e9 Merge pull request #8401 from ahocevar/css-side-effects
Make webpack's css loader work
2018-07-19 17:27:49 +02:00
Tim Schaub
1c5cc6ea7f Merge pull request #8386 from openlayers/greenkeeper/fs-extra-7.0.0
Update fs-extra to the latest version 🚀
2018-07-19 08:12:16 -07:00
Tim Schaub
b7c49e1007 Merge pull request #8403 from tschaub/md-links
Markdown links
2018-07-19 08:06:43 -07:00
Tim Schaub
e1e34e5636 Replace @see with See. 2018-07-19 08:37:32 -06:00
Tim Schaub
d46471d763 Replace {@link https://www.example.com/} with https://www.example.com/ 2018-07-19 08:34:35 -06:00
Frédéric Junod
dae843a98d Merge pull request #8402 from fredj/fixes_from_ts
Type fixes from the typescript checks
2018-07-19 16:28:18 +02:00
Frederic Junod
85d836d909 Remove 'Geolocation' prefix from types
So they are recognized by the TypeScript type checker.
2018-07-19 16:02:58 +02:00
Frederic Junod
323eb3f251 Fix reprojectionErrorThreshold property type 2018-07-19 16:02:58 +02:00
Frederic Junod
5d2cf66380 Add missing 'targetRotation' property in Animation typedef 2018-07-19 16:02:58 +02:00
Frederic Junod
2e60961700 Use 'HTMLElement' type instead of 'Element' in controls 2018-07-19 16:02:58 +02:00
Frederic Junod
c1ffb0a2a9 Move template type at the class level
This removes the TS1092 error from TypeScript: Type parameters cannot appear on a constructor declaration.
2018-07-19 15:53:52 +02:00
Tim Schaub
8f7b52f266 Merge pull request #8400 from tschaub/eslint-config-update
ESLint config update
2018-07-18 10:48:09 -07:00
ahocevar
bcefb07cf2 Make webpack's css loader work 2018-07-18 19:02:59 +02:00
Andreas Hocevar
52c75e32ee Merge pull request #8399 from ahocevar/copy-css
Copy ol.css to build dir when building package
2018-07-18 19:01:27 +02:00
ahocevar
60c8360330 Copy ol.css to build dir when building package 2018-07-18 18:37:05 +02:00
Tim Schaub
b8c9125602 Remove lint 2018-07-18 10:35:54 -06:00
Tim Schaub
71555002a8 Latest linter config 2018-07-18 10:33:31 -06:00
Tim Schaub
5d029f4256 Merge pull request #8397 from tschaub/rollupdate
Update rollup
2018-07-18 09:32:01 -07:00
Tim Schaub
6fa4fa59d6 Update rollup 2018-07-18 10:25:24 -06:00
Tim Schaub
b4ce8e4b3d Merge pull request #8385 from openlayers/class
Use class syntax
2018-07-18 09:16:27 -07:00
ahocevar
4cdab30201 Replace VERSION correctly in transpiled code 2018-07-18 18:05:02 +02:00
ahocevar
47c58d8a34 Transpile sources for testing 2018-07-18 17:54:29 +02:00
ahocevar
5124c98fb5 Default VERSION to 'latest' 2018-07-18 17:41:22 +02:00
ahocevar
aecb7e1789 Remove unused inherits 2018-07-18 16:33:35 +02:00
ahocevar
0a126b620c Use class keyword in tests 2018-07-18 16:30:09 +02:00
ahocevar
9ed3540edf Fix this access in WMTS source 2018-07-18 16:29:53 +02:00
ahocevar
4589345fac Remove leftover this in super call 2018-07-18 15:41:35 +02:00
ahocevar
e52cabcb31 Fix DragZoom tests 2018-07-18 15:41:13 +02:00
ahocevar
6f32d1a15b Deprecate ol/inherits 2018-07-18 15:40:53 +02:00
ahocevar
95533bef66 Fix WKT geometry type lookup and tests 2018-07-18 15:40:39 +02:00
ahocevar
4adab51768 stopPropagation and preventDefault are now separate functions 2018-07-18 12:21:42 +02:00
ahocevar
b813937991 Access the correct element 2018-07-18 12:19:33 +02:00
ahocevar
87a3510c83 Clean up super calls 2018-07-18 12:19:15 +02:00
ahocevar
d6190a0cd7 Remove accidently added .only() 2018-07-18 12:15:02 +02:00
ahocevar
8991dc9718 Do not use this before super() 2018-07-18 12:09:04 +02:00
Frederic Junod
65b306891b Remove 'struct' jsdoc tags, code indentation 2018-07-18 09:07:27 +02:00
Tim Schaub
b4e0d4c188 Super before this in TileJSON source 2018-07-18 01:00:19 -06:00
Tim Schaub
1309cf9b69 Call super before accessing this in Carto source 2018-07-18 00:53:57 -06:00
Tim Schaub
023bb638b2 Call super before accessing this in raster source 2018-07-18 00:53:17 -06:00
Tim Schaub
d885771d8d Call super before accessing this in BingMaps source 2018-07-18 00:52:23 -06:00
Tim Schaub
7713015b26 Call super before accessing this in icon 2018-07-18 00:49:00 -06:00
Tim Schaub
fe8fcfbc7e Call super in WebGL context 2018-07-18 00:45:19 -06:00
Tim Schaub
3f4ba0af5f Call super in regular shape 2018-07-18 00:44:24 -06:00
Tim Schaub
1e4ab17513 Assign to this after super in WMTS tile grid 2018-07-18 00:43:29 -06:00
Tim Schaub
5f058e877f Call super and fix up comments in render box 2018-07-18 00:39:51 -06:00
Tim Schaub
9ce36da349 Remove @extends and @constructor annotations 2018-07-18 00:36:29 -06:00
Tim Schaub
b7b15eb7f0 Remove unused inherits 2018-07-18 00:13:43 -06:00
Tim Schaub
1a5cf52b61 Remove remaining use of inherits in src 2018-07-17 23:43:10 -06:00
Tim Schaub
f6046c023c Clean up remaining ol/format/filter class 2018-07-17 18:30:15 -06:00
Tim Schaub
c4e5a7467e Clean up ol/renderer classes 2018-07-17 18:26:51 -06:00
Tim Schaub
9ee5edf19c Clean up ol/renderer/webgl classes 2018-07-17 18:23:52 -06:00
Tim Schaub
792e7e54f1 Clean up ol/renderer/canvas classes 2018-07-17 18:15:47 -06:00
Tim Schaub
45e0926896 Cleaned up ol/proj 2018-07-17 17:54:24 -06:00
Tim Schaub
069187859d Cleaned up ol/pointer classes 2018-07-17 17:48:27 -06:00
Tim Schaub
d855f5ba0a Call super instead of BaseObject 2018-07-17 14:57:57 -06:00
Tim Schaub
2f4aa5aa05 No inherits in ZoomToExtent 2018-07-17 14:56:19 -06:00
Tim Schaub
bd7328675a Construct error with message 2018-07-17 14:55:10 -06:00
Tim Schaub
7c6755d3ec Scripts for generating the package and legacy build 2018-07-17 14:48:17 -06:00
Tim Schaub
524b4c99d5 Bad @const annotation 2018-07-17 14:48:17 -06:00
ahocevar
e79add2e77 Use extends, super and proper constructor jsdoc for ol/interaction 2018-07-17 21:09:06 +02:00
ahocevar
fd962caa1c Use extends, super and proper constructor comments for format/filter/ 2018-07-17 18:36:26 +02:00
ahocevar
414d1556a7 Use extends and super for format/XMLFeature 2018-07-17 18:03:21 +02:00
ahocevar
a02c1713a4 Use extends and super for format/WMTSCapabilities 2018-07-17 18:02:01 +02:00
ahocevar
ba431421a1 Use extends and super for format/WMSGetFeatureInfo 2018-07-17 18:01:07 +02:00
ahocevar
a4abd990df Use extends and super for format/WMSCapabilities 2018-07-17 17:59:53 +02:00
ahocevar
df89b0718a Use extends and super for format/WKT 2018-07-17 17:56:30 +02:00
ahocevar
942a219c30 Use extends and super for format/WFS 2018-07-17 17:49:08 +02:00
ahocevar
788f932550 Use extends and super for format/TopoJSON 2018-07-17 17:15:41 +02:00
ahocevar
c969afcddc Use extends and super for format/TextFeature 2018-07-17 17:14:14 +02:00
ahocevar
9b2b921f7b Use extends and super for format/Polyline 2018-07-17 17:13:13 +02:00
ahocevar
092441017d Use extends and super for format/OWS 2018-07-17 17:04:02 +02:00
ahocevar
5e71e6ce80 Use extends and super for format/OSMXML 2018-07-17 17:02:55 +02:00
ahocevar
cf15af43e3 Use extends and super for format/MVT 2018-07-17 17:00:43 +02:00
ahocevar
a8bd0c5dd7 Use extends and super for format/KML 2018-07-17 16:59:13 +02:00
ahocevar
ad4e192ee9 Use extends and super for format/JSONFeature 2018-07-17 16:54:17 +02:00
ahocevar
6a39b9f412 Use extends and super for format/IGC 2018-07-17 16:49:38 +02:00
Frederic Junod
f140ff368d Move jsdoc constructor comments for controls 2018-07-17 16:44:53 +02:00
ahocevar
e1e5e54d74 Use extends and super for format/GPX 2018-07-17 16:43:54 +02:00
ahocevar
9a28af76ca Use extends and super for GMLBase 2018-07-17 16:43:54 +02:00
ahocevar
7f05bf1d7e Use extends and super for format/GML3 2018-07-17 16:43:54 +02:00
ahocevar
84e9d7c72e Use extends and super for format/GML2 2018-07-17 16:43:54 +02:00
ahocevar
672a462b1e Use extends and super for format/GeoJSON 2018-07-17 16:43:53 +02:00
Frederic Junod
c707b4c746 Use extends and super for geom 2018-07-17 16:21:54 +02:00
ahocevar
44bea898b8 Use extends and super for format/JSONFeature 2018-07-17 16:10:11 +02:00
ahocevar
a235dc906f Use extends and super for events/EventTarget 2018-07-17 16:01:04 +02:00
ahocevar
f5272bb391 Use extends and super for control/ZoomToExtent 2018-07-17 15:02:38 +02:00
ahocevar
6530119918 Use extends and super for control/ZoomSlider 2018-07-17 14:58:37 +02:00
ahocevar
11f1f5b25c Use new eslint config to enforce no-this-before-super 2018-07-17 14:58:12 +02:00
ahocevar
600205f4d9 Use extends and super for control/Zoom 2018-07-17 14:44:27 +02:00
ahocevar
1da14a6d97 Use extends and super for control/ScaleLine 2018-07-17 14:41:27 +02:00
ahocevar
7d5efd0348 Use extends and super for control/Rotate 2018-07-17 14:41:27 +02:00
ahocevar
6ffda39b14 Use extends and super for control/OverviewMap 2018-07-17 14:41:27 +02:00
ahocevar
353a00af89 Use extends and super for control/MousePosition 2018-07-17 14:41:26 +02:00
ahocevar
b9f08c6a2a Use extends and super for control/FullScreen 2018-07-17 14:41:26 +02:00
ahocevar
322a51d822 Use extends and super for control/Control 2018-07-17 14:41:25 +02:00
ahocevar
49c4a75777 Use extends and super for control/Attribution 2018-07-17 14:41:25 +02:00
ahocevar
778e867c79 Use extends and super for WebGLMap 2018-07-17 14:21:50 +02:00
ahocevar
4f26f145ae Use extends and super for View 2018-07-17 14:20:48 +02:00
ahocevar
9c994138ad Use extends and super for VectorTile 2018-07-17 14:19:43 +02:00
ahocevar
603f489708 Use extends and super for VectorImageTile 2018-07-17 14:18:40 +02:00
ahocevar
2e5054d11c Use extends and super for TileQueue 2018-07-17 14:15:34 +02:00
ahocevar
64190b7109 Use extends and super for TileCache 2018-07-17 14:15:34 +02:00
ahocevar
9e259c471d Use extends and super for Tile 2018-07-17 14:15:34 +02:00
ahocevar
505f88031b Use extends and super for PluggableMap 2018-07-17 14:15:33 +02:00
ahocevar
0f6ee28c19 Use extends and super for Overlay 2018-07-17 14:15:33 +02:00
ahocevar
2fd022d215 Use extends and super for Observable 2018-07-17 14:15:32 +02:00
ahocevar
2792ba701a Use extends and super for Object 2018-07-17 14:15:32 +02:00
ahocevar
e1fedca22e Use extends and super for MapEvent 2018-07-17 14:15:32 +02:00
ahocevar
5a90203aa0 Use extends and super for MapBrowserPointerEvent 2018-07-17 13:54:30 +02:00
ahocevar
edd23dbf6a Use extends and super for MapBrowserEventHandler 2018-07-17 13:53:05 +02:00
ahocevar
16849a3611 Use extends and super for MapBrowserEvent 2018-07-17 13:51:32 +02:00
ahocevar
de104d6e22 Use extends and super for Map 2018-07-17 13:49:53 +02:00
ahocevar
5f40b5b66b Use extends and super for ImageTile 2018-07-17 13:47:13 +02:00
ahocevar
6ca865375e Use extends and super for ImageCanvas 2018-07-17 13:45:54 +02:00
ahocevar
61c48ce09f Use extends and super for ImageBase 2018-07-17 13:40:49 +02:00
ahocevar
fb59d7a65b Use extends and super for Image 2018-07-17 13:28:27 +02:00
ahocevar
ec495bfcec Use extends and super for Geolocation 2018-07-17 11:56:21 +02:00
ahocevar
6f4d2e34a9 Use extends and super for Feature 2018-07-17 11:49:37 +02:00
ahocevar
aa7b6350ec Use extends and super for Collection 2018-07-17 11:46:19 +02:00
ahocevar
0224e2b3c5 Use extends and super for AssertionError 2018-07-17 11:45:50 +02:00
Frederic Junod
540b1793e7 Move jsdoc constructor comments 2018-07-17 10:20:26 +02:00
Frederic Junod
f2d0b11d24 Move jsdoc constructor comments 2018-07-17 09:59:00 +02:00
Frederic Junod
384920734f Fix webgl.js path import in webgl shaders 2018-07-17 09:19:04 +02:00
Frederic Junod
7e3e0e54ca Fix comments indentation 2018-07-17 09:15:16 +02:00
greenkeeper[bot]
c49d2e0115 chore(package): update fs-extra to version 7.0.0 2018-07-17 02:22:58 +00:00
Tim Schaub
d0ab8dce38 Lint removal 2018-07-16 17:57:57 -06:00
Tim Schaub
f78d0d4cfa Manual class transform 2018-07-16 17:09:50 -06:00
Tim Schaub
7b4a73f3b9 Automated class transform
npx lebab --replace src --transform class
2018-07-16 16:18:16 -06:00
Tim Schaub
60e85e7d89 Merge pull request #8383 from Turbo87/set-anchor
style/Icon: Add `setAnchor()` method
2018-07-16 04:56:03 -07:00
Tobias Bieniek
2096a1d0db style/Icon: Add setAnchor() method
This allows users to adjust the anchor after the `Icon` is defined. This can be useful if the anchor should depend on the rotation of the icon.
2018-07-16 12:48:52 +02:00
Andreas Hocevar
41fd1d4222 Merge pull request #8382 from openlayers/greenkeeper/webpack-4.16.1
Update webpack to the latest version 🚀
2018-07-16 12:26:31 +02:00
greenkeeper[bot]
b1f80a5998 chore(package): update webpack to version 4.16.1 2018-07-16 09:31:10 +00:00
Andreas Hocevar
19ca2c25c6 Merge pull request #8368 from ahocevar/imagemode-render-listeners
Make render listeners work with image render mode
2018-07-14 11:52:40 +02:00
Andreas Hocevar
84d2c3a42e Merge pull request #8376 from virtualcitySYSTEMS/feature-polygonMakeRegularXYZ
copy ZM values to polygon in makeRegular
2018-07-12 18:00:54 +02:00
Ben Kuster
88fbd6e35d moved copying of ZM values to Polygon.fromCircle 2018-07-12 17:25:31 +02:00
Ben Kuster
33ef64c912 copy ZM values to polygon in makeRegular 2018-07-12 12:52:05 +02:00
Andreas Hocevar
ed7788ca37 Merge pull request #8373 from openlayers/greenkeeper/webpack-4.16.0
Update webpack to the latest version 🚀
2018-07-11 20:54:07 +02:00
greenkeeper[bot]
623c887579 chore(package): update webpack to version 4.16.0 2018-07-11 09:53:51 +00:00
Andreas Hocevar
f2b7dfc26c Merge pull request #8372 from openlayers/release-v5.0.3
Release v5.0.3
2018-07-11 11:11:07 +02:00
ahocevar
349e602ee5 Update package version to 5.0.3 2018-07-11 11:01:34 +02:00
ahocevar
9cb10efe4b Changelog for v5.0.3 2018-07-11 10:56:05 +02:00
Andreas Hocevar
871a283601 Merge pull request #8364 from ahocevar/ie-examples
Make examples work in IE11
2018-07-11 10:51:08 +02:00
Andreas Hocevar
d1a609e0a3 Merge pull request #8363 from ahocevar/package-json-autogenerate
Autogenerate src/ol/package.json
2018-07-11 10:49:43 +02:00
Andreas Hocevar
e0c5529878 Merge pull request #8371 from ahocevar/empty-replay-groups
Skip rendering when there is no replay group
2018-07-11 10:47:42 +02:00
Andreas Hocevar
186d5466f4 Merge pull request #8364 from ahocevar/ie-examples
Make examples work in IE11
2018-07-11 10:16:45 +02:00
Andreas Hocevar
dc9e0a6bc4 Merge pull request #8363 from ahocevar/package-json-autogenerate
Autogenerate src/ol/package.json
2018-07-11 09:35:42 +02:00
Andreas Hocevar
b74dd515d5 Merge pull request #8371 from ahocevar/empty-replay-groups
Skip rendering when there is no replay group
2018-07-10 22:21:48 +02:00
ahocevar
1ee1ea6a1a Skip rendering when there is no replay group 2018-07-10 22:03:14 +02:00
ahocevar
fe0f91cb29 Add renderMode property to Heatmap layer 2018-07-10 14:10:35 +02:00
ahocevar
5d6721192d Make render listeners work with image render mode 2018-07-10 11:22:16 +02:00
Andreas Hocevar
d0a8043edc Merge pull request #8362 from ahocevar/smart-flat-coordinates
Smart flat coordinates
2018-07-09 10:27:11 +02:00
ahocevar
f3f0403cec Transpile examples for use with IE 11 2018-07-08 23:31:04 +02:00
ahocevar
84a88616a8 Match filename only when seraching source 2018-07-08 23:31:04 +02:00
ahocevar
4055a08043 Remove unused fields from package.json 2018-07-08 22:52:24 +02:00
ahocevar
afec93ae62 Autogenerate src/ol/package.json from package.json 2018-07-08 22:51:51 +02:00
ahocevar
e7d6bc055a Describe change in upgrade notes 2018-07-07 18:09:51 +02:00
ahocevar
97f6171b4c Rename setFlatCoordinatesInternal to setFlatCoordinates 2018-07-07 18:04:13 +02:00
ahocevar
e2f8d96763 Accept flat coordinates in Circle constructor 2018-07-07 18:02:38 +02:00
ahocevar
ce97cee6a6 Accept polygons and flat coordinates in MultiPolygon constructor 2018-07-07 17:31:35 +02:00
ahocevar
0ec0491ef6 Accept flat coordinates in LinearRing constructor 2018-07-07 17:12:12 +02:00
ahocevar
a09b6c91c9 Accept linestrings and flat coordinates in MultiLineString constructor 2018-07-07 17:01:39 +02:00
ahocevar
3871f7785a Accept flat coordinates for MultiPoint constructor 2018-07-07 16:26:24 +02:00
ahocevar
160f1bc286 Accept flat coordinates in LineString constructor 2018-07-07 16:04:43 +02:00
ahocevar
c0d04ea077 Do not accept null coordinates in Point constructor 2018-07-07 14:48:46 +02:00
ahocevar
da0838dde2 Treat WKT EMPTY geometries properly
Empty points have NaN as each coordinate, other geometry types have
empty arrays.
2018-07-07 14:48:06 +02:00
ahocevar
1da43d90af Allow flat coordinates for Polygon constructor 2018-07-07 14:16:39 +02:00
Andreas Hocevar
9ddd7e4751 Merge pull request #8355 from openlayers/greenkeeper/recast-0.15.2
Update recast to the latest version 🚀
2018-07-06 09:50:30 +02:00
Andreas Hocevar
538315f682 Merge pull request #8354 from openlayers/greenkeeper/webpack-4.15.1
Update webpack to the latest version 🚀
2018-07-06 09:33:56 +02:00
Tim Schaub
b8db6bf087 Merge pull request #8352 from tschaub/false
Set `sideEffects` to `false` instead of `"false"`
2018-07-05 12:51:13 -06:00
greenkeeper[bot]
42228ed87d chore(package): update recast to version 0.15.2 2018-07-05 17:32:58 +00:00
greenkeeper[bot]
707afeab06 chore(package): update webpack to version 4.15.1 2018-07-05 14:36:50 +00:00
Andreas Hocevar
7a7414447f Merge pull request #8348 from openlayers/greenkeeper/webpack-4.15.0
Update webpack to the latest version 🚀
2018-07-05 11:03:03 +02:00
Tim Schaub
fb28071dd1 Use false instead of "false" 2018-07-04 17:01:55 -06:00
Andreas Hocevar
6b39353ccb Merge pull request #8351 from ahocevar/post-release-fix
Fix typo in release notes
2018-07-05 00:19:28 +02:00
ahocevar
6f6e9a2af1 Fix typo in release notes 2018-07-05 00:18:53 +02:00
Andreas Hocevar
bc3e348b0d Merge pull request #8350 from ahocevar/release-v5.0.2
Updates for v5.0.2
2018-07-05 00:05:33 +02:00
ahocevar
59c3eedbab Updates for v5.0.2 2018-07-05 00:04:32 +02:00
Andreas Hocevar
60600d3108 Merge pull request #8349 from ahocevar/release-v5.0.1
Release v5.0.1
2018-07-04 23:57:53 +02:00
Andreas Hocevar
49050063d5 Merge pull request #8343 from tschaub/starter-project
Starter projects
2018-07-04 23:53:48 +02:00
Andreas Hocevar
1b9cad6b8d Merge pull request #8343 from tschaub/starter-project
Starter projects
2018-07-04 23:52:14 +02:00
greenkeeper[bot]
9c16cc4200 chore(package): update webpack to version 4.15.0 2018-07-04 20:45:17 +00:00
Andreas Hocevar
c9b638f5fd Merge pull request #8347 from ahocevar/post-release-notes-fixes
Fix typos in release notes
2018-07-04 22:17:50 +02:00
ahocevar
f3b79c57f7 Fix typos in release notes 2018-07-04 22:17:18 +02:00
Andreas Hocevar
769a14d0dc Merge pull request #8346 from openlayers/release-v5.0.1
Release v5.0.1
2018-07-04 22:07:56 +02:00
ahocevar
11024ad294 Update package version to 5.0.1 2018-07-04 22:02:38 +02:00
ahocevar
73f1428701 Changelog for v5.0.1 2018-07-04 21:52:27 +02:00
Andreas Hocevar
a579b168f7 Merge pull request #8341 from ahocevar/side-effects
Set sideEffects: false flag
2018-07-04 21:46:51 +02:00
Andreas Hocevar
537a21fd48 Merge pull request #8342 from ahocevar/quickstart-links
Fix links and description in quickstart tutorial
2018-07-04 21:46:29 +02:00
Andreas Hocevar
e18d485d01 Merge pull request #8342 from ahocevar/quickstart-links
Fix links and description in quickstart tutorial
2018-07-04 19:20:33 +02:00
Tim Schaub
853fc77f2a Merge pull request #8344 from tschaub/issue-templates
Updated issue and pr templates
2018-07-04 10:43:50 -06:00
Tim Schaub
c678354aec Remove Rollup/Closure gist 2018-07-04 09:05:04 -06:00
Tim Schaub
1f06f7c2ac Updated issue and pr templates 2018-07-04 08:58:29 -06:00
Tim Schaub
9c085e37de Starter project with Parcel 2018-07-04 08:45:39 -06:00
Tim Schaub
a6896ed531 New starter projects 2018-07-04 08:32:15 -06:00
ahocevar
9304ee25af Fix links and description in quickstart tutorial 2018-07-04 14:52:14 +02:00
Andreas Hocevar
f0f21d583a Merge pull request #8338 from openlayers/greenkeeper/recast-0.15.1
Update recast to the latest version 🚀
2018-07-04 13:46:23 +02:00
Andreas Hocevar
54d50af2c3 Merge pull request #8341 from ahocevar/side-effects
Set sideEffects: false flag
2018-07-04 13:44:37 +02:00
ahocevar
9f84494b02 Set sideEffects: false flag 2018-07-04 13:10:20 +02:00
greenkeeper[bot]
e18a23c877 chore(package): update recast to version 0.15.1 2018-07-04 02:57:20 +00:00
Andreas Hocevar
cb78019825 Merge pull request #8332 from openlayers/greenkeeper/webpack-4.14.0
Update webpack to the latest version 🚀
2018-07-02 07:17:08 +02:00
Frédéric Junod
352d77e2ec Merge pull request #8333 from openlayers/cleanup
Fix wrong return type for readHref function
2018-07-01 07:31:56 +02:00
greenkeeper[bot]
a978467726 chore(package): update webpack to version 4.14.0 2018-06-29 13:18:58 +00:00
Frederic Junod
ddeb091871 Fix wrong return type for readHref function 2018-06-29 14:15:07 +02:00
Frédéric Junod
bc60c8ec32 Merge pull request #8329 from fredj/better_typing
Better jsdoc typing
2018-06-29 13:12:09 +02:00
Frederic Junod
6da2e4cef4 More precise Event typing 2018-06-29 12:53:20 +02:00
Andreas Hocevar
001add5a28 Merge pull request #8326 from openlayers/greenkeeper/webpack-4.13.0
Update webpack to the latest version 🚀
2018-06-29 11:05:46 +02:00
Frederic Junod
8c4c70e9f0 Change 'Element' type to 'HTMLElement' 2018-06-29 09:31:59 +02:00
Frederic Junod
0c300d651f Change 'Image' type to 'HTMLImageElement' 2018-06-29 09:31:32 +02:00
greenkeeper[bot]
b072dc5968 chore(package): update webpack to version 4.13.0 2018-06-28 16:39:52 +00:00
Frédéric Junod
52e286b03c Merge pull request #8319 from fredj/cleanup
Remove reference to setProj4 function in documentation
2018-06-27 11:20:15 +02:00
Andreas Hocevar
7dcc720029 Improve readability 2018-06-27 11:15:49 +02:00
Frederic Junod
770407f1ba Remove reference to setProj4 function in documentation
The function was removed in #7598
2018-06-27 10:35:03 +02:00
Andreas Hocevar
53cb47cab9 Merge pull request #8321 from openlayers/greenkeeper/rollup-0.62.0
Update rollup to the latest version 🚀
2018-06-27 10:26:02 +02:00
greenkeeper[bot]
5ba08b7291 chore(package): update rollup to version 0.62.0 2018-06-27 08:11:02 +00:00
Andreas Hocevar
43e67b73c2 Merge pull request #8318 from openlayers/greenkeeper/webpack-4.12.2
Update webpack to the latest version 🚀
2018-06-27 09:39:54 +02:00
greenkeeper[bot]
4ed9f27cd1 chore(package): update webpack to version 4.12.2 2018-06-27 06:41:38 +00:00
Andreas Hocevar
bde6caf082 Merge pull request #8317 from openlayers/release-v5.0.0
Release v5.0.0
2018-06-26 22:08:29 +02:00
307 changed files with 42446 additions and 44491 deletions

View File

@@ -1,8 +1,9 @@
<!--
Thank you for your interest in making OpenLayers better! Thank you for your interest in making OpenLayers better!
To keep this project manageable for maintainers, we ask you to please check all boxes below before submitting an issue. If you are reporting a bug, please link to an example that reproduces the problem. This will make it easier for people who may want to help you debug.
- [ ] I am submitting a bug or feature request, not a usage question. Go to https://stackoverflow.com/questions/tagged/openlayers for questions. If you have a usage question, you might want to try Stack Overflow first: https://stackoverflow.com/questions/tagged/openlayers
- [ ] I have searched GitHub to see if a similar bug or feature request has already been reported.
- [ ] I have verified that the issue is present in the latest version of OpenLayers (see 'LATEST' on https://openlayers.org/). Thanks
- [ ] If reporting a bug, I have created a [CodePen](https://codepen.io) or prepared a stack trace (using the latest version and unminified code, so e.g. `ol-debug.js`, not `ol.js`) that shows the issue. -->

View File

@@ -1,8 +1,13 @@
<!--
Thank you for your interest in making OpenLayers better! Thank you for your interest in making OpenLayers better!
In order to get your proposed changes merged into the master branch, we ask you to please make sure the following boxes are checked *before* submitting your pull request. Before submitting a pull request, it is best to open an issue describing the bug you are fixing or the feature you are proposing to add.
- [ ] This pull request addresses an issue that has been marked with the 'Pull request accepted' label & I have added the link to that issue. Here are some other tips that make pull requests easier to review:
- [ ] It contains one or more small, incremental, logically separate commits, with no merge commits.
- [ ] I have used clear commit messages. * Commits in the branch are small and logically separated (with no unnecessary merge commits).
- [ ] Existing tests pass for me locally & I have added or updated tests for new or changed functionality. * Commit messages are clear.
* Existing tests pass, new functionality is covered by new tests, and fixes have regression tests.
Thanks
-->

1
.gitignore vendored
View File

@@ -2,4 +2,3 @@
/coverage/ /coverage/
/dist/ /dist/
node_modules/ node_modules/
src/index.js

View File

@@ -1,23 +1,44 @@
# OpenLayers # OpenLayers
[![Travis CI Status](https://secure.travis-ci.org/openlayers/openlayers.svg)](http://travis-ci.org/#!/openlayers/openlayers)
[![Greenkeeper badge](https://badges.greenkeeper.io/openlayers/openlayers.svg)](https://greenkeeper.io/)
[![Coverage Status](https://coveralls.io/repos/github/openlayers/openlayers/badge.svg?branch=master)](https://coveralls.io/github/openlayers/openlayers?branch=master)
[![OSGeo Project](https://img.shields.io/badge/OSGeo-Project-brightgreen.svg)](http://osgeo.org/)
[![jsDelivr Hits](https://data.jsdelivr.com/v1/package/npm/openlayers/badge?style=rounded)](https://www.jsdelivr.com/package/npm/openlayers)
[OpenLayers](https://openlayers.org/) is a high-performance, feature-packed library for creating interactive maps on the web. It can display map tiles, vector data and markers loaded from any source on any web page. OpenLayers has been developed to further the use of geographic information of all kinds. It is completely free, Open Source JavaScript, released under the 2-clause BSD License (also known as the FreeBSD). [OpenLayers](https://openlayers.org/) is a high-performance, feature-packed library for creating interactive maps on the web. It can display map tiles, vector data and markers loaded from any source on any web page. OpenLayers has been developed to further the use of geographic information of all kinds. It is completely free, Open Source JavaScript, released under the 2-clause BSD License (also known as the FreeBSD).
## Getting Started ## Getting Started
Use one of the following methods to use OpenLayers in your project: Install the [`ol` package](https://www.npmjs.com/package/ol):
* For use with webpack, Rollup, Browserify, or other module bundlers, install the [`ol` package](https://www.npmjs.com/package/ol):
``` ```
npm install ol npm install ol
``` ```
* If you just want to add a `<script>` tag to test things out, you can link directly to one of the full builds from [cdnjs](https://cdnjs.com/libraries/openlayers) (not recommended for production) Import just what you need for your application:
```js
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import XYZ from 'ol/source/XYZ';
new Map({
target: 'map',
layers: [
new TileLayer({
source: new XYZ({
url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png'
})
})
],
view: new View({
center: [0, 0],
zoom: 2
})
});
```
See the following examples for more detail on bundling OpenLayers with your application:
* Using [Rollup](https://github.com/openlayers/ol-rollup)
* Using [Webpack](https://github.com/openlayers/ol-webpack)
* Using [Parcel](https://github.com/openlayers/ol-parcel)
## Supported Browsers ## Supported Browsers
@@ -39,3 +60,5 @@ Please see our guide on [contributing](CONTRIBUTING.md) if you're interested in
- Need help? Find it on [Stack Overflow using the tag 'openlayers'](http://stackoverflow.com/questions/tagged/openlayers) - Need help? Find it on [Stack Overflow using the tag 'openlayers'](http://stackoverflow.com/questions/tagged/openlayers)
- Follow [@openlayers](https://twitter.com/openlayers) on Twitter - Follow [@openlayers](https://twitter.com/openlayers) on Twitter
[![Build Status](https://travis-ci.org/openlayers/openlayers.svg?branch=master)](https://travis-ci.org/openlayers/openlayers)

View File

@@ -1,5 +1,11 @@
## Upgrade notes ## Upgrade notes
### v5.1.0
#### Geometry constructor and `setCoordinates` no longer accept `null` coordinates
Geometries (`ol/geom/*`) now need to be constructed with valid coordinates (center for `ol/geom/Circle`) as first constructor argument. The same applies to the `setCoordinates()` (`setCenter() for `ol/geom/Circle`) method.
### v5.0.0 ### v5.0.0
#### Renamed `ol/source/TileUTFGrid` to `ol/source/UTFGrid` #### Renamed `ol/source/TileUTFGrid` to `ol/source/UTFGrid`

8
changelog/v5.0.1.md Normal file
View File

@@ -0,0 +1,8 @@
# 5.0.1
The v5.0.1 release helps reduce bundle sizes for bundlers that support the `"sideEffects": "false"`option in `package.json`, and fixes website documentation regarding cdn locations and debug build which has been replaced by source maps.
## Fixes
* [#8341](https://github.com/openlayers/openlayers/pull/8341) - Set sideEffects: false flag ([@ahocevar](https://github.com/ahocevar))
* [#8342](https://github.com/openlayers/openlayers/pull/8342) - Fix links and description in quickstart tutorial ([@ahocevar](https://github.com/ahocevar))

7
changelog/v5.0.2.md Normal file
View File

@@ -0,0 +1,7 @@
# 5.0.2
The v5.0.2 release updates the package readme with new example projects.
## Fixes
* [#8332](https://github.com/openlayers/openlayers/pull/8343) - Starter projects ([@tschaub](https://github.com/tschaub))

9
changelog/v5.0.3.md Normal file
View File

@@ -0,0 +1,9 @@
# 5.0.3
The v5.0.3 fixes a regression in the vector tile renderer and improves the built examples and release package.
## Fixes
* [#8364](https://github.com/openlayers/openlayers/pull/8364) - Make examples work in IE11 ([@ahocevar](https://github.com/ahocevar))
* [#8363](https://github.com/openlayers/openlayers/pull/8363) - Autogenerate src/ol/package.json ([@ahocevar](https://github.com/ahocevar))
* [#8371](https://github.com/openlayers/openlayers/pull/8371) - Skip rendering when there is no replay group ([@ahocevar](https://github.com/ahocevar))

64
changelog/v5.1.0.md Normal file
View File

@@ -0,0 +1,64 @@
# v5.1.0
The 5.1 release adds a few new features a handful of fixes. You should be able to upgrade without any additional work. See the one note below regarding `null` geometry coordinates.
We're working toward type checking with TypeScript. This will complete our move away from using the Closure Compiler for type checking and compilation. We're excited about the improved experience for application developers and will highlight some of the benefit in upcoming releases.
### Upgrade Notes
#### Geometry constructor and `setCoordinates` no longer accept `null` coordinates
Geometries (`ol/geom/*`) now need to be constructed with valid coordinates (center for `ol/geom/Circle`) as first constructor argument. The same applies to the `setCoordinates()` (`setCenter() for `ol/geom/Circle`) method.
### New Features and Fixes
* [#8409](https://github.com/openlayers/openlayers/pull/8409) - Add abstract translate to ol/geom/Geometry ([@pjeweb](https://github.com/pjeweb))
* [#8405](https://github.com/openlayers/openlayers/pull/8405) - Minor type fixes ([@tschaub](https://github.com/tschaub))
* [#8401](https://github.com/openlayers/openlayers/pull/8401) - Make webpack's css loader work ([@ahocevar](https://github.com/ahocevar))
* [#8403](https://github.com/openlayers/openlayers/pull/8403) - Markdown links ([@tschaub](https://github.com/tschaub))
* [#8402](https://github.com/openlayers/openlayers/pull/8402) - Type fixes from the typescript checks ([@fredj](https://github.com/fredj))
* [#8400](https://github.com/openlayers/openlayers/pull/8400) - ESLint config update ([@tschaub](https://github.com/tschaub))
* [#8399](https://github.com/openlayers/openlayers/pull/8399) - Copy ol.css to build dir when building package ([@ahocevar](https://github.com/ahocevar))
* [#8397](https://github.com/openlayers/openlayers/pull/8397) - Update rollup ([@tschaub](https://github.com/tschaub))
* [#8385](https://github.com/openlayers/openlayers/pull/8385) - Use class syntax ([@openlayers](https://github.com/openlayers))
* [#8383](https://github.com/openlayers/openlayers/pull/8383) - style/Icon: Add `setAnchor()` method ([@Turbo87](https://github.com/Turbo87))
* [#8368](https://github.com/openlayers/openlayers/pull/8368) - Make render listeners work with image render mode ([@ahocevar](https://github.com/ahocevar))
* [#8376](https://github.com/openlayers/openlayers/pull/8376) - copy ZM values to polygon in makeRegular ([@virtualcitySYSTEMS](https://github.com/virtualcitySYSTEMS))
* [#8372](https://github.com/openlayers/openlayers/pull/8372) - Release v5.0.3 ([@openlayers](https://github.com/openlayers))
* [#8364](https://github.com/openlayers/openlayers/pull/8364) - Make examples work in IE11 ([@ahocevar](https://github.com/ahocevar))
* [#8363](https://github.com/openlayers/openlayers/pull/8363) - Autogenerate src/ol/package.json ([@ahocevar](https://github.com/ahocevar))
* [#8371](https://github.com/openlayers/openlayers/pull/8371) - Skip rendering when there is no replay group ([@ahocevar](https://github.com/ahocevar))
* [#8362](https://github.com/openlayers/openlayers/pull/8362) - Smart flat coordinates ([@ahocevar](https://github.com/ahocevar))
* [#8352](https://github.com/openlayers/openlayers/pull/8352) - Set `sideEffects` to `false` instead of `"false"` ([@tschaub](https://github.com/tschaub))
* [#8351](https://github.com/openlayers/openlayers/pull/8351) - Fix typo in release notes ([@ahocevar](https://github.com/ahocevar))
* [#8350](https://github.com/openlayers/openlayers/pull/8350) - Updates for v5.0.2 ([@ahocevar](https://github.com/ahocevar))
* [#8349](https://github.com/openlayers/openlayers/pull/8349) - Release v5.0.1 ([@ahocevar](https://github.com/ahocevar))
* [#8343](https://github.com/openlayers/openlayers/pull/8343) - Starter projects ([@tschaub](https://github.com/tschaub))
* [#8347](https://github.com/openlayers/openlayers/pull/8347) - Fix typos in release notes ([@ahocevar](https://github.com/ahocevar))
* [#8346](https://github.com/openlayers/openlayers/pull/8346) - Release v5.0.1 ([@openlayers](https://github.com/openlayers))
* [#8342](https://github.com/openlayers/openlayers/pull/8342) - Fix links and description in quickstart tutorial ([@ahocevar](https://github.com/ahocevar))
* [#8344](https://github.com/openlayers/openlayers/pull/8344) - Updated issue and pr templates ([@tschaub](https://github.com/tschaub))
* [#8341](https://github.com/openlayers/openlayers/pull/8341) - Set sideEffects: false flag ([@ahocevar](https://github.com/ahocevar))
* [#8333](https://github.com/openlayers/openlayers/pull/8333) - Fix wrong return type for readHref function ([@openlayers](https://github.com/openlayers))
* [#8329](https://github.com/openlayers/openlayers/pull/8329) - Better jsdoc typing ([@fredj](https://github.com/fredj))
* [#8319](https://github.com/openlayers/openlayers/pull/8319) - Remove reference to setProj4 function in documentation ([@fredj](https://github.com/fredj))
<details>
<summary>Dependency Updates</summary>
* [#8410](https://github.com/openlayers/openlayers/pull/8410) - Update rollup to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#8408](https://github.com/openlayers/openlayers/pull/8408) - Update rollup to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#8386](https://github.com/openlayers/openlayers/pull/8386) - Update fs-extra to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#8382](https://github.com/openlayers/openlayers/pull/8382) - Update webpack to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#8373](https://github.com/openlayers/openlayers/pull/8373) - Update webpack to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#8355](https://github.com/openlayers/openlayers/pull/8355) - Update recast to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#8354](https://github.com/openlayers/openlayers/pull/8354) - Update webpack to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#8348](https://github.com/openlayers/openlayers/pull/8348) - Update webpack to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#8338](https://github.com/openlayers/openlayers/pull/8338) - Update recast to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#8332](https://github.com/openlayers/openlayers/pull/8332) - Update webpack to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#8326](https://github.com/openlayers/openlayers/pull/8326) - Update webpack to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#8321](https://github.com/openlayers/openlayers/pull/8321) - Update rollup to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
* [#8318](https://github.com/openlayers/openlayers/pull/8318) - Update webpack to the latest version 🚀 ([@openlayers](https://github.com/openlayers))
</details>

3
changelog/v5.1.1.md Normal file
View File

@@ -0,0 +1,3 @@
# 5.1.1
The 5.1.1 release is a patch to include the readme in the package. See the [5.1.0 notes](https://github.com/openlayers/openlayers/releases/tag/v5.0.3) for detail on the 5.1 release.

View File

@@ -7,7 +7,7 @@ import buble from 'rollup-plugin-buble';
import sourcemaps from 'rollup-plugin-sourcemaps'; import sourcemaps from 'rollup-plugin-sourcemaps';
export default { export default {
input: 'src/index.js', input: 'build/index.js',
output: [ output: [
{file: 'build/ol.js', format: 'iife', sourcemap: true} {file: 'build/ol.js', format: 'iife', sourcemap: true}
], ],

View File

@@ -7,6 +7,9 @@ layout: doc.hbs
This primer shows you how to put a simple map on a web page. This primer shows you how to put a simple map on a web page.
**For production, we strongly recommend bundling the application together with its dependencies, as explained in the [Building an OpenLayers Application](./tutorials/bundle.html) tutorial.**
## Put a map on a page ## Put a map on a page
Below you'll find a complete working example. Create a new file, copy in the contents below, and open in a browser: Below you'll find a complete working example. Create a new file, copy in the contents below, and open in a browser:
@@ -15,14 +18,14 @@ Below you'll find a complete working example. Create a new file, copy in the co
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<head> <head>
<link rel="stylesheet" href="https://openlayers.org/en/{{ latest }}/css/ol.css" type="text/css"> <link rel="stylesheet" href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/{{ latest }}/css/ol.css" type="text/css">
<style> <style>
.map { .map {
height: 400px; height: 400px;
width: 100%; width: 100%;
} }
</style> </style>
<script src="https://openlayers.org/en/{{ latest }}/build/ol.js" type="text/javascript"></script> <script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/{{ latest }}/build/ol.js"></script>
<title>OpenLayers example</title> <title>OpenLayers example</title>
</head> </head>
<body> <body>
@@ -56,10 +59,8 @@ To include a map a web page you will need 3 things:
### Include OpenLayers ### Include OpenLayers
**Caveat:** In production, it is not recommended to include dependencies as script tag. Instead, we recommend bundling the application together with its dependencies, as explained in the [Building an OpenLayers Application](./tutorials/bundle.html) tutorial.
```xml ```xml
<script src="https://openlayers.org/en/{{ latest }}/build/ol.js" type="text/javascript"></script> <script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/{{ latest }}/build/ol.js"></script>
``` ```
The first part is to include the JavaScript library. For the purpose of this tutorial, here we simply point to the openlayers.org website to get the whole library. In a production environment, we would build a custom version of the library including only the module needed for our application. The first part is to include the JavaScript library. For the purpose of this tutorial, here we simply point to the openlayers.org website to get the whole library. In a production environment, we would build a custom version of the library including only the module needed for our application.

View File

@@ -37,13 +37,13 @@ Class hierarchies grouped by their parent are provided in a subfolder of the pac
For convenience, these are also available as named exports, e.g. For convenience, these are also available as named exports, e.g.
```js ```js
import {Map, View} from `ol`; import {Map, View} from 'ol';
import {Tile, Vector} from `ol/layer`; import {Tile, Vector} from 'ol/layer';
``` ```
In addition to these re-exported classes, modules with lowercase names also provide constants or functions as named exports: In addition to these re-exported classes, modules with lowercase names also provide constants or functions as named exports:
```js ```js
import {inherits} from `ol`; import {inherits} from 'ol';
import {fromLonLat} from `ol/proj`; import {fromLonLat} from 'ol/proj';
``` ```

View File

@@ -1,4 +1,4 @@
import {inherits} from '../src/ol/index.js'; import {inherits} from '../src/ol/util.js';
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
import {defaults as defaultControls, Control} from '../src/ol/control.js'; import {defaults as defaultControls, Control} from '../src/ol/control.js';

View File

@@ -1,4 +1,4 @@
import {inherits} from '../src/ol/index.js'; import {inherits} from '../src/ol/util.js';
import Feature from '../src/ol/Feature.js'; import Feature from '../src/ol/Feature.js';
import Map from '../src/ol/Map.js'; import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js'; import View from '../src/ol/View.js';
@@ -29,7 +29,7 @@ app.Drag = function() {
}); });
/** /**
* @type {module:ol~Pixel} * @type {module:ol/pixel~Pixel}
* @private * @private
*/ */
this.coordinate_ = null; this.coordinate_ = null;

View File

@@ -18,6 +18,18 @@ module.exports = {
context: src, context: src,
target: 'web', target: 'web',
entry: entry, entry: entry,
module: {
rules: [{
use: {
loader: 'buble-loader'
},
test: /\.js$/,
include: [
path.join(__dirname, '..', '..', 'src'),
path.join(__dirname, '..')
]
}]
},
optimization: { optimization: {
runtimeChunk: { runtimeChunk: {
name: 'common' name: 'common'

View File

@@ -64,20 +64,20 @@ function createWordIndex(exampleData) {
/** /**
* Gets the source for the chunk that matches the jsPath * Gets the source for the chunk that matches the jsPath
* @param {Object} chunk Chunk. * @param {Object} chunk Chunk.
* @param {string} jsPath Path of the file. * @param {string} jsName Name of the file.
* @return {string} The source. * @return {string} The source.
*/ */
function getJsSource(chunk, jsPath) { function getJsSource(chunk, jsName) {
let jsSource; let jsSource;
for (let i = 0, ii = chunk.modules.length; i < ii; ++i) { for (let i = 0, ii = chunk.modules.length; i < ii; ++i) {
const module = chunk.modules[i]; const module = chunk.modules[i];
if (module.modules) { if (module.modules) {
jsSource = getJsSource(module, jsPath); jsSource = getJsSource(module, jsName);
if (jsSource) { if (jsSource) {
return jsSource; return jsSource;
} }
} }
if (module.identifier == jsPath) { if (module.identifier.endsWith(jsName)) {
return module.source; return module.source;
} }
} }
@@ -151,8 +151,7 @@ ExampleBuilder.prototype.render = async function(dir, chunk) {
// add in script tag // add in script tag
const jsName = `${name}.js`; const jsName = `${name}.js`;
const jsPath = path.join(dir, jsName); let jsSource = getJsSource(chunk, path.join('.', jsName));
let jsSource = getJsSource(chunk, jsPath);
jsSource = jsSource.replace(/'\.\.\/src\//g, '\''); jsSource = jsSource.replace(/'\.\.\/src\//g, '\'');
if (data.cloak) { if (data.cloak) {
for (const entry of data.cloak) { for (const entry of data.cloak) {

View File

@@ -1,12 +1,13 @@
{ {
"name": "openlayers", "name": "ol",
"version": "5.0.0", "version": "5.1.1",
"description": "OpenLayers mapping library", "description": "OpenLayers mapping library",
"keywords": [ "keywords": [
"map", "map",
"mapping", "mapping",
"ol" "ol"
], ],
"private": true,
"homepage": "https://openlayers.org/", "homepage": "https://openlayers.org/",
"scripts": { "scripts": {
"lint": "eslint tasks test src/ol examples config", "lint": "eslint tasks test src/ol examples config",
@@ -15,18 +16,14 @@
"karma": "karma start test/karma.config.js", "karma": "karma start test/karma.config.js",
"serve-examples": "webpack-dev-server --config examples/webpack/config.js --mode development --watch", "serve-examples": "webpack-dev-server --config examples/webpack/config.js --mode development --watch",
"build-examples": "webpack --config examples/webpack/config.js --mode production", "build-examples": "webpack --config examples/webpack/config.js --mode production",
"build-index": "node tasks/generate-index", "build-package": "npm run transpile && npm run copy-css && node tasks/prepare-package && cp README.md build/ol",
"set-version": "node tasks/set-version", "build-index": "npm run build-package && node tasks/generate-index",
"prebuild": "npm run set-version && npm run build-index", "build-legacy": "rm -rf build && npm run build-index && rollup --config config/rollup.js && cleancss --source-map src/ol/ol.css -o build/ol.css",
"prepare": "npm run set-version", "copy-css": "cp src/ol/ol.css build/ol/ol.css",
"build": "rollup --config config/rollup.js && cleancss --source-map src/ol/ol.css -o build/ol.css", "transpile": "rm -rf build/ol && mkdir -p build && buble --input src/ol --output build/ol --no modules --sourcemap",
"presrc-closure": "npm run prebuild",
"src-closure": "node tasks/transform-types",
"pretypecheck": "npm run src-closure",
"typecheck": "node tasks/typecheck",
"apidoc": "jsdoc config/jsdoc/api/index.md -c config/jsdoc/api/conf.json -P package.json -d build/apidoc" "apidoc": "jsdoc config/jsdoc/api/index.md -c config/jsdoc/api/conf.json -P package.json -d build/apidoc"
}, },
"main": "src/ol/index.js", "main": "index.js",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git://github.com/openlayers/openlayers.git" "url": "git://github.com/openlayers/openlayers.git"
@@ -35,29 +32,24 @@
"bugs": { "bugs": {
"url": "https://github.com/openlayers/openlayers/issues" "url": "https://github.com/openlayers/openlayers/issues"
}, },
"browser": "dist/ol.js",
"style": [
"css/ol.css"
],
"dependencies": { "dependencies": {
"pbf": "3.1.0", "pbf": "3.1.0",
"pixelworks": "1.1.0", "pixelworks": "1.1.0",
"rbush": "2.0.2" "rbush": "2.0.2"
}, },
"devDependencies": { "devDependencies": {
"babel-core": "^6.26.3", "buble": "^0.19.3",
"babel-plugin-jsdoc-closure": "1.5.1", "buble-loader": "^0.5.1",
"chaikin-smooth": "^1.0.4", "chaikin-smooth": "^1.0.4",
"clean-css-cli": "4.1.11", "clean-css-cli": "4.1.11",
"copy-webpack-plugin": "^4.4.1", "copy-webpack-plugin": "^4.4.1",
"coveralls": "3.0.1", "coveralls": "3.0.1",
"eslint": "5.0.1", "eslint": "5.0.1",
"eslint-config-openlayers": "^9.2.0", "eslint-config-openlayers": "^11.0.0",
"expect.js": "0.3.1", "expect.js": "0.3.1",
"front-matter": "^2.1.2", "front-matter": "^2.1.2",
"fs-extra": "^6.0.0", "fs-extra": "^7.0.0",
"glob": "^7.1.2", "glob": "^7.1.2",
"google-closure-compiler": "20180610.0.2",
"handlebars": "4.0.11", "handlebars": "4.0.11",
"istanbul": "0.4.5", "istanbul": "0.4.5",
"jquery": "3.3.1", "jquery": "3.3.1",
@@ -75,8 +67,7 @@
"mustache": "^2.3.0", "mustache": "^2.3.0",
"pixelmatch": "^4.0.2", "pixelmatch": "^4.0.2",
"proj4": "2.4.4", "proj4": "2.4.4",
"recast": "0.15.0", "rollup": "0.63.4",
"rollup": "0.61.2",
"rollup-plugin-buble": "0.19.2", "rollup-plugin-buble": "0.19.2",
"rollup-plugin-commonjs": "9.1.3", "rollup-plugin-commonjs": "9.1.3",
"rollup-plugin-node-resolve": "3.3.0", "rollup-plugin-node-resolve": "3.3.0",
@@ -86,12 +77,14 @@
"uglifyjs-webpack-plugin": "^1.2.5", "uglifyjs-webpack-plugin": "^1.2.5",
"url-polyfill": "^1.0.13", "url-polyfill": "^1.0.13",
"walk": "^2.3.9", "walk": "^2.3.9",
"webpack": "4.12.1", "webpack": "4.16.1",
"webpack-cli": "^3.0.3", "webpack-cli": "^3.0.8",
"webpack-dev-server": "^3.1.4" "webpack-dev-server": "^3.1.4"
}, },
"eslintConfig": { "eslintConfig": {
"extends": "openlayers" "extends": "openlayers"
}, },
"sideEffects": false "sideEffects": [
"ol.css"
]
} }

View File

@@ -1,29 +1,28 @@
/** /**
* @module ol/AssertionError * @module ol/AssertionError
*/ */
import {VERSION, inherits} from './util.js'; import {VERSION} from './util.js';
/** /**
* Error object thrown when an assertion failed. This is an ECMA-262 Error, * Error object thrown when an assertion failed. This is an ECMA-262 Error,
* extended with a `code` property. * extended with a `code` property.
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error} * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error.
* @constructor
* @extends {Error}
* @param {number} code Error code.
*/ */
const AssertionError = function(code) { class AssertionError extends Error {
const path = VERSION.split('-')[0];
/** /**
* @type {string} * @param {number} code Error code.
*/ */
this.message = 'Assertion failed. See https://openlayers.org/en/' + path + constructor(code) {
const path = VERSION.split('-')[0];
const message = 'Assertion failed. See https://openlayers.org/en/' + path +
'/doc/errors/#' + code + ' for details.'; '/doc/errors/#' + code + ' for details.';
super(message);
/** /**
* Error code. The meaning of the code can be found on * Error code. The meaning of the code can be found on
* {@link https://openlayers.org/en/latest/doc/errors/} (replace `latest` with * https://openlayers.org/en/latest/doc/errors/ (replace `latest` with
* the version found in the OpenLayers script's header comment if a version * the version found in the OpenLayers script's header comment if a version
* other than the latest is used). * other than the latest is used).
* @type {number} * @type {number}
@@ -31,10 +30,15 @@ const AssertionError = function(code) {
*/ */
this.code = code; this.code = code;
/**
* @type {string}
*/
this.name = 'AssertionError'; this.name = 'AssertionError';
}; // Re-assign message, see https://github.com/Rich-Harris/buble/issues/40
this.message = message;
}
inherits(AssertionError, Error); }
export default AssertionError; export default AssertionError;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/Collection * @module ol/Collection
*/ */
import {inherits} from './util.js';
import AssertionError from './AssertionError.js'; import AssertionError from './AssertionError.js';
import CollectionEventType from './CollectionEventType.js'; import CollectionEventType from './CollectionEventType.js';
import BaseObject from './Object.js'; import BaseObject from './Object.js';
@@ -21,15 +20,15 @@ const Property = {
* @classdesc * @classdesc
* Events emitted by {@link module:ol/Collection~Collection} instances are instances of this * Events emitted by {@link module:ol/Collection~Collection} instances are instances of this
* type. * type.
* */
* @constructor export class CollectionEvent extends Event {
* @extends {module:ol/events/Event}
/**
* @param {module:ol/CollectionEventType} type Type. * @param {module:ol/CollectionEventType} type Type.
* @param {*=} opt_element Element. * @param {*=} opt_element Element.
*/ */
export const CollectionEvent = function(type, opt_element) { constructor(type, opt_element) {
super(type);
Event.call(this, type);
/** /**
* The element that is added to or removed from the collection. * The element that is added to or removed from the collection.
@@ -38,9 +37,9 @@ export const CollectionEvent = function(type, opt_element) {
*/ */
this.element = opt_element; this.element = opt_element;
}; }
inherits(CollectionEvent, Event); }
/** /**
@@ -57,17 +56,18 @@ inherits(CollectionEvent, Event);
* Collection; they trigger events on the appropriate object, not on the * Collection; they trigger events on the appropriate object, not on the
* Collection as a whole. * Collection as a whole.
* *
* @constructor
* @extends {module:ol/Object}
* @fires module:ol/Collection~CollectionEvent
* @param {Array.<T>=} opt_array Array.
* @param {module:ol/Collection~Options=} opt_options Collection options.
* @template T * @template T
* @api * @api
*/ */
const Collection = function(opt_array, opt_options) { class Collection extends BaseObject {
BaseObject.call(this); /**
* @param {Array.<T>=} opt_array Array.
* @param {module:ol/Collection~Options=} opt_options Collection options.
*/
constructor(opt_array, opt_options) {
super();
const options = opt_options || {}; const options = opt_options || {};
@@ -91,21 +91,17 @@ const Collection = function(opt_array, opt_options) {
this.updateLength_(); this.updateLength_();
}; }
inherits(Collection, BaseObject);
/** /**
* Remove all elements from the collection. * Remove all elements from the collection.
* @api * @api
*/ */
Collection.prototype.clear = function() { clear() {
while (this.getLength() > 0) { while (this.getLength() > 0) {
this.pop(); this.pop();
} }
}; }
/** /**
* Add elements to the collection. This pushes each item in the provided array * Add elements to the collection. This pushes each item in the provided array
@@ -114,13 +110,12 @@ Collection.prototype.clear = function() {
* @return {module:ol/Collection.<T>} This collection. * @return {module:ol/Collection.<T>} This collection.
* @api * @api
*/ */
Collection.prototype.extend = function(arr) { extend(arr) {
for (let i = 0, ii = arr.length; i < ii; ++i) { for (let i = 0, ii = arr.length; i < ii; ++i) {
this.push(arr[i]); this.push(arr[i]);
} }
return this; return this;
}; }
/** /**
* Iterate over each element, calling the provided callback. * Iterate over each element, calling the provided callback.
@@ -129,13 +124,12 @@ Collection.prototype.extend = function(arr) {
* index and the array). The return value is ignored. * index and the array). The return value is ignored.
* @api * @api
*/ */
Collection.prototype.forEach = function(f) { forEach(f) {
const array = this.array_; const array = this.array_;
for (let i = 0, ii = array.length; i < ii; ++i) { for (let i = 0, ii = array.length; i < ii; ++i) {
f(array[i], i, array); f(array[i], i, array);
} }
}; }
/** /**
* Get a reference to the underlying Array object. Warning: if the array * Get a reference to the underlying Array object. Warning: if the array
@@ -145,10 +139,9 @@ Collection.prototype.forEach = function(f) {
* @return {!Array.<T>} Array. * @return {!Array.<T>} Array.
* @api * @api
*/ */
Collection.prototype.getArray = function() { getArray() {
return this.array_; return this.array_;
}; }
/** /**
* Get the element at the provided index. * Get the element at the provided index.
@@ -156,10 +149,9 @@ Collection.prototype.getArray = function() {
* @return {T} Element. * @return {T} Element.
* @api * @api
*/ */
Collection.prototype.item = function(index) { item(index) {
return this.array_[index]; return this.array_[index];
}; }
/** /**
* Get the length of this collection. * Get the length of this collection.
@@ -167,10 +159,9 @@ Collection.prototype.item = function(index) {
* @observable * @observable
* @api * @api
*/ */
Collection.prototype.getLength = function() { getLength() {
return /** @type {number} */ (this.get(Property.LENGTH)); return /** @type {number} */ (this.get(Property.LENGTH));
}; }
/** /**
* Insert an element at the provided index. * Insert an element at the provided index.
@@ -178,7 +169,7 @@ Collection.prototype.getLength = function() {
* @param {T} elem Element. * @param {T} elem Element.
* @api * @api
*/ */
Collection.prototype.insertAt = function(index, elem) { insertAt(index, elem) {
if (this.unique_) { if (this.unique_) {
this.assertUnique_(elem); this.assertUnique_(elem);
} }
@@ -186,8 +177,7 @@ Collection.prototype.insertAt = function(index, elem) {
this.updateLength_(); this.updateLength_();
this.dispatchEvent( this.dispatchEvent(
new CollectionEvent(CollectionEventType.ADD, elem)); new CollectionEvent(CollectionEventType.ADD, elem));
}; }
/** /**
* Remove the last element of the collection and return it. * Remove the last element of the collection and return it.
@@ -195,10 +185,9 @@ Collection.prototype.insertAt = function(index, elem) {
* @return {T|undefined} Element. * @return {T|undefined} Element.
* @api * @api
*/ */
Collection.prototype.pop = function() { pop() {
return this.removeAt(this.getLength() - 1); return this.removeAt(this.getLength() - 1);
}; }
/** /**
* Insert the provided element at the end of the collection. * Insert the provided element at the end of the collection.
@@ -206,15 +195,14 @@ Collection.prototype.pop = function() {
* @return {number} New length of the collection. * @return {number} New length of the collection.
* @api * @api
*/ */
Collection.prototype.push = function(elem) { push(elem) {
if (this.unique_) { if (this.unique_) {
this.assertUnique_(elem); this.assertUnique_(elem);
} }
const n = this.getLength(); const n = this.getLength();
this.insertAt(n, elem); this.insertAt(n, elem);
return this.getLength(); return this.getLength();
}; }
/** /**
* Remove the first occurrence of an element from the collection. * Remove the first occurrence of an element from the collection.
@@ -222,7 +210,7 @@ Collection.prototype.push = function(elem) {
* @return {T|undefined} The removed element or undefined if none found. * @return {T|undefined} The removed element or undefined if none found.
* @api * @api
*/ */
Collection.prototype.remove = function(elem) { remove(elem) {
const arr = this.array_; const arr = this.array_;
for (let i = 0, ii = arr.length; i < ii; ++i) { for (let i = 0, ii = arr.length; i < ii; ++i) {
if (arr[i] === elem) { if (arr[i] === elem) {
@@ -230,8 +218,7 @@ Collection.prototype.remove = function(elem) {
} }
} }
return undefined; return undefined;
}; }
/** /**
* Remove the element at the provided index and return it. * Remove the element at the provided index and return it.
@@ -240,14 +227,13 @@ Collection.prototype.remove = function(elem) {
* @return {T|undefined} Value. * @return {T|undefined} Value.
* @api * @api
*/ */
Collection.prototype.removeAt = function(index) { removeAt(index) {
const prev = this.array_[index]; const prev = this.array_[index];
this.array_.splice(index, 1); this.array_.splice(index, 1);
this.updateLength_(); this.updateLength_();
this.dispatchEvent(new CollectionEvent(CollectionEventType.REMOVE, prev)); this.dispatchEvent(new CollectionEvent(CollectionEventType.REMOVE, prev));
return prev; return prev;
}; }
/** /**
* Set the element at the provided index. * Set the element at the provided index.
@@ -255,7 +241,7 @@ Collection.prototype.removeAt = function(index) {
* @param {T} elem Element. * @param {T} elem Element.
* @api * @api
*/ */
Collection.prototype.setAt = function(index, elem) { setAt(index, elem) {
const n = this.getLength(); const n = this.getLength();
if (index < n) { if (index < n) {
if (this.unique_) { if (this.unique_) {
@@ -273,28 +259,28 @@ Collection.prototype.setAt = function(index, elem) {
} }
this.insertAt(index, elem); this.insertAt(index, elem);
} }
}; }
/** /**
* @private * @private
*/ */
Collection.prototype.updateLength_ = function() { updateLength_() {
this.set(Property.LENGTH, this.array_.length); this.set(Property.LENGTH, this.array_.length);
}; }
/** /**
* @private * @private
* @param {T} elem Element. * @param {T} elem Element.
* @param {number=} opt_except Optional index to ignore. * @param {number=} opt_except Optional index to ignore.
*/ */
Collection.prototype.assertUnique_ = function(elem, opt_except) { assertUnique_(elem, opt_except) {
for (let i = 0, ii = this.array_.length; i < ii; ++i) { for (let i = 0, ii = this.array_.length; i < ii; ++i) {
if (this.array_[i] === elem && i !== opt_except) { if (this.array_[i] === elem && i !== opt_except) {
throw new AssertionError(58); throw new AssertionError(58);
} }
} }
}; }
}
export default Collection; export default Collection;

View File

@@ -5,9 +5,18 @@ import {UNDEFINED} from './functions.js';
/** /**
* Objects that need to clean up after themselves. * Objects that need to clean up after themselves.
* @constructor
*/ */
const Disposable = function() {}; class Disposable {
/**
* Clean up.
*/
dispose() {
if (!this.disposed_) {
this.disposed_ = true;
this.disposeInternal();
}
}
}
/** /**
* The object has already been disposed. * The object has already been disposed.
@@ -16,16 +25,6 @@ const Disposable = function() {};
*/ */
Disposable.prototype.disposed_ = false; Disposable.prototype.disposed_ = false;
/**
* Clean up.
*/
Disposable.prototype.dispose = function() {
if (!this.disposed_) {
this.disposed_ = true;
this.disposeInternal();
}
};
/** /**
* Extension point for disposable objects. * Extension point for disposable objects.
* @protected * @protected

View File

@@ -4,7 +4,6 @@
import {assert} from './asserts.js'; import {assert} from './asserts.js';
import {listen, unlisten, unlistenByKey} from './events.js'; import {listen, unlisten, unlistenByKey} from './events.js';
import EventType from './events/EventType.js'; import EventType from './events/EventType.js';
import {inherits} from './util.js';
import BaseObject, {getChangeEventType} from './Object.js'; import BaseObject, {getChangeEventType} from './Object.js';
import Geometry from './geom/Geometry.js'; import Geometry from './geom/Geometry.js';
import Style from './style/Style.js'; import Style from './style/Style.js';
@@ -51,17 +50,19 @@ import Style from './style/Style.js';
* var point = feature.getGeometry(); * var point = feature.getGeometry();
* ``` * ```
* *
* @constructor * @api
* @extends {module:ol/Object} */
class Feature extends BaseObject {
/**
* @param {module:ol/geom/Geometry|Object.<string, *>=} opt_geometryOrProperties * @param {module:ol/geom/Geometry|Object.<string, *>=} opt_geometryOrProperties
* You may pass a Geometry object directly, or an object literal containing * You may pass a Geometry object directly, or an object literal containing
* properties. If you pass an object literal, you may include a Geometry * properties. If you pass an object literal, you may include a Geometry
* associated with a `geometry` key. * associated with a `geometry` key.
* @api
*/ */
const Feature = function(opt_geometryOrProperties) { constructor(opt_geometryOrProperties) {
BaseObject.call(this); super();
/** /**
* @private * @private
@@ -109,10 +110,7 @@ const Feature = function(opt_geometryOrProperties) {
this.setProperties(properties); this.setProperties(properties);
} }
} }
}; }
inherits(Feature, BaseObject);
/** /**
* Clone this feature. If the original feature has a geometry it * Clone this feature. If the original feature has a geometry it
@@ -120,7 +118,7 @@ inherits(Feature, BaseObject);
* @return {module:ol/Feature} The clone. * @return {module:ol/Feature} The clone.
* @api * @api
*/ */
Feature.prototype.clone = function() { clone() {
const clone = new Feature(this.getProperties()); const clone = new Feature(this.getProperties());
clone.setGeometryName(this.getGeometryName()); clone.setGeometryName(this.getGeometryName());
const geometry = this.getGeometry(); const geometry = this.getGeometry();
@@ -132,8 +130,7 @@ Feature.prototype.clone = function() {
clone.setStyle(style); clone.setStyle(style);
} }
return clone; return clone;
}; }
/** /**
* Get the feature's default geometry. A feature may have any number of named * Get the feature's default geometry. A feature may have any number of named
@@ -143,12 +140,11 @@ Feature.prototype.clone = function() {
* @api * @api
* @observable * @observable
*/ */
Feature.prototype.getGeometry = function() { getGeometry() {
return ( return (
/** @type {module:ol/geom/Geometry|undefined} */ (this.get(this.geometryName_)) /** @type {module:ol/geom/Geometry|undefined} */ (this.get(this.geometryName_))
); );
}; }
/** /**
* Get the feature identifier. This is a stable identifier for the feature and * Get the feature identifier. This is a stable identifier for the feature and
@@ -157,10 +153,9 @@ Feature.prototype.getGeometry = function() {
* @return {number|string|undefined} Id. * @return {number|string|undefined} Id.
* @api * @api
*/ */
Feature.prototype.getId = function() { getId() {
return this.id_; return this.id_;
}; }
/** /**
* Get the name of the feature's default geometry. By default, the default * Get the name of the feature's default geometry. By default, the default
@@ -169,10 +164,9 @@ Feature.prototype.getId = function() {
* for this feature. * for this feature.
* @api * @api
*/ */
Feature.prototype.getGeometryName = function() { getGeometryName() {
return this.geometryName_; return this.geometryName_;
}; }
/** /**
* Get the feature's style. Will return what was provided to the * Get the feature's style. Will return what was provided to the
@@ -180,10 +174,9 @@ Feature.prototype.getGeometryName = function() {
* @return {module:ol/style/Style|Array.<module:ol/style/Style>|module:ol/style/Style~StyleFunction} The feature style. * @return {module:ol/style/Style|Array.<module:ol/style/Style>|module:ol/style/Style~StyleFunction} The feature style.
* @api * @api
*/ */
Feature.prototype.getStyle = function() { getStyle() {
return this.style_; return this.style_;
}; }
/** /**
* Get the feature's style function. * Get the feature's style function.
@@ -191,23 +184,21 @@ Feature.prototype.getStyle = function() {
* representing the current style of this feature. * representing the current style of this feature.
* @api * @api
*/ */
Feature.prototype.getStyleFunction = function() { getStyleFunction() {
return this.styleFunction_; return this.styleFunction_;
}; }
/** /**
* @private * @private
*/ */
Feature.prototype.handleGeometryChange_ = function() { handleGeometryChange_() {
this.changed(); this.changed();
}; }
/** /**
* @private * @private
*/ */
Feature.prototype.handleGeometryChanged_ = function() { handleGeometryChanged_() {
if (this.geometryChangeKey_) { if (this.geometryChangeKey_) {
unlistenByKey(this.geometryChangeKey_); unlistenByKey(this.geometryChangeKey_);
this.geometryChangeKey_ = null; this.geometryChangeKey_ = null;
@@ -218,8 +209,7 @@ Feature.prototype.handleGeometryChanged_ = function() {
EventType.CHANGE, this.handleGeometryChange_, this); EventType.CHANGE, this.handleGeometryChange_, this);
} }
this.changed(); this.changed();
}; }
/** /**
* Set the default geometry for the feature. This will update the property * Set the default geometry for the feature. This will update the property
@@ -228,10 +218,9 @@ Feature.prototype.handleGeometryChanged_ = function() {
* @api * @api
* @observable * @observable
*/ */
Feature.prototype.setGeometry = function(geometry) { setGeometry(geometry) {
this.set(this.geometryName_, geometry); this.set(this.geometryName_, geometry);
}; }
/** /**
* Set the style for the feature. This can be a single style object, an array * Set the style for the feature. This can be a single style object, an array
@@ -241,12 +230,11 @@ Feature.prototype.setGeometry = function(geometry) {
* @api * @api
* @fires module:ol/events/Event~Event#event:change * @fires module:ol/events/Event~Event#event:change
*/ */
Feature.prototype.setStyle = function(style) { setStyle(style) {
this.style_ = style; this.style_ = style;
this.styleFunction_ = !style ? undefined : createStyleFunction(style); this.styleFunction_ = !style ? undefined : createStyleFunction(style);
this.changed(); this.changed();
}; }
/** /**
* Set the feature id. The feature id is considered stable and may be used when * Set the feature id. The feature id is considered stable and may be used when
@@ -257,11 +245,10 @@ Feature.prototype.setStyle = function(style) {
* @api * @api
* @fires module:ol/events/Event~Event#event:change * @fires module:ol/events/Event~Event#event:change
*/ */
Feature.prototype.setId = function(id) { setId(id) {
this.id_ = id; this.id_ = id;
this.changed(); this.changed();
}; }
/** /**
* Set the property name to be used when getting the feature's default geometry. * Set the property name to be used when getting the feature's default geometry.
@@ -270,7 +257,7 @@ Feature.prototype.setId = function(id) {
* @param {string} name The property name of the default geometry. * @param {string} name The property name of the default geometry.
* @api * @api
*/ */
Feature.prototype.setGeometryName = function(name) { setGeometryName(name) {
unlisten( unlisten(
this, getChangeEventType(this.geometryName_), this, getChangeEventType(this.geometryName_),
this.handleGeometryChanged_, this); this.handleGeometryChanged_, this);
@@ -279,7 +266,8 @@ Feature.prototype.setGeometryName = function(name) {
this, getChangeEventType(this.geometryName_), this, getChangeEventType(this.geometryName_),
this.handleGeometryChanged_, this); this.handleGeometryChanged_, this);
this.handleGeometryChanged_(); this.handleGeometryChanged_();
}; }
}
/** /**

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/Geolocation * @module ol/Geolocation
*/ */
import {inherits} from './util.js';
import GeolocationProperty from './GeolocationProperty.js'; import GeolocationProperty from './GeolocationProperty.js';
import BaseObject, {getChangeEventType} from './Object.js'; import BaseObject, {getChangeEventType} from './Object.js';
import {listen} from './events.js'; import {listen} from './events.js';
@@ -16,8 +15,8 @@ import {get as getProjection, getTransformFromProjections, identityTransform} fr
* @typedef {Object} Options * @typedef {Object} Options
* @property {boolean} [tracking=false] Start Tracking right after * @property {boolean} [tracking=false] Start Tracking right after
* instantiation. * instantiation.
* @property {GeolocationPositionOptions} [trackingOptions] Tracking options. * @property {PositionOptions} [trackingOptions] Tracking options.
* See {@link http://www.w3.org/TR/geolocation-API/#position_options_interface}. * See http://www.w3.org/TR/geolocation-API/#position_options_interface.
* @property {module:ol/proj~ProjectionLike} [projection] The projection the position * @property {module:ol/proj~ProjectionLike} [projection] The projection the position
* is reported in. * is reported in.
*/ */
@@ -44,14 +43,16 @@ import {get as getProjection, getTransformFromProjections, identityTransform} fr
* }); * });
* *
* @fires error * @fires error
* @constructor
* @extends {module:ol/Object}
* @param {module:ol/Geolocation~Options=} opt_options Options.
* @api * @api
*/ */
const Geolocation = function(opt_options) { class Geolocation extends BaseObject {
BaseObject.call(this); /**
* @param {module:ol/Geolocation~Options=} opt_options Options.
*/
constructor(opt_options) {
super();
const options = opt_options || {}; const options = opt_options || {};
@@ -90,24 +91,20 @@ const Geolocation = function(opt_options) {
this.setTracking(options.tracking !== undefined ? options.tracking : false); this.setTracking(options.tracking !== undefined ? options.tracking : false);
}; }
inherits(Geolocation, BaseObject);
/** /**
* @inheritDoc * @inheritDoc
*/ */
Geolocation.prototype.disposeInternal = function() { disposeInternal() {
this.setTracking(false); this.setTracking(false);
BaseObject.prototype.disposeInternal.call(this); super.disposeInternal();
}; }
/** /**
* @private * @private
*/ */
Geolocation.prototype.handleProjectionChanged_ = function() { handleProjectionChanged_() {
const projection = this.getProjection(); const projection = this.getProjection();
if (projection) { if (projection) {
this.transform_ = getTransformFromProjections( this.transform_ = getTransformFromProjections(
@@ -116,13 +113,12 @@ Geolocation.prototype.handleProjectionChanged_ = function() {
this.set(GeolocationProperty.POSITION, this.transform_(this.position_)); this.set(GeolocationProperty.POSITION, this.transform_(this.position_));
} }
} }
}; }
/** /**
* @private * @private
*/ */
Geolocation.prototype.handleTrackingChanged_ = function() { handleTrackingChanged_() {
if (GEOLOCATION) { if (GEOLOCATION) {
const tracking = this.getTracking(); const tracking = this.getTracking();
if (tracking && this.watchId_ === undefined) { if (tracking && this.watchId_ === undefined) {
@@ -135,14 +131,13 @@ Geolocation.prototype.handleTrackingChanged_ = function() {
this.watchId_ = undefined; this.watchId_ = undefined;
} }
} }
}; }
/** /**
* @private * @private
* @param {GeolocationPosition} position position event. * @param {Position} position position event.
*/ */
Geolocation.prototype.positionChange_ = function(position) { positionChange_(position) {
const coords = position.coords; const coords = position.coords;
this.set(GeolocationProperty.ACCURACY, coords.accuracy); this.set(GeolocationProperty.ACCURACY, coords.accuracy);
this.set(GeolocationProperty.ALTITUDE, this.set(GeolocationProperty.ALTITUDE,
@@ -166,7 +161,7 @@ Geolocation.prototype.positionChange_ = function(position) {
geometry.applyTransform(this.transform_); geometry.applyTransform(this.transform_);
this.set(GeolocationProperty.ACCURACY_GEOMETRY, geometry); this.set(GeolocationProperty.ACCURACY_GEOMETRY, geometry);
this.changed(); this.changed();
}; }
/** /**
* Triggered when the Geolocation returns an error. * Triggered when the Geolocation returns an error.
@@ -176,14 +171,13 @@ Geolocation.prototype.positionChange_ = function(position) {
/** /**
* @private * @private
* @param {GeolocationPositionError} error error object. * @param {PositionError} error error object.
*/ */
Geolocation.prototype.positionError_ = function(error) { positionError_(error) {
error.type = EventType.ERROR; error.type = EventType.ERROR;
this.setTracking(false); this.setTracking(false);
this.dispatchEvent(/** @type {{type: string, target: undefined}} */ (error)); this.dispatchEvent(/** @type {{type: string, target: undefined}} */ (error));
}; }
/** /**
* Get the accuracy of the position in meters. * Get the accuracy of the position in meters.
@@ -192,10 +186,9 @@ Geolocation.prototype.positionError_ = function(error) {
* @observable * @observable
* @api * @api
*/ */
Geolocation.prototype.getAccuracy = function() { getAccuracy() {
return /** @type {number|undefined} */ (this.get(GeolocationProperty.ACCURACY)); return /** @type {number|undefined} */ (this.get(GeolocationProperty.ACCURACY));
}; }
/** /**
* Get a geometry of the position accuracy. * Get a geometry of the position accuracy.
@@ -203,12 +196,11 @@ Geolocation.prototype.getAccuracy = function() {
* @observable * @observable
* @api * @api
*/ */
Geolocation.prototype.getAccuracyGeometry = function() { getAccuracyGeometry() {
return ( return (
/** @type {?module:ol/geom/Polygon} */ (this.get(GeolocationProperty.ACCURACY_GEOMETRY) || null) /** @type {?module:ol/geom/Polygon} */ (this.get(GeolocationProperty.ACCURACY_GEOMETRY) || null)
); );
}; }
/** /**
* Get the altitude associated with the position. * Get the altitude associated with the position.
@@ -217,10 +209,9 @@ Geolocation.prototype.getAccuracyGeometry = function() {
* @observable * @observable
* @api * @api
*/ */
Geolocation.prototype.getAltitude = function() { getAltitude() {
return /** @type {number|undefined} */ (this.get(GeolocationProperty.ALTITUDE)); return /** @type {number|undefined} */ (this.get(GeolocationProperty.ALTITUDE));
}; }
/** /**
* Get the altitude accuracy of the position. * Get the altitude accuracy of the position.
@@ -229,10 +220,9 @@ Geolocation.prototype.getAltitude = function() {
* @observable * @observable
* @api * @api
*/ */
Geolocation.prototype.getAltitudeAccuracy = function() { getAltitudeAccuracy() {
return /** @type {number|undefined} */ (this.get(GeolocationProperty.ALTITUDE_ACCURACY)); return /** @type {number|undefined} */ (this.get(GeolocationProperty.ALTITUDE_ACCURACY));
}; }
/** /**
* Get the heading as radians clockwise from North. * Get the heading as radians clockwise from North.
@@ -242,10 +232,9 @@ Geolocation.prototype.getAltitudeAccuracy = function() {
* @observable * @observable
* @api * @api
*/ */
Geolocation.prototype.getHeading = function() { getHeading() {
return /** @type {number|undefined} */ (this.get(GeolocationProperty.HEADING)); return /** @type {number|undefined} */ (this.get(GeolocationProperty.HEADING));
}; }
/** /**
* Get the position of the device. * Get the position of the device.
@@ -254,12 +243,11 @@ Geolocation.prototype.getHeading = function() {
* @observable * @observable
* @api * @api
*/ */
Geolocation.prototype.getPosition = function() { getPosition() {
return ( return (
/** @type {module:ol/coordinate~Coordinate|undefined} */ (this.get(GeolocationProperty.POSITION)) /** @type {module:ol/coordinate~Coordinate|undefined} */ (this.get(GeolocationProperty.POSITION))
); );
}; }
/** /**
* Get the projection associated with the position. * Get the projection associated with the position.
@@ -268,12 +256,11 @@ Geolocation.prototype.getPosition = function() {
* @observable * @observable
* @api * @api
*/ */
Geolocation.prototype.getProjection = function() { getProjection() {
return ( return (
/** @type {module:ol/proj/Projection|undefined} */ (this.get(GeolocationProperty.PROJECTION)) /** @type {module:ol/proj/Projection|undefined} */ (this.get(GeolocationProperty.PROJECTION))
); );
}; }
/** /**
* Get the speed in meters per second. * Get the speed in meters per second.
@@ -282,10 +269,9 @@ Geolocation.prototype.getProjection = function() {
* @observable * @observable
* @api * @api
*/ */
Geolocation.prototype.getSpeed = function() { getSpeed() {
return /** @type {number|undefined} */ (this.get(GeolocationProperty.SPEED)); return /** @type {number|undefined} */ (this.get(GeolocationProperty.SPEED));
}; }
/** /**
* Determine if the device location is being tracked. * Determine if the device location is being tracked.
@@ -293,24 +279,22 @@ Geolocation.prototype.getSpeed = function() {
* @observable * @observable
* @api * @api
*/ */
Geolocation.prototype.getTracking = function() { getTracking() {
return /** @type {boolean} */ (this.get(GeolocationProperty.TRACKING)); return /** @type {boolean} */ (this.get(GeolocationProperty.TRACKING));
}; }
/** /**
* Get the tracking options. * Get the tracking options.
* @see http://www.w3.org/TR/geolocation-API/#position-options * See http://www.w3.org/TR/geolocation-API/#position-options.
* @return {GeolocationPositionOptions|undefined} PositionOptions as defined by * @return {PositionOptions|undefined} PositionOptions as defined by
* the [HTML5 Geolocation spec * the [HTML5 Geolocation spec
* ](http://www.w3.org/TR/geolocation-API/#position_options_interface). * ](http://www.w3.org/TR/geolocation-API/#position_options_interface).
* @observable * @observable
* @api * @api
*/ */
Geolocation.prototype.getTrackingOptions = function() { getTrackingOptions() {
return /** @type {GeolocationPositionOptions|undefined} */ (this.get(GeolocationProperty.TRACKING_OPTIONS)); return /** @type {PositionOptions|undefined} */ (this.get(GeolocationProperty.TRACKING_OPTIONS));
}; }
/** /**
* Set the projection to use for transforming the coordinates. * Set the projection to use for transforming the coordinates.
@@ -319,10 +303,9 @@ Geolocation.prototype.getTrackingOptions = function() {
* @observable * @observable
* @api * @api
*/ */
Geolocation.prototype.setProjection = function(projection) { setProjection(projection) {
this.set(GeolocationProperty.PROJECTION, getProjection(projection)); this.set(GeolocationProperty.PROJECTION, getProjection(projection));
}; }
/** /**
* Enable or disable tracking. * Enable or disable tracking.
@@ -330,21 +313,23 @@ Geolocation.prototype.setProjection = function(projection) {
* @observable * @observable
* @api * @api
*/ */
Geolocation.prototype.setTracking = function(tracking) { setTracking(tracking) {
this.set(GeolocationProperty.TRACKING, tracking); this.set(GeolocationProperty.TRACKING, tracking);
}; }
/** /**
* Set the tracking options. * Set the tracking options.
* @see http://www.w3.org/TR/geolocation-API/#position-options * See http://www.w3.org/TR/geolocation-API/#position-options.
* @param {GeolocationPositionOptions} options PositionOptions as defined by the * @param {PositionOptions} options PositionOptions as defined by the
* [HTML5 Geolocation spec * [HTML5 Geolocation spec
* ](http://www.w3.org/TR/geolocation-API/#position_options_interface). * ](http://www.w3.org/TR/geolocation-API/#position_options_interface).
* @observable * @observable
* @api * @api
*/ */
Geolocation.prototype.setTrackingOptions = function(options) { setTrackingOptions(options) {
this.set(GeolocationProperty.TRACKING_OPTIONS, options); this.set(GeolocationProperty.TRACKING_OPTIONS, options);
}; }
}
export default Geolocation; export default Geolocation;

View File

@@ -112,11 +112,14 @@ const INTERVALS = [
/** /**
* Render a grid for a coordinate system on a map. * Render a grid for a coordinate system on a map.
* @constructor
* @param {module:ol/Graticule~Options=} opt_options Options.
* @api * @api
*/ */
const Graticule = function(opt_options) { class Graticule {
/**
* @param {module:ol/Graticule~Options=} opt_options Options.
*/
constructor(opt_options) {
const options = opt_options || {}; const options = opt_options || {};
/** /**
@@ -317,8 +320,7 @@ const Graticule = function(opt_options) {
} }
this.setMap(options.map !== undefined ? options.map : null); this.setMap(options.map !== undefined ? options.map : null);
}; }
/** /**
* @param {number} lon Longitude. * @param {number} lon Longitude.
@@ -330,7 +332,7 @@ const Graticule = function(opt_options) {
* @return {number} Index. * @return {number} Index.
* @private * @private
*/ */
Graticule.prototype.addMeridian_ = function(lon, minLat, maxLat, squaredTolerance, extent, index) { addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, index) {
const lineString = this.getMeridian_(lon, minLat, maxLat, squaredTolerance, index); const lineString = this.getMeridian_(lon, minLat, maxLat, squaredTolerance, index);
if (intersects(lineString.getExtent(), extent)) { if (intersects(lineString.getExtent(), extent)) {
if (this.meridiansLabels_) { if (this.meridiansLabels_) {
@@ -343,7 +345,7 @@ Graticule.prototype.addMeridian_ = function(lon, minLat, maxLat, squaredToleranc
this.meridians_[index++] = lineString; this.meridians_[index++] = lineString;
} }
return index; return index;
}; }
/** /**
* @param {module:ol/geom/LineString} lineString Meridian * @param {module:ol/geom/LineString} lineString Meridian
@@ -352,7 +354,7 @@ Graticule.prototype.addMeridian_ = function(lon, minLat, maxLat, squaredToleranc
* @return {module:ol/geom/Point} Meridian point. * @return {module:ol/geom/Point} Meridian point.
* @private * @private
*/ */
Graticule.prototype.getMeridianPoint_ = function(lineString, extent, index) { getMeridianPoint_(lineString, extent, index) {
const flatCoordinates = lineString.getFlatCoordinates(); const flatCoordinates = lineString.getFlatCoordinates();
const clampedBottom = Math.max(extent[1], flatCoordinates[1]); const clampedBottom = Math.max(extent[1], flatCoordinates[1]);
const clampedTop = Math.min(extent[3], flatCoordinates[flatCoordinates.length - 1]); const clampedTop = Math.min(extent[3], flatCoordinates[flatCoordinates.length - 1]);
@@ -360,12 +362,15 @@ Graticule.prototype.getMeridianPoint_ = function(lineString, extent, index) {
extent[1] + Math.abs(extent[1] - extent[3]) * this.lonLabelPosition_, extent[1] + Math.abs(extent[1] - extent[3]) * this.lonLabelPosition_,
clampedBottom, clampedTop); clampedBottom, clampedTop);
const coordinate = [flatCoordinates[0], lat]; const coordinate = [flatCoordinates[0], lat];
const point = this.meridiansLabels_[index] !== undefined ? let point;
this.meridiansLabels_[index].geom : new Point(null); if (index in this.meridiansLabels_) {
point = this.meridiansLabels_[index];
point.setCoordinates(coordinate); point.setCoordinates(coordinate);
} else {
point = new Point(coordinate);
}
return point; return point;
}; }
/** /**
* @param {number} lat Latitude. * @param {number} lat Latitude.
@@ -377,7 +382,7 @@ Graticule.prototype.getMeridianPoint_ = function(lineString, extent, index) {
* @return {number} Index. * @return {number} Index.
* @private * @private
*/ */
Graticule.prototype.addParallel_ = function(lat, minLon, maxLon, squaredTolerance, extent, index) { addParallel_(lat, minLon, maxLon, squaredTolerance, extent, index) {
const lineString = this.getParallel_(lat, minLon, maxLon, squaredTolerance, index); const lineString = this.getParallel_(lat, minLon, maxLon, squaredTolerance, index);
if (intersects(lineString.getExtent(), extent)) { if (intersects(lineString.getExtent(), extent)) {
if (this.parallelsLabels_) { if (this.parallelsLabels_) {
@@ -390,8 +395,7 @@ Graticule.prototype.addParallel_ = function(lat, minLon, maxLon, squaredToleranc
this.parallels_[index++] = lineString; this.parallels_[index++] = lineString;
} }
return index; return index;
}; }
/** /**
* @param {module:ol/geom/LineString} lineString Parallels. * @param {module:ol/geom/LineString} lineString Parallels.
@@ -400,7 +404,7 @@ Graticule.prototype.addParallel_ = function(lat, minLon, maxLon, squaredToleranc
* @return {module:ol/geom/Point} Parallel point. * @return {module:ol/geom/Point} Parallel point.
* @private * @private
*/ */
Graticule.prototype.getParallelPoint_ = function(lineString, extent, index) { getParallelPoint_(lineString, extent, index) {
const flatCoordinates = lineString.getFlatCoordinates(); const flatCoordinates = lineString.getFlatCoordinates();
const clampedLeft = Math.max(extent[0], flatCoordinates[0]); const clampedLeft = Math.max(extent[0], flatCoordinates[0]);
const clampedRight = Math.min(extent[2], flatCoordinates[flatCoordinates.length - 2]); const clampedRight = Math.min(extent[2], flatCoordinates[flatCoordinates.length - 2]);
@@ -408,12 +412,15 @@ Graticule.prototype.getParallelPoint_ = function(lineString, extent, index) {
extent[0] + Math.abs(extent[0] - extent[2]) * this.latLabelPosition_, extent[0] + Math.abs(extent[0] - extent[2]) * this.latLabelPosition_,
clampedLeft, clampedRight); clampedLeft, clampedRight);
const coordinate = [lon, flatCoordinates[1]]; const coordinate = [lon, flatCoordinates[1]];
const point = this.parallelsLabels_[index] !== undefined ? let point;
this.parallelsLabels_[index].geom : new Point(null); if (index in this.parallelsLabels_) {
point = this.parallelsLabels_[index];
point.setCoordinates(coordinate); point.setCoordinates(coordinate);
} else {
point = new Point(coordinate);
}
return point; return point;
}; }
/** /**
* @param {module:ol/extent~Extent} extent Extent. * @param {module:ol/extent~Extent} extent Extent.
@@ -422,7 +429,7 @@ Graticule.prototype.getParallelPoint_ = function(lineString, extent, index) {
* @param {number} squaredTolerance Squared tolerance. * @param {number} squaredTolerance Squared tolerance.
* @private * @private
*/ */
Graticule.prototype.createGraticule_ = function(extent, center, resolution, squaredTolerance) { createGraticule_(extent, center, resolution, squaredTolerance) {
const interval = this.getInterval_(resolution); const interval = this.getInterval_(resolution);
if (interval == -1) { if (interval == -1) {
@@ -507,15 +514,14 @@ Graticule.prototype.createGraticule_ = function(extent, center, resolution, squa
this.parallelsLabels_.length = idx; this.parallelsLabels_.length = idx;
} }
}; }
/** /**
* @param {number} resolution Resolution. * @param {number} resolution Resolution.
* @return {number} The interval in degrees. * @return {number} The interval in degrees.
* @private * @private
*/ */
Graticule.prototype.getInterval_ = function(resolution) { getInterval_(resolution) {
const centerLon = this.projectionCenterLonLat_[0]; const centerLon = this.projectionCenterLonLat_[0];
const centerLat = this.projectionCenterLonLat_[1]; const centerLat = this.projectionCenterLonLat_[1];
let interval = -1; let interval = -1;
@@ -539,18 +545,16 @@ Graticule.prototype.getInterval_ = function(resolution) {
interval = INTERVALS[i]; interval = INTERVALS[i];
} }
return interval; return interval;
}; }
/** /**
* Get the map associated with this graticule. * Get the map associated with this graticule.
* @return {module:ol/PluggableMap} The map. * @return {module:ol/PluggableMap} The map.
* @api * @api
*/ */
Graticule.prototype.getMap = function() { getMap() {
return this.map_; return this.map_;
}; }
/** /**
* @param {number} lon Longitude. * @param {number} lon Longitude.
@@ -561,23 +565,26 @@ Graticule.prototype.getMap = function() {
* @param {number} index Index. * @param {number} index Index.
* @private * @private
*/ */
Graticule.prototype.getMeridian_ = function(lon, minLat, maxLat, squaredTolerance, index) { getMeridian_(lon, minLat, maxLat, squaredTolerance, index) {
const flatCoordinates = meridian(lon, minLat, maxLat, this.projection_, squaredTolerance); const flatCoordinates = meridian(lon, minLat, maxLat, this.projection_, squaredTolerance);
const lineString = this.meridians_[index] !== undefined ? this.meridians_[index] : new LineString(null); let lineString = this.meridians_[index];
if (!lineString) {
lineString = this.meridians_[index] = new LineString(flatCoordinates, GeometryLayout.XY);
} else {
lineString.setFlatCoordinates(GeometryLayout.XY, flatCoordinates); lineString.setFlatCoordinates(GeometryLayout.XY, flatCoordinates);
lineString.changed();
}
return lineString; return lineString;
}; }
/** /**
* Get the list of meridians. Meridians are lines of equal longitude. * Get the list of meridians. Meridians are lines of equal longitude.
* @return {Array.<module:ol/geom/LineString>} The meridians. * @return {Array.<module:ol/geom/LineString>} The meridians.
* @api * @api
*/ */
Graticule.prototype.getMeridians = function() { getMeridians() {
return this.meridians_; return this.meridians_;
}; }
/** /**
* @param {number} lat Latitude. * @param {number} lat Latitude.
@@ -588,29 +595,32 @@ Graticule.prototype.getMeridians = function() {
* @param {number} index Index. * @param {number} index Index.
* @private * @private
*/ */
Graticule.prototype.getParallel_ = function(lat, minLon, maxLon, squaredTolerance, index) { getParallel_(lat, minLon, maxLon, squaredTolerance, index) {
const flatCoordinates = parallel(lat, minLon, maxLon, this.projection_, squaredTolerance); const flatCoordinates = parallel(lat, minLon, maxLon, this.projection_, squaredTolerance);
const lineString = this.parallels_[index] !== undefined ? this.parallels_[index] : new LineString(null); let lineString = this.parallels_[index];
if (!lineString) {
lineString = new LineString(flatCoordinates, GeometryLayout.XY);
} else {
lineString.setFlatCoordinates(GeometryLayout.XY, flatCoordinates); lineString.setFlatCoordinates(GeometryLayout.XY, flatCoordinates);
lineString.changed();
}
return lineString; return lineString;
}; }
/** /**
* Get the list of parallels. Parallels are lines of equal latitude. * Get the list of parallels. Parallels are lines of equal latitude.
* @return {Array.<module:ol/geom/LineString>} The parallels. * @return {Array.<module:ol/geom/LineString>} The parallels.
* @api * @api
*/ */
Graticule.prototype.getParallels = function() { getParallels() {
return this.parallels_; return this.parallels_;
}; }
/** /**
* @param {module:ol/render/Event} e Event. * @param {module:ol/render/Event} e Event.
* @private * @private
*/ */
Graticule.prototype.handlePostCompose_ = function(e) { handlePostCompose_(e) {
const vectorContext = e.vectorContext; const vectorContext = e.vectorContext;
const frameState = e.frameState; const frameState = e.frameState;
const extent = frameState.extent; const extent = frameState.extent;
@@ -659,14 +669,13 @@ Graticule.prototype.handlePostCompose_ = function(e) {
vectorContext.drawGeometry(labelData.geom); vectorContext.drawGeometry(labelData.geom);
} }
} }
}; }
/** /**
* @param {module:ol/proj/Projection} projection Projection. * @param {module:ol/proj/Projection} projection Projection.
* @private * @private
*/ */
Graticule.prototype.updateProjectionInfo_ = function(projection) { updateProjectionInfo_(projection) {
const epsg4326Projection = getProjection('EPSG:4326'); const epsg4326Projection = getProjection('EPSG:4326');
const worldExtent = projection.getWorldExtent(); const worldExtent = projection.getWorldExtent();
@@ -689,8 +698,7 @@ Graticule.prototype.updateProjectionInfo_ = function(projection) {
this.projectionCenterLonLat_ = this.toLonLatTransform_(getCenter(projection.getExtent())); this.projectionCenterLonLat_ = this.toLonLatTransform_(getCenter(projection.getExtent()));
this.projection_ = projection; this.projection_ = projection;
}; }
/** /**
* Set the map for this graticule. The graticule will be rendered on the * Set the map for this graticule. The graticule will be rendered on the
@@ -698,7 +706,7 @@ Graticule.prototype.updateProjectionInfo_ = function(projection) {
* @param {module:ol/PluggableMap} map Map. * @param {module:ol/PluggableMap} map Map.
* @api * @api
*/ */
Graticule.prototype.setMap = function(map) { setMap(map) {
if (this.map_) { if (this.map_) {
unlistenByKey(this.postcomposeListenerKey_); unlistenByKey(this.postcomposeListenerKey_);
this.postcomposeListenerKey_ = null; this.postcomposeListenerKey_ = null;
@@ -709,5 +717,7 @@ Graticule.prototype.setMap = function(map) {
map.render(); map.render();
} }
this.map_ = map; this.map_ = map;
}; }
}
export default Graticule; export default Graticule;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/Image * @module ol/Image
*/ */
import {inherits} from './util.js';
import ImageBase from './ImageBase.js'; import ImageBase from './ImageBase.js';
import ImageState from './ImageState.js'; import ImageState from './ImageState.js';
import {listenOnce, unlistenByKey} from './events.js'; import {listenOnce, unlistenByKey} from './events.js';
@@ -28,9 +27,9 @@ import {getHeight} from './extent.js';
*/ */
class ImageWrapper extends ImageBase {
/** /**
* @constructor
* @extends {module:ol/ImageBase}
* @param {module:ol/extent~Extent} extent Extent. * @param {module:ol/extent~Extent} extent Extent.
* @param {number|undefined} resolution Resolution. * @param {number|undefined} resolution Resolution.
* @param {number} pixelRatio Pixel ratio. * @param {number} pixelRatio Pixel ratio.
@@ -38,9 +37,9 @@ import {getHeight} from './extent.js';
* @param {?string} crossOrigin Cross origin. * @param {?string} crossOrigin Cross origin.
* @param {module:ol/Image~LoadFunction} imageLoadFunction Image load function. * @param {module:ol/Image~LoadFunction} imageLoadFunction Image load function.
*/ */
const ImageWrapper = function(extent, resolution, pixelRatio, src, crossOrigin, imageLoadFunction) { constructor(extent, resolution, pixelRatio, src, crossOrigin, imageLoadFunction) {
ImageBase.call(this, extent, resolution, pixelRatio, ImageState.IDLE); super(extent, resolution, pixelRatio, ImageState.IDLE);
/** /**
* @private * @private
@@ -50,7 +49,7 @@ const ImageWrapper = function(extent, resolution, pixelRatio, src, crossOrigin,
/** /**
* @private * @private
* @type {HTMLCanvasElement|Image|HTMLVideoElement} * @type {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement}
*/ */
this.image_ = new Image(); this.image_ = new Image();
if (crossOrigin !== null) { if (crossOrigin !== null) {
@@ -75,46 +74,40 @@ const ImageWrapper = function(extent, resolution, pixelRatio, src, crossOrigin,
*/ */
this.imageLoadFunction_ = imageLoadFunction; this.imageLoadFunction_ = imageLoadFunction;
}; }
inherits(ImageWrapper, ImageBase);
/** /**
* @inheritDoc * @inheritDoc
* @api * @api
*/ */
ImageWrapper.prototype.getImage = function() { getImage() {
return this.image_; return this.image_;
}; }
/** /**
* Tracks loading or read errors. * Tracks loading or read errors.
* *
* @private * @private
*/ */
ImageWrapper.prototype.handleImageError_ = function() { handleImageError_() {
this.state = ImageState.ERROR; this.state = ImageState.ERROR;
this.unlistenImage_(); this.unlistenImage_();
this.changed(); this.changed();
}; }
/** /**
* Tracks successful image load. * Tracks successful image load.
* *
* @private * @private
*/ */
ImageWrapper.prototype.handleImageLoad_ = function() { handleImageLoad_() {
if (this.resolution === undefined) { if (this.resolution === undefined) {
this.resolution = getHeight(this.extent) / this.image_.height; this.resolution = getHeight(this.extent) / this.image_.height;
} }
this.state = ImageState.LOADED; this.state = ImageState.LOADED;
this.unlistenImage_(); this.unlistenImage_();
this.changed(); this.changed();
}; }
/** /**
* Load the image or retry if loading previously failed. * Load the image or retry if loading previously failed.
@@ -123,7 +116,7 @@ ImageWrapper.prototype.handleImageLoad_ = function() {
* @override * @override
* @api * @api
*/ */
ImageWrapper.prototype.load = function() { load() {
if (this.state == ImageState.IDLE || this.state == ImageState.ERROR) { if (this.state == ImageState.IDLE || this.state == ImageState.ERROR) {
this.state = ImageState.LOADING; this.state = ImageState.LOADING;
this.changed(); this.changed();
@@ -135,25 +128,25 @@ ImageWrapper.prototype.load = function() {
]; ];
this.imageLoadFunction_(this, this.src_); this.imageLoadFunction_(this, this.src_);
} }
}; }
/** /**
* @param {HTMLCanvasElement|Image|HTMLVideoElement} image Image. * @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image.
*/ */
ImageWrapper.prototype.setImage = function(image) { setImage(image) {
this.image_ = image; this.image_ = image;
}; }
/** /**
* Discards event handlers which listen for load completion or errors. * Discards event handlers which listen for load completion or errors.
* *
* @private * @private
*/ */
ImageWrapper.prototype.unlistenImage_ = function() { unlistenImage_() {
this.imageListenerKeys_.forEach(unlistenByKey); this.imageListenerKeys_.forEach(unlistenByKey);
this.imageListenerKeys_ = null; this.imageListenerKeys_ = null;
}; }
}
export default ImageWrapper; export default ImageWrapper;

View File

@@ -1,22 +1,23 @@
/** /**
* @module ol/ImageBase * @module ol/ImageBase
*/ */
import {inherits} from './util.js';
import EventTarget from './events/EventTarget.js'; import EventTarget from './events/EventTarget.js';
import EventType from './events/EventType.js'; import EventType from './events/EventType.js';
/** /**
* @constructor
* @abstract * @abstract
* @extends {module:ol/events/EventTarget} */
class ImageBase extends EventTarget {
/**
* @param {module:ol/extent~Extent} extent Extent. * @param {module:ol/extent~Extent} extent Extent.
* @param {number|undefined} resolution Resolution. * @param {number|undefined} resolution Resolution.
* @param {number} pixelRatio Pixel ratio. * @param {number} pixelRatio Pixel ratio.
* @param {module:ol/ImageState} state State. * @param {module:ol/ImageState} state State.
*/ */
const ImageBase = function(extent, resolution, pixelRatio, state) { constructor(extent, resolution, pixelRatio, state) {
EventTarget.call(this); super();
/** /**
* @protected * @protected
@@ -42,62 +43,55 @@ const ImageBase = function(extent, resolution, pixelRatio, state) {
*/ */
this.state = state; this.state = state;
}; }
inherits(ImageBase, EventTarget);
/** /**
* @protected * @protected
*/ */
ImageBase.prototype.changed = function() { changed() {
this.dispatchEvent(EventType.CHANGE); this.dispatchEvent(EventType.CHANGE);
}; }
/** /**
* @return {module:ol/extent~Extent} Extent. * @return {module:ol/extent~Extent} Extent.
*/ */
ImageBase.prototype.getExtent = function() { getExtent() {
return this.extent; return this.extent;
}; }
/** /**
* @abstract * @abstract
* @return {HTMLCanvasElement|Image|HTMLVideoElement} Image. * @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.
*/ */
ImageBase.prototype.getImage = function() {}; getImage() {}
/** /**
* @return {number} PixelRatio. * @return {number} PixelRatio.
*/ */
ImageBase.prototype.getPixelRatio = function() { getPixelRatio() {
return this.pixelRatio_; return this.pixelRatio_;
}; }
/** /**
* @return {number} Resolution. * @return {number} Resolution.
*/ */
ImageBase.prototype.getResolution = function() { getResolution() {
return /** @type {number} */ (this.resolution); return /** @type {number} */ (this.resolution);
}; }
/** /**
* @return {module:ol/ImageState} State. * @return {module:ol/ImageState} State.
*/ */
ImageBase.prototype.getState = function() { getState() {
return this.state; return this.state;
}; }
/** /**
* Load not yet loaded URI. * Load not yet loaded URI.
* @abstract * @abstract
*/ */
ImageBase.prototype.load = function() {}; load() {}
}
export default ImageBase; export default ImageBase;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/ImageCanvas * @module ol/ImageCanvas
*/ */
import {inherits} from './util.js';
import ImageBase from './ImageBase.js'; import ImageBase from './ImageBase.js';
import ImageState from './ImageState.js'; import ImageState from './ImageState.js';
@@ -16,9 +15,9 @@ import ImageState from './ImageState.js';
*/ */
class ImageCanvas extends ImageBase {
/** /**
* @constructor
* @extends {module:ol/ImageBase}
* @param {module:ol/extent~Extent} extent Extent. * @param {module:ol/extent~Extent} extent Extent.
* @param {number} resolution Resolution. * @param {number} resolution Resolution.
* @param {number} pixelRatio Pixel ratio. * @param {number} pixelRatio Pixel ratio.
@@ -26,7 +25,11 @@ import ImageState from './ImageState.js';
* @param {module:ol/ImageCanvas~Loader=} opt_loader Optional loader function to * @param {module:ol/ImageCanvas~Loader=} opt_loader Optional loader function to
* support asynchronous canvas drawing. * support asynchronous canvas drawing.
*/ */
const ImageCanvas = function(extent, resolution, pixelRatio, canvas, opt_loader) { constructor(extent, resolution, pixelRatio, canvas, opt_loader) {
const state = opt_loader !== undefined ? ImageState.IDLE : ImageState.LOADED;
super(extent, resolution, pixelRatio, state);
/** /**
* Optional canvas loader function. * Optional canvas loader function.
@@ -35,10 +38,6 @@ const ImageCanvas = function(extent, resolution, pixelRatio, canvas, opt_loader)
*/ */
this.loader_ = opt_loader !== undefined ? opt_loader : null; this.loader_ = opt_loader !== undefined ? opt_loader : null;
const state = opt_loader !== undefined ? ImageState.IDLE : ImageState.LOADED;
ImageBase.call(this, extent, resolution, pixelRatio, state);
/** /**
* @private * @private
* @type {HTMLCanvasElement} * @type {HTMLCanvasElement}
@@ -51,26 +50,22 @@ const ImageCanvas = function(extent, resolution, pixelRatio, canvas, opt_loader)
*/ */
this.error_ = null; this.error_ = null;
}; }
inherits(ImageCanvas, ImageBase);
/** /**
* Get any error associated with asynchronous rendering. * Get any error associated with asynchronous rendering.
* @return {Error} Any error that occurred during rendering. * @return {Error} Any error that occurred during rendering.
*/ */
ImageCanvas.prototype.getError = function() { getError() {
return this.error_; return this.error_;
}; }
/** /**
* Handle async drawing complete. * Handle async drawing complete.
* @param {Error} err Any error during drawing. * @param {Error} err Any error during drawing.
* @private * @private
*/ */
ImageCanvas.prototype.handleLoad_ = function(err) { handleLoad_(err) {
if (err) { if (err) {
this.error_ = err; this.error_ = err;
this.state = ImageState.ERROR; this.state = ImageState.ERROR;
@@ -78,25 +73,26 @@ ImageCanvas.prototype.handleLoad_ = function(err) {
this.state = ImageState.LOADED; this.state = ImageState.LOADED;
} }
this.changed(); this.changed();
}; }
/** /**
* @inheritDoc * @inheritDoc
*/ */
ImageCanvas.prototype.load = function() { load() {
if (this.state == ImageState.IDLE) { if (this.state == ImageState.IDLE) {
this.state = ImageState.LOADING; this.state = ImageState.LOADING;
this.changed(); this.changed();
this.loader_(this.handleLoad_.bind(this)); this.loader_(this.handleLoad_.bind(this));
} }
}; }
/** /**
* @return {HTMLCanvasElement} Canvas element. * @return {HTMLCanvasElement} Canvas element.
*/ */
ImageCanvas.prototype.getImage = function() { getImage() {
return this.canvas_; return this.canvas_;
}; }
}
export default ImageCanvas; export default ImageCanvas;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/ImageTile * @module ol/ImageTile
*/ */
import {inherits} from './util.js';
import Tile from './Tile.js'; import Tile from './Tile.js';
import TileState from './TileState.js'; import TileState from './TileState.js';
import {createCanvasContext2D} from './dom.js'; import {createCanvasContext2D} from './dom.js';
@@ -14,9 +13,9 @@ import EventType from './events/EventType.js';
* @api * @api
*/ */
class ImageTile extends Tile {
/** /**
* @constructor
* @extends {module:ol/Tile}
* @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate. * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.
* @param {module:ol/TileState} state State. * @param {module:ol/TileState} state State.
* @param {string} src Image source URI. * @param {string} src Image source URI.
@@ -24,9 +23,9 @@ import EventType from './events/EventType.js';
* @param {module:ol/Tile~LoadFunction} tileLoadFunction Tile load function. * @param {module:ol/Tile~LoadFunction} tileLoadFunction Tile load function.
* @param {module:ol/Tile~Options=} opt_options Tile options. * @param {module:ol/Tile~Options=} opt_options Tile options.
*/ */
const ImageTile = function(tileCoord, state, src, crossOrigin, tileLoadFunction, opt_options) { constructor(tileCoord, state, src, crossOrigin, tileLoadFunction, opt_options) {
Tile.call(this, tileCoord, state, opt_options); super(tileCoord, state, opt_options);
/** /**
* @private * @private
@@ -44,7 +43,7 @@ const ImageTile = function(tileCoord, state, src, crossOrigin, tileLoadFunction,
/** /**
* @private * @private
* @type {Image|HTMLCanvasElement} * @type {HTMLImageElement|HTMLCanvasElement}
*/ */
this.image_ = new Image(); this.image_ = new Image();
if (crossOrigin !== null) { if (crossOrigin !== null) {
@@ -63,15 +62,12 @@ const ImageTile = function(tileCoord, state, src, crossOrigin, tileLoadFunction,
*/ */
this.tileLoadFunction_ = tileLoadFunction; this.tileLoadFunction_ = tileLoadFunction;
}; }
inherits(ImageTile, Tile);
/** /**
* @inheritDoc * @inheritDoc
*/ */
ImageTile.prototype.disposeInternal = function() { disposeInternal() {
if (this.state == TileState.LOADING) { if (this.state == TileState.LOADING) {
this.unlistenImage_(); this.unlistenImage_();
this.image_ = getBlankImage(); this.image_ = getBlankImage();
@@ -81,47 +77,43 @@ ImageTile.prototype.disposeInternal = function() {
} }
this.state = TileState.ABORT; this.state = TileState.ABORT;
this.changed(); this.changed();
Tile.prototype.disposeInternal.call(this); super.disposeInternal();
}; }
/** /**
* Get the HTML image element for this tile (may be a Canvas, Image, or Video). * Get the HTML image element for this tile (may be a Canvas, Image, or Video).
* @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image. * @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.
* @api * @api
*/ */
ImageTile.prototype.getImage = function() { getImage() {
return this.image_; return this.image_;
}; }
/** /**
* @inheritDoc * @inheritDoc
*/ */
ImageTile.prototype.getKey = function() { getKey() {
return this.src_; return this.src_;
}; }
/** /**
* Tracks loading or read errors. * Tracks loading or read errors.
* *
* @private * @private
*/ */
ImageTile.prototype.handleImageError_ = function() { handleImageError_() {
this.state = TileState.ERROR; this.state = TileState.ERROR;
this.unlistenImage_(); this.unlistenImage_();
this.image_ = getBlankImage(); this.image_ = getBlankImage();
this.changed(); this.changed();
}; }
/** /**
* Tracks successful image load. * Tracks successful image load.
* *
* @private * @private
*/ */
ImageTile.prototype.handleImageLoad_ = function() { handleImageLoad_() {
if (this.image_.naturalWidth && this.image_.naturalHeight) { if (this.image_.naturalWidth && this.image_.naturalHeight) {
this.state = TileState.LOADED; this.state = TileState.LOADED;
} else { } else {
@@ -129,14 +121,13 @@ ImageTile.prototype.handleImageLoad_ = function() {
} }
this.unlistenImage_(); this.unlistenImage_();
this.changed(); this.changed();
}; }
/** /**
* @inheritDoc * @inheritDoc
* @api * @api
*/ */
ImageTile.prototype.load = function() { load() {
if (this.state == TileState.ERROR) { if (this.state == TileState.ERROR) {
this.state = TileState.IDLE; this.state = TileState.IDLE;
this.image_ = new Image(); this.image_ = new Image();
@@ -155,18 +146,18 @@ ImageTile.prototype.load = function() {
]; ];
this.tileLoadFunction_(this, this.src_); this.tileLoadFunction_(this, this.src_);
} }
}; }
/** /**
* Discards event handlers which listen for load completion or errors. * Discards event handlers which listen for load completion or errors.
* *
* @private * @private
*/ */
ImageTile.prototype.unlistenImage_ = function() { unlistenImage_() {
this.imageListenerKeys_.forEach(unlistenByKey); this.imageListenerKeys_.forEach(unlistenByKey);
this.imageListenerKeys_ = null; this.imageListenerKeys_ = null;
}; }
}
/** /**

View File

@@ -6,15 +6,17 @@
* @classdesc * @classdesc
* Implementation of inertial deceleration for map movement. * Implementation of inertial deceleration for map movement.
* *
* @constructor * @api
*/
class Kinetic {
/**
* @param {number} decay Rate of decay (must be negative). * @param {number} decay Rate of decay (must be negative).
* @param {number} minVelocity Minimum velocity (pixels/millisecond). * @param {number} minVelocity Minimum velocity (pixels/millisecond).
* @param {number} delay Delay to consider to calculate the kinetic * @param {number} delay Delay to consider to calculate the kinetic
* initial values (milliseconds). * initial values (milliseconds).
* @struct
* @api
*/ */
const Kinetic = function(decay, minVelocity, delay) { constructor(decay, minVelocity, delay) {
/** /**
* @private * @private
@@ -51,32 +53,29 @@ const Kinetic = function(decay, minVelocity, delay) {
* @type {number} * @type {number}
*/ */
this.initialVelocity_ = 0; this.initialVelocity_ = 0;
}; }
/** /**
* FIXME empty description for jsdoc * FIXME empty description for jsdoc
*/ */
Kinetic.prototype.begin = function() { begin() {
this.points_.length = 0; this.points_.length = 0;
this.angle_ = 0; this.angle_ = 0;
this.initialVelocity_ = 0; this.initialVelocity_ = 0;
}; }
/** /**
* @param {number} x X. * @param {number} x X.
* @param {number} y Y. * @param {number} y Y.
*/ */
Kinetic.prototype.update = function(x, y) { update(x, y) {
this.points_.push(x, y, Date.now()); this.points_.push(x, y, Date.now());
}; }
/** /**
* @return {boolean} Whether we should do kinetic animation. * @return {boolean} Whether we should do kinetic animation.
*/ */
Kinetic.prototype.end = function() { end() {
if (this.points_.length < 6) { if (this.points_.length < 6) {
// at least 2 points are required (i.e. there must be at least 6 elements // at least 2 points are required (i.e. there must be at least 6 elements
// in the array) // in the array)
@@ -109,21 +108,21 @@ Kinetic.prototype.end = function() {
this.angle_ = Math.atan2(dy, dx); this.angle_ = Math.atan2(dy, dx);
this.initialVelocity_ = Math.sqrt(dx * dx + dy * dy) / duration; this.initialVelocity_ = Math.sqrt(dx * dx + dy * dy) / duration;
return this.initialVelocity_ > this.minVelocity_; return this.initialVelocity_ > this.minVelocity_;
}; }
/** /**
* @return {number} Total distance travelled (pixels). * @return {number} Total distance travelled (pixels).
*/ */
Kinetic.prototype.getDistance = function() { getDistance() {
return (this.minVelocity_ - this.initialVelocity_) / this.decay_; return (this.minVelocity_ - this.initialVelocity_) / this.decay_;
}; }
/** /**
* @return {number} Angle of the kinetic panning animation (radians). * @return {number} Angle of the kinetic panning animation (radians).
*/ */
Kinetic.prototype.getAngle = function() { getAngle() {
return this.angle_; return this.angle_;
}; }
}
export default Kinetic; export default Kinetic;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/Map * @module ol/Map
*/ */
import {inherits} from './util.js';
import PluggableMap from './PluggableMap.js'; import PluggableMap from './PluggableMap.js';
import {defaults as defaultControls} from './control/util.js'; import {defaults as defaultControls} from './control/util.js';
import {defaults as defaultInteractions} from './interaction.js'; import {defaults as defaultInteractions} from './interaction.js';
@@ -57,16 +56,18 @@ import CanvasVectorTileLayerRenderer from './renderer/canvas/VectorTileLayer.js'
* options or added with `addLayer` can be groups, which can contain further * options or added with `addLayer` can be groups, which can contain further
* groups, and so on. * groups, and so on.
* *
* @constructor
* @extends {module:ol/PluggableMap}
* @param {module:ol/PluggableMap~MapOptions} options Map options.
* @fires module:ol/MapBrowserEvent~MapBrowserEvent * @fires module:ol/MapBrowserEvent~MapBrowserEvent
* @fires module:ol/MapEvent~MapEvent * @fires module:ol/MapEvent~MapEvent
* @fires module:ol/render/Event~RenderEvent#postcompose * @fires module:ol/render/Event~RenderEvent#postcompose
* @fires module:ol/render/Event~RenderEvent#precompose * @fires module:ol/render/Event~RenderEvent#precompose
* @api * @api
*/ */
const Map = function(options) { class Map extends PluggableMap {
/**
* @param {module:ol/PluggableMap~MapOptions} options Map options.
*/
constructor(options) {
options = assign({}, options); options = assign({}, options);
if (!options.controls) { if (!options.controls) {
options.controls = defaultControls(); options.controls = defaultControls();
@@ -75,12 +76,10 @@ const Map = function(options) {
options.interactions = defaultInteractions(); options.interactions = defaultInteractions();
} }
PluggableMap.call(this, options); super(options);
}; }
inherits(Map, PluggableMap); createRenderer() {
Map.prototype.createRenderer = function() {
const renderer = new CanvasMapRenderer(this); const renderer = new CanvasMapRenderer(this);
renderer.registerLayerRenderers([ renderer.registerLayerRenderers([
CanvasImageLayerRenderer, CanvasImageLayerRenderer,
@@ -89,6 +88,8 @@ Map.prototype.createRenderer = function() {
CanvasVectorTileLayerRenderer CanvasVectorTileLayerRenderer
]); ]);
return renderer; return renderer;
}; }
}
export default Map; export default Map;

View File

@@ -1,25 +1,25 @@
/** /**
* @module ol/MapBrowserEvent * @module ol/MapBrowserEvent
*/ */
import {inherits} from './util.js';
import MapEvent from './MapEvent.js'; import MapEvent from './MapEvent.js';
/** /**
* @classdesc * @classdesc
* Events emitted as map browser events are instances of this type. * Events emitted as map browser events are instances of this type.
* See {@link module:ol/Map~Map} for which events trigger a map browser event. * See {@link module:ol/Map~Map} for which events trigger a map browser event.
* */
* @constructor class MapBrowserEvent extends MapEvent {
* @extends {module:ol/MapEvent}
/**
* @param {string} type Event type. * @param {string} type Event type.
* @param {module:ol/PluggableMap} map Map. * @param {module:ol/PluggableMap} map Map.
* @param {Event} browserEvent Browser event. * @param {Event} browserEvent Browser event.
* @param {boolean=} opt_dragging Is the map currently being dragged? * @param {boolean=} opt_dragging Is the map currently being dragged?
* @param {?module:ol/PluggableMap~FrameState=} opt_frameState Frame state. * @param {?module:ol/PluggableMap~FrameState=} opt_frameState Frame state.
*/ */
const MapBrowserEvent = function(type, map, browserEvent, opt_dragging, opt_frameState) { constructor(type, map, browserEvent, opt_dragging, opt_frameState) {
MapEvent.call(this, type, map, opt_frameState); super(type, map, opt_frameState);
/** /**
* The original browser event. * The original browser event.
@@ -31,7 +31,7 @@ const MapBrowserEvent = function(type, map, browserEvent, opt_dragging, opt_fram
/** /**
* The map pixel relative to the viewport corresponding to the original browser event. * The map pixel relative to the viewport corresponding to the original browser event.
* @type {module:ol~Pixel} * @type {module:ol/pixel~Pixel}
* @api * @api
*/ */
this.pixel = map.getEventPixel(browserEvent); this.pixel = map.getEventPixel(browserEvent);
@@ -52,31 +52,30 @@ const MapBrowserEvent = function(type, map, browserEvent, opt_dragging, opt_fram
*/ */
this.dragging = opt_dragging !== undefined ? opt_dragging : false; this.dragging = opt_dragging !== undefined ? opt_dragging : false;
}; }
inherits(MapBrowserEvent, MapEvent);
/** /**
* Prevents the default browser action. * Prevents the default browser action.
* @see https://developer.mozilla.org/en-US/docs/Web/API/event.preventDefault * See https://developer.mozilla.org/en-US/docs/Web/API/event.preventDefault.
* @override * @override
* @api * @api
*/ */
MapBrowserEvent.prototype.preventDefault = function() { preventDefault() {
MapEvent.prototype.preventDefault.call(this); super.preventDefault();
this.originalEvent.preventDefault(); this.originalEvent.preventDefault();
}; }
/** /**
* Prevents further propagation of the current event. * Prevents further propagation of the current event.
* @see https://developer.mozilla.org/en-US/docs/Web/API/event.stopPropagation * See https://developer.mozilla.org/en-US/docs/Web/API/event.stopPropagation.
* @override * @override
* @api * @api
*/ */
MapBrowserEvent.prototype.stopPropagation = function() { stopPropagation() {
MapEvent.prototype.stopPropagation.call(this); super.stopPropagation();
this.originalEvent.stopPropagation(); this.originalEvent.stopPropagation();
}; }
}
export default MapBrowserEvent; export default MapBrowserEvent;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/MapBrowserEventHandler * @module ol/MapBrowserEventHandler
*/ */
import {inherits} from './util.js';
import {DEVICE_PIXEL_RATIO} from './has.js'; import {DEVICE_PIXEL_RATIO} from './has.js';
import MapBrowserEventType from './MapBrowserEventType.js'; import MapBrowserEventType from './MapBrowserEventType.js';
import MapBrowserPointerEvent from './MapBrowserPointerEvent.js'; import MapBrowserPointerEvent from './MapBrowserPointerEvent.js';
@@ -10,17 +9,15 @@ import EventTarget from './events/EventTarget.js';
import PointerEventType from './pointer/EventType.js'; import PointerEventType from './pointer/EventType.js';
import PointerEventHandler from './pointer/PointerEventHandler.js'; import PointerEventHandler from './pointer/PointerEventHandler.js';
/** class MapBrowserEventHandler extends EventTarget {
* @param {module:ol/PluggableMap} map The map with the viewport to
* listen to events on.
* @param {number=} moveTolerance The minimal distance the pointer must travel
* to trigger a move.
* @constructor
* @extends {module:ol/events/EventTarget}
*/
const MapBrowserEventHandler = function(map, moveTolerance) {
EventTarget.call(this); /**
* @param {module:ol/PluggableMap} map The map with the viewport to listen to events on.
* @param {number=} moveTolerance The minimal distance the pointer must travel to trigger a move.
*/
constructor(map, moveTolerance) {
super();
/** /**
* This is the element that we will listen to the real events on. * This is the element that we will listen to the real events on.
@@ -110,17 +107,14 @@ const MapBrowserEventHandler = function(map, moveTolerance) {
PointerEventType.POINTERMOVE, PointerEventType.POINTERMOVE,
this.relayEvent_, this); this.relayEvent_, this);
}; }
inherits(MapBrowserEventHandler, EventTarget);
/** /**
* @param {module:ol/pointer/PointerEvent} pointerEvent Pointer * @param {module:ol/pointer/PointerEvent} pointerEvent Pointer
* event. * event.
* @private * @private
*/ */
MapBrowserEventHandler.prototype.emulateClick_ = function(pointerEvent) { emulateClick_(pointerEvent) {
let newEvent = new MapBrowserPointerEvent( let newEvent = new MapBrowserPointerEvent(
MapBrowserEventType.CLICK, this.map_, pointerEvent); MapBrowserEventType.CLICK, this.map_, pointerEvent);
this.dispatchEvent(newEvent); this.dispatchEvent(newEvent);
@@ -140,8 +134,7 @@ MapBrowserEventHandler.prototype.emulateClick_ = function(pointerEvent) {
this.dispatchEvent(newEvent); this.dispatchEvent(newEvent);
}.bind(this), 250); }.bind(this), 250);
} }
}; }
/** /**
* Keeps track on how many pointers are currently active. * Keeps track on how many pointers are currently active.
@@ -150,7 +143,7 @@ MapBrowserEventHandler.prototype.emulateClick_ = function(pointerEvent) {
* event. * event.
* @private * @private
*/ */
MapBrowserEventHandler.prototype.updateActivePointers_ = function(pointerEvent) { updateActivePointers_(pointerEvent) {
const event = pointerEvent; const event = pointerEvent;
if (event.type == MapBrowserEventType.POINTERUP || if (event.type == MapBrowserEventType.POINTERUP ||
@@ -160,15 +153,14 @@ MapBrowserEventHandler.prototype.updateActivePointers_ = function(pointerEvent)
this.trackedTouches_[event.pointerId] = true; this.trackedTouches_[event.pointerId] = true;
} }
this.activePointers_ = Object.keys(this.trackedTouches_).length; this.activePointers_ = Object.keys(this.trackedTouches_).length;
}; }
/** /**
* @param {module:ol/pointer/PointerEvent} pointerEvent Pointer * @param {module:ol/pointer/PointerEvent} pointerEvent Pointer
* event. * event.
* @private * @private
*/ */
MapBrowserEventHandler.prototype.handlePointerUp_ = function(pointerEvent) { handlePointerUp_(pointerEvent) {
this.updateActivePointers_(pointerEvent); this.updateActivePointers_(pointerEvent);
const newEvent = new MapBrowserPointerEvent( const newEvent = new MapBrowserPointerEvent(
MapBrowserEventType.POINTERUP, this.map_, pointerEvent); MapBrowserEventType.POINTERUP, this.map_, pointerEvent);
@@ -192,8 +184,7 @@ MapBrowserEventHandler.prototype.handlePointerUp_ = function(pointerEvent) {
this.documentPointerEventHandler_.dispose(); this.documentPointerEventHandler_.dispose();
this.documentPointerEventHandler_ = null; this.documentPointerEventHandler_ = null;
} }
}; }
/** /**
* @param {module:ol/pointer/PointerEvent} pointerEvent Pointer * @param {module:ol/pointer/PointerEvent} pointerEvent Pointer
@@ -201,17 +192,16 @@ MapBrowserEventHandler.prototype.handlePointerUp_ = function(pointerEvent) {
* @return {boolean} If the left mouse button was pressed. * @return {boolean} If the left mouse button was pressed.
* @private * @private
*/ */
MapBrowserEventHandler.prototype.isMouseActionButton_ = function(pointerEvent) { isMouseActionButton_(pointerEvent) {
return pointerEvent.button === 0; return pointerEvent.button === 0;
}; }
/** /**
* @param {module:ol/pointer/PointerEvent} pointerEvent Pointer * @param {module:ol/pointer/PointerEvent} pointerEvent Pointer
* event. * event.
* @private * @private
*/ */
MapBrowserEventHandler.prototype.handlePointerDown_ = function(pointerEvent) { handlePointerDown_(pointerEvent) {
this.updateActivePointers_(pointerEvent); this.updateActivePointers_(pointerEvent);
const newEvent = new MapBrowserPointerEvent( const newEvent = new MapBrowserPointerEvent(
MapBrowserEventType.POINTERDOWN, this.map_, pointerEvent); MapBrowserEventType.POINTERDOWN, this.map_, pointerEvent);
@@ -252,15 +242,14 @@ MapBrowserEventHandler.prototype.handlePointerDown_ = function(pointerEvent) {
this.handlePointerUp_, this) this.handlePointerUp_, this)
); );
} }
}; }
/** /**
* @param {module:ol/pointer/PointerEvent} pointerEvent Pointer * @param {module:ol/pointer/PointerEvent} pointerEvent Pointer
* event. * event.
* @private * @private
*/ */
MapBrowserEventHandler.prototype.handlePointerMove_ = function(pointerEvent) { handlePointerMove_(pointerEvent) {
// Between pointerdown and pointerup, pointermove events are triggered. // Between pointerdown and pointerup, pointermove events are triggered.
// To avoid a 'false' touchmove event to be dispatched, we test if the pointer // To avoid a 'false' touchmove event to be dispatched, we test if the pointer
// moved a significant distance. // moved a significant distance.
@@ -277,8 +266,7 @@ MapBrowserEventHandler.prototype.handlePointerMove_ = function(pointerEvent) {
// https://code.google.com/p/android/issues/detail?id=19827 // https://code.google.com/p/android/issues/detail?id=19827
// ex: Galaxy Tab P3110 + Android 4.1.1 // ex: Galaxy Tab P3110 + Android 4.1.1
pointerEvent.preventDefault(); pointerEvent.preventDefault();
}; }
/** /**
* Wrap and relay a pointer event. Note that this requires that the type * Wrap and relay a pointer event. Note that this requires that the type
@@ -287,12 +275,11 @@ MapBrowserEventHandler.prototype.handlePointerMove_ = function(pointerEvent) {
* event. * event.
* @private * @private
*/ */
MapBrowserEventHandler.prototype.relayEvent_ = function(pointerEvent) { relayEvent_(pointerEvent) {
const dragging = !!(this.down_ && this.isMoving_(pointerEvent)); const dragging = !!(this.down_ && this.isMoving_(pointerEvent));
this.dispatchEvent(new MapBrowserPointerEvent( this.dispatchEvent(new MapBrowserPointerEvent(
pointerEvent.type, this.map_, pointerEvent, dragging)); pointerEvent.type, this.map_, pointerEvent, dragging));
}; }
/** /**
* @param {module:ol/pointer/PointerEvent} pointerEvent Pointer * @param {module:ol/pointer/PointerEvent} pointerEvent Pointer
@@ -300,17 +287,16 @@ MapBrowserEventHandler.prototype.relayEvent_ = function(pointerEvent) {
* @return {boolean} Is moving. * @return {boolean} Is moving.
* @private * @private
*/ */
MapBrowserEventHandler.prototype.isMoving_ = function(pointerEvent) { isMoving_(pointerEvent) {
return this.dragging_ || return this.dragging_ ||
Math.abs(pointerEvent.clientX - this.down_.clientX) > this.moveTolerance_ || Math.abs(pointerEvent.clientX - this.down_.clientX) > this.moveTolerance_ ||
Math.abs(pointerEvent.clientY - this.down_.clientY) > this.moveTolerance_; Math.abs(pointerEvent.clientY - this.down_.clientY) > this.moveTolerance_;
}; }
/** /**
* @inheritDoc * @inheritDoc
*/ */
MapBrowserEventHandler.prototype.disposeInternal = function() { disposeInternal() {
if (this.relayedListenerKey_) { if (this.relayedListenerKey_) {
unlistenByKey(this.relayedListenerKey_); unlistenByKey(this.relayedListenerKey_);
this.relayedListenerKey_ = null; this.relayedListenerKey_ = null;
@@ -331,6 +317,9 @@ MapBrowserEventHandler.prototype.disposeInternal = function() {
this.pointerEventHandler_.dispose(); this.pointerEventHandler_.dispose();
this.pointerEventHandler_ = null; this.pointerEventHandler_ = null;
} }
EventTarget.prototype.disposeInternal.call(this); super.disposeInternal();
}; }
}
export default MapBrowserEventHandler; export default MapBrowserEventHandler;

View File

@@ -1,24 +1,20 @@
/** /**
* @module ol/MapBrowserPointerEvent * @module ol/MapBrowserPointerEvent
*/ */
import {inherits} from './util.js';
import MapBrowserEvent from './MapBrowserEvent.js'; import MapBrowserEvent from './MapBrowserEvent.js';
class MapBrowserPointerEvent extends MapBrowserEvent {
/** /**
* @constructor
* @extends {module:ol/MapBrowserEvent}
* @param {string} type Event type. * @param {string} type Event type.
* @param {module:ol/PluggableMap} map Map. * @param {module:ol/PluggableMap} map Map.
* @param {module:ol/pointer/PointerEvent} pointerEvent Pointer * @param {module:ol/pointer/PointerEvent} pointerEvent Pointer event.
* event.
* @param {boolean=} opt_dragging Is the map currently being dragged? * @param {boolean=} opt_dragging Is the map currently being dragged?
* @param {?module:ol/PluggableMap~FrameState=} opt_frameState Frame state. * @param {?module:ol/PluggableMap~FrameState=} opt_frameState Frame state.
*/ */
const MapBrowserPointerEvent = function(type, map, pointerEvent, opt_dragging, constructor(type, map, pointerEvent, opt_dragging, opt_frameState) {
opt_frameState) {
MapBrowserEvent.call(this, type, map, pointerEvent.originalEvent, opt_dragging, super(type, map, pointerEvent.originalEvent, opt_dragging, opt_frameState);
opt_frameState);
/** /**
* @const * @const
@@ -26,7 +22,8 @@ const MapBrowserPointerEvent = function(type, map, pointerEvent, opt_dragging,
*/ */
this.pointerEvent = pointerEvent; this.pointerEvent = pointerEvent;
}; }
}
inherits(MapBrowserPointerEvent, MapBrowserEvent);
export default MapBrowserPointerEvent; export default MapBrowserPointerEvent;

View File

@@ -1,23 +1,23 @@
/** /**
* @module ol/MapEvent * @module ol/MapEvent
*/ */
import {inherits} from './util.js';
import Event from './events/Event.js'; import Event from './events/Event.js';
/** /**
* @classdesc * @classdesc
* Events emitted as map events are instances of this type. * Events emitted as map events are instances of this type.
* See {@link module:ol/Map~Map} for which events trigger a map event. * See {@link module:ol/Map~Map} for which events trigger a map event.
* */
* @constructor class MapEvent extends Event {
* @extends {module:ol/events/Event}
/**
* @param {string} type Event type. * @param {string} type Event type.
* @param {module:ol/PluggableMap} map Map. * @param {module:ol/PluggableMap} map Map.
* @param {?module:ol/PluggableMap~FrameState=} opt_frameState Frame state. * @param {?module:ol/PluggableMap~FrameState=} opt_frameState Frame state.
*/ */
const MapEvent = function(type, map, opt_frameState) { constructor(type, map, opt_frameState) {
Event.call(this, type); super(type);
/** /**
* The map where the event occurred. * The map where the event occurred.
@@ -33,7 +33,8 @@ const MapEvent = function(type, map, opt_frameState) {
*/ */
this.frameState = opt_frameState !== undefined ? opt_frameState : null; this.frameState = opt_frameState !== undefined ? opt_frameState : null;
}; }
}
inherits(MapEvent, Event);
export default MapEvent; export default MapEvent;

View File

@@ -1,7 +1,7 @@
/** /**
* @module ol/Object * @module ol/Object
*/ */
import {getUid, inherits} from './util.js'; import {getUid} from './util.js';
import ObjectEventType from './ObjectEventType.js'; import ObjectEventType from './ObjectEventType.js';
import Observable from './Observable.js'; import Observable from './Observable.js';
import Event from './events/Event.js'; import Event from './events/Event.js';
@@ -10,17 +10,17 @@ import {assign} from './obj.js';
/** /**
* @classdesc * @classdesc
* Events emitted by {@link module:ol/Object~BaseObject} instances are instances of * Events emitted by {@link module:ol/Object~BaseObject} instances are instances of this type.
* this type. */
* class ObjectEvent extends Event {
/**
* @param {string} type The event type. * @param {string} type The event type.
* @param {string} key The property name. * @param {string} key The property name.
* @param {*} oldValue The old value for `key`. * @param {*} oldValue The old value for `key`.
* @extends {module:ol/events/Event}
* @constructor
*/ */
const ObjectEvent = function(type, key, oldValue) { constructor(type, key, oldValue) {
Event.call(this, type); super(type);
/** /**
* The name of the property whose value is changing. * The name of the property whose value is changing.
@@ -37,8 +37,9 @@ const ObjectEvent = function(type, key, oldValue) {
*/ */
this.oldValue = oldValue; this.oldValue = oldValue;
}; }
inherits(ObjectEvent, Event);
}
/** /**
@@ -81,16 +82,18 @@ inherits(ObjectEvent, Event);
* Properties can be deleted by using the unset method. E.g. * Properties can be deleted by using the unset method. E.g.
* object.unset('foo'). * object.unset('foo').
* *
* @constructor
* @extends {module:ol/Observable}
* @param {Object.<string, *>=} opt_values An object with key-value pairs.
* @fires module:ol/Object~ObjectEvent * @fires module:ol/Object~ObjectEvent
* @api * @api
*/ */
const BaseObject = function(opt_values) { class BaseObject extends Observable {
Observable.call(this);
// Call {@link module:ol~getUid} to ensure that the order of objects' ids is /**
* @param {Object.<string, *>=} opt_values An object with key-value pairs.
*/
constructor(opt_values) {
super();
// Call {@link module:ol/util~getUid} to ensure that the order of objects' ids is
// the same as the order in which they were created. This also helps to // the same as the order in which they were created. This also helps to
// ensure that object properties are always added in the same order, which // ensure that object properties are always added in the same order, which
// helps many JavaScript engines generate faster code. // helps many JavaScript engines generate faster code.
@@ -105,9 +108,100 @@ const BaseObject = function(opt_values) {
if (opt_values !== undefined) { if (opt_values !== undefined) {
this.setProperties(opt_values); this.setProperties(opt_values);
} }
}; }
inherits(BaseObject, Observable); /**
* Gets a value.
* @param {string} key Key name.
* @return {*} Value.
* @api
*/
get(key) {
let value;
if (this.values_.hasOwnProperty(key)) {
value = this.values_[key];
}
return value;
}
/**
* Get a list of object property names.
* @return {Array.<string>} List of property names.
* @api
*/
getKeys() {
return Object.keys(this.values_);
}
/**
* Get an object of all property names and values.
* @return {Object.<string, *>} Object.
* @api
*/
getProperties() {
return assign({}, this.values_);
}
/**
* @param {string} key Key name.
* @param {*} oldValue Old value.
*/
notify(key, oldValue) {
let eventType;
eventType = getChangeEventType(key);
this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));
eventType = ObjectEventType.PROPERTYCHANGE;
this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));
}
/**
* Sets a value.
* @param {string} key Key name.
* @param {*} value Value.
* @param {boolean=} opt_silent Update without triggering an event.
* @api
*/
set(key, value, opt_silent) {
if (opt_silent) {
this.values_[key] = value;
} else {
const oldValue = this.values_[key];
this.values_[key] = value;
if (oldValue !== value) {
this.notify(key, oldValue);
}
}
}
/**
* Sets a collection of key-value pairs. Note that this changes any existing
* properties and adds new ones (it does not remove any existing properties).
* @param {Object.<string, *>} values Values.
* @param {boolean=} opt_silent Update without triggering an event.
* @api
*/
setProperties(values, opt_silent) {
for (const key in values) {
this.set(key, values[key], opt_silent);
}
}
/**
* Unsets a property.
* @param {string} key Key name.
* @param {boolean=} opt_silent Unset without triggering an event.
* @api
*/
unset(key, opt_silent) {
if (key in this.values_) {
const oldValue = this.values_[key];
delete this.values_[key];
if (!opt_silent) {
this.notify(key, oldValue);
}
}
}
}
/** /**
@@ -127,103 +221,4 @@ export function getChangeEventType(key) {
} }
/**
* Gets a value.
* @param {string} key Key name.
* @return {*} Value.
* @api
*/
BaseObject.prototype.get = function(key) {
let value;
if (this.values_.hasOwnProperty(key)) {
value = this.values_[key];
}
return value;
};
/**
* Get a list of object property names.
* @return {Array.<string>} List of property names.
* @api
*/
BaseObject.prototype.getKeys = function() {
return Object.keys(this.values_);
};
/**
* Get an object of all property names and values.
* @return {Object.<string, *>} Object.
* @api
*/
BaseObject.prototype.getProperties = function() {
return assign({}, this.values_);
};
/**
* @param {string} key Key name.
* @param {*} oldValue Old value.
*/
BaseObject.prototype.notify = function(key, oldValue) {
let eventType;
eventType = getChangeEventType(key);
this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));
eventType = ObjectEventType.PROPERTYCHANGE;
this.dispatchEvent(new ObjectEvent(eventType, key, oldValue));
};
/**
* Sets a value.
* @param {string} key Key name.
* @param {*} value Value.
* @param {boolean=} opt_silent Update without triggering an event.
* @api
*/
BaseObject.prototype.set = function(key, value, opt_silent) {
if (opt_silent) {
this.values_[key] = value;
} else {
const oldValue = this.values_[key];
this.values_[key] = value;
if (oldValue !== value) {
this.notify(key, oldValue);
}
}
};
/**
* Sets a collection of key-value pairs. Note that this changes any existing
* properties and adds new ones (it does not remove any existing properties).
* @param {Object.<string, *>} values Values.
* @param {boolean=} opt_silent Update without triggering an event.
* @api
*/
BaseObject.prototype.setProperties = function(values, opt_silent) {
for (const key in values) {
this.set(key, values[key], opt_silent);
}
};
/**
* Unsets a property.
* @param {string} key Key name.
* @param {boolean=} opt_silent Unset without triggering an event.
* @api
*/
BaseObject.prototype.unset = function(key, opt_silent) {
if (key in this.values_) {
const oldValue = this.values_[key];
delete this.values_[key];
if (!opt_silent) {
this.notify(key, oldValue);
}
}
};
export default BaseObject; export default BaseObject;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/Observable * @module ol/Observable
*/ */
import {inherits} from './util.js';
import {listen, unlistenByKey, unlisten, listenOnce} from './events.js'; import {listen, unlistenByKey, unlisten, listenOnce} from './events.js';
import EventTarget from './events/EventTarget.js'; import EventTarget from './events/EventTarget.js';
import EventType from './events/EventType.js'; import EventType from './events/EventType.js';
@@ -14,15 +13,13 @@ import EventType from './events/EventType.js';
* and unregistration. A generic `change` event is always available through * and unregistration. A generic `change` event is always available through
* {@link module:ol/Observable~Observable#changed}. * {@link module:ol/Observable~Observable#changed}.
* *
* @constructor
* @extends {module:ol/events/EventTarget}
* @fires module:ol/events/Event~Event * @fires module:ol/events/Event~Event
* @struct
* @api * @api
*/ */
const Observable = function() { class Observable extends EventTarget {
constructor() {
EventTarget.call(this); super();
/** /**
* @private * @private
@@ -30,9 +27,88 @@ const Observable = function() {
*/ */
this.revision_ = 0; this.revision_ = 0;
}; }
inherits(Observable, EventTarget); /**
* Increases the revision counter and dispatches a 'change' event.
* @api
*/
changed() {
++this.revision_;
this.dispatchEvent(EventType.CHANGE);
}
/**
* Get the version number for this object. Each time the object is modified,
* its version number will be incremented.
* @return {number} Revision.
* @api
*/
getRevision() {
return this.revision_;
}
/**
* Listen for a certain type of event.
* @param {string|Array.<string>} type The event type or array of event types.
* @param {function(?): ?} listener The listener function.
* @return {module:ol/events~EventsKey|Array.<module:ol/events~EventsKey>} Unique key for the listener. If
* called with an array of event types as the first argument, the return
* will be an array of keys.
* @api
*/
on(type, listener) {
if (Array.isArray(type)) {
const len = type.length;
const keys = new Array(len);
for (let i = 0; i < len; ++i) {
keys[i] = listen(this, type[i], listener);
}
return keys;
} else {
return listen(this, /** @type {string} */ (type), listener);
}
}
/**
* Listen once for a certain type of event.
* @param {string|Array.<string>} type The event type or array of event types.
* @param {function(?): ?} listener The listener function.
* @return {module:ol/events~EventsKey|Array.<module:ol/events~EventsKey>} Unique key for the listener. If
* called with an array of event types as the first argument, the return
* will be an array of keys.
* @api
*/
once(type, listener) {
if (Array.isArray(type)) {
const len = type.length;
const keys = new Array(len);
for (let i = 0; i < len; ++i) {
keys[i] = listenOnce(this, type[i], listener);
}
return keys;
} else {
return listenOnce(this, /** @type {string} */ (type), listener);
}
}
/**
* Unlisten for a certain type of event.
* @param {string|Array.<string>} type The event type or array of event types.
* @param {function(?): ?} listener The listener function.
* @api
*/
un(type, listener) {
if (Array.isArray(type)) {
for (let i = 0, ii = type.length; i < ii; ++i) {
unlisten(this, type[i], listener);
}
return;
} else {
unlisten(this, /** @type {string} */ (type), listener);
}
}
}
/** /**
@@ -52,101 +128,4 @@ export function unByKey(key) {
} }
/**
* Increases the revision counter and dispatches a 'change' event.
* @api
*/
Observable.prototype.changed = function() {
++this.revision_;
this.dispatchEvent(EventType.CHANGE);
};
/**
* Dispatches an event and calls all listeners listening for events
* of this type. The event parameter can either be a string or an
* Object with a `type` property.
*
* @param {{type: string,
* target: (EventTarget|module:ol/events/EventTarget|undefined)}|
* module:ol/events/Event|string} event Event object.
* @function
* @api
*/
Observable.prototype.dispatchEvent;
/**
* Get the version number for this object. Each time the object is modified,
* its version number will be incremented.
* @return {number} Revision.
* @api
*/
Observable.prototype.getRevision = function() {
return this.revision_;
};
/**
* Listen for a certain type of event.
* @param {string|Array.<string>} type The event type or array of event types.
* @param {function(?): ?} listener The listener function.
* @return {module:ol/events~EventsKey|Array.<module:ol/events~EventsKey>} Unique key for the listener. If
* called with an array of event types as the first argument, the return
* will be an array of keys.
* @api
*/
Observable.prototype.on = function(type, listener) {
if (Array.isArray(type)) {
const len = type.length;
const keys = new Array(len);
for (let i = 0; i < len; ++i) {
keys[i] = listen(this, type[i], listener);
}
return keys;
} else {
return listen(this, /** @type {string} */ (type), listener);
}
};
/**
* Listen once for a certain type of event.
* @param {string|Array.<string>} type The event type or array of event types.
* @param {function(?): ?} listener The listener function.
* @return {module:ol/events~EventsKey|Array.<module:ol/events~EventsKey>} Unique key for the listener. If
* called with an array of event types as the first argument, the return
* will be an array of keys.
* @api
*/
Observable.prototype.once = function(type, listener) {
if (Array.isArray(type)) {
const len = type.length;
const keys = new Array(len);
for (let i = 0; i < len; ++i) {
keys[i] = listenOnce(this, type[i], listener);
}
return keys;
} else {
return listenOnce(this, /** @type {string} */ (type), listener);
}
};
/**
* Unlisten for a certain type of event.
* @param {string|Array.<string>} type The event type or array of event types.
* @param {function(?): ?} listener The listener function.
* @api
*/
Observable.prototype.un = function(type, listener) {
if (Array.isArray(type)) {
for (let i = 0, ii = type.length; i < ii; ++i) {
unlisten(this, type[i], listener);
}
return;
} else {
unlisten(this, /** @type {string} */ (type), listener);
}
};
export default Observable; export default Observable;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/Overlay * @module ol/Overlay
*/ */
import {inherits} from './util.js';
import MapEventType from './MapEventType.js'; import MapEventType from './MapEventType.js';
import BaseObject, {getChangeEventType} from './Object.js'; import BaseObject, {getChangeEventType} from './Object.js';
import OverlayPositioning from './OverlayPositioning.js'; import OverlayPositioning from './OverlayPositioning.js';
@@ -15,7 +14,7 @@ import {containsExtent} from './extent.js';
* @typedef {Object} Options * @typedef {Object} Options
* @property {number|string} [id] Set the overlay id. The overlay id can be used * @property {number|string} [id] Set the overlay id. The overlay id can be used
* with the {@link module:ol/Map~Map#getOverlayById} method. * with the {@link module:ol/Map~Map#getOverlayById} method.
* @property {Element} [element] The overlay element. * @property {HTMLElement} [element] The overlay element.
* @property {Array.<number>} [offset=[0, 0]] Offsets in pixels used when positioning * @property {Array.<number>} [offset=[0, 0]] Offsets in pixels used when positioning
* the overlay. The first element in the * the overlay. The first element in the
* array is the horizontal offset. A positive value shifts the overlay right. * array is the horizontal offset. A positive value shifts the overlay right.
@@ -93,14 +92,16 @@ const Property = {
* popup.setPosition(coordinate); * popup.setPosition(coordinate);
* map.addOverlay(popup); * map.addOverlay(popup);
* *
* @constructor
* @extends {module:ol/Object}
* @param {module:ol/Overlay~Options} options Overlay options.
* @api * @api
*/ */
const Overlay = function(options) { class Overlay extends BaseObject {
BaseObject.call(this); /**
* @param {module:ol/Overlay~Options} options Overlay options.
*/
constructor(options) {
super();
/** /**
* @protected * @protected
@@ -129,7 +130,7 @@ const Overlay = function(options) {
/** /**
* @protected * @protected
* @type {Element} * @type {HTMLElement}
*/ */
this.element = document.createElement('DIV'); this.element = document.createElement('DIV');
this.element.className = options.className !== undefined ? this.element.className = options.className !== undefined ?
@@ -211,31 +212,26 @@ const Overlay = function(options) {
this.setPosition(options.position); this.setPosition(options.position);
} }
}; }
inherits(Overlay, BaseObject);
/** /**
* Get the DOM element of this overlay. * Get the DOM element of this overlay.
* @return {Element|undefined} The Element containing the overlay. * @return {HTMLElement|undefined} The Element containing the overlay.
* @observable * @observable
* @api * @api
*/ */
Overlay.prototype.getElement = function() { getElement() {
return /** @type {Element|undefined} */ (this.get(Property.ELEMENT)); return /** @type {HTMLElement|undefined} */ (this.get(Property.ELEMENT));
}; }
/** /**
* Get the overlay identifier which is set on constructor. * Get the overlay identifier which is set on constructor.
* @return {number|string|undefined} Id. * @return {number|string|undefined} Id.
* @api * @api
*/ */
Overlay.prototype.getId = function() { getId() {
return this.id; return this.id;
}; }
/** /**
* Get the map associated with this overlay. * Get the map associated with this overlay.
@@ -244,12 +240,11 @@ Overlay.prototype.getId = function() {
* @observable * @observable
* @api * @api
*/ */
Overlay.prototype.getMap = function() { getMap() {
return ( return (
/** @type {module:ol/PluggableMap|undefined} */ (this.get(Property.MAP)) /** @type {module:ol/PluggableMap|undefined} */ (this.get(Property.MAP))
); );
}; }
/** /**
* Get the offset of this overlay. * Get the offset of this overlay.
@@ -257,10 +252,9 @@ Overlay.prototype.getMap = function() {
* @observable * @observable
* @api * @api
*/ */
Overlay.prototype.getOffset = function() { getOffset() {
return /** @type {Array.<number>} */ (this.get(Property.OFFSET)); return /** @type {Array.<number>} */ (this.get(Property.OFFSET));
}; }
/** /**
* Get the current position of this overlay. * Get the current position of this overlay.
@@ -269,12 +263,11 @@ Overlay.prototype.getOffset = function() {
* @observable * @observable
* @api * @api
*/ */
Overlay.prototype.getPosition = function() { getPosition() {
return ( return (
/** @type {module:ol/coordinate~Coordinate|undefined} */ (this.get(Property.POSITION)) /** @type {module:ol/coordinate~Coordinate|undefined} */ (this.get(Property.POSITION))
); );
}; }
/** /**
* Get the current positioning of this overlay. * Get the current positioning of this overlay.
@@ -283,29 +276,27 @@ Overlay.prototype.getPosition = function() {
* @observable * @observable
* @api * @api
*/ */
Overlay.prototype.getPositioning = function() { getPositioning() {
return ( return (
/** @type {module:ol/OverlayPositioning} */ (this.get(Property.POSITIONING)) /** @type {module:ol/OverlayPositioning} */ (this.get(Property.POSITIONING))
); );
}; }
/** /**
* @protected * @protected
*/ */
Overlay.prototype.handleElementChanged = function() { handleElementChanged() {
removeChildren(this.element); removeChildren(this.element);
const element = this.getElement(); const element = this.getElement();
if (element) { if (element) {
this.element.appendChild(element); this.element.appendChild(element);
} }
}; }
/** /**
* @protected * @protected
*/ */
Overlay.prototype.handleMapChanged = function() { handleMapChanged() {
if (this.mapPostrenderListenerKey) { if (this.mapPostrenderListenerKey) {
removeNode(this.element); removeNode(this.element);
unlistenByKey(this.mapPostrenderListenerKey); unlistenByKey(this.mapPostrenderListenerKey);
@@ -324,54 +315,48 @@ Overlay.prototype.handleMapChanged = function() {
container.appendChild(this.element); container.appendChild(this.element);
} }
} }
}; }
/** /**
* @protected * @protected
*/ */
Overlay.prototype.render = function() { render() {
this.updatePixelPosition(); this.updatePixelPosition();
}; }
/** /**
* @protected * @protected
*/ */
Overlay.prototype.handleOffsetChanged = function() { handleOffsetChanged() {
this.updatePixelPosition(); this.updatePixelPosition();
}; }
/** /**
* @protected * @protected
*/ */
Overlay.prototype.handlePositionChanged = function() { handlePositionChanged() {
this.updatePixelPosition(); this.updatePixelPosition();
if (this.get(Property.POSITION) && this.autoPan) { if (this.get(Property.POSITION) && this.autoPan) {
this.panIntoView(); this.panIntoView();
} }
}; }
/** /**
* @protected * @protected
*/ */
Overlay.prototype.handlePositioningChanged = function() { handlePositioningChanged() {
this.updatePixelPosition(); this.updatePixelPosition();
}; }
/** /**
* Set the DOM element to be associated with this overlay. * Set the DOM element to be associated with this overlay.
* @param {Element|undefined} element The Element containing the overlay. * @param {HTMLElement|undefined} element The Element containing the overlay.
* @observable * @observable
* @api * @api
*/ */
Overlay.prototype.setElement = function(element) { setElement(element) {
this.set(Property.ELEMENT, element); this.set(Property.ELEMENT, element);
}; }
/** /**
* Set the map to be associated with this overlay. * Set the map to be associated with this overlay.
@@ -380,10 +365,9 @@ Overlay.prototype.setElement = function(element) {
* @observable * @observable
* @api * @api
*/ */
Overlay.prototype.setMap = function(map) { setMap(map) {
this.set(Property.MAP, map); this.set(Property.MAP, map);
}; }
/** /**
* Set the offset for this overlay. * Set the offset for this overlay.
@@ -391,10 +375,9 @@ Overlay.prototype.setMap = function(map) {
* @observable * @observable
* @api * @api
*/ */
Overlay.prototype.setOffset = function(offset) { setOffset(offset) {
this.set(Property.OFFSET, offset); this.set(Property.OFFSET, offset);
}; }
/** /**
* Set the position for this overlay. If the position is `undefined` the * Set the position for this overlay. If the position is `undefined` the
@@ -404,17 +387,16 @@ Overlay.prototype.setOffset = function(offset) {
* @observable * @observable
* @api * @api
*/ */
Overlay.prototype.setPosition = function(position) { setPosition(position) {
this.set(Property.POSITION, position); this.set(Property.POSITION, position);
}; }
/** /**
* Pan the map so that the overlay is entirely visible in the current viewport * Pan the map so that the overlay is entirely visible in the current viewport
* (if necessary). * (if necessary).
* @protected * @protected
*/ */
Overlay.prototype.panIntoView = function() { panIntoView() {
const map = this.getMap(); const map = this.getMap();
if (!map || !map.getTargetElement()) { if (!map || !map.getTargetElement()) {
@@ -422,7 +404,7 @@ Overlay.prototype.panIntoView = function() {
} }
const mapRect = this.getRect(map.getTargetElement(), map.getSize()); const mapRect = this.getRect(map.getTargetElement(), map.getSize());
const element = /** @type {!Element} */ (this.getElement()); const element = this.getElement();
const overlayRect = this.getRect(element, [outerWidth(element), outerHeight(element)]); const overlayRect = this.getRect(element, [outerWidth(element), outerHeight(element)]);
const margin = this.autoPanMargin; const margin = this.autoPanMargin;
@@ -464,17 +446,16 @@ Overlay.prototype.panIntoView = function() {
}); });
} }
} }
}; }
/** /**
* Get the extent of an element relative to the document * Get the extent of an element relative to the document
* @param {Element|undefined} element The element. * @param {HTMLElement|undefined} element The element.
* @param {module:ol/size~Size|undefined} size The size of the element. * @param {module:ol/size~Size|undefined} size The size of the element.
* @return {module:ol/extent~Extent} The extent. * @return {module:ol/extent~Extent} The extent.
* @protected * @protected
*/ */
Overlay.prototype.getRect = function(element, size) { getRect(element, size) {
const box = element.getBoundingClientRect(); const box = element.getBoundingClientRect();
const offsetX = box.left + window.pageXOffset; const offsetX = box.left + window.pageXOffset;
const offsetY = box.top + window.pageYOffset; const offsetY = box.top + window.pageYOffset;
@@ -484,8 +465,7 @@ Overlay.prototype.getRect = function(element, size) {
offsetX + size[0], offsetX + size[0],
offsetY + size[1] offsetY + size[1]
]; ];
}; }
/** /**
* Set the positioning for this overlay. * Set the positioning for this overlay.
@@ -494,29 +474,27 @@ Overlay.prototype.getRect = function(element, size) {
* @observable * @observable
* @api * @api
*/ */
Overlay.prototype.setPositioning = function(positioning) { setPositioning(positioning) {
this.set(Property.POSITIONING, positioning); this.set(Property.POSITIONING, positioning);
}; }
/** /**
* Modify the visibility of the element. * Modify the visibility of the element.
* @param {boolean} visible Element visibility. * @param {boolean} visible Element visibility.
* @protected * @protected
*/ */
Overlay.prototype.setVisible = function(visible) { setVisible(visible) {
if (this.rendered.visible !== visible) { if (this.rendered.visible !== visible) {
this.element.style.display = visible ? '' : 'none'; this.element.style.display = visible ? '' : 'none';
this.rendered.visible = visible; this.rendered.visible = visible;
} }
}; }
/** /**
* Update pixel position. * Update pixel position.
* @protected * @protected
*/ */
Overlay.prototype.updatePixelPosition = function() { updatePixelPosition() {
const map = this.getMap(); const map = this.getMap();
const position = this.getPosition(); const position = this.getPosition();
if (!map || !map.isRendered() || !position) { if (!map || !map.isRendered() || !position) {
@@ -527,15 +505,14 @@ Overlay.prototype.updatePixelPosition = function() {
const pixel = map.getPixelFromCoordinate(position); const pixel = map.getPixelFromCoordinate(position);
const mapSize = map.getSize(); const mapSize = map.getSize();
this.updateRenderedPosition(pixel, mapSize); this.updateRenderedPosition(pixel, mapSize);
}; }
/** /**
* @param {module:ol~Pixel} pixel The pixel location. * @param {module:ol/pixel~Pixel} pixel The pixel location.
* @param {module:ol/size~Size|undefined} mapSize The map size. * @param {module:ol/size~Size|undefined} mapSize The map size.
* @protected * @protected
*/ */
Overlay.prototype.updateRenderedPosition = function(pixel, mapSize) { updateRenderedPosition(pixel, mapSize) {
const style = this.element.style; const style = this.element.style;
const offset = this.getOffset(); const offset = this.getOffset();
@@ -593,15 +570,16 @@ Overlay.prototype.updateRenderedPosition = function(pixel, mapSize) {
this.rendered.top_ = style.top = top; this.rendered.top_ = style.top = top;
} }
} }
}; }
/** /**
* returns the options this Overlay has been created with * returns the options this Overlay has been created with
* @return {module:ol/Overlay~Options} overlay options * @return {module:ol/Overlay~Options} overlay options
*/ */
Overlay.prototype.getOptions = function() { getOptions() {
return this.options; return this.options;
}; }
}
export default Overlay; export default Overlay;

View File

@@ -1,7 +1,7 @@
/** /**
* @module ol/PluggableMap * @module ol/PluggableMap
*/ */
import {getUid, inherits} from './util.js'; import {getUid} from './util.js';
import Collection from './Collection.js'; import Collection from './Collection.js';
import CollectionEventType from './CollectionEventType.js'; import CollectionEventType from './CollectionEventType.js';
import MapBrowserEvent from './MapBrowserEvent.js'; import MapBrowserEvent from './MapBrowserEvent.js';
@@ -76,7 +76,7 @@ import {create as createTransform, apply as applyTransform} from './transform.js
* @typedef {Object} MapOptionsInternal * @typedef {Object} MapOptionsInternal
* @property {module:ol/Collection.<module:ol/control/Control>} [controls] * @property {module:ol/Collection.<module:ol/control/Control>} [controls]
* @property {module:ol/Collection.<module:ol/interaction/Interaction>} [interactions] * @property {module:ol/Collection.<module:ol/interaction/Interaction>} [interactions]
* @property {Element|Document} keyboardEventTarget * @property {HTMLElement|Document} keyboardEventTarget
* @property {module:ol/Collection.<module:ol/Overlay>} overlays * @property {module:ol/Collection.<module:ol/Overlay>} overlays
* @property {Object.<string, *>} values * @property {Object.<string, *>} values
*/ */
@@ -93,7 +93,7 @@ import {create as createTransform, apply as applyTransform} from './transform.js
* @property {module:ol/Collection.<module:ol/interaction/Interaction>|Array.<module:ol/interaction/Interaction>} [interactions] * @property {module:ol/Collection.<module:ol/interaction/Interaction>|Array.<module:ol/interaction/Interaction>} [interactions]
* Interactions that are initially added to the map. If not specified, * Interactions that are initially added to the map. If not specified,
* {@link module:ol/interaction~defaults} is used. * {@link module:ol/interaction~defaults} is used.
* @property {Element|Document|string} [keyboardEventTarget] The element to * @property {HTMLElement|Document|string} [keyboardEventTarget] The element to
* listen to keyboard events on. This determines when the `KeyboardPan` and * listen to keyboard events on. This determines when the `KeyboardPan` and
* `KeyboardZoom` interactions trigger. For example, if this option is set to * `KeyboardZoom` interactions trigger. For example, if this option is set to
* `document` the keyboard interactions will always trigger. If this option is * `document` the keyboard interactions will always trigger. If this option is
@@ -120,7 +120,7 @@ import {create as createTransform, apply as applyTransform} from './transform.js
* Increasing this value can make it easier to click on the map. * Increasing this value can make it easier to click on the map.
* @property {module:ol/Collection.<module:ol/Overlay>|Array.<module:ol/Overlay>} [overlays] * @property {module:ol/Collection.<module:ol/Overlay>|Array.<module:ol/Overlay>} [overlays]
* Overlays initially added to the map. By default, no overlays are added. * Overlays initially added to the map. By default, no overlays are added.
* @property {Element|string} [target] The container for the map, either the * @property {HTMLElement|string} [target] The container for the map, either the
* element itself or the `id` of the element. If not specified at construction * element itself or the `id` of the element. If not specified at construction
* time, {@link module:ol/Map~Map#setTarget} must be called for the map to be * time, {@link module:ol/Map~Map#setTarget} must be called for the map to be
* rendered. * rendered.
@@ -131,18 +131,20 @@ import {create as createTransform, apply as applyTransform} from './transform.js
/** /**
* @constructor
* @extends {module:ol/Object}
* @param {module:ol/PluggableMap~MapOptions} options Map options.
* @fires module:ol/MapBrowserEvent~MapBrowserEvent * @fires module:ol/MapBrowserEvent~MapBrowserEvent
* @fires module:ol/MapEvent~MapEvent * @fires module:ol/MapEvent~MapEvent
* @fires module:ol/render/Event~RenderEvent#postcompose * @fires module:ol/render/Event~RenderEvent#postcompose
* @fires module:ol/render/Event~RenderEvent#precompose * @fires module:ol/render/Event~RenderEvent#precompose
* @api * @api
*/ */
const PluggableMap = function(options) { class PluggableMap extends BaseObject {
BaseObject.call(this); /**
* @param {module:ol/PluggableMap~MapOptions} options Map options.
*/
constructor(options) {
super();
const optionsInternal = createOptionsInternal(options); const optionsInternal = createOptionsInternal(options);
@@ -240,7 +242,7 @@ const PluggableMap = function(options) {
/** /**
* @private * @private
* @type {Element} * @type {!HTMLElement}
*/ */
this.viewport_ = document.createElement('DIV'); this.viewport_ = document.createElement('DIV');
this.viewport_.className = 'ol-viewport' + (TOUCH ? ' ol-touch' : ''); this.viewport_.className = 'ol-viewport' + (TOUCH ? ' ol-touch' : '');
@@ -254,7 +256,7 @@ const PluggableMap = function(options) {
/** /**
* @private * @private
* @type {!Element} * @type {!HTMLElement}
*/ */
this.overlayContainer_ = document.createElement('DIV'); this.overlayContainer_ = document.createElement('DIV');
this.overlayContainer_.className = 'ol-overlaycontainer'; this.overlayContainer_.className = 'ol-overlaycontainer';
@@ -262,7 +264,7 @@ const PluggableMap = function(options) {
/** /**
* @private * @private
* @type {!Element} * @type {!HTMLElement}
*/ */
this.overlayContainerStopEvent_ = document.createElement('DIV'); this.overlayContainerStopEvent_ = document.createElement('DIV');
this.overlayContainerStopEvent_.className = 'ol-overlaycontainer-stopevent'; this.overlayContainerStopEvent_.className = 'ol-overlaycontainer-stopevent';
@@ -293,7 +295,7 @@ const PluggableMap = function(options) {
/** /**
* @private * @private
* @type {Element|Document} * @type {HTMLElement|Document}
*/ */
this.keyboardEventTarget_ = optionsInternal.keyboardEventTarget; this.keyboardEventTarget_ = optionsInternal.keyboardEventTarget;
@@ -458,35 +460,29 @@ const PluggableMap = function(options) {
event.element.setMap(null); event.element.setMap(null);
}, this); }, this);
}; }
inherits(PluggableMap, BaseObject); createRenderer() {
PluggableMap.prototype.createRenderer = function() {
throw new Error('Use a map type that has a createRenderer method'); throw new Error('Use a map type that has a createRenderer method');
}; }
/** /**
* Add the given control to the map. * Add the given control to the map.
* @param {module:ol/control/Control} control Control. * @param {module:ol/control/Control} control Control.
* @api * @api
*/ */
PluggableMap.prototype.addControl = function(control) { addControl(control) {
this.getControls().push(control); this.getControls().push(control);
}; }
/** /**
* Add the given interaction to the map. * Add the given interaction to the map.
* @param {module:ol/interaction/Interaction} interaction Interaction to add. * @param {module:ol/interaction/Interaction} interaction Interaction to add.
* @api * @api
*/ */
PluggableMap.prototype.addInteraction = function(interaction) { addInteraction(interaction) {
this.getInteractions().push(interaction); this.getInteractions().push(interaction);
}; }
/** /**
* Adds the given layer to the top of this map. If you want to add a layer * Adds the given layer to the top of this map. If you want to add a layer
@@ -495,41 +491,38 @@ PluggableMap.prototype.addInteraction = function(interaction) {
* @param {module:ol/layer/Base} layer Layer. * @param {module:ol/layer/Base} layer Layer.
* @api * @api
*/ */
PluggableMap.prototype.addLayer = function(layer) { addLayer(layer) {
const layers = this.getLayerGroup().getLayers(); const layers = this.getLayerGroup().getLayers();
layers.push(layer); layers.push(layer);
}; }
/** /**
* Add the given overlay to the map. * Add the given overlay to the map.
* @param {module:ol/Overlay} overlay Overlay. * @param {module:ol/Overlay} overlay Overlay.
* @api * @api
*/ */
PluggableMap.prototype.addOverlay = function(overlay) { addOverlay(overlay) {
this.getOverlays().push(overlay); this.getOverlays().push(overlay);
}; }
/** /**
* This deals with map's overlay collection changes. * This deals with map's overlay collection changes.
* @param {module:ol/Overlay} overlay Overlay. * @param {module:ol/Overlay} overlay Overlay.
* @private * @private
*/ */
PluggableMap.prototype.addOverlayInternal_ = function(overlay) { addOverlayInternal_(overlay) {
const id = overlay.getId(); const id = overlay.getId();
if (id !== undefined) { if (id !== undefined) {
this.overlayIdIndex_[id.toString()] = overlay; this.overlayIdIndex_[id.toString()] = overlay;
} }
overlay.setMap(this); overlay.setMap(this);
}; }
/** /**
* *
* @inheritDoc * @inheritDoc
*/ */
PluggableMap.prototype.disposeInternal = function() { disposeInternal() {
this.mapBrowserEventHandler_.dispose(); this.mapBrowserEventHandler_.dispose();
unlisten(this.viewport_, EventType.CONTEXTMENU, this.handleBrowserEvent, this); unlisten(this.viewport_, EventType.CONTEXTMENU, this.handleBrowserEvent, this);
unlisten(this.viewport_, EventType.WHEEL, this.handleBrowserEvent, this); unlisten(this.viewport_, EventType.WHEEL, this.handleBrowserEvent, this);
@@ -543,15 +536,14 @@ PluggableMap.prototype.disposeInternal = function() {
this.animationDelayKey_ = undefined; this.animationDelayKey_ = undefined;
} }
this.setTarget(null); this.setTarget(null);
BaseObject.prototype.disposeInternal.call(this); super.disposeInternal();
}; }
/** /**
* Detect features that intersect a pixel on the viewport, and execute a * Detect features that intersect a pixel on the viewport, and execute a
* callback with each intersecting feature. Layers included in the detection can * callback with each intersecting feature. Layers included in the detection can
* be configured through the `layerFilter` option in `opt_options`. * be configured through the `layerFilter` option in `opt_options`.
* @param {module:ol~Pixel} pixel Pixel. * @param {module:ol/pixel~Pixel} pixel Pixel.
* @param {function(this: S, (module:ol/Feature|module:ol/render/Feature), * @param {function(this: S, (module:ol/Feature|module:ol/render/Feature),
* module:ol/layer/Layer): T} callback Feature callback. The callback will be * module:ol/layer/Layer): T} callback Feature callback. The callback will be
* called with two arguments. The first argument is one * called with two arguments. The first argument is one
@@ -566,7 +558,7 @@ PluggableMap.prototype.disposeInternal = function() {
* @template S,T * @template S,T
* @api * @api
*/ */
PluggableMap.prototype.forEachFeatureAtPixel = function(pixel, callback, opt_options) { forEachFeatureAtPixel(pixel, callback, opt_options) {
if (!this.frameState_) { if (!this.frameState_) {
return; return;
} }
@@ -579,18 +571,17 @@ PluggableMap.prototype.forEachFeatureAtPixel = function(pixel, callback, opt_opt
return this.renderer_.forEachFeatureAtCoordinate( return this.renderer_.forEachFeatureAtCoordinate(
coordinate, this.frameState_, hitTolerance, callback, null, coordinate, this.frameState_, hitTolerance, callback, null,
layerFilter, null); layerFilter, null);
}; }
/** /**
* Get all features that intersect a pixel on the viewport. * Get all features that intersect a pixel on the viewport.
* @param {module:ol~Pixel} pixel Pixel. * @param {module:ol/pixel~Pixel} pixel Pixel.
* @param {module:ol/PluggableMap~AtPixelOptions=} opt_options Optional options. * @param {module:ol/PluggableMap~AtPixelOptions=} opt_options Optional options.
* @return {Array.<module:ol/Feature|module:ol/render/Feature>} The detected features or * @return {Array.<module:ol/Feature|module:ol/render/Feature>} The detected features or
* `null` if none were found. * `null` if none were found.
* @api * @api
*/ */
PluggableMap.prototype.getFeaturesAtPixel = function(pixel, opt_options) { getFeaturesAtPixel(pixel, opt_options) {
let features = null; let features = null;
this.forEachFeatureAtPixel(pixel, function(feature) { this.forEachFeatureAtPixel(pixel, function(feature) {
if (!features) { if (!features) {
@@ -599,13 +590,13 @@ PluggableMap.prototype.getFeaturesAtPixel = function(pixel, opt_options) {
features.push(feature); features.push(feature);
}, opt_options); }, opt_options);
return features; return features;
}; }
/** /**
* Detect layers that have a color value at a pixel on the viewport, and * Detect layers that have a color value at a pixel on the viewport, and
* execute a callback with each matching layer. Layers included in the * execute a callback with each matching layer. Layers included in the
* detection can be configured through `opt_layerFilter`. * detection can be configured through `opt_layerFilter`.
* @param {module:ol~Pixel} pixel Pixel. * @param {module:ol/pixel~Pixel} pixel Pixel.
* @param {function(this: S, module:ol/layer/Layer, (Uint8ClampedArray|Uint8Array)): T} callback * @param {function(this: S, module:ol/layer/Layer, (Uint8ClampedArray|Uint8Array)): T} callback
* Layer callback. This callback will receive two arguments: first is the * Layer callback. This callback will receive two arguments: first is the
* {@link module:ol/layer/Layer layer}, second argument is an array representing * {@link module:ol/layer/Layer layer}, second argument is an array representing
@@ -618,7 +609,7 @@ PluggableMap.prototype.getFeaturesAtPixel = function(pixel, opt_options) {
* @template S,T * @template S,T
* @api * @api
*/ */
PluggableMap.prototype.forEachLayerAtPixel = function(pixel, callback, opt_options) { forEachLayerAtPixel(pixel, callback, opt_options) {
if (!this.frameState_) { if (!this.frameState_) {
return; return;
} }
@@ -628,19 +619,18 @@ PluggableMap.prototype.forEachLayerAtPixel = function(pixel, callback, opt_optio
const layerFilter = options.layerFilter || TRUE; const layerFilter = options.layerFilter || TRUE;
return this.renderer_.forEachLayerAtPixel( return this.renderer_.forEachLayerAtPixel(
pixel, this.frameState_, hitTolerance, callback, null, layerFilter, null); pixel, this.frameState_, hitTolerance, callback, null, layerFilter, null);
}; }
/** /**
* Detect if features intersect a pixel on the viewport. Layers included in the * Detect if features intersect a pixel on the viewport. Layers included in the
* detection can be configured through `opt_layerFilter`. * detection can be configured through `opt_layerFilter`.
* @param {module:ol~Pixel} pixel Pixel. * @param {module:ol/pixel~Pixel} pixel Pixel.
* @param {module:ol/PluggableMap~AtPixelOptions=} opt_options Optional options. * @param {module:ol/PluggableMap~AtPixelOptions=} opt_options Optional options.
* @return {boolean} Is there a feature at the given pixel? * @return {boolean} Is there a feature at the given pixel?
* @template U * @template U
* @api * @api
*/ */
PluggableMap.prototype.hasFeatureAtPixel = function(pixel, opt_options) { hasFeatureAtPixel(pixel, opt_options) {
if (!this.frameState_) { if (!this.frameState_) {
return false; return false;
} }
@@ -651,8 +641,7 @@ PluggableMap.prototype.hasFeatureAtPixel = function(pixel, opt_options) {
opt_options.hitTolerance * this.frameState_.pixelRatio : 0; opt_options.hitTolerance * this.frameState_.pixelRatio : 0;
return this.renderer_.hasFeatureAtCoordinate( return this.renderer_.hasFeatureAtCoordinate(
coordinate, this.frameState_, hitTolerance, layerFilter, null); coordinate, this.frameState_, hitTolerance, layerFilter, null);
}; }
/** /**
* Returns the coordinate in view projection for a browser event. * Returns the coordinate in view projection for a browser event.
@@ -660,74 +649,69 @@ PluggableMap.prototype.hasFeatureAtPixel = function(pixel, opt_options) {
* @return {module:ol/coordinate~Coordinate} Coordinate. * @return {module:ol/coordinate~Coordinate} Coordinate.
* @api * @api
*/ */
PluggableMap.prototype.getEventCoordinate = function(event) { getEventCoordinate(event) {
return this.getCoordinateFromPixel(this.getEventPixel(event)); return this.getCoordinateFromPixel(this.getEventPixel(event));
}; }
/** /**
* Returns the map pixel position for a browser event relative to the viewport. * Returns the map pixel position for a browser event relative to the viewport.
* @param {Event} event Event. * @param {Event} event Event.
* @return {module:ol~Pixel} Pixel. * @return {module:ol/pixel~Pixel} Pixel.
* @api * @api
*/ */
PluggableMap.prototype.getEventPixel = function(event) { getEventPixel(event) {
const viewportPosition = this.viewport_.getBoundingClientRect(); const viewportPosition = this.viewport_.getBoundingClientRect();
const eventPosition = event.changedTouches ? event.changedTouches[0] : event; const eventPosition = event.changedTouches ? event.changedTouches[0] : event;
return [ return [
eventPosition.clientX - viewportPosition.left, eventPosition.clientX - viewportPosition.left,
eventPosition.clientY - viewportPosition.top eventPosition.clientY - viewportPosition.top
]; ];
}; }
/** /**
* Get the target in which this map is rendered. * Get the target in which this map is rendered.
* Note that this returns what is entered as an option or in setTarget: * Note that this returns what is entered as an option or in setTarget:
* if that was an element, it returns an element; if a string, it returns that. * if that was an element, it returns an element; if a string, it returns that.
* @return {Element|string|undefined} The Element or id of the Element that the * @return {HTMLElement|string|undefined} The Element or id of the Element that the
* map is rendered in. * map is rendered in.
* @observable * @observable
* @api * @api
*/ */
PluggableMap.prototype.getTarget = function() { getTarget() {
return /** @type {Element|string|undefined} */ (this.get(MapProperty.TARGET)); return /** @type {HTMLElement|string|undefined} */ (this.get(MapProperty.TARGET));
}; }
/** /**
* Get the DOM element into which this map is rendered. In contrast to * Get the DOM element into which this map is rendered. In contrast to
* `getTarget` this method always return an `Element`, or `null` if the * `getTarget` this method always return an `Element`, or `null` if the
* map has no target. * map has no target.
* @return {Element} The element that the map is rendered in. * @return {HTMLElement} The element that the map is rendered in.
* @api * @api
*/ */
PluggableMap.prototype.getTargetElement = function() { getTargetElement() {
const target = this.getTarget(); const target = this.getTarget();
if (target !== undefined) { if (target !== undefined) {
return typeof target === 'string' ? document.getElementById(target) : target; return typeof target === 'string' ? document.getElementById(target) : target;
} else { } else {
return null; return null;
} }
}; }
/** /**
* Get the coordinate for a given pixel. This returns a coordinate in the * Get the coordinate for a given pixel. This returns a coordinate in the
* map view projection. * map view projection.
* @param {module:ol~Pixel} pixel Pixel position in the map viewport. * @param {module:ol/pixel~Pixel} pixel Pixel position in the map viewport.
* @return {module:ol/coordinate~Coordinate} The coordinate for the pixel position. * @return {module:ol/coordinate~Coordinate} The coordinate for the pixel position.
* @api * @api
*/ */
PluggableMap.prototype.getCoordinateFromPixel = function(pixel) { getCoordinateFromPixel(pixel) {
const frameState = this.frameState_; const frameState = this.frameState_;
if (!frameState) { if (!frameState) {
return null; return null;
} else { } else {
return applyTransform(frameState.pixelToCoordinateTransform, pixel.slice()); return applyTransform(frameState.pixelToCoordinateTransform, pixel.slice());
} }
}; }
/** /**
* Get the map controls. Modifying this collection changes the controls * Get the map controls. Modifying this collection changes the controls
@@ -735,10 +719,9 @@ PluggableMap.prototype.getCoordinateFromPixel = function(pixel) {
* @return {module:ol/Collection.<module:ol/control/Control>} Controls. * @return {module:ol/Collection.<module:ol/control/Control>} Controls.
* @api * @api
*/ */
PluggableMap.prototype.getControls = function() { getControls() {
return this.controls; return this.controls;
}; }
/** /**
* Get the map overlays. Modifying this collection changes the overlays * Get the map overlays. Modifying this collection changes the overlays
@@ -746,10 +729,9 @@ PluggableMap.prototype.getControls = function() {
* @return {module:ol/Collection.<module:ol/Overlay>} Overlays. * @return {module:ol/Collection.<module:ol/Overlay>} Overlays.
* @api * @api
*/ */
PluggableMap.prototype.getOverlays = function() { getOverlays() {
return this.overlays_; return this.overlays_;
}; }
/** /**
* Get an overlay by its identifier (the value returned by overlay.getId()). * Get an overlay by its identifier (the value returned by overlay.getId()).
@@ -759,11 +741,10 @@ PluggableMap.prototype.getOverlays = function() {
* @return {module:ol/Overlay} Overlay. * @return {module:ol/Overlay} Overlay.
* @api * @api
*/ */
PluggableMap.prototype.getOverlayById = function(id) { getOverlayById(id) {
const overlay = this.overlayIdIndex_[id.toString()]; const overlay = this.overlayIdIndex_[id.toString()];
return overlay !== undefined ? overlay : null; return overlay !== undefined ? overlay : null;
}; }
/** /**
* Get the map interactions. Modifying this collection changes the interactions * Get the map interactions. Modifying this collection changes the interactions
@@ -773,10 +754,9 @@ PluggableMap.prototype.getOverlayById = function(id) {
* @return {module:ol/Collection.<module:ol/interaction/Interaction>} Interactions. * @return {module:ol/Collection.<module:ol/interaction/Interaction>} Interactions.
* @api * @api
*/ */
PluggableMap.prototype.getInteractions = function() { getInteractions() {
return this.interactions; return this.interactions;
}; }
/** /**
* Get the layergroup associated with this map. * Get the layergroup associated with this map.
@@ -784,49 +764,45 @@ PluggableMap.prototype.getInteractions = function() {
* @observable * @observable
* @api * @api
*/ */
PluggableMap.prototype.getLayerGroup = function() { getLayerGroup() {
return ( return (
/** @type {module:ol/layer/Group} */ (this.get(MapProperty.LAYERGROUP)) /** @type {module:ol/layer/Group} */ (this.get(MapProperty.LAYERGROUP))
); );
}; }
/** /**
* Get the collection of layers associated with this map. * Get the collection of layers associated with this map.
* @return {!module:ol/Collection.<module:ol/layer/Base>} Layers. * @return {!module:ol/Collection.<module:ol/layer/Base>} Layers.
* @api * @api
*/ */
PluggableMap.prototype.getLayers = function() { getLayers() {
const layers = this.getLayerGroup().getLayers(); const layers = this.getLayerGroup().getLayers();
return layers; return layers;
}; }
/** /**
* Get the pixel for a coordinate. This takes a coordinate in the map view * Get the pixel for a coordinate. This takes a coordinate in the map view
* projection and returns the corresponding pixel. * projection and returns the corresponding pixel.
* @param {module:ol/coordinate~Coordinate} coordinate A map coordinate. * @param {module:ol/coordinate~Coordinate} coordinate A map coordinate.
* @return {module:ol~Pixel} A pixel position in the map viewport. * @return {module:ol/pixel~Pixel} A pixel position in the map viewport.
* @api * @api
*/ */
PluggableMap.prototype.getPixelFromCoordinate = function(coordinate) { getPixelFromCoordinate(coordinate) {
const frameState = this.frameState_; const frameState = this.frameState_;
if (!frameState) { if (!frameState) {
return null; return null;
} else { } else {
return applyTransform(frameState.coordinateToPixelTransform, coordinate.slice(0, 2)); return applyTransform(frameState.coordinateToPixelTransform, coordinate.slice(0, 2));
} }
}; }
/** /**
* Get the map renderer. * Get the map renderer.
* @return {module:ol/renderer/Map} Renderer * @return {module:ol/renderer/Map} Renderer
*/ */
PluggableMap.prototype.getRenderer = function() { getRenderer() {
return this.renderer_; return this.renderer_;
}; }
/** /**
* Get the size of this map. * Get the size of this map.
@@ -834,12 +810,11 @@ PluggableMap.prototype.getRenderer = function() {
* @observable * @observable
* @api * @api
*/ */
PluggableMap.prototype.getSize = function() { getSize() {
return ( return (
/** @type {module:ol/size~Size|undefined} */ (this.get(MapProperty.SIZE)) /** @type {module:ol/size~Size|undefined} */ (this.get(MapProperty.SIZE))
); );
}; }
/** /**
* Get the view associated with this map. A view manages properties such as * Get the view associated with this map. A view manages properties such as
@@ -848,46 +823,42 @@ PluggableMap.prototype.getSize = function() {
* @observable * @observable
* @api * @api
*/ */
PluggableMap.prototype.getView = function() { getView() {
return ( return (
/** @type {module:ol/View} */ (this.get(MapProperty.VIEW)) /** @type {module:ol/View} */ (this.get(MapProperty.VIEW))
); );
}; }
/** /**
* Get the element that serves as the map viewport. * Get the element that serves as the map viewport.
* @return {Element} Viewport. * @return {HTMLElement} Viewport.
* @api * @api
*/ */
PluggableMap.prototype.getViewport = function() { getViewport() {
return this.viewport_; return this.viewport_;
}; }
/** /**
* Get the element that serves as the container for overlays. Elements added to * Get the element that serves as the container for overlays. Elements added to
* this container will let mousedown and touchstart events through to the map, * this container will let mousedown and touchstart events through to the map,
* so clicks and gestures on an overlay will trigger {@link module:ol/MapBrowserEvent~MapBrowserEvent} * so clicks and gestures on an overlay will trigger {@link module:ol/MapBrowserEvent~MapBrowserEvent}
* events. * events.
* @return {!Element} The map's overlay container. * @return {!HTMLElement} The map's overlay container.
*/ */
PluggableMap.prototype.getOverlayContainer = function() { getOverlayContainer() {
return this.overlayContainer_; return this.overlayContainer_;
}; }
/** /**
* Get the element that serves as a container for overlays that don't allow * Get the element that serves as a container for overlays that don't allow
* event propagation. Elements added to this container won't let mousedown and * event propagation. Elements added to this container won't let mousedown and
* touchstart events through to the map, so clicks and gestures on an overlay * touchstart events through to the map, so clicks and gestures on an overlay
* don't trigger any {@link module:ol/MapBrowserEvent~MapBrowserEvent}. * don't trigger any {@link module:ol/MapBrowserEvent~MapBrowserEvent}.
* @return {!Element} The map's overlay container that stops events. * @return {!HTMLElement} The map's overlay container that stops events.
*/ */
PluggableMap.prototype.getOverlayContainerStopEvent = function() { getOverlayContainerStopEvent() {
return this.overlayContainerStopEvent_; return this.overlayContainerStopEvent_;
}; }
/** /**
* @param {module:ol/Tile} tile Tile. * @param {module:ol/Tile} tile Tile.
@@ -896,7 +867,7 @@ PluggableMap.prototype.getOverlayContainerStopEvent = function() {
* @param {number} tileResolution Tile resolution. * @param {number} tileResolution Tile resolution.
* @return {number} Tile priority. * @return {number} Tile priority.
*/ */
PluggableMap.prototype.getTilePriority = function(tile, tileSourceKey, tileCenter, tileResolution) { getTilePriority(tile, tileSourceKey, tileCenter, tileResolution) {
// Filter out tiles at higher zoom levels than the current zoom level, or that // Filter out tiles at higher zoom levels than the current zoom level, or that
// are outside the visible extent. // are outside the visible extent.
const frameState = this.frameState_; const frameState = this.frameState_;
@@ -916,24 +887,22 @@ PluggableMap.prototype.getTilePriority = function(tile, tileSourceKey, tileCente
const deltaY = tileCenter[1] - frameState.focus[1]; const deltaY = tileCenter[1] - frameState.focus[1];
return 65536 * Math.log(tileResolution) + return 65536 * Math.log(tileResolution) +
Math.sqrt(deltaX * deltaX + deltaY * deltaY) / tileResolution; Math.sqrt(deltaX * deltaX + deltaY * deltaY) / tileResolution;
}; }
/** /**
* @param {Event} browserEvent Browser event. * @param {Event} browserEvent Browser event.
* @param {string=} opt_type Type. * @param {string=} opt_type Type.
*/ */
PluggableMap.prototype.handleBrowserEvent = function(browserEvent, opt_type) { handleBrowserEvent(browserEvent, opt_type) {
const type = opt_type || browserEvent.type; const type = opt_type || browserEvent.type;
const mapBrowserEvent = new MapBrowserEvent(type, this, browserEvent); const mapBrowserEvent = new MapBrowserEvent(type, this, browserEvent);
this.handleMapBrowserEvent(mapBrowserEvent); this.handleMapBrowserEvent(mapBrowserEvent);
}; }
/** /**
* @param {module:ol/MapBrowserEvent} mapBrowserEvent The event to handle. * @param {module:ol/MapBrowserEvent} mapBrowserEvent The event to handle.
*/ */
PluggableMap.prototype.handleMapBrowserEvent = function(mapBrowserEvent) { handleMapBrowserEvent(mapBrowserEvent) {
if (!this.frameState_) { if (!this.frameState_) {
// With no view defined, we cannot translate pixels into geographical // With no view defined, we cannot translate pixels into geographical
// coordinates so interactions cannot be used. // coordinates so interactions cannot be used.
@@ -954,13 +923,12 @@ PluggableMap.prototype.handleMapBrowserEvent = function(mapBrowserEvent) {
} }
} }
} }
}; }
/** /**
* @protected * @protected
*/ */
PluggableMap.prototype.handlePostRender = function() { handlePostRender() {
const frameState = this.frameState_; const frameState = this.frameState_;
@@ -999,21 +967,19 @@ PluggableMap.prototype.handlePostRender = function() {
postRenderFunctions[i](this, frameState); postRenderFunctions[i](this, frameState);
} }
postRenderFunctions.length = 0; postRenderFunctions.length = 0;
}; }
/** /**
* @private * @private
*/ */
PluggableMap.prototype.handleSizeChanged_ = function() { handleSizeChanged_() {
this.render(); this.render();
}; }
/** /**
* @private * @private
*/ */
PluggableMap.prototype.handleTargetChanged_ = function() { handleTargetChanged_() {
// target may be undefined, null, a string or an Element. // target may be undefined, null, a string or an Element.
// If it's a string we convert it to an Element before proceeding. // If it's a string we convert it to an Element before proceeding.
// If it's not now an Element we remove the viewport from the DOM. // If it's not now an Element we remove the viewport from the DOM.
@@ -1057,29 +1023,26 @@ PluggableMap.prototype.handleTargetChanged_ = function() {
this.updateSize(); this.updateSize();
// updateSize calls setSize, so no need to call this.render // updateSize calls setSize, so no need to call this.render
// ourselves here. // ourselves here.
}; }
/** /**
* @private * @private
*/ */
PluggableMap.prototype.handleTileChange_ = function() { handleTileChange_() {
this.render(); this.render();
}; }
/** /**
* @private * @private
*/ */
PluggableMap.prototype.handleViewPropertyChanged_ = function() { handleViewPropertyChanged_() {
this.render(); this.render();
}; }
/** /**
* @private * @private
*/ */
PluggableMap.prototype.handleViewChanged_ = function() { handleViewChanged_() {
if (this.viewPropertyListenerKey_) { if (this.viewPropertyListenerKey_) {
unlistenByKey(this.viewPropertyListenerKey_); unlistenByKey(this.viewPropertyListenerKey_);
this.viewPropertyListenerKey_ = null; this.viewPropertyListenerKey_ = null;
@@ -1099,13 +1062,12 @@ PluggableMap.prototype.handleViewChanged_ = function() {
this.handleViewPropertyChanged_, this); this.handleViewPropertyChanged_, this);
} }
this.render(); this.render();
}; }
/** /**
* @private * @private
*/ */
PluggableMap.prototype.handleLayerGroupChanged_ = function() { handleLayerGroupChanged_() {
if (this.layerGroupPropertyListenerKeys_) { if (this.layerGroupPropertyListenerKeys_) {
this.layerGroupPropertyListenerKeys_.forEach(unlistenByKey); this.layerGroupPropertyListenerKeys_.forEach(unlistenByKey);
this.layerGroupPropertyListenerKeys_ = null; this.layerGroupPropertyListenerKeys_ = null;
@@ -1122,39 +1084,35 @@ PluggableMap.prototype.handleLayerGroupChanged_ = function() {
]; ];
} }
this.render(); this.render();
}; }
/** /**
* @return {boolean} Is rendered. * @return {boolean} Is rendered.
*/ */
PluggableMap.prototype.isRendered = function() { isRendered() {
return !!this.frameState_; return !!this.frameState_;
}; }
/** /**
* Requests an immediate render in a synchronous manner. * Requests an immediate render in a synchronous manner.
* @api * @api
*/ */
PluggableMap.prototype.renderSync = function() { renderSync() {
if (this.animationDelayKey_) { if (this.animationDelayKey_) {
cancelAnimationFrame(this.animationDelayKey_); cancelAnimationFrame(this.animationDelayKey_);
} }
this.animationDelay_(); this.animationDelay_();
}; }
/** /**
* Request a map rendering (at the next animation frame). * Request a map rendering (at the next animation frame).
* @api * @api
*/ */
PluggableMap.prototype.render = function() { render() {
if (this.animationDelayKey_ === undefined) { if (this.animationDelayKey_ === undefined) {
this.animationDelayKey_ = requestAnimationFrame(this.animationDelay_); this.animationDelayKey_ = requestAnimationFrame(this.animationDelay_);
} }
}; }
/** /**
* Remove the given control from the map. * Remove the given control from the map.
@@ -1163,10 +1121,9 @@ PluggableMap.prototype.render = function() {
* if the control was not found). * if the control was not found).
* @api * @api
*/ */
PluggableMap.prototype.removeControl = function(control) { removeControl(control) {
return this.getControls().remove(control); return this.getControls().remove(control);
}; }
/** /**
* Remove the given interaction from the map. * Remove the given interaction from the map.
@@ -1175,10 +1132,9 @@ PluggableMap.prototype.removeControl = function(control) {
* undefined if the interaction was not found). * undefined if the interaction was not found).
* @api * @api
*/ */
PluggableMap.prototype.removeInteraction = function(interaction) { removeInteraction(interaction) {
return this.getInteractions().remove(interaction); return this.getInteractions().remove(interaction);
}; }
/** /**
* Removes the given layer from the map. * Removes the given layer from the map.
@@ -1187,11 +1143,10 @@ PluggableMap.prototype.removeInteraction = function(interaction) {
* layer was not found). * layer was not found).
* @api * @api
*/ */
PluggableMap.prototype.removeLayer = function(layer) { removeLayer(layer) {
const layers = this.getLayerGroup().getLayers(); const layers = this.getLayerGroup().getLayers();
return layers.remove(layer); return layers.remove(layer);
}; }
/** /**
* Remove the given overlay from the map. * Remove the given overlay from the map.
@@ -1200,16 +1155,15 @@ PluggableMap.prototype.removeLayer = function(layer) {
* if the overlay was not found). * if the overlay was not found).
* @api * @api
*/ */
PluggableMap.prototype.removeOverlay = function(overlay) { removeOverlay(overlay) {
return this.getOverlays().remove(overlay); return this.getOverlays().remove(overlay);
}; }
/** /**
* @param {number} time Time. * @param {number} time Time.
* @private * @private
*/ */
PluggableMap.prototype.renderFrame_ = function(time) { renderFrame_(time) {
let viewState; let viewState;
const size = this.getSize(); const size = this.getSize();
@@ -1295,8 +1249,7 @@ PluggableMap.prototype.renderFrame_ = function(time) {
setTimeout(this.handlePostRender.bind(this), 0); setTimeout(this.handlePostRender.bind(this), 0);
}; }
/** /**
* Sets the layergroup of this map. * Sets the layergroup of this map.
@@ -1304,10 +1257,9 @@ PluggableMap.prototype.renderFrame_ = function(time) {
* @observable * @observable
* @api * @api
*/ */
PluggableMap.prototype.setLayerGroup = function(layerGroup) { setLayerGroup(layerGroup) {
this.set(MapProperty.LAYERGROUP, layerGroup); this.set(MapProperty.LAYERGROUP, layerGroup);
}; }
/** /**
* Set the size of this map. * Set the size of this map.
@@ -1315,22 +1267,20 @@ PluggableMap.prototype.setLayerGroup = function(layerGroup) {
* @observable * @observable
* @api * @api
*/ */
PluggableMap.prototype.setSize = function(size) { setSize(size) {
this.set(MapProperty.SIZE, size); this.set(MapProperty.SIZE, size);
}; }
/** /**
* Set the target element to render this map into. * Set the target element to render this map into.
* @param {Element|string|undefined} target The Element or id of the Element * @param {HTMLElement|string|undefined} target The Element or id of the Element
* that the map is rendered in. * that the map is rendered in.
* @observable * @observable
* @api * @api
*/ */
PluggableMap.prototype.setTarget = function(target) { setTarget(target) {
this.set(MapProperty.TARGET, target); this.set(MapProperty.TARGET, target);
}; }
/** /**
* Set the view for this map. * Set the view for this map.
@@ -1338,27 +1288,25 @@ PluggableMap.prototype.setTarget = function(target) {
* @observable * @observable
* @api * @api
*/ */
PluggableMap.prototype.setView = function(view) { setView(view) {
this.set(MapProperty.VIEW, view); this.set(MapProperty.VIEW, view);
}; }
/** /**
* @param {module:ol/Feature} feature Feature. * @param {module:ol/Feature} feature Feature.
*/ */
PluggableMap.prototype.skipFeature = function(feature) { skipFeature(feature) {
const featureUid = getUid(feature).toString(); const featureUid = getUid(feature).toString();
this.skippedFeatureUids_[featureUid] = true; this.skippedFeatureUids_[featureUid] = true;
this.render(); this.render();
}; }
/** /**
* Force a recalculation of the map viewport size. This should be called when * Force a recalculation of the map viewport size. This should be called when
* third-party code changes the size of the map viewport. * third-party code changes the size of the map viewport.
* @api * @api
*/ */
PluggableMap.prototype.updateSize = function() { updateSize() {
const targetElement = this.getTargetElement(); const targetElement = this.getTargetElement();
if (!targetElement) { if (!targetElement) {
@@ -1378,17 +1326,17 @@ PluggableMap.prototype.updateSize = function() {
parseFloat(computedStyle['borderBottomWidth']) parseFloat(computedStyle['borderBottomWidth'])
]); ]);
} }
}; }
/** /**
* @param {module:ol/Feature} feature Feature. * @param {module:ol/Feature} feature Feature.
*/ */
PluggableMap.prototype.unskipFeature = function(feature) { unskipFeature(feature) {
const featureUid = getUid(feature).toString(); const featureUid = getUid(feature).toString();
delete this.skippedFeatureUids_[featureUid]; delete this.skippedFeatureUids_[featureUid];
this.render(); this.render();
}; }
}
/** /**
@@ -1398,7 +1346,7 @@ PluggableMap.prototype.unskipFeature = function(feature) {
function createOptionsInternal(options) { function createOptionsInternal(options) {
/** /**
* @type {Element|Document} * @type {HTMLElement|Document}
*/ */
let keyboardEventTarget = null; let keyboardEventTarget = null;
if (options.keyboardEventTarget !== undefined) { if (options.keyboardEventTarget !== undefined) {

View File

@@ -1,52 +0,0 @@
# ol
OpenLayers as ES modules.
## Usage
Add the `ol` package as a dependency to your project.
npm install ol --save
Import just what you need for your application:
```js
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import XYZ from 'ol/source/XYZ';
new Map({
target: 'map',
layers: [
new TileLayer({
source: new XYZ({
url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png'
})
})
],
view: new View({
center: [0, 0],
zoom: 2
})
});
```
See the following examples for more detail on bundling OpenLayers with your application:
* Using [Rollup & Uglify](https://gist.github.com/tschaub/8beb328ea72b36446fc2198d008287de)
* Using [Rollup & Closure Compiler](https://gist.github.com/tschaub/32a5692bedac5254da24fa3b12072f35)
* Using [Webpack & Uglify](https://gist.github.com/tschaub/79025aef325cd2837364400a105405b8)
* Using [Webpack & Closure Compiler](https://gist.github.com/ahocevar/8ceafc6293455ba491dd9be12c15761f)
* Using [Browserify & Uglify](https://gist.github.com/tschaub/4bfb209a8f809823f1495b2e4436018e)
## Module Identifiers
The module identifiers shown in the above snippet (e.g. `ol/Map`, note the CamelCase module name) are default exports of constructors. There are also modules like 'ol/proj' (note the lowercase module name), which provide named exports for utility functions and constants, e.g.
```js
import {fromLonLat} from 'ol/proj';
map.setCenter(fromLonLat([16, 48]));
```
See the [API documentation](http://openlayers.org/en/latest/apidoc/) for a reference of all modules, and just keep in mind: CamelCase modules provide a default export, lowercase modules provide named exports.

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/Tile * @module ol/Tile
*/ */
import {inherits} from './util.js';
import TileState from './TileState.js'; import TileState from './TileState.js';
import {easeIn} from './easing.js'; import {easeIn} from './easing.js';
import EventTarget from './events/EventTarget.js'; import EventTarget from './events/EventTarget.js';
@@ -44,15 +43,17 @@ import EventType from './events/EventType.js';
* @classdesc * @classdesc
* Base class for tiles. * Base class for tiles.
* *
* @constructor
* @abstract * @abstract
* @extends {module:ol/events/EventTarget} */
class Tile extends EventTarget {
/**
* @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate. * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.
* @param {module:ol/TileState} state State. * @param {module:ol/TileState} state State.
* @param {module:ol/Tile~Options=} opt_options Tile options. * @param {module:ol/Tile~Options=} opt_options Tile options.
*/ */
const Tile = function(tileCoord, state, opt_options) { constructor(tileCoord, state, opt_options) {
EventTarget.call(this); super();
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
@@ -96,25 +97,21 @@ const Tile = function(tileCoord, state, opt_options) {
*/ */
this.transitionStarts_ = {}; this.transitionStarts_ = {};
}; }
inherits(Tile, EventTarget);
/** /**
* @protected * @protected
*/ */
Tile.prototype.changed = function() { changed() {
this.dispatchEvent(EventType.CHANGE); this.dispatchEvent(EventType.CHANGE);
}; }
/** /**
* @return {string} Key. * @return {string} Key.
*/ */
Tile.prototype.getKey = function() { getKey() {
return this.key + '/' + this.tileCoord; return this.key + '/' + this.tileCoord;
}; }
/** /**
* Get the interim tile most suitable for rendering using the chain of interim * Get the interim tile most suitable for rendering using the chain of interim
@@ -122,7 +119,7 @@ Tile.prototype.getKey = function() {
* such tile exists, the original tile is returned. * such tile exists, the original tile is returned.
* @return {!module:ol/Tile} Best tile for rendering. * @return {!module:ol/Tile} Best tile for rendering.
*/ */
Tile.prototype.getInterimTile = function() { getInterimTile() {
if (!this.interimTile) { if (!this.interimTile) {
//empty chain //empty chain
return this; return this;
@@ -142,13 +139,13 @@ Tile.prototype.getInterimTile = function() {
// we can not find a better tile // we can not find a better tile
return this; return this;
}; }
/** /**
* Goes through the chain of interim tiles and discards sections of the chain * Goes through the chain of interim tiles and discards sections of the chain
* that are no longer relevant. * that are no longer relevant.
*/ */
Tile.prototype.refreshInterimChain = function() { refreshInterimChain() {
if (!this.interimTile) { if (!this.interimTile) {
return; return;
} }
@@ -176,32 +173,31 @@ Tile.prototype.refreshInterimChain = function() {
} }
tile = prev.interimTile; tile = prev.interimTile;
} while (tile); } while (tile);
}; }
/** /**
* Get the tile coordinate for this tile. * Get the tile coordinate for this tile.
* @return {module:ol/tilecoord~TileCoord} The tile coordinate. * @return {module:ol/tilecoord~TileCoord} The tile coordinate.
* @api * @api
*/ */
Tile.prototype.getTileCoord = function() { getTileCoord() {
return this.tileCoord; return this.tileCoord;
}; }
/** /**
* @return {module:ol/TileState} State. * @return {module:ol/TileState} State.
*/ */
Tile.prototype.getState = function() { getState() {
return this.state; return this.state;
}; }
/** /**
* @param {module:ol/TileState} state State. * @param {module:ol/TileState} state State.
*/ */
Tile.prototype.setState = function(state) { setState(state) {
this.state = state; this.state = state;
this.changed(); this.changed();
}; }
/** /**
* Load the image or retry if loading previously failed. * Load the image or retry if loading previously failed.
@@ -210,7 +206,7 @@ Tile.prototype.setState = function(state) {
* @abstract * @abstract
* @api * @api
*/ */
Tile.prototype.load = function() {}; load() {}
/** /**
* Get the alpha value for rendering. * Get the alpha value for rendering.
@@ -218,7 +214,7 @@ Tile.prototype.load = function() {};
* @param {number} time The render frame time. * @param {number} time The render frame time.
* @return {number} A number between 0 and 1. * @return {number} A number between 0 and 1.
*/ */
Tile.prototype.getAlpha = function(id, time) { getAlpha(id, time) {
if (!this.transition_) { if (!this.transition_) {
return 1; return 1;
} }
@@ -236,7 +232,7 @@ Tile.prototype.getAlpha = function(id, time) {
return 1; return 1;
} }
return easeIn(delta / this.transition_); return easeIn(delta / this.transition_);
}; }
/** /**
* Determine if a tile is in an alpha transition. A tile is considered in * Determine if a tile is in an alpha transition. A tile is considered in
@@ -245,20 +241,23 @@ Tile.prototype.getAlpha = function(id, time) {
* @param {number} id An id for the renderer. * @param {number} id An id for the renderer.
* @return {boolean} The tile is in transition. * @return {boolean} The tile is in transition.
*/ */
Tile.prototype.inTransition = function(id) { inTransition(id) {
if (!this.transition_) { if (!this.transition_) {
return false; return false;
} }
return this.transitionStarts_[id] !== -1; return this.transitionStarts_[id] !== -1;
}; }
/** /**
* Mark a transition as complete. * Mark a transition as complete.
* @param {number} id An id for the renderer. * @param {number} id An id for the renderer.
*/ */
Tile.prototype.endTransition = function(id) { endTransition(id) {
if (this.transition_) { if (this.transition_) {
this.transitionStarts_[id] = -1; this.transitionStarts_[id] = -1;
} }
}; }
}
export default Tile; export default Tile;

View File

@@ -1,29 +1,24 @@
/** /**
* @module ol/TileCache * @module ol/TileCache
*/ */
import {inherits} from './util.js';
import LRUCache from './structs/LRUCache.js'; import LRUCache from './structs/LRUCache.js';
import {fromKey, getKey} from './tilecoord.js'; import {fromKey, getKey} from './tilecoord.js';
class TileCache extends LRUCache {
/** /**
* @constructor
* @extends {module:ol/structs/LRUCache.<module:ol/Tile>}
* @param {number=} opt_highWaterMark High water mark. * @param {number=} opt_highWaterMark High water mark.
* @struct
*/ */
const TileCache = function(opt_highWaterMark) { constructor(opt_highWaterMark) {
LRUCache.call(this, opt_highWaterMark); super(opt_highWaterMark);
};
inherits(TileCache, LRUCache);
}
/** /**
* @param {!Object.<string, module:ol/TileRange>} usedTiles Used tiles. * @param {!Object.<string, module:ol/TileRange>} usedTiles Used tiles.
*/ */
TileCache.prototype.expireCache = function(usedTiles) { expireCache(usedTiles) {
while (this.canExpireCache()) { while (this.canExpireCache()) {
const tile = this.peekLast(); const tile = this.peekLast();
const zKey = tile.tileCoord[0].toString(); const zKey = tile.tileCoord[0].toString();
@@ -33,13 +28,12 @@ TileCache.prototype.expireCache = function(usedTiles) {
this.pop().dispose(); this.pop().dispose();
} }
} }
}; }
/** /**
* Prune all tiles from the cache that don't have the same z as the newest tile. * Prune all tiles from the cache that don't have the same z as the newest tile.
*/ */
TileCache.prototype.pruneExceptNewestZ = function() { pruneExceptNewestZ() {
if (this.getCount() === 0) { if (this.getCount() === 0) {
return; return;
} }
@@ -52,5 +46,8 @@ TileCache.prototype.pruneExceptNewestZ = function() {
tile.dispose(); tile.dispose();
} }
}, this); }, this);
}; }
}
export default TileCache; export default TileCache;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/TileQueue * @module ol/TileQueue
*/ */
import {inherits} from './util.js';
import TileState from './TileState.js'; import TileState from './TileState.js';
import {listen, unlisten} from './events.js'; import {listen, unlisten} from './events.js';
import EventType from './events/EventType.js'; import EventType from './events/EventType.js';
@@ -13,19 +12,15 @@ import PriorityQueue from './structs/PriorityQueue.js';
*/ */
/** class TileQueue extends PriorityQueue {
* @constructor
* @extends {module:ol/structs/PriorityQueue.<Array>}
* @param {module:ol/TileQueue~PriorityFunction} tilePriorityFunction
* Tile priority function.
* @param {function(): ?} tileChangeCallback
* Function called on each tile change event.
* @struct
*/
const TileQueue = function(tilePriorityFunction, tileChangeCallback) {
PriorityQueue.call( /**
this, * @param {module:ol/TileQueue~PriorityFunction} tilePriorityFunction Tile priority function.
* @param {function(): ?} tileChangeCallback Function called on each tile change event.
*/
constructor(tilePriorityFunction, tileChangeCallback) {
super(
/** /**
* @param {Array} element Element. * @param {Array} element Element.
* @return {number} Priority. * @return {number} Priority.
@@ -59,37 +54,32 @@ const TileQueue = function(tilePriorityFunction, tileChangeCallback) {
*/ */
this.tilesLoadingKeys_ = {}; this.tilesLoadingKeys_ = {};
}; }
inherits(TileQueue, PriorityQueue);
/** /**
* @inheritDoc * @inheritDoc
*/ */
TileQueue.prototype.enqueue = function(element) { enqueue(element) {
const added = PriorityQueue.prototype.enqueue.call(this, element); const added = super.enqueue(element);
if (added) { if (added) {
const tile = element[0]; const tile = element[0];
listen(tile, EventType.CHANGE, this.handleTileChange, this); listen(tile, EventType.CHANGE, this.handleTileChange, this);
} }
return added; return added;
}; }
/** /**
* @return {number} Number of tiles loading. * @return {number} Number of tiles loading.
*/ */
TileQueue.prototype.getTilesLoading = function() { getTilesLoading() {
return this.tilesLoading_; return this.tilesLoading_;
}; }
/** /**
* @param {module:ol/events/Event} event Event. * @param {module:ol/events/Event} event Event.
* @protected * @protected
*/ */
TileQueue.prototype.handleTileChange = function(event) { handleTileChange(event) {
const tile = /** @type {module:ol/Tile} */ (event.target); const tile = /** @type {module:ol/Tile} */ (event.target);
const state = tile.getState(); const state = tile.getState();
if (state === TileState.LOADED || state === TileState.ERROR || if (state === TileState.LOADED || state === TileState.ERROR ||
@@ -102,14 +92,13 @@ TileQueue.prototype.handleTileChange = function(event) {
} }
this.tileChangeCallback_(); this.tileChangeCallback_();
} }
}; }
/** /**
* @param {number} maxTotalLoading Maximum number tiles to load simultaneously. * @param {number} maxTotalLoading Maximum number tiles to load simultaneously.
* @param {number} maxNewLoads Maximum number of new tiles to load. * @param {number} maxNewLoads Maximum number of new tiles to load.
*/ */
TileQueue.prototype.loadMoreTiles = function(maxTotalLoading, maxNewLoads) { loadMoreTiles(maxTotalLoading, maxNewLoads) {
let newLoads = 0; let newLoads = 0;
let abortedTiles = false; let abortedTiles = false;
let state, tile, tileKey; let state, tile, tileKey;
@@ -132,5 +121,8 @@ TileQueue.prototype.loadMoreTiles = function(maxTotalLoading, maxNewLoads) {
// a small, saturated tile cache. // a small, saturated tile cache.
this.tileChangeCallback_(); this.tileChangeCallback_();
} }
}; }
}
export default TileQueue; export default TileQueue;

View File

@@ -1,18 +1,20 @@
/** /**
* @module ol/TileRange * @module ol/TileRange
*/ */
/** /**
* A representation of a contiguous block of tiles. A tile range is specified * A representation of a contiguous block of tiles. A tile range is specified
* by its min/max tile coordinates and is inclusive of coordinates. * by its min/max tile coordinates and is inclusive of coordinates.
* */
* @constructor class TileRange {
/**
* @param {number} minX Minimum X. * @param {number} minX Minimum X.
* @param {number} maxX Maximum X. * @param {number} maxX Maximum X.
* @param {number} minY Minimum Y. * @param {number} minY Minimum Y.
* @param {number} maxY Maximum Y. * @param {number} maxY Maximum Y.
* @struct
*/ */
const TileRange = function(minX, maxX, minY, maxY) { constructor(minX, maxX, minY, maxY) {
/** /**
* @type {number} * @type {number}
@@ -34,7 +36,93 @@ const TileRange = function(minX, maxX, minY, maxY) {
*/ */
this.maxY = maxY; this.maxY = maxY;
}; }
/**
* @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.
* @return {boolean} Contains tile coordinate.
*/
contains(tileCoord) {
return this.containsXY(tileCoord[1], tileCoord[2]);
}
/**
* @param {module:ol/TileRange} tileRange Tile range.
* @return {boolean} Contains.
*/
containsTileRange(tileRange) {
return this.minX <= tileRange.minX && tileRange.maxX <= this.maxX &&
this.minY <= tileRange.minY && tileRange.maxY <= this.maxY;
}
/**
* @param {number} x Tile coordinate x.
* @param {number} y Tile coordinate y.
* @return {boolean} Contains coordinate.
*/
containsXY(x, y) {
return this.minX <= x && x <= this.maxX && this.minY <= y && y <= this.maxY;
}
/**
* @param {module:ol/TileRange} tileRange Tile range.
* @return {boolean} Equals.
*/
equals(tileRange) {
return this.minX == tileRange.minX && this.minY == tileRange.minY &&
this.maxX == tileRange.maxX && this.maxY == tileRange.maxY;
}
/**
* @param {module:ol/TileRange} tileRange Tile range.
*/
extend(tileRange) {
if (tileRange.minX < this.minX) {
this.minX = tileRange.minX;
}
if (tileRange.maxX > this.maxX) {
this.maxX = tileRange.maxX;
}
if (tileRange.minY < this.minY) {
this.minY = tileRange.minY;
}
if (tileRange.maxY > this.maxY) {
this.maxY = tileRange.maxY;
}
}
/**
* @return {number} Height.
*/
getHeight() {
return this.maxY - this.minY + 1;
}
/**
* @return {module:ol/size~Size} Size.
*/
getSize() {
return [this.getWidth(), this.getHeight()];
}
/**
* @return {number} Width.
*/
getWidth() {
return this.maxX - this.minX + 1;
}
/**
* @param {module:ol/TileRange} tileRange Tile range.
* @return {boolean} Intersects.
*/
intersects(tileRange) {
return this.minX <= tileRange.maxX &&
this.maxX >= tileRange.minX &&
this.minY <= tileRange.maxY &&
this.maxY >= tileRange.minY;
}
}
/** /**
@@ -58,96 +146,4 @@ export function createOrUpdate(minX, maxX, minY, maxY, tileRange) {
} }
/**
* @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.
* @return {boolean} Contains tile coordinate.
*/
TileRange.prototype.contains = function(tileCoord) {
return this.containsXY(tileCoord[1], tileCoord[2]);
};
/**
* @param {module:ol/TileRange} tileRange Tile range.
* @return {boolean} Contains.
*/
TileRange.prototype.containsTileRange = function(tileRange) {
return this.minX <= tileRange.minX && tileRange.maxX <= this.maxX &&
this.minY <= tileRange.minY && tileRange.maxY <= this.maxY;
};
/**
* @param {number} x Tile coordinate x.
* @param {number} y Tile coordinate y.
* @return {boolean} Contains coordinate.
*/
TileRange.prototype.containsXY = function(x, y) {
return this.minX <= x && x <= this.maxX && this.minY <= y && y <= this.maxY;
};
/**
* @param {module:ol/TileRange} tileRange Tile range.
* @return {boolean} Equals.
*/
TileRange.prototype.equals = function(tileRange) {
return this.minX == tileRange.minX && this.minY == tileRange.minY &&
this.maxX == tileRange.maxX && this.maxY == tileRange.maxY;
};
/**
* @param {module:ol/TileRange} tileRange Tile range.
*/
TileRange.prototype.extend = function(tileRange) {
if (tileRange.minX < this.minX) {
this.minX = tileRange.minX;
}
if (tileRange.maxX > this.maxX) {
this.maxX = tileRange.maxX;
}
if (tileRange.minY < this.minY) {
this.minY = tileRange.minY;
}
if (tileRange.maxY > this.maxY) {
this.maxY = tileRange.maxY;
}
};
/**
* @return {number} Height.
*/
TileRange.prototype.getHeight = function() {
return this.maxY - this.minY + 1;
};
/**
* @return {module:ol/size~Size} Size.
*/
TileRange.prototype.getSize = function() {
return [this.getWidth(), this.getHeight()];
};
/**
* @return {number} Width.
*/
TileRange.prototype.getWidth = function() {
return this.maxX - this.minX + 1;
};
/**
* @param {module:ol/TileRange} tileRange Tile range.
* @return {boolean} Intersects.
*/
TileRange.prototype.intersects = function(tileRange) {
return this.minX <= tileRange.maxX &&
this.maxX >= tileRange.minX &&
this.minY <= tileRange.maxY &&
this.maxY >= tileRange.minY;
};
export default TileRange; export default TileRange;

View File

@@ -1,7 +1,7 @@
/** /**
* @module ol/VectorImageTile * @module ol/VectorImageTile
*/ */
import {getUid, inherits} from './util.js'; import {getUid} from './util.js';
import Tile from './Tile.js'; import Tile from './Tile.js';
import TileState from './TileState.js'; import TileState from './TileState.js';
import {createCanvasContext2D} from './dom.js'; import {createCanvasContext2D} from './dom.js';
@@ -21,9 +21,9 @@ import {UNDEFINED} from './functions.js';
*/ */
class VectorImageTile extends Tile {
/** /**
* @constructor
* @extends {module:ol/Tile}
* @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate. * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.
* @param {module:ol/TileState} state State. * @param {module:ol/TileState} state State.
* @param {number} sourceRevision Source revision. * @param {number} sourceRevision Source revision.
@@ -43,11 +43,11 @@ import {UNDEFINED} from './functions.js';
* Function to call when a source tile's state changes. * Function to call when a source tile's state changes.
* @param {number} zoom Integer zoom to render the tile for. * @param {number} zoom Integer zoom to render the tile for.
*/ */
const VectorImageTile = function(tileCoord, state, sourceRevision, format, constructor(tileCoord, state, sourceRevision, format, tileLoadFunction,
tileLoadFunction, urlTileCoord, tileUrlFunction, sourceTileGrid, tileGrid, urlTileCoord, tileUrlFunction, sourceTileGrid, tileGrid, sourceTiles,
sourceTiles, pixelRatio, projection, tileClass, handleTileChange, zoom) { pixelRatio, projection, tileClass, handleTileChange, zoom) {
Tile.call(this, tileCoord, state, {transition: 0}); super(tileCoord, state, {transition: 0});
/** /**
* @private * @private
@@ -157,15 +157,12 @@ const VectorImageTile = function(tileCoord, state, sourceRevision, format,
} }
} }
}; }
inherits(VectorImageTile, Tile);
/** /**
* @inheritDoc * @inheritDoc
*/ */
VectorImageTile.prototype.disposeInternal = function() { disposeInternal() {
this.state = TileState.ABORT; this.state = TileState.ABORT;
this.changed(); this.changed();
if (this.interimTile) { if (this.interimTile) {
@@ -187,39 +184,36 @@ VectorImageTile.prototype.disposeInternal = function() {
this.loadListenerKeys_.length = 0; this.loadListenerKeys_.length = 0;
this.sourceTileListenerKeys_.forEach(unlistenByKey); this.sourceTileListenerKeys_.forEach(unlistenByKey);
this.sourceTileListenerKeys_.length = 0; this.sourceTileListenerKeys_.length = 0;
Tile.prototype.disposeInternal.call(this); super.disposeInternal();
}; }
/** /**
* @param {module:ol/layer/Layer} layer Layer. * @param {module:ol/layer/Layer} layer Layer.
* @return {CanvasRenderingContext2D} The rendering context. * @return {CanvasRenderingContext2D} The rendering context.
*/ */
VectorImageTile.prototype.getContext = function(layer) { getContext(layer) {
const key = getUid(layer).toString(); const key = getUid(layer).toString();
if (!(key in this.context_)) { if (!(key in this.context_)) {
this.context_[key] = createCanvasContext2D(); this.context_[key] = createCanvasContext2D();
} }
return this.context_[key]; return this.context_[key];
}; }
/** /**
* Get the Canvas for this tile. * Get the Canvas for this tile.
* @param {module:ol/layer/Layer} layer Layer. * @param {module:ol/layer/Layer} layer Layer.
* @return {HTMLCanvasElement} Canvas. * @return {HTMLCanvasElement} Canvas.
*/ */
VectorImageTile.prototype.getImage = function(layer) { getImage(layer) {
return this.getReplayState(layer).renderedTileRevision == -1 ? return this.getReplayState(layer).renderedTileRevision == -1 ?
null : this.getContext(layer).canvas; null : this.getContext(layer).canvas;
}; }
/** /**
* @param {module:ol/layer/Layer} layer Layer. * @param {module:ol/layer/Layer} layer Layer.
* @return {module:ol/VectorImageTile~ReplayState} The replay state. * @return {module:ol/VectorImageTile~ReplayState} The replay state.
*/ */
VectorImageTile.prototype.getReplayState = function(layer) { getReplayState(layer) {
const key = getUid(layer).toString(); const key = getUid(layer).toString();
if (!(key in this.replayState_)) { if (!(key in this.replayState_)) {
this.replayState_[key] = { this.replayState_[key] = {
@@ -230,30 +224,27 @@ VectorImageTile.prototype.getReplayState = function(layer) {
}; };
} }
return this.replayState_[key]; return this.replayState_[key];
}; }
/** /**
* @inheritDoc * @inheritDoc
*/ */
VectorImageTile.prototype.getKey = function() { getKey() {
return this.tileKeys.join('/') + '-' + this.sourceRevision_; return this.tileKeys.join('/') + '-' + this.sourceRevision_;
}; }
/** /**
* @param {string} tileKey Key (tileCoord) of the source tile. * @param {string} tileKey Key (tileCoord) of the source tile.
* @return {module:ol/VectorTile} Source tile. * @return {module:ol/VectorTile} Source tile.
*/ */
VectorImageTile.prototype.getTile = function(tileKey) { getTile(tileKey) {
return this.sourceTiles_[tileKey]; return this.sourceTiles_[tileKey];
}; }
/** /**
* @inheritDoc * @inheritDoc
*/ */
VectorImageTile.prototype.load = function() { load() {
// Source tiles with LOADED state - we just count them because once they are // Source tiles with LOADED state - we just count them because once they are
// loaded, we're no longer listening to state changes. // loaded, we're no longer listening to state changes.
let leftToLoad = 0; let leftToLoad = 0;
@@ -296,13 +287,12 @@ VectorImageTile.prototype.load = function() {
if (leftToLoad - Object.keys(errorSourceTiles).length == 0) { if (leftToLoad - Object.keys(errorSourceTiles).length == 0) {
setTimeout(this.finishLoading_.bind(this), 0); setTimeout(this.finishLoading_.bind(this), 0);
} }
}; }
/** /**
* @private * @private
*/ */
VectorImageTile.prototype.finishLoading_ = function() { finishLoading_() {
let loaded = this.tileKeys.length; let loaded = this.tileKeys.length;
let empty = 0; let empty = 0;
for (let i = loaded - 1; i >= 0; --i) { for (let i = loaded - 1; i >= 0; --i) {
@@ -321,7 +311,9 @@ VectorImageTile.prototype.finishLoading_ = function() {
} else { } else {
this.setState(empty == this.tileKeys.length ? TileState.EMPTY : TileState.ERROR); this.setState(empty == this.tileKeys.length ? TileState.EMPTY : TileState.ERROR);
} }
}; }
}
export default VectorImageTile; export default VectorImageTile;

View File

@@ -1,19 +1,26 @@
/** /**
* @module ol/VectorTile * @module ol/VectorTile
*/ */
import {getUid, inherits} from './util.js'; import {getUid} from './util.js';
import Tile from './Tile.js'; import Tile from './Tile.js';
import TileState from './TileState.js'; import TileState from './TileState.js';
/**
* @const
* @type {module:ol/extent~Extent}
*/
const DEFAULT_EXTENT = [0, 0, 4096, 4096];
/** /**
* @typedef {function(new: module:ol/VectorTile, module:ol/tilecoord~TileCoord, * @typedef {function(new: module:ol/VectorTile, module:ol/tilecoord~TileCoord,
* module:ol/TileState, string, ?string, module:ol/Tile~LoadFunction)} TileClass * module:ol/TileState, string, ?string, module:ol/Tile~LoadFunction)} TileClass
* @api * @api
*/ */
class VectorTile extends Tile {
/** /**
* @constructor
* @extends {module:ol/Tile}
* @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate. * @param {module:ol/tilecoord~TileCoord} tileCoord Tile coordinate.
* @param {module:ol/TileState} state State. * @param {module:ol/TileState} state State.
* @param {string} src Data source url. * @param {string} src Data source url.
@@ -21,9 +28,9 @@ import TileState from './TileState.js';
* @param {module:ol/Tile~LoadFunction} tileLoadFunction Tile load function. * @param {module:ol/Tile~LoadFunction} tileLoadFunction Tile load function.
* @param {module:ol/Tile~Options=} opt_options Tile options. * @param {module:ol/Tile~Options=} opt_options Tile options.
*/ */
const VectorTile = function(tileCoord, state, src, format, tileLoadFunction, opt_options) { constructor(tileCoord, state, src, format, tileLoadFunction, opt_options) {
Tile.call(this, tileCoord, state, opt_options); super(tileCoord, state, opt_options);
/** /**
* @type {number} * @type {number}
@@ -79,48 +86,36 @@ const VectorTile = function(tileCoord, state, src, format, tileLoadFunction, opt
*/ */
this.url_ = src; this.url_ = src;
}; }
inherits(VectorTile, Tile);
/**
* @const
* @type {module:ol/extent~Extent}
*/
const DEFAULT_EXTENT = [0, 0, 4096, 4096];
/** /**
* @inheritDoc * @inheritDoc
*/ */
VectorTile.prototype.disposeInternal = function() { disposeInternal() {
this.features_ = null; this.features_ = null;
this.replayGroups_ = {}; this.replayGroups_ = {};
this.state = TileState.ABORT; this.state = TileState.ABORT;
this.changed(); this.changed();
Tile.prototype.disposeInternal.call(this); super.disposeInternal();
}; }
/** /**
* Gets the extent of the vector tile. * Gets the extent of the vector tile.
* @return {module:ol/extent~Extent} The extent. * @return {module:ol/extent~Extent} The extent.
* @api * @api
*/ */
VectorTile.prototype.getExtent = function() { getExtent() {
return this.extent_ || DEFAULT_EXTENT; return this.extent_ || DEFAULT_EXTENT;
}; }
/** /**
* Get the feature format assigned for reading this tile's features. * Get the feature format assigned for reading this tile's features.
* @return {module:ol/format/Feature} Feature format. * @return {module:ol/format/Feature} Feature format.
* @api * @api
*/ */
VectorTile.prototype.getFormat = function() { getFormat() {
return this.format_; return this.format_;
}; }
/** /**
* Get the features for this tile. Geometries will be in the projection returned * Get the features for this tile. Geometries will be in the projection returned
@@ -128,18 +123,16 @@ VectorTile.prototype.getFormat = function() {
* @return {Array.<module:ol/Feature|module:ol/render/Feature>} Features. * @return {Array.<module:ol/Feature|module:ol/render/Feature>} Features.
* @api * @api
*/ */
VectorTile.prototype.getFeatures = function() { getFeatures() {
return this.features_; return this.features_;
}; }
/** /**
* @inheritDoc * @inheritDoc
*/ */
VectorTile.prototype.getKey = function() { getKey() {
return this.url_; return this.url_;
}; }
/** /**
* Get the feature projection of features returned by * Get the feature projection of features returned by
@@ -147,32 +140,29 @@ VectorTile.prototype.getKey = function() {
* @return {module:ol/proj/Projection} Feature projection. * @return {module:ol/proj/Projection} Feature projection.
* @api * @api
*/ */
VectorTile.prototype.getProjection = function() { getProjection() {
return this.projection_; return this.projection_;
}; }
/** /**
* @param {module:ol/layer/Layer} layer Layer. * @param {module:ol/layer/Layer} layer Layer.
* @param {string} key Key. * @param {string} key Key.
* @return {module:ol/render/ReplayGroup} Replay group. * @return {module:ol/render/ReplayGroup} Replay group.
*/ */
VectorTile.prototype.getReplayGroup = function(layer, key) { getReplayGroup(layer, key) {
return this.replayGroups_[getUid(layer) + ',' + key]; return this.replayGroups_[getUid(layer) + ',' + key];
}; }
/** /**
* @inheritDoc * @inheritDoc
*/ */
VectorTile.prototype.load = function() { load() {
if (this.state == TileState.IDLE) { if (this.state == TileState.IDLE) {
this.setState(TileState.LOADING); this.setState(TileState.LOADING);
this.tileLoadFunction_(this, this.url_); this.tileLoadFunction_(this, this.url_);
this.loader_(null, NaN, null); this.loader_(null, NaN, null);
} }
}; }
/** /**
* Handler for successful tile load. * Handler for successful tile load.
@@ -180,20 +170,18 @@ VectorTile.prototype.load = function() {
* @param {module:ol/proj/Projection} dataProjection Data projection. * @param {module:ol/proj/Projection} dataProjection Data projection.
* @param {module:ol/extent~Extent} extent Extent. * @param {module:ol/extent~Extent} extent Extent.
*/ */
VectorTile.prototype.onLoad = function(features, dataProjection, extent) { onLoad(features, dataProjection, extent) {
this.setProjection(dataProjection); this.setProjection(dataProjection);
this.setFeatures(features); this.setFeatures(features);
this.setExtent(extent); this.setExtent(extent);
}; }
/** /**
* Handler for tile load errors. * Handler for tile load errors.
*/ */
VectorTile.prototype.onError = function() { onError() {
this.setState(TileState.ERROR); this.setState(TileState.ERROR);
}; }
/** /**
* Function for use in an {@link module:ol/source/VectorTile~VectorTile}'s * Function for use in an {@link module:ol/source/VectorTile~VectorTile}'s
@@ -207,10 +195,9 @@ VectorTile.prototype.onError = function() {
* @param {module:ol/extent~Extent} extent The extent. * @param {module:ol/extent~Extent} extent The extent.
* @api * @api
*/ */
VectorTile.prototype.setExtent = function(extent) { setExtent(extent) {
this.extent_ = extent; this.extent_ = extent;
}; }
/** /**
* Function for use in an {@link module:ol/source/VectorTile~VectorTile}'s `tileLoadFunction`. * Function for use in an {@link module:ol/source/VectorTile~VectorTile}'s `tileLoadFunction`.
@@ -218,11 +205,10 @@ VectorTile.prototype.setExtent = function(extent) {
* @param {Array.<module:ol/Feature>} features Features. * @param {Array.<module:ol/Feature>} features Features.
* @api * @api
*/ */
VectorTile.prototype.setFeatures = function(features) { setFeatures(features) {
this.features_ = features; this.features_ = features;
this.setState(TileState.LOADED); this.setState(TileState.LOADED);
}; }
/** /**
* Function for use in an {@link module:ol/source/VectorTile~VectorTile}'s `tileLoadFunction`. * Function for use in an {@link module:ol/source/VectorTile~VectorTile}'s `tileLoadFunction`.
@@ -231,28 +217,27 @@ VectorTile.prototype.setFeatures = function(features) {
* @param {module:ol/proj/Projection} projection Feature projection. * @param {module:ol/proj/Projection} projection Feature projection.
* @api * @api
*/ */
VectorTile.prototype.setProjection = function(projection) { setProjection(projection) {
this.projection_ = projection; this.projection_ = projection;
}; }
/** /**
* @param {module:ol/layer/Layer} layer Layer. * @param {module:ol/layer/Layer} layer Layer.
* @param {string} key Key. * @param {string} key Key.
* @param {module:ol/render/ReplayGroup} replayGroup Replay group. * @param {module:ol/render/ReplayGroup} replayGroup Replay group.
*/ */
VectorTile.prototype.setReplayGroup = function(layer, key, replayGroup) { setReplayGroup(layer, key, replayGroup) {
this.replayGroups_[getUid(layer) + ',' + key] = replayGroup; this.replayGroups_[getUid(layer) + ',' + key] = replayGroup;
}; }
/** /**
* Set the feature loader for reading this tile's features. * Set the feature loader for reading this tile's features.
* @param {module:ol/featureloader~FeatureLoader} loader Feature loader. * @param {module:ol/featureloader~FeatureLoader} loader Feature loader.
* @api * @api
*/ */
VectorTile.prototype.setLoader = function(loader) { setLoader(loader) {
this.loader_ = loader; this.loader_ = loader;
}; }
}
export default VectorTile; export default VectorTile;

View File

@@ -2,7 +2,7 @@
* @module ol/View * @module ol/View
*/ */
import {DEFAULT_TILE_SIZE} from './tilegrid/common.js'; import {DEFAULT_TILE_SIZE} from './tilegrid/common.js';
import {getUid, inherits} from './util.js'; import {getUid} from './util.js';
import {UNDEFINED} from './functions.js'; import {UNDEFINED} from './functions.js';
import {createExtent, none as centerNone} from './centerconstraint.js'; import {createExtent, none as centerNone} from './centerconstraint.js';
import BaseObject from './Object.js'; import BaseObject from './Object.js';
@@ -33,7 +33,7 @@ import Units from './proj/Units.js';
* @property {number} [sourceResolution] * @property {number} [sourceResolution]
* @property {number} [targetResolution] * @property {number} [targetResolution]
* @property {number} [sourceRotation] * @property {number} [sourceRotation]
* @property {number} [sourceRotation] * @property {number} [targetRotation]
* @property {module:ol/coordinate~Coordinate} [anchor] * @property {module:ol/coordinate~Coordinate} [anchor]
* @property {number} start * @property {number} start
* @property {number} duration * @property {number} duration
@@ -224,13 +224,15 @@ const DEFAULT_MIN_ZOOM = 0;
* The *center constraint* is determined by the `extent` option. By * The *center constraint* is determined by the `extent` option. By
* default the center is not constrained at all. * default the center is not constrained at all.
* *
* @constructor
* @extends {module:ol/Object}
* @param {module:ol/View~ViewOptions=} opt_options View options.
* @api * @api
*/ */
const View = function(opt_options) { class View extends BaseObject {
BaseObject.call(this);
/**
* @param {module:ol/View~ViewOptions=} opt_options View options.
*/
constructor(opt_options) {
super();
const options = assign({}, opt_options); const options = assign({}, opt_options);
@@ -262,16 +264,13 @@ const View = function(opt_options) {
this.projection_ = createProjection(options.projection, 'EPSG:3857'); this.projection_ = createProjection(options.projection, 'EPSG:3857');
this.applyOptions_(options); this.applyOptions_(options);
}; }
inherits(View, BaseObject);
/** /**
* Set up the view with the given options. * Set up the view with the given options.
* @param {module:ol/View~ViewOptions} options View options. * @param {module:ol/View~ViewOptions} options View options.
*/ */
View.prototype.applyOptions_ = function(options) { applyOptions_(options) {
/** /**
* @type {Object.<string, *>} * @type {Object.<string, *>}
@@ -347,7 +346,7 @@ View.prototype.applyOptions_ = function(options) {
*/ */
this.options_ = options; this.options_ = options;
}; }
/** /**
* Get an updated version of the view options used to construct the view. The * Get an updated version of the view options used to construct the view. The
@@ -357,7 +356,7 @@ View.prototype.applyOptions_ = function(options) {
* @param {module:ol/View~ViewOptions} newOptions New options to be applied. * @param {module:ol/View~ViewOptions} newOptions New options to be applied.
* @return {module:ol/View~ViewOptions} New options updated with the current view state. * @return {module:ol/View~ViewOptions} New options updated with the current view state.
*/ */
View.prototype.getUpdatedOptions_ = function(newOptions) { getUpdatedOptions_(newOptions) {
const options = assign({}, this.options_); const options = assign({}, this.options_);
// preserve resolution (or zoom) // preserve resolution (or zoom)
@@ -374,8 +373,7 @@ View.prototype.getUpdatedOptions_ = function(newOptions) {
options.rotation = this.getRotation(); options.rotation = this.getRotation();
return assign({}, options, newOptions); return assign({}, options, newOptions);
}; }
/** /**
* Animate the view. The view's center, zoom (or resolution), and rotation * Animate the view. The view's center, zoom (or resolution), and rotation
@@ -410,7 +408,7 @@ View.prototype.getUpdatedOptions_ = function(newOptions) {
* the animation completed without being cancelled. * the animation completed without being cancelled.
* @api * @api
*/ */
View.prototype.animate = function(var_args) { animate(var_args) {
let animationCount = arguments.length; let animationCount = arguments.length;
let callback; let callback;
if (animationCount > 1 && typeof arguments[animationCount - 1] === 'function') { if (animationCount > 1 && typeof arguments[animationCount - 1] === 'function') {
@@ -490,34 +488,31 @@ View.prototype.animate = function(var_args) {
this.animations_.push(series); this.animations_.push(series);
this.setHint(ViewHint.ANIMATING, 1); this.setHint(ViewHint.ANIMATING, 1);
this.updateAnimations_(); this.updateAnimations_();
}; }
/** /**
* Determine if the view is being animated. * Determine if the view is being animated.
* @return {boolean} The view is being animated. * @return {boolean} The view is being animated.
* @api * @api
*/ */
View.prototype.getAnimating = function() { getAnimating() {
return this.hints_[ViewHint.ANIMATING] > 0; return this.hints_[ViewHint.ANIMATING] > 0;
}; }
/** /**
* Determine if the user is interacting with the view, such as panning or zooming. * Determine if the user is interacting with the view, such as panning or zooming.
* @return {boolean} The view is being interacted with. * @return {boolean} The view is being interacted with.
* @api * @api
*/ */
View.prototype.getInteracting = function() { getInteracting() {
return this.hints_[ViewHint.INTERACTING] > 0; return this.hints_[ViewHint.INTERACTING] > 0;
}; }
/** /**
* Cancel any ongoing animations. * Cancel any ongoing animations.
* @api * @api
*/ */
View.prototype.cancelAnimations = function() { cancelAnimations() {
this.setHint(ViewHint.ANIMATING, -this.hints_[ViewHint.ANIMATING]); this.setHint(ViewHint.ANIMATING, -this.hints_[ViewHint.ANIMATING]);
for (let i = 0, ii = this.animations_.length; i < ii; ++i) { for (let i = 0, ii = this.animations_.length; i < ii; ++i) {
const series = this.animations_[i]; const series = this.animations_[i];
@@ -526,12 +521,12 @@ View.prototype.cancelAnimations = function() {
} }
} }
this.animations_.length = 0; this.animations_.length = 0;
}; }
/** /**
* Update all animations. * Update all animations.
*/ */
View.prototype.updateAnimations_ = function() { updateAnimations_() {
if (this.updateAnimationKey_ !== undefined) { if (this.updateAnimationKey_ !== undefined) {
cancelAnimationFrame(this.updateAnimationKey_); cancelAnimationFrame(this.updateAnimationKey_);
this.updateAnimationKey_ = undefined; this.updateAnimationKey_ = undefined;
@@ -608,14 +603,14 @@ View.prototype.updateAnimations_ = function() {
if (more && this.updateAnimationKey_ === undefined) { if (more && this.updateAnimationKey_ === undefined) {
this.updateAnimationKey_ = requestAnimationFrame(this.updateAnimations_); this.updateAnimationKey_ = requestAnimationFrame(this.updateAnimations_);
} }
}; }
/** /**
* @param {number} rotation Target rotation. * @param {number} rotation Target rotation.
* @param {module:ol/coordinate~Coordinate} anchor Rotation anchor. * @param {module:ol/coordinate~Coordinate} anchor Rotation anchor.
* @return {module:ol/coordinate~Coordinate|undefined} Center for rotation and anchor. * @return {module:ol/coordinate~Coordinate|undefined} Center for rotation and anchor.
*/ */
View.prototype.calculateCenterRotate = function(rotation, anchor) { calculateCenterRotate(rotation, anchor) {
let center; let center;
const currentCenter = this.getCenter(); const currentCenter = this.getCenter();
if (currentCenter !== undefined) { if (currentCenter !== undefined) {
@@ -624,15 +619,14 @@ View.prototype.calculateCenterRotate = function(rotation, anchor) {
addCoordinate(center, anchor); addCoordinate(center, anchor);
} }
return center; return center;
}; }
/** /**
* @param {number} resolution Target resolution. * @param {number} resolution Target resolution.
* @param {module:ol/coordinate~Coordinate} anchor Zoom anchor. * @param {module:ol/coordinate~Coordinate} anchor Zoom anchor.
* @return {module:ol/coordinate~Coordinate|undefined} Center for resolution and anchor. * @return {module:ol/coordinate~Coordinate|undefined} Center for resolution and anchor.
*/ */
View.prototype.calculateCenterZoom = function(resolution, anchor) { calculateCenterZoom(resolution, anchor) {
let center; let center;
const currentCenter = this.getCenter(); const currentCenter = this.getCenter();
const currentResolution = this.getResolution(); const currentResolution = this.getResolution();
@@ -642,14 +636,13 @@ View.prototype.calculateCenterZoom = function(resolution, anchor) {
center = [x, y]; center = [x, y];
} }
return center; return center;
}; }
/** /**
* @private * @private
* @return {module:ol/size~Size} Viewport size or `[100, 100]` when no viewport is found. * @return {module:ol/size~Size} Viewport size or `[100, 100]` when no viewport is found.
*/ */
View.prototype.getSizeFromViewport_ = function() { getSizeFromViewport_() {
const size = [100, 100]; const size = [100, 100];
const selector = '.ol-viewport[data-view="' + getUid(this) + '"]'; const selector = '.ol-viewport[data-view="' + getUid(this) + '"]';
const element = document.querySelector(selector); const element = document.querySelector(selector);
@@ -659,8 +652,7 @@ View.prototype.getSizeFromViewport_ = function() {
size[1] = parseInt(metrics.height, 10); size[1] = parseInt(metrics.height, 10);
} }
return size; return size;
}; }
/** /**
* Get the constrained center of this view. * Get the constrained center of this view.
@@ -668,10 +660,9 @@ View.prototype.getSizeFromViewport_ = function() {
* @return {module:ol/coordinate~Coordinate|undefined} Constrained center. * @return {module:ol/coordinate~Coordinate|undefined} Constrained center.
* @api * @api
*/ */
View.prototype.constrainCenter = function(center) { constrainCenter(center) {
return this.constraints_.center(center); return this.constraints_.center(center);
}; }
/** /**
* Get the constrained resolution of this view. * Get the constrained resolution of this view.
@@ -681,12 +672,11 @@ View.prototype.constrainCenter = function(center) {
* @return {number|undefined} Constrained resolution. * @return {number|undefined} Constrained resolution.
* @api * @api
*/ */
View.prototype.constrainResolution = function(resolution, opt_delta, opt_direction) { constrainResolution(resolution, opt_delta, opt_direction) {
const delta = opt_delta || 0; const delta = opt_delta || 0;
const direction = opt_direction || 0; const direction = opt_direction || 0;
return this.constraints_.resolution(resolution, delta, direction); return this.constraints_.resolution(resolution, delta, direction);
}; }
/** /**
* Get the constrained rotation of this view. * Get the constrained rotation of this view.
@@ -695,11 +685,10 @@ View.prototype.constrainResolution = function(resolution, opt_delta, opt_directi
* @return {number|undefined} Constrained rotation. * @return {number|undefined} Constrained rotation.
* @api * @api
*/ */
View.prototype.constrainRotation = function(rotation, opt_delta) { constrainRotation(rotation, opt_delta) {
const delta = opt_delta || 0; const delta = opt_delta || 0;
return this.constraints_.rotation(rotation, delta); return this.constraints_.rotation(rotation, delta);
}; }
/** /**
* Get the view center. * Get the view center.
@@ -707,26 +696,24 @@ View.prototype.constrainRotation = function(rotation, opt_delta) {
* @observable * @observable
* @api * @api
*/ */
View.prototype.getCenter = function() { getCenter() {
return ( return (
/** @type {module:ol/coordinate~Coordinate|undefined} */ (this.get(ViewProperty.CENTER)) /** @type {module:ol/coordinate~Coordinate|undefined} */ (this.get(ViewProperty.CENTER))
); );
}; }
/** /**
* @return {module:ol/View~Constraints} Constraints. * @return {module:ol/View~Constraints} Constraints.
*/ */
View.prototype.getConstraints = function() { getConstraints() {
return this.constraints_; return this.constraints_;
}; }
/** /**
* @param {Array.<number>=} opt_hints Destination array. * @param {Array.<number>=} opt_hints Destination array.
* @return {Array.<number>} Hint. * @return {Array.<number>} Hint.
*/ */
View.prototype.getHints = function(opt_hints) { getHints(opt_hints) {
if (opt_hints !== undefined) { if (opt_hints !== undefined) {
opt_hints[0] = this.hints_[0]; opt_hints[0] = this.hints_[0];
opt_hints[1] = this.hints_[1]; opt_hints[1] = this.hints_[1];
@@ -734,8 +721,7 @@ View.prototype.getHints = function(opt_hints) {
} else { } else {
return this.hints_.slice(); return this.hints_.slice();
} }
}; }
/** /**
* Calculate the extent for the current view state and the passed size. * Calculate the extent for the current view state and the passed size.
@@ -747,7 +733,7 @@ View.prototype.getHints = function(opt_hints) {
* @return {module:ol/extent~Extent} Extent. * @return {module:ol/extent~Extent} Extent.
* @api * @api
*/ */
View.prototype.calculateExtent = function(opt_size) { calculateExtent(opt_size) {
const size = opt_size || this.getSizeFromViewport_(); const size = opt_size || this.getSizeFromViewport_();
const center = /** @type {!module:ol/coordinate~Coordinate} */ (this.getCenter()); const center = /** @type {!module:ol/coordinate~Coordinate} */ (this.getCenter());
assert(center, 1); // The view center is not defined assert(center, 1); // The view center is not defined
@@ -757,78 +743,70 @@ View.prototype.calculateExtent = function(opt_size) {
assert(rotation !== undefined, 3); // The view rotation is not defined assert(rotation !== undefined, 3); // The view rotation is not defined
return getForViewAndSize(center, resolution, rotation, size); return getForViewAndSize(center, resolution, rotation, size);
}; }
/** /**
* Get the maximum resolution of the view. * Get the maximum resolution of the view.
* @return {number} The maximum resolution of the view. * @return {number} The maximum resolution of the view.
* @api * @api
*/ */
View.prototype.getMaxResolution = function() { getMaxResolution() {
return this.maxResolution_; return this.maxResolution_;
}; }
/** /**
* Get the minimum resolution of the view. * Get the minimum resolution of the view.
* @return {number} The minimum resolution of the view. * @return {number} The minimum resolution of the view.
* @api * @api
*/ */
View.prototype.getMinResolution = function() { getMinResolution() {
return this.minResolution_; return this.minResolution_;
}; }
/** /**
* Get the maximum zoom level for the view. * Get the maximum zoom level for the view.
* @return {number} The maximum zoom level. * @return {number} The maximum zoom level.
* @api * @api
*/ */
View.prototype.getMaxZoom = function() { getMaxZoom() {
return /** @type {number} */ (this.getZoomForResolution(this.minResolution_)); return /** @type {number} */ (this.getZoomForResolution(this.minResolution_));
}; }
/** /**
* Set a new maximum zoom level for the view. * Set a new maximum zoom level for the view.
* @param {number} zoom The maximum zoom level. * @param {number} zoom The maximum zoom level.
* @api * @api
*/ */
View.prototype.setMaxZoom = function(zoom) { setMaxZoom(zoom) {
this.applyOptions_(this.getUpdatedOptions_({maxZoom: zoom})); this.applyOptions_(this.getUpdatedOptions_({maxZoom: zoom}));
}; }
/** /**
* Get the minimum zoom level for the view. * Get the minimum zoom level for the view.
* @return {number} The minimum zoom level. * @return {number} The minimum zoom level.
* @api * @api
*/ */
View.prototype.getMinZoom = function() { getMinZoom() {
return /** @type {number} */ (this.getZoomForResolution(this.maxResolution_)); return /** @type {number} */ (this.getZoomForResolution(this.maxResolution_));
}; }
/** /**
* Set a new minimum zoom level for the view. * Set a new minimum zoom level for the view.
* @param {number} zoom The minimum zoom level. * @param {number} zoom The minimum zoom level.
* @api * @api
*/ */
View.prototype.setMinZoom = function(zoom) { setMinZoom(zoom) {
this.applyOptions_(this.getUpdatedOptions_({minZoom: zoom})); this.applyOptions_(this.getUpdatedOptions_({minZoom: zoom}));
}; }
/** /**
* Get the view projection. * Get the view projection.
* @return {module:ol/proj/Projection} The projection of the view. * @return {module:ol/proj/Projection} The projection of the view.
* @api * @api
*/ */
View.prototype.getProjection = function() { getProjection() {
return this.projection_; return this.projection_;
}; }
/** /**
* Get the view resolution. * Get the view resolution.
@@ -836,10 +814,9 @@ View.prototype.getProjection = function() {
* @observable * @observable
* @api * @api
*/ */
View.prototype.getResolution = function() { getResolution() {
return /** @type {number|undefined} */ (this.get(ViewProperty.RESOLUTION)); return /** @type {number|undefined} */ (this.get(ViewProperty.RESOLUTION));
}; }
/** /**
* Get the resolutions for the view. This returns the array of resolutions * Get the resolutions for the view. This returns the array of resolutions
@@ -847,10 +824,9 @@ View.prototype.getResolution = function() {
* @return {Array.<number>|undefined} The resolutions of the view. * @return {Array.<number>|undefined} The resolutions of the view.
* @api * @api
*/ */
View.prototype.getResolutions = function() { getResolutions() {
return this.resolutions_; return this.resolutions_;
}; }
/** /**
* Get the resolution for a provided extent (in map units) and size (in pixels). * Get the resolution for a provided extent (in map units) and size (in pixels).
@@ -860,13 +836,12 @@ View.prototype.getResolutions = function() {
* the given size. * the given size.
* @api * @api
*/ */
View.prototype.getResolutionForExtent = function(extent, opt_size) { getResolutionForExtent(extent, opt_size) {
const size = opt_size || this.getSizeFromViewport_(); const size = opt_size || this.getSizeFromViewport_();
const xResolution = getWidth(extent) / size[0]; const xResolution = getWidth(extent) / size[0];
const yResolution = getHeight(extent) / size[1]; const yResolution = getHeight(extent) / size[1];
return Math.max(xResolution, yResolution); return Math.max(xResolution, yResolution);
}; }
/** /**
* Return a function that returns a value between 0 and 1 for a * Return a function that returns a value between 0 and 1 for a
@@ -874,7 +849,7 @@ View.prototype.getResolutionForExtent = function(extent, opt_size) {
* @param {number=} opt_power Power. * @param {number=} opt_power Power.
* @return {function(number): number} Resolution for value function. * @return {function(number): number} Resolution for value function.
*/ */
View.prototype.getResolutionForValueFunction = function(opt_power) { getResolutionForValueFunction(opt_power) {
const power = opt_power || 2; const power = opt_power || 2;
const maxResolution = this.maxResolution_; const maxResolution = this.maxResolution_;
const minResolution = this.minResolution_; const minResolution = this.minResolution_;
@@ -888,8 +863,7 @@ View.prototype.getResolutionForValueFunction = function(opt_power) {
const resolution = maxResolution / Math.pow(power, value * max); const resolution = maxResolution / Math.pow(power, value * max);
return resolution; return resolution;
}); });
}; }
/** /**
* Get the view rotation. * Get the view rotation.
@@ -897,10 +871,9 @@ View.prototype.getResolutionForValueFunction = function(opt_power) {
* @observable * @observable
* @api * @api
*/ */
View.prototype.getRotation = function() { getRotation() {
return /** @type {number} */ (this.get(ViewProperty.ROTATION)); return /** @type {number} */ (this.get(ViewProperty.ROTATION));
}; }
/** /**
* Return a function that returns a resolution for a value between * Return a function that returns a resolution for a value between
@@ -908,7 +881,7 @@ View.prototype.getRotation = function() {
* @param {number=} opt_power Power. * @param {number=} opt_power Power.
* @return {function(number): number} Value for resolution function. * @return {function(number): number} Value for resolution function.
*/ */
View.prototype.getValueForResolutionFunction = function(opt_power) { getValueForResolutionFunction(opt_power) {
const power = opt_power || 2; const power = opt_power || 2;
const maxResolution = this.maxResolution_; const maxResolution = this.maxResolution_;
const minResolution = this.minResolution_; const minResolution = this.minResolution_;
@@ -922,13 +895,12 @@ View.prototype.getValueForResolutionFunction = function(opt_power) {
const value = (Math.log(maxResolution / resolution) / Math.log(power)) / max; const value = (Math.log(maxResolution / resolution) / Math.log(power)) / max;
return value; return value;
}); });
}; }
/** /**
* @return {module:ol/View~State} View state. * @return {module:ol/View~State} View state.
*/ */
View.prototype.getState = function() { getState() {
const center = /** @type {module:ol/coordinate~Coordinate} */ (this.getCenter()); const center = /** @type {module:ol/coordinate~Coordinate} */ (this.getCenter());
const projection = this.getProjection(); const projection = this.getProjection();
const resolution = /** @type {number} */ (this.getResolution()); const resolution = /** @type {number} */ (this.getResolution());
@@ -942,8 +914,7 @@ View.prototype.getState = function() {
zoom: this.getZoom() zoom: this.getZoom()
}) })
); );
}; }
/** /**
* Get the current zoom level. If you configured your view with a resolutions * Get the current zoom level. If you configured your view with a resolutions
@@ -952,15 +923,14 @@ View.prototype.getState = function() {
* @return {number|undefined} Zoom. * @return {number|undefined} Zoom.
* @api * @api
*/ */
View.prototype.getZoom = function() { getZoom() {
let zoom; let zoom;
const resolution = this.getResolution(); const resolution = this.getResolution();
if (resolution !== undefined) { if (resolution !== undefined) {
zoom = this.getZoomForResolution(resolution); zoom = this.getZoomForResolution(resolution);
} }
return zoom; return zoom;
}; }
/** /**
* Get the zoom level for a resolution. * Get the zoom level for a resolution.
@@ -968,7 +938,7 @@ View.prototype.getZoom = function() {
* @return {number|undefined} The zoom level for the provided resolution. * @return {number|undefined} The zoom level for the provided resolution.
* @api * @api
*/ */
View.prototype.getZoomForResolution = function(resolution) { getZoomForResolution(resolution) {
let offset = this.minZoom_ || 0; let offset = this.minZoom_ || 0;
let max, zoomFactor; let max, zoomFactor;
if (this.resolutions_) { if (this.resolutions_) {
@@ -985,8 +955,7 @@ View.prototype.getZoomForResolution = function(resolution) {
zoomFactor = this.zoomFactor_; zoomFactor = this.zoomFactor_;
} }
return offset + Math.log(max / resolution) / Math.log(zoomFactor); return offset + Math.log(max / resolution) / Math.log(zoomFactor);
}; }
/** /**
* Get the resolution for a zoom level. * Get the resolution for a zoom level.
@@ -994,11 +963,10 @@ View.prototype.getZoomForResolution = function(resolution) {
* @return {number} The view resolution for the provided zoom level. * @return {number} The view resolution for the provided zoom level.
* @api * @api
*/ */
View.prototype.getResolutionForZoom = function(zoom) { getResolutionForZoom(zoom) {
return /** @type {number} */ (this.constrainResolution( return /** @type {number} */ (this.constrainResolution(
this.maxResolution_, zoom - this.minZoom_, 0)); this.maxResolution_, zoom - this.minZoom_, 0));
}; }
/** /**
* Fit the given geometry or extent based on the given map size and border. * Fit the given geometry or extent based on the given map size and border.
@@ -1010,7 +978,7 @@ View.prototype.getResolutionForZoom = function(zoom) {
* @param {module:ol/View~FitOptions=} opt_options Options. * @param {module:ol/View~FitOptions=} opt_options Options.
* @api * @api
*/ */
View.prototype.fit = function(geometryOrExtent, opt_options) { fit(geometryOrExtent, opt_options) {
const options = opt_options || {}; const options = opt_options || {};
let size = options.size; let size = options.size;
if (!size) { if (!size) {
@@ -1103,17 +1071,16 @@ View.prototype.fit = function(geometryOrExtent, opt_options) {
this.setCenter(center); this.setCenter(center);
setTimeout(callback.bind(undefined, true), 0); setTimeout(callback.bind(undefined, true), 0);
} }
}; }
/** /**
* Center on coordinate and view position. * Center on coordinate and view position.
* @param {module:ol/coordinate~Coordinate} coordinate Coordinate. * @param {module:ol/coordinate~Coordinate} coordinate Coordinate.
* @param {module:ol/size~Size} size Box pixel size. * @param {module:ol/size~Size} size Box pixel size.
* @param {module:ol~Pixel} position Position on the view to center on. * @param {module:ol/pixel~Pixel} position Position on the view to center on.
* @api * @api
*/ */
View.prototype.centerOn = function(coordinate, size, position) { centerOn(coordinate, size, position) {
// calculate rotated position // calculate rotated position
const rotation = this.getRotation(); const rotation = this.getRotation();
const cosAngle = Math.cos(-rotation); const cosAngle = Math.cos(-rotation);
@@ -1130,16 +1097,14 @@ View.prototype.centerOn = function(coordinate, size, position) {
const centerY = rotY * cosAngle + rotX * sinAngle; const centerY = rotY * cosAngle + rotX * sinAngle;
this.setCenter([centerX, centerY]); this.setCenter([centerX, centerY]);
}; }
/** /**
* @return {boolean} Is defined. * @return {boolean} Is defined.
*/ */
View.prototype.isDef = function() { isDef() {
return !!this.getCenter() && this.getResolution() !== undefined; return !!this.getCenter() && this.getResolution() !== undefined;
}; }
/** /**
* Rotate the view around a given coordinate. * Rotate the view around a given coordinate.
@@ -1147,14 +1112,13 @@ View.prototype.isDef = function() {
* @param {module:ol/coordinate~Coordinate=} opt_anchor The rotation center. * @param {module:ol/coordinate~Coordinate=} opt_anchor The rotation center.
* @api * @api
*/ */
View.prototype.rotate = function(rotation, opt_anchor) { rotate(rotation, opt_anchor) {
if (opt_anchor !== undefined) { if (opt_anchor !== undefined) {
const center = this.calculateCenterRotate(rotation, opt_anchor); const center = this.calculateCenterRotate(rotation, opt_anchor);
this.setCenter(center); this.setCenter(center);
} }
this.setRotation(rotation); this.setRotation(rotation);
}; }
/** /**
* Set the center of the current view. * Set the center of the current view.
@@ -1162,25 +1126,23 @@ View.prototype.rotate = function(rotation, opt_anchor) {
* @observable * @observable
* @api * @api
*/ */
View.prototype.setCenter = function(center) { setCenter(center) {
this.set(ViewProperty.CENTER, center); this.set(ViewProperty.CENTER, center);
if (this.getAnimating()) { if (this.getAnimating()) {
this.cancelAnimations(); this.cancelAnimations();
} }
}; }
/** /**
* @param {module:ol/ViewHint} hint Hint. * @param {module:ol/ViewHint} hint Hint.
* @param {number} delta Delta. * @param {number} delta Delta.
* @return {number} New value. * @return {number} New value.
*/ */
View.prototype.setHint = function(hint, delta) { setHint(hint, delta) {
this.hints_[hint] += delta; this.hints_[hint] += delta;
this.changed(); this.changed();
return this.hints_[hint]; return this.hints_[hint];
}; }
/** /**
* Set the resolution for this view. * Set the resolution for this view.
@@ -1188,13 +1150,12 @@ View.prototype.setHint = function(hint, delta) {
* @observable * @observable
* @api * @api
*/ */
View.prototype.setResolution = function(resolution) { setResolution(resolution) {
this.set(ViewProperty.RESOLUTION, resolution); this.set(ViewProperty.RESOLUTION, resolution);
if (this.getAnimating()) { if (this.getAnimating()) {
this.cancelAnimations(); this.cancelAnimations();
} }
}; }
/** /**
* Set the rotation for this view. * Set the rotation for this view.
@@ -1202,22 +1163,22 @@ View.prototype.setResolution = function(resolution) {
* @observable * @observable
* @api * @api
*/ */
View.prototype.setRotation = function(rotation) { setRotation(rotation) {
this.set(ViewProperty.ROTATION, rotation); this.set(ViewProperty.ROTATION, rotation);
if (this.getAnimating()) { if (this.getAnimating()) {
this.cancelAnimations(); this.cancelAnimations();
} }
}; }
/** /**
* Zoom to a specific zoom level. * Zoom to a specific zoom level.
* @param {number} zoom Zoom level. * @param {number} zoom Zoom level.
* @api * @api
*/ */
View.prototype.setZoom = function(zoom) { setZoom(zoom) {
this.setResolution(this.getResolutionForZoom(zoom)); this.setResolution(this.getResolutionForZoom(zoom));
}; }
}
/** /**

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/WebGLMap * @module ol/WebGLMap
*/ */
import {inherits} from './util.js';
import PluggableMap from './PluggableMap.js'; import PluggableMap from './PluggableMap.js';
import {defaults as defaultControls} from './control.js'; import {defaults as defaultControls} from './control.js';
import {defaults as defaultInteractions} from './interaction.js'; import {defaults as defaultInteractions} from './interaction.js';
@@ -57,16 +56,18 @@ import WebGLVectorLayerRenderer from './renderer/webgl/VectorLayer.js';
* {@link module:ol/layer/Base}, so layers entered in the options or added * {@link module:ol/layer/Base}, so layers entered in the options or added
* with `addLayer` can be groups, which can contain further groups, and so on. * with `addLayer` can be groups, which can contain further groups, and so on.
* *
* @constructor
* @extends {module:ol/PluggableMap}
* @param {module:ol/PluggableMap~MapOptions} options Map options.
* @fires module:ol/MapBrowserEvent~MapBrowserEvent * @fires module:ol/MapBrowserEvent~MapBrowserEvent
* @fires module:ol/MapEvent~MapEvent * @fires module:ol/MapEvent~MapEvent
* @fires module:ol/render/Event~RenderEvent#postcompose * @fires module:ol/render/Event~RenderEvent#postcompose
* @fires module:ol/render/Event~RenderEvent#precompose * @fires module:ol/render/Event~RenderEvent#precompose
* @api * @api
*/ */
const WebGLMap = function(options) { class WebGLMap extends PluggableMap {
/**
* @param {module:ol/PluggableMap~MapOptions} options Map options.
*/
constructor(options) {
options = assign({}, options); options = assign({}, options);
if (!options.controls) { if (!options.controls) {
options.controls = defaultControls(); options.controls = defaultControls();
@@ -75,13 +76,10 @@ const WebGLMap = function(options) {
options.interactions = defaultInteractions(); options.interactions = defaultInteractions();
} }
PluggableMap.call(this, options); super(options);
}; }
inherits(WebGLMap, PluggableMap); createRenderer() {
WebGLMap.prototype.createRenderer = function() {
const renderer = new WebGLMapRenderer(this); const renderer = new WebGLMapRenderer(this);
renderer.registerLayerRenderers([ renderer.registerLayerRenderers([
WebGLImageLayerRenderer, WebGLImageLayerRenderer,
@@ -89,6 +87,8 @@ WebGLMap.prototype.createRenderer = function() {
WebGLVectorLayerRenderer WebGLVectorLayerRenderer
]); ]);
return renderer; return renderer;
}; }
}
export default WebGLMap; export default WebGLMap;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/control/Attribution * @module ol/control/Attribution
*/ */
import {inherits} from '../util.js';
import {equals} from '../array.js'; import {equals} from '../array.js';
import Control from '../control/Control.js'; import Control from '../control/Control.js';
import {CLASS_CONTROL, CLASS_UNSELECTABLE, CLASS_COLLAPSED} from '../css.js'; import {CLASS_CONTROL, CLASS_UNSELECTABLE, CLASS_COLLAPSED} from '../css.js';
@@ -14,7 +13,7 @@ import {visibleAtResolution} from '../layer/Layer.js';
/** /**
* @typedef {Object} Options * @typedef {Object} Options
* @property {string} [className='ol-attribution'] CSS class name. * @property {string} [className='ol-attribution'] CSS class name.
* @property {Element|string} [target] Specify a target if you * @property {HTMLElement|string} [target] Specify a target if you
* want the control to be rendered outside of the map's * want the control to be rendered outside of the map's
* viewport. * viewport.
* @property {boolean} [collapsible=true] Specify if attributions can * @property {boolean} [collapsible=true] Specify if attributions can
@@ -26,7 +25,7 @@ import {visibleAtResolution} from '../layer/Layer.js';
* @property {string} [label='i'] Text label to use for the * @property {string} [label='i'] Text label to use for the
* collapsed attributions button. * collapsed attributions button.
* Instead of text, also an element (e.g. a `span` element) can be used. * Instead of text, also an element (e.g. a `span` element) can be used.
* @property {string|Element} [collapseLabel='»'] Text label to use * @property {string|HTMLElement} [collapseLabel='»'] Text label to use
* for the expanded attributions button. * for the expanded attributions button.
* Instead of text, also an element (e.g. a `span` element) can be used. * Instead of text, also an element (e.g. a `span` element) can be used.
* @property {function(module:ol/MapEvent)} [render] Function called when * @property {function(module:ol/MapEvent)} [render] Function called when
@@ -42,18 +41,26 @@ import {visibleAtResolution} from '../layer/Layer.js';
* By default it will show in the bottom right portion of the map, but this can * By default it will show in the bottom right portion of the map, but this can
* be changed by using a css selector for `.ol-attribution`. * be changed by using a css selector for `.ol-attribution`.
* *
* @constructor
* @extends {module:ol/control/Control}
* @param {module:ol/control/Attribution~Options=} opt_options Attribution options.
* @api * @api
*/ */
const Attribution = function(opt_options) { class Attribution extends Control {
/**
* @param {module:ol/control/Attribution~Options=} opt_options Attribution options.
*/
constructor(opt_options) {
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
super({
element: document.createElement('div'),
render: options.render || render,
target: options.target
});
/** /**
* @private * @private
* @type {Element} * @type {HTMLElement}
*/ */
this.ulElement_ = document.createElement('UL'); this.ulElement_ = document.createElement('UL');
@@ -83,7 +90,7 @@ const Attribution = function(opt_options) {
if (typeof collapseLabel === 'string') { if (typeof collapseLabel === 'string') {
/** /**
* @private * @private
* @type {Element} * @type {HTMLElement}
*/ */
this.collapseLabel_ = document.createElement('span'); this.collapseLabel_ = document.createElement('span');
this.collapseLabel_.textContent = collapseLabel; this.collapseLabel_.textContent = collapseLabel;
@@ -96,7 +103,7 @@ const Attribution = function(opt_options) {
if (typeof label === 'string') { if (typeof label === 'string') {
/** /**
* @private * @private
* @type {Element} * @type {HTMLElement}
*/ */
this.label_ = document.createElement('span'); this.label_ = document.createElement('span');
this.label_.textContent = label; this.label_.textContent = label;
@@ -117,17 +124,11 @@ const Attribution = function(opt_options) {
const cssClasses = className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL + const cssClasses = className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL +
(this.collapsed_ && this.collapsible_ ? ' ' + CLASS_COLLAPSED : '') + (this.collapsed_ && this.collapsible_ ? ' ' + CLASS_COLLAPSED : '') +
(this.collapsible_ ? '' : ' ol-uncollapsible'); (this.collapsible_ ? '' : ' ol-uncollapsible');
const element = document.createElement('div'); const element = this.element;
element.className = cssClasses; element.className = cssClasses;
element.appendChild(this.ulElement_); element.appendChild(this.ulElement_);
element.appendChild(button); element.appendChild(button);
Control.call(this, {
element: element,
render: options.render || render,
target: options.target
});
/** /**
* A list of currently rendered resolutions. * A list of currently rendered resolutions.
* @type {Array.<string>} * @type {Array.<string>}
@@ -141,10 +142,7 @@ const Attribution = function(opt_options) {
*/ */
this.renderedVisible_ = true; this.renderedVisible_ = true;
}; }
inherits(Attribution, Control);
/** /**
* Get a list of visible attributions. * Get a list of visible attributions.
@@ -152,7 +150,7 @@ inherits(Attribution, Control);
* @return {Array.<string>} Attributions. * @return {Array.<string>} Attributions.
* @private * @private
*/ */
Attribution.prototype.getSourceAttributions_ = function(frameState) { getSourceAttributions_(frameState) {
/** /**
* Used to determine if an attribution already exists. * Used to determine if an attribution already exists.
* @type {!Object.<string, boolean>} * @type {!Object.<string, boolean>}
@@ -203,25 +201,13 @@ Attribution.prototype.getSourceAttributions_ = function(frameState) {
} }
} }
return visibleAttributions; return visibleAttributions;
};
/**
* Update the attribution element.
* @param {module:ol/MapEvent} mapEvent Map event.
* @this {module:ol/control/Attribution}
* @api
*/
export function render(mapEvent) {
this.updateElement_(mapEvent.frameState);
} }
/** /**
* @private * @private
* @param {?module:ol/PluggableMap~FrameState} frameState Frame state. * @param {?module:ol/PluggableMap~FrameState} frameState Frame state.
*/ */
Attribution.prototype.updateElement_ = function(frameState) { updateElement_(frameState) {
if (!frameState) { if (!frameState) {
if (this.renderedVisible_) { if (this.renderedVisible_) {
this.element.style.display = 'none'; this.element.style.display = 'none';
@@ -252,23 +238,21 @@ Attribution.prototype.updateElement_ = function(frameState) {
} }
this.renderedAttributions_ = attributions; this.renderedAttributions_ = attributions;
}; }
/** /**
* @param {Event} event The event to handle * @param {MouseEvent} event The event to handle
* @private * @private
*/ */
Attribution.prototype.handleClick_ = function(event) { handleClick_(event) {
event.preventDefault(); event.preventDefault();
this.handleToggle_(); this.handleToggle_();
}; }
/** /**
* @private * @private
*/ */
Attribution.prototype.handleToggle_ = function() { handleToggle_() {
this.element.classList.toggle(CLASS_COLLAPSED); this.element.classList.toggle(CLASS_COLLAPSED);
if (this.collapsed_) { if (this.collapsed_) {
replaceNode(this.collapseLabel_, this.label_); replaceNode(this.collapseLabel_, this.label_);
@@ -276,25 +260,23 @@ Attribution.prototype.handleToggle_ = function() {
replaceNode(this.label_, this.collapseLabel_); replaceNode(this.label_, this.collapseLabel_);
} }
this.collapsed_ = !this.collapsed_; this.collapsed_ = !this.collapsed_;
}; }
/** /**
* Return `true` if the attribution is collapsible, `false` otherwise. * Return `true` if the attribution is collapsible, `false` otherwise.
* @return {boolean} True if the widget is collapsible. * @return {boolean} True if the widget is collapsible.
* @api * @api
*/ */
Attribution.prototype.getCollapsible = function() { getCollapsible() {
return this.collapsible_; return this.collapsible_;
}; }
/** /**
* Set whether the attribution should be collapsible. * Set whether the attribution should be collapsible.
* @param {boolean} collapsible True if the widget is collapsible. * @param {boolean} collapsible True if the widget is collapsible.
* @api * @api
*/ */
Attribution.prototype.setCollapsible = function(collapsible) { setCollapsible(collapsible) {
if (this.collapsible_ === collapsible) { if (this.collapsible_ === collapsible) {
return; return;
} }
@@ -303,8 +285,7 @@ Attribution.prototype.setCollapsible = function(collapsible) {
if (!collapsible && this.collapsed_) { if (!collapsible && this.collapsed_) {
this.handleToggle_(); this.handleToggle_();
} }
}; }
/** /**
* Collapse or expand the attribution according to the passed parameter. Will * Collapse or expand the attribution according to the passed parameter. Will
@@ -313,13 +294,12 @@ Attribution.prototype.setCollapsible = function(collapsible) {
* @param {boolean} collapsed True if the widget is collapsed. * @param {boolean} collapsed True if the widget is collapsed.
* @api * @api
*/ */
Attribution.prototype.setCollapsed = function(collapsed) { setCollapsed(collapsed) {
if (!this.collapsible_ || this.collapsed_ === collapsed) { if (!this.collapsible_ || this.collapsed_ === collapsed) {
return; return;
} }
this.handleToggle_(); this.handleToggle_();
}; }
/** /**
* Return `true` when the attribution is currently collapsed or `false` * Return `true` when the attribution is currently collapsed or `false`
@@ -327,7 +307,21 @@ Attribution.prototype.setCollapsed = function(collapsed) {
* @return {boolean} True if the widget is collapsed. * @return {boolean} True if the widget is collapsed.
* @api * @api
*/ */
Attribution.prototype.getCollapsed = function() { getCollapsed() {
return this.collapsed_; return this.collapsed_;
}; }
}
/**
* Update the attribution element.
* @param {module:ol/MapEvent} mapEvent Map event.
* @this {module:ol/control/Attribution}
* @api
*/
export function render(mapEvent) {
this.updateElement_(mapEvent.frameState);
}
export default Attribution; export default Attribution;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/control/Control * @module ol/control/Control
*/ */
import {inherits} from '../util.js';
import {UNDEFINED} from '../functions.js'; import {UNDEFINED} from '../functions.js';
import MapEventType from '../MapEventType.js'; import MapEventType from '../MapEventType.js';
import BaseObject from '../Object.js'; import BaseObject from '../Object.js';
@@ -11,13 +10,13 @@ import {listen, unlistenByKey} from '../events.js';
/** /**
* @typedef {Object} Options * @typedef {Object} Options
* @property {Element} [element] The element is the control's * @property {HTMLElement} [element] The element is the control's
* container element. This only needs to be specified if you're developing * container element. This only needs to be specified if you're developing
* a custom control. * a custom control.
* @property {function(module:ol/MapEvent)} [render] Function called when * @property {function(module:ol/MapEvent)} [render] Function called when
* the control should be re-rendered. This is called in a `requestAnimationFrame` * the control should be re-rendered. This is called in a `requestAnimationFrame`
* callback. * callback.
* @property {Element|string} [target] Specify a target if you want * @property {HTMLElement|string} [target] Specify a target if you want
* the control to be rendered outside of the map's viewport. * the control to be rendered outside of the map's viewport.
*/ */
@@ -44,24 +43,26 @@ import {listen, unlistenByKey} from '../events.js';
* You can also extend this base for your own control class. See * You can also extend this base for your own control class. See
* examples/custom-controls for an example of how to do this. * examples/custom-controls for an example of how to do this.
* *
* @constructor
* @extends {module:ol/Object}
* @param {module:ol/control/Control~Options} options Control options.
* @api * @api
*/ */
const Control = function(options) { class Control extends BaseObject {
BaseObject.call(this); /**
* @param {module:ol/control/Control~Options} options Control options.
*/
constructor(options) {
super();
/** /**
* @protected * @protected
* @type {Element} * @type {HTMLElement}
*/ */
this.element = options.element ? options.element : null; this.element = options.element ? options.element : null;
/** /**
* @private * @private
* @type {Element} * @type {HTMLElement}
*/ */
this.target_ = null; this.target_ = null;
@@ -86,29 +87,24 @@ const Control = function(options) {
this.setTarget(options.target); this.setTarget(options.target);
} }
}; }
inherits(Control, BaseObject);
/** /**
* @inheritDoc * @inheritDoc
*/ */
Control.prototype.disposeInternal = function() { disposeInternal() {
removeNode(this.element); removeNode(this.element);
BaseObject.prototype.disposeInternal.call(this); super.disposeInternal();
}; }
/** /**
* Get the map associated with this control. * Get the map associated with this control.
* @return {module:ol/PluggableMap} Map. * @return {module:ol/PluggableMap} Map.
* @api * @api
*/ */
Control.prototype.getMap = function() { getMap() {
return this.map_; return this.map_;
}; }
/** /**
* Remove the control from its current map and attach it to the new map. * Remove the control from its current map and attach it to the new map.
@@ -117,7 +113,7 @@ Control.prototype.getMap = function() {
* @param {module:ol/PluggableMap} map Map. * @param {module:ol/PluggableMap} map Map.
* @api * @api
*/ */
Control.prototype.setMap = function(map) { setMap(map) {
if (this.map_) { if (this.map_) {
removeNode(this.element); removeNode(this.element);
} }
@@ -136,8 +132,7 @@ Control.prototype.setMap = function(map) {
} }
map.render(); map.render();
} }
}; }
/** /**
* This function is used to set a target element for the control. It has no * This function is used to set a target element for the control. It has no
@@ -145,12 +140,15 @@ Control.prototype.setMap = function(map) {
* after `setMap` is called on the control). If no `target` is set in the * after `setMap` is called on the control). If no `target` is set in the
* options passed to the control constructor and if `setTarget` is not called * options passed to the control constructor and if `setTarget` is not called
* then the control is added to the map's overlay container. * then the control is added to the map's overlay container.
* @param {Element|string} target Target. * @param {HTMLElement|string} target Target.
* @api * @api
*/ */
Control.prototype.setTarget = function(target) { setTarget(target) {
this.target_ = typeof target === 'string' ? this.target_ = typeof target === 'string' ?
document.getElementById(target) : document.getElementById(target) :
target; target;
}; }
}
export default Control; export default Control;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/control/FullScreen * @module ol/control/FullScreen
*/ */
import {inherits} from '../util.js';
import Control from '../control/Control.js'; import Control from '../control/Control.js';
import {CLASS_CONTROL, CLASS_UNSELECTABLE, CLASS_UNSUPPORTED} from '../css.js'; import {CLASS_CONTROL, CLASS_UNSELECTABLE, CLASS_UNSUPPORTED} from '../css.js';
import {replaceNode} from '../dom.js'; import {replaceNode} from '../dom.js';
@@ -35,16 +34,16 @@ const getChangeType = (function() {
/** /**
* @typedef {Object} Options * @typedef {Object} Options
* @property {string} [className='ol-full-screen'] CSS class name. * @property {string} [className='ol-full-screen'] CSS class name.
* @property {string|Element} [label='\u2922'] Text label to use for the button. * @property {string|HTMLElement} [label='\u2922'] Text label to use for the button.
* Instead of text, also an element (e.g. a `span` element) can be used. * Instead of text, also an element (e.g. a `span` element) can be used.
* @property {string|Element} [labelActive='\u00d7'] Text label to use for the * @property {string|HTMLElement} [labelActive='\u00d7'] Text label to use for the
* button when full-screen is active. * button when full-screen is active.
* Instead of text, also an element (e.g. a `span` element) can be used. * Instead of text, also an element (e.g. a `span` element) can be used.
* @property {string} [tipLabel='Toggle full-screen'] Text label to use for the button tip. * @property {string} [tipLabel='Toggle full-screen'] Text label to use for the button tip.
* @property {boolean} [keys=false] Full keyboard access. * @property {boolean} [keys=false] Full keyboard access.
* @property {Element|string} [target] Specify a target if you want the * @property {HTMLElement|string} [target] Specify a target if you want the
* control to be rendered outside of the map's viewport. * control to be rendered outside of the map's viewport.
* @property {Element|string} [source] The element to be displayed * @property {HTMLElement|string} [source] The element to be displayed
* fullscreen. When not provided, the element containing the map viewport will * fullscreen. When not provided, the element containing the map viewport will
* be displayed fullscreen. * be displayed fullscreen.
*/ */
@@ -61,16 +60,22 @@ const getChangeType = (function() {
* The [Fullscreen API](http://www.w3.org/TR/fullscreen/) is used to * The [Fullscreen API](http://www.w3.org/TR/fullscreen/) is used to
* toggle the map in full screen mode. * toggle the map in full screen mode.
* *
*
* @constructor
* @extends {module:ol/control/Control}
* @param {module:ol/control/FullScreen~Options=} opt_options Options.
* @api * @api
*/ */
const FullScreen = function(opt_options) { class FullScreen extends Control {
/**
* @param {module:ol/control/FullScreen~Options=} opt_options Options.
*/
constructor(opt_options) {
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
super({
element: document.createElement('div'),
target: options.target
});
/** /**
* @private * @private
* @type {string} * @type {string}
@@ -82,7 +87,7 @@ const FullScreen = function(opt_options) {
/** /**
* @private * @private
* @type {Element} * @type {HTMLElement}
*/ */
this.labelNode_ = typeof label === 'string' ? this.labelNode_ = typeof label === 'string' ?
document.createTextNode(label) : label; document.createTextNode(label) : label;
@@ -91,7 +96,7 @@ const FullScreen = function(opt_options) {
/** /**
* @private * @private
* @type {Element} * @type {HTMLElement}
*/ */
this.labelActiveNode_ = typeof labelActive === 'string' ? this.labelActiveNode_ = typeof labelActive === 'string' ?
document.createTextNode(labelActive) : labelActive; document.createTextNode(labelActive) : labelActive;
@@ -109,15 +114,10 @@ const FullScreen = function(opt_options) {
const cssClasses = this.cssClassName_ + ' ' + CLASS_UNSELECTABLE + const cssClasses = this.cssClassName_ + ' ' + CLASS_UNSELECTABLE +
' ' + CLASS_CONTROL + ' ' + ' ' + CLASS_CONTROL + ' ' +
(!isFullScreenSupported() ? CLASS_UNSUPPORTED : ''); (!isFullScreenSupported() ? CLASS_UNSUPPORTED : '');
const element = document.createElement('div'); const element = this.element;
element.className = cssClasses; element.className = cssClasses;
element.appendChild(button); element.appendChild(button);
Control.call(this, {
element: element,
target: options.target
});
/** /**
* @private * @private
* @type {boolean} * @type {boolean}
@@ -126,29 +126,25 @@ const FullScreen = function(opt_options) {
/** /**
* @private * @private
* @type {Element|string|undefined} * @type {HTMLElement|string|undefined}
*/ */
this.source_ = options.source; this.source_ = options.source;
}; }
inherits(FullScreen, Control);
/** /**
* @param {Event} event The event to handle * @param {MouseEvent} event The event to handle
* @private * @private
*/ */
FullScreen.prototype.handleClick_ = function(event) { handleClick_(event) {
event.preventDefault(); event.preventDefault();
this.handleFullScreen_(); this.handleFullScreen_();
}; }
/** /**
* @private * @private
*/ */
FullScreen.prototype.handleFullScreen_ = function() { handleFullScreen_() {
if (!isFullScreenSupported()) { if (!isFullScreenSupported()) {
return; return;
} }
@@ -174,13 +170,12 @@ FullScreen.prototype.handleFullScreen_ = function() {
requestFullScreen(element); requestFullScreen(element);
} }
} }
}; }
/** /**
* @private * @private
*/ */
FullScreen.prototype.handleFullScreenChange_ = function() { handleFullScreenChange_() {
const button = this.element.firstElementChild; const button = this.element.firstElementChild;
const map = this.getMap(); const map = this.getMap();
if (isFullScreen()) { if (isFullScreen()) {
@@ -193,22 +188,23 @@ FullScreen.prototype.handleFullScreenChange_ = function() {
if (map) { if (map) {
map.updateSize(); map.updateSize();
} }
}; }
/** /**
* @inheritDoc * @inheritDoc
* @api * @api
*/ */
FullScreen.prototype.setMap = function(map) { setMap(map) {
Control.prototype.setMap.call(this, map); super.setMap(map);
if (map) { if (map) {
this.listenerKeys.push(listen(document, this.listenerKeys.push(listen(document,
getChangeType(), getChangeType(),
this.handleFullScreenChange_, this) this.handleFullScreenChange_, this)
); );
} }
}; }
}
/** /**
* @return {boolean} Fullscreen is supported by the current platform. * @return {boolean} Fullscreen is supported by the current platform.
@@ -235,7 +231,7 @@ function isFullScreen() {
/** /**
* Request to fullscreen an element. * Request to fullscreen an element.
* @param {Element} element Element to request fullscreen * @param {HTMLElement} element Element to request fullscreen
*/ */
function requestFullScreen(element) { function requestFullScreen(element) {
if (element.requestFullscreen) { if (element.requestFullscreen) {
@@ -251,7 +247,7 @@ function requestFullScreen(element) {
/** /**
* Request to fullscreen an element with keyboard input. * Request to fullscreen an element with keyboard input.
* @param {Element} element Element to request fullscreen * @param {HTMLElement} element Element to request fullscreen
*/ */
function requestFullScreenWithKeys(element) { function requestFullScreenWithKeys(element) {
if (element.mozRequestFullScreenWithKeys) { if (element.mozRequestFullScreenWithKeys) {

View File

@@ -1,8 +1,6 @@
/** /**
* @module ol/control/MousePosition * @module ol/control/MousePosition
*/ */
import {inherits} from '../util.js';
import {listen} from '../events.js'; import {listen} from '../events.js';
import EventType from '../events/EventType.js'; import EventType from '../events/EventType.js';
import {getChangeEventType} from '../Object.js'; import {getChangeEventType} from '../Object.js';
@@ -46,20 +44,21 @@ const COORDINATE_FORMAT = 'coordinateFormat';
* By default the control is shown in the top right corner of the map, but this * By default the control is shown in the top right corner of the map, but this
* can be changed by using the css selector `.ol-mouse-position`. * can be changed by using the css selector `.ol-mouse-position`.
* *
* @constructor
* @extends {module:ol/control/Control}
* @param {module:ol/control/MousePosition~Options=} opt_options Mouse position
* options.
* @api * @api
*/ */
const MousePosition = function(opt_options) { class MousePosition extends Control {
/**
* @param {module:ol/control/MousePosition~Options=} opt_options Mouse position options.
*/
constructor(opt_options) {
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
const element = document.createElement('DIV'); const element = document.createElement('DIV');
element.className = options.className !== undefined ? options.className : 'ol-mouse-position'; element.className = options.className !== undefined ? options.className : 'ol-mouse-position';
Control.call(this, { super({
element: element, element: element,
render: options.render || render, render: options.render || render,
target: options.target target: options.target
@@ -108,42 +107,18 @@ const MousePosition = function(opt_options) {
/** /**
* @private * @private
* @type {module:ol~Pixel} * @type {module:ol/pixel~Pixel}
*/ */
this.lastMouseMovePixel_ = null; this.lastMouseMovePixel_ = null;
};
inherits(MousePosition, Control);
/**
* Update the mouseposition element.
* @param {module:ol/MapEvent} mapEvent Map event.
* @this {module:ol/control/MousePosition}
* @api
*/
export function render(mapEvent) {
const frameState = mapEvent.frameState;
if (!frameState) {
this.mapProjection_ = null;
} else {
if (this.mapProjection_ != frameState.viewState.projection) {
this.mapProjection_ = frameState.viewState.projection;
this.transform_ = null;
} }
}
this.updateHTML_(this.lastMouseMovePixel_);
}
/** /**
* @private * @private
*/ */
MousePosition.prototype.handleProjectionChanged_ = function() { handleProjectionChanged_() {
this.transform_ = null; this.transform_ = null;
}; }
/** /**
* Return the coordinate format type used to render the current position or * Return the coordinate format type used to render the current position or
@@ -153,12 +128,11 @@ MousePosition.prototype.handleProjectionChanged_ = function() {
* @observable * @observable
* @api * @api
*/ */
MousePosition.prototype.getCoordinateFormat = function() { getCoordinateFormat() {
return ( return (
/** @type {module:ol/coordinate~CoordinateFormat|undefined} */ (this.get(COORDINATE_FORMAT)) /** @type {module:ol/coordinate~CoordinateFormat|undefined} */ (this.get(COORDINATE_FORMAT))
); );
}; }
/** /**
* Return the projection that is used to report the mouse position. * Return the projection that is used to report the mouse position.
@@ -167,40 +141,37 @@ MousePosition.prototype.getCoordinateFormat = function() {
* @observable * @observable
* @api * @api
*/ */
MousePosition.prototype.getProjection = function() { getProjection() {
return ( return (
/** @type {module:ol/proj/Projection|undefined} */ (this.get(PROJECTION)) /** @type {module:ol/proj/Projection|undefined} */ (this.get(PROJECTION))
); );
}; }
/** /**
* @param {Event} event Browser event. * @param {Event} event Browser event.
* @protected * @protected
*/ */
MousePosition.prototype.handleMouseMove = function(event) { handleMouseMove(event) {
const map = this.getMap(); const map = this.getMap();
this.lastMouseMovePixel_ = map.getEventPixel(event); this.lastMouseMovePixel_ = map.getEventPixel(event);
this.updateHTML_(this.lastMouseMovePixel_); this.updateHTML_(this.lastMouseMovePixel_);
}; }
/** /**
* @param {Event} event Browser event. * @param {Event} event Browser event.
* @protected * @protected
*/ */
MousePosition.prototype.handleMouseOut = function(event) { handleMouseOut(event) {
this.updateHTML_(null); this.updateHTML_(null);
this.lastMouseMovePixel_ = null; this.lastMouseMovePixel_ = null;
}; }
/** /**
* @inheritDoc * @inheritDoc
* @api * @api
*/ */
MousePosition.prototype.setMap = function(map) { setMap(map) {
Control.prototype.setMap.call(this, map); super.setMap(map);
if (map) { if (map) {
const viewport = map.getViewport(); const viewport = map.getViewport();
this.listenerKeys.push( this.listenerKeys.push(
@@ -212,8 +183,7 @@ MousePosition.prototype.setMap = function(map) {
); );
} }
} }
}; }
/** /**
* Set the coordinate format type used to render the current position. * Set the coordinate format type used to render the current position.
@@ -222,10 +192,9 @@ MousePosition.prototype.setMap = function(map) {
* @observable * @observable
* @api * @api
*/ */
MousePosition.prototype.setCoordinateFormat = function(format) { setCoordinateFormat(format) {
this.set(COORDINATE_FORMAT, format); this.set(COORDINATE_FORMAT, format);
}; }
/** /**
* Set the projection that is used to report the mouse position. * Set the projection that is used to report the mouse position.
@@ -234,16 +203,15 @@ MousePosition.prototype.setCoordinateFormat = function(format) {
* @observable * @observable
* @api * @api
*/ */
MousePosition.prototype.setProjection = function(projection) { setProjection(projection) {
this.set(PROJECTION, getProjection(projection)); this.set(PROJECTION, getProjection(projection));
}; }
/** /**
* @param {?module:ol~Pixel} pixel Pixel. * @param {?module:ol/pixel~Pixel} pixel Pixel.
* @private * @private
*/ */
MousePosition.prototype.updateHTML_ = function(pixel) { updateHTML_(pixel) {
let html = this.undefinedHTML_; let html = this.undefinedHTML_;
if (pixel && this.mapProjection_) { if (pixel && this.mapProjection_) {
if (!this.transform_) { if (!this.transform_) {
@@ -271,7 +239,28 @@ MousePosition.prototype.updateHTML_ = function(pixel) {
this.element.innerHTML = html; this.element.innerHTML = html;
this.renderedHTML_ = html; this.renderedHTML_ = html;
} }
}; }
}
/**
* Update the mouseposition element.
* @param {module:ol/MapEvent} mapEvent Map event.
* @this {module:ol/control/MousePosition}
* @api
*/
export function render(mapEvent) {
const frameState = mapEvent.frameState;
if (!frameState) {
this.mapProjection_ = null;
} else {
if (this.mapProjection_ != frameState.viewState.projection) {
this.mapProjection_ = frameState.viewState.projection;
this.transform_ = null;
}
}
this.updateHTML_(this.lastMouseMovePixel_);
}
export default MousePosition; export default MousePosition;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/control/OverviewMap * @module ol/control/OverviewMap
*/ */
import {inherits} from '../util.js';
import Collection from '../Collection.js'; import Collection from '../Collection.js';
import Map from '../Map.js'; import Map from '../Map.js';
import MapEventType from '../MapEventType.js'; import MapEventType from '../MapEventType.js';
@@ -40,17 +39,17 @@ const MIN_RATIO = 0.1;
* @typedef {Object} Options * @typedef {Object} Options
* @property {string} [className='ol-overviewmap'] CSS class name. * @property {string} [className='ol-overviewmap'] CSS class name.
* @property {boolean} [collapsed=true] Whether the control should start collapsed or not (expanded). * @property {boolean} [collapsed=true] Whether the control should start collapsed or not (expanded).
* @property {string|Element} [collapseLabel='«'] Text label to use for the * @property {string|HTMLElement} [collapseLabel='«'] Text label to use for the
* expanded overviewmap button. Instead of text, also an element (e.g. a `span` element) can be used. * expanded overviewmap button. Instead of text, also an element (e.g. a `span` element) can be used.
* @property {boolean} [collapsible=true] Whether the control can be collapsed or not. * @property {boolean} [collapsible=true] Whether the control can be collapsed or not.
* @property {string|Element} [label='»'] Text label to use for the collapsed * @property {string|HTMLElement} [label='»'] Text label to use for the collapsed
* overviewmap button. Instead of text, also an element (e.g. a `span` element) can be used. * overviewmap button. Instead of text, also an element (e.g. a `span` element) can be used.
* @property {Array.<module:ol/layer/Layer>|module:ol/Collection.<module:ol/layer/Layer>} [layers] * @property {Array.<module:ol/layer/Layer>|module:ol/Collection.<module:ol/layer/Layer>} [layers]
* Layers for the overview map. If not set, then all main map layers are used * Layers for the overview map. If not set, then all main map layers are used
* instead. * instead.
* @property {function(module:ol/MapEvent)} [render] Function called when the control * @property {function(module:ol/MapEvent)} [render] Function called when the control
* should be re-rendered. This is called in a `requestAnimationFrame` callback. * should be re-rendered. This is called in a `requestAnimationFrame` callback.
* @property {Element|string} [target] Specify a target if you want the control * @property {HTMLElement|string} [target] Specify a target if you want the control
* to be rendered outside of the map's viewport. * to be rendered outside of the map's viewport.
* @property {string} [tipLabel='Overview map'] Text label to use for the button tip. * @property {string} [tipLabel='Overview map'] Text label to use for the button tip.
* @property {module:ol/View} [view] Custom view for the overview map. If not provided, * @property {module:ol/View} [view] Custom view for the overview map. If not provided,
@@ -61,15 +60,24 @@ const MIN_RATIO = 0.1;
/** /**
* Create a new control with a map acting as an overview map for an other * Create a new control with a map acting as an overview map for an other
* defined map. * defined map.
* @constructor *
* @extends {module:ol/control/Control}
* @param {module:ol/control/OverviewMap~Options=} opt_options OverviewMap options.
* @api * @api
*/ */
const OverviewMap = function(opt_options) { class OverviewMap extends Control {
/**
* @param {module:ol/control/OverviewMap~Options=} opt_options OverviewMap options.
*/
constructor(opt_options) {
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
super({
element: document.createElement('div'),
render: options.render || render,
target: options.target
});
/** /**
* @type {boolean} * @type {boolean}
* @private * @private
@@ -96,7 +104,7 @@ const OverviewMap = function(opt_options) {
if (typeof collapseLabel === 'string') { if (typeof collapseLabel === 'string') {
/** /**
* @private * @private
* @type {Element} * @type {HTMLElement}
*/ */
this.collapseLabel_ = document.createElement('span'); this.collapseLabel_ = document.createElement('span');
this.collapseLabel_.textContent = collapseLabel; this.collapseLabel_.textContent = collapseLabel;
@@ -110,7 +118,7 @@ const OverviewMap = function(opt_options) {
if (typeof label === 'string') { if (typeof label === 'string') {
/** /**
* @private * @private
* @type {Element} * @type {HTMLElement}
*/ */
this.label_ = document.createElement('span'); this.label_ = document.createElement('span');
this.label_.textContent = label; this.label_.textContent = label;
@@ -129,7 +137,7 @@ const OverviewMap = function(opt_options) {
this.handleClick_, this); this.handleClick_, this);
/** /**
* @type {Element} * @type {HTMLElement}
* @private * @private
*/ */
this.ovmapDiv_ = document.createElement('DIV'); this.ovmapDiv_ = document.createElement('DIV');
@@ -174,17 +182,11 @@ const OverviewMap = function(opt_options) {
const cssClasses = className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL + const cssClasses = className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL +
(this.collapsed_ && this.collapsible_ ? ' ' + CLASS_COLLAPSED : '') + (this.collapsed_ && this.collapsible_ ? ' ' + CLASS_COLLAPSED : '') +
(this.collapsible_ ? '' : ' ol-uncollapsible'); (this.collapsible_ ? '' : ' ol-uncollapsible');
const element = document.createElement('div'); const element = this.element;
element.className = cssClasses; element.className = cssClasses;
element.appendChild(this.ovmapDiv_); element.appendChild(this.ovmapDiv_);
element.appendChild(button); element.appendChild(button);
Control.call(this, {
element: element,
render: options.render || render,
target: options.target
});
/* Interactive map */ /* Interactive map */
const scope = this; const scope = this;
@@ -222,16 +224,13 @@ const OverviewMap = function(opt_options) {
window.addEventListener('mousemove', move); window.addEventListener('mousemove', move);
window.addEventListener('mouseup', endMoving); window.addEventListener('mouseup', endMoving);
}); });
}; }
inherits(OverviewMap, Control);
/** /**
* @inheritDoc * @inheritDoc
* @api * @api
*/ */
OverviewMap.prototype.setMap = function(map) { setMap(map) {
const oldMap = this.getMap(); const oldMap = this.getMap();
if (map === oldMap) { if (map === oldMap) {
return; return;
@@ -243,7 +242,7 @@ OverviewMap.prototype.setMap = function(map) {
} }
this.ovmap_.setTarget(null); this.ovmap_.setTarget(null);
} }
Control.prototype.setMap.call(this, map); super.setMap(map);
if (map) { if (map) {
this.ovmap_.setTarget(this.ovmapDiv_); this.ovmap_.setTarget(this.ovmapDiv_);
@@ -265,15 +264,14 @@ OverviewMap.prototype.setMap = function(map) {
} }
} }
} }
}; }
/** /**
* Handle map property changes. This only deals with changes to the map's view. * Handle map property changes. This only deals with changes to the map's view.
* @param {module:ol/Object~ObjectEvent} event The propertychange event. * @param {module:ol/Object~ObjectEvent} event The propertychange event.
* @private * @private
*/ */
OverviewMap.prototype.handleMapPropertyChange_ = function(event) { handleMapPropertyChange_(event) {
if (event.key === MapProperty.VIEW) { if (event.key === MapProperty.VIEW) {
const oldView = /** @type {module:ol/View} */ (event.oldValue); const oldView = /** @type {module:ol/View} */ (event.oldValue);
if (oldView) { if (oldView) {
@@ -282,32 +280,29 @@ OverviewMap.prototype.handleMapPropertyChange_ = function(event) {
const newView = this.getMap().getView(); const newView = this.getMap().getView();
this.bindView_(newView); this.bindView_(newView);
} }
}; }
/** /**
* Register listeners for view property changes. * Register listeners for view property changes.
* @param {module:ol/View} view The view. * @param {module:ol/View} view The view.
* @private * @private
*/ */
OverviewMap.prototype.bindView_ = function(view) { bindView_(view) {
listen(view, listen(view,
getChangeEventType(ViewProperty.ROTATION), getChangeEventType(ViewProperty.ROTATION),
this.handleRotationChanged_, this); this.handleRotationChanged_, this);
}; }
/** /**
* Unregister listeners for view property changes. * Unregister listeners for view property changes.
* @param {module:ol/View} view The view. * @param {module:ol/View} view The view.
* @private * @private
*/ */
OverviewMap.prototype.unbindView_ = function(view) { unbindView_(view) {
unlisten(view, unlisten(view,
getChangeEventType(ViewProperty.ROTATION), getChangeEventType(ViewProperty.ROTATION),
this.handleRotationChanged_, this); this.handleRotationChanged_, this);
}; }
/** /**
* Handle rotation changes to the main map. * Handle rotation changes to the main map.
@@ -315,23 +310,10 @@ OverviewMap.prototype.unbindView_ = function(view) {
* overview map's view. * overview map's view.
* @private * @private
*/ */
OverviewMap.prototype.handleRotationChanged_ = function() { handleRotationChanged_() {
this.ovmap_.getView().setRotation(this.getMap().getView().getRotation()); this.ovmap_.getView().setRotation(this.getMap().getView().getRotation());
};
/**
* Update the overview map element.
* @param {module:ol/MapEvent} mapEvent Map event.
* @this {module:ol/control/OverviewMap}
* @api
*/
export function render(mapEvent) {
this.validateExtent_();
this.updateBox_();
} }
/** /**
* Reset the overview map extent if the box size (width or * Reset the overview map extent if the box size (width or
* height) is less than the size of the overview map size times minRatio * height) is less than the size of the overview map size times minRatio
@@ -343,7 +325,7 @@ export function render(mapEvent) {
* main map center location. * main map center location.
* @private * @private
*/ */
OverviewMap.prototype.validateExtent_ = function() { validateExtent_() {
const map = this.getMap(); const map = this.getMap();
const ovmap = this.ovmap_; const ovmap = this.ovmap_;
@@ -380,15 +362,14 @@ OverviewMap.prototype.validateExtent_ = function() {
} else if (!containsExtent(ovextent, extent)) { } else if (!containsExtent(ovextent, extent)) {
this.recenter_(); this.recenter_();
} }
}; }
/** /**
* Reset the overview map extent to half calculated min and max ratio times * Reset the overview map extent to half calculated min and max ratio times
* the extent of the main map. * the extent of the main map.
* @private * @private
*/ */
OverviewMap.prototype.resetExtent_ = function() { resetExtent_() {
if (MAX_RATIO === 0 || MIN_RATIO === 0) { if (MAX_RATIO === 0 || MIN_RATIO === 0) {
return; return;
} }
@@ -411,15 +392,14 @@ OverviewMap.prototype.resetExtent_ = function() {
const ratio = 1 / (Math.pow(2, steps / 2) * MIN_RATIO); const ratio = 1 / (Math.pow(2, steps / 2) * MIN_RATIO);
scaleFromCenter(extent, ratio); scaleFromCenter(extent, ratio);
ovview.fit(extent); ovview.fit(extent);
}; }
/** /**
* Set the center of the overview map to the map center without changing its * Set the center of the overview map to the map center without changing its
* resolution. * resolution.
* @private * @private
*/ */
OverviewMap.prototype.recenter_ = function() { recenter_() {
const map = this.getMap(); const map = this.getMap();
const ovmap = this.ovmap_; const ovmap = this.ovmap_;
@@ -428,14 +408,13 @@ OverviewMap.prototype.recenter_ = function() {
const ovview = ovmap.getView(); const ovview = ovmap.getView();
ovview.setCenter(view.getCenter()); ovview.setCenter(view.getCenter());
}; }
/** /**
* Update the box using the main map extent * Update the box using the main map extent
* @private * @private
*/ */
OverviewMap.prototype.updateBox_ = function() { updateBox_() {
const map = this.getMap(); const map = this.getMap();
const ovmap = this.ovmap_; const ovmap = this.ovmap_;
@@ -467,8 +446,7 @@ OverviewMap.prototype.updateBox_ = function() {
box.style.width = Math.abs((bottomLeft[0] - topRight[0]) / ovresolution) + 'px'; box.style.width = Math.abs((bottomLeft[0] - topRight[0]) / ovresolution) + 'px';
box.style.height = Math.abs((topRight[1] - bottomLeft[1]) / ovresolution) + 'px'; box.style.height = Math.abs((topRight[1] - bottomLeft[1]) / ovresolution) + 'px';
} }
}; }
/** /**
* @param {number} rotation Target rotation. * @param {number} rotation Target rotation.
@@ -476,8 +454,7 @@ OverviewMap.prototype.updateBox_ = function() {
* @return {module:ol/coordinate~Coordinate|undefined} Coordinate for rotation and center anchor. * @return {module:ol/coordinate~Coordinate|undefined} Coordinate for rotation and center anchor.
* @private * @private
*/ */
OverviewMap.prototype.calculateCoordinateRotate_ = function( calculateCoordinateRotate_(rotation, coordinate) {
rotation, coordinate) {
let coordinateRotate; let coordinateRotate;
const map = this.getMap(); const map = this.getMap();
@@ -494,23 +471,21 @@ OverviewMap.prototype.calculateCoordinateRotate_ = function(
addCoordinate(coordinateRotate, currentCenter); addCoordinate(coordinateRotate, currentCenter);
} }
return coordinateRotate; return coordinateRotate;
}; }
/** /**
* @param {Event} event The event to handle * @param {MouseEvent} event The event to handle
* @private * @private
*/ */
OverviewMap.prototype.handleClick_ = function(event) { handleClick_(event) {
event.preventDefault(); event.preventDefault();
this.handleToggle_(); this.handleToggle_();
}; }
/** /**
* @private * @private
*/ */
OverviewMap.prototype.handleToggle_ = function() { handleToggle_() {
this.element.classList.toggle(CLASS_COLLAPSED); this.element.classList.toggle(CLASS_COLLAPSED);
if (this.collapsed_) { if (this.collapsed_) {
replaceNode(this.collapseLabel_, this.label_); replaceNode(this.collapseLabel_, this.label_);
@@ -531,25 +506,23 @@ OverviewMap.prototype.handleToggle_ = function() {
}, },
this); this);
} }
}; }
/** /**
* Return `true` if the overview map is collapsible, `false` otherwise. * Return `true` if the overview map is collapsible, `false` otherwise.
* @return {boolean} True if the widget is collapsible. * @return {boolean} True if the widget is collapsible.
* @api * @api
*/ */
OverviewMap.prototype.getCollapsible = function() { getCollapsible() {
return this.collapsible_; return this.collapsible_;
}; }
/** /**
* Set whether the overview map should be collapsible. * Set whether the overview map should be collapsible.
* @param {boolean} collapsible True if the widget is collapsible. * @param {boolean} collapsible True if the widget is collapsible.
* @api * @api
*/ */
OverviewMap.prototype.setCollapsible = function(collapsible) { setCollapsible(collapsible) {
if (this.collapsible_ === collapsible) { if (this.collapsible_ === collapsible) {
return; return;
} }
@@ -558,8 +531,7 @@ OverviewMap.prototype.setCollapsible = function(collapsible) {
if (!collapsible && this.collapsed_) { if (!collapsible && this.collapsed_) {
this.handleToggle_(); this.handleToggle_();
} }
}; }
/** /**
* Collapse or expand the overview map according to the passed parameter. Will * Collapse or expand the overview map according to the passed parameter. Will
@@ -568,30 +540,43 @@ OverviewMap.prototype.setCollapsible = function(collapsible) {
* @param {boolean} collapsed True if the widget is collapsed. * @param {boolean} collapsed True if the widget is collapsed.
* @api * @api
*/ */
OverviewMap.prototype.setCollapsed = function(collapsed) { setCollapsed(collapsed) {
if (!this.collapsible_ || this.collapsed_ === collapsed) { if (!this.collapsible_ || this.collapsed_ === collapsed) {
return; return;
} }
this.handleToggle_(); this.handleToggle_();
}; }
/** /**
* Determine if the overview map is collapsed. * Determine if the overview map is collapsed.
* @return {boolean} The overview map is collapsed. * @return {boolean} The overview map is collapsed.
* @api * @api
*/ */
OverviewMap.prototype.getCollapsed = function() { getCollapsed() {
return this.collapsed_; return this.collapsed_;
}; }
/** /**
* Return the overview map. * Return the overview map.
* @return {module:ol/PluggableMap} Overview map. * @return {module:ol/PluggableMap} Overview map.
* @api * @api
*/ */
OverviewMap.prototype.getOverviewMap = function() { getOverviewMap() {
return this.ovmap_; return this.ovmap_;
}; }
}
/**
* Update the overview map element.
* @param {module:ol/MapEvent} mapEvent Map event.
* @this {module:ol/control/OverviewMap}
* @api
*/
export function render(mapEvent) {
this.validateExtent_();
this.updateBox_();
}
export default OverviewMap; export default OverviewMap;

View File

@@ -1,19 +1,17 @@
/** /**
* @module ol/control/Rotate * @module ol/control/Rotate
*/ */
import Control from '../control/Control.js'; import Control from '../control/Control.js';
import {CLASS_CONTROL, CLASS_HIDDEN, CLASS_UNSELECTABLE} from '../css.js'; import {CLASS_CONTROL, CLASS_HIDDEN, CLASS_UNSELECTABLE} from '../css.js';
import {easeOut} from '../easing.js'; import {easeOut} from '../easing.js';
import {listen} from '../events.js'; import {listen} from '../events.js';
import EventType from '../events/EventType.js'; import EventType from '../events/EventType.js';
import {inherits} from '../util.js';
/** /**
* @typedef {Object} Options * @typedef {Object} Options
* @property {string} [className='ol-rotate'] CSS class name. * @property {string} [className='ol-rotate'] CSS class name.
* @property {string|Element} [label='⇧'] Text label to use for the rotate button. * @property {string|HTMLElement} [label='⇧'] Text label to use for the rotate button.
* Instead of text, also an element (e.g. a `span` element) can be used. * Instead of text, also an element (e.g. a `span` element) can be used.
* @property {string} [tipLabel='Reset rotation'] Text label to use for the rotate tip. * @property {string} [tipLabel='Reset rotation'] Text label to use for the rotate tip.
* @property {number} [duration=250] Animation duration in milliseconds. * @property {number} [duration=250] Animation duration in milliseconds.
@@ -22,7 +20,7 @@ import {inherits} from '../util.js';
* be re-rendered. This is called in a `requestAnimationFrame` callback. * be re-rendered. This is called in a `requestAnimationFrame` callback.
* @property {function()} [resetNorth] Function called when the control is clicked. * @property {function()} [resetNorth] Function called when the control is clicked.
* This will override the default `resetNorth`. * This will override the default `resetNorth`.
* @property {Element|string} [target] Specify a target if you want the control to be * @property {HTMLElement|string} [target] Specify a target if you want the control to be
* rendered outside of the map's viewport. * rendered outside of the map's viewport.
*/ */
@@ -33,21 +31,29 @@ import {inherits} from '../util.js';
* To style this control use css selector `.ol-rotate`. A `.ol-hidden` css * To style this control use css selector `.ol-rotate`. A `.ol-hidden` css
* selector is added to the button when the rotation is 0. * selector is added to the button when the rotation is 0.
* *
* @constructor
* @extends {module:ol/control/Control}
* @param {module:ol/control/Rotate~Options=} opt_options Rotate options.
* @api * @api
*/ */
const Rotate = function(opt_options) { class Rotate extends Control {
/**
* @param {module:ol/control/Rotate~Options=} opt_options Rotate options.
*/
constructor(opt_options) {
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
super({
element: document.createElement('div'),
render: options.render || render,
target: options.target
});
const className = options.className !== undefined ? options.className : 'ol-rotate'; const className = options.className !== undefined ? options.className : 'ol-rotate';
const label = options.label !== undefined ? options.label : '\u21E7'; const label = options.label !== undefined ? options.label : '\u21E7';
/** /**
* @type {Element} * @type {HTMLElement}
* @private * @private
*/ */
this.label_ = null; this.label_ = null;
@@ -69,22 +75,15 @@ const Rotate = function(opt_options) {
button.title = tipLabel; button.title = tipLabel;
button.appendChild(this.label_); button.appendChild(this.label_);
listen(button, EventType.CLICK, listen(button, EventType.CLICK, this.handleClick_, this);
Rotate.prototype.handleClick_, this);
const cssClasses = className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL; const cssClasses = className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL;
const element = document.createElement('div'); const element = this.element;
element.className = cssClasses; element.className = cssClasses;
element.appendChild(button); element.appendChild(button);
this.callResetNorth_ = options.resetNorth ? options.resetNorth : undefined; this.callResetNorth_ = options.resetNorth ? options.resetNorth : undefined;
Control.call(this, {
element: element,
render: options.render || render,
target: options.target
});
/** /**
* @type {number} * @type {number}
* @private * @private
@@ -107,29 +106,25 @@ const Rotate = function(opt_options) {
this.element.classList.add(CLASS_HIDDEN); this.element.classList.add(CLASS_HIDDEN);
} }
}; }
inherits(Rotate, Control);
/** /**
* @param {Event} event The event to handle * @param {MouseEvent} event The event to handle
* @private * @private
*/ */
Rotate.prototype.handleClick_ = function(event) { handleClick_(event) {
event.preventDefault(); event.preventDefault();
if (this.callResetNorth_ !== undefined) { if (this.callResetNorth_ !== undefined) {
this.callResetNorth_(); this.callResetNorth_();
} else { } else {
this.resetNorth_(); this.resetNorth_();
} }
}; }
/** /**
* @private * @private
*/ */
Rotate.prototype.resetNorth_ = function() { resetNorth_() {
const map = this.getMap(); const map = this.getMap();
const view = map.getView(); const view = map.getView();
if (!view) { if (!view) {
@@ -148,7 +143,8 @@ Rotate.prototype.resetNorth_ = function() {
view.setRotation(0); view.setRotation(0);
} }
} }
}; }
}
/** /**

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/control/ScaleLine * @module ol/control/ScaleLine
*/ */
import {inherits} from '../util.js';
import {getChangeEventType} from '../Object.js'; import {getChangeEventType} from '../Object.js';
import {assert} from '../asserts.js'; import {assert} from '../asserts.js';
import Control from '../control/Control.js'; import Control from '../control/Control.js';
@@ -43,7 +42,7 @@ const LEADING_DIGITS = [1, 2, 5];
* @property {number} [minWidth=64] Minimum width in pixels. * @property {number} [minWidth=64] Minimum width in pixels.
* @property {function(module:ol/MapEvent)} [render] Function called when the control * @property {function(module:ol/MapEvent)} [render] Function called when the control
* should be re-rendered. This is called in a `requestAnimationFrame` callback. * should be re-rendered. This is called in a `requestAnimationFrame` callback.
* @property {Element|string} [target] Specify a target if you want the control * @property {HTMLElement|string} [target] Specify a target if you want the control
* to be rendered outside of the map's viewport. * to be rendered outside of the map's viewport.
* @property {module:ol/control/ScaleLine~Units|string} [units='metric'] Units. * @property {module:ol/control/ScaleLine~Units|string} [units='metric'] Units.
*/ */
@@ -59,31 +58,34 @@ const LEADING_DIGITS = [1, 2, 5];
* By default the scale line will show in the bottom left portion of the map, * By default the scale line will show in the bottom left portion of the map,
* but this can be changed by using the css selector `.ol-scale-line`. * but this can be changed by using the css selector `.ol-scale-line`.
* *
* @constructor
* @extends {module:ol/control/Control}
* @param {module:ol/control/ScaleLine~Options=} opt_options Scale line options.
* @api * @api
*/ */
const ScaleLine = function(opt_options) { class ScaleLine extends Control {
/**
* @param {module:ol/control/ScaleLine~Options=} opt_options Scale line options.
*/
constructor(opt_options) {
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
const className = options.className !== undefined ? options.className : 'ol-scale-line'; const className = options.className !== undefined ? options.className : 'ol-scale-line';
super({
element: document.createElement('DIV'),
render: options.render || render,
target: options.target
});
/** /**
* @private * @private
* @type {Element} * @type {HTMLElement}
*/ */
this.innerElement_ = document.createElement('DIV'); this.innerElement_ = document.createElement('DIV');
this.innerElement_.className = className + '-inner'; this.innerElement_.className = className + '-inner';
/** this.element.className = className + ' ' + CLASS_UNSELECTABLE;
* @private this.element.appendChild(this.innerElement_);
* @type {Element}
*/
this.element_ = document.createElement('DIV');
this.element_.className = className + ' ' + CLASS_UNSELECTABLE;
this.element_.appendChild(this.innerElement_);
/** /**
* @private * @private
@@ -115,12 +117,6 @@ const ScaleLine = function(opt_options) {
*/ */
this.renderedHTML_ = ''; this.renderedHTML_ = '';
Control.call(this, {
element: this.element_,
render: options.render || render,
target: options.target
});
listen( listen(
this, getChangeEventType(UNITS_PROP), this, getChangeEventType(UNITS_PROP),
this.handleUnitsChanged_, this); this.handleUnitsChanged_, this);
@@ -128,10 +124,7 @@ const ScaleLine = function(opt_options) {
this.setUnits(/** @type {module:ol/control/ScaleLine~Units} */ (options.units) || this.setUnits(/** @type {module:ol/control/ScaleLine~Units} */ (options.units) ||
Units.METRIC); Units.METRIC);
}; }
inherits(ScaleLine, Control);
/** /**
* Return the units to use in the scale line. * Return the units to use in the scale line.
@@ -140,37 +133,18 @@ inherits(ScaleLine, Control);
* @observable * @observable
* @api * @api
*/ */
ScaleLine.prototype.getUnits = function() { getUnits() {
return ( return (
/** @type {module:ol/control/ScaleLine~Units|undefined} */ (this.get(UNITS_PROP)) /** @type {module:ol/control/ScaleLine~Units|undefined} */ (this.get(UNITS_PROP))
); );
};
/**
* Update the scale line element.
* @param {module:ol/MapEvent} mapEvent Map event.
* @this {module:ol/control/ScaleLine}
* @api
*/
export function render(mapEvent) {
const frameState = mapEvent.frameState;
if (!frameState) {
this.viewState_ = null;
} else {
this.viewState_ = frameState.viewState;
} }
this.updateElement_();
}
/** /**
* @private * @private
*/ */
ScaleLine.prototype.handleUnitsChanged_ = function() { handleUnitsChanged_() {
this.updateElement_(); this.updateElement_();
}; }
/** /**
* Set the units to use in the scale line. * Set the units to use in the scale line.
@@ -178,20 +152,19 @@ ScaleLine.prototype.handleUnitsChanged_ = function() {
* @observable * @observable
* @api * @api
*/ */
ScaleLine.prototype.setUnits = function(units) { setUnits(units) {
this.set(UNITS_PROP, units); this.set(UNITS_PROP, units);
}; }
/** /**
* @private * @private
*/ */
ScaleLine.prototype.updateElement_ = function() { updateElement_() {
const viewState = this.viewState_; const viewState = this.viewState_;
if (!viewState) { if (!viewState) {
if (this.renderedVisible_) { if (this.renderedVisible_) {
this.element_.style.display = 'none'; this.element.style.display = 'none';
this.renderedVisible_ = false; this.renderedVisible_ = false;
} }
return; return;
@@ -278,7 +251,7 @@ ScaleLine.prototype.updateElement_ = function() {
Math.pow(10, Math.floor(i / 3)); Math.pow(10, Math.floor(i / 3));
width = Math.round(count / pointResolution); width = Math.round(count / pointResolution);
if (isNaN(width)) { if (isNaN(width)) {
this.element_.style.display = 'none'; this.element.style.display = 'none';
this.renderedVisible_ = false; this.renderedVisible_ = false;
return; return;
} else if (width >= this.minWidth_) { } else if (width >= this.minWidth_) {
@@ -299,10 +272,29 @@ ScaleLine.prototype.updateElement_ = function() {
} }
if (!this.renderedVisible_) { if (!this.renderedVisible_) {
this.element_.style.display = ''; this.element.style.display = '';
this.renderedVisible_ = true; this.renderedVisible_ = true;
} }
}; }
}
/**
* Update the scale line element.
* @param {module:ol/MapEvent} mapEvent Map event.
* @this {module:ol/control/ScaleLine}
* @api
*/
export function render(mapEvent) {
const frameState = mapEvent.frameState;
if (!frameState) {
this.viewState_ = null;
} else {
this.viewState_ = frameState.viewState;
}
this.updateElement_();
}
export default ScaleLine; export default ScaleLine;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/control/Zoom * @module ol/control/Zoom
*/ */
import {inherits} from '../util.js';
import {listen} from '../events.js'; import {listen} from '../events.js';
import EventType from '../events/EventType.js'; import EventType from '../events/EventType.js';
import Control from '../control/Control.js'; import Control from '../control/Control.js';
@@ -13,14 +12,14 @@ import {easeOut} from '../easing.js';
* @typedef {Object} Options * @typedef {Object} Options
* @property {number} [duration=250] Animation duration in milliseconds. * @property {number} [duration=250] Animation duration in milliseconds.
* @property {string} [className='ol-zoom'] CSS class name. * @property {string} [className='ol-zoom'] CSS class name.
* @property {string|Element} [zoomInLabel='+'] Text label to use for the zoom-in * @property {string|HTMLElement} [zoomInLabel='+'] Text label to use for the zoom-in
* button. Instead of text, also an element (e.g. a `span` element) can be used. * button. Instead of text, also an element (e.g. a `span` element) can be used.
* @property {string|Element} [zoomOutLabel='-'] Text label to use for the zoom-out button. * @property {string|HTMLElement} [zoomOutLabel='-'] Text label to use for the zoom-out button.
* Instead of text, also an element (e.g. a `span` element) can be used. * Instead of text, also an element (e.g. a `span` element) can be used.
* @property {string} [zoomInTipLabel='Zoom in'] Text label to use for the button tip. * @property {string} [zoomInTipLabel='Zoom in'] Text label to use for the button tip.
* @property {string} [zoomOutTipLabel='Zoom out'] Text label to use for the button tip. * @property {string} [zoomOutTipLabel='Zoom out'] Text label to use for the button tip.
* @property {number} [delta=1] The zoom delta applied on each click. * @property {number} [delta=1] The zoom delta applied on each click.
* @property {Element|string} [target] Specify a target if you want the control to be * @property {HTMLElement|string} [target] Specify a target if you want the control to be
* rendered outside of the map's viewport. * rendered outside of the map's viewport.
*/ */
@@ -31,15 +30,22 @@ import {easeOut} from '../easing.js';
* This control is one of the default controls of a map. To style this control * This control is one of the default controls of a map. To style this control
* use css selectors `.ol-zoom-in` and `.ol-zoom-out`. * use css selectors `.ol-zoom-in` and `.ol-zoom-out`.
* *
* @constructor
* @extends {module:ol/control/Control}
* @param {module:ol/control/Zoom~Options=} opt_options Zoom options.
* @api * @api
*/ */
const Zoom = function(opt_options) { class Zoom extends Control {
/**
* @param {module:ol/control/Zoom~Options=} opt_options Zoom options.
*/
constructor(opt_options) {
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
super({
element: document.createElement('div'),
target: options.target
});
const className = options.className !== undefined ? options.className : 'ol-zoom'; const className = options.className !== undefined ? options.className : 'ol-zoom';
const delta = options.delta !== undefined ? options.delta : 1; const delta = options.delta !== undefined ? options.delta : 1;
@@ -60,8 +66,7 @@ const Zoom = function(opt_options) {
typeof zoomInLabel === 'string' ? document.createTextNode(zoomInLabel) : zoomInLabel typeof zoomInLabel === 'string' ? document.createTextNode(zoomInLabel) : zoomInLabel
); );
listen(inElement, EventType.CLICK, listen(inElement, EventType.CLICK, this.handleClick_.bind(this, delta));
Zoom.prototype.handleClick_.bind(this, delta));
const outElement = document.createElement('button'); const outElement = document.createElement('button');
outElement.className = className + '-out'; outElement.className = className + '-out';
@@ -71,47 +76,37 @@ const Zoom = function(opt_options) {
typeof zoomOutLabel === 'string' ? document.createTextNode(zoomOutLabel) : zoomOutLabel typeof zoomOutLabel === 'string' ? document.createTextNode(zoomOutLabel) : zoomOutLabel
); );
listen(outElement, EventType.CLICK, listen(outElement, EventType.CLICK, this.handleClick_.bind(this, -delta));
Zoom.prototype.handleClick_.bind(this, -delta));
const cssClasses = className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL; const cssClasses = className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL;
const element = document.createElement('div'); const element = this.element;
element.className = cssClasses; element.className = cssClasses;
element.appendChild(inElement); element.appendChild(inElement);
element.appendChild(outElement); element.appendChild(outElement);
Control.call(this, {
element: element,
target: options.target
});
/** /**
* @type {number} * @type {number}
* @private * @private
*/ */
this.duration_ = options.duration !== undefined ? options.duration : 250; this.duration_ = options.duration !== undefined ? options.duration : 250;
}; }
inherits(Zoom, Control);
/** /**
* @param {number} delta Zoom delta. * @param {number} delta Zoom delta.
* @param {Event} event The event to handle * @param {MouseEvent} event The event to handle
* @private * @private
*/ */
Zoom.prototype.handleClick_ = function(delta, event) { handleClick_(delta, event) {
event.preventDefault(); event.preventDefault();
this.zoomByDelta_(delta); this.zoomByDelta_(delta);
}; }
/** /**
* @param {number} delta Zoom delta. * @param {number} delta Zoom delta.
* @private * @private
*/ */
Zoom.prototype.zoomByDelta_ = function(delta) { zoomByDelta_(delta) {
const map = this.getMap(); const map = this.getMap();
const view = map.getView(); const view = map.getView();
if (!view) { if (!view) {
@@ -135,5 +130,8 @@ Zoom.prototype.zoomByDelta_ = function(delta) {
view.setResolution(newResolution); view.setResolution(newResolution);
} }
} }
}; }
}
export default Zoom; export default Zoom;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/control/ZoomSlider * @module ol/control/ZoomSlider
*/ */
import {inherits} from '../util.js';
import ViewHint from '../ViewHint.js'; import ViewHint from '../ViewHint.js';
import Control from '../control/Control.js'; import Control from '../control/Control.js';
import {CLASS_CONTROL, CLASS_UNSELECTABLE} from '../css.js'; import {CLASS_CONTROL, CLASS_UNSELECTABLE} from '../css.js';
@@ -42,15 +41,22 @@ const Direction = {
* *
* map.addControl(new ZoomSlider()); * map.addControl(new ZoomSlider());
* *
* @constructor
* @extends {module:ol/control/Control}
* @param {module:ol/control/ZoomSlider~Options=} opt_options Zoom slider options.
* @api * @api
*/ */
const ZoomSlider = function(opt_options) { class ZoomSlider extends Control {
/**
* @param {module:ol/control/ZoomSlider~Options=} opt_options Zoom slider options.
*/
constructor(opt_options) {
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
super({
element: document.createElement('div'),
render: options.render || render
});
/** /**
* Will hold the current resolution of the view. * Will hold the current resolution of the view.
* *
@@ -123,7 +129,7 @@ const ZoomSlider = function(opt_options) {
const thumbElement = document.createElement('button'); const thumbElement = document.createElement('button');
thumbElement.setAttribute('type', 'button'); thumbElement.setAttribute('type', 'button');
thumbElement.className = className + '-thumb ' + CLASS_UNSELECTABLE; thumbElement.className = className + '-thumb ' + CLASS_UNSELECTABLE;
const containerElement = document.createElement('div'); const containerElement = this.element;
containerElement.className = className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL; containerElement.className = className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL;
containerElement.appendChild(thumbElement); containerElement.appendChild(thumbElement);
/** /**
@@ -141,35 +147,25 @@ const ZoomSlider = function(opt_options) {
listen(containerElement, EventType.CLICK, this.handleContainerClick_, this); listen(containerElement, EventType.CLICK, this.handleContainerClick_, this);
listen(thumbElement, EventType.CLICK, stopPropagation); listen(thumbElement, EventType.CLICK, stopPropagation);
}
Control.call(this, {
element: containerElement,
render: options.render || render
});
};
inherits(ZoomSlider, Control);
/** /**
* @inheritDoc * @inheritDoc
*/ */
ZoomSlider.prototype.disposeInternal = function() { disposeInternal() {
this.dragger_.dispose(); this.dragger_.dispose();
Control.prototype.disposeInternal.call(this); super.disposeInternal();
}; }
/** /**
* @inheritDoc * @inheritDoc
*/ */
ZoomSlider.prototype.setMap = function(map) { setMap(map) {
Control.prototype.setMap.call(this, map); super.setMap(map);
if (map) { if (map) {
map.render(); map.render();
} }
}; }
/** /**
* Initializes the slider element. This will determine and set this controls * Initializes the slider element. This will determine and set this controls
@@ -178,13 +174,13 @@ ZoomSlider.prototype.setMap = function(map) {
* *
* @private * @private
*/ */
ZoomSlider.prototype.initSlider_ = function() { initSlider_() {
const container = this.element; const container = this.element;
const containerSize = { const containerSize = {
width: container.offsetWidth, height: container.offsetHeight width: container.offsetWidth, height: container.offsetHeight
}; };
const thumb = container.firstElementChild; const thumb = /** @type {HTMLElement} */ (container.firstElementChild);
const computedStyle = getComputedStyle(thumb); const computedStyle = getComputedStyle(thumb);
const thumbWidth = thumb.offsetWidth + const thumbWidth = thumb.offsetWidth +
parseFloat(computedStyle['marginRight']) + parseFloat(computedStyle['marginRight']) +
@@ -202,7 +198,148 @@ ZoomSlider.prototype.initSlider_ = function() {
this.heightLimit_ = containerSize.height - thumbHeight; this.heightLimit_ = containerSize.height - thumbHeight;
} }
this.sliderInitialized_ = true; this.sliderInitialized_ = true;
}; }
/**
* @param {MouseEvent} event The browser event to handle.
* @private
*/
handleContainerClick_(event) {
const view = this.getMap().getView();
const relativePosition = this.getRelativePosition_(
event.offsetX - this.thumbSize_[0] / 2,
event.offsetY - this.thumbSize_[1] / 2);
const resolution = this.getResolutionForPosition_(relativePosition);
view.animate({
resolution: view.constrainResolution(resolution),
duration: this.duration_,
easing: easeOut
});
}
/**
* Handle dragger start events.
* @param {module:ol/pointer/PointerEvent} event The drag event.
* @private
*/
handleDraggerStart_(event) {
if (!this.dragging_ && event.originalEvent.target === this.element.firstElementChild) {
this.getMap().getView().setHint(ViewHint.INTERACTING, 1);
this.previousX_ = event.clientX;
this.previousY_ = event.clientY;
this.dragging_ = true;
}
}
/**
* Handle dragger drag events.
*
* @param {module:ol/pointer/PointerEvent|Event} event The drag event.
* @private
*/
handleDraggerDrag_(event) {
if (this.dragging_) {
const element = /** @type {HTMLElement} */ (this.element.firstElementChild);
const deltaX = event.clientX - this.previousX_ + parseInt(element.style.left, 10);
const deltaY = event.clientY - this.previousY_ + parseInt(element.style.top, 10);
const relativePosition = this.getRelativePosition_(deltaX, deltaY);
this.currentResolution_ = this.getResolutionForPosition_(relativePosition);
this.getMap().getView().setResolution(this.currentResolution_);
this.setThumbPosition_(this.currentResolution_);
this.previousX_ = event.clientX;
this.previousY_ = event.clientY;
}
}
/**
* Handle dragger end events.
* @param {module:ol/pointer/PointerEvent|Event} event The drag event.
* @private
*/
handleDraggerEnd_(event) {
if (this.dragging_) {
const view = this.getMap().getView();
view.setHint(ViewHint.INTERACTING, -1);
view.animate({
resolution: view.constrainResolution(this.currentResolution_),
duration: this.duration_,
easing: easeOut
});
this.dragging_ = false;
this.previousX_ = undefined;
this.previousY_ = undefined;
}
}
/**
* Positions the thumb inside its container according to the given resolution.
*
* @param {number} res The res.
* @private
*/
setThumbPosition_(res) {
const position = this.getPositionForResolution_(res);
const thumb = /** @type {HTMLElement} */ (this.element.firstElementChild);
if (this.direction_ == Direction.HORIZONTAL) {
thumb.style.left = this.widthLimit_ * position + 'px';
} else {
thumb.style.top = this.heightLimit_ * position + 'px';
}
}
/**
* Calculates the relative position of the thumb given x and y offsets. The
* relative position scales from 0 to 1. The x and y offsets are assumed to be
* in pixel units within the dragger limits.
*
* @param {number} x Pixel position relative to the left of the slider.
* @param {number} y Pixel position relative to the top of the slider.
* @return {number} The relative position of the thumb.
* @private
*/
getRelativePosition_(x, y) {
let amount;
if (this.direction_ === Direction.HORIZONTAL) {
amount = x / this.widthLimit_;
} else {
amount = y / this.heightLimit_;
}
return clamp(amount, 0, 1);
}
/**
* Calculates the corresponding resolution of the thumb given its relative
* position (where 0 is the minimum and 1 is the maximum).
*
* @param {number} position The relative position of the thumb.
* @return {number} The corresponding resolution.
* @private
*/
getResolutionForPosition_(position) {
const fn = this.getMap().getView().getResolutionForValueFunction();
return fn(1 - position);
}
/**
* Determines the relative position of the slider for the given resolution. A
* relative position of 0 corresponds to the minimum view resolution. A
* relative position of 1 corresponds to the maximum view resolution.
*
* @param {number} res The resolution.
* @return {number} The relative position value (between 0 and 1).
* @private
*/
getPositionForResolution_(res) {
const fn = this.getMap().getView().getValueForResolutionFunction();
return 1 - fn(res);
}
}
/** /**
@@ -226,151 +363,4 @@ export function render(mapEvent) {
} }
/**
* @param {Event} event The browser event to handle.
* @private
*/
ZoomSlider.prototype.handleContainerClick_ = function(event) {
const view = this.getMap().getView();
const relativePosition = this.getRelativePosition_(
event.offsetX - this.thumbSize_[0] / 2,
event.offsetY - this.thumbSize_[1] / 2);
const resolution = this.getResolutionForPosition_(relativePosition);
view.animate({
resolution: view.constrainResolution(resolution),
duration: this.duration_,
easing: easeOut
});
};
/**
* Handle dragger start events.
* @param {module:ol/pointer/PointerEvent} event The drag event.
* @private
*/
ZoomSlider.prototype.handleDraggerStart_ = function(event) {
if (!this.dragging_ && event.originalEvent.target === this.element.firstElementChild) {
this.getMap().getView().setHint(ViewHint.INTERACTING, 1);
this.previousX_ = event.clientX;
this.previousY_ = event.clientY;
this.dragging_ = true;
}
};
/**
* Handle dragger drag events.
*
* @param {module:ol/pointer/PointerEvent|Event} event The drag event.
* @private
*/
ZoomSlider.prototype.handleDraggerDrag_ = function(event) {
if (this.dragging_) {
const element = this.element.firstElementChild;
const deltaX = event.clientX - this.previousX_ + parseInt(element.style.left, 10);
const deltaY = event.clientY - this.previousY_ + parseInt(element.style.top, 10);
const relativePosition = this.getRelativePosition_(deltaX, deltaY);
this.currentResolution_ = this.getResolutionForPosition_(relativePosition);
this.getMap().getView().setResolution(this.currentResolution_);
this.setThumbPosition_(this.currentResolution_);
this.previousX_ = event.clientX;
this.previousY_ = event.clientY;
}
};
/**
* Handle dragger end events.
* @param {module:ol/pointer/PointerEvent|Event} event The drag event.
* @private
*/
ZoomSlider.prototype.handleDraggerEnd_ = function(event) {
if (this.dragging_) {
const view = this.getMap().getView();
view.setHint(ViewHint.INTERACTING, -1);
view.animate({
resolution: view.constrainResolution(this.currentResolution_),
duration: this.duration_,
easing: easeOut
});
this.dragging_ = false;
this.previousX_ = undefined;
this.previousY_ = undefined;
}
};
/**
* Positions the thumb inside its container according to the given resolution.
*
* @param {number} res The res.
* @private
*/
ZoomSlider.prototype.setThumbPosition_ = function(res) {
const position = this.getPositionForResolution_(res);
const thumb = this.element.firstElementChild;
if (this.direction_ == Direction.HORIZONTAL) {
thumb.style.left = this.widthLimit_ * position + 'px';
} else {
thumb.style.top = this.heightLimit_ * position + 'px';
}
};
/**
* Calculates the relative position of the thumb given x and y offsets. The
* relative position scales from 0 to 1. The x and y offsets are assumed to be
* in pixel units within the dragger limits.
*
* @param {number} x Pixel position relative to the left of the slider.
* @param {number} y Pixel position relative to the top of the slider.
* @return {number} The relative position of the thumb.
* @private
*/
ZoomSlider.prototype.getRelativePosition_ = function(x, y) {
let amount;
if (this.direction_ === Direction.HORIZONTAL) {
amount = x / this.widthLimit_;
} else {
amount = y / this.heightLimit_;
}
return clamp(amount, 0, 1);
};
/**
* Calculates the corresponding resolution of the thumb given its relative
* position (where 0 is the minimum and 1 is the maximum).
*
* @param {number} position The relative position of the thumb.
* @return {number} The corresponding resolution.
* @private
*/
ZoomSlider.prototype.getResolutionForPosition_ = function(position) {
const fn = this.getMap().getView().getResolutionForValueFunction();
return fn(1 - position);
};
/**
* Determines the relative position of the slider for the given resolution. A
* relative position of 0 corresponds to the minimum view resolution. A
* relative position of 1 corresponds to the maximum view resolution.
*
* @param {number} res The resolution.
* @return {number} The relative position value (between 0 and 1).
* @private
*/
ZoomSlider.prototype.getPositionForResolution_ = function(res) {
const fn = this.getMap().getView().getValueForResolutionFunction();
return 1 - fn(res);
};
export default ZoomSlider; export default ZoomSlider;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/control/ZoomToExtent * @module ol/control/ZoomToExtent
*/ */
import {inherits} from '../util.js';
import {listen} from '../events.js'; import {listen} from '../events.js';
import EventType from '../events/EventType.js'; import EventType from '../events/EventType.js';
import Control from '../control/Control.js'; import Control from '../control/Control.js';
@@ -11,9 +10,9 @@ import {CLASS_CONTROL, CLASS_UNSELECTABLE} from '../css.js';
/** /**
* @typedef {Object} Options * @typedef {Object} Options
* @property {string} [className='ol-zoom-extent'] Class name. * @property {string} [className='ol-zoom-extent'] Class name.
* @property {Element|string} [target] Specify a target if you want the control * @property {HTMLElement|string} [target] Specify a target if you want the control
* to be rendered outside of the map's viewport. * to be rendered outside of the map's viewport.
* @property {string|Element} [label='E'] Text label to use for the button. * @property {string|HTMLElement} [label='E'] Text label to use for the button.
* Instead of text, also an element (e.g. a `span` element) can be used. * Instead of text, also an element (e.g. a `span` element) can be used.
* @property {string} [tipLabel='Fit to extent'] Text label to use for the button tip. * @property {string} [tipLabel='Fit to extent'] Text label to use for the button tip.
* @property {module:ol/extent~Extent} [extent] The extent to zoom to. If undefined the validity * @property {module:ol/extent~Extent} [extent] The extent to zoom to. If undefined the validity
@@ -26,14 +25,21 @@ import {CLASS_CONTROL, CLASS_UNSELECTABLE} from '../css.js';
* A button control which, when pressed, changes the map view to a specific * A button control which, when pressed, changes the map view to a specific
* extent. To style this control use the css selector `.ol-zoom-extent`. * extent. To style this control use the css selector `.ol-zoom-extent`.
* *
* @constructor
* @extends {module:ol/control/Control}
* @param {module:ol/control/ZoomToExtent~Options=} opt_options Options.
* @api * @api
*/ */
const ZoomToExtent = function(opt_options) { class ZoomToExtent extends Control {
/**
* @param {module:ol/control/ZoomToExtent~Options=} opt_options Options.
*/
constructor(opt_options) {
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
super({
element: document.createElement('div'),
target: options.target
});
/** /**
* @type {module:ol/extent~Extent} * @type {module:ol/extent~Extent}
* @protected * @protected
@@ -54,36 +60,29 @@ const ZoomToExtent = function(opt_options) {
listen(button, EventType.CLICK, this.handleClick_, this); listen(button, EventType.CLICK, this.handleClick_, this);
const cssClasses = className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL; const cssClasses = className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL;
const element = document.createElement('div'); const element = this.element;
element.className = cssClasses; element.className = cssClasses;
element.appendChild(button); element.appendChild(button);
}
Control.call(this, {
element: element,
target: options.target
});
};
inherits(ZoomToExtent, Control);
/** /**
* @param {Event} event The event to handle * @param {MouseEvent} event The event to handle
* @private * @private
*/ */
ZoomToExtent.prototype.handleClick_ = function(event) { handleClick_(event) {
event.preventDefault(); event.preventDefault();
this.handleZoomToExtent(); this.handleZoomToExtent();
}; }
/** /**
* @protected * @protected
*/ */
ZoomToExtent.prototype.handleZoomToExtent = function() { handleZoomToExtent() {
const map = this.getMap(); const map = this.getMap();
const view = map.getView(); const view = map.getView();
const extent = !this.extent ? view.getProjection().getExtent() : this.extent; const extent = !this.extent ? view.getProjection().getExtent() : this.extent;
view.fit(extent); view.fit(extent);
}; }
}
export default ZoomToExtent; export default ZoomToExtent;

View File

@@ -25,7 +25,7 @@ export function createCanvasContext2D(opt_width, opt_height) {
* Get the current computed width for the given element including margin, * Get the current computed width for the given element including margin,
* padding and border. * padding and border.
* Equivalent to jQuery's `$(el).outerWidth(true)`. * Equivalent to jQuery's `$(el).outerWidth(true)`.
* @param {!Element} element Element. * @param {!HTMLElement} element Element.
* @return {number} The width. * @return {number} The width.
*/ */
export function outerWidth(element) { export function outerWidth(element) {
@@ -41,7 +41,7 @@ export function outerWidth(element) {
* Get the current computed height for the given element including margin, * Get the current computed height for the given element including margin,
* padding and border. * padding and border.
* Equivalent to jQuery's `$(el).outerHeight(true)`. * Equivalent to jQuery's `$(el).outerHeight(true)`.
* @param {!Element} element Element. * @param {!HTMLElement} element Element.
* @return {number} The height. * @return {number} The height.
*/ */
export function outerHeight(element) { export function outerHeight(element) {

View File

@@ -127,7 +127,7 @@ function removeListeners(target, type) {
/** /**
* Registers an event listener on an event target. Inspired by * Registers an event listener on an event target. Inspired by
* {@link https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html} * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html
* *
* This function efficiently binds a `listener` to a `this` object, and returns * This function efficiently binds a `listener` to a `this` object, and returns
* a key for use with {@link module:ol/events~unlistenByKey}. * a key for use with {@link module:ol/events~unlistenByKey}.
@@ -170,7 +170,7 @@ export function listen(target, type, listener, opt_this, opt_once) {
/** /**
* Registers a one-off event listener on an event target. Inspired by * Registers a one-off event listener on an event target. Inspired by
* {@link https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html} * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html
* *
* This function efficiently binds a `listener` as self-unregistering listener * This function efficiently binds a `listener` as self-unregistering listener
* to a `this` object, and returns a key for use with * to a `this` object, and returns a key for use with
@@ -195,7 +195,7 @@ export function listenOnce(target, type, listener, opt_this) {
/** /**
* Unregisters an event listener on an event target. Inspired by * Unregisters an event listener on an event target. Inspired by
* {@link https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html} * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html
* *
* To return a listener, this function needs to be called with the exact same * To return a listener, this function needs to be called with the exact same
* arguments that were used for a previous {@link module:ol/events~listen} call. * arguments that were used for a previous {@link module:ol/events~listen} call.
@@ -219,7 +219,7 @@ export function unlisten(target, type, listener, opt_this) {
/** /**
* Unregisters event listeners on an event target. Inspired by * Unregisters event listeners on an event target. Inspired by
* {@link https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html} * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html
* *
* The argument passed to this function is the key returned from * The argument passed to this function is the key returned from
* {@link module:ol/events~listen} or {@link module:ol/events~listenOnce}. * {@link module:ol/events~listen} or {@link module:ol/events~listenOnce}.
@@ -246,7 +246,7 @@ export function unlistenByKey(key) {
/** /**
* Unregisters all event listeners on an event target. Inspired by * Unregisters all event listeners on an event target. Inspired by
* {@link https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html} * https://google.github.io/closure-library/api/source/closure/goog/events/events.js.src.html
* *
* @param {module:ol/events/EventTarget~EventTargetLike} target Target. * @param {module:ol/events/EventTarget~EventTargetLike} target Target.
*/ */

View File

@@ -1,20 +1,23 @@
/** /**
* @module ol/events/Event * @module ol/events/Event
*/ */
/** /**
* @classdesc * @classdesc
* Stripped down implementation of the W3C DOM Level 2 Event interface. * Stripped down implementation of the W3C DOM Level 2 Event interface.
* @see {@link https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-interface} * See https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-interface.
* *
* This implementation only provides `type` and `target` properties, and * This implementation only provides `type` and `target` properties, and
* `stopPropagation` and `preventDefault` methods. It is meant as base class * `stopPropagation` and `preventDefault` methods. It is meant as base class
* for higher level events defined in the library, and works with * for higher level events defined in the library, and works with
* {@link module:ol/events/EventTarget~EventTarget}. * {@link module:ol/events/EventTarget~EventTarget}.
* */
* @constructor class Event {
/**
* @param {string} type Type. * @param {string} type Type.
*/ */
const Event = function(type) { constructor(type) {
/** /**
* @type {boolean} * @type {boolean}
@@ -34,25 +37,27 @@ const Event = function(type) {
* @api * @api
*/ */
this.target = null; this.target = null;
}
};
/** /**
* Stop event propagation. * Stop event propagation.
* @function * @function
* @api * @api
*/ */
Event.prototype.preventDefault = preventDefault() {
/**
* Stop event propagation.
* @function
* @api
*/
Event.prototype.stopPropagation = function() {
this.propagationStopped = true; this.propagationStopped = true;
}; }
/**
* Stop event propagation.
* @function
* @api
*/
stopPropagation() {
this.propagationStopped = true;
}
}
/** /**

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/events/EventTarget * @module ol/events/EventTarget
*/ */
import {inherits} from '../util.js';
import Disposable from '../Disposable.js'; import Disposable from '../Disposable.js';
import {unlistenAll} from '../events.js'; import {unlistenAll} from '../events.js';
import {UNDEFINED} from '../functions.js'; import {UNDEFINED} from '../functions.js';
@@ -16,7 +15,7 @@ import Event from '../events/Event.js';
/** /**
* @classdesc * @classdesc
* A simplified implementation of the W3C DOM Level 2 EventTarget interface. * A simplified implementation of the W3C DOM Level 2 EventTarget interface.
* @see {@link https://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-EventTarget} * See https://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-EventTarget.
* *
* There are two important simplifications compared to the specification: * There are two important simplifications compared to the specification:
* *
@@ -27,13 +26,11 @@ import Event from '../events/Event.js';
* `stopPropagation` or `preventDefault` on an event object, it means that no * `stopPropagation` or `preventDefault` on an event object, it means that no
* more listeners after this one will be called. Same as when the listener * more listeners after this one will be called. Same as when the listener
* returns false. * returns false.
*
* @constructor
* @extends {module:ol/Disposable}
*/ */
const EventTarget = function() { class EventTarget extends Disposable {
constructor() {
Disposable.call(this); super();
/** /**
* @private * @private
@@ -53,16 +50,13 @@ const EventTarget = function() {
*/ */
this.listeners_ = {}; this.listeners_ = {};
}; }
inherits(EventTarget, Disposable);
/** /**
* @param {string} type Type. * @param {string} type Type.
* @param {module:ol/events~ListenerFunction} listener Listener. * @param {module:ol/events~ListenerFunction} listener Listener.
*/ */
EventTarget.prototype.addEventListener = function(type, listener) { addEventListener(type, listener) {
let listeners = this.listeners_[type]; let listeners = this.listeners_[type];
if (!listeners) { if (!listeners) {
listeners = this.listeners_[type] = []; listeners = this.listeners_[type] = [];
@@ -70,17 +64,22 @@ EventTarget.prototype.addEventListener = function(type, listener) {
if (listeners.indexOf(listener) === -1) { if (listeners.indexOf(listener) === -1) {
listeners.push(listener); listeners.push(listener);
} }
}; }
/** /**
* Dispatches an event and calls all listeners listening for events
* of this type. The event parameter can either be a string or an
* Object with a `type` property.
*
* @param {{type: string, * @param {{type: string,
* target: (EventTarget|module:ol/events/EventTarget|undefined)}|module:ol/events/Event| * target: (EventTarget|module:ol/events/EventTarget|undefined)}|
* string} event Event or event type. * module:ol/events/Event|string} event Event object.
* @return {boolean|undefined} `false` if anyone called preventDefault on the * @return {boolean|undefined} `false` if anyone called preventDefault on the
* event object or if any of the listeners returned false. * event object or if any of the listeners returned false.
* @function
* @api
*/ */
EventTarget.prototype.dispatchEvent = function(event) { dispatchEvent(event) {
const evt = typeof event === 'string' ? new Event(event) : event; const evt = typeof event === 'string' ? new Event(event) : event;
const type = evt.type; const type = evt.type;
evt.target = this; evt.target = this;
@@ -109,16 +108,14 @@ EventTarget.prototype.dispatchEvent = function(event) {
} }
return propagate; return propagate;
} }
}; }
/** /**
* @inheritDoc * @inheritDoc
*/ */
EventTarget.prototype.disposeInternal = function() { disposeInternal() {
unlistenAll(this); unlistenAll(this);
}; }
/** /**
* Get the listeners for a specified event type. Listeners are returned in the * Get the listeners for a specified event type. Listeners are returned in the
@@ -127,28 +124,26 @@ EventTarget.prototype.disposeInternal = function() {
* @param {string} type Type. * @param {string} type Type.
* @return {Array.<module:ol/events~ListenerFunction>} Listeners. * @return {Array.<module:ol/events~ListenerFunction>} Listeners.
*/ */
EventTarget.prototype.getListeners = function(type) { getListeners(type) {
return this.listeners_[type]; return this.listeners_[type];
}; }
/** /**
* @param {string=} opt_type Type. If not provided, * @param {string=} opt_type Type. If not provided,
* `true` will be returned if this EventTarget has any listeners. * `true` will be returned if this EventTarget has any listeners.
* @return {boolean} Has listeners. * @return {boolean} Has listeners.
*/ */
EventTarget.prototype.hasListener = function(opt_type) { hasListener(opt_type) {
return opt_type ? return opt_type ?
opt_type in this.listeners_ : opt_type in this.listeners_ :
Object.keys(this.listeners_).length > 0; Object.keys(this.listeners_).length > 0;
}; }
/** /**
* @param {string} type Type. * @param {string} type Type.
* @param {module:ol/events~ListenerFunction} listener Listener. * @param {module:ol/events~ListenerFunction} listener Listener.
*/ */
EventTarget.prototype.removeEventListener = function(type, listener) { removeEventListener(type, listener) {
const listeners = this.listeners_[type]; const listeners = this.listeners_[type];
if (listeners) { if (listeners) {
const index = listeners.indexOf(listener); const index = listeners.indexOf(listener);
@@ -163,5 +158,8 @@ EventTarget.prototype.removeEventListener = function(type, listener) {
} }
} }
} }
}; }
}
export default EventTarget; export default EventTarget;

View File

@@ -237,7 +237,7 @@ export const mouseOnly = function(mapBrowserEvent) {
/** /**
* Return `true` if the event originates from a primary pointer in * Return `true` if the event originates from a primary pointer in
* contact with the surface or if the left mouse button is pressed. * contact with the surface or if the left mouse button is pressed.
* @see http://www.w3.org/TR/pointerevents/#button-states * See http://www.w3.org/TR/pointerevents/#button-states.
* *
* @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event. * @param {module:ol/MapBrowserEvent} mapBrowserEvent Map browser event.
* @return {boolean} True if the event originates from a primary pointer. * @return {boolean} True if the event originates from a primary pointer.

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/format/EsriJSON * @module ol/format/EsriJSON
*/ */
import {inherits} from '../util.js';
import Feature from '../Feature.js'; import Feature from '../Feature.js';
import {assert} from '../asserts.js'; import {assert} from '../asserts.js';
import {containsExtent} from '../extent.js'; import {containsExtent} from '../extent.js';
@@ -58,16 +57,18 @@ GEOMETRY_WRITERS[GeometryType.MULTI_POLYGON] = writeMultiPolygonGeometry;
* @classdesc * @classdesc
* Feature format for reading and writing data in the EsriJSON format. * Feature format for reading and writing data in the EsriJSON format.
* *
* @constructor
* @extends {module:ol/format/JSONFeature}
* @param {module:ol/format/EsriJSON~Options=} opt_options Options.
* @api * @api
*/ */
const EsriJSON = function(opt_options) { class EsriJSON extends JSONFeature {
/**
* @param {module:ol/format/EsriJSON~Options=} opt_options Options.
*/
constructor(opt_options) {
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
JSONFeature.call(this); super();
/** /**
* Name of the geometry attribute for features. * Name of the geometry attribute for features.
@@ -76,9 +77,134 @@ const EsriJSON = function(opt_options) {
*/ */
this.geometryName_ = options.geometryName; this.geometryName_ = options.geometryName;
}; }
inherits(EsriJSON, JSONFeature); /**
* @inheritDoc
*/
readFeatureFromObject(object, opt_options) {
const esriJSONFeature = /** @type {EsriJSONFeature} */ (object);
const geometry = readGeometry(esriJSONFeature.geometry, opt_options);
const feature = new Feature();
if (this.geometryName_) {
feature.setGeometryName(this.geometryName_);
}
feature.setGeometry(geometry);
if (opt_options && opt_options.idField &&
esriJSONFeature.attributes[opt_options.idField]) {
feature.setId(/** @type {number} */(esriJSONFeature.attributes[opt_options.idField]));
}
if (esriJSONFeature.attributes) {
feature.setProperties(esriJSONFeature.attributes);
}
return feature;
}
/**
* @inheritDoc
*/
readFeaturesFromObject(object, opt_options) {
const esriJSONObject = /** @type {EsriJSONObject} */ (object);
const options = opt_options ? opt_options : {};
if (esriJSONObject.features) {
const esriJSONFeatureCollection = /** @type {EsriJSONFeatureCollection} */ (object);
/** @type {Array.<module:ol/Feature>} */
const features = [];
const esriJSONFeatures = esriJSONFeatureCollection.features;
options.idField = object.objectIdFieldName;
for (let i = 0, ii = esriJSONFeatures.length; i < ii; ++i) {
features.push(this.readFeatureFromObject(esriJSONFeatures[i], options));
}
return features;
} else {
return [this.readFeatureFromObject(object, options)];
}
}
/**
* @inheritDoc
*/
readGeometryFromObject(object, opt_options) {
return readGeometry(/** @type {EsriJSONGeometry} */(object), opt_options);
}
/**
* @inheritDoc
*/
readProjectionFromObject(object) {
const esriJSONObject = /** @type {EsriJSONObject} */ (object);
if (esriJSONObject.spatialReference && esriJSONObject.spatialReference.wkid) {
const crs = esriJSONObject.spatialReference.wkid;
return getProjection('EPSG:' + crs);
} else {
return null;
}
}
/**
* Encode a geometry as a EsriJSON object.
*
* @param {module:ol/geom/Geometry} geometry Geometry.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {EsriJSONGeometry} Object.
* @override
* @api
*/
writeGeometryObject(geometry, opt_options) {
return writeGeometry(geometry, this.adaptOptions(opt_options));
}
/**
* Encode a feature as a esriJSON Feature object.
*
* @param {module:ol/Feature} feature Feature.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {Object} Object.
* @override
* @api
*/
writeFeatureObject(feature, opt_options) {
opt_options = this.adaptOptions(opt_options);
const object = {};
const geometry = feature.getGeometry();
if (geometry) {
object['geometry'] = writeGeometry(geometry, opt_options);
if (opt_options && opt_options.featureProjection) {
object['geometry']['spatialReference'] = /** @type {EsriJSONCRS} */({
wkid: getProjection(opt_options.featureProjection).getCode().split(':').pop()
});
}
}
const properties = feature.getProperties();
delete properties[feature.getGeometryName()];
if (!isEmpty(properties)) {
object['attributes'] = properties;
} else {
object['attributes'] = {};
}
return object;
}
/**
* Encode an array of features as a EsriJSON object.
*
* @param {Array.<module:ol/Feature>} features Features.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {Object} EsriJSON Object.
* @override
* @api
*/
writeFeaturesObject(features, opt_options) {
opt_options = this.adaptOptions(opt_options);
const objects = [];
for (let i = 0, ii = features.length; i < ii; ++i) {
objects.push(this.writeFeatureObject(features[i], opt_options));
}
return /** @type {EsriJSONFeatureCollection} */ ({
'features': objects
});
}
}
/** /**
@@ -413,121 +539,6 @@ function writeMultiPolygonGeometry(geometry, opt_options) {
} }
/**
* Read a feature from a EsriJSON Feature source. Only works for Feature,
* use `readFeatures` to read FeatureCollection source.
*
* @function
* @param {ArrayBuffer|Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {module:ol/Feature} Feature.
* @api
*/
EsriJSON.prototype.readFeature;
/**
* Read all features from a EsriJSON source. Works with both Feature and
* FeatureCollection sources.
*
* @function
* @param {ArrayBuffer|Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {Array.<module:ol/Feature>} Features.
* @api
*/
EsriJSON.prototype.readFeatures;
/**
* @inheritDoc
*/
EsriJSON.prototype.readFeatureFromObject = function(object, opt_options) {
const esriJSONFeature = /** @type {EsriJSONFeature} */ (object);
const geometry = readGeometry(esriJSONFeature.geometry, opt_options);
const feature = new Feature();
if (this.geometryName_) {
feature.setGeometryName(this.geometryName_);
}
feature.setGeometry(geometry);
if (opt_options && opt_options.idField &&
esriJSONFeature.attributes[opt_options.idField]) {
feature.setId(/** @type {number} */(esriJSONFeature.attributes[opt_options.idField]));
}
if (esriJSONFeature.attributes) {
feature.setProperties(esriJSONFeature.attributes);
}
return feature;
};
/**
* @inheritDoc
*/
EsriJSON.prototype.readFeaturesFromObject = function(object, opt_options) {
const esriJSONObject = /** @type {EsriJSONObject} */ (object);
const options = opt_options ? opt_options : {};
if (esriJSONObject.features) {
const esriJSONFeatureCollection = /** @type {EsriJSONFeatureCollection} */ (object);
/** @type {Array.<module:ol/Feature>} */
const features = [];
const esriJSONFeatures = esriJSONFeatureCollection.features;
options.idField = object.objectIdFieldName;
for (let i = 0, ii = esriJSONFeatures.length; i < ii; ++i) {
features.push(this.readFeatureFromObject(esriJSONFeatures[i], options));
}
return features;
} else {
return [this.readFeatureFromObject(object, options)];
}
};
/**
* Read a geometry from a EsriJSON source.
*
* @function
* @param {ArrayBuffer|Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {module:ol/geom/Geometry} Geometry.
* @api
*/
EsriJSON.prototype.readGeometry;
/**
* @inheritDoc
*/
EsriJSON.prototype.readGeometryFromObject = function(object, opt_options) {
return readGeometry(/** @type {EsriJSONGeometry} */(object), opt_options);
};
/**
* Read the projection from a EsriJSON source.
*
* @function
* @param {ArrayBuffer|Document|Node|Object|string} source Source.
* @return {module:ol/proj/Projection} Projection.
* @api
*/
EsriJSON.prototype.readProjection;
/**
* @inheritDoc
*/
EsriJSON.prototype.readProjectionFromObject = function(object) {
const esriJSONObject = /** @type {EsriJSONObject} */ (object);
if (esriJSONObject.spatialReference && esriJSONObject.spatialReference.wkid) {
const crs = esriJSONObject.spatialReference.wkid;
return getProjection('EPSG:' + crs);
} else {
return null;
}
};
/** /**
* @param {module:ol/geom/Geometry} geometry Geometry. * @param {module:ol/geom/Geometry} geometry Geometry.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options. * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
@@ -540,106 +551,4 @@ function writeGeometry(geometry, opt_options) {
} }
/**
* Encode a geometry as a EsriJSON string.
*
* @function
* @param {module:ol/geom/Geometry} geometry Geometry.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {string} EsriJSON.
* @api
*/
EsriJSON.prototype.writeGeometry;
/**
* Encode a geometry as a EsriJSON object.
*
* @param {module:ol/geom/Geometry} geometry Geometry.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {EsriJSONGeometry} Object.
* @override
* @api
*/
EsriJSON.prototype.writeGeometryObject = function(geometry, opt_options) {
return writeGeometry(geometry, this.adaptOptions(opt_options));
};
/**
* Encode a feature as a EsriJSON Feature string.
*
* @function
* @param {module:ol/Feature} feature Feature.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {string} EsriJSON.
* @api
*/
EsriJSON.prototype.writeFeature;
/**
* Encode a feature as a esriJSON Feature object.
*
* @param {module:ol/Feature} feature Feature.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {Object} Object.
* @override
* @api
*/
EsriJSON.prototype.writeFeatureObject = function(feature, opt_options) {
opt_options = this.adaptOptions(opt_options);
const object = {};
const geometry = feature.getGeometry();
if (geometry) {
object['geometry'] = writeGeometry(geometry, opt_options);
if (opt_options && opt_options.featureProjection) {
object['geometry']['spatialReference'] = /** @type {EsriJSONCRS} */({
wkid: getProjection(opt_options.featureProjection).getCode().split(':').pop()
});
}
}
const properties = feature.getProperties();
delete properties[feature.getGeometryName()];
if (!isEmpty(properties)) {
object['attributes'] = properties;
} else {
object['attributes'] = {};
}
return object;
};
/**
* Encode an array of features as EsriJSON.
*
* @function
* @param {Array.<module:ol/Feature>} features Features.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {string} EsriJSON.
* @api
*/
EsriJSON.prototype.writeFeatures;
/**
* Encode an array of features as a EsriJSON object.
*
* @param {Array.<module:ol/Feature>} features Features.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {Object} EsriJSON Object.
* @override
* @api
*/
EsriJSON.prototype.writeFeaturesObject = function(features, opt_options) {
opt_options = this.adaptOptions(opt_options);
const objects = [];
for (let i = 0, ii = features.length; i < ii; ++i) {
objects.push(this.writeFeatureObject(features[i], opt_options));
}
return /** @type {EsriJSONFeatureCollection} */ ({
'features': objects
});
};
export default EsriJSON; export default EsriJSON;

View File

@@ -56,11 +56,11 @@ import {get as getProjection, equivalent as equivalentProjection, transformExten
* {@link module:ol/Feature~Feature} objects from a variety of commonly used geospatial * {@link module:ol/Feature~Feature} objects from a variety of commonly used geospatial
* file formats. See the documentation for each format for more details. * file formats. See the documentation for each format for more details.
* *
* @constructor
* @abstract * @abstract
* @api * @api
*/ */
const FeatureFormat = function() { class FeatureFormat {
constructor() {
/** /**
* @protected * @protected
@@ -74,8 +74,7 @@ const FeatureFormat = function() {
*/ */
this.defaultFeatureProjection = null; this.defaultFeatureProjection = null;
}; }
/** /**
* Adds the data projection to the read options. * Adds the data projection to the read options.
@@ -84,7 +83,7 @@ const FeatureFormat = function() {
* @return {module:ol/format/Feature~ReadOptions|undefined} Options. * @return {module:ol/format/Feature~ReadOptions|undefined} Options.
* @protected * @protected
*/ */
FeatureFormat.prototype.getReadOptions = function(source, opt_options) { getReadOptions(source, opt_options) {
let options; let options;
if (opt_options) { if (opt_options) {
options = { options = {
@@ -94,8 +93,7 @@ FeatureFormat.prototype.getReadOptions = function(source, opt_options) {
}; };
} }
return this.adaptOptions(options); return this.adaptOptions(options);
}; }
/** /**
* Sets the `dataProjection` on the options, if no `dataProjection` * Sets the `dataProjection` on the options, if no `dataProjection`
@@ -106,29 +104,26 @@ FeatureFormat.prototype.getReadOptions = function(source, opt_options) {
* @return {module:ol/format/Feature~WriteOptions|module:ol/format/Feature~ReadOptions|undefined} * @return {module:ol/format/Feature~WriteOptions|module:ol/format/Feature~ReadOptions|undefined}
* Updated options. * Updated options.
*/ */
FeatureFormat.prototype.adaptOptions = function(options) { adaptOptions(options) {
return assign({ return assign({
dataProjection: this.dataProjection, dataProjection: this.dataProjection,
featureProjection: this.defaultFeatureProjection featureProjection: this.defaultFeatureProjection
}, options); }, options);
}; }
/** /**
* Get the extent from the source of the last {@link readFeatures} call. * Get the extent from the source of the last {@link readFeatures} call.
* @return {module:ol/extent~Extent} Tile extent. * @return {module:ol/extent~Extent} Tile extent.
*/ */
FeatureFormat.prototype.getLastExtent = function() { getLastExtent() {
return null; return null;
}; }
/** /**
* @abstract * @abstract
* @return {module:ol/format/FormatType} Format. * @return {module:ol/format/FormatType} Format.
*/ */
FeatureFormat.prototype.getType = function() {}; getType() {}
/** /**
* Read a single feature from a source. * Read a single feature from a source.
@@ -138,8 +133,7 @@ FeatureFormat.prototype.getType = function() {};
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options. * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {module:ol/Feature} Feature. * @return {module:ol/Feature} Feature.
*/ */
FeatureFormat.prototype.readFeature = function(source, opt_options) {}; readFeature(source, opt_options) {}
/** /**
* Read all features from a source. * Read all features from a source.
@@ -149,8 +143,7 @@ FeatureFormat.prototype.readFeature = function(source, opt_options) {};
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options. * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {Array.<module:ol/Feature>} Features. * @return {Array.<module:ol/Feature>} Features.
*/ */
FeatureFormat.prototype.readFeatures = function(source, opt_options) {}; readFeatures(source, opt_options) {}
/** /**
* Read a single geometry from a source. * Read a single geometry from a source.
@@ -160,8 +153,7 @@ FeatureFormat.prototype.readFeatures = function(source, opt_options) {};
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options. * @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {module:ol/geom/Geometry} Geometry. * @return {module:ol/geom/Geometry} Geometry.
*/ */
FeatureFormat.prototype.readGeometry = function(source, opt_options) {}; readGeometry(source, opt_options) {}
/** /**
* Read the projection from a source. * Read the projection from a source.
@@ -170,8 +162,7 @@ FeatureFormat.prototype.readGeometry = function(source, opt_options) {};
* @param {Document|Node|Object|string} source Source. * @param {Document|Node|Object|string} source Source.
* @return {module:ol/proj/Projection} Projection. * @return {module:ol/proj/Projection} Projection.
*/ */
FeatureFormat.prototype.readProjection = function(source) {}; readProjection(source) {}
/** /**
* Encode a feature in this format. * Encode a feature in this format.
@@ -181,8 +172,7 @@ FeatureFormat.prototype.readProjection = function(source) {};
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options. * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {string} Result. * @return {string} Result.
*/ */
FeatureFormat.prototype.writeFeature = function(feature, opt_options) {}; writeFeature(feature, opt_options) {}
/** /**
* Encode an array of features in this format. * Encode an array of features in this format.
@@ -192,8 +182,7 @@ FeatureFormat.prototype.writeFeature = function(feature, opt_options) {};
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options. * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {string} Result. * @return {string} Result.
*/ */
FeatureFormat.prototype.writeFeatures = function(features, opt_options) {}; writeFeatures(features, opt_options) {}
/** /**
* Write a single geometry in this format. * Write a single geometry in this format.
@@ -203,7 +192,8 @@ FeatureFormat.prototype.writeFeatures = function(features, opt_options) {};
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options. * @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {string} Result. * @return {string} Result.
*/ */
FeatureFormat.prototype.writeGeometry = function(geometry, opt_options) {}; writeGeometry(geometry, opt_options) {}
}
export default FeatureFormat; export default FeatureFormat;

View File

@@ -9,10 +9,8 @@ import GML3 from '../format/GML3.js';
* version 3.1.1. * version 3.1.1.
* Currently only supports GML 3.1.1 Simple Features profile. * Currently only supports GML 3.1.1 Simple Features profile.
* *
* @constructor
* @param {module:ol/format/GMLBase~Options=} opt_options * @param {module:ol/format/GMLBase~Options=} opt_options
* Optional configuration object. * Optional configuration object.
* @extends {module:ol/format/GMLBase}
* @api * @api
*/ */
const GML = GML3; const GML = GML3;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/format/GML2 * @module ol/format/GML2
*/ */
import {inherits} from '../util.js';
import {createOrUpdate} from '../extent.js'; import {createOrUpdate} from '../extent.js';
import {transformWithOptions} from '../format/Feature.js'; import {transformWithOptions} from '../format/Feature.js';
import GMLBase, {GMLNS} from '../format/GMLBase.js'; import GMLBase, {GMLNS} from '../format/GMLBase.js';
@@ -20,25 +19,39 @@ import {createElementNS, getAllTextContent, makeArrayPusher, makeChildAppender,
const schemaLocation = GMLNS + ' http://schemas.opengis.net/gml/2.1.2/feature.xsd'; const schemaLocation = GMLNS + ' http://schemas.opengis.net/gml/2.1.2/feature.xsd';
/**
* @const
* @type {Object.<string, string>}
*/
const MULTIGEOMETRY_TO_MEMBER_NODENAME = {
'MultiLineString': 'lineStringMember',
'MultiCurve': 'curveMember',
'MultiPolygon': 'polygonMember',
'MultiSurface': 'surfaceMember'
};
/** /**
* @classdesc * @classdesc
* Feature format for reading and writing data in the GML format, * Feature format for reading and writing data in the GML format,
* version 2.1.2. * version 2.1.2.
* *
* @constructor
* @param {module:ol/format/GMLBase~Options=} opt_options Optional configuration object.
* @extends {module:ol/format/GMLBase}
* @api * @api
*/ */
const GML2 = function(opt_options) { class GML2 extends GMLBase {
/**
* @param {module:ol/format/GMLBase~Options=} opt_options Optional configuration object.
*/
constructor(opt_options) {
const options = /** @type {module:ol/format/GMLBase~Options} */ const options = /** @type {module:ol/format/GMLBase~Options} */
(opt_options ? opt_options : {}); (opt_options ? opt_options : {});
GMLBase.call(this, options); super(options);
this.FEATURE_COLLECTION_PARSERS[GMLNS][ this.FEATURE_COLLECTION_PARSERS[GMLNS][
'featureMember'] = 'featureMember'] =
makeArrayPusher(GMLBase.prototype.readFeaturesInternal); makeArrayPusher(this.readFeaturesInternal);
/** /**
* @inheritDoc * @inheritDoc
@@ -46,10 +59,7 @@ const GML2 = function(opt_options) {
this.schemaLocation = options.schemaLocation ? this.schemaLocation = options.schemaLocation ?
options.schemaLocation : schemaLocation; options.schemaLocation : schemaLocation;
}; }
inherits(GML2, GMLBase);
/** /**
* @param {Node} node Node. * @param {Node} node Node.
@@ -57,7 +67,7 @@ inherits(GML2, GMLBase);
* @private * @private
* @return {Array.<number>|undefined} Flat coordinates. * @return {Array.<number>|undefined} Flat coordinates.
*/ */
GML2.prototype.readFlatCoordinates_ = function(node, objectStack) { readFlatCoordinates_(node, objectStack) {
const s = getAllTextContent(node, false).replace(/^\s*|\s*$/g, ''); const s = getAllTextContent(node, false).replace(/^\s*|\s*$/g, '');
const context = /** @type {module:ol/xml~NodeStackItem} */ (objectStack[0]); const context = /** @type {module:ol/xml~NodeStackItem} */ (objectStack[0]);
const containerSrs = context['srsName']; const containerSrs = context['srsName'];
@@ -82,8 +92,7 @@ GML2.prototype.readFlatCoordinates_ = function(node, objectStack) {
} }
} }
return flatCoordinates; return flatCoordinates;
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
@@ -91,22 +100,21 @@ GML2.prototype.readFlatCoordinates_ = function(node, objectStack) {
* @private * @private
* @return {module:ol/extent~Extent|undefined} Envelope. * @return {module:ol/extent~Extent|undefined} Envelope.
*/ */
GML2.prototype.readBox_ = function(node, objectStack) { readBox_(node, objectStack) {
/** @type {Array.<number>} */ /** @type {Array.<number>} */
const flatCoordinates = pushParseAndPop([null], const flatCoordinates = pushParseAndPop([null],
this.BOX_PARSERS_, node, objectStack, this); this.BOX_PARSERS_, node, objectStack, this);
return createOrUpdate(flatCoordinates[1][0], return createOrUpdate(flatCoordinates[1][0],
flatCoordinates[1][1], flatCoordinates[1][3], flatCoordinates[1][1], flatCoordinates[1][3],
flatCoordinates[1][4]); flatCoordinates[1][4]);
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack. * @param {Array.<*>} objectStack Object stack.
* @private * @private
*/ */
GML2.prototype.innerBoundaryIsParser_ = function(node, objectStack) { innerBoundaryIsParser_(node, objectStack) {
/** @type {Array.<number>|undefined} */ /** @type {Array.<number>|undefined} */
const flatLinearRing = pushParseAndPop(undefined, const flatLinearRing = pushParseAndPop(undefined,
this.RING_PARSERS, node, objectStack, this); this.RING_PARSERS, node, objectStack, this);
@@ -115,15 +123,14 @@ GML2.prototype.innerBoundaryIsParser_ = function(node, objectStack) {
(objectStack[objectStack.length - 1]); (objectStack[objectStack.length - 1]);
flatLinearRings.push(flatLinearRing); flatLinearRings.push(flatLinearRing);
} }
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack. * @param {Array.<*>} objectStack Object stack.
* @private * @private
*/ */
GML2.prototype.outerBoundaryIsParser_ = function(node, objectStack) { outerBoundaryIsParser_(node, objectStack) {
/** @type {Array.<number>|undefined} */ /** @type {Array.<number>|undefined} */
const flatLinearRing = pushParseAndPop(undefined, const flatLinearRing = pushParseAndPop(undefined,
this.RING_PARSERS, node, objectStack, this); this.RING_PARSERS, node, objectStack, this);
@@ -132,8 +139,7 @@ GML2.prototype.outerBoundaryIsParser_ = function(node, objectStack) {
(objectStack[objectStack.length - 1]); (objectStack[objectStack.length - 1]);
flatLinearRings[0] = flatLinearRing; flatLinearRings[0] = flatLinearRing;
} }
}; }
/** /**
* @const * @const
@@ -143,7 +149,7 @@ GML2.prototype.outerBoundaryIsParser_ = function(node, objectStack) {
* @return {Node|undefined} Node. * @return {Node|undefined} Node.
* @private * @private
*/ */
GML2.prototype.GEOMETRY_NODE_FACTORY_ = function(value, objectStack, opt_nodeName) { GEOMETRY_NODE_FACTORY_(value, objectStack, opt_nodeName) {
const context = objectStack[objectStack.length - 1]; const context = objectStack[objectStack.length - 1];
const multiSurface = context['multiSurface']; const multiSurface = context['multiSurface'];
const surface = context['surface']; const surface = context['surface'];
@@ -163,15 +169,14 @@ GML2.prototype.GEOMETRY_NODE_FACTORY_ = function(value, objectStack, opt_nodeNam
} }
return createElementNS('http://www.opengis.net/gml', return createElementNS('http://www.opengis.net/gml',
nodeName); nodeName);
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {module:ol/Feature} feature Feature. * @param {module:ol/Feature} feature Feature.
* @param {Array.<*>} objectStack Node stack. * @param {Array.<*>} objectStack Node stack.
*/ */
GML2.prototype.writeFeatureElement = function(node, feature, objectStack) { writeFeatureElement(node, feature, objectStack) {
const fid = feature.getId(); const fid = feature.getId();
if (fid) { if (fid) {
node.setAttribute('fid', fid); node.setAttribute('fid', fid);
@@ -210,8 +215,7 @@ GML2.prototype.writeFeatureElement = function(node, feature, objectStack) {
makeSimpleNodeFactory(undefined, featureNS), makeSimpleNodeFactory(undefined, featureNS),
values, values,
objectStack, keys); objectStack, keys);
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
@@ -219,7 +223,7 @@ GML2.prototype.writeFeatureElement = function(node, feature, objectStack) {
* @param {Array.<*>} objectStack Node stack. * @param {Array.<*>} objectStack Node stack.
* @private * @private
*/ */
GML2.prototype.writeCurveOrLineString_ = function(node, geometry, objectStack) { writeCurveOrLineString_(node, geometry, objectStack) {
const context = objectStack[objectStack.length - 1]; const context = objectStack[objectStack.length - 1];
const srsName = context['srsName']; const srsName = context['srsName'];
if (node.nodeName !== 'LineStringSegment' && srsName) { if (node.nodeName !== 'LineStringSegment' && srsName) {
@@ -236,8 +240,7 @@ GML2.prototype.writeCurveOrLineString_ = function(node, geometry, objectStack) {
this.writeCurveSegments_(segments, this.writeCurveSegments_(segments,
geometry, objectStack); geometry, objectStack);
} }
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
@@ -245,14 +248,13 @@ GML2.prototype.writeCurveOrLineString_ = function(node, geometry, objectStack) {
* @param {Array.<*>} objectStack Node stack. * @param {Array.<*>} objectStack Node stack.
* @private * @private
*/ */
GML2.prototype.writeLineStringOrCurveMember_ = function(node, line, objectStack) { writeLineStringOrCurveMember_(node, line, objectStack) {
const child = this.GEOMETRY_NODE_FACTORY_(line, objectStack); const child = this.GEOMETRY_NODE_FACTORY_(line, objectStack);
if (child) { if (child) {
node.appendChild(child); node.appendChild(child);
this.writeCurveOrLineString_(child, line, objectStack); this.writeCurveOrLineString_(child, line, objectStack);
} }
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
@@ -260,7 +262,7 @@ GML2.prototype.writeLineStringOrCurveMember_ = function(node, line, objectStack)
* @param {Array.<*>} objectStack Node stack. * @param {Array.<*>} objectStack Node stack.
* @private * @private
*/ */
GML2.prototype.writeMultiCurveOrLineString_ = function(node, geometry, objectStack) { writeMultiCurveOrLineString_(node, geometry, objectStack) {
const context = objectStack[objectStack.length - 1]; const context = objectStack[objectStack.length - 1];
const hasZ = context['hasZ']; const hasZ = context['hasZ'];
const srsName = context['srsName']; const srsName = context['srsName'];
@@ -273,15 +275,14 @@ GML2.prototype.writeMultiCurveOrLineString_ = function(node, geometry, objectSta
this.LINESTRINGORCURVEMEMBER_SERIALIZERS_, this.LINESTRINGORCURVEMEMBER_SERIALIZERS_,
this.MULTIGEOMETRY_MEMBER_NODE_FACTORY_, lines, this.MULTIGEOMETRY_MEMBER_NODE_FACTORY_, lines,
objectStack, undefined, this); objectStack, undefined, this);
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {module:ol/geom/Geometry|module:ol/extent~Extent} geometry Geometry. * @param {module:ol/geom/Geometry|module:ol/extent~Extent} geometry Geometry.
* @param {Array.<*>} objectStack Node stack. * @param {Array.<*>} objectStack Node stack.
*/ */
GML2.prototype.writeGeometryElement = function(node, geometry, objectStack) { writeGeometryElement(node, geometry, objectStack) {
const context = /** @type {module:ol/format/Feature~WriteOptions} */ (objectStack[objectStack.length - 1]); const context = /** @type {module:ol/format/Feature~WriteOptions} */ (objectStack[objectStack.length - 1]);
const item = assign({}, context); const item = assign({}, context);
item.node = node; item.node = node;
@@ -300,23 +301,21 @@ GML2.prototype.writeGeometryElement = function(node, geometry, objectStack) {
(item), this.GEOMETRY_SERIALIZERS_, (item), this.GEOMETRY_SERIALIZERS_,
this.GEOMETRY_NODE_FACTORY_, [value], this.GEOMETRY_NODE_FACTORY_, [value],
objectStack, undefined, this); objectStack, undefined, this);
}; }
/** /**
* @param {string} namespaceURI XML namespace. * @param {string} namespaceURI XML namespace.
* @returns {Node} coordinates node. * @returns {Node} coordinates node.
* @private * @private
*/ */
GML2.prototype.createCoordinatesNode_ = function(namespaceURI) { createCoordinatesNode_(namespaceURI) {
const coordinates = createElementNS(namespaceURI, 'coordinates'); const coordinates = createElementNS(namespaceURI, 'coordinates');
coordinates.setAttribute('decimal', '.'); coordinates.setAttribute('decimal', '.');
coordinates.setAttribute('cs', ','); coordinates.setAttribute('cs', ',');
coordinates.setAttribute('ts', ' '); coordinates.setAttribute('ts', ' ');
return coordinates; return coordinates;
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
@@ -324,7 +323,7 @@ GML2.prototype.createCoordinatesNode_ = function(namespaceURI) {
* @param {Array.<*>} objectStack Node stack. * @param {Array.<*>} objectStack Node stack.
* @private * @private
*/ */
GML2.prototype.writeCoordinates_ = function(node, value, objectStack) { writeCoordinates_(node, value, objectStack) {
const context = objectStack[objectStack.length - 1]; const context = objectStack[objectStack.length - 1];
const hasZ = context['hasZ']; const hasZ = context['hasZ'];
const srsName = context['srsName']; const srsName = context['srsName'];
@@ -337,8 +336,7 @@ GML2.prototype.writeCoordinates_ = function(node, value, objectStack) {
parts[i] = this.getCoords_(point, srsName, hasZ); parts[i] = this.getCoords_(point, srsName, hasZ);
} }
writeStringTextNode(node, parts.join(' ')); writeStringTextNode(node, parts.join(' '));
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
@@ -346,12 +344,11 @@ GML2.prototype.writeCoordinates_ = function(node, value, objectStack) {
* @param {Array.<*>} objectStack Node stack. * @param {Array.<*>} objectStack Node stack.
* @private * @private
*/ */
GML2.prototype.writeCurveSegments_ = function(node, line, objectStack) { writeCurveSegments_(node, line, objectStack) {
const child = createElementNS(node.namespaceURI, 'LineStringSegment'); const child = createElementNS(node.namespaceURI, 'LineStringSegment');
node.appendChild(child); node.appendChild(child);
this.writeCurveOrLineString_(child, line, objectStack); this.writeCurveOrLineString_(child, line, objectStack);
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
@@ -359,7 +356,7 @@ GML2.prototype.writeCurveSegments_ = function(node, line, objectStack) {
* @param {Array.<*>} objectStack Node stack. * @param {Array.<*>} objectStack Node stack.
* @private * @private
*/ */
GML2.prototype.writeSurfaceOrPolygon_ = function(node, geometry, objectStack) { writeSurfaceOrPolygon_(node, geometry, objectStack) {
const context = objectStack[objectStack.length - 1]; const context = objectStack[objectStack.length - 1];
const hasZ = context['hasZ']; const hasZ = context['hasZ'];
const srsName = context['srsName']; const srsName = context['srsName'];
@@ -379,8 +376,7 @@ GML2.prototype.writeSurfaceOrPolygon_ = function(node, geometry, objectStack) {
this.writeSurfacePatches_( this.writeSurfacePatches_(
patches, geometry, objectStack); patches, geometry, objectStack);
} }
}; }
/** /**
* @param {*} value Value. * @param {*} value Value.
@@ -389,7 +385,7 @@ GML2.prototype.writeSurfaceOrPolygon_ = function(node, geometry, objectStack) {
* @return {Node} Node. * @return {Node} Node.
* @private * @private
*/ */
GML2.prototype.RING_NODE_FACTORY_ = function(value, objectStack, opt_nodeName) { RING_NODE_FACTORY_(value, objectStack, opt_nodeName) {
const context = objectStack[objectStack.length - 1]; const context = objectStack[objectStack.length - 1];
const parentNode = context.node; const parentNode = context.node;
const exteriorWritten = context['exteriorWritten']; const exteriorWritten = context['exteriorWritten'];
@@ -398,8 +394,7 @@ GML2.prototype.RING_NODE_FACTORY_ = function(value, objectStack, opt_nodeName) {
} }
return createElementNS(parentNode.namespaceURI, return createElementNS(parentNode.namespaceURI,
exteriorWritten !== undefined ? 'innerBoundaryIs' : 'outerBoundaryIs'); exteriorWritten !== undefined ? 'innerBoundaryIs' : 'outerBoundaryIs');
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
@@ -407,12 +402,11 @@ GML2.prototype.RING_NODE_FACTORY_ = function(value, objectStack, opt_nodeName) {
* @param {Array.<*>} objectStack Node stack. * @param {Array.<*>} objectStack Node stack.
* @private * @private
*/ */
GML2.prototype.writeSurfacePatches_ = function(node, polygon, objectStack) { writeSurfacePatches_(node, polygon, objectStack) {
const child = createElementNS(node.namespaceURI, 'PolygonPatch'); const child = createElementNS(node.namespaceURI, 'PolygonPatch');
node.appendChild(child); node.appendChild(child);
this.writeSurfaceOrPolygon_(child, polygon, objectStack); this.writeSurfaceOrPolygon_(child, polygon, objectStack);
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
@@ -420,12 +414,11 @@ GML2.prototype.writeSurfacePatches_ = function(node, polygon, objectStack) {
* @param {Array.<*>} objectStack Node stack. * @param {Array.<*>} objectStack Node stack.
* @private * @private
*/ */
GML2.prototype.writeRing_ = function(node, ring, objectStack) { writeRing_(node, ring, objectStack) {
const linearRing = createElementNS(node.namespaceURI, 'LinearRing'); const linearRing = createElementNS(node.namespaceURI, 'LinearRing');
node.appendChild(linearRing); node.appendChild(linearRing);
this.writeLinearRing_(linearRing, ring, objectStack); this.writeLinearRing_(linearRing, ring, objectStack);
}; }
/** /**
* @param {Array.<number>} point Point geometry. * @param {Array.<number>} point Point geometry.
@@ -434,7 +427,7 @@ GML2.prototype.writeRing_ = function(node, ring, objectStack) {
* @return {string} The coords string. * @return {string} The coords string.
* @private * @private
*/ */
GML2.prototype.getCoords_ = function(point, opt_srsName, opt_hasZ) { getCoords_(point, opt_srsName, opt_hasZ) {
let axisOrientation = 'enu'; let axisOrientation = 'enu';
if (opt_srsName) { if (opt_srsName) {
axisOrientation = getProjection(opt_srsName).getAxisOrientation(); axisOrientation = getProjection(opt_srsName).getAxisOrientation();
@@ -449,8 +442,7 @@ GML2.prototype.getCoords_ = function(point, opt_srsName, opt_hasZ) {
} }
return coords; return coords;
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
@@ -458,7 +450,7 @@ GML2.prototype.getCoords_ = function(point, opt_srsName, opt_hasZ) {
* @param {Array.<*>} objectStack Node stack. * @param {Array.<*>} objectStack Node stack.
* @private * @private
*/ */
GML2.prototype.writePoint_ = function(node, geometry, objectStack) { writePoint_(node, geometry, objectStack) {
const context = objectStack[objectStack.length - 1]; const context = objectStack[objectStack.length - 1];
const hasZ = context['hasZ']; const hasZ = context['hasZ'];
const srsName = context['srsName']; const srsName = context['srsName'];
@@ -470,8 +462,7 @@ GML2.prototype.writePoint_ = function(node, geometry, objectStack) {
const point = geometry.getCoordinates(); const point = geometry.getCoordinates();
const coord = this.getCoords_(point, srsName, hasZ); const coord = this.getCoords_(point, srsName, hasZ);
writeStringTextNode(coordinates, coord); writeStringTextNode(coordinates, coord);
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
@@ -479,7 +470,7 @@ GML2.prototype.writePoint_ = function(node, geometry, objectStack) {
* @param {Array.<*>} objectStack Node stack. * @param {Array.<*>} objectStack Node stack.
* @private * @private
*/ */
GML2.prototype.writeMultiPoint_ = function(node, geometry, objectStack) { writeMultiPoint_(node, geometry, objectStack) {
const context = objectStack[objectStack.length - 1]; const context = objectStack[objectStack.length - 1];
const hasZ = context['hasZ']; const hasZ = context['hasZ'];
const srsName = context['srsName']; const srsName = context['srsName'];
@@ -491,8 +482,7 @@ GML2.prototype.writeMultiPoint_ = function(node, geometry, objectStack) {
this.POINTMEMBER_SERIALIZERS_, this.POINTMEMBER_SERIALIZERS_,
makeSimpleNodeFactory('pointMember'), points, makeSimpleNodeFactory('pointMember'), points,
objectStack, undefined, this); objectStack, undefined, this);
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
@@ -500,12 +490,11 @@ GML2.prototype.writeMultiPoint_ = function(node, geometry, objectStack) {
* @param {Array.<*>} objectStack Node stack. * @param {Array.<*>} objectStack Node stack.
* @private * @private
*/ */
GML2.prototype.writePointMember_ = function(node, point, objectStack) { writePointMember_(node, point, objectStack) {
const child = createElementNS(node.namespaceURI, 'Point'); const child = createElementNS(node.namespaceURI, 'Point');
node.appendChild(child); node.appendChild(child);
this.writePoint_(child, point, objectStack); this.writePoint_(child, point, objectStack);
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
@@ -513,7 +502,7 @@ GML2.prototype.writePointMember_ = function(node, point, objectStack) {
* @param {Array.<*>} objectStack Node stack. * @param {Array.<*>} objectStack Node stack.
* @private * @private
*/ */
GML2.prototype.writeLinearRing_ = function(node, geometry, objectStack) { writeLinearRing_(node, geometry, objectStack) {
const context = objectStack[objectStack.length - 1]; const context = objectStack[objectStack.length - 1];
const srsName = context['srsName']; const srsName = context['srsName'];
if (srsName) { if (srsName) {
@@ -522,8 +511,7 @@ GML2.prototype.writeLinearRing_ = function(node, geometry, objectStack) {
const coordinates = this.createCoordinatesNode_(node.namespaceURI); const coordinates = this.createCoordinatesNode_(node.namespaceURI);
node.appendChild(coordinates); node.appendChild(coordinates);
this.writeCoordinates_(coordinates, geometry, objectStack); this.writeCoordinates_(coordinates, geometry, objectStack);
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
@@ -531,7 +519,7 @@ GML2.prototype.writeLinearRing_ = function(node, geometry, objectStack) {
* @param {Array.<*>} objectStack Node stack. * @param {Array.<*>} objectStack Node stack.
* @private * @private
*/ */
GML2.prototype.writeMultiSurfaceOrPolygon_ = function(node, geometry, objectStack) { writeMultiSurfaceOrPolygon_(node, geometry, objectStack) {
const context = objectStack[objectStack.length - 1]; const context = objectStack[objectStack.length - 1];
const hasZ = context['hasZ']; const hasZ = context['hasZ'];
const srsName = context['srsName']; const srsName = context['srsName'];
@@ -544,8 +532,7 @@ GML2.prototype.writeMultiSurfaceOrPolygon_ = function(node, geometry, objectStac
this.SURFACEORPOLYGONMEMBER_SERIALIZERS_, this.SURFACEORPOLYGONMEMBER_SERIALIZERS_,
this.MULTIGEOMETRY_MEMBER_NODE_FACTORY_, polygons, this.MULTIGEOMETRY_MEMBER_NODE_FACTORY_, polygons,
objectStack, undefined, this); objectStack, undefined, this);
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
@@ -553,15 +540,14 @@ GML2.prototype.writeMultiSurfaceOrPolygon_ = function(node, geometry, objectStac
* @param {Array.<*>} objectStack Node stack. * @param {Array.<*>} objectStack Node stack.
* @private * @private
*/ */
GML2.prototype.writeSurfaceOrPolygonMember_ = function(node, polygon, objectStack) { writeSurfaceOrPolygonMember_(node, polygon, objectStack) {
const child = this.GEOMETRY_NODE_FACTORY_( const child = this.GEOMETRY_NODE_FACTORY_(
polygon, objectStack); polygon, objectStack);
if (child) { if (child) {
node.appendChild(child); node.appendChild(child);
this.writeSurfaceOrPolygon_(child, polygon, objectStack); this.writeSurfaceOrPolygon_(child, polygon, objectStack);
} }
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
@@ -569,7 +555,7 @@ GML2.prototype.writeSurfaceOrPolygonMember_ = function(node, polygon, objectStac
* @param {Array.<*>} objectStack Node stack. * @param {Array.<*>} objectStack Node stack.
* @private * @private
*/ */
GML2.prototype.writeEnvelope = function(node, extent, objectStack) { writeEnvelope(node, extent, objectStack) {
const context = objectStack[objectStack.length - 1]; const context = objectStack[objectStack.length - 1];
const srsName = context['srsName']; const srsName = context['srsName'];
if (srsName) { if (srsName) {
@@ -582,20 +568,7 @@ GML2.prototype.writeEnvelope = function(node, extent, objectStack) {
OBJECT_PROPERTY_NODE_FACTORY, OBJECT_PROPERTY_NODE_FACTORY,
values, values,
objectStack, keys, this); objectStack, keys, this);
}; }
/**
* @const
* @type {Object.<string, string>}
*/
const MULTIGEOMETRY_TO_MEMBER_NODENAME = {
'MultiLineString': 'lineStringMember',
'MultiCurve': 'curveMember',
'MultiPolygon': 'polygonMember',
'MultiSurface': 'surfaceMember'
};
/** /**
* @const * @const
@@ -605,12 +578,12 @@ const MULTIGEOMETRY_TO_MEMBER_NODENAME = {
* @return {Node|undefined} Node. * @return {Node|undefined} Node.
* @private * @private
*/ */
GML2.prototype.MULTIGEOMETRY_MEMBER_NODE_FACTORY_ = function(value, objectStack, opt_nodeName) { MULTIGEOMETRY_MEMBER_NODE_FACTORY_(value, objectStack, opt_nodeName) {
const parentNode = objectStack[objectStack.length - 1].node; const parentNode = objectStack[objectStack.length - 1].node;
return createElementNS('http://www.opengis.net/gml', return createElementNS('http://www.opengis.net/gml',
MULTIGEOMETRY_TO_MEMBER_NODENAME[parentNode.nodeName]); MULTIGEOMETRY_TO_MEMBER_NODENAME[parentNode.nodeName]);
}; }
}
/** /**
* @const * @const
@@ -623,7 +596,6 @@ GML2.prototype.GEOMETRY_FLAT_COORDINATES_PARSERS_ = {
} }
}; };
/** /**
* @const * @const
* @type {Object.<string, Object.<string, module:ol/xml~Parser>>} * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}
@@ -636,7 +608,6 @@ GML2.prototype.FLAT_LINEAR_RINGS_PARSERS_ = {
} }
}; };
/** /**
* @const * @const
* @type {Object.<string, Object.<string, module:ol/xml~Parser>>} * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}
@@ -649,7 +620,6 @@ GML2.prototype.BOX_PARSERS_ = {
} }
}; };
/** /**
* @const * @const
* @type {Object.<string, Object.<string, module:ol/xml~Parser>>} * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}
@@ -673,7 +643,6 @@ GML2.prototype.GEOMETRY_PARSERS_ = {
} }
}; };
/** /**
* @const * @const
* @type {Object.<string, Object.<string, module:ol/xml~Serializer>>} * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}
@@ -707,7 +676,6 @@ GML2.prototype.GEOMETRY_SERIALIZERS_ = {
} }
}; };
/** /**
* @type {Object.<string, Object.<string, module:ol/xml~Serializer>>} * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}
* @private * @private
@@ -721,7 +689,6 @@ GML2.prototype.LINESTRINGORCURVEMEMBER_SERIALIZERS_ = {
} }
}; };
/** /**
* @type {Object.<string, Object.<string, module:ol/xml~Serializer>>} * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}
* @private * @private
@@ -733,7 +700,6 @@ GML2.prototype.RING_SERIALIZERS_ = {
} }
}; };
/** /**
* @type {Object.<string, Object.<string, module:ol/xml~Serializer>>} * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}
* @private * @private
@@ -745,7 +711,6 @@ GML2.prototype.POINTMEMBER_SERIALIZERS_ = {
} }
}; };
/** /**
* @const * @const
* @type {Object.<string, Object.<string, module:ol/xml~Serializer>>} * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}
@@ -760,7 +725,6 @@ GML2.prototype.SURFACEORPOLYGONMEMBER_SERIALIZERS_ = {
} }
}; };
/** /**
* @type {Object.<string, Object.<string, module:ol/xml~Serializer>>} * @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}
* @private * @private

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,6 @@
// FIXME Envelopes should not be treated as geometries! readEnvelope_ is part // FIXME Envelopes should not be treated as geometries! readEnvelope_ is part
// of GEOMETRY_PARSERS_ and methods using GEOMETRY_PARSERS_ do not expect // of GEOMETRY_PARSERS_ and methods using GEOMETRY_PARSERS_ do not expect
// envelopes/extents, only geometries! // envelopes/extents, only geometries!
import {inherits} from '../util.js';
import {extend} from '../array.js'; import {extend} from '../array.js';
import Feature from '../Feature.js'; import Feature from '../Feature.js';
import {transformWithOptions} from '../format/Feature.js'; import {transformWithOptions} from '../format/Feature.js';
@@ -29,6 +28,20 @@ import {getAllTextContent, getAttributeNS, makeArrayPusher, makeReplacer, parseN
export const GMLNS = 'http://www.opengis.net/gml'; export const GMLNS = 'http://www.opengis.net/gml';
/**
* A regular expression that matches if a string only contains whitespace
* characters. It will e.g. match `''`, `' '`, `'\n'` etc. The non-breaking
* space (0xa0) is explicitly included as IE doesn't include it in its
* definition of `\s`.
*
* Information from `goog.string.isEmptyOrWhitespace`: https://github.com/google/closure-library/blob/e877b1e/closure/goog/string/string.js#L156-L160
*
* @const
* @type {RegExp}
*/
const ONLY_WHITESPACE_RE = /^[\s\xa0]*$/;
/** /**
* @typedef {Object} Options * @typedef {Object} Options
* @property {Object.<string, string>|string} [featureNS] Feature * @property {Object.<string, string>|string} [featureNS] Feature
@@ -69,13 +82,16 @@ export const GMLNS = 'http://www.opengis.net/gml';
* This class cannot be instantiated, it contains only base content that * This class cannot be instantiated, it contains only base content that
* is shared with versioned format classes GML2 and GML3. * is shared with versioned format classes GML2 and GML3.
* *
* @constructor
* @abstract * @abstract
* @param {module:ol/format/GMLBase~Options=} opt_options
* Optional configuration object.
* @extends {module:ol/format/XMLFeature}
*/ */
const GMLBase = function(opt_options) { class GMLBase extends XMLFeature {
/**
* @param {module:ol/format/GMLBase~Options=} opt_options Optional configuration object.
*/
constructor(opt_options) {
super();
const options = /** @type {module:ol/format/GMLBase~Options} */ (opt_options ? opt_options : {}); const options = /** @type {module:ol/format/GMLBase~Options} */ (opt_options ? opt_options : {});
/** /**
@@ -107,36 +123,18 @@ const GMLBase = function(opt_options) {
*/ */
this.FEATURE_COLLECTION_PARSERS = {}; this.FEATURE_COLLECTION_PARSERS = {};
this.FEATURE_COLLECTION_PARSERS[GMLNS] = { this.FEATURE_COLLECTION_PARSERS[GMLNS] = {
'featureMember': makeReplacer(GMLBase.prototype.readFeaturesInternal), 'featureMember': makeReplacer(this.readFeaturesInternal),
'featureMembers': makeReplacer(GMLBase.prototype.readFeaturesInternal) 'featureMembers': makeReplacer(this.readFeaturesInternal)
}; };
XMLFeature.call(this); }
};
inherits(GMLBase, XMLFeature);
/**
* A regular expression that matches if a string only contains whitespace
* characters. It will e.g. match `''`, `' '`, `'\n'` etc. The non-breaking
* space (0xa0) is explicitly included as IE doesn't include it in its
* definition of `\s`.
*
* Information from `goog.string.isEmptyOrWhitespace`: https://github.com/google/closure-library/blob/e877b1e/closure/goog/string/string.js#L156-L160
*
* @const
* @type {RegExp}
*/
const ONLY_WHITESPACE_RE = /^[\s\xa0]*$/;
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack. * @param {Array.<*>} objectStack Object stack.
* @return {Array.<module:ol/Feature> | undefined} Features. * @return {Array.<module:ol/Feature> | undefined} Features.
*/ */
GMLBase.prototype.readFeaturesInternal = function(node, objectStack) { readFeaturesInternal(node, objectStack) {
const localName = node.localName; const localName = node.localName;
let features = null; let features = null;
if (localName == 'FeatureCollection') { if (localName == 'FeatureCollection') {
@@ -217,15 +215,14 @@ GMLBase.prototype.readFeaturesInternal = function(node, objectStack) {
features = []; features = [];
} }
return features; return features;
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack. * @param {Array.<*>} objectStack Object stack.
* @return {module:ol/geom/Geometry|undefined} Geometry. * @return {module:ol/geom/Geometry|undefined} Geometry.
*/ */
GMLBase.prototype.readGeometryElement = function(node, objectStack) { readGeometryElement(node, objectStack) {
const context = /** @type {Object} */ (objectStack[0]); const context = /** @type {Object} */ (objectStack[0]);
context['srsName'] = node.firstElementChild.getAttribute('srsName'); context['srsName'] = node.firstElementChild.getAttribute('srsName');
context['srsDimension'] = node.firstElementChild.getAttribute('srsDimension'); context['srsDimension'] = node.firstElementChild.getAttribute('srsDimension');
@@ -238,15 +235,14 @@ GMLBase.prototype.readGeometryElement = function(node, objectStack) {
} else { } else {
return undefined; return undefined;
} }
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack. * @param {Array.<*>} objectStack Object stack.
* @return {module:ol/Feature} Feature. * @return {module:ol/Feature} Feature.
*/ */
GMLBase.prototype.readFeatureElement = function(node, objectStack) { readFeatureElement(node, objectStack) {
let n; let n;
const fid = node.getAttribute('fid') || getAttributeNS(node, GMLNS, 'id'); const fid = node.getAttribute('fid') || getAttributeNS(node, GMLNS, 'id');
const values = {}; const values = {};
@@ -280,30 +276,26 @@ GMLBase.prototype.readFeatureElement = function(node, objectStack) {
feature.setId(fid); feature.setId(fid);
} }
return feature; return feature;
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack. * @param {Array.<*>} objectStack Object stack.
* @return {module:ol/geom/Point|undefined} Point. * @return {module:ol/geom/Point|undefined} Point.
*/ */
GMLBase.prototype.readPoint = function(node, objectStack) { readPoint(node, objectStack) {
const flatCoordinates = this.readFlatCoordinatesFromNode_(node, objectStack); const flatCoordinates = this.readFlatCoordinatesFromNode_(node, objectStack);
if (flatCoordinates) { if (flatCoordinates) {
const point = new Point(null); return new Point(flatCoordinates, GeometryLayout.XYZ);
point.setFlatCoordinates(GeometryLayout.XYZ, flatCoordinates); }
return point;
} }
};
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack. * @param {Array.<*>} objectStack Object stack.
* @return {module:ol/geom/MultiPoint|undefined} MultiPoint. * @return {module:ol/geom/MultiPoint|undefined} MultiPoint.
*/ */
GMLBase.prototype.readMultiPoint = function(node, objectStack) { readMultiPoint(node, objectStack) {
/** @type {Array.<Array.<number>>} */ /** @type {Array.<Array.<number>>} */
const coordinates = pushParseAndPop([], const coordinates = pushParseAndPop([],
this.MULTIPOINT_PARSERS_, node, objectStack, this); this.MULTIPOINT_PARSERS_, node, objectStack, this);
@@ -312,92 +304,76 @@ GMLBase.prototype.readMultiPoint = function(node, objectStack) {
} else { } else {
return undefined; return undefined;
} }
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack. * @param {Array.<*>} objectStack Object stack.
* @return {module:ol/geom/MultiLineString|undefined} MultiLineString. * @return {module:ol/geom/MultiLineString|undefined} MultiLineString.
*/ */
GMLBase.prototype.readMultiLineString = function(node, objectStack) { readMultiLineString(node, objectStack) {
/** @type {Array.<module:ol/geom/LineString>} */ /** @type {Array.<module:ol/geom/LineString>} */
const lineStrings = pushParseAndPop([], const lineStrings = pushParseAndPop([],
this.MULTILINESTRING_PARSERS_, node, objectStack, this); this.MULTILINESTRING_PARSERS_, node, objectStack, this);
if (lineStrings) { if (lineStrings) {
const multiLineString = new MultiLineString(null); return new MultiLineString(lineStrings);
multiLineString.setLineStrings(lineStrings); }
return multiLineString;
} else {
return undefined;
} }
};
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack. * @param {Array.<*>} objectStack Object stack.
* @return {module:ol/geom/MultiPolygon|undefined} MultiPolygon. * @return {module:ol/geom/MultiPolygon|undefined} MultiPolygon.
*/ */
GMLBase.prototype.readMultiPolygon = function(node, objectStack) { readMultiPolygon(node, objectStack) {
/** @type {Array.<module:ol/geom/Polygon>} */ /** @type {Array.<module:ol/geom/Polygon>} */
const polygons = pushParseAndPop([], this.MULTIPOLYGON_PARSERS_, node, objectStack, this); const polygons = pushParseAndPop([], this.MULTIPOLYGON_PARSERS_, node, objectStack, this);
if (polygons) { if (polygons) {
const multiPolygon = new MultiPolygon(null); return new MultiPolygon(polygons);
multiPolygon.setPolygons(polygons); }
return multiPolygon;
} else {
return undefined;
} }
};
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack. * @param {Array.<*>} objectStack Object stack.
* @private * @private
*/ */
GMLBase.prototype.pointMemberParser_ = function(node, objectStack) { pointMemberParser_(node, objectStack) {
parseNode(this.POINTMEMBER_PARSERS_, node, objectStack, this); parseNode(this.POINTMEMBER_PARSERS_, node, objectStack, this);
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack. * @param {Array.<*>} objectStack Object stack.
* @private * @private
*/ */
GMLBase.prototype.lineStringMemberParser_ = function(node, objectStack) { lineStringMemberParser_(node, objectStack) {
parseNode(this.LINESTRINGMEMBER_PARSERS_, node, objectStack, this); parseNode(this.LINESTRINGMEMBER_PARSERS_, node, objectStack, this);
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack. * @param {Array.<*>} objectStack Object stack.
* @private * @private
*/ */
GMLBase.prototype.polygonMemberParser_ = function(node, objectStack) { polygonMemberParser_(node, objectStack) {
parseNode(this.POLYGONMEMBER_PARSERS_, node, objectStack, this); parseNode(this.POLYGONMEMBER_PARSERS_, node, objectStack, this);
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack. * @param {Array.<*>} objectStack Object stack.
* @return {module:ol/geom/LineString|undefined} LineString. * @return {module:ol/geom/LineString|undefined} LineString.
*/ */
GMLBase.prototype.readLineString = function(node, objectStack) { readLineString(node, objectStack) {
const flatCoordinates = this.readFlatCoordinatesFromNode_(node, objectStack); const flatCoordinates = this.readFlatCoordinatesFromNode_(node, objectStack);
if (flatCoordinates) { if (flatCoordinates) {
const lineString = new LineString(null); const lineString = new LineString(flatCoordinates, GeometryLayout.XYZ);
lineString.setFlatCoordinates(GeometryLayout.XYZ, flatCoordinates);
return lineString; return lineString;
} else { } else {
return undefined; return undefined;
} }
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
@@ -405,7 +381,7 @@ GMLBase.prototype.readLineString = function(node, objectStack) {
* @private * @private
* @return {Array.<number>|undefined} LinearRing flat coordinates. * @return {Array.<number>|undefined} LinearRing flat coordinates.
*/ */
GMLBase.prototype.readFlatLinearRing_ = function(node, objectStack) { readFlatLinearRing_(node, objectStack) {
const ring = pushParseAndPop(null, const ring = pushParseAndPop(null,
this.GEOMETRY_FLAT_COORDINATES_PARSERS_, node, this.GEOMETRY_FLAT_COORDINATES_PARSERS_, node,
objectStack, this); objectStack, this);
@@ -414,37 +390,30 @@ GMLBase.prototype.readFlatLinearRing_ = function(node, objectStack) {
} else { } else {
return undefined; return undefined;
} }
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack. * @param {Array.<*>} objectStack Object stack.
* @return {module:ol/geom/LinearRing|undefined} LinearRing. * @return {module:ol/geom/LinearRing|undefined} LinearRing.
*/ */
GMLBase.prototype.readLinearRing = function(node, objectStack) { readLinearRing(node, objectStack) {
const flatCoordinates = this.readFlatCoordinatesFromNode_(node, objectStack); const flatCoordinates = this.readFlatCoordinatesFromNode_(node, objectStack);
if (flatCoordinates) { if (flatCoordinates) {
const ring = new LinearRing(null); return new LinearRing(flatCoordinates, GeometryLayout.XYZ);
ring.setFlatCoordinates(GeometryLayout.XYZ, flatCoordinates); }
return ring;
} else {
return undefined;
} }
};
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack. * @param {Array.<*>} objectStack Object stack.
* @return {module:ol/geom/Polygon|undefined} Polygon. * @return {module:ol/geom/Polygon|undefined} Polygon.
*/ */
GMLBase.prototype.readPolygon = function(node, objectStack) { readPolygon(node, objectStack) {
/** @type {Array.<Array.<number>>} */ /** @type {Array.<Array.<number>>} */
const flatLinearRings = pushParseAndPop([null], const flatLinearRings = pushParseAndPop([null],
this.FLAT_LINEAR_RINGS_PARSERS_, node, objectStack, this); this.FLAT_LINEAR_RINGS_PARSERS_, node, objectStack, this);
if (flatLinearRings && flatLinearRings[0]) { if (flatLinearRings && flatLinearRings[0]) {
const polygon = new Polygon(null);
const flatCoordinates = flatLinearRings[0]; const flatCoordinates = flatLinearRings[0];
const ends = [flatCoordinates.length]; const ends = [flatCoordinates.length];
let i, ii; let i, ii;
@@ -452,13 +421,11 @@ GMLBase.prototype.readPolygon = function(node, objectStack) {
extend(flatCoordinates, flatLinearRings[i]); extend(flatCoordinates, flatLinearRings[i]);
ends.push(flatCoordinates.length); ends.push(flatCoordinates.length);
} }
polygon.setFlatCoordinates(GeometryLayout.XYZ, flatCoordinates, ends); return new Polygon(flatCoordinates, GeometryLayout.XYZ, ends);
return polygon;
} else { } else {
return undefined; return undefined;
} }
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
@@ -466,10 +433,41 @@ GMLBase.prototype.readPolygon = function(node, objectStack) {
* @private * @private
* @return {Array.<number>} Flat coordinates. * @return {Array.<number>} Flat coordinates.
*/ */
GMLBase.prototype.readFlatCoordinatesFromNode_ = function(node, objectStack) { readFlatCoordinatesFromNode_(node, objectStack) {
return pushParseAndPop(null, this.GEOMETRY_FLAT_COORDINATES_PARSERS_, node, objectStack, this); return pushParseAndPop(null, this.GEOMETRY_FLAT_COORDINATES_PARSERS_, node, objectStack, this);
}; }
/**
* @inheritDoc
*/
readGeometryFromNode(node, opt_options) {
const geometry = this.readGeometryElement(node,
[this.getReadOptions(node, opt_options ? opt_options : {})]);
return geometry ? geometry : null;
}
/**
* @inheritDoc
*/
readFeaturesFromNode(node, opt_options) {
const options = {
featureType: this.featureType,
featureNS: this.featureNS
};
if (opt_options) {
assign(options, this.getReadOptions(node, opt_options));
}
const features = this.readFeaturesInternal(node, [options]);
return features || [];
}
/**
* @inheritDoc
*/
readProjectionFromNode(node) {
return getProjection(this.srsName ? this.srsName : node.firstElementChild.getAttribute('srsName'));
}
}
/** /**
* @const * @const
@@ -557,49 +555,4 @@ GMLBase.prototype.RING_PARSERS = {
} }
}; };
/**
* @inheritDoc
*/
GMLBase.prototype.readGeometryFromNode = function(node, opt_options) {
const geometry = this.readGeometryElement(node,
[this.getReadOptions(node, opt_options ? opt_options : {})]);
return geometry ? geometry : null;
};
/**
* Read all features from a GML FeatureCollection.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Options.
* @return {Array.<module:ol/Feature>} Features.
* @api
*/
GMLBase.prototype.readFeatures;
/**
* @inheritDoc
*/
GMLBase.prototype.readFeaturesFromNode = function(node, opt_options) {
const options = {
featureType: this.featureType,
featureNS: this.featureNS
};
if (opt_options) {
assign(options, this.getReadOptions(node, opt_options));
}
const features = this.readFeaturesInternal(node, [options]);
return features || [];
};
/**
* @inheritDoc
*/
GMLBase.prototype.readProjectionFromNode = function(node) {
return getProjection(this.srsName ? this.srsName : node.firstElementChild.getAttribute('srsName'));
};
export default GMLBase; export default GMLBase;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/format/GPX * @module ol/format/GPX
*/ */
import {inherits} from '../util.js';
import Feature from '../Feature.js'; import Feature from '../Feature.js';
import {includes} from '../array.js'; import {includes} from '../array.js';
import {transformWithOptions} from '../format/Feature.js'; import {transformWithOptions} from '../format/Feature.js';
@@ -18,52 +17,6 @@ import {createElementNS, makeArrayPusher, makeArraySerializer, makeChildAppender
XML_SCHEMA_INSTANCE_URI} from '../xml.js'; XML_SCHEMA_INSTANCE_URI} from '../xml.js';
/**
* @typedef {Object} Options
* @property {function(module:ol/Feature, Node)} [readExtensions] Callback function
* to process `extensions` nodes. To prevent memory leaks, this callback function must
* not store any references to the node. Note that the `extensions`
* node is not allowed in GPX 1.0. Moreover, only `extensions`
* nodes from `wpt`, `rte` and `trk` can be processed, as those are
* directly mapped to a feature.
*/
/**
* @typedef {Object} LayoutOptions
* @property {boolean} [hasZ]
* @property {boolean} [hasM]
*/
/**
* @classdesc
* Feature format for reading and writing data in the GPX format.
*
* @constructor
* @extends {module:ol/format/XMLFeature}
* @param {module:ol/format/GPX~Options=} opt_options Options.
* @api
*/
const GPX = function(opt_options) {
const options = opt_options ? opt_options : {};
XMLFeature.call(this);
/**
* @inheritDoc
*/
this.dataProjection = getProjection('EPSG:4326');
/**
* @type {function(module:ol/Feature, Node)|undefined}
* @private
*/
this.readExtensions_ = options.readExtensions;
};
inherits(GPX, XMLFeature);
/** /**
* @const * @const
* @type {Array.<null|string>} * @type {Array.<null|string>}
@@ -117,6 +70,159 @@ const LINK_PARSERS = makeStructureNS(
}); });
/**
* @const
* @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}
*/
const GPX_SERIALIZERS = makeStructureNS(
NAMESPACE_URIS, {
'rte': makeChildAppender(writeRte),
'trk': makeChildAppender(writeTrk),
'wpt': makeChildAppender(writeWpt)
});
/**
* @typedef {Object} Options
* @property {function(module:ol/Feature, Node)} [readExtensions] Callback function
* to process `extensions` nodes. To prevent memory leaks, this callback function must
* not store any references to the node. Note that the `extensions`
* node is not allowed in GPX 1.0. Moreover, only `extensions`
* nodes from `wpt`, `rte` and `trk` can be processed, as those are
* directly mapped to a feature.
*/
/**
* @typedef {Object} LayoutOptions
* @property {boolean} [hasZ]
* @property {boolean} [hasM]
*/
/**
* @classdesc
* Feature format for reading and writing data in the GPX format.
*
* Note that {@link module:ol/format/GPX~GPX#readFeature} only reads the first
* feature of the source.
*
* When reading, routes (`<rte>`) are converted into LineString geometries, and
* tracks (`<trk>`) into MultiLineString. Any properties on route and track
* waypoints are ignored.
*
* When writing, LineString geometries are output as routes (`<rte>`), and
* MultiLineString as tracks (`<trk>`).
*
* @api
*/
class GPX extends XMLFeature {
/**
* @param {module:ol/format/GPX~Options=} opt_options Options.
*/
constructor(opt_options) {
super();
const options = opt_options ? opt_options : {};
/**
* @inheritDoc
*/
this.dataProjection = getProjection('EPSG:4326');
/**
* @type {function(module:ol/Feature, Node)|undefined}
* @private
*/
this.readExtensions_ = options.readExtensions;
}
/**
* @param {Array.<module:ol/Feature>} features List of features.
* @private
*/
handleReadExtensions_(features) {
if (!features) {
features = [];
}
for (let i = 0, ii = features.length; i < ii; ++i) {
const feature = features[i];
if (this.readExtensions_) {
const extensionsNode = feature.get('extensionsNode_') || null;
this.readExtensions_(feature, extensionsNode);
}
feature.set('extensionsNode_', undefined);
}
}
/**
* @inheritDoc
*/
readFeatureFromNode(node, opt_options) {
if (!includes(NAMESPACE_URIS, node.namespaceURI)) {
return null;
}
const featureReader = FEATURE_READER[node.localName];
if (!featureReader) {
return null;
}
const feature = featureReader(node, [this.getReadOptions(node, opt_options)]);
if (!feature) {
return null;
}
this.handleReadExtensions_([feature]);
return feature;
}
/**
* @inheritDoc
*/
readFeaturesFromNode(node, opt_options) {
if (!includes(NAMESPACE_URIS, node.namespaceURI)) {
return [];
}
if (node.localName == 'gpx') {
/** @type {Array.<module:ol/Feature>} */
const features = pushParseAndPop([], GPX_PARSERS,
node, [this.getReadOptions(node, opt_options)]);
if (features) {
this.handleReadExtensions_(features);
return features;
} else {
return [];
}
}
return [];
}
/**
* Encode an array of features in the GPX format as an XML node.
* LineString geometries are output as routes (`<rte>`), and MultiLineString
* as tracks (`<trk>`).
*
* @param {Array.<module:ol/Feature>} features Features.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Options.
* @return {Node} Node.
* @override
* @api
*/
writeFeaturesNode(features, opt_options) {
opt_options = this.adaptOptions(opt_options);
//FIXME Serialize metadata
const gpx = createElementNS('http://www.topografix.com/GPX/1/1', 'gpx');
const xmlnsUri = 'http://www.w3.org/2000/xmlns/';
gpx.setAttributeNS(xmlnsUri, 'xmlns:xsi', XML_SCHEMA_INSTANCE_URI);
gpx.setAttributeNS(XML_SCHEMA_INSTANCE_URI, 'xsi:schemaLocation', SCHEMA_LOCATION);
gpx.setAttribute('version', '1.1');
gpx.setAttribute('creator', 'OpenLayers');
pushSerializeAndPop(/** @type {module:ol/xml~NodeStackItem} */
({node: gpx}), GPX_SERIALIZERS, GPX_NODE_FACTORY, features, [opt_options]);
return gpx;
}
}
/** /**
* @const * @const
* @type {Object.<string, Object.<string, module:ol/xml~Parser>>} * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}
@@ -380,18 +486,6 @@ function GPX_NODE_FACTORY(value, objectStack, opt_nodeName) {
} }
/**
* @const
* @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}
*/
const GPX_SERIALIZERS = makeStructureNS(
NAMESPACE_URIS, {
'rte': makeChildAppender(writeRte),
'trk': makeChildAppender(writeTrk),
'wpt': makeChildAppender(writeWpt)
});
/** /**
* @param {Array.<number>} flatCoordinates Flat coordinates. * @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {module:ol/format/GPX~LayoutOptions} layoutOptions Layout options. * @param {module:ol/format/GPX~LayoutOptions} layoutOptions Layout options.
@@ -553,8 +647,7 @@ function readRte(node, objectStack) {
const layoutOptions = /** @type {module:ol/format/GPX~LayoutOptions} */ (values['layoutOptions']); const layoutOptions = /** @type {module:ol/format/GPX~LayoutOptions} */ (values['layoutOptions']);
delete values['layoutOptions']; delete values['layoutOptions'];
const layout = applyLayoutOptions(layoutOptions, flatCoordinates); const layout = applyLayoutOptions(layoutOptions, flatCoordinates);
const geometry = new LineString(null); const geometry = new LineString(flatCoordinates, layout);
geometry.setFlatCoordinates(layout, flatCoordinates);
transformWithOptions(geometry, false, options); transformWithOptions(geometry, false, options);
const feature = new Feature(geometry); const feature = new Feature(geometry);
feature.setProperties(values); feature.setProperties(values);
@@ -585,8 +678,7 @@ function readTrk(node, objectStack) {
const layoutOptions = /** @type {module:ol/format/GPX~LayoutOptions} */ (values['layoutOptions']); const layoutOptions = /** @type {module:ol/format/GPX~LayoutOptions} */ (values['layoutOptions']);
delete values['layoutOptions']; delete values['layoutOptions'];
const layout = applyLayoutOptions(layoutOptions, flatCoordinates, ends); const layout = applyLayoutOptions(layoutOptions, flatCoordinates, ends);
const geometry = new MultiLineString(null); const geometry = new MultiLineString(flatCoordinates, layout, ends);
geometry.setFlatCoordinates(layout, flatCoordinates, ends);
transformWithOptions(geometry, false, options); transformWithOptions(geometry, false, options);
const feature = new Feature(geometry); const feature = new Feature(geometry);
feature.setProperties(values); feature.setProperties(values);
@@ -616,106 +708,6 @@ function readWpt(node, objectStack) {
} }
/**
* @param {Array.<module:ol/Feature>} features List of features.
* @private
*/
GPX.prototype.handleReadExtensions_ = function(features) {
if (!features) {
features = [];
}
for (let i = 0, ii = features.length; i < ii; ++i) {
const feature = features[i];
if (this.readExtensions_) {
const extensionsNode = feature.get('extensionsNode_') || null;
this.readExtensions_(feature, extensionsNode);
}
feature.set('extensionsNode_', undefined);
}
};
/**
* Read the first feature from a GPX source.
* Routes (`<rte>`) are converted into LineString geometries, and tracks (`<trk>`)
* into MultiLineString. Any properties on route and track waypoints are ignored.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {module:ol/Feature} Feature.
* @api
*/
GPX.prototype.readFeature;
/**
* @inheritDoc
*/
GPX.prototype.readFeatureFromNode = function(node, opt_options) {
if (!includes(NAMESPACE_URIS, node.namespaceURI)) {
return null;
}
const featureReader = FEATURE_READER[node.localName];
if (!featureReader) {
return null;
}
const feature = featureReader(node, [this.getReadOptions(node, opt_options)]);
if (!feature) {
return null;
}
this.handleReadExtensions_([feature]);
return feature;
};
/**
* Read all features from a GPX source.
* Routes (`<rte>`) are converted into LineString geometries, and tracks (`<trk>`)
* into MultiLineString. Any properties on route and track waypoints are ignored.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {Array.<module:ol/Feature>} Features.
* @api
*/
GPX.prototype.readFeatures;
/**
* @inheritDoc
*/
GPX.prototype.readFeaturesFromNode = function(node, opt_options) {
if (!includes(NAMESPACE_URIS, node.namespaceURI)) {
return [];
}
if (node.localName == 'gpx') {
/** @type {Array.<module:ol/Feature>} */
const features = pushParseAndPop([], GPX_PARSERS,
node, [this.getReadOptions(node, opt_options)]);
if (features) {
this.handleReadExtensions_(features);
return features;
} else {
return [];
}
}
return [];
};
/**
* Read the projection from a GPX source.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @return {module:ol/proj/Projection} Projection.
* @api
*/
GPX.prototype.readProjection;
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {string} value Value for the link's `href` attribute. * @param {string} value Value for the link's `href` attribute.
@@ -862,43 +854,4 @@ function writeWpt(node, feature, objectStack) {
} }
/**
* Encode an array of features in the GPX format.
* LineString geometries are output as routes (`<rte>`), and MultiLineString
* as tracks (`<trk>`).
*
* @function
* @param {Array.<module:ol/Feature>} features Features.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {string} Result.
* @api
*/
GPX.prototype.writeFeatures;
/**
* Encode an array of features in the GPX format as an XML node.
* LineString geometries are output as routes (`<rte>`), and MultiLineString
* as tracks (`<trk>`).
*
* @param {Array.<module:ol/Feature>} features Features.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Options.
* @return {Node} Node.
* @override
* @api
*/
GPX.prototype.writeFeaturesNode = function(features, opt_options) {
opt_options = this.adaptOptions(opt_options);
//FIXME Serialize metadata
const gpx = createElementNS('http://www.topografix.com/GPX/1/1', 'gpx');
const xmlnsUri = 'http://www.w3.org/2000/xmlns/';
gpx.setAttributeNS(xmlnsUri, 'xmlns:xsi', XML_SCHEMA_INSTANCE_URI);
gpx.setAttributeNS(XML_SCHEMA_INSTANCE_URI, 'xsi:schemaLocation', SCHEMA_LOCATION);
gpx.setAttribute('version', '1.1');
gpx.setAttribute('creator', 'OpenLayers');
pushSerializeAndPop(/** @type {module:ol/xml~NodeStackItem} */
({node: gpx}), GPX_SERIALIZERS, GPX_NODE_FACTORY, features, [opt_options]);
return gpx;
};
export default GPX; export default GPX;

View File

@@ -4,7 +4,6 @@
// TODO: serialize dataProjection as crs member when writing // TODO: serialize dataProjection as crs member when writing
// see https://github.com/openlayers/openlayers/issues/2078 // see https://github.com/openlayers/openlayers/issues/2078
import {inherits} from '../util.js';
import {assert} from '../asserts.js'; import {assert} from '../asserts.js';
import Feature from '../Feature.js'; import Feature from '../Feature.js';
import {transformWithOptions} from '../format/Feature.js'; import {transformWithOptions} from '../format/Feature.js';
@@ -37,16 +36,18 @@ import {get as getProjection} from '../proj.js';
* @classdesc * @classdesc
* Feature format for reading and writing data in the GeoJSON format. * Feature format for reading and writing data in the GeoJSON format.
* *
* @constructor
* @extends {module:ol/format/JSONFeature}
* @param {module:ol/format/GeoJSON~Options=} opt_options Options.
* @api * @api
*/ */
const GeoJSON = function(opt_options) { class GeoJSON extends JSONFeature {
/**
* @param {module:ol/format/GeoJSON~Options=} opt_options Options.
*/
constructor(opt_options) {
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
JSONFeature.call(this); super();
/** /**
* @inheritDoc * @inheritDoc
@@ -73,9 +74,159 @@ const GeoJSON = function(opt_options) {
*/ */
this.extractGeometryName_ = options.extractGeometryName; this.extractGeometryName_ = options.extractGeometryName;
}; }
inherits(GeoJSON, JSONFeature); /**
* @inheritDoc
*/
readFeatureFromObject(object, opt_options) {
/**
* @type {GeoJSONFeature}
*/
let geoJSONFeature = null;
if (object.type === 'Feature') {
geoJSONFeature = /** @type {GeoJSONFeature} */ (object);
} else {
geoJSONFeature = /** @type {GeoJSONFeature} */ ({
type: 'Feature',
geometry: /** @type {GeoJSONGeometry|GeoJSONGeometryCollection} */ (object)
});
}
const geometry = readGeometry(geoJSONFeature.geometry, opt_options);
const feature = new Feature();
if (this.geometryName_) {
feature.setGeometryName(this.geometryName_);
} else if (this.extractGeometryName_ && geoJSONFeature.geometry_name !== undefined) {
feature.setGeometryName(geoJSONFeature.geometry_name);
}
feature.setGeometry(geometry);
if (geoJSONFeature.id !== undefined) {
feature.setId(geoJSONFeature.id);
}
if (geoJSONFeature.properties) {
feature.setProperties(geoJSONFeature.properties);
}
return feature;
}
/**
* @inheritDoc
*/
readFeaturesFromObject(object, opt_options) {
const geoJSONObject = /** @type {GeoJSONObject} */ (object);
/** @type {Array.<module:ol/Feature>} */
let features = null;
if (geoJSONObject.type === 'FeatureCollection') {
const geoJSONFeatureCollection = /** @type {GeoJSONFeatureCollection} */ (object);
features = [];
const geoJSONFeatures = geoJSONFeatureCollection.features;
for (let i = 0, ii = geoJSONFeatures.length; i < ii; ++i) {
features.push(this.readFeatureFromObject(geoJSONFeatures[i], opt_options));
}
} else {
features = [this.readFeatureFromObject(object, opt_options)];
}
return features;
}
/**
* @inheritDoc
*/
readGeometryFromObject(object, opt_options) {
return readGeometry(/** @type {GeoJSONGeometry} */ (object), opt_options);
}
/**
* @inheritDoc
*/
readProjectionFromObject(object) {
const geoJSONObject = /** @type {GeoJSONObject} */ (object);
const crs = geoJSONObject.crs;
let projection;
if (crs) {
if (crs.type == 'name') {
projection = getProjection(crs.properties.name);
} else {
assert(false, 36); // Unknown SRS type
}
} else {
projection = this.dataProjection;
}
return (
/** @type {module:ol/proj/Projection} */ (projection)
);
}
/**
* Encode a feature as a GeoJSON Feature object.
*
* @param {module:ol/Feature} feature Feature.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {GeoJSONFeature} Object.
* @override
* @api
*/
writeFeatureObject(feature, opt_options) {
opt_options = this.adaptOptions(opt_options);
const object = /** @type {GeoJSONFeature} */ ({
'type': 'Feature'
});
const id = feature.getId();
if (id !== undefined) {
object.id = id;
}
const geometry = feature.getGeometry();
if (geometry) {
object.geometry = writeGeometry(geometry, opt_options);
} else {
object.geometry = null;
}
const properties = feature.getProperties();
delete properties[feature.getGeometryName()];
if (!isEmpty(properties)) {
object.properties = properties;
} else {
object.properties = null;
}
return object;
}
/**
* Encode an array of features as a GeoJSON object.
*
* @param {Array.<module:ol/Feature>} features Features.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {GeoJSONFeatureCollection} GeoJSON Object.
* @override
* @api
*/
writeFeaturesObject(features, opt_options) {
opt_options = this.adaptOptions(opt_options);
const objects = [];
for (let i = 0, ii = features.length; i < ii; ++i) {
objects.push(this.writeFeatureObject(features[i], opt_options));
}
return /** @type {GeoJSONFeatureCollection} */ ({
type: 'FeatureCollection',
features: objects
});
}
/**
* Encode a geometry as a GeoJSON object.
*
* @param {module:ol/geom/Geometry} geometry Geometry.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {GeoJSONGeometry|GeoJSONGeometryCollection} Object.
* @override
* @api
*/
writeGeometryObject(geometry, opt_options) {
return writeGeometry(geometry, this.adaptOptions(opt_options));
}
}
/** /**
@@ -325,249 +476,4 @@ function writePolygonGeometry(geometry, opt_options) {
} }
/**
* Read a feature from a GeoJSON Feature source. Only works for Feature or
* geometry types. Use {@link module:ol/format/GeoJSON#readFeatures} to read
* FeatureCollection source. If feature at source has an id, it will be used
* as Feature id by calling {@link module:ol/Feature#setId} internally.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {module:ol/Feature} Feature.
* @api
*/
GeoJSON.prototype.readFeature;
/**
* Read all features from a GeoJSON source. Works for all GeoJSON types.
* If the source includes only geometries, features will be created with those
* geometries.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {Array.<module:ol/Feature>} Features.
* @api
*/
GeoJSON.prototype.readFeatures;
/**
* @inheritDoc
*/
GeoJSON.prototype.readFeatureFromObject = function(object, opt_options) {
/**
* @type {GeoJSONFeature}
*/
let geoJSONFeature = null;
if (object.type === 'Feature') {
geoJSONFeature = /** @type {GeoJSONFeature} */ (object);
} else {
geoJSONFeature = /** @type {GeoJSONFeature} */ ({
type: 'Feature',
geometry: /** @type {GeoJSONGeometry|GeoJSONGeometryCollection} */ (object)
});
}
const geometry = readGeometry(geoJSONFeature.geometry, opt_options);
const feature = new Feature();
if (this.geometryName_) {
feature.setGeometryName(this.geometryName_);
} else if (this.extractGeometryName_ && geoJSONFeature.geometry_name !== undefined) {
feature.setGeometryName(geoJSONFeature.geometry_name);
}
feature.setGeometry(geometry);
if (geoJSONFeature.id !== undefined) {
feature.setId(geoJSONFeature.id);
}
if (geoJSONFeature.properties) {
feature.setProperties(geoJSONFeature.properties);
}
return feature;
};
/**
* @inheritDoc
*/
GeoJSON.prototype.readFeaturesFromObject = function(object, opt_options) {
const geoJSONObject = /** @type {GeoJSONObject} */ (object);
/** @type {Array.<module:ol/Feature>} */
let features = null;
if (geoJSONObject.type === 'FeatureCollection') {
const geoJSONFeatureCollection = /** @type {GeoJSONFeatureCollection} */ (object);
features = [];
const geoJSONFeatures = geoJSONFeatureCollection.features;
for (let i = 0, ii = geoJSONFeatures.length; i < ii; ++i) {
features.push(this.readFeatureFromObject(geoJSONFeatures[i], opt_options));
}
} else {
features = [this.readFeatureFromObject(object, opt_options)];
}
return features;
};
/**
* Read a geometry from a GeoJSON source.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {module:ol/geom/Geometry} Geometry.
* @api
*/
GeoJSON.prototype.readGeometry;
/**
* @inheritDoc
*/
GeoJSON.prototype.readGeometryFromObject = function(object, opt_options) {
return readGeometry(/** @type {GeoJSONGeometry} */ (object), opt_options);
};
/**
* Read the projection from a GeoJSON source.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @return {module:ol/proj/Projection} Projection.
* @api
*/
GeoJSON.prototype.readProjection;
/**
* @inheritDoc
*/
GeoJSON.prototype.readProjectionFromObject = function(object) {
const geoJSONObject = /** @type {GeoJSONObject} */ (object);
const crs = geoJSONObject.crs;
let projection;
if (crs) {
if (crs.type == 'name') {
projection = getProjection(crs.properties.name);
} else {
assert(false, 36); // Unknown SRS type
}
} else {
projection = this.dataProjection;
}
return (
/** @type {module:ol/proj/Projection} */ (projection)
);
};
/**
* Encode a feature as a GeoJSON Feature string.
*
* @function
* @param {module:ol/Feature} feature Feature.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {string} GeoJSON.
* @override
* @api
*/
GeoJSON.prototype.writeFeature;
/**
* Encode a feature as a GeoJSON Feature object.
*
* @param {module:ol/Feature} feature Feature.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {GeoJSONFeature} Object.
* @override
* @api
*/
GeoJSON.prototype.writeFeatureObject = function(feature, opt_options) {
opt_options = this.adaptOptions(opt_options);
const object = /** @type {GeoJSONFeature} */ ({
'type': 'Feature'
});
const id = feature.getId();
if (id !== undefined) {
object.id = id;
}
const geometry = feature.getGeometry();
if (geometry) {
object.geometry = writeGeometry(geometry, opt_options);
} else {
object.geometry = null;
}
const properties = feature.getProperties();
delete properties[feature.getGeometryName()];
if (!isEmpty(properties)) {
object.properties = properties;
} else {
object.properties = null;
}
return object;
};
/**
* Encode an array of features as GeoJSON.
*
* @function
* @param {Array.<module:ol/Feature>} features Features.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {string} GeoJSON.
* @api
*/
GeoJSON.prototype.writeFeatures;
/**
* Encode an array of features as a GeoJSON object.
*
* @param {Array.<module:ol/Feature>} features Features.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {GeoJSONFeatureCollection} GeoJSON Object.
* @override
* @api
*/
GeoJSON.prototype.writeFeaturesObject = function(features, opt_options) {
opt_options = this.adaptOptions(opt_options);
const objects = [];
for (let i = 0, ii = features.length; i < ii; ++i) {
objects.push(this.writeFeatureObject(features[i], opt_options));
}
return /** @type {GeoJSONFeatureCollection} */ ({
type: 'FeatureCollection',
features: objects
});
};
/**
* Encode a geometry as a GeoJSON string.
*
* @function
* @param {module:ol/geom/Geometry} geometry Geometry.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {string} GeoJSON.
* @api
*/
GeoJSON.prototype.writeGeometry;
/**
* Encode a geometry as a GeoJSON object.
*
* @param {module:ol/geom/Geometry} geometry Geometry.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {GeoJSONGeometry|GeoJSONGeometryCollection} Object.
* @override
* @api
*/
GeoJSON.prototype.writeGeometryObject = function(geometry, opt_options) {
return writeGeometry(geometry, this.adaptOptions(opt_options));
};
export default GeoJSON; export default GeoJSON;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/format/IGC * @module ol/format/IGC
*/ */
import {inherits} from '../util.js';
import Feature from '../Feature.js'; import Feature from '../Feature.js';
import {transformWithOptions} from '../format/Feature.js'; import {transformWithOptions} from '../format/Feature.js';
import TextFeature from '../format/TextFeature.js'; import TextFeature from '../format/TextFeature.js';
@@ -19,44 +18,6 @@ const IGCZ = {
NONE: 'none' NONE: 'none'
}; };
/**
* @typedef {Object} Options
* @property {IGCZ|string} [altitudeMode='none'] Altitude mode. Possible
* values are `'barometric'`, `'gps'`, and `'none'`.
*/
/**
* @classdesc
* Feature format for `*.igc` flight recording files.
*
* @constructor
* @extends {module:ol/format/TextFeature}
* @param {module:ol/format/IGC~Options=} opt_options Options.
* @api
*/
const IGC = function(opt_options) {
const options = opt_options ? opt_options : {};
TextFeature.call(this);
/**
* @inheritDoc
*/
this.dataProjection = getProjection('EPSG:4326');
/**
* @private
* @type {IGCZ}
*/
this.altitudeMode_ = options.altitudeMode ? options.altitudeMode : IGCZ.NONE;
};
inherits(IGC, TextFeature);
/** /**
* @const * @const
* @type {RegExp} * @type {RegExp}
@@ -89,21 +50,48 @@ const NEWLINE_RE = /\r\n|\r|\n/;
/** /**
* Read the feature from the IGC source. * @typedef {Object} Options
* @property {IGCZ|string} [altitudeMode='none'] Altitude mode. Possible
* values are `'barometric'`, `'gps'`, and `'none'`.
*/
/**
* @classdesc
* Feature format for `*.igc` flight recording files.
*
* As IGC sources contain a single feature,
* {@link module:ol/format/IGC~IGC#readFeatures} will return the feature in an
* array
* *
* @function
* @param {Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {module:ol/Feature} Feature.
* @api * @api
*/ */
IGC.prototype.readFeature; class IGC extends TextFeature {
/**
* @param {module:ol/format/IGC~Options=} opt_options Options.
*/
constructor(opt_options) {
super();
const options = opt_options ? opt_options : {};
/** /**
* @inheritDoc * @inheritDoc
*/ */
IGC.prototype.readFeatureFromText = function(text, opt_options) { this.dataProjection = getProjection('EPSG:4326');
/**
* @private
* @type {IGCZ}
*/
this.altitudeMode_ = options.altitudeMode ? options.altitudeMode : IGCZ.NONE;
}
/**
* @inheritDoc
*/
readFeatureFromText(text, opt_options) {
const altitudeMode = this.altitudeMode_; const altitudeMode = this.altitudeMode_;
const lines = text.split(NEWLINE_RE); const lines = text.split(NEWLINE_RE);
/** @type {Object.<string, string>} */ /** @type {Object.<string, string>} */
@@ -168,76 +156,48 @@ IGC.prototype.readFeatureFromText = function(text, opt_options) {
if (flatCoordinates.length === 0) { if (flatCoordinates.length === 0) {
return null; return null;
} }
const lineString = new LineString(null);
const layout = altitudeMode == IGCZ.NONE ? GeometryLayout.XYM : GeometryLayout.XYZM; const layout = altitudeMode == IGCZ.NONE ? GeometryLayout.XYM : GeometryLayout.XYZM;
lineString.setFlatCoordinates(layout, flatCoordinates); const lineString = new LineString(flatCoordinates, layout);
const feature = new Feature(transformWithOptions(lineString, false, opt_options)); const feature = new Feature(transformWithOptions(lineString, false, opt_options));
feature.setProperties(properties); feature.setProperties(properties);
return feature; return feature;
}; }
/**
* Read the feature from the source. As IGC sources contain a single
* feature, this will return the feature in an array.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {Array.<module:ol/Feature>} Features.
* @api
*/
IGC.prototype.readFeatures;
/** /**
* @inheritDoc * @inheritDoc
*/ */
IGC.prototype.readFeaturesFromText = function(text, opt_options) { readFeaturesFromText(text, opt_options) {
const feature = this.readFeatureFromText(text, opt_options); const feature = this.readFeatureFromText(text, opt_options);
if (feature) { if (feature) {
return [feature]; return [feature];
} else { } else {
return []; return [];
} }
}; }
/**
* Read the projection from the IGC source.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @return {module:ol/proj/Projection} Projection.
* @api
*/
IGC.prototype.readProjection;
/** /**
* Not implemented. * Not implemented.
* @inheritDoc * @inheritDoc
*/ */
IGC.prototype.writeFeatureText = function(feature, opt_options) {}; writeFeatureText(feature, opt_options) {}
/** /**
* Not implemented. * Not implemented.
* @inheritDoc * @inheritDoc
*/ */
IGC.prototype.writeFeaturesText = function(features, opt_options) {}; writeFeaturesText(features, opt_options) {}
/** /**
* Not implemented. * Not implemented.
* @inheritDoc * @inheritDoc
*/ */
IGC.prototype.writeGeometryText = function(geometry, opt_options) {}; writeGeometryText(geometry, opt_options) {}
/** /**
* Not implemented. * Not implemented.
* @inheritDoc * @inheritDoc
*/ */
IGC.prototype.readGeometryFromText = function(text, opt_options) {}; readGeometryFromText(text, opt_options) {}
}
export default IGC; export default IGC;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/format/JSONFeature * @module ol/format/JSONFeature
*/ */
import {inherits} from '../util.js';
import FeatureFormat from '../format/Feature.js'; import FeatureFormat from '../format/Feature.js';
import FormatType from '../format/FormatType.js'; import FormatType from '../format/FormatType.js';
@@ -11,15 +10,167 @@ import FormatType from '../format/FormatType.js';
* instantiated in apps. * instantiated in apps.
* Base class for JSON feature formats. * Base class for JSON feature formats.
* *
* @constructor
* @abstract * @abstract
* @extends {module:ol/format/Feature}
*/ */
const JSONFeature = function() { class JSONFeature extends FeatureFormat {
FeatureFormat.call(this); constructor() {
}; super();
}
inherits(JSONFeature, FeatureFormat); /**
* @inheritDoc
*/
getType() {
return FormatType.JSON;
}
/**
* Read a feature. Only works for a single feature. Use `readFeatures` to
* read a feature collection.
*
* @param {ArrayBuffer|Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {module:ol/Feature} Feature.
* @api
*/
readFeature(source, opt_options) {
return this.readFeatureFromObject(
getObject(source), this.getReadOptions(source, opt_options));
}
/**
* Read all features. Works with both a single feature and a feature
* collection.
*
* @param {ArrayBuffer|Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {Array.<module:ol/Feature>} Features.
* @api
*/
readFeatures(source, opt_options) {
return this.readFeaturesFromObject(
getObject(source), this.getReadOptions(source, opt_options));
}
/**
* @abstract
* @param {Object} object Object.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @protected
* @return {module:ol/Feature} Feature.
*/
readFeatureFromObject(object, opt_options) {}
/**
* @abstract
* @param {Object} object Object.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @protected
* @return {Array.<module:ol/Feature>} Features.
*/
readFeaturesFromObject(object, opt_options) {}
/**
* Read a geometry.
*
* @param {ArrayBuffer|Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {module:ol/geom/Geometry} Geometry.
* @api
*/
readGeometry(source, opt_options) {
return this.readGeometryFromObject(
getObject(source), this.getReadOptions(source, opt_options));
}
/**
* @abstract
* @param {Object} object Object.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @protected
* @return {module:ol/geom/Geometry} Geometry.
*/
readGeometryFromObject(object, opt_options) {}
/**
* Read the projection.
*
* @param {ArrayBuffer|Document|Node|Object|string} source Source.
* @return {module:ol/proj/Projection} Projection.
* @api
*/
readProjection(source) {
return this.readProjectionFromObject(getObject(source));
}
/**
* @abstract
* @param {Object} object Object.
* @protected
* @return {module:ol/proj/Projection} Projection.
*/
readProjectionFromObject(object) {}
/**
* Encode a feature as string.
*
* @param {module:ol/Feature} feature Feature.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {string} Encoded feature.
* @api
*/
writeFeature(feature, opt_options) {
return JSON.stringify(this.writeFeatureObject(feature, opt_options));
}
/**
* @abstract
* @param {module:ol/Feature} feature Feature.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {Object} Object.
*/
writeFeatureObject(feature, opt_options) {}
/**
* Encode an array of features as string.
*
* @param {Array.<module:ol/Feature>} features Features.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {string} Encoded features.
* @api
*/
writeFeatures(features, opt_options) {
return JSON.stringify(this.writeFeaturesObject(features, opt_options));
}
/**
* @abstract
* @param {Array.<module:ol/Feature>} features Features.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {Object} Object.
*/
writeFeaturesObject(features, opt_options) {}
/**
* Encode a geometry as string.
*
* @param {module:ol/geom/Geometry} geometry Geometry.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {string} Encoded geometry.
* @api
*/
writeGeometry(geometry, opt_options) {
return JSON.stringify(this.writeGeometryObject(geometry, opt_options));
}
/**
* @abstract
* @param {module:ol/geom/Geometry} geometry Geometry.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {Object} Object.
*/
writeGeometryObject(geometry, opt_options) {}
}
/** /**
@@ -38,135 +189,4 @@ function getObject(source) {
} }
/**
* @inheritDoc
*/
JSONFeature.prototype.getType = function() {
return FormatType.JSON;
};
/**
* @inheritDoc
*/
JSONFeature.prototype.readFeature = function(source, opt_options) {
return this.readFeatureFromObject(
getObject(source), this.getReadOptions(source, opt_options));
};
/**
* @inheritDoc
*/
JSONFeature.prototype.readFeatures = function(source, opt_options) {
return this.readFeaturesFromObject(
getObject(source), this.getReadOptions(source, opt_options));
};
/**
* @abstract
* @param {Object} object Object.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @protected
* @return {module:ol/Feature} Feature.
*/
JSONFeature.prototype.readFeatureFromObject = function(object, opt_options) {};
/**
* @abstract
* @param {Object} object Object.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @protected
* @return {Array.<module:ol/Feature>} Features.
*/
JSONFeature.prototype.readFeaturesFromObject = function(object, opt_options) {};
/**
* @inheritDoc
*/
JSONFeature.prototype.readGeometry = function(source, opt_options) {
return this.readGeometryFromObject(
getObject(source), this.getReadOptions(source, opt_options));
};
/**
* @abstract
* @param {Object} object Object.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @protected
* @return {module:ol/geom/Geometry} Geometry.
*/
JSONFeature.prototype.readGeometryFromObject = function(object, opt_options) {};
/**
* @inheritDoc
*/
JSONFeature.prototype.readProjection = function(source) {
return this.readProjectionFromObject(getObject(source));
};
/**
* @abstract
* @param {Object} object Object.
* @protected
* @return {module:ol/proj/Projection} Projection.
*/
JSONFeature.prototype.readProjectionFromObject = function(object) {};
/**
* @inheritDoc
*/
JSONFeature.prototype.writeFeature = function(feature, opt_options) {
return JSON.stringify(this.writeFeatureObject(feature, opt_options));
};
/**
* @abstract
* @param {module:ol/Feature} feature Feature.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {Object} Object.
*/
JSONFeature.prototype.writeFeatureObject = function(feature, opt_options) {};
/**
* @inheritDoc
*/
JSONFeature.prototype.writeFeatures = function(features, opt_options) {
return JSON.stringify(this.writeFeaturesObject(features, opt_options));
};
/**
* @abstract
* @param {Array.<module:ol/Feature>} features Features.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {Object} Object.
*/
JSONFeature.prototype.writeFeaturesObject = function(features, opt_options) {};
/**
* @inheritDoc
*/
JSONFeature.prototype.writeGeometry = function(geometry, opt_options) {
return JSON.stringify(this.writeGeometryObject(geometry, opt_options));
};
/**
* @abstract
* @param {module:ol/geom/Geometry} geometry Geometry.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {Object} Object.
*/
JSONFeature.prototype.writeGeometryObject = function(geometry, opt_options) {};
export default JSONFeature; export default JSONFeature;

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,6 @@
*/ */
//FIXME Implement projection handling //FIXME Implement projection handling
import {inherits} from '../util.js';
import {assert} from '../asserts.js'; import {assert} from '../asserts.js';
import PBF from 'pbf'; import PBF from 'pbf';
import FeatureFormat, {transformWithOptions} from '../format/Feature.js'; import FeatureFormat, {transformWithOptions} from '../format/Feature.js';
@@ -42,14 +41,16 @@ import RenderFeature from '../render/Feature.js';
* @classdesc * @classdesc
* Feature format for reading data in the Mapbox MVT format. * Feature format for reading data in the Mapbox MVT format.
* *
* @constructor
* @extends {module:ol/format/Feature}
* @param {module:ol/format/MVT~Options=} opt_options Options. * @param {module:ol/format/MVT~Options=} opt_options Options.
* @api * @api
*/ */
const MVT = function(opt_options) { class MVT extends FeatureFormat {
FeatureFormat.call(this); /**
* @param {module:ol/format/MVT~Options=} opt_options Options.
*/
constructor(opt_options) {
super();
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
@@ -94,9 +95,228 @@ const MVT = function(opt_options) {
*/ */
this.extent_ = null; this.extent_ = null;
}; }
inherits(MVT, FeatureFormat); /**
* Read the raw geometry from the pbf offset stored in a raw feature's geometry
* property.
* @suppress {missingProperties}
* @param {Object} pbf PBF.
* @param {Object} feature Raw feature.
* @param {Array.<number>} flatCoordinates Array to store flat coordinates in.
* @param {Array.<number>} ends Array to store ends in.
* @private
*/
readRawGeometry_(pbf, feature, flatCoordinates, ends) {
pbf.pos = feature.geometry;
const end = pbf.readVarint() + pbf.pos;
let cmd = 1;
let length = 0;
let x = 0;
let y = 0;
let coordsLen = 0;
let currentEnd = 0;
while (pbf.pos < end) {
if (!length) {
const cmdLen = pbf.readVarint();
cmd = cmdLen & 0x7;
length = cmdLen >> 3;
}
length--;
if (cmd === 1 || cmd === 2) {
x += pbf.readSVarint();
y += pbf.readSVarint();
if (cmd === 1) { // moveTo
if (coordsLen > currentEnd) {
ends.push(coordsLen);
currentEnd = coordsLen;
}
}
flatCoordinates.push(x, y);
coordsLen += 2;
} else if (cmd === 7) {
if (coordsLen > currentEnd) {
// close polygon
flatCoordinates.push(
flatCoordinates[currentEnd], flatCoordinates[currentEnd + 1]);
coordsLen += 2;
}
} else {
assert(false, 59); // Invalid command found in the PBF
}
}
if (coordsLen > currentEnd) {
ends.push(coordsLen);
currentEnd = coordsLen;
}
}
/**
* @private
* @param {Object} pbf PBF
* @param {Object} rawFeature Raw Mapbox feature.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {module:ol/Feature|module:ol/render/Feature} Feature.
*/
createFeature_(pbf, rawFeature, opt_options) {
const type = rawFeature.type;
if (type === 0) {
return null;
}
let feature;
const id = rawFeature.id;
const values = rawFeature.properties;
values[this.layerName_] = rawFeature.layer.name;
const flatCoordinates = [];
const ends = [];
this.readRawGeometry_(pbf, rawFeature, flatCoordinates, ends);
const geometryType = getGeometryType(type, ends.length);
if (this.featureClass_ === RenderFeature) {
feature = new this.featureClass_(geometryType, flatCoordinates, ends, values, id);
} else {
let geom;
if (geometryType == GeometryType.POLYGON) {
const endss = [];
let offset = 0;
let prevEndIndex = 0;
for (let i = 0, ii = ends.length; i < ii; ++i) {
const end = ends[i];
if (!linearRingIsClockwise(flatCoordinates, offset, end, 2)) {
endss.push(ends.slice(prevEndIndex, i));
prevEndIndex = i;
}
offset = end;
}
if (endss.length > 1) {
geom = new MultiPolygon(flatCoordinates, GeometryLayout.XY, endss);
} else {
geom = new Polygon(flatCoordinates, GeometryLayout.XY, ends);
}
} else {
geom = geometryType === GeometryType.POINT ? new Point(flatCoordinates, GeometryLayout.XY) :
geometryType === GeometryType.LINE_STRING ? new LineString(flatCoordinates, GeometryLayout.XY) :
geometryType === GeometryType.POLYGON ? new Polygon(flatCoordinates, GeometryLayout.XY, ends) :
geometryType === GeometryType.MULTI_POINT ? new MultiPoint(flatCoordinates, GeometryLayout.XY) :
geometryType === GeometryType.MULTI_LINE_STRING ? new MultiLineString(flatCoordinates, GeometryLayout.XY, ends) :
null;
}
feature = new this.featureClass_();
if (this.geometryName_) {
feature.setGeometryName(this.geometryName_);
}
const geometry = transformWithOptions(geom, false, this.adaptOptions(opt_options));
feature.setGeometry(geometry);
feature.setId(id);
feature.setProperties(values);
}
return feature;
}
/**
* @inheritDoc
* @api
*/
getLastExtent() {
return this.extent_;
}
/**
* @inheritDoc
*/
getType() {
return FormatType.ARRAY_BUFFER;
}
/**
* @inheritDoc
* @api
*/
readFeatures(source, opt_options) {
const layers = this.layers_;
const pbf = new PBF(/** @type {ArrayBuffer} */ (source));
const pbfLayers = pbf.readFields(layersPBFReader, {});
/** @type {Array.<module:ol/Feature|module:ol/render/Feature>} */
const features = [];
for (const name in pbfLayers) {
if (layers && layers.indexOf(name) == -1) {
continue;
}
const pbfLayer = pbfLayers[name];
for (let i = 0, ii = pbfLayer.length; i < ii; ++i) {
const rawFeature = readRawFeature(pbf, pbfLayer, i);
features.push(this.createFeature_(pbf, rawFeature));
}
this.extent_ = pbfLayer ? [0, 0, pbfLayer.extent, pbfLayer.extent] : null;
}
return features;
}
/**
* @inheritDoc
* @api
*/
readProjection(source) {
return this.dataProjection;
}
/**
* Sets the layers that features will be read from.
* @param {Array.<string>} layers Layers.
* @api
*/
setLayers(layers) {
this.layers_ = layers;
}
/**
* Not implemented.
* @override
*/
readFeature() {}
/**
* Not implemented.
* @override
*/
readGeometry() {}
/**
* Not implemented.
* @override
*/
writeFeature() {}
/**
* Not implemented.
* @override
*/
writeGeometry() {}
/**
* Not implemented.
* @override
*/
writeFeatures() {}
}
/** /**
@@ -201,72 +421,6 @@ function readRawFeature(pbf, layer, i) {
} }
/**
* Read the raw geometry from the pbf offset stored in a raw feature's geometry
* property.
* @suppress {missingProperties}
* @param {Object} pbf PBF.
* @param {Object} feature Raw feature.
* @param {Array.<number>} flatCoordinates Array to store flat coordinates in.
* @param {Array.<number>} ends Array to store ends in.
* @private
*/
MVT.prototype.readRawGeometry_ = function(pbf, feature, flatCoordinates, ends) {
pbf.pos = feature.geometry;
const end = pbf.readVarint() + pbf.pos;
let cmd = 1;
let length = 0;
let x = 0;
let y = 0;
let coordsLen = 0;
let currentEnd = 0;
while (pbf.pos < end) {
if (!length) {
const cmdLen = pbf.readVarint();
cmd = cmdLen & 0x7;
length = cmdLen >> 3;
}
length--;
if (cmd === 1 || cmd === 2) {
x += pbf.readSVarint();
y += pbf.readSVarint();
if (cmd === 1) { // moveTo
if (coordsLen > currentEnd) {
ends.push(coordsLen);
currentEnd = coordsLen;
}
}
flatCoordinates.push(x, y);
coordsLen += 2;
} else if (cmd === 7) {
if (coordsLen > currentEnd) {
// close polygon
flatCoordinates.push(
flatCoordinates[currentEnd], flatCoordinates[currentEnd + 1]);
coordsLen += 2;
}
} else {
assert(false, 59); // Invalid command found in the PBF
}
}
if (coordsLen > currentEnd) {
ends.push(coordsLen);
currentEnd = coordsLen;
}
};
/** /**
* @suppress {missingProperties} * @suppress {missingProperties}
* @param {number} type The raw feature's geometry type * @param {number} type The raw feature's geometry type
@@ -292,170 +446,4 @@ function getGeometryType(type, numEnds) {
return geometryType; return geometryType;
} }
/**
* @private
* @param {Object} pbf PBF
* @param {Object} rawFeature Raw Mapbox feature.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {module:ol/Feature|module:ol/render/Feature} Feature.
*/
MVT.prototype.createFeature_ = function(pbf, rawFeature, opt_options) {
const type = rawFeature.type;
if (type === 0) {
return null;
}
let feature;
const id = rawFeature.id;
const values = rawFeature.properties;
values[this.layerName_] = rawFeature.layer.name;
const flatCoordinates = [];
let ends = [];
this.readRawGeometry_(pbf, rawFeature, flatCoordinates, ends);
const geometryType = getGeometryType(type, ends.length);
if (this.featureClass_ === RenderFeature) {
feature = new this.featureClass_(geometryType, flatCoordinates, ends, values, id);
} else {
let geom;
if (geometryType == GeometryType.POLYGON) {
const endss = [];
let offset = 0;
let prevEndIndex = 0;
for (let i = 0, ii = ends.length; i < ii; ++i) {
const end = ends[i];
if (!linearRingIsClockwise(flatCoordinates, offset, end, 2)) {
endss.push(ends.slice(prevEndIndex, i));
prevEndIndex = i;
}
offset = end;
}
if (endss.length > 1) {
ends = endss;
geom = new MultiPolygon(null);
} else {
geom = new Polygon(null);
}
} else {
geom = geometryType === GeometryType.POINT ? new Point(null) :
geometryType === GeometryType.LINE_STRING ? new LineString(null) :
geometryType === GeometryType.POLYGON ? new Polygon(null) :
geometryType === GeometryType.MULTI_POINT ? new MultiPoint (null) :
geometryType === GeometryType.MULTI_LINE_STRING ? new MultiLineString(null) :
null;
}
geom.setFlatCoordinates(GeometryLayout.XY, flatCoordinates, ends);
feature = new this.featureClass_();
if (this.geometryName_) {
feature.setGeometryName(this.geometryName_);
}
const geometry = transformWithOptions(geom, false, this.adaptOptions(opt_options));
feature.setGeometry(geometry);
feature.setId(id);
feature.setProperties(values);
}
return feature;
};
/**
* @inheritDoc
* @api
*/
MVT.prototype.getLastExtent = function() {
return this.extent_;
};
/**
* @inheritDoc
*/
MVT.prototype.getType = function() {
return FormatType.ARRAY_BUFFER;
};
/**
* @inheritDoc
* @api
*/
MVT.prototype.readFeatures = function(source, opt_options) {
const layers = this.layers_;
const pbf = new PBF(/** @type {ArrayBuffer} */ (source));
const pbfLayers = pbf.readFields(layersPBFReader, {});
/** @type {Array.<module:ol/Feature|module:ol/render/Feature>} */
const features = [];
for (const name in pbfLayers) {
if (layers && layers.indexOf(name) == -1) {
continue;
}
const pbfLayer = pbfLayers[name];
for (let i = 0, ii = pbfLayer.length; i < ii; ++i) {
const rawFeature = readRawFeature(pbf, pbfLayer, i);
features.push(this.createFeature_(pbf, rawFeature));
}
this.extent_ = pbfLayer ? [0, 0, pbfLayer.extent, pbfLayer.extent] : null;
}
return features;
};
/**
* @inheritDoc
* @api
*/
MVT.prototype.readProjection = function(source) {
return this.dataProjection;
};
/**
* Sets the layers that features will be read from.
* @param {Array.<string>} layers Layers.
* @api
*/
MVT.prototype.setLayers = function(layers) {
this.layers_ = layers;
};
/**
* Not implemented.
* @override
*/
MVT.prototype.readFeature = function() {};
/**
* Not implemented.
* @override
*/
MVT.prototype.readGeometry = function() {};
/**
* Not implemented.
* @override
*/
MVT.prototype.writeFeature = function() {};
/**
* Not implemented.
* @override
*/
MVT.prototype.writeGeometry = function() {};
/**
* Not implemented.
* @override
*/
MVT.prototype.writeFeatures = function() {};
export default MVT; export default MVT;

View File

@@ -2,7 +2,6 @@
* @module ol/format/OSMXML * @module ol/format/OSMXML
*/ */
// FIXME add typedef for stack state objects // FIXME add typedef for stack state objects
import {inherits} from '../util.js';
import {extend} from '../array.js'; import {extend} from '../array.js';
import Feature from '../Feature.js'; import Feature from '../Feature.js';
import {transformWithOptions} from '../format/Feature.js'; import {transformWithOptions} from '../format/Feature.js';
@@ -15,26 +14,6 @@ import {isEmpty} from '../obj.js';
import {get as getProjection} from '../proj.js'; import {get as getProjection} from '../proj.js';
import {pushParseAndPop, makeStructureNS} from '../xml.js'; import {pushParseAndPop, makeStructureNS} from '../xml.js';
/**
* @classdesc
* Feature format for reading data in the
* [OSMXML format](http://wiki.openstreetmap.org/wiki/OSM_XML).
*
* @constructor
* @extends {module:ol/format/XMLFeature}
* @api
*/
const OSMXML = function() {
XMLFeature.call(this);
/**
* @inheritDoc
*/
this.dataProjection = getProjection('EPSG:4326');
};
inherits(OSMXML, XMLFeature);
/** /**
* @const * @const
@@ -65,6 +44,83 @@ const PARSERS = makeStructureNS(
}); });
/**
* @classdesc
* Feature format for reading data in the
* [OSMXML format](http://wiki.openstreetmap.org/wiki/OSM_XML).
*
* @api
*/
class OSMXML extends XMLFeature {
constructor() {
super();
/**
* @inheritDoc
*/
this.dataProjection = getProjection('EPSG:4326');
}
/**
* @inheritDoc
*/
readFeaturesFromNode(node, opt_options) {
const options = this.getReadOptions(node, opt_options);
if (node.localName == 'osm') {
const state = pushParseAndPop({
nodes: {},
ways: [],
features: []
}, PARSERS, node, [options]);
// parse nodes in ways
for (let j = 0; j < state.ways.length; j++) {
const values = /** @type {Object} */ (state.ways[j]);
/** @type {Array.<number>} */
const flatCoordinates = [];
for (let i = 0, ii = values.ndrefs.length; i < ii; i++) {
const point = state.nodes[values.ndrefs[i]];
extend(flatCoordinates, point);
}
let geometry;
if (values.ndrefs[0] == values.ndrefs[values.ndrefs.length - 1]) {
// closed way
geometry = new Polygon(flatCoordinates, GeometryLayout.XY, [flatCoordinates.length]);
} else {
geometry = new LineString(flatCoordinates, GeometryLayout.XY);
}
transformWithOptions(geometry, false, options);
const feature = new Feature(geometry);
feature.setId(values.id);
feature.setProperties(values.tags);
state.features.push(feature);
}
if (state.features) {
return state.features;
}
}
return [];
}
/**
* Not implemented.
* @inheritDoc
*/
writeFeatureNode(feature, opt_options) {}
/**
* Not implemented.
* @inheritDoc
*/
writeFeaturesNode(features, opt_options) {}
/**
* Not implemented.
* @inheritDoc
*/
writeGeometryNode(geometry, opt_options) {}
}
/** /**
* @const * @const
* @type {Object.<string, Object.<string, module:ol/xml~Parser>>} * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}
@@ -140,90 +196,4 @@ function readTag(node, objectStack) {
} }
/**
* Read all features from an OSM source.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {Array.<module:ol/Feature>} Features.
* @api
*/
OSMXML.prototype.readFeatures;
/**
* @inheritDoc
*/
OSMXML.prototype.readFeaturesFromNode = function(node, opt_options) {
const options = this.getReadOptions(node, opt_options);
if (node.localName == 'osm') {
const state = pushParseAndPop({
nodes: {},
ways: [],
features: []
}, PARSERS, node, [options]);
// parse nodes in ways
for (let j = 0; j < state.ways.length; j++) {
const values = /** @type {Object} */ (state.ways[j]);
/** @type {Array.<number>} */
const flatCoordinates = [];
for (let i = 0, ii = values.ndrefs.length; i < ii; i++) {
const point = state.nodes[values.ndrefs[i]];
extend(flatCoordinates, point);
}
let geometry;
if (values.ndrefs[0] == values.ndrefs[values.ndrefs.length - 1]) {
// closed way
geometry = new Polygon(null);
geometry.setFlatCoordinates(GeometryLayout.XY, flatCoordinates,
[flatCoordinates.length]);
} else {
geometry = new LineString(null);
geometry.setFlatCoordinates(GeometryLayout.XY, flatCoordinates);
}
transformWithOptions(geometry, false, options);
const feature = new Feature(geometry);
feature.setId(values.id);
feature.setProperties(values.tags);
state.features.push(feature);
}
if (state.features) {
return state.features;
}
}
return [];
};
/**
* Read the projection from an OSM source.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @return {module:ol/proj/Projection} Projection.
* @api
*/
OSMXML.prototype.readProjection;
/**
* Not implemented.
* @inheritDoc
*/
OSMXML.prototype.writeFeatureNode = function(feature, opt_options) {};
/**
* Not implemented.
* @inheritDoc
*/
OSMXML.prototype.writeFeaturesNode = function(features, opt_options) {};
/**
* Not implemented.
* @inheritDoc
*/
OSMXML.prototype.writeGeometryNode = function(geometry, opt_options) {};
export default OSMXML; export default OSMXML;

View File

@@ -1,22 +1,11 @@
/** /**
* @module ol/format/OWS * @module ol/format/OWS
*/ */
import {inherits} from '../util.js';
import {readHref} from '../format/XLink.js'; import {readHref} from '../format/XLink.js';
import XML from '../format/XML.js'; import XML from '../format/XML.js';
import {readString} from '../format/xsd.js'; import {readString} from '../format/xsd.js';
import {makeObjectPropertyPusher, makeObjectPropertySetter, makeStructureNS, pushParseAndPop} from '../xml.js'; import {makeObjectPropertyPusher, makeObjectPropertySetter, makeStructureNS, pushParseAndPop} from '../xml.js';
/**
* @constructor
* @extends {module:ol/format/XML}
*/
const OWS = function() {
XML.call(this);
};
inherits(OWS, XML);
/** /**
* @const * @const
@@ -37,6 +26,34 @@ const PARSERS = makeStructureNS(
}); });
class OWS extends XML {
constructor() {
super();
}
/**
* @inheritDoc
*/
readFromDocument(doc) {
for (let n = doc.firstChild; n; n = n.nextSibling) {
if (n.nodeType == Node.ELEMENT_NODE) {
return this.readFromNode(n);
}
}
return null;
}
/**
* @inheritDoc
*/
readFromNode(node) {
const owsObject = pushParseAndPop({},
PARSERS, node, []);
return owsObject ? owsObject : null;
}
}
/** /**
* @const * @const
* @type {Object.<string, Object.<string, module:ol/xml~Parser>>} * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}
@@ -187,29 +204,6 @@ const SERVICE_PROVIDER_PARSERS =
}); });
/**
* @inheritDoc
*/
OWS.prototype.readFromDocument = function(doc) {
for (let n = doc.firstChild; n; n = n.nextSibling) {
if (n.nodeType == Node.ELEMENT_NODE) {
return this.readFromNode(n);
}
}
return null;
};
/**
* @inheritDoc
*/
OWS.prototype.readFromNode = function(node) {
const owsObject = pushParseAndPop({},
PARSERS, node, []);
return owsObject ? owsObject : null;
};
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack. * @param {Array.<*>} objectStack Object stack.

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/format/Polyline * @module ol/format/Polyline
*/ */
import {inherits} from '../util.js';
import {assert} from '../asserts.js'; import {assert} from '../asserts.js';
import Feature from '../Feature.js'; import Feature from '../Feature.js';
import {transformWithOptions} from '../format/Feature.js'; import {transformWithOptions} from '../format/Feature.js';
@@ -27,16 +26,25 @@ import {get as getProjection} from '../proj.js';
* Feature format for reading and writing data in the Encoded * Feature format for reading and writing data in the Encoded
* Polyline Algorithm Format. * Polyline Algorithm Format.
* *
* @constructor * When reading features, the coordinates are assumed to be in two dimensions
* @extends {module:ol/format/TextFeature} * and in [latitude, longitude] order.
* @param {module:ol/format/Polyline~Options=} opt_options Optional configuration object. *
* As Polyline sources contain a single feature,
* {@link module:ol/format/Polyline~Polyline#readFeatures} will return the
* feature in an array.
*
* @api * @api
*/ */
const Polyline = function(opt_options) { class Polyline extends TextFeature {
/**
* @param {module:ol/format/Polyline~Options=} opt_options Optional configuration object.
*/
constructor(opt_options) {
super();
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
TextFeature.call(this);
/** /**
* @inheritDoc * @inheritDoc
@@ -55,9 +63,74 @@ const Polyline = function(opt_options) {
*/ */
this.geometryLayout_ = options.geometryLayout ? this.geometryLayout_ = options.geometryLayout ?
options.geometryLayout : GeometryLayout.XY; options.geometryLayout : GeometryLayout.XY;
}; }
inherits(Polyline, TextFeature); /**
* @inheritDoc
*/
readFeatureFromText(text, opt_options) {
const geometry = this.readGeometryFromText(text, opt_options);
return new Feature(geometry);
}
/**
* @inheritDoc
*/
readFeaturesFromText(text, opt_options) {
const feature = this.readFeatureFromText(text, opt_options);
return [feature];
}
/**
* @inheritDoc
*/
readGeometryFromText(text, opt_options) {
const stride = getStrideForLayout(this.geometryLayout_);
const flatCoordinates = decodeDeltas(text, stride, this.factor_);
flipXY(flatCoordinates, 0, flatCoordinates.length, stride, flatCoordinates);
const coordinates = inflateCoordinates(flatCoordinates, 0, flatCoordinates.length, stride);
return (
/** @type {module:ol/geom/Geometry} */ (transformWithOptions(
new LineString(coordinates, this.geometryLayout_),
false,
this.adaptOptions(opt_options)
))
);
}
/**
* @inheritDoc
*/
writeFeatureText(feature, opt_options) {
const geometry = feature.getGeometry();
if (geometry) {
return this.writeGeometryText(geometry, opt_options);
} else {
assert(false, 40); // Expected `feature` to have a geometry
return '';
}
}
/**
* @inheritDoc
*/
writeFeaturesText(features, opt_options) {
return this.writeFeatureText(features[0], opt_options);
}
/**
* @inheritDoc
*/
writeGeometryText(geometry, opt_options) {
geometry = /** @type {module:ol/geom/LineString} */
(transformWithOptions(geometry, true, this.adaptOptions(opt_options)));
const flatCoordinates = geometry.getFlatCoordinates();
const stride = geometry.getStride();
flipXY(flatCoordinates, 0, flatCoordinates.length, stride, flatCoordinates);
return encodeDeltas(flatCoordinates, stride, this.factor_);
}
}
/** /**
@@ -264,135 +337,4 @@ export function encodeUnsignedInteger(num) {
} }
/**
* Read the feature from the Polyline source. The coordinates are assumed to be
* in two dimensions and in latitude, longitude order.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {module:ol/Feature} Feature.
* @api
*/
Polyline.prototype.readFeature;
/**
* @inheritDoc
*/
Polyline.prototype.readFeatureFromText = function(text, opt_options) {
const geometry = this.readGeometryFromText(text, opt_options);
return new Feature(geometry);
};
/**
* Read the feature from the source. As Polyline sources contain a single
* feature, this will return the feature in an array.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {Array.<module:ol/Feature>} Features.
* @api
*/
Polyline.prototype.readFeatures;
/**
* @inheritDoc
*/
Polyline.prototype.readFeaturesFromText = function(text, opt_options) {
const feature = this.readFeatureFromText(text, opt_options);
return [feature];
};
/**
* Read the geometry from the source.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {module:ol/geom/Geometry} Geometry.
* @api
*/
Polyline.prototype.readGeometry;
/**
* @inheritDoc
*/
Polyline.prototype.readGeometryFromText = function(text, opt_options) {
const stride = getStrideForLayout(this.geometryLayout_);
const flatCoordinates = decodeDeltas(text, stride, this.factor_);
flipXY(flatCoordinates, 0, flatCoordinates.length, stride, flatCoordinates);
const coordinates = inflateCoordinates(flatCoordinates, 0, flatCoordinates.length, stride);
return (
/** @type {module:ol/geom/Geometry} */ (transformWithOptions(
new LineString(coordinates, this.geometryLayout_),
false,
this.adaptOptions(opt_options)
))
);
};
/**
* Read the projection from a Polyline source.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @return {module:ol/proj/Projection} Projection.
* @api
*/
Polyline.prototype.readProjection;
/**
* @inheritDoc
*/
Polyline.prototype.writeFeatureText = function(feature, opt_options) {
const geometry = feature.getGeometry();
if (geometry) {
return this.writeGeometryText(geometry, opt_options);
} else {
assert(false, 40); // Expected `feature` to have a geometry
return '';
}
};
/**
* @inheritDoc
*/
Polyline.prototype.writeFeaturesText = function(features, opt_options) {
return this.writeFeatureText(features[0], opt_options);
};
/**
* Write a single geometry in Polyline format.
*
* @function
* @param {module:ol/geom/Geometry} geometry Geometry.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {string} Geometry.
* @api
*/
Polyline.prototype.writeGeometry;
/**
* @inheritDoc
*/
Polyline.prototype.writeGeometryText = function(geometry, opt_options) {
geometry = /** @type {module:ol/geom/LineString} */
(transformWithOptions(geometry, true, this.adaptOptions(opt_options)));
const flatCoordinates = geometry.getFlatCoordinates();
const stride = geometry.getStride();
flipXY(flatCoordinates, 0, flatCoordinates.length, stride, flatCoordinates);
return encodeDeltas(flatCoordinates, stride, this.factor_);
};
export default Polyline; export default Polyline;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/format/TextFeature * @module ol/format/TextFeature
*/ */
import {inherits} from '../util.js';
import FeatureFormat from '../format/Feature.js'; import FeatureFormat from '../format/Feature.js';
import FormatType from '../format/FormatType.js'; import FormatType from '../format/FormatType.js';
@@ -11,15 +10,169 @@ import FormatType from '../format/FormatType.js';
* instantiated in apps. * instantiated in apps.
* Base class for text feature formats. * Base class for text feature formats.
* *
* @constructor
* @abstract * @abstract
* @extends {module:ol/format/Feature}
*/ */
const TextFeature = function() { class TextFeature extends FeatureFormat {
FeatureFormat.call(this); constructor() {
}; super();
}
inherits(TextFeature, FeatureFormat); /**
* @inheritDoc
*/
getType() {
return FormatType.TEXT;
}
/**
* Read the feature from the source.
*
* @param {Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {module:ol/Feature} Feature.
* @api
*/
readFeature(source, opt_options) {
return this.readFeatureFromText(getText(source), this.adaptOptions(opt_options));
}
/**
* @abstract
* @param {string} text Text.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @protected
* @return {module:ol/Feature} Feature.
*/
readFeatureFromText(text, opt_options) {}
/**
* Read the features from the source.
*
* @param {Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {Array.<module:ol/Feature>} Features.
* @api
*/
readFeatures(source, opt_options) {
return this.readFeaturesFromText(getText(source), this.adaptOptions(opt_options));
}
/**
* @abstract
* @param {string} text Text.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @protected
* @return {Array.<module:ol/Feature>} Features.
*/
readFeaturesFromText(text, opt_options) {}
/**
* Read the geometry from the source.
*
* @param {Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {module:ol/geom/Geometry} Geometry.
* @api
*/
readGeometry(source, opt_options) {
return this.readGeometryFromText(getText(source), this.adaptOptions(opt_options));
}
/**
* @abstract
* @param {string} text Text.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @protected
* @return {module:ol/geom/Geometry} Geometry.
*/
readGeometryFromText(text, opt_options) {}
/**
* Read the projection from the source.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @return {module:ol/proj/Projection} Projection.
* @api
*/
readProjection(source) {
return this.readProjectionFromText(getText(source));
}
/**
* @param {string} text Text.
* @protected
* @return {module:ol/proj/Projection} Projection.
*/
readProjectionFromText(text) {
return this.dataProjection;
}
/**
* Encode a feature as a string.
*
* @function
* @param {module:ol/Feature} feature Feature.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {string} Encoded feature.
* @api
*/
writeFeature(feature, opt_options) {
return this.writeFeatureText(feature, this.adaptOptions(opt_options));
}
/**
* @abstract
* @param {module:ol/Feature} feature Features.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @protected
* @return {string} Text.
*/
writeFeatureText(feature, opt_options) {}
/**
* Encode an array of features as string.
*
* @param {Array.<module:ol/Feature>} features Features.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {string} Encoded features.
* @api
*/
writeFeatures(features, opt_options) {
return this.writeFeaturesText(features, this.adaptOptions(opt_options));
}
/**
* @abstract
* @param {Array.<module:ol/Feature>} features Features.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @protected
* @return {string} Text.
*/
writeFeaturesText(features, opt_options) {}
/**
* Write a single geometry.
*
* @function
* @param {module:ol/geom/Geometry} geometry Geometry.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {string} Geometry.
* @api
*/
writeGeometry(geometry, opt_options) {
return this.writeGeometryText(geometry, this.adaptOptions(opt_options));
}
/**
* @abstract
* @param {module:ol/geom/Geometry} geometry Geometry.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @protected
* @return {string} Text.
*/
writeGeometryText(geometry, opt_options) {}
}
/** /**
@@ -35,136 +188,4 @@ function getText(source) {
} }
/**
* @inheritDoc
*/
TextFeature.prototype.getType = function() {
return FormatType.TEXT;
};
/**
* @inheritDoc
*/
TextFeature.prototype.readFeature = function(source, opt_options) {
return this.readFeatureFromText(getText(source), this.adaptOptions(opt_options));
};
/**
* @abstract
* @param {string} text Text.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @protected
* @return {module:ol/Feature} Feature.
*/
TextFeature.prototype.readFeatureFromText = function(text, opt_options) {};
/**
* @inheritDoc
*/
TextFeature.prototype.readFeatures = function(source, opt_options) {
return this.readFeaturesFromText(getText(source), this.adaptOptions(opt_options));
};
/**
* @abstract
* @param {string} text Text.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @protected
* @return {Array.<module:ol/Feature>} Features.
*/
TextFeature.prototype.readFeaturesFromText = function(text, opt_options) {};
/**
* @inheritDoc
*/
TextFeature.prototype.readGeometry = function(source, opt_options) {
return this.readGeometryFromText(getText(source), this.adaptOptions(opt_options));
};
/**
* @abstract
* @param {string} text Text.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @protected
* @return {module:ol/geom/Geometry} Geometry.
*/
TextFeature.prototype.readGeometryFromText = function(text, opt_options) {};
/**
* @inheritDoc
*/
TextFeature.prototype.readProjection = function(source) {
return this.readProjectionFromText(getText(source));
};
/**
* @param {string} text Text.
* @protected
* @return {module:ol/proj/Projection} Projection.
*/
TextFeature.prototype.readProjectionFromText = function(text) {
return this.dataProjection;
};
/**
* @inheritDoc
*/
TextFeature.prototype.writeFeature = function(feature, opt_options) {
return this.writeFeatureText(feature, this.adaptOptions(opt_options));
};
/**
* @abstract
* @param {module:ol/Feature} feature Features.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @protected
* @return {string} Text.
*/
TextFeature.prototype.writeFeatureText = function(feature, opt_options) {};
/**
* @inheritDoc
*/
TextFeature.prototype.writeFeatures = function(features, opt_options) {
return this.writeFeaturesText(features, this.adaptOptions(opt_options));
};
/**
* @abstract
* @param {Array.<module:ol/Feature>} features Features.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @protected
* @return {string} Text.
*/
TextFeature.prototype.writeFeaturesText = function(features, opt_options) {};
/**
* @inheritDoc
*/
TextFeature.prototype.writeGeometry = function(geometry, opt_options) {
return this.writeGeometryText(geometry, this.adaptOptions(opt_options));
};
/**
* @abstract
* @param {module:ol/geom/Geometry} geometry Geometry.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @protected
* @return {string} Text.
*/
TextFeature.prototype.writeGeometryText = function(geometry, opt_options) {};
export default TextFeature; export default TextFeature;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/format/TopoJSON * @module ol/format/TopoJSON
*/ */
import {inherits} from '../util.js';
import Feature from '../Feature.js'; import Feature from '../Feature.js';
import {transformWithOptions} from '../format/Feature.js'; import {transformWithOptions} from '../format/Feature.js';
import JSONFeature from '../format/JSONFeature.js'; import JSONFeature from '../format/JSONFeature.js';
@@ -43,17 +42,18 @@ import {get as getProjection} from '../proj.js';
* @classdesc * @classdesc
* Feature format for reading data in the TopoJSON format. * Feature format for reading data in the TopoJSON format.
* *
* @constructor
* @extends {module:ol/format/JSONFeature}
* @param {module:ol/format/TopoJSON~Options=} opt_options Options.
* @api * @api
*/ */
const TopoJSON = function(opt_options) { class TopoJSON extends JSONFeature {
/**
* @param {module:ol/format/TopoJSON~Options=} opt_options Options.
*/
constructor(opt_options) {
super();
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
JSONFeature.call(this);
/** /**
* @private * @private
* @type {string|undefined} * @type {string|undefined}
@@ -73,9 +73,86 @@ const TopoJSON = function(opt_options) {
options.dataProjection ? options.dataProjection ?
options.dataProjection : 'EPSG:4326'); options.dataProjection : 'EPSG:4326');
}; }
inherits(TopoJSON, JSONFeature); /**
* @inheritDoc
*/
readFeaturesFromObject(object, opt_options) {
if (object.type == 'Topology') {
const topoJSONTopology = /** @type {TopoJSONTopology} */ (object);
let transform, scale = null, translate = null;
if (topoJSONTopology.transform) {
transform = topoJSONTopology.transform;
scale = transform.scale;
translate = transform.translate;
}
const arcs = topoJSONTopology.arcs;
if (transform) {
transformArcs(arcs, scale, translate);
}
/** @type {Array.<module:ol/Feature>} */
const features = [];
const topoJSONFeatures = topoJSONTopology.objects;
const property = this.layerName_;
let feature;
for (const objectName in topoJSONFeatures) {
if (this.layers_ && this.layers_.indexOf(objectName) == -1) {
continue;
}
if (topoJSONFeatures[objectName].type === 'GeometryCollection') {
feature = /** @type {TopoJSONGeometryCollection} */ (topoJSONFeatures[objectName]);
features.push.apply(features, readFeaturesFromGeometryCollection(
feature, arcs, scale, translate, property, objectName, opt_options));
} else {
feature = /** @type {TopoJSONGeometry} */ (topoJSONFeatures[objectName]);
features.push(readFeatureFromGeometry(
feature, arcs, scale, translate, property, objectName, opt_options));
}
}
return features;
} else {
return [];
}
}
/**
* @inheritDoc
*/
readProjectionFromObject(object) {
return this.dataProjection;
}
/**
* Not implemented.
* @inheritDoc
*/
writeFeatureObject(feature, opt_options) {}
/**
* Not implemented.
* @inheritDoc
*/
writeFeaturesObject(features, opt_options) {}
/**
* Not implemented.
* @inheritDoc
*/
writeGeometryObject(geometry, opt_options) {}
/**
* Not implemented.
* @override
*/
readGeometryFromObject() {}
/**
* Not implemented.
* @override
*/
readFeatureFromObject() {}
}
/** /**
@@ -298,59 +375,6 @@ function readFeatureFromGeometry(object, arcs, scale, translate, property, name,
} }
/**
* Read all features from a TopoJSON source.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @return {Array.<module:ol/Feature>} Features.
* @api
*/
TopoJSON.prototype.readFeatures;
/**
* @inheritDoc
*/
TopoJSON.prototype.readFeaturesFromObject = function(object, opt_options) {
if (object.type == 'Topology') {
const topoJSONTopology = /** @type {TopoJSONTopology} */ (object);
let transform, scale = null, translate = null;
if (topoJSONTopology.transform) {
transform = topoJSONTopology.transform;
scale = transform.scale;
translate = transform.translate;
}
const arcs = topoJSONTopology.arcs;
if (transform) {
transformArcs(arcs, scale, translate);
}
/** @type {Array.<module:ol/Feature>} */
const features = [];
const topoJSONFeatures = topoJSONTopology.objects;
const property = this.layerName_;
let feature;
for (const objectName in topoJSONFeatures) {
if (this.layers_ && this.layers_.indexOf(objectName) == -1) {
continue;
}
if (topoJSONFeatures[objectName].type === 'GeometryCollection') {
feature = /** @type {TopoJSONGeometryCollection} */ (topoJSONFeatures[objectName]);
features.push.apply(features, readFeaturesFromGeometryCollection(
feature, arcs, scale, translate, property, objectName, opt_options));
} else {
feature = /** @type {TopoJSONGeometry} */ (topoJSONFeatures[objectName]);
features.push(readFeatureFromGeometry(
feature, arcs, scale, translate, property, objectName, opt_options));
}
}
return features;
} else {
return [];
}
};
/** /**
* Apply a linear transform to array of arcs. The provided array of arcs is * Apply a linear transform to array of arcs. The provided array of arcs is
* modified in place. * modified in place.
@@ -401,56 +425,4 @@ function transformVertex(vertex, scale, translate) {
} }
/**
* Read the projection from a TopoJSON source.
*
* @param {Document|Node|Object|string} object Source.
* @return {module:ol/proj/Projection} Projection.
* @override
* @api
*/
TopoJSON.prototype.readProjection;
/**
* @inheritDoc
*/
TopoJSON.prototype.readProjectionFromObject = function(object) {
return this.dataProjection;
};
/**
* Not implemented.
* @inheritDoc
*/
TopoJSON.prototype.writeFeatureObject = function(feature, opt_options) {};
/**
* Not implemented.
* @inheritDoc
*/
TopoJSON.prototype.writeFeaturesObject = function(features, opt_options) {};
/**
* Not implemented.
* @inheritDoc
*/
TopoJSON.prototype.writeGeometryObject = function(geometry, opt_options) {};
/**
* Not implemented.
* @override
*/
TopoJSON.prototype.readGeometryFromObject = function() {};
/**
* Not implemented.
* @override
*/
TopoJSON.prototype.readFeatureFromObject = function() {};
export default TopoJSON; export default TopoJSON;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/format/WFS * @module ol/format/WFS
*/ */
import {inherits} from '../util.js';
import {assert} from '../asserts.js'; import {assert} from '../asserts.js';
import GML2 from '../format/GML2.js'; import GML2 from '../format/GML2.js';
import GML3 from '../format/GML3.js'; import GML3 from '../format/GML3.js';
@@ -17,6 +16,69 @@ import {createElementNS, isDocument, isNode, makeArrayPusher, makeChildAppender,
pushParseAndPop, pushSerializeAndPop, XML_SCHEMA_INSTANCE_URI} from '../xml.js'; pushParseAndPop, pushSerializeAndPop, XML_SCHEMA_INSTANCE_URI} from '../xml.js';
/**
* @const
* @type {Object.<string, Object.<string, module:ol/xml~Parser>>}
*/
const FEATURE_COLLECTION_PARSERS = {
'http://www.opengis.net/gml': {
'boundedBy': makeObjectPropertySetter(
GMLBase.prototype.readGeometryElement, 'bounds')
}
};
/**
* @const
* @type {Object.<string, Object.<string, module:ol/xml~Parser>>}
*/
const TRANSACTION_SUMMARY_PARSERS = {
'http://www.opengis.net/wfs': {
'totalInserted': makeObjectPropertySetter(readNonNegativeInteger),
'totalUpdated': makeObjectPropertySetter(readNonNegativeInteger),
'totalDeleted': makeObjectPropertySetter(readNonNegativeInteger)
}
};
/**
* @const
* @type {Object.<string, Object.<string, module:ol/xml~Parser>>}
*/
const TRANSACTION_RESPONSE_PARSERS = {
'http://www.opengis.net/wfs': {
'TransactionSummary': makeObjectPropertySetter(
readTransactionSummary, 'transactionSummary'),
'InsertResults': makeObjectPropertySetter(
readInsertResults, 'insertIds')
}
};
/**
* @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}
*/
const QUERY_SERIALIZERS = {
'http://www.opengis.net/wfs': {
'PropertyName': makeChildAppender(writeStringTextNode)
}
};
/**
* @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}
*/
const TRANSACTION_SERIALIZERS = {
'http://www.opengis.net/wfs': {
'Insert': makeChildAppender(writeFeature),
'Update': makeChildAppender(writeUpdate),
'Delete': makeChildAppender(writeDelete),
'Property': makeChildAppender(writeProperty),
'Native': makeChildAppender(writeNative)
}
};
/** /**
* @typedef {Object} Options * @typedef {Object} Options
* @property {Object.<string, string>|string} [featureNS] The namespace URI used for features. * @property {Object.<string, string>|string} [featureNS] The namespace URI used for features.
@@ -138,12 +200,16 @@ const DEFAULT_VERSION = '1.1.0';
* as option if you want to read a WFS that contains GML2 (WFS 1.0.0). * as option if you want to read a WFS that contains GML2 (WFS 1.0.0).
* Also see {@link module:ol/format/GMLBase~GMLBase} which is used by this format. * Also see {@link module:ol/format/GMLBase~GMLBase} which is used by this format.
* *
* @constructor
* @param {module:ol/format/WFS~Options=} opt_options Optional configuration object.
* @extends {module:ol/format/XMLFeature}
* @api * @api
*/ */
const WFS = function(opt_options) { class WFS extends XMLFeature {
/**
* @param {module:ol/format/WFS~Options=} opt_options Optional configuration object.
*/
constructor(opt_options) {
super();
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
/** /**
@@ -171,45 +237,26 @@ const WFS = function(opt_options) {
*/ */
this.schemaLocation_ = options.schemaLocation ? this.schemaLocation_ = options.schemaLocation ?
options.schemaLocation : SCHEMA_LOCATIONS[DEFAULT_VERSION]; options.schemaLocation : SCHEMA_LOCATIONS[DEFAULT_VERSION];
}
XMLFeature.call(this);
};
inherits(WFS, XMLFeature);
/** /**
* @return {Array.<string>|string|undefined} featureType * @return {Array.<string>|string|undefined} featureType
*/ */
WFS.prototype.getFeatureType = function() { getFeatureType() {
return this.featureType_; return this.featureType_;
}; }
/** /**
* @param {Array.<string>|string|undefined} featureType Feature type(s) to parse. * @param {Array.<string>|string|undefined} featureType Feature type(s) to parse.
*/ */
WFS.prototype.setFeatureType = function(featureType) { setFeatureType(featureType) {
this.featureType_ = featureType; this.featureType_ = featureType;
}; }
/**
* Read all features from a WFS FeatureCollection.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {Array.<module:ol/Feature>} Features.
* @api
*/
WFS.prototype.readFeatures;
/** /**
* @inheritDoc * @inheritDoc
*/ */
WFS.prototype.readFeaturesFromNode = function(node, opt_options) { readFeaturesFromNode(node, opt_options) {
const context = /** @type {module:ol/xml~NodeStackItem} */ ({ const context = /** @type {module:ol/xml~NodeStackItem} */ ({
'featureType': this.featureType_, 'featureType': this.featureType_,
'featureNS': this.featureNS_ 'featureNS': this.featureNS_
@@ -226,8 +273,7 @@ WFS.prototype.readFeaturesFromNode = function(node, opt_options) {
features = []; features = [];
} }
return features; return features;
}; }
/** /**
* Read transaction response of the source. * Read transaction response of the source.
@@ -236,7 +282,7 @@ WFS.prototype.readFeaturesFromNode = function(node, opt_options) {
* @return {module:ol/format/WFS~TransactionResponse|undefined} Transaction response. * @return {module:ol/format/WFS~TransactionResponse|undefined} Transaction response.
* @api * @api
*/ */
WFS.prototype.readTransactionResponse = function(source) { readTransactionResponse(source) {
if (isDocument(source)) { if (isDocument(source)) {
return this.readTransactionResponseFromDocument( return this.readTransactionResponseFromDocument(
/** @type {Document} */ (source)); /** @type {Document} */ (source));
@@ -248,8 +294,7 @@ WFS.prototype.readTransactionResponse = function(source) {
} else { } else {
return undefined; return undefined;
} }
}; }
/** /**
* Read feature collection metadata of the source. * Read feature collection metadata of the source.
@@ -259,7 +304,7 @@ WFS.prototype.readTransactionResponse = function(source) {
* FeatureCollection metadata. * FeatureCollection metadata.
* @api * @api
*/ */
WFS.prototype.readFeatureCollectionMetadata = function(source) { readFeatureCollectionMetadata(source) {
if (isDocument(source)) { if (isDocument(source)) {
return this.readFeatureCollectionMetadataFromDocument( return this.readFeatureCollectionMetadataFromDocument(
/** @type {Document} */ (source)); /** @type {Document} */ (source));
@@ -272,42 +317,28 @@ WFS.prototype.readFeatureCollectionMetadata = function(source) {
} else { } else {
return undefined; return undefined;
} }
}; }
/** /**
* @param {Document} doc Document. * @param {Document} doc Document.
* @return {module:ol/format/WFS~FeatureCollectionMetadata|undefined} * @return {module:ol/format/WFS~FeatureCollectionMetadata|undefined}
* FeatureCollection metadata. * FeatureCollection metadata.
*/ */
WFS.prototype.readFeatureCollectionMetadataFromDocument = function(doc) { readFeatureCollectionMetadataFromDocument(doc) {
for (let n = doc.firstChild; n; n = n.nextSibling) { for (let n = doc.firstChild; n; n = n.nextSibling) {
if (n.nodeType == Node.ELEMENT_NODE) { if (n.nodeType == Node.ELEMENT_NODE) {
return this.readFeatureCollectionMetadataFromNode(n); return this.readFeatureCollectionMetadataFromNode(n);
} }
} }
return undefined; return undefined;
};
/**
* @const
* @type {Object.<string, Object.<string, module:ol/xml~Parser>>}
*/
const FEATURE_COLLECTION_PARSERS = {
'http://www.opengis.net/gml': {
'boundedBy': makeObjectPropertySetter(
GMLBase.prototype.readGeometryElement, 'bounds')
} }
};
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @return {module:ol/format/WFS~FeatureCollectionMetadata|undefined} * @return {module:ol/format/WFS~FeatureCollectionMetadata|undefined}
* FeatureCollection metadata. * FeatureCollection metadata.
*/ */
WFS.prototype.readFeatureCollectionMetadataFromNode = function(node) { readFeatureCollectionMetadataFromNode(node) {
const result = {}; const result = {};
const value = readNonNegativeIntegerString( const value = readNonNegativeIntegerString(
node.getAttribute('numberOfFeatures')); node.getAttribute('numberOfFeatures'));
@@ -315,20 +346,194 @@ WFS.prototype.readFeatureCollectionMetadataFromNode = function(node) {
return pushParseAndPop( return pushParseAndPop(
/** @type {module:ol/format/WFS~FeatureCollectionMetadata} */ (result), /** @type {module:ol/format/WFS~FeatureCollectionMetadata} */ (result),
FEATURE_COLLECTION_PARSERS, node, [], this.gmlFormat_); FEATURE_COLLECTION_PARSERS, node, [], this.gmlFormat_);
}; }
/** /**
* @const * @param {Document} doc Document.
* @type {Object.<string, Object.<string, module:ol/xml~Parser>>} * @return {module:ol/format/WFS~TransactionResponse|undefined} Transaction response.
*/ */
const TRANSACTION_SUMMARY_PARSERS = { readTransactionResponseFromDocument(doc) {
'http://www.opengis.net/wfs': { for (let n = doc.firstChild; n; n = n.nextSibling) {
'totalInserted': makeObjectPropertySetter(readNonNegativeInteger), if (n.nodeType == Node.ELEMENT_NODE) {
'totalUpdated': makeObjectPropertySetter(readNonNegativeInteger), return this.readTransactionResponseFromNode(n);
'totalDeleted': makeObjectPropertySetter(readNonNegativeInteger)
} }
}
return undefined;
}
/**
* @param {Node} node Node.
* @return {module:ol/format/WFS~TransactionResponse|undefined} Transaction response.
*/
readTransactionResponseFromNode(node) {
return pushParseAndPop(
/** @type {module:ol/format/WFS~TransactionResponse} */({}),
TRANSACTION_RESPONSE_PARSERS, node, []);
}
/**
* Encode format as WFS `GetFeature` and return the Node.
*
* @param {module:ol/format/WFS~WriteGetFeatureOptions} options Options.
* @return {Node} Result.
* @api
*/
writeGetFeature(options) {
const node = createElementNS(WFSNS, 'GetFeature');
node.setAttribute('service', 'WFS');
node.setAttribute('version', '1.1.0');
let filter;
if (options) {
if (options.handle) {
node.setAttribute('handle', options.handle);
}
if (options.outputFormat) {
node.setAttribute('outputFormat', options.outputFormat);
}
if (options.maxFeatures !== undefined) {
node.setAttribute('maxFeatures', options.maxFeatures);
}
if (options.resultType) {
node.setAttribute('resultType', options.resultType);
}
if (options.startIndex !== undefined) {
node.setAttribute('startIndex', options.startIndex);
}
if (options.count !== undefined) {
node.setAttribute('count', options.count);
}
filter = options.filter;
if (options.bbox) {
assert(options.geometryName,
12); // `options.geometryName` must also be provided when `options.bbox` is set
const bbox = bboxFilter(
/** @type {string} */ (options.geometryName), options.bbox, options.srsName);
if (filter) {
// if bbox and filter are both set, combine the two into a single filter
filter = andFilter(filter, bbox);
} else {
filter = bbox;
}
}
}
node.setAttributeNS(XML_SCHEMA_INSTANCE_URI, 'xsi:schemaLocation', this.schemaLocation_);
/** @type {module:ol/xml~NodeStackItem} */
const context = {
node: node,
'srsName': options.srsName,
'featureNS': options.featureNS ? options.featureNS : this.featureNS_,
'featurePrefix': options.featurePrefix,
'geometryName': options.geometryName,
'filter': filter,
'propertyNames': options.propertyNames ? options.propertyNames : []
}; };
assert(Array.isArray(options.featureTypes),
11); // `options.featureTypes` should be an Array
writeGetFeature(node, /** @type {!Array.<string>} */ (options.featureTypes), [context]);
return node;
}
/**
* Encode format as WFS `Transaction` and return the Node.
*
* @param {Array.<module:ol/Feature>} inserts The features to insert.
* @param {Array.<module:ol/Feature>} updates The features to update.
* @param {Array.<module:ol/Feature>} deletes The features to delete.
* @param {module:ol/format/WFS~WriteTransactionOptions} options Write options.
* @return {Node} Result.
* @api
*/
writeTransaction(inserts, updates, deletes, options) {
const objectStack = [];
const node = createElementNS(WFSNS, 'Transaction');
const version = options.version ? options.version : DEFAULT_VERSION;
const gmlVersion = version === '1.0.0' ? 2 : 3;
node.setAttribute('service', 'WFS');
node.setAttribute('version', version);
let baseObj;
/** @type {module:ol/xml~NodeStackItem} */
let obj;
if (options) {
baseObj = options.gmlOptions ? options.gmlOptions : {};
if (options.handle) {
node.setAttribute('handle', options.handle);
}
}
const schemaLocation = SCHEMA_LOCATIONS[version];
node.setAttributeNS(XML_SCHEMA_INSTANCE_URI, 'xsi:schemaLocation', schemaLocation);
const featurePrefix = options.featurePrefix ? options.featurePrefix : FEATURE_PREFIX;
if (inserts) {
obj = {node: node, 'featureNS': options.featureNS,
'featureType': options.featureType, 'featurePrefix': featurePrefix,
'gmlVersion': gmlVersion, 'hasZ': options.hasZ, 'srsName': options.srsName};
assign(obj, baseObj);
pushSerializeAndPop(obj,
TRANSACTION_SERIALIZERS,
makeSimpleNodeFactory('Insert'), inserts,
objectStack);
}
if (updates) {
obj = {node: node, 'featureNS': options.featureNS,
'featureType': options.featureType, 'featurePrefix': featurePrefix,
'gmlVersion': gmlVersion, 'hasZ': options.hasZ, 'srsName': options.srsName};
assign(obj, baseObj);
pushSerializeAndPop(obj,
TRANSACTION_SERIALIZERS,
makeSimpleNodeFactory('Update'), updates,
objectStack);
}
if (deletes) {
pushSerializeAndPop({node: node, 'featureNS': options.featureNS,
'featureType': options.featureType, 'featurePrefix': featurePrefix,
'gmlVersion': gmlVersion, 'srsName': options.srsName},
TRANSACTION_SERIALIZERS,
makeSimpleNodeFactory('Delete'), deletes,
objectStack);
}
if (options.nativeElements) {
pushSerializeAndPop({node: node, 'featureNS': options.featureNS,
'featureType': options.featureType, 'featurePrefix': featurePrefix,
'gmlVersion': gmlVersion, 'srsName': options.srsName},
TRANSACTION_SERIALIZERS,
makeSimpleNodeFactory('Native'), options.nativeElements,
objectStack);
}
return node;
}
/**
* @inheritDoc
*/
readProjectionFromDocument(doc) {
for (let n = doc.firstChild; n; n = n.nextSibling) {
if (n.nodeType == Node.ELEMENT_NODE) {
return this.readProjectionFromNode(n);
}
}
return null;
}
/**
* @inheritDoc
*/
readProjectionFromNode(node) {
if (node.firstElementChild &&
node.firstElementChild.firstElementChild) {
node = node.firstElementChild.firstElementChild;
for (let n = node.firstElementChild; n; n = n.nextElementSibling) {
if (!(n.childNodes.length === 0 ||
(n.childNodes.length === 1 &&
n.firstChild.nodeType === 3))) {
const objectStack = [{}];
this.gmlFormat_.readGeometryElement(n, objectStack);
return getProjection(objectStack.pop().srsName);
}
}
}
return null;
}
}
/** /**
@@ -386,55 +591,6 @@ function readInsertResults(node, objectStack) {
} }
/**
* @const
* @type {Object.<string, Object.<string, module:ol/xml~Parser>>}
*/
const TRANSACTION_RESPONSE_PARSERS = {
'http://www.opengis.net/wfs': {
'TransactionSummary': makeObjectPropertySetter(
readTransactionSummary, 'transactionSummary'),
'InsertResults': makeObjectPropertySetter(
readInsertResults, 'insertIds')
}
};
/**
* @param {Document} doc Document.
* @return {module:ol/format/WFS~TransactionResponse|undefined} Transaction response.
*/
WFS.prototype.readTransactionResponseFromDocument = function(doc) {
for (let n = doc.firstChild; n; n = n.nextSibling) {
if (n.nodeType == Node.ELEMENT_NODE) {
return this.readTransactionResponseFromNode(n);
}
}
return undefined;
};
/**
* @param {Node} node Node.
* @return {module:ol/format/WFS~TransactionResponse|undefined} Transaction response.
*/
WFS.prototype.readTransactionResponseFromNode = function(node) {
return pushParseAndPop(
/** @type {module:ol/format/WFS~TransactionResponse} */({}),
TRANSACTION_RESPONSE_PARSERS, node, []);
};
/**
* @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}
*/
const QUERY_SERIALIZERS = {
'http://www.opengis.net/wfs': {
'PropertyName': makeChildAppender(writeStringTextNode)
}
};
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {module:ol/Feature} feature Feature. * @param {module:ol/Feature} feature Feature.
@@ -507,20 +663,6 @@ function writeDelete(node, feature, objectStack) {
} }
/**
* @type {Object.<string, Object.<string, module:ol/xml~Serializer>>}
*/
const TRANSACTION_SERIALIZERS = {
'http://www.opengis.net/wfs': {
'Insert': makeChildAppender(writeFeature),
'Update': makeChildAppender(writeUpdate),
'Delete': makeChildAppender(writeDelete),
'Property': makeChildAppender(writeProperty),
'Native': makeChildAppender(writeNative)
}
};
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {module:ol/Feature} feature Feature. * @param {module:ol/Feature} feature Feature.
@@ -942,180 +1084,4 @@ function writeGetFeature(node, featureTypes, objectStack) {
} }
/**
* Encode format as WFS `GetFeature` and return the Node.
*
* @param {module:ol/format/WFS~WriteGetFeatureOptions} options Options.
* @return {Node} Result.
* @api
*/
WFS.prototype.writeGetFeature = function(options) {
const node = createElementNS(WFSNS, 'GetFeature');
node.setAttribute('service', 'WFS');
node.setAttribute('version', '1.1.0');
let filter;
if (options) {
if (options.handle) {
node.setAttribute('handle', options.handle);
}
if (options.outputFormat) {
node.setAttribute('outputFormat', options.outputFormat);
}
if (options.maxFeatures !== undefined) {
node.setAttribute('maxFeatures', options.maxFeatures);
}
if (options.resultType) {
node.setAttribute('resultType', options.resultType);
}
if (options.startIndex !== undefined) {
node.setAttribute('startIndex', options.startIndex);
}
if (options.count !== undefined) {
node.setAttribute('count', options.count);
}
filter = options.filter;
if (options.bbox) {
assert(options.geometryName,
12); // `options.geometryName` must also be provided when `options.bbox` is set
const bbox = bboxFilter(
/** @type {string} */ (options.geometryName), options.bbox, options.srsName);
if (filter) {
// if bbox and filter are both set, combine the two into a single filter
filter = andFilter(filter, bbox);
} else {
filter = bbox;
}
}
}
node.setAttributeNS(XML_SCHEMA_INSTANCE_URI, 'xsi:schemaLocation', this.schemaLocation_);
/** @type {module:ol/xml~NodeStackItem} */
const context = {
node: node,
'srsName': options.srsName,
'featureNS': options.featureNS ? options.featureNS : this.featureNS_,
'featurePrefix': options.featurePrefix,
'geometryName': options.geometryName,
'filter': filter,
'propertyNames': options.propertyNames ? options.propertyNames : []
};
assert(Array.isArray(options.featureTypes),
11); // `options.featureTypes` should be an Array
writeGetFeature(node, /** @type {!Array.<string>} */ (options.featureTypes), [context]);
return node;
};
/**
* Encode format as WFS `Transaction` and return the Node.
*
* @param {Array.<module:ol/Feature>} inserts The features to insert.
* @param {Array.<module:ol/Feature>} updates The features to update.
* @param {Array.<module:ol/Feature>} deletes The features to delete.
* @param {module:ol/format/WFS~WriteTransactionOptions} options Write options.
* @return {Node} Result.
* @api
*/
WFS.prototype.writeTransaction = function(inserts, updates, deletes, options) {
const objectStack = [];
const node = createElementNS(WFSNS, 'Transaction');
const version = options.version ? options.version : DEFAULT_VERSION;
const gmlVersion = version === '1.0.0' ? 2 : 3;
node.setAttribute('service', 'WFS');
node.setAttribute('version', version);
let baseObj;
/** @type {module:ol/xml~NodeStackItem} */
let obj;
if (options) {
baseObj = options.gmlOptions ? options.gmlOptions : {};
if (options.handle) {
node.setAttribute('handle', options.handle);
}
}
const schemaLocation = SCHEMA_LOCATIONS[version];
node.setAttributeNS(XML_SCHEMA_INSTANCE_URI, 'xsi:schemaLocation', schemaLocation);
const featurePrefix = options.featurePrefix ? options.featurePrefix : FEATURE_PREFIX;
if (inserts) {
obj = {node: node, 'featureNS': options.featureNS,
'featureType': options.featureType, 'featurePrefix': featurePrefix,
'gmlVersion': gmlVersion, 'hasZ': options.hasZ, 'srsName': options.srsName};
assign(obj, baseObj);
pushSerializeAndPop(obj,
TRANSACTION_SERIALIZERS,
makeSimpleNodeFactory('Insert'), inserts,
objectStack);
}
if (updates) {
obj = {node: node, 'featureNS': options.featureNS,
'featureType': options.featureType, 'featurePrefix': featurePrefix,
'gmlVersion': gmlVersion, 'hasZ': options.hasZ, 'srsName': options.srsName};
assign(obj, baseObj);
pushSerializeAndPop(obj,
TRANSACTION_SERIALIZERS,
makeSimpleNodeFactory('Update'), updates,
objectStack);
}
if (deletes) {
pushSerializeAndPop({node: node, 'featureNS': options.featureNS,
'featureType': options.featureType, 'featurePrefix': featurePrefix,
'gmlVersion': gmlVersion, 'srsName': options.srsName},
TRANSACTION_SERIALIZERS,
makeSimpleNodeFactory('Delete'), deletes,
objectStack);
}
if (options.nativeElements) {
pushSerializeAndPop({node: node, 'featureNS': options.featureNS,
'featureType': options.featureType, 'featurePrefix': featurePrefix,
'gmlVersion': gmlVersion, 'srsName': options.srsName},
TRANSACTION_SERIALIZERS,
makeSimpleNodeFactory('Native'), options.nativeElements,
objectStack);
}
return node;
};
/**
* Read the projection from a WFS source.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @return {?module:ol/proj/Projection} Projection.
* @api
*/
WFS.prototype.readProjection;
/**
* @inheritDoc
*/
WFS.prototype.readProjectionFromDocument = function(doc) {
for (let n = doc.firstChild; n; n = n.nextSibling) {
if (n.nodeType == Node.ELEMENT_NODE) {
return this.readProjectionFromNode(n);
}
}
return null;
};
/**
* @inheritDoc
*/
WFS.prototype.readProjectionFromNode = function(node) {
if (node.firstElementChild &&
node.firstElementChild.firstElementChild) {
node = node.firstElementChild.firstElementChild;
for (let n = node.firstElementChild; n; n = n.nextElementSibling) {
if (!(n.childNodes.length === 0 ||
(n.childNodes.length === 1 &&
n.firstChild.nodeType === 3))) {
const objectStack = [{}];
this.gmlFormat_.readGeometryElement(n, objectStack);
return getProjection(objectStack.pop().srsName);
}
}
}
return null;
};
export default WFS; export default WFS;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/format/WKT * @module ol/format/WKT
*/ */
import {inherits} from '../util.js';
import Feature from '../Feature.js'; import Feature from '../Feature.js';
import {transformWithOptions} from '../format/Feature.js'; import {transformWithOptions} from '../format/Feature.js';
import TextFeature from '../format/TextFeature.js'; import TextFeature from '../format/TextFeature.js';
@@ -17,6 +16,19 @@ import Polygon from '../geom/Polygon.js';
import SimpleGeometry from '../geom/SimpleGeometry.js'; import SimpleGeometry from '../geom/SimpleGeometry.js';
/**
* @enum {function (new:module:ol/geom/Geometry, Array, module:ol/geom/GeometryLayout)}
*/
const GeometryConstructor = {
'POINT': Point,
'LINESTRING': LineString,
'POLYGON': Polygon,
'MULTIPOINT': MultiPoint,
'MULTILINESTRING': MultiLineString,
'MULTIPOLYGON': MultiPolygon
};
/** /**
* @typedef {Object} Options * @typedef {Object} Options
* @property {boolean} [splitCollection=false] Whether to split GeometryCollections into * @property {boolean} [splitCollection=false] Whether to split GeometryCollections into
@@ -71,13 +83,25 @@ const TokenType = {
EOF: 6 EOF: 6
}; };
/**
* @const
* @type {Object.<string, string>}
*/
const WKTGeometryType = {};
for (const type in GeometryType) {
WKTGeometryType[type] = GeometryType[type].toUpperCase();
}
/** /**
* Class to tokenize a WKT string. * Class to tokenize a WKT string.
* @param {string} wkt WKT string.
* @constructor
*/ */
const Lexer = function(wkt) { class Lexer {
/**
* @param {string} wkt WKT string.
*/
constructor(wkt) {
/** /**
* @type {string} * @type {string}
@@ -89,18 +113,16 @@ const Lexer = function(wkt) {
* @private * @private
*/ */
this.index_ = -1; this.index_ = -1;
}; }
/** /**
* @param {string} c Character. * @param {string} c Character.
* @return {boolean} Whether the character is alphabetic. * @return {boolean} Whether the character is alphabetic.
* @private * @private
*/ */
Lexer.prototype.isAlpha_ = function(c) { isAlpha_(c) {
return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z'; return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z';
}; }
/** /**
* @param {string} c Character. * @param {string} c Character.
@@ -109,36 +131,33 @@ Lexer.prototype.isAlpha_ = function(c) {
* @return {boolean} Whether the character is numeric. * @return {boolean} Whether the character is numeric.
* @private * @private
*/ */
Lexer.prototype.isNumeric_ = function(c, opt_decimal) { isNumeric_(c, opt_decimal) {
const decimal = opt_decimal !== undefined ? opt_decimal : false; const decimal = opt_decimal !== undefined ? opt_decimal : false;
return c >= '0' && c <= '9' || c == '.' && !decimal; return c >= '0' && c <= '9' || c == '.' && !decimal;
}; }
/** /**
* @param {string} c Character. * @param {string} c Character.
* @return {boolean} Whether the character is whitespace. * @return {boolean} Whether the character is whitespace.
* @private * @private
*/ */
Lexer.prototype.isWhiteSpace_ = function(c) { isWhiteSpace_(c) {
return c == ' ' || c == '\t' || c == '\r' || c == '\n'; return c == ' ' || c == '\t' || c == '\r' || c == '\n';
}; }
/** /**
* @return {string} Next string character. * @return {string} Next string character.
* @private * @private
*/ */
Lexer.prototype.nextChar_ = function() { nextChar_() {
return this.wkt.charAt(++this.index_); return this.wkt.charAt(++this.index_);
}; }
/** /**
* Fetch and return the next token. * Fetch and return the next token.
* @return {!module:ol/format/WKT~Token} Next string token. * @return {!module:ol/format/WKT~Token} Next string token.
*/ */
Lexer.prototype.nextToken = function() { nextToken() {
const c = this.nextChar_(); const c = this.nextChar_();
const token = {position: this.index_, value: c}; const token = {position: this.index_, value: c};
@@ -163,14 +182,13 @@ Lexer.prototype.nextToken = function() {
} }
return token; return token;
}; }
/** /**
* @return {number} Numeric token value. * @return {number} Numeric token value.
* @private * @private
*/ */
Lexer.prototype.readNumber_ = function() { readNumber_() {
let c; let c;
const index = this.index_; const index = this.index_;
let decimal = false; let decimal = false;
@@ -192,29 +210,31 @@ Lexer.prototype.readNumber_ = function() {
scientificNotation && (c == '-' || c == '+') scientificNotation && (c == '-' || c == '+')
); );
return parseFloat(this.wkt.substring(index, this.index_--)); return parseFloat(this.wkt.substring(index, this.index_--));
}; }
/** /**
* @return {string} String token value. * @return {string} String token value.
* @private * @private
*/ */
Lexer.prototype.readText_ = function() { readText_() {
let c; let c;
const index = this.index_; const index = this.index_;
do { do {
c = this.nextChar_(); c = this.nextChar_();
} while (this.isAlpha_(c)); } while (this.isAlpha_(c));
return this.wkt.substring(index, this.index_--).toUpperCase(); return this.wkt.substring(index, this.index_--).toUpperCase();
}; }
}
/** /**
* Class to parse the tokens from the WKT string. * Class to parse the tokens from the WKT string.
* @param {module:ol/format/WKT~Lexer} lexer The lexer.
* @constructor
*/ */
const Parser = function(lexer) { class Parser {
/**
* @param {module:ol/format/WKT~Lexer} lexer The lexer.
*/
constructor(lexer) {
/** /**
* @type {module:ol/format/WKT~Lexer} * @type {module:ol/format/WKT~Lexer}
@@ -233,59 +253,55 @@ const Parser = function(lexer) {
* @private * @private
*/ */
this.layout_ = GeometryLayout.XY; this.layout_ = GeometryLayout.XY;
}; }
/** /**
* Fetch the next token form the lexer and replace the active token. * Fetch the next token form the lexer and replace the active token.
* @private * @private
*/ */
Parser.prototype.consume_ = function() { consume_() {
this.token_ = this.lexer_.nextToken(); this.token_ = this.lexer_.nextToken();
}; }
/** /**
* Tests if the given type matches the type of the current token. * Tests if the given type matches the type of the current token.
* @param {module:ol/format/WKT~TokenType} type Token type. * @param {module:ol/format/WKT~TokenType} type Token type.
* @return {boolean} Whether the token matches the given type. * @return {boolean} Whether the token matches the given type.
*/ */
Parser.prototype.isTokenType = function(type) { isTokenType(type) {
const isMatch = this.token_.type == type; const isMatch = this.token_.type == type;
return isMatch; return isMatch;
}; }
/** /**
* If the given type matches the current token, consume it. * If the given type matches the current token, consume it.
* @param {module:ol/format/WKT~TokenType} type Token type. * @param {module:ol/format/WKT~TokenType} type Token type.
* @return {boolean} Whether the token matches the given type. * @return {boolean} Whether the token matches the given type.
*/ */
Parser.prototype.match = function(type) { match(type) {
const isMatch = this.isTokenType(type); const isMatch = this.isTokenType(type);
if (isMatch) { if (isMatch) {
this.consume_(); this.consume_();
} }
return isMatch; return isMatch;
}; }
/** /**
* Try to parse the tokens provided by the lexer. * Try to parse the tokens provided by the lexer.
* @return {module:ol/geom/Geometry} The geometry. * @return {module:ol/geom/Geometry} The geometry.
*/ */
Parser.prototype.parse = function() { parse() {
this.consume_(); this.consume_();
const geometry = this.parseGeometry_(); const geometry = this.parseGeometry_();
return geometry; return geometry;
}; }
/** /**
* Try to parse the dimensional info. * Try to parse the dimensional info.
* @return {module:ol/geom/GeometryLayout} The layout. * @return {module:ol/geom/GeometryLayout} The layout.
* @private * @private
*/ */
Parser.prototype.parseGeometryLayout_ = function() { parseGeometryLayout_() {
let layout = GeometryLayout.XY; let layout = GeometryLayout.XY;
const dimToken = this.token_; const dimToken = this.token_;
if (this.isTokenType(TokenType.TEXT)) { if (this.isTokenType(TokenType.TEXT)) {
@@ -302,14 +318,13 @@ Parser.prototype.parseGeometryLayout_ = function() {
} }
} }
return layout; return layout;
}; }
/** /**
* @return {!Array.<module:ol/geom/Geometry>} A collection of geometries. * @return {!Array.<module:ol/geom/Geometry>} A collection of geometries.
* @private * @private
*/ */
Parser.prototype.parseGeometryCollectionText_ = function() { parseGeometryCollectionText_() {
if (this.match(TokenType.LEFT_PAREN)) { if (this.match(TokenType.LEFT_PAREN)) {
const geometries = []; const geometries = [];
do { do {
@@ -322,14 +337,13 @@ Parser.prototype.parseGeometryCollectionText_ = function() {
return []; return [];
} }
throw new Error(this.formatErrorMessage_()); throw new Error(this.formatErrorMessage_());
}; }
/** /**
* @return {Array.<number>} All values in a point. * @return {Array.<number>} All values in a point.
* @private * @private
*/ */
Parser.prototype.parsePointText_ = function() { parsePointText_() {
if (this.match(TokenType.LEFT_PAREN)) { if (this.match(TokenType.LEFT_PAREN)) {
const coordinates = this.parsePoint_(); const coordinates = this.parsePoint_();
if (this.match(TokenType.RIGHT_PAREN)) { if (this.match(TokenType.RIGHT_PAREN)) {
@@ -339,14 +353,13 @@ Parser.prototype.parsePointText_ = function() {
return null; return null;
} }
throw new Error(this.formatErrorMessage_()); throw new Error(this.formatErrorMessage_());
}; }
/** /**
* @return {!Array.<!Array.<number>>} All points in a linestring. * @return {!Array.<!Array.<number>>} All points in a linestring.
* @private * @private
*/ */
Parser.prototype.parseLineStringText_ = function() { parseLineStringText_() {
if (this.match(TokenType.LEFT_PAREN)) { if (this.match(TokenType.LEFT_PAREN)) {
const coordinates = this.parsePointList_(); const coordinates = this.parsePointList_();
if (this.match(TokenType.RIGHT_PAREN)) { if (this.match(TokenType.RIGHT_PAREN)) {
@@ -356,14 +369,13 @@ Parser.prototype.parseLineStringText_ = function() {
return []; return [];
} }
throw new Error(this.formatErrorMessage_()); throw new Error(this.formatErrorMessage_());
}; }
/** /**
* @return {!Array.<!Array.<number>>} All points in a polygon. * @return {!Array.<!Array.<number>>} All points in a polygon.
* @private * @private
*/ */
Parser.prototype.parsePolygonText_ = function() { parsePolygonText_() {
if (this.match(TokenType.LEFT_PAREN)) { if (this.match(TokenType.LEFT_PAREN)) {
const coordinates = this.parseLineStringTextList_(); const coordinates = this.parseLineStringTextList_();
if (this.match(TokenType.RIGHT_PAREN)) { if (this.match(TokenType.RIGHT_PAREN)) {
@@ -373,14 +385,13 @@ Parser.prototype.parsePolygonText_ = function() {
return []; return [];
} }
throw new Error(this.formatErrorMessage_()); throw new Error(this.formatErrorMessage_());
}; }
/** /**
* @return {!Array.<!Array.<number>>} All points in a multipoint. * @return {!Array.<!Array.<number>>} All points in a multipoint.
* @private * @private
*/ */
Parser.prototype.parseMultiPointText_ = function() { parseMultiPointText_() {
if (this.match(TokenType.LEFT_PAREN)) { if (this.match(TokenType.LEFT_PAREN)) {
let coordinates; let coordinates;
if (this.token_.type == TokenType.LEFT_PAREN) { if (this.token_.type == TokenType.LEFT_PAREN) {
@@ -395,15 +406,14 @@ Parser.prototype.parseMultiPointText_ = function() {
return []; return [];
} }
throw new Error(this.formatErrorMessage_()); throw new Error(this.formatErrorMessage_());
}; }
/** /**
* @return {!Array.<!Array.<number>>} All linestring points * @return {!Array.<!Array.<number>>} All linestring points
* in a multilinestring. * in a multilinestring.
* @private * @private
*/ */
Parser.prototype.parseMultiLineStringText_ = function() { parseMultiLineStringText_() {
if (this.match(TokenType.LEFT_PAREN)) { if (this.match(TokenType.LEFT_PAREN)) {
const coordinates = this.parseLineStringTextList_(); const coordinates = this.parseLineStringTextList_();
if (this.match(TokenType.RIGHT_PAREN)) { if (this.match(TokenType.RIGHT_PAREN)) {
@@ -413,14 +423,13 @@ Parser.prototype.parseMultiLineStringText_ = function() {
return []; return [];
} }
throw new Error(this.formatErrorMessage_()); throw new Error(this.formatErrorMessage_());
}; }
/** /**
* @return {!Array.<!Array.<number>>} All polygon points in a multipolygon. * @return {!Array.<!Array.<number>>} All polygon points in a multipolygon.
* @private * @private
*/ */
Parser.prototype.parseMultiPolygonText_ = function() { parseMultiPolygonText_() {
if (this.match(TokenType.LEFT_PAREN)) { if (this.match(TokenType.LEFT_PAREN)) {
const coordinates = this.parsePolygonTextList_(); const coordinates = this.parsePolygonTextList_();
if (this.match(TokenType.RIGHT_PAREN)) { if (this.match(TokenType.RIGHT_PAREN)) {
@@ -430,14 +439,13 @@ Parser.prototype.parseMultiPolygonText_ = function() {
return []; return [];
} }
throw new Error(this.formatErrorMessage_()); throw new Error(this.formatErrorMessage_());
}; }
/** /**
* @return {!Array.<number>} A point. * @return {!Array.<number>} A point.
* @private * @private
*/ */
Parser.prototype.parsePoint_ = function() { parsePoint_() {
const coordinates = []; const coordinates = [];
const dimensions = this.layout_.length; const dimensions = this.layout_.length;
for (let i = 0; i < dimensions; ++i) { for (let i = 0; i < dimensions; ++i) {
@@ -452,84 +460,141 @@ Parser.prototype.parsePoint_ = function() {
return coordinates; return coordinates;
} }
throw new Error(this.formatErrorMessage_()); throw new Error(this.formatErrorMessage_());
}; }
/** /**
* @return {!Array.<!Array.<number>>} An array of points. * @return {!Array.<!Array.<number>>} An array of points.
* @private * @private
*/ */
Parser.prototype.parsePointList_ = function() { parsePointList_() {
const coordinates = [this.parsePoint_()]; const coordinates = [this.parsePoint_()];
while (this.match(TokenType.COMMA)) { while (this.match(TokenType.COMMA)) {
coordinates.push(this.parsePoint_()); coordinates.push(this.parsePoint_());
} }
return coordinates; return coordinates;
}; }
/** /**
* @return {!Array.<!Array.<number>>} An array of points. * @return {!Array.<!Array.<number>>} An array of points.
* @private * @private
*/ */
Parser.prototype.parsePointTextList_ = function() { parsePointTextList_() {
const coordinates = [this.parsePointText_()]; const coordinates = [this.parsePointText_()];
while (this.match(TokenType.COMMA)) { while (this.match(TokenType.COMMA)) {
coordinates.push(this.parsePointText_()); coordinates.push(this.parsePointText_());
} }
return coordinates; return coordinates;
}; }
/** /**
* @return {!Array.<!Array.<number>>} An array of points. * @return {!Array.<!Array.<number>>} An array of points.
* @private * @private
*/ */
Parser.prototype.parseLineStringTextList_ = function() { parseLineStringTextList_() {
const coordinates = [this.parseLineStringText_()]; const coordinates = [this.parseLineStringText_()];
while (this.match(TokenType.COMMA)) { while (this.match(TokenType.COMMA)) {
coordinates.push(this.parseLineStringText_()); coordinates.push(this.parseLineStringText_());
} }
return coordinates; return coordinates;
}; }
/** /**
* @return {!Array.<!Array.<number>>} An array of points. * @return {!Array.<!Array.<number>>} An array of points.
* @private * @private
*/ */
Parser.prototype.parsePolygonTextList_ = function() { parsePolygonTextList_() {
const coordinates = [this.parsePolygonText_()]; const coordinates = [this.parsePolygonText_()];
while (this.match(TokenType.COMMA)) { while (this.match(TokenType.COMMA)) {
coordinates.push(this.parsePolygonText_()); coordinates.push(this.parsePolygonText_());
} }
return coordinates; return coordinates;
}; }
/** /**
* @return {boolean} Whether the token implies an empty geometry. * @return {boolean} Whether the token implies an empty geometry.
* @private * @private
*/ */
Parser.prototype.isEmptyGeometry_ = function() { isEmptyGeometry_() {
const isEmpty = this.isTokenType(TokenType.TEXT) && const isEmpty = this.isTokenType(TokenType.TEXT) &&
this.token_.value == EMPTY; this.token_.value == EMPTY;
if (isEmpty) { if (isEmpty) {
this.consume_(); this.consume_();
} }
return isEmpty; return isEmpty;
}; }
/** /**
* Create an error message for an unexpected token error. * Create an error message for an unexpected token error.
* @return {string} Error message. * @return {string} Error message.
* @private * @private
*/ */
Parser.prototype.formatErrorMessage_ = function() { formatErrorMessage_() {
return 'Unexpected `' + this.token_.value + '` at position ' + return 'Unexpected `' + this.token_.value + '` at position ' +
this.token_.position + ' in `' + this.lexer_.wkt + '`'; this.token_.position + ' in `' + this.lexer_.wkt + '`';
}; }
/**
* @return {!module:ol/geom/Geometry} The geometry.
* @private
*/
parseGeometry_() {
const token = this.token_;
if (this.match(TokenType.TEXT)) {
const geomType = token.value;
this.layout_ = this.parseGeometryLayout_();
if (geomType == 'GEOMETRYCOLLECTION') {
const geometries = this.parseGeometryCollectionText_();
return new GeometryCollection(geometries);
} else {
const ctor = GeometryConstructor[geomType];
if (!ctor) {
throw new Error('Invalid geometry type: ' + geomType);
}
let coordinates;
switch (geomType) {
case 'POINT': {
coordinates = this.parsePointText_();
break;
}
case 'LINESTRING': {
coordinates = this.parseLineStringText_();
break;
}
case 'POLYGON': {
coordinates = this.parsePolygonText_();
break;
}
case 'MULTIPOINT': {
coordinates = this.parseMultiPointText_();
break;
}
case 'MULTILINESTRING': {
coordinates = this.parseMultiLineStringText_();
break;
}
case 'MULTIPOLYGON': {
coordinates = this.parseMultiPolygonText_();
break;
}
default: {
throw new Error('Invalid geometry type: ' + geomType);
}
}
if (!coordinates) {
if (ctor === GeometryConstructor['POINT']) {
coordinates = [NaN, NaN];
} else {
coordinates = [];
}
}
return new ctor(coordinates, this.layout_);
}
}
throw new Error(this.formatErrorMessage_());
}
}
/** /**
@@ -537,16 +602,18 @@ Parser.prototype.formatErrorMessage_ = function() {
* Geometry format for reading and writing data in the `WellKnownText` (WKT) * Geometry format for reading and writing data in the `WellKnownText` (WKT)
* format. * format.
* *
* @constructor
* @extends {module:ol/format/TextFeature}
* @param {module:ol/format/WKT~Options=} opt_options Options.
* @api * @api
*/ */
const WKT = function(opt_options) { class WKT extends TextFeature {
/**
* @param {module:ol/format/WKT~Options=} opt_options Options.
*/
constructor(opt_options) {
super();
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
TextFeature.call(this);
/** /**
* Split GeometryCollection into multiple features. * Split GeometryCollection into multiple features.
@@ -556,9 +623,104 @@ const WKT = function(opt_options) {
this.splitCollection_ = options.splitCollection !== undefined ? this.splitCollection_ = options.splitCollection !== undefined ?
options.splitCollection : false; options.splitCollection : false;
}; }
inherits(WKT, TextFeature); /**
* Parse a WKT string.
* @param {string} wkt WKT string.
* @return {module:ol/geom/Geometry|undefined}
* The geometry created.
* @private
*/
parse_(wkt) {
const lexer = new Lexer(wkt);
const parser = new Parser(lexer);
return parser.parse();
}
/**
* @inheritDoc
*/
readFeatureFromText(text, opt_options) {
const geom = this.readGeometryFromText(text, opt_options);
if (geom) {
const feature = new Feature();
feature.setGeometry(geom);
return feature;
}
return null;
}
/**
* @inheritDoc
*/
readFeaturesFromText(text, opt_options) {
let geometries = [];
const geometry = this.readGeometryFromText(text, opt_options);
if (this.splitCollection_ &&
geometry.getType() == GeometryType.GEOMETRY_COLLECTION) {
geometries = (/** @type {module:ol/geom/GeometryCollection} */ (geometry))
.getGeometriesArray();
} else {
geometries = [geometry];
}
const features = [];
for (let i = 0, ii = geometries.length; i < ii; ++i) {
const feature = new Feature();
feature.setGeometry(geometries[i]);
features.push(feature);
}
return features;
}
/**
* @inheritDoc
*/
readGeometryFromText(text, opt_options) {
const geometry = this.parse_(text);
if (geometry) {
return (
/** @type {module:ol/geom/Geometry} */ (transformWithOptions(geometry, false, opt_options))
);
} else {
return null;
}
}
/**
* @inheritDoc
*/
writeFeatureText(feature, opt_options) {
const geometry = feature.getGeometry();
if (geometry) {
return this.writeGeometryText(geometry, opt_options);
}
return '';
}
/**
* @inheritDoc
*/
writeFeaturesText(features, opt_options) {
if (features.length == 1) {
return this.writeFeatureText(features[0], opt_options);
}
const geometries = [];
for (let i = 0, ii = features.length; i < ii; ++i) {
geometries.push(features[i].getGeometry());
}
const collection = new GeometryCollection(geometries);
return this.writeGeometryText(collection, opt_options);
}
/**
* @inheritDoc
*/
writeGeometryText(geometry, opt_options) {
return encode(/** @type {module:ol/geom/Geometry} */ (
transformWithOptions(geometry, true, opt_options)));
}
}
/** /**
@@ -712,231 +874,4 @@ function encode(geom) {
} }
/**
* Parse a WKT string.
* @param {string} wkt WKT string.
* @return {module:ol/geom/Geometry|undefined}
* The geometry created.
* @private
*/
WKT.prototype.parse_ = function(wkt) {
const lexer = new Lexer(wkt);
const parser = new Parser(lexer);
return parser.parse();
};
/**
* Read a feature from a WKT source.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {module:ol/Feature} Feature.
* @api
*/
WKT.prototype.readFeature;
/**
* @inheritDoc
*/
WKT.prototype.readFeatureFromText = function(text, opt_options) {
const geom = this.readGeometryFromText(text, opt_options);
if (geom) {
const feature = new Feature();
feature.setGeometry(geom);
return feature;
}
return null;
};
/**
* Read all features from a WKT source.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {Array.<module:ol/Feature>} Features.
* @api
*/
WKT.prototype.readFeatures;
/**
* @inheritDoc
*/
WKT.prototype.readFeaturesFromText = function(text, opt_options) {
let geometries = [];
const geometry = this.readGeometryFromText(text, opt_options);
if (this.splitCollection_ &&
geometry.getType() == GeometryType.GEOMETRY_COLLECTION) {
geometries = (/** @type {module:ol/geom/GeometryCollection} */ (geometry))
.getGeometriesArray();
} else {
geometries = [geometry];
}
const features = [];
for (let i = 0, ii = geometries.length; i < ii; ++i) {
const feature = new Feature();
feature.setGeometry(geometries[i]);
features.push(feature);
}
return features;
};
/**
* Read a single geometry from a WKT source.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {module:ol/geom/Geometry} Geometry.
* @api
*/
WKT.prototype.readGeometry;
/**
* @inheritDoc
*/
WKT.prototype.readGeometryFromText = function(text, opt_options) {
const geometry = this.parse_(text);
if (geometry) {
return (
/** @type {module:ol/geom/Geometry} */ (transformWithOptions(geometry, false, opt_options))
);
} else {
return null;
}
};
/**
* @enum {function (new:module:ol/geom/Geometry, Array, module:ol/geom/GeometryLayout)}
*/
const GeometryConstructor = {
'POINT': Point,
'LINESTRING': LineString,
'POLYGON': Polygon,
'MULTIPOINT': MultiPoint,
'MULTILINESTRING': MultiLineString,
'MULTIPOLYGON': MultiPolygon
};
/**
* @enum {(function(): Array)}
*/
const GeometryParser = {
'POINT': Parser.prototype.parsePointText_,
'LINESTRING': Parser.prototype.parseLineStringText_,
'POLYGON': Parser.prototype.parsePolygonText_,
'MULTIPOINT': Parser.prototype.parseMultiPointText_,
'MULTILINESTRING': Parser.prototype.parseMultiLineStringText_,
'MULTIPOLYGON': Parser.prototype.parseMultiPolygonText_
};
/**
* @return {!module:ol/geom/Geometry} The geometry.
* @private
*/
Parser.prototype.parseGeometry_ = function() {
const token = this.token_;
if (this.match(TokenType.TEXT)) {
const geomType = token.value;
this.layout_ = this.parseGeometryLayout_();
if (geomType == GeometryType.GEOMETRY_COLLECTION.toUpperCase()) {
const geometries = this.parseGeometryCollectionText_();
return new GeometryCollection(geometries);
} else {
const parser = GeometryParser[geomType];
const ctor = GeometryConstructor[geomType];
if (!parser || !ctor) {
throw new Error('Invalid geometry type: ' + geomType);
}
const coordinates = parser.call(this);
return new ctor(coordinates, this.layout_);
}
}
throw new Error(this.formatErrorMessage_());
};
/**
* Encode a feature as a WKT string.
*
* @function
* @param {module:ol/Feature} feature Feature.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {string} WKT string.
* @api
*/
WKT.prototype.writeFeature;
/**
* @inheritDoc
*/
WKT.prototype.writeFeatureText = function(feature, opt_options) {
const geometry = feature.getGeometry();
if (geometry) {
return this.writeGeometryText(geometry, opt_options);
}
return '';
};
/**
* Encode an array of features as a WKT string.
*
* @function
* @param {Array.<module:ol/Feature>} features Features.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {string} WKT string.
* @api
*/
WKT.prototype.writeFeatures;
/**
* @inheritDoc
*/
WKT.prototype.writeFeaturesText = function(features, opt_options) {
if (features.length == 1) {
return this.writeFeatureText(features[0], opt_options);
}
const geometries = [];
for (let i = 0, ii = features.length; i < ii; ++i) {
geometries.push(features[i].getGeometry());
}
const collection = new GeometryCollection(geometries);
return this.writeGeometryText(collection, opt_options);
};
/**
* Write a single geometry as a WKT string.
*
* @function
* @param {module:ol/geom/Geometry} geometry Geometry.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {string} WKT string.
* @api
*/
WKT.prototype.writeGeometry;
/**
* @inheritDoc
*/
WKT.prototype.writeGeometryText = function(geometry, opt_options) {
return encode(/** @type {module:ol/geom/Geometry} */ (
transformWithOptions(geometry, true, opt_options)));
};
export default WKT; export default WKT;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/format/WMSCapabilities * @module ol/format/WMSCapabilities
*/ */
import {inherits} from '../util.js';
import {readHref} from '../format/XLink.js'; import {readHref} from '../format/XLink.js';
import XML from '../format/XML.js'; import XML from '../format/XML.js';
import {readDecimalString, readString, readNonNegativeInteger, readDecimal, readBooleanString, readNonNegativeIntegerString} from '../format/xsd.js'; import {readDecimalString, readString, readNonNegativeInteger, readDecimal, readBooleanString, readNonNegativeIntegerString} from '../format/xsd.js';
@@ -9,27 +8,6 @@ import {makeArrayPusher, makeObjectPropertyPusher, makeObjectPropertySetter,
makeStructureNS, pushParseAndPop} from '../xml.js'; makeStructureNS, pushParseAndPop} from '../xml.js';
/**
* @classdesc
* Format for reading WMS capabilities data
*
* @constructor
* @extends {module:ol/format/XML}
* @api
*/
const WMSCapabilities = function() {
XML.call(this);
/**
* @type {string|undefined}
*/
this.version = undefined;
};
inherits(WMSCapabilities, XML);
/** /**
* @const * @const
* @type {Array.<null|string>} * @type {Array.<null|string>}
@@ -63,6 +41,47 @@ const CAPABILITY_PARSERS = makeStructureNS(
}); });
/**
* @classdesc
* Format for reading WMS capabilities data
*
* @api
*/
class WMSCapabilities extends XML {
constructor() {
super();
/**
* @type {string|undefined}
*/
this.version = undefined;
}
/**
* @inheritDoc
*/
readFromDocument(doc) {
for (let n = doc.firstChild; n; n = n.nextSibling) {
if (n.nodeType == Node.ELEMENT_NODE) {
return this.readFromNode(n);
}
}
return null;
}
/**
* @inheritDoc
*/
readFromNode(node) {
this.version = node.getAttribute('version').trim();
const wmsCapabilityObject = pushParseAndPop({
'version': this.version
}, PARSERS, node, []);
return wmsCapabilityObject ? wmsCapabilityObject : null;
}
}
/** /**
* @const * @const
* @type {Object.<string, Object.<string, module:ol/xml~Parser>>} * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}
@@ -266,42 +285,6 @@ const KEYWORDLIST_PARSERS = makeStructureNS(
}); });
/**
* Read a WMS capabilities document.
*
* @function
* @param {Document|Node|string} source The XML source.
* @return {Object} An object representing the WMS capabilities.
* @api
*/
WMSCapabilities.prototype.read;
/**
* @inheritDoc
*/
WMSCapabilities.prototype.readFromDocument = function(doc) {
for (let n = doc.firstChild; n; n = n.nextSibling) {
if (n.nodeType == Node.ELEMENT_NODE) {
return this.readFromNode(n);
}
}
return null;
};
/**
* @inheritDoc
*/
WMSCapabilities.prototype.readFromNode = function(node) {
this.version = node.getAttribute('version').trim();
const wmsCapabilityObject = pushParseAndPop({
'version': this.version
}, PARSERS, node, []);
return wmsCapabilityObject ? wmsCapabilityObject : null;
};
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack. * @param {Array.<*>} objectStack Object stack.

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/format/WMSGetFeatureInfo * @module ol/format/WMSGetFeatureInfo
*/ */
import {inherits} from '../util.js';
import {extend, includes} from '../array.js'; import {extend, includes} from '../array.js';
import GML2 from '../format/GML2.js'; import GML2 from '../format/GML2.js';
import XMLFeature from '../format/XMLFeature.js'; import XMLFeature from '../format/XMLFeature.js';
@@ -15,17 +14,34 @@ import {makeArrayPusher, makeStructureNS, pushParseAndPop} from '../xml.js';
*/ */
/**
* @const
* @type {string}
*/
const featureIdentifier = '_feature';
/**
* @const
* @type {string}
*/
const layerIdentifier = '_layer';
/** /**
* @classdesc * @classdesc
* Format for reading WMSGetFeatureInfo format. It uses * Format for reading WMSGetFeatureInfo format. It uses
* {@link module:ol/format/GML2~GML2} to read features. * {@link module:ol/format/GML2~GML2} to read features.
* *
* @constructor
* @extends {module:ol/format/XMLFeature}
* @param {module:ol/format/WMSGetFeatureInfo~Options=} opt_options Options.
* @api * @api
*/ */
const WMSGetFeatureInfo = function(opt_options) { class WMSGetFeatureInfo extends XMLFeature {
/**
* @param {module:ol/format/WMSGetFeatureInfo~Options=} opt_options Options.
*/
constructor(opt_options) {
super();
const options = opt_options ? opt_options : {}; const options = opt_options ? opt_options : {};
@@ -48,42 +64,21 @@ const WMSGetFeatureInfo = function(opt_options) {
* @type {Array.<string>} * @type {Array.<string>}
*/ */
this.layers_ = options.layers ? options.layers : null; this.layers_ = options.layers ? options.layers : null;
}
XMLFeature.call(this);
};
inherits(WMSGetFeatureInfo, XMLFeature);
/**
* @const
* @type {string}
*/
const featureIdentifier = '_feature';
/**
* @const
* @type {string}
*/
const layerIdentifier = '_layer';
/** /**
* @return {Array.<string>} layers * @return {Array.<string>} layers
*/ */
WMSGetFeatureInfo.prototype.getLayers = function() { getLayers() {
return this.layers_; return this.layers_;
}; }
/** /**
* @param {Array.<string>} layers Layers to parse. * @param {Array.<string>} layers Layers to parse.
*/ */
WMSGetFeatureInfo.prototype.setLayers = function(layers) { setLayers(layers) {
this.layers_ = layers; this.layers_ = layers;
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
@@ -91,7 +86,7 @@ WMSGetFeatureInfo.prototype.setLayers = function(layers) {
* @return {Array.<module:ol/Feature>} Features. * @return {Array.<module:ol/Feature>} Features.
* @private * @private
*/ */
WMSGetFeatureInfo.prototype.readFeatures_ = function(node, objectStack) { readFeatures_(node, objectStack) {
node.setAttribute('namespaceURI', this.featureNS_); node.setAttribute('namespaceURI', this.featureNS_);
const localName = node.localName; const localName = node.localName;
/** @type {Array.<module:ol/Feature>} */ /** @type {Array.<module:ol/Feature>} */
@@ -142,50 +137,37 @@ WMSGetFeatureInfo.prototype.readFeatures_ = function(node, objectStack) {
} }
} }
return features; return features;
}; }
/**
* Read all features from a WMSGetFeatureInfo response.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Options.
* @return {Array.<module:ol/Feature>} Features.
* @api
*/
WMSGetFeatureInfo.prototype.readFeatures;
/** /**
* @inheritDoc * @inheritDoc
*/ */
WMSGetFeatureInfo.prototype.readFeaturesFromNode = function(node, opt_options) { readFeaturesFromNode(node, opt_options) {
const options = {}; const options = {};
if (opt_options) { if (opt_options) {
assign(options, this.getReadOptions(node, opt_options)); assign(options, this.getReadOptions(node, opt_options));
} }
return this.readFeatures_(node, [options]); return this.readFeatures_(node, [options]);
}; }
/** /**
* Not implemented. * Not implemented.
* @inheritDoc * @inheritDoc
*/ */
WMSGetFeatureInfo.prototype.writeFeatureNode = function(feature, opt_options) {}; writeFeatureNode(feature, opt_options) {}
/** /**
* Not implemented. * Not implemented.
* @inheritDoc * @inheritDoc
*/ */
WMSGetFeatureInfo.prototype.writeFeaturesNode = function(features, opt_options) {}; writeFeaturesNode(features, opt_options) {}
/** /**
* Not implemented. * Not implemented.
* @inheritDoc * @inheritDoc
*/ */
WMSGetFeatureInfo.prototype.writeGeometryNode = function(geometry, opt_options) {}; writeGeometryNode(geometry, opt_options) {}
}
export default WMSGetFeatureInfo; export default WMSGetFeatureInfo;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/format/WMTSCapabilities * @module ol/format/WMTSCapabilities
*/ */
import {inherits} from '../util.js';
import {boundingExtent} from '../extent.js'; import {boundingExtent} from '../extent.js';
import OWS from '../format/OWS.js'; import OWS from '../format/OWS.js';
import {readHref} from '../format/XLink.js'; import {readHref} from '../format/XLink.js';
@@ -10,26 +9,6 @@ import {readString, readNonNegativeInteger, readDecimal} from '../format/xsd.js'
import {pushParseAndPop, makeStructureNS, import {pushParseAndPop, makeStructureNS,
makeObjectPropertySetter, makeObjectPropertyPusher, makeArrayPusher} from '../xml.js'; makeObjectPropertySetter, makeObjectPropertyPusher, makeArrayPusher} from '../xml.js';
/**
* @classdesc
* Format for reading WMTS capabilities data.
*
* @constructor
* @extends {module:ol/format/XML}
* @api
*/
const WMTSCapabilities = function() {
XML.call(this);
/**
* @type {module:ol/format/OWS}
* @private
*/
this.owsParser_ = new OWS();
};
inherits(WMTSCapabilities, XML);
/** /**
* @const * @const
@@ -61,6 +40,51 @@ const PARSERS = makeStructureNS(
}); });
/**
* @classdesc
* Format for reading WMTS capabilities data.
*
* @api
*/
class WMTSCapabilities extends XML {
constructor() {
super();
/**
* @type {module:ol/format/OWS}
* @private
*/
this.owsParser_ = new OWS();
}
/**
* @inheritDoc
*/
readFromDocument(doc) {
for (let n = doc.firstChild; n; n = n.nextSibling) {
if (n.nodeType == Node.ELEMENT_NODE) {
return this.readFromNode(n);
}
}
return null;
}
/**
* @inheritDoc
*/
readFromNode(node) {
const version = node.getAttribute('version').trim();
let WMTSCapabilityObject = this.owsParser_.readFromNode(node);
if (!WMTSCapabilityObject) {
return null;
}
WMTSCapabilityObject['version'] = version;
WMTSCapabilityObject = pushParseAndPop(WMTSCapabilityObject, PARSERS, node, []);
return WMTSCapabilityObject ? WMTSCapabilityObject : null;
}
}
/** /**
* @const * @const
* @type {Object.<string, Object.<string, module:ol/xml~Parser>>} * @type {Object.<string, Object.<string, module:ol/xml~Parser>>}
@@ -193,45 +217,6 @@ const TM_PARSERS = makeStructureNS(
})); }));
/**
* Read a WMTS capabilities document.
*
* @function
* @param {Document|Node|string} source The XML source.
* @return {Object} An object representing the WMTS capabilities.
* @api
*/
WMTSCapabilities.prototype.read;
/**
* @inheritDoc
*/
WMTSCapabilities.prototype.readFromDocument = function(doc) {
for (let n = doc.firstChild; n; n = n.nextSibling) {
if (n.nodeType == Node.ELEMENT_NODE) {
return this.readFromNode(n);
}
}
return null;
};
/**
* @inheritDoc
*/
WMTSCapabilities.prototype.readFromNode = function(node) {
const version = node.getAttribute('version').trim();
let WMTSCapabilityObject = this.owsParser_.readFromNode(node);
if (!WMTSCapabilityObject) {
return null;
}
WMTSCapabilityObject['version'] = version;
WMTSCapabilityObject = pushParseAndPop(WMTSCapabilityObject, PARSERS, node, []);
return WMTSCapabilityObject ? WMTSCapabilityObject : null;
};
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack. * @param {Array.<*>} objectStack Object stack.

View File

@@ -12,7 +12,7 @@ const NAMESPACE_URI = 'http://www.w3.org/1999/xlink';
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @return {boolean|undefined} Boolean. * @return {string|undefined} href.
*/ */
export function readHref(node) { export function readHref(node) {
return node.getAttributeNS(NAMESPACE_URI, 'href'); return node.getAttributeNS(NAMESPACE_URI, 'href');

View File

@@ -7,19 +7,17 @@ import {isDocument, isNode, parse} from '../xml.js';
* @classdesc * @classdesc
* Generic format for reading non-feature XML data * Generic format for reading non-feature XML data
* *
* @constructor
* @abstract * @abstract
* @struct
*/ */
const XML = function() { class XML {
};
/** /**
* @param {Document|Node|string} source Source. * Read the source document.
* @return {Object} The parsed result. *
* @param {Document|Node|string} source The XML source.
* @return {Object} An object representing the source.
* @api
*/ */
XML.prototype.read = function(source) { read(source) {
if (isDocument(source)) { if (isDocument(source)) {
return this.readFromDocument(/** @type {Document} */ (source)); return this.readFromDocument(/** @type {Document} */ (source));
} else if (isNode(source)) { } else if (isNode(source)) {
@@ -30,21 +28,21 @@ XML.prototype.read = function(source) {
} else { } else {
return null; return null;
} }
}; }
/** /**
* @abstract * @abstract
* @param {Document} doc Document. * @param {Document} doc Document.
* @return {Object} Object * @return {Object} Object
*/ */
XML.prototype.readFromDocument = function(doc) {}; readFromDocument(doc) {}
/** /**
* @abstract * @abstract
* @param {Node} node Node. * @param {Node} node Node.
* @return {Object} Object * @return {Object} Object
*/ */
XML.prototype.readFromNode = function(node) {}; readFromNode(node) {}
}
export default XML; export default XML;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/format/XMLFeature * @module ol/format/XMLFeature
*/ */
import {inherits} from '../util.js';
import {extend} from '../array.js'; import {extend} from '../array.js';
import FeatureFormat from '../format/Feature.js'; import FeatureFormat from '../format/Feature.js';
import FormatType from '../format/FormatType.js'; import FormatType from '../format/FormatType.js';
@@ -13,36 +12,35 @@ import {isDocument, isNode, parse} from '../xml.js';
* instantiated in apps. * instantiated in apps.
* Base class for XML feature formats. * Base class for XML feature formats.
* *
* @constructor
* @abstract * @abstract
* @extends {module:ol/format/Feature}
*/ */
const XMLFeature = function() { class XMLFeature extends FeatureFormat {
constructor() {
super();
/** /**
* @type {XMLSerializer} * @type {XMLSerializer}
* @private * @private
*/ */
this.xmlSerializer_ = new XMLSerializer(); this.xmlSerializer_ = new XMLSerializer();
}
FeatureFormat.call(this);
};
inherits(XMLFeature, FeatureFormat);
/** /**
* @inheritDoc * @inheritDoc
*/ */
XMLFeature.prototype.getType = function() { getType() {
return FormatType.XML; return FormatType.XML;
}; }
/** /**
* @inheritDoc * Read a single feature.
*
* @param {Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Read options.
* @return {module:ol/Feature} Feature.
* @api
*/ */
XMLFeature.prototype.readFeature = function(source, opt_options) { readFeature(source, opt_options) {
if (isDocument(source)) { if (isDocument(source)) {
return this.readFeatureFromDocument(/** @type {Document} */ (source), opt_options); return this.readFeatureFromDocument(/** @type {Document} */ (source), opt_options);
} else if (isNode(source)) { } else if (isNode(source)) {
@@ -53,38 +51,41 @@ XMLFeature.prototype.readFeature = function(source, opt_options) {
} else { } else {
return null; return null;
} }
}; }
/** /**
* @param {Document} doc Document. * @param {Document} doc Document.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Options. * @param {module:ol/format/Feature~ReadOptions=} opt_options Options.
* @return {module:ol/Feature} Feature. * @return {module:ol/Feature} Feature.
*/ */
XMLFeature.prototype.readFeatureFromDocument = function(doc, opt_options) { readFeatureFromDocument(doc, opt_options) {
const features = this.readFeaturesFromDocument(doc, opt_options); const features = this.readFeaturesFromDocument(doc, opt_options);
if (features.length > 0) { if (features.length > 0) {
return features[0]; return features[0];
} else { } else {
return null; return null;
} }
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Options. * @param {module:ol/format/Feature~ReadOptions=} opt_options Options.
* @return {module:ol/Feature} Feature. * @return {module:ol/Feature} Feature.
*/ */
XMLFeature.prototype.readFeatureFromNode = function(node, opt_options) { readFeatureFromNode(node, opt_options) {
return null; // not implemented return null; // not implemented
}; }
/** /**
* @inheritDoc * Read all features from a feature collection.
*
* @function
* @param {Document|Node|Object|string} source Source.
* @param {module:ol/format/Feature~ReadOptions=} opt_options Options.
* @return {Array.<module:ol/Feature>} Features.
* @api
*/ */
XMLFeature.prototype.readFeatures = function(source, opt_options) { readFeatures(source, opt_options) {
if (isDocument(source)) { if (isDocument(source)) {
return this.readFeaturesFromDocument( return this.readFeaturesFromDocument(
/** @type {Document} */ (source), opt_options); /** @type {Document} */ (source), opt_options);
@@ -96,8 +97,7 @@ XMLFeature.prototype.readFeatures = function(source, opt_options) {
} else { } else {
return []; return [];
} }
}; }
/** /**
* @param {Document} doc Document. * @param {Document} doc Document.
@@ -105,7 +105,7 @@ XMLFeature.prototype.readFeatures = function(source, opt_options) {
* @protected * @protected
* @return {Array.<module:ol/Feature>} Features. * @return {Array.<module:ol/Feature>} Features.
*/ */
XMLFeature.prototype.readFeaturesFromDocument = function(doc, opt_options) { readFeaturesFromDocument(doc, opt_options) {
/** @type {Array.<module:ol/Feature>} */ /** @type {Array.<module:ol/Feature>} */
const features = []; const features = [];
for (let n = doc.firstChild; n; n = n.nextSibling) { for (let n = doc.firstChild; n; n = n.nextSibling) {
@@ -114,8 +114,7 @@ XMLFeature.prototype.readFeaturesFromDocument = function(doc, opt_options) {
} }
} }
return features; return features;
}; }
/** /**
* @abstract * @abstract
@@ -124,13 +123,12 @@ XMLFeature.prototype.readFeaturesFromDocument = function(doc, opt_options) {
* @protected * @protected
* @return {Array.<module:ol/Feature>} Features. * @return {Array.<module:ol/Feature>} Features.
*/ */
XMLFeature.prototype.readFeaturesFromNode = function(node, opt_options) {}; readFeaturesFromNode(node, opt_options) {}
/** /**
* @inheritDoc * @inheritDoc
*/ */
XMLFeature.prototype.readGeometry = function(source, opt_options) { readGeometry(source, opt_options) {
if (isDocument(source)) { if (isDocument(source)) {
return this.readGeometryFromDocument( return this.readGeometryFromDocument(
/** @type {Document} */ (source), opt_options); /** @type {Document} */ (source), opt_options);
@@ -142,8 +140,7 @@ XMLFeature.prototype.readGeometry = function(source, opt_options) {
} else { } else {
return null; return null;
} }
}; }
/** /**
* @param {Document} doc Document. * @param {Document} doc Document.
@@ -151,10 +148,9 @@ XMLFeature.prototype.readGeometry = function(source, opt_options) {
* @protected * @protected
* @return {module:ol/geom/Geometry} Geometry. * @return {module:ol/geom/Geometry} Geometry.
*/ */
XMLFeature.prototype.readGeometryFromDocument = function(doc, opt_options) { readGeometryFromDocument(doc, opt_options) {
return null; // not implemented return null; // not implemented
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
@@ -162,15 +158,18 @@ XMLFeature.prototype.readGeometryFromDocument = function(doc, opt_options) {
* @protected * @protected
* @return {module:ol/geom/Geometry} Geometry. * @return {module:ol/geom/Geometry} Geometry.
*/ */
XMLFeature.prototype.readGeometryFromNode = function(node, opt_options) { readGeometryFromNode(node, opt_options) {
return null; // not implemented return null; // not implemented
}; }
/** /**
* @inheritDoc * Read the projection from the source.
*
* @param {Document|Node|Object|string} source Source.
* @return {module:ol/proj/Projection} Projection.
* @api
*/ */
XMLFeature.prototype.readProjection = function(source) { readProjection(source) {
if (isDocument(source)) { if (isDocument(source)) {
return this.readProjectionFromDocument(/** @type {Document} */ (source)); return this.readProjectionFromDocument(/** @type {Document} */ (source));
} else if (isNode(source)) { } else if (isNode(source)) {
@@ -181,37 +180,33 @@ XMLFeature.prototype.readProjection = function(source) {
} else { } else {
return null; return null;
} }
}; }
/** /**
* @param {Document} doc Document. * @param {Document} doc Document.
* @protected * @protected
* @return {module:ol/proj/Projection} Projection. * @return {module:ol/proj/Projection} Projection.
*/ */
XMLFeature.prototype.readProjectionFromDocument = function(doc) { readProjectionFromDocument(doc) {
return this.dataProjection; return this.dataProjection;
}; }
/** /**
* @param {Node} node Node. * @param {Node} node Node.
* @protected * @protected
* @return {module:ol/proj/Projection} Projection. * @return {module:ol/proj/Projection} Projection.
*/ */
XMLFeature.prototype.readProjectionFromNode = function(node) { readProjectionFromNode(node) {
return this.dataProjection; return this.dataProjection;
}; }
/** /**
* @inheritDoc * @inheritDoc
*/ */
XMLFeature.prototype.writeFeature = function(feature, opt_options) { writeFeature(feature, opt_options) {
const node = this.writeFeatureNode(feature, opt_options); const node = this.writeFeatureNode(feature, opt_options);
return this.xmlSerializer_.serializeToString(node); return this.xmlSerializer_.serializeToString(node);
}; }
/** /**
* @param {module:ol/Feature} feature Feature. * @param {module:ol/Feature} feature Feature.
@@ -219,45 +214,49 @@ XMLFeature.prototype.writeFeature = function(feature, opt_options) {
* @protected * @protected
* @return {Node} Node. * @return {Node} Node.
*/ */
XMLFeature.prototype.writeFeatureNode = function(feature, opt_options) { writeFeatureNode(feature, opt_options) {
return null; // not implemented return null; // not implemented
}; }
/** /**
* @inheritDoc * Encode an array of features as string.
*
* @param {Array.<module:ol/Feature>} features Features.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Write options.
* @return {string} Result.
* @api
*/ */
XMLFeature.prototype.writeFeatures = function(features, opt_options) { writeFeatures(features, opt_options) {
const node = this.writeFeaturesNode(features, opt_options); const node = this.writeFeaturesNode(features, opt_options);
return this.xmlSerializer_.serializeToString(node); return this.xmlSerializer_.serializeToString(node);
}; }
/** /**
* @param {Array.<module:ol/Feature>} features Features. * @param {Array.<module:ol/Feature>} features Features.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Options. * @param {module:ol/format/Feature~WriteOptions=} opt_options Options.
* @return {Node} Node. * @return {Node} Node.
*/ */
XMLFeature.prototype.writeFeaturesNode = function(features, opt_options) { writeFeaturesNode(features, opt_options) {
return null; // not implemented return null; // not implemented
}; }
/** /**
* @inheritDoc * @inheritDoc
*/ */
XMLFeature.prototype.writeGeometry = function(geometry, opt_options) { writeGeometry(geometry, opt_options) {
const node = this.writeGeometryNode(geometry, opt_options); const node = this.writeGeometryNode(geometry, opt_options);
return this.xmlSerializer_.serializeToString(node); return this.xmlSerializer_.serializeToString(node);
}; }
/** /**
* @param {module:ol/geom/Geometry} geometry Geometry. * @param {module:ol/geom/Geometry} geometry Geometry.
* @param {module:ol/format/Feature~WriteOptions=} opt_options Options. * @param {module:ol/format/Feature~WriteOptions=} opt_options Options.
* @return {Node} Node. * @return {Node} Node.
*/ */
XMLFeature.prototype.writeGeometryNode = function(geometry, opt_options) { writeGeometryNode(geometry, opt_options) {
return null; // not implemented return null; // not implemented
}; }
}
export default XMLFeature; export default XMLFeature;

View File

@@ -1,23 +1,24 @@
/** /**
* @module ol/format/filter/And * @module ol/format/filter/And
*/ */
import {inherits} from '../../util.js';
import LogicalNary from '../filter/LogicalNary.js'; import LogicalNary from '../filter/LogicalNary.js';
/** /**
* @classdesc * @classdesc
* Represents a logical `<And>` operator between two or more filter conditions. * Represents a logical `<And>` operator between two or more filter conditions.
* *
* @constructor
* @abstract * @abstract
* @param {...module:ol/format/filter/Filter} conditions Conditions.
* @extends {module:ol/format/filter/LogicalNary}
*/ */
const And = function(conditions) { class And extends LogicalNary {
const params = ['And'].concat(Array.prototype.slice.call(arguments));
LogicalNary.apply(this, params);
};
inherits(And, LogicalNary); /**
* @param {...module:ol/format/filter/Filter} conditions Conditions.
*/
constructor(conditions) {
const params = ['And'].concat(Array.prototype.slice.call(arguments));
super(...params);
}
}
export default And; export default And;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/format/filter/Bbox * @module ol/format/filter/Bbox
*/ */
import {inherits} from '../../util.js';
import Filter from '../filter/Filter.js'; import Filter from '../filter/Filter.js';
/** /**
@@ -9,17 +8,19 @@ import Filter from '../filter/Filter.js';
* Represents a `<BBOX>` operator to test whether a geometry-valued property * Represents a `<BBOX>` operator to test whether a geometry-valued property
* intersects a fixed bounding box * intersects a fixed bounding box
* *
* @constructor
* @param {!string} geometryName Geometry name to use.
* @param {!module:ol/extent~Extent} extent Extent.
* @param {string=} opt_srsName SRS name. No srsName attribute will be
* set on geometries when this is not provided.
* @extends {module:ol/format/filter/Filter}
* @api * @api
*/ */
const Bbox = function(geometryName, extent, opt_srsName) { class Bbox extends Filter {
Filter.call(this, 'BBOX'); /**
* @param {!string} geometryName Geometry name to use.
* @param {!module:ol/extent~Extent} extent Extent.
* @param {string=} opt_srsName SRS name. No srsName attribute will be set
* on geometries when this is not provided.
*/
constructor(geometryName, extent, opt_srsName) {
super('BBOX');
/** /**
* @type {!string} * @type {!string}
@@ -35,8 +36,8 @@ const Bbox = function(geometryName, extent, opt_srsName) {
* @type {string|undefined} * @type {string|undefined}
*/ */
this.srsName = opt_srsName; this.srsName = opt_srsName;
}; }
inherits(Bbox, Filter); }
export default Bbox; export default Bbox;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/format/filter/Comparison * @module ol/format/filter/Comparison
*/ */
import {inherits} from '../../util.js';
import Filter from '../filter/Filter.js'; import Filter from '../filter/Filter.js';
/** /**
@@ -9,22 +8,24 @@ import Filter from '../filter/Filter.js';
* Abstract class; normally only used for creating subclasses and not instantiated in apps. * Abstract class; normally only used for creating subclasses and not instantiated in apps.
* Base class for WFS GetFeature property comparison filters. * Base class for WFS GetFeature property comparison filters.
* *
* @constructor
* @abstract * @abstract
*/
class Comparison extends Filter {
/**
* @param {!string} tagName The XML tag name for this filter. * @param {!string} tagName The XML tag name for this filter.
* @param {!string} propertyName Name of the context property to compare. * @param {!string} propertyName Name of the context property to compare.
* @extends {module:ol/format/filter/Filter}
*/ */
const Comparison = function(tagName, propertyName) { constructor(tagName, propertyName) {
Filter.call(this, tagName); super(tagName);
/** /**
* @type {!string} * @type {!string}
*/ */
this.propertyName = propertyName; this.propertyName = propertyName;
}; }
inherits(Comparison, Filter); }
export default Comparison; export default Comparison;

View File

@@ -1,7 +1,6 @@
/** /**
* @module ol/format/filter/ComparisonBinary * @module ol/format/filter/ComparisonBinary
*/ */
import {inherits} from '../../util.js';
import Comparison from '../filter/Comparison.js'; import Comparison from '../filter/Comparison.js';
/** /**
@@ -9,17 +8,19 @@ import Comparison from '../filter/Comparison.js';
* Abstract class; normally only used for creating subclasses and not instantiated in apps. * Abstract class; normally only used for creating subclasses and not instantiated in apps.
* Base class for WFS GetFeature property binary comparison filters. * Base class for WFS GetFeature property binary comparison filters.
* *
* @constructor
* @abstract * @abstract
*/
class ComparisonBinary extends Comparison {
/**
* @param {!string} tagName The XML tag name for this filter. * @param {!string} tagName The XML tag name for this filter.
* @param {!string} propertyName Name of the context property to compare. * @param {!string} propertyName Name of the context property to compare.
* @param {!(string|number)} expression The value to compare. * @param {!(string|number)} expression The value to compare.
* @param {boolean=} opt_matchCase Case-sensitive? * @param {boolean=} opt_matchCase Case-sensitive?
* @extends {module:ol/format/filter/Comparison}
*/ */
const ComparisonBinary = function(tagName, propertyName, expression, opt_matchCase) { constructor(tagName, propertyName, expression, opt_matchCase) {
Comparison.call(this, tagName, propertyName); super(tagName, propertyName);
/** /**
* @type {!(string|number)} * @type {!(string|number)}
@@ -30,7 +31,8 @@ const ComparisonBinary = function(tagName, propertyName, expression, opt_matchCa
* @type {boolean|undefined} * @type {boolean|undefined}
*/ */
this.matchCase = opt_matchCase; this.matchCase = opt_matchCase;
}; }
}
inherits(ComparisonBinary, Comparison);
export default ComparisonBinary; export default ComparisonBinary;

View File

@@ -1,27 +1,28 @@
/** /**
* @module ol/format/filter/Contains * @module ol/format/filter/Contains
*/ */
import {inherits} from '../../util.js';
import Spatial from '../filter/Spatial.js'; import Spatial from '../filter/Spatial.js';
/** /**
* @classdesc * @classdesc
* Represents a `<Contains>` operator to test whether a geometry-valued property * Represents a `<Contains>` operator to test whether a geometry-valued property
* contains a given geometry. * contains a given geometry.
* */
* @constructor class Contains extends Spatial {
/**
* @param {!string} geometryName Geometry name to use. * @param {!string} geometryName Geometry name to use.
* @param {!module:ol/geom/Geometry} geometry Geometry. * @param {!module:ol/geom/Geometry} geometry Geometry.
* @param {string=} opt_srsName SRS name. No srsName attribute will be * @param {string=} opt_srsName SRS name. No srsName attribute will be
* set on geometries when this is not provided. * set on geometries when this is not provided.
* @extends {module:ol/format/filter/Spatial}
* @api * @api
*/ */
const Contains = function(geometryName, geometry, opt_srsName) { constructor(geometryName, geometry, opt_srsName) {
Spatial.call(this, 'Contains', geometryName, geometry, opt_srsName); super('Contains', geometryName, geometry, opt_srsName);
}; }
}
inherits(Contains, Spatial);
export default Contains; export default Contains;

View File

@@ -1,22 +1,22 @@
/** /**
* @module ol/format/filter/During * @module ol/format/filter/During
*/ */
import {inherits} from '../../util.js';
import Comparison from '../filter/Comparison.js'; import Comparison from '../filter/Comparison.js';
/** /**
* @classdesc * @classdesc
* Represents a `<During>` comparison operator. * Represents a `<During>` comparison operator.
* */
* @constructor class During extends Comparison {
/**
* @param {!string} propertyName Name of the context property to compare. * @param {!string} propertyName Name of the context property to compare.
* @param {!string} begin The begin date in ISO-8601 format. * @param {!string} begin The begin date in ISO-8601 format.
* @param {!string} end The end date in ISO-8601 format. * @param {!string} end The end date in ISO-8601 format.
* @extends {module:ol/format/filter/Comparison}
* @api * @api
*/ */
const During = function(propertyName, begin, end) { constructor(propertyName, begin, end) {
Comparison.call(this, 'During', propertyName); super('During', propertyName);
/** /**
* @type {!string} * @type {!string}
@@ -27,7 +27,8 @@ const During = function(propertyName, begin, end) {
* @type {!string} * @type {!string}
*/ */
this.end = end; this.end = end;
}; }
}
inherits(During, Comparison);
export default During; export default During;

View File

@@ -1,23 +1,24 @@
/** /**
* @module ol/format/filter/EqualTo * @module ol/format/filter/EqualTo
*/ */
import {inherits} from '../../util.js';
import ComparisonBinary from '../filter/ComparisonBinary.js'; import ComparisonBinary from '../filter/ComparisonBinary.js';
/** /**
* @classdesc * @classdesc
* Represents a `<PropertyIsEqualTo>` comparison operator. * Represents a `<PropertyIsEqualTo>` comparison operator.
* */
* @constructor class EqualTo extends ComparisonBinary {
/**
* @param {!string} propertyName Name of the context property to compare. * @param {!string} propertyName Name of the context property to compare.
* @param {!(string|number)} expression The value to compare. * @param {!(string|number)} expression The value to compare.
* @param {boolean=} opt_matchCase Case-sensitive? * @param {boolean=} opt_matchCase Case-sensitive?
* @extends {module:ol/format/filter/ComparisonBinary}
* @api * @api
*/ */
const EqualTo = function(propertyName, expression, opt_matchCase) { constructor(propertyName, expression, opt_matchCase) {
ComparisonBinary.call(this, 'PropertyIsEqualTo', propertyName, expression, opt_matchCase); super('PropertyIsEqualTo', propertyName, expression, opt_matchCase);
}; }
}
inherits(EqualTo, ComparisonBinary);
export default EqualTo; export default EqualTo;

View File

@@ -8,26 +8,28 @@
* Abstract class; normally only used for creating subclasses and not instantiated in apps. * Abstract class; normally only used for creating subclasses and not instantiated in apps.
* Base class for WFS GetFeature filters. * Base class for WFS GetFeature filters.
* *
* @constructor
* @abstract * @abstract
* @param {!string} tagName The XML tag name for this filter.
* @struct
*/ */
const Filter = function(tagName) { class Filter {
/**
* @param {!string} tagName The XML tag name for this filter.
*/
constructor(tagName) {
/** /**
* @private * @private
* @type {!string} * @type {!string}
*/ */
this.tagName_ = tagName; this.tagName_ = tagName;
}; }
/** /**
* The XML tag name for a filter. * The XML tag name for a filter.
* @returns {!string} Name. * @returns {!string} Name.
*/ */
Filter.prototype.getTagName = function() { getTagName() {
return this.tagName_; return this.tagName_;
}; }
}
export default Filter; export default Filter;

View File

@@ -1,22 +1,23 @@
/** /**
* @module ol/format/filter/GreaterThan * @module ol/format/filter/GreaterThan
*/ */
import {inherits} from '../../util.js';
import ComparisonBinary from '../filter/ComparisonBinary.js'; import ComparisonBinary from '../filter/ComparisonBinary.js';
/** /**
* @classdesc * @classdesc
* Represents a `<PropertyIsGreaterThan>` comparison operator. * Represents a `<PropertyIsGreaterThan>` comparison operator.
* */
* @constructor class GreaterThan extends ComparisonBinary {
/**
* @param {!string} propertyName Name of the context property to compare. * @param {!string} propertyName Name of the context property to compare.
* @param {!number} expression The value to compare. * @param {!number} expression The value to compare.
* @extends {module:ol/format/filter/ComparisonBinary}
* @api * @api
*/ */
const GreaterThan = function(propertyName, expression) { constructor(propertyName, expression) {
ComparisonBinary.call(this, 'PropertyIsGreaterThan', propertyName, expression); super('PropertyIsGreaterThan', propertyName, expression);
}; }
}
inherits(GreaterThan, ComparisonBinary);
export default GreaterThan; export default GreaterThan;

View File

@@ -1,22 +1,23 @@
/** /**
* @module ol/format/filter/GreaterThanOrEqualTo * @module ol/format/filter/GreaterThanOrEqualTo
*/ */
import {inherits} from '../../util.js';
import ComparisonBinary from '../filter/ComparisonBinary.js'; import ComparisonBinary from '../filter/ComparisonBinary.js';
/** /**
* @classdesc * @classdesc
* Represents a `<PropertyIsGreaterThanOrEqualTo>` comparison operator. * Represents a `<PropertyIsGreaterThanOrEqualTo>` comparison operator.
* */
* @constructor class GreaterThanOrEqualTo extends ComparisonBinary {
/**
* @param {!string} propertyName Name of the context property to compare. * @param {!string} propertyName Name of the context property to compare.
* @param {!number} expression The value to compare. * @param {!number} expression The value to compare.
* @extends {module:ol/format/filter/ComparisonBinary}
* @api * @api
*/ */
const GreaterThanOrEqualTo = function(propertyName, expression) { constructor(propertyName, expression) {
ComparisonBinary.call(this, 'PropertyIsGreaterThanOrEqualTo', propertyName, expression); super('PropertyIsGreaterThanOrEqualTo', propertyName, expression);
}; }
}
inherits(GreaterThanOrEqualTo, ComparisonBinary);
export default GreaterThanOrEqualTo; export default GreaterThanOrEqualTo;

View File

@@ -1,27 +1,25 @@
/** /**
* @module ol/format/filter/Intersects * @module ol/format/filter/Intersects
*/ */
import {inherits} from '../../util.js';
import Spatial from '../filter/Spatial.js'; import Spatial from '../filter/Spatial.js';
/** /**
* @classdesc * @classdesc
* Represents a `<Intersects>` operator to test whether a geometry-valued property * Represents a `<Intersects>` operator to test whether a geometry-valued property
* intersects a given geometry. * intersects a given geometry.
* */
* @constructor class Intersects extends Spatial {
/**
* @param {!string} geometryName Geometry name to use. * @param {!string} geometryName Geometry name to use.
* @param {!module:ol/geom/Geometry} geometry Geometry. * @param {!module:ol/geom/Geometry} geometry Geometry.
* @param {string=} opt_srsName SRS name. No srsName attribute will be * @param {string=} opt_srsName SRS name. No srsName attribute will be
* set on geometries when this is not provided. * set on geometries when this is not provided.
* @extends {module:ol/format/filter/Spatial}
* @api
*/ */
const Intersects = function(geometryName, geometry, opt_srsName) { constructor(geometryName, geometry, opt_srsName) {
super('Intersects', geometryName, geometry, opt_srsName);
}
Spatial.call(this, 'Intersects', geometryName, geometry, opt_srsName); }
};
inherits(Intersects, Spatial);
export default Intersects; export default Intersects;

View File

@@ -1,22 +1,22 @@
/** /**
* @module ol/format/filter/IsBetween * @module ol/format/filter/IsBetween
*/ */
import {inherits} from '../../util.js';
import Comparison from '../filter/Comparison.js'; import Comparison from '../filter/Comparison.js';
/** /**
* @classdesc * @classdesc
* Represents a `<PropertyIsBetween>` comparison operator. * Represents a `<PropertyIsBetween>` comparison operator.
* */
* @constructor class IsBetween extends Comparison {
/**
* @param {!string} propertyName Name of the context property to compare. * @param {!string} propertyName Name of the context property to compare.
* @param {!number} lowerBoundary The lower bound of the range. * @param {!number} lowerBoundary The lower bound of the range.
* @param {!number} upperBoundary The upper bound of the range. * @param {!number} upperBoundary The upper bound of the range.
* @extends {module:ol/format/filter/Comparison}
* @api * @api
*/ */
const IsBetween = function(propertyName, lowerBoundary, upperBoundary) { constructor(propertyName, lowerBoundary, upperBoundary) {
Comparison.call(this, 'PropertyIsBetween', propertyName); super('PropertyIsBetween', propertyName);
/** /**
* @type {!number} * @type {!number}
@@ -27,7 +27,8 @@ const IsBetween = function(propertyName, lowerBoundary, upperBoundary) {
* @type {!number} * @type {!number}
*/ */
this.upperBoundary = upperBoundary; this.upperBoundary = upperBoundary;
};
inherits(IsBetween, Comparison); }
}
export default IsBetween; export default IsBetween;

View File

@@ -1,14 +1,16 @@
/** /**
* @module ol/format/filter/IsLike * @module ol/format/filter/IsLike
*/ */
import {inherits} from '../../util.js';
import Comparison from '../filter/Comparison.js'; import Comparison from '../filter/Comparison.js';
/** /**
* @classdesc * @classdesc
* Represents a `<PropertyIsLike>` comparison operator. * Represents a `<PropertyIsLike>` comparison operator.
* */
* @constructor class IsLike extends Comparison {
/**
* [constructor description]
* @param {!string} propertyName Name of the context property to compare. * @param {!string} propertyName Name of the context property to compare.
* @param {!string} pattern Text pattern. * @param {!string} pattern Text pattern.
* @param {string=} opt_wildCard Pattern character which matches any sequence of * @param {string=} opt_wildCard Pattern character which matches any sequence of
@@ -18,11 +20,10 @@ import Comparison from '../filter/Comparison.js';
* @param {string=} opt_escapeChar Escape character which can be used to escape * @param {string=} opt_escapeChar Escape character which can be used to escape
* the pattern characters. Default is '!'. * the pattern characters. Default is '!'.
* @param {boolean=} opt_matchCase Case-sensitive? * @param {boolean=} opt_matchCase Case-sensitive?
* @extends {module:ol/format/filter/Comparison}
* @api * @api
*/ */
const IsLike = function(propertyName, pattern, opt_wildCard, opt_singleChar, opt_escapeChar, opt_matchCase) { constructor(propertyName, pattern, opt_wildCard, opt_singleChar, opt_escapeChar, opt_matchCase) {
Comparison.call(this, 'PropertyIsLike', propertyName); super('PropertyIsLike', propertyName);
/** /**
* @type {!string} * @type {!string}
@@ -48,7 +49,8 @@ const IsLike = function(propertyName, pattern, opt_wildCard, opt_singleChar, opt
* @type {boolean|undefined} * @type {boolean|undefined}
*/ */
this.matchCase = opt_matchCase; this.matchCase = opt_matchCase;
};
inherits(IsLike, Comparison); }
}
export default IsLike; export default IsLike;

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