Compare commits

...

212 Commits

Author SHA1 Message Date
Bart van den Eijnden
84ed12ec46 Update package version to 3.7.0 2015-07-03 11:34:19 +02:00
Bart van den Eijnden
5fb692a876 Changelog for v3.7.0 2015-07-03 11:33:48 +02:00
Andreas Hocevar
06908775e8 Merge pull request #3867 from ahocevar/no-proj-extent-required
Do not require projection extent for x-wrapping tile sources
2015-07-03 11:25:06 +02:00
Andreas Hocevar
da66a37182 Do not require projection extent for x-wrapping tile sources 2015-07-03 11:05:49 +02:00
Bart van den Eijnden
96eaf2de06 Merge pull request #3635 from bjornharrtell/modify-singleclick-vertex
Create vertex on boundary single click
2015-07-03 11:00:33 +02:00
Andreas Hocevar
86d9d691e4 Merge pull request #3806 from ahocevar/clip-wrapx
Do not clip canvas for vector layers when wrapping the world
2015-07-03 10:47:45 +02:00
Björn Harrtell
c69ba6a3dd Create vertex on boundary single click 2015-07-03 10:26:38 +02:00
Bart van den Eijnden
2adf3befb8 Merge pull request #3461 from bjornharrtell/modifyevent
High level Modify interaction events
2015-07-03 10:24:43 +02:00
Björn Harrtell
f81e36d8e0 Add mapBrowserPointerEvent property to ModifyEvent 2015-07-03 10:11:24 +02:00
Björn Harrtell
f7d62f054c High level Modify interaction events 2015-07-03 10:11:24 +02:00
Bart van den Eijnden
c0b6eefd8f Merge pull request #3865 from bartvde/fit
ol.View#fit()
2015-07-02 16:58:33 +02:00
Andreas Hocevar
a09fa923a5 Merge pull request #3864 from klokantech/xyz-canwrapx
Check projection.canWrapX() before wrapping tiles
2015-07-02 17:04:11 +03:00
Bart van den Eijnden
7c207d47bb Move upgrade notes to 3.7 and fix typos 2015-07-02 15:23:34 +02:00
Petr Sloup
eac5d652cf Check projection.canWrapX() before wrapping tiles
Even if wrapX is true on the source
2015-07-02 15:21:34 +02:00
vmalaret
4d3e903670 ol.View#fit -- fix docs and add assertions 2015-07-02 15:19:09 +02:00
vmalaret
e7cd691362 rotation support for ol.View#calculateExtent 2015-07-02 15:19:08 +02:00
vmalaret
74759142d9 Replace fitGeometry and fitExtent with fit
Fit accepts either a geometry or an extent.

This combines two previously distinct functions
into one more flexible call.

Also brings the rotations support and options
previously available to fitGeometry to extents
2015-07-02 15:19:08 +02:00
Bart van den Eijnden
3021d3a6a7 Merge pull request #3863 from nhambletCCRI/cdataInGML
Handle CDATA in attribute parsing for GML format
2015-07-02 14:57:21 +02:00
Nick Hamblet
cfafe90235 Handle CDATA in attribute parsing for GML format
Following [3827](https://github.com/openlayers/ol3/issues/3827),
handle CDATA XML nodes in attribute parsing of GML data. Currently
such data will be expected to be a geometry, and will fail to parse.

Treating the CDATA node as text is the easiest way to handle such
an attribute.
2015-07-01 16:32:17 -04:00
Tim Schaub
ccaca9fc52 Merge pull request #3860 from tschaub/update-bootstrap
Update example layout.
2015-07-01 08:01:32 -06:00
Pierre GIRAUD
3f918f4e8d Merge pull request #3861 from openlayers/pgiraud-patch-1
Don't force 'dom' renderer
2015-07-01 12:59:01 +02:00
Pierre GIRAUD
5871d64c9d Don't force 'dom' renderer 2015-07-01 12:31:40 +02:00
Tim Schaub
d1f19b8e0d Use the latest Bootstrap 2015-06-30 22:30:28 -06:00
Pierre GIRAUD
3f214f6ac4 Merge pull request #3855 from pgiraud/wmts_ign
Adding an example with WMTS tiles from IGN Geoportail
2015-06-30 07:28:29 +02:00
Andreas Hocevar
0159d20d6d Merge pull request #3856 from plepe/bug-3851
ol.source.TileVector(): bind success function of tileLoadFunction to source
2015-06-29 22:35:15 +03:00
Stephan Bösch-Plepelits
ce20380078 ol.source.TileVector(): bind success function of tileLoadFunction to source
- fixes #3851
2015-06-29 21:01:08 +02:00
Pierre GIRAUD
f9e5c9c596 Adding an example with WMTS tiles from IGN Geoportail 2015-06-29 11:42:38 +02:00
Tim Schaub
7d04ef3e2d Merge pull request #3848 from tschaub/webpack
Check for exports before define.
2015-06-25 11:55:32 -06:00
Frédéric Junod
ced3633d80 Merge pull request #3845 from fredj/collection_null_array
Prevent null array to be passed to an ol.Collection
2015-06-25 09:25:37 +02:00
Pierre GIRAUD
e62b2e4479 Merge pull request #3849 from pgiraud/dms_notation_leading_zeros
Pad min. and sec. with leading zeros in DMS notation
2015-06-25 09:23:37 +02:00
Frederic Junod
8cf57941ac Prevent null array to be passed to ol.Collection 2015-06-25 09:11:38 +02:00
Frederic Junod
dd132c9fad Add non-nullable notation to features array 2015-06-25 09:11:38 +02:00
Pierre GIRAUD
1cdfc709ae Pad min. and sec. with leading zeros in DMS notation
FIxes 3776
2015-06-25 08:40:43 +02:00
Tim Schaub
1b01efc08b Check for exports before define 2015-06-24 21:53:52 -06:00
Pierre GIRAUD
28450cbb5a Merge pull request #3842 from pgiraud/feature_animation
Adding a feature-animation example
2015-06-24 16:09:50 +02:00
Pierre GIRAUD
1c341e288c Adding a feature-animation example 2015-06-24 15:31:43 +02:00
Andreas Hocevar
3f23deb09a Merge pull request #3833 from bjornharrtell/customtilexhr
Enable use of custom XHR loader for TileVector sources
2015-06-23 14:31:26 +02:00
Björn Harrtell
ceafa88dc8 Enable use of custom XHR loader for TileVector sources 2015-06-23 14:07:19 +02:00
Bart van den Eijnden
54186d7893 Merge pull request #3834 from bartvde/arcgisrest-dpi
ArcGIS tiled example broken in Chrome
2015-06-22 12:43:35 +02:00
Bart van den Eijnden
9a0c0e2f2b Make sure we don't generate any floating point DPI values for ol.source.TileArcGISRest 2015-06-22 12:01:14 +02:00
Éric Lemoine
c6d1778202 Merge pull request #3829 from kzr-pzr/master
incorrect assert message
2015-06-20 12:24:35 +02:00
peterko
e532727713 incorrect assert message 2015-06-20 11:09:36 +02:00
Andreas Hocevar
edc16b9739 Merge pull request #3828 from ahocevar/fix-doc-typo
Fix typo in upgrade notes
2015-06-20 10:35:36 +02:00
Andreas Hocevar
59871274ca Fix typo in upgrade notes 2015-06-20 10:34:28 +02:00
Andreas Hocevar
039b54de48 Merge pull request #3826 from klokantech/xyzsource-tilegrid
Allow custom tileGrid in ol.source.XYZ
2015-06-20 10:25:28 +02:00
Petr Sloup
5993b45c63 Allow custom tileGrid in ol.source.XYZ 2015-06-19 19:58:06 +02:00
Andreas Hocevar
5c5364bbb7 Merge pull request #3815 from ahocevar/tilegrid-no-surprises
Simplify tilegrid API and internals
2015-06-19 19:05:19 +02:00
Andreas Hocevar
6411c9267b More clarity about origin and direction of tile coordinates 2015-06-19 18:49:49 +02:00
Andreas Hocevar
f85fcf30a2 Additional tests 2015-06-19 18:34:26 +02:00
Andreas Hocevar
b5e0ae6f8c Explain changes in upgrade notes 2015-06-19 18:34:20 +02:00
Andreas Hocevar
e6f5c2a008 Cleanup and example updates 2015-06-19 18:34:19 +02:00
Andreas Hocevar
31cfa0d952 Make tile range calculation work with arbitrary origins 2015-06-19 18:34:19 +02:00
Andreas Hocevar
a753d282cc Use top-left corner of extent for all generated tile grids 2015-06-19 18:34:18 +02:00
Andreas Hocevar
e3a8dc89de Fix calculation of tile coord from coordinate
Tile coord calculation was wrong in the case of reverseIntersectionPolicy
for y coords, and for extents with +/- Infinity.
2015-06-19 18:34:18 +02:00
Andreas Hocevar
18aa9b5091 Remove unused createFromQuadKey function 2015-06-19 18:34:18 +02:00
Andreas Hocevar
84e051d19b Fix TileDebugSource to display '' for out-of-range tiles 2015-06-19 18:34:18 +02:00
Andreas Hocevar
af319c259b Do not transform tile coordinates for tileUrlFunction 2015-06-19 18:34:09 +02:00
Andreas Hocevar
0af5642569 Merge pull request #3820 from ahocevar/vectorlayer-like-featureoverlay
Make unmanaged vector layers behave more like ol.FeatureOverlay
2015-06-19 18:18:07 +02:00
Andreas Hocevar
7463a58066 Do not clip canvas for vector layers when wrapping the world 2015-06-19 14:55:20 +02:00
Andreas Hocevar
f645a9e1e4 Make unmanaged vector layers behave more like ol.FeatureOverlay
* Skipped features need to be hit-detected on unmanaged layers.
* updateWhileAnimating and updateWhileInteracting are recommended to
  achieve the same instant visual feedback that ol.FeatureOverlay had.
2015-06-19 13:06:29 +02:00
Andreas Hocevar
a9591f8b99 Merge pull request #3822 from probins/update
Correct docs for updateWhileInteracting
2015-06-19 12:59:30 +02:00
Peter Robins
43d9ebe51d Correct docs for updateWhileInteracting 2015-06-19 07:24:12 +00:00
Tim Schaub
aa90c97ba3 Merge pull request #3818 from probins/transform
Make geometry.transform api stable again.
2015-06-18 10:42:08 -06:00
Peter Robins
874c4aef21 Make Geometry.transform api stable again 2015-06-18 16:01:25 +00:00
Andreas Hocevar
2249c82ac2 Merge pull request #3801 from ahocevar/tilevector-extent
Respect the tile grid's extent in ol.source.TileVector
2015-06-18 10:46:48 +02:00
Andreas Hocevar
a2c9a0796c Merge pull request #3810 from ahocevar/tilegrid-example-docs
Improve TileGrid documentation and examples
2015-06-16 23:53:49 +02:00
Andreas Hocevar
d6bb13b54b Add note about extent 2015-06-16 18:47:50 +02:00
Andreas Hocevar
d628f6b098 Use the tileSize variable 2015-06-16 17:16:28 +02:00
Andreas Hocevar
e2da56afa1 Tile grid documentation improvements
Using the term 'bottom-left' for origin and origins is misleading, because
many developers use -y-1 for the tile url's y in their tile url functions,
and the origin really only determines where tile coordinates start to
increase from left to right and from bottom to top.
2015-06-16 17:16:19 +02:00
Frédéric Junod
f74e4c95ff Merge pull request #3808 from probins/patch-1
Correct typo in OverlayOptions
2015-06-16 10:37:53 +02:00
Éric Lemoine
b8cb1fe795 Merge pull request #3766 from elemoine/draw-click-tolerance
Add a clickTolerance option to the Draw interaction
2015-06-16 10:06:01 +02:00
Peter Robins
1e8968d97a Correct typo in OverlayOptions 2015-06-16 09:04:12 +01:00
Andreas Hocevar
9c480d77f5 Merge pull request #3804 from ahocevar/fix-tilegrid-docs
Remove sentence that was only meant for WMTS tile grids
2015-06-15 16:44:54 +02:00
Andreas Hocevar
0e943f5832 Remove sentence that was only meant for WMTS tile grids 2015-06-15 16:08:29 +02:00
Éric Lemoine
e99f43af8d Add a clickTolerance option to the Draw interaction 2015-06-15 15:32:34 +02:00
Andreas Hocevar
2bcb10c973 Respect the tile grid's extent
By adding a getTileCoordForTileUrlFuction method like for ol.source.Tile,
we can now properly handle extent and resolution restrictions, and reuse
tiles on wrapped worlds. Also adds the missing wrapX option to
ol.source.TileVector.
2015-06-15 11:15:25 +02:00
Andreas Hocevar
9301fff6cb Merge pull request #3800 from probins/editstyle
Remove further references to FeatureOverlay
2015-06-13 19:08:50 +02:00
Peter Robins
83c33a03c6 Remove further references to FeatureOverlay 2015-06-13 14:01:45 +00:00
Andreas Hocevar
e848acd806 Merge pull request #3780 from ahocevar/call-tileurlfunction-with-transformed-tilecoord
Only expose transformed tile coordinates to the API
2015-06-12 11:18:16 +02:00
Andreas Hocevar
72cc824502 Explain changes in upgrade notes 2015-06-12 09:47:43 +02:00
Andreas Hocevar
4b3aac32c3 Return transformed tile coordinates from ol.TileGrid's API methods 2015-06-12 09:47:32 +02:00
Andreas Hocevar
acab0ebd57 Display transformed tile coordinates in ol.source.TileDebug 2015-06-12 09:46:17 +02:00
Andreas Hocevar
6a4d1c9b89 Pass transformed tile coordinates to the tileUrlFunction 2015-06-12 09:45:03 +02:00
Andreas Hocevar
698b62af98 Merge pull request #3793 from ahocevar/unmanaged-to-managed
Use 'managed' instead of 'unmanaged' in LayerState
2015-06-11 18:56:31 +02:00
Andreas Hocevar
817370a65b Use 'managed' instead of 'unmanaged' in LayerState 2015-06-11 18:34:20 +02:00
Marc Jansen
07d5211e30 Merge pull request #3792 from marcjansen/group-docs
Link to correct layer base class
2015-06-11 17:57:57 +02:00
Marc Jansen
3fcecc98e6 Merge pull request #3791 from marcjansen/overlay-remains
Remove docs referring to removed feature overlay
2015-06-11 17:55:50 +02:00
Marc Jansen
6ed677a3f0 Link to correct layer base class 2015-06-11 17:50:40 +02:00
Marc Jansen
dd16bb984c Remove docs referring to removed feature overlay 2015-06-11 17:47:16 +02:00
Frédéric Junod
f672c1792b Merge pull request #3790 from fredj/geojson_quotes
Remove unnecessary quotes around object keys
2015-06-11 13:32:58 +02:00
Frederic Junod
0286564e8a Remove unnecessary quotes around object keys 2015-06-11 11:58:11 +02:00
Andreas Hocevar
96e75ab17f Merge pull request #3787 from ahocevar/unmanaged-layerstate
Add 'unmanaged' to ol.layer.LayerState
2015-06-11 10:53:38 +02:00
Frédéric Junod
a6dddfa282 Merge pull request #3784 from fredj/geojson_geometry
Always write the GeoJSONFeature geometry property
2015-06-11 10:20:02 +02:00
Andreas Hocevar
5a2a7d30e6 Add 'unmanaged' to ol.layer.LayerState 2015-06-11 10:17:11 +02:00
Frederic Junod
d5ea855108 Add missing GeoJSONGeometryCollection type to GeoJSONFeature#geometry 2015-06-11 09:53:06 +02:00
Frederic Junod
d8a495b639 Always write the GeoJSONFeature geometry property 2015-06-11 09:53:06 +02:00
Andreas Hocevar
4aa3ef59d5 Merge pull request #3783 from ahocevar/wmts-hidpi-from-capabilities
Fix broken wmts-hidpi example
2015-06-10 20:03:53 +02:00
Andreas Hocevar
7451e176ef Use capabilities to create layer source options 2015-06-10 18:32:21 +02:00
Andreas Hocevar
872d869ded Merge pull request #3782 from gberaudo/typo
Fix assert documentation typo
2015-06-10 15:47:35 +02:00
Guillaume Beraudo
d48e818390 Fix assert documentation typo 2015-06-10 15:36:43 +02:00
Andreas Hocevar
fad3cf9672 Merge pull request #3758 from ahocevar/remove-featureoverlay
Removal of ol.FeatureOverlay
2015-06-10 14:33:28 +02:00
Andreas Hocevar
9acd65270a Make clear how to remove an unmanaged layer from a map 2015-06-09 15:44:39 +02:00
Andreas Hocevar
57e1dda5f1 Make sure that #clear() keeps the collection in sync 2015-06-09 15:44:39 +02:00
Andreas Hocevar
53d5d8c1d9 Get rid of ol.FeatureOverlay
This also introduces a wrapX option to the Draw, Modify and Select
interaction.
2015-06-09 15:44:31 +02:00
Andreas Hocevar
54da473991 Allow layers that are not managed by the map
When a layer is configured with a map, it will be added on top of other
layers, and not be managed in the map's features collection. The layerState
will have an 'unmanaged' flag for such layers. For vector layers, this flag
is used to not skip any features.
2015-06-09 15:44:29 +02:00
Andreas Hocevar
f186ed3deb Alternatively manage features in an ol.Collection
ol.layer.Vector can now manage both an RTree and a Collection of features.
The new useSpatialIndex option allows to opt out of RTree management, and
the new ol.Collection type of the features option allows to opt in for
Collection management.
2015-06-09 15:44:18 +02:00
Pierre GIRAUD
973cc6fd89 Merge pull request #3775 from pgiraud/touch-classname
Add ol-touch but keep ol-viewport className.
2015-06-09 12:20:55 +02:00
Pierre GIRAUD
36b521a00e Add ol-touch but keep ol-viewport className. 2015-06-09 11:34:19 +02:00
Bart van den Eijnden
10b54a9f3f Merge pull request #3713 from bartvde/issue-3713
Add missing propertyNames member for olx.format.WFSWriteGetFeatureOptions
2015-06-08 16:15:17 +02:00
Bart van den Eijnden
e3bc0bca3e Add missing propertyNames member for olx.format.WFSWriteGetFeatureOptions extern 2015-06-08 15:56:42 +02:00
Andreas Hocevar
b903cee7dd Merge pull request #3763 from probins/drawmod
Standardise draw/modify descriptions
2015-06-07 17:34:47 +02:00
Andreas Hocevar
2e406c9633 Merge pull request #3767 from openlayers/release-v3.6.0
Release v3.6.0
2015-06-07 14:18:09 +02:00
Andreas Hocevar
9f4112a8f9 Update package version to 3.6.0 2015-06-07 14:16:34 +02:00
Andreas Hocevar
30ddbad4fe Changelog for v3.6.0 2015-06-07 14:14:49 +02:00
Marc Jansen
efd1caf00f Merge pull request #3764 from alvinlindstam/intersectsExtent
Add tests and implementation for intersectsExtent (ol.geom.Geometry)
2015-06-05 14:52:50 +02:00
Marc Jansen
488a55c83c Add more tests for intersectsExtent 2015-06-05 14:20:06 +02:00
Alvin Lindstam
1dc6c99328 Make ol.geom.Circle support #intersectsExtent, with tests 2015-06-05 14:19:46 +02:00
Alvin Lindstam
405d5666e2 Add tests for intersectsExtent/getExtent
This commit adds tests for `intersectsExtent` of Point, LineString, Polygon,
MultiPoint, MultiLineString, MultiPolygon and GeometryCollection.

It also adds a basic test for `getExtent` of MultiPolygon
2015-06-05 14:19:46 +02:00
Peter Robins
282fdafad7 Standardise draw/modify descriptions 2015-06-05 07:54:22 +00:00
Andreas Hocevar
bad5a97d20 Merge pull request #3757 from bjornharrtell/selectevent-browser
Add mapBrowserEvent as a member of ol.SelectEvent
2015-06-04 18:56:55 +02:00
Björn Harrtell
9a9b838235 Add mapBrowserEvent as a member of ol.SelectEvent 2015-06-04 16:53:53 +02:00
Marc Jansen
5bdfc35d35 Merge pull request #3759 from gberaudo/api_tilegrid_createTileCoordTransform
Mark tilegrid.createTileCoordTransform() @api
2015-06-04 10:19:34 +02:00
Guillaume Beraudo
361d83dc73 Mark tilegrid.createTileCoordTransform() @api
Necessary since the removal of tilegridXYZ type.
2015-06-04 09:24:35 +02:00
Andreas Hocevar
8f2cfe9420 Merge pull request #3747 from ahocevar/tilecoordtransform
Make tileCoordTransform a member again
2015-06-03 14:11:00 +02:00
Andreas Hocevar
5d9708be11 Add tests 2015-06-03 12:41:35 +02:00
Andreas Hocevar
ea7879f616 Merge pull request #3751 from ahocevar/tilejson-test
Do not rely on remote services for tests
2015-06-01 11:23:52 +02:00
Andreas Hocevar
682c816b9b Do not rely on remote services for tests 2015-06-01 10:09:38 +02:00
Marc Jansen
b1289dbae7 Merge pull request #3749 from marcjansen/typo
Fix typo in API docs
2015-06-01 08:51:56 +02:00
Marc Jansen
cf99bcbba1 Fix typo in API docs 2015-06-01 07:56:58 +02:00
Andreas Hocevar
5ae2521724 Make tileCoordTransform configurable
Instead of using the static createOriginTopLeftTileCoordTransform
function, the correct transform is now a non-API config option of the tile
grid.
2015-05-31 22:22:41 +02:00
Marc Jansen
81b13f295b Merge pull request #3739 from marcjansen/simpler-scientific-wkt
Simplify detection of scientific notation in WKT format
2015-05-31 15:50:50 +02:00
Marc Jansen
e43573bcf2 Merge pull request #3741 from marcjansen/callback-docs
Enhance docs of arguments and return values of callbacks / filters
2015-05-29 13:52:27 +02:00
Marc Jansen
894be51b36 Merge pull request #3740 from probins/fireselect
Add @fires to select interaction
2015-05-29 13:30:05 +02:00
Marc Jansen
b06f3457da Enhance docs of arguments of callbacks/filters 2015-05-29 13:20:58 +02:00
Peter Robins
7f1053d2cd Add @fires to select interaction 2015-05-29 10:59:07 +00:00
Marc Jansen
96741e1f0b Simplify detection of scientific notation
This change allows us to remove some avoidable function calls (specifically
to goog.isDef(c) and  c.toLowerCase()). Additionally, the new check is simpler
to read.
2015-05-29 09:33:29 +02:00
Andreas Hocevar
f5cd9a3eba Merge pull request #3738 from ahocevar/tileurlfunction-docs
Improve doucmentation for ol.TileUrlFunctionType
2015-05-28 22:48:19 +02:00
Andreas Hocevar
4196e34c73 Improve doucmentation for ol.TileUrlFunctionType 2015-05-28 18:52:35 +02:00
Frédéric Junod
22bed40f5c Merge pull request #3736 from fredj/examples_html_markup
Fix invalid example HTML markup
2015-05-28 10:44:51 +02:00
Frédéric Junod
a33008be9e Merge pull request #3735 from probins/snap
Snap example: remove featureoverlay from tags
2015-05-28 10:26:52 +02:00
Frederic Junod
746116d266 Fix invalid example HTML markup 2015-05-28 10:23:14 +02:00
Peter Robins
1f6d2eff96 Snap example: remove featureoverlay from tags 2015-05-28 07:57:17 +00:00
Marc Jansen
764f821a70 Merge pull request #3732 from marcjansen/control-blur-binding
Add a method to bind button bluring on mouseout/focusout
2015-05-27 09:22:15 +02:00
Marc Jansen
41596d808b Add method to bind bluring on mouseout/focusout 2015-05-26 22:32:09 +02:00
Frédéric Junod
ec208916d2 Merge pull request #3659 from fredj/undo_forEachFeatureAtCoordinate
Revert "Implement ol.renderer.Layer#forEachFeatureAtCoordinate"
2015-05-26 09:34:06 +02:00
Bart van den Eijnden
78dcbe6b8e Merge pull request #3683 from probins/group
Improve Map docs for layers and layergroups
2015-05-23 17:25:25 +02:00
Peter Robins
074941bf1f Improve Map docs for layers and layergroups 2015-05-23 11:53:37 +00:00
Éric Lemoine
824a77e41b Merge pull request #3720 from elemoine/missingprovides
Add missing goog.provides in drawinteraction.js
2015-05-22 12:15:56 +02:00
Éric Lemoine
e766d00e7b Add upgrade note of ol.DrawEvent and ol.DrawEventType 2015-05-22 11:58:48 +02:00
Frédéric Junod
2e2d08f552 Merge pull request #3725 from fredj/doc
Document default value for olx.interaction.ModifyOptions#pixelTolerance
2015-05-22 11:43:38 +02:00
Frederic Junod
9870fe58e0 Document default value for olx.interaction.ModifyOptions#pixelTolerance 2015-05-22 11:26:58 +02:00
Andreas Hocevar
80efbb60d0 Merge pull request #3722 from ahocevar/tilejson-tilegrid
Use the correct TileCoord transform function
2015-05-22 11:08:07 +02:00
Andreas Hocevar
111e6db8c8 Add tests 2015-05-22 10:55:18 +02:00
Andreas Hocevar
f40aa54c18 Use the correct TileCoord transform function 2015-05-22 09:19:59 +02:00
Éric Lemoine
531b35d7c2 Be consistent with the way we name types 2015-05-21 17:32:32 +02:00
Éric Lemoine
879307da1b Add missing goog.provides in drawinteraction.js 2015-05-21 15:41:51 +02:00
Éric Lemoine
acb0a8da53 Merge pull request #3692 from bill-chadwick/windows
Updates for building on Windows using Cygwin.
2015-05-21 12:57:34 +02:00
Tobias Sauerwein
e87b616de8 Merge pull request #3718 from tsauerwein/renderOrder-assertion
Add a assertion for renderOrder
2015-05-21 11:20:27 +02:00
tsauerwein
a3f9b3ba43 Add assertion for renderOrder 2015-05-21 09:26:47 +02:00
Bart van den Eijnden
680f140858 Merge pull request #3711 from marcjansen/color
Fix and test ol.color.blend
2015-05-20 15:25:54 +02:00
Marc Jansen
b6a4188ce4 Fix and test ol.color.blend 2015-05-20 12:50:52 +02:00
Andreas Hocevar
4be106d014 Merge pull request #3673 from ahocevar/draw-regular-polygon
More control over ol.interaction.Draw, to allow e.g. square drawing
2015-05-20 12:08:15 +02:00
Andreas Hocevar
100020fd59 Refactoring for more consistency
* Min and max number of points configurable for lines and polygons
* Polygons from custom geometryFunction now have a sketch line
* The example shows how to use a custom geometryFunction
2015-05-20 10:28:16 +02:00
Marc Jansen
3580cdc823 Merge pull request #3710 from marcjansen/extent-tests
Add more tests for ol.extent
2015-05-20 06:26:49 +02:00
Marc Jansen
f0720b2f97 Add more tests for ol.extent 2015-05-19 22:25:55 +02:00
Bart van den Eijnden
e578f98c73 Merge pull request #3709 from bartvde/issue-3709
vector-wfs example does not work in JSFiddle
2015-05-19 21:58:50 +02:00
Bart van den Eijnden
1dbf8cd4d6 Make sure vector-wfs example works in JSFiddle 2015-05-19 21:08:30 +02:00
Marc Jansen
0f36d1a7c2 Merge pull request #3699 from marcjansen/scientific-wkt
Add support for scientific notation to WKT format
2015-05-18 12:00:56 +02:00
Marc Jansen
2b76bc05a5 Add support for scientific notation to WKT format 2015-05-18 11:27:39 +02:00
Marc Jansen
1ac41c7403 Merge pull request #3696 from marcjansen/will-it-blend
Add an example for various blend modes
2015-05-15 17:09:33 +02:00
Marc Jansen
96550c8fcf Merge pull request #3697 from marcjansen/npm-license-warning
Use a valid SPDX license expression
2015-05-15 16:58:50 +02:00
Marc Jansen
26f1062dbf Use a valid SPDX license expression 2015-05-15 13:55:22 +02:00
Marc Jansen
26ad3fe6b1 Add an example for various blend modes 2015-05-15 13:33:31 +02:00
Éric Lemoine
34986b0870 Merge pull request #3694 from probins/patch-2
Correct typo in upgrade-notes
2015-05-15 10:26:06 +02:00
Andreas Hocevar
19c91235ce Add convenience function to create a regular polygon geometryFunction 2015-05-14 23:24:29 +02:00
Andreas Hocevar
901a0f6d8e Add functions to create regular polygons 2015-05-14 23:24:29 +02:00
Andreas Hocevar
250221cded Add new geometryFunction option
This allows applications to control the geometry that is created from the
drawing sketch. Will e.g. be useful to create a regular polygon instead of
a circle when in Circle mode.
2015-05-14 23:24:29 +02:00
Andreas Hocevar
4e94908440 Define getCoordinates and setCoordinates in the base class
Since these methods are implemented by all subclasses, it makes sense to
define them in the base class as abstract method.
2015-05-14 23:24:29 +02:00
Peter Robins
23b207dae4 Correct typo in upgrade-notes 2015-05-14 16:08:16 +01:00
Éric Lemoine
16c4082898 Merge pull request #3693 from tremby/contains-extent-doc
Fix ol.extent.containsExtent documentation
2015-05-14 09:10:45 +02:00
bill-chadwick
51c8bcae57 Updates for building on Windows using Cygwin.
Tested on Windows 7.
2015-05-14 07:08:16 +01:00
Bart Nagel
b606f4996b Fix ol.extent.containsExtent documentation
The `ol.extent.containsExtent` documentation had its arguments backwards
(or the implementation did).

The documentation said "the first extent is contained by or on the edge
of the second", but the function checked the opposite.

The wording was also a little strange, since from the name of the
function alone `containsExtent` I'd guess that the first argument would
be the (potential) container, and the second would be the (potentially)
contained. But the documentation has the wording "check if one extent is
*contained by* or on the edge of another", suggesting the first argument
is the contained and the second the container.

This patch keeps the current functionality but clarifies the
documentation.
2015-05-13 12:10:06 -07:00
Éric Lemoine
7dc2a2b97e Merge pull request #3689 from probins/wmts
Fix WMTS.optionsFromCapabilities if no OperationsMetadata section
2015-05-13 15:22:34 +02:00
Peter Robins
a243149d02 Fix WMTS.optionsFromCapabilities if no OperationsMetadata section 2015-05-13 12:43:12 +00:00
Frédéric Junod
a314813511 Merge pull request #3688 from fredj/failIfMajorPerformanceCaveat_externs
Add two missing properties to extern of WebGLContextAttributes
2015-05-12 15:14:05 +02:00
Frederic Junod
fe79389fd3 Add two missing properties to extern of WebGLContextAttributes
To be removed when the closure-compiler is updated
2015-05-12 13:55:13 +02:00
Bart van den Eijnden
d5c69b2e5e Merge pull request #3682 from bartvde/api-addlayer
Add a note about using the collection in addLayer
2015-05-10 17:32:19 +02:00
Bart van den Eijnden
2724292de1 Add a note about using the collection in addLayer 2015-05-10 12:20:02 +02:00
Éric Lemoine
829337c219 Merge pull request #3649 from elemoine/servejs
More specific regex in serve.js
2015-05-09 16:34:43 +02:00
Tim Schaub
549d0a7601 Merge pull request #3677 from tschaub/example-metadata
Add metadata to examples,
2015-05-09 08:34:04 -06:00
Tim Schaub
b602285992 Add metadata to the mobile full-screen example 2015-05-08 06:39:06 -06:00
Tim Schaub
82b1355591 Add metadata to the geolocation orientation example 2015-05-08 06:31:34 -06:00
Marc Jansen
249f432b2e Merge pull request #3672 from marcjansen/link-faq
Add link to FAQ-document and fix internal links
2015-05-08 12:27:17 +02:00
Marc Jansen
45a5b1d24e Add link to FAQ-document and fix internal links 2015-05-08 11:02:39 +02:00
Marc Jansen
c5b788f370 Merge pull request #3665 from marcjansen/missing-resources
Add proj4js and projection definition files to example resources
2015-05-06 15:26:22 +02:00
Marc Jansen
ebded733f7 Add proj4js/projection definition files to example 2015-05-06 13:27:27 +02:00
Tobias Sauerwein
e4e91b82d6 Merge pull request #3662 from tsauerwein/renderbuffer-docs
Clarify docs for renderBuffer option
2015-05-06 09:09:12 +02:00
Tim Schaub
8f9cde0595 Merge pull request #3664 from tschaub/download-page
Link to download page.
2015-05-05 15:27:23 -06:00
Tim Schaub
f47d873ae5 Link to download page 2015-05-05 14:11:11 -06:00
Andreas Hocevar
492a3c8f7a Merge pull request #3639 from ahocevar/tilegrid-extent
Add extent support to ol.tilegrid.TileGrid
2015-05-05 19:22:10 +02:00
Tim Schaub
0bf70489b6 Merge pull request #3663 from tschaub/fewer-version-numbers
Readme should not include the version number.
2015-05-05 11:21:42 -06:00
Andreas Hocevar
32efd99397 Do not require projection extent for WMTS bbox validity check 2015-05-05 18:52:33 +02:00
Andreas Hocevar
0650a97371 Explain tilegrid and xyz source changes 2015-05-05 18:52:33 +02:00
Andreas Hocevar
b05193fa45 Replace ol.tilegrid.XYZ with an ol.tilegrid.createXYZ function 2015-05-05 18:52:33 +02:00
Andreas Hocevar
a116878a57 Allow extents to restrict tile ranges requested from the server
The addition of full extent tile ranges also allows us to simplify wrapX
handling for tile layers. By limiting wrapX to true and false as possible
values, we can remove a lot of guessing logic.
2015-05-05 18:52:33 +02:00
Andreas Hocevar
700903ca5c Add tests for ol.tilegrid.TileGrid
These tests are taken from ol.tilegrid.XYZ, to make sure that
ol.tilegrid.TileGrid works the same way. The additional tests show that the
#getTileCoordForXYAndResolution_() method do not handle coordinates at
tile boundaries properly, so this is fixed.
2015-05-05 18:52:32 +02:00
Tim Schaub
4192092dcf Readme should not include the version number
We should not repeat the version number throughout the source.  Eventually, the download page will be http://openlayers.org/download/.
2015-05-05 10:28:03 -06:00
tsauerwein
c0d9a822f8 Clarify docs for renderBuffer 2015-05-05 17:22:33 +02:00
Frederic Junod
bb6192bc10 Revert "Implement ol.renderer.Layer#forEachFeatureAtCoordinate"
This reverts commit dd07fd7977.
2015-05-05 09:38:50 +02:00
Frédéric Junod
56e8575e41 Merge pull request #3637 from fredj/forEachFeatureAtCoordinate
Implement ol.renderer.Layer#forEachFeatureAtCoordinate
2015-05-05 07:48:54 +02:00
Éric Lemoine
762bb0f055 More specific regex in serve.js
This is to be able to use the dev server (`npm start`) to serve the hosted examples (located in the `build/hosted/<branch>` dir after `make host-examples`).
2015-04-30 09:14:40 +02:00
Frederic Junod
dd07fd7977 Implement ol.renderer.Layer#forEachFeatureAtCoordinate
And remove identical implementation in children classes.
2015-04-28 14:08:45 +02:00
161 changed files with 5418 additions and 2222 deletions

View File

@@ -329,3 +329,33 @@ Occasionally other changes to `master` might mean that your pull request cannot
be merged automatically. In this case you may need to rebase your branch on a
more recent `master`, resolve any conflicts, and `git push --force` to update
your branch so that it can be merged automatically.
## Building on Windows
Most developers build on Linux. Building on Windows is possible under Cygwin.
When installing Cygwin from https://www.cygwin.com/, include the developer
tools to get GNU make.
First (before npm install), to avoid file permission problems between Windows
and Cygwin, edit Cygwin's /etc/fstab file to disable ACLs like this
`none /cygdrive cygdrive binary,noacl,posix=0,user 0 0`
Python is normally installed with Cygwin so need not be installed separately.
By default Cygwin will use its own version of Python rather than Window's,
so the Python modules should be installed for Cygwin's Python.
The build targets `check-deps`, `serve`, `lint`, `build`, `test`, `check` and
`host-examples` described above should all work. `host-examples` takes quite a
while to run. If a target does not run properly first time, try it again.
Currently, Firefox fails to run http://localhost:3000/build/examples
from make serve, but Chrome and Internet Explorer will.
Microsoft Visual Studio's javascript debugger may be used to debug the
build/hosted/your-branch/examples. It will be convenient to set
build/hosted/your-branch/examples/index.html as the startup page.
Your ol3 source tree need not be under the Cygwin root.
if you checkout to c:/ol3 then you can build under Cygwin at /cygdrive/c/ol3 .
However, keep the path to the ol3 files short otherwise you may see
`ENAMETOOLONG` errors.

View File

@@ -23,7 +23,11 @@ CHECK_EXAMPLE_TIMESTAMPS = $(patsubst examples/%.html,build/timestamps/check-%-t
TASKS_JS := $(shell find tasks -name '*.js')
CLOSURE_LIB = $(shell node -e 'process.stdout.write(require("closure-util").getLibraryPath())')
ifeq (CYGWIN,$(findstring CYGWIN,$(OS)))
CLOSURE_LIB = $(shell cygpath -u $(shell node -e 'process.stdout.write(require("closure-util").getLibraryPath())'))
else
CLOSURE_LIB = $(shell node -e 'process.stdout.write(require("closure-util").getLibraryPath())')
endif
ifeq ($(OS),Darwin)
STAT_COMPRESSED = stat -f ' compressed: %z bytes'

View File

@@ -7,7 +7,7 @@
## Getting Started
- Download the [latest release](https://github.com/openlayers/ol3/releases/tag/v3.4.0)
- Download the [latest release](http://openlayers.org/download/)
- Install with npm: `npm install openlayers`
- Clone the repo: `git clone git@github.com:openlayers/ol3.git`

View File

@@ -1,5 +1,123 @@
## Upgrade notes
### v3.8.0
### v3.7.0
#### Removal of `ol.FeatureOverlay`
Instead of an `ol.FeatureOverlay`, we now use an `ol.layer.Vector` with an
`ol.source.Vector`. If you previously had:
```js
var featureOverlay = new ol.FeatureOverlay({
map: map,
style: overlayStyle
});
featureOverlay.addFeature(feature);
featureOverlay.removeFeature(feature);
var collection = featureOverlay.getFeatures();
```
you will have to change this to:
```js
var collection = new ol.Collection();
var featureOverlay = new ol.layer.Vector({
map: map,
source: new ol.source.Vector({
features: collection,
useSpatialIndex: false // optional, might improve performance
}),
style: overlayStyle,
updateWhileAnimating: true, // optional, for instant visual feedback
updateWhileInteracting: true // optional, for instant visual feedback
});
featureOverlay.getSource().addFeature(feature);
featureOverlay.getSource().removeFeature(feature);
```
With the removal of `ol.FeatureOverlay`, `zIndex` symbolizer properties of overlays are no longer stacked per map, but per layer/overlay. If you previously had multiple feature overlays where you controlled the rendering order of features by using `zIndex` symbolizer properties, you can now achieve the same rendering order only if all overlay features are on the same layer.
Note that `ol.FeatureOverlay#getFeatures()` returned an `{ol.Collection.<ol.Feature>}`, whereas `ol.source.Vector#getFeatures()` returns an `{Array.<ol.Feature>}`.
#### `ol.TileCoord` changes
Until now, the API exposed two different types of `ol.TileCoord` tile coordinates: internal ones that increase left to right and upward, and transformed ones that may increase downward, as defined by a transform function on the tile grid. With this change, the API now only exposes tile coordinates that increase left to right and upward.
Previously, tile grids created by OpenLayers either had their origin at the top-left or at the bottom-left corner of the extent. To make it easier for application developers to transform tile coordinates to the common XYZ tiling scheme, all tile grids that OpenLayers creates internally have their origin now at the top-left corner of the extent.
This change affects applications that configure a custom `tileUrlFunction` for an `ol.source.Tile`. Previously, the `tileUrlFunction` was called with rather unpredictable tile coordinates, depending on whether a tile coordinate transform took place before calling the `tileUrlFunction`. Now it is always called with OpenLayers tile coordinates. To transform these into the common XYZ tiling scheme, a custom `tileUrlFunction` has to change the `y` value (tile row) of the `ol.TileCoord`:
```js
function tileUrlFunction = function(tileCoord, pixelRatio, projection) {
var urlTemplate = '{z}/{x}/{y}';
return urlTemplate
.replace('{z}', tileCoord[0].toString())
.replace('{x}', tileCoord[1].toString())
.replace('{y}', (-tileCoord[2] - 1).toString());
}
```
The `ol.tilegrid.TileGrid#createTileCoordTransform()` function which could be used to get the tile grid's tile coordinate transform function has been removed. This function was confusing and should no longer be needed now that application developers get tile coordinates in a known layout.
The code snippets below show how your application code needs to be changed:
Old application code (with `ol.tilegrid.TileGrid#createTileCoordTransform()`):
```js
var transform = source.getTileGrid().createTileCoordTransform();
var tileUrlFunction = function(tileCoord, pixelRatio, projection) {
tileCoord = transform(tileCoord, projection);
return 'http://mytiles.com/' +
tileCoord[0] + '/' + tileCoord[1] + '/' + tileCoord[2] + '.png';
};
```
Old application code (with custom `y` transform):
```js
var tileUrlFunction = function(tileCoord, pixelRatio, projection) {
var z = tileCoord[0];
var yFromBottom = tileCoord[2];
var resolution = tileGrid.getResolution(z);
var tileHeight = ol.size.toSize(tileSize)[1];
var matrixHeight =
Math.floor(ol.extent.getHeight(extent) / tileHeight / resolution);
return 'http://mytiles.com/' +
tileCoord[0] + '/' + tileCoord[1] + '/' +
(matrixHeight - yFromBottom - 1) + '.png';
};
```
New application code (simple -y - 1 transform):
```js
var tileUrlFunction = function(tileCoord, pixelRatio, projection) {
return 'http://mytiles.com/' +
tileCoord[0] + '/' + tileCoord[1] + '/' + (-tileCoord[2] - 1) + '.png';
};
```
#### Removal of `ol.tilegrid.Zoomify`
The replacement of `ol.tilegrid.Zoomify` is a plain `ol.tilegrid.TileGrid`, configured with `extent`, `origin` and `resolutions`. If the `size` passed to the `ol.source.Zoomify` source is `[width, height]`, then the extent for the tile grid will be `[0, -height, width, 0]`, and the origin will be `[0, 0]`.
#### Replace `ol.View.fitExtent()` and `ol.View.fitGeometry()` with `ol.View.fit()`
* This combines two previously distinct functions into one more flexible call which takes either a geometry or an extent.
* Rename all calls to `fitExtent` and `fitGeometry` to `fit`.
#### Change to `ol.interaction.Modify`
When single clicking a line or boundary within the `pixelTolerance`, a vertex is now created.
### v3.6.0
#### `ol.interaction.Draw` changes
* The `minPointsPerRing` config option has been renamed to `minPoints`. It is now also available for linestring drawing, not only for polygons.
* The `ol.DrawEvent` and `ol.DrawEventType` types were renamed to `ol.interaction.DrawEvent` and `ol.interaction.DrawEventType`. This has an impact on your code only if your code is compiled together with ol3.
#### `ol.tilegrid` changes
* The `ol.tilegrid.XYZ` constructor has been replaced by a static `ol.tilegrid.createXYZ()` function. The `ol.tilegrid.createXYZ()` function takes the same arguments as the previous `ol.tilegrid.XYZ` constructor, but returns an `ol.tilegrid.TileGrid` instance.
* The internal tile coordinate scheme for XYZ sources has been changed. Previously, the `y` of tile coordinates was transformed to the coordinates used by sources by calculating `-y-1`. Now, it is transformed by calculating `height-y-1`, where height is the number of rows of the tile grid at the zoom level of the tile coordinate.
* The `widths` constructor option of `ol.tilegrid.TileGrid` and subclasses is no longer available, and it is no longer necessary to get proper wrapping at the 180° meridian. However, for `ol.tilegrid.WMTS`, there is a new option `sizes`, where each entry is an `ol.Size` with the `width` ('TileMatrixWidth' in WMTS capabilities) as first and the `height` ('TileMatrixHeight') as second entry of the array. For other tile grids, users can
now specify an `extent` instead of `widths`. These settings are used to restrict the range of tiles that sources will request.
* For `ol.source.TileWMS`, the default value of `warpX` used to be `undefined`, meaning that WMS requests with out-of-extent tile BBOXes would be sent. Now `wrapX` can only be `true` or `false`, and the new default is `true`. No application code changes should be required, but the resulting WMS requests for out-of-extent tiles will no longer use out-of-extent BBOXes, but ones that are shifted to real-world coordinates.
### v3.5.0
#### `ol.Object` and `bindTo`

64
changelog/v3.6.0.md Normal file
View File

@@ -0,0 +1,64 @@
# v3.6.0
## Summary
The v3.6.0 release includes features and fixes from 40 pull requests since v3.5.0. To simplify the code base, there were some changes to "experimental" features. Please follow the upgrade notes to make your applications work with the latest release.
## Upgrade notes
### `ol.interaction.Draw` changes
* The `minPointsPerRing` config option has been renamed to `minPoints`. It is now also available for linestring drawing, not only for polygons.
* The `ol.DrawEvent` and `ol.DrawEventType` types were renamed to `ol.interaction.DrawEvent` and `ol.interaction.DrawEventType`. This has an impact on your code only if your code is compiled together with ol3.
### `ol.tilegrid` changes
* The `ol.tilegrid.XYZ` constructor has been replaced by a static `ol.tilegrid.createXYZ()` function. The `ol.tilegrid.createXYZ()` function takes the same arguments as the previous `ol.tilegrid.XYZ` constructor, but returns an `ol.tilegrid.TileGrid` instance.
* The internal tile coordinate scheme for XYZ sources has been changed. Previously, the `y` of tile coordinates was transformed to the coordinates used by sources by calculating `-y-1`. Now, it is transformed by calculating `height-y-1`, where height is the number of rows of the tile grid at the zoom level of the tile coordinate.
* The `widths` constructor option of `ol.tilegrid.TileGrid` and subclasses is no longer available, and it is no longer necessary to get proper wrapping at the 180° meridian. However, for `ol.tilegrid.WMTS`, there is a new option `sizes`, where each entry is an `ol.Size` with the `width` ('TileMatrixWidth' in WMTS capabilities) as first and the `height` ('TileMatrixHeight') as second entry of the array. For other tile grids, users can
now specify an `extent` instead of `widths`. These settings are used to restrict the range of tiles that sources will request.
* For `ol.source.TileWMS`, the default value of `warpX` used to be `undefined`, meaning that WMS requests with out-of-extent tile BBOXes would be sent. Now `wrapX` can only be `true` or `false`, and the new default is `true`. No application code changes should be required, but the resulting WMS requests for out-of-extent tiles will no longer use out-of-extent BBOXes, but ones that are shifted to real-world coordinates.
## New features and fixes
* [#3764](https://github.com/openlayers/ol3/pull/3764) - Add tests and implementation for intersectsExtent (ol.geom.Geometry) ([@alvinlindstam](https://github.com/alvinlindstam))
* [#3757](https://github.com/openlayers/ol3/pull/3757) - Add mapBrowserEvent as a member of ol.SelectEvent ([@bjornharrtell](https://github.com/bjornharrtell))
* [#3759](https://github.com/openlayers/ol3/pull/3759) - Mark tilegrid.createTileCoordTransform() @api ([@gberaudo](https://github.com/gberaudo))
* [#3747](https://github.com/openlayers/ol3/pull/3747) - Make tileCoordTransform a member again ([@ahocevar](https://github.com/ahocevar))
* [#3751](https://github.com/openlayers/ol3/pull/3751) - Do not rely on remote services for tests ([@ahocevar](https://github.com/ahocevar))
* [#3749](https://github.com/openlayers/ol3/pull/3749) - Fix typo in API docs ([@marcjansen](https://github.com/marcjansen))
* [#3739](https://github.com/openlayers/ol3/pull/3739) - Simplify detection of scientific notation in WKT format ([@marcjansen](https://github.com/marcjansen))
* [#3741](https://github.com/openlayers/ol3/pull/3741) - Enhance docs of arguments and return values of callbacks / filters ([@marcjansen](https://github.com/marcjansen))
* [#3740](https://github.com/openlayers/ol3/pull/3740) - Add @fires to select interaction ([@probins](https://github.com/probins))
* [#3738](https://github.com/openlayers/ol3/pull/3738) - Improve doucmentation for ol.TileUrlFunctionType ([@ahocevar](https://github.com/ahocevar))
* [#3736](https://github.com/openlayers/ol3/pull/3736) - Fix invalid example HTML markup ([@fredj](https://github.com/fredj))
* [#3735](https://github.com/openlayers/ol3/pull/3735) - Snap example: remove featureoverlay from tags ([@probins](https://github.com/probins))
* [#3732](https://github.com/openlayers/ol3/pull/3732) - Add a method to bind button bluring on mouseout/focusout ([@marcjansen](https://github.com/marcjansen))
* [#3659](https://github.com/openlayers/ol3/pull/3659) - Revert "Implement ol.renderer.Layer#forEachFeatureAtCoordinate" ([@fredj](https://github.com/fredj))
* [#3683](https://github.com/openlayers/ol3/pull/3683) - Improve Map docs for layers and layergroups ([@probins](https://github.com/probins))
* [#3720](https://github.com/openlayers/ol3/pull/3720) - Add missing goog.provides in drawinteraction.js ([@elemoine](https://github.com/elemoine))
* [#3725](https://github.com/openlayers/ol3/pull/3725) - Document default value for olx.interaction.ModifyOptions#pixelTolerance ([@fredj](https://github.com/fredj))
* [#3722](https://github.com/openlayers/ol3/pull/3722) - Use the correct TileCoord transform function ([@ahocevar](https://github.com/ahocevar))
* [#3692](https://github.com/openlayers/ol3/pull/3692) - Updates for building on Windows using Cygwin. ([@bill-chadwick](https://github.com/bill-chadwick))
* [#3718](https://github.com/openlayers/ol3/pull/3718) - Add a assertion for renderOrder ([@tsauerwein](https://github.com/tsauerwein))
* [#3711](https://github.com/openlayers/ol3/pull/3711) - Fix and test ol.color.blend ([@marcjansen](https://github.com/marcjansen))
* [#3673](https://github.com/openlayers/ol3/pull/3673) - More control over ol.interaction.Draw, to allow e.g. square drawing ([@ahocevar](https://github.com/ahocevar))
* [#3710](https://github.com/openlayers/ol3/pull/3710) - Add more tests for ol.extent ([@marcjansen](https://github.com/marcjansen))
* [#3709](https://github.com/openlayers/ol3/pull/3709) - vector-wfs example does not work in JSFiddle ([@bartvde](https://github.com/bartvde))
* [#3699](https://github.com/openlayers/ol3/pull/3699) - Add support for scientific notation to WKT format ([@marcjansen](https://github.com/marcjansen))
* [#3696](https://github.com/openlayers/ol3/pull/3696) - Add an example for various blend modes ([@marcjansen](https://github.com/marcjansen))
* [#3697](https://github.com/openlayers/ol3/pull/3697) - Use a valid SPDX license expression ([@marcjansen](https://github.com/marcjansen))
* [#3694](https://github.com/openlayers/ol3/pull/3694) - Correct typo in upgrade-notes ([@probins](https://github.com/probins))
* [#3693](https://github.com/openlayers/ol3/pull/3693) - Fix ol.extent.containsExtent documentation ([@tremby](https://github.com/tremby))
* [#3689](https://github.com/openlayers/ol3/pull/3689) - Fix WMTS.optionsFromCapabilities if no OperationsMetadata section ([@probins](https://github.com/probins))
* [#3688](https://github.com/openlayers/ol3/pull/3688) - Add two missing properties to extern of WebGLContextAttributes ([@fredj](https://github.com/fredj))
* [#3682](https://github.com/openlayers/ol3/pull/3682) - Add a note about using the collection in addLayer ([@bartvde](https://github.com/bartvde))
* [#3649](https://github.com/openlayers/ol3/pull/3649) - More specific regex in serve.js ([@elemoine](https://github.com/elemoine))
* [#3677](https://github.com/openlayers/ol3/pull/3677) - Add metadata to examples, ([@tschaub](https://github.com/tschaub))
* [#3672](https://github.com/openlayers/ol3/pull/3672) - Add link to FAQ-document and fix internal links ([@marcjansen](https://github.com/marcjansen))
* [#3665](https://github.com/openlayers/ol3/pull/3665) - Add proj4js and projection definition files to example resources ([@marcjansen](https://github.com/marcjansen))
* [#3662](https://github.com/openlayers/ol3/pull/3662) - Clarify docs for renderBuffer option ([@tsauerwein](https://github.com/tsauerwein))
* [#3664](https://github.com/openlayers/ol3/pull/3664) - Link to download page. ([@tschaub](https://github.com/tschaub))
* [#3639](https://github.com/openlayers/ol3/pull/3639) - Add extent support to ol.tilegrid.TileGrid ([@ahocevar](https://github.com/ahocevar))
* [#3663](https://github.com/openlayers/ol3/pull/3663) - Readme should not include the version number. ([@tschaub](https://github.com/tschaub))
* [#3637](https://github.com/openlayers/ol3/pull/3637) - Implement ol.renderer.Layer#forEachFeatureAtCoordinate ([@fredj](https://github.com/fredj))

152
changelog/v3.7.0.md Normal file
View File

@@ -0,0 +1,152 @@
# v3.7.0
## Summary
The v3.7.0 release includes features and fixes from 43 pull requests since v3.6.0. To simplify the code base, there were some changes to "experimental" features. Please follow the upgrade notes to make your applications work with the latest release.
## Upgrade notes
#### Removal of `ol.FeatureOverlay`
Instead of an `ol.FeatureOverlay`, we now use an `ol.layer.Vector` with an
`ol.source.Vector`. If you previously had:
```js
var featureOverlay = new ol.FeatureOverlay({
map: map,
style: overlayStyle
});
featureOverlay.addFeature(feature);
featureOverlay.removeFeature(feature);
var collection = featureOverlay.getFeatures();
```
you will have to change this to:
```js
var collection = new ol.Collection();
var featureOverlay = new ol.layer.Vector({
map: map,
source: new ol.source.Vector({
features: collection,
useSpatialIndex: false // optional, might improve performance
}),
style: overlayStyle,
updateWhileAnimating: true, // optional, for instant visual feedback
updateWhileInteracting: true // optional, for instant visual feedback
});
featureOverlay.getSource().addFeature(feature);
featureOverlay.getSource().removeFeature(feature);
```
With the removal of `ol.FeatureOverlay`, `zIndex` symbolizer properties of overlays are no longer stacked per map, but per layer/overlay. If you previously had multiple feature overlays where you controlled the rendering order of features by using `zIndex` symbolizer properties, you can now achieve the same rendering order only if all overlay features are on the same layer.
Note that `ol.FeatureOverlay#getFeatures()` returned an `{ol.Collection.<ol.Feature>}`, whereas `ol.source.Vector#getFeatures()` returns an `{Array.<ol.Feature>}`.
#### `ol.TileCoord` changes
Until now, the API exposed two different types of `ol.TileCoord` tile coordinates: internal ones that increase left to right and upward, and transformed ones that may increase downward, as defined by a transform function on the tile grid. With this change, the API now only exposes tile coordinates that increase left to right and upward.
Previously, tile grids created by OpenLayers either had their origin at the top-left or at the bottom-left corner of the extent. To make it easier for application developers to transform tile coordinates to the common XYZ tiling scheme, all tile grids that OpenLayers creates internally have their origin now at the top-left corner of the extent.
This change affects applications that configure a custom `tileUrlFunction` for an `ol.source.Tile`. Previously, the `tileUrlFunction` was called with rather unpredictable tile coordinates, depending on whether a tile coordinate transform took place before calling the `tileUrlFunction`. Now it is always called with OpenLayers tile coordinates. To transform these into the common XYZ tiling scheme, a custom `tileUrlFunction` has to change the `y` value (tile row) of the `ol.TileCoord`:
```js
function tileUrlFunction = function(tileCoord, pixelRatio, projection) {
var urlTemplate = '{z}/{x}/{y}';
return urlTemplate
.replace('{z}', tileCoord[0].toString())
.replace('{x}', tileCoord[1].toString())
.replace('{y}', (-tileCoord[2] - 1).toString());
}
```
The `ol.tilegrid.TileGrid#createTileCoordTransform()` function which could be used to get the tile grid's tile coordinate transform function has been removed. This function was confusing and should no longer be needed now that application developers get tile coordinates in a known layout.
The code snippets below show how your application code needs to be changed:
Old application code (with `ol.tilegrid.TileGrid#createTileCoordTransform()`):
```js
var transform = source.getTileGrid().createTileCoordTransform();
var tileUrlFunction = function(tileCoord, pixelRatio, projection) {
tileCoord = transform(tileCoord, projection);
return 'http://mytiles.com/' +
tileCoord[0] + '/' + tileCoord[1] + '/' + tileCoord[2] + '.png';
};
```
Old application code (with custom `y` transform):
```js
var tileUrlFunction = function(tileCoord, pixelRatio, projection) {
var z = tileCoord[0];
var yFromBottom = tileCoord[2];
var resolution = tileGrid.getResolution(z);
var tileHeight = ol.size.toSize(tileSize)[1];
var matrixHeight =
Math.floor(ol.extent.getHeight(extent) / tileHeight / resolution);
return 'http://mytiles.com/' +
tileCoord[0] + '/' + tileCoord[1] + '/' +
(matrixHeight - yFromBottom - 1) + '.png';
};
```
New application code (simple -y - 1 transform):
```js
var tileUrlFunction = function(tileCoord, pixelRatio, projection) {
return 'http://mytiles.com/' +
tileCoord[0] + '/' + tileCoord[1] + '/' + (-tileCoord[2] - 1) + '.png';
};
```
#### Removal of `ol.tilegrid.Zoomify`
The replacement of `ol.tilegrid.Zoomify` is a plain `ol.tilegrid.TileGrid`, configured with `extent`, `origin` and `resolutions`. If the `size` passed to the `ol.source.Zoomify` source is `[width, height]`, then the extent for the tile grid will be `[0, -height, width, 0]`, and the origin will be `[0, 0]`.
#### Replace `ol.View.fitExtent()` and `ol.View.fitGeometry()` with `ol.View.fit()`
* This combines two previously distinct functions into one more flexible call which takes either a geometry or an extent.
* Rename all calls to `fitExtent` and `fitGeometry` to `fit`.
#### Change to `ol.interaction.Modify`
When single clicking a line or boundary within the `pixelTolerance`, a vertex is now created.
## New features and fixes
* [#3867](https://github.com/openlayers/ol3/pull/3867) - Do not require projection extent for x-wrapping tile sources ([@ahocevar](https://github.com/ahocevar))
* [#3635](https://github.com/openlayers/ol3/pull/3635) - Create vertex on boundary single click ([@bjornharrtell](https://github.com/bjornharrtell))
* [#3806](https://github.com/openlayers/ol3/pull/3806) - Do not clip canvas for vector layers when wrapping the world ([@ahocevar](https://github.com/ahocevar))
* [#3461](https://github.com/openlayers/ol3/pull/3461) - High level Modify interaction events ([@bjornharrtell](https://github.com/bjornharrtell))
* [#3865](https://github.com/openlayers/ol3/pull/3865) - ol.View#fit() ([@bartvde](https://github.com/bartvde))
* [#3864](https://github.com/openlayers/ol3/pull/3864) - Check projection.canWrapX() before wrapping tiles ([@klokantech](https://github.com/klokantech))
* [#3863](https://github.com/openlayers/ol3/pull/3863) - Handle CDATA in attribute parsing for GML format ([@nhambletCCRI](https://github.com/nhambletCCRI))
* [#3860](https://github.com/openlayers/ol3/pull/3860) - Update example layout. ([@tschaub](https://github.com/tschaub))
* [#3861](https://github.com/openlayers/ol3/pull/3861) - Don't force 'dom' renderer ([@openlayers](https://github.com/openlayers))
* [#3855](https://github.com/openlayers/ol3/pull/3855) - Adding an example with WMTS tiles from IGN Geoportail ([@pgiraud](https://github.com/pgiraud))
* [#3856](https://github.com/openlayers/ol3/pull/3856) - ol.source.TileVector(): bind success function of tileLoadFunction to source ([@plepe](https://github.com/plepe))
* [#3848](https://github.com/openlayers/ol3/pull/3848) - Check for exports before define. ([@tschaub](https://github.com/tschaub))
* [#3845](https://github.com/openlayers/ol3/pull/3845) - Prevent null array to be passed to an ol.Collection ([@fredj](https://github.com/fredj))
* [#3849](https://github.com/openlayers/ol3/pull/3849) - Pad min. and sec. with leading zeros in DMS notation ([@pgiraud](https://github.com/pgiraud))
* [#3842](https://github.com/openlayers/ol3/pull/3842) - Adding a feature-animation example ([@pgiraud](https://github.com/pgiraud))
* [#3833](https://github.com/openlayers/ol3/pull/3833) - Enable use of custom XHR loader for TileVector sources ([@bjornharrtell](https://github.com/bjornharrtell))
* [#3834](https://github.com/openlayers/ol3/pull/3834) - ArcGIS tiled example broken in Chrome ([@bartvde](https://github.com/bartvde))
* [#3829](https://github.com/openlayers/ol3/pull/3829) - incorrect assert message ([@kzr-pzr](https://github.com/kzr-pzr))
* [#3828](https://github.com/openlayers/ol3/pull/3828) - Fix typo in upgrade notes ([@ahocevar](https://github.com/ahocevar))
* [#3826](https://github.com/openlayers/ol3/pull/3826) - Allow custom tileGrid in ol.source.XYZ ([@klokantech](https://github.com/klokantech))
* [#3815](https://github.com/openlayers/ol3/pull/3815) - Simplify tilegrid API and internals ([@ahocevar](https://github.com/ahocevar))
* [#3820](https://github.com/openlayers/ol3/pull/3820) - Make unmanaged vector layers behave more like ol.FeatureOverlay ([@ahocevar](https://github.com/ahocevar))
* [#3822](https://github.com/openlayers/ol3/pull/3822) - Correct docs for updateWhileInteracting ([@probins](https://github.com/probins))
* [#3818](https://github.com/openlayers/ol3/pull/3818) - Make geometry.transform api stable again. ([@probins](https://github.com/probins))
* [#3801](https://github.com/openlayers/ol3/pull/3801) - Respect the tile grid's extent in ol.source.TileVector ([@ahocevar](https://github.com/ahocevar))
* [#3810](https://github.com/openlayers/ol3/pull/3810) - Improve TileGrid documentation and examples ([@ahocevar](https://github.com/ahocevar))
* [#3808](https://github.com/openlayers/ol3/pull/3808) - Correct typo in OverlayOptions ([@probins](https://github.com/probins))
* [#3766](https://github.com/openlayers/ol3/pull/3766) - Add a clickTolerance option to the Draw interaction ([@elemoine](https://github.com/elemoine))
* [#3804](https://github.com/openlayers/ol3/pull/3804) - Remove sentence that was only meant for WMTS tile grids ([@ahocevar](https://github.com/ahocevar))
* [#3800](https://github.com/openlayers/ol3/pull/3800) - Remove further references to FeatureOverlay ([@probins](https://github.com/probins))
* [#3780](https://github.com/openlayers/ol3/pull/3780) - Only expose transformed tile coordinates to the API ([@ahocevar](https://github.com/ahocevar))
* [#3793](https://github.com/openlayers/ol3/pull/3793) - Use 'managed' instead of 'unmanaged' in LayerState ([@ahocevar](https://github.com/ahocevar))
* [#3792](https://github.com/openlayers/ol3/pull/3792) - Link to correct layer base class ([@marcjansen](https://github.com/marcjansen))
* [#3791](https://github.com/openlayers/ol3/pull/3791) - Remove docs referring to removed feature overlay ([@marcjansen](https://github.com/marcjansen))
* [#3790](https://github.com/openlayers/ol3/pull/3790) - Remove unnecessary quotes around object keys ([@fredj](https://github.com/fredj))
* [#3787](https://github.com/openlayers/ol3/pull/3787) - Add 'unmanaged' to ol.layer.LayerState ([@ahocevar](https://github.com/ahocevar))
* [#3784](https://github.com/openlayers/ol3/pull/3784) - Always write the GeoJSONFeature geometry property ([@fredj](https://github.com/fredj))
* [#3783](https://github.com/openlayers/ol3/pull/3783) - Fix broken wmts-hidpi example ([@ahocevar](https://github.com/ahocevar))
* [#3782](https://github.com/openlayers/ol3/pull/3782) - Fix assert documentation typo ([@gberaudo](https://github.com/gberaudo))
* [#3758](https://github.com/openlayers/ol3/pull/3758) - Removal of ol.FeatureOverlay ([@ahocevar](https://github.com/ahocevar))
* [#3775](https://github.com/openlayers/ol3/pull/3775) - Add ol-touch but keep ol-viewport className. ([@pgiraud](https://github.com/pgiraud))
* [#3713](https://github.com/openlayers/ol3/pull/3713) - Add missing propertyNames member for olx.format.WFSWriteGetFeatureOptions ([@bartvde](https://github.com/bartvde))
* [#3763](https://github.com/openlayers/ol3/pull/3763) - Standardise draw/modify descriptions ([@probins](https://github.com/probins))

View File

@@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" type="text/css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" type="text/css">
<link rel="stylesheet" href="../css/ol.css" type="text/css">
<link rel="stylesheet" href="./resources/layout.css" type="text/css">
{{{ extraHead }}}
@@ -15,13 +15,11 @@
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container" id="navbar-inner-container">
<a class="brand" href="./"><img src="./resources/logo-70x70.png"> OpenLayers 3 Examples</a>
</div>
<header class="navbar" role="navigation">
<div class="container" id="navbar-inner-container">
<a class="navbar-brand" href="./"><img src="./resources/logo-70x70.png">&nbsp;OpenLayers 3 Examples</a>
</div>
</div>
</header>
<div class="container-fluid">
@@ -52,8 +50,8 @@
&lt;head&gt;
&lt;title&gt;{{ title }}&lt;/title&gt;
&lt;script src="https://code.jquery.com/jquery-1.11.2.min.js"&gt;&lt;/script&gt;
&lt;link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css"&gt;
&lt;script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"&gt;&lt;/script&gt;
&lt;link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"&gt;
&lt;script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"&gt;&lt;/script&gt;
&lt;link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ol3/{{ olVersion }}/ol.css" type="text/css"&gt;
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/ol3/{{ olVersion }}/ol.js"&gt;&lt;/script&gt;
{{ extraHead }}
@@ -73,12 +71,12 @@
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
</div>
</form>
</div>
</div>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/twitter-bootstrap/2.3.1/js/bootstrap.min.js"></script>
<script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="./resources/common.js"></script>
<script src="./resources/prism/prism.min.js"></script>
{{{ js.tag }}}

View File

@@ -14,15 +14,16 @@ free to ping us or to send a pull request enhancing this document.
Table of contents:
* [What projection is OpenLayers using?](#what-projection-is-openlayers-using)
* [How do I change the projection of my map?](#how-do-i-change-the-projection-of-my-map)
* [Why is my map centered on the gulf of guinea (or africa, the ocean, null-island)?](#why-is-my-map-centered-on-the-gulf-of-guinea-or-africa-the-ocean-null-island)
* [Why is the order of a coordinate [lon,lat], and not [lat,lon]?](#why-is-the-order-of-a-coordinate-lonlat-and-not-latlon)
* [Why aren't there any features in my source?](#why-arent-there-any-features-in-my-source)
* [How do I force a re-render of the map?](#how-do-i-force-a-re-render-of-the-map)
* [How do I create a custom build of OpenLayers?](#how-do-i-create-a-custom-build-of-openlayers)
* [Do I need to write my own code using Closure library?](#do-i-need-to-write-my-own-code-using-closure-library)
* [Do I need to compress my code with Closure compiler?](#do-i-need-to-compress-my-code-with-closure-compiler)
* [What projection is OpenLayers using?](#what-projection-is-openlayers-using-)
* [How do I change the projection of my map?](#how-do-i-change-the-projection-of-my-map-)
* [Why is my map centered on the gulf of guinea (or africa, the ocean, null-island)?](#why-is-my-map-centered-on-the-gulf-of-guinea-or-africa-the-ocean-null-island-)
* [Why is the order of a coordinate [lon,lat], and not [lat,lon]?](#why-is-the-order-of-a-coordinate-lon-lat-and-not-lat-lon-)
* [Why aren't there any features in my source?](#why-aren-t-there-any-features-in-my-source-)
* [How do I force a re-render of the map?](#how-do-i-force-a-re-render-of-the-map-)
* [How do I create a custom build of OpenLayers?](#how-do-i-create-a-custom-build-of-openlayers-)
* [Do I need to write my own code using Closure library?](#do-i-need-to-write-my-own-code-using-closure-library-)
* [Do I need to compress my code with Closure compiler?](#do-i-need-to-compress-my-code-with-closure-compiler-)
## What projection is OpenLayers using?
@@ -302,7 +303,7 @@ map.renderSync();
## How do I create a custom build of OpenLayers?
Please refer to [this blog post](http://boundlessgeo.com/2014/10/openlayers-custom-builds-revisited/)
Please refer to the [official create custom builds tutorial](tutorials/custom-builds.html)
which explains how to create a custom build of OpenLayers with just those parts
included that you want.
@@ -326,7 +327,8 @@ compiler](https://developers.google.com/closure/compiler/).
It may be a good choice though, because when your application code and the
OpenLayers source code is compiled together using closure compiler, the
resulting build will most probably be the smallest in terms of byte-size. For
more details refer to [this tutorial](compile-application.md).
more details refer to the
[compile application and OpenLayers together tutorial](tutorials/closure.html).
If you don't want to use the closure compiler, or you can't, you are not at all
forced to use it.

View File

@@ -13,6 +13,10 @@ Make sure to also check out the [OpenLayers 3 workshop](../../../ol3-workshop/).
Find additional reference material in the [API docs](../apidoc).
# Questions
# Frequently Asked Questions (FAQ)
If you cannot find an answer in the documentation, you can ask your question on [stackoverflow using the tag 'openlayers-3'](http://stackoverflow.com/questions/tagged/openlayers-3).
We have put together a document that lists [Frequently Asked Questions (FAQ)](faq.html) and our answers. Common problems that may arise when using OpenLayers 3 are explained there, and chances are you'll find an appropriate solution in this document.
# More questions?
If you cannot find an answer in the documentation or the FAQ, you can ask your question on [stackoverflow using the tag 'openlayers-3'](http://stackoverflow.com/questions/tagged/openlayers-3).

4
examples/blend-modes.css Normal file
View File

@@ -0,0 +1,4 @@
.map{
background-repeat: repeat;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAApSURBVBiVY7x///5/BjSgqKjIiC7GhC6ACwygQgxHMzAwMGDz4FDwDAD5/wevjSk4mwAAAABJRU5ErkJggg==);
}

76
examples/blend-modes.html Normal file
View File

@@ -0,0 +1,76 @@
---
template: example.html
title: Blend modes example
shortdesc: Shows how to change the canvas compositing / blending mode in post- and precompose eventhandlers.
docs: >
<p>This example shows how to change the canvas compositing / blending mode in
post- and precompose event handlers. The Canvas 2D API provides the property
<code>globalCompositeOperation</code> with which one can influence which
composition operation will be used when drawing on the canvas. The various
options are well described on the <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation">MDN
documentation page</a>.</p>
<p>In this example three circles on the corners of an equilateral triangle are
drawn with red, green or blue styles respectively. By setting the
<code>globalCompositeOperation</code> you can change how these colors turn out
when they are combined on the map.</p>
<p>You can select an operation in the select-field and you can also control
which layers will be affected by the chosen operation through the layer
checkboxes.</p>
tags: "blendmode, blend-mode, blend mode, blendingmode, blending-mode, blending mode, composition, compositing, canvas, vector"
---
<div class="row-fluid">
<div class="span12">
<div id="map" class="map"></div>
</div>
</div>
<div class="row-fluid">
<div class="span12">
<form class="form-horizontal">
<label>
<select id="blend-mode" class="form-control">
<option value="source-over">source-over (default)</option>
<option>source-in</option>
<option>source-out</option>
<option>source-atop</option>
<option>destination-over</option>
<option>destination-in</option>
<option>destination-out</option>
<option>destination-atop</option>
<option>lighter</option>
<option>copy</option>
<option>xor</option>
<option>multiply</option>
<option>screen</option>
<option>overlay</option>
<option>darken</option>
<option>lighten</option>
<option>color-dodge</option>
<option>color-burn</option>
<option>hard-light</option>
<option>soft-light</option>
<option selected>difference</option>
<option>exclusion</option>
<option>hue</option>
<option>saturation</option>
<option>color</option>
<option>luminosity</option>
</select>
Canvas compositing / blending mode
</label>
<label>
<input type="checkbox" id="affect-red" checked>
Red circle affected
</label>
<label>
<input type="checkbox" id="affect-green" checked>
Green circle affected
</label>
<label>
<input type="checkbox" id="affect-blue" checked>
Blue circle affected
</label>
</form>
</div>
</div>

177
examples/blend-modes.js Normal file
View File

@@ -0,0 +1,177 @@
goog.require('ol.Feature');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.geom.Point');
goog.require('ol.layer.Vector');
goog.require('ol.source.Vector');
goog.require('ol.style.Circle');
goog.require('ol.style.Fill');
goog.require('ol.style.Stroke');
goog.require('ol.style.Style');
// Create separate layers for red, green an blue circles.
//
// Every layer has one feature that is styled with a circle, together the
// features form the corners of an equilateral triangle and their styles overlap
var redLayer = new ol.layer.Vector({
source: new ol.source.Vector({
features: [new ol.Feature(new ol.geom.Point([0, 0]))]
}),
style: new ol.style.Style({
image: new ol.style.Circle({
fill: new ol.style.Fill({
color: 'rgba(255,0,0,0.8)'
}),
stroke: new ol.style.Stroke({
color: 'rgb(255,0,0)',
width: 15
}),
radius: 120
})
})
});
var greenLayer = new ol.layer.Vector({
source: new ol.source.Vector({
// 433.013 is roughly 250 * Math.sqrt(3)
features: [new ol.Feature(new ol.geom.Point([250, 433.013]))]
}),
style: new ol.style.Style({
image: new ol.style.Circle({
fill: new ol.style.Fill({
color: 'rgba(0,255,0,0.8)'
}),
stroke: new ol.style.Stroke({
color: 'rgb(0,255,0)',
width: 15
}),
radius: 120
})
})
});
var blueLayer = new ol.layer.Vector({
source: new ol.source.Vector({
features: [new ol.Feature(new ol.geom.Point([500, 0]))]
}),
style: new ol.style.Style({
image: new ol.style.Circle({
fill: new ol.style.Fill({
color: 'rgba(0,0,255,0.8)'
}),
stroke: new ol.style.Stroke({
color: 'rgb(0,0,255)',
width: 15
}),
radius: 120
})
})
});
// Create the map, the view is centered on the triangle. Zooming and panning is
// restricted to a sane area
var map = new ol.Map({
layers: [
redLayer,
greenLayer,
blueLayer
],
target: 'map',
view: new ol.View({
center: [250, 220],
extent: [0, 0, 500, 500],
resolution: 4,
minResolution: 2,
maxResolution: 32
})
});
// Various helper methods and event handlers
/**
* This method sets the globalCompositeOperation to the value of the select
* field and it is bound to the precompose event of the layers.
*
* @param {ol.render.Event} evt The render event.
*/
var setBlendModeFromSelect = function(evt) {
evt.context.globalCompositeOperation = select.value;
};
/**
* This method resets the globalCompositeOperation to the default value of
* 'source-over' and it is bound to the postcompose event of the layers.
*
* @param {ol.render.Event} evt The render event.
*/
var resetBlendModeFromSelect = function(evt) {
evt.context.globalCompositeOperation = 'source-over';
};
/**
* Bind the pre- and postcompose handlers to the passed layer.
*
* @param {ol.layer.Vector} layer The layer to bind the handlers to.
*/
var bindLayerListeners = function(layer) {
layer.on('precompose', setBlendModeFromSelect);
layer.on('postcompose', resetBlendModeFromSelect);
};
/**
* Unind the pre- and postcompose handlers to the passed layers.
*
* @param {ol.layer.Vector} layer The layer to unbind the handlers from.
*/
var unbindLayerListeners = function(layer) {
layer.un('precompose', setBlendModeFromSelect);
layer.un('postcompose', resetBlendModeFromSelect);
};
/**
* Handler for the click event of the 'affect-XXX' checkboxes.
*
* @this {HTMLInputElement}
*/
var affectLayerClicked = function() {
var layer;
if (this.id == 'affect-red') {
layer = redLayer;
} else if (this.id == 'affect-green') {
layer = greenLayer;
} else {
layer = blueLayer;
}
if (this.checked) {
bindLayerListeners(layer);
} else {
unbindLayerListeners(layer);
}
map.render();
};
// Get the form elements and bind the listeners
var select = document.getElementById('blend-mode');
var affectRed = document.getElementById('affect-red');
var affectGreen = document.getElementById('affect-green');
var affectBlue = document.getElementById('affect-blue');
// Rerender map when blend mode changes
select.addEventListener('change', function() {
map.render();
});
// Unbind / bind listeners depending on the checked state when the checkboxes
// are clicked
affectRed.addEventListener('click', affectLayerClicked);
affectGreen.addEventListener('click', affectLayerClicked);
affectBlue.addEventListener('click', affectLayerClicked);
// Initially bind listeners
bindLayerListeners(redLayer);
bindLayerListeners(greenLayer);
bindLayerListeners(blueLayer);

View File

@@ -3,8 +3,11 @@ template: example.html
title: Canvas tiles example
shortdesc: Renders tiles with coordinates for debugging.
docs: >
<p>The black grid tiles are generated on the client with an HTML5 canvas. Note that the tile coordinates are ol3 normalized tile coordinates (origin bottom left), not
OSM tile coordinates (origin top left).</p>
The black grid tiles are generated on the client with an HTML5 canvas. The
displayed tile coordinates are OpenLayers tile coordinates. These increase
from bottom to top, but standard XYZ tiling scheme coordinates increase from
top to bottom. To calculate the `y` for a standard XYZ tile coordinate, use
`-y - 1`.
tags: "layers, openstreetmap, canvas"
---
<div class="row-fluid">

View File

@@ -5,20 +5,18 @@ goog.require('ol.layer.Tile');
goog.require('ol.proj');
goog.require('ol.source.OSM');
goog.require('ol.source.TileDebug');
goog.require('ol.tilegrid.XYZ');
var osmSource = new ol.source.OSM();
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
source: osmSource
}),
new ol.layer.Tile({
source: new ol.source.TileDebug({
projection: 'EPSG:3857',
tileGrid: new ol.tilegrid.XYZ({
maxZoom: 22
})
tileGrid: osmSource.getTileGrid()
})
})
],

View File

@@ -6,7 +6,7 @@ docs: >
This example demonstrates how a map's view can be
adjusted so a geometry or coordinate is positioned at a specific
pixel location. The map above has top, right, bottom, and left
padding applied inside the viewport. The view's <code>fitGeometry</code> method
padding applied inside the viewport. The view's <code>fit</code> method
is used to fit a geometry in the view with the same padding. The
view's <code>centerOn</code> method is used to position a coordinate (Lausanne)
at a specific pixel location (the center of the black box).

View File

@@ -65,7 +65,7 @@ zoomtoswitzerlandbest.addEventListener('click', function() {
var feature = source.getFeatures()[0];
var polygon = /** @type {ol.geom.SimpleGeometry} */ (feature.getGeometry());
var size = /** @type {ol.Size} */ (map.getSize());
view.fitGeometry(
view.fit(
polygon,
size,
{
@@ -81,7 +81,7 @@ zoomtoswitzerlandconstrained.addEventListener('click', function() {
var feature = source.getFeatures()[0];
var polygon = /** @type {ol.geom.SimpleGeometry} */ (feature.getGeometry());
var size = /** @type {ol.Size} */ (map.getSize());
view.fitGeometry(
view.fit(
polygon,
size,
{
@@ -96,7 +96,7 @@ zoomtoswitzerlandnearest.addEventListener('click', function() {
var feature = source.getFeatures()[0];
var polygon = /** @type {ol.geom.SimpleGeometry} */ (feature.getGeometry());
var size = /** @type {ol.Size} */ (map.getSize());
view.fitGeometry(
view.fit(
polygon,
size,
{
@@ -111,7 +111,7 @@ zoomtolausanne.addEventListener('click', function() {
var feature = source.getFeatures()[1];
var point = /** @type {ol.geom.SimpleGeometry} */ (feature.getGeometry());
var size = /** @type {ol.Size} */ (map.getSize());
view.fitGeometry(
view.fit(
point,
size,
{

View File

@@ -122,7 +122,7 @@ dragAndDropInteraction.on('addfeatures', function(event) {
style: styleFunction
})
}));
map.getView().fitExtent(
map.getView().fit(
vectorSource.getExtent(), /** @type {ol.Size} */ (map.getSize()));
});

View File

@@ -118,7 +118,7 @@ dragAndDropInteraction.on('addfeatures', function(event) {
source: vectorSource,
style: styleFunction
}));
map.getView().fitExtent(
map.getView().fit(
vectorSource.getExtent(), /** @type {ol.Size} */ (map.getSize()));
});

View File

@@ -1,11 +1,13 @@
goog.require('ol.FeatureOverlay');
goog.require('ol.Collection');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.events.condition');
goog.require('ol.interaction.Draw');
goog.require('ol.interaction.Modify');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
goog.require('ol.source.MapQuest');
goog.require('ol.source.Vector');
goog.require('ol.style.Circle');
goog.require('ol.style.Fill');
goog.require('ol.style.Stroke');
@@ -24,11 +26,9 @@ var map = new ol.Map({
})
});
// The features are not added to a regular vector layer/source,
// but to a feature overlay which holds a collection of features.
// This collection is passed to the modify and also the draw
// interaction, so that both can add or modify features.
var featureOverlay = new ol.FeatureOverlay({
var features = new ol.Collection();
var featureOverlay = new ol.layer.Vector({
source: new ol.source.Vector({features: features}),
style: new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(255, 255, 255, 0.2)'
@@ -48,7 +48,7 @@ var featureOverlay = new ol.FeatureOverlay({
featureOverlay.setMap(map);
var modify = new ol.interaction.Modify({
features: featureOverlay.getFeatures(),
features: features,
// the SHIFT key must be pressed to delete vertices, so
// that new vertices can be drawn at the same position
// of existing vertices
@@ -62,7 +62,7 @@ map.addInteraction(modify);
var draw; // global so we can remove it later
function addInteraction() {
draw = new ol.interaction.Draw({
features: featureOverlay.getFeatures(),
features: features,
type: /** @type {ol.geom.GeometryType} */ (typeSelect.value)
});
map.addInteraction(draw);

View File

@@ -6,7 +6,10 @@ docs: >
Example of using the Draw interaction. Select a geometry type from the
dropdown above to start drawing. To finish drawing, click the last
point. To activate freehand drawing for lines and polygons, hold the `Shift`
key.
key. Square drawing is achieved by using Circle mode with a `geometryFunction`
that creates a 4-sided regular polygon instead of a circle. Box drawing uses a
custom `geometryFunction` that takes start and end point of a line with 2
points and creates a rectangular box.
tags: "draw, edit, freehand, vector"
---
<div class="row-fluid">
@@ -20,6 +23,8 @@ tags: "draw, edit, freehand, vector"
<option value="LineString">LineString</option>
<option value="Polygon">Polygon</option>
<option value="Circle">Circle</option>
<option value="Square">Square</option>
<option value="Box">Box</option>
</select>
</form>
</div>

View File

@@ -1,5 +1,6 @@
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.geom.Polygon');
goog.require('ol.interaction.Draw');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
@@ -51,9 +52,30 @@ var draw; // global so we can remove it later
function addInteraction() {
var value = typeSelect.value;
if (value !== 'None') {
var geometryFunction, maxPoints;
if (value === 'Square') {
value = 'Circle';
geometryFunction = ol.interaction.Draw.createRegularPolygon(4);
} else if (value === 'Box') {
value = 'LineString';
maxPoints = 2;
geometryFunction = function(coordinates, geometry) {
if (!geometry) {
geometry = new ol.geom.Polygon(null);
}
var start = coordinates[0];
var end = coordinates[1];
geometry.setCoordinates([
[start, [start[0], end[1]], end, [end[0], start[1]], start]
]);
return geometry;
};
}
draw = new ol.interaction.Draw({
source: source,
type: /** @type {ol.geom.GeometryType} */ (value)
type: /** @type {ol.geom.GeometryType} */ (value),
geometryFunction: geometryFunction,
maxPoints: maxPoints
});
map.addInteraction(draw);
}

View File

@@ -0,0 +1,15 @@
---
template: example.html
title: Feature animation example
shortdesc: Demonstrates how to animate features.
docs: >
This example shows how to use <b>postcompose</b> and <b>vectorContext</b> to
animate features. Here we choose to do a flash animation each time a feature
is added to the layer.
tags: "animation, vector, feature, flash"
---
<div class="row">
<div class="span8">
<div id="map" class="map"></div>
</div>
</div>

View File

@@ -0,0 +1,96 @@
goog.require('ol.Feature');
goog.require('ol.Map');
goog.require('ol.Observable');
goog.require('ol.View');
goog.require('ol.control');
goog.require('ol.easing');
goog.require('ol.geom.Point');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
goog.require('ol.proj');
goog.require('ol.source.OSM');
goog.require('ol.source.Vector');
goog.require('ol.style.Circle');
goog.require('ol.style.Stroke');
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM({
wrapX: false
})
})
],
controls: ol.control.defaults({
attributionOptions: /** @type {olx.control.AttributionOptions} */ ({
collapsible: false
})
}),
renderer: common.getRendererFromQueryString(),
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 1
})
});
var source = new ol.source.Vector({
wrapX: false
});
var vector = new ol.layer.Vector({
source: source
});
map.addLayer(vector);
function addRandomFeature() {
var x = Math.random() * 360 - 180;
var y = Math.random() * 180 - 90;
var geom = new ol.geom.Point(ol.proj.transform([x, y],
'EPSG:4326', 'EPSG:3857'));
var feature = new ol.Feature(geom);
source.addFeature(feature);
}
var duration = 3000;
function flash(feature) {
var start = new Date().getTime();
var listenerKey;
function animate(event) {
var vectorContext = event.vectorContext;
var frameState = event.frameState;
var flashGeom = feature.getGeometry().clone();
var elapsed = frameState.time - start;
var elapsedRatio = elapsed / duration;
// radius will be 5 at start and 30 at end.
var radius = ol.easing.easeOut(elapsedRatio) * 25 + 5;
var opacity = ol.easing.easeOut(1 - elapsedRatio);
var flashStyle = new ol.style.Circle({
radius: radius,
snapToPixel: false,
stroke: new ol.style.Stroke({
color: 'rgba(255, 0, 0, ' + opacity + ')',
width: 1,
opacity: opacity
})
});
vectorContext.setImageStyle(flashStyle);
vectorContext.drawPointGeometry(flashGeom, null);
if (elapsed > duration) {
ol.Observable.unByKey(listenerKey);
return;
}
// tell OL3 to continue postcompose animation
frameState.animate = true;
}
listenerKey = map.on('postcompose', animate);
}
source.on('addfeature', function(e) {
flash(e.feature);
});
window.setInterval(addRandomFeature, 1000);

View File

@@ -1,5 +1,8 @@
---
template: "example-verbatim.html"
template: example-verbatim.html
title: Geolocation Tracking with Orientation
shortdesc: Example of a geolocated and oriented map.
tags: "fullscreen, geolocation, orientation, mobile"
---
<!doctype html>
<html lang="en">
@@ -7,7 +10,7 @@ template: "example-verbatim.html"
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" type="text/css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" type="text/css">
<link rel="stylesheet" href="../css/ol.css" type="text/css">
<link rel="stylesheet" href="./resources/layout.css" type="text/css">
<title>Mobile Geolocation Tracking with Orientation</title>
@@ -41,15 +44,8 @@ template: "example-verbatim.html"
<button id="geolocate">Geolocate Me!</button>
<button id="simulate">Simulate</button>
</div>
<script src="http://code.jquery.com/jquery-1.9.1.min.js" type="text/javascript"></script>
<script src="./resources/common.js" type="text/javascript"></script>
<script src="loader.js?id=geolocation-orientation" type="text/javascript"></script>
<div style="display: none;">
<div id="title">Geolocation tracking with orientation example</div>
<div id="shortdesc">Example of a geolocated and oriented map.</div>
<div id="tags">fullscreen, geolocation, orientation, mobile</div>
</div>
</body>
</html>

View File

@@ -1,12 +1,13 @@
goog.require('ol.Feature');
goog.require('ol.FeatureOverlay');
goog.require('ol.Geolocation');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.control');
goog.require('ol.geom.Point');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
goog.require('ol.source.OSM');
goog.require('ol.source.Vector');
goog.require('ol.style.Circle');
goog.require('ol.style.Fill');
goog.require('ol.style.Stroke');
@@ -85,7 +86,9 @@ geolocation.on('change:position', function() {
new ol.geom.Point(coordinates) : null);
});
var featuresOverlay = new ol.FeatureOverlay({
var featuresOverlay = new ol.layer.Vector({
map: map,
features: [accuracyFeature, positionFeature]
source: new ol.source.Vector({
features: [accuracyFeature, positionFeature]
})
});

View File

@@ -1,5 +1,4 @@
goog.require('ol.Feature');
goog.require('ol.FeatureOverlay');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.geom.Point');
@@ -102,12 +101,14 @@ for (i = 0; i < featureCount; i += 30) {
overlayFeatures.push(clone);
}
var featureOverlay = new ol.FeatureOverlay({
var featureOverlay = new ol.layer.Vector({
map: map,
source: new ol.source.Vector({
features: overlayFeatures
}),
style: new ol.style.Style({
image: icons[iconCount - 1]
}),
features: overlayFeatures
})
});
map.on('click', function(evt) {

View File

@@ -1,6 +1,5 @@
goog.require('ol.Attribution');
goog.require('ol.Feature');
goog.require('ol.FeatureOverlay');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.control');
@@ -180,7 +179,8 @@ map.on('postcompose', function(evt) {
}
});
var featureOverlay = new ol.FeatureOverlay({
var featureOverlay = new ol.layer.Vector({
source: new ol.source.Vector(),
map: map,
style: new ol.style.Style({
image: new ol.style.Circle({
@@ -203,7 +203,7 @@ document.getElementById('time').addEventListener('input', function() {
if (highlight === undefined) {
highlight = new ol.Feature(new ol.geom.Point(coordinate));
feature.set('highlight', highlight);
featureOverlay.addFeature(highlight);
featureOverlay.getSource().addFeature(highlight);
} else {
highlight.getGeometry().setCoordinates(coordinate);
}

View File

@@ -1,9 +1,9 @@
goog.require('ol.FeatureOverlay');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.format.GeoJSON');
goog.require('ol.layer.Image');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
goog.require('ol.source.ImageVector');
goog.require('ol.source.MapQuest');
goog.require('ol.source.Vector');
@@ -42,7 +42,8 @@ var map = new ol.Map({
})
});
var featureOverlay = new ol.FeatureOverlay({
var featureOverlay = new ol.layer.Vector({
source: new ol.source.Vector(),
map: map,
style: new ol.style.Style({
stroke: new ol.style.Stroke({
@@ -71,10 +72,10 @@ var displayFeatureInfo = function(pixel) {
if (feature !== highlight) {
if (highlight) {
featureOverlay.removeFeature(highlight);
featureOverlay.getSource().removeFeature(highlight);
}
if (feature) {
featureOverlay.addFeature(feature);
featureOverlay.getSource().addFeature(feature);
}
highlight = feature;
}

View File

@@ -4,24 +4,33 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" type="text/css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" type="text/css">
<link rel="stylesheet" href="../css/ol.css" type="text/css">
<link rel="stylesheet" href="./resources/layout.css" type="text/css">
<style>
body {
padding-top: 70px;
}
.navbar-form {
margin-top: 12px;
}
input.search-query {
color: #333;
}
.example {
padding: 10px;
background-color: #F5F5F5;
height: 140px;
padding: 3px;
background-color: #eee;
border-radius: 3px;
margin-bottom: 10px;
margin: 10px 0;
overflow: auto;
}
.example p.description {
font-size: smaller;
margin: 5px 0;
}
.example:hover {
background-color: #ddd;
}
.navbar-search.pull-left {
padding: 5px;
}
::-webkit-scrollbar {
width: 8px;
@@ -174,35 +183,31 @@
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="brand" href="./"><img src="./resources/logo-70x70.png"> OpenLayers 3 Examples</a>
<form class="navbar-search pull-left">
<input name="q" type="text" id="keywords" class="search-query" placeholder="Search">
<span id="count"></span>
</form>
</div>
<header class="navbar navbar-fixed-top" role="navigation">
<div class="container">
<a class="navbar-brand" href="./"><img src="./resources/logo-70x70.png">&nbsp;OpenLayers 3 Examples</a>
<form class="navbar-form navbar-left" role="search">
<input name="q" type="text" id="keywords" class="search-query" placeholder="Search">
<span id="count"></span>
</form>
</div>
</div>
</header>
<div class="container-fluid">
<div id="examples"></div>
<div style="display: none;">
<div id="template">
<div class="span4 example" jugl:repeat="example examples">
<a jugl:attributes="href example.link" class="mainlink">
<strong><span jugl:replace="example.title">title</span></strong><br>
<small jugl:content="'(' + example.example + ')'"></small>
</a>
<p><div jugl:content="example.shortdesc"></div></p>
<p><small jugl:content="'tags: ' + example.tags"></small></p>
<div id="template" class="row">
<div class="col-md-4 col-sm-4" jugl:repeat="example examples">
<div class="example">
<a jugl:attributes="href example.link" class="mainlink">
<strong><span jugl:replace="example.title">title</span></strong><br>
<small jugl:content="'(' + example.example + ')'"></small>
</a>
<p class="description" jugl:content="example.shortdesc"></p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -1,5 +1,8 @@
---
template: "example-verbatim.html"
template: example-verbatim.html
title: Full-Screen Mobile
shortdesc: Example of a full screen map.
tags: "fullscreen, geolocation, mobile"
---
<!doctype html>
<html lang="en">
@@ -23,11 +26,5 @@ template: "example-verbatim.html"
<script src="./resources/common.js" type="text/javascript"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/fastclick/1.0.6/fastclick.min.js" type="text/javascript"></script>
<script src="loader.js?id=mobile-full-screen" type="text/javascript"></script>
<div style="display: none;">
<div id="title">Mobile full screen example</div>
<div id="shortdesc">Example of a full screen map.</div>
<div id="tags">fullscreen, bing, geolocation, mobile</div>
</div>
</body>
</html>

View File

@@ -24,7 +24,9 @@ var vector = new ol.layer.Vector({
})
});
var select = new ol.interaction.Select();
var select = new ol.interaction.Select({
wrapX: false
});
var modify = new ol.interaction.Modify({
features: select.getFeatures()

View File

@@ -1,15 +1,59 @@
@import url(http://fonts.googleapis.com/css?family=Quattrocento+Sans:400,400italic,700);
body {
padding-top: 60px;
font-family: 'Quattrocento Sans', sans-serif;
font-size: 16px;
}
.navbar {
background-color: #1F6B75;
color: white;
border: 0;
border-radius: 0;
}
.navbar-brand {
color: white;
font-weight: bold;
font-size: 160%;
padding: 8px 0;
}
.navbar-brand:hover,
.navbar-brand:focus {
color: #aae1e9;
}
.navbar-brand img {
height: 35px;
vertical-align: middle;
margin-right: 5px;
display: inline-block;
}
ul.inline,
ol.inline {
margin-left: 0;
padding-left: 0;
list-style: none;
}
ul.inline>li,
ol.inline>li {
display: inline-block;
padding-left: 5px;
padding-right: 5px;
}
.map {
height: 400px;
width: 100%;
background: url(map-background.jpg) repeat;
margin-bottom: 10px;
}
.ol-attribution {
.ol-attribution.ol-logo-only,
.ol-attribution.ol-uncollapsible {
max-width: calc(100% - 3em);
height: 1.5em;
}
.ol-attribution ul {
font-size: 1rem;
}
.ol-control button, .ol-attribution, .ol-scale-line-inner {
font-family: 'Lucida Grande',Verdana,Geneva,Lucida,Arial,Helvetica,sans-serif;
@@ -21,18 +65,3 @@ body {
#api-links ul {
display: inline;
}
body, h1, h2, h3, h4, p, li, td, th {
font-family: Quattrocento Sans;
}
.navbar-inverse .navbar-inner {
background: #1F6B75;
}
.navbar-inverse .brand {
color: white;
padding: 5px;
}
.brand img {
width: 35px;
height: 35px;
}

View File

@@ -29,7 +29,7 @@ docs: >
</select>
</div>
</form>
tags: "draw, edit, modify, vector, featureoverlay, snap"
tags: "draw, edit, modify, vector, snap"
---
<div class="row-fluid">
<div class="span12">

View File

@@ -7,13 +7,12 @@ goog.require('ol.source.TileVector');
goog.require('ol.style.Fill');
goog.require('ol.style.Stroke');
goog.require('ol.style.Style');
goog.require('ol.tilegrid.XYZ');
var waterLayer = new ol.layer.Vector({
source: new ol.source.TileVector({
format: new ol.format.TopoJSON(),
projection: 'EPSG:3857',
tileGrid: new ol.tilegrid.XYZ({
tileGrid: ol.tilegrid.createXYZ({
maxZoom: 19
}),
url: 'http://{a-c}.tile.openstreetmap.us/' +
@@ -31,7 +30,7 @@ var roadLayer = new ol.layer.Vector({
source: new ol.source.TileVector({
format: new ol.format.TopoJSON(),
projection: 'EPSG:3857',
tileGrid: new ol.tilegrid.XYZ({
tileGrid: ol.tilegrid.createXYZ({
maxZoom: 19
}),
url: 'http://{a-c}.tile.openstreetmap.us/' +
@@ -87,7 +86,7 @@ var buildingLayer = new ol.layer.Vector({
defaultProjection: 'EPSG:4326'
}),
projection: 'EPSG:3857',
tileGrid: new ol.tilegrid.XYZ({
tileGrid: ol.tilegrid.createXYZ({
maxZoom: 19
}),
url: 'http://{a-c}.tile.openstreetmap.us/' +
@@ -106,7 +105,7 @@ var landuseLayer = new ol.layer.Vector({
defaultProjection: 'EPSG:4326'
}),
projection: 'EPSG:3857',
tileGrid: new ol.tilegrid.XYZ({
tileGrid: ol.tilegrid.createXYZ({
maxZoom: 19
}),
url: 'http://{a-c}.tile.openstreetmap.us/' +

View File

@@ -12,7 +12,6 @@ goog.require('ol.loadingstrategy');
goog.require('ol.proj');
goog.require('ol.source.Vector');
goog.require('ol.source.XYZ');
goog.require('ol.tilegrid.XYZ');
var serviceUrl = 'http://services.arcgis.com/rOo16HdIMeOBI4Mb/arcgis/rest/' +
@@ -45,7 +44,7 @@ var vectorSource = new ol.source.Vector({
}
}});
},
strategy: ol.loadingstrategy.tile(new ol.tilegrid.XYZ({
strategy: ol.loadingstrategy.tile(ol.tilegrid.createXYZ({
tileSize: 512
}))
});

View File

@@ -11,7 +11,6 @@ goog.require('ol.source.XYZ');
goog.require('ol.style.Fill');
goog.require('ol.style.Stroke');
goog.require('ol.style.Style');
goog.require('ol.tilegrid.XYZ');
var serviceUrl = 'http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/' +
@@ -91,7 +90,7 @@ var vectorSource = new ol.source.Vector({
}
}});
},
strategy: ol.loadingstrategy.tile(new ol.tilegrid.XYZ({
strategy: ol.loadingstrategy.tile(ol.tilegrid.createXYZ({
tileSize: 512
}))
});

View File

@@ -1,4 +1,3 @@
goog.require('ol.FeatureOverlay');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.format.GeoJSON');
@@ -60,7 +59,8 @@ var map = new ol.Map({
var highlightStyleCache = {};
var featureOverlay = new ol.FeatureOverlay({
var featureOverlay = new ol.layer.Vector({
source: new ol.source.Vector(),
map: map,
style: function(feature, resolution) {
var text = resolution < 5000 ? feature.get('name') : '';
@@ -106,10 +106,10 @@ var displayFeatureInfo = function(pixel) {
if (feature !== highlight) {
if (highlight) {
featureOverlay.removeFeature(highlight);
featureOverlay.getSource().removeFeature(highlight);
}
if (feature) {
featureOverlay.addFeature(feature);
featureOverlay.getSource().addFeature(feature);
}
highlight = feature;
}

View File

@@ -12,7 +12,6 @@ goog.require('ol.style.Circle');
goog.require('ol.style.Fill');
goog.require('ol.style.Stroke');
goog.require('ol.style.Style');
goog.require('ol.tilegrid.XYZ');
var styles = {
'amenity': {
@@ -102,7 +101,7 @@ var vectorSource = new ol.source.Vector({
vectorSource.addFeatures(features);
});
},
strategy: ol.loadingstrategy.tile(new ol.tilegrid.XYZ({
strategy: ol.loadingstrategy.tile(ol.tilegrid.createXYZ({
maxZoom: 19
}))
});

View File

@@ -8,7 +8,6 @@ goog.require('ol.source.BingMaps');
goog.require('ol.source.Vector');
goog.require('ol.style.Stroke');
goog.require('ol.style.Style');
goog.require('ol.tilegrid.XYZ');
// format used to parse WFS GetFeature responses
@@ -24,14 +23,17 @@ var vectorSource = new ol.source.Vector({
// parameter to the URL
$.ajax({url: url, dataType: 'jsonp', jsonp: false});
},
strategy: ol.loadingstrategy.tile(new ol.tilegrid.XYZ({
strategy: ol.loadingstrategy.tile(ol.tilegrid.createXYZ({
maxZoom: 19
}))
});
// the global function whose name is specified in the URL of JSONP WFS
// GetFeature requests
var loadFeatures = function(response) {
/**
* JSONP WFS callback function.
* @param {Object} response The response object.
*/
window.loadFeatures = function(response) {
vectorSource.addFeatures(geojsonFormat.readFeatures(response));
};

View File

@@ -15,7 +15,7 @@ for (var i = 0, ii = resolutions.length; i < ii; ++i) {
resolutions[i] = startResolution / Math.pow(2, i);
}
var tileGrid = new ol.tilegrid.TileGrid({
origin: ol.extent.getBottomLeft(projExtent),
extent: [-13884991, 2870341, -7455066, 6338219],
resolutions: resolutions,
tileSize: [512, 256]
});
@@ -25,7 +25,6 @@ var layers = [
source: new ol.source.MapQuest({layer: 'sat'})
}),
new ol.layer.Tile({
extent: [-13884991, 2870341, -7455066, 6338219],
source: new ol.source.TileWMS({
url: 'http://demo.boundlessgeo.com/geoserver/wms',
params: {'LAYERS': 'topp:states', 'TILED': true},

View File

@@ -5,6 +5,9 @@ shortdesc: Example of integrating Proj4js for coordinate transforms.
docs: >
With transparent [Proj4js](http://proj4js.org/) integration, OpenLayers can transform coordinates between arbitrary projections.
tags: "wms, single image, proj4js, projection"
resources:
- http://cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.6/proj4.js
- http://epsg.io/21781-1753.js
---
<div class="row-fluid">
<div class="span12">

View File

@@ -13,8 +13,7 @@ var layers = [
source: new ol.source.TileWMS({
url: 'http://demo.boundlessgeo.com/geoserver/ne/wms',
params: {'LAYERS': 'ne:ne_10m_admin_0_countries', 'TILED': true},
serverType: 'geoserver',
wrapX: true
serverType: 'geoserver'
})
})
];

View File

@@ -1,75 +1,38 @@
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.format.WMTSCapabilities');
goog.require('ol.has');
goog.require('ol.layer.Tile');
goog.require('ol.source.WMTS');
goog.require('ol.tilegrid.WMTS');
var template =
'{Layer}/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpeg';
var urls = [
'http://maps1.wien.gv.at/basemap/' + template,
'http://maps2.wien.gv.at/basemap/' + template,
'http://maps3.wien.gv.at/basemap/' + template,
'http://maps4.wien.gv.at/basemap/' + template,
'http://maps.wien.gv.at/basemap/' + template
];
var capabilitiesUrl = 'http://www.basemap.at/wmts/1.0.0/WMTSCapabilities.xml';
// HiDPI support:
// * Use 'bmaphidpi' layer (pixel ratio 2) for device pixel ratio > 1
// * Use 'geolandbasemap' layer (pixel ratio 1) for device pixel ratio == 1
var hiDPI = ol.has.DEVICE_PIXEL_RATIO > 1;
var source = new ol.source.WMTS({
projection: 'EPSG:3857',
layer: hiDPI ? 'bmaphidpi' : 'geolandbasemap',
tilePixelRatio: hiDPI ? 2 : 1,
style: 'normal',
matrixSet: 'google3857',
urls: urls,
requestEncoding: 'REST',
tileGrid: new ol.tilegrid.WMTS({
origin: [-20037508.3428, 20037508.3428],
resolutions: [
559082264.029 * 0.28E-3,
279541132.015 * 0.28E-3,
139770566.007 * 0.28E-3,
69885283.0036 * 0.28E-3,
34942641.5018 * 0.28E-3,
17471320.7509 * 0.28E-3,
8735660.37545 * 0.28E-3,
4367830.18773 * 0.28E-3,
2183915.09386 * 0.28E-3,
1091957.54693 * 0.28E-3,
545978.773466 * 0.28E-3,
272989.386733 * 0.28E-3,
136494.693366 * 0.28E-3,
68247.3466832 * 0.28E-3,
34123.6733416 * 0.28E-3,
17061.8366708 * 0.28E-3,
8530.91833540 * 0.28E-3,
4265.45916770 * 0.28E-3,
2132.72958385 * 0.28E-3,
1066.36479193 * 0.28E-3
],
matrixIds: [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
]
})
});
var layer = hiDPI ? 'bmaphidpi' : 'geolandbasemap';
var tilePixelRatio = hiDPI ? 2 : 1;
var map = new ol.Map({
layers: [
new ol.layer.Tile({
extent: [977844.377599999, 5837774.6617, 1915609.8654, 6295560.8122],
source: source
})
],
target: 'map',
view: new ol.View({
center: [1823849, 6143760],
zoom: 11
})
});
$.ajax(capabilitiesUrl).then(function(response) {
var result = new ol.format.WMTSCapabilities().read(response);
var options = ol.source.WMTS.optionsFromCapabilities(result, {
layer: layer,
matrixSet: 'google3857',
requestEncoding: 'REST',
style: 'normal'
});
options.tilePixelRatio = tilePixelRatio;
map.addLayer(new ol.layer.Tile({
source: new ol.source.WMTS(options)
}));
});

18
examples/wmts-ign.html Normal file
View File

@@ -0,0 +1,18 @@
---
template: example.html
title: IGN WMTS example
shortdesc: Demonstrates displaying IGN (France) WMTS layers.
docs: >
In this example an IGN WMTS layer is displayed.
For more information on IGN's WMTS service see the
<a href="http://professionnels.ign.fr/api-sig">IGN Géoportail API web page
</a> and
<a href="http://www.geoportail.gouv.fr/depot/api/cgu/DT_APIGeoportail.pdf">
Descriptif technique des web services du Géoportail</a> (french).
tags: "french, ign, geoportail, wmts"
---
<div class="row-fluid">
<div class="span12">
<div id="map" class="map"></div>
</div>
</div>

64
examples/wmts-ign.js Normal file
View File

@@ -0,0 +1,64 @@
goog.require('ol.Attribution');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.control');
goog.require('ol.extent');
goog.require('ol.layer.Tile');
goog.require('ol.proj');
goog.require('ol.source.WMTS');
goog.require('ol.tilegrid.WMTS');
var map = new ol.Map({
target: 'map',
controls: ol.control.defaults({
attributionOptions: /** @type {olx.control.AttributionOptions} */ ({
collapsible: false
})
}),
view: new ol.View({
zoom: 5,
center: ol.proj.transform([5, 45], 'EPSG:4326', 'EPSG:3857')
})
});
var resolutions = [];
var matrixIds = [];
var proj3857 = ol.proj.get('EPSG:3857');
var maxResolution = ol.extent.getWidth(proj3857.getExtent()) / 256;
for (var i = 0; i < 18; i++) {
matrixIds[i] = i.toString();
resolutions[i] = maxResolution / Math.pow(2, i);
}
var tileGrid = new ol.tilegrid.WMTS({
origin: [-20037508, 20037508],
resolutions: resolutions,
matrixIds: matrixIds
});
// API key valid for 'openlayers.org' and 'localhost'.
// Expiration date is 06/29/2018.
var key = '2mqbg0z6cx7ube8gsou10nrt';
var ign_source = new ol.source.WMTS({
url: 'http://wxs.ign.fr/' + key + '/wmts',
layer: 'GEOGRAPHICALGRIDSYSTEMS.MAPS',
matrixSet: 'PM',
format: 'image/jpeg',
projection: 'EPSG:3857',
tileGrid: tileGrid,
style: 'normal',
attributions: [new ol.Attribution({
html: '<a href="http://www.geoportail.fr/" target="_blank">' +
'<img src="http://api.ign.fr/geoportail/api/js/latest/' +
'theme/geoportal/img/logo_gp.gif"></a>'
})]
});
var ign = new ol.layer.Tile({
source: ign_source
});
map.addLayer(ign);

View File

@@ -3,7 +3,7 @@ template: example.html
title: XYZ Esri EPSG:4326 tileSize 512 example
shortdesc: Example of a XYZ source in EPSG:4326 using Esri 512x512 tiles.
docs: >
ArcGIS REST tile services with custom tile sizes (here: 512x512 pixels) and projection (here: EPSG:4326) are supported by `ol.source.XYZ`. A custom tile grid and tile url function are required.
ArcGIS REST tile services with custom tile sizes (here: 512x512 pixels) and projection (here: EPSG:4326) are supported by `ol.source.XYZ`. A custom tile url function is used to handle zoom level offsets.
tags: "xyz, esri, tilesize, custom projection"
---
<div class="row-fluid">

View File

@@ -1,33 +1,19 @@
goog.require('ol.Attribution');
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.extent');
goog.require('ol.layer.Tile');
goog.require('ol.proj');
goog.require('ol.source.TileImage');
goog.require('ol.tilegrid.TileGrid');
goog.require('ol.source.XYZ');
var attribution = new ol.Attribution({
html: 'Copyright:&copy; 2013 ESRI, i-cubed, GeoEye'
});
var projection = ol.proj.get('EPSG:4326');
var projectionExtent = projection.getExtent();
// The tile size supported by the ArcGIS tile service.
var tileSize = 512;
// Calculate the resolutions supported by the ArcGIS tile service.
// There are 16 resolutions, with a factor of 2 between successive
// resolutions. The max resolution is such that the world (360°)
// fits into two (512x512 px) tiles.
var maxResolution = ol.extent.getWidth(projectionExtent) / (tileSize * 2);
var resolutions = new Array(16);
var z;
for (z = 0; z < 16; ++z) {
resolutions[z] = maxResolution / Math.pow(2, z);
}
var urlTemplate = 'http://services.arcgisonline.com/arcgis/rest/services/' +
'ESRI_Imagery_World_2D/MapServer/tile/{z}/{y}/{x}';
@@ -35,31 +21,17 @@ var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
/* ol.source.XYZ and ol.tilegrid.XYZ have no resolutions config */
source: new ol.source.TileImage({
source: new ol.source.XYZ({
attributions: [attribution],
tileUrlFunction: function(tileCoord, pixelRatio, projection) {
var z = tileCoord[0];
var x = tileCoord[1];
var y = -tileCoord[2] - 1;
// wrap the world on the X axis
var n = Math.pow(2, z + 1); // 2 tiles at z=0
x = x % n;
if (x * n < 0) {
// x and n differ in sign so add n to wrap the result
// to the correct sign
x = x + n;
}
return urlTemplate.replace('{z}', z.toString())
.replace('{y}', y.toString())
.replace('{x}', x.toString());
},
maxZoom: 16,
projection: projection,
tileGrid: new ol.tilegrid.TileGrid({
origin: ol.extent.getTopLeft(projectionExtent),
resolutions: resolutions,
tileSize: 512
})
tileSize: tileSize,
tileUrlFunction: function(tileCoord) {
return urlTemplate.replace('{z}', (tileCoord[0] - 1).toString())
.replace('{x}', tileCoord[1].toString())
.replace('{y}', (-tileCoord[2] - 1).toString());
},
wrapX: true
})
})
],

View File

@@ -30,3 +30,15 @@ Touch.prototype.webkitRadiusX;
/** @type {number} */
Touch.prototype.webkitRadiusY;
/**
* @type {boolean}
*/
WebGLContextAttributes.prototype.preferLowPowerToHighPerformance;
/**
* @type {boolean}
*/
WebGLContextAttributes.prototype.failIfMajorPerformanceCaveat;

View File

@@ -123,7 +123,7 @@ var GeoJSONFeature = function() {};
/**
* @type {GeoJSONGeometry}
* @type {GeoJSONGeometry|GeoJSONGeometryCollection}
*/
GeoJSONFeature.prototype.geometry;

View File

@@ -49,6 +49,25 @@ oli.DrawEvent.prototype.feature;
/**
* @interface
*/
oli.ModifyEvent = function() {};
/**
* @type {ol.Collection.<ol.Feature>}
*/
oli.ModifyEvent.prototype.features;
/**
* @type {ol.MapBrowserPointerEvent}
*/
oli.ModifyEvent.prototype.mapBrowserPointerEvent;
/**
* @interface
*/
@@ -120,21 +139,27 @@ oli.MapEvent.prototype.frameState;
/**
* @interface
*/
oli.SelectEvent = function() {};
oli.SelectEvent = function() {};
/**
* @type {Array.<ol.Feature>}
*/
/**
* @type {Array.<ol.Feature>}
*/
oli.SelectEvent.prototype.deselected;
/**
* @type {Array.<ol.Feature>}
*/
/**
* @type {Array.<ol.Feature>}
*/
oli.SelectEvent.prototype.selected;
/**
* @type {ol.MapBrowserEvent}
*/
oli.SelectEvent.prototype.mapBrowserEvent;
/**
* @type {Object}

View File

@@ -1,3 +1,4 @@
/**
* @type {Object}
*/
@@ -226,7 +227,10 @@ olx.MapOptions.prototype.keyboardEventTarget;
/**
* Layers. If this is not defined, a map with no layers will be rendered.
* Layers. If this is not defined, a map with no layers will be rendered. Note
* that layers are rendered in the order supplied, so if you want, for example,
* a vector layer to appear on top of a tile layer, it must come after the tile
* layer.
* @type {Array.<ol.layer.Base>|ol.Collection.<ol.layer.Base>|undefined}
* @api stable
*/
@@ -328,7 +332,7 @@ olx.OverlayOptions.prototype.element;
/**
* Offsets in pixels used when positioning the overlay. The fist element in the
* Offsets in pixels used when positioning the overlay. The first element in the
* array is the horizontal offset. A positive value shifts the overlay right.
* The second element in the array is the vertical offset. A positive value
* shifts the overlay down. Default is `[0, 0]`.
@@ -1907,6 +1911,7 @@ olx.format.WFSOptions.prototype.schemaLocation;
* outputFormat: (string|undefined),
* maxFeatures: (number|undefined),
* geometryName: (string|undefined),
* propertyNames: (Array.<string>|undefined),
* bbox: (ol.Extent|undefined)}}
* @api
*/
@@ -1978,6 +1983,14 @@ olx.format.WFSWriteGetFeatureOptions.prototype.maxFeatures;
olx.format.WFSWriteGetFeatureOptions.prototype.geometryName;
/**
* Optional list of property names to serialize.
* @type {Array.<string>|undefined}
* @api
*/
olx.format.WFSWriteGetFeatureOptions.prototype.propertyNames;
/**
* Extent to use for the BBOX filter.
* @type {ol.Extent|undefined}
@@ -2353,20 +2366,36 @@ olx.interaction.DragZoomOptions.prototype.style;
/**
* @typedef {{features: (ol.Collection.<ol.Feature>|undefined),
* @typedef {{clickTolerance: (number|undefined),
* features: (ol.Collection.<ol.Feature>|undefined),
* source: (ol.source.Vector|undefined),
* snapTolerance: (number|undefined),
* type: ol.geom.GeometryType,
* minPointsPerRing: (number|undefined),
* maxPoints: (number|undefined),
* minPoints: (number|undefined),
* style: (ol.style.Style|Array.<ol.style.Style>|ol.style.StyleFunction|undefined),
* geometryFunction: (ol.interaction.DrawGeometryFunctionType|undefined),
* geometryName: (string|undefined),
* condition: (ol.events.ConditionType|undefined),
* freehandCondition: (ol.events.ConditionType|undefined)}}
* freehandCondition: (ol.events.ConditionType|undefined),
* wrapX: (boolean|undefined)}}
* @api
*/
olx.interaction.DrawOptions;
/**
* The maximum distance in pixels between "down" and "up" for a "up" event
* to be considered a "click" event and actually add a point/vertex to the
* geometry being drawn. Default is 6 pixels. That value was chosen for
* the draw interaction to behave correctly on mouse as well as on touch
* devices.
* @type {number|undefined}
* @api
*/
olx.interaction.DrawOptions.prototype.clickTolerance;
/**
* Destination collection for the drawn features.
* @type {ol.Collection.<ol.Feature>|undefined}
@@ -2393,7 +2422,7 @@ olx.interaction.DrawOptions.prototype.snapTolerance;
/**
* Drawing type ('Point', 'LineString', 'Polygon', 'MultiPoint',
* 'MultiLineString', or 'MultiPolygon').
* 'MultiLineString', 'MultiPolygon' or 'Circle').
* @type {ol.geom.GeometryType}
* @api
*/
@@ -2401,12 +2430,21 @@ olx.interaction.DrawOptions.prototype.type;
/**
* The number of points that must be drawn before a polygon ring can be finished.
* Default is `3`.
* The number of points that can be drawn before a polygon ring or line string
* is finished. The default is no restriction.
* @type {number|undefined}
* @api
*/
olx.interaction.DrawOptions.prototype.minPointsPerRing;
olx.interaction.DrawOptions.prototype.maxPoints;
/**
* The number of points that must be drawn before a polygon ring or line string
* can be finished. Default is `3` for polygon rings and `2` for line strings.
* @type {number|undefined}
* @api
*/
olx.interaction.DrawOptions.prototype.minPoints;
/**
@@ -2417,6 +2455,14 @@ olx.interaction.DrawOptions.prototype.minPointsPerRing;
olx.interaction.DrawOptions.prototype.style;
/**
* Function that is called when a geometry's coordinates are updated.
* @type {ol.interaction.DrawGeometryFunctionType|undefined}
* @api
*/
olx.interaction.DrawOptions.prototype.geometryFunction;
/**
* Geometry name to use for features created by the draw interaction.
* @type {string|undefined}
@@ -2448,6 +2494,14 @@ olx.interaction.DrawOptions.prototype.condition;
olx.interaction.DrawOptions.prototype.freehandCondition;
/**
* Wrap the world horizontally on the sketch overlay. Default is `false`.
* @type {boolean|undefined}
* @api
*/
olx.interaction.DrawOptions.prototype.wrapX;
/**
* @typedef {{condition: (ol.events.ConditionType|undefined),
* duration: (number|undefined),
@@ -2523,7 +2577,8 @@ olx.interaction.KeyboardZoomOptions.prototype.delta;
* @typedef {{deleteCondition: (ol.events.ConditionType|undefined),
* pixelTolerance: (number|undefined),
* style: (ol.style.Style|Array.<ol.style.Style>|ol.style.StyleFunction|undefined),
* features: ol.Collection.<ol.Feature>}}
* features: ol.Collection.<ol.Feature>,
* wrapX: (boolean|undefined)}}
* @api
*/
olx.interaction.ModifyOptions;
@@ -2542,7 +2597,7 @@ olx.interaction.ModifyOptions.prototype.deleteCondition;
/**
* Pixel tolerance for considering the pointer close enough to a segment or
* vertex for editing.
* vertex for editing. Default is `10`.
* @type {number|undefined}
* @api
*/
@@ -2550,7 +2605,8 @@ olx.interaction.ModifyOptions.prototype.pixelTolerance;
/**
* FeatureOverlay style.
* Style used for the features being modified. By default the default edit
* style is used (see {@link ol.style}).
* @type {ol.style.Style|Array.<ol.style.Style>|ol.style.StyleFunction|undefined}
* @api
*/
@@ -2565,6 +2621,14 @@ olx.interaction.ModifyOptions.prototype.style;
olx.interaction.ModifyOptions.prototype.features;
/**
* Wrap the world horizontally on the sketch overlay. Default is `false`.
* @type {boolean|undefined}
* @api
*/
olx.interaction.ModifyOptions.prototype.wrapX;
/**
* @typedef {{duration: (number|undefined)}}
* @api
@@ -2686,7 +2750,8 @@ olx.interaction.PointerOptions.prototype.handleUpEvent;
* removeCondition: (ol.events.ConditionType|undefined),
* toggleCondition: (ol.events.ConditionType|undefined),
* multi: (boolean|undefined),
* filter: (ol.interaction.SelectFilterFunction|undefined)}}
* filter: (ol.interaction.SelectFilterFunction|undefined),
* wrapX: (boolean|undefined)}}
* @api
*/
olx.interaction.SelectOptions;
@@ -2731,7 +2796,8 @@ olx.interaction.SelectOptions.prototype.layers;
/**
* Style for the selected features (those in the FeatureOverlay).
* Style for the selected features. By default the default edit style is used
* (see {@link ol.style}).
* @type {ol.style.Style|Array.<ol.style.Style>|ol.style.StyleFunction|undefined}
* @api
*/
@@ -2781,6 +2847,14 @@ olx.interaction.SelectOptions.prototype.multi;
olx.interaction.SelectOptions.prototype.filter;
/**
* Wrap the world horizontally on the selection overlay. Default is `true`.
* @type {boolean|undefined}
* @api
*/
olx.interaction.SelectOptions.prototype.wrapX;
/**
* Options for snap
* @typedef {{
@@ -3260,6 +3334,7 @@ olx.layer.HeatmapOptions.prototype.visible;
* hue: (number|undefined),
* opacity: (number|undefined),
* saturation: (number|undefined),
* map: (ol.Map|undefined),
* source: (ol.source.Image|undefined),
* visible: (boolean|undefined),
* extent: (ol.Extent|undefined),
@@ -3318,6 +3393,17 @@ olx.layer.ImageOptions.prototype.saturation;
olx.layer.ImageOptions.prototype.source;
/**
* Sets the layer as overlay on a map. The map will not manage this layer in its
* layers collection, and the layer will be rendered on top. This is useful for
* temporary layers. The standard way to add a layer to a map and have it
* managed by the map is to use {@link ol.Map#addLayer}.
* @type {ol.Map|undefined}
* @api
*/
olx.layer.ImageOptions.prototype.map;
/**
* Visibility. Default is `true` (visible).
* @type {boolean|undefined}
@@ -3359,6 +3445,7 @@ olx.layer.ImageOptions.prototype.maxResolution;
* preload: (number|undefined),
* saturation: (number|undefined),
* source: (ol.source.Tile|undefined),
* map: (ol.Map|undefined),
* visible: (boolean|undefined),
* extent: (ol.Extent|undefined),
* minResolution: (number|undefined),
@@ -3426,6 +3513,17 @@ olx.layer.TileOptions.prototype.saturation;
olx.layer.TileOptions.prototype.source;
/**
* Sets the layer as overlay on a map. The map will not manage this layer in its
* layers collection, and the layer will be rendered on top. This is useful for
* temporary layers. The standard way to add a layer to a map and have it
* managed by the map is to use {@link ol.Map#addLayer}.
* @type {ol.Map|undefined}
* @api
*/
olx.layer.TileOptions.prototype.map;
/**
* Visibility. Default is `true` (visible).
* @type {boolean|undefined}
@@ -3478,6 +3576,7 @@ olx.layer.TileOptions.prototype.useInterimTilesOnError;
* renderBuffer: (number|undefined),
* saturation: (number|undefined),
* source: (ol.source.Vector|undefined),
* map: (ol.Map|undefined),
* style: (ol.style.Style|Array.<ol.style.Style>|ol.style.StyleFunction|undefined),
* updateWhileAnimating: (boolean|undefined),
* updateWhileInteracting: (boolean|undefined),
@@ -3521,6 +3620,17 @@ olx.layer.VectorOptions.prototype.renderOrder;
olx.layer.VectorOptions.prototype.hue;
/**
* Sets the layer as overlay on a map. The map will not manage this layer in its
* layers collection, and the layer will be rendered on top. This is useful for
* temporary layers. The standard way to add a layer to a map and have it
* managed by the map is to use {@link ol.Map#addLayer}.
* @type {ol.Map|undefined}
* @api
*/
olx.layer.VectorOptions.prototype.map;
/**
* The bounding extent for layer rendering. The layer will not be rendered
* outside of this extent.
@@ -3556,8 +3666,9 @@ olx.layer.VectorOptions.prototype.opacity;
/**
* The buffer around the viewport extent used by the renderer when getting
* features from the vector source. Recommended value: the size of the
* largest symbol or line width. Default is 100 pixels.
* features from the vector source for the rendering or hit-detection.
* Recommended value: the size of the largest symbol, line width or label.
* Default is 100 pixels.
* @type {number|undefined}
* @api
*/
@@ -3602,7 +3713,7 @@ olx.layer.VectorOptions.prototype.updateWhileAnimating;
/**
* When set to `true`, feature batches will be recreated during interactions.
* See also `updateWhileInteracting`. Default is `false`.
* See also `updateWhileAnimating`. Default is `false`.
* @type {boolean|undefined}
* @api
*/
@@ -3617,39 +3728,6 @@ olx.layer.VectorOptions.prototype.updateWhileInteracting;
olx.layer.VectorOptions.prototype.visible;
/**
* @typedef {{features: (Array.<ol.Feature>|ol.Collection.<ol.Feature>|undefined),
* map: (ol.Map|undefined),
* style: (ol.style.Style|Array.<ol.style.Style>|ol.style.StyleFunction|undefined)}}
* @api
*/
olx.FeatureOverlayOptions;
/**
* Features.
* @type {Array.<ol.Feature>|ol.Collection.<ol.Feature>|undefined}
* @api
*/
olx.FeatureOverlayOptions.prototype.features;
/**
* Map.
* @type {ol.Map|undefined}
* @api
*/
olx.FeatureOverlayOptions.prototype.map;
/**
* Feature style.
* @type {ol.style.Style|Array.<ol.style.Style>|ol.style.StyleFunction|undefined}
* @api
*/
olx.FeatureOverlayOptions.prototype.style;
/**
* Namespace.
* @type {Object}
@@ -3945,12 +4023,14 @@ olx.source.TileImageOptions.prototype.wrapX;
/**
* @typedef {{attributions: (Array.<ol.Attribution>|undefined),
* format: ol.format.Feature,
* format: (ol.format.Feature|undefined),
* logo: (string|olx.LogoOptions|undefined),
* tileGrid: ol.tilegrid.TileGrid,
* tileUrlFunction: (ol.TileUrlFunctionType|undefined),
* tileLoadFunction: (ol.TileVectorLoadFunctionType|undefined),
* url: (string|undefined),
* urls: (Array.<string>|undefined)}}
* urls: (Array.<string>|undefined),
* wrapX: (boolean|undefined)}}
* @api
*/
olx.source.TileVectorOptions;
@@ -3965,8 +4045,8 @@ olx.source.TileVectorOptions.prototype.attributions;
/**
* Format.
* @type {ol.format.Feature}
* Format. Required unless tileLoadFunction is used.
* @type {ol.format.Feature|undefined}
* @api
*/
olx.source.TileVectorOptions.prototype.format;
@@ -3997,6 +4077,16 @@ olx.source.TileVectorOptions.prototype.tileGrid;
olx.source.TileVectorOptions.prototype.tileUrlFunction;
/**
* Optional function to override the default loading and format parsing behaviour.
* If this option is used format is ignored and the provided function will be
* responsible for data retrieval and transformation into features.
* @type {ol.TileVectorLoadFunctionType|undefined}
* @api
*/
olx.source.TileVectorOptions.prototype.tileLoadFunction;
/**
* URL template. Must include `{x}`, `{y}` or `{-y}`, and `{z}` placeholders.
* @type {string|undefined}
@@ -4013,6 +4103,16 @@ olx.source.TileVectorOptions.prototype.url;
olx.source.TileVectorOptions.prototype.urls;
/**
* Wrap the world horizontally. Default is `true`. For vector editing across the
* -180° and 180° meridians to work properly, this should be set to `false`. The
* resulting geometry coordinates will then exceed the world bounds.
* @type {boolean|undefined}
* @api
*/
olx.source.TileVectorOptions.prototype.wrapX;
/**
* @typedef {{url: (string|undefined),
* displayDpi: (number|undefined),
@@ -4147,7 +4247,8 @@ olx.source.MapQuestOptions.prototype.url;
/**
* @typedef {{projection: ol.proj.ProjectionLike,
* tileGrid: (ol.tilegrid.TileGrid|undefined)}}
* tileGrid: (ol.tilegrid.TileGrid|undefined),
* wrapX: (boolean|undefined)}}
* @api
*/
olx.source.TileDebugOptions;
@@ -4169,6 +4270,14 @@ olx.source.TileDebugOptions.prototype.projection;
olx.source.TileDebugOptions.prototype.tileGrid;
/**
* Whether to wrap the world horizontally. Default is `true`.
* @type {boolean|undefined}
* @api
*/
olx.source.TileDebugOptions.prototype.wrapX;
/**
* @typedef {{attributions: (Array.<ol.Attribution>|undefined),
* crossOrigin: (null|string|undefined),
@@ -4942,11 +5051,10 @@ olx.source.TileWMSOptions.prototype.urls;
/**
* Whether to wrap the world horizontally. The default, `undefined`, is to
* request out-of-bounds tiles from the server. This works well in e.g.
* GeoServer. When set to `false`, only one world will be rendered. When set to
* `true`, tiles will be requested for one world only, but they will be wrapped
* horizontally to render multiple worlds.
* Whether to wrap the world horizontally. When set to `false`, only one world
* will be rendered. When `true`, tiles will be requested for one world only,
* but they will be wrapped horizontally to render multiple worlds. The default
* is `true`.
* @type {boolean|undefined}
* @api
*/
@@ -4955,12 +5063,13 @@ olx.source.TileWMSOptions.prototype.wrapX;
/**
* @typedef {{attributions: (Array.<ol.Attribution>|undefined),
* features: (Array.<ol.Feature>|undefined),
* features: (Array.<ol.Feature>|ol.Collection.<ol.Feature>|undefined),
* format: (ol.format.Feature|undefined),
* loader: (ol.FeatureLoader|undefined),
* logo: (string|olx.LogoOptions|undefined),
* strategy: (ol.LoadingStrategy|undefined),
* url: (string|undefined),
* useSpatialIndex: (boolean|undefined),
* wrapX: (boolean|undefined)}}
* @api
*/
@@ -4976,8 +5085,9 @@ olx.source.VectorOptions.prototype.attributions;
/**
* Features.
* @type {Array.<ol.Feature>|undefined}
* Features. If provided as {@link ol.Collection}, the features in the source
* and the collection will stay in sync.
* @type {Array.<ol.Feature>|ol.Collection.<ol.Feature>|undefined}
* @api stable
*/
olx.source.VectorOptions.prototype.features;
@@ -5030,6 +5140,29 @@ olx.source.VectorOptions.prototype.strategy;
olx.source.VectorOptions.prototype.url;
/**
* By default, an RTree is used as spatial index. When features are removed and
* added frequently, and the total number of features is low, setting this to
* `false` may improve performance.
*
* Note that
* {@link ol.source.Vector#getFeaturesInExtent},
* {@link ol.source.Vector#getClosestFeatureToCoordinate} and
* {@link ol.source.Vector#getExtent} cannot be used when `useSpatialIndex` is
* set to `false`, and {@link ol.source.Vector#forEachFeatureInExtent} will loop
* through all features.
*
* When set to `false`, the features will be maintained in an
* {@link ol.Collection}, which can be retrieved through
* {@link ol.source.Vector#getFeaturesCollection}.
*
* The default is `true`.
* @type {boolean|undefined}
* @api
*/
olx.source.VectorOptions.prototype.useSpatialIndex;
/**
* Wrap the world horizontally. Default is `true`. For vector editing across the
* -180° and 180° meridians to work properly, this should be set to `false`. The
@@ -5237,6 +5370,7 @@ olx.source.WMTSOptions.prototype.wrapX;
* projection: ol.proj.ProjectionLike,
* maxZoom: (number|undefined),
* minZoom: (number|undefined),
* tileGrid: (ol.tilegrid.TileGrid|undefined),
* tileLoadFunction: (ol.TileLoadFunctionType|undefined),
* tilePixelRatio: (number|undefined),
* tileSize: (number|ol.Size|undefined),
@@ -5301,6 +5435,14 @@ olx.source.XYZOptions.prototype.maxZoom;
olx.source.XYZOptions.prototype.minZoom;
/**
* Tile grid.
* @type {ol.tilegrid.TileGrid}
* @api
*/
olx.source.XYZOptions.prototype.tileGrid;
/**
* Optional function to load a tile given a URL.
* @type {ol.TileLoadFunctionType|undefined}
@@ -6014,18 +6156,29 @@ olx.tilegrid;
/**
* @typedef {{minZoom: (number|undefined),
* @typedef {{extent: (ol.Extent|undefined),
* minZoom: (number|undefined),
* origin: (ol.Coordinate|undefined),
* origins: (Array.<ol.Coordinate>|undefined),
* resolutions: !Array.<number>,
* sizes: (Array.<ol.Size>|undefined),
* tileSize: (number|ol.Size|undefined),
* tileSizes: (Array.<number|ol.Size>|undefined),
* widths: (Array.<number>|undefined)}}
* tileSizes: (Array.<number|ol.Size>|undefined)}}
* @api
*/
olx.tilegrid.TileGridOptions;
/**
* Extent for the tile grid. No tiles outside this extent will be requested by
* {@link ol.source.Tile} sources. When no `origin` or `origins` are
* configured, the `origin` will be set to the top-left corner of the extent.
* @type {ol.Extent|undefined}
* @api
*/
olx.tilegrid.TileGridOptions.prototype.extent;
/**
* Minimum zoom. Default is 0.
* @type {number|undefined}
@@ -6035,7 +6188,9 @@ olx.tilegrid.TileGridOptions.prototype.minZoom;
/**
* Origin. Default is null.
* The tile grid origin, i.e. where the `x` and `y` axes meet (`[z, 0, 0]`).
* Tile coordinates increase left to right and upwards. If not specified,
* `extent` or `origins` must be provided.
* @type {ol.Coordinate|undefined}
* @api stable
*/
@@ -6043,8 +6198,11 @@ olx.tilegrid.TileGridOptions.prototype.origin;
/**
* Origins. If given, the array length should match the length of the
* `resolutions` array, i.e. each resolution can have a different origin.
* Tile grid origins, i.e. where the `x` and `y` axes meet (`[z, 0, 0]`), for
* each zoom level. If given, the array length should match the length of the
* `resolutions` array, i.e. each resolution can have a different origin. Tile
* coordinates increase left to right and upwards. If not specified, `extent`
* or `origin` must be provided.
* @type {Array.<ol.Coordinate>|undefined}
* @api stable
*/
@@ -6079,43 +6237,47 @@ olx.tilegrid.TileGridOptions.prototype.tileSizes;
/**
* Number of tile columns that cover the grid's extent for each zoom level. Only
* required when used with a source that has `wrapX` set to `true`, and only
* when the grid's origin differs from the one of the projection's extent. The
* array length has to match the length of the `resolutions` array, i.e. each
* resolution will have a matching entry here.
* @type {Array.<number>|undefined}
* @api
*/
olx.tilegrid.TileGridOptions.prototype.widths;
/**
* @typedef {{origin: (ol.Coordinate|undefined),
* @typedef {{extent: (ol.Extent|undefined),
* origin: (ol.Coordinate|undefined),
* origins: (Array.<ol.Coordinate>|undefined),
* resolutions: !Array.<number>,
* matrixIds: !Array.<string>,
* sizes: (Array.<ol.Size>|undefined),
* tileSize: (number|ol.Size|undefined),
* tileSizes: (Array.<number|ol.Size>|undefined),
* widths: (Array.<number>|undefined)}}
* tileSizes: (Array.<number|ol.Size>|undefined)}}
* @api
*/
olx.tilegrid.WMTSOptions;
/**
* Origin.
* @type {ol.Coordinate|undefined}
* Extent for the tile grid. No tiles outside this extent will be requested by
* {@link ol.source.Tile} sources. When no `origin` or `origins` are
* configured, the `origin` will be set to the top-left corner of the extent.
* @type {ol.Extent|undefined}
* @api
*/
olx.tilegrid.WMTSOptions.prototype.extent;
/**
* The tile grid origin, i.e. where the `x` and `y` axes meet (`[z, 0, 0]`).
* Tile coordinates increase left to right and upwards. If not specified,
* `extent` or `origins` must be provided.
* @type {ol.Coordinate|undefined}
* @api stable
*/
olx.tilegrid.WMTSOptions.prototype.origin;
/**
* Origins. The length of this array needs to match the length of the
* `resolutions` array.
* Tile grid origins, i.e. where the `x` and `y` axes meet (`[z, 0, 0]`), for
* each zoom level. If given, the array length should match the length of the
* `resolutions` array, i.e. each resolution can have a different origin. Tile
* coordinates increase left to right and upwards. If not specified, `extent` or
* `origin` must be provided.
* @type {Array.<ol.Coordinate>|undefined}
* @api
* @api stable
*/
olx.tilegrid.WMTSOptions.prototype.origins;
@@ -6139,6 +6301,21 @@ olx.tilegrid.WMTSOptions.prototype.resolutions;
olx.tilegrid.WMTSOptions.prototype.matrixIds;
/**
* Number of tile rows and columns of the grid for each zoom level. The values
* here are the `TileMatrixWidth` and `TileMatrixHeight` advertised in the
* GetCapabilities response of the WMTS, and define the grid's extent together
* with the `origin`. An `extent` can be configured in addition, and will
* further limit the extent for which tile requests are made by sources. Note
* that when the top-left corner of the `extent` is used as `origin` or
* `origins`, then the `y` value must be negative because OpenLayers tile
* coordinates increase upwards.
* @type {Array.<ol.Size>|undefined}
* @api
*/
olx.tilegrid.WMTSOptions.prototype.sizes;
/**
* Tile size.
* @type {number|ol.Size|undefined}
@@ -6215,21 +6392,6 @@ olx.tilegrid.XYZOptions.prototype.minZoom;
olx.tilegrid.XYZOptions.prototype.tileSize;
/**
* @typedef {{resolutions: !Array.<number>}}
* @api
*/
olx.tilegrid.ZoomifyOptions;
/**
* Resolutions.
* @type {!Array.<number>}
* @api
*/
olx.tilegrid.ZoomifyOptions.prototype.resolutions;
/**
* Namespace.
* @type {Object}
@@ -6245,7 +6407,7 @@ olx.view;
* minResolution: (number|undefined)}}
* @api
*/
olx.view.FitGeometryOptions;
olx.view.FitOptions;
/**
@@ -6254,7 +6416,7 @@ olx.view.FitGeometryOptions;
* @type {!Array.<number>}
* @api
*/
olx.view.FitGeometryOptions.prototype.padding;
olx.view.FitOptions.prototype.padding;
/**
@@ -6262,7 +6424,7 @@ olx.view.FitGeometryOptions.prototype.padding;
* @type {boolean|undefined}
* @api
*/
olx.view.FitGeometryOptions.prototype.constrainResolution;
olx.view.FitOptions.prototype.constrainResolution;
/**
@@ -6270,7 +6432,7 @@ olx.view.FitGeometryOptions.prototype.constrainResolution;
* @type {boolean|undefined}
* @api
*/
olx.view.FitGeometryOptions.prototype.nearest;
olx.view.FitOptions.prototype.nearest;
/**
@@ -6278,7 +6440,7 @@ olx.view.FitGeometryOptions.prototype.nearest;
* @type {number|undefined}
* @api
*/
olx.view.FitGeometryOptions.prototype.minResolution;
olx.view.FitOptions.prototype.minResolution;
/**
@@ -6287,7 +6449,7 @@ olx.view.FitGeometryOptions.prototype.minResolution;
* @type {number|undefined}
* @api
*/
olx.view.FitGeometryOptions.prototype.maxZoom;
olx.view.FitOptions.prototype.maxZoom;
/* typedefs for object literals exposed by the library */

View File

@@ -1,6 +1,6 @@
{
"name": "openlayers",
"version": "3.5.0",
"version": "3.7.0",
"description": "Build tools and sources for developing OpenLayers based mapping applications",
"keywords": [
"map",
@@ -19,7 +19,7 @@
"type": "git",
"url": "git://github.com/openlayers/ol3.git"
},
"license": "BSD",
"license": "BSD-2-Clause",
"bugs": {
"url": "https://github.com/openlayers/ol3/issues"
},

View File

@@ -78,8 +78,8 @@ ol.Attribution.prototype.intersectsAnyTileRange =
if (testTileRange.intersects(tileRange)) {
return true;
}
var extentTileRange = tileGrid.getTileRange(
parseInt(zKey, 10), projection);
var extentTileRange = tileGrid.getTileRangeForExtentAndZ(
projection.getExtent(), parseInt(zKey, 10));
var width = extentTileRange.getWidth();
if (tileRange.minX < extentTileRange.minX ||
tileRange.maxX > extentTileRange.maxX) {

View File

@@ -79,7 +79,7 @@ ol.CollectionProperty = {
* @constructor
* @extends {ol.Object}
* @fires ol.CollectionEvent
* @param {Array.<T>=} opt_array Array.
* @param {!Array.<T>=} opt_array Array.
* @template T
* @api stable
*/
@@ -89,7 +89,7 @@ ol.Collection = function(opt_array) {
/**
* @private
* @type {Array.<T>}
* @type {!Array.<T>}
*/
this.array_ = goog.isDef(opt_array) ? opt_array : [];
@@ -113,7 +113,7 @@ ol.Collection.prototype.clear = function() {
/**
* Add elements to the collection. This pushes each item in the provided array
* to the end of the collection.
* @param {Array.<T>} arr Array.
* @param {!Array.<T>} arr Array.
* @return {ol.Collection.<T>} This collection.
* @api stable
*/
@@ -145,7 +145,7 @@ ol.Collection.prototype.forEach = function(f, opt_this) {
* is mutated, no events will be dispatched by the collection, and the
* collection's "length" property won't be in sync with the actual length
* of the array.
* @return {Array.<T>} Array.
* @return {!Array.<T>} Array.
* @api stable
*/
ol.Collection.prototype.getArray = function() {

View File

@@ -64,12 +64,12 @@ ol.color.blend = function(dst, src, opt_color) {
// FIXME do we need to scale by 255?
var out = goog.isDef(opt_color) ? opt_color : [];
var dstA = dst[3];
var srcA = dst[3];
var srcA = src[3];
if (dstA == 1) {
out[0] = (src[0] * srcA + dst[0] * (1 - srcA) + 0.5) | 0;
out[1] = (src[1] * srcA + dst[1] * (1 - srcA) + 0.5) | 0;
out[2] = (src[2] * srcA + dst[2] * (1 - srcA) + 0.5) | 0;
out[4] = 1;
out[3] = 1;
} else if (srcA === 0) {
out[0] = dst[0];
out[1] = dst[1];

View File

@@ -3,6 +3,7 @@ goog.provide('ol.control.Control');
goog.require('goog.array');
goog.require('goog.dom');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('ol.MapEventType');
goog.require('ol.Object');
@@ -78,6 +79,24 @@ ol.control.Control = function(options) {
goog.inherits(ol.control.Control, ol.Object);
/**
* Bind a listener that blurs the passed element on any mouseout- or
* focusout-event.
*
* @param {!Element} button The button which shall blur on mouseout- or
* focusout-event.
* @protected
*/
ol.control.Control.bindMouseOutFocusOutBlur = function(button) {
goog.events.listen(button, [
goog.events.EventType.MOUSEOUT,
goog.events.EventType.FOCUSOUT
], /** @this {Element} */ function() {
this.blur();
}, false);
};
/**
* @inheritDoc
*/

View File

@@ -67,12 +67,7 @@ ol.control.FullScreen = function(opt_options) {
goog.events.listen(button, goog.events.EventType.CLICK,
this.handleClick_, false, this);
goog.events.listen(button, [
goog.events.EventType.MOUSEOUT,
goog.events.EventType.FOCUSOUT
], function() {
this.blur();
}, false);
ol.control.Control.bindMouseOutFocusOutBlur(button);
goog.events.listen(goog.global.document,
goog.dom.fullscreen.EventType.CHANGE,

View File

@@ -90,12 +90,7 @@ ol.control.OverviewMap = function(opt_options) {
goog.events.listen(button, goog.events.EventType.CLICK,
this.handleClick_, false, this);
goog.events.listen(button, [
goog.events.EventType.MOUSEOUT,
goog.events.EventType.FOCUSOUT
], function() {
this.blur();
}, false);
ol.control.Control.bindMouseOutFocusOutBlur(button);
var ovmapDiv = goog.dom.createDom(goog.dom.TagName.DIV, 'ol-overviewmap-map');
@@ -343,7 +338,7 @@ ol.control.OverviewMap.prototype.resetExtent_ = function() {
ol.OVERVIEWMAP_MAX_RATIO / ol.OVERVIEWMAP_MIN_RATIO) / Math.LN2;
var ratio = 1 / (Math.pow(2, steps / 2) * ol.OVERVIEWMAP_MIN_RATIO);
ol.extent.scaleFromCenter(extent, ratio);
ovview.fitExtent(extent, ovmapSize);
ovview.fit(extent, ovmapSize);
};

View File

@@ -60,12 +60,7 @@ ol.control.Rotate = function(opt_options) {
goog.events.listen(button, goog.events.EventType.CLICK,
ol.control.Rotate.prototype.handleClick_, false, this);
goog.events.listen(button, [
goog.events.EventType.MOUSEOUT,
goog.events.EventType.FOCUSOUT
], function() {
this.blur();
}, false);
ol.control.Control.bindMouseOutFocusOutBlur(button);
var cssClasses = className + ' ' + ol.css.CLASS_UNSELECTABLE + ' ' +
ol.css.CLASS_CONTROL;

View File

@@ -50,12 +50,7 @@ ol.control.Zoom = function(opt_options) {
goog.events.EventType.CLICK, goog.partial(
ol.control.Zoom.prototype.handleClick_, delta), false, this);
goog.events.listen(inElement, [
goog.events.EventType.MOUSEOUT,
goog.events.EventType.FOCUSOUT
], function() {
this.blur();
}, false);
ol.control.Control.bindMouseOutFocusOutBlur(inElement);
var outElement = goog.dom.createDom(goog.dom.TagName.BUTTON, {
'class': className + '-out',

View File

@@ -43,12 +43,7 @@ ol.control.ZoomToExtent = function(opt_options) {
goog.events.listen(button, goog.events.EventType.CLICK,
this.handleClick_, false, this);
goog.events.listen(button, [
goog.events.EventType.MOUSEOUT,
goog.events.EventType.FOCUSOUT
], function() {
this.blur();
}, false);
ol.control.Control.bindMouseOutFocusOutBlur(button);
var cssClasses = className + ' ' + ol.css.CLASS_UNSELECTABLE + ' ' +
ol.css.CLASS_CONTROL;
@@ -82,5 +77,5 @@ ol.control.ZoomToExtent.prototype.handleZoomToExtent_ = function() {
view.getProjection().getExtent() : this.extent_;
var size = map.getSize();
goog.asserts.assert(goog.isDef(size), 'size should be defined');
view.fitExtent(extent, size);
view.fit(extent, size);
};

View File

@@ -3,6 +3,7 @@ goog.provide('ol.CoordinateFormatType');
goog.provide('ol.coordinate');
goog.require('goog.math');
goog.require('goog.string');
/**
@@ -129,8 +130,8 @@ ol.coordinate.degreesToStringHDMS_ = function(degrees, hemispheres) {
var normalizedDegrees = goog.math.modulo(degrees + 180, 360) - 180;
var x = Math.abs(Math.round(3600 * normalizedDegrees));
return Math.floor(x / 3600) + '\u00b0 ' +
Math.floor((x / 60) % 60) + '\u2032 ' +
Math.floor(x % 60) + '\u2033 ' +
goog.string.padNumber(Math.floor((x / 60) % 60), 2) + '\u2032 ' +
goog.string.padNumber(Math.floor(x % 60), 2) + '\u2033 ' +
hemispheres.charAt(normalizedDegrees < 0 ? 1 : 0);
};

View File

@@ -164,12 +164,15 @@ ol.extent.containsCoordinate = function(extent, coordinate) {
/**
* Check if one extent is contained by or on the edge of another.
* Check if one extent contains another.
*
* An extent is deemed contained if it lies completely within the other extent,
* including if they share one or more edges.
*
* @param {ol.Extent} extent1 Extent 1.
* @param {ol.Extent} extent2 Extent 2.
* @return {boolean} The first extent is contained by or on the edge of the
* second.
* @return {boolean} The second extent is contained by or on the edge of the
* first.
* @api stable
*/
ol.extent.containsExtent = function(extent1, extent2) {

View File

@@ -18,7 +18,7 @@ goog.require('ol.style.Style');
* GeoJSON.
*
* Features can be styled individually with `setStyle`; otherwise they use the
* style of their vector layer or feature overlay.
* style of their vector layer.
*
* Note that attribute properties are set as {@link ol.Object} properties on
* the feature object, so they are observable, and have get/set accessors.

View File

@@ -1,326 +0,0 @@
goog.provide('ol.FeatureOverlay');
goog.require('goog.array');
goog.require('goog.asserts');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('goog.object');
goog.require('ol.Collection');
goog.require('ol.CollectionEventType');
goog.require('ol.Feature');
goog.require('ol.render.EventType');
goog.require('ol.renderer.vector');
goog.require('ol.style.Style');
/**
* @classdesc
* A mechanism for changing the style of a small number of features on a
* temporary basis, for example highlighting. This is necessary with the Canvas
* renderer, where, unlike in SVG, features cannot be individually referenced.
* See examples/vector-layers for an example: create a FeatureOverlay with a
* different style, copy the feature(s) you want rendered in this different
* style into it, and then remove them again when you're finished.
*
* @constructor
* @param {olx.FeatureOverlayOptions=} opt_options Options.
* @api
*/
ol.FeatureOverlay = function(opt_options) {
var options = goog.isDef(opt_options) ? opt_options : {};
/**
* @private
* @type {ol.Collection.<ol.Feature>}
*/
this.features_ = null;
/**
* @private
* @type {Array.<goog.events.Key>}
*/
this.featuresListenerKeys_ = null;
/**
* @private
* @type {Object.<string, goog.events.Key>}
*/
this.featureChangeListenerKeys_ = null;
/**
* @private
* @type {ol.Map}
*/
this.map_ = null;
/**
* @private
* @type {goog.events.Key}
*/
this.postComposeListenerKey_ = null;
/**
* @private
* @type {ol.style.Style|Array.<ol.style.Style>|ol.style.StyleFunction}
*/
this.style_ = null;
/**
* @private
* @type {ol.style.StyleFunction|undefined}
*/
this.styleFunction_ = undefined;
this.setStyle(goog.isDef(options.style) ?
options.style : ol.style.defaultStyleFunction);
if (goog.isDef(options.features)) {
if (goog.isArray(options.features)) {
this.setFeatures(new ol.Collection(options.features.slice()));
} else {
goog.asserts.assertInstanceof(options.features, ol.Collection,
'options.features should be an ol.Collection');
this.setFeatures(options.features);
}
} else {
this.setFeatures(new ol.Collection());
}
if (goog.isDef(options.map)) {
this.setMap(options.map);
}
};
/**
* Add a feature to the overlay.
* @param {ol.Feature} feature Feature.
* @api
*/
ol.FeatureOverlay.prototype.addFeature = function(feature) {
this.features_.push(feature);
};
/**
* Get the features on the overlay.
* @return {ol.Collection.<ol.Feature>} Features collection.
* @api
*/
ol.FeatureOverlay.prototype.getFeatures = function() {
return this.features_;
};
/**
* Get the map associated with the overlay.
* @return {?ol.Map} The map with which this feature overlay is associated.
* @api
*/
ol.FeatureOverlay.prototype.getMap = function() {
return this.map_;
};
/**
* @private
*/
ol.FeatureOverlay.prototype.handleFeatureChange_ = function() {
this.render_();
};
/**
* @private
* @param {ol.CollectionEvent} collectionEvent Collection event.
*/
ol.FeatureOverlay.prototype.handleFeaturesAdd_ = function(collectionEvent) {
goog.asserts.assert(!goog.isNull(this.featureChangeListenerKeys_),
'this.featureChangeListenerKeys_ should not be null');
var feature = /** @type {ol.Feature} */ (collectionEvent.element);
this.featureChangeListenerKeys_[goog.getUid(feature).toString()] =
goog.events.listen(feature, goog.events.EventType.CHANGE,
this.handleFeatureChange_, false, this);
this.render_();
};
/**
* @private
* @param {ol.CollectionEvent} collectionEvent Collection event.
*/
ol.FeatureOverlay.prototype.handleFeaturesRemove_ = function(collectionEvent) {
goog.asserts.assert(!goog.isNull(this.featureChangeListenerKeys_),
'this.featureChangeListenerKeys_ should not be null');
var feature = /** @type {ol.Feature} */ (collectionEvent.element);
var key = goog.getUid(feature).toString();
goog.events.unlistenByKey(this.featureChangeListenerKeys_[key]);
delete this.featureChangeListenerKeys_[key];
this.render_();
};
/**
* Handle changes in image style state.
* @param {goog.events.Event} event Image style change event.
* @private
*/
ol.FeatureOverlay.prototype.handleImageChange_ = function(event) {
this.render_();
};
/**
* @param {ol.render.Event} event Event.
* @private
*/
ol.FeatureOverlay.prototype.handleMapPostCompose_ = function(event) {
if (goog.isNull(this.features_)) {
return;
}
var styleFunction = this.styleFunction_;
if (!goog.isDef(styleFunction)) {
styleFunction = ol.style.defaultStyleFunction;
}
var replayGroup = /** @type {ol.render.IReplayGroup} */
(event.replayGroup);
goog.asserts.assert(goog.isDef(replayGroup),
'replayGroup should be defined');
var frameState = event.frameState;
var pixelRatio = frameState.pixelRatio;
var resolution = frameState.viewState.resolution;
var squaredTolerance = ol.renderer.vector.getSquaredTolerance(resolution,
pixelRatio);
var i, ii, styles, featureStyleFunction;
this.features_.forEach(function(feature) {
featureStyleFunction = feature.getStyleFunction();
styles = goog.isDef(featureStyleFunction) ?
featureStyleFunction.call(feature, resolution) :
styleFunction(feature, resolution);
if (!goog.isDefAndNotNull(styles)) {
return;
}
ii = styles.length;
for (i = 0; i < ii; ++i) {
ol.renderer.vector.renderFeature(replayGroup, feature, styles[i],
squaredTolerance, this.handleImageChange_, this);
}
}, this);
};
/**
* Remove a feature from the overlay.
* @param {ol.Feature} feature The feature to be removed.
* @api
*/
ol.FeatureOverlay.prototype.removeFeature = function(feature) {
this.features_.remove(feature);
};
/**
* @private
*/
ol.FeatureOverlay.prototype.render_ = function() {
if (!goog.isNull(this.map_)) {
this.map_.render();
}
};
/**
* Set the features for the overlay.
* @param {ol.Collection.<ol.Feature>} features Features collection.
* @api
*/
ol.FeatureOverlay.prototype.setFeatures = function(features) {
if (!goog.isNull(this.featuresListenerKeys_)) {
goog.array.forEach(this.featuresListenerKeys_, goog.events.unlistenByKey);
this.featuresListenerKeys_ = null;
}
if (!goog.isNull(this.featureChangeListenerKeys_)) {
goog.array.forEach(
goog.object.getValues(this.featureChangeListenerKeys_),
goog.events.unlistenByKey);
this.featureChangeListenerKeys_ = null;
}
this.features_ = features;
if (!goog.isNull(features)) {
this.featuresListenerKeys_ = [
goog.events.listen(features, ol.CollectionEventType.ADD,
this.handleFeaturesAdd_, false, this),
goog.events.listen(features, ol.CollectionEventType.REMOVE,
this.handleFeaturesRemove_, false, this)
];
this.featureChangeListenerKeys_ = {};
features.forEach(function(feature) {
this.featureChangeListenerKeys_[goog.getUid(feature).toString()] =
goog.events.listen(feature, goog.events.EventType.CHANGE,
this.handleFeatureChange_, false, this);
}, this);
}
this.render_();
};
/**
* Set the map for the overlay.
* @param {ol.Map} map Map.
* @api
*/
ol.FeatureOverlay.prototype.setMap = function(map) {
if (!goog.isNull(this.postComposeListenerKey_)) {
goog.events.unlistenByKey(this.postComposeListenerKey_);
this.postComposeListenerKey_ = null;
}
this.render_();
this.map_ = map;
if (!goog.isNull(map)) {
this.postComposeListenerKey_ = goog.events.listen(
map, ol.render.EventType.POSTCOMPOSE, this.handleMapPostCompose_, false,
this);
map.render();
}
};
/**
* Set the style for features. This can be a single style object, an array
* of styles, or a function that takes a feature and resolution and returns
* an array of styles.
* @param {ol.style.Style|Array.<ol.style.Style>|ol.style.StyleFunction} style
* Overlay style.
* @api
*/
ol.FeatureOverlay.prototype.setStyle = function(style) {
this.style_ = style;
this.styleFunction_ = ol.style.createStyleFunction(style);
this.render_();
};
/**
* Get the style for features. This returns whatever was passed to the `style`
* option at construction or to the `setStyle` method.
* @return {ol.style.Style|Array.<ol.style.Style>|ol.style.StyleFunction}
* Overlay style.
* @api
*/
ol.FeatureOverlay.prototype.getStyle = function() {
return this.style_;
};
/**
* Get the style function.
* @return {ol.style.StyleFunction|undefined} Style function.
* @api
*/
ol.FeatureOverlay.prototype.getStyleFunction = function() {
return this.styleFunction_;
};

View File

@@ -198,8 +198,8 @@ ol.format.GeoJSON.writeGeometry_ = function(geometry, opt_options) {
*/
ol.format.GeoJSON.writeEmptyGeometryCollectionGeometry_ = function(geometry) {
return /** @type {GeoJSONGeometryCollection} */ ({
'type': 'GeometryCollection',
'geometries': []
type: 'GeometryCollection',
geometries: []
});
};
@@ -219,8 +219,8 @@ ol.format.GeoJSON.writeGeometryCollectionGeometry_ = function(
return ol.format.GeoJSON.writeGeometry_(geometry, opt_options);
});
return /** @type {GeoJSONGeometryCollection} */ ({
'type': 'GeometryCollection',
'geometries': geometries
type: 'GeometryCollection',
geometries: geometries
});
};
@@ -235,8 +235,8 @@ ol.format.GeoJSON.writeLineStringGeometry_ = function(geometry, opt_options) {
goog.asserts.assertInstanceof(geometry, ol.geom.LineString,
'geometry should be an ol.geom.LineString');
return /** @type {GeoJSONGeometry} */ ({
'type': 'LineString',
'coordinates': geometry.getCoordinates()
type: 'LineString',
coordinates: geometry.getCoordinates()
});
};
@@ -252,8 +252,8 @@ ol.format.GeoJSON.writeMultiLineStringGeometry_ =
goog.asserts.assertInstanceof(geometry, ol.geom.MultiLineString,
'geometry should be an ol.geom.MultiLineString');
return /** @type {GeoJSONGeometry} */ ({
'type': 'MultiLineString',
'coordinates': geometry.getCoordinates()
type: 'MultiLineString',
coordinates: geometry.getCoordinates()
});
};
@@ -268,8 +268,8 @@ ol.format.GeoJSON.writeMultiPointGeometry_ = function(geometry, opt_options) {
goog.asserts.assertInstanceof(geometry, ol.geom.MultiPoint,
'geometry should be an ol.geom.MultiPoint');
return /** @type {GeoJSONGeometry} */ ({
'type': 'MultiPoint',
'coordinates': geometry.getCoordinates()
type: 'MultiPoint',
coordinates: geometry.getCoordinates()
});
};
@@ -288,8 +288,8 @@ ol.format.GeoJSON.writeMultiPolygonGeometry_ = function(geometry, opt_options) {
right = opt_options.rightHanded;
}
return /** @type {GeoJSONGeometry} */ ({
'type': 'MultiPolygon',
'coordinates': geometry.getCoordinates(right)
type: 'MultiPolygon',
coordinates: geometry.getCoordinates(right)
});
};
@@ -304,8 +304,8 @@ ol.format.GeoJSON.writePointGeometry_ = function(geometry, opt_options) {
goog.asserts.assertInstanceof(geometry, ol.geom.Point,
'geometry should be an ol.geom.Point');
return /** @type {GeoJSONGeometry} */ ({
'type': 'Point',
'coordinates': geometry.getCoordinates()
type: 'Point',
coordinates: geometry.getCoordinates()
});
};
@@ -324,8 +324,8 @@ ol.format.GeoJSON.writePolygonGeometry_ = function(geometry, opt_options) {
right = opt_options.rightHanded;
}
return /** @type {GeoJSONGeometry} */ ({
'type': 'Polygon',
'coordinates': geometry.getCoordinates(right)
type: 'Polygon',
coordinates: geometry.getCoordinates(right)
});
};
@@ -541,6 +541,8 @@ ol.format.GeoJSON.prototype.writeFeatureObject = function(
if (goog.isDefAndNotNull(geometry)) {
object['geometry'] =
ol.format.GeoJSON.writeGeometry_(geometry, opt_options);
} else {
object['geometry'] = null;
}
var properties = feature.getProperties();
goog.object.remove(properties, feature.getGeometryName());
@@ -582,8 +584,8 @@ ol.format.GeoJSON.prototype.writeFeaturesObject =
objects.push(this.writeFeatureObject(features[i], opt_options));
}
return /** @type {GeoJSONFeatureCollection} */ ({
'type': 'FeatureCollection',
'features': objects
type: 'FeatureCollection',
features: objects
});
};

View File

@@ -203,10 +203,11 @@ ol.format.GMLBase.prototype.readFeatureElement = function(node, objectStack) {
n = n.nextElementSibling) {
var localName = ol.xml.getLocalName(n);
// Assume attribute elements have one child node and that the child
// is a text node. Otherwise assume it is a geometry node.
// is a text or CDATA node (to be treated as text).
// Otherwise assume it is a geometry node.
if (n.childNodes.length === 0 ||
(n.childNodes.length === 1 &&
n.firstChild.nodeType === 3)) {
(n.firstChild.nodeType === 3 || n.firstChild.nodeType === 4))) {
var value = ol.xml.getAllTextContent(n, false);
if (goog.string.isEmpty(value)) {
value = undefined;

View File

@@ -491,12 +491,23 @@ ol.format.WKT.Lexer.prototype.nextToken = function() {
ol.format.WKT.Lexer.prototype.readNumber_ = function() {
var c, index = this.index_;
var decimal = false;
var scientificNotation = false;
do {
if (c == '.') {
decimal = true;
} else if (c == 'e' || c == 'E') {
scientificNotation = true;
}
c = this.nextChar_();
} while (this.isNumeric_(c, decimal));
} while (
this.isNumeric_(c, decimal) ||
// if we haven't detected a scientific number before, 'e' or 'E'
// hint that we should continue to read
!scientificNotation && (c == 'e' || c == 'E') ||
// once we know that we have a scientific number, both '-' and '+'
// are allowed
scientificNotation && (c == '-' || c == '+')
);
return parseFloat(this.wkt.substring(index, this.index_--));
};

View File

@@ -137,6 +137,29 @@ ol.geom.Circle.prototype.getType = function() {
};
/**
* @inheritDoc
* @api stable
*/
ol.geom.Circle.prototype.intersectsExtent = function(extent) {
var circleExtent = this.getExtent();
if (ol.extent.intersects(extent, circleExtent)) {
var center = this.getCenter();
if (extent[0] <= center[0] && extent[2] >= center[0]) {
return true;
}
if (extent[1] <= center[1] && extent[3] >= center[1]) {
return true;
}
return ol.extent.forEachCorner(extent, this.containsCoordinate, this);
}
return false;
};
/**
* Set the center of the circle as {@link ol.Coordinate coordinate}.
* @param {ol.Coordinate} center Center.

View File

@@ -229,6 +229,7 @@ ol.geom.Geometry.prototype.translate = goog.abstractMethod;
* string identifier or a {@link ol.proj.Projection} object.
* @return {ol.geom.Geometry} This geometry. Note that original geometry is
* modified in place.
* @api stable
*/
ol.geom.Geometry.prototype.transform = function(source, destination) {
this.applyTransform(ol.proj.getTransform(source, destination));

View File

@@ -2,6 +2,7 @@ goog.provide('ol.geom.Polygon');
goog.require('goog.array');
goog.require('goog.asserts');
goog.require('goog.math');
goog.require('ol.extent');
goog.require('ol.geom.GeometryLayout');
goog.require('ol.geom.GeometryType');
@@ -422,3 +423,53 @@ ol.geom.Polygon.fromExtent = function(extent) {
ol.geom.GeometryLayout.XY, flatCoordinates, [flatCoordinates.length]);
return polygon;
};
/**
* Create a regular polygon from a circle.
* @param {ol.geom.Circle} circle Circle geometry.
* @param {number=} opt_sides Number of sides of the polygon. Default is 32.
* @param {number=} opt_angle Start angle for the first vertex of the polygon in
* radians. Default is 0.
* @return {ol.geom.Polygon} Polygon geometry.
* @api
*/
ol.geom.Polygon.fromCircle = function(circle, opt_sides, opt_angle) {
var sides = goog.isDef(opt_sides) ? opt_sides : 32;
var stride = circle.getStride();
var layout = circle.getLayout();
var polygon = new ol.geom.Polygon(null, layout);
var flatCoordinates = goog.array.repeat(0, stride * (sides + 1));
var ends = [flatCoordinates.length];
polygon.setFlatCoordinates(layout, flatCoordinates, ends);
ol.geom.Polygon.makeRegular(
polygon, circle.getCenter(), circle.getRadius(), opt_angle);
return polygon;
};
/**
* Modify the coordinates of a polygon to make it a regular polygon.
* @param {ol.geom.Polygon} polygon Polygon geometry.
* @param {ol.Coordinate} center Center of the regular polygon.
* @param {number} radius Radius of the regular polygon.
* @param {number=} opt_angle Start angle for the first vertex of the polygon in
* radians. Default is 0.
*/
ol.geom.Polygon.makeRegular = function(polygon, center, radius, opt_angle) {
var flatCoordinates = polygon.getFlatCoordinates();
var layout = polygon.getLayout();
var stride = polygon.getStride();
var ends = polygon.getEnds();
goog.asserts.assert(ends.length === 1, 'only 1 ring is supported');
var sides = flatCoordinates.length / stride - 1;
var startAngle = goog.isDef(opt_angle) ? opt_angle : 0;
var angle, coord, offset;
for (var i = 0; i <= sides; ++i) {
offset = i * stride;
angle = startAngle + (goog.math.modulo(i, sides) * 2 * Math.PI / sides);
flatCoordinates[offset] = center[0] + (radius * Math.cos(angle));
flatCoordinates[offset + 1] = center[1] + (radius * Math.sin(angle));
}
polygon.setFlatCoordinates(layout, flatCoordinates, ends);
};

View File

@@ -98,6 +98,12 @@ ol.geom.SimpleGeometry.prototype.computeExtent = function(extent) {
};
/**
* @return {Array} Coordinates.
*/
ol.geom.SimpleGeometry.prototype.getCoordinates = goog.abstractMethod;
/**
* Return the first coordinate of the geometry.
* @return {ol.Coordinate} First coordinate.
@@ -209,6 +215,13 @@ ol.geom.SimpleGeometry.prototype.setFlatCoordinatesInternal =
};
/**
* @param {Array} coordinates Coordinates.
* @param {ol.geom.GeometryLayout=} opt_layout Layout.
*/
ol.geom.SimpleGeometry.prototype.setCoordinates = goog.abstractMethod;
/**
* @param {ol.geom.GeometryLayout|undefined} layout Layout.
* @param {Array} coordinates Coordinates.

View File

@@ -1,6 +1,8 @@
goog.provide('ol.DrawEvent');
goog.provide('ol.DrawEventType');
goog.provide('ol.interaction.Draw');
goog.provide('ol.interaction.DrawEvent');
goog.provide('ol.interaction.DrawEventType');
goog.provide('ol.interaction.DrawGeometryFunctionType');
goog.provide('ol.interaction.DrawMode');
goog.require('goog.asserts');
goog.require('goog.events');
@@ -8,10 +10,10 @@ goog.require('goog.events.Event');
goog.require('ol.Collection');
goog.require('ol.Coordinate');
goog.require('ol.Feature');
goog.require('ol.FeatureOverlay');
goog.require('ol.MapBrowserEvent');
goog.require('ol.MapBrowserEvent.EventType');
goog.require('ol.Object');
goog.require('ol.coordinate');
goog.require('ol.events.condition');
goog.require('ol.geom.Circle');
goog.require('ol.geom.GeometryType');
@@ -21,8 +23,10 @@ goog.require('ol.geom.MultiPoint');
goog.require('ol.geom.MultiPolygon');
goog.require('ol.geom.Point');
goog.require('ol.geom.Polygon');
goog.require('ol.geom.SimpleGeometry');
goog.require('ol.interaction.InteractionProperty');
goog.require('ol.interaction.Pointer');
goog.require('ol.layer.Vector');
goog.require('ol.source.Vector');
goog.require('ol.style.Style');
@@ -30,16 +34,16 @@ goog.require('ol.style.Style');
/**
* @enum {string}
*/
ol.DrawEventType = {
ol.interaction.DrawEventType = {
/**
* Triggered upon feature draw start
* @event ol.DrawEvent#drawstart
* @event ol.interaction.DrawEvent#drawstart
* @api stable
*/
DRAWSTART: 'drawstart',
/**
* Triggered upon feature draw end
* @event ol.DrawEvent#drawend
* @event ol.interaction.DrawEvent#drawend
* @api stable
*/
DRAWEND: 'drawend'
@@ -55,10 +59,10 @@ ol.DrawEventType = {
* @constructor
* @extends {goog.events.Event}
* @implements {oli.DrawEvent}
* @param {ol.DrawEventType} type Type.
* @param {ol.interaction.DrawEventType} type Type.
* @param {ol.Feature} feature The feature drawn.
*/
ol.DrawEvent = function(type, feature) {
ol.interaction.DrawEvent = function(type, feature) {
goog.base(this, type);
@@ -70,17 +74,17 @@ ol.DrawEvent = function(type, feature) {
this.feature = feature;
};
goog.inherits(ol.DrawEvent, goog.events.Event);
goog.inherits(ol.interaction.DrawEvent, goog.events.Event);
/**
* @classdesc
* Interaction that allows drawing geometries.
* Interaction for drawing feature geometries.
*
* @constructor
* @extends {ol.interaction.Pointer}
* @fires ol.DrawEvent
* @fires ol.interaction.DrawEvent
* @param {olx.interaction.DrawOptions} options Options.
* @api stable
*/
@@ -126,15 +130,6 @@ ol.interaction.Draw = function(options) {
this.snapTolerance_ = goog.isDef(options.snapTolerance) ?
options.snapTolerance : 12;
/**
* The number of points that must be drawn before a polygon ring can be
* finished. The default is 3.
* @type {number}
* @private
*/
this.minPointsPerRing_ = goog.isDef(options.minPointsPerRing) ?
options.minPointsPerRing : 3;
/**
* Geometry type.
* @type {ol.geom.GeometryType}
@@ -149,6 +144,77 @@ ol.interaction.Draw = function(options) {
*/
this.mode_ = ol.interaction.Draw.getMode_(this.type_);
/**
* The number of points that must be drawn before a polygon ring or line
* string can be finished. The default is 3 for polygon rings and 2 for
* line strings.
* @type {number}
* @private
*/
this.minPoints_ = goog.isDef(options.minPoints) ?
options.minPoints :
(this.mode_ === ol.interaction.DrawMode.POLYGON ? 3 : 2);
/**
* The number of points that can be drawn before a polygon ring or line string
* is finished. The default is no restriction.
* @type {number}
* @private
*/
this.maxPoints_ = goog.isDef(options.maxPoints) ?
options.maxPoints : Infinity;
var geometryFunction = options.geometryFunction;
if (!goog.isDef(geometryFunction)) {
if (this.type_ === ol.geom.GeometryType.CIRCLE) {
/**
* @param {ol.Coordinate|Array.<ol.Coordinate>|Array.<Array.<ol.Coordinate>>} coordinates
* @param {ol.geom.SimpleGeometry=} opt_geometry
* @return {ol.geom.SimpleGeometry}
*/
geometryFunction = function(coordinates, opt_geometry) {
var circle = goog.isDef(opt_geometry) ? opt_geometry :
new ol.geom.Circle([NaN, NaN]);
goog.asserts.assertInstanceof(circle, ol.geom.Circle,
'geometry must be an ol.geom.Circle');
var squaredLength = ol.coordinate.squaredDistance(
coordinates[0], coordinates[1]);
circle.setCenterAndRadius(coordinates[0], Math.sqrt(squaredLength));
return circle;
};
} else {
var Constructor;
var mode = this.mode_;
if (mode === ol.interaction.DrawMode.POINT) {
Constructor = ol.geom.Point;
} else if (mode === ol.interaction.DrawMode.LINE_STRING) {
Constructor = ol.geom.LineString;
} else if (mode === ol.interaction.DrawMode.POLYGON) {
Constructor = ol.geom.Polygon;
}
/**
* @param {ol.Coordinate|Array.<ol.Coordinate>|Array.<Array.<ol.Coordinate>>} coordinates
* @param {ol.geom.SimpleGeometry=} opt_geometry
* @return {ol.geom.SimpleGeometry}
*/
geometryFunction = function(coordinates, opt_geometry) {
var geometry = opt_geometry;
if (goog.isDef(geometry)) {
geometry.setCoordinates(coordinates);
} else {
geometry = new Constructor(coordinates);
}
return geometry;
};
}
}
/**
* @type {ol.interaction.DrawGeometryFunctionType}
* @private
*/
this.geometryFunction_ = geometryFunction;
/**
* Finish coordinate for the feature (first point for polygons, last point for
* linestrings).
@@ -171,6 +237,13 @@ ol.interaction.Draw = function(options) {
*/
this.sketchPoint_ = null;
/**
* Sketch coordinates. Used when drawing a line or polygon.
* @type {ol.Coordinate|Array.<ol.Coordinate>|Array.<Array.<ol.Coordinate>>}
* @private
*/
this.sketchCoords_ = null;
/**
* Sketch line. Used when drawing polygon.
* @type {ol.Feature}
@@ -179,11 +252,11 @@ ol.interaction.Draw = function(options) {
this.sketchLine_ = null;
/**
* Sketch polygon. Used when drawing polygon.
* @type {Array.<Array.<ol.Coordinate>>}
* Sketch line coordinates. Used when drawing a polygon or circle.
* @type {Array.<ol.Coordinate>}
* @private
*/
this.sketchPolygonCoords_ = null;
this.sketchLineCoords_ = null;
/**
* Squared tolerance for handling up events. If the squared distance
@@ -192,14 +265,19 @@ ol.interaction.Draw = function(options) {
* @type {number}
* @private
*/
this.squaredClickTolerance_ = 4;
this.squaredClickTolerance_ = goog.isDef(options.clickTolerance) ?
options.clickTolerance * options.clickTolerance : 36;
/**
* Draw overlay where our sketch features are drawn.
* @type {ol.FeatureOverlay}
* @type {ol.layer.Vector}
* @private
*/
this.overlay_ = new ol.FeatureOverlay({
this.overlay_ = new ol.layer.Vector({
source: new ol.source.Vector({
useSpatialIndex: false,
wrapX: goog.isDef(options.wrapX) ? options.wrapX : false
}),
style: goog.isDef(options.style) ?
options.style : ol.interaction.Draw.getDefaultStyleFunction()
});
@@ -362,20 +440,15 @@ ol.interaction.Draw.prototype.handlePointerMove_ = function(event) {
ol.interaction.Draw.prototype.atFinish_ = function(event) {
var at = false;
if (!goog.isNull(this.sketchFeature_)) {
var geometry = this.sketchFeature_.getGeometry();
var potentiallyDone = false;
var potentiallyFinishCoordinates = [this.finishCoordinate_];
if (this.mode_ === ol.interaction.DrawMode.LINE_STRING) {
goog.asserts.assertInstanceof(geometry, ol.geom.LineString,
'geometry should be an ol.geom.LineString');
potentiallyDone = geometry.getCoordinates().length > 2;
potentiallyDone = this.sketchCoords_.length > this.minPoints_;
} else if (this.mode_ === ol.interaction.DrawMode.POLYGON) {
goog.asserts.assertInstanceof(geometry, ol.geom.Polygon,
'geometry should be an ol.geom.Polygon');
potentiallyDone = geometry.getCoordinates()[0].length >
this.minPointsPerRing_;
potentiallyFinishCoordinates = [this.sketchPolygonCoords_[0][0],
this.sketchPolygonCoords_[0][this.sketchPolygonCoords_[0].length - 2]];
potentiallyDone = this.sketchCoords_[0].length >
this.minPoints_;
potentiallyFinishCoordinates = [this.sketchCoords_[0][0],
this.sketchCoords_[0][this.sketchCoords_[0].length - 2]];
}
if (potentiallyDone) {
var map = event.map;
@@ -425,23 +498,22 @@ ol.interaction.Draw.prototype.createOrUpdateSketchPoint_ = function(event) {
ol.interaction.Draw.prototype.startDrawing_ = function(event) {
var start = event.coordinate;
this.finishCoordinate_ = start;
var geometry;
if (this.mode_ === ol.interaction.DrawMode.POINT) {
geometry = new ol.geom.Point(start.slice());
this.sketchCoords_ = start.slice();
} else if (this.mode_ === ol.interaction.DrawMode.POLYGON) {
this.sketchCoords_ = [[start.slice(), start.slice()]];
this.sketchLineCoords_ = this.sketchCoords_[0];
} else {
if (this.mode_ === ol.interaction.DrawMode.LINE_STRING) {
geometry = new ol.geom.LineString([start.slice(), start.slice()]);
} else if (this.mode_ === ol.interaction.DrawMode.POLYGON) {
this.sketchLine_ = new ol.Feature(new ol.geom.LineString([start.slice(),
start.slice()]));
this.sketchPolygonCoords_ = [[start.slice(), start.slice()]];
geometry = new ol.geom.Polygon(this.sketchPolygonCoords_);
} else if (this.mode_ === ol.interaction.DrawMode.CIRCLE) {
geometry = new ol.geom.Circle(start.slice(), 0);
this.sketchLine_ = new ol.Feature(new ol.geom.LineString([start.slice(),
start.slice()]));
this.sketchCoords_ = [start.slice(), start.slice()];
if (this.mode_ === ol.interaction.DrawMode.CIRCLE) {
this.sketchLineCoords_ = this.sketchCoords_;
}
}
if (!goog.isNull(this.sketchLineCoords_)) {
this.sketchLine_ = new ol.Feature(
new ol.geom.LineString(this.sketchLineCoords_));
}
var geometry = this.geometryFunction_(this.sketchCoords_);
goog.asserts.assert(goog.isDef(geometry), 'geometry should be defined');
this.sketchFeature_ = new ol.Feature();
if (goog.isDef(this.geometryName_)) {
@@ -449,8 +521,8 @@ ol.interaction.Draw.prototype.startDrawing_ = function(event) {
}
this.sketchFeature_.setGeometry(geometry);
this.updateSketchFeatures_();
this.dispatchEvent(new ol.DrawEvent(ol.DrawEventType.DRAWSTART,
this.sketchFeature_));
this.dispatchEvent(new ol.interaction.DrawEvent(
ol.interaction.DrawEventType.DRAWSTART, this.sketchFeature_));
};
@@ -462,60 +534,50 @@ ol.interaction.Draw.prototype.startDrawing_ = function(event) {
ol.interaction.Draw.prototype.modifyDrawing_ = function(event) {
var coordinate = event.coordinate;
var geometry = this.sketchFeature_.getGeometry();
var coordinates, last, sketchLineGeom;
goog.asserts.assertInstanceof(geometry, ol.geom.SimpleGeometry,
'geometry should be ol.geom.SimpleGeometry or subclass');
var coordinates, last;
if (this.mode_ === ol.interaction.DrawMode.POINT) {
goog.asserts.assertInstanceof(geometry, ol.geom.Point,
'geometry should be an ol.geom.Point');
last = geometry.getCoordinates();
last[0] = coordinate[0];
last[1] = coordinate[1];
geometry.setCoordinates(last);
} else {
if (this.mode_ === ol.interaction.DrawMode.LINE_STRING) {
goog.asserts.assertInstanceof(geometry, ol.geom.LineString,
'geometry should be an ol.geom.LineString');
coordinates = geometry.getCoordinates();
} else if (this.mode_ === ol.interaction.DrawMode.POLYGON) {
goog.asserts.assertInstanceof(geometry, ol.geom.Polygon,
'geometry should be an ol.geom.Polygon');
coordinates = this.sketchPolygonCoords_[0];
} else if (this.mode_ === ol.interaction.DrawMode.CIRCLE) {
goog.asserts.assertInstanceof(geometry, ol.geom.Circle,
'geometry should be an ol.geom.Circle');
coordinates = geometry.getCenter();
}
last = this.sketchCoords_;
} else if (this.mode_ === ol.interaction.DrawMode.POLYGON) {
coordinates = this.sketchCoords_[0];
last = coordinates[coordinates.length - 1];
if (this.atFinish_(event)) {
// snap to finish
coordinate = this.finishCoordinate_.slice();
}
} else {
coordinates = this.sketchCoords_;
last = coordinates[coordinates.length - 1];
}
last[0] = coordinate[0];
last[1] = coordinate[1];
goog.asserts.assert(!goog.isNull(this.sketchCoords_),
'sketchCoords_ must not be null');
this.geometryFunction_(this.sketchCoords_, geometry);
if (!goog.isNull(this.sketchPoint_)) {
var sketchPointGeom = this.sketchPoint_.getGeometry();
goog.asserts.assertInstanceof(sketchPointGeom, ol.geom.Point,
'sketchPointGeom should be an ol.geom.Point');
sketchPointGeom.setCoordinates(coordinate);
last = coordinates[coordinates.length - 1];
last[0] = coordinate[0];
last[1] = coordinate[1];
if (this.mode_ === ol.interaction.DrawMode.LINE_STRING) {
goog.asserts.assertInstanceof(geometry, ol.geom.LineString,
'geometry should be an ol.geom.LineString');
geometry.setCoordinates(coordinates);
} else if (this.mode_ === ol.interaction.DrawMode.POLYGON) {
sketchLineGeom = this.sketchLine_.getGeometry();
goog.asserts.assertInstanceof(sketchLineGeom, ol.geom.LineString,
'sketchLineGeom should be an ol.geom.LineString');
sketchLineGeom.setCoordinates(coordinates);
goog.asserts.assertInstanceof(geometry, ol.geom.Polygon,
'geometry should be an ol.geom.Polygon');
geometry.setCoordinates(this.sketchPolygonCoords_);
} else if (this.mode_ === ol.interaction.DrawMode.CIRCLE) {
goog.asserts.assertInstanceof(geometry, ol.geom.Circle,
'geometry should be an ol.geom.Circle');
sketchLineGeom = this.sketchLine_.getGeometry();
goog.asserts.assertInstanceof(sketchLineGeom, ol.geom.LineString,
'sketchLineGeom should be an ol.geom.LineString');
sketchLineGeom.setCoordinates([geometry.getCenter(), coordinate]);
geometry.setRadius(sketchLineGeom.getLength());
}
var sketchLineGeom;
if (geometry instanceof ol.geom.Polygon &&
this.mode_ !== ol.interaction.DrawMode.POLYGON) {
if (goog.isNull(this.sketchLine_)) {
this.sketchLine_ = new ol.Feature(new ol.geom.LineString(null));
}
var ring = geometry.getLinearRing(0);
sketchLineGeom = this.sketchLine_.getGeometry();
goog.asserts.assertInstanceof(sketchLineGeom, ol.geom.LineString,
'sketchLineGeom must be an ol.geom.LineString');
sketchLineGeom.setFlatCoordinates(
ring.getLayout(), ring.getFlatCoordinates());
} else if (!goog.isNull(this.sketchLineCoords_)) {
sketchLineGeom = this.sketchLine_.getGeometry();
goog.asserts.assertInstanceof(sketchLineGeom, ol.geom.LineString,
'sketchLineGeom must be an ol.geom.LineString');
sketchLineGeom.setCoordinates(this.sketchLineCoords_);
}
this.updateSketchFeatures_();
};
@@ -529,57 +591,57 @@ ol.interaction.Draw.prototype.modifyDrawing_ = function(event) {
ol.interaction.Draw.prototype.addToDrawing_ = function(event) {
var coordinate = event.coordinate;
var geometry = this.sketchFeature_.getGeometry();
goog.asserts.assertInstanceof(geometry, ol.geom.SimpleGeometry,
'geometry must be an ol.geom.SimpleGeometry');
var done;
var coordinates;
if (this.mode_ === ol.interaction.DrawMode.LINE_STRING) {
this.finishCoordinate_ = coordinate.slice();
goog.asserts.assertInstanceof(geometry, ol.geom.LineString,
'geometry should be an ol.geom.LineString');
coordinates = geometry.getCoordinates();
coordinates = this.sketchCoords_;
coordinates.push(coordinate.slice());
geometry.setCoordinates(coordinates);
done = coordinates.length > this.maxPoints_;
this.geometryFunction_(coordinates, geometry);
} else if (this.mode_ === ol.interaction.DrawMode.POLYGON) {
this.sketchPolygonCoords_[0].push(coordinate.slice());
goog.asserts.assertInstanceof(geometry, ol.geom.Polygon,
'geometry should be an ol.geom.Polygon');
geometry.setCoordinates(this.sketchPolygonCoords_);
coordinates = this.sketchCoords_[0];
coordinates.push(coordinate.slice());
done = coordinates.length > this.maxPoints_;
if (done) {
this.finishCoordinate_ = coordinates[0];
}
this.geometryFunction_(this.sketchCoords_, geometry);
}
this.updateSketchFeatures_();
if (done) {
this.finishDrawing();
}
};
/**
* Stop drawing and add the sketch feature to the target layer.
* The {@link ol.DrawEventType.DRAWEND} event is dispatched before inserting
* the feature.
* The {@link ol.interaction.DrawEventType.DRAWEND} event is dispatched before
* inserting the feature.
* @api
*/
ol.interaction.Draw.prototype.finishDrawing = function() {
var sketchFeature = this.abortDrawing_();
goog.asserts.assert(!goog.isNull(sketchFeature),
'sketchFeature should not be null');
var coordinates;
var coordinates = this.sketchCoords_;
var geometry = sketchFeature.getGeometry();
if (this.mode_ === ol.interaction.DrawMode.POINT) {
goog.asserts.assertInstanceof(geometry, ol.geom.Point,
'geometry should be an ol.geom.Point');
coordinates = geometry.getCoordinates();
} else if (this.mode_ === ol.interaction.DrawMode.LINE_STRING) {
goog.asserts.assertInstanceof(geometry, ol.geom.LineString,
'geometry should be an ol.geom.LineString');
coordinates = geometry.getCoordinates();
goog.asserts.assertInstanceof(geometry, ol.geom.SimpleGeometry,
'geometry must be an ol.geom.SimpleGeometry');
if (this.mode_ === ol.interaction.DrawMode.LINE_STRING) {
// remove the redundant last point
coordinates.pop();
geometry.setCoordinates(coordinates);
this.geometryFunction_(coordinates, geometry);
} else if (this.mode_ === ol.interaction.DrawMode.POLYGON) {
goog.asserts.assertInstanceof(geometry, ol.geom.Polygon,
'geometry should be an ol.geom.Polygon');
// When we finish drawing a polygon on the last point,
// the last coordinate is duplicated as for LineString
// we force the replacement by the first point
this.sketchPolygonCoords_[0].pop();
this.sketchPolygonCoords_[0].push(this.sketchPolygonCoords_[0][0]);
geometry.setCoordinates(this.sketchPolygonCoords_);
coordinates = geometry.getCoordinates();
coordinates[0].pop();
coordinates[0].push(coordinates[0][0]);
this.geometryFunction_(coordinates, geometry);
}
// cast multi-part geometries
@@ -592,7 +654,8 @@ ol.interaction.Draw.prototype.finishDrawing = function() {
}
// First dispatch event to allow full set up of feature
this.dispatchEvent(new ol.DrawEvent(ol.DrawEventType.DRAWEND, sketchFeature));
this.dispatchEvent(new ol.interaction.DrawEvent(
ol.interaction.DrawEventType.DRAWEND, sketchFeature));
// Then insert feature
if (!goog.isNull(this.features_)) {
@@ -616,7 +679,7 @@ ol.interaction.Draw.prototype.abortDrawing_ = function() {
this.sketchFeature_ = null;
this.sketchPoint_ = null;
this.sketchLine_ = null;
this.overlay_.getFeatures().clear();
this.overlay_.getSource().clear(true);
}
return sketchFeature;
};
@@ -643,7 +706,9 @@ ol.interaction.Draw.prototype.updateSketchFeatures_ = function() {
if (!goog.isNull(this.sketchPoint_)) {
sketchFeatures.push(this.sketchPoint_);
}
this.overlay_.setFeatures(new ol.Collection(sketchFeatures));
var overlaySource = this.overlay_.getSource();
overlaySource.clear(true);
overlaySource.addFeatures(sketchFeatures);
};
@@ -660,6 +725,44 @@ ol.interaction.Draw.prototype.updateState_ = function() {
};
/**
* Create a `geometryFunction` for `mode: 'Circle'` that will create a regular
* polygon with a user specified number of sides and start angle instead of an
* `ol.geom.Circle` geometry.
* @param {number=} opt_sides Number of sides of the regular polygon. Default is
* 32.
* @param {number=} opt_angle Angle of the first point in radians. 0 means East.
* Default is the angle defined by the heading from the center of the
* regular polygon to the current pointer position.
* @return {ol.interaction.DrawGeometryFunctionType} Function that draws a
* polygon.
* @api
*/
ol.interaction.Draw.createRegularPolygon = function(opt_sides, opt_angle) {
return (
/**
* @param {ol.Coordinate|Array.<ol.Coordinate>|Array.<Array.<ol.Coordinate>>} coordinates
* @param {ol.geom.SimpleGeometry=} opt_geometry
* @return {ol.geom.SimpleGeometry}
*/
function(coordinates, opt_geometry) {
var center = coordinates[0];
var end = coordinates[1];
var radius = Math.sqrt(
ol.coordinate.squaredDistance(center, end));
var geometry = goog.isDef(opt_geometry) ? opt_geometry :
ol.geom.Polygon.fromCircle(new ol.geom.Circle(center), opt_sides);
goog.asserts.assertInstanceof(geometry, ol.geom.Polygon,
'geometry must be a polygon');
var angle = goog.isDef(opt_angle) ? opt_angle :
Math.atan((end[1] - center[1]) / (end[0] - center[0]));
ol.geom.Polygon.makeRegular(geometry, center, radius, angle);
return geometry;
}
);
};
/**
* Get the drawing mode. The mode for mult-part geometries is the same as for
* their single-part cousins.
@@ -686,6 +789,19 @@ ol.interaction.Draw.getMode_ = function(type) {
};
/**
* Function that takes coordinates and an optional existing geometry as
* arguments, and returns a geometry. The optional existing geometry is the
* geometry that is returned when the function is called without a second
* argument.
* @typedef {function(!(ol.Coordinate|Array.<ol.Coordinate>|
* Array.<Array.<ol.Coordinate>>), ol.geom.SimpleGeometry=):
* ol.geom.SimpleGeometry}
* @api
*/
ol.interaction.DrawGeometryFunctionType;
/**
* Draw mode. This collapses multi-part geometry types with their single-part
* cousins.

View File

@@ -3,11 +3,11 @@ goog.provide('ol.interaction.Modify');
goog.require('goog.array');
goog.require('goog.asserts');
goog.require('goog.events');
goog.require('goog.events.Event');
goog.require('goog.functions');
goog.require('ol.Collection');
goog.require('ol.CollectionEventType');
goog.require('ol.Feature');
goog.require('ol.FeatureOverlay');
goog.require('ol.MapBrowserEvent.EventType');
goog.require('ol.ViewHint');
goog.require('ol.coordinate');
@@ -21,10 +21,66 @@ goog.require('ol.geom.MultiPolygon');
goog.require('ol.geom.Point');
goog.require('ol.geom.Polygon');
goog.require('ol.interaction.Pointer');
goog.require('ol.layer.Vector');
goog.require('ol.source.Vector');
goog.require('ol.structs.RBush');
goog.require('ol.style.Style');
/**
* @enum {string}
*/
ol.ModifyEventType = {
/**
* Triggered upon feature modification start
* @event ol.ModifyEvent#modifystart
* @api
*/
MODIFYSTART: 'modifystart',
/**
* Triggered upon feature modification end
* @event ol.ModifyEvent#modifyend
* @api
*/
MODIFYEND: 'modifyend'
};
/**
* @classdesc
* Events emitted by {@link ol.interaction.Modify} instances are instances of
* this type.
*
* @constructor
* @extends {goog.events.Event}
* @implements {oli.ModifyEvent}
* @param {ol.ModifyEventType} type Type.
* @param {ol.Collection.<ol.Feature>} features The features modified.
* @param {ol.MapBrowserPointerEvent} mapBrowserPointerEvent Associated
* {@link ol.MapBrowserPointerEvent}.
*/
ol.ModifyEvent = function(type, features, mapBrowserPointerEvent) {
goog.base(this, type);
/**
* The features being modified.
* @type {ol.Collection.<ol.Feature>}
* @api
*/
this.features = features;
/**
* Associated {@link ol.MapBrowserPointerEvent}.
* @type {ol.MapBrowserPointerEvent}
* @api
*/
this.mapBrowserPointerEvent = mapBrowserPointerEvent;
};
goog.inherits(ol.ModifyEvent, goog.events.Event);
/**
* @typedef {{depth: (Array.<number>|undefined),
* feature: ol.Feature,
@@ -38,12 +94,13 @@ ol.interaction.SegmentDataType;
/**
* @classdesc
* Interaction for modifying vector data.
* Interaction for modifying feature geometries.
*
* @constructor
* @extends {ol.interaction.Pointer}
* @param {olx.interaction.ModifyOptions} options Options.
* @api stable
* @fires ol.ModifyEvent
* @api
*/
ol.interaction.Modify = function(options) {
@@ -84,6 +141,14 @@ ol.interaction.Modify = function(options) {
*/
this.lastPixel_ = [0, 0];
/**
* Keep track of the last inserted pixel location to avoid
* unintentional deletion.
* @type {ol.Pixel}
* @private
*/
this.lastNewVertexPixel_ = [NaN, NaN];
/**
* Segment RTree for each layer
* @type {Object.<*, ol.structs.RBush>}
@@ -112,12 +177,18 @@ ol.interaction.Modify = function(options) {
/**
* Draw overlay where are sketch features are drawn.
* @type {ol.FeatureOverlay}
* @type {ol.layer.Vector}
* @private
*/
this.overlay_ = new ol.FeatureOverlay({
this.overlay_ = new ol.layer.Vector({
source: new ol.source.Vector({
useSpatialIndex: false,
wrapX: goog.isDef(options.wrapX) ? options.wrapX : false
}),
style: goog.isDef(options.style) ? options.style :
ol.interaction.Modify.getDefaultStyleFunction()
ol.interaction.Modify.getDefaultStyleFunction(),
updateWhileAnimating: true,
updateWhileInteracting: true
});
/**
@@ -208,7 +279,7 @@ ol.interaction.Modify.prototype.handleFeatureRemove_ = function(evt) {
// There remains only vertexFeature…
if (!goog.isNull(this.vertexFeature_) &&
this.features_.getLength() === 0) {
this.overlay_.removeFeature(this.vertexFeature_);
this.overlay_.getSource().removeFeature(this.vertexFeature_);
this.vertexFeature_ = null;
}
};
@@ -383,7 +454,7 @@ ol.interaction.Modify.prototype.createOrUpdateVertexFeature_ =
if (goog.isNull(vertexFeature)) {
vertexFeature = new ol.Feature(new ol.geom.Point(coordinates));
this.vertexFeature_ = vertexFeature;
this.overlay_.addFeature(vertexFeature);
this.overlay_.getSource().addFeature(vertexFeature);
} else {
var geometry = /** @type {ol.geom.Point} */ (vertexFeature.getGeometry());
geometry.setCoordinates(coordinates);
@@ -459,6 +530,8 @@ ol.interaction.Modify.handleDownEvent_ = function(evt) {
for (i = insertVertices.length - 1; i >= 0; --i) {
this.insertVertex_.apply(this, insertVertices[i]);
}
this.dispatchEvent(new ol.ModifyEvent(ol.ModifyEventType.MODIFYSTART,
this.features_, evt));
}
return !goog.isNull(this.vertexFeature_);
};
@@ -530,6 +603,8 @@ ol.interaction.Modify.handleUpEvent_ = function(evt) {
this.rBush_.update(ol.extent.boundingExtent(segmentData.segment),
segmentData);
}
this.dispatchEvent(new ol.ModifyEvent(ol.ModifyEventType.MODIFYEND,
this.features_, evt));
return false;
};
@@ -551,10 +626,15 @@ ol.interaction.Modify.handleEvent = function(mapBrowserEvent) {
}
if (!goog.isNull(this.vertexFeature_) &&
this.deleteCondition_(mapBrowserEvent)) {
var geometry = this.vertexFeature_.getGeometry();
goog.asserts.assertInstanceof(geometry, ol.geom.Point,
'geometry should be an ol.geom.Point');
handled = this.removeVertex_();
if (!(this.lastNewVertexPixel_[0] === this.lastPixel_[0] &&
this.lastNewVertexPixel_[1] === this.lastPixel_[1])) {
var geometry = this.vertexFeature_.getGeometry();
goog.asserts.assertInstanceof(geometry, ol.geom.Point,
'geometry should be an ol.geom.Point');
handled = this.removeVertex_();
} else {
handled = true;
}
}
return ol.interaction.Pointer.handleEvent.call(this, mapBrowserEvent) &&
!handled;
@@ -630,7 +710,7 @@ ol.interaction.Modify.prototype.handlePointerAtPixel_ = function(pixel, map) {
}
}
if (!goog.isNull(this.vertexFeature_)) {
this.overlay_.removeFeature(this.vertexFeature_);
this.overlay_.getSource().removeFeature(this.vertexFeature_);
this.vertexFeature_ = null;
}
};
@@ -709,6 +789,7 @@ ol.interaction.Modify.prototype.insertVertex_ = function(segmentData, vertex) {
rTree.insert(ol.extent.boundingExtent(newSegmentData2.segment),
newSegmentData2);
this.dragSegments_.push([newSegmentData2, 0]);
this.lastNewVertexPixel_ = this.lastPixel_;
};
@@ -800,7 +881,7 @@ ol.interaction.Modify.prototype.removeVertex_ = function() {
newSegmentData);
this.updateSegmentIndices_(geometry, index, segmentData.depth, -1);
this.overlay_.removeFeature(this.vertexFeature_);
this.overlay_.getSource().removeFeature(this.vertexFeature_);
this.vertexFeature_ = null;
}
}

View File

@@ -8,10 +8,11 @@ goog.require('goog.events.Event');
goog.require('goog.functions');
goog.require('ol.CollectionEventType');
goog.require('ol.Feature');
goog.require('ol.FeatureOverlay');
goog.require('ol.events.condition');
goog.require('ol.geom.GeometryType');
goog.require('ol.interaction.Interaction');
goog.require('ol.layer.Vector');
goog.require('ol.source.Vector');
goog.require('ol.style.Style');
@@ -46,11 +47,13 @@ ol.interaction.SelectFilterFunction;
* @param {string} type The event type.
* @param {Array.<ol.Feature>} selected Selected features.
* @param {Array.<ol.Feature>} deselected Deselected features.
* @param {ol.MapBrowserEvent} mapBrowserEvent Associated
* {@link ol.MapBrowserEvent}.
* @implements {oli.SelectEvent}
* @extends {goog.events.Event}
* @constructor
*/
ol.SelectEvent = function(type, selected, deselected) {
ol.SelectEvent = function(type, selected, deselected, mapBrowserEvent) {
goog.base(this, type);
/**
@@ -66,6 +69,13 @@ ol.SelectEvent = function(type, selected, deselected) {
* @api
*/
this.deselected = deselected;
/**
* Associated {@link ol.MapBrowserEvent}.
* @type {ol.MapBrowserEvent}
* @api
*/
this.mapBrowserEvent = mapBrowserEvent;
};
goog.inherits(ol.SelectEvent, goog.events.Event);
@@ -73,7 +83,7 @@ goog.inherits(ol.SelectEvent, goog.events.Event);
/**
* @classdesc
* Handles selection of vector data. A {@link ol.FeatureOverlay} is maintained
* Handles selection of vector data. An {@link ol.source.Vector} is maintained
* internally to store the selected feature(s). Which features are selected is
* determined by the `condition` option, and optionally the `toggle` or
* `add`/`remove` options.
@@ -81,6 +91,7 @@ goog.inherits(ol.SelectEvent, goog.events.Event);
* @constructor
* @extends {ol.interaction.Interaction}
* @param {olx.interaction.SelectOptions=} opt_options Options.
* @fires ol.SelectEvent
* @api stable
*/
ol.interaction.Select = function(opt_options) {
@@ -159,14 +170,20 @@ ol.interaction.Select = function(opt_options) {
/**
* @private
* @type {ol.FeatureOverlay}
* @type {ol.layer.Vector}
*/
this.featureOverlay_ = new ol.FeatureOverlay({
this.featureOverlay_ = new ol.layer.Vector({
source: new ol.source.Vector({
useSpatialIndex: false,
wrapX: options.wrapX
}),
style: goog.isDef(options.style) ? options.style :
ol.interaction.Select.getDefaultStyleFunction()
ol.interaction.Select.getDefaultStyleFunction(),
updateWhileAnimating: true,
updateWhileInteracting: true
});
var features = this.featureOverlay_.getFeatures();
var features = this.featureOverlay_.getSource().getFeaturesCollection();
goog.events.listen(features, ol.CollectionEventType.ADD,
this.addFeature_, false, this);
goog.events.listen(features, ol.CollectionEventType.REMOVE,
@@ -182,7 +199,7 @@ goog.inherits(ol.interaction.Select, ol.interaction.Interaction);
* @api stable
*/
ol.interaction.Select.prototype.getFeatures = function() {
return this.featureOverlay_.getFeatures();
return this.featureOverlay_.getSource().getFeaturesCollection();
};
@@ -203,9 +220,9 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) {
var toggle = this.toggleCondition_(mapBrowserEvent);
var set = !add && !remove && !toggle;
var map = mapBrowserEvent.map;
var features = this.featureOverlay_.getFeatures();
var /** @type {Array.<ol.Feature>} */ deselected = [];
var /** @type {Array.<ol.Feature>} */ selected = [];
var features = this.featureOverlay_.getSource().getFeaturesCollection();
var /** @type {!Array.<ol.Feature>} */ deselected = [];
var /** @type {!Array.<ol.Feature>} */ selected = [];
var change = false;
if (set) {
// Replace the currently selected feature(s) with the feature(s) at the
@@ -265,7 +282,8 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) {
}
if (change) {
this.dispatchEvent(
new ol.SelectEvent(ol.SelectEventType.SELECT, selected, deselected));
new ol.SelectEvent(ol.SelectEventType.SELECT, selected, deselected,
mapBrowserEvent));
}
return ol.events.condition.pointerMove(mapBrowserEvent);
};
@@ -279,7 +297,8 @@ ol.interaction.Select.handleEvent = function(mapBrowserEvent) {
*/
ol.interaction.Select.prototype.setMap = function(map) {
var currentMap = this.getMap();
var selectedFeatures = this.featureOverlay_.getFeatures();
var selectedFeatures =
this.featureOverlay_.getSource().getFeaturesCollection();
if (!goog.isNull(currentMap)) {
selectedFeatures.forEach(currentMap.unskipFeature, currentMap);
}

View File

@@ -6,6 +6,7 @@ goog.require('goog.object');
goog.require('ol.Object');
goog.require('ol.layer.Base');
goog.require('ol.layer.LayerProperty');
goog.require('ol.render.EventType');
goog.require('ol.source.State');
@@ -32,12 +33,28 @@ ol.layer.Layer = function(options) {
goog.base(this, /** @type {olx.layer.LayerOptions} */ (baseOptions));
/**
* @private
* @type {goog.events.Key}
*/
this.mapPrecomposeKey_ = null;
/**
* @private
* @type {goog.events.Key}
*/
this.mapRenderKey_ = null;
/**
* @private
* @type {goog.events.Key}
*/
this.sourceChangeKey_ = null;
if (goog.isDef(options.map)) {
this.setMap(options.map);
}
goog.events.listen(this,
ol.Object.getChangeEventType(ol.layer.LayerProperty.SOURCE),
this.handleSourcePropertyChange_, false, this);
@@ -129,6 +146,33 @@ ol.layer.Layer.prototype.handleSourcePropertyChange_ = function() {
};
/**
* Sets the layer to be rendered on a map. The map will not manage this layer in
* its layers collection, and the layer will be rendered on top. This is useful
* for temporary layers. To remove an unmanaged layer from the map, use
* `#setMap(null)`. To add the layer to a map and have it managed by the map,
* use {@link ol.Map#addLayer} instead.
* @param {ol.Map} map Map.
* @api
*/
ol.layer.Layer.prototype.setMap = function(map) {
goog.events.unlistenByKey(this.mapPrecomposeKey_);
this.changed();
goog.events.unlistenByKey(this.mapRenderKey_);
if (!goog.isNull(map)) {
this.mapPrecomposeKey_ = goog.events.listen(
map, ol.render.EventType.PRECOMPOSE, function(evt) {
var layerState = this.getLayerState();
layerState.managed = false;
evt.frameState.layerStatesArray.push(layerState);
evt.frameState.layerStates[goog.getUid(this)] = layerState;
}, false, this);
this.mapRenderKey_ = goog.events.listen(
this, goog.events.EventType.CHANGE, map.render, false, map);
}
};
/**
* Set the layer source.
* @param {ol.source.Source} source The layer source.

View File

@@ -35,6 +35,7 @@ ol.layer.LayerProperty = {
* saturation: number,
* sourceState: ol.source.State,
* visible: boolean,
* managed: boolean,
* extent: (ol.Extent|undefined),
* maxResolution: number,
* minResolution: number}}
@@ -142,6 +143,7 @@ ol.layer.Base.prototype.getLayerState = function() {
saturation: Math.max(saturation, 0),
sourceState: sourceState,
visible: visible,
managed: true,
extent: extent,
maxResolution: maxResolution,
minResolution: Math.max(minResolution, 0)

View File

@@ -163,7 +163,7 @@ ol.layer.Group.prototype.handleLayersRemove_ = function(collectionEvent) {
* Returns the {@link ol.Collection collection} of {@link ol.layer.Layer layers}
* in this group.
* @return {!ol.Collection.<ol.layer.Base>} Collection of
* {@link ol.layer.Layer layers} that are part of this group.
* {@link ol.layer.Base layers} that are part of this group.
* @observable
* @api stable
*/
@@ -177,7 +177,7 @@ ol.layer.Group.prototype.getLayers = function() {
* Set the {@link ol.Collection collection} of {@link ol.layer.Layer layers}
* in this group.
* @param {!ol.Collection.<ol.layer.Base>} layers Collection of
* {@link ol.layer.Layer layers} that are part of this group.
* {@link ol.layer.Base layers} that are part of this group.
* @observable
* @api stable
*/

View File

@@ -1,5 +1,6 @@
goog.provide('ol.layer.Vector');
goog.require('goog.asserts');
goog.require('goog.object');
goog.require('ol.layer.Layer');
goog.require('ol.style.Style');
@@ -32,6 +33,11 @@ ol.layer.Vector = function(opt_options) {
var options = goog.isDef(opt_options) ?
opt_options : /** @type {olx.layer.VectorOptions} */ ({});
goog.asserts.assert(
!goog.isDef(options.renderOrder) || goog.isNull(options.renderOrder) ||
goog.isFunction(options.renderOrder),
'renderOrder must be a comparator function');
var baseOptions = goog.object.clone(options);
delete baseOptions.style;
@@ -153,6 +159,10 @@ ol.layer.Vector.prototype.getUpdateWhileInteracting = function() {
* Render order.
*/
ol.layer.Vector.prototype.setRenderOrder = function(renderOrder) {
goog.asserts.assert(
!goog.isDef(renderOrder) || goog.isNull(renderOrder) ||
goog.isFunction(renderOrder),
'renderOrder must be a comparator function');
this.set(ol.layer.VectorProperty.RENDER_ORDER, renderOrder);
};

View File

@@ -13,6 +13,7 @@ goog.require('goog.debug.Console');
goog.require('goog.dom');
goog.require('goog.dom.TagName');
goog.require('goog.dom.ViewportSizeMonitor');
goog.require('goog.dom.classlist');
goog.require('goog.events');
goog.require('goog.events.BrowserEvent');
goog.require('goog.events.Event');
@@ -151,6 +152,15 @@ ol.MapProperty = {
* a further element within the viewport, either DOM or Canvas, depending on the
* renderer.
*
* Layers are stored as a `ol.Collection` in layerGroups. A top-level group is
* provided by the library. This is what is accessed by `getLayerGroup` and
* `setLayerGroup`. Layers entered in the options are added to this group, and
* `addLayer` and `removeLayer` change the layer collection in the group.
* `getLayers` is a convenience function for `getLayerGroup().getLayers()`.
* Note that `ol.layer.Group` is a subclass of `ol.layer.Base`, so layers
* entered in the options or added with `addLayer` can be groups, which can
* contain further groups, and so on.
*
* @constructor
* @extends {ol.Object}
* @param {olx.MapOptions} options Map options.
@@ -257,7 +267,7 @@ ol.Map = function(options) {
// prevent page zoom on IE >= 10 browsers
this.viewport_.style.msTouchAction = 'none';
if (ol.has.TOUCH) {
this.viewport_.className = 'ol-touch';
goog.dom.classlist.add(this.viewport_, 'ol-touch');
}
/**
@@ -503,7 +513,9 @@ ol.Map.prototype.addInteraction = function(interaction) {
/**
* Adds the given layer to the top of this map.
* Adds the given layer to the top of this map. If you want to add a layer
* elsewhere in the stack, use `getLayers()` and the methods available on
* {@link ol.Collection}.
* @param {ol.layer.Base} layer Layer.
* @api stable
*/
@@ -560,19 +572,20 @@ ol.Map.prototype.disposeInternal = function() {
/**
* Detect features that intersect a pixel on the viewport, and execute a
* callback with each intersecting feature. Layers included in the detection can
* be configured through `opt_layerFilter`. Feature overlays will always be
* included in the detection.
* be configured through `opt_layerFilter`.
* @param {ol.Pixel} pixel Pixel.
* @param {function(this: S, ol.Feature, ol.layer.Layer): T} callback Feature
* callback. If the detected feature is not on a layer, but on a
* {@link ol.FeatureOverlay}, then the 2nd argument to this function will
* be `null`. To stop detection, callback functions can return a truthy
* value.
* callback. The callback will be called with two arguments. The first
* argument is one {@link ol.Feature feature} at the pixel, the second is
* the {@link ol.layer.Layer layer} of the feature. To stop detection,
* callback functions can return a truthy value.
* @param {S=} opt_this Value to use as `this` when executing `callback`.
* @param {(function(this: U, ol.layer.Layer): boolean)=} opt_layerFilter Layer
* filter function, only layers which are visible and for which this
* function returns `true` will be tested for features. By default, all
* visible layers will be tested. Feature overlays will always be tested.
* filter function. The filter function will receive one argument, the
* {@link ol.layer.Layer layer-candidate} and it should return a boolean
* value. Only layers which are visible and for which this function returns
* `true` will be tested for features. By default, all visible layers will
* be tested.
* @param {U=} opt_this2 Value to use as `this` when executing `layerFilter`.
* @return {T|undefined} Callback result, i.e. the return value of last
* callback execution, or the first truthy callback return value.
@@ -598,19 +611,19 @@ ol.Map.prototype.forEachFeatureAtPixel =
/**
* Detect layers that have a color value at a pixel on the viewport, and
* execute a callback with each matching layer. Layers included in the
* detection can be configured through `opt_layerFilter`. Feature overlays will
* always be included in the detection.
* detection can be configured through `opt_layerFilter`.
* @param {ol.Pixel} pixel Pixel.
* @param {function(this: S, ol.layer.Layer): T} callback Layer
* callback. If the detected feature is not on a layer, but on a
* {@link ol.FeatureOverlay}, then the argument to this function will
* be `null`. To stop detection, callback functions can return a truthy
* value.
* callback. Will receive one argument, the {@link ol.layer.Layer layer}
* that contains the color pixel. To stop detection, callback functions can
* return a truthy value.
* @param {S=} opt_this Value to use as `this` when executing `callback`.
* @param {(function(this: U, ol.layer.Layer): boolean)=} opt_layerFilter Layer
* filter function, only layers which are visible and for which this
* function returns `true` will be tested for features. By default, all
* visible layers will be tested. Feature overlays will always be tested.
* filter function. The filter function will receive one argument, the
* {@link ol.layer.Layer layer-candidate} and it should return a boolean
* value. Only layers which are visible and for which this function returns
* `true` will be tested for features. By default, all visible layers will
* be tested.
* @param {U=} opt_this2 Value to use as `this` when executing `layerFilter`.
* @return {T|undefined} Callback result, i.e. the return value of last
* callback execution, or the first truthy callback return value.
@@ -634,13 +647,14 @@ ol.Map.prototype.forEachLayerAtPixel =
/**
* Detect if features intersect a pixel on the viewport. Layers included in the
* detection can be configured through `opt_layerFilter`. Feature overlays will
* always be included in the detection.
* 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, only layers which are visible and for which this
* function returns `true` will be tested for features. By default, all
* visible layers will be tested. Feature overlays will always be tested.
* filter function. The filter function will receive one argument, the
* {@link ol.layer.Layer layer-candidate} and it should return a boolean
* value. Only layers which are visible and for which this function returns
* `true` will be tested for features. By default, all visible layers will
* be tested.
* @param {U=} opt_this Value to use as `this` when executing `layerFilter`.
* @return {boolean} Is there a feature at the given pixel?
* @template U

View File

@@ -471,8 +471,8 @@ ol.render.canvas.Immediate.prototype.drawCircleGeometry =
* Render a feature into the canvas. In order to respect the zIndex of the
* style this method draws asynchronously and thus *after* calls to
* drawXxxxGeometry have been finished, effectively drawing the feature
* *on top* of everything else. You probably should be using
* {@link ol.FeatureOverlay} instead of calling this method directly.
* *on top* of everything else. You probably should be using an
* {@link ol.layer.Vector} instead of calling this method directly.
*
* @param {ol.Feature} feature Feature.
* @param {ol.style.Style} style Style.

View File

@@ -353,7 +353,7 @@ ol.render.canvas.Replay.prototype.replay_ = function(
'3rd instruction should be a number');
dd = /** @type {number} */ (instruction[2]);
goog.asserts.assert(goog.isString(instruction[3]),
'4th instruction should be a number');
'4th instruction should be a string');
text = /** @type {string} */ (instruction[3]);
goog.asserts.assert(goog.isNumber(instruction[4]),
'5th instruction should be a number');

View File

@@ -35,14 +35,13 @@ ol.render.EventType = {
* @param {ol.render.EventType} type Type.
* @param {Object=} opt_target Target.
* @param {ol.render.VectorContext=} opt_vectorContext Vector context.
* @param {ol.render.IReplayGroup=} opt_replayGroup Replay group.
* @param {olx.FrameState=} opt_frameState Frame state.
* @param {?CanvasRenderingContext2D=} opt_context Context.
* @param {?ol.webgl.Context=} opt_glContext WebGL Context.
*/
ol.render.Event = function(
type, opt_target, opt_vectorContext, opt_replayGroup, opt_frameState,
opt_context, opt_glContext) {
type, opt_target, opt_vectorContext, opt_frameState, opt_context,
opt_glContext) {
goog.base(this, type, opt_target);
@@ -53,11 +52,6 @@ ol.render.Event = function(
*/
this.vectorContext = opt_vectorContext;
/**
* @type {ol.render.IReplayGroup|undefined}
*/
this.replayGroup = opt_replayGroup;
/**
* @type {olx.FrameState|undefined}
* @api

View File

@@ -131,8 +131,8 @@ ol.renderer.canvas.Layer.prototype.dispatchComposeEvent_ =
var render = new ol.render.canvas.Immediate(
context, frameState.pixelRatio, frameState.extent, transform,
frameState.viewState.rotation);
var composeEvent = new ol.render.Event(type, layer, render, null,
frameState, context, null);
var composeEvent = new ol.render.Event(type, layer, render, frameState,
context, null);
layer.dispatchEvent(composeEvent);
render.flush();
}

View File

@@ -10,7 +10,6 @@ goog.require('ol');
goog.require('ol.RendererType');
goog.require('ol.css');
goog.require('ol.dom');
goog.require('ol.extent');
goog.require('ol.layer.Image');
goog.require('ol.layer.Layer');
goog.require('ol.layer.Tile');
@@ -18,13 +17,11 @@ goog.require('ol.layer.Vector');
goog.require('ol.render.Event');
goog.require('ol.render.EventType');
goog.require('ol.render.canvas.Immediate');
goog.require('ol.render.canvas.ReplayGroup');
goog.require('ol.renderer.Map');
goog.require('ol.renderer.canvas.ImageLayer');
goog.require('ol.renderer.canvas.Layer');
goog.require('ol.renderer.canvas.TileLayer');
goog.require('ol.renderer.canvas.VectorLayer');
goog.require('ol.renderer.vector');
goog.require('ol.source.State');
goog.require('ol.vec.Mat4');
@@ -103,55 +100,27 @@ ol.renderer.canvas.Map.prototype.dispatchComposeEvent_ =
var extent = frameState.extent;
var pixelRatio = frameState.pixelRatio;
var viewState = frameState.viewState;
var projection = viewState.projection;
var resolution = viewState.resolution;
var rotation = viewState.rotation;
var offsetX = 0;
if (projection.canWrapX()) {
var projectionExtent = projection.getExtent();
var worldWidth = ol.extent.getWidth(projectionExtent);
var x = frameState.focus[0];
if (x < projectionExtent[0] || x > projectionExtent[2]) {
var worldsAway = Math.ceil((projectionExtent[0] - x) / worldWidth);
offsetX = worldWidth * worldsAway;
extent = [
extent[0] + offsetX, extent[1],
extent[2] + offsetX, extent[3]
];
}
}
var transform = this.getTransform(frameState, offsetX);
var tolerance = ol.renderer.vector.getTolerance(resolution, pixelRatio);
var replayGroup = new ol.render.canvas.ReplayGroup(
tolerance, extent, resolution);
var transform = this.getTransform(frameState);
var vectorContext = new ol.render.canvas.Immediate(context, pixelRatio,
extent, transform, rotation);
var composeEvent = new ol.render.Event(type, map, vectorContext,
replayGroup, frameState, context, null);
frameState, context, null);
map.dispatchEvent(composeEvent);
replayGroup.finish();
if (!replayGroup.isEmpty()) {
replayGroup.replay(context, pixelRatio, transform, rotation, {});
}
vectorContext.flush();
this.replayGroup = replayGroup;
}
};
/**
* @param {olx.FrameState} frameState Frame state.
* @param {number} offsetX Offset on the x-axis in view coordinates.
* @protected
* @return {!goog.vec.Mat4.Number} Transform.
*/
ol.renderer.canvas.Map.prototype.getTransform = function(frameState, offsetX) {
ol.renderer.canvas.Map.prototype.getTransform = function(frameState) {
var pixelRatio = frameState.pixelRatio;
var viewState = frameState.viewState;
var resolution = viewState.resolution;
@@ -159,8 +128,7 @@ ol.renderer.canvas.Map.prototype.getTransform = function(frameState, offsetX) {
this.canvas_.width / 2, this.canvas_.height / 2,
pixelRatio / resolution, -pixelRatio / resolution,
-viewState.rotation,
-viewState.center[0] - offsetX,
-viewState.center[1]);
-viewState.center[0], -viewState.center[1]);
};

View File

@@ -77,9 +77,9 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame =
function(frameState, layerState, context) {
var extent = frameState.extent;
var focus = frameState.focus;
var pixelRatio = frameState.pixelRatio;
var skippedFeatureUids = frameState.skippedFeatureUids;
var skippedFeatureUids = layerState.managed ?
frameState.skippedFeatureUids : {};
var viewState = frameState.viewState;
var projection = viewState.projection;
var rotation = viewState.rotation;
@@ -108,20 +108,11 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame =
// see http://jsperf.com/context-save-restore-versus-variable
var alpha = replayContext.globalAlpha;
replayContext.globalAlpha = layerState.opacity;
var noSkip = {};
var focusX = focus[0];
replayGroup.replay(replayContext, pixelRatio, transform, rotation,
skippedFeatureUids);
if (vectorSource.getWrapX() && projection.canWrapX() &&
!ol.extent.containsExtent(projectionExtent, extent)) {
var projLeft = projectionExtent[0];
var projRight = projectionExtent[2];
// A feature from skippedFeatureUids will only be skipped in the world
// that has the frameState's focus, because this is where a feature
// overlay for highlighting or selection would render the skipped
// feature.
replayGroup.replay(replayContext, pixelRatio, transform, rotation,
projLeft <= focusX && focusX <= projRight ?
skippedFeatureUids : noSkip);
var startX = extent[0];
var worldWidth = ol.extent.getWidth(projectionExtent);
var world = 0;
@@ -131,8 +122,7 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame =
offsetX = worldWidth * world;
transform = this.getTransform(frameState, offsetX);
replayGroup.replay(replayContext, pixelRatio, transform, rotation,
projLeft + offsetX <= focusX && focusX <= projRight + offsetX ?
skippedFeatureUids : noSkip);
skippedFeatureUids);
startX += worldWidth;
}
world = 0;
@@ -142,13 +132,11 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame =
offsetX = worldWidth * world;
transform = this.getTransform(frameState, offsetX);
replayGroup.replay(replayContext, pixelRatio, transform, rotation,
projLeft + offsetX <= focusX && focusX <= projRight + offsetX ?
skippedFeatureUids : noSkip);
skippedFeatureUids);
startX -= worldWidth;
}
} else {
replayGroup.replay(
replayContext, pixelRatio, transform, rotation, skippedFeatureUids);
// restore original transform for render and compose events
transform = this.getTransform(frameState, 0);
}
if (replayContext != context) {
@@ -174,10 +162,11 @@ ol.renderer.canvas.VectorLayer.prototype.forEachFeatureAtCoordinate =
var resolution = frameState.viewState.resolution;
var rotation = frameState.viewState.rotation;
var layer = this.getLayer();
var layerState = frameState.layerStates[goog.getUid(layer)];
/** @type {Object.<string, boolean>} */
var features = {};
return this.replayGroup_.forEachFeatureAtCoordinate(coordinate,
resolution, rotation, frameState.skippedFeatureUids,
return this.replayGroup_.forEachFeatureAtCoordinate(coordinate, resolution,
rotation, layerState.managed ? frameState.skippedFeatureUids : {},
/**
* @param {ol.Feature} feature Feature.
* @return {?} Callback result.
@@ -249,9 +238,15 @@ ol.renderer.canvas.VectorLayer.prototype.prepareFrame =
if (vectorSource.getWrapX() && viewState.projection.canWrapX() &&
!ol.extent.containsExtent(projectionExtent, frameState.extent)) {
// do not clip when the view crosses the -180° or 180° meridians
extent[0] = projectionExtent[0];
extent[2] = projectionExtent[2];
// For the replay group, we need an extent that intersects the real world
// (-180° to +180°). To support geometries in a coordinate range from -540°
// to +540°, we add at least 1 world width on each side of the projection
// extent. If the viewport is wider than the world, we need to add half of
// the viewport width to make sure we cover the whole viewport.
var worldWidth = ol.extent.getWidth(projectionExtent);
var buffer = Math.max(ol.extent.getWidth(extent) / 2, worldWidth);
extent[0] = projectionExtent[0] - buffer;
extent[2] = projectionExtent[2] + buffer;
}
if (!this.dirty_ &&

View File

@@ -20,13 +20,11 @@ goog.require('ol.layer.Vector');
goog.require('ol.render.Event');
goog.require('ol.render.EventType');
goog.require('ol.render.canvas.Immediate');
goog.require('ol.render.canvas.ReplayGroup');
goog.require('ol.renderer.Map');
goog.require('ol.renderer.dom.ImageLayer');
goog.require('ol.renderer.dom.Layer');
goog.require('ol.renderer.dom.TileLayer');
goog.require('ol.renderer.dom.VectorLayer');
goog.require('ol.renderer.vector');
goog.require('ol.source.State');
goog.require('ol.vec.Mat4');
@@ -139,7 +137,6 @@ ol.renderer.dom.Map.prototype.dispatchComposeEvent_ =
var extent = frameState.extent;
var pixelRatio = frameState.pixelRatio;
var viewState = frameState.viewState;
var resolution = viewState.resolution;
var rotation = viewState.rotation;
var context = this.context_;
var canvas = context.canvas;
@@ -153,18 +150,10 @@ ol.renderer.dom.Map.prototype.dispatchComposeEvent_ =
-viewState.center[0], -viewState.center[1]);
var vectorContext = new ol.render.canvas.Immediate(context, pixelRatio,
extent, this.transform_, rotation);
var replayGroup = new ol.render.canvas.ReplayGroup(
ol.renderer.vector.getTolerance(resolution, pixelRatio), extent,
resolution);
var composeEvent = new ol.render.Event(type, map, vectorContext,
replayGroup, frameState, context, null);
frameState, context, null);
map.dispatchEvent(composeEvent);
replayGroup.finish();
if (!replayGroup.isEmpty()) {
replayGroup.replay(context, pixelRatio, this.transform_, rotation, {});
}
vectorContext.flush();
this.replayGroup = replayGroup;
}
};

View File

@@ -142,7 +142,7 @@ ol.renderer.dom.VectorLayer.prototype.composeFrame =
context.globalAlpha = layerState.opacity;
replayGroup.replay(context, pixelRatio, transform, viewRotation,
frameState.skippedFeatureUids);
layerState.managed ? frameState.skippedFeatureUids : {});
this.dispatchEvent_(ol.render.EventType.RENDER, frameState, transform);
}
@@ -165,8 +165,8 @@ ol.renderer.dom.VectorLayer.prototype.dispatchEvent_ =
var render = new ol.render.canvas.Immediate(
context, frameState.pixelRatio, frameState.extent, transform,
frameState.viewState.rotation);
var event = new ol.render.Event(type, layer, render, null,
frameState, context, null);
var event = new ol.render.Event(type, layer, render, frameState,
context, null);
layer.dispatchEvent(event);
render.flush();
}
@@ -184,10 +184,11 @@ ol.renderer.dom.VectorLayer.prototype.forEachFeatureAtCoordinate =
var resolution = frameState.viewState.resolution;
var rotation = frameState.viewState.rotation;
var layer = this.getLayer();
var layerState = frameState.layerStates[goog.getUid(layer)];
/** @type {Object.<string, boolean>} */
var features = {};
return this.replayGroup_.forEachFeatureAtCoordinate(coordinate,
resolution, rotation, frameState.skippedFeatureUids,
return this.replayGroup_.forEachFeatureAtCoordinate(coordinate, resolution,
rotation, layerState.managed ? frameState.skippedFeatureUids : {},
/**
* @param {ol.Feature} feature Feature.
* @return {?} Callback result.

View File

@@ -48,12 +48,6 @@ ol.renderer.Map = function(container, map) {
*/
this.map_ = map;
/**
* @protected
* @type {ol.render.IReplayGroup}
*/
this.replayGroup = null;
/**
* @private
* @type {Object.<string, ol.renderer.Layer>}
@@ -137,7 +131,6 @@ ol.renderer.Map.prototype.forEachFeatureAtCoordinate =
var result;
var viewState = frameState.viewState;
var viewResolution = viewState.resolution;
var viewRotation = viewState.rotation;
/** @type {Object.<string, boolean>} */
var features = {};
@@ -168,13 +161,6 @@ ol.renderer.Map.prototype.forEachFeatureAtCoordinate =
}
}
if (!goog.isNull(this.replayGroup)) {
result = this.replayGroup.forEachFeatureAtCoordinate(translatedCoordinate,
viewResolution, viewRotation, {}, forEachFeatureAtCoordinate);
if (result) {
return result;
}
}
var layerStates = frameState.layerStatesArray;
var numLayers = layerStates.length;
var i;
@@ -216,20 +202,7 @@ ol.renderer.Map.prototype.forEachLayerAtPixel =
var result;
var viewState = frameState.viewState;
var viewResolution = viewState.resolution;
var viewRotation = viewState.rotation;
if (!goog.isNull(this.replayGroup)) {
var coordinate = this.getMap().getCoordinateFromPixel(pixel);
var hasFeature = this.replayGroup.forEachFeatureAtCoordinate(coordinate,
viewResolution, viewRotation, {}, goog.functions.TRUE);
if (hasFeature) {
result = callback.call(thisArg, null);
if (result) {
return result;
}
}
}
var layerStates = frameState.layerStatesArray;
var numLayers = layerStates.length;
var i;

View File

@@ -247,7 +247,7 @@ ol.renderer.webgl.Layer.prototype.dispatchComposeEvent_ =
var render = new ol.render.webgl.Immediate(
context, center, resolution, rotation, size, extent, pixelRatio);
var composeEvent = new ol.render.Event(
type, layer, render, null, frameState, null, context);
type, layer, render, frameState, null, context);
layer.dispatchEvent(composeEvent);
}
};

View File

@@ -24,9 +24,7 @@ goog.require('ol.layer.Vector');
goog.require('ol.render.Event');
goog.require('ol.render.EventType');
goog.require('ol.render.webgl.Immediate');
goog.require('ol.render.webgl.ReplayGroup');
goog.require('ol.renderer.Map');
goog.require('ol.renderer.vector');
goog.require('ol.renderer.webgl.ImageLayer');
goog.require('ol.renderer.webgl.Layer');
goog.require('ol.renderer.webgl.TileLayer');
@@ -287,27 +285,14 @@ ol.renderer.webgl.Map.prototype.dispatchComposeEvent_ =
var resolution = viewState.resolution;
var center = viewState.center;
var rotation = viewState.rotation;
var tolerance = ol.renderer.vector.getTolerance(resolution, pixelRatio);
var vectorContext = new ol.render.webgl.Immediate(context,
center, resolution, rotation, size, extent, pixelRatio);
var replayGroup = new ol.render.webgl.ReplayGroup(tolerance, extent);
var composeEvent = new ol.render.Event(type, map, vectorContext,
replayGroup, frameState, null, context);
frameState, null, context);
map.dispatchEvent(composeEvent);
replayGroup.finish(context);
if (!replayGroup.isEmpty()) {
// use default color values
var d = ol.renderer.webgl.Map.DEFAULT_COLOR_VALUES_;
replayGroup.replay(context, center, resolution, rotation, size,
pixelRatio, d.opacity, d.brightness, d.contrast,
d.hue, d.saturation, {});
}
replayGroup.getDeleteResourcesFunction(context)();
vectorContext.flush();
this.replayGroup = replayGroup;
}
};
@@ -561,37 +546,8 @@ ol.renderer.webgl.Map.prototype.forEachFeatureAtCoordinate =
return false;
}
var context = this.getContext();
var viewState = frameState.viewState;
// do the hit-detection for the overlays first
if (!goog.isNull(this.replayGroup)) {
/** @type {Object.<string, boolean>} */
var features = {};
// use default color values
var d = ol.renderer.webgl.Map.DEFAULT_COLOR_VALUES_;
result = this.replayGroup.forEachFeatureAtCoordinate(coordinate,
context, viewState.center, viewState.resolution, viewState.rotation,
frameState.size, frameState.pixelRatio,
d.opacity, d.brightness, d.contrast, d.hue, d.saturation, {},
/**
* @param {ol.Feature} feature Feature.
* @return {?} Callback result.
*/
function(feature) {
goog.asserts.assert(goog.isDef(feature), 'received a feature');
var key = goog.getUid(feature).toString();
if (!(key in features)) {
features[key] = true;
return callback.call(thisArg, feature, null);
}
});
if (result) {
return result;
}
}
var layerStates = frameState.layerStatesArray;
var numLayers = layerStates.length;
var i;
@@ -623,22 +579,8 @@ ol.renderer.webgl.Map.prototype.hasFeatureAtCoordinate =
return false;
}
var context = this.getContext();
var viewState = frameState.viewState;
// do the hit-detection for the overlays first
if (!goog.isNull(this.replayGroup)) {
// use default color values
var d = ol.renderer.webgl.Map.DEFAULT_COLOR_VALUES_;
hasFeature = this.replayGroup.hasFeatureAtCoordinate(coordinate,
context, viewState.center, viewState.resolution, viewState.rotation,
frameState.size, frameState.pixelRatio,
d.opacity, d.brightness, d.contrast, d.hue, d.saturation, {});
if (hasFeature) {
return true;
}
}
var layerStates = frameState.layerStatesArray;
var numLayers = layerStates.length;
var i;
@@ -669,27 +611,9 @@ ol.renderer.webgl.Map.prototype.forEachLayerAtPixel =
return false;
}
var context = this.getContext();
var viewState = frameState.viewState;
var result;
// do the hit-detection for the overlays first
if (!goog.isNull(this.replayGroup)) {
// use default color values
var d = ol.renderer.webgl.Map.DEFAULT_COLOR_VALUES_;
var coordinate = this.getMap().getCoordinateFromPixel(pixel);
var hasFeature = this.replayGroup.hasFeatureAtCoordinate(coordinate,
context, viewState.center, viewState.resolution, viewState.rotation,
frameState.size, frameState.pixelRatio,
d.opacity, d.brightness, d.contrast, d.hue, d.saturation, {});
if (hasFeature) {
result = callback.call(thisArg, null);
if (result) {
return result;
}
}
}
var layerStates = frameState.layerStatesArray;
var numLayers = layerStates.length;
var i;

View File

@@ -83,7 +83,8 @@ ol.renderer.webgl.VectorLayer.prototype.composeFrame =
viewState.center, viewState.resolution, viewState.rotation,
frameState.size, frameState.pixelRatio, layerState.opacity,
layerState.brightness, layerState.contrast, layerState.hue,
layerState.saturation, frameState.skippedFeatureUids);
layerState.saturation,
layerState.managed ? frameState.skippedFeatureUids : {});
}
};
@@ -121,7 +122,8 @@ ol.renderer.webgl.VectorLayer.prototype.forEachFeatureAtCoordinate =
context, viewState.center, viewState.resolution, viewState.rotation,
frameState.size, frameState.pixelRatio,
layerState.opacity, layerState.brightness, layerState.contrast,
layerState.hue, layerState.saturation, frameState.skippedFeatureUids,
layerState.hue, layerState.saturation,
layerState.managed ? frameState.skippedFeatureUids : {},
/**
* @param {ol.Feature} feature Feature.
* @return {?} Callback result.

View File

@@ -12,7 +12,6 @@ goog.require('ol.proj');
goog.require('ol.source.State');
goog.require('ol.source.TileImage');
goog.require('ol.tilecoord');
goog.require('ol.tilegrid.XYZ');
@@ -103,44 +102,47 @@ ol.source.BingMaps.prototype.handleImageryMetadataResponse =
var maxZoom = this.maxZoom_ == -1 ? resource.zoomMax : this.maxZoom_;
var sourceProjection = this.getProjection();
var tileGrid = new ol.tilegrid.XYZ({
extent: ol.tilegrid.extentFromProjection(sourceProjection),
var extent = ol.tilegrid.extentFromProjection(sourceProjection);
var tileSize = resource.imageWidth == resource.imageHeight ?
resource.imageWidth : [resource.imageWidth, resource.imageHeight];
var tileGrid = ol.tilegrid.createXYZ({
extent: extent,
minZoom: resource.zoomMin,
maxZoom: maxZoom,
tileSize: resource.imageWidth == resource.imageHeight ?
resource.imageWidth : [resource.imageWidth, resource.imageHeight]
tileSize: tileSize
});
this.tileGrid = tileGrid;
var culture = this.culture_;
this.tileUrlFunction = ol.TileUrlFunction.withTileCoordTransform(
tileGrid.createTileCoordTransform(),
ol.TileUrlFunction.createFromTileUrlFunctions(
goog.array.map(
resource.imageUrlSubdomains,
function(subdomain) {
var imageUrl = resource.imageUrl
.replace('{subdomain}', subdomain)
.replace('{culture}', culture);
return (
/**
* @param {ol.TileCoord} tileCoord Tile coordinate.
* @param {number} pixelRatio Pixel ratio.
* @param {ol.proj.Projection} projection Projection.
* @return {string|undefined} Tile URL.
*/
function(tileCoord, pixelRatio, projection) {
goog.asserts.assert(ol.proj.equivalent(
projection, sourceProjection),
'projections are equivalent');
if (goog.isNull(tileCoord)) {
return undefined;
} else {
return imageUrl.replace(
'{quadkey}', ol.tilecoord.quadKey(tileCoord));
}
});
})));
this.tileUrlFunction = ol.TileUrlFunction.createFromTileUrlFunctions(
goog.array.map(
resource.imageUrlSubdomains,
function(subdomain) {
var quadKeyTileCoord = [0, 0, 0];
var imageUrl = resource.imageUrl
.replace('{subdomain}', subdomain)
.replace('{culture}', culture);
return (
/**
* @param {ol.TileCoord} tileCoord Tile coordinate.
* @param {number} pixelRatio Pixel ratio.
* @param {ol.proj.Projection} projection Projection.
* @return {string|undefined} Tile URL.
*/
function(tileCoord, pixelRatio, projection) {
goog.asserts.assert(ol.proj.equivalent(
projection, sourceProjection),
'projections are equivalent');
if (goog.isNull(tileCoord)) {
return undefined;
} else {
ol.tilecoord.createOrUpdate(tileCoord[0], tileCoord[1],
-tileCoord[2] - 1, quadKeyTileCoord);
return imageUrl.replace('{quadkey}', ol.tilecoord.quadKey(
quadKeyTileCoord));
}
});
}));
if (resource.imageryProviders) {
var transform = ol.proj.getTransformFromProjections(

View File

@@ -75,9 +75,9 @@ ol.source.Source = function(options) {
/**
* @private
* @type {boolean|undefined}
* @type {boolean}
*/
this.wrapX_ = options.wrapX;
this.wrapX_ = goog.isDef(options.wrapX) ? options.wrapX : false;
};
goog.inherits(ol.source.Source, ol.Object);

View File

@@ -111,7 +111,7 @@ ol.source.TileArcGISRest.prototype.getRequestUrl_ =
params['BBOX'] = tileExtent.join(',');
params['BBOXSR'] = srid;
params['IMAGESR'] = srid;
params['DPI'] = 90 * pixelRatio;
params['DPI'] = Math.round(90 * pixelRatio);
var url;
if (urls.length == 1) {

View File

@@ -7,7 +7,6 @@ goog.require('ol.dom');
goog.require('ol.size');
goog.require('ol.source.Tile');
goog.require('ol.tilecoord');
goog.require('ol.tilegrid.TileGrid');
@@ -15,10 +14,11 @@ goog.require('ol.tilegrid.TileGrid');
* @constructor
* @extends {ol.Tile}
* @param {ol.TileCoord} tileCoord Tile coordinate.
* @param {ol.tilegrid.TileGrid} tileGrid Tile grid.
* @param {ol.Size} tileSize Tile size.
* @param {string} text Text.
* @private
*/
ol.DebugTile_ = function(tileCoord, tileGrid) {
ol.DebugTile_ = function(tileCoord, tileSize, text) {
goog.base(this, tileCoord, ol.TileState.LOADED);
@@ -26,8 +26,13 @@ ol.DebugTile_ = function(tileCoord, tileGrid) {
* @private
* @type {ol.Size}
*/
this.tileSize_ = ol.size.toSize(
tileGrid.getTileSize(tileCoord[0]));
this.tileSize_ = tileSize;
/**
* @private
* @type {string}
*/
this.text_ = text;
/**
* @private
@@ -58,8 +63,7 @@ ol.DebugTile_.prototype.getImage = function(opt_context) {
context.textAlign = 'center';
context.textBaseline = 'middle';
context.font = '24px sans-serif';
context.fillText(ol.tilecoord.toString(this.tileCoord),
tileSize[0] / 2, tileSize[1] / 2);
context.fillText(this.text_, tileSize[0] / 2, tileSize[1] / 2);
this.canvasByContext_[key] = context.canvas;
return context.canvas;
@@ -87,7 +91,8 @@ ol.source.TileDebug = function(options) {
goog.base(this, {
opaque: false,
projection: options.projection,
tileGrid: options.tileGrid
tileGrid: options.tileGrid,
wrapX: goog.isDef(options.wrapX) ? options.wrapX : true
});
};
@@ -102,7 +107,12 @@ ol.source.TileDebug.prototype.getTile = function(z, x, y) {
if (this.tileCache.containsKey(tileCoordKey)) {
return /** @type {!ol.DebugTile_} */ (this.tileCache.get(tileCoordKey));
} else {
var tile = new ol.DebugTile_([z, x, y], this.tileGrid);
var tileSize = ol.size.toSize(this.tileGrid.getTileSize(z));
var tileCoord = [z, x, y];
var textTileCoord = this.getTileCoordForTileUrlFunction(tileCoord);
var text = goog.isNull(textTileCoord) ? '' : ol.tilecoord.toString(
this.getTileCoordForTileUrlFunction(textTileCoord));
var tile = new ol.DebugTile_(tileCoord, tileSize, text);
this.tileCache.set(tileCoordKey, tile);
return tile;
}

View File

@@ -93,7 +93,8 @@ ol.source.TileImage.prototype.getTile =
} else {
goog.asserts.assert(projection, 'argument projection is truthy');
var tileCoord = [z, x, y];
var urlTileCoord = this.getWrapXTileCoord(tileCoord, projection);
var urlTileCoord = this.getTileCoordForTileUrlFunction(
tileCoord, projection);
var tileUrl = goog.isNull(urlTileCoord) ? undefined :
this.tileUrlFunction(urlTileCoord, pixelRatio, projection);
var tile = new this.tileClass(

View File

@@ -17,7 +17,6 @@ goog.require('ol.extent');
goog.require('ol.proj');
goog.require('ol.source.State');
goog.require('ol.source.TileImage');
goog.require('ol.tilegrid.XYZ');
@@ -69,16 +68,14 @@ ol.source.TileJSON.prototype.handleTileJSONResponse = function(tileJSON) {
}
var minZoom = tileJSON.minzoom || 0;
var maxZoom = tileJSON.maxzoom || 22;
var tileGrid = new ol.tilegrid.XYZ({
var tileGrid = ol.tilegrid.createXYZ({
extent: ol.tilegrid.extentFromProjection(sourceProjection),
maxZoom: maxZoom,
minZoom: minZoom
});
this.tileGrid = tileGrid;
this.tileUrlFunction = ol.TileUrlFunction.withTileCoordTransform(
tileGrid.createTileCoordTransform({extent: extent}),
ol.TileUrlFunction.createFromTemplates(tileJSON.tiles));
this.tileUrlFunction = ol.TileUrlFunction.createFromTemplates(tileJSON.tiles);
if (goog.isDef(tileJSON.attribution) &&
goog.isNull(this.getAttributions())) {

View File

@@ -2,6 +2,7 @@ goog.provide('ol.source.Tile');
goog.provide('ol.source.TileEvent');
goog.provide('ol.source.TileOptions');
goog.require('goog.asserts');
goog.require('goog.events.Event');
goog.require('ol.Attribution');
goog.require('ol.Extent');
@@ -216,28 +217,24 @@ ol.source.Tile.prototype.getTilePixelSize =
/**
* Handles x-axis wrapping. When `wrapX` is `undefined` or the projection is not
* a global projection, `tileCoord` will be returned unaltered. When `wrapX` is
* `true`, the tile coordinate will be wrapped horizontally.
* When `wrapX` is `false`, `null` will be returned for tiles that are
* outside the projection extent.
* Returns a tile coordinate wrapped around the x-axis. When the tile coordinate
* is outside the resolution and extent range of the tile grid, `null` will be
* returned.
* @param {ol.TileCoord} tileCoord Tile coordinate.
* @param {ol.proj.Projection=} opt_projection Projection.
* @return {ol.TileCoord} Tile coordinate.
* @return {ol.TileCoord} Tile coordinate to be passed to the tileUrlFunction or
* null if no tile URL should be created for the passed `tileCoord`.
*/
ol.source.Tile.prototype.getWrapXTileCoord =
ol.source.Tile.prototype.getTileCoordForTileUrlFunction =
function(tileCoord, opt_projection) {
var projection = goog.isDef(opt_projection) ?
opt_projection : this.getProjection();
var tileGrid = this.getTileGridForProjection(projection);
var wrapX = this.getWrapX();
if (goog.isDef(wrapX) && tileGrid.isGlobal(tileCoord[0], projection)) {
return wrapX ?
ol.tilecoord.wrapX(tileCoord, tileGrid, projection) :
ol.tilecoord.clipX(tileCoord, tileGrid, projection);
} else {
return tileCoord;
goog.asserts.assert(!goog.isNull(tileGrid), 'tile grid needed');
if (this.getWrapX() && projection.isGlobal()) {
tileCoord = ol.tilecoord.wrapX(tileCoord, tileGrid, projection);
}
return ol.tilecoord.withinExtentAndZ(tileCoord, tileGrid) ? tileCoord : null;
};

View File

@@ -13,7 +13,6 @@ goog.require('ol.extent');
goog.require('ol.proj');
goog.require('ol.source.State');
goog.require('ol.source.Tile');
goog.require('ol.tilegrid.XYZ');
@@ -122,7 +121,7 @@ ol.source.TileUTFGrid.prototype.handleTileJSONResponse = function(tileJSON) {
}
var minZoom = tileJSON.minzoom || 0;
var maxZoom = tileJSON.maxzoom || 22;
var tileGrid = new ol.tilegrid.XYZ({
var tileGrid = ol.tilegrid.createXYZ({
extent: ol.tilegrid.extentFromProjection(sourceProjection),
maxZoom: maxZoom,
minZoom: minZoom
@@ -137,11 +136,7 @@ ol.source.TileUTFGrid.prototype.handleTileJSONResponse = function(tileJSON) {
return;
}
this.tileUrlFunction_ = ol.TileUrlFunction.withTileCoordTransform(
tileGrid.createTileCoordTransform({
extent: extent
}),
ol.TileUrlFunction.createFromTemplates(grids));
this.tileUrlFunction_ = ol.TileUrlFunction.createFromTemplates(grids);
if (goog.isDef(tileJSON.attribution)) {
var attributionExtent = goog.isDef(extent) ?
@@ -178,7 +173,9 @@ ol.source.TileUTFGrid.prototype.getTile =
} else {
goog.asserts.assert(projection, 'argument projection is truthy');
var tileCoord = [z, x, y];
var tileUrl = this.tileUrlFunction_(tileCoord, pixelRatio, projection);
var urlTileCoord =
this.getTileCoordForTileUrlFunction(tileCoord, projection);
var tileUrl = this.tileUrlFunction_(urlTileCoord, pixelRatio, projection);
var tile = new ol.source.TileUTFGridTile_(
tileCoord,
goog.isDef(tileUrl) ? ol.TileState.IDLE : ol.TileState.EMPTY,

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