Previously, listeners for the Snap
interaction's snap
event received null
as value for the feature
property when snapped to a segment. Now, the value of the feature
property is always set to the snapped feature.
To distinguish between a vertex and a segment snap, look at the snap
event's segment
property. It will set to null
on a vertex snap, and to the snapped segment on a segment snap.
No special changes are required when upgrading to the 9.1.0 release.
Decluttered items in Vector and VectorTile layers now maintain the render order of the layers and within a layer. They do not get lifted to a higher place in the stack any more.
For most use cases, this is the desired behavior. If, however, you've been relying on the previous behavior, you now have to create separate layers above the layer stack, with just the styles for the declutter items.
It is no longer necessary to call this function to put layers above decluttered symbols and text, because decluttering no longer lifts elements above the layer stack.
To upgrade, simply remove the code where you use the flushDeclutterItems()
method.
- Removed the
ol/style/RegularShape
'sradius1
property. Useradius
for regular polygons orradius
andradius2
for stars. - Removed the
shape-radius1
property fromol/style/flat~FlatShape
. Useshape-radius
instead.
ol/geom/GeometryCollection
can no longer be created without providing a Geometry array. Empty arrays are still valid.
- The
finishDrawing()
method now returns the drawn feature ornull
if no drawing could be finished. Previously it returnedundefined
.
The ZoomToExtent
control now expects geographic coordinates when useGeographic
is set. Before it expected coordinates in the projection of the map.
- Deprecated
ol/AssertionError
and error codes have been removed.
The Stamen map tiles are now hosted by Stadia Maps. See the announcement about the partnership and the migration guide from Stadia Maps.
If you were previously using the Stamen
source in your application, update this to use the StadiaMaps
source instead.
import Map from 'ol/Map.js';
-import Stamen from 'ol/source/Stamen.js';
+import StadiaMaps from 'ol/source/StadiaMaps.js';
import TileLayer from 'ol/layer/Tile.js';
import View from 'ol/View.js';
const map = new Map({
layers: [
+ // NOTE: Layers from Stadia Maps do not require an API key for localhost development or most production
+ // web deployments. See https://docs.stadiamaps.com/authentication/ for details.
new TileLayer({
- source: new Stamen({
- layer: 'watercolor',
+ source: new StadiaMaps({
+ layer: 'stamen_watercolor',
+ // apiKey: 'OPTIONAL'
}),
}),
new TileLayer({
- source: new Stamen({
- layer: 'terrain-labels',
+ source: new StadiaMaps({
+ layer: 'stamen_terrain_labels',
+ // apiKey: 'OPTIONAL'
}),
}),
],
Simply remove this option if you used it as intended, i.e. to provide the actual image size.
The imageSize
option never worked as advertised. The intended use of imageSize
was to provide the actual size of the image
. This was redundant for all images except SVG images with intrinsic sizing, but for those it never worked.
What the imageSize
option actually did when a size different from the actual image size was provided (unintended use), was a modification of the imageExtent
.
So for an image with an actual width and height of 256 pixels and an incorrectly configured image size of [254, 254]
, this was what actually happened:
const extent = [
-13629027.891360067, 4539747.983913189,
-13619243.951739565, 4559315.863154193,
];
const staticOptions = {
url: myImageUrl,
imageExtent: [
...getBottomLeft(extent),
imageExtent[0] + (getWidth(extent) / 254) * 256,
imageExtent[1] + (getHeight(extent) / 254) * 256,
]
};
Try to get rid of such an unintended use, or replace the imageSize
option with an extent calculation like the above.
The imgSize
property is no longer needed. If you had it configured, simply remove it.
This property is no longer needed and can simply be removed.
The WebGLPointsLayer
class used to rely on a custom style format that was made specifically for this layer and which looked like this:
const circleStyle = {
symbol: {
symbolType: 'circle',
size: 10,
color: 'orange'
}
}
const iconStyle = {
symbol: {
symbolType: 'image',
src: '../images/icon.png',
size: [16, 32],
textureCoord: [0, 0, 0.25, 1]
}
}
Since then, a flat style format was introduced in the library which offered a more complete way to express styling for points, and covered the capabilities of the other renderers as well:
const circleStyle = {
'circle-radius': 8,
'circle-fill-color': 'blue',
'circle-stroke-width': 2,
'circle-stroke-color': 'darkblue',
}
const starStyle = {
'shape-radius1': 12,
'shape-radius2': 6,
'shape-points': 5,
'shape-fill-color': 'blue',
'shape-stroke-width': 2,
'shape-stroke-color': 'darkblue',
}
const iconStyle = {
'icon-src': '../images/icon.png',
'icon-scale': 2,
'icon-size': [16, 16],
'icon-offset': [32, 64],
}
From now on, only this new styling format will be supported. Support for the previous styling format is dropped and any usage of it will not show anything on screen. This is also true for the WebGLVectorLayerRenderer
and WebGLVectorTileRenderer
classes.
Here is a quick guide to help you migrate to the new style format:
- for
symbolType: 'circle'
:- set
circle-radius
to half of thesymbol.size
value - if using an array for the
symbol.size
property, use a combination ofcircle-radius
andcircle-scale
- set
circle-fill-color
to thesymbol.color
value
- set
- for
symbolType: 'triangle'
:- set
shape-points
to3
- set
shape-radius
to half of thesymbol.size
value - if using an array for the
symbol.size
property, use a combination ofshape-radius
andshape-scale
- set
- for
symbolType: 'square'
:- set
shape-points
to4
- set
shape-radius1
to half of thesymbol.size
value - set
shape-radius2
to half of thesymbol.size
value multiplied byMath.sqrt(2)
- if using an array for the
symbol.size
property, use a combination ofshape-radius1
,shape-radius2
andshape-scale
- set
shape-fill-color
to thesymbol.color
value
- set
- for
symbolType: 'image'
:- set
icon-src
to thesymbol.src
value - set
icon-width
andicon-height
according to thesymbol.size
value - set
icon-color
to thesymbol.color
value - if using the
symbol.textureCoord
property, use a combination oficon-size
andicon-offset
to achieve the same result; note that these are expressed in pixels!
- set
- for all symbol types (
*
has to be replaced bycircle
,shape
oricon
accordingly):- set
*-rotation
to thesymbol.rotation
value - set
*-opacity
to thesymbol.opacity
value - set
*-displacement
to thesymbol.offset
value - set
*-rotate-with-view
to thesymbol.rotateWithView
value
- set
Please note that not all the point styling options are yet supported by WebGL renderers. Unsupported options are:
- decluttering
- dash and line joins for outlines
- fill patterns
Previously with some styles involving image or text scale or rotation, or view rotation ol/render/canvas/Immediate#drawFeature
and ol/render/canvas/Immediate#drawGeometry
might reset any canvas context transform set by the application. If you were relying on this unintended and inconsistent behavior the application must now reset the context itself.
To avoid a circular dependency between the ol
and ol-mapbox-style
packages, this layer has been removed. If you have been using ol/layer/MapboxVector
, you can easily switch to using MapboxVectorLayer
from the ol-mapbox-style
package, version 11 or greater.
Before:
import MapboxVectorLayer from 'ol/layer/MapboxVector';
After:
import {MapboxVectorLayer} from 'ol-mapbox-style';
The ol/webGL/Buffer
, ol/webgl/PostProcessingPass
and ol/webgl/RenderTarget
classes have been removed from the API. If you rely on these, try to stop depending on them, or at least watch out for changes with every new relase, because changes or removal won't be mentioned any more in the upgrade notes.
If ol/style/RegularShape
or ol/style/Circle
is passed an ol/style/Stroke
with the lineDash option, the new default lineCap is 'round'. Previously the lineCap option was ignored and the canvas' default of 'butt' was used.
Previously, text labels with transparent fills were not hit detected. Now, you can control whether a transparent fill in a text label is hit detected or not.
To create a text style with a transparent fill that will be hit detected, use a fill with 'transparent'
as the color.
// transparent fill, will be hit detected
const style = Style({
text: new Text({
fill: new Fill({
color: 'transparent',
}),
stroke: new Stroke({
color: 'red',
width: 2,
}),
}),
});
Or, if using the flat literal style syntax:
// transparent fill, will be hit detected
const style = {
'text-fill-color': 'transparent',
'text-stroke-color': 'red',
'text-stroke-width': 2,
}
By contrast, if you want a transparent fill that will not be hit detected, do the following:
// absent fill, will not be hit detected
const style = Style({
text: new Text({
fill: null,
stroke: new Stroke({
color: 'red',
width: 2,
}),
}),
});
Or, if using the flat literal style syntax:
// absent fill, will not be hit detected
const style = {
'text-fill-color': 'none',
'text-stroke-color': 'red',
'text-stroke-width': 2,
}
The start
and end
behavior previously was equivalent to right
and left
. Now it takes the text direction into account, so it will mean left
and right
for left-to-right text.
MultiLineString stroke, and Polygon, MultiPolygon and Circle geometry outlines are now hit detected along their entire length by ol/Map
methods (forEachFeatureAtPixel
, getFeaturesAtPixel
, hasFeatureAtPixel
) even if the line is dashed. This is consistent with LineString stroke and the getFeatures
methods of ol/layer/Vector
and ol/layer/VectorTile
.
ol/style/Image
subclasses are hit detected regardless of their opacity
setting. This makes icon styles consistent with the use of transparent fill in regular shapes.
Previously, ol/source/Raster
processed input sources at the current view resolution, which caused interpolation artefacts in cases where input sources were up- or downsampled. Now, ol/source/Raster
picks up the resolutions from the first input source that has resolutions configured (either implicitly through a tile grid in the case of tile sources, or directly when configured through the resolutions
constructor option). This improves the rendered output in most cases.
If the previous behavior is desired, configure the source with resolutions: null
.
Previously, ol/control/MousePosition
always displayed coordinates as-is. Now it has a wrapX
option,
which is true
by default. This avoids longitudes outside the -180 to 180 degrees range.
If you want the previous behavior, which displays coordinates with longitudes less than -180 or greater than 180, configure the control with wrapX: false
.
If you have been using the full (or legacy) build of the library, note that the location of these scripts is changing for this and future releases. The previous locations were not stable, and although we do not recommend linking to the full build for production applications, there are many instances of this that were breaking due to changing URLs. See the download page for details on the new versioned URLs for the full build.
Future versions will no longer throw ol/AssertionError
with an error code
. Instead, they will throw Error
with just the error message.
The updateParams()
method is the only way to update WMS parameters. Changes made directly to the params
object passed as a constructor option will have no effect.
- The
tilePixelRatio
has been removed from theDataTile
source. - The
imageSmoothing
option has been removed from sources. - The
undefinedHTML
option has been removed from theMousePosition
control. - The
forEachLayerAtPixel
method has been removed from theMap
class. - Deprecated options have been removed from the
Overlay
component. - The
labelCache
has been removed from theol/render/canvas.js
module.
Please see https://docs.microsoft.com/en-us/lifecycle/announcements/internet-explorer-11-end-of-support.
The toStringHDMS
function from the ol/coordinate.js
module now formats longitude, latitude pairs so that the minutes and seconds are omitted if they are zero. This changes the values displayed on graticules.
The default intervals
now align with integer minutes and seconds better suited to the default label formatter. If formatting in decimal degrees you may wish to specify custom intervals
suited to that format.
Inserting with setAt
or insertAt
beyond the current length used to create a sparse Collection with undefined
inserted for any missing indexes. This will now throw an error instead.
The control will now by default keep displaying the last mouse position when the mouse leaves the viewport. With placeholder: ' '
you can keep the old behaviour. The placeholder
option no longer accepts false
as a valid value, instead simply omit the option. The undefinedHTML
option has been removed. You should use placeholder
instead.
The PluggableMap
class has been removed. If you want to create a custom map class, extend the Map
class instead.
ol/style/Image
and subclasses displacement
is no longer scaled with the image. If you previously expected this unintended behavior you should now increase the displacement when setting the scale.
If you were previously trying to scale data tiles using the tilePixelRatio
property for data tile sources (this is rare), you should now use the explicit tileSize
and tileGrid
properties. The source's tileSize
represents the source tile dimensions and the tile grid's tileSize
represents the desired rendered dimensions.
const source = new DataTileSource({
tileSize: [512, 512], // source tile size
tileGrid: createXYZ({tileSize: [256, 256]}), // rendered tile size
});
The forward
and inverse
functions passed to addCooordinateTransforms
now receive a coordinate with all dimensions of the original coordinate, not just two. If you previously had coordinates with more than two dimensions and added a transform like
addCoordinateTransforms(
'EPSG:4326',
new Projection({code: 'latlong', units: 'degrees'}),
function(coordinate) { return coordinate.reverse(); },
function(coordinate) { return coordinate.reverse(); }
);
you have to change that to
addCoordinateTransforms(
'EPSG:4326',
new Projection({code: 'latlong', units: 'degrees'}),
function(coordinate) { return coordinate.slice(0, 2).reverse() },
function(coordinate) { return coordinate.slice(0, 2).reverse() }
);
This change only affects users that were using the non-API string enums
- ol/OverlayPositioning
- ol/extent/Corner
- ol/format/FormatType
- ol/geom/GeometryType
- ol/source/State
- ol/source/WMSServerType
- ol/source/WMTSRequestEncoding
Instead of these, use the respective string
s, which are now typesafe by means of union types.
No special changes are required when upgrading to the 6.14.0 release.
Raster layers (static images, image tiles, data tiles) have a new layer.getData(pixel)
method that returns the pixel data at the provided location. The return value depends on the underlying source data type. For example, a GeoTIFF may return a Float32Array
with one value per band, while a PNG rendered from a tile layer will return a Uint8ClampedArray
of RGBA values.
If you were previously using the map.forEachLayerAtPixel()
method, you should use the new layer.getData()
method instead. The old method returns composite pixel values from multiple layers and is limited to RGBA values. The new method doesn't suffer from these shortcomings and is more performant.
The map.forEachLayerAtPixel()
method has been deprecated. It will be removed (or its behavior may change) in the next major release. Please use the layer.getData()
method instead.
No special changes are required when upgrading to the 6.12.0 release.
No special changes are required when upgrading to the 6.11.0 release.
Sources now have an interpolate
option. This option controls whether data from the source is interpolated when resampling.
For ol/source/DataTile
sources, the default is interpolate: false
. This means that when a data tile source is used with a WebGL tile layer renderer, your style expression will have access to pixel values in the data tiles without interpolation. If this option is set to true, linear interpolation will be used when over- or under-sampling the data.
The imageSmoothing
option for sources has been deprecated and will be removed in the next major release. Use the interpolate
option instead.
// if you were using `imageSmoothing`
const before = new TileSource({
imageSmoothing: false
});
// use the `interpolate` option instead
const after = new TileSource({
interpolate: false
});
There should be nothing special required when upgrading from v6.8 to v6.9.
There should be nothing special required when upgrading from v6.7 to v6.8.
There should be nothing special required when upgrading from v6.6 to v6.7.
The ol package now includes TypeScript declarations as *.d.ts
files.
If desired, e.g. when you don't want to adjust your code after upgrading from a previous version where you used @types/ol
, you can opt out of the included types and use third-party types by specifying aliases in the compilerOptions
section of tsconfig.json
, e.g.
"baseUrl": "./",
"paths": {
"ol": ["node_modules/@types/ol"],
"ol/*": ["node_modules/@types/ol/*"]
},
The undefinedHTML
option for the MousePosition control has been deprecated and will be removed in a future release. Use the new placeholder
option instead.
When the mouse position is not available, the control renders a non-breaking space. To render something else instead,
set the placeholder
option. If you want to retain the last position when the mouse leaves the viewport, set
placeholder: false
. This will be the default behavior in a future release.
The placeholder
option has no effect if the deprecated undefinedHTML
option is also used. You should use the placeholder
option instead of undefinedHTML
.
renderMode: 'image'
for vector tile layers has been deprecated. Applications continue to work, but a warning will be issued to the console. To get rid of the warning, simply remove the renderMode
option.
Previously, the hitTolerance
option of the map's getFeaturesAtPixel()
, forEachFeatureAtPixel()
and hasFeatureAtPixel()
methods behaved differently depending on the devicePixelRatio
(or the pixelRatio
of the map), because the original value was internally multiplied by the device pixel ratio twice instead of just once. Now this is fixed. Note: The hitTolerance
's units are css pixels. The documentation was updated to reflect this.
If your application adjusts for that with code like
{ hitTolerance: 10 / devicePixelRatio, }
you'll have to change that code to
{ hitTolerance: 10, }
Now that all major browsers support Pointer events natively, we removed the elm-pep dependency. If you are targeting older browsers that do not support Pointer events, you now need to include a pointer events polyfill (elm-pep or pepjs) in your application.
Previously, when the Geolocation class encounter an error the tracking was stopped. It now continues to track. To get the previous behavior, use the following code:
geolocation.on('error', function (error) {
geolocation.setTracking(false);
});
Previously, when an extent crossed the date line, vector source loaders were called with an extent with 540 degrees of longitude. Now, two loader calls with the visible extent on both sides of the projection extent are issued. This should not require any application code changes, but may affect custom loaders.
Due to performance considerations, the layers in a map will sometimes be rendered into one
single canvas instead of separate elements.
This means map.forEachLayerAtPixel
will bring up false positives.
The easiest solution to avoid that is to assign different className
properties to each layer like so:
new Layer({
// ...
className: 'my-layer'
})
Please note that this may incur a significant performance loss when dealing with many layers and/or targeting mobile devices.
If you were previously using this constant, you can check if 'ontouchstart'
is defined in window
instead.
if ('ontouchstart' in window) {
// ...
}
If you were previously using this constant, you can check if 'geolocation'
is defined in navigator
instead.
if ('geolocation' in navigator) {
// ...
}
The CSS media print rules were removed from the ol.css
file. To get the previous behavior, use the following CSS:
@media print {
.ol-control {
display: none;
}
}
The optional this (i.e. opt_this) arguments were removed from the following methods. Please use closures, the es6 arrow function or the bind method to achieve this effect (Bind is explained here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind).
forEachCorner
inol/extent
LRUCache#forEach
RBush#forEach
andRBush#forEachInExtent
The setCenter
, setZoom
, setResolution
and setRotation
methods on ol/View
do not bypass constraints anymore
Previously, these methods allowed setting values that were inconsistent with the given view constraints. This is no longer the case and all changes to the view state now follow the same logic: target values are provided and constraints are applied on these to determine the actual values to be used.
Removal of the constrainResolution
option on View.fit
, PinchZoom
, MouseWheelZoom
and ol/interaction.js
The constrainResolution
option is now only supported by the View
class. A View.setConstrainResolution
method was added as well.
Generally, the responsibility of applying center/rotation/resolutions constraints was moved from interactions and controls to the View
class.
Previously, this options only constrained the view center. This behaviour can still be obtained by specifying constrainOnlyCenter
in the view options.
As a side effect, the view rotate
method is gone and has been replaced with adjustRotation
which takes a delta as input.
Previously, maps showed multiple worlds at low zoom levels. In addition, it used to be possible to pan off the north or south edge of the world. Now, the view is restricted to show only one world, and you cannot pan off the edge. To get the previous behavior, configure the ol/View
with multiWorld: true
.
The inherits
function that was used to inherit the prototype methods from one constructor into another has been removed.
The standard ECMAScript classes should be used instead.
The deprecated getSnapToPixel
and setSnapToPixel
functions from the ImageStyle
class have been removed.
Previously, the internal tile coordinates used in the library had an unusual row order – the origin of the tile coordinate system was at the top left as expected, but the rows increased upwards. This meant that all tile coordinates within a tile grid's extent had negative y
values.
Now, the internal tile coordinates used in the library have the same row order as standard (e.g. XYZ) tile coordinates. The origin is at the top left (as before), and rows or y
values increase downward. So the top left tile of a tile grid is now 0, 0
, whereas it was 0, -1
before.
x, y values for tile coordinates
origin
*__________________________
| | | |
| 0, 0 | 1, 0 | 2, 0 |
|________|________|________|
| | | |
| 0, 1 | 1, 1 | 2, 1 |
|________|________|________|
| | | |
| 0, 2 | 1, 2 | 2, 2 |
|________|________|________|
This change should only affect you if you were using a custom tileLoadFunction
or tileUrlFunction
. For example, if you used to have a tileUrlFunction
that looked like this:
// before
function tileUrlFunction(tileCoord) {
const z = tileCoord[0];
const x = tileCoord[1];
const y = -tileCoord[2] - 1;
// do something with z, x, y
}
You would now do something like this:
// after
function tileUrlFunction(tileCoord) {
const z = tileCoord[0];
const x = tileCoord[1];
const y = tileCoord[2];
// do something with z, x, y
}
In addition (this should be exceedingly rare), if you previously created a ol/tilegrid/WMTS
by hand and you were providing an array of sizes
, you no longer have to provide a negative height if your tile origin is the top-left corner (the common case). On the other hand, if you are providing a custom array of sizes
and your origin is the bottom of the grid (this is uncommon), your height values must now be negative.
If you were previously using VectorTile
layers with renderMode: 'vector'
, you have to remove this configuration option. That mode was removed. 'hybrid'
(default) and 'image'
are still available.
If you were previously using Vector
layers with renderMode: 'image'
, you have to remove this configuration option. Instead, use the new ol/layer/VectorImage
layer with your ol/source/Vector
.
If a map has more than one layer with declutter
set to true, decluttering now considers all Vector
and VectorTile
layers, instead of decluttering each layer separately. Only VectorImage
layers continue to be decluttered separately. The higher the z-index of a layer, the higher the priority of its decluttered items.
Within a layer, the declutter order has changed. Previously, styles with a lower zIndex
were prioritized over those with a higher zIndex
. Now the opposite order is used.
On vector layers, even if decluttered images or texts have a lower z-Index than polygons or lines, they will now be rendered on top of the polygons or lines. For vector tile layers, this was the case already in previous releases.
If you were previously registering for precompose
and postcompose
events, you should now register for prerender
and postrender
events on layers. Instead of the previous render
event, you should now listen for postrender
. Layers are no longer composed to a single Canvas element. Instead, they are added to the map viewport as individual elements.
Previously, render events included a vectorContext
property that allowed you to render features or geometries directly to the map. This is still possible, but you now have to explicitly create a vector context with the getVectorContext
function. This change makes the immediate rendering API an explicit dependency if your application uses it. If you don't use this API, your application bundle will not include the vector rendering modules (as it did before).
Here is an abbreviated example of how to use the getVectorContext
function:
import {getVectorContext} from 'ol/render';
// construct your map and layers as usual
layer.on('postrender', function(event) {
const vectorContext = getVectorContext(event);
// use any of the drawing methods on the vector context
});
Previously, it was possible to render a single layer in two maps. Now, each layer can only belong to a single map (in the same way that a single DOM element can only have one parent).
Due to the constraint above (layers can only be added to a single map), the overview map needs to be constructed with a list of layers.
Previously, a graticule was not a layer. Now it is. See the graticule example for details on how to add a graticule layer to your map.
The getLastExtent()
method, which was required for custom tileLoadFunction
s in ol/source/Vector
, has been removed because it is no longer needed (see below).
- Removal of the
getProjection()
andsetProjection()
methods. These were used in customtileLoadFunction
s onol/source/VectorTile
, which work differently now (see below). - Removal of the
getExtent()
andsetExtent()
methods. These were used in customtileLoadFunction
s onol/source/VectorTile
, which work differently now (see below).
Previously, applications needed to call setProjection()
and setExtent()
on the tile in a custom tileLoadFunction
on ol/source/VectorTile
. The format's getLastExtent()
method was used to get the extent. All this is no longer needed. Instead, the extent
(first argument to the loader function) and projection
(third argument to the loader function) are simply passed as extent
and featureProjection
options to the format's readFeatures()
method.
Example for an old tileLoadFunction
:
function(tile, url) {
tile.setLoader(function() {
fetch(url).then(function(response) {
response.arrayBuffer().then(function(data) {
var format = tile.getFormat();
tile.setProjection(format.readProjection(data));
tile.setFeatures(format.readFeatures(data, {
// featureProjection is not required for ol/format/MVT
featureProjection: map.getView().getProjection()
}));
tile.setExtent(format.getLastExtent());
})
})
}
});
This function needs to be changed to:
function(tile, url) {
tile.setLoader(function(extent, resolution, projection) {
fetch(url).then(function(response) {
response.arrayBuffer().then(function(data) {
var format = tile.getFormat();
tile.setFeatures(format.readFeatures(data, {
// extent is only required for ol/format/MVT
extent: extent,
featureProjection: projection
}));
})
})
}
});
The WebGL map and layers renderers are gone, replaced by a WebGLHelper
function that provides a lightweight,
low-level access to the WebGL API. This is implemented in a new WebGLPointsLayer
which does simple rendering of large number
of points with custom shaders.
This is now used in the Heatmap
layer.
The removed classes and components are:
WebGLMap
andWebGLMapRenderer
WebGLLayerRenderer
WebGLImageLayer
andWebGLImageLayerRenderer
WebGLTileLayer
andWebGLTileLayerRenderer
WebGLVectorLayer
andWebGLVectorLayerRenderer
WebGLReplay
and derived classes, along with associated shadersWebGLReplayGroup
WebGLImmediateRenderer
WebGLMap
- The shader build process using
mustache
and theMakefile
at the root
Following the removal of the experimental WebGL renderer, the AtlasManager has been removed as well. The atlas was only used by this renderer.
The non API getChecksum
functions of the style is also removed.
The ol/source/Vector#clear()
method no longer triggers a reload of the data from the server. If you were previously using clear()
to refetch from the server, you now have to use refresh()
.
The ol/source/Vector#refresh()
method now removes all features from the source and triggers a reload of the data from the server. If you were previously using the refresh()
method to re-render a vector layer, you should instead call ol/layer/Vector#changed()
.
The getGetFeatureInfoUrl
of ol/source/ImageWMS
and ol/source/TileWMS
is now called getFeatureInfoUrl
.
getFeaturesAtPixel
now returns an empty array instead of null if no features were found.
Hit detection over styled Circle geometry and Circle and RegularShape styles is now consistent with that for styled Polygon geometry. There is no hit detection over the interior of unfilled shapes. To get the previous behavior, specify a Fill style with transparent color.
It is now possible to configure vector tile layers with declutter: true
and renderMode: 'image'
. However, note that decluttering will be done per tile, resulting in labels and point symbols getting cut off at tile boundaries.
Until now, using both options forced the render mode to be hybrid
.
ol/PluggableMap
and subclasses no longer support the loadTilesWhileAnimating
and loadTilesWhileInteracting
options. These options were used to enable tile loading during animations and interactions. With the new DOM composition render strategy, it is no longer necessary to postpone tile loading until after animations or interactions.
The getUid
function from the ol/util
module now returns a string instead of a number.
When a map contains a layer from a ol/source/OSM
source, the ol/control/Attribution
control will be shown with the collapsible: false
behavior.
To get the previous behavior, configure the ol/control/Attribution
control with collapsible: true
.
The snapToPixel
option has been removed, and the getSnapToPixel
and setSnapToPixel
methods are deprecated.
The renderer now snaps to integer pixels when no interaction or animation is running to get crisp rendering. During interaction or animation, it does not snap to integer pixels to avoid jitter.
When rendering with the Immediate API, symbols will no longer be snapped to integer pixels. To get crisp images, set context.imageSmoothingEnabled = false
before rendering with the Immediate API, and context.imageSmoothingEnabled = true
afterwards.
Geometries (ol/geom/*
) now need to be constructed with valid coordinates (center for ol/geom/Circle
) as first constructor argument. The same applies to the setCoordinates()
(setCenter()
for ol/geom/Circle
) method.
The module name is now ol/source/UTFGrid
(ol.source.UTFGrid
in the full build).
Renaming of the defaultDataProjection
in the options and property of the ol/format/Feature
class and its subclasses
The defaultDataProjection
option is now named dataProjection
. The protected property available on the class is also renamed.
The transition
option to get an opacity transition to fade in tiles has been disabled for ol/source/VectorTile
. Vector tiles are now always rendered without an opacity transition.
The origin for gradients and patterns has changed from the top-left corner of the extent of the geometry being filled to 512 css pixel increments from map coordinate [0, 0]
. This allows repeat patterns to be aligned properly with vector tiles. For seamless repeat patterns, width and height of the pattern image must be a factor of two (2, 4, 8, ..., 512).
The renderer
option has been removed from the Map
constructor. The purpose of this change is to avoid bundling code in your application that you do not need. Previously, code for both the Canvas and WebGL renderers was included in all applications - even though most people only use one renderer. The Map
constructor now gives you a Canvas (2D) based renderer. If you want to try the WebGL renderer, you can import the constructor from ol/WebGLMap
.
Old code:
import Map from 'ol/Map';
const canvasMap = new Map({
renderer: ['canvas']
// other options...
});
const webglMap = new Map({
renderer: ['webgl']
// other options...
});
New code:
import Map from 'ol/Map';
import WebGLMap from 'ol/WebGLMap';
const canvasMap = new Map({
// options...
});
const webglMap = new WebGLMap({
// options...
});
The signature of the vector style function passed to the feature has changed. The function now always takes the feature
and the resolution
as arguments, the feature
is no longer bound to this
.
Old code:
feature.setStyle(function(resolution) {
var text = this.get('name');
...
});
New code:
feature.setStyle(function(feature, resolution) {
var text = feature.get('name');
...
});
For better drawing experience, two changes were made to the behavior of the Draw interaction:
- On long press, the current vertex can be dragged to its desired position.
- On touch move (e.g. when panning the map on a mobile device), no draw cursor is shown, and the geometry being drawn is not updated. But because of 1., the draw cursor will appear on long press. Mouse moves are not affected by this change.
Because relying on a globally available proj4 is not practical with ES modules, we have made a change to the way we integrate proj4:
- The
setProj4()
function from theol/proj
module was removed. - A new
ol/proj/proj4
module with aregister()
function was added. Regardless of whether the application importsproj4
or uses a globalproj4
, this function needs to be called with the proj4 instance as argument whenever projection definitions were added to proj4's registry with (proj4.defs
).
It is also recommended to no longer use a global proj4
. Instead,
npm install proj4
and import it:
import proj4 from 'proj4';
Applications can be updated by importing the register
function from the ol/proj/proj4
module
import {register} from 'ol/proj/proj4'
and calling it before using projections, and any time the proj4 registry was changed by proj4.defs()
calls:
register(proj4);
The map and sources no longer accept a logo
option. Instead, if you wish to append a logo to your map, add the desired markup directly in your HTML. In addition, you can use the attributions
property of a source to display arbitrary markup per-source with the attribution control.
The ol/Sphere
constructor has been removed. If you were using the getGeodesicArea
method, use the getArea
function instead. If you were using the haversineDistance
method, use the getDistance
function instead.
Examples before:
// using ol@4
import Sphere from 'ol/sphere';
var sphere = new Sphere(Sphere.DEFAULT_RADIUS);
var area = sphere.getGeodesicArea(polygon);
var distance = sphere.haversineDistance(g1, g2);
Examples after:
// using ol@5
import {circular as circularPolygon} from 'ol/geom/Polygon';
import {getArea, getDistance} from 'ol/sphere';
var area = getArea(polygon);
var distance = getDistance(g1, g2);
var circle = circularPolygon(center, radius);
The circular
function exported from ol/geom/Polygon
no longer requires a Sphere
as the first argument.
Example before:
// using ol@4
import Polygon from 'ol/geom/polygon';
import Sphere from 'ol/sphere';
var poly = Polygon.circular(new Sphere(Sphere.DEFAULT_RADIUS), center, radius);
Example after:
// using ol@5
import {circular as circularPolygon} from 'ol/geom/Polygon';
var poly = circularPolygon(center, radius);
The optional this (i.e. opt_this) arguments were removed from the following methods. Please use closures, the es6 arrow function or the bind method to achieve this effect (Bind is explained here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind).
- Collection#forEach
- geom/LineString#forEachSegment
- Observable#on, #once, #un
- Map#forEachLayerAtPixel
- source/TileUTFGrid#forDataAtCoordinateAndResolution
- source/Vector#forEachFeature, #forEachFeatureInExtent, #forEachFeatureIntersectingExtent
If you are using the layer filter, please note that you now have to pass in the layer filter via an AtPixelOptions
object. If you are not using the layer filter the usage has not changed.
Old syntax:
map.forEachLayerAtPixel(pixel, callback, callbackThis, layerFilterFn, layerFilterThis);
New syntax:
map.forEachLayerAtPixel(pixel, callback, {
layerFilter: layerFilterFn
});
To bind a function to a this, please use the bind method of the function (See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind).
This change is due to the introduction of the hitTolerance
parameter which can be passed in via this AtPixelOptions
object, too.
To update your applications, simply replace exceedLength
with overflow
.
Rendering vector sources as image is now directly supported by ol.layer.Vector
with the new renderMode: 'image'
configuration option. Change code like this:
new ol.layer.Image({
source: new ol.source.ImageVector({
style: myStyle,
source: new ol.source.Vector({
url: 'my/data.json',
format: new ol.format.GeoJSON()
})
})
});
to:
new ol.layer.Vector({
renderMode: 'image',
style: myStyle,
source: new ol.source.Vector({
url: 'my/data.json',
format: new ol.format.GeoJSON()
})
});
Previous version of GeoServer returned invalid crs in GeoJSON output. The workaround in ol.format.GeoJSON
used to read this crs code is now removed.
ol.Attribution
is deprecated and will be removed in the next major version. Instead, you can construct a source with a string attribution or an array of strings. For dynamic attributions, you can provide a function that gets called with the current frame state.
Before:
var source = new ol.source.XYZ({
attributions: [
new ol.Attribution({html: 'some attribution'})
]
});
After:
var source = new ol.source.XYZ({
attributions: 'some attribution'
});
In addition to passing a string or an array of strings for the attributions
option, you can also pass a function that will get called with the current frame state.
var source = new ol.source.XYZ({
attributions: function(frameState) {
// inspect the frame state and return attributions
return 'some attribution'; // or ['multiple', 'attributions'] or null
}
});
Polygon labels are now only rendered when the label does not exceed the polygon at the label position. To get the old behavior, configure your ol.style.Text
with exceedLength: true
.
It is no longer necessary to set the projection on the tile. Instead, the readFeatures
method must be called with the tile's extent as extent
option and the view's projection as featureProjection
.
Before:
tile.setLoader(function() {
var data = // ... fetch data
var format = tile.getFormat();
tile.setFeatures(format.readFeatures(data));
tile.setProjection(format.readProjection(data));
// uncomment the line below for ol.format.MVT only
//tile.setExtent(format.getLastExtent());
});
After:
tile.setLoader(function() {
var data = // ... fetch data
var format = tile.getFormat();
tile.setFeatures(format.readFeatures(data, {
featureProjection: map.getView().getProjection(),
// uncomment the line below for ol.format.MVT only
//extent: tile.getExtent()
}));
);
ol.DeviceOrientation
is deprecated and will be removed in the next major version.
The device-orientation example has been updated to use the (gyronorm.js)[https://github.com/dorukeker/gyronorm.js] library.
By default, the ol.source.VectorTile
constructor creates an XYZ tile grid (in Web Mercator) for 512 pixel tiles and assumes a max zoom level of 22. If you were creating a vector tile source with an explicit tileGrid
option, you can now remove this.
Before:
var source = new ol.source.VectorTile({
tileGrid: ol.tilegrid.createXYZ({tileSize: 512, maxZoom: 22}),
url: url
});
After:
var source = new ol.source.VectorTile({
url: url
});
If you need to change the max zoom level, you can pass the source a maxZoom
option. If you need to change the tile size, you can pass the source a tileSize
option. If you need a completely custom tile grid, you can still pass the source a tileGrid
option.
To delete features with the modify interaction, press the alt
key while clicking on an existing vertex. If you want to configure the modify interaction with a different delete condition, use the deleteCondition
option. For example, to allow deletion on a single click with no modifier keys, configure the interaction like this:
var interaction = new ol.interaction.Modify({
source: source,
deleteCondition: function(event) {
return ol.events.condition.noModifierKeys(event) && ol.events.condition.singleClick(event);
}
});
The motivation for this change is to make the modify, draw, and snap interactions all work well together. Previously, the use of these interactions with the default configuration would make it so you couldn't reliably add new vertices (click with no modifier) and delete existing vertices (click with no modifier).
The tilePixelRatio
option was only used for tiles in projections with tile-pixels
as units. For tiles read with ol.format.MVT
and the default tile loader, or tiles with the default pixel size of 4096 pixels, no changes are necessary. For the very rare cases that do not fall under these categories, a custom tileLoadFunction
now needs to be configured on the ol.source.VectorTile
. In addition to calling tile.setFeatures()
and tile.setProjection()
, it also needs to contain code like the following:
var extent = tile.getFormat() instanceof ol.format.MVT ?
tile.getLastExtent() :
[0, 0, tilePixelRatio * tileSize, tilePixelRatio * tileSize];
tile.setExtent(extent);
Usually rotation animations should animate along the shortest arc. There are rare occasions where a spinning animation effect is desired. So if you previously had something like
map.getView().animate({
rotation: 2 * Math.PI,
duration: 2000
});
we recommend to split the animation into two parts and use different easing functions. The code below results in the same effect as the snippet above did with previous versions:
map.getView().animate({
rotation: Math.PI,
easing: ol.easing.easeIn
}, {
rotation: 2 * Math.PI,
easing: ol.easing.easeOut
});
To provide a more consistent behaviour the following getters now return the same value that was given to constructor:
ol.style.RegularShape#getPoints
does not return the double amount of points anymore if a radius2 is set.
ol.style.RegularShape#getRadius2
will return undefined
if no radius2 is set.
Previously, you could do this:
map.addLayer(layer);
map.addLayer(layer);
However, after adding a duplicate layer, things failed if you tried to remove that layer.
Now, map.addLayer()
throws if you try adding a layer that has already been added to the map.
The constrainResolution
configuration for ol.interaction.PinchZoom
and ol.interaction.MouseWheelZoom
can now be set directly with an option in ol.interaction.defaults
:
ol.interaction.defaults({
constrainResolution: true
});
Instead specifying a base url, the url
for the ol.source.Zoomify
source can now be a template. The {TileGroup}
, {x}
, {y}
, {z}
and placeholders must be included in the url
in this case. the url
can now also include subdomain placeholders:
new ol.source.Zoomify({
url: 'https://{a-f}.example.com/cgi-bin/iipsrv.fcgi?zoomify=/a/b/{TileGroup}/{z}-{x}-{y}.jpg'
});
The deprecated ol.animation
functions and map.beforeRender()
method have been removed. Use view.animate()
instead.
The unByKey()
method has been removed from ol.Observable
instances. Use the ol.Observable.unByKey()
static function instead.
var key = map.on('moveend', function() { ...});
map.unByKey(key);
New code:
var key = map.on('moveend', function() { ...});
ol.Observable.unByKey(key);
In most cases, it is no longer necessary to provide an ol.Size
(previously the 2nd argument) to ol.View#fit()
. By default, the size of the first map that uses the view will be used. If you want to specify a different size, it goes in the options now (previously the 3rd argument, now the 2nd).
Most common use case - old API:
map.getView().fit(extent, map.getSize());
Most common use case - new API:
map.getView().fit(extent);
Advanced use - old API:
map.getView().fit(extent, [200, 100], {padding: 10});
Advanced use - new API:
map.getView().fit(extent, {size: [200, 100], padding 10});
The ol.DEBUG
, ol.ENABLE_TILE
, ol.ENABLE_IMAGE
, ol.ENABLE_VECTOR
, and ol.ENABLE_VECTOR_TILE
build flags are no longer necessary and have been removed. If you were using these in a define
array for a custom build, you can remove them.
If you leave ol.ENABLE_WEBGL
set to true
in your build, you should set ol.DEBUG_WEBGL
to false
to avoid including debuggable shader sources.
The map.beforeRender()
and ol.animation
functions have been deprecated in favor of a new view.animate()
function. Use of the deprecated functions will result in a warning during development. These functions are subject to removal in an upcoming release.
For details on the view.animate()
method, see the API docs and the view animation example. Upgrading should be relatively straightforward. For example, if you wanted to have an animated pan, zoom, and rotation previously, you might have done this:
var zoom = ol.animation.zoom({
resolution: view.getResolution()
});
var pan = ol.animation.pan({
source: view.getCenter()
});
var rotate = ol.animation.rotate({
rotation: view.getRotation()
});
map.beforeRender(zoom, pan, rotate);
map.setZoom(1);
map.setCenter([0, 0]);
map.setRotation(Math.PI);
Now, the same can be accomplished with this:
view.animate({
zoom: 1,
center: [0, 0],
rotation: Math.PI
});
If you are using the layer filter of one of these methods, please note that you now have to pass in the layer filter via an ol.AtPixelOptions
object. If you are not using the layer filter the usage has not changed.
Old syntax:
map.forEachFeatureAtPixel(pixel, callback, callbackThis, layerFilterFn, layerFilterThis);
map.hasFeatureAtPixel(pixel, layerFilterFn, layerFilterThis);
New syntax:
map.forEachFeatureAtPixel(pixel, callback.bind(callbackThis), {
layerFilter: layerFilterFn.bind(layerFilterThis)
});
map.hasFeatureAtPixel(pixel, {
layerFilter: layerFilterFn.bind(layerFilterThis)
});
This change is due to the introduction of the hitTolerance
parameter which can be passed in via this ol.AtPixelOptions
object, too.
The experimental getPointResolution
method has been removed from ol.Projection
instances. Since the implementation of this method required an inverse transform (function for transforming projected coordinates to geographic coordinates) and ol.Projection
instances are not constructed with forward or inverse transforms, it does not make sense that a projection instance can always calculate the point resolution.
As a substitute for the projection.getPointResolution()
function, a ol.proj.getPointResolution()
function has been added. To upgrade, you will need to change things like this:
projection.getPointResolution(resolution, point);
into this:
ol.proj.getPointResolution(projection, resolution, point);
Note that if you were previously creating a projection with a getPointResolution
function in the constructor (or calling projection.setGetPointResolution()
after construction), this function will be used by ol.proj.getPointResolution()
.
The old behavior of ol.interaction.PinchZoom
was to zoom to the next integer zoom level after the user ends the gesture.
Now the pinch zoom keeps the user selected zoom level even if it is a fractional zoom.
To get the old behavior set the new constrainResolution
parameter to true
like this:
new ol.interaction.PinchZoom({constrainResolution: true})
See the new pinch-zoom
example for a complete implementation.
The origin for gradients and patterns has changed from [0, 0]
to the top-left
corner of the extent of the geometry being filled.
Previously, gradients and patterns were aligned with the canvas, so they did not
move and rotate with the map. This was changed to a more expected behavior by anchoring the fill to the map origin (usually at map coordinate [0, 0]
).
As last step in the removal of the dependency on Google Closure Library, the goog.DEBUG
compiler define was renamed to ol.DEBUG
. Please change accordingly in your custom build configuration json files.
ol.format.ogc.filter
was simplified to ol.format.filter
; to upgrade your code, simply remove the ogc
string from the name.
For example: ol.format.ogc.filter.and
to ol.format.filter.and
.
A number of internal types have been renamed. This will not affect those who use the API provided by the library, but if you are compiling your application together with OpenLayers and using type names, you'll need to do the following:
- rename
ol.CollectionProperty
tool.Collection.Property
- rename
ol.DeviceOrientationProperty
tool.DeviceOrientation.Property
- rename
ol.DragBoxEvent
tool.interaction.DragBox.Event
- rename
ol.DragBoxEventType
tool.interaction.DragBox.EventType
- rename
ol.GeolocationProperty
tool.Geolocation.Property
- rename
ol.OverlayPositioning
tool.Overlay.Positioning
- rename
ol.OverlayProperty
tool.Overlay.Property
- rename
ol.control.MousePositionProperty
tool.control.MousePosition.Property
- rename
ol.format.IGCZ
tool.format.IGC.Z
- rename
ol.interaction.InteractionProperty
tool.interaction.Interaction.Property
- rename
ol.interaction.DrawMode
tool.interaction.Draw.Mode
- rename
ol.interaction.DrawEvent
tool.interaction.Draw.Event
- rename
ol.interaction.DrawEventType
tool.interaction.Draw.EventType
- rename
ol.interaction.ExtentEvent
tool.interaction.Extent.Event
- rename
ol.interaction.ExtentEventType
tool.interaction.Extent.EventType
- rename
ol.interaction.DragAndDropEvent
tool.interaction.DragAndDrop.Event
- rename
ol.interaction.DragAndDropEventType
tool.interaction.DragAndDrop.EventType
- rename
ol.interaction.ModifyEvent
tool.interaction.Modify.Event
- rename
ol.interaction.SelectEvent
tool.interaction.Select.Event
- rename
ol.interaction.SelectEventType
tool.interaction.Select.EventType
- rename
ol.interaction.TranslateEvent
tool.interaction.Translate.Event
- rename
ol.interaction.TranslateEventType
tool.interaction.Translate.EventType
- rename
ol.layer.GroupProperty
tool.layer.Group.Property
- rename
ol.layer.HeatmapLayerProperty
tool.layer.Heatmap.Property
- rename
ol.layer.TileProperty
tool.layer.Tile.Property
- rename
ol.layer.VectorTileRenderType
tool.layer.VectorTile.RenderType
- rename
ol.MapEventType
tool.MapEvent.Type
- rename
ol.MapProperty
tool.Map.Property
- rename
ol.ModifyEventType
tool.interaction.Modify.EventType
- rename
ol.RendererType
tool.renderer.Type
- rename
ol.render.EventType
tool.render.Event.Type
- rename
ol.source.ImageEvent
tool.source.Image.Event
- rename
ol.source.ImageEventType
tool.source.Image.EventType
- rename
ol.source.RasterEvent
tool.source.Raster.Event
- rename
ol.source.RasterEventType
tool.source.Raster.EventType
- rename
ol.source.TileEvent
tool.source.Tile.Event
- rename
ol.source.TileEventType
tool.source.Tile.EventType
- rename
ol.source.VectorEvent
tool.source.Vector.Event
- rename
ol.source.VectorEventType
tool.source.Vector.EventType
- rename
ol.source.wms.ServerType
tool.source.WMSServerType
- rename
ol.source.WMTSRequestEncoding
tool.source.WMTS.RequestEncoding
- rename
ol.style.IconAnchorUnits
tool.style.Icon.AnchorUnits
- rename
ol.style.IconOrigin
tool.style.Icon.Origin
The DOM renderer has been removed. Instead, the Canvas renderer should be used. If you were previously constructing a map with 'dom'
as the renderer
option, you will see an error message in the console in debug mode and the Canvas renderer will be used instead. To remove the warning, remove the renderer
option from your map constructor.
Previously, minified builds of the library did not have any assertions. This caused applications to fail silently or with cryptic stack traces. Starting with this release, developers get notified of many runtime errors through the new ol.AssertionError
. This error has a code
property. The meaning of the code can be found on https://openlayers.org/en/latest/doc/errors/. There are additional console assertion checks in debug mode when the goog.DEBUG
compiler flag is true
. As this is true
by default, it is recommended that those creating custom builds set this to false
so these assertions are stripped.'
This option was previously needed to use named colors with the WebGL renderer but is no longer needed.
The URL constructor is supported by all modern browsers, but not by older ones, such as IE. To use the KML format in such older browsers, a URL polyfill will have to be loaded before use.
A number of internal types have been renamed. This will not affect those who use the API provided by the library, but if you are compiling your application together with OpenLayers and using type names, you'll need to do the following:
- rename
ol.CollectionEventType
tool.Collection.EventType
- rename
ol.CollectionEvent
tool.Collection.Event
- rename
ol.ViewHint
tool.View.Hint
- rename
ol.ViewProperty
tool.View.Property
- rename
ol.render.webgl.imagereplay.shader.Default.Locations
tool.render.webgl.imagereplay.defaultshader.Locations
- rename
ol.render.webgl.imagereplay.shader.DefaultFragment
tool.render.webgl.imagereplay.defaultshader.Fragment
- rename
ol.render.webgl.imagereplay.shader.DefaultVertex
tool.render.webgl.imagereplay.defaultshader.Vertex
- rename
ol.renderer.webgl.map.shader.Default.Locations
tool.renderer.webgl.defaultmapshader.Locations
- rename
ol.renderer.webgl.map.shader.Default.Locations
tool.renderer.webgl.defaultmapshader.Locations
- rename
ol.renderer.webgl.map.shader.DefaultFragment
tool.renderer.webgl.defaultmapshader.Fragment
- rename
ol.renderer.webgl.map.shader.DefaultVertex
tool.renderer.webgl.defaultmapshader.Vertex
- rename
ol.renderer.webgl.tilelayer.shader.Fragment
tool.renderer.webgl.tilelayershader.Fragment
- rename
ol.renderer.webgl.tilelayer.shader.Locations
tool.renderer.webgl.tilelayershader.Locations
- rename
ol.renderer.webgl.tilelayer.shader.Vertex
tool.renderer.webgl.tilelayershader.Vertex
- rename
ol.webgl.WebGLContextEventType
tool.webgl.ContextEventType
- rename
ol.webgl.shader.Fragment
tool.webgl.Fragment
- rename
ol.webgl.shader.Vertex
tool.webgl.Vertex
Because of changes at MapQuest (see: https://lists.openstreetmap.org/pipermail/talk/2016-June/076106.html) we had to remove the MapQuest source for now (see #5484 for details).
The event object previously had a mapBrowserPointerEvent
property, which has been renamed to mapBrowserEvent
.
Users compiling their code with the library and using types in the ol.raster
namespace should note that this has now been removed. ol.raster.Pixel
has been deleted, and the other types have been renamed as follows, and your code may need changing if you use these:
ol.raster.Operation
tool.RasterOperation
ol.raster.OperationType
tool.RasterOperationType
Users compiling their code with the library should note that the following typedefs have been renamed; your code may need changing if you use these:
- ol.events.ConditionType to ol.EventsConditionType
- ol.events.EventTargetLike to ol.EventTargetLike
- ol.events.Key to ol.EventsKey
- ol.events.ListenerFunctionType to ol.EventsListenerFunctionType
- ol.interaction.DragBoxEndConditionType to ol.DragBoxEndConditionType
- ol.interaction.DrawGeometryFunctionType to ol.DrawGeometryFunctionType
- ol.interaction.SegmentDataType to ol.ModifySegmentDataType
- ol.interaction.SelectFilterFunction to ol.SelectFilterFunction
- ol.interaction.SnapResultType to ol.SnapResultType
- ol.interaction.SnapSegmentDataType to ol.SnapSegmentDataType
- ol.proj.ProjectionLike to ol.ProjectionLike
- ol.style.AtlasBlock to ol.AtlasBlock
- ol.style.AtlasInfo to ol.AtlasInfo
- ol.style.AtlasManagerInfo to ol.AtlasManagerInfo
- ol.style.CircleRenderOptions to ol.CircleRenderOptions
- ol.style.ImageOptions to ol.StyleImageOptions
- ol.style.GeometryFunction to ol.StyleGeometryFunction
- ol.style.RegularShapeRenderOptions to ol.RegularShapeRenderOptions
- ol.style.StyleFunction to ol.StyleFunction
Previously, if you called source.setUrl()
on a tile source, all currently rendered tiles would be cleared before new tiles were loaded and rendered. This clearing of the map is undesirable if you are trying to smoothly update the tiles used by a source. This behavior has now changed, and calling source.setUrl()
(or source.setUrls()
) will not clear currently rendered tiles before loading and rendering new tiles. Instead, previously rendered tiles remain rendered until new tiles have loaded and can replace them. If you want to achieve the old behavior (render a blank map before loading new tiles), you can call source.refresh()
or you can replace the old source with a new one (using layer.setSource()
).
This change should not affect the great majority of application developers, but it's possible there are edge cases when compiling application code together with the library which cause compiler errors or warnings. In this case, please raise a GitHub issue. goog.require
s for typedefs should not be necessary.
Users compiling their code with the library should note that the following API @typedef
s have been renamed; your code may need changing if you use these:
ol.format.WFS.FeatureCollectionMetadata
tool.WFSFeatureCollectionMetadata
ol.format.WFS.TransactionResponse
tool.WFSTransactionResponse
This option is no longer needed, so it was removed from the API.
The ol.source.TileUTFGrid
now uses XMLHttpRequest to load UTFGrid tiles by default. This works out of the box with the v4 Mapbox API. To work with the v3 API, you must use the new jsonp
option on the source. See the examples below for detail.
// To work with the v4 API
var v4source = new ol.source.TileUTFGrid({
url: 'https://api.tiles.mapbox.com/v4/example.json?access_token=' + YOUR_KEY_HERE
});
// To work with the v3 API
var v3source = new ol.source.TileUTFGrid({
jsonp: true, // <--- this is required for v3
url: 'http://api.tiles.mapbox.com/v3/example.json'
});
As of this release, OpenLayers requires a classList
polyfill for IE 9 support. See https://cdn.polyfill.io/v2/docs/features#Element_prototype_classList.
Listeners for precompose
, render
, and postcompose
receive an event with a vectorContext
property with methods for immediate vector rendering. The previous geometry drawing methods have been replaced with a single vectorContext.drawGeometry(geometry)
method. If you were using any of the following experimental methods on the vector context, replace them with drawGeometry
:
- Removed experimental geometry drawing methods:
drawPointGeometry
,drawLineStringGeometry
,drawPolygonGeometry
,drawMultiPointGeometry
,drawMultiLineStringGeometry
,drawMultiPolygonGeometry
, anddrawCircleGeometry
(all have been replaced withdrawGeometry
).
In addition, the previous methods for setting style parts have been replaced with a single vectorContext.setStyle(style)
method. If you were using any of the following experimental methods on the vector context, replace them with setStyle
:
- Removed experimental style setting methods:
setFillStrokeStyle
,setImageStyle
,setTextStyle
(all have been replaced withsetStyle
).
Below is an example of how the vector context might have been used in the past:
// OLD WAY, NO LONGER SUPPORTED
map.on('postcompose', function(event) {
event.vectorContext.setFillStrokeStyle(style.getFill(), style.getStroke());
event.vectorContext.drawPointGeometry(geometry);
});
Here is an example of how you could accomplish the same with the new methods:
// NEW WAY, USE THIS INSTEAD OF THE CODE ABOVE
map.on('postcompose', function(event) {
event.vectorContext.setStyle(style);
event.vectorContext.drawGeometry(geometry);
});
A final change to the immediate rendering API is that vectorContext.drawFeature()
calls are now "immediate" as well. The drawing now occurs synchronously. This means that any zIndex
in a style passed to drawFeature()
will be ignored. To achieve zIndex
ordering, order your calls to drawFeature()
instead.
The ol.DEFAULT_TILE_CACHE_HIGH_WATER_MARK
define has been removed. The size of the cache can now be defined on every tile based ol.source
:
new ol.layer.Tile({
source: new ol.source.OSM({
cacheSize: 128
})
})
The default cache size is 2048
.
As of this release, OpenLayers requires a requestAnimationFrame
/cancelAnimationFrame
polyfill for IE 9 support. See https://cdn.polyfill.io/v2/docs/features/#requestAnimationFrame.
It is the responsibility of the application to undo any canvas transform changes at the end of a layer 'precompose' or 'postcompose' handler. Previously, it was ok to set a null transform. The API now guarantees a device pixel coordinate system on the canvas with its origin in the top left corner of the map. However, applications should not rely on the underlying canvas being the same size as the visible viewport.
Old code:
layer.on('precompose', function(e) {
// rely on canvas dimensions to move coordinate origin to center
e.context.translate(e.context.canvas.width / 2, e.context.canvas.height / 2);
e.context.scale(3, 3);
// draw an x in the center of the viewport
e.context.moveTo(-20, -20);
e.context.lineTo(20, 20);
e.context.moveTo(-20, 20);
e.context.lineTo(20, -20);
// rely on the canvas having a null transform
e.context.setTransform(1, 0, 0, 1, 0, 0);
});
New code:
layer.on('precompose', function(e) {
// use map size and pixel ratio to move coordinate origin to center
var size = map.getSize();
var pixelRatio = e.frameState.pixelRatio;
e.context.translate(size[0] / 2 * pixelRatio, size[1] / 2 * pixelRatio);
e.context.scale(3, 3);
// draw an x in the center of the viewport
e.context.moveTo(-20, -20);
e.context.lineTo(20, 20);
e.context.moveTo(-20, 20);
e.context.lineTo(20, -20);
// undo all transforms
e.context.scale(1 / 3, 1 / 3);
e.context.translate(-size[0] / 2 * pixelRatio, -size[1] / 2 * pixelRatio);
});
Before this release, OpenLayers depended on the global proj4 namespace. When using a module loader like Browserify, you might not want to depend on the global proj4
namespace. You can use the ol.proj.setProj4
function to set the proj4 function object. For example in a browserify ES6 environment:
import ol from 'openlayers';
import proj4 from 'proj4';
ol.proj.setProj4(proj4);
The ol.source.TileJSON
now uses XMLHttpRequest
to load the TileJSON instead of JSONP with callback.
When using server without proper CORS support, jsonp: true
option can be passed to the constructor to get the same behavior as before:
new ol.source.TileJSON({
url: 'http://serverwithoutcors.com/tilejson.json',
jsonp: true
})
Also for Mapbox v3, make sure you use urls ending with .json
(which are able to handle both XMLHttpRequest
and JSONP) instead of .jsonp
.
The optional layerFilter
function is now also called for unmanaged layers. To get the same behaviour as before, wrap your layer filter code in an if block like this:
function layerFilter(layer) {
if (map.getLayers().getArray().indexOf(layer) !== -1) {
// existing layer filter code
}
}
KML icons are scaled 50% so that the rendering better matches Google Earth rendering.
If a KML placemark has a name and is a point, an ol.style.Text
is created with the name displayed to the right of the icon (if there is an icon).
This can be controlled with the showPointNames option which defaults to true.
To disable rendering of the point names for placemarks, use the option: new ol.format.KML({ showPointNames: false });
Styling is no longer done with ol.Style
, but with pure CSS. The style
constructor option is no longer required, and no longer available. Instead, there is a className
option for the CSS selector. The default for ol.interaction.DragBox
is ol-dragbox
, and ol.interaction.DragZoom
uses ol-dragzoom
. If you previously had
new ol.interaction.DragZoom({
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'red',
width: 3
}),
fill: new ol.style.Fill({
color: [255, 255, 255, 0.4]
})
})
});
you'll now just need
new ol.interaction.DragZoom();
but with additional css:
.ol-dragzoom {
border-color: red;
border-width: 3px;
background-color: rgba(255,255,255,0.4);
}
With the introduction of true vector tile support, ol.source.TileVector
becomes obsolete. Change your code to use ol.layer.VectorTile
and ol.source.VectorTile
instead of ol.layer.Vector
and ol.source.TileVector
.
ol.Map#forEachFeatureAtPixel
will still be called for unmanaged layers, but the 2nd argument to the callback function will be null
instead of a reference to the unmanaged layer. This brings back the behavior of the abandoned ol.FeatureOverlay
that was replaced by unmanaged layers.
If you are affected by this change, please change your unmanaged layer to a regular layer by using e.g. ol.Map#addLayer
instead of ol.layer.Layer#setMap
.
The experimental setHue
, setContrast
, setBrightness
, setSaturation
, and the corresponding getter methods have been removed. These properties only worked with the WebGL renderer. If are interested in applying color transforms, look for the postcompose
event in the API docs. In addition, the ol.source.Raster
source provides a way to create new raster data based on arbitrary transforms run on any number of input sources.
The experimental getAnchor
, getOrigin
, and getSize
methods have been removed. The anchor and origin of a circle symbolizer are not modifiable, so these properties should not need to be accessed. The radius and stroke width can be used to calculate the rendered size of a circle symbolizer if needed:
// calculate rendered size of a circle symbolizer
var width = 2 * circle.getRadius();
if (circle.getStroke()) {
width += circle.getStroke().getWidth() + 1;
}
There should be nothing special required when upgrading from v3.7.0 to v3.8.0.
Instead of an ol.FeatureOverlay
, we now use an ol.layer.Vector
with an
ol.source.Vector
. If you previously had:
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:
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>}
.
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
:
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()
):
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):
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):
var tileUrlFunction = function(tileCoord, pixelRatio, projection) {
return 'http://mytiles.com/' +
tileCoord[0] + '/' + tileCoord[1] + '/' + (-tileCoord[2] - 1) + '.png';
};
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]
.
- This combines two previously distinct functions into one more flexible call which takes either a geometry or an extent.
- Rename all calls to
fitExtent
andfitGeometry
tofit
.
When single clicking a line or boundary within the pixelTolerance
, a vertex is now created.
- The
minPointsPerRing
config option has been renamed tominPoints
. It is now also available for linestring drawing, not only for polygons. - The
ol.DrawEvent
andol.DrawEventType
types were renamed tool.interaction.DrawEvent
andol.interaction.DrawEventType
. This has an impact on your code only if your code is compiled together with OpenLayers.
- The
ol.tilegrid.XYZ
constructor has been replaced by a staticol.tilegrid.createXYZ()
function. Theol.tilegrid.createXYZ()
function takes the same arguments as the previousol.tilegrid.XYZ
constructor, but returns anol.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 calculatingheight-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 ofol.tilegrid.TileGrid
and subclasses is no longer available, and it is no longer necessary to get proper wrapping at the 180° meridian. However, forol.tilegrid.WMTS
, there is a new optionsizes
, where each entry is anol.Size
with thewidth
('TileMatrixWidth' in WMTS capabilities) as first and theheight
('TileMatrixHeight') as second entry of the array. For other tile grids, users can now specify anextent
instead ofwidths
. These settings are used to restrict the range of tiles that sources will request. - For
ol.source.TileWMS
, the default value ofwarpX
used to beundefined
, meaning that WMS requests with out-of-extent tile BBOXes would be sent. NowwrapX
can only betrue
orfalse
, and the new default istrue
. 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.
-
The following experimental methods have been removed from
ol.Object
:bindTo
,unbind
, andunbindAll
. If you want to get notification aboutol.Object
property changes, you can listen for the'propertychange'
event (e.g.object.on('propertychange', listener)
). Two-way binding can be set up at the application level using property change listeners. See #3472 for details on the change. -
The experimental
ol.dom.Input
component has been removed. If you need to synchronize the state of a dom Input element with anol.Object
, this can be accomplished using listeners for change events. For example, you might bind the state of a checkbox type input with a layer's visibility like this:var layer = new ol.layer.Tile(); var checkbox = document.querySelector('#checkbox'); checkbox.addEventListener('change', function() { var checked = this.checked; if (checked !== layer.getVisible()) { layer.setVisible(checked); } }); layer.on('change:visible', function() { var visible = this.getVisible(); if (visible !== checkbox.checked) { checkbox.checked = visible; } });
-
The following experimental vector classes have been removed:
ol.source.GeoJSON
,ol.source.GML
,ol.source.GPX
,ol.source.IGC
,ol.source.KML
,ol.source.OSMXML
, andol.source.TopoJSON
. You now will useol.source.Vector
instead.For example, if you used
ol.source.GeoJSON
as follows:var source = new ol.source.GeoJSON({ url: 'features.json', projection: 'EPSG:3857' });
you will need to change your code to:
var source = new ol.source.Vector({ url: 'features.json', format: new ol.format.GeoJSON() });
See https://openlayers.org/en/latest/examples/vector-layer.html for a real example.
Note that you no longer need to set a
projection
on the source!Previously the vector data was loaded at source construction time, and, if the data projection and the source projection were not the same, the vector data was transformed to the source projection before being inserted (as features) into the source.
The vector data is now loaded at render time, when the view projection is known. And the vector data is transformed to the view projection if the data projection and the source projection are not the same.
If you still want to "eagerly" load the source you will use something like this:
var source = new ol.source.Vector(); $.ajax('features.json').then(function(response) { var geojsonFormat = new ol.format.GeoJSON(); var features = geojsonFormat.readFeatures(response, {featureProjection: 'EPSG:3857'}); source.addFeatures(features); });
The above code uses jQuery to send an Ajax request, but you can obviously use any Ajax library.
See https://openlayers.org/en/latest/examples/igc.html for a real example.
-
Note about KML
If you used
ol.source.KML
'sextractStyles
ordefaultStyle
options, you will now have to set these options onol.format.KML
instead. For example, if you used:var source = new ol.source.KML({ url: 'features.kml', extractStyles: false, projection: 'EPSG:3857' });
you will now use:
var source = new ol.source.Vector({ url: 'features.kml', format: new ol.format.KML({ extractStyles: false }) });
-
The
ol.source.ServerVector
class has been removed. If you used it, for example as follows:var source = new ol.source.ServerVector({ format: new ol.format.GeoJSON(), loader: function(extent, resolution, projection) { var url = …; $.ajax(url).then(function(response) { source.addFeatures(source.readFeatures(response)); }); }, strategy: ol.loadingstrategy.bbox, projection: 'EPSG:3857' });
you will need to change your code to:
var source = new ol.source.Vector({ loader: function(extent, resolution, projection) { var url = …; $.ajax(url).then(function(response) { var format = new ol.format.GeoJSON(); var features = format.readFeatures(response, {featureProjection: projection}); source.addFeatures(features); }); }, strategy: ol.loadingstrategy.bbox });
See https://openlayers.org/en/latest/examples/vector-osm.html for a real example.
-
The experimental
ol.loadingstrategy.createTile
function has been renamed tool.loadingstrategy.tile
. The signature of the function hasn't changed. See https://openlayers.org/en/latest/examples/vector-osm.html for an example.
- When manually loading an image for
ol.style.Icon
, the image size should now be set with theimgSize
option and not withsize
.size
is supposed to be used for the size of a sub-rectangle in an image sprite.
The return value of ol.tilegrid.TileGrid#getTileSize()
will now be an ol.Size
array instead of a number if non-square tiles (i.e. an ol.Size
array instead of a number as tilsSize
) are used. To always get an ol.Size
, the new ol.size.toSize()
was added.
When finishing a draw, the drawend
event is now dispatched before the feature is inserted to either the source or the collection. This change allows application code to finish setting up the feature.
If you compile your application together with the library and use the ol.feature.FeatureStyleFunction
type annotation (this should be extremely rare), the type is now named ol.FeatureStyleFunction
.
There should be nothing special required when upgrading from v3.3.0 to v3.4.0.
-
The
ol.events.condition.mouseMove
function was replaced byol.events.condition.pointerMove
(see #3281). For example, if you useol.events.condition.mouseMove
as the condition in aSelect
interaction then you now need to useol.events.condition.pointerMove
:var selectInteraction = new ol.interaction.Select({ condition: ol.events.condition.pointerMove // … });