Compare commits

..

243 Commits

Author SHA1 Message Date
Tim Schaub
a9b62af3fc Merge pull request #6232 from openlayers/release-v3.20.0
Release v3.20.0
2016-12-10 13:10:00 -07:00
Tim Schaub
53473ddeb1 Add note about WebGL rendering 2016-12-10 12:50:06 -07:00
Tim Schaub
49b3359aa8 Update package version to 3.20.0 2016-12-10 12:24:34 -07:00
Tim Schaub
b21944fb50 Changelog for v3.20.0 2016-12-10 12:24:02 -07:00
Tim Schaub
4db2177c1d Merge pull request #6230 from tschaub/attribution-ignore-duplicates
Ignore duplicated attributions
2016-12-10 11:50:54 -07:00
Tim Schaub
bb62360213 Create a lookup of unique attributions 2016-12-10 11:36:27 -07:00
Andreas Hocevar
adacfb6453 Add test for duplicated attribution 2016-12-10 11:31:22 -07:00
Attila Berényi
bedda42c3e Ignore duplicate attributions.
See https://github.com/openlayers/ol3/issues/5297
2016-12-10 11:31:05 -07:00
Tim Schaub
862152f9db Merge pull request #6192 from tchandelle/delete-vertex
Modify interaction: always stop event propagation when removing vertex
2016-12-10 11:18:37 -07:00
Tim Schaub
da419ffc6c Merge pull request #6228 from tschaub/rename-example
Rename the pinch zoom example
2016-12-09 12:42:49 -07:00
Andreas Hocevar
676b3efbd7 Merge pull request #6229 from openlayers/greenkeeper-phantomjs-prebuilt-2.1.14
Update phantomjs-prebuilt to version 2.1.14 🚀
2016-12-09 20:35:47 +01:00
greenkeeperio-bot
f0dc965974 chore(package): update phantomjs-prebuilt to version 2.1.14
https://greenkeeper.io/
2016-12-09 10:44:14 -07:00
Tim Schaub
1f742da046 Merge pull request #6196 from raiyni/ExtendedData
KML ExtendedData Export
2016-12-09 10:41:33 -07:00
Tim Schaub
a2fc950b44 Merge pull request #6227 from openlayers/greenkeeper-eslint-3.12.0
Update eslint to version 3.12.0 🚀
2016-12-09 10:33:07 -07:00
Tim Schaub
2bb61dab60 Example wording 2016-12-09 10:32:06 -07:00
Tim Schaub
8d5042c1b1 Dash as word separators in URLs for consistency 2016-12-09 10:24:55 -07:00
Tim Schaub
4ff87a0eef Merge pull request #6224 from aAXEe/pinZoom-allowFractionalZoom
Pinch zoom: allow fractional zoom
2016-12-09 10:22:05 -07:00
greenkeeperio-bot
403bc4bbe1 chore(package): update eslint to version 3.12.0
https://greenkeeper.io/
2016-12-09 10:15:41 -07:00
Axel Utech
61ac0c47ed add an upgrade note about the new pinchZoom behavior 2016-12-09 18:03:20 +01:00
Axel Utech
f5a27d2788 add a pinchZoom example demonstrating the old behavior with constrained zooms 2016-12-09 18:03:01 +01:00
Axel Utech
321b1f72ad add an option to make the pinchZoom constrain zoom levels to integers
Changes the default behavior of ol.interaction.PinchZoom to keep
the fractional zoom level after the gesture.
The old behavior of zooming to the next whole-number level can be
enforced with the new parameter `constrainResolution`.
2016-12-09 18:02:36 +01:00
Tim Schaub
fbbc42f8f9 Merge pull request #6226 from tchandelle/doc-anchors
Improve the headers styles in the api doc
2016-12-09 09:42:38 -07:00
Andreas Hocevar
26f31e3771 Merge pull request #5995 from KlausBenndorf/hitTolerance
Add hit tolerance parameter to ol.Map#forEachFeatureAtPixel
2016-12-08 11:06:46 +01:00
simonseyock
f28e0ebc1f Added hitTolerance parameter to reworked files 2016-12-08 10:21:57 +01:00
simonseyock
f10ae6c474 Adressed review.
Reusing transform
Changing either size of the canvas or clearing it
adding unit of hitTolerance to jsdoc
2016-12-08 10:14:36 +01:00
simonseyock
55ec0af072 Simplified api 2016-12-08 10:14:36 +01:00
simonseyock
8edc2be103 Added hitTolerance to TranslateInteraction 2016-12-08 10:14:09 +01:00
simonseyock
a469803941 adjusted hitTolerance by pixelRatio 2016-12-08 10:14:09 +01:00
simonseyock
00a4f3b410 buffering extent by resolution*hitTolerance 2016-12-08 10:14:09 +01:00
simonseyock
f6ee11bb68 Documentation and linting 2016-12-08 10:14:09 +01:00
simonseyock
eede027417 Added buffer to ol.renderer.canvas.VectorTileLayer#forEachFeatureAtCoordinate
buffering by pointResolution times hitTolerance
2016-12-08 10:14:09 +01:00
simonseyock
3a08cfd7c6 Added test for ol.render.canvas.ReplayGroup#getCircleArray_ 2016-12-08 10:14:09 +01:00
simonseyock
e9d2b913ea removed uses of lazy evaluation of || 2016-12-08 10:14:09 +01:00
simonseyock
4640c44f2a Added old syntax and hasFeatureAtPixel to changelog 2016-12-08 10:14:09 +01:00
simonseyock
c93b0ba859 Added upgrade note 2016-12-08 10:14:09 +01:00
simonseyock
5608e7284b Renamed FeatureAtPixelOptions to AtPixelOptions for future use in forEachLayerAtPixel 2016-12-08 10:14:09 +01:00
simonseyock
f0439685ad minor typos 2016-12-08 10:14:09 +01:00
simonseyock
da020d77e9 Added cache for circle arrays. Reusing context. 2016-12-08 10:14:09 +01:00
simonseyock
e0edefb4d7 Added hitTolerance to select interaction. Added hitTolerance to select interaction example. 2016-12-08 10:14:09 +01:00
simonseyock
2ea41afe6e Added hitTolerance to hasFeatureAtPixel. Corrected JsDoc problems. 2016-12-08 10:14:09 +01:00
simonseyock
63f57768a3 Removed olx.LayerFilter 2016-12-08 10:14:09 +01:00
simonseyock
80e392ea52 Satisfying linter, jsdoc & compiler 2016-12-08 10:14:09 +01:00
simonseyock
2493eb2c20 Implemented midpoint circle algorithm 2016-12-08 10:13:47 +01:00
simonseyock
5ce0d8aa2a changed signature of internal methods 2016-12-08 10:13:47 +01:00
simonseyock
80188b2044 Change signature of api methods 2016-12-08 10:12:42 +01:00
simonseyock
a6c768ae07 Make forEachFeatureAtCoordinate work with variable hitContext size 2016-12-08 10:12:42 +01:00
simonseyock
85893646c4 Added hitTolerance test 2016-12-08 10:12:42 +01:00
Frédéric Junod
e95778e47f Merge pull request #6220 from fredj/collection_push_length
Fix ol.Collection#push return value
2016-12-08 08:26:31 +01:00
Frédéric Junod
000453a0e1 Merge pull request #6213 from drnextgis/preload
Add preload option to olx.layer.VectorTileOptions
2016-12-08 08:25:56 +01:00
Andreas Hocevar
0061b15a91 Merge pull request #6222 from ahocevar/fix-foreachlayeratpixel
Fix forEachLayerAtPixel and improve class hierarchy
2016-12-07 22:29:05 +01:00
Andreas Hocevar
d854222c4b Fix forEachLayerAtPixel and improve class hierarchy 2016-12-07 19:39:52 +01:00
Marc Jansen
f795019215 Merge pull request #6075 from tchandelle/modify_stride
Keep the other dim from the original segment when modifying vertex
2016-12-07 19:22:59 +01:00
Frederic Junod
5e0ce08804 Fix ol.Collection#push return value 2016-12-07 15:11:31 +01:00
Frédéric Junod
10e36a0529 Merge pull request #6218 from gberaudo/modify_interaction_check_map_rendered
Make modify interaction more robust
2016-12-07 12:14:05 +01:00
Guillaume Beraudo
109e6a8324 Make modify interaction more robust
When the map has not been rendered yet, adding a feature should not
trigger coordinate related functions as they make use of the framestate.
2016-12-07 11:15:28 +01:00
drnextgis
f492d69691 Add preload option to olx.layer.VectorTileOptions 2016-12-07 10:22:13 +07:00
Tim Schaub
59e802737e Merge pull request #6205 from tschaub/no-extra-provides
Rework remaining modules with multiple provides
2016-12-06 17:46:44 -07:00
Tim Schaub
63e952a91a Treat one-provide violations as errors 2016-12-06 14:50:35 -07:00
Tim Schaub
041766d53c Reworked mapbrowser* things 2016-12-06 14:49:43 -07:00
Tim Schaub
57e3e7273e Add Property enum to ol.layer.Base 2016-12-06 14:49:43 -07:00
Tim Schaub
66dc2582ef Dedicated module for GeometryLayout 2016-12-06 14:49:43 -07:00
Tim Schaub
7858b68fc0 Dedicated module for GeometryType enum 2016-12-06 14:49:43 -07:00
Tim Schaub
c00906cde9 Add Event to ol.Object 2016-12-06 14:49:43 -07:00
Tim Schaub
daba1fbcb6 Add EventType enum to ol.Object 2016-12-06 14:49:43 -07:00
Tim Schaub
3d2f677f2a Add OperationType enum to ol.source.Raster 2016-12-06 14:49:43 -07:00
Tim Schaub
c0fe3f1e4f Dedicated module for ol.extent.Relationship enum 2016-12-06 14:49:43 -07:00
Tim Schaub
780bb1b30d Dedicated module for ol.extent.Corner enum 2016-12-06 14:49:43 -07:00
Tim Schaub
82c0dcdc00 Merge pull request #6207 from tschaub/require-all
Require all when generating exports
2016-12-06 14:41:02 -07:00
Tim Schaub
fc8915d8b7 Merge pull request #6204 from tschaub/proj
Refactored proj modules
2016-12-06 14:38:35 -07:00
Andreas Hocevar
db5032af49 Merge pull request #6209 from ahocevar/not-to-be
Test array with to.eql(), not to.be.eql()
2016-12-06 16:25:08 +01:00
Andreas Hocevar
132be598e7 Test array with to.eql(), not to.be.eql() 2016-12-06 16:03:35 +01:00
Andreas Hocevar
89ebf0a182 Merge pull request #6091 from tchandelle/linedash
Apply pixelRatio to line dash
2016-12-06 15:53:23 +01:00
Andreas Hocevar
621589b318 Merge pull request #6082 from ahocevar/unified-canvas-rendering
Unified canvas rendering
2016-12-06 08:59:40 +01:00
Andreas Hocevar
93d86e63fc Defer frame preparation when too much time was spent 2016-12-06 08:51:55 +01:00
Andreas Hocevar
ee7b894350 Refactor VectorTile renderer and add lower resolution clipping 2016-12-06 08:51:55 +01:00
Andreas Hocevar
0d65d1d813 Remove support for skipped features 2016-12-06 08:47:41 +01:00
Andreas Hocevar
2aa4f0c01c Fix forEachLayerAtPixel for the canvas renderer 2016-12-06 08:47:41 +01:00
Andreas Hocevar
ccdb955cd9 Simplify canvas tile renderer with image composition 2016-12-06 08:47:40 +01:00
Tim Schaub
f898a3b182 Merge pull request #6173 from bjornharrtell/topolis
Topolis example
2016-12-05 18:11:20 -07:00
Tim Schaub
c8064d15b7 Merge pull request #6206 from tschaub/zero
Stop asserting that zero duration animations take time
2016-12-05 08:59:05 -07:00
Thomas Chandelle
3b64133f21 Add tests for linedash for HiDPI display 2016-12-05 09:26:06 +01:00
Thomas Chandelle
7ee04ec200 Compare current linedash and new linedash as arrays 2016-12-05 09:24:13 +01:00
Thomas Chandelle
a0e310700c Apply pixelRatio to line dash 2016-12-05 09:24:13 +01:00
Tim Schaub
99eddbb31f Require all when generating exports 2016-12-04 16:43:15 -07:00
Tim Schaub
dfbc7bb743 Stop dividing by zero 2016-12-04 15:10:53 -07:00
Tim Schaub
12add87603 Stop asserting that zero duration animations take time 2016-12-04 15:04:54 -07:00
Tim Schaub
6259caf634 Consistently return a function or undefined 2016-12-04 12:58:33 -08:00
Tim Schaub
6d22119425 One provide per proj module 2016-12-04 12:44:04 -08:00
Tim Schaub
08569d4eb3 Dedicated module for ol.proj.Projection 2016-12-04 12:41:04 -08:00
Tim Schaub
a33caa598c Dedicated module for proj4 access 2016-12-04 10:37:33 -08:00
Tim Schaub
b54342dfb8 Dedicated module for projections cache 2016-12-04 10:24:43 -08:00
Tim Schaub
679fe298aa Dedicated module for transforms cache 2016-12-04 10:09:32 -08:00
Tim Schaub
fd6116ab6b Dedicated module for ol.proj.Units 2016-12-04 09:17:24 -08:00
Tim Schaub
f6a3ec513e Merge pull request #6203 from tschaub/missing-requires
Address a few missing requires
2016-12-04 10:11:28 -07:00
Tim Schaub
ab640a20d0 Move CLONE_PROPS to ol.pointer.PointerEventHandler 2016-12-03 10:48:32 -08:00
Tim Schaub
fda2d8e40e Functions in ol.geom.flat.interpolate namespace 2016-12-03 10:45:52 -08:00
Tim Schaub
37c445275f Require ol.MapBrowserEvent 2016-12-03 10:37:49 -08:00
Tim Schaub
e87407c28f Merge pull request #6201 from tschaub/arcgis-fix
Remove assertion in TileArcGISRest source
2016-12-03 10:29:07 -08:00
Tim Schaub
a3f3c24c51 Merge pull request #6202 from tschaub/animate-zero
Allow animation duration to be zero
2016-12-03 10:28:18 -08:00
Tim Schaub
c04a011077 Merge pull request #6198 from oterral/flyTo
Fix sourceResolution value in view.animate
2016-12-02 23:07:30 -08:00
Tim Schaub
dfb4c800b9 Allow animation duration to be zero 2016-12-02 19:15:34 -08:00
Tim Schaub
fdec14c425 Merge pull request #6177 from tchandelle/fit-animations
Add duration and easing options to view.fit() for animations
2016-12-02 19:09:08 -08:00
Tim Schaub
ce8cf27ad3 Remove assertion 2016-12-02 15:22:10 -08:00
oterral
9eda6df821 Fix sourceResolution value in view.animate 2016-12-02 16:39:25 +01:00
Ron Young
85881082b0 use feature geometry in filter 2016-12-01 21:38:13 -06:00
Ron Young
fdff4c5c7c export ExtendedData tests 2016-12-01 21:11:13 -06:00
Ron Young
aa08f88105 node factories, serializers, and writers for exporing ExtendedData 2016-12-01 21:10:07 -06:00
Ron Young
cde48521d0 add ol.format.XSD CDATA writer 2016-12-01 20:33:47 -06:00
Marc Jansen
bdeaafcdf7 Merge pull request #6078 from bjornharrtell/windingnumber
Use winding number algorithm for linearRingContainsXY
2016-12-01 13:46:07 +01:00
Thomas Chandelle
510076290d Always stop event propagation when removing vertex 2016-12-01 10:27:47 +01:00
Andreas Hocevar
9dc300d520 Merge pull request #6187 from openlayers/greenkeeper-pbf-3.0.5
Update pbf to version 3.0.5 🚀
2016-11-30 16:25:13 +01:00
greenkeeperio-bot
5c0a6de288 chore(package): update pbf to version 3.0.5
https://greenkeeper.io/
2016-11-30 06:35:35 -08:00
Thomas Chandelle
b77b5e5a55 Replace the anchor by an empty div element 2016-11-29 17:00:29 +01:00
Andreas Hocevar
794628782c Merge pull request #6175 from tchandelle/projection-perf
Generate projection transform function only when requested
2016-11-29 13:21:11 +01:00
Andreas Hocevar
fe758c2606 Simplify and make the compiler happy 2016-11-29 12:14:11 +01:00
Andreas Hocevar
c03f19bf5c Merge pull request #6181 from ahocevar/bing-key
Replace expired Bing key with a new one
2016-11-29 11:41:06 +01:00
Andreas Hocevar
d9453890eb Replace expired Bing key with a new one 2016-11-29 11:31:17 +01:00
Marc Jansen
4dc828c691 Merge pull request #6164 from marcjansen/color-parsing
Simplify color parsing and allow more decimals
2016-11-29 11:03:22 +01:00
Marc Jansen
88cfdb435c Use indexOf instead of RegExp as suggested 2016-11-29 10:55:04 +01:00
Björn Harrtell
656af72615 Use winding number algorithm for linearRingContainsXY 2016-11-29 09:10:47 +01:00
Björn Harrtell
6c644186ba Add test case for ol.geom.flat.contains 2016-11-29 09:07:10 +01:00
Frédéric Junod
51f7bfb415 Merge pull request #6178 from fredj/missing_require
Add missing goog.require
2016-11-29 08:20:57 +01:00
Andreas Hocevar
8f7aee4847 Merge pull request #6176 from tchandelle/animation-easing
Doc: easing option is optional
2016-11-28 19:28:08 +01:00
Andreas Hocevar
8c6437fba5 Merge pull request #6180 from openlayers/greenkeeper-eslint-3.11.1
Update eslint to version 3.11.1 🚀
2016-11-28 19:27:33 +01:00
greenkeeperio-bot
65c89199f1 chore(package): update eslint to version 3.11.1
https://greenkeeper.io/
2016-11-28 10:33:30 -07:00
Frédéric Junod
9ef0434be2 Merge pull request #6179 from fredj/rm_unused
Remove unused ol.Map.removePreRenderFunction function
2016-11-28 16:53:15 +01:00
Frederic Junod
59b8d969d6 Remove unused ol.Map.removePreRenderFunction function
The function is no longer used after #6079
2016-11-28 14:02:42 +01:00
Thomas Chandelle
5b04771d3f Add duration and easing options to view.fit() for animations 2016-11-28 13:55:40 +01:00
Frederic Junod
1b6c239114 Add missing goog.require 2016-11-28 13:46:26 +01:00
Thomas Chandelle
c4af981b01 easing option is optional
jsdoc was probably interpreting function(number):number|undefined as
a function that returns a number or undefined.
2016-11-28 13:07:02 +01:00
Thomas Chandelle
c898cda2e6 Generate projection transform function only when requested 2016-11-28 09:50:41 +01:00
Bart van den Eijnden
d47e5aed10 Merge pull request #6052 from oterral/teo_dflt_style
Remove the use of ol.format.KML.DEFAULT_IMAGE_SCALE_MULTIPLIER_ when …
2016-11-28 09:38:10 +01:00
Björn Harrtell
7ad519fbf3 Topolis example 2016-11-27 00:46:25 +01:00
Frédéric Junod
8fe783d975 Merge pull request #6159 from tchandelle/examples-require-carriage-return
Remove carriage return after goog.require in examples
2016-11-25 13:20:15 +01:00
Frédéric Junod
15769101af Merge pull request #6169 from tchandelle/image-rotation-webgl
Image rotation in WebGL was anti-clockwise
2016-11-25 10:18:10 +01:00
Tobias Sauerwein
0e95905c6f Merge pull request #5590 from thhomas/kml-region-extendeddata
Kml format: improved support for region and extendeddata
2016-11-25 09:33:46 +01:00
Thomas Chandelle
9ffa103a79 Image rotation in WebGL was anti-clockwise 2016-11-25 09:02:20 +01:00
Marc Jansen
7f0d914161 Merge pull request #5462 from GaborFarkas/webgl_vector
WebGL vector support
2016-11-25 09:01:10 +01:00
Frédéric Junod
66a55d126b Merge pull request #6168 from openlayers/greenkeeper-mocha-3.2.0
Update mocha to version 3.2.0 🚀
2016-11-25 08:45:26 +01:00
greenkeeperio-bot
d5c7692a96 chore(package): update mocha to version 3.2.0
https://greenkeeper.io/
2016-11-24 17:34:54 -07:00
Bart van den Eijnden
3e31ff113b Merge pull request #5589 from thhomas/wmts-tilematrixlimits
Wmts tilematrixlimits
2016-11-24 10:14:25 +01:00
Thomas Tilak
1f04a0aad9 adds TileMatrixSetLimits to WMTS format reader
enhance wmtstilegrid to use it when building matrixId and resolution arrays
2016-11-23 18:50:24 +01:00
Thomas Tilak
d2e3017088 improve kml parsing of <Region> and <ExtendedData> tags 2016-11-23 17:46:04 +01:00
Marc Jansen
02d41caa8a Simplify color parsing and allow more decimals 2016-11-23 16:06:08 +01:00
GaborFarkas
dba0934112 Refactor LineString GLSL & clean up 2016-11-23 10:14:20 +01:00
GaborFarkas
d27591dea7 Adjust WebGL immediate test 2016-11-23 09:51:38 +01:00
GaborFarkas
0f204641e3 Clean up GLSLs somewhat 2016-11-23 09:51:37 +01:00
GaborFarkas
02461b3416 Add no-op WebGL text replay 2016-11-23 09:51:37 +01:00
GaborFarkas
3e56dba1b4 Do not draw vectors outside viewport 2016-11-23 09:51:37 +01:00
GaborFarkas
3b2ff5a2ee Revamp WebGL CircleReplay 2016-11-23 09:51:37 +01:00
GaborFarkas
efbc4ead8d Minor fixes according to review 2016-11-23 09:51:37 +01:00
GaborFarkas
dd905ffb5b Cleanup and fix DPR in WebGL CircleReplay 2016-11-23 09:51:37 +01:00
GaborFarkas
a7ddda7d81 Force close polygon contours (WebGL) 2016-11-23 09:51:37 +01:00
GaborFarkas
ca1414b2d0 Add depth test to PolygonReplay 2016-11-23 09:51:37 +01:00
GaborFarkas
310fabe94a Add tests for WebGL Immediate API 2016-11-23 09:51:37 +01:00
GaborFarkas
0c45b52a7a Add functions to WebGL Immediate API 2016-11-23 09:51:37 +01:00
GaborFarkas
8a6b206220 Add more tests 2016-11-23 09:51:37 +01:00
GaborFarkas
0cb0ea2a8a Add tests for ol.render.webgl.CircleReplay 2016-11-23 09:51:37 +01:00
GaborFarkas
c675a33235 Add tests for ol.render.webgl.Replay 2016-11-23 09:51:37 +01:00
GaborFarkas
62fb8d8fd8 Fix typos 2016-11-23 09:51:37 +01:00
GaborFarkas
36df9a9c09 Add missing requires 2016-11-23 09:51:37 +01:00
GaborFarkas
dc360c2d7f Refactor WebGL render tests 2016-11-23 09:51:37 +01:00
GaborFarkas
763bbca549 Fix skipping replay 2016-11-23 09:51:37 +01:00
GaborFarkas
697cbf16f0 Fix some rendering issues with complex styling 2016-11-23 09:51:37 +01:00
GaborFarkas
dd7e49c217 Fix canvas cricle test 2016-11-23 09:51:37 +01:00
GaborFarkas
58afee6706 Clean up polygon replay GLSL 2016-11-23 09:51:37 +01:00
GaborFarkas
ac6408be3b Add circle replay to WebGL renderer 2016-11-23 09:51:36 +01:00
GaborFarkas
86c914f3df Fix glitched lines with rotated view 2016-11-23 09:51:36 +01:00
GaborFarkas
5fb0a84579 Fix WebGL PolygonReplay#bridgeHole_ 2016-11-23 09:51:36 +01:00
GaborFarkas
a002474761 Fix typo in polygon rendering test 2016-11-23 09:51:36 +01:00
GaborFarkas
e124b34b24 Correctly draw polygons with transparent border 2016-11-23 09:51:36 +01:00
GaborFarkas
3af5c2805e Add tests to WebGL triangulating functions 2016-11-23 09:51:36 +01:00
GaborFarkas
004c0f7e27 Fix WebGL PolygonReplay#getPointsInTriangle_ 2016-11-23 09:51:36 +01:00
GaborFarkas
0c3d5eca5c Add tests for the linked list struct 2016-11-23 09:51:36 +01:00
GaborFarkas
71d790ccfd Add zIndex support to WebGL renderer 2016-11-23 09:51:36 +01:00
GaborFarkas
8e8098b362 Add some test to PolygonReplay 2016-11-23 09:51:36 +01:00
GaborFarkas
5cf2e9c072 Add shutdown methods to replays 2016-11-23 09:51:36 +01:00
GaborFarkas
360e77481d Restructure webgl replays 2016-11-23 09:51:36 +01:00
GaborFarkas
dc27f768d0 Correctly triangulate simple polygons. 2016-11-23 09:51:36 +01:00
GaborFarkas
a0089b5126 Correctly triangulate bad polygons. 2016-11-23 09:51:36 +01:00
GaborFarkas
657f2c7b6c Optimize processing flat coordinates 2016-11-23 09:51:36 +01:00
GaborFarkas
5d65028d26 Initial ear clipping algorithm 2016-11-23 09:51:33 +01:00
GaborFarkas
88f7e7a38d Utilities for polygon renderer 2016-11-23 09:49:48 +01:00
GaborFarkas
610084d456 Linked list structure for polygon renderer 2016-11-23 09:49:48 +01:00
GaborFarkas
18bc820f8b Prevent overdraw in PolygonReplay. 2016-11-23 09:49:48 +01:00
GaborFarkas
4b2fb38954 Fix preparation of multipolygons with holes. 2016-11-23 09:49:48 +01:00
GaborFarkas
226bf5a9ea Allow empty fillStyle for polygons. 2016-11-23 09:49:48 +01:00
GaborFarkas
16a50ee0c7 Extend PolygonReplay with hit detection and skipping. 2016-11-23 09:49:48 +01:00
GaborFarkas
ce3b286cd3 RTE correct only once. 2016-11-23 09:49:48 +01:00
GaborFarkas
112fae228a Sanity check fill colors. 2016-11-23 09:49:48 +01:00
GaborFarkas
18cf6c30bd Add basic polygon renderer. 2016-11-23 09:49:48 +01:00
GaborFarkas
269c3eb943 Set WebGL LineString threshold to 14.6
This commit will be a fixup for the previous one, or get deleted eventually.
2016-11-23 09:49:48 +01:00
GaborFarkas
e893603966 Add tests to LineStringReplay 2016-11-23 09:49:47 +01:00
GaborFarkas
638b7752fa Fix bugs in LineStringReplay. 2016-11-23 09:49:47 +01:00
GaborFarkas
f96a4a7301 Properly handle zeros in stroke style. 2016-11-23 09:49:47 +01:00
GaborFarkas
1c7203a203 Add skipping capability to LineStringReplay 2016-11-23 09:49:47 +01:00
GaborFarkas
48d3bfe297 Take line width into account when forming miters. 2016-11-23 09:49:47 +01:00
GaborFarkas
16dfc5dfba Adjust replays to new version. 2016-11-23 09:49:47 +01:00
GaborFarkas
c966e21e40 Fix black canvas when image is missing 2016-11-23 09:49:47 +01:00
GaborFarkas
2415050500 Add hit detection support to LineStringReplay
Also, making it more consistent with ImageReplay
2016-11-23 09:49:47 +01:00
GaborFarkas
b7396b0b94 Improve code quality
Cleaning up, making the code more consistent, and restructuring commonly used methods.
2016-11-23 09:49:47 +01:00
GaborFarkas
3897312af6 Add full support to different styles in one layer. 2016-11-23 09:49:47 +01:00
GaborFarkas
9d6a860cd1 Fix overdraw issue with Firefox
As usual, Firefox is the good guy here, too, and this is an issue with Chrome
2016-11-23 09:49:47 +01:00
GaborFarkas
4d8777220a Fix compiler and compiled lib related problems. 2016-11-23 09:49:47 +01:00
GaborFarkas
b0d11391b2 Fix rounding problems
Fragment shader does not know about the projection matrix, thus it has to take the pixel ratio into account.
2016-11-23 09:49:47 +01:00
GaborFarkas
249084dcd4 Eliminate overdraw with a nice little trick 2016-11-23 09:49:47 +01:00
GaborFarkas
c9c970303f Handling sharp angles in linestring GLSL 2016-11-23 09:49:47 +01:00
GaborFarkas
3f828248b9 Rework isClosed with added tests 2016-11-23 09:49:47 +01:00
GaborFarkas
e64549c50c Fix weird behaviour of boundaries
With drawElements, it seems like we cannot connect an old index with a much fresher one, as it will produce weird errors.
2016-11-23 09:49:47 +01:00
GaborFarkas
4be8de62ae Refactor linestring geom validation
Now it only focuses on issues not addressed by ol.geom.flat.simplify methods.
2016-11-23 09:49:47 +01:00
GaborFarkas
f15a9652d8 Fix rendering of boundaries. 2016-11-23 09:49:47 +01:00
GaborFarkas
eba006b796 Falling back to bevel when exceeding miterLimit 2016-11-23 09:49:47 +01:00
GaborFarkas
8c561a45b9 Inspect linestring validity before drawing 2016-11-23 09:49:46 +01:00
GaborFarkas
99e4009b19 Minor improvements
ol.render.webgl.LineStringReplay.startIndices_ is initialized with a 0, and the end index of a valid line is added in every valid iteration.

drawElements_ is refactored for a clearer code.
2016-11-23 09:49:46 +01:00
GaborFarkas
e2ec6d0b82 Adding support for closed lines 2016-11-23 09:49:46 +01:00
GaborFarkas
0f8e1a7e40 Refactoring ol.render.webgl.LineStringReplay 2016-11-23 09:49:46 +01:00
GaborFarkas
c13d09ba23 Handle case of one segment lines with identical coordinates + quality improvements 2016-11-23 09:49:46 +01:00
GaborFarkas
fb71860a03 Adding linestring cap support 2016-11-23 09:49:46 +01:00
GaborFarkas
350d1add81 Change goog.base to call, and goog.inherits to ol.inherits 2016-11-23 09:49:46 +01:00
GaborFarkas
0972988bdb Properly triangulate linestrings 2016-11-23 09:49:46 +01:00
GaborFarkas
c7edd21cc3 Extend linestring renderer with GLSL and indexed geometries. 2016-11-23 09:49:46 +01:00
GaborFarkas
caeb8e4820 Eliminating jitter by restructuring 2016-11-23 09:49:46 +01:00
GaborFarkas
6e958514ee Taking line width into account 2016-11-23 09:49:46 +01:00
GaborFarkas
628db9146d Creating a webgl.Replay struct, making the WebGL LineString renderer compilable 2016-11-23 09:49:46 +01:00
GaborFarkas
f5978c659c Adding some defaults 2016-11-23 09:49:46 +01:00
GaborFarkas
a6ddee0c5f Updating old code to current ol3 version 2016-11-23 09:49:46 +01:00
GaborFarkas
a052b645df Fix dependencies 2016-11-23 09:49:46 +01:00
Guillaume Beraudo
e40b545e40 Add basic WEBGL LineString rendering
Use gl.LINES and hardcode a width.
Implement polygon stroking using the line string replay.
2016-11-23 09:49:46 +01:00
Guillaume Beraudo
8e9b589ca9 Add tests to PolygonReplay renderer 2016-11-23 09:49:46 +01:00
Guillaume Beraudo
581ea8c775 Add color to WEBGL polygons 2016-11-23 09:49:46 +01:00
Guillaume Beraudo
2519cf36fc Basic WEBGL rendering of polygons 2016-11-23 09:49:46 +01:00
Guillaume Beraudo
8bdbe7aae0 Add earcut to package.json and wrap it in ol.ext
Earcut is a library for triangulating polygons.
See https://github.com/mapbox/earcut.
2016-11-23 09:49:46 +01:00
Bart van den Eijnden
c8d35e4fb0 Merge pull request #6155 from romanzoller/gpx-geometry-layout
Set GeometryLayout correctly when reading GPX
2016-11-23 08:52:26 +01:00
Frédéric Junod
13884dac4d Merge pull request #6161 from openlayers/greenkeeper-async-2.1.4
Update async to version 2.1.4 🚀
2016-11-23 08:22:23 +01:00
greenkeeperio-bot
9a900becd3 chore(package): update async to version 2.1.4
https://greenkeeper.io/
2016-11-22 12:28:01 -07:00
Thomas Chandelle
d8c428a8a2 Remove also carriage return after goog.require in examples 2016-11-22 16:49:12 +01:00
Roman Zoller
f56b2c8a75 Set GeometryLayout correctly when reading GPX
Fixes #6148
2016-11-22 10:42:11 +01:00
Bart van den Eijnden
d759ad603a Merge pull request #6153 from romanzoller/remove-licenses
Remove legacy licenses folder
2016-11-22 09:32:11 +01:00
Andreas Hocevar
caef2b51b4 Merge pull request #6154 from openlayers/greenkeeper-mocha-phantomjs-core-2.1.0
Update mocha-phantomjs-core to version 2.1.0 🚀
2016-11-21 23:07:37 +01:00
greenkeeperio-bot
2842938514 chore(package): update mocha-phantomjs-core to version 2.1.0
https://greenkeeper.io/
2016-11-21 12:41:06 -07:00
Roman Zoller
6ce1731a03 Remove legacy licenses folder
Fixes #6152
2016-11-21 15:38:04 +01:00
Thomas Chandelle
5d61218134 Keep the other dim from the original segment when modifying vertex 2016-11-04 09:47:30 +01:00
oterral
a28576d2b9 Remove the use of ol.format.KML.DEFAULT_IMAGE_SCALE_MULTIPLIER_ when it's not wanted 2016-11-03 11:11:53 +01:00
206 changed files with 10946 additions and 3108 deletions

View File

@@ -1,6 +1,6 @@
## Upgrade notes
### Next release
### v3.20.0
#### Use `view.animate()` instead of `map.beforeRender()` and `ol.animation` functions
@@ -35,6 +35,59 @@ view.animate({
});
```
#### `ol.Map#forEachFeatureAtPixel` and `ol.Map#hasFeatureAtPixel` parameters have changed
If you are using the layer filter of one of these methods, please note that you now have to pass in the layer filter via an `ol.AtPixelOptions` object. If you are not using the layer filter the usage has not changed.
Old syntax:
```js
map.forEachFeatureAtPixel(pixel, callback, callbackThis, layerFilterFn, layerFilterThis);
map.hasFeatureAtPixel(pixel, layerFilterFn, layerFilterThis);
```
New syntax:
```js
map.forEachFeatureAtPixel(pixel, callback.bind(callbackThis), {
layerFilter: layerFilterFn.bind(layerFilterThis)
});
map.hasFeatureAtPixel(pixel, {
layerFilter: layerFilterFn.bind(layerFilterThis)
});
```
This change is due to the introduction of the `hitTolerance` parameter which can be passed in via this `ol.AtPixelOptions` object, too.
#### Use `ol.proj.getPointResolution()` instead of `projection.getPointResolution()`
The experimental `getPointResolution` method has been removed from `ol.Projection` instances. Since the implementation of this method required an inverse transform (function for transforming projected coordinates to geographic coordinates) and `ol.Projection` instances are not constructed with forward or inverse transforms, it does not make sense that a projection instance can always calculate the point resolution.
As a substitute for the `projection.getPointResolution()` function, a `ol.proj.getPointResolution()` function has been added. To upgrade, you will need to change things like this:
```js
projection.getPointResolution(resolution, point);
```
into this:
```js
ol.proj.getPointResolution(projection, resolution, point);
```
Note that if you were previously creating a projection with a `getPointResolution` function in the constructor (or calling `projection.setGetPointResolution()` after construction), this function will be used by `ol.proj.getPointResolution()`.
#### `ol.interaction.PinchZoom` no longer zooms to a whole-number zoom level after the gesture ends
The old behavior of `ol.interaction.PinchZoom` was to zoom to the next integer zoom level after the user ends the gesture.
Now the pinch zoom keeps the user selected zoom level even if it is a fractional zoom.
To get the old behavior set the new `constrainResolution` parameter to `true` like this:
```js
new ol.interaction.PinchZoom({constrainResolution: true})
```
See the new `pinch-zoom` example for a complete implementation.
### v3.19.1
#### `ol.style.Fill` with `CanvasGradient` or `CanvasPattern`

195
changelog/v3.20.0.md Normal file
View File

@@ -0,0 +1,195 @@
# v3.20.0
## Summary
The v3.20.0 release includes enhancements and fixes from 89 pull requests since the previous release.
Among the changes, take a look at the new `view.animate()` function. This replaces the previous `map.beforeRender()` and `ol.animation` functions with more intuitive view animations that allow for chaining together multiple transitions and support a callback on animation end. In addition, two or more maps that share a view will be animated together. See the upgrade notes and the animation example for more detail.
On the subject of view transitions, scrolling with a trackpad or magic mouse now transitions the view resolution smoothly. Instead of jumping to the next integer zoom level, trackpad or magic mouse scrolling can leave the view at a fractional zoom level. In line with this trackpad behavior, pinch zooming on touch devices also now leaves the view at a fractional zoom level (see the upgrade notes for an option to restore the old behavior).
On the rendering front, the Canvas renderer got another overhaul. This release brings back the strategy of rendering to a dedicated Canvas element per layer. If you were experiencing issues with gaps between tiles on rotated views or when zooming, this change should bring rendering improvements.
Also on the rendering front, @GaborFarkas completed a nearly 5 month effort to bring line and polygon support to the WebGL renderer. If you're interested in experimenting with WebGL for vector rendering, use `renderer: 'webgl'` in your map constructor.
See the full list of changes below. There are some other gems down there.
## Upgrade notes
#### Use `view.animate()` instead of `map.beforeRender()` and `ol.animation` functions
The `map.beforeRender()` and `ol.animation` functions have been deprecated in favor of a new `view.animate()` function. Use of the deprecated functions will result in a warning during development. These functions are subject to removal in an upcoming release.
For details on the `view.animate()` method, see the API docs and the view animation example. Upgrading should be relatively straightforward. For example, if you wanted to have an animated pan, zoom, and rotation previously, you might have done this:
```js
var zoom = ol.animation.zoom({
resolution: view.getResolution()
});
var pan = ol.animation.pan({
source: view.getCenter()
});
var rotate = ol.animation.rotate({
rotation: view.getRotation()
});
map.beforeRender(zoom, pan, rotate);
map.setZoom(1);
map.setCenter([0, 0]);
map.setRotation(Math.PI);
```
Now, the same can be accomplished with this:
```js
view.animate({
zoom: 1,
center: [0, 0],
rotation: Math.PI
});
```
#### `ol.Map#forEachFeatureAtPixel` and `ol.Map#hasFeatureAtPixel` parameters have changed
If you are using the layer filter of one of these methods, please note that you now have to pass in the layer filter via an `ol.AtPixelOptions` object. If you are not using the layer filter the usage has not changed.
Old syntax:
```js
map.forEachFeatureAtPixel(pixel, callback, callbackThis, layerFilterFn, layerFilterThis);
map.hasFeatureAtPixel(pixel, layerFilterFn, layerFilterThis);
```
New syntax:
```js
map.forEachFeatureAtPixel(pixel, callback.bind(callbackThis), {
layerFilter: layerFilterFn.bind(layerFilterThis)
});
map.hasFeatureAtPixel(pixel, {
layerFilter: layerFilterFn.bind(layerFilterThis)
});
```
This change is due to the introduction of the `hitTolerance` parameter which can be passed in via this `ol.AtPixelOptions` object, too.
#### Use `ol.proj.getPointResolution()` instead of `projection.getPointResolution()`
The experimental `getPointResolution` method has been removed from `ol.Projection` instances. Since the implementation of this method required an inverse transform (function for transforming projected coordinates to geographic coordinates) and `ol.Projection` instances are not constructed with forward or inverse transforms, it does not make sense that a projection instance can always calculate the point resolution.
As a substitute for the `projection.getPointResolution()` function, a `ol.proj.getPointResolution()` function has been added. To upgrade, you will need to change things like this:
```js
projection.getPointResolution(resolution, point);
```
into this:
```js
ol.proj.getPointResolution(projection, resolution, point);
```
Note that if you were previously creating a projection with a `getPointResolution` function in the constructor (or calling `projection.setGetPointResolution()` after construction), this function will be used by `ol.proj.getPointResolution()`.
#### `ol.interaction.PinchZoom` no longer zooms to a whole-number zoom level after the gesture ends
The old behavior of `ol.interaction.PinchZoom` was to zoom to the next integer zoom level after the user ends the gesture.
Now the pinch zoom keeps the user selected zoom level even if it is a fractional zoom.
To get the old behavior set the new `constrainResolution` parameter to `true` like this:
```js
new ol.interaction.PinchZoom({constrainResolution: true})
```
See the new `pinch-zoom` example for a complete implementation.
## Detailed changes
* [#6230](https://github.com/openlayers/ol3/pull/6230) - Ignore duplicated attributions ([@tschaub](https://github.com/tschaub))
* [#6192](https://github.com/openlayers/ol3/pull/6192) - Modify interaction: always stop event propagation when removing vertex ([@tchandelle](https://github.com/tchandelle))
* [#6228](https://github.com/openlayers/ol3/pull/6228) - Rename the pinch zoom example ([@tschaub](https://github.com/tschaub))
* [#6229](https://github.com/openlayers/ol3/pull/6229) - Update phantomjs-prebuilt to version 2.1.14 🚀 ([@openlayers](https://github.com/openlayers))
* [#6196](https://github.com/openlayers/ol3/pull/6196) - KML ExtendedData Export ([@raiyni](https://github.com/raiyni))
* [#6227](https://github.com/openlayers/ol3/pull/6227) - Update eslint to version 3.12.0 🚀 ([@openlayers](https://github.com/openlayers))
* [#6224](https://github.com/openlayers/ol3/pull/6224) - Pinch zoom: allow fractional zoom ([@aAXEe](https://github.com/aAXEe))
* [#6226](https://github.com/openlayers/ol3/pull/6226) - Improve the headers styles in the api doc ([@tchandelle](https://github.com/tchandelle))
* [#5995](https://github.com/openlayers/ol3/pull/5995) - Add hit tolerance parameter to ol.Map#forEachFeatureAtPixel ([@KlausBenndorf](https://github.com/KlausBenndorf))
* [#6220](https://github.com/openlayers/ol3/pull/6220) - Fix ol.Collection#push return value ([@fredj](https://github.com/fredj))
* [#6213](https://github.com/openlayers/ol3/pull/6213) - Add preload option to olx.layer.VectorTileOptions ([@drnextgis](https://github.com/drnextgis))
* [#6222](https://github.com/openlayers/ol3/pull/6222) - Fix forEachLayerAtPixel and improve class hierarchy ([@ahocevar](https://github.com/ahocevar))
* [#6075](https://github.com/openlayers/ol3/pull/6075) - Keep the other dim from the original segment when modifying vertex ([@tchandelle](https://github.com/tchandelle))
* [#6218](https://github.com/openlayers/ol3/pull/6218) - Make modify interaction more robust ([@gberaudo](https://github.com/gberaudo))
* [#6205](https://github.com/openlayers/ol3/pull/6205) - Rework remaining modules with multiple provides ([@tschaub](https://github.com/tschaub))
* [#6207](https://github.com/openlayers/ol3/pull/6207) - Require all when generating exports ([@tschaub](https://github.com/tschaub))
* [#6204](https://github.com/openlayers/ol3/pull/6204) - Refactored proj modules ([@tschaub](https://github.com/tschaub))
* [#6209](https://github.com/openlayers/ol3/pull/6209) - Test array with to.eql(), not to.be.eql() ([@ahocevar](https://github.com/ahocevar))
* [#6091](https://github.com/openlayers/ol3/pull/6091) - Apply pixelRatio to line dash ([@tchandelle](https://github.com/tchandelle))
* [#6082](https://github.com/openlayers/ol3/pull/6082) - Unified canvas rendering ([@ahocevar](https://github.com/ahocevar))
* [#6173](https://github.com/openlayers/ol3/pull/6173) - Topolis example ([@bjornharrtell](https://github.com/bjornharrtell))
* [#6206](https://github.com/openlayers/ol3/pull/6206) - Stop asserting that zero duration animations take time ([@tschaub](https://github.com/tschaub))
* [#6203](https://github.com/openlayers/ol3/pull/6203) - Address a few missing requires ([@tschaub](https://github.com/tschaub))
* [#6201](https://github.com/openlayers/ol3/pull/6201) - Remove assertion in TileArcGISRest source ([@tschaub](https://github.com/tschaub))
* [#6202](https://github.com/openlayers/ol3/pull/6202) - Allow animation duration to be zero ([@tschaub](https://github.com/tschaub))
* [#6198](https://github.com/openlayers/ol3/pull/6198) - Fix sourceResolution value in view.animate ([@oterral](https://github.com/oterral))
* [#6177](https://github.com/openlayers/ol3/pull/6177) - Add duration and easing options to view.fit() for animations ([@tchandelle](https://github.com/tchandelle))
* [#6078](https://github.com/openlayers/ol3/pull/6078) - Use winding number algorithm for linearRingContainsXY ([@bjornharrtell](https://github.com/bjornharrtell))
* [#6187](https://github.com/openlayers/ol3/pull/6187) - Update pbf to version 3.0.5 🚀 ([@openlayers](https://github.com/openlayers))
* [#6175](https://github.com/openlayers/ol3/pull/6175) - Generate projection transform function only when requested ([@tchandelle](https://github.com/tchandelle))
* [#6181](https://github.com/openlayers/ol3/pull/6181) - Replace expired Bing key with a new one ([@ahocevar](https://github.com/ahocevar))
* [#6164](https://github.com/openlayers/ol3/pull/6164) - Simplify color parsing and allow more decimals ([@marcjansen](https://github.com/marcjansen))
* [#6178](https://github.com/openlayers/ol3/pull/6178) - Add missing goog.require ([@fredj](https://github.com/fredj))
* [#6176](https://github.com/openlayers/ol3/pull/6176) - Doc: easing option is optional ([@tchandelle](https://github.com/tchandelle))
* [#6180](https://github.com/openlayers/ol3/pull/6180) - Update eslint to version 3.11.1 🚀 ([@openlayers](https://github.com/openlayers))
* [#6179](https://github.com/openlayers/ol3/pull/6179) - Remove unused ol.Map.removePreRenderFunction function ([@fredj](https://github.com/fredj))
* [#6052](https://github.com/openlayers/ol3/pull/6052) - Remove the use of ol.format.KML.DEFAULT_IMAGE_SCALE_MULTIPLIER_ when … ([@oterral](https://github.com/oterral))
* [#6159](https://github.com/openlayers/ol3/pull/6159) - Remove carriage return after goog.require in examples ([@tchandelle](https://github.com/tchandelle))
* [#6169](https://github.com/openlayers/ol3/pull/6169) - Image rotation in WebGL was anti-clockwise ([@tchandelle](https://github.com/tchandelle))
* [#5590](https://github.com/openlayers/ol3/pull/5590) - Kml format: improved support for region and extendeddata ([@thhomas](https://github.com/thhomas))
* [#5462](https://github.com/openlayers/ol3/pull/5462) - WebGL vector support ([@GaborFarkas](https://github.com/GaborFarkas))
* [#6168](https://github.com/openlayers/ol3/pull/6168) - Update mocha to version 3.2.0 🚀 ([@openlayers](https://github.com/openlayers))
* [#5589](https://github.com/openlayers/ol3/pull/5589) - Wmts tilematrixlimits ([@thhomas](https://github.com/thhomas))
* [#6155](https://github.com/openlayers/ol3/pull/6155) - Set GeometryLayout correctly when reading GPX ([@romanzoller](https://github.com/romanzoller))
* [#6161](https://github.com/openlayers/ol3/pull/6161) - Update async to version 2.1.4 🚀 ([@openlayers](https://github.com/openlayers))
* [#6153](https://github.com/openlayers/ol3/pull/6153) - Remove legacy licenses folder ([@romanzoller](https://github.com/romanzoller))
* [#6154](https://github.com/openlayers/ol3/pull/6154) - Update mocha-phantomjs-core to version 2.1.0 🚀 ([@openlayers](https://github.com/openlayers))
* [#6146](https://github.com/openlayers/ol3/pull/6146) - Merge ol.style.Circle and RegularShape together ([@tchandelle](https://github.com/tchandelle))
* [#6139](https://github.com/openlayers/ol3/pull/6139) - Match equivalent projections from WMTS caps ([@bartvde](https://github.com/bartvde))
* [#6138](https://github.com/openlayers/ol3/pull/6138) - Update clean-css to version 3.4.21 🚀 ([@openlayers](https://github.com/openlayers))
* [#6132](https://github.com/openlayers/ol3/pull/6132) - Add getter for color property to ol.style.Icon ([@tohu12](https://github.com/tohu12))
* [#6127](https://github.com/openlayers/ol3/pull/6127) - Format WKT Z, M and ZM ([@omarkljung](https://github.com/omarkljung))
* [#6136](https://github.com/openlayers/ol3/pull/6136) - Update eslint to version 3.10.2 🚀 ([@openlayers](https://github.com/openlayers))
* [#6133](https://github.com/openlayers/ol3/pull/6133) - Doc clarification ol.MapBrowserEvent#pixel, ol.MapBrowserEvent#coordinate, ol.Map#getEventCoordinate ([@KlausBenndorf](https://github.com/KlausBenndorf))
* [#6134](https://github.com/openlayers/ol3/pull/6134) - Add setter methods for fill, image, stroke and text styles ([@dnlkoch](https://github.com/dnlkoch))
* [#6129](https://github.com/openlayers/ol3/pull/6129) - Update pbf to version 3.0.4 🚀 ([@openlayers](https://github.com/openlayers))
* [#6121](https://github.com/openlayers/ol3/pull/6121) - Hint change means view change ([@tschaub](https://github.com/tschaub))
* [#6120](https://github.com/openlayers/ol3/pull/6120) - Set interacting hint during trackpad scroll ([@tschaub](https://github.com/tschaub))
* [#6128](https://github.com/openlayers/ol3/pull/6128) - Update pbf to version 3.0.3 🚀 ([@openlayers](https://github.com/openlayers))
* [#6124](https://github.com/openlayers/ol3/pull/6124) - Allow up to 16 decimals for alpha channel when parsing rgba strings to colors ([@marcjansen](https://github.com/marcjansen))
* [#6117](https://github.com/openlayers/ol3/pull/6117) - Update handlebars to version 4.0.6 🚀 ([@openlayers](https://github.com/openlayers))
* [#6113](https://github.com/openlayers/ol3/pull/6113) - Smooth trackpad zooming ([@tschaub](https://github.com/tschaub))
* [#6105](https://github.com/openlayers/ol3/pull/6105) - Move vector tile loader functions into vector tile module ([@tschaub](https://github.com/tschaub))
* [#6114](https://github.com/openlayers/ol3/pull/6114) - Updated linter config and curly conditional blocks ([@tschaub](https://github.com/tschaub))
* [#6106](https://github.com/openlayers/ol3/pull/6106) - Add type annotations for vector tiles ([@tschaub](https://github.com/tschaub))
* [#6107](https://github.com/openlayers/ol3/pull/6107) - Reset hint first and notify of change when cancelling animations ([@tschaub](https://github.com/tschaub))
* [#6112](https://github.com/openlayers/ol3/pull/6112) - Update eslint to version 3.10.0 🚀 ([@openlayers](https://github.com/openlayers))
* [#6110](https://github.com/openlayers/ol3/pull/6110) - Update coveralls to version 2.11.15 🚀 ([@openlayers](https://github.com/openlayers))
* [#6077](https://github.com/openlayers/ol3/pull/6077) - Optionally enable hidpi support for Bing ([@bartvde](https://github.com/bartvde))
* [#6103](https://github.com/openlayers/ol3/pull/6103) - Properly complete multiple parallel animations ([@tschaub](https://github.com/tschaub))
* [#6101](https://github.com/openlayers/ol3/pull/6101) - Avoid starting new zoom animation while already animating ([@tschaub](https://github.com/tschaub))
* [#6099](https://github.com/openlayers/ol3/pull/6099) - Modify interaction tests : check for change events ([@tchandelle](https://github.com/tchandelle))
* [#6069](https://github.com/openlayers/ol3/pull/6069) - If there is no features option, all features will be translated. ([@tchandelle](https://github.com/tchandelle))
* [#6097](https://github.com/openlayers/ol3/pull/6097) - API index page : Fix link anchor to static members ([@tchandelle](https://github.com/tchandelle))
* [#6095](https://github.com/openlayers/ol3/pull/6095) - LineString Arrows example: rotate with the view ([@tchandelle](https://github.com/tchandelle))
* [#6093](https://github.com/openlayers/ol3/pull/6093) - Update mustache to version 2.3.0 🚀 ([@openlayers](https://github.com/openlayers))
* [#6079](https://github.com/openlayers/ol3/pull/6079) - Add view animation ([@tschaub](https://github.com/tschaub))
* [#6081](https://github.com/openlayers/ol3/pull/6081) - Update metalsmith-layouts to version 1.7.0 🚀 ([@openlayers](https://github.com/openlayers))
* [#6074](https://github.com/openlayers/ol3/pull/6074) - Fix typo on style name on Modify Features Test example ([@tchandelle](https://github.com/tchandelle))
* [#6073](https://github.com/openlayers/ol3/pull/6073) - Fix link to errors doc ([@tchandelle](https://github.com/tchandelle))
* [#6072](https://github.com/openlayers/ol3/pull/6072) - Update metalsmith to version 2.3.0 🚀 ([@openlayers](https://github.com/openlayers))
* [#6068](https://github.com/openlayers/ol3/pull/6068) - Fix GeoJSON writeGeometry tests ([@ahocevar](https://github.com/ahocevar))
* [#6067](https://github.com/openlayers/ol3/pull/6067) - Do not draw circle when pointer not moved ([@ahocevar](https://github.com/ahocevar))
* [#6064](https://github.com/openlayers/ol3/pull/6064) - Make vertex candidate selection work better on rotated views ([@ahocevar](https://github.com/ahocevar))
* [#6054](https://github.com/openlayers/ol3/pull/6054) - Update eslint to version 3.9.1 🚀 ([@openlayers](https://github.com/openlayers))
* [#6058](https://github.com/openlayers/ol3/pull/6058) - Update fs-extra to version 1.0.0 🚀 ([@openlayers](https://github.com/openlayers))
* [#6053](https://github.com/openlayers/ol3/pull/6053) - Update glob to version 7.1.1 🚀 ([@openlayers](https://github.com/openlayers))
* [#6045](https://github.com/openlayers/ol3/pull/6045) - Add an example using Mapbox Terrain-RGB tiles ([@tschaub](https://github.com/tschaub))
* [#6042](https://github.com/openlayers/ol3/pull/6042) - Set constants of KML format even if a default style is provided ([@oterral](https://github.com/oterral))

View File

@@ -34,7 +34,7 @@ Interactions for [vector features](ol.Feature.html)
<tr><th>Projections</th><th>Observable objects</th><th>Other components</th></tr>
<tr><td><p>All coordinates and extents need to be provided in view projection (default: EPSG:3857). To transform, use [ol.proj.transform()](ol.proj.html#.transform) and [ol.proj.transformExtent()](ol.proj.html#.transformExtent).</p>
[ol.proj](ol.proj.html)</td>
<td><p>Changes to all [ol.Objects](ol.Object.html) can observed by calling the [object.on('propertychange')](ol.Object.html#on) method. Listeners receive an [ol.ObjectEvent](ol.ObjectEvent.html) with information on the changed property and old value.</p>
<td><p>Changes to all [ol.Objects](ol.Object.html) can observed by calling the [object.on('propertychange')](ol.Object.html#on) method. Listeners receive an [ol.Object.Event](ol.Object.Event.html) with information on the changed property and old value.</p>
<td>[ol.DeviceOrientation](ol.DeviceOrientation.html)<br>
[ol.Geolocation](ol.Geolocation.html)<br>
[ol.Overlay](ol.Overlay.html)<br></td>

View File

@@ -47,7 +47,7 @@ exports.handlers = {
if (!cls.fires) {
cls.fires = [];
}
event = 'ol.ObjectEvent#event:change:' + name;
event = 'ol.Object.Event#event:change:' + name;
if (cls.fires.indexOf(event) == -1) {
cls.fires.push(event);
}

View File

@@ -45,9 +45,11 @@
body {
padding-top: 50px;
}
.nameContainer .name, .prettyprint.source .pln {
.nameContainer .anchor {
padding-top: 50px;
margin-top: -50px;
width: 0px;
height: 0px;
}
a {
position: relative;
@@ -294,6 +296,7 @@ span.type-signature.static {
color: gray;
}
.main .nameContainer h4 {
margin-top: 0px;
margin-right: 150px;
line-height: 1.3;
}

View File

@@ -11,7 +11,9 @@ if (data.type && data.type.names) {
?>
<dt class="<?js= (data.stability && data.stability !== 'stable') ? 'unstable' : '' ?>">
<div class="nameContainer">
<h4 class="name" id="<?js= id ?>">
<div class="anchor" id="<?js= id ?>">
</div>
<h4 class="name">
<?js= data.attribs + (data.scope === 'static' ? longname : name) + typeSignature ?>
<?js= this.partial('stability.tmpl', data) ?>
</h4>

View File

@@ -5,7 +5,9 @@ var self = this;
<dt class="<?js= (data.stability && data.stability !== 'stable') ? 'unstable' : '' ?>">
<div class="nameContainer<?js if (data.inherited) { ?> inherited<?js } ?>">
<?js if (data.stability || kind !== 'class') { ?>
<h4 class="name" id="<?js= id ?>">
<div class="anchor" id="<?js= id ?>">
</div>
<h4 class="name">
<?js= data.attribs + (kind === 'class' ? 'new ' : '') + (data.scope === 'static' ? longname : name) + (kind !== 'event' ? data.signature : '') ?>
<?js if (data.inherited || data.inherits) { ?>
<span class="inherited"><?js= this.linkto(data.inherits, 'inherited') ?></span>

View File

@@ -8,7 +8,7 @@
<th>Name</th>
<th>Type</th>
<th>Settable</th>
<th><a href="ol.ObjectEvent.html">ol.ObjectEvent</a> type</th>
<th><a href="ol.Object.Event.html">ol.Object.Event</a> type</th>
<th class="last">Description</th>
</tr>
</thead>

View File

@@ -7,6 +7,8 @@
"d3": false,
"jsPDF": false,
"jsts": false,
"topolis": false,
"toastr": false,
"saveAs": false,
"topojson": false,
"turf": false

View File

@@ -6,7 +6,7 @@ docs: >
<p>When the Bing Maps tile service doesn't have tiles for a given resolution and region it returns "placeholder" tiles indicating that. Zoom the map beyond level 19 to see the "placeholder" tiles. If you want OpenLayers to display stretched tiles in place of "placeholder" tiles beyond zoom level 19 then set <code>maxZoom</code> to <code>19</code> in the options passed to <code>ol.source.BingMaps</code>.</p>
tags: "bing, bing-maps"
cloak:
AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF: Your Bing Maps Key from http://www.bingmapsportal.com/ here
As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5: Your Bing Maps Key from http://www.bingmapsportal.com/ here
---
<div id="map" class="map"></div>
<select id="layer-select">

View File

@@ -18,7 +18,7 @@ for (i = 0, ii = styles.length; i < ii; ++i) {
visible: false,
preload: Infinity,
source: new ol.source.BingMaps({
key: 'AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF',
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5',
imagerySet: styles[i]
// use maxZoom 19 to see stretched tiles instead of the BingMaps
// "no photos at this zoom level" tiles

View File

@@ -6,7 +6,7 @@ docs: >
Example of using the drag-and-drop interaction with a ol.source.ImageVector. Drag and drop GPX, GeoJSON, IGC, KML, or TopoJSON files on to the map. Each file is rendered to an image on the client.
tags: "drag-and-drop-image-vector, gpx, geojson, igc, kml, topojson, vector, image"
cloak:
AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF: Your Bing Maps Key from http://www.bingmapsportal.com/ here
As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5: Your Bing Maps Key from http://www.bingmapsportal.com/ here
---
<div id="map" class="map"></div>
<div id="info">&nbsp;</div>

View File

@@ -100,7 +100,7 @@ var map = new ol.Map({
new ol.layer.Tile({
source: new ol.source.BingMaps({
imagerySet: 'Aerial',
key: 'AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF'
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5'
})
})
],

View File

@@ -6,7 +6,7 @@ docs: >
Example of using the drag-and-drop interaction. Drag and drop GPX, GeoJSON, IGC, KML, or TopoJSON files on to the map. There is no projection transform support, so this will only work with data in EPSG:4326 and EPSG:3857.
tags: "drag-and-drop, gpx, geojson, igc, kml, topojson"
cloak:
AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF: Your Bing Maps Key from http://www.bingmapsportal.com/ here
As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5: Your Bing Maps Key from http://www.bingmapsportal.com/ here
---
<div id="map" class="map"></div>
<div id="info">&nbsp;</div>

View File

@@ -99,7 +99,7 @@ var map = new ol.Map({
new ol.layer.Tile({
source: new ol.source.BingMaps({
imagerySet: 'Aerial',
key: 'AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF'
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5'
})
})
],

View File

@@ -7,6 +7,8 @@ docs: >
animate a (marker) feature along a line. In this example an encoded polyline
is being used.
tags: "animation, feature, postcompose, polyline"
cloak:
As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5: Your Bing Maps Key from http://www.bingmapsportal.com/ here
---
<div id="map" class="map"></div>
<label for="speed">

View File

@@ -140,7 +140,7 @@ var map = new ol.Map({
new ol.layer.Tile({
source: new ol.source.BingMaps({
imagerySet: 'AerialWithLabels',
key: 'AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF'
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5'
})
}),
vectorLayer

View File

@@ -7,6 +7,6 @@ docs: >
<p>If there is no button on the map, your browser does not support the <a href="http://caniuse.com/#feat=fullscreen">Full Screen API</a>.</p>
tags: "full-screen, drag, rotate, zoom, bing, bing-maps"
cloak:
AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF: Your Bing Maps Key from http://www.bingmapsportal.com/ here
As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5: Your Bing Maps Key from http://www.bingmapsportal.com/ here
---
<div id="map" class="map"></div>

View File

@@ -18,7 +18,7 @@ var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.BingMaps({
key: 'AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF',
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5',
imagerySet: 'Aerial'
})
})

View File

@@ -7,6 +7,6 @@ docs: >
<p>If there is no button on the map, your browser does not support the <a href="http://caniuse.com/#feat=fullscreen">Full Screen API</a>.</p>
tags: "full-screen, bing, bing-maps"
cloak:
AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF: Your Bing Maps Key from http://www.bingmapsportal.com/ here
As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5: Your Bing Maps Key from http://www.bingmapsportal.com/ here
---
<div id="map" class="map"></div>

View File

@@ -18,7 +18,7 @@ var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.BingMaps({
key: 'AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF',
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5',
imagerySet: 'Aerial'
})
})

View File

@@ -6,7 +6,7 @@ docs: >
Example of using the GPX source.
tags: "GPX"
cloak:
AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF: Your Bing Maps Key from http://www.bingmapsportal.com/ here
As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5: Your Bing Maps Key from http://www.bingmapsportal.com/ here
---
<div id="map" class="map"></div>
<div id="info">&nbsp;</div>

View File

@@ -13,7 +13,7 @@ goog.require('ol.style.Style');
var raster = new ol.layer.Tile({
source: new ol.source.BingMaps({
imagerySet: 'Aerial',
key: 'AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF'
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5'
})
});

View File

@@ -8,7 +8,7 @@ docs: >
In this example, the <code>postcompose</code> listener applies a filter to the image data.</p>
tags: "filter, image manipulation"
cloak:
AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF: Your Bing Maps Key from http://www.bingmapsportal.com/ here
As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5: Your Bing Maps Key from http://www.bingmapsportal.com/ here
---
<div id="map" class="map"></div>
<select id="kernel" name="kernel">

View File

@@ -4,7 +4,7 @@ goog.require('ol.layer.Tile');
goog.require('ol.proj');
goog.require('ol.source.BingMaps');
var key = 'AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF';
var key = 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5';
var imagery = new ol.layer.Tile({
source: new ol.source.BingMaps({key: key, imagerySet: 'Aerial'})

View File

@@ -6,7 +6,7 @@ docs: >
This example uses the <code>ol.format.KML</code> to parse KML for rendering with a vector source.
tags: "KML"
cloak:
AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF: Your Bing Maps Key from http://www.bingmapsportal.com/ here
As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5: Your Bing Maps Key from http://www.bingmapsportal.com/ here
---
<div id="map" class="map"></div>
<div id="info">&nbsp;</div>

View File

@@ -12,7 +12,7 @@ var projection = ol.proj.get('EPSG:3857');
var raster = new ol.layer.Tile({
source: new ol.source.BingMaps({
imagerySet: 'Aerial',
key: 'AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF'
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5'
})
});

View File

@@ -10,6 +10,6 @@ docs: >
<p>Move around the map to see the effect. Use the ↑ up and ↓ down arrow keys to adjust the spyglass size.</p>
tags: "spy, image manipulation"
cloak:
AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF: Your Bing Maps Key from http://www.bingmapsportal.com/ here
As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5: Your Bing Maps Key from http://www.bingmapsportal.com/ here
---
<div id="map" class="map"></div>

View File

@@ -4,7 +4,7 @@ goog.require('ol.layer.Tile');
goog.require('ol.proj');
goog.require('ol.source.BingMaps');
var key = 'AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF';
var key = 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5';
var roads = new ol.layer.Tile({
source: new ol.source.BingMaps({key: key, imagerySet: 'Road'})

View File

@@ -6,7 +6,7 @@ docs: >
Example of a Layer swipe map.
tags: "swipe, openstreetmap"
cloak:
AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF: Your Bing Maps Key from http://www.bingmapsportal.com/ here
As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5: Your Bing Maps Key from http://www.bingmapsportal.com/ here
---
<div id="map" class="map"></div>
<input id="swipe" type="range" style="width: 100%">

View File

@@ -10,7 +10,7 @@ var osm = new ol.layer.Tile({
});
var bing = new ol.layer.Tile({
source: new ol.source.BingMaps({
key: 'AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF',
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5',
imagerySet: 'Aerial'
})
});

View File

@@ -4,7 +4,7 @@ title: Full-Screen Mobile
shortdesc: Example of a full screen map.
tags: "fullscreen, geolocation, mobile"
cloak:
AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF: Your Bing Maps Key from http://www.bingmapsportal.com/ here
As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5: Your Bing Maps Key from http://www.bingmapsportal.com/ here
---
<!doctype html>
<html lang="en">

View File

@@ -14,7 +14,7 @@ var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.BingMaps({
key: 'AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF',
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5',
imagerySet: 'Road'
})
})

11
examples/pinch-zoom.html Normal file
View File

@@ -0,0 +1,11 @@
---
layout: example.html
title: Pinch Zoom
shortdesc: Restrict pinch zooming to integer zoom levels.
docs: >
By default, the `ol.interaction.PinchZoom` can leave the map at fractional zoom levels.
If instead you want to constrain pinch zooming to integer zoom levels, set
<code>constrainResolution: true</code> when constructing the interaction.
tags: "pinch, zoom, interaction"
---
<div id="map" class="map"></div>

25
examples/pinch-zoom.js Normal file
View File

@@ -0,0 +1,25 @@
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.interaction');
goog.require('ol.interaction.PinchZoom');
goog.require('ol.layer.Tile');
goog.require('ol.source.OSM');
var map = new ol.Map({
interactions: ol.interaction.defaults({pinchZoom: false}).extend([
new ol.interaction.PinchZoom({
constrainResolution: true // force zooming to a integer zoom
})
]),
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 2
})
});

View File

@@ -6,7 +6,7 @@ docs: >
<p>The map on the top preloads low resolution tiles. The map on the bottom does not use any preloading. Try zooming out and panning to see the difference.</p>
tags: "preload, bing"
cloak:
AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF: Your Bing Maps Key from http://www.bingmapsportal.com/ here
As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5: Your Bing Maps Key from http://www.bingmapsportal.com/ here
---
<div id="map1" class="map"></div>
<div id="map2" class="map"></div>

View File

@@ -14,7 +14,7 @@ var map1 = new ol.Map({
new ol.layer.Tile({
preload: Infinity,
source: new ol.source.BingMaps({
key: 'AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF',
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5',
imagerySet: 'Aerial'
})
})
@@ -28,7 +28,7 @@ var map2 = new ol.Map({
new ol.layer.Tile({
preload: 0, // default value
source: new ol.source.BingMaps({
key: 'AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF',
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5',
imagerySet: 'AerialWithLabels'
})
})

View File

@@ -22,7 +22,7 @@ tags: "raster, pixel"
resources:
- https://d3js.org/d3.v3.min.js
cloak:
AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF: Your Bing Maps Key from http://www.bingmapsportal.com/ here
As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5: Your Bing Maps Key from http://www.bingmapsportal.com/ here
---
<div class="rel">
<div id="map" class="map"></div>

View File

@@ -50,7 +50,7 @@ function summarize(value, counts) {
* Use aerial imagery as the input data for the raster source.
*/
var bing = new ol.source.BingMaps({
key: 'AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF',
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5',
imagerySet: 'Aerial'
});

View File

@@ -25,7 +25,7 @@ docs: >
</p>
tags: "raster, region growing"
cloak:
AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF: Your Bing Maps Key from http://www.bingmapsportal.com/ here
As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5: Your Bing Maps Key from http://www.bingmapsportal.com/ here
---
<div id="map" class="map" style="cursor: pointer"></div>
<table class="controls">

View File

@@ -72,7 +72,7 @@ function next4Edges(edge) {
];
}
var key = 'AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF';
var key = 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5';
var imagery = new ol.layer.Tile({
source: new ol.source.BingMaps({key: key, imagerySet: 'Aerial'})

View File

@@ -18,5 +18,13 @@ tags: "select, vector"
<option value="altclick">Alt+Click</option>
<option value="none">None</option>
</select>
<span id="status">&nbsp;0 selected features</span>
<span id="status">&nbsp;0 selected features</span>
<br />
<label>Hit tolerance for selecting features </label>
<select id="hitTolerance" class="form-control">
<option value="0" selected>0 Pixels</option>
<option value="5">5 Pixels</option>
<option value="10">10 Pixels</option>
</select>
<canvas id="circle" style="vertical-align: middle"/>
</form>

View File

@@ -31,23 +31,28 @@ var map = new ol.Map({
var select = null; // ref to currently selected interaction
// select interaction working on "singleclick"
var selectSingleClick = new ol.interaction.Select();
var selectSingleClick = new ol.interaction.Select({
multi: true // multi is used in this example if hitTolerance > 0
});
// select interaction working on "click"
var selectClick = new ol.interaction.Select({
condition: ol.events.condition.click
condition: ol.events.condition.click,
multi: true
});
// select interaction working on "pointermove"
var selectPointerMove = new ol.interaction.Select({
condition: ol.events.condition.pointerMove
condition: ol.events.condition.pointerMove,
multi: true
});
var selectAltClick = new ol.interaction.Select({
condition: function(mapBrowserEvent) {
return ol.events.condition.click(mapBrowserEvent) &&
ol.events.condition.altKeyOnly(mapBrowserEvent);
}
},
multi: true
});
var selectElement = document.getElementById('type');
@@ -85,3 +90,27 @@ var changeInteraction = function() {
*/
selectElement.onchange = changeInteraction;
changeInteraction();
var selectHitToleranceElement = document.getElementById('hitTolerance');
var circleCanvas = document.getElementById('circle');
var changeHitTolerance = function() {
var value = parseInt(selectHitToleranceElement.value, 10);
selectSingleClick.setHitTolerance(value);
selectClick.setHitTolerance(value);
selectPointerMove.setHitTolerance(value);
selectAltClick.setHitTolerance(value);
var size = 2 * value + 2;
circleCanvas.width = size;
circleCanvas.height = size;
var ctx = circleCanvas.getContext('2d');
ctx.clearRect(0, 0, size, size);
ctx.beginPath();
ctx.arc(value + 1, value + 1, value + 0.5, 0, 2 * Math.PI);
ctx.fill();
ctx.stroke();
};
selectHitToleranceElement.onchange = changeHitTolerance;
changeHitTolerance();

15
examples/topolis.html Normal file
View File

@@ -0,0 +1,15 @@
---
layout: example.html
title: topolis integration
shortdesc: Example on how to use topolis with OpenLayers 3.
docs: >
Example showing the integration of <a href="https://github.com/bjornharrtell/topolis">topolis</a>
with OpenLayers 3, enabling creating and editing topological geometry. Standard interaction draws edges, snapping to existing edges. Delete an edge by drawing a new edge crossing the one to delete.
tags: "draw, edit, vector, topology, topolis"
resources:
- https://cdn.rawgit.com/bjornharrtell/topolis/releases/0.1.1/topolis.min.js
- https://code.jquery.com/jquery-3.1.1.min.js
- https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.3/toastr.min.js
- https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.3/toastr.min.css
---
<div id="map" class="map"></div>

216
examples/topolis.js Normal file
View File

@@ -0,0 +1,216 @@
// NOCOMPILE
// this example uses topolis and toastr for which we don't have an externs file.
goog.require('ol.Feature');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.geom.Point');
goog.require('ol.geom.LineString');
goog.require('ol.geom.Polygon');
goog.require('ol.interaction.Draw');
goog.require('ol.interaction.Snap');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
goog.require('ol.source.OSM');
goog.require('ol.source.Vector');
goog.require('ol.style.Style');
goog.require('ol.style.Stroke');
goog.require('ol.style.Fill');
goog.require('ol.style.Circle');
goog.require('ol.style.Text');
goog.require('ol.control.MousePosition');
var raster = new ol.layer.Tile({
source: new ol.source.OSM()
});
var nodes = new ol.source.Vector({wrapX: false});
var nodesLayer = new ol.layer.Vector({
source: nodes,
style: function(f) {
var style = new ol.style.Style({
image: new ol.style.Circle({
radius: 8,
fill: new ol.style.Fill({color: 'rgba(255, 0, 0, 0.2)'}),
stroke: new ol.style.Stroke({color: 'red', width: 1})
}),
text: new ol.style.Text({
text: f.get('node').id.toString(),
fill: new ol.style.Fill({color: 'red'}),
stroke: new ol.style.Stroke({
color: 'white',
width: 3
})
})
});
return [style];
}
});
var edges = new ol.source.Vector({wrapX: false});
var edgesLayer = new ol.layer.Vector({
source: edges,
style: function(f) {
var style = new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'blue',
width: 1
}),
text: new ol.style.Text({
text: f.get('edge').id.toString(),
fill: new ol.style.Fill({color: 'blue'}),
stroke: new ol.style.Stroke({
color: 'white',
width: 2
})
})
});
return [style];
}
});
var faces = new ol.source.Vector({wrapX: false});
var facesLayer = new ol.layer.Vector({
source: faces,
style: function(f) {
var style = new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'black',
width: 1
}),
fill: new ol.style.Fill({
color: 'rgba(0, 255, 0, 0.2)'
}),
text: new ol.style.Text({
font: 'bold 12px sans-serif',
text: f.get('face').id.toString(),
fill: new ol.style.Fill({color: 'green'}),
stroke: new ol.style.Stroke({
color: 'white',
width: 2
})
})
});
return [style];
}
});
var map = new ol.Map({
layers: [raster, facesLayer, edgesLayer, nodesLayer],
target: 'map',
view: new ol.View({
center: [-11000000, 4600000],
zoom: 16
})
});
var topo = topolis.createTopology();
topo.on('addnode', nodeToFeature);
topo.on('removenode', function(e) {
removeElementFeature(nodes, e);
});
topo.on('addedge', edgeToFeature);
topo.on('modedge', function(e) {
var feature = edges.getFeatureById(e.id);
feature.setGeometry(new ol.geom.LineString(e.coordinates));
});
topo.on('removeedge', function(e) {
removeElementFeature(edges, e);
});
topo.on('addface', faceToFeature);
topo.on('removeface', function(e) {
removeElementFeature(faces, e);
});
function removeElementFeature(source, element) {
var feature = source.getFeatureById(element.id);
source.removeFeature(feature);
}
function nodeToFeature(node) {
var feature = new ol.Feature({
geometry: new ol.geom.Point(node.coordinate),
node: node
});
feature.setId(node.id);
nodes.addFeature(feature);
}
function edgeToFeature(edge) {
var feature = new ol.Feature({
geometry: new ol.geom.LineString(edge.coordinates),
edge: edge
});
feature.setId(edge.id);
edges.addFeature(feature);
}
function faceToFeature(face) {
var coordinates = topo.getFaceGeometry(face);
var feature = new ol.Feature({
geometry: new ol.geom.Polygon(coordinates),
face: face
});
feature.setId(face.id);
faces.addFeature(feature);
}
function createNode(topo, coord) {
var node;
var existingEdge = topo.getEdgeByPoint(coord, 5)[0];
if (existingEdge) {
node = topo.modEdgeSplit(existingEdge, coord);
} else {
node = topo.addIsoNode(coord);
}
return node;
}
function onDrawend(e) {
var edgeGeom = e.feature.getGeometry().getCoordinates();
var startCoord = edgeGeom[0];
var endCoord = edgeGeom[edgeGeom.length - 1];
var start, end;
try {
start = topo.getNodeByPoint(startCoord);
end = topo.getNodeByPoint(endCoord);
var edgesAtStart = topo.getEdgeByPoint(startCoord, 5);
var edgesAtEnd = topo.getEdgeByPoint(endCoord, 5);
var crossing = topo.getEdgesByLine(edgeGeom);
if (crossing.length === 1 && !start && !end && edgesAtStart.length === 0 && edgesAtEnd.length === 0) {
topo.remEdgeNewFace(crossing[0]);
start = crossing[0].start;
if (start.face) {
topo.removeIsoNode(start);
}
end = crossing[0].end;
if (end.face) {
topo.removeIsoNode(end);
}
return;
}
if (!start) {
start = createNode(topo, startCoord);
edgeGeom[0] = start.coordinate;
}
if (!end) {
end = createNode(topo, endCoord);
edgeGeom[edgeGeom.length - 1] = end.coordinate;
}
topo.addEdgeNewFaces(start, end, edgeGeom);
} catch (e) {
toastr.warning(e.toString());
}
}
var draw = new ol.interaction.Draw({
type: 'LineString'
});
draw.on('drawend', onDrawend);
map.addInteraction(draw);
var snap = new ol.interaction.Snap({
source: edges
});
map.addInteraction(snap);
map.addControl(new ol.control.MousePosition());

View File

@@ -6,6 +6,6 @@ docs: >
OSM XML vector data is loaded dynamically from a the [Overpass API](http://overpass-api.de) using a bbox strategy. Note that panning and zooming will eventually lead to "Too many requests" errors from the Overpass API.
tags: "vector, osmxml, loading, server, strategy, bbox"
cloak:
AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF: Your Bing Maps Key from http://www.bingmapsportal.com/ here
As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5: Your Bing Maps Key from http://www.bingmapsportal.com/ here
---
<div id="map" class="map"></div>

View File

@@ -119,7 +119,7 @@ var vector = new ol.layer.Vector({
var raster = new ol.layer.Tile({
source: new ol.source.BingMaps({
imagerySet: 'Aerial',
key: 'AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF'
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5'
})
});

View File

@@ -8,6 +8,6 @@ docs: >
that match the query.
tags: "vector, WFS, GetFeature, filter"
cloak:
AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF: Your Bing Maps Key from http://www.bingmapsportal.com/ here
As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5: Your Bing Maps Key from http://www.bingmapsportal.com/ here
---
<div id="map" class="map"></div>

View File

@@ -25,7 +25,7 @@ var vector = new ol.layer.Vector({
var raster = new ol.layer.Tile({
source: new ol.source.BingMaps({
imagerySet: 'Aerial',
key: 'AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF'
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5'
})
});

View File

@@ -6,6 +6,6 @@ docs: >
This example loads new features from GeoServer WFS when the view extent changes.
tags: "vector, WFS, bbox, loading, server"
cloak:
AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF: Your Bing Maps Key from http://www.bingmapsportal.com/ here
As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5: Your Bing Maps Key from http://www.bingmapsportal.com/ here
---
<div id="map" class="map"></div>

View File

@@ -35,7 +35,7 @@ var vector = new ol.layer.Vector({
var raster = new ol.layer.Tile({
source: new ol.source.BingMaps({
imagerySet: 'Aerial',
key: 'AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF'
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5'
})
});

View File

@@ -6,6 +6,6 @@ docs: >
This map has a view that is constrained between zoom levels 9 and 13. This is done using the `minZoom` and `maxZoom` view options.
tags: "bing, zoom, minZoom, maxZoom"
cloak:
AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF: Your Bing Maps Key from http://www.bingmapsportal.com/ here
As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5: Your Bing Maps Key from http://www.bingmapsportal.com/ here
---
<div id="map" class="map"></div>

View File

@@ -9,7 +9,7 @@ var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.BingMaps({
key: 'AkGbxXx6tDWf1swIhPJyoAVp06H0s0gDTYslNWWHZ6RoPqMpB9ld5FY1WutX8UoF',
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5',
imagerySet: 'Aerial'
})
})

View File

@@ -109,22 +109,28 @@ oli.ModifyEvent.prototype.features;
oli.ModifyEvent.prototype.mapBrowserEvent;
/**
* @type {Object}
*/
oli.Object;
/**
* @interface
*/
oli.ObjectEvent = function() {};
oli.Object.Event = function() {};
/**
* @type {string}
*/
oli.ObjectEvent.prototype.key;
oli.Object.Event.prototype.key;
/**
* @type {*}
*/
oli.ObjectEvent.prototype.oldValue;
oli.Object.Event.prototype.oldValue;
/**

View File

@@ -302,6 +302,36 @@ olx.MapOptions.prototype.target;
olx.MapOptions.prototype.view;
/**
* Object literal with options for the {@link ol.Map#forEachFeatureAtPixel} and
* {@link ol.Map#hasFeatureAtPixel} methods.
* @typedef {{layerFilter: ((function(ol.layer.Layer): boolean)|undefined),
* hitTolerance: (number|undefined)}}
*/
olx.AtPixelOptions;
/**
* Layer filter function. The filter function will receive one argument, the
* {@link ol.layer.Layer layer-candidate} and it should return a boolean value.
* Only layers which are visible and for which this function returns `true`
* will be tested for features. By default, all visible layers will be tested.
* @type {((function(ol.layer.Layer): boolean)|undefined)}
* @api stable
*/
olx.AtPixelOptions.prototype.layerFilter;
/**
* Hit-detection tolerance in pixels. Pixels inside the radius around the given position
* will be checked for features. This only works for the canvas renderer and
* not for WebGL.
* @type {number|undefined}
* @api
*/
olx.AtPixelOptions.prototype.hitTolerance;
/**
* Object literal with config options for the overlay.
* @typedef {{id: (number|string|undefined),
@@ -419,7 +449,7 @@ olx.OverlayOptions.prototype.autoPanMargin;
/**
* @typedef {{
* duration: (number|undefined),
* easing: (function(number):number|undefined)
* easing: (undefined|function(number):number)
* }}
*/
olx.OverlayPanOptions;
@@ -436,7 +466,7 @@ olx.OverlayPanOptions.prototype.duration;
/**
* The easing function to use. Can be an {@link ol.easing} or a custom function.
* Default is {@link ol.easing.inAndOut}.
* @type {function(number):number|undefined}
* @type {undefined|function(number):number}
* @api
*/
olx.OverlayPanOptions.prototype.easing;
@@ -695,7 +725,7 @@ olx.ViewOptions.prototype.zoomFactor;
* rotation: (number|undefined),
* anchor: (ol.Coordinate|undefined),
* duration: (number|undefined),
* easing: (function(number):number|undefined)
* easing: (undefined|function(number):number)
* }}
*/
olx.AnimationOptions;
@@ -756,7 +786,7 @@ olx.AnimationOptions.prototype.duration;
* The function will be called for each frame with a number representing a
* fraction of the animation's duration. The function should return a number
* between 0 and 1 representing the progress toward the destination state.
* @type {function(number):number|undefined}
* @type {undefined|function(number):number}
* @api
*/
olx.AnimationOptions.prototype.easing;
@@ -773,7 +803,7 @@ olx.animation;
* @typedef {{resolution: number,
* start: (number|undefined),
* duration: (number|undefined),
* easing: (function(number):number|undefined)}}
* easing: (undefined|function(number):number)}}
*/
olx.animation.BounceOptions;
@@ -806,7 +836,7 @@ olx.animation.BounceOptions.prototype.duration;
/**
* The easing function to use. Can be an {@link ol.easing} or a custom function.
* Default is {@link ol.easing.upAndDown}.
* @type {function(number):number|undefined}
* @type {undefined|function(number):number}
* @api
*/
olx.animation.BounceOptions.prototype.easing;
@@ -816,7 +846,7 @@ olx.animation.BounceOptions.prototype.easing;
* @typedef {{source: ol.Coordinate,
* start: (number|undefined),
* duration: (number|undefined),
* easing: (function(number):number|undefined)}}
* easing: (undefined|function(number):number)}}
*/
olx.animation.PanOptions;
@@ -848,7 +878,7 @@ olx.animation.PanOptions.prototype.duration;
/**
* The easing function to use. Can be an {@link ol.easing} or a custom function.
* Default is {@link ol.easing.inAndOut}.
* @type {function(number):number|undefined}
* @type {undefined|function(number):number}
* @api
*/
olx.animation.PanOptions.prototype.easing;
@@ -859,7 +889,7 @@ olx.animation.PanOptions.prototype.easing;
* anchor: (ol.Coordinate|undefined),
* start: (number|undefined),
* duration: (number|undefined),
* easing: (function(number):number|undefined)}}
* easing: (undefined|function(number):number)}}
*/
olx.animation.RotateOptions;
@@ -901,7 +931,7 @@ olx.animation.RotateOptions.prototype.duration;
/**
* The easing function to use. Can be an {@link ol.easing} or a custom function.
* Default is {@link ol.easing.inAndOut}.
* @type {function(number):number|undefined}
* @type {undefined|function(number):number}
* @api
*/
olx.animation.RotateOptions.prototype.easing;
@@ -911,7 +941,7 @@ olx.animation.RotateOptions.prototype.easing;
* @typedef {{resolution: number,
* start: (number|undefined),
* duration: (number|undefined),
* easing: (function(number):number|undefined)}}
* easing: (undefined|function(number):number)}}
*/
olx.animation.ZoomOptions;
@@ -944,7 +974,7 @@ olx.animation.ZoomOptions.prototype.duration;
/**
* The easing function to use. Can be an {@link ol.easing} or a custom function.
* Default is {@link ol.easing.inAndOut}.
* @type {function(number):number|undefined}
* @type {undefined|function(number):number}
* @api
*/
olx.animation.ZoomOptions.prototype.easing;
@@ -2871,7 +2901,8 @@ olx.interaction.ExtentOptions.prototype.wrapX;
/**
* @typedef {{
* features: (ol.Collection.<ol.Feature>|undefined),
* layers: (undefined|Array.<ol.layer.Layer>|function(ol.layer.Layer): boolean)
* layers: (undefined|Array.<ol.layer.Layer>|function(ol.layer.Layer): boolean),
* hitTolerance: (number|undefined)
* }}
*/
olx.interaction.TranslateOptions;
@@ -2898,6 +2929,16 @@ olx.interaction.TranslateOptions.prototype.features;
olx.interaction.TranslateOptions.prototype.layers;
/**
* Hit-detection tolerance. Pixels inside the radius around the given position
* will be checked for features. This only works for the canvas renderer and
* not for WebGL.
* @type {number|undefined}
* @api
*/
olx.interaction.TranslateOptions.prototype.hitTolerance;
/**
* @typedef {{condition: (ol.EventsConditionType|undefined),
* duration: (number|undefined),
@@ -3104,6 +3145,13 @@ olx.interaction.PinchZoomOptions;
*/
olx.interaction.PinchZoomOptions.prototype.duration;
/**
* Zoom to the closest integer zoom level after the pinch gesture ends. Default is `false`.
* @type {boolean|undefined}
* @api
*/
olx.interaction.PinchZoomOptions.prototype.constrainResolution;
/**
* @typedef {{handleDownEvent: (function(ol.MapBrowserPointerEvent):boolean|undefined),
@@ -3173,7 +3221,8 @@ olx.interaction.PointerOptions.prototype.handleUpEvent;
* multi: (boolean|undefined),
* features: (ol.Collection.<ol.Feature>|undefined),
* filter: (ol.SelectFilterFunction|undefined),
* wrapX: (boolean|undefined)}}
* wrapX: (boolean|undefined),
* hitTolerance: (number|undefined)}}
*/
olx.interaction.SelectOptions;
@@ -3287,6 +3336,16 @@ olx.interaction.SelectOptions.prototype.filter;
olx.interaction.SelectOptions.prototype.wrapX;
/**
* Hit-detection tolerance. Pixels inside the radius around the given position
* will be checked for features. This only works for the canvas renderer and
* not for WebGL.
* @type {number|undefined}
* @api
*/
olx.interaction.SelectOptions.prototype.hitTolerance;
/**
* Options for snap
* @typedef {{
@@ -3953,6 +4012,7 @@ olx.layer.VectorOptions.prototype.visible;
* minResolution: (number|undefined),
* maxResolution: (number|undefined),
* opacity: (number|undefined),
* preload: (number|undefined),
* renderBuffer: (number|undefined),
* renderMode: (ol.layer.VectorTile.RenderType|string|undefined),
* renderOrder: (function(ol.Feature, ol.Feature):number|undefined),
@@ -4047,6 +4107,15 @@ olx.layer.VectorTileOptions.prototype.maxResolution;
olx.layer.VectorTileOptions.prototype.opacity;
/**
* Preload. Load low-resolution tiles up to `preload` levels. By default
* `preload` is `0`, which means no preloading.
* @type {number|undefined}
* @api stable
*/
olx.layer.VectorTileOptions.prototype.preload;
/**
* Source.
* @type {ol.source.VectorTile|undefined}
@@ -5257,7 +5326,7 @@ olx.source.ImageVectorOptions.prototype.style;
* operation: (ol.RasterOperation|undefined),
* lib: (Object|undefined),
* threads: (number|undefined),
* operationType: (ol.RasterOperationType|undefined)}}
* operationType: (ol.source.Raster.OperationType|undefined)}}
* @api
*/
olx.source.RasterOptions;
@@ -5305,7 +5374,7 @@ olx.source.RasterOptions.prototype.threads;
* `'pixel'` operations are assumed, and operations will be called with an
* array of pixels from input sources. If set to `'image'`, operations will
* be called with an array of ImageData objects from input sources.
* @type {ol.RasterOperationType|undefined}
* @type {ol.source.Raster.OperationType|undefined}
* @api
*/
olx.source.RasterOptions.prototype.operationType;
@@ -7562,7 +7631,10 @@ olx.view;
* constrainResolution: (boolean|undefined),
* nearest: (boolean|undefined),
* maxZoom: (number|undefined),
* minResolution: (number|undefined)}}
* minResolution: (number|undefined),
* duration: (number|undefined),
* easing: (undefined|function(number):number)
* }}
*/
olx.view.FitOptions;
@@ -7609,6 +7681,26 @@ olx.view.FitOptions.prototype.minResolution;
olx.view.FitOptions.prototype.maxZoom;
/**
* The duration of the animation in milliseconds. By default, there is no
* animations.
* @type {number|undefined}
* @api
*/
olx.view.FitOptions.prototype.duration;
/**
* The easing function used during the animation (defaults to {@link ol.easing.inAndOut}).
* The function will be called for each frame with a number representing a
* fraction of the animation's duration. The function should return a number
* between 0 and 1 representing the progress toward the destination state.
* @type {undefined|function(number):number}
* @api
*/
olx.view.FitOptions.prototype.easing;
/* typedefs for object literals exposed by the library */

View File

@@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -1,28 +0,0 @@
Redistribution and use of this software in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of Yahoo! Inc. nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of Yahoo! Inc.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -1,18 +0,0 @@
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -1,6 +1,6 @@
{
"name": "openlayers",
"version": "3.20.0-beta.1",
"version": "3.20.0",
"description": "Build tools and sources for developing OpenLayers based mapping applications",
"keywords": [
"map",
@@ -30,7 +30,7 @@
"css/ol.css"
],
"dependencies": {
"async": "2.1.2",
"async": "2.1.4",
"browserify": "13.1.1",
"closure-util": "1.15.1",
"derequire": "2.0.3",
@@ -42,7 +42,7 @@
"metalsmith": "2.3.0",
"metalsmith-layouts": "1.7.0",
"nomnom": "1.8.1",
"pbf": "3.0.4",
"pbf": "3.0.5",
"pixelworks": "1.1.0",
"rbush": "2.0.1",
"temp": "0.8.3",
@@ -53,17 +53,17 @@
"clean-css": "3.4.21",
"coveralls": "2.11.15",
"debounce": "^1.0.0",
"eslint": "3.10.2",
"eslint": "3.12.0",
"eslint-config-openlayers": "6.0.0",
"eslint-plugin-openlayers-internal": "2.2.0",
"expect.js": "0.3.1",
"gaze": "^1.0.0",
"istanbul": "0.4.5",
"jquery": "3.1.1",
"mocha": "3.1.2",
"mocha-phantomjs-core": "^1.3.0",
"mocha": "3.2.0",
"mocha-phantomjs-core": "^2.1.0",
"mustache": "2.3.0",
"phantomjs-prebuilt": "2.1.13",
"phantomjs-prebuilt": "2.1.14",
"proj4": "2.3.15",
"resemblejs": "2.2.2",
"serve-files": "1.0.0",
@@ -100,7 +100,7 @@
"openlayers-internal/no-duplicate-requires": 2,
"openlayers-internal/no-missing-requires": 1,
"openlayers-internal/no-unused-requires": 2,
"openlayers-internal/one-provide": 1,
"openlayers-internal/one-provide": 2,
"openlayers-internal/requires-first": 2,
"openlayers-internal/valid-provide": 2,
"openlayers-internal/valid-requires": 2

View File

@@ -145,13 +145,13 @@ ol.Collection.prototype.pop = function() {
/**
* Insert the provided element at the end of the collection.
* @param {T} elem Element.
* @return {number} Length.
* @return {number} New length of the collection.
* @api stable
*/
ol.Collection.prototype.push = function(elem) {
var n = this.array_.length;
var n = this.getLength();
this.insertAt(n, elem);
return n;
return this.getLength();
};

View File

@@ -13,34 +13,13 @@ goog.require('ol.math');
ol.color.HEX_COLOR_RE_ = /^#(?:[0-9a-f]{3}){1,2}$/i;
/**
* Regular expression for matching and capturing RGB style strings.
* @const
* @type {RegExp}
* @private
*/
ol.color.RGB_COLOR_RE_ =
/^(?:rgb)?\((0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2})\)$/i;
/**
* Regular expression for matching and capturing RGBA style strings.
* @const
* @type {RegExp}
* @private
*/
ol.color.RGBA_COLOR_RE_ =
/^(?:rgba)?\((0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|1|0\.\d{0,16})\)$/i;
/**
* Regular expression for matching potential named color style strings.
* @const
* @type {RegExp}
* @private
*/
ol.color.NAMED_COLOR_RE_ =
/^([a-z]*)$/i;
ol.color.NAMED_COLOR_RE_ = /^([a-z]*)$/i;
/**
@@ -151,7 +130,7 @@ ol.color.fromString = (
* @return {ol.Color} Color.
*/
ol.color.fromStringInternal_ = function(s) {
var r, g, b, a, color, match;
var r, g, b, a, color, parts;
if (ol.color.NAMED_COLOR_RE_.exec(s)) {
s = ol.color.fromNamed(s);
@@ -171,17 +150,13 @@ ol.color.fromStringInternal_ = function(s) {
}
a = 1;
color = [r, g, b, a];
} else if ((match = ol.color.RGBA_COLOR_RE_.exec(s))) { // rgba()
r = Number(match[1]);
g = Number(match[2]);
b = Number(match[3]);
a = Number(match[4]);
color = ol.color.normalize([r, g, b, a]);
} else if ((match = ol.color.RGB_COLOR_RE_.exec(s))) { // rgb()
r = Number(match[1]);
g = Number(match[2]);
b = Number(match[3]);
color = ol.color.normalize([r, g, b, 1]);
} else if (s.indexOf('rgba(') == 0) { // rgba()
parts = s.slice(5, -1).split(',').map(Number);
color = ol.color.normalize(parts);
} else if (s.indexOf('rgb(') == 0) { // rgb()
parts = s.slice(4, -1).split(',').map(Number);
parts.push(1);
color = ol.color.normalize(parts);
} else {
ol.asserts.assert(false, 14); // Invalid color
}

View File

@@ -157,6 +157,7 @@ ol.control.Attribution.prototype.getSourceAttributions = function(frameState) {
var attributions = ol.obj.assign({}, frameState.attributions);
/** @type {Object.<string, ol.Attribution>} */
var hiddenAttributions = {};
var uniqueAttributions = {};
var projection = /** @type {!ol.proj.Projection} */ (frameState.viewState.projection);
for (i = 0, ii = layerStatesArray.length; i < ii; i++) {
source = layerStatesArray[i].layer.getSource();
@@ -186,7 +187,11 @@ ol.control.Attribution.prototype.getSourceAttributions = function(frameState) {
if (sourceAttributionKey in hiddenAttributions) {
delete hiddenAttributions[sourceAttributionKey];
}
attributions[sourceAttributionKey] = sourceAttribution;
var html = sourceAttribution.getHTML();
if (!(html in uniqueAttributions)) {
uniqueAttributions[html] = true;
attributions[sourceAttributionKey] = sourceAttribution;
}
} else {
hiddenAttributions[sourceAttributionKey] = sourceAttribution;
}

View File

@@ -5,7 +5,6 @@ goog.require('ol.Collection');
goog.require('ol.Map');
goog.require('ol.MapEvent');
goog.require('ol.Object');
goog.require('ol.ObjectEventType');
goog.require('ol.Overlay');
goog.require('ol.View');
goog.require('ol.control.Control');
@@ -166,7 +165,7 @@ ol.control.OverviewMap.prototype.setMap = function(map) {
if (map) {
this.listenerKeys.push(ol.events.listen(
map, ol.ObjectEventType.PROPERTYCHANGE,
map, ol.Object.EventType.PROPERTYCHANGE,
this.handleMapPropertyChange_, this));
// TODO: to really support map switching, this would need to be reworked
@@ -188,7 +187,7 @@ ol.control.OverviewMap.prototype.setMap = function(map) {
/**
* Handle map property changes. This only deals with changes to the map's view.
* @param {ol.ObjectEvent} event The propertychange event.
* @param {ol.Object.Event} event The propertychange event.
* @private
*/
ol.control.OverviewMap.prototype.handleMapPropertyChange_ = function(event) {

View File

@@ -6,7 +6,7 @@ goog.require('ol.asserts');
goog.require('ol.control.Control');
goog.require('ol.css');
goog.require('ol.events');
goog.require('ol.proj.METERS_PER_UNIT');
goog.require('ol.proj');
goog.require('ol.proj.Units');
@@ -169,7 +169,7 @@ ol.control.ScaleLine.prototype.updateElement_ = function() {
var projection = viewState.projection;
var metersPerUnit = projection.getMetersPerUnit();
var pointResolution =
projection.getPointResolution(viewState.resolution, center) *
ol.proj.getPointResolution(projection, viewState.resolution, center) *
metersPerUnit;
var nominalCount = this.minWidth_ * pointResolution;

View File

@@ -1,6 +1,6 @@
goog.provide('ol.events.condition');
goog.require('ol.MapBrowserEvent.EventType');
goog.require('ol.MapBrowserEvent');
goog.require('ol.asserts');
goog.require('ol.functions');
goog.require('ol.has');

12
src/ol/extent/corner.js Normal file
View File

@@ -0,0 +1,12 @@
goog.provide('ol.extent.Corner');
/**
* Extent corner.
* @enum {string}
*/
ol.extent.Corner = {
BOTTOM_LEFT: 'bottom-left',
BOTTOM_RIGHT: 'bottom-right',
TOP_LEFT: 'top-left',
TOP_RIGHT: 'top-right'
};

View File

@@ -1,35 +1,9 @@
goog.provide('ol.extent');
goog.provide('ol.extent.Corner');
goog.provide('ol.extent.Relationship');
goog.require('ol');
goog.require('ol.asserts');
/**
* Extent corner.
* @enum {string}
*/
ol.extent.Corner = {
BOTTOM_LEFT: 'bottom-left',
BOTTOM_RIGHT: 'bottom-right',
TOP_LEFT: 'top-left',
TOP_RIGHT: 'top-right'
};
/**
* Relationship to an extent.
* @enum {number}
*/
ol.extent.Relationship = {
UNKNOWN: 0,
INTERSECTING: 1,
ABOVE: 2,
RIGHT: 4,
BELOW: 8,
LEFT: 16
};
goog.require('ol.extent.Corner');
goog.require('ol.extent.Relationship');
/**

View File

@@ -0,0 +1,15 @@
goog.provide('ol.extent.Relationship');
/**
* Relationship to an extent.
* @enum {number}
*/
ol.extent.Relationship = {
UNKNOWN: 0,
INTERSECTING: 1,
ABOVE: 2,
RIGHT: 4,
BELOW: 8,
LEFT: 16
};

View File

@@ -66,12 +66,13 @@ ol.format.GPX.SCHEMA_LOCATION_ = 'http://www.topografix.com/GPX/1/1 ' +
/**
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {ol.LayoutOptions} layoutOptions Layout options.
* @param {Node} node Node.
* @param {Object} values Values.
* @private
* @return {Array.<number>} Flat coordinates.
*/
ol.format.GPX.appendCoordinate_ = function(flatCoordinates, node, values) {
ol.format.GPX.appendCoordinate_ = function(flatCoordinates, layoutOptions, node, values) {
ol.DEBUG && console.assert(node.nodeType == Node.ELEMENT_NODE,
'node.nodeType should be ELEMENT');
flatCoordinates.push(
@@ -80,12 +81,14 @@ ol.format.GPX.appendCoordinate_ = function(flatCoordinates, node, values) {
if ('ele' in values) {
flatCoordinates.push(/** @type {number} */ (values['ele']));
delete values['ele'];
layoutOptions.hasZ = true;
} else {
flatCoordinates.push(0);
}
if ('time' in values) {
flatCoordinates.push(/** @type {number} */ (values['time']));
delete values['time'];
layoutOptions.hasM = true;
} else {
flatCoordinates.push(0);
}
@@ -93,6 +96,51 @@ ol.format.GPX.appendCoordinate_ = function(flatCoordinates, node, values) {
};
/**
* Choose GeometryLayout based on flags in layoutOptions and adjust flatCoordinates
* and ends arrays by shrinking them accordingly (removing unused zero entries).
*
* @param {ol.LayoutOptions} layoutOptions Layout options.
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {Array.<number>=} ends Ends.
* @return {ol.geom.GeometryLayout} Layout.
*/
ol.format.GPX.applyLayoutOptions_ = function(layoutOptions, flatCoordinates, ends) {
var layout = ol.geom.GeometryLayout.XY;
var stride = 2;
if (layoutOptions.hasZ && layoutOptions.hasM) {
layout = ol.geom.GeometryLayout.XYZM;
stride = 4;
} else if (layoutOptions.hasZ) {
layout = ol.geom.GeometryLayout.XYZ;
stride = 3;
} else if (layoutOptions.hasM) {
layout = ol.geom.GeometryLayout.XYM;
stride = 3;
}
if (stride !== 4) {
var i, ii;
for (i = 0, ii = flatCoordinates.length / 4; i < ii; i++) {
flatCoordinates[i * stride] = flatCoordinates[i * 4];
flatCoordinates[i * stride + 1] = flatCoordinates[i * 4 + 1];
if (layoutOptions.hasZ) {
flatCoordinates[i * stride + 2] = flatCoordinates[i * 4 + 2];
}
if (layoutOptions.hasM) {
flatCoordinates[i * stride + 2] = flatCoordinates[i * 4 + 3];
}
}
flatCoordinates.length = flatCoordinates.length / 4 * stride;
if (ends) {
for (i = 0, ii = ends.length; i < ii; i++) {
ends[i] = ends[i] / 4 * stride;
}
}
}
return layout;
};
/**
* @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack.
@@ -141,7 +189,9 @@ ol.format.GPX.parseRtePt_ = function(node, objectStack) {
var rteValues = /** @type {Object} */ (objectStack[objectStack.length - 1]);
var flatCoordinates = /** @type {Array.<number>} */
(rteValues['flatCoordinates']);
ol.format.GPX.appendCoordinate_(flatCoordinates, node, values);
var layoutOptions = /** @type {ol.LayoutOptions} */
(rteValues['layoutOptions']);
ol.format.GPX.appendCoordinate_(flatCoordinates, layoutOptions, node, values);
}
};
@@ -161,7 +211,9 @@ ol.format.GPX.parseTrkPt_ = function(node, objectStack) {
var trkValues = /** @type {Object} */ (objectStack[objectStack.length - 1]);
var flatCoordinates = /** @type {Array.<number>} */
(trkValues['flatCoordinates']);
ol.format.GPX.appendCoordinate_(flatCoordinates, node, values);
var layoutOptions = /** @type {ol.LayoutOptions} */
(trkValues['layoutOptions']);
ol.format.GPX.appendCoordinate_(flatCoordinates, layoutOptions, node, values);
}
};
@@ -197,7 +249,8 @@ ol.format.GPX.readRte_ = function(node, objectStack) {
ol.DEBUG && console.assert(node.localName == 'rte', 'localName should be rte');
var options = /** @type {olx.format.ReadOptions} */ (objectStack[0]);
var values = ol.xml.pushParseAndPop({
'flatCoordinates': []
'flatCoordinates': [],
'layoutOptions': {}
}, ol.format.GPX.RTE_PARSERS_, node, objectStack);
if (!values) {
return undefined;
@@ -205,8 +258,11 @@ ol.format.GPX.readRte_ = function(node, objectStack) {
var flatCoordinates = /** @type {Array.<number>} */
(values['flatCoordinates']);
delete values['flatCoordinates'];
var layoutOptions = /** @type {ol.LayoutOptions} */ (values['layoutOptions']);
delete values['layoutOptions'];
var layout = ol.format.GPX.applyLayoutOptions_(layoutOptions, flatCoordinates);
var geometry = new ol.geom.LineString(null);
geometry.setFlatCoordinates(ol.geom.GeometryLayout.XYZM, flatCoordinates);
geometry.setFlatCoordinates(layout, flatCoordinates);
ol.format.Feature.transformWithOptions(geometry, false, options);
var feature = new ol.Feature(geometry);
feature.setProperties(values);
@@ -227,7 +283,8 @@ ol.format.GPX.readTrk_ = function(node, objectStack) {
var options = /** @type {olx.format.ReadOptions} */ (objectStack[0]);
var values = ol.xml.pushParseAndPop({
'flatCoordinates': [],
'ends': []
'ends': [],
'layoutOptions': {}
}, ol.format.GPX.TRK_PARSERS_, node, objectStack);
if (!values) {
return undefined;
@@ -237,9 +294,11 @@ ol.format.GPX.readTrk_ = function(node, objectStack) {
delete values['flatCoordinates'];
var ends = /** @type {Array.<number>} */ (values['ends']);
delete values['ends'];
var layoutOptions = /** @type {ol.LayoutOptions} */ (values['layoutOptions']);
delete values['layoutOptions'];
var layout = ol.format.GPX.applyLayoutOptions_(layoutOptions, flatCoordinates, ends);
var geometry = new ol.geom.MultiLineString(null);
geometry.setFlatCoordinates(
ol.geom.GeometryLayout.XYZM, flatCoordinates, ends);
geometry.setFlatCoordinates(layout, flatCoordinates, ends);
ol.format.Feature.transformWithOptions(geometry, false, options);
var feature = new ol.Feature(geometry);
feature.setProperties(values);
@@ -263,9 +322,10 @@ ol.format.GPX.readWpt_ = function(node, objectStack) {
if (!values) {
return undefined;
}
var coordinates = ol.format.GPX.appendCoordinate_([], node, values);
var geometry = new ol.geom.Point(
coordinates, ol.geom.GeometryLayout.XYZM);
var layoutOptions = /** @type {ol.LayoutOptions} */ ({});
var coordinates = ol.format.GPX.appendCoordinate_([], layoutOptions, node, values);
var layout = ol.format.GPX.applyLayoutOptions_(layoutOptions, coordinates);
var geometry = new ol.geom.Point(coordinates, layout);
ol.format.Feature.transformWithOptions(geometry, false, options);
var feature = new ol.Feature(geometry);
feature.setProperties(values);

View File

@@ -311,11 +311,8 @@ ol.format.KML.createNameStyleFunction_ = function(foundStyle, name) {
if (imageSize === null) {
imageSize = ol.format.KML.DEFAULT_IMAGE_STYLE_SIZE_;
}
var imageScale = foundStyle.getImage().getScale();
if (isNaN(imageScale)) {
imageScale = ol.format.KML.DEFAULT_IMAGE_SCALE_MULTIPLIER_;
}
if (imageSize.length == 2) {
var imageScale = foundStyle.getImage().getScale();
// Offset the label to be centered to the right of the icon, if there is
// one.
textOffset[0] = imageScale * imageSize[0] / 2;
@@ -543,9 +540,7 @@ ol.format.KML.readStyleMapValue_ = function(node, objectStack) {
return ol.xml.pushParseAndPop(undefined,
ol.format.KML.STYLE_MAP_PARSERS_, node, objectStack);
};
/**
/**
* @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack.
* @private
@@ -621,11 +616,6 @@ ol.format.KML.IconStyleParser_ = function(node, objectStack) {
var scale = /** @type {number|undefined} */
(object['scale']);
if (isNaN(scale) || scale === undefined) {
scale = ol.format.KML.DEFAULT_IMAGE_SCALE_MULTIPLIER_;
} else {
scale = scale * ol.format.KML.DEFAULT_IMAGE_SCALE_MULTIPLIER_;
}
if (drawIcon) {
if (src == ol.format.KML.DEFAULT_IMAGE_STYLE_SRC_) {
@@ -1166,14 +1156,13 @@ ol.format.KML.DataParser_ = function(node, objectStack) {
'node.nodeType should be ELEMENT');
ol.DEBUG && console.assert(node.localName == 'Data', 'localName should be Data');
var name = node.getAttribute('name');
ol.xml.parseNode(ol.format.KML.DATA_PARSERS_, node, objectStack);
var featureObject =
/** @type {Object} */ (objectStack[objectStack.length - 1]);
if (name !== null) {
var data = ol.xml.pushParseAndPop(
undefined, ol.format.KML.DATA_PARSERS_, node, objectStack);
if (data) {
var featureObject =
/** @type {Object} */ (objectStack[objectStack.length - 1]);
featureObject[name] = data;
}
featureObject[name] = featureObject.value;
} else if (featureObject.displayName !== null) {
featureObject[featureObject.displayName] = featureObject.value;
}
};
@@ -1191,6 +1180,18 @@ ol.format.KML.ExtendedDataParser_ = function(node, objectStack) {
ol.xml.parseNode(ol.format.KML.EXTENDED_DATA_PARSERS_, node, objectStack);
};
/**
* @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack.
* @private
*/
ol.format.KML.RegionParser_ = function(node, objectStack) {
ol.DEBUG && console.assert(node.nodeType == Node.ELEMENT_NODE,
'node.nodeType should be ELEMENT');
ol.DEBUG && console.assert(node.localName == 'Region',
'localName should be Region');
ol.xml.parseNode(ol.format.KML.REGION_PARSERS_, node, objectStack);
};
/**
* @param {Node} node Node.
@@ -1282,6 +1283,56 @@ ol.format.KML.SimpleDataParser_ = function(node, objectStack) {
};
/**
* @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack.
* @private
*/
ol.format.KML.LatLonAltBoxParser_ = function(node, objectStack) {
ol.DEBUG && console.assert(node.nodeType == Node.ELEMENT_NODE,
'node.nodeType should be ELEMENT');
ol.DEBUG && console.assert(node.localName == 'LatLonAltBox',
'localName should be LatLonAltBox');
var object = ol.xml.pushParseAndPop({}, ol.format.KML.LAT_LON_ALT_BOX_PARSERS_, node, objectStack);
if (!object) {
return;
}
var regionObject = /** @type {Object} */ (objectStack[objectStack.length - 1]);
var extent = [
parseFloat(object['west']),
parseFloat(object['south']),
parseFloat(object['east']),
parseFloat(object['north'])
];
regionObject['extent'] = extent;
regionObject['altitudeMode'] = object['altitudeMode'];
regionObject['minAltitude'] = parseFloat(object['minAltitude']);
regionObject['maxAltitude'] = parseFloat(object['maxAltitude']);
};
/**
* @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack.
* @private
*/
ol.format.KML.LodParser_ = function(node, objectStack) {
ol.DEBUG && console.assert(node.nodeType == Node.ELEMENT_NODE,
'node.nodeType should be ELEMENT');
ol.DEBUG && console.assert(node.localName == 'Lod',
'localName should be Lod');
var object = ol.xml.pushParseAndPop({}, ol.format.KML.LOD_PARSERS_, node, objectStack);
if (!object) {
return;
}
var lodObject = /** @type {Object} */ (objectStack[objectStack.length - 1]);
lodObject['minLodPixels'] = parseFloat(object['minLodPixels']);
lodObject['maxLodPixels'] = parseFloat(object['maxLodPixels']);
lodObject['minFadeExtent'] = parseFloat(object['minFadeExtent']);
lodObject['maxFadeExtent'] = parseFloat(object['maxFadeExtent']);
};
/**
* @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack.
@@ -1370,7 +1421,8 @@ ol.format.KML.whenParser_ = function(node, objectStack) {
*/
ol.format.KML.DATA_PARSERS_ = ol.xml.makeStructureNS(
ol.format.KML.NAMESPACE_URIS_, {
'value': ol.xml.makeReplacer(ol.format.XSD.readString)
'displayName': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
'value': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString)
});
@@ -1386,6 +1438,49 @@ ol.format.KML.EXTENDED_DATA_PARSERS_ = ol.xml.makeStructureNS(
});
/**
* @const
* @type {Object.<string, Object.<string, ol.XmlParser>>}
* @private
*/
ol.format.KML.REGION_PARSERS_ = ol.xml.makeStructureNS(
ol.format.KML.NAMESPACE_URIS_, {
'LatLonAltBox': ol.format.KML.LatLonAltBoxParser_,
'Lod': ol.format.KML.LodParser_
});
/**
* @const
* @type {Object.<string, Object.<string, ol.XmlParser>>}
* @private
*/
ol.format.KML.LAT_LON_ALT_BOX_PARSERS_ = ol.xml.makeStructureNS(
ol.format.KML.NAMESPACE_URIS_, {
'altitudeMode': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
'minAltitude': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
'maxAltitude': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
'north': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
'south': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
'east': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
'west': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal)
});
/**
* @const
* @type {Object.<string, Object.<string, ol.XmlParser>>}
* @private
*/
ol.format.KML.LOD_PARSERS_ = ol.xml.makeStructureNS(
ol.format.KML.NAMESPACE_URIS_, {
'minLodPixels': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
'maxLodPixels': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
'minFadeExtent': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal),
'maxFadeExtent': ol.xml.makeObjectPropertySetter(ol.format.XSD.readDecimal)
});
/**
* @const
* @type {Object.<string, Object.<string, ol.XmlParser>>}
@@ -1546,6 +1641,7 @@ ol.format.KML.GX_MULTITRACK_GEOMETRY_PARSERS_ = ol.xml.makeStructureNS(
ol.format.KML.NETWORK_LINK_PARSERS_ = ol.xml.makeStructureNS(
ol.format.KML.NAMESPACE_URIS_, {
'ExtendedData': ol.format.KML.ExtendedDataParser_,
'Region': ol.format.KML.RegionParser_,
'Link': ol.format.KML.LinkParser_,
'address': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
'description': ol.xml.makeObjectPropertySetter(ol.format.XSD.readString),
@@ -1599,6 +1695,7 @@ ol.format.KML.PAIR_PARSERS_ = ol.xml.makeStructureNS(
ol.format.KML.PLACEMARK_PARSERS_ = ol.xml.makeStructureNS(
ol.format.KML.NAMESPACE_URIS_, {
'ExtendedData': ol.format.KML.ExtendedDataParser_,
'Region': ol.format.KML.RegionParser_,
'MultiGeometry': ol.xml.makeObjectPropertySetter(
ol.format.KML.readMultiGeometry_, 'geometry'),
'LineString': ol.xml.makeObjectPropertySetter(
@@ -2044,6 +2141,72 @@ ol.format.KML.prototype.readNetworkLinksFromNode = function(node) {
};
/**
* Read the regions of the KML.
*
* @param {Document|Node|string} source Source.
* @return {Array.<Object>} Regions.
* @api
*/
ol.format.KML.prototype.readRegion = function(source) {
var regions = [];
if (ol.xml.isDocument(source)) {
ol.array.extend(regions, this.readRegionFromDocument(
/** @type {Document} */ (source)));
} else if (ol.xml.isNode(source)) {
ol.array.extend(regions, this.readRegionFromNode(
/** @type {Node} */ (source)));
} else if (typeof source === 'string') {
var doc = ol.xml.parse(source);
ol.array.extend(regions, this.readRegionFromDocument(doc));
}
return regions;
};
/**
* @param {Document} doc Document.
* @return {Array.<Object>} Region.
*/
ol.format.KML.prototype.readRegionFromDocument = function(doc) {
var n, regions = [];
for (n = doc.firstChild; n; n = n.nextSibling) {
if (n.nodeType == Node.ELEMENT_NODE) {
ol.array.extend(regions, this.readRegionFromNode(n));
}
}
return regions;
};
/**
* @param {Node} node Node.
* @return {Array.<Object>} Region.
* @api
*/
ol.format.KML.prototype.readRegionFromNode = function(node) {
var n, regions = [];
for (n = node.firstElementChild; n; n = n.nextElementSibling) {
if (ol.array.includes(ol.format.KML.NAMESPACE_URIS_, n.namespaceURI) &&
n.localName == 'Region') {
var obj = ol.xml.pushParseAndPop({}, ol.format.KML.REGION_PARSERS_,
n, []);
regions.push(obj);
}
}
for (n = node.firstElementChild; n; n = n.nextElementSibling) {
var localName = n.localName;
if (ol.array.includes(ol.format.KML.NAMESPACE_URIS_, n.namespaceURI) &&
(localName == 'Document' ||
localName == 'Folder' ||
localName == 'kml')) {
ol.array.extend(regions, this.readRegionFromNode(n));
}
}
return regions;
};
/**
* Read the projection from a KML source.
*
@@ -2115,6 +2278,54 @@ ol.format.KML.writeCoordinatesTextNode_ = function(node, coordinates, objectStac
};
/**
* @param {Node} node Node.
* @param {{name: *, value: *}} pair Name value pair.
* @param {Array.<*>} objectStack Object stack.
* @private
*/
ol.format.KML.writeDataNode_ = function(node, pair, objectStack) {
node.setAttribute('name', pair.name);
var /** @type {ol.XmlNodeStackItem} */ context = {node: node};
var value = pair.value;
if (typeof value == 'object') {
if (value !== null && value.displayName) {
ol.xml.pushSerializeAndPop(context, ol.format.KML.EXTENDEDDATA_NODE_SERIALIZERS_,
ol.xml.OBJECT_PROPERTY_NODE_FACTORY, [value.displayName], objectStack, ['displayName']);
}
if (value !== null && value.value) {
ol.xml.pushSerializeAndPop(context, ol.format.KML.EXTENDEDDATA_NODE_SERIALIZERS_,
ol.xml.OBJECT_PROPERTY_NODE_FACTORY, [value.value], objectStack, ['value']);
}
} else {
ol.xml.pushSerializeAndPop(context, ol.format.KML.EXTENDEDDATA_NODE_SERIALIZERS_,
ol.xml.OBJECT_PROPERTY_NODE_FACTORY, [value], objectStack, ['value']);
}
};
/**
* @param {Node} node Node to append a TextNode with the name to.
* @param {string} name DisplayName.
* @private
*/
ol.format.KML.writeDataNodeName_ = function(node, name) {
ol.format.XSD.writeCDATASection(node, name);
};
/**
* @param {Node} node Node to append a CDATA Section with the value to.
* @param {string} value Value.
* @private
*/
ol.format.KML.writeDataNodeValue_ = function(node, value) {
ol.format.XSD.writeStringTextNode(node, value);
};
/**
* @param {Node} node Node.
* @param {Array.<ol.Feature>} features Features.
@@ -2130,6 +2341,24 @@ ol.format.KML.writeDocument_ = function(node, features, objectStack) {
};
/**
* @param {Node} node Node.
* @param {{names: Array<string>, values: (Array<*>)}} namesAndValues Names and values.
* @param {Array.<*>} objectStack Object stack.
* @private
*/
ol.format.KML.writeExtendedData_ = function(node, namesAndValues, objectStack) {
var /** @type {ol.XmlNodeStackItem} */ context = {node: node};
var names = namesAndValues.names, values = namesAndValues.values;
var length = names.length;
for (var i = 0; i < length; i++) {
ol.xml.pushSerializeAndPop(context, ol.format.KML.EXTENDEDDATA_NODE_SERIALIZERS_,
ol.format.KML.DATA_NODE_FACTORY_, [{name: names[i], value: values[i]}], objectStack);
}
};
/**
* @param {Node} node Node.
* @param {Object} icon Icon object.
@@ -2327,6 +2556,21 @@ ol.format.KML.writePlacemark_ = function(node, feature, objectStack) {
// serialize properties (properties unknown to KML are not serialized)
var properties = feature.getProperties();
// don't export these to ExtendedData
var filter = {'address': 1, 'description': 1, 'name': 1, 'open': 1,
'phoneNumber': 1, 'styleUrl': 1, 'visibility': 1};
filter[feature.getGeometryName()] = 1;
var keys = Object.keys(properties || {}).sort().filter(function(v) {
return !filter[v];
});
if (keys.length > 0) {
var sequence = ol.xml.makeSequence(properties, keys);
var namesAndValues = {names: keys, values: sequence};
ol.xml.pushSerializeAndPop(context, ol.format.KML.PLACEMARK_SERIALIZERS_,
ol.format.KML.EXTENDEDDATA_NODE_FACTORY_, [namesAndValues], objectStack);
}
var styleFunction = feature.getStyleFunction();
if (styleFunction) {
// FIXME the styles returned by the style function are supposed to be
@@ -2431,7 +2675,7 @@ ol.format.KML.writePolyStyle_ = function(node, style, objectStack) {
ol.format.KML.writeScaleTextNode_ = function(node, scale) {
// the Math is to remove any excess decimals created by float arithmetic
ol.format.XSD.writeDecimalTextNode(node,
Math.round(scale * scale * 1e6) / 1e6);
Math.round(scale * 1e6) / 1e6);
};
@@ -2515,6 +2759,19 @@ ol.format.KML.DOCUMENT_SERIALIZERS_ = ol.xml.makeStructureNS(
});
/**
* @const
* @type {Object.<string, Object.<string, ol.XmlSerializer>>}
* @private
*/
ol.format.KML.EXTENDEDDATA_NODE_SERIALIZERS_ = ol.xml.makeStructureNS(
ol.format.KML.NAMESPACE_URIS_, {
'Data': ol.xml.makeChildAppender(ol.format.KML.writeDataNode_),
'value': ol.xml.makeChildAppender(ol.format.KML.writeDataNodeValue_),
'displayName': ol.xml.makeChildAppender(ol.format.KML.writeDataNodeName_)
});
/**
* @const
* @type {Object.<string, string>}
@@ -2682,6 +2939,8 @@ ol.format.KML.PLACEMARK_SEQUENCE_ = ol.xml.makeStructureNS(
*/
ol.format.KML.PLACEMARK_SERIALIZERS_ = ol.xml.makeStructureNS(
ol.format.KML.NAMESPACE_URIS_, {
'ExtendedData': ol.xml.makeChildAppender(
ol.format.KML.writeExtendedData_),
'MultiGeometry': ol.xml.makeChildAppender(
ol.format.KML.writeMultiGeometry_),
'LineString': ol.xml.makeChildAppender(
@@ -2837,6 +3096,26 @@ ol.format.KML.COORDINATES_NODE_FACTORY_ =
ol.xml.makeSimpleNodeFactory('coordinates');
/**
* A factory for creating Data nodes.
* @const
* @type {function(*, Array.<*>): (Node|undefined)}
* @private
*/
ol.format.KML.DATA_NODE_FACTORY_ =
ol.xml.makeSimpleNodeFactory('Data');
/**
* A factory for creating ExtendedData nodes.
* @const
* @type {function(*, Array.<*>): (Node|undefined)}
* @private
*/
ol.format.KML.EXTENDEDDATA_NODE_FACTORY_ =
ol.xml.makeSimpleNodeFactory('ExtendedData');
/**
* A factory for creating innerBoundaryIs nodes.
* @const

View File

@@ -251,6 +251,32 @@ ol.format.WMTSCapabilities.readTileMatrix_ = function(node, objectStack) {
};
/**
* @private
* @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack.
* @return {Object|undefined} TileMatrixSetLimits Object.
*/
ol.format.WMTSCapabilities.readTileMatrixLimitsList_ = function(node,
objectStack) {
return ol.xml.pushParseAndPop([],
ol.format.WMTSCapabilities.TMS_LIMITS_LIST_PARSERS_, node,
objectStack);
};
/**
* @private
* @param {Node} node Node.
* @param {Array.<*>} objectStack Object stack.
* @return {Object|undefined} TileMatrixLimits Array.
*/
ol.format.WMTSCapabilities.readTileMatrixLimits_ = function(node, objectStack) {
return ol.xml.pushParseAndPop({},
ol.format.WMTSCapabilities.TMS_LIMITS_PARSERS_, node, objectStack);
};
/**
* @const
* @private
@@ -353,7 +379,40 @@ ol.format.WMTSCapabilities.STYLE_PARSERS_ = ol.xml.makeStructureNS(
ol.format.WMTSCapabilities.TMS_LINKS_PARSERS_ = ol.xml.makeStructureNS(
ol.format.WMTSCapabilities.NAMESPACE_URIS_, {
'TileMatrixSet': ol.xml.makeObjectPropertySetter(
ol.format.XSD.readString)
ol.format.XSD.readString),
'TileMatrixSetLimits': ol.xml.makeObjectPropertySetter(
ol.format.WMTSCapabilities.readTileMatrixLimitsList_)
});
/**
* @const
* @type {Object.<string, Object.<string, ol.XmlParser>>}
* @private
*/
ol.format.WMTSCapabilities.TMS_LIMITS_LIST_PARSERS_ = ol.xml.makeStructureNS(
ol.format.WMTSCapabilities.NAMESPACE_URIS_, {
'TileMatrixLimits': ol.xml.makeArrayPusher(
ol.format.WMTSCapabilities.readTileMatrixLimits_)
});
/**
* @const
* @type {Object.<string, Object.<string, ol.XmlParser>>}
* @private
*/
ol.format.WMTSCapabilities.TMS_LIMITS_PARSERS_ = ol.xml.makeStructureNS(
ol.format.WMTSCapabilities.NAMESPACE_URIS_, {
'TileMatrix': ol.xml.makeObjectPropertySetter(
ol.format.XSD.readString),
'MinTileRow': ol.xml.makeObjectPropertySetter(
ol.format.XSD.readNonNegativeInteger),
'MaxTileRow': ol.xml.makeObjectPropertySetter(
ol.format.XSD.readNonNegativeInteger),
'MinTileCol': ol.xml.makeObjectPropertySetter(
ol.format.XSD.readNonNegativeInteger),
'MaxTileCol': ol.xml.makeObjectPropertySetter(
ol.format.XSD.readNonNegativeInteger)
});

View File

@@ -114,6 +114,15 @@ ol.format.XSD.writeBooleanTextNode = function(node, bool) {
};
/**
* @param {Node} node Node to append a CDATA Section with the string to.
* @param {string} string String.
*/
ol.format.XSD.writeCDATASection = function(node, string) {
node.appendChild(ol.xml.DOCUMENT.createCDATASection(string));
};
/**
* @param {Node} node Node to append a TextNode with the dateTime to.
* @param {number} dateTime DateTime in seconds.

View File

@@ -36,22 +36,30 @@ ol.geom.flat.contains.linearRingContainsExtent = function(flatCoordinates, offse
* @return {boolean} Contains (x, y).
*/
ol.geom.flat.contains.linearRingContainsXY = function(flatCoordinates, offset, end, stride, x, y) {
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
var contains = false;
// http://geomalgorithms.com/a03-_inclusion.html
// Copyright 2000 softSurfer, 2012 Dan Sunday
// This code may be freely used and modified for any purpose
// providing that this copyright notice is included with it.
// SoftSurfer makes no warranty for this code, and cannot be held
// liable for any real or imagined damage resulting from its use.
// Users of this code must verify correctness for their application.
var wn = 0;
var x1 = flatCoordinates[end - stride];
var y1 = flatCoordinates[end - stride + 1];
for (; offset < end; offset += stride) {
var x2 = flatCoordinates[offset];
var y2 = flatCoordinates[offset + 1];
var intersect = ((y1 > y) != (y2 > y)) &&
(x < (x2 - x1) * (y - y1) / (y2 - y1) + x1);
if (intersect) {
contains = !contains;
if (y1 <= y) {
if (y2 > y && ((x2 - x1) * (y - y1)) - ((x - x1) * (y2 - y1)) > 0) {
wn++;
}
} else if (y2 <= y && ((x2 - x1) * (y - y1)) - ((x - x1) * (y2 - y1)) < 0) {
wn--;
}
x1 = x2;
y1 = y2;
}
return contains;
return wn !== 0;
};

View File

@@ -80,7 +80,7 @@ ol.geom.flat.interpolate.lineString = function(flatCoordinates, offset, end, str
* @param {boolean} extrapolate Extrapolate.
* @return {ol.Coordinate} Coordinate.
*/
ol.geom.flat.lineStringCoordinateAtM = function(flatCoordinates, offset, end, stride, m, extrapolate) {
ol.geom.flat.interpolate.lineStringCoordinateAtM = function(flatCoordinates, offset, end, stride, m, extrapolate) {
if (end == offset) {
return null;
}
@@ -147,10 +147,10 @@ ol.geom.flat.lineStringCoordinateAtM = function(flatCoordinates, offset, end, st
* @param {boolean} interpolate Interpolate.
* @return {ol.Coordinate} Coordinate.
*/
ol.geom.flat.lineStringsCoordinateAtM = function(
ol.geom.flat.interpolate.lineStringsCoordinateAtM = function(
flatCoordinates, offset, ends, stride, m, extrapolate, interpolate) {
if (interpolate) {
return ol.geom.flat.lineStringCoordinateAtM(
return ol.geom.flat.interpolate.lineStringCoordinateAtM(
flatCoordinates, offset, ends[ends.length - 1], stride, m, extrapolate);
}
var coordinate;
@@ -181,12 +181,12 @@ ol.geom.flat.lineStringsCoordinateAtM = function(
if (m < flatCoordinates[offset + stride - 1]) {
return null;
} else if (m <= flatCoordinates[end - 1]) {
return ol.geom.flat.lineStringCoordinateAtM(
return ol.geom.flat.interpolate.lineStringCoordinateAtM(
flatCoordinates, offset, end, stride, m, false);
}
offset = end;
}
ol.DEBUG && console.assert(false,
'ol.geom.flat.lineStringsCoordinateAtM should have returned');
'ol.geom.flat.interpolate.lineStringsCoordinateAtM should have returned');
return null;
};

View File

@@ -0,0 +1,20 @@
goog.provide('ol.geom.flat.topology');
goog.require('ol.geom.flat.area');
/**
* Check if the linestring is a boundary.
* @param {Array.<number>} flatCoordinates Flat coordinates.
* @param {number} offset Offset.
* @param {number} end End.
* @param {number} stride Stride.
* @return {boolean} The linestring is a boundary.
*/
ol.geom.flat.topology.lineStringIsClosed = function(flatCoordinates, offset, end, stride) {
var lastCoord = end - stride;
if (flatCoordinates[offset] === flatCoordinates[lastCoord] &&
flatCoordinates[offset + 1] === flatCoordinates[lastCoord + 1] && (end - offset) / stride > 3) {
return !!ol.geom.flat.area.linearRing(flatCoordinates, offset, end, stride);
}
return false;
};

View File

@@ -1,48 +1,13 @@
goog.provide('ol.geom.Geometry');
goog.provide('ol.geom.GeometryLayout');
goog.provide('ol.geom.GeometryType');
goog.require('ol');
goog.require('ol.functions');
goog.require('ol.Object');
goog.require('ol.extent');
goog.require('ol.functions');
goog.require('ol.proj');
goog.require('ol.proj.Units');
/**
* The geometry type. One of `'Point'`, `'LineString'`, `'LinearRing'`,
* `'Polygon'`, `'MultiPoint'`, `'MultiLineString'`, `'MultiPolygon'`,
* `'GeometryCollection'`, `'Circle'`.
* @enum {string}
*/
ol.geom.GeometryType = {
POINT: 'Point',
LINE_STRING: 'LineString',
LINEAR_RING: 'LinearRing',
POLYGON: 'Polygon',
MULTI_POINT: 'MultiPoint',
MULTI_LINE_STRING: 'MultiLineString',
MULTI_POLYGON: 'MultiPolygon',
GEOMETRY_COLLECTION: 'GeometryCollection',
CIRCLE: 'Circle'
};
/**
* The coordinate layout for geometries, indicating whether a 3rd or 4th z ('Z')
* or measure ('M') coordinate is available. Supported values are `'XY'`,
* `'XYZ'`, `'XYM'`, `'XYZM'`.
* @enum {string}
*/
ol.geom.GeometryLayout = {
XY: 'XY',
XYZ: 'XYZ',
XYM: 'XYM',
XYZM: 'XYZM'
};
/**
* @classdesc
* Abstract base class; normally only used for creating subclasses and not

View File

@@ -0,0 +1,15 @@
goog.provide('ol.geom.GeometryLayout');
/**
* The coordinate layout for geometries, indicating whether a 3rd or 4th z ('Z')
* or measure ('M') coordinate is available. Supported values are `'XY'`,
* `'XYZ'`, `'XYM'`, `'XYZM'`.
* @enum {string}
*/
ol.geom.GeometryLayout = {
XY: 'XY',
XYZ: 'XYZ',
XYM: 'XYM',
XYZM: 'XYZM'
};

View File

@@ -0,0 +1,20 @@
goog.provide('ol.geom.GeometryType');
/**
* The geometry type. One of `'Point'`, `'LineString'`, `'LinearRing'`,
* `'Polygon'`, `'MultiPoint'`, `'MultiLineString'`, `'MultiPolygon'`,
* `'GeometryCollection'`, `'Circle'`.
* @enum {string}
*/
ol.geom.GeometryType = {
POINT: 'Point',
LINE_STRING: 'LineString',
LINEAR_RING: 'LinearRing',
POLYGON: 'Polygon',
MULTI_POINT: 'MultiPoint',
MULTI_LINE_STRING: 'MultiLineString',
MULTI_POLYGON: 'MultiPolygon',
GEOMETRY_COLLECTION: 'GeometryCollection',
CIRCLE: 'Circle'
};

View File

@@ -147,7 +147,7 @@ ol.geom.LineString.prototype.getCoordinateAtM = function(m, opt_extrapolate) {
return null;
}
var extrapolate = opt_extrapolate !== undefined ? opt_extrapolate : false;
return ol.geom.flat.lineStringCoordinateAtM(this.flatCoordinates, 0,
return ol.geom.flat.interpolate.lineStringCoordinateAtM(this.flatCoordinates, 0,
this.flatCoordinates.length, this.stride, m, extrapolate);
};

View File

@@ -134,7 +134,7 @@ ol.geom.MultiLineString.prototype.getCoordinateAtM = function(m, opt_extrapolate
}
var extrapolate = opt_extrapolate !== undefined ? opt_extrapolate : false;
var interpolate = opt_interpolate !== undefined ? opt_interpolate : false;
return ol.geom.flat.lineStringsCoordinateAtM(this.flatCoordinates, 0,
return ol.geom.flat.interpolate.lineStringsCoordinateAtM(this.flatCoordinates, 0,
this.ends_, this.stride, m, extrapolate, interpolate);
};

View File

@@ -1,7 +1,7 @@
goog.provide('ol.interaction.DoubleClickZoom');
goog.require('ol');
goog.require('ol.MapBrowserEvent.EventType');
goog.require('ol.MapBrowserEvent');
goog.require('ol.interaction.Interaction');

View File

@@ -5,7 +5,7 @@ goog.require('ol.events');
goog.require('ol.extent');
goog.require('ol.events.Event');
goog.require('ol.Feature');
goog.require('ol.MapBrowserEvent.EventType');
goog.require('ol.MapBrowserEvent');
goog.require('ol.Object');
goog.require('ol.coordinate');
goog.require('ol.functions');

View File

@@ -2,7 +2,7 @@ goog.provide('ol.interaction.Extent');
goog.require('ol');
goog.require('ol.Feature');
goog.require('ol.MapBrowserEvent.EventType');
goog.require('ol.MapBrowserEvent');
goog.require('ol.MapBrowserPointerEvent');
goog.require('ol.coordinate');
goog.require('ol.events.Event');

View File

@@ -3,7 +3,7 @@ goog.provide('ol.interaction.Modify');
goog.require('ol');
goog.require('ol.Collection');
goog.require('ol.Feature');
goog.require('ol.MapBrowserEvent.EventType');
goog.require('ol.MapBrowserEvent');
goog.require('ol.MapBrowserPointerEvent');
goog.require('ol.View');
goog.require('ol.array');
@@ -198,7 +198,7 @@ ol.interaction.Modify.prototype.addFeature_ = function(feature) {
this.SEGMENT_WRITERS_[geometry.getType()].call(this, feature, geometry);
}
var map = this.getMap();
if (map) {
if (map && map.isRendered()) {
this.handlePointerAtPixel_(this.lastPixel_, map);
}
ol.events.listen(feature, ol.events.EventType.CHANGE,
@@ -580,7 +580,7 @@ ol.interaction.Modify.handleDragEvent_ = function(evt) {
var index = dragSegment[1];
while (vertex.length < geometry.getStride()) {
vertex.push(0);
vertex.push(segment[index][vertex.length]);
}
switch (geometry.getType()) {
@@ -823,16 +823,16 @@ ol.interaction.Modify.prototype.insertVertex_ = function(segmentData, vertex) {
* @api
*/
ol.interaction.Modify.prototype.removePoint = function() {
var handled = false;
if (this.lastPointerEvent_ && this.lastPointerEvent_.type != ol.MapBrowserEvent.EventType.POINTERDRAG) {
var evt = this.lastPointerEvent_;
this.willModifyFeatures_(evt);
handled = this.removeVertex_();
this.removeVertex_();
this.dispatchEvent(new ol.interaction.Modify.Event(
ol.interaction.Modify.EventType.MODIFYEND, this.features_, evt));
this.modified_ = false;
return true;
}
return handled;
return false;
};
/**

View File

@@ -27,6 +27,12 @@ ol.interaction.PinchZoom = function(opt_options) {
var options = opt_options ? opt_options : {};
/**
* @private
* @type {boolean}
*/
this.constrainResolution_ = options.constrainResolution || false;
/**
* @private
* @type {ol.Coordinate}
@@ -111,13 +117,15 @@ ol.interaction.PinchZoom.handleUpEvent_ = function(mapBrowserEvent) {
var map = mapBrowserEvent.map;
var view = map.getView();
view.setHint(ol.View.Hint.INTERACTING, -1);
var resolution = view.getResolution();
// Zoom to final resolution, with an animation, and provide a
// direction not to zoom out/in if user was pinching in/out.
// Direction is > 0 if pinching out, and < 0 if pinching in.
var direction = this.lastScaleDelta_ - 1;
ol.interaction.Interaction.zoom(map, view, resolution,
this.anchor_, this.duration_, direction);
if (this.constrainResolution_) {
var resolution = view.getResolution();
// Zoom to final resolution, with an animation, and provide a
// direction not to zoom out/in if user was pinching in/out.
// Direction is > 0 if pinching out, and < 0 if pinching in.
var direction = this.lastScaleDelta_ - 1;
ol.interaction.Interaction.zoom(map, view, resolution,
this.anchor_, this.duration_, direction);
}
return false;
} else {
return true;

View File

@@ -2,7 +2,7 @@ goog.provide('ol.interaction.Pointer');
goog.require('ol');
goog.require('ol.functions');
goog.require('ol.MapBrowserEvent.EventType');
goog.require('ol.MapBrowserEvent');
goog.require('ol.MapBrowserPointerEvent');
goog.require('ol.interaction.Interaction');
goog.require('ol.obj');

View File

@@ -82,6 +82,12 @@ ol.interaction.Select = function(opt_options) {
this.filter_ = options.filter ? options.filter :
ol.functions.TRUE;
/**
* @private
* @type {number}
*/
this.hitTolerance_ = options.hitTolerance ? options.hitTolerance : 0;
var featureOverlay = new ol.layer.Vector({
source: new ol.source.Vector({
useSpatialIndex: false,
@@ -160,6 +166,16 @@ ol.interaction.Select.prototype.getFeatures = function() {
};
/**
* Returns the Hit-detection tolerance.
* @returns {number} Hit tolerance in pixels.
* @api
*/
ol.interaction.Select.prototype.getHitTolerance = function() {
return this.hitTolerance_;
};
/**
* Returns the associated {@link ol.layer.Vector vectorlayer} of
* the (last) selected feature. Note that this will not work with any
@@ -201,7 +217,7 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) {
// the pixel.
ol.obj.clear(this.featureLayerAssociation_);
map.forEachFeatureAtPixel(mapBrowserEvent.pixel,
/**
(/**
* @param {ol.Feature|ol.render.Feature} feature Feature.
* @param {ol.layer.Layer} layer Layer.
* @return {boolean|undefined} Continue to iterate over the features.
@@ -212,7 +228,10 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) {
this.addFeatureLayerAssociation_(feature, layer);
return !this.multi_;
}
}, this, this.layerFilter_);
}).bind(this), {
layerFilter: this.layerFilter_,
hitTolerance: this.hitTolerance_
});
var i;
for (i = features.getLength() - 1; i >= 0; --i) {
var feature = features.item(i);
@@ -231,7 +250,7 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) {
} else {
// Modify the currently selected feature(s).
map.forEachFeatureAtPixel(mapBrowserEvent.pixel,
/**
(/**
* @param {ol.Feature|ol.render.Feature} feature Feature.
* @param {ol.layer.Layer} layer Layer.
* @return {boolean|undefined} Continue to iterate over the features.
@@ -249,7 +268,10 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) {
}
return !this.multi_;
}
}, this, this.layerFilter_);
}).bind(this), {
layerFilter: this.layerFilter_,
hitTolerance: this.hitTolerance_
});
var j;
for (j = deselected.length - 1; j >= 0; --j) {
features.remove(deselected[j]);
@@ -265,6 +287,18 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) {
};
/**
* Hit-detection tolerance. Pixels inside the radius around the given position
* will be checked for features. This only works for the canvas renderer and
* not for WebGL.
* @param {number} hitTolerance Hit tolerance in pixels.
* @api
*/
ol.interaction.Select.prototype.setHitTolerance = function(hitTolerance) {
this.hitTolerance_ = hitTolerance;
};
/**
* Remove the interaction from its current map, if any, and attach it to a new
* map, if any. Pass `null` to just remove the interaction from the current map.

View File

@@ -70,6 +70,12 @@ ol.interaction.Translate = function(opt_options) {
*/
this.layerFilter_ = layerFilter;
/**
* @private
* @type {number}
*/
this.hitTolerance_ = options.hitTolerance ? options.hitTolerance : 0;
/**
* @type {ol.Feature}
* @private
@@ -197,7 +203,32 @@ ol.interaction.Translate.prototype.featuresAtPixel_ = function(pixel, map) {
ol.array.includes(this.features_.getArray(), feature)) {
return feature;
}
}, this, this.layerFilter_);
}.bind(this), {
layerFilter: this.layerFilter_,
hitTolerance: this.hitTolerance_
});
};
/**
* Returns the Hit-detection tolerance.
* @returns {number} Hit tolerance in pixels.
* @api
*/
ol.interaction.Translate.prototype.getHitTolerance = function() {
return this.hitTolerance_;
};
/**
* Hit-detection tolerance. Pixels inside the radius around the given position
* will be checked for features. This only works for the canvas renderer and
* not for WebGL.
* @param {number} hitTolerance Hit tolerance in pixels.
* @api
*/
ol.interaction.Translate.prototype.setHitTolerance = function(hitTolerance) {
this.hitTolerance_ = hitTolerance;
};

View File

@@ -1,5 +1,4 @@
goog.provide('ol.layer.Base');
goog.provide('ol.layer.LayerProperty');
goog.require('ol');
goog.require('ol.Object');
@@ -7,20 +6,6 @@ goog.require('ol.math');
goog.require('ol.obj');
/**
* @enum {string}
*/
ol.layer.LayerProperty = {
OPACITY: 'opacity',
VISIBLE: 'visible',
EXTENT: 'extent',
Z_INDEX: 'zIndex',
MAX_RESOLUTION: 'maxResolution',
MIN_RESOLUTION: 'minResolution',
SOURCE: 'source'
};
/**
* @classdesc
* Abstract base class; normally only used for creating subclasses and not
@@ -42,15 +27,15 @@ ol.layer.Base = function(options) {
* @type {Object.<string, *>}
*/
var properties = ol.obj.assign({}, options);
properties[ol.layer.LayerProperty.OPACITY] =
properties[ol.layer.Base.Property.OPACITY] =
options.opacity !== undefined ? options.opacity : 1;
properties[ol.layer.LayerProperty.VISIBLE] =
properties[ol.layer.Base.Property.VISIBLE] =
options.visible !== undefined ? options.visible : true;
properties[ol.layer.LayerProperty.Z_INDEX] =
properties[ol.layer.Base.Property.Z_INDEX] =
options.zIndex !== undefined ? options.zIndex : 0;
properties[ol.layer.LayerProperty.MAX_RESOLUTION] =
properties[ol.layer.Base.Property.MAX_RESOLUTION] =
options.maxResolution !== undefined ? options.maxResolution : Infinity;
properties[ol.layer.LayerProperty.MIN_RESOLUTION] =
properties[ol.layer.Base.Property.MIN_RESOLUTION] =
options.minResolution !== undefined ? options.minResolution : 0;
this.setProperties(properties);
@@ -111,7 +96,7 @@ ol.layer.Base.prototype.getLayerStatesArray = function(opt_states) {};
*/
ol.layer.Base.prototype.getExtent = function() {
return /** @type {ol.Extent|undefined} */ (
this.get(ol.layer.LayerProperty.EXTENT));
this.get(ol.layer.Base.Property.EXTENT));
};
@@ -123,7 +108,7 @@ ol.layer.Base.prototype.getExtent = function() {
*/
ol.layer.Base.prototype.getMaxResolution = function() {
return /** @type {number} */ (
this.get(ol.layer.LayerProperty.MAX_RESOLUTION));
this.get(ol.layer.Base.Property.MAX_RESOLUTION));
};
@@ -135,7 +120,7 @@ ol.layer.Base.prototype.getMaxResolution = function() {
*/
ol.layer.Base.prototype.getMinResolution = function() {
return /** @type {number} */ (
this.get(ol.layer.LayerProperty.MIN_RESOLUTION));
this.get(ol.layer.Base.Property.MIN_RESOLUTION));
};
@@ -146,7 +131,7 @@ ol.layer.Base.prototype.getMinResolution = function() {
* @api stable
*/
ol.layer.Base.prototype.getOpacity = function() {
return /** @type {number} */ (this.get(ol.layer.LayerProperty.OPACITY));
return /** @type {number} */ (this.get(ol.layer.Base.Property.OPACITY));
};
@@ -164,7 +149,7 @@ ol.layer.Base.prototype.getSourceState = function() {};
* @api stable
*/
ol.layer.Base.prototype.getVisible = function() {
return /** @type {boolean} */ (this.get(ol.layer.LayerProperty.VISIBLE));
return /** @type {boolean} */ (this.get(ol.layer.Base.Property.VISIBLE));
};
@@ -176,7 +161,7 @@ ol.layer.Base.prototype.getVisible = function() {
* @api
*/
ol.layer.Base.prototype.getZIndex = function() {
return /** @type {number} */ (this.get(ol.layer.LayerProperty.Z_INDEX));
return /** @type {number} */ (this.get(ol.layer.Base.Property.Z_INDEX));
};
@@ -188,7 +173,7 @@ ol.layer.Base.prototype.getZIndex = function() {
* @api stable
*/
ol.layer.Base.prototype.setExtent = function(extent) {
this.set(ol.layer.LayerProperty.EXTENT, extent);
this.set(ol.layer.Base.Property.EXTENT, extent);
};
@@ -199,7 +184,7 @@ ol.layer.Base.prototype.setExtent = function(extent) {
* @api stable
*/
ol.layer.Base.prototype.setMaxResolution = function(maxResolution) {
this.set(ol.layer.LayerProperty.MAX_RESOLUTION, maxResolution);
this.set(ol.layer.Base.Property.MAX_RESOLUTION, maxResolution);
};
@@ -210,7 +195,7 @@ ol.layer.Base.prototype.setMaxResolution = function(maxResolution) {
* @api stable
*/
ol.layer.Base.prototype.setMinResolution = function(minResolution) {
this.set(ol.layer.LayerProperty.MIN_RESOLUTION, minResolution);
this.set(ol.layer.Base.Property.MIN_RESOLUTION, minResolution);
};
@@ -221,7 +206,7 @@ ol.layer.Base.prototype.setMinResolution = function(minResolution) {
* @api stable
*/
ol.layer.Base.prototype.setOpacity = function(opacity) {
this.set(ol.layer.LayerProperty.OPACITY, opacity);
this.set(ol.layer.Base.Property.OPACITY, opacity);
};
@@ -232,7 +217,7 @@ ol.layer.Base.prototype.setOpacity = function(opacity) {
* @api stable
*/
ol.layer.Base.prototype.setVisible = function(visible) {
this.set(ol.layer.LayerProperty.VISIBLE, visible);
this.set(ol.layer.Base.Property.VISIBLE, visible);
};
@@ -244,5 +229,19 @@ ol.layer.Base.prototype.setVisible = function(visible) {
* @api
*/
ol.layer.Base.prototype.setZIndex = function(zindex) {
this.set(ol.layer.LayerProperty.Z_INDEX, zindex);
this.set(ol.layer.Base.Property.Z_INDEX, zindex);
};
/**
* @enum {string}
*/
ol.layer.Base.Property = {
OPACITY: 'opacity',
VISIBLE: 'visible',
EXTENT: 'extent',
Z_INDEX: 'zIndex',
MAX_RESOLUTION: 'maxResolution',
MIN_RESOLUTION: 'minResolution',
SOURCE: 'source'
};

View File

@@ -4,7 +4,6 @@ goog.require('ol');
goog.require('ol.asserts');
goog.require('ol.Collection');
goog.require('ol.Object');
goog.require('ol.ObjectEventType');
goog.require('ol.events');
goog.require('ol.events.EventType');
goog.require('ol.extent');
@@ -104,7 +103,7 @@ ol.layer.Group.prototype.handleLayersChanged_ = function(event) {
for (i = 0, ii = layersArray.length; i < ii; i++) {
layer = layersArray[i];
this.listenerKeys_[ol.getUid(layer).toString()] = [
ol.events.listen(layer, ol.ObjectEventType.PROPERTYCHANGE,
ol.events.listen(layer, ol.Object.EventType.PROPERTYCHANGE,
this.handleLayerChange_, this),
ol.events.listen(layer, ol.events.EventType.CHANGE,
this.handleLayerChange_, this)
@@ -125,7 +124,7 @@ ol.layer.Group.prototype.handleLayersAdd_ = function(collectionEvent) {
ol.DEBUG && console.assert(!(key in this.listenerKeys_),
'listeners already registered');
this.listenerKeys_[key] = [
ol.events.listen(layer, ol.ObjectEventType.PROPERTYCHANGE,
ol.events.listen(layer, ol.Object.EventType.PROPERTYCHANGE,
this.handleLayerChange_, this),
ol.events.listen(layer, ol.events.EventType.CHANGE,
this.handleLayerChange_, this)

View File

@@ -5,7 +5,6 @@ goog.require('ol.events.EventType');
goog.require('ol');
goog.require('ol.Object');
goog.require('ol.layer.Base');
goog.require('ol.layer.LayerProperty');
goog.require('ol.obj');
goog.require('ol.render.Event');
goog.require('ol.source.State');
@@ -62,7 +61,7 @@ ol.layer.Layer = function(options) {
}
ol.events.listen(this,
ol.Object.getChangeEventType(ol.layer.LayerProperty.SOURCE),
ol.Object.getChangeEventType(ol.layer.Base.Property.SOURCE),
this.handleSourcePropertyChange_, this);
var source = options.source ? options.source : null;
@@ -112,7 +111,7 @@ ol.layer.Layer.prototype.getLayerStatesArray = function(opt_states) {
* @api stable
*/
ol.layer.Layer.prototype.getSource = function() {
var source = this.get(ol.layer.LayerProperty.SOURCE);
var source = this.get(ol.layer.Base.Property.SOURCE);
return /** @type {ol.source.Source} */ (source) || null;
};
@@ -198,5 +197,5 @@ ol.layer.Layer.prototype.setMap = function(map) {
* @api stable
*/
ol.layer.Layer.prototype.setSource = function(source) {
this.set(ol.layer.LayerProperty.SOURCE, source);
this.set(ol.layer.Base.Property.SOURCE, source);
};

View File

@@ -7,14 +7,11 @@ goog.provide('ol.Map');
goog.require('ol');
goog.require('ol.Collection');
goog.require('ol.MapBrowserEvent');
goog.require('ol.MapBrowserEvent.EventType');
goog.require('ol.MapBrowserEventHandler');
goog.require('ol.MapEvent');
goog.require('ol.Object');
goog.require('ol.ObjectEventType');
goog.require('ol.TileQueue');
goog.require('ol.View');
goog.require('ol.array');
goog.require('ol.asserts');
goog.require('ol.control');
goog.require('ol.dom');
@@ -532,15 +529,6 @@ ol.Map.prototype.beforeRender = function(var_args) {
};
/**
* @param {ol.PreRenderFunction} preRenderFunction Pre-render function.
* @return {boolean} Whether the preRenderFunction has been found and removed.
*/
ol.Map.prototype.removePreRenderFunction = function(preRenderFunction) {
return ol.array.remove(this.preRenderFunctions_, preRenderFunction);
};
/**
*
* @inheritDoc
@@ -579,31 +567,25 @@ ol.Map.prototype.disposeInternal = function() {
* the {@link ol.layer.Layer layer} of the feature and will be null for
* unmanaged layers. To stop detection, callback functions can return a
* truthy value.
* @param {S=} opt_this Value to use as `this` when executing `callback`.
* @param {(function(this: U, ol.layer.Layer): boolean)=} opt_layerFilter Layer
* filter function. The filter function will receive one argument, the
* {@link ol.layer.Layer layer-candidate} and it should return a boolean
* value. Only layers which are visible and for which this function returns
* `true` will be tested for features. By default, all visible layers will
* be tested.
* @param {U=} opt_this2 Value to use as `this` when executing `layerFilter`.
* @param {olx.AtPixelOptions=} opt_options Optional options.
* @return {T|undefined} Callback result, i.e. the return value of last
* callback execution, or the first truthy callback return value.
* @template S,T,U
* @template S,T
* @api stable
*/
ol.Map.prototype.forEachFeatureAtPixel = function(pixel, callback, opt_this, opt_layerFilter, opt_this2) {
ol.Map.prototype.forEachFeatureAtPixel = function(pixel, callback, opt_options) {
if (!this.frameState_) {
return;
}
var coordinate = this.getCoordinateFromPixel(pixel);
var thisArg = opt_this !== undefined ? opt_this : null;
var layerFilter = opt_layerFilter !== undefined ?
opt_layerFilter : ol.functions.TRUE;
var thisArg2 = opt_this2 !== undefined ? opt_this2 : null;
opt_options = opt_options !== undefined ? opt_options : {};
var hitTolerance = opt_options.hitTolerance !== undefined ?
opt_options.hitTolerance * this.frameState_.pixelRatio : 0;
var layerFilter = opt_options.layerFilter !== undefined ?
opt_options.layerFilter : ol.functions.TRUE;
return this.renderer_.forEachFeatureAtCoordinate(
coordinate, this.frameState_, callback, thisArg,
layerFilter, thisArg2);
coordinate, this.frameState_, hitTolerance, callback, null,
layerFilter, null);
};
@@ -649,27 +631,23 @@ ol.Map.prototype.forEachLayerAtPixel = function(pixel, callback, opt_this, opt_l
* Detect if features intersect a pixel on the viewport. Layers included in the
* detection can be configured through `opt_layerFilter`.
* @param {ol.Pixel} pixel Pixel.
* @param {(function(this: U, ol.layer.Layer): boolean)=} opt_layerFilter Layer
* filter function. The filter function will receive one argument, the
* {@link ol.layer.Layer layer-candidate} and it should return a boolean
* value. Only layers which are visible and for which this function returns
* `true` will be tested for features. By default, all visible layers will
* be tested.
* @param {U=} opt_this Value to use as `this` when executing `layerFilter`.
* @param {olx.AtPixelOptions=} opt_options Optional options.
* @return {boolean} Is there a feature at the given pixel?
* @template U
* @api
*/
ol.Map.prototype.hasFeatureAtPixel = function(pixel, opt_layerFilter, opt_this) {
ol.Map.prototype.hasFeatureAtPixel = function(pixel, opt_options) {
if (!this.frameState_) {
return false;
}
var coordinate = this.getCoordinateFromPixel(pixel);
var layerFilter = opt_layerFilter !== undefined ?
opt_layerFilter : ol.functions.TRUE;
var thisArg = opt_this !== undefined ? opt_this : null;
opt_options = opt_options !== undefined ? opt_options : {};
var layerFilter = opt_options.layerFilter !== undefined ?
opt_options.layerFilter : ol.functions.TRUE;
var hitTolerance = opt_options.hitTolerance !== undefined ?
opt_options.hitTolerance * this.frameState_.pixelRatio : 0;
return this.renderer_.hasFeatureAtCoordinate(
coordinate, this.frameState_, layerFilter, thisArg);
coordinate, this.frameState_, hitTolerance, layerFilter, null);
};
@@ -1115,7 +1093,7 @@ ol.Map.prototype.handleViewChanged_ = function() {
var view = this.getView();
if (view) {
this.viewPropertyListenerKey_ = ol.events.listen(
view, ol.ObjectEventType.PROPERTYCHANGE,
view, ol.Object.EventType.PROPERTYCHANGE,
this.handleViewPropertyChanged_, this);
this.viewChangeListenerKey_ = ol.events.listen(
view, ol.events.EventType.CHANGE,
@@ -1137,7 +1115,7 @@ ol.Map.prototype.handleLayerGroupChanged_ = function() {
if (layerGroup) {
this.layerGroupPropertyListenerKeys_ = [
ol.events.listen(
layerGroup, ol.ObjectEventType.PROPERTYCHANGE,
layerGroup, ol.Object.EventType.PROPERTYCHANGE,
this.render, this),
ol.events.listen(
layerGroup, ol.events.EventType.CHANGE,

View File

@@ -1,15 +1,8 @@
goog.provide('ol.MapBrowserEvent');
goog.provide('ol.MapBrowserEvent.EventType');
goog.provide('ol.MapBrowserEventHandler');
goog.provide('ol.MapBrowserPointerEvent');
goog.require('ol');
goog.require('ol.MapEvent');
goog.require('ol.events');
goog.require('ol.events.EventTarget');
goog.require('ol.events.EventType');
goog.require('ol.pointer.EventType');
goog.require('ol.pointer.PointerEventHandler');
/**
@@ -90,339 +83,6 @@ ol.MapBrowserEvent.prototype.stopPropagation = function() {
};
/**
* @constructor
* @extends {ol.MapBrowserEvent}
* @param {string} type Event type.
* @param {ol.Map} map Map.
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
* @param {boolean=} opt_dragging Is the map currently being dragged?
* @param {?olx.FrameState=} opt_frameState Frame state.
*/
ol.MapBrowserPointerEvent = function(type, map, pointerEvent, opt_dragging,
opt_frameState) {
ol.MapBrowserEvent.call(this, type, map, pointerEvent.originalEvent, opt_dragging,
opt_frameState);
/**
* @const
* @type {ol.pointer.PointerEvent}
*/
this.pointerEvent = pointerEvent;
};
ol.inherits(ol.MapBrowserPointerEvent, ol.MapBrowserEvent);
/**
* @param {ol.Map} map The map with the viewport to listen to events on.
* @constructor
* @extends {ol.events.EventTarget}
*/
ol.MapBrowserEventHandler = function(map) {
ol.events.EventTarget.call(this);
/**
* This is the element that we will listen to the real events on.
* @type {ol.Map}
* @private
*/
this.map_ = map;
/**
* @type {number}
* @private
*/
this.clickTimeoutId_ = 0;
/**
* @type {boolean}
* @private
*/
this.dragging_ = false;
/**
* @type {!Array.<ol.EventsKey>}
* @private
*/
this.dragListenerKeys_ = [];
/**
* The most recent "down" type event (or null if none have occurred).
* Set on pointerdown.
* @type {ol.pointer.PointerEvent}
* @private
*/
this.down_ = null;
var element = this.map_.getViewport();
/**
* @type {number}
* @private
*/
this.activePointers_ = 0;
/**
* @type {!Object.<number, boolean>}
* @private
*/
this.trackedTouches_ = {};
/**
* Event handler which generates pointer events for
* the viewport element.
*
* @type {ol.pointer.PointerEventHandler}
* @private
*/
this.pointerEventHandler_ = new ol.pointer.PointerEventHandler(element);
/**
* Event handler which generates pointer events for
* the document (used when dragging).
*
* @type {ol.pointer.PointerEventHandler}
* @private
*/
this.documentPointerEventHandler_ = null;
/**
* @type {?ol.EventsKey}
* @private
*/
this.pointerdownListenerKey_ = ol.events.listen(this.pointerEventHandler_,
ol.pointer.EventType.POINTERDOWN,
this.handlePointerDown_, this);
/**
* @type {?ol.EventsKey}
* @private
*/
this.relayedListenerKey_ = ol.events.listen(this.pointerEventHandler_,
ol.pointer.EventType.POINTERMOVE,
this.relayEvent_, this);
};
ol.inherits(ol.MapBrowserEventHandler, ol.events.EventTarget);
/**
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
* @private
*/
ol.MapBrowserEventHandler.prototype.emulateClick_ = function(pointerEvent) {
var newEvent = new ol.MapBrowserPointerEvent(
ol.MapBrowserEvent.EventType.CLICK, this.map_, pointerEvent);
this.dispatchEvent(newEvent);
if (this.clickTimeoutId_ !== 0) {
// double-click
clearTimeout(this.clickTimeoutId_);
this.clickTimeoutId_ = 0;
newEvent = new ol.MapBrowserPointerEvent(
ol.MapBrowserEvent.EventType.DBLCLICK, this.map_, pointerEvent);
this.dispatchEvent(newEvent);
} else {
// click
this.clickTimeoutId_ = setTimeout(function() {
this.clickTimeoutId_ = 0;
var newEvent = new ol.MapBrowserPointerEvent(
ol.MapBrowserEvent.EventType.SINGLECLICK, this.map_, pointerEvent);
this.dispatchEvent(newEvent);
}.bind(this), 250);
}
};
/**
* Keeps track on how many pointers are currently active.
*
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
* @private
*/
ol.MapBrowserEventHandler.prototype.updateActivePointers_ = function(pointerEvent) {
var event = pointerEvent;
if (event.type == ol.MapBrowserEvent.EventType.POINTERUP ||
event.type == ol.MapBrowserEvent.EventType.POINTERCANCEL) {
delete this.trackedTouches_[event.pointerId];
} else if (event.type == ol.MapBrowserEvent.EventType.POINTERDOWN) {
this.trackedTouches_[event.pointerId] = true;
}
this.activePointers_ = Object.keys(this.trackedTouches_).length;
};
/**
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
* @private
*/
ol.MapBrowserEventHandler.prototype.handlePointerUp_ = function(pointerEvent) {
this.updateActivePointers_(pointerEvent);
var newEvent = new ol.MapBrowserPointerEvent(
ol.MapBrowserEvent.EventType.POINTERUP, this.map_, pointerEvent);
this.dispatchEvent(newEvent);
// We emulate click events on left mouse button click, touch contact, and pen
// contact. isMouseActionButton returns true in these cases (evt.button is set
// to 0).
// See http://www.w3.org/TR/pointerevents/#button-states
if (!this.dragging_ && this.isMouseActionButton_(pointerEvent)) {
ol.DEBUG && console.assert(this.down_, 'this.down_ must be truthy');
this.emulateClick_(this.down_);
}
ol.DEBUG && console.assert(this.activePointers_ >= 0,
'this.activePointers_ should be equal to or larger than 0');
if (this.activePointers_ === 0) {
this.dragListenerKeys_.forEach(ol.events.unlistenByKey);
this.dragListenerKeys_.length = 0;
this.dragging_ = false;
this.down_ = null;
this.documentPointerEventHandler_.dispose();
this.documentPointerEventHandler_ = null;
}
};
/**
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
* @return {boolean} If the left mouse button was pressed.
* @private
*/
ol.MapBrowserEventHandler.prototype.isMouseActionButton_ = function(pointerEvent) {
return pointerEvent.button === 0;
};
/**
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
* @private
*/
ol.MapBrowserEventHandler.prototype.handlePointerDown_ = function(pointerEvent) {
this.updateActivePointers_(pointerEvent);
var newEvent = new ol.MapBrowserPointerEvent(
ol.MapBrowserEvent.EventType.POINTERDOWN, this.map_, pointerEvent);
this.dispatchEvent(newEvent);
this.down_ = pointerEvent;
if (this.dragListenerKeys_.length === 0) {
/* Set up a pointer event handler on the `document`,
* which is required when the pointer is moved outside
* the viewport when dragging.
*/
this.documentPointerEventHandler_ =
new ol.pointer.PointerEventHandler(document);
this.dragListenerKeys_.push(
ol.events.listen(this.documentPointerEventHandler_,
ol.MapBrowserEvent.EventType.POINTERMOVE,
this.handlePointerMove_, this),
ol.events.listen(this.documentPointerEventHandler_,
ol.MapBrowserEvent.EventType.POINTERUP,
this.handlePointerUp_, this),
/* Note that the listener for `pointercancel is set up on
* `pointerEventHandler_` and not `documentPointerEventHandler_` like
* the `pointerup` and `pointermove` listeners.
*
* The reason for this is the following: `TouchSource.vacuumTouches_()`
* issues `pointercancel` events, when there was no `touchend` for a
* `touchstart`. Now, let's say a first `touchstart` is registered on
* `pointerEventHandler_`. The `documentPointerEventHandler_` is set up.
* But `documentPointerEventHandler_` doesn't know about the first
* `touchstart`. If there is no `touchend` for the `touchstart`, we can
* only receive a `touchcancel` from `pointerEventHandler_`, because it is
* only registered there.
*/
ol.events.listen(this.pointerEventHandler_,
ol.MapBrowserEvent.EventType.POINTERCANCEL,
this.handlePointerUp_, this)
);
}
};
/**
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
* @private
*/
ol.MapBrowserEventHandler.prototype.handlePointerMove_ = function(pointerEvent) {
// Fix IE10 on windows Surface : When you tap the tablet, it triggers
// multiple pointermove events between pointerdown and pointerup with
// the exact same coordinates of the pointerdown event. To avoid a
// 'false' touchmove event to be dispatched , we test if the pointer
// effectively moved.
if (this.isMoving_(pointerEvent)) {
this.dragging_ = true;
var newEvent = new ol.MapBrowserPointerEvent(
ol.MapBrowserEvent.EventType.POINTERDRAG, this.map_, pointerEvent,
this.dragging_);
this.dispatchEvent(newEvent);
}
// Some native android browser triggers mousemove events during small period
// of time. See: https://code.google.com/p/android/issues/detail?id=5491 or
// https://code.google.com/p/android/issues/detail?id=19827
// ex: Galaxy Tab P3110 + Android 4.1.1
pointerEvent.preventDefault();
};
/**
* Wrap and relay a pointer event. Note that this requires that the type
* string for the MapBrowserPointerEvent matches the PointerEvent type.
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
* @private
*/
ol.MapBrowserEventHandler.prototype.relayEvent_ = function(pointerEvent) {
var dragging = !!(this.down_ && this.isMoving_(pointerEvent));
this.dispatchEvent(new ol.MapBrowserPointerEvent(
pointerEvent.type, this.map_, pointerEvent, dragging));
};
/**
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
* @return {boolean} Is moving.
* @private
*/
ol.MapBrowserEventHandler.prototype.isMoving_ = function(pointerEvent) {
return pointerEvent.clientX != this.down_.clientX ||
pointerEvent.clientY != this.down_.clientY;
};
/**
* @inheritDoc
*/
ol.MapBrowserEventHandler.prototype.disposeInternal = function() {
if (this.relayedListenerKey_) {
ol.events.unlistenByKey(this.relayedListenerKey_);
this.relayedListenerKey_ = null;
}
if (this.pointerdownListenerKey_) {
ol.events.unlistenByKey(this.pointerdownListenerKey_);
this.pointerdownListenerKey_ = null;
}
this.dragListenerKeys_.forEach(ol.events.unlistenByKey);
this.dragListenerKeys_.length = 0;
if (this.documentPointerEventHandler_) {
this.documentPointerEventHandler_.dispose();
this.documentPointerEventHandler_ = null;
}
if (this.pointerEventHandler_) {
this.pointerEventHandler_.dispose();
this.pointerEventHandler_ = null;
}
ol.events.EventTarget.prototype.disposeInternal.call(this);
};
/**
* Constants for event names.
* @enum {string}

View File

@@ -0,0 +1,317 @@
goog.provide('ol.MapBrowserEventHandler');
goog.require('ol');
goog.require('ol.MapBrowserEvent');
goog.require('ol.MapBrowserPointerEvent');
goog.require('ol.events');
goog.require('ol.events.EventTarget');
goog.require('ol.pointer.EventType');
goog.require('ol.pointer.PointerEventHandler');
/**
* @param {ol.Map} map The map with the viewport to listen to events on.
* @constructor
* @extends {ol.events.EventTarget}
*/
ol.MapBrowserEventHandler = function(map) {
ol.events.EventTarget.call(this);
/**
* This is the element that we will listen to the real events on.
* @type {ol.Map}
* @private
*/
this.map_ = map;
/**
* @type {number}
* @private
*/
this.clickTimeoutId_ = 0;
/**
* @type {boolean}
* @private
*/
this.dragging_ = false;
/**
* @type {!Array.<ol.EventsKey>}
* @private
*/
this.dragListenerKeys_ = [];
/**
* The most recent "down" type event (or null if none have occurred).
* Set on pointerdown.
* @type {ol.pointer.PointerEvent}
* @private
*/
this.down_ = null;
var element = this.map_.getViewport();
/**
* @type {number}
* @private
*/
this.activePointers_ = 0;
/**
* @type {!Object.<number, boolean>}
* @private
*/
this.trackedTouches_ = {};
/**
* Event handler which generates pointer events for
* the viewport element.
*
* @type {ol.pointer.PointerEventHandler}
* @private
*/
this.pointerEventHandler_ = new ol.pointer.PointerEventHandler(element);
/**
* Event handler which generates pointer events for
* the document (used when dragging).
*
* @type {ol.pointer.PointerEventHandler}
* @private
*/
this.documentPointerEventHandler_ = null;
/**
* @type {?ol.EventsKey}
* @private
*/
this.pointerdownListenerKey_ = ol.events.listen(this.pointerEventHandler_,
ol.pointer.EventType.POINTERDOWN,
this.handlePointerDown_, this);
/**
* @type {?ol.EventsKey}
* @private
*/
this.relayedListenerKey_ = ol.events.listen(this.pointerEventHandler_,
ol.pointer.EventType.POINTERMOVE,
this.relayEvent_, this);
};
ol.inherits(ol.MapBrowserEventHandler, ol.events.EventTarget);
/**
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
* @private
*/
ol.MapBrowserEventHandler.prototype.emulateClick_ = function(pointerEvent) {
var newEvent = new ol.MapBrowserPointerEvent(
ol.MapBrowserEvent.EventType.CLICK, this.map_, pointerEvent);
this.dispatchEvent(newEvent);
if (this.clickTimeoutId_ !== 0) {
// double-click
clearTimeout(this.clickTimeoutId_);
this.clickTimeoutId_ = 0;
newEvent = new ol.MapBrowserPointerEvent(
ol.MapBrowserEvent.EventType.DBLCLICK, this.map_, pointerEvent);
this.dispatchEvent(newEvent);
} else {
// click
this.clickTimeoutId_ = setTimeout(function() {
this.clickTimeoutId_ = 0;
var newEvent = new ol.MapBrowserPointerEvent(
ol.MapBrowserEvent.EventType.SINGLECLICK, this.map_, pointerEvent);
this.dispatchEvent(newEvent);
}.bind(this), 250);
}
};
/**
* Keeps track on how many pointers are currently active.
*
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
* @private
*/
ol.MapBrowserEventHandler.prototype.updateActivePointers_ = function(pointerEvent) {
var event = pointerEvent;
if (event.type == ol.MapBrowserEvent.EventType.POINTERUP ||
event.type == ol.MapBrowserEvent.EventType.POINTERCANCEL) {
delete this.trackedTouches_[event.pointerId];
} else if (event.type == ol.MapBrowserEvent.EventType.POINTERDOWN) {
this.trackedTouches_[event.pointerId] = true;
}
this.activePointers_ = Object.keys(this.trackedTouches_).length;
};
/**
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
* @private
*/
ol.MapBrowserEventHandler.prototype.handlePointerUp_ = function(pointerEvent) {
this.updateActivePointers_(pointerEvent);
var newEvent = new ol.MapBrowserPointerEvent(
ol.MapBrowserEvent.EventType.POINTERUP, this.map_, pointerEvent);
this.dispatchEvent(newEvent);
// We emulate click events on left mouse button click, touch contact, and pen
// contact. isMouseActionButton returns true in these cases (evt.button is set
// to 0).
// See http://www.w3.org/TR/pointerevents/#button-states
if (!this.dragging_ && this.isMouseActionButton_(pointerEvent)) {
ol.DEBUG && console.assert(this.down_, 'this.down_ must be truthy');
this.emulateClick_(this.down_);
}
ol.DEBUG && console.assert(this.activePointers_ >= 0,
'this.activePointers_ should be equal to or larger than 0');
if (this.activePointers_ === 0) {
this.dragListenerKeys_.forEach(ol.events.unlistenByKey);
this.dragListenerKeys_.length = 0;
this.dragging_ = false;
this.down_ = null;
this.documentPointerEventHandler_.dispose();
this.documentPointerEventHandler_ = null;
}
};
/**
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
* @return {boolean} If the left mouse button was pressed.
* @private
*/
ol.MapBrowserEventHandler.prototype.isMouseActionButton_ = function(pointerEvent) {
return pointerEvent.button === 0;
};
/**
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
* @private
*/
ol.MapBrowserEventHandler.prototype.handlePointerDown_ = function(pointerEvent) {
this.updateActivePointers_(pointerEvent);
var newEvent = new ol.MapBrowserPointerEvent(
ol.MapBrowserEvent.EventType.POINTERDOWN, this.map_, pointerEvent);
this.dispatchEvent(newEvent);
this.down_ = pointerEvent;
if (this.dragListenerKeys_.length === 0) {
/* Set up a pointer event handler on the `document`,
* which is required when the pointer is moved outside
* the viewport when dragging.
*/
this.documentPointerEventHandler_ =
new ol.pointer.PointerEventHandler(document);
this.dragListenerKeys_.push(
ol.events.listen(this.documentPointerEventHandler_,
ol.MapBrowserEvent.EventType.POINTERMOVE,
this.handlePointerMove_, this),
ol.events.listen(this.documentPointerEventHandler_,
ol.MapBrowserEvent.EventType.POINTERUP,
this.handlePointerUp_, this),
/* Note that the listener for `pointercancel is set up on
* `pointerEventHandler_` and not `documentPointerEventHandler_` like
* the `pointerup` and `pointermove` listeners.
*
* The reason for this is the following: `TouchSource.vacuumTouches_()`
* issues `pointercancel` events, when there was no `touchend` for a
* `touchstart`. Now, let's say a first `touchstart` is registered on
* `pointerEventHandler_`. The `documentPointerEventHandler_` is set up.
* But `documentPointerEventHandler_` doesn't know about the first
* `touchstart`. If there is no `touchend` for the `touchstart`, we can
* only receive a `touchcancel` from `pointerEventHandler_`, because it is
* only registered there.
*/
ol.events.listen(this.pointerEventHandler_,
ol.MapBrowserEvent.EventType.POINTERCANCEL,
this.handlePointerUp_, this)
);
}
};
/**
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
* @private
*/
ol.MapBrowserEventHandler.prototype.handlePointerMove_ = function(pointerEvent) {
// Fix IE10 on windows Surface : When you tap the tablet, it triggers
// multiple pointermove events between pointerdown and pointerup with
// the exact same coordinates of the pointerdown event. To avoid a
// 'false' touchmove event to be dispatched , we test if the pointer
// effectively moved.
if (this.isMoving_(pointerEvent)) {
this.dragging_ = true;
var newEvent = new ol.MapBrowserPointerEvent(
ol.MapBrowserEvent.EventType.POINTERDRAG, this.map_, pointerEvent,
this.dragging_);
this.dispatchEvent(newEvent);
}
// Some native android browser triggers mousemove events during small period
// of time. See: https://code.google.com/p/android/issues/detail?id=5491 or
// https://code.google.com/p/android/issues/detail?id=19827
// ex: Galaxy Tab P3110 + Android 4.1.1
pointerEvent.preventDefault();
};
/**
* Wrap and relay a pointer event. Note that this requires that the type
* string for the MapBrowserPointerEvent matches the PointerEvent type.
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
* @private
*/
ol.MapBrowserEventHandler.prototype.relayEvent_ = function(pointerEvent) {
var dragging = !!(this.down_ && this.isMoving_(pointerEvent));
this.dispatchEvent(new ol.MapBrowserPointerEvent(
pointerEvent.type, this.map_, pointerEvent, dragging));
};
/**
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
* @return {boolean} Is moving.
* @private
*/
ol.MapBrowserEventHandler.prototype.isMoving_ = function(pointerEvent) {
return pointerEvent.clientX != this.down_.clientX ||
pointerEvent.clientY != this.down_.clientY;
};
/**
* @inheritDoc
*/
ol.MapBrowserEventHandler.prototype.disposeInternal = function() {
if (this.relayedListenerKey_) {
ol.events.unlistenByKey(this.relayedListenerKey_);
this.relayedListenerKey_ = null;
}
if (this.pointerdownListenerKey_) {
ol.events.unlistenByKey(this.pointerdownListenerKey_);
this.pointerdownListenerKey_ = null;
}
this.dragListenerKeys_.forEach(ol.events.unlistenByKey);
this.dragListenerKeys_.length = 0;
if (this.documentPointerEventHandler_) {
this.documentPointerEventHandler_.dispose();
this.documentPointerEventHandler_ = null;
}
if (this.pointerEventHandler_) {
this.pointerEventHandler_.dispose();
this.pointerEventHandler_ = null;
}
ol.events.EventTarget.prototype.disposeInternal.call(this);
};

View File

@@ -0,0 +1,29 @@
goog.provide('ol.MapBrowserPointerEvent');
goog.require('ol');
goog.require('ol.MapBrowserEvent');
/**
* @constructor
* @extends {ol.MapBrowserEvent}
* @param {string} type Event type.
* @param {ol.Map} map Map.
* @param {ol.pointer.PointerEvent} pointerEvent Pointer event.
* @param {boolean=} opt_dragging Is the map currently being dragged?
* @param {?olx.FrameState=} opt_frameState Frame state.
*/
ol.MapBrowserPointerEvent = function(type, map, pointerEvent, opt_dragging,
opt_frameState) {
ol.MapBrowserEvent.call(this, type, map, pointerEvent.originalEvent, opt_dragging,
opt_frameState);
/**
* @const
* @type {ol.pointer.PointerEvent}
*/
this.pointerEvent = pointerEvent;
};
ol.inherits(ol.MapBrowserPointerEvent, ol.MapBrowserEvent);

View File

@@ -1,6 +1,4 @@
goog.provide('ol.Object');
goog.provide('ol.ObjectEvent');
goog.provide('ol.ObjectEventType');
goog.require('ol');
goog.require('ol.Observable');
@@ -8,52 +6,6 @@ goog.require('ol.events.Event');
goog.require('ol.obj');
/**
* @enum {string}
*/
ol.ObjectEventType = {
/**
* Triggered when a property is changed.
* @event ol.ObjectEvent#propertychange
* @api stable
*/
PROPERTYCHANGE: 'propertychange'
};
/**
* @classdesc
* Events emitted by {@link ol.Object} instances are instances of this type.
*
* @param {string} type The event type.
* @param {string} key The property name.
* @param {*} oldValue The old value for `key`.
* @extends {ol.events.Event}
* @implements {oli.ObjectEvent}
* @constructor
*/
ol.ObjectEvent = function(type, key, oldValue) {
ol.events.Event.call(this, type);
/**
* The name of the property whose value is changing.
* @type {string}
* @api stable
*/
this.key = key;
/**
* The old value. To get the new value use `e.target.get(e.key)` where
* `e` is the event object.
* @type {*}
* @api stable
*/
this.oldValue = oldValue;
};
ol.inherits(ol.ObjectEvent, ol.events.Event);
/**
* @classdesc
* Abstract base class; normally only used for creating subclasses and not
@@ -96,7 +48,7 @@ ol.inherits(ol.ObjectEvent, ol.events.Event);
* @constructor
* @extends {ol.Observable}
* @param {Object.<string, *>=} opt_values An object with key-value pairs.
* @fires ol.ObjectEvent
* @fires ol.Object.Event
* @api
*/
ol.Object = function(opt_values) {
@@ -181,9 +133,9 @@ ol.Object.prototype.getProperties = function() {
ol.Object.prototype.notify = function(key, oldValue) {
var eventType;
eventType = ol.Object.getChangeEventType(key);
this.dispatchEvent(new ol.ObjectEvent(eventType, key, oldValue));
eventType = ol.ObjectEventType.PROPERTYCHANGE;
this.dispatchEvent(new ol.ObjectEvent(eventType, key, oldValue));
this.dispatchEvent(new ol.Object.Event(eventType, key, oldValue));
eventType = ol.Object.EventType.PROPERTYCHANGE;
this.dispatchEvent(new ol.Object.Event(eventType, key, oldValue));
};
@@ -237,3 +189,49 @@ ol.Object.prototype.unset = function(key, opt_silent) {
}
}
};
/**
* @enum {string}
*/
ol.Object.EventType = {
/**
* Triggered when a property is changed.
* @event ol.Object.Event#propertychange
* @api stable
*/
PROPERTYCHANGE: 'propertychange'
};
/**
* @classdesc
* Events emitted by {@link ol.Object} instances are instances of this type.
*
* @param {string} type The event type.
* @param {string} key The property name.
* @param {*} oldValue The old value for `key`.
* @extends {ol.events.Event}
* @implements {oli.Object.Event}
* @constructor
*/
ol.Object.Event = function(type, key, oldValue) {
ol.events.Event.call(this, type);
/**
* The name of the property whose value is changing.
* @type {string}
* @api stable
*/
this.key = key;
/**
* The old value. To get the new value use `e.target.get(e.key)` where
* `e` is the event object.
* @type {*}
* @api stable
*/
this.oldValue = oldValue;
};
ol.inherits(ol.Object.Event, ol.events.Event);

View File

@@ -205,9 +205,9 @@ ol.pointer.PointerEventHandler.prototype.removeEvents_ = function(events) {
*/
ol.pointer.PointerEventHandler.prototype.cloneEvent = function(event, inEvent) {
var eventCopy = {}, p;
for (var i = 0, ii = ol.pointer.CLONE_PROPS.length; i < ii; i++) {
p = ol.pointer.CLONE_PROPS[i][0];
eventCopy[p] = event[p] || inEvent[p] || ol.pointer.CLONE_PROPS[i][1];
for (var i = 0, ii = ol.pointer.PointerEventHandler.CLONE_PROPS.length; i < ii; i++) {
p = ol.pointer.PointerEventHandler.CLONE_PROPS[i][0];
eventCopy[p] = event[p] || inEvent[p] || ol.pointer.PointerEventHandler.CLONE_PROPS[i][1];
}
return eventCopy;
@@ -407,7 +407,7 @@ ol.pointer.PointerEventHandler.prototype.disposeInternal = function() {
* Properties to copy when cloning an event, with default values.
* @type {Array.<Array>}
*/
ol.pointer.CLONE_PROPS = [
ol.pointer.PointerEventHandler.CLONE_PROPS = [
// MouseEvent
['bubbles', false],
['cancelable', false],

View File

@@ -22,20 +22,15 @@ ol.proj.EPSG3857_ = function(code) {
units: ol.proj.Units.METERS,
extent: ol.proj.EPSG3857.EXTENT,
global: true,
worldExtent: ol.proj.EPSG3857.WORLD_EXTENT
worldExtent: ol.proj.EPSG3857.WORLD_EXTENT,
getPointResolution: function(resolution, point) {
return resolution / ol.math.cosh(point[1] / ol.proj.EPSG3857.RADIUS);
}
});
};
ol.inherits(ol.proj.EPSG3857_, ol.proj.Projection);
/**
* @inheritDoc
*/
ol.proj.EPSG3857_.prototype.getPointResolution = function(resolution, point) {
return resolution / ol.math.cosh(point[1] / ol.proj.EPSG3857.RADIUS);
};
/**
* @const
* @type {number}

View File

@@ -35,14 +35,6 @@ ol.proj.EPSG4326_ = function(code, opt_axisOrientation) {
ol.inherits(ol.proj.EPSG4326_, ol.proj.Projection);
/**
* @inheritDoc
*/
ol.proj.EPSG4326_.prototype.getPointResolution = function(resolution, point) {
return resolution;
};
/**
* Extent of the EPSG:4326 projection which is the whole world.
*

View File

@@ -1,405 +1,22 @@
goog.provide('ol.proj');
goog.provide('ol.proj.METERS_PER_UNIT');
goog.provide('ol.proj.Projection');
goog.provide('ol.proj.Units');
goog.require('ol');
goog.require('ol.extent');
goog.require('ol.obj');
goog.require('ol.proj.Projection');
goog.require('ol.proj.Units');
goog.require('ol.proj.proj4');
goog.require('ol.proj.projections');
goog.require('ol.proj.transforms');
goog.require('ol.sphere.NORMAL');
/**
* Projection units: `'degrees'`, `'ft'`, `'m'`, `'pixels'`, `'tile-pixels'` or
* `'us-ft'`.
* @enum {string}
*/
ol.proj.Units = {
DEGREES: 'degrees',
FEET: 'ft',
METERS: 'm',
PIXELS: 'pixels',
TILE_PIXELS: 'tile-pixels',
USFEET: 'us-ft'
};
/**
* Meters per unit lookup table.
* @const
* @type {Object.<ol.proj.Units, number>}
* @api stable
*/
ol.proj.METERS_PER_UNIT = {};
ol.proj.METERS_PER_UNIT[ol.proj.Units.DEGREES] =
2 * Math.PI * ol.sphere.NORMAL.radius / 360;
ol.proj.METERS_PER_UNIT[ol.proj.Units.FEET] = 0.3048;
ol.proj.METERS_PER_UNIT[ol.proj.Units.METERS] = 1;
ol.proj.METERS_PER_UNIT[ol.proj.Units.USFEET] = 1200 / 3937;
/**
* @classdesc
* Projection definition class. One of these is created for each projection
* supported in the application and stored in the {@link ol.proj} namespace.
* You can use these in applications, but this is not required, as API params
* and options use {@link ol.ProjectionLike} which means the simple string
* code will suffice.
*
* You can use {@link ol.proj.get} to retrieve the object for a particular
* projection.
*
* The library includes definitions for `EPSG:4326` and `EPSG:3857`, together
* with the following aliases:
* * `EPSG:4326`: CRS:84, urn:ogc:def:crs:EPSG:6.6:4326,
* urn:ogc:def:crs:OGC:1.3:CRS84, urn:ogc:def:crs:OGC:2:84,
* http://www.opengis.net/gml/srs/epsg.xml#4326,
* urn:x-ogc:def:crs:EPSG:4326
* * `EPSG:3857`: EPSG:102100, EPSG:102113, EPSG:900913,
* urn:ogc:def:crs:EPSG:6.18:3:3857,
* http://www.opengis.net/gml/srs/epsg.xml#3857
*
* If you use proj4js, aliases can be added using `proj4.defs()`; see
* [documentation](https://github.com/proj4js/proj4js). To set an alternative
* namespace for proj4, use {@link ol.proj.setProj4}.
*
* @constructor
* @param {olx.ProjectionOptions} options Projection options.
* @struct
* @api stable
*/
ol.proj.Projection = function(options) {
/**
* @private
* @type {string}
*/
this.code_ = options.code;
/**
* @private
* @type {ol.proj.Units}
*/
this.units_ = /** @type {ol.proj.Units} */ (options.units);
/**
* @private
* @type {ol.Extent}
*/
this.extent_ = options.extent !== undefined ? options.extent : null;
/**
* @private
* @type {ol.Extent}
*/
this.worldExtent_ = options.worldExtent !== undefined ?
options.worldExtent : null;
/**
* @private
* @type {string}
*/
this.axisOrientation_ = options.axisOrientation !== undefined ?
options.axisOrientation : 'enu';
/**
* @private
* @type {boolean}
*/
this.global_ = options.global !== undefined ? options.global : false;
/**
* @private
* @type {boolean}
*/
this.canWrapX_ = !!(this.global_ && this.extent_);
/**
* @private
* @type {function(number, ol.Coordinate):number}
*/
this.getPointResolutionFunc_ = options.getPointResolution !== undefined ?
options.getPointResolution : this.getPointResolution_;
/**
* @private
* @type {ol.tilegrid.TileGrid}
*/
this.defaultTileGrid_ = null;
/**
* @private
* @type {number|undefined}
*/
this.metersPerUnit_ = options.metersPerUnit;
var projections = ol.proj.projections_;
var code = options.code;
ol.DEBUG && console.assert(code !== undefined,
'Option "code" is required for constructing instance');
if (ol.ENABLE_PROJ4JS) {
var proj4js = ol.proj.proj4_ || window['proj4'];
if (typeof proj4js == 'function' && projections[code] === undefined) {
var def = proj4js.defs(code);
if (def !== undefined) {
if (def.axis !== undefined && options.axisOrientation === undefined) {
this.axisOrientation_ = def.axis;
}
if (options.metersPerUnit === undefined) {
this.metersPerUnit_ = def.to_meter;
}
if (options.units === undefined) {
this.units_ = def.units;
}
var currentCode, currentDef, currentProj, proj4Transform;
for (currentCode in projections) {
currentDef = proj4js.defs(currentCode);
if (currentDef !== undefined) {
currentProj = ol.proj.get(currentCode);
if (currentDef === def) {
ol.proj.addEquivalentProjections([currentProj, this]);
} else {
proj4Transform = proj4js(currentCode, code);
ol.proj.addCoordinateTransforms(currentProj, this,
proj4Transform.forward, proj4Transform.inverse);
}
}
}
}
}
}
};
/**
* @return {boolean} The projection is suitable for wrapping the x-axis
*/
ol.proj.Projection.prototype.canWrapX = function() {
return this.canWrapX_;
};
/**
* Get the code for this projection, e.g. 'EPSG:4326'.
* @return {string} Code.
* @api stable
*/
ol.proj.Projection.prototype.getCode = function() {
return this.code_;
};
/**
* Get the validity extent for this projection.
* @return {ol.Extent} Extent.
* @api stable
*/
ol.proj.Projection.prototype.getExtent = function() {
return this.extent_;
};
/**
* Get the units of this projection.
* @return {ol.proj.Units} Units.
* @api stable
*/
ol.proj.Projection.prototype.getUnits = function() {
return this.units_;
};
/**
* Get the amount of meters per unit of this projection. If the projection is
* not configured with `metersPerUnit` or a units identifier, the return is
* `undefined`.
* @return {number|undefined} Meters.
* @api stable
*/
ol.proj.Projection.prototype.getMetersPerUnit = function() {
return this.metersPerUnit_ || ol.proj.METERS_PER_UNIT[this.units_];
};
/**
* Get the world extent for this projection.
* @return {ol.Extent} Extent.
* @api
*/
ol.proj.Projection.prototype.getWorldExtent = function() {
return this.worldExtent_;
};
/**
* Get the axis orientation of this projection.
* Example values are:
* enu - the default easting, northing, elevation.
* neu - northing, easting, up - useful for "lat/long" geographic coordinates,
* or south orientated transverse mercator.
* wnu - westing, northing, up - some planetary coordinate systems have
* "west positive" coordinate systems
* @return {string} Axis orientation.
*/
ol.proj.Projection.prototype.getAxisOrientation = function() {
return this.axisOrientation_;
};
/**
* Is this projection a global projection which spans the whole world?
* @return {boolean} Whether the projection is global.
* @api stable
*/
ol.proj.Projection.prototype.isGlobal = function() {
return this.global_;
};
/**
* Set if the projection is a global projection which spans the whole world
* @param {boolean} global Whether the projection is global.
* @api stable
*/
ol.proj.Projection.prototype.setGlobal = function(global) {
this.global_ = global;
this.canWrapX_ = !!(global && this.extent_);
};
/**
* @return {ol.tilegrid.TileGrid} The default tile grid.
*/
ol.proj.Projection.prototype.getDefaultTileGrid = function() {
return this.defaultTileGrid_;
};
/**
* @param {ol.tilegrid.TileGrid} tileGrid The default tile grid.
*/
ol.proj.Projection.prototype.setDefaultTileGrid = function(tileGrid) {
this.defaultTileGrid_ = tileGrid;
};
/**
* Set the validity extent for this projection.
* @param {ol.Extent} extent Extent.
* @api stable
*/
ol.proj.Projection.prototype.setExtent = function(extent) {
this.extent_ = extent;
this.canWrapX_ = !!(this.global_ && extent);
};
/**
* Set the world extent for this projection.
* @param {ol.Extent} worldExtent World extent
* [minlon, minlat, maxlon, maxlat].
* @api
*/
ol.proj.Projection.prototype.setWorldExtent = function(worldExtent) {
this.worldExtent_ = worldExtent;
};
/**
* Set the getPointResolution function for this projection.
* @param {function(number, ol.Coordinate):number} func Function
* @api
*/
ol.proj.Projection.prototype.setGetPointResolution = function(func) {
this.getPointResolutionFunc_ = func;
};
/**
* Default version.
* Get the resolution of the point in degrees or distance units.
* For projections with degrees as the unit this will simply return the
* provided resolution. For other projections the point resolution is
* estimated by transforming the 'point' pixel to EPSG:4326,
* measuring its width and height on the normal sphere,
* and taking the average of the width and height.
* @param {number} resolution Nominal resolution in projection units.
* @param {ol.Coordinate} point Point to find adjusted resolution at.
* @return {number} Point resolution at point in projection units.
* @private
*/
ol.proj.Projection.prototype.getPointResolution_ = function(resolution, point) {
var units = this.getUnits();
if (units == ol.proj.Units.DEGREES) {
return resolution;
} else {
// Estimate point resolution by transforming the center pixel to EPSG:4326,
// measuring its width and height on the normal sphere, and taking the
// average of the width and height.
var toEPSG4326 = ol.proj.getTransformFromProjections(
this, ol.proj.get('EPSG:4326'));
var vertices = [
point[0] - resolution / 2, point[1],
point[0] + resolution / 2, point[1],
point[0], point[1] - resolution / 2,
point[0], point[1] + resolution / 2
];
vertices = toEPSG4326(vertices, vertices, 2);
var width = ol.sphere.NORMAL.haversineDistance(
vertices.slice(0, 2), vertices.slice(2, 4));
var height = ol.sphere.NORMAL.haversineDistance(
vertices.slice(4, 6), vertices.slice(6, 8));
var pointResolution = (width + height) / 2;
var metersPerUnit = this.getMetersPerUnit();
if (metersPerUnit !== undefined) {
pointResolution /= metersPerUnit;
}
return pointResolution;
}
};
/**
* Get the resolution of the point in degrees or distance units.
* For projections with degrees as the unit this will simply return the
* provided resolution. The default for other projections is to estimate
* the point resolution by transforming the 'point' pixel to EPSG:4326,
* measuring its width and height on the normal sphere,
* and taking the average of the width and height.
* An alternative implementation may be given when constructing a
* projection. For many local projections,
* such a custom function will return the resolution unchanged.
* @param {number} resolution Resolution in projection units.
* @param {ol.Coordinate} point Point.
* @return {number} Point resolution in projection units.
* @api
*/
ol.proj.Projection.prototype.getPointResolution = function(resolution, point) {
return this.getPointResolutionFunc_(resolution, point);
};
/**
* @private
* @type {Object.<string, ol.proj.Projection>}
*/
ol.proj.projections_ = {};
/**
* @private
* @type {Object.<string, Object.<string, ol.TransformFunction>>}
*/
ol.proj.transforms_ = {};
/**
* @private
* @type {proj4}
*/
ol.proj.proj4_ = null;
ol.proj.METERS_PER_UNIT = ol.proj.Units.METERS_PER_UNIT;
if (ol.ENABLE_PROJ4JS) {
@@ -418,11 +35,60 @@ if (ol.ENABLE_PROJ4JS) {
ol.proj.setProj4 = function(proj4) {
ol.DEBUG && console.assert(typeof proj4 == 'function',
'proj4 argument should be a function');
ol.proj.proj4_ = proj4;
ol.proj.proj4.set(proj4);
};
}
/**
* Get the resolution of the point in degrees or distance units.
* For projections with degrees as the unit this will simply return the
* provided resolution. For other projections the point resolution is
* estimated by transforming the 'point' pixel to EPSG:4326,
* measuring its width and height on the normal sphere,
* and taking the average of the width and height.
* @param {ol.proj.Projection} projection The projection.
* @param {number} resolution Nominal resolution in projection units.
* @param {ol.Coordinate} point Point to find adjusted resolution at.
* @return {number} Point resolution at point in projection units.
* @api
*/
ol.proj.getPointResolution = function(projection, resolution, point) {
var pointResolution;
var getter = projection.getPointResolutionFunc();
if (getter) {
pointResolution = getter(resolution, point);
} else {
var units = projection.getUnits();
if (units == ol.proj.Units.DEGREES) {
pointResolution = resolution;
} else {
// Estimate point resolution by transforming the center pixel to EPSG:4326,
// measuring its width and height on the normal sphere, and taking the
// average of the width and height.
var toEPSG4326 = ol.proj.getTransformFromProjections(projection, ol.proj.get('EPSG:4326'));
var vertices = [
point[0] - resolution / 2, point[1],
point[0] + resolution / 2, point[1],
point[0], point[1] - resolution / 2,
point[0], point[1] + resolution / 2
];
vertices = toEPSG4326(vertices, vertices, 2);
var width = ol.sphere.NORMAL.haversineDistance(
vertices.slice(0, 2), vertices.slice(2, 4));
var height = ol.sphere.NORMAL.haversineDistance(
vertices.slice(4, 6), vertices.slice(6, 8));
pointResolution = (width + height) / 2;
var metersPerUnit = projection.getMetersPerUnit();
if (metersPerUnit !== undefined) {
pointResolution /= metersPerUnit;
}
}
}
return pointResolution;
};
/**
* Registers transformation functions that don't alter coordinates. Those allow
* to transform between projections with equal meaning.
@@ -435,7 +101,7 @@ ol.proj.addEquivalentProjections = function(projections) {
projections.forEach(function(source) {
projections.forEach(function(destination) {
if (source !== destination) {
ol.proj.addTransform(source, destination, ol.proj.cloneTransform);
ol.proj.transforms.add(source, destination, ol.proj.cloneTransform);
}
});
});
@@ -458,8 +124,8 @@ ol.proj.addEquivalentProjections = function(projections) {
ol.proj.addEquivalentTransforms = function(projections1, projections2, forwardTransform, inverseTransform) {
projections1.forEach(function(projection1) {
projections2.forEach(function(projection2) {
ol.proj.addTransform(projection1, projection2, forwardTransform);
ol.proj.addTransform(projection2, projection1, inverseTransform);
ol.proj.transforms.add(projection1, projection2, forwardTransform);
ol.proj.transforms.add(projection2, projection1, inverseTransform);
});
});
};
@@ -473,8 +139,8 @@ ol.proj.addEquivalentTransforms = function(projections1, projections2, forwardTr
* @api stable
*/
ol.proj.addProjection = function(projection) {
ol.proj.projections_[projection.getCode()] = projection;
ol.proj.addTransform(projection, projection, ol.proj.cloneTransform);
ol.proj.projections.add(projection.getCode(), projection);
ol.proj.transforms.add(projection, projection, ol.proj.cloneTransform);
};
@@ -490,11 +156,11 @@ ol.proj.addProjections = function(projections) {
/**
* FIXME empty description for jsdoc
* Clear all cached projections and transforms.
*/
ol.proj.clearAllProjections = function() {
ol.proj.projections_ = {};
ol.proj.transforms_ = {};
ol.proj.projections.clear();
ol.proj.transforms.clear();
};
@@ -514,25 +180,6 @@ ol.proj.createProjection = function(projection, defaultCode) {
};
/**
* Registers a conversion function to convert coordinates from the source
* projection to the destination projection.
*
* @param {ol.proj.Projection} source Source.
* @param {ol.proj.Projection} destination Destination.
* @param {ol.TransformFunction} transformFn Transform.
*/
ol.proj.addTransform = function(source, destination, transformFn) {
var sourceCode = source.getCode();
var destinationCode = destination.getCode();
var transforms = ol.proj.transforms_;
if (!(sourceCode in transforms)) {
transforms[sourceCode] = {};
}
transforms[sourceCode][destinationCode] = transformFn;
};
/**
* Registers coordinate transform functions to convert coordinates between the
* source projection and the destination projection.
@@ -555,9 +202,9 @@ ol.proj.addTransform = function(source, destination, transformFn) {
ol.proj.addCoordinateTransforms = function(source, destination, forward, inverse) {
var sourceProj = ol.proj.get(source);
var destProj = ol.proj.get(destination);
ol.proj.addTransform(sourceProj, destProj,
ol.proj.transforms.add(sourceProj, destProj,
ol.proj.createTransformFromCoordinateTransform(forward));
ol.proj.addTransform(destProj, sourceProj,
ol.proj.transforms.add(destProj, sourceProj,
ol.proj.createTransformFromCoordinateTransform(inverse));
};
@@ -595,32 +242,6 @@ ol.proj.createTransformFromCoordinateTransform = function(transform) {
};
/**
* Unregisters the conversion function to convert coordinates from the source
* projection to the destination projection. This method is used to clean up
* cached transforms during testing.
*
* @param {ol.proj.Projection} source Source projection.
* @param {ol.proj.Projection} destination Destination projection.
* @return {ol.TransformFunction} transformFn The unregistered transform.
*/
ol.proj.removeTransform = function(source, destination) {
var sourceCode = source.getCode();
var destinationCode = destination.getCode();
var transforms = ol.proj.transforms_;
ol.DEBUG && console.assert(sourceCode in transforms,
'sourceCode should be in transforms');
ol.DEBUG && console.assert(destinationCode in transforms[sourceCode],
'destinationCode should be in transforms of sourceCode');
var transform = transforms[sourceCode][destinationCode];
delete transforms[sourceCode][destinationCode];
if (ol.obj.isEmpty(transforms[sourceCode])) {
delete transforms[sourceCode];
}
return transform;
};
/**
* Transforms a coordinate from longitude/latitude to a different projection.
* @param {ol.Coordinate} coordinate Coordinate as longitude and latitude, i.e.
@@ -661,22 +282,22 @@ ol.proj.toLonLat = function(coordinate, opt_projection) {
* @api stable
*/
ol.proj.get = function(projectionLike) {
var projection;
var projection = null;
if (projectionLike instanceof ol.proj.Projection) {
projection = projectionLike;
} else if (typeof projectionLike === 'string') {
var code = projectionLike;
projection = ol.proj.projections_[code];
projection = ol.proj.projections.get(code);
if (ol.ENABLE_PROJ4JS) {
var proj4js = ol.proj.proj4_ || window['proj4'];
if (projection === undefined && typeof proj4js == 'function' &&
var proj4js = ol.proj.proj4.get();
if (!projection && typeof proj4js == 'function' &&
proj4js.defs(code) !== undefined) {
projection = new ol.proj.Projection({code: code});
ol.proj.addProjection(projection);
}
}
}
return projection || null;
return projection;
};
@@ -733,15 +354,29 @@ ol.proj.getTransform = function(source, destination) {
* @return {ol.TransformFunction} Transform function.
*/
ol.proj.getTransformFromProjections = function(sourceProjection, destinationProjection) {
var transforms = ol.proj.transforms_;
var sourceCode = sourceProjection.getCode();
var destinationCode = destinationProjection.getCode();
var transform;
if (sourceCode in transforms && destinationCode in transforms[sourceCode]) {
transform = transforms[sourceCode][destinationCode];
var transform = ol.proj.transforms.get(sourceCode, destinationCode);
if (ol.ENABLE_PROJ4JS && !transform) {
var proj4js = ol.proj.proj4.get();
if (typeof proj4js == 'function') {
var sourceDef = proj4js.defs(sourceCode);
var destinationDef = proj4js.defs(destinationCode);
if (sourceDef !== undefined && destinationDef !== undefined) {
if (sourceDef === destinationDef) {
ol.proj.addEquivalentProjections([destinationProjection, sourceProjection]);
} else {
var proj4Transform = proj4js(destinationCode, sourceCode);
ol.proj.addCoordinateTransforms(destinationProjection, sourceProjection,
proj4Transform.forward, proj4Transform.inverse);
}
transform = ol.proj.transforms.get(sourceCode, destinationCode);
}
}
}
if (transform === undefined) {
ol.DEBUG && console.assert(transform !== undefined, 'transform should be defined');
if (!transform) {
ol.DEBUG && console.assert(transform, 'transform should be defined');
transform = ol.proj.identityTransform;
}
return transform;

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