Compare commits

..

1 Commits

Author SHA1 Message Date
ahocevar
f02f6a11ab Version and beta tag for v6.0.0-beta.1 2019-02-04 14:00:42 +01:00
94 changed files with 739 additions and 1013 deletions

View File

@@ -41,13 +41,14 @@ See the following examples for more detail on bundling OpenLayers with your appl
* Using [Parcel](https://github.com/openlayers/ol-parcel)
* Using [Browserify](https://github.com/openlayers/ol-browserify)
## IntelliSense support and type checking for VS Code
## TypeScript and VS Code IntelliSense support
The `ol` package contains a `src/` folder with JSDoc annotated sources. TypeScript can get type definitions from these sources with a `jsconfig.json` config file in the project root:
The `ol` package contains a `src/` folder with JSDoc annotated sources. TypeScript can get type definitions from these sources with a `tsconfig.json` like this:
```js
{
"compilerOptions": {
"checkJs": true,
// Enable JavaScript support
"allowJs": true,
// Point to the JSDoc typed sources when using modules from the ol package
"baseUrl": "./",
"paths": {
@@ -56,14 +57,11 @@ The `ol` package contains a `src/` folder with JSDoc annotated sources. TypeScri
}
},
"include": [
"**/*.js",
// Include JavaScript files from the ol package
"node_modules/ol/**/*.js"
]
}
```
Project template with this configuration: https://gist.github.com/9a7253cb4712e8bf38d75d8ac898e36c.
Note that the above only works when authoring in plain JavaScript. For similar configurations with a `tsconfig.json` in TypeScript projects, your mileage may vary.
## Supported Browsers

View File

@@ -4,13 +4,11 @@
#### Backwards incompatible changes
##### Removal of deprecated methods
##### Removal of the deprecated "inherits" function
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.
##### New internal tile coordinates
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.
@@ -62,10 +60,6 @@ In addition (this should be exceedingly rare), if you previously created a `ol/t
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.
##### Removal of the "renderMode" option for vector layers
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`.
##### New `prerender` and `postrender` layer events replace old `precompose`, `render` and `postcompose` events
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.
@@ -124,19 +118,8 @@ The removed classes and components are:
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.
##### Change of the behavior of the vector source's clear() and refresh() methods
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()`.
#### Other changes
##### Allow declutter in image render mode
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`.
##### Always load tiles while animating or interacting
`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.

View File

@@ -21,7 +21,7 @@ Table of contents:
* [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-)
* [Why are my features not found?](#why-are-my-features-not-found-)
* [Why is zooming or clicking off, inaccurate?](#user-content-why-is-zooming-or-clicking-off-inaccurate)
## What projection is OpenLayers using?
@@ -371,30 +371,3 @@ const vectorLayer = new VectorLayer({
```
The recommended value is the size of the largest symbol, line width or label.
## Why is zooming or clicking in the map off/inaccurate?
OpenLayers does not update the map when the container element is resized. This can be caused by progressive updates
to CSS styles or manually resizing the map. When that happens, any interaction will become inaccurate: the map would zoom in and out, and end up not being centered on the pointer. This makes it hard to do certain interactions, e.g. selecting the desired feature.
There is currently no built-in way to react to element's size changes, as [Resize Observer API](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) is only implemented in Chrome.
There is however an easy to use [polyfill](https://github.com/que-etc/resize-observer-polyfill):
```javascript
import Map from 'ol/Map';
import ResizeObserver from 'resize-observer-polyfill';
const mapElement = document.querySelector('#map')
const map = new Map({
target: mapElement
})
const sizeObserver = new ResizeObserver(() => {
map.updateSize()
})
sizeObserver.observe(mapElement)
// called when the map is destroyed
// sizeObserver.disconnect()
```

View File

@@ -12,8 +12,9 @@ cloak:
<div id="map" class="map"></div>
<select id="layer-select">
<option value="Aerial">Aerial</option>
<option value="AerialWithLabelsOnDemand" selected>Aerial with labels</option>
<option value="RoadOnDemand">Road</option>
<option value="CanvasDark">Road dark</option>
<option value="OrdnanceSurvey">Ordnance Survey</option>
<option value="AerialWithLabels" selected>Aerial with labels</option>
<option value="Road">Road (static)</option>
<option value="RoadOnDemand">Road (dynamic)</option>
<option value="collinsBart">Collins Bart</option>
<option value="ordnanceSurvey">Ordnance Survey</option>
</select>

View File

@@ -5,11 +5,12 @@ import BingMaps from '../src/ol/source/BingMaps.js';
const styles = [
'Road',
'RoadOnDemand',
'Aerial',
'AerialWithLabelsOnDemand',
'CanvasDark',
'OrdnanceSurvey'
'AerialWithLabels',
'collinsBart',
'ordnanceSurvey'
];
const layers = [];
let i, ii;

View File

@@ -26,8 +26,9 @@ const styleFunction = function(feature) {
scale = size / 10;
let style = styleCache[size];
if (!style) {
const canvas = document.createElement('canvas');
const vectorContext = toContext(canvas.getContext('2d'),
const canvas = /** @type {HTMLCanvasElement} */ (document.createElement('canvas'));
const vectorContext = toContext(
/** @type {CanvasRenderingContext2D} */ (canvas.getContext('2d')),
{size: [size, size], pixelRatio: 1});
vectorContext.setStyle(new Style({
fill: new Fill({color: 'rgba(255, 153, 0, 0.4)'}),

View File

@@ -63,10 +63,7 @@ exportButton.addEventListener('click', function() {
pdf.save('map.pdf');
// Reset original map size
map.setSize(size);
map.getView().fit(extent, {
size: size,
constrainResolution: false
});
map.getView().fit(extent, {size});
exportButton.disabled = false;
document.body.style.cursor = 'auto';
});

View File

@@ -133,7 +133,7 @@ const map = new Map({
layers: [
new TileLayer({
source: new BingMaps({
imagerySet: 'AerialWithLabelsOnDemand',
imagerySet: 'AerialWithLabels',
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5'
})
}),

View File

@@ -1,3 +1,6 @@
.map:-moz-full-screen {
height: 100%;
}
.map:-webkit-full-screen {
height: 100%;
}

View File

@@ -1,3 +1,6 @@
.fullscreen:-moz-full-screen {
height: 100%;
}
.fullscreen:-webkit-full-screen {
height: 100%;
}

View File

@@ -1,3 +1,6 @@
.map:-moz-full-screen {
height: 100%;
}
.map:-webkit-full-screen {
height: 100%;
}

View File

@@ -33,11 +33,8 @@ map.on('singleclick', function(evt) {
evt.coordinate, viewResolution, 'EPSG:3857',
{'INFO_FORMAT': 'text/html'});
if (url) {
fetch(url)
.then((response) => response.text())
.then((html) => {
document.getElementById('info').innerHTML = html;
});
document.getElementById('info').innerHTML =
'<iframe seamless src="' + url + '"></iframe>';
}
});

View File

@@ -33,11 +33,8 @@ map.on('singleclick', function(evt) {
evt.coordinate, viewResolution, 'EPSG:3857',
{'INFO_FORMAT': 'text/html'});
if (url) {
fetch(url)
.then((response) => response.text())
.then((html) => {
document.getElementById('info').innerHTML = html;
});
document.getElementById('info').innerHTML =
'<iframe seamless src="' + url + '"></iframe>';
}
});

View File

@@ -7,7 +7,7 @@ import BingMaps from '../src/ol/source/BingMaps.js';
const key = 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5';
const roads = new TileLayer({
source: new BingMaps({key: key, imagerySet: 'RoadOnDemand'})
source: new BingMaps({key: key, imagerySet: 'Road'})
});
const imagery = new TileLayer({

View File

@@ -8,7 +8,7 @@ tags: "mapbox, vector, tiles, mobile"
resources:
- resources/mapbox-streets-v6-style.js
cloak:
- key: pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiY2pzbmg0Nmk5MGF5NzQzbzRnbDNoeHJrbiJ9.7_-_gL8ur7ZtEiNwRfCy7Q
- key: pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiRk1kMWZaSSJ9.E5BkluenyWQMsBLsuByrmg
value: Your Mapbox access token from http://mapbox.com/ here
---
<div id="map" class="map"></div>

View File

@@ -8,7 +8,7 @@ import {Fill, Icon, Stroke, Style, Text} from '../src/ol/style.js';
import TileGrid from '../src/ol/tilegrid/TileGrid.js';
const key = 'pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiY2pzbmg0Nmk5MGF5NzQzbzRnbDNoeHJrbiJ9.7_-_gL8ur7ZtEiNwRfCy7Q';
const key = 'pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiRk1kMWZaSSJ9.E5BkluenyWQMsBLsuByrmg';
// Calculation of resolutions that match zoom levels 1, 3, 5, 7, 9, 11, 13, 15.
const resolutions = [];

View File

@@ -8,7 +8,7 @@ tags: "simple, mapbox, vector, tiles"
resources:
- resources/mapbox-streets-v6-style.js
cloak:
- key: pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiY2pzbmg0Nmk5MGF5NzQzbzRnbDNoeHJrbiJ9.7_-_gL8ur7ZtEiNwRfCy7Q
- key: pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiRk1kMWZaSSJ9.E5BkluenyWQMsBLsuByrmg
value: Your Mapbox access token from http://mapbox.com/ here
---
<div id="map" class="map"></div>

View File

@@ -6,7 +6,7 @@ import VectorTileSource from '../src/ol/source/VectorTile.js';
import {Fill, Icon, Stroke, Style, Text} from '../src/ol/style.js';
const key = 'pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiY2pzbmg0Nmk5MGF5NzQzbzRnbDNoeHJrbiJ9.7_-_gL8ur7ZtEiNwRfCy7Q';
const key = 'pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiRk1kMWZaSSJ9.E5BkluenyWQMsBLsuByrmg';
const map = new Map({
layers: [

View File

@@ -14,7 +14,6 @@ cloak:
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<title>Mobile full screen example</title>
<link rel="stylesheet" href="../css/ol.css" type="text/css">
<style type="text/css">
html, body, .map {
margin: 0;

View File

@@ -15,7 +15,7 @@ const map = new Map({
new TileLayer({
source: new BingMaps({
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5',
imagerySet: 'RoadOnDemand'
imagerySet: 'Road'
})
})
],

View File

@@ -29,7 +29,7 @@ const map2 = new Map({
preload: 0, // default value
source: new BingMaps({
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5',
imagerySet: 'AerialWithLabelsOnDemand'
imagerySet: 'AerialWithLabels'
})
})
],

View File

@@ -7,7 +7,7 @@ docs: >
Tiles made with [TileMill](http://tilemill.com). Hosting on MapBox.com or with open-source [TileServer](https://github.com/klokantech/tileserver-php/).
tags: "utfgrid, tilejson"
cloak:
- key: pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiY2pzbmg0Nmk5MGF5NzQzbzRnbDNoeHJrbiJ9.7_-_gL8ur7ZtEiNwRfCy7Q
- key: pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiRk1kMWZaSSJ9.E5BkluenyWQMsBLsuByrmg
value: Your Mapbox access token from http://mapbox.com/ here
---
<div id="map" class="map"></div>

View File

@@ -5,7 +5,7 @@ import TileLayer from '../src/ol/layer/Tile.js';
import TileJSON from '../src/ol/source/TileJSON.js';
import UTFGrid from '../src/ol/source/UTFGrid.js';
const key = 'pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiY2pzbmg0Nmk5MGF5NzQzbzRnbDNoeHJrbiJ9.7_-_gL8ur7ZtEiNwRfCy7Q';
const key = 'pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiRk1kMWZaSSJ9.E5BkluenyWQMsBLsuByrmg';
const mapLayer = new TileLayer({
source: new TileJSON({

View File

@@ -1,6 +1,6 @@
{
"name": "ol",
"version": "6.0.0-beta.2",
"version": "6.0.0-beta.1",
"description": "OpenLayers mapping library",
"keywords": [
"map",
@@ -42,29 +42,29 @@
},
"devDependencies": {
"@openlayers/eslint-plugin": "^4.0.0-beta.1",
"@types/arcgis-rest-api": "^10.4.4",
"@types/geojson": "^7946.0.6",
"@types/arcgis-rest-api": "^10.4.3",
"@types/geojson": "^7946.0.5",
"@types/pbf": "^3.0.1",
"@types/rbush": "^2.0.2",
"@types/topojson-specification": "^1.0.1",
"@types/topojson-specification": "^1.0.0",
"buble": "^0.19.6",
"buble-loader": "^0.5.1",
"chaikin-smooth": "^1.0.4",
"clean-css-cli": "4.2.1",
"copy-webpack-plugin": "^5.0.0",
"coveralls": "3.0.3",
"eslint": "^5.13.0",
"copy-webpack-plugin": "^4.6.0",
"coveralls": "3.0.1",
"eslint": "^5.8.0",
"eslint-config-openlayers": "^11.0.0",
"expect.js": "0.3.1",
"front-matter": "^3.0.1",
"fs-extra": "^7.0.1",
"glob": "^7.1.2",
"globby": "^8.0.1",
"handlebars": "4.1.0",
"handlebars": "4.0.11",
"istanbul": "0.4.5",
"jquery": "3.3.1",
"jsdoc": "3.5.5",
"jsdoc-plugin-typescript": "^1.0.7",
"jsdoc-plugin-typescript": "^1.0.6",
"karma": "^4.0.0",
"karma-chrome-launcher": "2.2.0",
"karma-coverage": "^1.1.2",
@@ -73,25 +73,25 @@
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^4.0.0-rc.2",
"loglevelnext": "^3.0.0",
"marked": "0.6.1",
"mocha": "6.0.2",
"ol-mapbox-style": "^4.0.0",
"marked": "0.6.0",
"mocha": "5.2.0",
"ol-mapbox-style": "^3.6.3",
"pixelmatch": "^4.0.2",
"pngjs": "^3.3.3",
"proj4": "2.5.0",
"puppeteer": "^1.12.2",
"puppeteer": "^1.11.0",
"serve-static": "^1.13.2",
"shx": "^0.3.2",
"sinon": "^7.2.3",
"terser-webpack-plugin": "^1.2.2",
"terser-webpack-plugin": "^1.2.1",
"typescript": "^3.2.2",
"url-polyfill": "^1.1.3",
"walk": "^2.3.9",
"webpack": "4.29.6",
"webpack-cli": "^3.2.3",
"webpack-dev-middleware": "^3.5.2",
"webpack": "4.29.0",
"webpack-cli": "^3.2.0",
"webpack-dev-middleware": "^3.5.1",
"webpack-dev-server": "^3.1.14",
"yargs": "^13.2.0"
"yargs": "^12.0.2"
},
"eslintConfig": {
"extends": "openlayers",

View File

@@ -351,7 +351,7 @@ if (require.main === module) {
option('headless', {
describe: 'Launch Puppeteer in headless mode',
type: 'boolean',
default: false
default: process.env.CI ? false : true
}).
option('puppeteer-args', {
describe: 'Additional args for Puppeteer',

View File

@@ -4,6 +4,13 @@
import Tile from './Tile.js';
import TileState from './TileState.js';
/**
* @const
* @type {import("./extent.js").Extent}
*/
const DEFAULT_EXTENT = [0, 0, 4096, 4096];
class VectorTile extends Tile {
/**
@@ -82,7 +89,7 @@ class VectorTile extends Tile {
* @api
*/
getExtent() {
return this.extent_;
return this.extent_ || DEFAULT_EXTENT;
}
/**
@@ -140,8 +147,8 @@ class VectorTile extends Tile {
*/
onLoad(features, dataProjection, extent) {
this.setProjection(dataProjection);
this.setExtent(extent);
this.setFeatures(features);
this.setExtent(extent);
}
/**
@@ -159,7 +166,7 @@ class VectorTile extends Tile {
* calculated by multiplying the tile size with the tile pixel ratio. For
* sources using {@link module:ol/format/MVT~MVT} as feature format, the
* {@link module:ol/format/MVT~MVT#getLastExtent} method will return the correct
* extent.
* extent. The default is `[0, 0, 4096, 4096]`.
* @param {import("./extent.js").Extent} extent The extent.
* @api
*/

View File

@@ -7,7 +7,7 @@ import {replaceNode} from '../dom.js';
import {listen} from '../events.js';
import EventType from '../events/EventType.js';
const events = ['fullscreenchange', 'webkitfullscreenchange', 'MSFullscreenChange'];
const events = ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange', 'MSFullscreenChange'];
/**
* @typedef {Object} Options
@@ -209,6 +209,7 @@ function isFullScreenSupported() {
const body = document.body;
return !!(
body.webkitRequestFullscreen ||
(body.mozRequestFullScreen && document.mozFullScreenEnabled) ||
(body.msRequestFullscreen && document.msFullscreenEnabled) ||
(body.requestFullscreen && document.fullscreenEnabled)
);
@@ -219,7 +220,8 @@ function isFullScreenSupported() {
*/
function isFullScreen() {
return !!(
document.webkitIsFullScreen || document.msFullscreenElement || document.fullscreenElement
document.webkitIsFullScreen || document.mozFullScreen ||
document.msFullscreenElement || document.fullscreenElement
);
}
@@ -232,6 +234,8 @@ function requestFullScreen(element) {
element.requestFullscreen();
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen();
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullscreen();
}
@@ -242,7 +246,9 @@ function requestFullScreen(element) {
* @param {HTMLElement} element Element to request fullscreen
*/
function requestFullScreenWithKeys(element) {
if (element.webkitRequestFullscreen) {
if (element.mozRequestFullScreenWithKeys) {
element.mozRequestFullScreenWithKeys();
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullscreen();
} else {
requestFullScreen(element);
@@ -257,6 +263,8 @@ function exitFullScreen() {
document.exitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
}

View File

@@ -169,6 +169,8 @@ export function render(mapEvent) {
this.element.classList.remove(CLASS_HIDDEN);
}
}
this.label_.style.msTransform = transform;
this.label_.style.webkitTransform = transform;
this.label_.style.transform = transform;
}
this.rotation_ = rotation;

View File

@@ -201,12 +201,20 @@ class ScaleLine extends Control {
ProjUnits.METERS;
let pointResolution =
getPointResolution(projection, viewState.resolution, center, pointResolutionUnits);
if (projection.getUnits() != ProjUnits.DEGREES && projection.getMetersPerUnit()
&& pointResolutionUnits == ProjUnits.METERS) {
pointResolution *= projection.getMetersPerUnit();
}
let nominalCount = this.minWidth_ * pointResolution;
let suffix = '';
if (units == Units.DEGREES) {
const metersPerDegree = METERS_PER_UNIT[ProjUnits.DEGREES];
nominalCount *= metersPerDegree;
if (projection.getUnits() == ProjUnits.DEGREES) {
nominalCount *= metersPerDegree;
} else {
pointResolution /= metersPerDegree;
}
if (nominalCount < metersPerDegree / 60) {
suffix = '\u2033'; // seconds
pointResolution *= 3600;

View File

@@ -10,14 +10,14 @@
* @return {CanvasRenderingContext2D} The context.
*/
export function createCanvasContext2D(opt_width, opt_height) {
const canvas = document.createElement('canvas');
const canvas = /** @type {HTMLCanvasElement} */ (document.createElement('canvas'));
if (opt_width) {
canvas.width = opt_width;
}
if (opt_height) {
canvas.height = opt_height;
}
return canvas.getContext('2d');
return /** @type {CanvasRenderingContext2D} */ (canvas.getContext('2d'));
}

View File

@@ -230,33 +230,6 @@ export const mouseOnly = function(mapBrowserEvent) {
return pointerEvent.pointerType == 'mouse';
};
/**
* Return `true` if the event originates from a touchable device.
*
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
* @return {boolean} True if the event originates from a touchable device.
* @api
*/
export const touchOnly = function(mapBrowserEvent) {
const pointerEvt = /** @type {import("../MapBrowserPointerEvent").default} */ (mapBrowserEvent).pointerEvent;
assert(pointerEvt !== undefined, 56); // mapBrowserEvent must originate from a pointer event
// see http://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType
return pointerEvt.pointerType === 'touch';
};
/**
* Return `true` if the event originates from a digital pen.
*
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
* @return {boolean} True if the event originates from a digital pen.
* @api
*/
export const penOnly = function(mapBrowserEvent) {
const pointerEvt = /** @type {import("../MapBrowserPointerEvent").default} */ (mapBrowserEvent).pointerEvent;
assert(pointerEvt !== undefined, 56); // mapBrowserEvent must originate from a pointer event
// see http://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType
return pointerEvt.pointerType === 'pen';
};
/**
* Return `true` if the event originates from a primary pointer in

View File

@@ -410,15 +410,15 @@ function readPolygonGeometry(object) {
/**
* @param {import("../geom/Point.js").default} geometry Geometry.
* @param {import("../geom/Geometry.js").default} geometry Geometry.
* @param {import("./Feature.js").WriteOptions=} opt_options Write options.
* @return {EsriJSONPoint} EsriJSON geometry.
*/
function writePointGeometry(geometry, opt_options) {
const coordinates = geometry.getCoordinates();
const coordinates = /** @type {import("../geom/Point.js").default} */ (geometry).getCoordinates();
/** @type {EsriJSONPoint} */
let esriJSON;
const layout = geometry.getLayout();
const layout = /** @type {import("../geom/Point.js").default} */ (geometry).getLayout();
if (layout === GeometryLayout.XYZ) {
esriJSON = {
x: coordinates[0],
@@ -466,11 +466,12 @@ function getHasZM(geometry) {
/**
* @param {import("../geom/LineString.js").default} lineString Geometry.
* @param {import("../geom/Geometry.js").default} geometry Geometry.
* @param {import("./Feature.js").WriteOptions=} opt_options Write options.
* @return {EsriJSONPolyline} EsriJSON geometry.
*/
function writeLineStringGeometry(lineString, opt_options) {
function writeLineStringGeometry(geometry, opt_options) {
const lineString = /** @type {import("../geom/LineString.js").default} */ (geometry);
const hasZM = getHasZM(lineString);
return {
hasZ: hasZM.hasZ,
@@ -483,11 +484,12 @@ function writeLineStringGeometry(lineString, opt_options) {
/**
* @param {import("../geom/Polygon.js").default} polygon Geometry.
* @param {import("../geom/Geometry.js").default} geometry Geometry.
* @param {import("./Feature.js").WriteOptions=} opt_options Write options.
* @return {EsriJSONPolygon} EsriJSON geometry.
*/
function writePolygonGeometry(polygon, opt_options) {
function writePolygonGeometry(geometry, opt_options) {
const polygon = /** @type {import("../geom/Polygon.js").default} */ (geometry);
// Esri geometries use the left-hand rule
const hasZM = getHasZM(polygon);
return {
@@ -499,11 +501,12 @@ function writePolygonGeometry(polygon, opt_options) {
/**
* @param {import("../geom/MultiLineString.js").default} multiLineString Geometry.
* @param {import("../geom/Geometry.js").default} geometry Geometry.
* @param {import("./Feature.js").WriteOptions=} opt_options Write options.
* @return {EsriJSONPolyline} EsriJSON geometry.
*/
function writeMultiLineStringGeometry(multiLineString, opt_options) {
function writeMultiLineStringGeometry(geometry, opt_options) {
const multiLineString = /** @type {import("../geom/MultiLineString.js").default} */ (geometry);
const hasZM = getHasZM(multiLineString);
return {
hasZ: hasZM.hasZ,
@@ -514,11 +517,12 @@ function writeMultiLineStringGeometry(multiLineString, opt_options) {
/**
* @param {import("../geom/MultiPoint.js").default} multiPoint Geometry.
* @param {import("../geom/Geometry.js").default} geometry Geometry.
* @param {import("./Feature.js").WriteOptions=} opt_options Write options.
* @return {EsriJSONMultipoint} EsriJSON geometry.
*/
function writeMultiPointGeometry(multiPoint, opt_options) {
function writeMultiPointGeometry(geometry, opt_options) {
const multiPoint = /** @type {import("../geom/MultiPoint.js").default} */ (geometry);
const hasZM = getHasZM(multiPoint);
return {
hasZ: hasZM.hasZ,
@@ -529,13 +533,13 @@ function writeMultiPointGeometry(multiPoint, opt_options) {
/**
* @param {import("../geom/MultiPolygon.js").default} geometry Geometry.
* @param {import("../geom/Geometry.js").default} geometry Geometry.
* @param {import("./Feature.js").WriteOptions=} opt_options Write options.
* @return {EsriJSONPolygon} EsriJSON geometry.
*/
function writeMultiPolygonGeometry(geometry, opt_options) {
const hasZM = getHasZM(geometry);
const coordinates = geometry.getCoordinates(false);
const hasZM = getHasZM(/** @type {import("../geom/MultiPolygon.js").default} */(geometry));
const coordinates = /** @type {import("../geom/MultiPolygon.js").default} */ (geometry).getCoordinates(false);
const output = [];
for (let i = 0; i < coordinates.length; i++) {
for (let x = coordinates[i].length - 1; x >= 0; x--) {

View File

@@ -718,7 +718,8 @@ class WKT extends TextFeature {
* @inheritDoc
*/
writeGeometryText(geometry, opt_options) {
return encode(transformGeometryWithOptions(geometry, true, opt_options));
return encode(/** @type {import("../geom/Geometry.js").default} */ (
transformGeometryWithOptions(geometry, true, opt_options)));
}
}

View File

@@ -16,7 +16,7 @@ import {deflateMultiCoordinatesArray} from './flat/deflate.js';
import {inflateMultiCoordinatesArray} from './flat/inflate.js';
import {getInteriorPointsOfMultiArray} from './flat/interiorpoint.js';
import {intersectsLinearRingMultiArray} from './flat/intersectsextent.js';
import {linearRingssAreOriented, orientLinearRingsArray} from './flat/orient.js';
import {linearRingsAreOriented, orientLinearRingsArray} from './flat/orient.js';
import {quantizeMultiArray} from './flat/simplify.js';
/**
@@ -251,7 +251,7 @@ class MultiPolygon extends SimpleGeometry {
getOrientedFlatCoordinates() {
if (this.orientedRevision_ != this.getRevision()) {
const flatCoordinates = this.flatCoordinates;
if (linearRingssAreOriented(
if (linearRingsAreOriented(
flatCoordinates, 0, this.endss_, this.stride)) {
this.orientedFlatCoordinates_ = flatCoordinates;
} else {

View File

@@ -16,7 +16,7 @@ import {deflateCoordinatesArray} from './flat/deflate.js';
import {inflateCoordinatesArray} from './flat/inflate.js';
import {getInteriorPointOfArray} from './flat/interiorpoint.js';
import {intersectsLinearRingArray} from './flat/intersectsextent.js';
import {linearRingsAreOriented, orientLinearRings} from './flat/orient.js';
import {linearRingIsOriented, orientLinearRings} from './flat/orient.js';
import {quantizeArray} from './flat/simplify.js';
import {modulo} from '../math.js';
@@ -266,7 +266,7 @@ class Polygon extends SimpleGeometry {
getOrientedFlatCoordinates() {
if (this.orientedRevision_ != this.getRevision()) {
const flatCoordinates = this.flatCoordinates;
if (linearRingsAreOriented(
if (linearRingIsOriented(
flatCoordinates, 0, this.ends_, this.stride)) {
this.orientedFlatCoordinates_ = flatCoordinates;
} else {

View File

@@ -41,7 +41,7 @@ export function linearRingIsClockwise(flatCoordinates, offset, end, stride) {
* (counter-clockwise exterior ring and clockwise interior rings).
* @return {boolean} Rings are correctly oriented.
*/
export function linearRingsAreOriented(flatCoordinates, offset, ends, stride, opt_right) {
export function linearRingIsOriented(flatCoordinates, offset, ends, stride, opt_right) {
const right = opt_right !== undefined ? opt_right : false;
for (let i = 0, ii = ends.length; i < ii; ++i) {
const end = ends[i];
@@ -75,16 +75,12 @@ export function linearRingsAreOriented(flatCoordinates, offset, ends, stride, op
* (counter-clockwise exterior ring and clockwise interior rings).
* @return {boolean} Rings are correctly oriented.
*/
export function linearRingssAreOriented(flatCoordinates, offset, endss, stride, opt_right) {
export function linearRingsAreOriented(flatCoordinates, offset, endss, stride, opt_right) {
for (let i = 0, ii = endss.length; i < ii; ++i) {
const ends = endss[i];
if (!linearRingsAreOriented(
flatCoordinates, offset, ends, stride, opt_right)) {
if (!linearRingIsOriented(
flatCoordinates, offset, endss[i], stride, opt_right)) {
return false;
}
if (ends.length) {
offset = ends[ends.length - 1];
}
}
return true;
}

View File

@@ -11,19 +11,21 @@
* @param {number} offset Offset.
* @param {number} end End.
* @param {number} stride Stride.
* @param {function(import("../../coordinate.js").Coordinate, import("../../coordinate.js").Coordinate): T} callback Function
* @param {function(this: S, import("../../coordinate.js").Coordinate, import("../../coordinate.js").Coordinate): T} callback Function
* called for each segment.
* @param {S=} opt_this The object to be used as the value of 'this'
* within callback.
* @return {T|boolean} Value.
* @template T
* @template T,S
*/
export function forEach(flatCoordinates, offset, end, stride, callback) {
export function forEach(flatCoordinates, offset, end, stride, callback, opt_this) {
const point1 = [flatCoordinates[offset], flatCoordinates[offset + 1]];
const point2 = [];
let ret;
for (; (offset + stride) < end; offset += stride) {
point2[0] = flatCoordinates[offset + stride];
point2[1] = flatCoordinates[offset + stride + 1];
ret = callback(point1, point2);
ret = callback.call(opt_this, point1, point2);
if (ret) {
return ret;
}

View File

@@ -891,7 +891,7 @@ class Draw extends PointerInteraction {
this.sketchFeature_ = null;
this.sketchPoint_ = null;
this.sketchLine_ = null;
this.overlay_.getSource().clear(true);
/** @type {VectorSource} */ (this.overlay_.getSource()).clear(true);
}
return sketchFeature;
}
@@ -930,7 +930,7 @@ class Draw extends PointerInteraction {
if (this.sketchPoint_) {
sketchFeatures.push(this.sketchPoint_);
}
const overlaySource = this.overlay_.getSource();
const overlaySource = /** @type {VectorSource} */ (this.overlay_.getSource());
overlaySource.clear(true);
overlaySource.addFeatures(sketchFeatures);
}

View File

@@ -242,7 +242,7 @@ class ExtentInteraction extends PointerInteraction {
extentFeature = new Feature(polygonFromExtent(extent));
}
this.extentFeature_ = extentFeature;
this.extentOverlay_.getSource().addFeature(extentFeature);
/** @type {VectorSource} */ (this.extentOverlay_.getSource()).addFeature(extentFeature);
} else {
if (!extent) {
extentFeature.setGeometry(undefined);
@@ -263,7 +263,7 @@ class ExtentInteraction extends PointerInteraction {
if (!vertexFeature) {
vertexFeature = new Feature(new Point(vertex));
this.vertexFeature_ = vertexFeature;
this.vertexOverlay_.getSource().addFeature(vertexFeature);
/** @type {VectorSource} */ (this.vertexOverlay_.getSource()).addFeature(vertexFeature);
} else {
const geometry = /** @type {Point} */ (vertexFeature.getGeometry());
geometry.setCoordinates(vertex);

View File

@@ -368,7 +368,7 @@ class Modify extends PointerInteraction {
// Remove the vertex feature if the collection of canditate features
// is empty.
if (this.vertexFeature_ && this.features_.getLength() === 0) {
this.overlay_.getSource().removeFeature(this.vertexFeature_);
/** @type {VectorSource} */ (this.overlay_.getSource()).removeFeature(this.vertexFeature_);
this.vertexFeature_ = null;
}
unlisten(feature, EventType.CHANGE,
@@ -407,7 +407,7 @@ class Modify extends PointerInteraction {
*/
setActive(active) {
if (this.vertexFeature_ && !active) {
this.overlay_.getSource().removeFeature(this.vertexFeature_);
/** @type {VectorSource} */ (this.overlay_.getSource()).removeFeature(this.vertexFeature_);
this.vertexFeature_ = null;
}
super.setActive(active);
@@ -658,7 +658,7 @@ class Modify extends PointerInteraction {
if (!vertexFeature) {
vertexFeature = new Feature(new Point(coordinates));
this.vertexFeature_ = vertexFeature;
this.overlay_.getSource().addFeature(vertexFeature);
/** @type {VectorSource} */ (this.overlay_.getSource()).addFeature(vertexFeature);
} else {
const geometry = /** @type {Point} */ (vertexFeature.getGeometry());
geometry.setCoordinates(coordinates);
@@ -944,7 +944,7 @@ class Modify extends PointerInteraction {
}
}
if (this.vertexFeature_) {
this.overlay_.getSource().removeFeature(this.vertexFeature_);
/** @type {VectorSource} */ (this.overlay_.getSource()).removeFeature(this.vertexFeature_);
this.vertexFeature_ = null;
}
}
@@ -1139,7 +1139,7 @@ class Modify extends PointerInteraction {
}
this.updateSegmentIndices_(geometry, index, segmentData.depth, -1);
if (this.vertexFeature_) {
this.overlay_.getSource().removeFeature(this.vertexFeature_);
/** @type {VectorSource} */ (this.overlay_.getSource()).removeFeature(this.vertexFeature_);
this.vertexFeature_ = null;
}
dragSegments.length = 0;

View File

@@ -275,7 +275,7 @@ class Select extends Interaction {
* @api
*/
getFeatures() {
return this.featureOverlay_.getSource().getFeaturesCollection();
return /** @type {VectorSource} */ (this.featureOverlay_.getSource()).getFeaturesCollection();
}
/**

View File

@@ -34,7 +34,6 @@ import Layer from './Layer.js';
* property on the layer object; for example, setting `title: 'My Title'` in the
* options means that `title` is observable, and has get/set accessors.
*
* @extends {Layer<import("../source/Image.js").default>}
* @api
*/
class BaseImageLayer extends Layer {
@@ -49,4 +48,12 @@ class BaseImageLayer extends Layer {
}
/**
* Return the associated {@link module:ol/source/Image source} of the image layer.
* @function
* @return {import("../source/Image.js").default} Source.
* @api
*/
BaseImageLayer.prototype.getSource;
export default BaseImageLayer;

View File

@@ -39,7 +39,6 @@ import {assign} from '../obj.js';
* property on the layer object; for example, setting `title: 'My Title'` in the
* options means that `title` is observable, and has get/set accessors.
*
* @extends {Layer<import("../source/Tile.js").default>}
* @api
*/
class BaseTileLayer extends Layer {
@@ -103,4 +102,13 @@ class BaseTileLayer extends Layer {
}
/**
* Return the associated {@link module:ol/source/Tile tilesource} of the layer.
* @function
* @return {import("../source/Tile.js").default} Source.
* @api
*/
BaseTileLayer.prototype.getSource;
export default BaseTileLayer;

View File

@@ -61,8 +61,6 @@ const Property = {
* property on the layer object; for example, setting `title: 'My Title'` in the
* options means that `title` is observable, and has get/set accessors.
*
* @template {import("../source/Vector.js").default|import("../source/VectorTile.js").default} VectorSourceType
* @extends {Layer<VectorSourceType>}
* @api
*/
class BaseVectorLayer extends Layer {
@@ -133,6 +131,13 @@ class BaseVectorLayer extends Layer {
return this.declutter_;
}
/**
* @param {boolean} declutter Declutter.
*/
setDeclutter(declutter) {
this.declutter_ = declutter;
}
/**
* @return {number|undefined} Render buffer.
*/
@@ -214,4 +219,13 @@ class BaseVectorLayer extends Layer {
}
/**
* Return the associated {@link module:ol/source/Vector vectorsource} of the layer.
* @function
* @return {import("../source/Vector.js").default} Source.
* @api
*/
BaseVectorLayer.prototype.getSource;
export default BaseVectorLayer;

View File

@@ -150,11 +150,7 @@ class Graticule extends VectorLayer {
constructor(opt_options) {
const options = opt_options ? opt_options : {};
const baseOptions = assign({
updateWhileAnimating: true,
updateWhileInteracting: true,
renderBuffer: 0
}, options);
const baseOptions = assign({}, options);
delete baseOptions.maxLines;
delete baseOptions.strokeStyle;
@@ -426,6 +422,11 @@ class Graticule extends VectorLayer {
this.setRenderOrder(null);
this.renderBuffer_ = 0;
this.updateWhileAnimating_ = true;
this.updateWhileInteracting_ = true;
this.tmpExtent_ = null;
}
@@ -436,7 +437,7 @@ class Graticule extends VectorLayer {
* @param {import("../proj/Projection.js").default} projection Projection
*/
loaderFunction(extent, resolution, projection) {
const source = this.getSource();
const source = /** @type {import("../source/Vector.js").default} */ (this.getSource());
// only consider the intersection between our own extent & the requested one
const layerExtent = this.getExtent() || [-Infinity, -Infinity, Infinity, Infinity];

View File

@@ -62,8 +62,6 @@ import SourceState from '../source/State.js';
*
* @fires import("../render/Event.js").RenderEvent#prerender
* @fires import("../render/Event.js").RenderEvent#postrender
*
* @template {import("../source/Source.js").default} SourceType
*/
class Layer extends BaseLayer {
/**
@@ -108,7 +106,7 @@ class Layer extends BaseLayer {
getChangeEventType(LayerProperty.SOURCE),
this.handleSourcePropertyChange_, this);
const source = options.source ? /** @type {SourceType} */ (options.source) : null;
const source = options.source ? options.source : null;
this.setSource(source);
}
@@ -132,12 +130,15 @@ class Layer extends BaseLayer {
/**
* Get the layer source.
* @return {SourceType} The layer source (or `null` if not yet set).
* @return {import("../source/Source.js").default} The layer source (or `null` if not yet set).
* @observable
* @api
*/
getSource() {
return /** @type {SourceType} */ (this.get(LayerProperty.SOURCE)) || null;
const source = this.get(LayerProperty.SOURCE);
return (
/** @type {import("../source/Source.js").default} */ (source) || null
);
}
/**
@@ -226,7 +227,7 @@ class Layer extends BaseLayer {
/**
* Set the layer source.
* @param {SourceType} source The layer source.
* @param {import("../source/Source.js").default} source The layer source.
* @observable
* @api
*/

View File

@@ -17,7 +17,6 @@ import CanvasVectorLayerRenderer from '../renderer/canvas/VectorLayer.js';
* property on the layer object; for example, setting `title: 'My Title'` in the
* options means that `title` is observable, and has get/set accessors.
*
* @extends {BaseVectorLayer<import("../source/Vector.js").default>}
* @api
*/
class VectorLayer extends BaseVectorLayer {

View File

@@ -6,41 +6,7 @@ import {assign} from '../obj.js';
import CanvasVectorImageLayerRenderer from '../renderer/canvas/VectorImageLayer.js';
/**
* @typedef {Object} Options
* @property {number} [opacity=1] Opacity (0, 1).
* @property {boolean} [visible=true] Visibility.
* @property {import("../extent.js").Extent} [extent] The bounding extent for layer rendering. The layer will not be
* rendered outside of this extent.
* @property {number} [zIndex] The z-index for layer rendering. At rendering time, the layers
* will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed
* for layers that are added to the map's `layers` collection, or `Infinity` when the layer's `setMap()`
* method was used.
* @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be
* visible.
* @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will
* be visible.
* @property {import("../render.js").OrderFunction} [renderOrder] Render order. Function to be used when sorting
* features before rendering. By default features are drawn in the order that they are created. Use
* `null` to avoid the sort, but get an undefined draw order.
* @property {number} [renderBuffer=100] The buffer in pixels around the viewport extent used by the
* renderer when getting features from the vector source for the rendering or hit-detection.
* Recommended value: the size of the largest symbol, line width or label.
* @property {import("../source/Vector.js").default} [source] Source.
* @property {import("../PluggableMap.js").default} [map] Sets the layer as overlay on a map. The map will not manage
* this layer in its layers collection, and the layer will be rendered on top. This is useful for
* temporary layers. The standard way to add a layer to a map and have it managed by the map is to
* use {@link module:ol/Map#addLayer}.
* @property {boolean} [declutter=false] Declutter images and text. Decluttering is applied to all
* image and text styles, and the priority is defined by the z-index of the style. Lower z-index
* means higher priority.
* @property {import("../style/Style.js").StyleLike} [style] Layer style. See
* {@link module:ol/style} for default style which will be used if this is not defined.
* @property {boolean} [updateWhileAnimating=false] When set to `true`, feature batches will
* be recreated during animations. This means that no vectors will be shown clipped, but the
* setting will have a performance impact for large amounts of vector data. When set to `false`,
* batches will be recreated when no animation is active.
* @property {boolean} [updateWhileInteracting=false] When set to `true`, feature batches will
* be recreated during interactions. See also `updateWhileAnimating`.
* @typedef {import("./BaseVector.js").Options} Options
* @property {number} [imageRatio=1] Ratio by which the rendered extent should be larger than the
* viewport extent. A larger ratio avoids cut images during panning, but will cause a decrease in performance.
*/

View File

@@ -33,13 +33,12 @@ import {assign} from '../obj.js';
* point symbol or line width.
* @property {import("./VectorTileRenderType.js").default|string} [renderMode='hybrid'] Render mode for vector tiles:
* * `'image'`: Vector tiles are rendered as images. Great performance, but point symbols and texts
* are always rotated with the view and pixels are scaled during zoom animations. When `declutter`
* is set to `true`, the decluttering is done per tile resulting in labels and point symbols getting
* cut off at tile boundaries.
* are always rotated with the view and pixels are scaled during zoom animations.
* * `'hybrid'`: Polygon and line elements are rendered as images, so pixels are scaled during zoom
* animations. Point symbols and texts are accurately rendered as vectors and can stay upright on
* rotated views.
*
* When `declutter` is set to `true`, `'hybrid'` will be used instead of `'image'`.
* @property {import("../source/VectorTile.js").default} [source] Source.
* @property {import("../PluggableMap.js").default} [map] Sets the layer as overlay on a map. The map will not manage
* this layer in its layers collection, and the layer will be rendered on top. This is useful for
@@ -47,7 +46,8 @@ import {assign} from '../obj.js';
* use {@link module:ol/Map#addLayer}.
* @property {boolean} [declutter=false] Declutter images and text. Decluttering is applied to all
* image and text styles, and the priority is defined by the z-index of the style. Lower z-index
* means higher priority.
* means higher priority. When set to `true`, a `renderMode` of `'image'` will be overridden with
* `'hybrid'`.
* @property {import("../style/Style.js").StyleLike} [style] Layer style. See
* {@link module:ol/style} for default style which will be used if this is not defined.
* @property {boolean} [updateWhileAnimating=false] When set to `true`, feature batches will be
@@ -70,7 +70,6 @@ import {assign} from '../obj.js';
* options means that `title` is observable, and has get/set accessors.
*
* @param {Options=} opt_options Options.
* @extends {BaseVectorLayer<import("../source/VectorTile.js").default>}
* @api
*/
class VectorTileLayer extends BaseVectorLayer {
@@ -86,12 +85,16 @@ class VectorTileLayer extends BaseVectorLayer {
super(/** @type {import("./Vector.js").Options} */ (baseOptions));
const renderMode = options.renderMode || VectorTileRenderType.HYBRID;
let renderMode = options.renderMode || VectorTileRenderType.HYBRID;
assert(renderMode == undefined ||
renderMode == VectorTileRenderType.IMAGE ||
renderMode == VectorTileRenderType.HYBRID,
28); // `renderMode` must be `'image'` or `'hybrid'`
if (options.declutter && renderMode == VectorTileRenderType.IMAGE) {
renderMode = VectorTileRenderType.HYBRID;
}
/**
* @private
* @type {VectorTileRenderType}
@@ -162,4 +165,11 @@ class VectorTileLayer extends BaseVectorLayer {
}
/**
* Return the associated {@link module:ol/source/VectorTile vectortilesource} of the layer.
* @function
* @return {import("../source/VectorTile.js").default} Source.
* @api
*/
VectorTileLayer.prototype.getSource;
export default VectorTileLayer;

View File

@@ -188,12 +188,6 @@ export function getPointResolution(projection, resolution, point, opt_units) {
const getter = projection.getPointResolutionFunc();
if (getter) {
pointResolution = getter(resolution, point);
if (opt_units && opt_units !== projection.getUnits()) {
const metersPerUnit = projection.getMetersPerUnit();
if (metersPerUnit) {
pointResolution = pointResolution * metersPerUnit / METERS_PER_UNIT[opt_units];
}
}
} else {
const units = projection.getUnits();
if (units == Units.DEGREES && !opt_units || opt_units == Units.DEGREES) {

View File

@@ -19,7 +19,7 @@ import {METERS_PER_UNIT} from './Units.js';
* @property {function(number, import("../coordinate.js").Coordinate):number} [getPointResolution]
* Function to determine resolution at a point. The function is called with a
* `{number}` view resolution and an `{import("../coordinate.js").Coordinate}` as arguments, and returns
* the `{number}` resolution in projection units at the passed coordinate. If this is `undefined`,
* the `{number}` resolution at the passed coordinate. If this is `undefined`,
* the default {@link module:ol/proj#getPointResolution} function will be used.
*/

View File

@@ -22,7 +22,7 @@ class RenderBox extends Disposable {
* @type {HTMLDivElement}
* @private
*/
this.element_ = document.createElement('div');
this.element_ = /** @type {HTMLDivElement} */ (document.createElement('div'));
this.element_.style.position = 'absolute';
this.element_.className = 'ol-box ' + className;

View File

@@ -22,82 +22,81 @@ const tmpTransform = createTransform();
* Lightweight, read-only, {@link module:ol/Feature~Feature} and {@link module:ol/geom/Geometry~Geometry} like
* structure, optimized for vector tile rendering and styling. Geometry access
* through the API is limited to getting the type and extent of the geometry.
*
* @param {GeometryType} type Geometry type.
* @param {Array<number>} flatCoordinates Flat coordinates. These always need
* to be right-handed for polygons.
* @param {Array<number>|Array<Array<number>>} ends Ends or Endss.
* @param {Object<string, *>} properties Properties.
* @param {number|string|undefined} id Feature id.
*/
class RenderFeature {
/**
* @param {GeometryType} type Geometry type.
* @param {Array<number>} flatCoordinates Flat coordinates. These always need
* to be right-handed for polygons.
* @param {Array<number>|Array<Array<number>>} ends Ends or Endss.
* @param {Object<string, *>} properties Properties.
* @param {number|string|undefined} id Feature id.
*/
constructor(type, flatCoordinates, ends, properties, id) {
/**
* @private
* @type {import("../extent.js").Extent|undefined}
*/
* @private
* @type {import("../extent.js").Extent|undefined}
*/
this.extent_;
/**
* @private
* @type {number|string|undefined}
*/
* @private
* @type {number|string|undefined}
*/
this.id_ = id;
/**
* @private
* @type {GeometryType}
*/
* @private
* @type {GeometryType}
*/
this.type_ = type;
/**
* @private
* @type {Array<number>}
*/
* @private
* @type {Array<number>}
*/
this.flatCoordinates_ = flatCoordinates;
/**
* @private
* @type {Array<number>}
*/
* @private
* @type {Array<number>}
*/
this.flatInteriorPoints_ = null;
/**
* @private
* @type {Array<number>}
*/
* @private
* @type {Array<number>}
*/
this.flatMidpoints_ = null;
/**
* @private
* @type {Array<number>|Array<Array<number>>}
*/
* @private
* @type {Array<number>|Array<Array<number>>}
*/
this.ends_ = ends;
/**
* @private
* @type {Object<string, *>}
*/
* @private
* @type {Object<string, *>}
*/
this.properties_ = properties;
}
/**
* Get a feature property by its key.
* @param {string} key Key
* @return {*} Value for the requested key.
* @api
*/
* Get a feature property by its key.
* @param {string} key Key
* @return {*} Value for the requested key.
* @api
*/
get(key) {
return this.properties_[key];
}
/**
* Get the extent of this feature's geometry.
* @return {import("../extent.js").Extent} Extent.
* @api
*/
* Get the extent of this feature's geometry.
* @return {import("../extent.js").Extent} Extent.
* @api
*/
getExtent() {
if (!this.extent_) {
this.extent_ = this.type_ === GeometryType.POINT ?
@@ -110,8 +109,8 @@ class RenderFeature {
}
/**
* @return {Array<number>} Flat interior points.
*/
* @return {Array<number>} Flat interior points.
*/
getFlatInteriorPoint() {
if (!this.flatInteriorPoints_) {
const flatCenter = getCenter(this.getExtent());
@@ -122,8 +121,8 @@ class RenderFeature {
}
/**
* @return {Array<number>} Flat interior points.
*/
* @return {Array<number>} Flat interior points.
*/
getFlatInteriorPoints() {
if (!this.flatInteriorPoints_) {
const flatCenters = linearRingssCenter(
@@ -135,8 +134,8 @@ class RenderFeature {
}
/**
* @return {Array<number>} Flat midpoint.
*/
* @return {Array<number>} Flat midpoint.
*/
getFlatMidpoint() {
if (!this.flatMidpoints_) {
this.flatMidpoints_ = interpolatePoint(
@@ -146,8 +145,8 @@ class RenderFeature {
}
/**
* @return {Array<number>} Flat midpoints.
*/
* @return {Array<number>} Flat midpoints.
*/
getFlatMidpoints() {
if (!this.flatMidpoints_) {
this.flatMidpoints_ = [];
@@ -166,28 +165,28 @@ class RenderFeature {
}
/**
* Get the feature identifier. This is a stable identifier for the feature and
* is set when reading data from a remote source.
* @return {number|string|undefined} Id.
* @api
*/
* Get the feature identifier. This is a stable identifier for the feature and
* is set when reading data from a remote source.
* @return {number|string|undefined} Id.
* @api
*/
getId() {
return this.id_;
}
/**
* @return {Array<number>} Flat coordinates.
*/
* @return {Array<number>} Flat coordinates.
*/
getOrientedFlatCoordinates() {
return this.flatCoordinates_;
}
/**
* For API compatibility with {@link module:ol/Feature~Feature}, this method is useful when
* determining the geometry type in style function (see {@link #getType}).
* @return {RenderFeature} Feature.
* @api
*/
* For API compatibility with {@link module:ol/Feature~Feature}, this method is useful when
* determining the geometry type in style function (see {@link #getType}).
* @return {RenderFeature} Feature.
* @api
*/
getGeometry() {
return this;
}
@@ -201,17 +200,17 @@ class RenderFeature {
}
/**
* Get the feature properties.
* @return {Object<string, *>} Feature properties.
* @api
*/
* Get the feature properties.
* @return {Object<string, *>} Feature properties.
* @api
*/
getProperties() {
return this.properties_;
}
/**
* @return {number} Stride.
*/
* @return {number} Stride.
*/
getStride() {
return 2;
}
@@ -224,21 +223,21 @@ class RenderFeature {
}
/**
* Get the type of this feature's geometry.
* @return {GeometryType} Geometry type.
* @api
*/
* Get the type of this feature's geometry.
* @return {GeometryType} Geometry type.
* @api
*/
getType() {
return this.type_;
}
/**
* Transform geometry coordinates from tile pixel space to projected.
* The SRS of the source and destination are expected to be the same.
*
* @param {import("../proj.js").ProjectionLike} source The current projection
* @param {import("../proj.js").ProjectionLike} destination The desired projection.
*/
* Transform geometry coordinates from tile pixel space to projected.
* The SRS of the source and destination are expected to be the same.
*
* @param {import("../proj.js").ProjectionLike} source The current projection
* @param {import("../proj.js").ProjectionLike} destination The desired projection.
*/
transform(source, destination) {
source = getProjection(source);
const pixelExtent = source.getExtent();

View File

@@ -206,7 +206,7 @@ class CanvasBuilder extends VectorContext {
* @inheritDoc.
*/
drawCustom(geometry, feature, renderer) {
this.beginGeometry(feature);
this.beginGeometry(geometry, feature);
const type = geometry.getType();
const stride = geometry.getStride();
const builderBegin = this.coordinates.length;
@@ -248,14 +248,15 @@ class CanvasBuilder extends VectorContext {
this.instructions.push([CanvasInstruction.CUSTOM,
builderBegin, builderEnd, geometry, renderer]);
}
this.endGeometry(feature);
this.endGeometry(geometry, feature);
}
/**
* @protected
* @param {import("../../geom/Geometry.js").default|import("../Feature.js").default} geometry Geometry.
* @param {import("../../Feature.js").FeatureLike} feature Feature.
*/
beginGeometry(feature) {
beginGeometry(geometry, feature) {
this.beginGeometryInstruction1_ = [CanvasInstruction.BEGIN_GEOMETRY, feature, 0];
this.instructions.push(this.beginGeometryInstruction1_);
this.beginGeometryInstruction2_ = [CanvasInstruction.BEGIN_GEOMETRY, feature, 0];
@@ -352,9 +353,10 @@ class CanvasBuilder extends VectorContext {
/**
* @param {import("../canvas.js").FillStrokeState} state State.
* @param {import("../../geom/Geometry.js").default|import("../Feature.js").default} geometry Geometry.
* @return {Array<*>} Fill instruction.
*/
createFill(state) {
createFill(state, geometry) {
const fillStyle = state.fillStyle;
/** @type {Array<*>} */
const fillInstruction = [CanvasInstruction.SET_FILL_STYLE, fillStyle];
@@ -387,13 +389,14 @@ class CanvasBuilder extends VectorContext {
/**
* @param {import("../canvas.js").FillStrokeState} state State.
* @param {function(this:CanvasBuilder, import("../canvas.js").FillStrokeState):Array<*>} createFill Create fill.
* @param {function(this:CanvasBuilder, import("../canvas.js").FillStrokeState, (import("../../geom/Geometry.js").default|import("../Feature.js").default)):Array<*>} createFill Create fill.
* @param {import("../../geom/Geometry.js").default|import("../Feature.js").default} geometry Geometry.
*/
updateFillStyle(state, createFill) {
updateFillStyle(state, createFill, geometry) {
const fillStyle = state.fillStyle;
if (typeof fillStyle !== 'string' || state.currentFillStyle != fillStyle) {
if (fillStyle !== undefined) {
this.instructions.push(createFill.call(this, state));
this.instructions.push(createFill.call(this, state, geometry));
}
state.currentFillStyle = fillStyle;
}
@@ -432,9 +435,10 @@ class CanvasBuilder extends VectorContext {
}
/**
* @param {import("../../geom/Geometry.js").default|import("../Feature.js").default} geometry Geometry.
* @param {import("../../Feature.js").FeatureLike} feature Feature.
*/
endGeometry(feature) {
endGeometry(geometry, feature) {
this.beginGeometryInstruction1_[2] = this.instructions.length;
this.beginGeometryInstruction1_ = null;
this.beginGeometryInstruction2_[2] = this.hitDetectionInstructions.length;

View File

@@ -113,7 +113,7 @@ class CanvasImageBuilder extends CanvasBuilder {
if (!this.image_) {
return;
}
this.beginGeometry(feature);
this.beginGeometry(pointGeometry, feature);
const flatCoordinates = pointGeometry.getFlatCoordinates();
const stride = pointGeometry.getStride();
const myBegin = this.coordinates.length;
@@ -132,7 +132,7 @@ class CanvasImageBuilder extends CanvasBuilder {
this.originX_, this.originY_, this.rotateWithView_, this.rotation_,
this.scale_, this.width_
]);
this.endGeometry(feature);
this.endGeometry(pointGeometry, feature);
}
/**
@@ -142,7 +142,7 @@ class CanvasImageBuilder extends CanvasBuilder {
if (!this.image_) {
return;
}
this.beginGeometry(feature);
this.beginGeometry(multiPointGeometry, feature);
const flatCoordinates = multiPointGeometry.getFlatCoordinates();
const stride = multiPointGeometry.getStride();
const myBegin = this.coordinates.length;
@@ -162,7 +162,7 @@ class CanvasImageBuilder extends CanvasBuilder {
this.originX_, this.originY_, this.rotateWithView_, this.rotation_,
this.scale_, this.width_
]);
this.endGeometry(feature);
this.endGeometry(multiPointGeometry, feature);
}
/**

View File

@@ -44,7 +44,7 @@ class CanvasLineStringBuilder extends CanvasBuilder {
return;
}
this.updateStrokeStyle(state, this.applyStroke);
this.beginGeometry(feature);
this.beginGeometry(lineStringGeometry, feature);
this.hitDetectionInstructions.push([
CanvasInstruction.SET_STROKE_STYLE,
state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,
@@ -54,7 +54,7 @@ class CanvasLineStringBuilder extends CanvasBuilder {
const stride = lineStringGeometry.getStride();
this.drawFlatCoordinates_(flatCoordinates, 0, flatCoordinates.length, stride);
this.hitDetectionInstructions.push(strokeInstruction);
this.endGeometry(feature);
this.endGeometry(lineStringGeometry, feature);
}
/**
@@ -68,7 +68,7 @@ class CanvasLineStringBuilder extends CanvasBuilder {
return;
}
this.updateStrokeStyle(state, this.applyStroke);
this.beginGeometry(feature);
this.beginGeometry(multiLineStringGeometry, feature);
this.hitDetectionInstructions.push([
CanvasInstruction.SET_STROKE_STYLE,
state.strokeStyle, state.lineWidth, state.lineCap, state.lineJoin,
@@ -82,7 +82,7 @@ class CanvasLineStringBuilder extends CanvasBuilder {
offset = this.drawFlatCoordinates_(flatCoordinates, offset, ends[i], stride);
}
this.hitDetectionInstructions.push(strokeInstruction);
this.endGeometry(feature);
this.endGeometry(multiLineStringGeometry, feature);
}
/**

View File

@@ -72,8 +72,8 @@ class CanvasPolygonBuilder extends CanvasBuilder {
if (fillStyle === undefined && strokeStyle === undefined) {
return;
}
this.setFillStrokeStyles_();
this.beginGeometry(feature);
this.setFillStrokeStyles_(circleGeometry);
this.beginGeometry(circleGeometry, feature);
if (state.fillStyle !== undefined) {
this.hitDetectionInstructions.push([
CanvasInstruction.SET_FILL_STYLE,
@@ -103,7 +103,7 @@ class CanvasPolygonBuilder extends CanvasBuilder {
this.instructions.push(strokeInstruction);
this.hitDetectionInstructions.push(strokeInstruction);
}
this.endGeometry(feature);
this.endGeometry(circleGeometry, feature);
}
/**
@@ -116,8 +116,8 @@ class CanvasPolygonBuilder extends CanvasBuilder {
if (fillStyle === undefined && strokeStyle === undefined) {
return;
}
this.setFillStrokeStyles_();
this.beginGeometry(feature);
this.setFillStrokeStyles_(polygonGeometry);
this.beginGeometry(polygonGeometry, feature);
if (state.fillStyle !== undefined) {
this.hitDetectionInstructions.push([
CanvasInstruction.SET_FILL_STYLE,
@@ -135,7 +135,7 @@ class CanvasPolygonBuilder extends CanvasBuilder {
const flatCoordinates = polygonGeometry.getOrientedFlatCoordinates();
const stride = polygonGeometry.getStride();
this.drawFlatCoordinatess_(flatCoordinates, 0, ends, stride);
this.endGeometry(feature);
this.endGeometry(polygonGeometry, feature);
}
/**
@@ -148,8 +148,8 @@ class CanvasPolygonBuilder extends CanvasBuilder {
if (fillStyle === undefined && strokeStyle === undefined) {
return;
}
this.setFillStrokeStyles_();
this.beginGeometry(feature);
this.setFillStrokeStyles_(multiPolygonGeometry);
this.beginGeometry(multiPolygonGeometry, feature);
if (state.fillStyle !== undefined) {
this.hitDetectionInstructions.push([
CanvasInstruction.SET_FILL_STYLE,
@@ -170,7 +170,7 @@ class CanvasPolygonBuilder extends CanvasBuilder {
for (let i = 0, ii = endss.length; i < ii; ++i) {
offset = this.drawFlatCoordinatess_(flatCoordinates, offset, endss[i], stride);
}
this.endGeometry(feature);
this.endGeometry(multiPolygonGeometry, feature);
}
/**
@@ -195,12 +195,13 @@ class CanvasPolygonBuilder extends CanvasBuilder {
/**
* @private
* @param {import("../../geom/Geometry.js").default|import("../Feature.js").default} geometry Geometry.
*/
setFillStrokeStyles_() {
setFillStrokeStyles_(geometry) {
const state = this.state;
const fillStyle = state.fillStyle;
if (fillStyle !== undefined) {
this.updateFillStyle(state, this.createFill);
this.updateFillStyle(state, this.createFill, geometry);
}
if (state.strokeStyle !== undefined) {
this.updateStrokeStyle(state, this.applyStroke);

View File

@@ -184,7 +184,7 @@ class CanvasTextBuilder extends CanvasBuilder {
ends.push(endss[i][0]);
}
}
this.beginGeometry(feature);
this.beginGeometry(geometry, feature);
const textAlign = textState.textAlign;
let flatOffset = 0;
let flatEnd;
@@ -204,7 +204,7 @@ class CanvasTextBuilder extends CanvasBuilder {
this.drawChars_(begin, end, this.declutterGroup_);
begin = end;
}
this.endGeometry(feature);
this.endGeometry(geometry, feature);
} else {
@@ -258,8 +258,8 @@ class CanvasTextBuilder extends CanvasBuilder {
if (textState.backgroundFill || textState.backgroundStroke) {
this.setFillStrokeStyle(textState.backgroundFill, textState.backgroundStroke);
if (textState.backgroundFill) {
this.updateFillStyle(this.state, this.createFill);
this.hitDetectionInstructions.push(this.createFill(this.state));
this.updateFillStyle(this.state, this.createFill, geometry);
this.hitDetectionInstructions.push(this.createFill(this.state, geometry));
}
if (textState.backgroundStroke) {
this.updateStrokeStyle(this.state, this.applyStroke);
@@ -267,7 +267,7 @@ class CanvasTextBuilder extends CanvasBuilder {
}
}
this.beginGeometry(feature);
this.beginGeometry(geometry, feature);
// The image is unknown at this stage so we pass null; it will be computed at render time.
// For clarity, we pass NaN for offsetX, offsetY, width and height, which will be computed at
@@ -293,7 +293,7 @@ class CanvasTextBuilder extends CanvasBuilder {
this.textOffsetX_, this.textOffsetY_, geometryWidths
]);
this.endGeometry(feature);
this.endGeometry(geometry, feature);
}
}

View File

@@ -221,8 +221,10 @@ class LayerRenderer extends Observable {
* @param {import("../extent.js").Extent} extent Extent.
* @param {number} currentZ Current Z.
* @param {number} preload Load low resolution tiles up to 'preload' levels.
* @param {function(import("../Tile.js").default)=} opt_tileCallback Tile callback.
* @param {function(this: T, import("../Tile.js").default)=} opt_tileCallback Tile callback.
* @param {T=} opt_this Object to use as `this` in `opt_tileCallback`.
* @protected
* @template T
*/
manageTilePyramid(
frameState,
@@ -233,7 +235,8 @@ class LayerRenderer extends Observable {
extent,
currentZ,
preload,
opt_tileCallback
opt_tileCallback,
opt_this
) {
const tileSourceKey = getUid(tileSource);
if (!(tileSourceKey in frameState.wantedTiles)) {
@@ -258,7 +261,7 @@ class LayerRenderer extends Observable {
}
}
if (opt_tileCallback !== undefined) {
opt_tileCallback(tile);
opt_tileCallback.call(opt_this, tile);
}
} else {
tileSource.useTile(z, x, y, projection);

View File

@@ -305,4 +305,12 @@ function getLayerStatesMap(layerStatesArray) {
}, {});
}
/**
* @param {import("../layer/Layer.js").State} state1 First layer state.
* @param {import("../layer/Layer.js").State} state2 Second layer state.
* @return {number} The zIndex difference.
*/
export function sortByZIndex(state1, state2) {
return state1.zIndex - state2.zIndex;
}
export default MapRenderer;

View File

@@ -43,7 +43,8 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer {
const viewState = frameState.viewState;
const viewResolution = viewState.resolution;
const imageSource = this.getLayer().getSource();
const imageLayer = /** @type {import("../../layer/Image.js").default} */ (this.getLayer());
const imageSource = /** @type {import("../../source/Image.js").default} */ (imageLayer.getSource());
const hints = frameState.viewHints;

View File

@@ -88,7 +88,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
*/
getTile(z, x, y, pixelRatio, projection) {
const tileLayer = /** @type {import("../../layer/Tile.js").default} */ (this.getLayer());
const tileSource = tileLayer.getSource();
const tileSource = /** @type {import("../../source/Tile.js").default} */ (tileLayer.getSource());
let tile = tileSource.getTile(z, x, y, pixelRatio, projection);
if (tile.getState() == TileState.ERROR) {
if (!tileLayer.getUseInterimTilesOnError()) {
@@ -105,16 +105,6 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
return tile;
}
/**
* @inheritDoc
*/
loadedTileCallback(tiles, zoom, tile) {
if (this.isDrawableTile(tile)) {
return super.loadedTileCallback(tiles, zoom, tile);
}
return false;
}
/**
* @inheritDoc
*/
@@ -140,7 +130,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
const pixelRatio = frameState.pixelRatio;
const tileLayer = /** @type {import("../../layer/Tile.js").default} */ (this.getLayer());
const tileSource = tileLayer.getSource();
const tileSource = /** @type {import("../../source/Tile.js").default} */ (tileLayer.getSource());
const sourceRevision = tileSource.getRevision();
const tileGrid = tileSource.getTileGridForProjection(projection);
const z = tileGrid.getZForResolution(viewResolution, this.zDirection);
@@ -209,7 +199,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
covered = findLoadedTiles(z + 1, childTileRange);
}
if (!covered) {
tileGrid.forEachTileCoordParentTileRange(tile.tileCoord, findLoadedTiles, tmpTileRange, tmpExtent);
tileGrid.forEachTileCoordParentTileRange(tile.tileCoord, findLoadedTiles, null, tmpTileRange, tmpExtent);
}
}
@@ -291,7 +281,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
const w = nextX - x;
const h = nextY - y;
this.drawTileImage(tile, frameState, x, y, w, h, tileGutter, z === currentZ);
this.drawTileImage(tile, frameState, layerState, x, y, w, h, tileGutter, z === currentZ);
this.renderedTiles.push(tile);
this.updateUsedTiles(frameState.usedTiles, tileSource, tile);
}
@@ -328,6 +318,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
/**
* @param {import("../../Tile.js").default} tile Tile.
* @param {import("../../PluggableMap.js").FrameState} frameState Frame state.
* @param {import("../../layer/Layer.js").State} layerState Layer state.
* @param {number} x Left of the tile.
* @param {number} y Top of the tile.
* @param {number} w Width of the tile.
@@ -335,7 +326,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
* @param {number} gutter Tile gutter.
* @param {boolean} transition Apply an alpha transition.
*/
drawTileImage(tile, frameState, x, y, w, h, gutter, transition) {
drawTileImage(tile, frameState, layerState, x, y, w, h, gutter, transition) {
const image = this.getTileImage(tile);
if (!image) {
return;
@@ -343,7 +334,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
const uid = getUid(this);
const alpha = transition ? tile.getAlpha(uid, frameState.time) : 1;
const tileLayer = /** @type {import("../../layer/Tile.js").default} */ (this.getLayer());
const tileSource = tileLayer.getSource();
const tileSource = /** @type {import("../../source/Tile.js").default} */ (tileLayer.getSource());
if (alpha === 1 && !tileSource.getOpaque(frameState.viewState.projection)) {
this.context.clearRect(x, y, w, h);
}

View File

@@ -8,9 +8,6 @@ import {getHeight, getWidth, isEmpty, scaleFromCenter} from '../../extent.js';
import {assign} from '../../obj.js';
import CanvasImageLayerRenderer from './ImageLayer.js';
import CanvasVectorLayerRenderer from './VectorLayer.js';
import {listen} from '../../events.js';
import EventType from '../../events/EventType.js';
import ImageState from '../../ImageState.js';
/**
* @classdesc
@@ -85,19 +82,17 @@ class CanvasVectorImageLayerRenderer extends CanvasImageLayerRenderer {
if (vectorRenderer.prepareFrame(imageFrameState, layerState) &&
(vectorRenderer.replayGroupChanged ||
!equals(skippedFeatures, newSkippedFeatures))) {
context.canvas.width = imageFrameState.size[0] * pixelRatio;
context.canvas.height = imageFrameState.size[1] * pixelRatio;
vectorRenderer.renderFrame(imageFrameState, layerState);
skippedFeatures = newSkippedFeatures;
callback();
}
});
listen(image, EventType.CHANGE, function() {
if (image.getState() === ImageState.LOADED) {
this.image_ = image;
this.skippedFeatures_ = skippedFeatures;
}
}, this);
image.load();
if (this.loadImage(image)) {
this.image_ = image;
this.skippedFeatures_ = skippedFeatures;
}
}
if (this.image_) {

View File

@@ -129,7 +129,7 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
const projection = viewState.projection;
const rotation = viewState.rotation;
const projectionExtent = projection.getExtent();
const vectorSource = this.getLayer().getSource();
const vectorSource = /** @type {import("../../source/Vector.js").default} */ (this.getLayer().getSource());
// clipped rendering if layer extent is set
const clipExtent = layerState.extent;
@@ -196,7 +196,7 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
} else {
const resolution = frameState.viewState.resolution;
const rotation = frameState.viewState.rotation;
const layer = this.getLayer();
const layer = /** @type {import("../../layer/Vector.js").default} */ (this.getLayer());
/** @type {!Object<string, boolean>} */
const features = {};
const result = this.replayGroup_.forEachFeatureAtCoordinate(coordinate, resolution, rotation, hitTolerance, {},
@@ -239,7 +239,7 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
*/
prepareFrame(frameState, layerState) {
const vectorLayer = /** @type {import("../../layer/Vector.js").default} */ (this.getLayer());
const vectorSource = vectorLayer.getSource();
const vectorSource = /** @type {import("../../source/Vector.js").default} */ (vectorLayer.getSource());
const animating = frameState.viewHints[ViewHint.ANIMATING];
const interacting = frameState.viewHints[ViewHint.INTERACTING];

View File

@@ -205,14 +205,16 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
* @inheritDoc
*/
getTileImage(tile) {
return tile.getImage(this.getLayer());
const tileLayer = /** @type {import("../../layer/Tile.js").default} */ (this.getLayer());
return tile.getImage(tileLayer);
}
/**
* @inheritDoc
*/
prepareFrame(frameState, layerState) {
const layerRevision = this.getLayer().getRevision();
const layer = /** @type {import("../../layer/VectorTile.js").default} */ (this.getLayer());
const layerRevision = layer.getRevision();
if (this.renderedLayerRevision_ != layerRevision) {
this.renderedTiles.length = 0;
}
@@ -227,9 +229,9 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
* @private
*/
updateExecutorGroup_(tile, pixelRatio, projection) {
const layer = /** @type {import("../../layer/VectorTile.js").default} */ (this.getLayer());
const layer = /** @type {import("../../layer/Vector.js").default} */ (this.getLayer());
const revision = layer.getRevision();
const renderOrder = layer.getRenderOrder() || null;
const renderOrder = /** @type {import("../../render.js").OrderFunction} */ (layer.getRenderOrder()) || null;
const builderState = tile.getReplayState(layer);
if (!builderState.dirty && builderState.renderedRevision == revision &&
@@ -237,7 +239,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
return;
}
const source = layer.getSource();
const source = /** @type {import("../../source/VectorTile.js").default} */ (layer.getSource());
const sourceTileGrid = source.getTileGrid();
const tileGrid = source.getTileGridForProjection(projection);
const zoom = tile.tileCoord[0];
@@ -332,24 +334,21 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
const rotation = frameState.viewState.rotation;
hitTolerance = hitTolerance == undefined ? 0 : hitTolerance;
const layer = this.getLayer();
const source = layer.getSource();
const source = /** @type {import("../../source/VectorTile").default} */ (layer.getSource());
const tileGrid = source.getTileGridForProjection(frameState.viewState.projection);
/** @type {!Object<string, boolean>} */
const features = {};
const renderedTiles = /** @type {Array<import("../../VectorRenderTile.js").default>} */ (this.renderedTiles);
let found;
let bufferedExtent, found;
let i, ii;
for (i = 0, ii = renderedTiles.length; i < ii; ++i) {
const tile = renderedTiles[i];
if (!this.declutterTree_) {
// When not decluttering, we only need to consider the tile that contains the given
// coordinate, because each feature will be rendered for each tile that contains it.
const tileExtent = tileGrid.getTileCoordExtent(tile.wrappedTileCoord);
if (!containsCoordinate(tileExtent, coordinate)) {
continue;
}
const tileExtent = tileGrid.getTileCoordExtent(tile.wrappedTileCoord);
bufferedExtent = buffer(tileExtent, hitTolerance * resolution, bufferedExtent);
if (!containsCoordinate(bufferedExtent, coordinate)) {
continue;
}
const executorGroups = tile.executorGroups[getUid(layer)];
for (let t = 0, tt = executorGroups.length; t < tt; ++t) {
@@ -360,10 +359,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
* @return {?} Callback result.
*/
function(feature) {
let key = feature.getId();
if (key === undefined) {
key = getUid(feature);
}
const key = getUid(feature);
if (!(key in features)) {
features[key] = true;
return callback.call(thisArg, feature, layer);
@@ -382,7 +378,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
*/
getReplayTransform_(tile, frameState) {
const layer = this.getLayer();
const source = layer.getSource();
const source = /** @type {import("../../source/VectorTile.js").default} */ (layer.getSource());
const tileGrid = source.getTileGrid();
const tileCoord = tile.tileCoord;
const tileResolution = tileGrid.getResolution(tileCoord[0]);
@@ -439,7 +435,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
const context = this.overlayContext_;
const declutterReplays = layer.getDeclutter() ? {} : null;
const source = layer.getSource();
const source = /** @type {import("../../source/VectorTile.js").default} */ (layer.getSource());
const replayTypes = VECTOR_REPLAYS[renderMode];
const pixelRatio = frameState.pixelRatio;
const rotation = frameState.viewState.rotation;
@@ -551,10 +547,6 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
const tile = this.renderTileImageQueue_[uid];
frameState.animate = true;
delete this.renderTileImageQueue_[uid];
const layer = /** @type {import("../../layer/VectorTile.js").default} */ (this.getLayer());
if (this.declutterTree_ && layer.getRenderMode() === VectorTileRenderType.IMAGE) {
this.declutterTree_.clear();
}
this.renderTileImage_(tile, frameState.pixelRatio, frameState.viewState.projection);
}
clear(this.renderTileImageQueue_);
@@ -616,7 +608,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
replayState.renderedTileZ = tile.sourceZ;
const tileCoord = tile.wrappedTileCoord;
const z = tileCoord[0];
const source = layer.getSource();
const source = /** @type {import("../../source/VectorTile.js").default} */ (layer.getSource());
const tileGrid = source.getTileGridForProjection(projection);
const resolution = tileGrid.getResolution(z);
const context = tile.getContext(layer);

View File

@@ -264,7 +264,7 @@ class WebGLPointsLayerRenderer extends LayerRenderer {
*/
prepareFrame(frameState) {
const vectorLayer = /** @type {import("../../layer/Vector.js").default} */ (this.getLayer());
const vectorSource = vectorLayer.getSource();
const vectorSource = /** @type {import("../../source/Vector.js").default} */ (vectorLayer.getSource());
const stride = 12;

View File

@@ -145,7 +145,7 @@ class Source extends BaseObject {
}
/**
* Refreshes the source. The source will be cleared, and data from the server will be reloaded.
* Refreshes the source and finally dispatches a 'change' event.
* @api
*/
refresh() {

View File

@@ -75,7 +75,7 @@ class TileSource extends Source {
if (tileGrid) {
toSize(tileGrid.getTileSize(tileGrid.getMinZoom()), tileSize);
}
const canUseScreen = 'screen' in self;
const canUseScreen = 'screen ' in self;
const width = canUseScreen ? (screen.availWidth || screen.width) : 1920;
const height = canUseScreen ? (screen.availHeight || screen.height) : 1080;
cacheSize = 4 * Math.ceil(width / tileSize[0]) * Math.ceil(height / tileSize[1]);
@@ -300,20 +300,12 @@ class TileSource extends Source {
return withinExtentAndZ(tileCoord, tileGrid) ? tileCoord : null;
}
/**
* Remove all cached tiles from the source. The next render cycle will fetch new tiles.
* @api
*/
clear() {
this.tileCache.clear();
}
/**
* @inheritDoc
*/
refresh() {
this.clear();
super.refresh();
this.tileCache.clear();
this.changed();
}
/**

View File

@@ -55,8 +55,6 @@ import {createXYZ, extentFromProjection} from '../tilegrid.js';
* imageTile.getImage().src = src;
* };
* ```
* @property {number|import("../size.js").Size} [tileSize=[256, 256]] The tile size used by the tile service.
* Note: `tileSize` and other non-standard TileJSON properties are currently ignored.
* @property {string} [url] URL to the TileJSON file. If not provided, `tileJSON` must be configured.
* @property {boolean} [wrapX=true] Whether to wrap the world horizontally.
* @property {number} [transition] Duration of the opacity transition for rendering.
@@ -92,12 +90,6 @@ class TileJSON extends TileImage {
*/
this.tileJSON_ = null;
/**
* @type {number|import("../size.js").Size}
* @private
*/
this.tileSize_ = options.tileSize;
if (options.url) {
if (options.jsonp) {
@@ -176,8 +168,7 @@ class TileJSON extends TileImage {
const tileGrid = createXYZ({
extent: extentFromProjection(sourceProjection),
maxZoom: maxZoom,
minZoom: minZoom,
tileSize: this.tileSize_
minZoom: minZoom
});
this.tileGrid = tileGrid;

View File

@@ -138,23 +138,25 @@ export class CustomTile extends Tile {
* Calls the callback (synchronously by default) with the available data
* for given coordinate (or `null` if not yet loaded).
* @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
* @param {function(*): void} callback Callback.
* @param {function(this: T, *): void} callback Callback.
* @param {T=} opt_this The object to use as `this` in the callback.
* @param {boolean=} opt_request If `true` the callback is always async.
* The tile data is requested if not yet loaded.
* @template T
*/
forDataAtCoordinate(coordinate, callback, opt_request) {
forDataAtCoordinate(coordinate, callback, opt_this, opt_request) {
if (this.state == TileState.IDLE && opt_request === true) {
listenOnce(this, EventType.CHANGE, function(e) {
callback(this.getData(coordinate));
callback.call(opt_this, this.getData(coordinate));
}, this);
this.loadInternal_();
} else {
if (opt_request === true) {
setTimeout(function() {
callback(this.getData(coordinate));
callback.call(opt_this, this.getData(coordinate));
}.bind(this), 0);
} else {
callback(this.getData(coordinate));
callback.call(opt_this, this.getData(coordinate));
}
}
}
@@ -389,7 +391,7 @@ class UTFGrid extends TileSource {
coordinate, resolution);
const tile = /** @type {!CustomTile} */(this.getTile(
tileCoord[0], tileCoord[1], tileCoord[2], 1, this.getProjection()));
tile.forDataAtCoordinate(coordinate, callback, opt_request);
tile.forDataAtCoordinate(coordinate, callback, null, opt_request);
} else {
if (opt_request === true) {
setTimeout(function() {

View File

@@ -498,6 +498,7 @@ class VectorSource extends Source {
if (this.featuresRtree_) {
this.featuresRtree_.clear();
}
this.loadedExtentsRtree_.clear();
this.nullGeometryFeatures_ = {};
const clearEvent = new VectorSourceEvent(VectorEventType.CLEAR);
@@ -893,15 +894,6 @@ class VectorSource extends Source {
}
}
/**
* @inheritDoc
*/
refresh() {
this.clear(true);
this.loadedExtentsRtree_.clear();
super.refresh();
}
/**
* Remove an extent from the list of loaded extents.
@@ -985,7 +977,7 @@ class VectorSource extends Source {
/**
* Set the new loader of the source. The next render cycle will use the
* Set the new loader of the source. The next loadFeatures call will use the
* new loader.
* @param {import("../featureloader.js").FeatureLoader} loader The loader to set.
* @api
@@ -994,16 +986,6 @@ class VectorSource extends Source {
this.loader_ = loader;
}
/**
* Points the source to a new url. The next render cycle will use the new url.
* @param {string|import("../featureloader.js").FeatureUrlFunction} url Url.
* @api
*/
setUrl(url) {
assert(this.format_, 7); // `format` must be set when `url` is set
this.setLoader(xhr(url, this.format_));
}
}

View File

@@ -42,11 +42,12 @@ import {equals} from '../array.js';
* var data = // ... fetch data
* var format = tile.getFormat();
* tile.setProjection(format.readProjection(data));
* tile.setExtent(format.getLastExtent()); // line only required for ol/format/MVT
* tile.setFeatures(format.readFeatures(data, {
* // featureProjection is not required for ol/format/MVT
* featureProjection: map.getView().getProjection()
* }));
* // the line below is only required for ol/format/MVT
* tile.setExtent(format.getLastExtent());
* }
* });
* ```

View File

@@ -87,7 +87,6 @@ export class CustomTile extends ImageTile {
* you must provide a `crossOrigin` value you want to access pixel data with the Canvas renderer.
* See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.
* @property {import("../proj.js").ProjectionLike} [projection] Projection.
* @property {number} [tilePixelRatio] The pixel ratio used by the tile service. For example, if the tile service advertizes 256px by 256px tiles but actually sends 512px by 512px images (for retina/hidpi devices) then `tilePixelRatio` should be set to `2`
* @property {number} [reprojectionErrorThreshold=0.5] Maximum allowed reprojection error (in pixels).
* Higher values can increase reprojection performance, but decrease precision.
* @property {string} [url] URL template or base URL of the Zoomify service.
@@ -245,7 +244,6 @@ class Zoomify extends TileImage {
cacheSize: options.cacheSize,
crossOrigin: options.crossOrigin,
projection: options.projection,
tilePixelRatio: options.tilePixelRatio,
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
tileClass: ZoomifyTileClass,
tileGrid: tileGrid,

View File

@@ -42,7 +42,9 @@ class IconImage extends EventTarget {
* @private
* @type {HTMLCanvasElement}
*/
this.canvas_ = color ? document.createElement('canvas') : null;
this.canvas_ = color ?
/** @type {HTMLCanvasElement} */ (document.createElement('canvas')) :
null;
/**
* @private

View File

@@ -103,6 +103,16 @@ class ImageStyle {
return this.scale_;
}
/**
* This method is deprecated and always returns false.
* @return {boolean} false.
* @deprecated
* @api
*/
getSnapToPixel() {
return false;
}
/**
* Get the anchor point in pixels. The anchor determines the center point for the
* symbolizer.
@@ -213,6 +223,14 @@ class ImageStyle {
this.scale_ = scale;
}
/**
* This method is deprecated and does nothing.
* @param {boolean} snapToPixel Snap to pixel?
* @deprecated
* @api
*/
setSnapToPixel(snapToPixel) {}
/**
* @abstract
* @param {function(this: T, import("../events/Event.js").default): void} listener Listener function.

View File

@@ -59,114 +59,114 @@ class Text {
const options = opt_options || {};
/**
* @private
* @type {string|undefined}
*/
* @private
* @type {string|undefined}
*/
this.font_ = options.font;
/**
* @private
* @type {number|undefined}
*/
* @private
* @type {number|undefined}
*/
this.rotation_ = options.rotation;
/**
* @private
* @type {boolean|undefined}
*/
* @private
* @type {boolean|undefined}
*/
this.rotateWithView_ = options.rotateWithView;
/**
* @private
* @type {number|undefined}
*/
* @private
* @type {number|undefined}
*/
this.scale_ = options.scale;
/**
* @private
* @type {string|undefined}
*/
* @private
* @type {string|undefined}
*/
this.text_ = options.text;
/**
* @private
* @type {string|undefined}
*/
* @private
* @type {string|undefined}
*/
this.textAlign_ = options.textAlign;
/**
* @private
* @type {string|undefined}
*/
* @private
* @type {string|undefined}
*/
this.textBaseline_ = options.textBaseline;
/**
* @private
* @type {import("./Fill.js").default}
*/
* @private
* @type {import("./Fill.js").default}
*/
this.fill_ = options.fill !== undefined ? options.fill :
new Fill({color: DEFAULT_FILL_COLOR});
/**
* @private
* @type {number}
*/
* @private
* @type {number}
*/
this.maxAngle_ = options.maxAngle !== undefined ? options.maxAngle : Math.PI / 4;
/**
* @private
* @type {import("./TextPlacement.js").default|string}
*/
* @private
* @type {import("./TextPlacement.js").default|string}
*/
this.placement_ = options.placement !== undefined ? options.placement : TextPlacement.POINT;
/**
* @private
* @type {boolean}
*/
* @private
* @type {boolean}
*/
this.overflow_ = !!options.overflow;
/**
* @private
* @type {import("./Stroke.js").default}
*/
* @private
* @type {import("./Stroke.js").default}
*/
this.stroke_ = options.stroke !== undefined ? options.stroke : null;
/**
* @private
* @type {number}
*/
* @private
* @type {number}
*/
this.offsetX_ = options.offsetX !== undefined ? options.offsetX : 0;
/**
* @private
* @type {number}
*/
* @private
* @type {number}
*/
this.offsetY_ = options.offsetY !== undefined ? options.offsetY : 0;
/**
* @private
* @type {import("./Fill.js").default}
*/
* @private
* @type {import("./Fill.js").default}
*/
this.backgroundFill_ = options.backgroundFill ? options.backgroundFill : null;
/**
* @private
* @type {import("./Stroke.js").default}
*/
* @private
* @type {import("./Stroke.js").default}
*/
this.backgroundStroke_ = options.backgroundStroke ? options.backgroundStroke : null;
/**
* @private
* @type {Array<number>}
*/
* @private
* @type {Array<number>}
*/
this.padding_ = options.padding === undefined ? null : options.padding;
}
/**
* Clones the style.
* @return {Text} The cloned style.
* @api
*/
* Clones the style.
* @return {Text} The cloned style.
* @api
*/
clone() {
return new Text({
font: this.getFont(),
@@ -189,324 +189,314 @@ class Text {
}
/**
* Get the `overflow` configuration.
* @return {boolean} Let text overflow the length of the path they follow.
* @api
*/
* Get the `overflow` configuration.
* @return {boolean} Let text overflow the length of the path they follow.
* @api
*/
getOverflow() {
return this.overflow_;
}
/**
* Get the font name.
* @return {string|undefined} Font.
* @api
*/
* Get the font name.
* @return {string|undefined} Font.
* @api
*/
getFont() {
return this.font_;
}
/**
* Get the maximum angle between adjacent characters.
* @return {number} Angle in radians.
* @api
*/
* Get the maximum angle between adjacent characters.
* @return {number} Angle in radians.
* @api
*/
getMaxAngle() {
return this.maxAngle_;
}
/**
* Get the label placement.
* @return {import("./TextPlacement.js").default|string} Text placement.
* @api
*/
* Get the label placement.
* @return {import("./TextPlacement.js").default|string} Text placement.
* @api
*/
getPlacement() {
return this.placement_;
}
/**
* Get the x-offset for the text.
* @return {number} Horizontal text offset.
* @api
*/
* Get the x-offset for the text.
* @return {number} Horizontal text offset.
* @api
*/
getOffsetX() {
return this.offsetX_;
}
/**
* Get the y-offset for the text.
* @return {number} Vertical text offset.
* @api
*/
* Get the y-offset for the text.
* @return {number} Vertical text offset.
* @api
*/
getOffsetY() {
return this.offsetY_;
}
/**
* Get the fill style for the text.
* @return {import("./Fill.js").default} Fill style.
* @api
*/
* Get the fill style for the text.
* @return {import("./Fill.js").default} Fill style.
* @api
*/
getFill() {
return this.fill_;
}
/**
* Determine whether the text rotates with the map.
* @return {boolean|undefined} Rotate with map.
* @api
*/
* Determine whether the text rotates with the map.
* @return {boolean|undefined} Rotate with map.
* @api
*/
getRotateWithView() {
return this.rotateWithView_;
}
/**
* Get the text rotation.
* @return {number|undefined} Rotation.
* @api
*/
* Get the text rotation.
* @return {number|undefined} Rotation.
* @api
*/
getRotation() {
return this.rotation_;
}
/**
* Get the text scale.
* @return {number|undefined} Scale.
* @api
*/
* Get the text scale.
* @return {number|undefined} Scale.
* @api
*/
getScale() {
return this.scale_;
}
/**
* Get the stroke style for the text.
* @return {import("./Stroke.js").default} Stroke style.
* @api
*/
* Get the stroke style for the text.
* @return {import("./Stroke.js").default} Stroke style.
* @api
*/
getStroke() {
return this.stroke_;
}
/**
* Get the text to be rendered.
* @return {string|undefined} Text.
* @api
*/
* Get the text to be rendered.
* @return {string|undefined} Text.
* @api
*/
getText() {
return this.text_;
}
/**
* Get the text alignment.
* @return {string|undefined} Text align.
* @api
*/
* Get the text alignment.
* @return {string|undefined} Text align.
* @api
*/
getTextAlign() {
return this.textAlign_;
}
/**
* Get the text baseline.
* @return {string|undefined} Text baseline.
* @api
*/
* Get the text baseline.
* @return {string|undefined} Text baseline.
* @api
*/
getTextBaseline() {
return this.textBaseline_;
}
/**
* Get the background fill style for the text.
* @return {import("./Fill.js").default} Fill style.
* @api
*/
* Get the background fill style for the text.
* @return {import("./Fill.js").default} Fill style.
* @api
*/
getBackgroundFill() {
return this.backgroundFill_;
}
/**
* Get the background stroke style for the text.
* @return {import("./Stroke.js").default} Stroke style.
* @api
*/
* Get the background stroke style for the text.
* @return {import("./Stroke.js").default} Stroke style.
* @api
*/
getBackgroundStroke() {
return this.backgroundStroke_;
}
/**
* Get the padding for the text.
* @return {Array<number>} Padding.
* @api
*/
* Get the padding for the text.
* @return {Array<number>} Padding.
* @api
*/
getPadding() {
return this.padding_;
}
/**
* Set the `overflow` property.
*
* @param {boolean} overflow Let text overflow the path that it follows.
* @api
*/
* Set the `overflow` property.
*
* @param {boolean} overflow Let text overflow the path that it follows.
* @api
*/
setOverflow(overflow) {
this.overflow_ = overflow;
}
/**
* Set the font.
*
* @param {string|undefined} font Font.
* @api
*/
* Set the font.
*
* @param {string|undefined} font Font.
* @api
*/
setFont(font) {
this.font_ = font;
}
/**
* Set the maximum angle between adjacent characters.
*
* @param {number} maxAngle Angle in radians.
* @api
*/
* Set the maximum angle between adjacent characters.
*
* @param {number} maxAngle Angle in radians.
* @api
*/
setMaxAngle(maxAngle) {
this.maxAngle_ = maxAngle;
}
/**
* Set the x offset.
*
* @param {number} offsetX Horizontal text offset.
* @api
*/
* Set the x offset.
*
* @param {number} offsetX Horizontal text offset.
* @api
*/
setOffsetX(offsetX) {
this.offsetX_ = offsetX;
}
/**
* Set the y offset.
*
* @param {number} offsetY Vertical text offset.
* @api
*/
* Set the y offset.
*
* @param {number} offsetY Vertical text offset.
* @api
*/
setOffsetY(offsetY) {
this.offsetY_ = offsetY;
}
/**
* Set the text placement.
*
* @param {import("./TextPlacement.js").default|string} placement Placement.
* @api
*/
* Set the text placement.
*
* @param {import("./TextPlacement.js").default|string} placement Placement.
* @api
*/
setPlacement(placement) {
this.placement_ = placement;
}
/**
* Set whether to rotate the text with the view.
*
* @param {boolean} rotateWithView Rotate with map.
* @api
*/
setRotateWithView(rotateWithView) {
this.rotateWithView_ = rotateWithView;
}
/**
* Set the fill.
*
* @param {import("./Fill.js").default} fill Fill style.
* @api
*/
* Set the fill.
*
* @param {import("./Fill.js").default} fill Fill style.
* @api
*/
setFill(fill) {
this.fill_ = fill;
}
/**
* Set the rotation.
*
* @param {number|undefined} rotation Rotation.
* @api
*/
* Set the rotation.
*
* @param {number|undefined} rotation Rotation.
* @api
*/
setRotation(rotation) {
this.rotation_ = rotation;
}
/**
* Set the scale.
*
* @param {number|undefined} scale Scale.
* @api
*/
* Set the scale.
*
* @param {number|undefined} scale Scale.
* @api
*/
setScale(scale) {
this.scale_ = scale;
}
/**
* Set the stroke.
*
* @param {import("./Stroke.js").default} stroke Stroke style.
* @api
*/
* Set the stroke.
*
* @param {import("./Stroke.js").default} stroke Stroke style.
* @api
*/
setStroke(stroke) {
this.stroke_ = stroke;
}
/**
* Set the text.
*
* @param {string|undefined} text Text.
* @api
*/
* Set the text.
*
* @param {string|undefined} text Text.
* @api
*/
setText(text) {
this.text_ = text;
}
/**
* Set the text alignment.
*
* @param {string|undefined} textAlign Text align.
* @api
*/
* Set the text alignment.
*
* @param {string|undefined} textAlign Text align.
* @api
*/
setTextAlign(textAlign) {
this.textAlign_ = textAlign;
}
/**
* Set the text baseline.
*
* @param {string|undefined} textBaseline Text baseline.
* @api
*/
* Set the text baseline.
*
* @param {string|undefined} textBaseline Text baseline.
* @api
*/
setTextBaseline(textBaseline) {
this.textBaseline_ = textBaseline;
}
/**
* Set the background fill.
*
* @param {import("./Fill.js").default} fill Fill style.
* @api
*/
* Set the background fill.
*
* @param {import("./Fill.js").default} fill Fill style.
* @api
*/
setBackgroundFill(fill) {
this.backgroundFill_ = fill;
}
/**
* Set the background stroke.
*
* @param {import("./Stroke.js").default} stroke Stroke style.
* @api
*/
* Set the background stroke.
*
* @param {import("./Stroke.js").default} stroke Stroke style.
* @api
*/
setBackgroundStroke(stroke) {
this.backgroundStroke_ = stroke;
}
/**
* Set the padding (`[top, right, bottom, left]`).
*
* @param {!Array<number>} padding Padding.
* @api
*/
* Set the padding (`[top, right, bottom, left]`).
*
* @param {!Array<number>} padding Padding.
* @api
*/
setPadding(padding) {
this.padding_ = padding;
}

View File

@@ -203,12 +203,14 @@ class TileGrid {
/**
* @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.
* @param {function(number, import("../TileRange.js").default): boolean} callback Callback.
* @param {function(this: T, number, import("../TileRange.js").default): boolean} callback Callback.
* @param {T=} opt_this The object to use as `this` in `callback`.
* @param {import("../TileRange.js").default=} opt_tileRange Temporary import("../TileRange.js").default object.
* @param {import("../extent.js").Extent=} opt_extent Temporary import("../extent.js").Extent object.
* @return {boolean} Callback succeeded.
* @template T
*/
forEachTileCoordParentTileRange(tileCoord, callback, opt_tileRange, opt_extent) {
forEachTileCoordParentTileRange(tileCoord, callback, opt_this, opt_tileRange, opt_extent) {
let tileRange, x, y;
let tileCoordExtent = null;
let z = tileCoord[0] - 1;
@@ -226,7 +228,7 @@ class TileGrid {
} else {
tileRange = this.getTileRangeForExtentAndZ(tileCoordExtent, z, opt_tileRange);
}
if (callback(z, tileRange)) {
if (callback.call(opt_this, z, tileRange)) {
return true;
}
--z;

View File

@@ -323,7 +323,7 @@ let HAS = false;
//TODO Remove side effects
if (typeof window !== 'undefined' && 'WebGLRenderingContext' in window) {
try {
const canvas = document.createElement('canvas');
const canvas = /** @type {HTMLCanvasElement} */ (document.createElement('canvas'));
const gl = getContext(canvas);
if (gl) {
HAS = true;

View File

@@ -74,7 +74,6 @@ module.exports = function(karma) {
}
});
process.env.CHROME_BIN = require('puppeteer').executablePath();
if (process.env.CIRCLECI) {
karma.set({
browsers: ['Chrome'],

View File

@@ -470,7 +470,6 @@ describe('ol.rendering.layer.Vector', function() {
it('declutters text', function(done) {
createMap();
const layer = new VectorLayer({
declutter: true,
source: source
});
map.addLayer(layer);
@@ -489,6 +488,7 @@ describe('ol.rendering.layer.Vector', function() {
text: 'east'
}));
layer.setDeclutter(true);
layer.setStyle(function(feature) {
return new Style({
text: new Text({
@@ -510,7 +510,6 @@ describe('ol.rendering.layer.Vector', function() {
it('declutters text and respects z-index', function(done) {
createMap();
const layer = new VectorLayer({
declutter: true,
source: source
});
map.addLayer(layer);
@@ -531,6 +530,7 @@ describe('ol.rendering.layer.Vector', function() {
zIndex: 1
}));
layer.setDeclutter(true);
layer.setStyle(function(feature) {
return new Style({
zIndex: feature.get('zIndex'),
@@ -550,7 +550,6 @@ describe('ol.rendering.layer.Vector', function() {
it('declutters images', function(done) {
createMap();
const layer = new VectorLayer({
declutter: true,
source: source
});
map.addLayer(layer);
@@ -566,6 +565,7 @@ describe('ol.rendering.layer.Vector', function() {
geometry: new Point([center[0] + 540, center[1]])
}));
layer.setDeclutter(true);
layer.setStyle(function(feature) {
return new Style({
image: new CircleStyle({
@@ -589,7 +589,6 @@ describe('ol.rendering.layer.Vector', function() {
it('declutters images and respects z-index', function(done) {
createMap();
const layer = new VectorLayer({
declutter: true,
source: source
});
map.addLayer(layer);
@@ -607,6 +606,7 @@ describe('ol.rendering.layer.Vector', function() {
zIndex: 1
}));
layer.setDeclutter(true);
layer.setStyle(function(feature) {
return new Style({
zIndex: feature.get('zIndex'),
@@ -628,7 +628,6 @@ describe('ol.rendering.layer.Vector', function() {
it('declutters image & text groups', function(done) {
createMap();
const layer = new VectorLayer({
declutter: true,
source: source
});
map.addLayer(layer);
@@ -646,6 +645,7 @@ describe('ol.rendering.layer.Vector', function() {
text: 'east'
}));
layer.setDeclutter(true);
layer.setStyle(function(feature) {
return new Style({
image: new CircleStyle({
@@ -672,7 +672,6 @@ describe('ol.rendering.layer.Vector', function() {
it('declutters text along lines and images', function(done) {
createMap();
const layer = new VectorLayer({
declutter: true,
source: source
});
map.addLayer(layer);
@@ -705,6 +704,8 @@ describe('ol.rendering.layer.Vector', function() {
source.addFeature(point);
source.addFeature(line);
layer.setDeclutter(true);
map.once('postrender', function() {
expectResemble(map, 'rendering/ol/layer/expected/vector-canvas-declutter-line.png',
IMAGE_TOLERANCE, done);
@@ -714,7 +715,6 @@ describe('ol.rendering.layer.Vector', function() {
it('declutters text along lines and images with z-index', function(done) {
createMap();
const layer = new VectorLayer({
declutter: true,
source: source
});
map.addLayer(layer);
@@ -749,6 +749,8 @@ describe('ol.rendering.layer.Vector', function() {
source.addFeature(point);
source.addFeature(line);
layer.setDeclutter(true);
map.once('postrender', function() {
const hitDetected = map.getFeaturesAtPixel([35, 46]);
expect(hitDetected).to.have.length(1);

View File

@@ -166,7 +166,6 @@ describe('ol.rendering.layer.VectorImage', function() {
it('declutters text', function(done) {
createMap();
const layer = new VectorImageLayer({
declutter: true,
source: source
});
map.addLayer(layer);
@@ -185,6 +184,7 @@ describe('ol.rendering.layer.VectorImage', function() {
text: 'east'
}));
layer.setDeclutter(true);
layer.setStyle(function(feature) {
return new Style({
text: new Text({
@@ -206,7 +206,6 @@ describe('ol.rendering.layer.VectorImage', function() {
it('declutters images', function(done) {
createMap();
const layer = new VectorImageLayer({
declutter: true,
source: source
});
map.addLayer(layer);
@@ -222,6 +221,7 @@ describe('ol.rendering.layer.VectorImage', function() {
geometry: new Point([center[0] + 540, center[1]])
}));
layer.setDeclutter(true);
layer.setStyle(function(feature) {
return new Style({
image: new CircleStyle({
@@ -245,7 +245,6 @@ describe('ol.rendering.layer.VectorImage', function() {
it('declutters text along lines and images', function(done) {
createMap();
const layer = new VectorImageLayer({
declutter: true,
source: source
});
map.addLayer(layer);
@@ -278,6 +277,8 @@ describe('ol.rendering.layer.VectorImage', function() {
source.addFeature(point);
source.addFeature(line);
layer.setDeclutter(true);
map.once('postrender', function() {
expectResemble(map, 'rendering/ol/layer/expected/vector-canvas-declutter-line.png',
IMAGE_TOLERANCE, done);

View File

@@ -1,10 +1,8 @@
import Map from '../../../../src/ol/Map.js';
import View from '../../../../src/ol/View.js';
import ScaleLine, {render} from '../../../../src/ol/control/ScaleLine.js';
import {fromLonLat, clearAllProjections, addCommon} from '../../../../src/ol/proj.js';
import {fromLonLat} from '../../../../src/ol/proj.js';
import Projection from '../../../../src/ol/proj/Projection.js';
import proj4 from 'proj4';
import {register} from '../../../../src/ol/proj/proj4.js';
describe('ol.control.ScaleLine', function() {
let map;
@@ -246,25 +244,6 @@ describe('ol.control.ScaleLine', function() {
});
describe('projections affect the scaleline', function() {
beforeEach(function() {
proj4.defs('Indiana-East', 'PROJCS["IN83-EF",GEOGCS["LL83",DATUM["NAD83",' +
'SPHEROID["GRS1980",6378137.000,298.25722210]],PRIMEM["Greenwich",0],' +
'UNIT["Degree",0.017453292519943295]],PROJECTION["Transverse_Mercator"],' +
'PARAMETER["false_easting",328083.333],' +
'PARAMETER["false_northing",820208.333],' +
'PARAMETER["scale_factor",0.999966666667],' +
'PARAMETER["central_meridian",-85.66666666666670],' +
'PARAMETER["latitude_of_origin",37.50000000000000],' +
'UNIT["Foot_US",0.30480060960122]]');
register(proj4);
});
afterEach(function() {
clearAllProjections();
addCommon();
});
it('is rendered differently for different projections', function() {
const ctrl = new ScaleLine();
ctrl.setMap(map);
@@ -274,47 +253,15 @@ describe('ol.control.ScaleLine', function() {
projection: 'EPSG:3857'
}));
map.renderSync();
expect(ctrl.element.innerText).to.be('2000 km');
const innerHtml3857 = ctrl.element.innerHTML;
map.setView(new View({
center: [7, 52],
zoom: 2,
projection: 'EPSG:4326'
}));
map.renderSync();
expect(ctrl.element.innerText).to.be('5000 km');
map.setView(new View({
center: fromLonLat([-85.685, 39.891], 'Indiana-East'),
zoom: 7,
projection: 'Indiana-East'
}));
map.renderSync();
expect(ctrl.element.innerText).to.be('100 km');
});
it('shows the same scale for different projections at higher resolutions', function() {
const ctrl = new ScaleLine();
ctrl.setMap(map);
map.setView(new View({
center: fromLonLat([-85.685, 39.891]),
zoom: 7,
projection: 'EPSG:3857'
}));
map.renderSync();
expect(ctrl.element.innerText).to.be('100 km');
map.setView(new View({
center: [-85.685, 39.891],
zoom: 7,
projection: 'EPSG:4326'
}));
map.renderSync();
expect(ctrl.element.innerText).to.be('100 km');
map.setView(new View({
center: fromLonLat([-85.685, 39.891], 'Indiana-East'),
zoom: 7,
projection: 'Indiana-East'
}));
map.renderSync();
expect(ctrl.element.innerText).to.be('100 km');
const innerHtml4326 = ctrl.element.innerHTML;
expect(innerHtml4326).to.not.be(innerHtml3857);
});
it('Projection\'s metersPerUnit affect scale for non-degree units', function() {
@@ -397,7 +344,7 @@ describe('ol.control.ScaleLine', function() {
const ctrl = new ScaleLine();
ctrl.setMap(map);
map.setView(new View({
center: [7, 0],
center: fromLonLat([7, 0]),
zoom: 2,
projection: 'EPSG:4326'
}));
@@ -415,7 +362,7 @@ describe('ol.control.ScaleLine', function() {
});
ctrl.setMap(map);
map.setView(new View({
center: [7, 0],
center: fromLonLat([7, 0]),
zoom: 2,
projection: 'EPSG:4326'
}));

View File

@@ -1,5 +1,5 @@
import {linearRingIsClockwise, linearRingsAreOriented,
linearRingssAreOriented, orientLinearRings, orientLinearRingsArray} from '../../../../../src/ol/geom/flat/orient.js';
import {linearRingIsClockwise, linearRingIsOriented,
linearRingsAreOriented, orientLinearRings, orientLinearRingsArray} from '../../../../../src/ol/geom/flat/orient.js';
describe('ol.geom.flat.orient', function() {
@@ -22,8 +22,8 @@ describe('ol.geom.flat.orient', function() {
});
describe('ol.geom.flat.orient.linearRingsAreOriented', function() {
const oriented = linearRingsAreOriented;
describe('ol.geom.flat.orient.linearRingIsOriented', function() {
const oriented = linearRingIsOriented;
const rightCoords = [
-180, -90, 180, -90, 180, 90, -180, 90, -180, -90,
@@ -49,8 +49,8 @@ describe('ol.geom.flat.orient', function() {
});
describe('ol.geom.flat.orient.linearRingssAreOriented', function() {
const oriented = linearRingssAreOriented;
describe('ol.geom.flat.orient.linearRingsAreOriented', function() {
const oriented = linearRingsAreOriented;
const rightCoords = [
-180, -90, 180, -90, 180, 90, -180, 90, -180, -90,

View File

@@ -188,17 +188,6 @@ describe('ol.geom.MultiPolygon', function() {
});
describe('#getArea', function() {
it('works with a clockwise and a counterclockwise Polygon', function() {
const multiPolygon = new MultiPolygon([
[[[1, 3], [1, 2], [0, 2], [1, 3]]], // clockwise polygon with area 0.5
[[[2, 1], [2, 0.5], [3, 1], [2, 1]]] // counterclockwise polygon with area 0.25
]);
expect(multiPolygon.getArea()).to.be(0.75);
});
});
describe('#getInteriorPoints', function() {
it('returns XYM multipoint with intersection width as M', function() {

View File

@@ -1,9 +1,11 @@
import {getUid} from '../../../../src/ol/util.js';
import {stableSort} from '../../../../src/ol/array.js';
import Collection from '../../../../src/ol/Collection.js';
import {getIntersection} from '../../../../src/ol/extent.js';
import LayerGroup from '../../../../src/ol/layer/Group.js';
import Layer from '../../../../src/ol/layer/Layer.js';
import {assign} from '../../../../src/ol/obj.js';
import {sortByZIndex} from '../../../../src/ol/renderer/Map.js';
import Source from '../../../../src/ol/source/Source.js';
@@ -329,36 +331,6 @@ describe('ol.layer.Group', function() {
describe('#getLayerStatesArray', function() {
let layer1, layer2, layer3;
beforeEach(function() {
layer1 = new Layer({
source: new Source({
projection: 'EPSG:4326'
})
});
layer2 = new Layer({
source: new Source({
projection: 'EPSG:4326'
}),
opacity: 0.5,
visible: false,
maxResolution: 500,
minResolution: 0.25
});
layer3 = new Layer({
source: new Source({
projection: 'EPSG:4326'
}),
extent: [-5, -2, 5, 2]
});
});
afterEach(function() {
layer1.dispose();
layer2.dispose();
layer3.dispose();
});
it('returns an empty array if no layer', function() {
const layerGroup = new LayerGroup();
@@ -369,6 +341,27 @@ describe('ol.layer.Group', function() {
layerGroup.dispose();
});
const layer1 = new Layer({
source: new Source({
projection: 'EPSG:4326'
})
});
const layer2 = new Layer({
source: new Source({
projection: 'EPSG:4326'
}),
opacity: 0.5,
visible: false,
maxResolution: 500,
minResolution: 0.25
});
const layer3 = new Layer({
source: new Source({
projection: 'EPSG:4326'
}),
extent: [-5, -2, 5, 2]
});
it('does not transform layerStates by default', function() {
const layerGroup = new LayerGroup({
layers: [layer1, layer2]
@@ -451,6 +444,55 @@ describe('ol.layer.Group', function() {
layerGroup.dispose();
});
it('let order of layers without Z-index unchanged', function() {
const layerGroup = new LayerGroup({
layers: [layer1, layer2]
});
const layerStatesArray = layerGroup.getLayerStatesArray();
const initialArray = layerStatesArray.slice();
stableSort(layerStatesArray, sortByZIndex);
expect(layerStatesArray[0]).to.eql(initialArray[0]);
expect(layerStatesArray[1]).to.eql(initialArray[1]);
layerGroup.dispose();
});
it('orders layer with higher Z-index on top', function() {
const layer10 = new Layer({
source: new Source({
projection: 'EPSG:4326'
})
});
layer10.setZIndex(10);
const layerM1 = new Layer({
source: new Source({
projection: 'EPSG:4326'
})
});
layerM1.setZIndex(-1);
const layerGroup = new LayerGroup({
layers: [layer1, layer10, layer2, layerM1]
});
const layerStatesArray = layerGroup.getLayerStatesArray();
const initialArray = layerStatesArray.slice();
stableSort(layerStatesArray, sortByZIndex);
expect(layerStatesArray[0]).to.eql(initialArray[3]);
expect(layerStatesArray[1]).to.eql(initialArray[0]);
expect(layerStatesArray[2]).to.eql(initialArray[2]);
expect(layerStatesArray[3]).to.eql(initialArray[1]);
layer10.dispose();
layerM1.dispose();
layerGroup.dispose();
});
layer1.dispose();
layer2.dispose();
layer3.dispose();
});
});

View File

@@ -9,12 +9,11 @@ import {
toLonLat,
getTransform,
getPointResolution,
getTransformFromProjections,
METERS_PER_UNIT
getTransformFromProjections
} from '../../../src/ol/proj.js';
import {register} from '../../../src/ol/proj/proj4.js';
import {HALF_SIZE} from '../../../src/ol/proj/epsg3857.js';
import {METERS_PER_UNIT as metersPerDegree} from '../../../src/ol/proj/epsg4326.js';
import {METERS_PER_UNIT} from '../../../src/ol/proj/epsg4326.js';
import Projection from '../../../src/ol/proj/Projection.js';
@@ -269,7 +268,7 @@ describe('ol.proj', function() {
expect(pointResolution).to.roughlyEqual(0.615661, 1e-5);
});
it('returns the correct point resolution for EPSG:3857 with custom units', function() {
let pointResolution = getPointResolution('EPSG:3857', METERS_PER_UNIT['degrees'], [0, 0], 'degrees');
let pointResolution = getPointResolution('EPSG:3857', 1, [0, 0], 'degrees');
expect(pointResolution).to.be(1);
pointResolution = getPointResolution('EPSG:4326', 1, fromLonLat([0, 52]), 'degrees');
expect(pointResolution).to.be(1);
@@ -601,7 +600,7 @@ describe('ol.proj', function() {
it('returns value in meters', function() {
const epsg4326 = getProjection('EPSG:4326');
expect(epsg4326.getMetersPerUnit()).to.eql(metersPerDegree);
expect(epsg4326.getMetersPerUnit()).to.eql(METERS_PER_UNIT);
});
it('works for proj4js projections without units', function() {

View File

@@ -203,7 +203,6 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
let tile;
tileCallback = function(t) {
t.setProjection(proj);
t.setExtent([0, 0, 4096, 4096]);
tile = t;
};
map.renderSync();

View File

@@ -18,7 +18,7 @@ describe('ol.source.BingMaps', function() {
beforeEach(function(done) {
source = new BingMaps({
imagerySet: 'AerialWithLabelsOnDemand',
imagerySet: 'AerialWithLabels',
key: ''
});
@@ -39,7 +39,7 @@ describe('ol.source.BingMaps', function() {
});
it('getImagerySet works correctly', function() {
expect(source.getImagerySet()).to.equal('AerialWithLabelsOnDemand');
expect(source.getImagerySet()).to.equal('AerialWithLabels');
});
it('getApiKey works correctly', function() {

View File

@@ -1,10 +1,6 @@
import ImageWMS from '../../../../src/ol/source/ImageWMS.js';
import Image from '../../../../src/ol/layer/Image.js';
import {get as getProjection} from '../../../../src/ol/proj.js';
import {getWidth, getHeight} from '../../../../src/ol/extent.js';
import View from '../../../../src/ol/View.js';
import Map from '../../../../src/ol/Map.js';
import ImageState from '../../../../src/ol/ImageState.js';
describe('ol.source.ImageWMS', function() {
@@ -330,51 +326,4 @@ describe('ol.source.ImageWMS', function() {
});
});
describe('#refresh()', function() {
let map, source;
let callCount = 0;
beforeEach(function(done) {
source = new ImageWMS(options);
source.setImageLoadFunction(function(image) {
++callCount;
image.state = ImageState.LOADED;
source.loading = false;
});
const target = document.createElement('div');
target.style.width = target.style.height = '100px';
document.body.appendChild(target);
map = new Map({
target: target,
layers: [
new Image({
source: source
})
],
view: new View({
center: [0, 0],
zoom: 0
})
});
map.once('rendercomplete', function() {
callCount = 0;
done();
});
});
afterEach(function() {
document.body.removeChild(map.getTargetElement());
map.setTarget(null);
});
it('reloads from server', function(done) {
map.once('rendercomplete', function() {
expect(callCount).to.be(1);
done();
});
source.refresh();
});
});
});

View File

@@ -59,10 +59,6 @@ describe('ol.source.Tile', function() {
expect(source).to.be.a(Source);
expect(source).to.be.a(TileSource);
});
it('sets a screen dependent cache size', function() {
const source = new TileSource({});
expect(source.tileCache.highWaterMark).to.be(4 * Math.ceil(screen.availWidth / 256) * Math.ceil(screen.availHeight / 256));
});
it('sets a custom cache size', function() {
const projection = getProjection('EPSG:4326');
const source = new TileSource({

View File

@@ -9,7 +9,6 @@ import VectorLayer from '../../../../src/ol/layer/Vector.js';
import {bbox as bboxStrategy} from '../../../../src/ol/loadingstrategy.js';
import {get as getProjection, transformExtent, fromLonLat} from '../../../../src/ol/proj.js';
import VectorSource from '../../../../src/ol/source/Vector.js';
import GeoJSON from '../../../../src/ol/format/GeoJSON.js';
describe('ol.source.Vector', function() {
@@ -148,79 +147,6 @@ describe('ol.source.Vector', function() {
});
describe('clear and refresh', function() {
let map, source, spy;
beforeEach(function(done) {
source = new VectorSource({
format: new GeoJSON(),
url: 'spec/ol/source/vectorsource/single-feature.json'
});
const target = document.createElement('div');
target.style.width = target.style.height = '100px';
document.body.appendChild(target);
map = new Map({
target: target,
layers: [
new VectorLayer({
source: source
})
],
view: new View({
center: [0, 0],
zoom: 0
})
});
map.once('rendercomplete', function() {
spy = sinon.spy(source, 'loader_');
done();
});
});
afterEach(function() {
if (spy) {
source.loader_.restore();
}
document.body.removeChild(map.getTargetElement());
map.setTarget(null);
});
it('#refresh() reloads from server', function(done) {
expect(source.getFeatures()).to.have.length(1);
map.once('rendercomplete', function() {
expect(source.getFeatures()).to.have.length(1);
expect(spy.callCount).to.be(1);
done();
});
source.refresh();
});
it('#clear() removes all features from the source', function(done) {
expect(source.getFeatures()).to.have.length(1);
map.once('rendercomplete', function() {
expect(source.getFeatures()).to.have.length(0);
expect(spy.callCount).to.be(0);
done();
});
source.clear();
});
it('After #setUrl(), refresh() loads from the new url', function(done) {
source.loader_.restore();
spy = undefined;
expect(source.getFeatures()).to.have.length(1);
const oldCoordinates = source.getFeatures()[0].getGeometry().getCoordinates();
map.on('rendercomplete', function() {
expect(source.getFeatures()).to.have.length(1);
const newCoordinates = source.getFeatures()[0].getGeometry().getCoordinates();
expect(newCoordinates).to.not.eql(oldCoordinates);
done();
});
source.setUrl('spec/ol/data/point.json');
source.refresh();
});
});
describe('when populated with 10 random points and a null', function() {
let features;
@@ -241,6 +167,8 @@ describe('ol.source.Vector', function() {
describe('#clear', function() {
it('removes all features using fast path', function() {
const changeSpy = sinon.spy();
listen(vectorSource, 'change', changeSpy);
const removeFeatureSpy = sinon.spy();
listen(vectorSource, 'removefeature', removeFeatureSpy);
const clearSourceSpy = sinon.spy();
@@ -248,6 +176,8 @@ describe('ol.source.Vector', function() {
vectorSource.clear(true);
expect(vectorSource.getFeatures()).to.eql([]);
expect(vectorSource.isEmpty()).to.be(true);
expect(changeSpy).to.be.called();
expect(changeSpy.callCount).to.be(1);
expect(removeFeatureSpy).not.to.be.called();
expect(removeFeatureSpy.callCount).to.be(0);
expect(clearSourceSpy).to.be.called();
@@ -255,6 +185,8 @@ describe('ol.source.Vector', function() {
});
it('removes all features using slow path', function() {
const changeSpy = sinon.spy();
listen(vectorSource, 'change', changeSpy);
const removeFeatureSpy = sinon.spy();
listen(vectorSource, 'removefeature', removeFeatureSpy);
const clearSourceSpy = sinon.spy();
@@ -262,6 +194,8 @@ describe('ol.source.Vector', function() {
vectorSource.clear();
expect(vectorSource.getFeatures()).to.eql([]);
expect(vectorSource.isEmpty()).to.be(true);
expect(changeSpy).to.be.called();
expect(changeSpy.callCount).to.be(1);
expect(removeFeatureSpy).to.be.called();
expect(removeFeatureSpy.callCount).to.be(features.length);
expect(clearSourceSpy).to.be.called();
@@ -587,7 +521,7 @@ describe('ol.source.Vector', function() {
source.loadFeatures([-10000, -10000, 10000, 10000], 1,
getProjection('EPSG:3857'));
source.setLoader(loader2);
source.refresh();
source.clear();
source.loadFeatures([-10000, -10000, 10000, 10000], 1,
getProjection('EPSG:3857'));
expect(count1).to.eql(1);

View File

@@ -1,11 +1,8 @@
import TileSource from '../../../../src/ol/source/Tile.js';
import TileLayer from '../../../../src/ol/layer/Tile.js';
import TileImage from '../../../../src/ol/source/TileImage.js';
import UrlTile from '../../../../src/ol/source/UrlTile.js';
import XYZ from '../../../../src/ol/source/XYZ.js';
import {createXYZ} from '../../../../src/ol/tilegrid.js';
import View from '../../../../src/ol/View.js';
import Map from '../../../../src/ol/Map.js';
describe('ol.source.XYZ', function() {
@@ -186,62 +183,4 @@ describe('ol.source.XYZ', function() {
});
describe('clear and refresh', function() {
let map, source;
let callCount = 0;
beforeEach(function(done) {
source = new XYZ({
url: 'spec/ol/data/osm-{z}-{x}-{y}.png',
tileLoadFunction: function(image, src) {
++callCount;
image.getImage().src = src;
}
});
const target = document.createElement('div');
target.style.width = target.style.height = '100px';
document.body.appendChild(target);
map = new Map({
target: target,
layers: [
new TileLayer({
source: source
})
],
view: new View({
center: [0, 0],
zoom: 0
})
});
map.once('rendercomplete', function() {
callCount = 0;
done();
});
});
afterEach(function() {
document.body.removeChild(map.getTargetElement());
map.setTarget(null);
});
it('#refresh() reloads from server', function(done) {
map.once('rendercomplete', function() {
expect(callCount).to.be(1);
done();
});
source.refresh();
});
it('#clear() clears the tile cache', function(done) {
map.once('rendercomplete', function() {
done(new Error('should not re-render'));
});
source.clear();
setTimeout(function() {
done();
}, 1000);
});
});
});

View File

@@ -97,13 +97,4 @@ describe('ol.style.Text', function() {
});
describe('#setRotateWithView', function() {
it('sets the rotateWithView property', function() {
const textStyle = new Text();
expect(textStyle.getRotateWithView()).to.eql(undefined);
textStyle.setRotateWithView(true);
expect(textStyle.getRotateWithView()).to.eql(true);
});
});
});

10
types/dom.d.ts vendored
View File

@@ -4,20 +4,30 @@
*/
interface Document {
readonly mozFullScreen: boolean;
readonly webkitIsFullScreen: boolean;
readonly fullscreenElement: Element;
readonly mozFullScreenElement: Element;
readonly msFullscreenElement: Element;
readonly webkitFullscreenElement: Element;
readonly mozFullScreenEnabled: boolean;
readonly msFullscreenEnabled: boolean;
readonly webkitFullscreenEnabled: boolean;
mozCancelFullScreen(): void;
msExitFullscreen(): void;
webkitExitFullscreen(): void;
}
interface Element {
mozRequestFullScreen(): Promise<void>;
mozRequestFullScreenWithKeys(): Promise<void>;
msRequestFullscreen(): Promise<void>;
webkitRequestFullscreen(allowKeyboardInput?: number): Promise<void>;
}
interface CSSStyleDeclaration {
msTransform: string | null;
}