Compare commits
127 Commits
v6.0.0-bet
...
v6.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dec44a7202 | ||
|
|
082e160212 | ||
|
|
65ad4932f4 | ||
|
|
c767091faf | ||
|
|
d8aec039a9 | ||
|
|
230205c3fd | ||
|
|
c66347c365 | ||
|
|
bf2a13138d | ||
|
|
8f85b1ba23 | ||
|
|
576fc6a82e | ||
|
|
1e1a6d0939 | ||
|
|
8034b72231 | ||
|
|
2d2f4eb1a2 | ||
|
|
ac9b435a74 | ||
|
|
9946554575 | ||
|
|
e6458222c1 | ||
|
|
62d8760420 | ||
|
|
1cc92b4751 | ||
|
|
8bf0284443 | ||
|
|
17551d2f08 | ||
|
|
3f47a7e7be | ||
|
|
0cc1166a2d | ||
|
|
6d09acc0d3 | ||
|
|
ba9cdd3aa2 | ||
|
|
387f797f23 | ||
|
|
f6fba61b47 | ||
|
|
15cbd69457 | ||
|
|
3dca01490f | ||
|
|
b9c2ef389c | ||
|
|
6000b296e2 | ||
|
|
2869ed245c | ||
|
|
993bf0d2cb | ||
|
|
2dda7127ed | ||
|
|
3cef9f2e00 | ||
|
|
6948bb7ebb | ||
|
|
7a0619447c | ||
|
|
30925b4250 | ||
|
|
f232622ad4 | ||
|
|
3a20993d1f | ||
|
|
612dd6fe28 | ||
|
|
dc3ab508d4 | ||
|
|
ff063caa4e | ||
|
|
a629b7e5f2 | ||
|
|
99c920d393 | ||
|
|
26950a2fca | ||
|
|
5aabff5821 | ||
|
|
a8e31dddee | ||
|
|
b6bd35c15c | ||
|
|
5222a0ffd6 | ||
|
|
f43898bac1 | ||
|
|
dd683855f2 | ||
|
|
6812e13490 | ||
|
|
e8794e78a1 | ||
|
|
2f3e8d04f1 | ||
|
|
a0ff08b734 | ||
|
|
32325bc4ab | ||
|
|
0ddc7da2f8 | ||
|
|
c0000e745e | ||
|
|
f493f01bd0 | ||
|
|
22e1bb0e2f | ||
|
|
7e3ed92ba6 | ||
|
|
ad51c7c08f | ||
|
|
7a8a0c18ae | ||
|
|
5cff84522a | ||
|
|
562f14fc83 | ||
|
|
79fc4bafe6 | ||
|
|
4b48997a0b | ||
|
|
ab2d97d49b | ||
|
|
5616c535b0 | ||
|
|
b4306da7bb | ||
|
|
32d1d9214c | ||
|
|
12d21689c6 | ||
|
|
87d80be915 | ||
|
|
89295b0359 | ||
|
|
621a573dd8 | ||
|
|
73032db345 | ||
|
|
1f86818250 | ||
|
|
534afae345 | ||
|
|
ac3072d888 | ||
|
|
018a7e2753 | ||
|
|
3cc18b6ea1 | ||
|
|
0507132a21 | ||
|
|
7147dce4d0 | ||
|
|
cc976dd4ad | ||
|
|
dfd7b1f24f | ||
|
|
bb35a03704 | ||
|
|
ed340d7e2c | ||
|
|
24e4f41452 | ||
|
|
f44a199bae | ||
|
|
37af683630 | ||
|
|
bb756bdc2c | ||
|
|
f3ea4e0301 | ||
|
|
4a3e4c7c23 | ||
|
|
cb77f9e3dd | ||
|
|
8ff29f8431 | ||
|
|
c4937bc716 | ||
|
|
abb696d0fa | ||
|
|
75a0a0ed49 | ||
|
|
d9a4f37f75 | ||
|
|
933a6297bb | ||
|
|
3bca9b5297 | ||
|
|
28b99767f8 | ||
|
|
e852294938 | ||
|
|
917950a32b | ||
|
|
5ffca0633c | ||
|
|
38920867fb | ||
|
|
6224d749c4 | ||
|
|
1257ade199 | ||
|
|
f25a16d90c | ||
|
|
b6425187de | ||
|
|
2b5e5459ab | ||
|
|
8145b358c0 | ||
|
|
034e0be76f | ||
|
|
6b60b25e8b | ||
|
|
9bceccb5d1 | ||
|
|
0497225d5d | ||
|
|
49a65568d8 | ||
|
|
a4b76b2a00 | ||
|
|
61fdf965ba | ||
|
|
9e928b996c | ||
|
|
3d60dfdeeb | ||
|
|
54c670de77 | ||
|
|
9aa11d2e11 | ||
|
|
0d6368d4ec | ||
|
|
caac90e8d7 | ||
|
|
c428421586 | ||
|
|
c9939d2bff |
@@ -31,6 +31,24 @@ function hasApiMembers(doclet) {
|
||||
}
|
||||
|
||||
function includeAugments(doclet) {
|
||||
// Make sure that `observables` and `fires` are taken from an already processed `class` doclet.
|
||||
// This is necessary because JSDoc generates multiple doclets with the same longname.
|
||||
const cls = classes[doclet.longname];
|
||||
if (cls.observables && !doclet.observables) {
|
||||
doclet.observables = cls.observables;
|
||||
}
|
||||
if (doclet.fires && cls.fires) {
|
||||
for (let i = 0, ii = cls.fires.length; i < ii; ++i) {
|
||||
const fires = cls.fires[i];
|
||||
if (doclet.fires.indexOf(fires) == -1) {
|
||||
doclet.fires.push(fires);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cls.fires && !doclet.fires) {
|
||||
doclet.fires = cls.fires;
|
||||
}
|
||||
|
||||
const augments = doclet.augments;
|
||||
if (augments) {
|
||||
let cls;
|
||||
@@ -148,7 +166,7 @@ exports.handlers = {
|
||||
// constructor from the docs.
|
||||
doclet._hideConstructor = true;
|
||||
includeAugments(doclet);
|
||||
} else if (doclet.undocumented !== false && !doclet._hideConstructor && !(doclet.kind == 'typedef' && doclet.longname in types)) {
|
||||
} else if (!doclet._hideConstructor && !(doclet.kind == 'typedef' && doclet.longname in types)) {
|
||||
// Remove all other undocumented symbols
|
||||
doclet.undocumented = true;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ The above snippets can be combined into a single script that renders a map with
|
||||
import Map from 'ol/Map';
|
||||
import View from 'ol/View';
|
||||
import OSM from 'ol/source/OSM';
|
||||
import TileLayer from 'ol/source/Tile';
|
||||
import TileLayer from 'ol/layer/Tile';
|
||||
|
||||
new Map({
|
||||
layers: [
|
||||
|
||||
@@ -21,7 +21,8 @@ const map = new Map({
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
zoom: 1
|
||||
zoom: 1,
|
||||
multiWorld: true
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
@@ -18,3 +18,4 @@ cloak:
|
||||
value: Your Mapbox access token from https://mapbox.com/ here
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
<div>Current sighting: <span id="info"></span></div>
|
||||
|
||||
@@ -103,7 +103,7 @@ function loadData() {
|
||||
|
||||
loadData();
|
||||
|
||||
new Map({
|
||||
const map = new Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new TileJSON({
|
||||
@@ -121,3 +121,18 @@ new Map({
|
||||
zoom: 2
|
||||
})
|
||||
});
|
||||
|
||||
const info = document.getElementById('info');
|
||||
map.on('pointermove', function(evt) {
|
||||
if (map.getView().getInteracting()) {
|
||||
return;
|
||||
}
|
||||
const pixel = evt.pixel;
|
||||
info.innerText = '';
|
||||
map.forEachFeatureAtPixel(pixel, function(feature) {
|
||||
const datetime = feature.get('datetime');
|
||||
const duration = feature.get('duration');
|
||||
const shape = feature.get('shape');
|
||||
info.innerText = 'On ' + datetime + ', lasted ' + duration + ' seconds and had a "' + shape + '" shape.';
|
||||
});
|
||||
});
|
||||
|
||||
13
examples/layer-zoom-limits.html
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Layer Zoom Limits
|
||||
shortdesc: Using minZoom and maxZoom to control layer visibility.
|
||||
docs: >
|
||||
Layers support `minZoom` and `maxZoom` options for controlling visibility based on the view's zoom level.
|
||||
If min or max zoom are set, the layer will only be visible at zoom levels greater than the `minZoom` and
|
||||
less than or equal to the `maxZoom`. After construction, the layer's `setMinZoom` and `setMaxZoom` can
|
||||
be used to set limits. This example shows an OSM layer at zoom levels 14 and lower and a USGS layer at
|
||||
zoom levels higher than 14.
|
||||
tags: "minZoom, maxZoom, layer"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
33
examples/layer-zoom-limits.js
Normal file
@@ -0,0 +1,33 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
import XYZ from '../src/ol/source/XYZ.js';
|
||||
import {transformExtent, fromLonLat} from '../src/ol/proj.js';
|
||||
|
||||
const mapExtent = [-112.261791, 35.983744, -112.113981, 36.132062];
|
||||
|
||||
const map = new Map({
|
||||
target: 'map',
|
||||
layers: [
|
||||
new TileLayer({
|
||||
maxZoom: 14, // visible at zoom levels 14 and below
|
||||
source: new OSM()
|
||||
}),
|
||||
new TileLayer({
|
||||
minZoom: 14, // visible at zoom levels above 14
|
||||
source: new XYZ({
|
||||
attributions: 'Tiles © USGS, rendered with ' +
|
||||
'<a href="http://www.maptiler.com/">MapTiler</a>',
|
||||
url: 'https://tileserver.maptiler.com/grandcanyon/{z}/{x}/{y}.png'
|
||||
})
|
||||
})
|
||||
],
|
||||
view: new View({
|
||||
center: fromLonLat([-112.18688965, 36.057944835]),
|
||||
zoom: 15,
|
||||
maxZoom: 18,
|
||||
extent: transformExtent(mapExtent, 'EPSG:4326', 'EPSG:3857'),
|
||||
constrainOnlyCenter: true
|
||||
})
|
||||
});
|
||||
@@ -9,7 +9,7 @@ resources:
|
||||
- https://unpkg.com/mapbox-gl@0.54.0/dist/mapbox-gl.js
|
||||
- https://unpkg.com/mapbox-gl@0.54.0/dist/mapbox-gl.css
|
||||
cloak:
|
||||
- key: ER67WIiPdCQvhgsUjoWK
|
||||
- key: get_your_own_D6rA4zTHduk6KOKTXzGB
|
||||
value: Get your own API key at https://www.maptiler.com/cloud/
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
|
||||
@@ -8,7 +8,7 @@ import VectorSource from '../src/ol/source/Vector.js';
|
||||
import GeoJSON from '../src/ol/format/GeoJSON.js';
|
||||
|
||||
const center = [-98.8, 37.9];
|
||||
const key = 'ER67WIiPdCQvhgsUjoWK';
|
||||
const key = 'get_your_own_D6rA4zTHduk6KOKTXzGB';
|
||||
|
||||
const mbMap = new mapboxgl.Map({
|
||||
style: 'https://api.maptiler.com/maps/bright/style.json?key=' + key,
|
||||
|
||||
@@ -4,7 +4,7 @@ title: Vector tiles created from a Mapbox Style object
|
||||
shortdesc: Example of using ol-mapbox-style with tiles from tilehosting.com.
|
||||
tags: "vector tiles, mapbox style, ol-mapbox-style, maptiler"
|
||||
cloak:
|
||||
- key: ER67WIiPdCQvhgsUjoWK
|
||||
- key: get_your_own_D6rA4zTHduk6KOKTXzGB
|
||||
value: Get your own API key at https://www.maptiler.com/cloud/
|
||||
---
|
||||
<!doctype html>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import apply from 'ol-mapbox-style';
|
||||
|
||||
apply('map', 'https://api.maptiler.com/maps/topo/style.json?key=ER67WIiPdCQvhgsUjoWK');
|
||||
apply('map', 'https://api.maptiler.com/maps/topo/style.json?key=get_your_own_D6rA4zTHduk6KOKTXzGB');
|
||||
|
||||
7
examples/side-by-side.css
Normal file
@@ -0,0 +1,7 @@
|
||||
@media (min-width: 800px) {
|
||||
.half {
|
||||
padding: 0 10px;
|
||||
width: 50%;
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
19
examples/side-by-side.html
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Shared Views
|
||||
shortdesc: Two maps share view properties
|
||||
docs: >
|
||||
Two maps (one Road, one Aerial) share the same center, resolution and rotation.
|
||||
tags: "side-by-side, bing, bing-maps"
|
||||
cloak:
|
||||
- key: As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5
|
||||
value: Your Bing Maps Key from http://www.bingmapsportal.com/ here
|
||||
---
|
||||
<div class="half">
|
||||
<h4>Road</h4>
|
||||
<div id="roadMap" class="map"></div>
|
||||
</div>
|
||||
<div class="half">
|
||||
<h4>Aerial</h4>
|
||||
<div id="aerialMap" class="map"></div>
|
||||
</div>
|
||||
37
examples/side-by-side.js
Normal file
@@ -0,0 +1,37 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import BingMaps from '../src/ol/source/BingMaps.js';
|
||||
|
||||
const roadLayer = new TileLayer({
|
||||
source: new BingMaps({
|
||||
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5',
|
||||
imagerySet: 'RoadOnDemand',
|
||||
maxZoom: 19
|
||||
})
|
||||
});
|
||||
|
||||
const aerialLayer = new TileLayer({
|
||||
source: new BingMaps({
|
||||
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5',
|
||||
imagerySet: 'Aerial',
|
||||
maxZoom: 19
|
||||
})
|
||||
});
|
||||
|
||||
const view = new View({
|
||||
center: [-6655.5402445057125, 6709968.258934638],
|
||||
zoom: 13
|
||||
});
|
||||
|
||||
const map1 = new Map({
|
||||
target: 'roadMap',
|
||||
layers: [roadLayer],
|
||||
view: view
|
||||
});
|
||||
|
||||
const map2 = new Map({
|
||||
target: 'aerialMap',
|
||||
layers: [aerialLayer],
|
||||
view: view
|
||||
});
|
||||
15
examples/wms-getlegendgraphic.html
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: WMS GetLegendGraphic
|
||||
shortdesc: Example of a WMS GetLegendGraphic.
|
||||
docs: >
|
||||
WMS supports the [getLegendGraphic request](https://docs.geoserver.org/latest/en/user/services/wms/get_legend_graphic/index.html).
|
||||
This example demonstrates the use of the `getGetLegendGraphicUrl` method.
|
||||
|
||||
|
||||
As a legend can be responsive to the scale it is updated on every change of the resolution.
|
||||
tags: "GetLegendGraphic, getGetLegendGraphicURL, WMS"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
Legend:
|
||||
<div><img id="legend" src=""/></div>
|
||||
47
examples/wms-getlegendgraphic.js
Normal file
@@ -0,0 +1,47 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {Image as ImageLayer, Tile as TileLayer} from '../src/ol/layer.js';
|
||||
import ImageWMS from '../src/ol/source/ImageWMS.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
|
||||
const wmsSource = new ImageWMS({
|
||||
url: 'https://ahocevar.com/geoserver/wms',
|
||||
params: {'LAYERS': 'topp:states'},
|
||||
ratio: 1,
|
||||
serverType: 'geoserver'
|
||||
});
|
||||
|
||||
const updateLegend = function(resolution) {
|
||||
const graphicUrl = wmsSource.getGetLegendGraphicUrl(resolution);
|
||||
const img = document.getElementById('legend');
|
||||
img.src = graphicUrl;
|
||||
};
|
||||
|
||||
const layers = [
|
||||
new TileLayer({
|
||||
source: new OSM()
|
||||
}),
|
||||
new ImageLayer({
|
||||
extent: [-13884991, 2870341, -7455066, 6338219],
|
||||
source: wmsSource
|
||||
})
|
||||
];
|
||||
|
||||
const map = new Map({
|
||||
layers: layers,
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [-10997148, 4569099],
|
||||
zoom: 4
|
||||
})
|
||||
});
|
||||
|
||||
// Initial legend
|
||||
const resolution = map.getView().getResolution();
|
||||
updateLegend(resolution);
|
||||
|
||||
// Update the legend when the resolution changes
|
||||
map.getView().on('change:resolution', function(event) {
|
||||
const resolution = event.target.getResolution();
|
||||
updateLegend(resolution);
|
||||
});
|
||||
323
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ol",
|
||||
"version": "6.0.0-beta.11",
|
||||
"version": "6.0.0-beta.12",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -1192,9 +1192,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"agent-base": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz",
|
||||
"integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==",
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
|
||||
"integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"es6-promisify": "^5.0.0"
|
||||
@@ -2387,9 +2387,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
|
||||
"integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==",
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
@@ -2692,9 +2692,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"coveralls": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.3.tgz",
|
||||
"integrity": "sha512-viNfeGlda2zJr8Gj1zqXpDMRjw9uM54p7wzZdvLRyOgnAfCe974Dq4veZkjJdxQXbmdppu6flEajFYseHYaUhg==",
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.4.tgz",
|
||||
"integrity": "sha512-eyqUWA/7RT0JagiL0tThVhjbIjoiEUyWCjtUJoOPcWoeofP5WK/jb2OJYoBFrR6DvplR+AxOyuBqk4JHkk5ykA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"growl": "~> 1.10.0",
|
||||
@@ -3340,9 +3340,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"es6-promise": {
|
||||
"version": "4.2.6",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz",
|
||||
"integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==",
|
||||
"version": "4.2.8",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
|
||||
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==",
|
||||
"dev": true
|
||||
},
|
||||
"es6-promisify": {
|
||||
@@ -3404,13 +3404,13 @@
|
||||
}
|
||||
},
|
||||
"eslint": {
|
||||
"version": "5.16.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz",
|
||||
"integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==",
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.0.0.tgz",
|
||||
"integrity": "sha512-SrrIfcd4tOgsspOKTSwamuTOAMZOUigHQhVMrzNjz4/B9Za6SHQDIocMIyIDfwDgx6MhS15nS6HC8kumCV2qBQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.0.0",
|
||||
"ajv": "^6.9.1",
|
||||
"ajv": "^6.10.0",
|
||||
"chalk": "^2.1.0",
|
||||
"cross-spawn": "^6.0.5",
|
||||
"debug": "^4.0.1",
|
||||
@@ -3418,18 +3418,19 @@
|
||||
"eslint-scope": "^4.0.3",
|
||||
"eslint-utils": "^1.3.1",
|
||||
"eslint-visitor-keys": "^1.0.0",
|
||||
"espree": "^5.0.1",
|
||||
"espree": "^6.0.0",
|
||||
"esquery": "^1.0.1",
|
||||
"esutils": "^2.0.2",
|
||||
"file-entry-cache": "^5.0.1",
|
||||
"functional-red-black-tree": "^1.0.1",
|
||||
"glob": "^7.1.2",
|
||||
"glob-parent": "^3.1.0",
|
||||
"globals": "^11.7.0",
|
||||
"ignore": "^4.0.6",
|
||||
"import-fresh": "^3.0.0",
|
||||
"imurmurhash": "^0.1.4",
|
||||
"inquirer": "^6.2.2",
|
||||
"js-yaml": "^3.13.0",
|
||||
"is-glob": "^4.0.0",
|
||||
"js-yaml": "^3.13.1",
|
||||
"json-stable-stringify-without-jsonify": "^1.0.1",
|
||||
"levn": "^0.3.0",
|
||||
"lodash": "^4.17.11",
|
||||
@@ -3437,7 +3438,6 @@
|
||||
"mkdirp": "^0.5.1",
|
||||
"natural-compare": "^1.4.0",
|
||||
"optionator": "^0.8.2",
|
||||
"path-is-inside": "^1.0.2",
|
||||
"progress": "^2.0.0",
|
||||
"regexpp": "^2.0.1",
|
||||
"semver": "^5.5.1",
|
||||
@@ -3648,9 +3648,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"espree": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz",
|
||||
"integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==",
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-6.0.0.tgz",
|
||||
"integrity": "sha512-lJvCS6YbCn3ImT3yKkPe0+tJ+mH6ljhGNjHQH9mRtiO6gjhVAOhVXW1yjnwqGwTkK3bGbye+hb00nFNmu0l/1Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"acorn": "^6.0.7",
|
||||
@@ -4490,25 +4490,29 @@
|
||||
"dependencies": {
|
||||
"abbrev": {
|
||||
"version": "1.1.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
|
||||
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"are-we-there-yet": {
|
||||
"version": "1.1.5",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
|
||||
"integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4518,13 +4522,15 @@
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4534,37 +4540,43 @@
|
||||
},
|
||||
"chownr": {
|
||||
"version": "1.1.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz",
|
||||
"integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4573,25 +4585,29 @@
|
||||
},
|
||||
"deep-extend": {
|
||||
"version": "0.6.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
|
||||
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"delegates": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"detect-libc": {
|
||||
"version": "1.0.3",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
|
||||
"integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"fs-minipass": {
|
||||
"version": "1.2.5",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz",
|
||||
"integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4600,13 +4616,15 @@
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"gauge": {
|
||||
"version": "2.7.4",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
|
||||
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4622,7 +4640,8 @@
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.3",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
|
||||
"integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4636,13 +4655,15 @@
|
||||
},
|
||||
"has-unicode": {
|
||||
"version": "2.0.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
||||
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4651,7 +4672,8 @@
|
||||
},
|
||||
"ignore-walk": {
|
||||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz",
|
||||
"integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4660,7 +4682,8 @@
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4670,19 +4693,22 @@
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
|
||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
||||
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4691,13 +4717,15 @@
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4706,13 +4734,15 @@
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.3.5",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz",
|
||||
"integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4722,7 +4752,8 @@
|
||||
},
|
||||
"minizlib": {
|
||||
"version": "1.2.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz",
|
||||
"integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4731,7 +4762,8 @@
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4740,13 +4772,15 @@
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"needle": {
|
||||
"version": "2.3.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/needle/-/needle-2.3.0.tgz",
|
||||
"integrity": "sha512-QBZu7aAFR0522EyaXZM0FZ9GLpq6lvQ3uq8gteiDUp7wKdy0lSd2hPlgFwVuW1CBkfEs9PfDQsQzZghLs/psdg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4757,7 +4791,8 @@
|
||||
},
|
||||
"node-pre-gyp": {
|
||||
"version": "0.12.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz",
|
||||
"integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4775,7 +4810,8 @@
|
||||
},
|
||||
"nopt": {
|
||||
"version": "4.0.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz",
|
||||
"integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4785,13 +4821,15 @@
|
||||
},
|
||||
"npm-bundled": {
|
||||
"version": "1.0.6",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz",
|
||||
"integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"npm-packlist": {
|
||||
"version": "1.4.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.1.tgz",
|
||||
"integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4801,7 +4839,8 @@
|
||||
},
|
||||
"npmlog": {
|
||||
"version": "4.1.2",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
|
||||
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4813,19 +4852,22 @@
|
||||
},
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
|
||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4834,19 +4876,22 @@
|
||||
},
|
||||
"os-homedir": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
|
||||
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"os-tmpdir": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
|
||||
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"osenv": {
|
||||
"version": "0.1.5",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
|
||||
"integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4856,19 +4901,22 @@
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
|
||||
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"rc": {
|
||||
"version": "1.2.8",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
|
||||
"integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4880,7 +4928,8 @@
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
@@ -4888,7 +4937,8 @@
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4903,7 +4953,8 @@
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.6.3",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
|
||||
"integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4912,43 +4963,50 @@
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"sax": {
|
||||
"version": "1.2.4",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
|
||||
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.2",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
||||
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"string-width": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4959,7 +5017,8 @@
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4968,7 +5027,8 @@
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4977,13 +5037,15 @@
|
||||
},
|
||||
"strip-json-comments": {
|
||||
"version": "2.0.1",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
|
||||
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"tar": {
|
||||
"version": "4.4.8",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz",
|
||||
"integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -4998,13 +5060,15 @@
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"wide-align": {
|
||||
"version": "1.1.3",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
|
||||
"integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
@@ -5013,13 +5077,15 @@
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.3",
|
||||
"bundled": true,
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
|
||||
"integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
@@ -5565,9 +5631,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"inquirer": {
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.3.1.tgz",
|
||||
"integrity": "sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA==",
|
||||
"version": "6.4.1",
|
||||
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.4.1.tgz",
|
||||
"integrity": "sha512-/Jw+qPZx4EDYsaT6uz7F4GJRNFMRdKNeUZw3ZnKV8lyuUgz/YWRCSUAJMZSVhSq4Ec0R2oYnyi6b3d4JXcL5Nw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-escapes": "^3.2.0",
|
||||
@@ -7305,9 +7371,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node-libs-browser": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.0.tgz",
|
||||
"integrity": "sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA==",
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz",
|
||||
"integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert": "^1.1.1",
|
||||
@@ -7320,7 +7386,7 @@
|
||||
"events": "^3.0.0",
|
||||
"https-browserify": "^1.0.0",
|
||||
"os-browserify": "^0.3.0",
|
||||
"path-browserify": "0.0.0",
|
||||
"path-browserify": "0.0.1",
|
||||
"process": "^0.11.10",
|
||||
"punycode": "^1.2.4",
|
||||
"querystring-es3": "^0.2.0",
|
||||
@@ -7332,7 +7398,7 @@
|
||||
"tty-browserify": "0.0.0",
|
||||
"url": "^0.11.0",
|
||||
"util": "^0.11.0",
|
||||
"vm-browserify": "0.0.4"
|
||||
"vm-browserify": "^1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"punycode": {
|
||||
@@ -7764,9 +7830,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"path-browserify": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz",
|
||||
"integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=",
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz",
|
||||
"integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==",
|
||||
"dev": true
|
||||
},
|
||||
"path-dirname": {
|
||||
@@ -7895,12 +7961,12 @@
|
||||
}
|
||||
},
|
||||
"pixelmatch": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz",
|
||||
"integrity": "sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ=",
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.0.2.tgz",
|
||||
"integrity": "sha512-b65UpTI40rGFY8QwN6IYuCbpmwAOL6M8d6voX4F3zR99UmDqh7r2QWLxoeHOazBRgEmDUdqNVESDREqFxQS7rQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"pngjs": "^3.0.0"
|
||||
"pngjs": "^3.4.0"
|
||||
}
|
||||
},
|
||||
"pixelworks": {
|
||||
@@ -8037,9 +8103,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"psl": {
|
||||
"version": "1.1.31",
|
||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz",
|
||||
"integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==",
|
||||
"version": "1.1.33",
|
||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.1.33.tgz",
|
||||
"integrity": "sha512-LTDP2uSrsc7XCb5lO7A8BI1qYxRe/8EqlRvMeEl6rsnYAqDOl8xHR+8lSAIVfrNaSAlTPTNOCgNjWcoUL3AZsw==",
|
||||
"dev": true
|
||||
},
|
||||
"public-encrypt": {
|
||||
@@ -8096,9 +8162,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"puppeteer": {
|
||||
"version": "1.17.0",
|
||||
"resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.17.0.tgz",
|
||||
"integrity": "sha512-3EXZSximCzxuVKpIHtyec8Wm2dWZn1fc5tQi34qWfiUgubEVYHjUvr0GOJojqf3mifI6oyKnCdrGxaOI+lWReA==",
|
||||
"version": "1.18.0",
|
||||
"resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.18.0.tgz",
|
||||
"integrity": "sha512-NCwSN4wEIj43k4jO8Asa5nzibrIDFHWykqkZFjkGr0/f6U73k1ysql0gadQmOGLtZewXvvWqlNo+4ZMgX+5vZA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "^4.1.0",
|
||||
@@ -8705,9 +8771,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"rxjs": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.1.tgz",
|
||||
"integrity": "sha512-y0j31WJc83wPu31vS1VlAFW5JGrnGC+j+TtGAa1fRQphy48+fDYiDmX8tjGloToEsMkxnouOg/1IzXGKkJnZMg==",
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz",
|
||||
"integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tslib": "^1.9.0"
|
||||
@@ -9731,9 +9797,9 @@
|
||||
}
|
||||
},
|
||||
"table": {
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://registry.npmjs.org/table/-/table-5.2.3.tgz",
|
||||
"integrity": "sha512-N2RsDAMvDLvYwFcwbPyF3VmVSSkuF+G1e+8inhBLtHpvwXGw4QRPEZhihQNeEN0i1up6/f6ObCJXNdlRG3YVyQ==",
|
||||
"version": "5.4.1",
|
||||
"resolved": "https://registry.npmjs.org/table/-/table-5.4.1.tgz",
|
||||
"integrity": "sha512-E6CK1/pZe2N75rGZQotFOdmzWQ1AILtgYbMAbAjvms0S1l5IDB47zG3nCnFGB/w+7nB3vKofbLXCH7HPBo864w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^6.9.1",
|
||||
@@ -9952,9 +10018,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
|
||||
"integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==",
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
|
||||
"integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==",
|
||||
"dev": true
|
||||
},
|
||||
"tty-browserify": {
|
||||
@@ -10343,13 +10409,10 @@
|
||||
}
|
||||
},
|
||||
"vm-browserify": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz",
|
||||
"integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"indexof": "0.0.1"
|
||||
}
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz",
|
||||
"integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==",
|
||||
"dev": true
|
||||
},
|
||||
"void-elements": {
|
||||
"version": "2.0.1",
|
||||
@@ -10393,9 +10456,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"webpack": {
|
||||
"version": "4.32.2",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.32.2.tgz",
|
||||
"integrity": "sha512-F+H2Aa1TprTQrpodRAWUMJn7A8MgDx82yQiNvYMaj3d1nv3HetKU0oqEulL9huj8enirKi8KvEXQ3QtuHF89Zg==",
|
||||
"version": "4.35.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.35.0.tgz",
|
||||
"integrity": "sha512-M5hL3qpVvtr8d4YaJANbAQBc4uT01G33eDpl/psRTBCfjxFTihdhin1NtAKB1ruDwzeVdcsHHV3NX+QsAgOosw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
|
||||
20
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ol",
|
||||
"version": "6.0.0-beta.11",
|
||||
"version": "6.0.0-beta.12",
|
||||
"description": "OpenLayers mapping library",
|
||||
"keywords": [
|
||||
"map",
|
||||
@@ -54,23 +54,23 @@
|
||||
"chaikin-smooth": "^1.0.4",
|
||||
"clean-css-cli": "4.3.0",
|
||||
"copy-webpack-plugin": "^5.0.3",
|
||||
"coveralls": "3.0.4",
|
||||
"coveralls": "3.0.5",
|
||||
"eslint": "^6.0.0",
|
||||
"eslint-config-openlayers": "^12.0.0",
|
||||
"expect.js": "0.3.1",
|
||||
"front-matter": "^3.0.2",
|
||||
"fs-extra": "^8.0.0",
|
||||
"glob": "^7.1.4",
|
||||
"globby": "^9.2.0",
|
||||
"globby": "^10.0.0",
|
||||
"handlebars": "4.1.2",
|
||||
"html-to-image": "^0.1.0",
|
||||
"istanbul": "0.4.5",
|
||||
"istanbul-instrumenter-loader": "^3.0.1",
|
||||
"jquery": "3.4.1",
|
||||
"jsdoc": "3.6.2",
|
||||
"jsdoc": "3.6.3",
|
||||
"jsdoc-plugin-typescript": "^2.0.1",
|
||||
"karma": "^4.1.0",
|
||||
"karma-chrome-launcher": "2.2.0",
|
||||
"karma-chrome-launcher": "3.0.0",
|
||||
"karma-coverage": "^1.1.2",
|
||||
"karma-coverage-istanbul-reporter": "^2.0.5",
|
||||
"karma-firefox-launcher": "^1.1.0",
|
||||
@@ -78,13 +78,13 @@
|
||||
"karma-sourcemap-loader": "^0.3.7",
|
||||
"karma-webpack": "^4.0.0-rc.2",
|
||||
"loglevelnext": "^3.0.1",
|
||||
"marked": "0.6.2",
|
||||
"mocha": "6.1.4",
|
||||
"ol-mapbox-style": "^5.0.0-beta.2",
|
||||
"marked": "0.7.0",
|
||||
"mocha": "6.2.0",
|
||||
"ol-mapbox-style": "^5.0.0-beta.3",
|
||||
"pixelmatch": "^5.0.0",
|
||||
"pngjs": "^3.4.0",
|
||||
"proj4": "2.5.0",
|
||||
"puppeteer": "~1.18.0",
|
||||
"puppeteer": "~1.19.0",
|
||||
"rollup": "^1.12.0",
|
||||
"rollup-plugin-babel": "^4.3.2",
|
||||
"rollup-plugin-commonjs": "^10.0.0",
|
||||
@@ -97,7 +97,7 @@
|
||||
"typescript": "^3.4.5",
|
||||
"url-polyfill": "^1.1.5",
|
||||
"walk": "^2.3.9",
|
||||
"webpack": "4.35.0",
|
||||
"webpack": "4.39.0",
|
||||
"webpack-cli": "^3.3.2",
|
||||
"webpack-dev-middleware": "^3.6.2",
|
||||
"webpack-dev-server": "^3.3.1",
|
||||
|
||||
BIN
rendering/cases/circle-style/expected.png
Normal file
|
After Width: | Height: | Size: 4.2 KiB |
57
rendering/cases/circle-style/main.js
Normal file
@@ -0,0 +1,57 @@
|
||||
import Map from '../../../src/ol/Map.js';
|
||||
import View from '../../../src/ol/View.js';
|
||||
import Feature from '../../../src/ol/Feature.js';
|
||||
import Point from '../../../src/ol/geom/Point.js';
|
||||
import VectorLayer from '../../../src/ol/layer/Vector.js';
|
||||
import VectorSource from '../../../src/ol/source/Vector.js';
|
||||
import Circle from '../../../src/ol/style/Circle.js';
|
||||
import Style from '../../../src/ol/style/Style.js';
|
||||
import Stroke from '../../../src/ol/style/Stroke.js';
|
||||
|
||||
|
||||
const vectorSource = new VectorSource();
|
||||
|
||||
vectorSource.addFeatures([
|
||||
new Feature({
|
||||
geometry: new Point([-50, 50]),
|
||||
radius: 10
|
||||
}),
|
||||
new Feature({
|
||||
geometry: new Point([50, -50]),
|
||||
radius: 20
|
||||
}),
|
||||
new Feature({
|
||||
geometry: new Point([50, 50]),
|
||||
radius: 30
|
||||
})
|
||||
]);
|
||||
|
||||
const style = new Style({
|
||||
image: new Circle({
|
||||
radius: 1,
|
||||
stroke: new Stroke({
|
||||
color: '#00f',
|
||||
width: 3
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
new Map({
|
||||
pixelRatio: 1,
|
||||
layers: [
|
||||
new VectorLayer({
|
||||
source: vectorSource,
|
||||
style: function(feature) {
|
||||
style.getImage().setRadius(feature.get('radius'));
|
||||
return style;
|
||||
}
|
||||
})
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
resolution: 1
|
||||
})
|
||||
});
|
||||
|
||||
render();
|
||||
BIN
rendering/cases/reproj-image/expected.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
31
rendering/cases/reproj-image/main.js
Normal file
@@ -0,0 +1,31 @@
|
||||
import Map from '../../../src/ol/Map.js';
|
||||
import View from '../../../src/ol/View.js';
|
||||
import Static from '../../../src/ol/source/ImageStatic.js';
|
||||
import {
|
||||
get as getProjection,
|
||||
transformExtent
|
||||
} from '../../../src/ol/proj.js';
|
||||
import ImageLayer from '../../../src/ol/layer/Image.js';
|
||||
|
||||
const source = new Static({
|
||||
url: '/data/tiles/osm/5/5/12.png',
|
||||
imageExtent: transformExtent([-123, 37, -122, 38], 'EPSG:4326', 'EPSG:3857'),
|
||||
projection: getProjection('EPSG:3857')
|
||||
});
|
||||
|
||||
new Map({
|
||||
pixelRatio: 1,
|
||||
target: 'map',
|
||||
layers: [new ImageLayer({
|
||||
source: source
|
||||
})],
|
||||
view: new View({
|
||||
center: [-122.416667, 37.783333],
|
||||
zoom: 8,
|
||||
projection: 'EPSG:4326'
|
||||
})
|
||||
});
|
||||
|
||||
render({
|
||||
tolerance: 0.001
|
||||
});
|
||||
BIN
rendering/cases/reproj-tile-4326/expected.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
36
rendering/cases/reproj-tile-4326/main.js
Normal file
@@ -0,0 +1,36 @@
|
||||
import Map from '../../../src/ol/Map.js';
|
||||
import View from '../../../src/ol/View.js';
|
||||
import XYZ from '../../../src/ol/source/XYZ.js';
|
||||
import TileLayer from '../../../src/ol/layer/Tile.js';
|
||||
import {toLonLat, get} from '../../../src/ol/proj.js';
|
||||
import {createXYZ, createForProjection} from '../../../src/ol/tilegrid.js';
|
||||
|
||||
const tileGrid = createXYZ();
|
||||
const extent = tileGrid.getTileCoordExtent([5, 5, 12]);
|
||||
const center = [(extent[0] + extent[2]) / 2, extent[1]];
|
||||
|
||||
const source = new XYZ({
|
||||
transition: 0,
|
||||
minZoom: 5,
|
||||
maxZoom: 5,
|
||||
url: '/data/tiles/osm/{z}/{x}/{y}.png'
|
||||
});
|
||||
|
||||
source.setTileGridForProjection(get('EPSG:4326'), createForProjection(get('EPSG:4326'), 7, [64, 64]));
|
||||
|
||||
new Map({
|
||||
pixelRatio: 1,
|
||||
target: 'map',
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: source
|
||||
})
|
||||
],
|
||||
view: new View({
|
||||
projection: 'EPSG:4326',
|
||||
center: toLonLat(center),
|
||||
zoom: 5
|
||||
})
|
||||
});
|
||||
|
||||
render();
|
||||
BIN
rendering/cases/reproj-tile-5070/expected.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
41
rendering/cases/reproj-tile-5070/main.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import Map from '../../../src/ol/Map.js';
|
||||
import View from '../../../src/ol/View.js';
|
||||
import XYZ from '../../../src/ol/source/XYZ.js';
|
||||
import TileLayer from '../../../src/ol/layer/Tile.js';
|
||||
import {get, transform} from '../../../src/ol/proj.js';
|
||||
import {register} from '../../../src/ol/proj/proj4.js';
|
||||
import proj4 from 'proj4';
|
||||
|
||||
proj4.defs('EPSG:5070',
|
||||
'+proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=23 +lon_0=-96 +x_0=0 ' +
|
||||
'+y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs');
|
||||
register(proj4);
|
||||
const proj5070 = get('EPSG:5070');
|
||||
proj5070.setExtent([-6e6, 0, 4e6, 6e6]);
|
||||
|
||||
const center4326 = [-118.125, 31.95];
|
||||
const center = transform(center4326, 'EPSG:4326', 'EPSG:5070');
|
||||
|
||||
const source = new XYZ({
|
||||
transition: 0,
|
||||
minZoom: 5,
|
||||
maxZoom: 5,
|
||||
url: '/data/tiles/osm/{z}/{x}/{y}.png'
|
||||
});
|
||||
|
||||
new Map({
|
||||
pixelRatio: 1,
|
||||
target: 'map',
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: source
|
||||
})
|
||||
],
|
||||
view: new View({
|
||||
projection: 'EPSG:5070',
|
||||
center: center,
|
||||
zoom: 4
|
||||
})
|
||||
});
|
||||
|
||||
render();
|
||||
BIN
rendering/cases/reproj-tile-54009/expected.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
40
rendering/cases/reproj-tile-54009/main.js
Normal file
@@ -0,0 +1,40 @@
|
||||
import Map from '../../../src/ol/Map.js';
|
||||
import View from '../../../src/ol/View.js';
|
||||
import XYZ from '../../../src/ol/source/XYZ.js';
|
||||
import TileLayer from '../../../src/ol/layer/Tile.js';
|
||||
import {get, transform} from '../../../src/ol/proj.js';
|
||||
import {register} from '../../../src/ol/proj/proj4.js';
|
||||
import proj4 from 'proj4';
|
||||
|
||||
proj4.defs('ESRI:54009', '+proj=moll +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs');
|
||||
|
||||
register(proj4);
|
||||
const proj54009 = get('ESRI:54009');
|
||||
proj54009.setExtent([-18e6, -9e6, 18e6, 9e6]);
|
||||
|
||||
const center4326 = [-118.125, 31.95];
|
||||
const center = transform(center4326, 'EPSG:4326', 'ESRI:54009');
|
||||
|
||||
const source = new XYZ({
|
||||
transition: 0,
|
||||
minZoom: 5,
|
||||
maxZoom: 5,
|
||||
url: '/data/tiles/osm/{z}/{x}/{y}.png'
|
||||
});
|
||||
|
||||
new Map({
|
||||
pixelRatio: 1,
|
||||
target: 'map',
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: source
|
||||
})
|
||||
],
|
||||
view: new View({
|
||||
projection: 'ESRI:54009',
|
||||
center: center,
|
||||
zoom: 6
|
||||
})
|
||||
});
|
||||
|
||||
render();
|
||||
BIN
rendering/cases/reproj-tile-dateline-merc/expected.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
40
rendering/cases/reproj-tile-dateline-merc/main.js
Normal file
@@ -0,0 +1,40 @@
|
||||
import Map from '../../../src/ol/Map.js';
|
||||
import View from '../../../src/ol/View.js';
|
||||
import XYZ from '../../../src/ol/source/XYZ.js';
|
||||
import TileLayer from '../../../src/ol/layer/Tile.js';
|
||||
import {get, transform} from '../../../src/ol/proj.js';
|
||||
import {register} from '../../../src/ol/proj/proj4.js';
|
||||
import proj4 from 'proj4';
|
||||
|
||||
proj4.defs('merc_180', '+proj=merc +lon_0=180 +units=m +no_defs');
|
||||
|
||||
register(proj4);
|
||||
const merc = get('merc_180');
|
||||
merc.setExtent([-20026376.39, -20048966.10, 20026376.39, 20048966.10]);
|
||||
|
||||
const center4326 = [180, 0];
|
||||
const center = transform(center4326, 'EPSG:4326', 'merc_180');
|
||||
|
||||
const source = new XYZ({
|
||||
projection: 'EPSG:4326',
|
||||
minZoom: 0,
|
||||
maxZoom: 0,
|
||||
url: '/data/tiles/4326/{z}/{x}/{y}.png'
|
||||
});
|
||||
|
||||
new Map({
|
||||
pixelRatio: 1,
|
||||
target: 'map',
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: source
|
||||
})
|
||||
],
|
||||
view: new View({
|
||||
projection: 'merc_180',
|
||||
center: center,
|
||||
zoom: 0
|
||||
})
|
||||
});
|
||||
|
||||
render();
|
||||
BIN
rendering/cases/reproj-tile-none-square/expected.png
Normal file
|
After Width: | Height: | Size: 9.7 KiB |
38
rendering/cases/reproj-tile-none-square/main.js
Normal file
@@ -0,0 +1,38 @@
|
||||
import Map from '../../../src/ol/Map.js';
|
||||
import View from '../../../src/ol/View.js';
|
||||
import XYZ from '../../../src/ol/source/XYZ.js';
|
||||
import TileLayer from '../../../src/ol/layer/Tile.js';
|
||||
import {toLonLat} from '../../../src/ol/proj.js';
|
||||
import {createXYZ} from '../../../src/ol/tilegrid.js';
|
||||
|
||||
const tileGrid = createXYZ({tileSize: [512, 256]});
|
||||
const extent = tileGrid.getTileCoordExtent([5, 3, 12]);
|
||||
const center = [
|
||||
(extent[0] + extent[2]) / 2,
|
||||
(extent[1] + extent[3]) / 2
|
||||
];
|
||||
|
||||
const source = new XYZ({
|
||||
projection: 'EPSG:3857',
|
||||
minZoom: 5,
|
||||
maxZoom: 5,
|
||||
url: '/data/tiles/512x256/{z}/{x}/{y}.png',
|
||||
tileSize: [512, 256]
|
||||
});
|
||||
|
||||
new Map({
|
||||
pixelRatio: 1,
|
||||
target: 'map',
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: source
|
||||
})
|
||||
],
|
||||
view: new View({
|
||||
projection: 'EPSG:4326',
|
||||
center: toLonLat(center),
|
||||
zoom: 5
|
||||
})
|
||||
});
|
||||
|
||||
render();
|
||||
BIN
rendering/cases/reproj-tile-northpole/expected.png
Normal file
|
After Width: | Height: | Size: 51 KiB |
40
rendering/cases/reproj-tile-northpole/main.js
Normal file
@@ -0,0 +1,40 @@
|
||||
import Map from '../../../src/ol/Map.js';
|
||||
import View from '../../../src/ol/View.js';
|
||||
import XYZ from '../../../src/ol/source/XYZ.js';
|
||||
import TileLayer from '../../../src/ol/layer/Tile.js';
|
||||
import {get, transform} from '../../../src/ol/proj.js';
|
||||
import {register} from '../../../src/ol/proj/proj4.js';
|
||||
import proj4 from 'proj4';
|
||||
|
||||
proj4.defs('EPSG:3413', '+proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 ' +
|
||||
'+k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs');
|
||||
|
||||
register(proj4);
|
||||
const proj3413 = get('EPSG:3413');
|
||||
proj3413.setExtent([-4194304, -4194304, 4194304, 4194304]);
|
||||
|
||||
const center4326 = [0, 90];
|
||||
const center = transform(center4326, 'EPSG:4326', 'EPSG:3413');
|
||||
|
||||
const source = new XYZ({
|
||||
maxZoom: 0,
|
||||
projection: 'EPSG:4326',
|
||||
url: '/data/tiles/4326/{z}/{x}/{y}.png'
|
||||
});
|
||||
|
||||
new Map({
|
||||
pixelRatio: 1,
|
||||
target: 'map',
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: source
|
||||
})
|
||||
],
|
||||
view: new View({
|
||||
projection: 'EPSG:3413',
|
||||
center: center,
|
||||
zoom: 0
|
||||
})
|
||||
});
|
||||
|
||||
render();
|
||||
BIN
rendering/data/tiles/4326/0/0/0.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
@@ -159,7 +159,7 @@ class ImageWrapper extends ImageBase {
|
||||
export function listenImage(image, loadHandler, errorHandler) {
|
||||
const img = /** @type {HTMLImageElement} */ (image);
|
||||
|
||||
if (IMAGE_DECODE) {
|
||||
if (img.src && IMAGE_DECODE) {
|
||||
const promise = img.decode();
|
||||
let listening = true;
|
||||
const unlisten = function() {
|
||||
|
||||
@@ -9,5 +9,6 @@ export default {
|
||||
IDLE: 0,
|
||||
LOADING: 1,
|
||||
LOADED: 2,
|
||||
ERROR: 3
|
||||
ERROR: 3,
|
||||
EMPTY: 4
|
||||
};
|
||||
|
||||
@@ -1224,7 +1224,7 @@ class PluggableMap extends BaseObject {
|
||||
let frameState = null;
|
||||
if (size !== undefined && hasArea(size) && view && view.isDef()) {
|
||||
const viewHints = view.getHints(this.frameState_ ? this.frameState_.viewHints : undefined);
|
||||
viewState = view.getState(this.pixelRatio_);
|
||||
viewState = view.getState();
|
||||
frameState = {
|
||||
animate: false,
|
||||
coordinateToPixelTransform: this.coordinateToPixelTransform_,
|
||||
|
||||
@@ -927,10 +927,9 @@ class View extends BaseObject {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} pixelRatio Pixel ratio for center rounding.
|
||||
* @return {State} View state.
|
||||
*/
|
||||
getState(pixelRatio) {
|
||||
getState() {
|
||||
const center = /** @type {import("./coordinate.js").Coordinate} */ (this.getCenter());
|
||||
const projection = this.getProjection();
|
||||
const resolution = /** @type {number} */ (this.getResolution());
|
||||
@@ -1148,7 +1147,6 @@ class View extends BaseObject {
|
||||
* constraint will apply.
|
||||
* @param {number} ratio The ratio to apply on the view resolution.
|
||||
* @param {import("./coordinate.js").Coordinate=} opt_anchor The origin of the transformation.
|
||||
* @observable
|
||||
* @api
|
||||
*/
|
||||
adjustResolution(ratio, opt_anchor) {
|
||||
@@ -1180,7 +1178,6 @@ class View extends BaseObject {
|
||||
* constraint will apply.
|
||||
* @param {number} delta Relative value to add to the zoom rotation, in radians.
|
||||
* @param {import("./coordinate.js").Coordinate=} opt_anchor The rotation center.
|
||||
* @observable
|
||||
* @api
|
||||
*/
|
||||
adjustRotation(delta, opt_anchor) {
|
||||
|
||||
@@ -7,7 +7,7 @@ import {CLASS_CONTROL, CLASS_UNSELECTABLE, CLASS_COLLAPSED} from '../css.js';
|
||||
import {removeChildren, replaceNode} from '../dom.js';
|
||||
import {listen} from '../events.js';
|
||||
import EventType from '../events/EventType.js';
|
||||
import {visibleAtResolution} from '../layer/Layer.js';
|
||||
import {inView} from '../layer/Layer.js';
|
||||
|
||||
|
||||
/**
|
||||
@@ -170,10 +170,9 @@ class Attribution extends Control {
|
||||
const visibleAttributions = [];
|
||||
|
||||
const layerStatesArray = frameState.layerStatesArray;
|
||||
const resolution = frameState.viewState.resolution;
|
||||
for (let i = 0, ii = layerStatesArray.length; i < ii; ++i) {
|
||||
const layerState = layerStatesArray[i];
|
||||
if (!visibleAtResolution(layerState, resolution)) {
|
||||
if (!inView(layerState, frameState.viewState)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -108,12 +108,6 @@ class MousePosition extends Control {
|
||||
*/
|
||||
this.transform_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {import("../pixel.js").Pixel}
|
||||
*/
|
||||
this.lastMouseMovePixel_ = null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,8 +150,7 @@ class MousePosition extends Control {
|
||||
*/
|
||||
handleMouseMove(event) {
|
||||
const map = this.getMap();
|
||||
this.lastMouseMovePixel_ = map.getEventPixel(event);
|
||||
this.updateHTML_(this.lastMouseMovePixel_);
|
||||
this.updateHTML_(map.getEventPixel(event));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,7 +159,6 @@ class MousePosition extends Control {
|
||||
*/
|
||||
handleMouseOut(event) {
|
||||
this.updateHTML_(null);
|
||||
this.lastMouseMovePixel_ = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,6 +2,13 @@
|
||||
* @module ol/css
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} FontParameters
|
||||
* @property {Array<string>} families
|
||||
* @property {string} style
|
||||
* @property {string} weight
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The CSS class for hidden feature.
|
||||
@@ -62,10 +69,13 @@ export const CLASS_COLLAPSED = 'ol-collapsed';
|
||||
* Get the list of font families from a font spec. Note that this doesn't work
|
||||
* for font families that have commas in them.
|
||||
* @param {string} The CSS font property.
|
||||
* @return {Object<string>} The font families (or null if the input spec is invalid).
|
||||
* @return {FontParameters} The font families (or null if the input spec is invalid).
|
||||
*/
|
||||
export const getFontFamilies = (function() {
|
||||
export const getFontParameters = (function() {
|
||||
let style;
|
||||
/**
|
||||
* @type {Object<string, FontParameters>}
|
||||
*/
|
||||
const cache = {};
|
||||
return function(font) {
|
||||
if (!style) {
|
||||
@@ -74,11 +84,18 @@ export const getFontFamilies = (function() {
|
||||
if (!(font in cache)) {
|
||||
style.font = font;
|
||||
const family = style.fontFamily;
|
||||
const fontWeight = style.fontWeight;
|
||||
const fontStyle = style.fontStyle;
|
||||
style.font = '';
|
||||
if (!family) {
|
||||
return null;
|
||||
}
|
||||
cache[font] = family.split(/,\s?/);
|
||||
const families = family.split(/,\s?/);
|
||||
cache[font] = {
|
||||
families: families,
|
||||
weight: fontWeight,
|
||||
style: fontStyle
|
||||
};
|
||||
}
|
||||
return cache[font];
|
||||
};
|
||||
|
||||
@@ -256,10 +256,10 @@ function readGeometry(object, opt_options) {
|
||||
const rings = convertRings(esriJSONPolygon.rings, layout);
|
||||
if (rings.length === 1) {
|
||||
type = GeometryType.POLYGON;
|
||||
object['rings'] = rings[0];
|
||||
object = Object.assign({}, object, {['rings']: rings[0]});
|
||||
} else {
|
||||
type = GeometryType.MULTI_POLYGON;
|
||||
object['rings'] = rings;
|
||||
object = Object.assign({}, object, {['rings']: rings});
|
||||
}
|
||||
}
|
||||
const geometryReader = GEOMETRY_READERS[type];
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import {assign} from '../obj.js';
|
||||
import {abstract} from '../util.js';
|
||||
import {get as getProjection, equivalent as equivalentProjection, transformExtent} from '../proj.js';
|
||||
import Units from '../proj/Units.js';
|
||||
|
||||
|
||||
/**
|
||||
@@ -89,8 +90,9 @@ class FeatureFormat {
|
||||
let options;
|
||||
if (opt_options) {
|
||||
let dataProjection = opt_options.dataProjection ?
|
||||
opt_options.dataProjection : this.readProjection(source);
|
||||
if (opt_options.extent) {
|
||||
getProjection(opt_options.dataProjection) : this.readProjection(source);
|
||||
if (opt_options.extent &&
|
||||
dataProjection && dataProjection.getUnits() === Units.TILE_PIXELS) {
|
||||
dataProjection = getProjection(dataProjection);
|
||||
dataProjection.setWorldExtent(opt_options.extent);
|
||||
}
|
||||
|
||||
@@ -94,6 +94,8 @@ import {assert} from '../asserts.js';
|
||||
* image service additional to the ones indicated by the compliance level.
|
||||
* @property {Array<string>} [extraFeatures] Additional supported features whose support
|
||||
* is not indicated by the compliance level.
|
||||
* @property {Array<string>} [preferredFormats] Image formats that should preferrably
|
||||
* be used.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -156,15 +158,15 @@ IIIF_PROFILE_VALUES[Versions.VERSION3] = {
|
||||
qualities: ['default']
|
||||
},
|
||||
'level1': {
|
||||
supports: ['regionByPx', 'regionSquare', 'sizeByW', 'sizeByH'],
|
||||
supports: ['regionByPx', 'regionSquare', 'sizeByW', 'sizeByH', 'sizeByWh'],
|
||||
formats: ['jpg'],
|
||||
qualities: ['default']
|
||||
},
|
||||
'level2': {
|
||||
supports: ['regionByPx', 'regionSquare', 'regionByPct',
|
||||
'sizeByW', 'sizeByH', 'sizeByPct', 'sizeByConfinedWh', 'sizeByWh'],
|
||||
formats: ['jpg'],
|
||||
qualities: ['default', 'bitonal']
|
||||
formats: ['jpg', 'png'],
|
||||
qualities: ['default']
|
||||
}
|
||||
};
|
||||
IIIF_PROFILE_VALUES['none'] = {
|
||||
@@ -231,7 +233,16 @@ function generateVersion2Options(iiifInfo) {
|
||||
}
|
||||
|
||||
function generateVersion3Options(iiifInfo) {
|
||||
const levelProfile = iiifInfo.getComplianceLevelSupportedFeatures();
|
||||
const levelProfile = iiifInfo.getComplianceLevelSupportedFeatures(),
|
||||
formats = iiifInfo.imageInfo.extraFormats === undefined ? levelProfile.formats :
|
||||
[...levelProfile.formats, ...iiifInfo.imageInfo.extraFormats],
|
||||
preferredFormat = iiifInfo.imageInfo.preferredFormats !== undefined && Array.isArray(iiifInfo.imageInfo.preferredFormats) &&
|
||||
iiifInfo.imageInfo.preferredFormats.length > 0 ?
|
||||
iiifInfo.imageInfo.preferredFormats.filter(function(format) {
|
||||
return ['jpg', 'png', 'gif'].includes(format);
|
||||
}).reduce(function(acc, format) {
|
||||
return acc === undefined && formats.includes(format) ? format : acc;
|
||||
}, undefined) : undefined;
|
||||
return {
|
||||
url: iiifInfo.imageInfo['id'],
|
||||
sizes: iiifInfo.imageInfo.sizes === undefined ? undefined : iiifInfo.imageInfo.sizes.map(function(size) {
|
||||
@@ -251,13 +262,10 @@ function generateVersion3Options(iiifInfo) {
|
||||
})[0],
|
||||
supports: iiifInfo.imageInfo.extraFeatures === undefined ? levelProfile.supports :
|
||||
[...levelProfile.supports, ...iiifInfo.imageInfo.extraFeatures],
|
||||
formats: iiifInfo.imageInfo.extraFormats === undefined ? levelProfile.formats :
|
||||
[...levelProfile.formats, ...iiifInfo.imageInfo.extraFormats],
|
||||
formats: formats,
|
||||
qualities: iiifInfo.imageInfo.extraQualities === undefined ? levelProfile.qualities :
|
||||
[...levelProfile.supports, ...iiifInfo.imageInfo.extraQualities],
|
||||
maxWidth: undefined,
|
||||
maxHeight: undefined,
|
||||
maxArea: undefined
|
||||
[...levelProfile.qualities, ...iiifInfo.imageInfo.extraQualities],
|
||||
preferredFormat: preferredFormat
|
||||
};
|
||||
}
|
||||
|
||||
@@ -414,7 +422,8 @@ class IIIFInfo {
|
||||
version: version,
|
||||
size: [this.imageInfo.width, this.imageInfo.height],
|
||||
sizes: imageOptions.sizes,
|
||||
format: imageOptions.formats.includes(options.format) ? options.format : 'jpg',
|
||||
format: options.format !== undefined && imageOptions.formats.includes(options.format) ? options.format :
|
||||
imageOptions.preferredFormat !== undefined ? imageOptions.preferredFormat : 'jpg',
|
||||
supports: imageOptions.supports,
|
||||
quality: options.quality && imageOptions.qualities.includes(options.quality) ?
|
||||
options.quality : imageOptions.qualities.includes('native') ? 'native' : 'default',
|
||||
|
||||
@@ -408,7 +408,7 @@ class WFS extends XMLFeature {
|
||||
node.setAttribute('count', String(options.count));
|
||||
}
|
||||
if (options.viewParams !== undefined) {
|
||||
node.setAttribute('viewParams ', options.viewParams);
|
||||
node.setAttribute('viewParams', options.viewParams);
|
||||
}
|
||||
filter = options.filter;
|
||||
if (options.bbox) {
|
||||
|
||||
@@ -17,6 +17,8 @@ import DragBox from './DragBox.js';
|
||||
* Default is {@link module:ol/events/condition~shiftKeyOnly}.
|
||||
* @property {number} [duration=200] Animation duration in milliseconds.
|
||||
* @property {boolean} [out=false] Use interaction for zooming out.
|
||||
* @property {number} [minArea=64] The minimum area of the box in pixel, this value is used by the parent default
|
||||
* `boxEndCondition` function.
|
||||
*/
|
||||
|
||||
|
||||
@@ -42,6 +44,7 @@ class DragZoom extends DragBox {
|
||||
super({
|
||||
condition: condition,
|
||||
className: options.className || 'ol-dragzoom',
|
||||
minArea: options.minArea,
|
||||
onBoxEnd: onBoxEnd
|
||||
});
|
||||
|
||||
|
||||
@@ -23,6 +23,10 @@ import {assign} from '../obj.js';
|
||||
* visible.
|
||||
* @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will
|
||||
* be visible.
|
||||
* @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be
|
||||
* visible.
|
||||
* @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will
|
||||
* be visible.
|
||||
*/
|
||||
|
||||
|
||||
@@ -57,6 +61,10 @@ class BaseLayer extends BaseObject {
|
||||
options.maxResolution !== undefined ? options.maxResolution : Infinity;
|
||||
properties[LayerProperty.MIN_RESOLUTION] =
|
||||
options.minResolution !== undefined ? options.minResolution : 0;
|
||||
properties[LayerProperty.MIN_ZOOM] =
|
||||
options.minZoom !== undefined ? options.minZoom : -Infinity;
|
||||
properties[LayerProperty.MAX_ZOOM] =
|
||||
options.maxZoom !== undefined ? options.maxZoom : Infinity;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
@@ -103,6 +111,8 @@ class BaseLayer extends BaseObject {
|
||||
state.zIndex = this.getZIndex() || (state.managed === false ? Infinity : 0);
|
||||
state.maxResolution = this.getMaxResolution();
|
||||
state.minResolution = Math.max(this.getMinResolution(), 0);
|
||||
state.minZoom = this.getMinZoom();
|
||||
state.maxZoom = this.getMaxZoom();
|
||||
this.state_ = state;
|
||||
|
||||
return state;
|
||||
@@ -161,6 +171,26 @@ class BaseLayer extends BaseObject {
|
||||
return /** @type {number} */ (this.get(LayerProperty.MIN_RESOLUTION));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the minimum zoom level of the layer.
|
||||
* @return {number} The minimum zoom level of the layer.
|
||||
* @observable
|
||||
* @api
|
||||
*/
|
||||
getMinZoom() {
|
||||
return /** @type {number} */ (this.get(LayerProperty.MIN_ZOOM));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the maximum zoom level of the layer.
|
||||
* @return {number} The maximum zoom level of the layer.
|
||||
* @observable
|
||||
* @api
|
||||
*/
|
||||
getMaxZoom() {
|
||||
return /** @type {number} */ (this.get(LayerProperty.MAX_ZOOM));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the opacity of the layer (between 0 and 1).
|
||||
* @return {number} The opacity of the layer.
|
||||
@@ -231,6 +261,30 @@ class BaseLayer extends BaseObject {
|
||||
this.set(LayerProperty.MIN_RESOLUTION, minResolution);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum zoom (exclusive) at which the layer is visible.
|
||||
* Note that the zoom levels for layer visibility are based on the
|
||||
* view zoom level, which may be different from a tile source zoom level.
|
||||
* @param {number} maxZoom The maximum zoom of the layer.
|
||||
* @observable
|
||||
* @api
|
||||
*/
|
||||
setMaxZoom(maxZoom) {
|
||||
this.set(LayerProperty.MAX_ZOOM, maxZoom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the minimum zoom (inclusive) at which the layer is visible.
|
||||
* Note that the zoom levels for layer visibility are based on the
|
||||
* view zoom level, which may be different from a tile source zoom level.
|
||||
* @param {number} minZoom The minimum zoom of the layer.
|
||||
* @observable
|
||||
* @api
|
||||
*/
|
||||
setMinZoom(minZoom) {
|
||||
this.set(LayerProperty.MIN_ZOOM, minZoom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the opacity of the layer, allowed values range from 0 to 1.
|
||||
* @param {number} opacity The opacity of the layer.
|
||||
|
||||
@@ -29,6 +29,10 @@ import SourceState from '../source/State.js';
|
||||
* visible.
|
||||
* @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will
|
||||
* be visible.
|
||||
* @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be
|
||||
* visible.
|
||||
* @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will
|
||||
* be visible.
|
||||
* @property {Array<import("./Base.js").default>|import("../Collection.js").default<import("./Base.js").default>} [layers] Child layers.
|
||||
*/
|
||||
|
||||
@@ -215,6 +219,10 @@ class LayerGroup extends BaseLayer {
|
||||
layerState.maxResolution, ownLayerState.maxResolution);
|
||||
layerState.minResolution = Math.max(
|
||||
layerState.minResolution, ownLayerState.minResolution);
|
||||
layerState.minZoom = Math.max(
|
||||
layerState.minZoom, ownLayerState.minZoom);
|
||||
layerState.maxZoom = Math.min(
|
||||
layerState.maxZoom, ownLayerState.maxZoom);
|
||||
if (ownLayerState.extent !== undefined) {
|
||||
if (layerState.extent !== undefined) {
|
||||
layerState.extent = getIntersection(layerState.extent, ownLayerState.extent);
|
||||
|
||||
@@ -183,31 +183,24 @@ class Heatmap extends VectorLayer {
|
||||
precision mediump float;
|
||||
attribute vec2 a_position;
|
||||
attribute vec2 a_texCoord;
|
||||
attribute float a_rotateWithView;
|
||||
attribute vec2 a_offsets;
|
||||
attribute float a_opacity;
|
||||
|
||||
uniform mat4 u_projectionMatrix;
|
||||
uniform mat4 u_offsetScaleMatrix;
|
||||
uniform mat4 u_offsetRotateMatrix;
|
||||
uniform float u_size;
|
||||
|
||||
varying vec2 v_texCoord;
|
||||
varying float v_opacity;
|
||||
|
||||
void main(void) {
|
||||
mat4 offsetMatrix = u_offsetScaleMatrix;
|
||||
if (a_rotateWithView == 1.0) {
|
||||
offsetMatrix = u_offsetScaleMatrix * u_offsetRotateMatrix;
|
||||
}
|
||||
vec4 offsets = offsetMatrix * vec4(a_offsets, 0.0, 0.0);
|
||||
vec4 offsets = u_offsetScaleMatrix * vec4(a_offsets, 0.0, 0.0);
|
||||
gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets * u_size;
|
||||
v_texCoord = a_texCoord;
|
||||
v_opacity = a_opacity;
|
||||
}`,
|
||||
fragmentShader: `
|
||||
precision mediump float;
|
||||
uniform float u_resolution;
|
||||
uniform float u_blurSlope;
|
||||
|
||||
varying vec2 v_texCoord;
|
||||
@@ -226,10 +219,7 @@ class Heatmap extends VectorLayer {
|
||||
}.bind(this),
|
||||
u_blurSlope: function() {
|
||||
return this.get(Property.RADIUS) / Math.max(1, this.get(Property.BLUR));
|
||||
}.bind(this),
|
||||
u_resolution: function(frameState) {
|
||||
return frameState.viewState.resolution;
|
||||
}
|
||||
}.bind(this)
|
||||
},
|
||||
postProcesses: [
|
||||
{
|
||||
@@ -240,7 +230,6 @@ class Heatmap extends VectorLayer {
|
||||
uniform sampler2D u_gradientTexture;
|
||||
|
||||
varying vec2 v_texCoord;
|
||||
varying vec2 v_screenCoord;
|
||||
|
||||
void main() {
|
||||
vec4 color = texture2D(u_image, v_texCoord);
|
||||
|
||||
@@ -50,6 +50,8 @@ import SourceState from '../source/State.js';
|
||||
* @property {number} zIndex
|
||||
* @property {number} maxResolution
|
||||
* @property {number} minResolution
|
||||
* @property {number} minZoom
|
||||
* @property {number} maxZoom
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -277,17 +279,22 @@ class Layer extends BaseLayer {
|
||||
|
||||
|
||||
/**
|
||||
* Return `true` if the layer is visible, and if the passed resolution is
|
||||
* between the layer's minResolution and maxResolution. The comparison is
|
||||
* inclusive for `minResolution` and exclusive for `maxResolution`.
|
||||
* Return `true` if the layer is visible and if the provided view state
|
||||
* has resolution and zoom levels that are in range of the layer's min/max.
|
||||
* @param {State} layerState Layer state.
|
||||
* @param {number} resolution Resolution.
|
||||
* @return {boolean} The layer is visible at the given resolution.
|
||||
* @param {import("../View.js").State} viewState View state.
|
||||
* @return {boolean} The layer is visible at the given view state.
|
||||
*/
|
||||
export function visibleAtResolution(layerState, resolution) {
|
||||
return layerState.visible && resolution >= layerState.minResolution &&
|
||||
resolution < layerState.maxResolution;
|
||||
export function inView(layerState, viewState) {
|
||||
if (!layerState.visible) {
|
||||
return false;
|
||||
}
|
||||
const resolution = viewState.resolution;
|
||||
if (resolution < layerState.minResolution || resolution >= layerState.maxResolution) {
|
||||
return false;
|
||||
}
|
||||
const zoom = viewState.zoom;
|
||||
return zoom > layerState.minZoom && zoom <= layerState.maxZoom;
|
||||
}
|
||||
|
||||
|
||||
export default Layer;
|
||||
|
||||
@@ -12,5 +12,7 @@ export default {
|
||||
Z_INDEX: 'zIndex',
|
||||
MAX_RESOLUTION: 'maxResolution',
|
||||
MIN_RESOLUTION: 'minResolution',
|
||||
MAX_ZOOM: 'maxZoom',
|
||||
MIN_ZOOM: 'minZoom',
|
||||
SOURCE: 'source'
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @module ol/render/canvas
|
||||
*/
|
||||
import {getFontFamilies} from '../css.js';
|
||||
import {getFontParameters} from '../css.js';
|
||||
import {createCanvasContext2D} from '../dom.js';
|
||||
import {clear} from '../obj.js';
|
||||
import {create as createTransform} from '../transform.js';
|
||||
@@ -18,19 +18,19 @@ import LabelCache from './canvas/LabelCache.js';
|
||||
* @typedef {Object} FillStrokeState
|
||||
* @property {import("../colorlike.js").ColorLike} [currentFillStyle]
|
||||
* @property {import("../colorlike.js").ColorLike} [currentStrokeStyle]
|
||||
* @property {string} [currentLineCap]
|
||||
* @property {CanvasLineCap} [currentLineCap]
|
||||
* @property {Array<number>} currentLineDash
|
||||
* @property {number} [currentLineDashOffset]
|
||||
* @property {string} [currentLineJoin]
|
||||
* @property {CanvasLineJoin} [currentLineJoin]
|
||||
* @property {number} [currentLineWidth]
|
||||
* @property {number} [currentMiterLimit]
|
||||
* @property {number} [lastStroke]
|
||||
* @property {import("../colorlike.js").ColorLike} [fillStyle]
|
||||
* @property {import("../colorlike.js").ColorLike} [strokeStyle]
|
||||
* @property {string} [lineCap]
|
||||
* @property {CanvasLineCap} [lineCap]
|
||||
* @property {Array<number>} lineDash
|
||||
* @property {number} [lineDashOffset]
|
||||
* @property {string} [lineJoin]
|
||||
* @property {CanvasLineJoin} [lineJoin]
|
||||
* @property {number} [lineWidth]
|
||||
* @property {number} [miterLimit]
|
||||
*/
|
||||
@@ -38,10 +38,10 @@ import LabelCache from './canvas/LabelCache.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} StrokeState
|
||||
* @property {string} lineCap
|
||||
* @property {CanvasLineCap} lineCap
|
||||
* @property {Array<number>} lineDash
|
||||
* @property {number} lineDashOffset
|
||||
* @property {string} lineJoin
|
||||
* @property {CanvasLineJoin} lineJoin
|
||||
* @property {number} lineWidth
|
||||
* @property {number} miterLimit
|
||||
* @property {import("../colorlike.js").ColorLike} strokeStyle
|
||||
@@ -92,7 +92,7 @@ export const defaultFillStyle = '#000';
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
* @type {CanvasLineCap}
|
||||
*/
|
||||
export const defaultLineCap = 'round';
|
||||
|
||||
@@ -113,7 +113,7 @@ export const defaultLineDashOffset = 0;
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
* @type {CanvasLineJoin}
|
||||
*/
|
||||
export const defaultLineJoin = 'round';
|
||||
|
||||
@@ -180,6 +180,10 @@ export const checkedFonts = {};
|
||||
*/
|
||||
let measureContext = null;
|
||||
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
let measureFont;
|
||||
|
||||
/**
|
||||
* @type {!Object<string, number>}
|
||||
@@ -192,7 +196,7 @@ export const textHeights = {};
|
||||
* @param {string} fontSpec CSS font spec.
|
||||
*/
|
||||
export const checkFont = (function() {
|
||||
const retries = 60;
|
||||
const retries = 100;
|
||||
const checked = checkedFonts;
|
||||
const size = '32px ';
|
||||
const referenceFonts = ['monospace', 'serif'];
|
||||
@@ -200,32 +204,30 @@ export const checkFont = (function() {
|
||||
const text = 'wmytzilWMYTZIL@#/&?$%10\uF013';
|
||||
let interval, referenceWidth;
|
||||
|
||||
function isAvailable(font) {
|
||||
/**
|
||||
* @param {string} fontStyle Css font-style
|
||||
* @param {string} fontWeight Css font-weight
|
||||
* @param {*} fontFamily Css font-family
|
||||
* @return {boolean} Font with style and weight is available
|
||||
*/
|
||||
function isAvailable(fontStyle, fontWeight, fontFamily) {
|
||||
const context = getMeasureContext();
|
||||
// Check weight ranges according to
|
||||
// https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight#Fallback_weights
|
||||
for (let weight = 100; weight <= 700; weight += 300) {
|
||||
const fontWeight = weight + ' ';
|
||||
let available = true;
|
||||
for (let i = 0; i < len; ++i) {
|
||||
const referenceFont = referenceFonts[i];
|
||||
context.font = fontWeight + size + referenceFont;
|
||||
referenceWidth = context.measureText(text).width;
|
||||
if (font != referenceFont) {
|
||||
context.font = fontWeight + size + font + ',' + referenceFont;
|
||||
const width = context.measureText(text).width;
|
||||
// If width and referenceWidth are the same, then the fallback was used
|
||||
// instead of the font we wanted, so the font is not available.
|
||||
available = available && width != referenceWidth;
|
||||
}
|
||||
}
|
||||
if (available) {
|
||||
// Consider font available when it is available in one weight range.
|
||||
//FIXME With this we miss rare corner cases, so we should consider
|
||||
//FIXME checking availability for each requested weight range.
|
||||
return true;
|
||||
let available = true;
|
||||
for (let i = 0; i < len; ++i) {
|
||||
const referenceFont = referenceFonts[i];
|
||||
context.font = fontStyle + ' ' + fontWeight + ' ' + size + referenceFont;
|
||||
referenceWidth = context.measureText(text).width;
|
||||
if (fontFamily != referenceFont) {
|
||||
context.font = fontStyle + ' ' + fontWeight + ' ' + size + fontFamily + ',' + referenceFont;
|
||||
const width = context.measureText(text).width;
|
||||
// If width and referenceWidth are the same, then the fallback was used
|
||||
// instead of the font we wanted, so the font is not available.
|
||||
available = available && width != referenceWidth;
|
||||
}
|
||||
}
|
||||
if (available) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -233,12 +235,15 @@ export const checkFont = (function() {
|
||||
let done = true;
|
||||
for (const font in checked) {
|
||||
if (checked[font] < retries) {
|
||||
if (isAvailable(font)) {
|
||||
if (isAvailable.apply(this, font.split('\n'))) {
|
||||
checked[font] = retries;
|
||||
clear(textHeights);
|
||||
// Make sure that loaded fonts are picked up by Safari
|
||||
measureContext = null;
|
||||
labelCache.clear();
|
||||
measureFont = undefined;
|
||||
if (labelCache.getCount()) {
|
||||
labelCache.clear();
|
||||
}
|
||||
} else {
|
||||
++checked[font];
|
||||
done = false;
|
||||
@@ -252,16 +257,18 @@ export const checkFont = (function() {
|
||||
}
|
||||
|
||||
return function(fontSpec) {
|
||||
const fontFamilies = getFontFamilies(fontSpec);
|
||||
if (!fontFamilies) {
|
||||
const font = getFontParameters(fontSpec);
|
||||
if (!font) {
|
||||
return;
|
||||
}
|
||||
for (let i = 0, ii = fontFamilies.length; i < ii; ++i) {
|
||||
const fontFamily = fontFamilies[i];
|
||||
if (!(fontFamily in checked)) {
|
||||
checked[fontFamily] = retries;
|
||||
if (!isAvailable(fontFamily)) {
|
||||
checked[fontFamily] = 0;
|
||||
const families = font.families;
|
||||
for (let i = 0, ii = families.length; i < ii; ++i) {
|
||||
const family = families[i];
|
||||
const key = font.style + '\n' + font.weight + '\n' + family;
|
||||
if (!(key in checked)) {
|
||||
checked[key] = retries;
|
||||
if (!isAvailable(font.style, font.weight, family)) {
|
||||
checked[key] = 0;
|
||||
if (interval === undefined) {
|
||||
interval = setInterval(check, 32);
|
||||
}
|
||||
@@ -317,8 +324,8 @@ export const measureTextHeight = (function() {
|
||||
*/
|
||||
export function measureTextWidth(font, text) {
|
||||
const measureContext = getMeasureContext();
|
||||
if (font != measureContext.font) {
|
||||
measureContext.font = font;
|
||||
if (font != measureFont) {
|
||||
measureContext.font = measureFont = font;
|
||||
}
|
||||
return measureContext.measureText(text).width;
|
||||
}
|
||||
|
||||
@@ -207,8 +207,8 @@ class Executor extends Disposable {
|
||||
if (strokeKey) {
|
||||
context.strokeStyle = strokeState.strokeStyle;
|
||||
context.lineWidth = strokeWidth;
|
||||
context.lineCap = /** @type {CanvasLineCap} */ (strokeState.lineCap);
|
||||
context.lineJoin = /** @type {CanvasLineJoin} */ (strokeState.lineJoin);
|
||||
context.lineCap = strokeState.lineCap;
|
||||
context.lineJoin = strokeState.lineJoin;
|
||||
context.miterLimit = strokeState.miterLimit;
|
||||
if (context.setLineDash && strokeState.lineDash.length) {
|
||||
context.setLineDash(strokeState.lineDash);
|
||||
|
||||
@@ -692,12 +692,12 @@ class CanvasImmediateRenderer extends VectorContext {
|
||||
const context = this.context_;
|
||||
const contextStrokeState = this.contextStrokeState_;
|
||||
if (!contextStrokeState) {
|
||||
context.lineCap = /** @type {CanvasLineCap} */ (strokeState.lineCap);
|
||||
context.lineCap = strokeState.lineCap;
|
||||
if (context.setLineDash) {
|
||||
context.setLineDash(strokeState.lineDash);
|
||||
context.lineDashOffset = strokeState.lineDashOffset;
|
||||
}
|
||||
context.lineJoin = /** @type {CanvasLineJoin} */ (strokeState.lineJoin);
|
||||
context.lineJoin = strokeState.lineJoin;
|
||||
context.lineWidth = strokeState.lineWidth;
|
||||
context.miterLimit = strokeState.miterLimit;
|
||||
context.strokeStyle = strokeState.strokeStyle;
|
||||
@@ -712,7 +712,7 @@ class CanvasImmediateRenderer extends VectorContext {
|
||||
};
|
||||
} else {
|
||||
if (contextStrokeState.lineCap != strokeState.lineCap) {
|
||||
contextStrokeState.lineCap = context.lineCap = /** @type {CanvasLineCap} */ (strokeState.lineCap);
|
||||
contextStrokeState.lineCap = context.lineCap = strokeState.lineCap;
|
||||
}
|
||||
if (context.setLineDash) {
|
||||
if (!equals(contextStrokeState.lineDash, strokeState.lineDash)) {
|
||||
@@ -724,7 +724,7 @@ class CanvasImmediateRenderer extends VectorContext {
|
||||
}
|
||||
}
|
||||
if (contextStrokeState.lineJoin != strokeState.lineJoin) {
|
||||
contextStrokeState.lineJoin = context.lineJoin = /** @type {CanvasLineJoin} */ (strokeState.lineJoin);
|
||||
contextStrokeState.lineJoin = context.lineJoin = strokeState.lineJoin;
|
||||
}
|
||||
if (contextStrokeState.lineWidth != strokeState.lineWidth) {
|
||||
contextStrokeState.lineWidth = context.lineWidth = strokeState.lineWidth;
|
||||
|
||||
@@ -21,8 +21,8 @@ class LabelCache extends LRUCache {
|
||||
}
|
||||
|
||||
clear() {
|
||||
super.clear();
|
||||
this.consumers = {};
|
||||
super.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @module ol/renderer/Composite
|
||||
*/
|
||||
import {CLASS_UNSELECTABLE} from '../css.js';
|
||||
import {visibleAtResolution} from '../layer/Layer.js';
|
||||
import {inView} from '../layer/Layer.js';
|
||||
import RenderEvent from '../render/Event.js';
|
||||
import RenderEventType from '../render/EventType.js';
|
||||
import MapRenderer from './Map.js';
|
||||
@@ -95,7 +95,7 @@ class CompositeMapRenderer extends MapRenderer {
|
||||
const layerStatesArray = frameState.layerStatesArray.sort(function(a, b) {
|
||||
return a.zIndex - b.zIndex;
|
||||
});
|
||||
const viewResolution = frameState.viewState.resolution;
|
||||
const viewState = frameState.viewState;
|
||||
|
||||
this.children_.length = 0;
|
||||
let hasOverlay = false;
|
||||
@@ -104,7 +104,7 @@ class CompositeMapRenderer extends MapRenderer {
|
||||
const layerState = layerStatesArray[i];
|
||||
hasOverlay = hasOverlay || layerState.hasOverlay;
|
||||
frameState.layerIndex = i;
|
||||
if (!visibleAtResolution(layerState, viewResolution) ||
|
||||
if (!inView(layerState, viewState) ||
|
||||
(layerState.sourceState != SourceState.READY && layerState.sourceState != SourceState.UNDEFINED)) {
|
||||
continue;
|
||||
}
|
||||
@@ -142,7 +142,6 @@ class CompositeMapRenderer extends MapRenderer {
|
||||
*/
|
||||
forEachLayerAtPixel(pixel, frameState, hitTolerance, callback, layerFilter) {
|
||||
const viewState = frameState.viewState;
|
||||
const viewResolution = viewState.resolution;
|
||||
|
||||
const layerStates = frameState.layerStatesArray;
|
||||
const numLayers = layerStates.length;
|
||||
@@ -150,7 +149,7 @@ class CompositeMapRenderer extends MapRenderer {
|
||||
for (let i = numLayers - 1; i >= 0; --i) {
|
||||
const layerState = layerStates[i];
|
||||
const layer = layerState.layer;
|
||||
if (layer.hasRenderer() && visibleAtResolution(layerState, viewResolution) && layerFilter(layer)) {
|
||||
if (layer.hasRenderer() && inView(layerState, viewState) && layerFilter(layer)) {
|
||||
const layerRenderer = layer.getRenderer();
|
||||
const data = layerRenderer.getDataAtPixel(pixel, frameState, hitTolerance);
|
||||
if (data) {
|
||||
|
||||
@@ -132,15 +132,6 @@ class LayerRenderer extends Observable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
|
||||
* @param {import("../PluggableMap.js").FrameState} frameState Frame state.
|
||||
* @return {boolean} Is there a feature at the given coordinate?
|
||||
*/
|
||||
hasFeatureAtCoordinate(coordinate, frameState) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the image if not already loaded, and register the image change
|
||||
* listener if needed.
|
||||
|
||||
@@ -5,7 +5,7 @@ import {abstract, getUid} from '../util.js';
|
||||
import Disposable from '../Disposable.js';
|
||||
import {getWidth} from '../extent.js';
|
||||
import {TRUE} from '../functions.js';
|
||||
import {visibleAtResolution} from '../layer/Layer.js';
|
||||
import {inView} from '../layer/Layer.js';
|
||||
import {shared as iconImageCache} from '../style/IconImageCache.js';
|
||||
import {compose as composeTransform, makeInverse} from '../transform.js';
|
||||
import {renderDeclutterItems} from '../render.js';
|
||||
@@ -87,7 +87,6 @@ class MapRenderer extends Disposable {
|
||||
) {
|
||||
let result;
|
||||
const viewState = frameState.viewState;
|
||||
const viewResolution = viewState.resolution;
|
||||
|
||||
/**
|
||||
* @param {boolean} managed Managed layer.
|
||||
@@ -126,7 +125,7 @@ class MapRenderer extends Disposable {
|
||||
for (i = numLayers - 1; i >= 0; --i) {
|
||||
const layerState = layerStates[i];
|
||||
const layer = /** @type {import("../layer/Layer.js").default} */ (layerState.layer);
|
||||
if (layer.hasRenderer() && visibleAtResolution(layerState, viewResolution) && layerFilter.call(thisArg2, layer)) {
|
||||
if (layer.hasRenderer() && inView(layerState, viewState) && layerFilter.call(thisArg2, layer)) {
|
||||
const layerRenderer = layer.getRenderer();
|
||||
const source = layer.getSource();
|
||||
if (layerRenderer && source) {
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
makeInverse
|
||||
} from '../../transform.js';
|
||||
import CanvasExecutorGroup, {replayDeclutter} from '../../render/canvas/ExecutorGroup.js';
|
||||
import {clear} from '../../obj.js';
|
||||
|
||||
|
||||
/**
|
||||
@@ -343,11 +344,13 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
|
||||
let i, ii;
|
||||
for (i = 0, ii = renderedTiles.length; i < ii; ++i) {
|
||||
const tile = renderedTiles[i];
|
||||
const tileExtent = tileGrid.getTileCoordExtent(tile.wrappedTileCoord);
|
||||
const tileContainsCoordinate = containsCoordinate(tileExtent, coordinate);
|
||||
|
||||
if (!declutter) {
|
||||
// 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)) {
|
||||
if (!tileContainsCoordinate) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -360,13 +363,15 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
|
||||
* @return {?} Callback result.
|
||||
*/
|
||||
function(feature) {
|
||||
let key = feature.getId();
|
||||
if (key === undefined) {
|
||||
key = getUid(feature);
|
||||
}
|
||||
if (!(key in features)) {
|
||||
features[key] = true;
|
||||
return callback(feature, layer);
|
||||
if (tileContainsCoordinate || (declutteredFeatures && declutteredFeatures.indexOf(feature) !== -1)) {
|
||||
let key = feature.getId();
|
||||
if (key === undefined) {
|
||||
key = getUid(feature);
|
||||
}
|
||||
if (!(key in features)) {
|
||||
features[key] = true;
|
||||
return callback(feature, layer);
|
||||
}
|
||||
}
|
||||
}, layer.getDeclutter() ? declutteredFeatures : null);
|
||||
}
|
||||
@@ -378,6 +383,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
|
||||
* @inheritDoc
|
||||
*/
|
||||
handleFontsChanged() {
|
||||
clear(this.renderTileImageQueue_);
|
||||
const layer = this.getLayer();
|
||||
if (layer.getVisible() && this.renderedLayerRevision_ !== undefined) {
|
||||
layer.changed();
|
||||
|
||||
@@ -81,6 +81,7 @@ class WebGLLayerRenderer extends LayerRenderer {
|
||||
getShaderCompileErrors() {
|
||||
return this.helper.getShaderCompileErrors();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -231,11 +232,47 @@ export function writePointFeatureToBuffers(instructions, elementIndex, vertexBuf
|
||||
* @private
|
||||
* @return {ImageData} Image data.
|
||||
*/
|
||||
export function getBlankTexture() {
|
||||
export function getBlankImageData() {
|
||||
const canvas = document.createElement('canvas');
|
||||
const image = canvas.getContext('2d').createImageData(1, 1);
|
||||
image.data[0] = image.data[1] = image.data[2] = image.data[3] = 255;
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a color array based on a numerical id
|
||||
* Note: the range for each component is 0 to 1 with 256 steps
|
||||
* @param {number} id Id
|
||||
* @param {Array<number>} [opt_array] Reusable array
|
||||
* @return {Array<number>} Color array containing the encoded id
|
||||
*/
|
||||
export function colorEncodeId(id, opt_array) {
|
||||
const array = opt_array || [];
|
||||
const radix = 256;
|
||||
const divide = radix - 1;
|
||||
array[0] = Math.floor(id / radix / radix / radix) / divide;
|
||||
array[1] = (Math.floor(id / radix / radix) % radix) / divide;
|
||||
array[2] = (Math.floor(id / radix) % radix) / divide;
|
||||
array[3] = (id % radix) / divide;
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads an id from a color-encoded array
|
||||
* Note: the expected range for each component is 0 to 1 with 256 steps.
|
||||
* @param {Array<number>} color Color array containing the encoded id
|
||||
* @return {number} Decoded id
|
||||
*/
|
||||
export function colorDecodeId(color) {
|
||||
let id = 0;
|
||||
const radix = 256;
|
||||
const mult = radix - 1;
|
||||
id += Math.round(color[0] * radix * radix * radix * mult);
|
||||
id += Math.round(color[1] * radix * radix * mult);
|
||||
id += Math.round(color[2] * radix * mult);
|
||||
id += Math.round(color[3] * mult);
|
||||
return id;
|
||||
}
|
||||
|
||||
export default WebGLLayerRenderer;
|
||||
|
||||
@@ -6,7 +6,9 @@ import {DYNAMIC_DRAW, ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER, FLOAT} from '../../web
|
||||
import {DefaultAttrib, DefaultUniform} from '../../webgl/Helper.js';
|
||||
import GeometryType from '../../geom/GeometryType.js';
|
||||
import WebGLLayerRenderer, {
|
||||
getBlankTexture,
|
||||
colorDecodeId,
|
||||
colorEncodeId,
|
||||
getBlankImageData,
|
||||
POINT_INSTRUCTIONS_COUNT, POINT_VERTEX_STRIDE, WebGLWorkerMessageType,
|
||||
writePointFeatureInstructions
|
||||
} from './Layer.js';
|
||||
@@ -19,6 +21,8 @@ import {
|
||||
apply as applyTransform
|
||||
} from '../../transform.js';
|
||||
import {create as createWebGLWorker} from '../../worker/webgl.js';
|
||||
import {getUid} from '../../util.js';
|
||||
import WebGLRenderTarget from '../../webgl/RenderTarget.js';
|
||||
|
||||
const VERTEX_SHADER = `
|
||||
precision mediump float;
|
||||
@@ -68,6 +72,26 @@ const FRAGMENT_SHADER = `
|
||||
gl_FragColor.rgb *= gl_FragColor.a;
|
||||
}`;
|
||||
|
||||
const HIT_FRAGMENT_SHADER = `
|
||||
precision mediump float;
|
||||
|
||||
uniform sampler2D u_texture;
|
||||
|
||||
varying vec2 v_texCoord;
|
||||
varying float v_opacity;
|
||||
varying vec4 v_color;
|
||||
|
||||
void main(void) {
|
||||
if (v_opacity == 0.0) {
|
||||
discard;
|
||||
}
|
||||
vec4 textureColor = texture2D(u_texture, v_texCoord);
|
||||
if (textureColor.a < 0.1) {
|
||||
discard;
|
||||
}
|
||||
gl_FragColor = v_color;
|
||||
}`;
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
* @property {function(import("../../Feature").default):number} [sizeCallback] Will be called on every feature in the
|
||||
@@ -87,7 +111,7 @@ const FRAGMENT_SHADER = `
|
||||
* source to compute the opacity of the quad on screen (from 0 to 1). This is only done on source change.
|
||||
* Note: this is multiplied with the color of the point which can also have an alpha value < 1.
|
||||
* @property {function(import("../../Feature").default):boolean} [rotateWithViewCallback] Will be called on every feature in the
|
||||
* source to compute whether the quad on screen must stay upwards (`false`) or follow the view rotation (`true`).
|
||||
* source to compute whether the quad on screen must stay upwards (`false`) or follow the view rotation (`true`). Default is `false`.
|
||||
* This is only done on source change.
|
||||
* @property {HTMLCanvasElement|HTMLImageElement|ImageData} [texture] Texture to use on points. `texCoordCallback` and `sizeCallback`
|
||||
* must be defined for this to have any effect.
|
||||
@@ -200,7 +224,7 @@ class WebGLPointsLayerRenderer extends WebGLLayerRenderer {
|
||||
const options = opt_options || {};
|
||||
|
||||
const uniforms = options.uniforms || {};
|
||||
uniforms.u_texture = options.texture || getBlankTexture();
|
||||
uniforms.u_texture = options.texture || getBlankImageData();
|
||||
const projectionMatrixTransform = createTransform();
|
||||
uniforms[DefaultUniform.PROJECTION_MATRIX] = projectionMatrixTransform;
|
||||
|
||||
@@ -212,14 +236,17 @@ class WebGLPointsLayerRenderer extends WebGLLayerRenderer {
|
||||
this.sourceRevision_ = -1;
|
||||
|
||||
this.verticesBuffer_ = new WebGLArrayBuffer(ARRAY_BUFFER, DYNAMIC_DRAW);
|
||||
this.hitVerticesBuffer_ = new WebGLArrayBuffer(ARRAY_BUFFER, DYNAMIC_DRAW);
|
||||
this.indicesBuffer_ = new WebGLArrayBuffer(ELEMENT_ARRAY_BUFFER, DYNAMIC_DRAW);
|
||||
|
||||
this.program_ = this.helper.getProgram(
|
||||
options.fragmentShader || FRAGMENT_SHADER,
|
||||
options.vertexShader || VERTEX_SHADER
|
||||
);
|
||||
|
||||
this.helper.useProgram(this.program_);
|
||||
this.hitProgram_ = this.helper.getProgram(
|
||||
HIT_FRAGMENT_SHADER,
|
||||
options.vertexShader || VERTEX_SHADER
|
||||
);
|
||||
|
||||
this.sizeCallback_ = options.sizeCallback || function() {
|
||||
return 1;
|
||||
@@ -274,32 +301,45 @@ class WebGLPointsLayerRenderer extends WebGLLayerRenderer {
|
||||
*/
|
||||
this.renderInstructions_ = new Float32Array(0);
|
||||
|
||||
/**
|
||||
* These instructions are used for hit detection
|
||||
* @type {Float32Array}
|
||||
* @private
|
||||
*/
|
||||
this.hitRenderInstructions_ = new Float32Array(0);
|
||||
|
||||
/**
|
||||
* @type {WebGLRenderTarget}
|
||||
* @private
|
||||
*/
|
||||
this.hitRenderTarget_ = new WebGLRenderTarget(this.helper);
|
||||
|
||||
this.worker_ = createWebGLWorker();
|
||||
this.worker_.addEventListener('message', function(event) {
|
||||
const received = event.data;
|
||||
if (received.type === WebGLWorkerMessageType.GENERATE_BUFFERS) {
|
||||
const projectionTransform = received.projectionTransform;
|
||||
this.verticesBuffer_.fromArrayBuffer(received.vertexBuffer);
|
||||
if (received.hitDetection) {
|
||||
this.hitVerticesBuffer_.fromArrayBuffer(received.vertexBuffer);
|
||||
this.helper.flushBufferData(this.hitVerticesBuffer_);
|
||||
} else {
|
||||
this.verticesBuffer_.fromArrayBuffer(received.vertexBuffer);
|
||||
this.helper.flushBufferData(this.verticesBuffer_);
|
||||
}
|
||||
this.indicesBuffer_.fromArrayBuffer(received.indexBuffer);
|
||||
this.helper.flushBufferData(this.verticesBuffer_);
|
||||
this.helper.flushBufferData(this.indicesBuffer_);
|
||||
|
||||
// saves the projection transform for the current frame state
|
||||
this.renderTransform_ = projectionTransform;
|
||||
makeInverseTransform(this.invertRenderTransform_, this.renderTransform_);
|
||||
|
||||
this.renderInstructions_ = new Float32Array(event.data.renderInstructions);
|
||||
if (received.hitDetection) {
|
||||
this.hitRenderInstructions_ = new Float32Array(event.data.renderInstructions);
|
||||
} else {
|
||||
this.renderInstructions_ = new Float32Array(event.data.renderInstructions);
|
||||
}
|
||||
}
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
disposeInternal() {
|
||||
super.disposeInternal();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@@ -315,6 +355,9 @@ class WebGLPointsLayerRenderer extends WebGLLayerRenderer {
|
||||
canvas.style.opacity = opacity;
|
||||
}
|
||||
|
||||
this.renderHitDetection(frameState);
|
||||
this.hitRenderTarget_.clearCachedData();
|
||||
|
||||
return canvas;
|
||||
}
|
||||
|
||||
@@ -332,7 +375,6 @@ class WebGLPointsLayerRenderer extends WebGLLayerRenderer {
|
||||
const sourceChanged = this.sourceRevision_ < vectorSource.getRevision();
|
||||
if (sourceChanged) {
|
||||
this.sourceRevision_ = vectorSource.getRevision();
|
||||
this.geojsonFeatureCache_ = {};
|
||||
|
||||
const projection = viewState.projection;
|
||||
const resolution = viewState.resolution;
|
||||
@@ -350,6 +392,7 @@ class WebGLPointsLayerRenderer extends WebGLLayerRenderer {
|
||||
this.helper.makeProjectionTransform(frameState, this.currentTransform_);
|
||||
multiplyTransform(this.currentTransform_, this.invertRenderTransform_);
|
||||
|
||||
this.helper.useProgram(this.program_);
|
||||
this.helper.prepareDraw(frameState);
|
||||
|
||||
// write new data
|
||||
@@ -385,11 +428,16 @@ class WebGLPointsLayerRenderer extends WebGLLayerRenderer {
|
||||
if (!this.renderInstructions_ || this.renderInstructions_.length !== totalInstructionsCount) {
|
||||
this.renderInstructions_ = new Float32Array(totalInstructionsCount);
|
||||
}
|
||||
if (!this.hitRenderInstructions_ || this.hitRenderInstructions_.length !== totalInstructionsCount) {
|
||||
this.hitRenderInstructions_ = new Float32Array(totalInstructionsCount);
|
||||
}
|
||||
|
||||
// loop on features to fill the buffer
|
||||
let feature;
|
||||
const tmpCoords = [];
|
||||
const tmpColor = [];
|
||||
let elementIndex = 0;
|
||||
let u0, v0, u1, v1, size, opacity, rotateWithView, color;
|
||||
for (let i = 0; i < features.length; i++) {
|
||||
feature = features[i];
|
||||
if (!feature.getGeometry() || feature.getGeometry().getType() !== GeometryType.POINT) {
|
||||
@@ -400,19 +448,45 @@ class WebGLPointsLayerRenderer extends WebGLLayerRenderer {
|
||||
tmpCoords[1] = this.coordCallback_(feature, 1);
|
||||
applyTransform(projectionTransform, tmpCoords);
|
||||
|
||||
elementIndex = writePointFeatureInstructions(
|
||||
u0 = this.texCoordCallback_(feature, 0);
|
||||
v0 = this.texCoordCallback_(feature, 1);
|
||||
u1 = this.texCoordCallback_(feature, 2);
|
||||
v1 = this.texCoordCallback_(feature, 3);
|
||||
size = this.sizeCallback_(feature);
|
||||
opacity = this.opacityCallback_(feature);
|
||||
rotateWithView = this.rotateWithViewCallback_(feature);
|
||||
color = this.colorCallback_(feature, this.colorArray_);
|
||||
|
||||
writePointFeatureInstructions(
|
||||
this.renderInstructions_,
|
||||
elementIndex,
|
||||
tmpCoords[0],
|
||||
tmpCoords[1],
|
||||
this.texCoordCallback_(feature, 0),
|
||||
this.texCoordCallback_(feature, 1),
|
||||
this.texCoordCallback_(feature, 2),
|
||||
this.texCoordCallback_(feature, 3),
|
||||
this.sizeCallback_(feature),
|
||||
this.opacityCallback_(feature),
|
||||
this.rotateWithViewCallback_(feature),
|
||||
this.colorCallback_(feature, this.colorArray_)
|
||||
u0,
|
||||
v0,
|
||||
u1,
|
||||
v1,
|
||||
size,
|
||||
opacity,
|
||||
rotateWithView,
|
||||
color
|
||||
);
|
||||
|
||||
// for hit detection, the feature uid is saved in the opacity value
|
||||
// and the index of the opacity value is encoded in the color values
|
||||
elementIndex = writePointFeatureInstructions(
|
||||
this.hitRenderInstructions_,
|
||||
elementIndex,
|
||||
tmpCoords[0],
|
||||
tmpCoords[1],
|
||||
u0,
|
||||
v0,
|
||||
u1,
|
||||
v1,
|
||||
size,
|
||||
opacity > 0 ? Number(getUid(feature)) : 0,
|
||||
rotateWithView,
|
||||
colorEncodeId(elementIndex + 7, tmpColor)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -423,12 +497,73 @@ class WebGLPointsLayerRenderer extends WebGLLayerRenderer {
|
||||
};
|
||||
// additional properties will be sent back as-is by the worker
|
||||
message['projectionTransform'] = projectionTransform;
|
||||
|
||||
this.worker_.postMessage(message, [this.renderInstructions_.buffer]);
|
||||
this.renderInstructions_ = null;
|
||||
|
||||
/** @type import('./Layer').WebGLWorkerGenerateBuffersMessage */
|
||||
const hitMessage = {
|
||||
type: WebGLWorkerMessageType.GENERATE_BUFFERS,
|
||||
renderInstructions: this.hitRenderInstructions_.buffer
|
||||
};
|
||||
hitMessage['projectionTransform'] = projectionTransform;
|
||||
hitMessage['hitDetection'] = true;
|
||||
this.worker_.postMessage(hitMessage, [this.hitRenderInstructions_.buffer]);
|
||||
this.hitRenderInstructions_ = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback, declutteredFeatures) {
|
||||
if (!this.hitRenderInstructions_) {
|
||||
return;
|
||||
}
|
||||
|
||||
const pixel = applyTransform(frameState.coordinateToPixelTransform, coordinate.slice());
|
||||
|
||||
const data = this.hitRenderTarget_.readPixel(pixel[0], pixel[1]);
|
||||
const color = [
|
||||
data[0] / 255,
|
||||
data[1] / 255,
|
||||
data[2] / 255,
|
||||
data[3] / 255
|
||||
];
|
||||
const index = colorDecodeId(color);
|
||||
const opacity = this.hitRenderInstructions_[index];
|
||||
const uid = Math.floor(opacity).toString();
|
||||
|
||||
const source = this.getLayer().getSource();
|
||||
const feature = source.getFeatureByUid(uid);
|
||||
if (feature) {
|
||||
return callback(feature, this.getLayer());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the hit detection data to the corresponding render target
|
||||
* @param {import("../../PluggableMap.js").FrameState} frameState current frame state
|
||||
*/
|
||||
renderHitDetection(frameState) {
|
||||
this.hitRenderTarget_.setSize(frameState.size);
|
||||
|
||||
this.helper.useProgram(this.hitProgram_);
|
||||
this.helper.prepareDrawToRenderTarget(frameState, this.hitRenderTarget_, true);
|
||||
|
||||
this.helper.bindBuffer(this.hitVerticesBuffer_);
|
||||
this.helper.bindBuffer(this.indicesBuffer_);
|
||||
|
||||
const stride = POINT_VERTEX_STRIDE;
|
||||
const bytesPerFloat = Float32Array.BYTES_PER_ELEMENT;
|
||||
this.helper.enableAttributeArray(DefaultAttrib.POSITION, 2, FLOAT, bytesPerFloat * stride, 0);
|
||||
this.helper.enableAttributeArray(DefaultAttrib.OFFSETS, 2, FLOAT, bytesPerFloat * stride, bytesPerFloat * 2);
|
||||
this.helper.enableAttributeArray(DefaultAttrib.TEX_COORD, 2, FLOAT, bytesPerFloat * stride, bytesPerFloat * 4);
|
||||
this.helper.enableAttributeArray(DefaultAttrib.OPACITY, 1, FLOAT, bytesPerFloat * stride, bytesPerFloat * 6);
|
||||
this.helper.enableAttributeArray(DefaultAttrib.ROTATE_WITH_VIEW, 1, FLOAT, bytesPerFloat * stride, bytesPerFloat * 7);
|
||||
this.helper.enableAttributeArray(DefaultAttrib.COLOR, 4, FLOAT, bytesPerFloat * stride, bytesPerFloat * 8);
|
||||
|
||||
const renderCount = this.indicesBuffer_.getArray() ? this.indicesBuffer_.getArray().length : 0;
|
||||
this.helper.drawElements(0, renderCount);
|
||||
}
|
||||
}
|
||||
|
||||
export default WebGLPointsLayerRenderer;
|
||||
|
||||
@@ -51,10 +51,7 @@ class ReprojImage extends ImageBase {
|
||||
|
||||
const sourceExtent = triangulation.calculateSourceExtent();
|
||||
const sourceImage = getImageFunction(sourceExtent, sourceResolution, pixelRatio);
|
||||
let state = ImageState.LOADED;
|
||||
if (sourceImage) {
|
||||
state = ImageState.IDLE;
|
||||
}
|
||||
const state = sourceImage ? ImageState.IDLE : ImageState.EMPTY;
|
||||
const sourcePixelRatio = sourceImage ? sourceImage.getPixelRatio() : 1;
|
||||
|
||||
super(targetExtent, targetResolution, sourcePixelRatio, state);
|
||||
|
||||
@@ -65,7 +65,7 @@ class IIIF extends TileImage {
|
||||
constructor(opt_options) {
|
||||
|
||||
/**
|
||||
* @type {Partial<Options>} options
|
||||
* @type {Partial<Options>}
|
||||
*/
|
||||
const options = opt_options || {};
|
||||
|
||||
|
||||
@@ -191,6 +191,45 @@ class ImageWMS extends ImageSource {
|
||||
1, sourceProjectionObj || projectionObj, baseParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the GetLegendGraphic URL, optionally optimized for the passed
|
||||
* resolution and possibly including any passed specific parameters. Returns
|
||||
* `undefined` if the GetLegendGraphic URL cannot be constructed.
|
||||
*
|
||||
* @param {number} [resolution] Resolution. If set to undefined, `SCALE`
|
||||
* will not be calculated and included in URL.
|
||||
* @param {Object} [params] GetLegendGraphic params. Default `FORMAT` is
|
||||
* `image/png`. `VERSION` should not be specified here.
|
||||
* @return {string|undefined} GetLegendGraphic URL.
|
||||
* @api
|
||||
*/
|
||||
getGetLegendGraphicUrl(resolution, params) {
|
||||
const layers = this.params_.LAYERS;
|
||||
const isSingleLayer = !Array.isArray(layers) || this.params_['LAYERS'].length === 1;
|
||||
if (this.url_ === undefined || !isSingleLayer) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const baseParams = {
|
||||
'SERVICE': 'WMS',
|
||||
'VERSION': DEFAULT_WMS_VERSION,
|
||||
'REQUEST': 'GetLegendGraphic',
|
||||
'FORMAT': 'image/png',
|
||||
'LAYER': layers
|
||||
};
|
||||
|
||||
if (resolution !== undefined) {
|
||||
const mpu = this.getProjection() ? this.getProjection().getMetersPerUnit() : 1;
|
||||
const dpi = 25.4 / 0.28;
|
||||
const inchesPerMeter = 39.37;
|
||||
baseParams['SCALE'] = resolution * mpu * inchesPerMeter * dpi;
|
||||
}
|
||||
|
||||
assign(baseParams, params);
|
||||
|
||||
return appendParams(/** @type {string} */ (this.url_), baseParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user-provided params, i.e. those passed to the constructor through
|
||||
* the "params" option, and possibly updated using the updateParams method.
|
||||
|
||||
@@ -211,6 +211,45 @@ class TileWMS extends TileImage {
|
||||
1, sourceProjectionObj || projectionObj, baseParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the GetLegendGraphic URL, optionally optimized for the passed
|
||||
* resolution and possibly including any passed specific parameters. Returns
|
||||
* `undefined` if the GetLegendGraphic URL cannot be constructed.
|
||||
*
|
||||
* @param {number} [resolution] Resolution. If set to undefined, `SCALE`
|
||||
* will not be calculated and included in URL.
|
||||
* @param {Object} [params] GetLegendGraphic params. Default `FORMAT` is
|
||||
* `image/png`. `VERSION` should not be specified here.
|
||||
* @return {string|undefined} GetLegendGraphic URL.
|
||||
* @api
|
||||
*/
|
||||
getGetLegendGraphicUrl(resolution, params) {
|
||||
const layers = this.params_.LAYERS;
|
||||
const isSingleLayer = !Array.isArray(layers) || this.params_['LAYERS'].length === 1;
|
||||
if (this.urls[0] === undefined || !isSingleLayer) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const baseParams = {
|
||||
'SERVICE': 'WMS',
|
||||
'VERSION': DEFAULT_WMS_VERSION,
|
||||
'REQUEST': 'GetLegendGraphic',
|
||||
'FORMAT': 'image/png',
|
||||
'LAYER': layers
|
||||
};
|
||||
|
||||
if (resolution !== undefined) {
|
||||
const mpu = this.getProjection() ? this.getProjection().getMetersPerUnit() : 1;
|
||||
const dpi = 25.4 / 0.28;
|
||||
const inchesPerMeter = 39.37;
|
||||
baseParams['SCALE'] = resolution * mpu * inchesPerMeter * dpi;
|
||||
}
|
||||
|
||||
assign(baseParams, params);
|
||||
|
||||
return appendParams(/** @type {string} */ (this.urls[0]), baseParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
|
||||
@@ -155,7 +155,7 @@ export class VectorSourceEvent extends Event {
|
||||
* by this source are suitable for editing. See {@link module:ol/source/VectorTile~VectorTile} for
|
||||
* vector data that is optimized for rendering.
|
||||
*
|
||||
* @fires VectorSourceEvent<Geometry>
|
||||
* @fires VectorSourceEvent
|
||||
* @api
|
||||
* @template {import("../geom/Geometry.js").default} Geometry
|
||||
*/
|
||||
@@ -241,11 +241,11 @@ class VectorSource extends Source {
|
||||
this.idIndex_ = {};
|
||||
|
||||
/**
|
||||
* A lookup of features without id (keyed by getUid(feature)).
|
||||
* A lookup of features by uid (using getUid(feature)).
|
||||
* @private
|
||||
* @type {!Object<string, import("../Feature.js").default<Geometry>>}
|
||||
*/
|
||||
this.undefIdIndex_ = {};
|
||||
this.uidIndex_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -359,10 +359,11 @@ class VectorSource extends Source {
|
||||
} else {
|
||||
valid = false;
|
||||
}
|
||||
} else {
|
||||
assert(!(featureKey in this.undefIdIndex_),
|
||||
}
|
||||
if (valid) {
|
||||
assert(!(featureKey in this.uidIndex_),
|
||||
30); // The passed `feature` was already added to the source
|
||||
this.undefIdIndex_[featureKey] = feature;
|
||||
this.uidIndex_[featureKey] = feature;
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
@@ -489,7 +490,7 @@ class VectorSource extends Source {
|
||||
if (!this.featuresCollection_) {
|
||||
this.featureChangeKeys_ = {};
|
||||
this.idIndex_ = {};
|
||||
this.undefIdIndex_ = {};
|
||||
this.uidIndex_ = {};
|
||||
}
|
||||
} else {
|
||||
if (this.featuresRtree_) {
|
||||
@@ -770,6 +771,18 @@ class VectorSource extends Source {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a feature by its internal unique identifier (using `getUid`).
|
||||
*
|
||||
* @param {string} uid Feature identifier.
|
||||
* @return {import("../Feature.js").default<Geometry>} The feature (or `null` if not found).
|
||||
*/
|
||||
getFeatureByUid(uid) {
|
||||
const feature = this.uidIndex_[uid];
|
||||
return feature !== undefined ? feature : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the format associated with this source.
|
||||
*
|
||||
@@ -831,20 +844,13 @@ class VectorSource extends Source {
|
||||
const id = feature.getId();
|
||||
if (id !== undefined) {
|
||||
const sid = id.toString();
|
||||
if (featureKey in this.undefIdIndex_) {
|
||||
delete this.undefIdIndex_[featureKey];
|
||||
if (this.idIndex_[sid] !== feature) {
|
||||
this.removeFromIdIndex_(feature);
|
||||
this.idIndex_[sid] = feature;
|
||||
} else {
|
||||
if (this.idIndex_[sid] !== feature) {
|
||||
this.removeFromIdIndex_(feature);
|
||||
this.idIndex_[sid] = feature;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!(featureKey in this.undefIdIndex_)) {
|
||||
this.removeFromIdIndex_(feature);
|
||||
this.undefIdIndex_[featureKey] = feature;
|
||||
}
|
||||
this.removeFromIdIndex_(feature);
|
||||
this.uidIndex_[featureKey] = feature;
|
||||
}
|
||||
this.changed();
|
||||
this.dispatchEvent(new VectorSourceEvent(
|
||||
@@ -862,7 +868,7 @@ class VectorSource extends Source {
|
||||
if (id !== undefined) {
|
||||
return id in this.idIndex_;
|
||||
} else {
|
||||
return getUid(feature) in this.undefIdIndex_;
|
||||
return getUid(feature) in this.uidIndex_;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -964,9 +970,8 @@ class VectorSource extends Source {
|
||||
const id = feature.getId();
|
||||
if (id !== undefined) {
|
||||
delete this.idIndex_[id.toString()];
|
||||
} else {
|
||||
delete this.undefIdIndex_[featureKey];
|
||||
}
|
||||
delete this.uidIndex_[featureKey];
|
||||
this.dispatchEvent(new VectorSourceEvent(
|
||||
VectorEventType.REMOVEFEATURE, feature));
|
||||
}
|
||||
|
||||
@@ -179,99 +179,101 @@ class VectorTile extends UrlTile {
|
||||
* @return {Array<import("../VectorTile").default>} Tile keys.
|
||||
*/
|
||||
getSourceTiles(pixelRatio, projection, tile) {
|
||||
const sourceTiles = [];
|
||||
const urlTileCoord = tile.wrappedTileCoord;
|
||||
if (urlTileCoord) {
|
||||
const tileGrid = this.getTileGridForProjection(projection);
|
||||
const extent = tileGrid.getTileCoordExtent(urlTileCoord);
|
||||
const z = urlTileCoord[0];
|
||||
const resolution = tileGrid.getResolution(z);
|
||||
// make extent 1 pixel smaller so we don't load tiles for < 0.5 pixel render space
|
||||
bufferExtent(extent, -1 / resolution, extent);
|
||||
const sourceTileGrid = this.tileGrid;
|
||||
const sourceExtent = sourceTileGrid.getExtent();
|
||||
if (sourceExtent) {
|
||||
getIntersection(extent, sourceExtent, extent);
|
||||
}
|
||||
const sourceZ = sourceTileGrid.getZForResolution(resolution, 1);
|
||||
const minZoom = sourceTileGrid.getMinZoom();
|
||||
const tileGrid = this.getTileGridForProjection(projection);
|
||||
const extent = tileGrid.getTileCoordExtent(urlTileCoord);
|
||||
const z = urlTileCoord[0];
|
||||
const resolution = tileGrid.getResolution(z);
|
||||
// make extent 1 pixel smaller so we don't load tiles for < 0.5 pixel render space
|
||||
bufferExtent(extent, -1 / resolution, extent);
|
||||
const sourceTileGrid = this.tileGrid;
|
||||
const sourceExtent = sourceTileGrid.getExtent();
|
||||
if (sourceExtent) {
|
||||
getIntersection(extent, sourceExtent, extent);
|
||||
}
|
||||
const sourceZ = sourceTileGrid.getZForResolution(resolution, 1);
|
||||
const minZoom = sourceTileGrid.getMinZoom();
|
||||
|
||||
let loadedZ = sourceZ + 1;
|
||||
let covered, empty;
|
||||
do {
|
||||
--loadedZ;
|
||||
covered = true;
|
||||
empty = true;
|
||||
sourceTileGrid.forEachTileCoord(extent, loadedZ, function(sourceTileCoord) {
|
||||
const tileKey = getKey(sourceTileCoord);
|
||||
let sourceTile;
|
||||
if (tileKey in this.sourceTiles_) {
|
||||
sourceTile = this.sourceTiles_[tileKey];
|
||||
const state = sourceTile.getState();
|
||||
if (state === TileState.LOADED || state === TileState.ERROR || state === TileState.EMPTY) {
|
||||
empty = empty && state === TileState.EMPTY;
|
||||
sourceTiles.push(sourceTile);
|
||||
return;
|
||||
}
|
||||
} else if (loadedZ === sourceZ) {
|
||||
const tileUrl = this.tileUrlFunction(sourceTileCoord, pixelRatio, projection);
|
||||
sourceTile = new this.tileClass(sourceTileCoord,
|
||||
tileUrl == undefined ? TileState.EMPTY : TileState.IDLE,
|
||||
tileUrl == undefined ? '' : tileUrl,
|
||||
const previousSourceTiles = this.sourceTilesByTileKey_[getKey(tile.tileCoord)];
|
||||
if (previousSourceTiles && previousSourceTiles.length > 0 && previousSourceTiles[0].tileCoord[0] === sourceZ) {
|
||||
return previousSourceTiles;
|
||||
}
|
||||
|
||||
const sourceTiles = [];
|
||||
let loadedZ = sourceZ + 1;
|
||||
let covered, empty;
|
||||
do {
|
||||
--loadedZ;
|
||||
covered = true;
|
||||
empty = true;
|
||||
sourceTileGrid.forEachTileCoord(extent, loadedZ, function(sourceTileCoord) {
|
||||
const tileKey = getKey(sourceTileCoord);
|
||||
let sourceTile;
|
||||
if (tileKey in this.sourceTiles_) {
|
||||
sourceTile = this.sourceTiles_[tileKey];
|
||||
const state = sourceTile.getState();
|
||||
if (state === TileState.LOADED || state === TileState.ERROR || state === TileState.EMPTY) {
|
||||
empty = empty && state === TileState.EMPTY;
|
||||
sourceTiles.push(sourceTile);
|
||||
return;
|
||||
}
|
||||
} else if (loadedZ === sourceZ) {
|
||||
const tileUrl = this.tileUrlFunction(sourceTileCoord, pixelRatio, projection);
|
||||
if (tileUrl !== undefined) {
|
||||
sourceTile = new this.tileClass(sourceTileCoord, TileState.IDLE, tileUrl,
|
||||
this.format_, this.tileLoadFunction);
|
||||
sourceTile.extent = sourceTileGrid.getTileCoordExtent(sourceTileCoord);
|
||||
sourceTile.projection = projection;
|
||||
sourceTile.resolution = sourceTileGrid.getResolution(sourceTileCoord[0]);
|
||||
this.sourceTiles_[tileKey] = sourceTile;
|
||||
empty = empty && sourceTile.getState() === TileState.EMPTY;
|
||||
empty = false;
|
||||
listen(sourceTile, EventType.CHANGE, this.handleTileChange, this);
|
||||
sourceTile.load();
|
||||
} else {
|
||||
empty = false;
|
||||
}
|
||||
covered = false;
|
||||
if (!sourceTile) {
|
||||
return;
|
||||
}
|
||||
if (sourceTile.getState() !== TileState.EMPTY && tile.getState() === TileState.IDLE) {
|
||||
tile.loadingSourceTiles++;
|
||||
const key = listen(sourceTile, EventType.CHANGE, function() {
|
||||
const state = sourceTile.getState();
|
||||
const sourceTileKey = getKey(sourceTile.tileCoord);
|
||||
if (state === TileState.LOADED || state === TileState.ERROR) {
|
||||
if (state === TileState.LOADED) {
|
||||
unlistenByKey(key);
|
||||
tile.loadingSourceTiles--;
|
||||
delete tile.errorSourceTileKeys[sourceTileKey];
|
||||
} else if (state === TileState.ERROR) {
|
||||
tile.errorSourceTileKeys[sourceTileKey] = true;
|
||||
}
|
||||
if (tile.loadingSourceTiles - Object.keys(tile.errorSourceTileKeys).length === 0) {
|
||||
tile.hifi = true;
|
||||
tile.sourceZ = sourceZ;
|
||||
tile.setState(isEmpty(tile.errorSourceTileKeys) ? TileState.LOADED : TileState.ERROR);
|
||||
}
|
||||
} else {
|
||||
empty = false;
|
||||
}
|
||||
covered = false;
|
||||
if (!sourceTile) {
|
||||
return;
|
||||
}
|
||||
if (sourceTile.getState() !== TileState.EMPTY && tile.getState() === TileState.IDLE) {
|
||||
tile.loadingSourceTiles++;
|
||||
const key = listen(sourceTile, EventType.CHANGE, function() {
|
||||
const state = sourceTile.getState();
|
||||
const sourceTileKey = getKey(sourceTile.tileCoord);
|
||||
if (state === TileState.LOADED || state === TileState.ERROR) {
|
||||
if (state === TileState.LOADED) {
|
||||
unlistenByKey(key);
|
||||
tile.loadingSourceTiles--;
|
||||
delete tile.errorSourceTileKeys[sourceTileKey];
|
||||
} else if (state === TileState.ERROR) {
|
||||
tile.errorSourceTileKeys[sourceTileKey] = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}.bind(this));
|
||||
if (!covered) {
|
||||
sourceTiles.length = 0;
|
||||
if (tile.loadingSourceTiles - Object.keys(tile.errorSourceTileKeys).length === 0) {
|
||||
tile.hifi = true;
|
||||
tile.sourceZ = sourceZ;
|
||||
tile.setState(isEmpty(tile.errorSourceTileKeys) ? TileState.LOADED : TileState.ERROR);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} while (!covered && loadedZ > minZoom);
|
||||
if (!empty && tile.getState() === TileState.IDLE) {
|
||||
tile.setState(TileState.LOADING);
|
||||
}.bind(this));
|
||||
if (!covered) {
|
||||
sourceTiles.length = 0;
|
||||
}
|
||||
if (covered || empty) {
|
||||
tile.hifi = sourceZ === loadedZ;
|
||||
tile.sourceZ = loadedZ;
|
||||
const previousSourceTiles = this.sourceTilesByTileKey_[getKey(tile.tileCoord)];
|
||||
if (tile.getState() < TileState.LOADED) {
|
||||
tile.setState(empty ? TileState.EMPTY : TileState.LOADED);
|
||||
} else if (!previousSourceTiles || !equals(sourceTiles, previousSourceTiles)) {
|
||||
this.removeSourceTiles(tile);
|
||||
this.addSourceTiles(tile, sourceTiles);
|
||||
}
|
||||
} while (!covered && loadedZ > minZoom);
|
||||
if (!empty && tile.getState() === TileState.IDLE) {
|
||||
tile.setState(TileState.LOADING);
|
||||
}
|
||||
if (covered || empty) {
|
||||
tile.hifi = sourceZ === loadedZ;
|
||||
tile.sourceZ = loadedZ;
|
||||
if (tile.getState() < TileState.LOADED) {
|
||||
tile.setState(empty ? TileState.EMPTY : TileState.LOADED);
|
||||
} else if (!previousSourceTiles || !equals(sourceTiles, previousSourceTiles)) {
|
||||
this.removeSourceTiles(tile);
|
||||
this.addSourceTiles(tile, sourceTiles);
|
||||
}
|
||||
}
|
||||
return sourceTiles;
|
||||
@@ -312,26 +314,34 @@ class VectorTile extends UrlTile {
|
||||
*/
|
||||
getTile(z, x, y, pixelRatio, projection) {
|
||||
const tileCoordKey = getKeyZXY(z, x, y);
|
||||
const key = this.getKey();
|
||||
let tile;
|
||||
if (this.tileCache.containsKey(tileCoordKey)) {
|
||||
return (
|
||||
/** @type {!import("../Tile.js").default} */ (this.tileCache.get(tileCoordKey))
|
||||
);
|
||||
} else {
|
||||
const tileCoord = [z, x, y];
|
||||
const urlTileCoord = this.getTileCoordForTileUrlFunction(
|
||||
tileCoord, projection);
|
||||
const tile = new VectorRenderTile(
|
||||
tileCoord,
|
||||
urlTileCoord !== null ? TileState.IDLE : TileState.EMPTY,
|
||||
urlTileCoord,
|
||||
this.tileGrid,
|
||||
this.getSourceTiles.bind(this, pixelRatio, projection),
|
||||
this.removeSourceTiles.bind(this));
|
||||
|
||||
tile.key = this.getRevision().toString();
|
||||
this.tileCache.set(tileCoordKey, tile);
|
||||
return tile;
|
||||
tile = /** @type {!import("../Tile.js").default} */ (this.tileCache.get(tileCoordKey));
|
||||
if (tile.key === key) {
|
||||
return tile;
|
||||
}
|
||||
}
|
||||
const tileCoord = [z, x, y];
|
||||
const urlTileCoord = this.getTileCoordForTileUrlFunction(
|
||||
tileCoord, projection);
|
||||
const newTile = new VectorRenderTile(
|
||||
tileCoord,
|
||||
urlTileCoord !== null ? TileState.IDLE : TileState.EMPTY,
|
||||
urlTileCoord,
|
||||
this.tileGrid,
|
||||
this.getSourceTiles.bind(this, pixelRatio, projection),
|
||||
this.removeSourceTiles.bind(this));
|
||||
|
||||
newTile.key = key;
|
||||
if (tile) {
|
||||
newTile.interimTile = tile;
|
||||
newTile.refreshInterimChain();
|
||||
this.tileCache.replace(tileCoordKey, newTile);
|
||||
} else {
|
||||
this.tileCache.set(tileCoordKey, newTile);
|
||||
}
|
||||
return newTile;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -53,13 +53,14 @@ class CircleStyle extends RegularShape {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the circle radius.
|
||||
*
|
||||
* @param {number} radius Circle radius.
|
||||
* @api
|
||||
*/
|
||||
* Set the circle radius.
|
||||
*
|
||||
* @param {number} radius Circle radius.
|
||||
* @api
|
||||
*/
|
||||
setRadius(radius) {
|
||||
this.radius_ = radius;
|
||||
this.render();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,10 +30,10 @@ import ImageStyle from './Image.js';
|
||||
* @property {import("../colorlike.js").ColorLike} [strokeStyle]
|
||||
* @property {number} strokeWidth
|
||||
* @property {number} size
|
||||
* @property {string} lineCap
|
||||
* @property {CanvasLineCap} lineCap
|
||||
* @property {Array<number>} lineDash
|
||||
* @property {number} lineDashOffset
|
||||
* @property {string} lineJoin
|
||||
* @property {CanvasLineJoin} lineJoin
|
||||
* @property {number} miterLimit
|
||||
*/
|
||||
|
||||
@@ -142,7 +142,7 @@ class RegularShape extends ImageStyle {
|
||||
*/
|
||||
this.hitDetectionImageSize_ = null;
|
||||
|
||||
this.render_();
|
||||
this.render();
|
||||
|
||||
}
|
||||
|
||||
@@ -301,9 +301,9 @@ class RegularShape extends ImageStyle {
|
||||
/**
|
||||
* @protected
|
||||
*/
|
||||
render_() {
|
||||
let lineCap = '';
|
||||
let lineJoin = '';
|
||||
render() {
|
||||
let lineCap = defaultLineCap;
|
||||
let lineJoin = defaultLineJoin;
|
||||
let miterLimit = 0;
|
||||
let lineDash = null;
|
||||
let lineDashOffset = 0;
|
||||
@@ -338,7 +338,6 @@ class RegularShape extends ImageStyle {
|
||||
|
||||
let size = 2 * (this.radius_ + strokeWidth) + 1;
|
||||
|
||||
/** @type {RenderOptions} */
|
||||
const renderOptions = {
|
||||
strokeStyle: strokeStyle,
|
||||
strokeWidth: strokeWidth,
|
||||
@@ -418,8 +417,8 @@ class RegularShape extends ImageStyle {
|
||||
context.setLineDash(renderOptions.lineDash);
|
||||
context.lineDashOffset = renderOptions.lineDashOffset;
|
||||
}
|
||||
context.lineCap = /** @type {CanvasLineCap} */ (renderOptions.lineCap);
|
||||
context.lineJoin = /** @type {CanvasLineJoin} */ (renderOptions.lineJoin);
|
||||
context.lineCap = renderOptions.lineCap;
|
||||
context.lineJoin = renderOptions.lineJoin;
|
||||
context.miterLimit = renderOptions.miterLimit;
|
||||
context.stroke();
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
* @property {import("../color.js").Color|import("../colorlike.js").ColorLike} [color] A color, gradient or pattern.
|
||||
* See {@link module:ol/color~Color} and {@link module:ol/colorlike~ColorLike} for possible formats.
|
||||
* Default null; if null, the Canvas/renderer default black will be used.
|
||||
* @property {string} [lineCap='round'] Line cap style: `butt`, `round`, or `square`.
|
||||
* @property {string} [lineJoin='round'] Line join style: `bevel`, `round`, or `miter`.
|
||||
* @property {CanvasLineCap} [lineCap='round'] Line cap style: `butt`, `round`, or `square`.
|
||||
* @property {CanvasLineJoin} [lineJoin='round'] Line join style: `bevel`, `round`, or `miter`.
|
||||
* @property {Array<number>} [lineDash] Line dash pattern. Default is `undefined` (no dash).
|
||||
* Please note that Internet Explorer 10 and lower do not support the `setLineDash` method on
|
||||
* the `CanvasRenderingContext2D` and therefore this option will have no visual effect in these browsers.
|
||||
@@ -43,7 +43,7 @@ class Stroke {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
* @type {CanvasLineCap|undefined}
|
||||
*/
|
||||
this.lineCap_ = options.lineCap;
|
||||
|
||||
@@ -61,7 +61,7 @@ class Stroke {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string|undefined}
|
||||
* @type {CanvasLineJoin|undefined}
|
||||
*/
|
||||
this.lineJoin_ = options.lineJoin;
|
||||
|
||||
@@ -107,7 +107,7 @@ class Stroke {
|
||||
|
||||
/**
|
||||
* Get the line cap type for the stroke.
|
||||
* @return {string|undefined} Line cap.
|
||||
* @return {CanvasLineCap|undefined} Line cap.
|
||||
* @api
|
||||
*/
|
||||
getLineCap() {
|
||||
@@ -134,7 +134,7 @@ class Stroke {
|
||||
|
||||
/**
|
||||
* Get the line join type for the stroke.
|
||||
* @return {string|undefined} Line join.
|
||||
* @return {CanvasLineJoin|undefined} Line join.
|
||||
* @api
|
||||
*/
|
||||
getLineJoin() {
|
||||
@@ -172,7 +172,7 @@ class Stroke {
|
||||
/**
|
||||
* Set the line cap.
|
||||
*
|
||||
* @param {string|undefined} lineCap Line cap.
|
||||
* @param {CanvasLineCap|undefined} lineCap Line cap.
|
||||
* @api
|
||||
*/
|
||||
setLineCap(lineCap) {
|
||||
@@ -208,7 +208,7 @@ class Stroke {
|
||||
/**
|
||||
* Set the line join.
|
||||
*
|
||||
* @param {string|undefined} lineJoin Line join.
|
||||
* @param {CanvasLineJoin|undefined} lineJoin Line join.
|
||||
* @api
|
||||
*/
|
||||
setLineJoin(lineJoin) {
|
||||
|
||||
@@ -432,6 +432,31 @@ class WebGLHelper extends Disposable {
|
||||
gl.enable(gl.BLEND);
|
||||
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
gl.useProgram(this.currentProgram_);
|
||||
this.applyFrameState(frameState);
|
||||
this.applyUniforms(frameState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the render target & bind it for future draw operations.
|
||||
* This is similar to `prepareDraw`, only post processes will not be applied.
|
||||
* Note: the whole viewport will be drawn to the render target, regardless of its size.
|
||||
* @param {import("../PluggableMap.js").FrameState} frameState current frame state
|
||||
* @param {import("./RenderTarget.js").default} renderTarget Render target to draw to
|
||||
* @param {boolean} [opt_disableAlphaBlend] If true, no alpha blending will happen.
|
||||
*/
|
||||
prepareDrawToRenderTarget(frameState, renderTarget, opt_disableAlphaBlend) {
|
||||
const gl = this.getGL();
|
||||
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, renderTarget.getFramebuffer());
|
||||
gl.viewport(0, 0, frameState.size[0], frameState.size[1]);
|
||||
gl.bindTexture(gl.TEXTURE_2D, renderTarget.getTexture());
|
||||
gl.clearColor(0.0, 0.0, 0.0, 0.0);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.enable(gl.BLEND);
|
||||
gl.blendFunc(gl.ONE, opt_disableAlphaBlend ? gl.ZERO : gl.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
gl.useProgram(this.currentProgram_);
|
||||
this.applyFrameState(frameState);
|
||||
this.applyUniforms(frameState);
|
||||
}
|
||||
@@ -742,57 +767,36 @@ class WebGLHelper extends Disposable {
|
||||
// TODO: shutdown program
|
||||
|
||||
/**
|
||||
* TODO: these are not used and should be reworked
|
||||
* @param {number=} opt_wrapS wrapS.
|
||||
* @param {number=} opt_wrapT wrapT.
|
||||
* @return {WebGLTexture} The texture.
|
||||
* Will create or reuse a given webgl texture and apply the given size. If no image data
|
||||
* specified, the texture will be empty, otherwise image data will be used and the `size`
|
||||
* parameter will be ignored.
|
||||
* Note: wrap parameters are set to clamp to edge, min filter is set to linear.
|
||||
* @param {Array<number>} size Expected size of the texture
|
||||
* @param {ImageData|HTMLImageElement|HTMLCanvasElement} [opt_data] Image data/object to bind to the texture
|
||||
* @param {WebGLTexture} [opt_texture] Existing texture to reuse
|
||||
* @return {WebGLTexture} The generated texture
|
||||
* @api
|
||||
*/
|
||||
createTextureInternal(opt_wrapS, opt_wrapT) {
|
||||
createTexture(size, opt_data, opt_texture) {
|
||||
const gl = this.getGL();
|
||||
const texture = gl.createTexture();
|
||||
const texture = opt_texture || gl.createTexture();
|
||||
|
||||
// set params & size
|
||||
const level = 0;
|
||||
const internalFormat = gl.RGBA;
|
||||
const border = 0;
|
||||
const format = gl.RGBA;
|
||||
const type = gl.UNSIGNED_BYTE;
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
||||
if (opt_data) {
|
||||
gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, format, type, opt_data);
|
||||
} else {
|
||||
gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, size[0], size[1], border, format, type, null);
|
||||
}
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
|
||||
if (opt_wrapS !== undefined) {
|
||||
gl.texParameteri(
|
||||
gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, opt_wrapS);
|
||||
}
|
||||
if (opt_wrapT !== undefined) {
|
||||
gl.texParameteri(
|
||||
gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, opt_wrapT);
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: these are not used and should be reworked
|
||||
* @param {number} width Width.
|
||||
* @param {number} height Height.
|
||||
* @param {number=} opt_wrapS wrapS.
|
||||
* @param {number=} opt_wrapT wrapT.
|
||||
* @return {WebGLTexture} The texture.
|
||||
*/
|
||||
createEmptyTexture(width, height, opt_wrapS, opt_wrapT) {
|
||||
const gl = this.getGL();
|
||||
const texture = this.createTextureInternal(opt_wrapS, opt_wrapT);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
||||
return texture;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* TODO: these are not used and should be reworked
|
||||
* @param {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} image Image.
|
||||
* @param {number=} opt_wrapS wrapS.
|
||||
* @param {number=} opt_wrapT wrapT.
|
||||
* @return {WebGLTexture} The texture.
|
||||
*/
|
||||
createTexture(image, opt_wrapS, opt_wrapT) {
|
||||
const gl = this.getGL();
|
||||
const texture = this.createTextureInternal(opt_wrapS, opt_wrapT);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
|
||||
return texture;
|
||||
}
|
||||
}
|
||||
|
||||
164
src/ol/webgl/RenderTarget.js
Normal file
@@ -0,0 +1,164 @@
|
||||
/**
|
||||
* A wrapper class to simplify rendering to a texture instead of the final canvas
|
||||
* @module ol/webgl/RenderTarget
|
||||
*/
|
||||
import {equals} from '../array.js';
|
||||
|
||||
// for pixel color reading
|
||||
const tmpArray4 = new Uint8Array(4);
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* This class is a wrapper around the association of both a `WebGLTexture` and a `WebGLFramebuffer` instances,
|
||||
* simplifying initialization and binding for rendering.
|
||||
* @api
|
||||
*/
|
||||
class WebGLRenderTarget {
|
||||
|
||||
/**
|
||||
* @param {import("./Helper.js").default} helper WebGL helper; mandatory.
|
||||
* @param {Array<number>} [opt_size] Expected size of the render target texture; note: this can be changed later on.
|
||||
*/
|
||||
constructor(helper, opt_size) {
|
||||
/**
|
||||
* @private
|
||||
* @type {import("./Helper.js").default}
|
||||
*/
|
||||
this.helper_ = helper;
|
||||
const gl = helper.getGL();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {WebGLTexture}
|
||||
*/
|
||||
this.texture_ = gl.createTexture();
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {WebGLFramebuffer}
|
||||
*/
|
||||
this.framebuffer_ = gl.createFramebuffer();
|
||||
|
||||
/**
|
||||
* @type {Array<number>}
|
||||
* @private
|
||||
*/
|
||||
this.size_ = opt_size || [1, 1];
|
||||
|
||||
/**
|
||||
* @type {Uint8Array}
|
||||
* @private
|
||||
*/
|
||||
this.data_ = new Uint8Array(0);
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
this.dataCacheDirty_ = true;
|
||||
|
||||
this.updateSize_();
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the size of the render target texture. Note: will do nothing if the size
|
||||
* is already the same.
|
||||
* @param {Array<number>} size Expected size of the render target texture
|
||||
* @api
|
||||
*/
|
||||
setSize(size) {
|
||||
if (equals(size, this.size_)) {
|
||||
return;
|
||||
}
|
||||
this.size_[0] = size[0];
|
||||
this.size_[1] = size[1];
|
||||
this.updateSize_();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the render target texture
|
||||
* @return {Array<number>} Size of the render target texture
|
||||
* @api
|
||||
*/
|
||||
getSize() {
|
||||
return this.size_;
|
||||
}
|
||||
|
||||
/**
|
||||
* This will cause following calls to `#readAll` or `#readPixel` to download the content of the
|
||||
* render target into memory, which is an expensive operation.
|
||||
* This content will be kept in cache but should be cleared after each new render.
|
||||
* @api
|
||||
*/
|
||||
clearCachedData() {
|
||||
this.dataCacheDirty_ = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full content of the frame buffer as a series of r, g, b, a components
|
||||
* in the 0-255 range (unsigned byte).
|
||||
* @return {Uint8Array} Integer array of color values
|
||||
* @api
|
||||
*/
|
||||
readAll() {
|
||||
if (this.dataCacheDirty_) {
|
||||
const size = this.size_;
|
||||
const gl = this.helper_.getGL();
|
||||
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer_);
|
||||
gl.readPixels(0, 0, size[0], size[1], gl.RGBA, gl.UNSIGNED_BYTE, this.data_);
|
||||
this.dataCacheDirty_ = false;
|
||||
}
|
||||
return this.data_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads one pixel of the frame buffer as an array of r, g, b, a components
|
||||
* in the 0-255 range (unsigned byte).
|
||||
* @param {number} x Pixel coordinate
|
||||
* @param {number} y Pixel coordinate
|
||||
* @returns {Uint8Array} Integer array with one color value (4 components)
|
||||
* @api
|
||||
*/
|
||||
readPixel(x, y) {
|
||||
this.readAll();
|
||||
const index = Math.floor(x) + (this.size_[1] - Math.floor(y) - 1) * this.size_[0];
|
||||
tmpArray4[0] = this.data_[index * 4];
|
||||
tmpArray4[1] = this.data_[index * 4 + 1];
|
||||
tmpArray4[2] = this.data_[index * 4 + 2];
|
||||
tmpArray4[3] = this.data_[index * 4 + 3];
|
||||
return tmpArray4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {WebGLTexture} Texture to render to
|
||||
*/
|
||||
getTexture() {
|
||||
return this.texture_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {WebGLFramebuffer} Frame buffer of the render target
|
||||
*/
|
||||
getFramebuffer() {
|
||||
return this.framebuffer_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
updateSize_() {
|
||||
const size = this.size_;
|
||||
const gl = this.helper_.getGL();
|
||||
|
||||
this.texture_ = this.helper_.createTexture(size, null, this.texture_);
|
||||
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer_);
|
||||
gl.viewport(0, 0, size[0], size[1]);
|
||||
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture_, 0);
|
||||
|
||||
this.data_ = new Uint8Array(size[0] * size[1] * 4);
|
||||
}
|
||||
}
|
||||
|
||||
export default WebGLRenderTarget;
|
||||
@@ -1,48 +0,0 @@
|
||||
/**
|
||||
* @module ol/webgl/Shader
|
||||
*/
|
||||
import {abstract} from '../util.js';
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
*/
|
||||
class WebGLShader {
|
||||
|
||||
/**
|
||||
* @param {string} source Source.
|
||||
*/
|
||||
constructor(source) {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
this.source_ = source;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {boolean} Is animated?
|
||||
*/
|
||||
isAnimated() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @abstract
|
||||
* @return {number} Type.
|
||||
*/
|
||||
getType() {
|
||||
return abstract();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string} Source.
|
||||
*/
|
||||
getSource() {
|
||||
return this.source_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default WebGLShader;
|
||||
|
Before Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.4 KiB |
@@ -1,60 +0,0 @@
|
||||
import {listen} from '../../../../src/ol/events.js';
|
||||
import {get as getProjection} from '../../../../src/ol/proj.js';
|
||||
import {HALF_SIZE} from '../../../../src/ol/proj/epsg3857.js';
|
||||
import ReprojImage from '../../../../src/ol/reproj/Image.js';
|
||||
import Static from '../../../../src/ol/source/ImageStatic.js';
|
||||
import {createXYZ, createForProjection} from '../../../../src/ol/tilegrid.js';
|
||||
|
||||
|
||||
describe('ol.rendering.reproj.Image', function() {
|
||||
|
||||
function testSingleImage(source, targetProj,
|
||||
targetExtent, targetResolution, pixelRatio, expectedUrl, done) {
|
||||
const sourceProj = source.getProjection();
|
||||
|
||||
let imagesRequested = 0;
|
||||
|
||||
const image = new ReprojImage(sourceProj, getProjection(targetProj),
|
||||
targetExtent, targetResolution, pixelRatio,
|
||||
function(extent, resolution, pixelRatio) {
|
||||
imagesRequested++;
|
||||
return source.getImage(extent, resolution, pixelRatio, sourceProj);
|
||||
});
|
||||
if (image.getState() == 0) { // IDLE
|
||||
listen(image, 'change', function(e) {
|
||||
if (image.getState() == 2) { // LOADED
|
||||
expect(imagesRequested).to.be(1);
|
||||
resembleCanvas(image.getImage(), expectedUrl, IMAGE_TOLERANCE, done);
|
||||
}
|
||||
});
|
||||
image.load();
|
||||
}
|
||||
}
|
||||
|
||||
let source;
|
||||
|
||||
describe('image reprojections from EPSG:3857', function() {
|
||||
beforeEach(function() {
|
||||
source = new Static({
|
||||
url: 'rendering/ol/data/tiles/osm/5/5/12.png',
|
||||
imageExtent: createXYZ().getTileCoordExtent([5, 5, -13]),
|
||||
projection: getProjection('EPSG:3857')
|
||||
});
|
||||
});
|
||||
|
||||
it('works for identity reprojection', function(done) {
|
||||
testSingleImage(source, 'EPSG:3857',
|
||||
createXYZ().getTileCoordExtent([5, 5, -13]),
|
||||
2 * HALF_SIZE / (256 * (1 << 5)), 1,
|
||||
'rendering/ol/data/tiles/osm/5/5/12.png', done);
|
||||
});
|
||||
|
||||
it('to EPSG:4326', function(done) {
|
||||
testSingleImage(source, 'EPSG:4326',
|
||||
createForProjection('EPSG:4326').
|
||||
getTileCoordExtent([6, 10, -10]),
|
||||
360 / (256 * (1 << 4)), 1,
|
||||
'rendering/ol/reproj/expected/image-3857-to-4326.png', done);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,186 +0,0 @@
|
||||
import TileState from '../../../../src/ol/TileState.js';
|
||||
import {listen} from '../../../../src/ol/events.js';
|
||||
import {get as getProjection} from '../../../../src/ol/proj.js';
|
||||
import ReprojTile from '../../../../src/ol/reproj/Tile.js';
|
||||
import XYZ from '../../../../src/ol/source/XYZ.js';
|
||||
import {createForProjection} from '../../../../src/ol/tilegrid.js';
|
||||
import {register} from '../../../../src/ol/proj/proj4.js';
|
||||
|
||||
|
||||
describe('ol.rendering.reproj.Tile', function() {
|
||||
|
||||
function testSingleTile(source, targetProjection, targetTileGrid, z, x, y,
|
||||
pixelRatio, expectedUrl, expectedRequests, done) {
|
||||
const sourceProjection = source.getProjection();
|
||||
const sourceGutter = source.getGutterForProjection(sourceProjection);
|
||||
|
||||
let tilesRequested = 0;
|
||||
|
||||
const tile = new ReprojTile(sourceProjection, source.getTileGrid(),
|
||||
getProjection(targetProjection), targetTileGrid,
|
||||
[z, x, y], null, pixelRatio, sourceGutter,
|
||||
function(z, x, y, pixelRatio) {
|
||||
tilesRequested++;
|
||||
return source.getTile(z, x, y, pixelRatio, sourceProjection);
|
||||
});
|
||||
if (tile.getState() == TileState.IDLE) {
|
||||
listen(tile, 'change', function(e) {
|
||||
if (tile.getState() == TileState.LOADED) {
|
||||
expect(tilesRequested).to.be(expectedRequests);
|
||||
resembleCanvas(tile.getImage(), expectedUrl, 7.5, done);
|
||||
}
|
||||
});
|
||||
tile.load();
|
||||
}
|
||||
}
|
||||
|
||||
let source;
|
||||
|
||||
describe('single tile reprojections from EPSG:3857', function() {
|
||||
beforeEach(function() {
|
||||
source = new XYZ({
|
||||
projection: 'EPSG:3857',
|
||||
url: 'rendering/ol/data/tiles/osm/{z}/{x}/{y}.png'
|
||||
});
|
||||
});
|
||||
|
||||
it('works for identity reprojection', function(done) {
|
||||
testSingleTile(source, 'EPSG:3857', source.getTileGrid(), 5, 5, -13, 1,
|
||||
'rendering/ol/data/tiles/osm/5/5/12.png', 1, done);
|
||||
});
|
||||
|
||||
it('to EPSG:4326', function(done) {
|
||||
const tileGrid = createForProjection('EPSG:4326', 7, [64, 64]);
|
||||
testSingleTile(source, 'EPSG:4326', tileGrid, 7, 21, -20, 1,
|
||||
'rendering/ol/reproj/expected/osm4326.png', 1, done);
|
||||
});
|
||||
|
||||
it('to EPSG:5070', function(done) {
|
||||
proj4.defs('EPSG:5070',
|
||||
'+proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=23 +lon_0=-96 +x_0=0 ' +
|
||||
'+y_0=0 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs');
|
||||
register(proj4);
|
||||
const proj5070 = getProjection('EPSG:5070');
|
||||
proj5070.setExtent([-6e6, 0, 4e6, 6e6]);
|
||||
|
||||
const tileGrid = createForProjection('EPSG:5070', 5, [64, 64]);
|
||||
testSingleTile(source, 'EPSG:5070', tileGrid, 5, 13, -15, 1,
|
||||
'rendering/ol/reproj/expected/osm5070.png', 1, done);
|
||||
});
|
||||
|
||||
it('to ESRI:54009', function(done) {
|
||||
proj4.defs('ESRI:54009',
|
||||
'+proj=moll +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs');
|
||||
register(proj4);
|
||||
const proj54009 = getProjection('ESRI:54009');
|
||||
proj54009.setExtent([-18e6, -9e6, 18e6, 9e6]);
|
||||
|
||||
const tileGrid = createForProjection('ESRI:54009', 7, [64, 64]);
|
||||
testSingleTile(source, 'ESRI:54009', tileGrid, 7, 27, -16, 1,
|
||||
'rendering/ol/reproj/expected/osm54009.png', 1, done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('stitching several tiles from EPSG:3857', function() {
|
||||
beforeEach(function() {
|
||||
source = new XYZ({
|
||||
projection: 'EPSG:3857',
|
||||
url: 'rendering/ol/data/tiles/osm/{z}/{x}/{y}.png'
|
||||
});
|
||||
});
|
||||
|
||||
it('to EPSG:4326', function(done) {
|
||||
const tileGrid = createForProjection('EPSG:4326', 7, [64, 64]);
|
||||
testSingleTile(source, 'EPSG:4326', tileGrid, 7, 23, -21, 1,
|
||||
'rendering/ol/reproj/expected/stitch-osm4326.png', 2, done);
|
||||
});
|
||||
|
||||
it('to EPSG:3740', function(done) {
|
||||
proj4.defs('EPSG:3740',
|
||||
'+proj=utm +zone=10 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 ' +
|
||||
'+units=m +no_defs');
|
||||
register(proj4);
|
||||
const proj3740 = getProjection('EPSG:3740');
|
||||
proj3740.setExtent([318499.05, 2700792.39, 4359164.89, 7149336.98]);
|
||||
|
||||
const tileGrid = createForProjection('EPSG:3740', 4, [64, 64]);
|
||||
testSingleTile(source, 'EPSG:3740', tileGrid, 4, 4, -13, 1,
|
||||
'rendering/ol/reproj/expected/stitch-osm3740.png', 4, done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('tile projection from EPSG:4326', function() {
|
||||
beforeEach(function() {
|
||||
source = new XYZ({
|
||||
projection: 'EPSG:4326',
|
||||
maxZoom: 0,
|
||||
url: 'rendering/ol/data/tiles/4326/{z}/{x}/{y}.png'
|
||||
});
|
||||
});
|
||||
|
||||
it('works for identity reprojection', function(done) {
|
||||
testSingleTile(source, 'EPSG:4326', source.getTileGrid(), 0, 0, -1, 1,
|
||||
'rendering/ol/data/tiles/4326/0/0/0.png', 1, done);
|
||||
});
|
||||
|
||||
it('to EPSG:3857', function(done) {
|
||||
const tileGrid = createForProjection('EPSG:3857', 0, [64, 64]);
|
||||
testSingleTile(source, 'EPSG:3857', tileGrid, 0, 0, -1, 1,
|
||||
'rendering/ol/reproj/expected/4326-to-3857.png', 1, done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('non-square source tiles', function() {
|
||||
beforeEach(function() {
|
||||
source = new XYZ({
|
||||
projection: 'EPSG:3857',
|
||||
url: 'rendering/ol/data/tiles/osm-512x256/{z}/{x}/{y}.png',
|
||||
tileSize: [512, 256]
|
||||
});
|
||||
});
|
||||
|
||||
it('works for identity reprojection', function(done) {
|
||||
testSingleTile(source, 'EPSG:3857', source.getTileGrid(), 5, 3, -13, 1,
|
||||
'rendering/ol/data/tiles/osm-512x256/5/3/12.png', 1, done);
|
||||
});
|
||||
|
||||
it('to 64x128 EPSG:4326', function(done) {
|
||||
const tileGrid = createForProjection('EPSG:4326', 7, [64, 128]);
|
||||
testSingleTile(source, 'EPSG:4326', tileGrid, 7, 27, -10, 1,
|
||||
'rendering/ol/reproj/expected/512x256-to-64x128.png', 1, done);
|
||||
});
|
||||
});
|
||||
|
||||
describe('dateline wrapping', function() {
|
||||
beforeEach(function() {
|
||||
source = new XYZ({
|
||||
projection: 'EPSG:4326',
|
||||
maxZoom: 0,
|
||||
url: 'rendering/ol/data/tiles/4326/{z}/{x}/{y}.png'
|
||||
});
|
||||
});
|
||||
|
||||
it('wraps X when prime meridian is shifted', function(done) {
|
||||
proj4.defs('merc_180', '+proj=merc +lon_0=180 +units=m +no_defs');
|
||||
register(proj4);
|
||||
const proj_ = getProjection('merc_180');
|
||||
proj_.setExtent([-20026376.39, -20048966.10, 20026376.39, 20048966.10]);
|
||||
|
||||
const tileGrid = createForProjection('merc_180', 0, [64, 64]);
|
||||
testSingleTile(source, 'merc_180', tileGrid, 0, 0, -1, 1,
|
||||
'rendering/ol/reproj/expected/dateline-merc-180.png', 2, done);
|
||||
});
|
||||
|
||||
it('displays north pole correctly (EPSG:3413)', function(done) {
|
||||
proj4.defs('EPSG:3413', '+proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 ' +
|
||||
'+k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs');
|
||||
register(proj4);
|
||||
const proj3413 = getProjection('EPSG:3413');
|
||||
proj3413.setExtent([-4194304, -4194304, 4194304, 4194304]);
|
||||
|
||||
const tileGrid = createForProjection('EPSG:3413', 0, [64, 64]);
|
||||
testSingleTile(source, 'EPSG:3413', tileGrid, 0, 0, -1, 1,
|
||||
'rendering/ol/reproj/expected/dateline-pole.png', 2, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,44 +1,56 @@
|
||||
import {getFontFamilies} from '../../../src/ol/css.js';
|
||||
import {getFontParameters} from '../../../src/ol/css.js';
|
||||
|
||||
describe('ol.css', function() {
|
||||
|
||||
describe('getFontFamilies()', function() {
|
||||
describe('getFontParameters()', function() {
|
||||
const cases = [{
|
||||
font: '2em "Open Sans"',
|
||||
style: 'normal',
|
||||
weight: 'normal',
|
||||
families: ['"Open Sans"']
|
||||
}, {
|
||||
font: '2em \'Open Sans\'',
|
||||
style: 'normal',
|
||||
weight: 'normal',
|
||||
families: ['"Open Sans"']
|
||||
}, {
|
||||
font: '2em "Open Sans", sans-serif',
|
||||
style: 'normal',
|
||||
weight: 'normal',
|
||||
families: ['"Open Sans"', 'sans-serif']
|
||||
}, {
|
||||
font: 'italic small-caps bolder 16px/3 cursive',
|
||||
style: 'italic',
|
||||
weight: 'bolder',
|
||||
families: ['cursive']
|
||||
}, {
|
||||
font: 'garbage 2px input',
|
||||
families: null
|
||||
}, {
|
||||
font: '100% fantasy',
|
||||
style: 'normal',
|
||||
weight: 'normal',
|
||||
families: ['fantasy']
|
||||
}];
|
||||
|
||||
cases.forEach(function(c, i) {
|
||||
it('works for ' + c.font, function() {
|
||||
const families = getFontFamilies(c.font);
|
||||
const font = getFontParameters(c.font);
|
||||
if (c.families === null) {
|
||||
expect(families).to.be(null);
|
||||
expect(font).to.be(null);
|
||||
return;
|
||||
}
|
||||
families.forEach(function(family, j) {
|
||||
font.families.forEach(function(family, j) {
|
||||
// Safari uses single quotes for font families, so we have to do extra work
|
||||
if (family.charAt(0) === '\'') {
|
||||
// we wouldn't want to do this in the lib since it doesn't properly escape quotes
|
||||
// but we know that our test cases don't include quotes in font names
|
||||
families[j] = '"' + family.slice(1, -1) + '"';
|
||||
font.families[j] = '"' + family.slice(1, -1) + '"';
|
||||
}
|
||||
});
|
||||
expect(families).to.eql(c.families);
|
||||
expect(font.style).to.eql(c.style);
|
||||
expect(font.weight).to.eql(c.weight);
|
||||
expect(font.families).to.eql(c.families);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -712,6 +712,23 @@ describe('ol.format.EsriJSON', function() {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should not mutate input', function() {
|
||||
const input = {
|
||||
rings: [
|
||||
[[0, 1, 0, 1], [1, 4, 0, 1], [4, 3, 0, 1], [3, 0, 0, 1]],
|
||||
[[2, 2, 0, 1], [3, 2, 0, 1], [3, 3, 0, 1], [2, 3, 0, 1]],
|
||||
[[10, 1, 0, 1], [11, 5, 0, 1], [14, 3, 0, 1], [13, 0, 0, 1]]
|
||||
],
|
||||
hasZ: true,
|
||||
hasM: true
|
||||
};
|
||||
const str = JSON.stringify(input);
|
||||
const obj = format.readGeometry(input);
|
||||
|
||||
expect(obj).to.be.a(MultiPolygon);
|
||||
expect(str).to.eql(JSON.stringify(input));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#readProjection', function() {
|
||||
|
||||
@@ -219,7 +219,40 @@ describe('ol.format.IIIFInfo', function() {
|
||||
expect(level.supports).to.contain('sizeByDistortedWh');
|
||||
expect(level.supports).to.contain('sizeByWh');
|
||||
|
||||
// TODO test version 3 compliance level features once version 3 is final
|
||||
iiifInfo.setImageInfo({
|
||||
'@context': 'http://iiif.io/api/image/3/context.json',
|
||||
profile: 'level0'
|
||||
});
|
||||
level = iiifInfo.getComplianceLevelSupportedFeatures();
|
||||
expect(level.supports).to.be.empty();
|
||||
|
||||
iiifInfo.setImageInfo({
|
||||
'@context': 'http://iiif.io/api/image/3/context.json',
|
||||
profile: 'level1'
|
||||
});
|
||||
level = iiifInfo.getComplianceLevelSupportedFeatures();
|
||||
expect(level.supports).to.have.length(5);
|
||||
expect(level.supports).to.contain('regionByPx');
|
||||
expect(level.supports).to.contain('regionSquare');
|
||||
expect(level.supports).to.contain('sizeByW');
|
||||
expect(level.supports).to.contain('sizeByH');
|
||||
expect(level.supports).to.contain('sizeByWh');
|
||||
|
||||
iiifInfo.setImageInfo({
|
||||
'@context': 'http://iiif.io/api/image/3/context.json',
|
||||
profile: 'level2'
|
||||
});
|
||||
level = iiifInfo.getComplianceLevelSupportedFeatures();
|
||||
expect(level.supports).to.have.length(8);
|
||||
expect(level.supports).to.contain('regionByPx');
|
||||
expect(level.supports).to.contain('regionByPct');
|
||||
expect(level.supports).to.contain('regionSquare');
|
||||
expect(level.supports).to.contain('sizeByW');
|
||||
expect(level.supports).to.contain('sizeByH');
|
||||
expect(level.supports).to.contain('sizeByWh');
|
||||
expect(level.supports).to.contain('sizeByConfinedWh');
|
||||
expect(level.supports).to.contain('sizeByPct');
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -290,7 +323,22 @@ describe('ol.format.IIIFInfo', function() {
|
||||
height: 1500,
|
||||
profile: ['http://iiif.io/api/image/2/level2.json']
|
||||
});
|
||||
const options = iiifInfo.getTileSourceOptions({
|
||||
let options = iiifInfo.getTileSourceOptions({
|
||||
quality: 'bitonal',
|
||||
format: 'png'
|
||||
});
|
||||
expect(options).to.have.property('quality', 'bitonal');
|
||||
expect(options).to.have.property('format', 'png');
|
||||
|
||||
iiifInfo.setImageInfo({
|
||||
'@context': 'http://iiif.io/api/image/3/context.json',
|
||||
'@id': 'http://iiif.test/version3/id',
|
||||
width: 2000,
|
||||
height: 1500,
|
||||
profile: 'level2',
|
||||
extraQualities: ['gray', 'bitonal']
|
||||
});
|
||||
options = iiifInfo.getTileSourceOptions({
|
||||
quality: 'bitonal',
|
||||
format: 'png'
|
||||
});
|
||||
@@ -308,7 +356,21 @@ describe('ol.format.IIIFInfo', function() {
|
||||
height: 1500,
|
||||
profile: ['http://iiif.io/api/image/2/level1.json']
|
||||
});
|
||||
const options = iiifInfo.getTileSourceOptions({
|
||||
let options = iiifInfo.getTileSourceOptions({
|
||||
quality: 'bitonal',
|
||||
format: 'png'
|
||||
});
|
||||
expect(options).to.have.property('quality', 'default');
|
||||
expect(options).to.have.property('format', 'jpg');
|
||||
|
||||
iiifInfo.setImageInfo({
|
||||
'@context': 'http://iiif.io/api/image/3/context.json',
|
||||
'@id': 'http://iiif.test/version3/id',
|
||||
width: 2000,
|
||||
height: 1500,
|
||||
profile: 'level1'
|
||||
});
|
||||
options = iiifInfo.getTileSourceOptions({
|
||||
quality: 'bitonal',
|
||||
format: 'png'
|
||||
});
|
||||
@@ -350,7 +412,8 @@ describe('ol.format.IIIFInfo', function() {
|
||||
expect(options.supports).to.contain('regionSquare');
|
||||
expect(options.supports).to.contain('sizeByW');
|
||||
expect(options.supports).to.contain('sizeByH');
|
||||
expect(options.supports).to.have.length(6);
|
||||
expect(options.supports).to.contain('sizeByWh');
|
||||
expect(options.supports).to.have.length(7);
|
||||
|
||||
});
|
||||
|
||||
@@ -448,6 +511,26 @@ describe('ol.format.IIIFInfo', function() {
|
||||
expect(options.tileSize[0]).to.be(512);
|
||||
expect(options.tileSize[1]).to.be(1024);
|
||||
|
||||
iiifInfo.setImageInfo({
|
||||
'@context': 'http://iiif.io/api/image/3/context.json',
|
||||
'@id': 'http://iiif.test/id',
|
||||
profile: 'level0',
|
||||
tiles: [{
|
||||
scaleFactors: [1, 2, 4, 8],
|
||||
width: 512,
|
||||
height: 256
|
||||
}]
|
||||
});
|
||||
options = iiifInfo.getTileSourceOptions();
|
||||
expect(options.resolutions).to.have.length(4);
|
||||
expect(options.resolutions).to.contain(1);
|
||||
expect(options.resolutions).to.contain(2);
|
||||
expect(options.resolutions).to.contain(4);
|
||||
expect(options.resolutions).to.contain(8);
|
||||
expect(options.tileSize).to.have.length(2);
|
||||
expect(options.tileSize[0]).to.be(512);
|
||||
expect(options.tileSize[1]).to.be(256);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -470,7 +553,7 @@ describe('ol.format.IIIFInfo', function() {
|
||||
height: 250
|
||||
}]
|
||||
});
|
||||
const options = iiifInfo.getTileSourceOptions();
|
||||
let options = iiifInfo.getTileSourceOptions();
|
||||
expect(options.sizes).to.have.length(3);
|
||||
expect(options.sizes[0]).to.have.length(2);
|
||||
expect(options.sizes[0][0]).to.be(2000);
|
||||
@@ -482,6 +565,62 @@ describe('ol.format.IIIFInfo', function() {
|
||||
expect(options.sizes[2][0]).to.be(500);
|
||||
expect(options.sizes[2][1]).to.be(250);
|
||||
|
||||
iiifInfo.setImageInfo({
|
||||
'@context': 'http://iiif.io/api/image/3/context.json',
|
||||
'@id': 'http://iiif.test/id',
|
||||
'sizes': [{
|
||||
width: 1500,
|
||||
height: 800
|
||||
}]
|
||||
});
|
||||
options = iiifInfo.getTileSourceOptions();
|
||||
expect(options.sizes).to.have.length(1);
|
||||
expect(options.sizes[0]).to.have.length(2);
|
||||
expect(options.sizes[0][0]).to.be(1500);
|
||||
expect(options.sizes[0][1]).to.be(800);
|
||||
|
||||
});
|
||||
|
||||
it('respects the preferred image formats', function() {
|
||||
|
||||
iiifInfo.setImageInfo({
|
||||
'@context': 'http://iiif.io/api/image/3/context.json',
|
||||
'id': 'http://iiif.test/id',
|
||||
'profile': 'level0',
|
||||
'preferredFormats': ['png', 'gif']
|
||||
});
|
||||
let options = iiifInfo.getTileSourceOptions();
|
||||
expect(options.format).to.be('jpg');
|
||||
|
||||
iiifInfo.setImageInfo({
|
||||
'@context': 'http://iiif.io/api/image/3/context.json',
|
||||
'id': 'http://iiif.test/id',
|
||||
'profile': 'level1',
|
||||
'preferredFormats': ['png', 'gif']
|
||||
});
|
||||
options = iiifInfo.getTileSourceOptions();
|
||||
expect(options.format).to.be('jpg');
|
||||
|
||||
iiifInfo.setImageInfo({
|
||||
'@context': 'http://iiif.io/api/image/3/context.json',
|
||||
'id': 'http://iiif.test/id',
|
||||
'profile': 'level1',
|
||||
'extraFormats': ['webp', 'gif'],
|
||||
'preferredFormats': ['webp', 'png', 'gif']
|
||||
});
|
||||
options = iiifInfo.getTileSourceOptions();
|
||||
expect(options.format).to.be('gif');
|
||||
|
||||
iiifInfo.setImageInfo({
|
||||
'@context': 'http://iiif.io/api/image/3/context.json',
|
||||
'id': 'http://iiif.test/id',
|
||||
'profile': 'level2',
|
||||
'preferredFormats': ['png', 'gif']
|
||||
});
|
||||
options = iiifInfo.getTileSourceOptions();
|
||||
expect(options.format).to.be('png');
|
||||
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
@@ -21,6 +21,17 @@ describe('HTML Image loading', function() {
|
||||
}, 200);
|
||||
});
|
||||
|
||||
it('handles load event when src is set later', function(done) {
|
||||
listenImage(img, handleLoad, handleError);
|
||||
img.src = 'spec/ol/data/dot.png';
|
||||
|
||||
setTimeout(function() {
|
||||
expect(handleLoad).to.be.called();
|
||||
expect(handleError).not.to.be.called();
|
||||
done();
|
||||
}, 200);
|
||||
});
|
||||
|
||||
it('handles error event', function(done) {
|
||||
img.src = 'invalid.jpeg';
|
||||
listenImage(img, handleLoad, handleError);
|
||||
|
||||
@@ -44,7 +44,9 @@ describe('ol.layer.Group', function() {
|
||||
extent: undefined,
|
||||
zIndex: 0,
|
||||
maxResolution: Infinity,
|
||||
minResolution: 0
|
||||
minResolution: 0,
|
||||
minZoom: -Infinity,
|
||||
maxZoom: Infinity
|
||||
});
|
||||
});
|
||||
|
||||
@@ -147,13 +149,17 @@ describe('ol.layer.Group', function() {
|
||||
visible: false,
|
||||
zIndex: 10,
|
||||
maxResolution: 500,
|
||||
minResolution: 0.25
|
||||
minResolution: 0.25,
|
||||
minZoom: 1,
|
||||
maxZoom: 10
|
||||
});
|
||||
|
||||
expect(layerGroup.getOpacity()).to.be(0.5);
|
||||
expect(layerGroup.getVisible()).to.be(false);
|
||||
expect(layerGroup.getMaxResolution()).to.be(500);
|
||||
expect(layerGroup.getMinResolution()).to.be(0.25);
|
||||
expect(layerGroup.getMinZoom()).to.be(1);
|
||||
expect(layerGroup.getMaxZoom()).to.be(10);
|
||||
expect(layerGroup.getLayerState()).to.eql({
|
||||
layer: layerGroup,
|
||||
opacity: 0.5,
|
||||
@@ -164,7 +170,9 @@ describe('ol.layer.Group', function() {
|
||||
extent: undefined,
|
||||
zIndex: 10,
|
||||
maxResolution: 500,
|
||||
minResolution: 0.25
|
||||
minResolution: 0.25,
|
||||
minZoom: 1,
|
||||
maxZoom: 10
|
||||
});
|
||||
expect(layerGroup.getLayers()).to.be.a(Collection);
|
||||
expect(layerGroup.getLayers().getLength()).to.be(1);
|
||||
@@ -206,7 +214,9 @@ describe('ol.layer.Group', function() {
|
||||
extent: groupExtent,
|
||||
zIndex: 0,
|
||||
maxResolution: 500,
|
||||
minResolution: 0.25
|
||||
minResolution: 0.25,
|
||||
minZoom: -Infinity,
|
||||
maxZoom: Infinity
|
||||
});
|
||||
expect(layerGroup.getLayers()).to.be.a(Collection);
|
||||
expect(layerGroup.getLayers().getLength()).to.be(1);
|
||||
@@ -237,6 +247,8 @@ describe('ol.layer.Group', function() {
|
||||
layerGroup.setExtent(groupExtent);
|
||||
layerGroup.setMaxResolution(500);
|
||||
layerGroup.setMinResolution(0.25);
|
||||
layerGroup.setMinZoom(5);
|
||||
layerGroup.setMaxZoom(10);
|
||||
expect(layerGroup.getLayerState()).to.eql({
|
||||
layer: layerGroup,
|
||||
opacity: 0.3,
|
||||
@@ -247,7 +259,9 @@ describe('ol.layer.Group', function() {
|
||||
extent: groupExtent,
|
||||
zIndex: 10,
|
||||
maxResolution: 500,
|
||||
minResolution: 0.25
|
||||
minResolution: 0.25,
|
||||
minZoom: 5,
|
||||
maxZoom: 10
|
||||
});
|
||||
});
|
||||
|
||||
@@ -264,7 +278,9 @@ describe('ol.layer.Group', function() {
|
||||
extent: undefined,
|
||||
zIndex: 0,
|
||||
maxResolution: Infinity,
|
||||
minResolution: 0
|
||||
minResolution: 0,
|
||||
minZoom: -Infinity,
|
||||
maxZoom: Infinity
|
||||
});
|
||||
|
||||
layerGroup.setOpacity(3);
|
||||
@@ -279,7 +295,9 @@ describe('ol.layer.Group', function() {
|
||||
extent: undefined,
|
||||
zIndex: 0,
|
||||
maxResolution: Infinity,
|
||||
minResolution: 0
|
||||
minResolution: 0,
|
||||
minZoom: -Infinity,
|
||||
maxZoom: Infinity
|
||||
});
|
||||
});
|
||||
|
||||
@@ -452,12 +470,58 @@ describe('ol.layer.Group', function() {
|
||||
extent: undefined,
|
||||
zIndex: 0,
|
||||
maxResolution: 150,
|
||||
minResolution: 0.25
|
||||
minResolution: 0.25,
|
||||
minZoom: -Infinity,
|
||||
maxZoom: Infinity
|
||||
});
|
||||
|
||||
layerGroup.dispose();
|
||||
});
|
||||
|
||||
it('returns max minZoom', function() {
|
||||
const group = new LayerGroup({
|
||||
minZoom: 5,
|
||||
layers: [
|
||||
new Layer({
|
||||
source: new Source({
|
||||
projection: 'EPSG:4326'
|
||||
})
|
||||
}),
|
||||
new Layer({
|
||||
source: new Source({
|
||||
projection: 'EPSG:4326'
|
||||
}),
|
||||
minZoom: 10
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
expect(group.getLayerStatesArray()[0].minZoom).to.be(5);
|
||||
expect(group.getLayerStatesArray()[1].minZoom).to.be(10);
|
||||
});
|
||||
|
||||
it('returns min maxZoom of layers', function() {
|
||||
const group = new LayerGroup({
|
||||
maxZoom: 5,
|
||||
layers: [
|
||||
new Layer({
|
||||
source: new Source({
|
||||
projection: 'EPSG:4326'
|
||||
})
|
||||
}),
|
||||
new Layer({
|
||||
source: new Source({
|
||||
projection: 'EPSG:4326'
|
||||
}),
|
||||
maxZoom: 2
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
expect(group.getLayerStatesArray()[0].maxZoom).to.be(5);
|
||||
expect(group.getLayerStatesArray()[1].maxZoom).to.be(2);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Map from '../../../../src/ol/Map.js';
|
||||
import Layer, {visibleAtResolution} from '../../../../src/ol/layer/Layer.js';
|
||||
import Layer, {inView} from '../../../../src/ol/layer/Layer.js';
|
||||
import {get as getProjection} from '../../../../src/ol/proj.js';
|
||||
import RenderEvent from '../../../../src/ol/render/Event.js';
|
||||
import Source from '../../../../src/ol/source/Source.js';
|
||||
@@ -43,6 +43,14 @@ describe('ol.layer.Layer', function() {
|
||||
expect(layer.getMinResolution()).to.be(0);
|
||||
});
|
||||
|
||||
it('provides default min zoom', function() {
|
||||
expect(layer.getMinZoom()).to.be(-Infinity);
|
||||
});
|
||||
|
||||
it('provides default max zoom', function() {
|
||||
expect(layer.getMaxZoom()).to.be(Infinity);
|
||||
});
|
||||
|
||||
it('provides default layerState', function() {
|
||||
expect(layer.getLayerState()).to.eql({
|
||||
layer: layer,
|
||||
@@ -54,7 +62,9 @@ describe('ol.layer.Layer', function() {
|
||||
extent: undefined,
|
||||
zIndex: 0,
|
||||
maxResolution: Infinity,
|
||||
minResolution: 0
|
||||
minResolution: 0,
|
||||
minZoom: -Infinity,
|
||||
maxZoom: Infinity
|
||||
});
|
||||
});
|
||||
|
||||
@@ -72,6 +82,8 @@ describe('ol.layer.Layer', function() {
|
||||
zIndex: 10,
|
||||
maxResolution: 500,
|
||||
minResolution: 0.25,
|
||||
minZoom: 1,
|
||||
maxZoom: 10,
|
||||
foo: 42
|
||||
});
|
||||
|
||||
@@ -79,6 +91,8 @@ describe('ol.layer.Layer', function() {
|
||||
expect(layer.getVisible()).to.be(false);
|
||||
expect(layer.getMaxResolution()).to.be(500);
|
||||
expect(layer.getMinResolution()).to.be(0.25);
|
||||
expect(layer.getMinZoom()).to.be(1);
|
||||
expect(layer.getMaxZoom()).to.be(10);
|
||||
expect(layer.get('foo')).to.be(42);
|
||||
expect(layer.getLayerState()).to.eql({
|
||||
layer: layer,
|
||||
@@ -90,7 +104,9 @@ describe('ol.layer.Layer', function() {
|
||||
extent: undefined,
|
||||
zIndex: 10,
|
||||
maxResolution: 500,
|
||||
minResolution: 0.25
|
||||
minResolution: 0.25,
|
||||
minZoom: 1,
|
||||
maxZoom: 10
|
||||
});
|
||||
|
||||
layer.dispose();
|
||||
@@ -108,7 +124,7 @@ describe('ol.layer.Layer', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('visibleAtResolution', function() {
|
||||
describe('inView', function() {
|
||||
let layer;
|
||||
|
||||
beforeEach(function() {
|
||||
@@ -123,36 +139,196 @@ describe('ol.layer.Layer', function() {
|
||||
layer.dispose();
|
||||
});
|
||||
|
||||
it('returns false if layer is not visible', function() {
|
||||
layer.setVisible(false);
|
||||
layer.setMinResolution(3);
|
||||
layer.setMaxResolution(5);
|
||||
const layerState = layer.getLayerState();
|
||||
expect(visibleAtResolution(layerState, 4)).to.be(false);
|
||||
});
|
||||
const cases = [{
|
||||
when: 'layer is not visible',
|
||||
visible: false,
|
||||
view: {
|
||||
resolution: 4, zoom: 4
|
||||
},
|
||||
inView: false
|
||||
}, {
|
||||
when: 'layer is not visible (with min/max zoom and resolution)',
|
||||
visible: false,
|
||||
minZoom: 2,
|
||||
maxZoom: 6,
|
||||
minResolution: 2,
|
||||
maxResolution: 6,
|
||||
view: {
|
||||
resolution: 4, zoom: 4
|
||||
},
|
||||
inView: false
|
||||
}, {
|
||||
when: 'view zoom is less than minZoom',
|
||||
minZoom: 2,
|
||||
view: {
|
||||
resolution: 1, zoom: 1
|
||||
},
|
||||
inView: false
|
||||
}, {
|
||||
when: 'view zoom is less than minZoom (with maxZoom)',
|
||||
minZoom: 2,
|
||||
maxZoom: 4,
|
||||
view: {
|
||||
resolution: 1, zoom: 1
|
||||
},
|
||||
inView: false
|
||||
}, {
|
||||
when: 'view zoom is equal to minZoom',
|
||||
minZoom: 2,
|
||||
view: {
|
||||
resolution: 2, zoom: 2
|
||||
},
|
||||
inView: false
|
||||
}, {
|
||||
when: 'view zoom is equal to minZoom (with maxZoom)',
|
||||
minZoom: 2,
|
||||
maxZoom: 4,
|
||||
view: {
|
||||
resolution: 2, zoom: 2
|
||||
},
|
||||
inView: false
|
||||
}, {
|
||||
when: 'view zoom is greater than minZoom',
|
||||
minZoom: 2,
|
||||
view: {
|
||||
resolution: 3, zoom: 3
|
||||
},
|
||||
inView: true
|
||||
}, {
|
||||
when: 'view zoom is greater than minZoom (with maxZoom)',
|
||||
minZoom: 2,
|
||||
maxZoom: 4,
|
||||
view: {
|
||||
resolution: 3, zoom: 3
|
||||
},
|
||||
inView: true
|
||||
}, {
|
||||
when: 'view zoom is equal to maxZoom',
|
||||
maxZoom: 4,
|
||||
view: {
|
||||
resolution: 4, zoom: 4
|
||||
},
|
||||
inView: true
|
||||
}, {
|
||||
when: 'view zoom is equal to maxZoom (with minZoom)',
|
||||
minZoom: 2,
|
||||
maxZoom: 4,
|
||||
view: {
|
||||
resolution: 4, zoom: 4
|
||||
},
|
||||
inView: true
|
||||
}, {
|
||||
when: 'view zoom is greater than maxZoom',
|
||||
maxZoom: 4,
|
||||
view: {
|
||||
resolution: 5, zoom: 5
|
||||
},
|
||||
inView: false
|
||||
}, {
|
||||
when: 'view zoom is greater than maxZoom (with minZoom)',
|
||||
minZoom: 2,
|
||||
maxZoom: 4,
|
||||
view: {
|
||||
resolution: 5, zoom: 5
|
||||
},
|
||||
inView: false
|
||||
}, {
|
||||
when: 'view resolution is less than minResolution',
|
||||
minResolution: 2,
|
||||
view: {
|
||||
resolution: 1, zoom: 1
|
||||
},
|
||||
inView: false
|
||||
}, {
|
||||
when: 'view resolution is less than minResolution (with maxResolution)',
|
||||
minResolution: 2,
|
||||
maxResolution: 4,
|
||||
view: {
|
||||
resolution: 1, zoom: 1
|
||||
},
|
||||
inView: false
|
||||
}, {
|
||||
when: 'view resolution is equal to minResolution',
|
||||
minResolution: 2,
|
||||
view: {
|
||||
resolution: 2, zoom: 2
|
||||
},
|
||||
inView: true
|
||||
}, {
|
||||
when: 'view resolution is equal to minResolution (with maxResolution)',
|
||||
minResolution: 2,
|
||||
maxResolution: 4,
|
||||
view: {
|
||||
resolution: 2, zoom: 2
|
||||
},
|
||||
inView: true
|
||||
}, {
|
||||
when: 'view resolution is greater than minResolution',
|
||||
minResolution: 2,
|
||||
view: {
|
||||
resolution: 3, zoom: 3
|
||||
},
|
||||
inView: true
|
||||
}, {
|
||||
when: 'view resolution is greater than minResolution (with maxResolution)',
|
||||
minResolution: 2,
|
||||
maxResolution: 4,
|
||||
view: {
|
||||
resolution: 3, zoom: 3
|
||||
},
|
||||
inView: true
|
||||
}, {
|
||||
when: 'view resolution is equal to maxResolution',
|
||||
maxResolution: 4,
|
||||
view: {
|
||||
resolution: 4, zoom: 4
|
||||
},
|
||||
inView: false
|
||||
}, {
|
||||
when: 'view resolution is equal to maxResolution (with minResolution)',
|
||||
minResolution: 2,
|
||||
maxResolution: 4,
|
||||
view: {
|
||||
resolution: 4, zoom: 4
|
||||
},
|
||||
inView: false
|
||||
}, {
|
||||
when: 'view resolution is greater than maxResolution',
|
||||
maxResolution: 4,
|
||||
view: {
|
||||
resolution: 5, zoom: 5
|
||||
},
|
||||
inView: false
|
||||
}, {
|
||||
when: 'view resolution is greater than maxResolution (with minResolution)',
|
||||
minResolution: 2,
|
||||
maxResolution: 4,
|
||||
view: {
|
||||
resolution: 5, zoom: 5
|
||||
},
|
||||
inView: false
|
||||
}];
|
||||
|
||||
it('returns false if resolution lower than minResolution', function() {
|
||||
layer.setVisible(true);
|
||||
layer.setMinResolution(3);
|
||||
layer.setMaxResolution(5);
|
||||
const layerState = layer.getLayerState();
|
||||
expect(visibleAtResolution(layerState, 2)).to.be(false);
|
||||
});
|
||||
|
||||
it('returns false if resolution greater than maxResolution', function() {
|
||||
layer.setVisible(true);
|
||||
layer.setMinResolution(3);
|
||||
layer.setMaxResolution(5);
|
||||
const layerState = layer.getLayerState();
|
||||
expect(visibleAtResolution(layerState, 6)).to.be(false);
|
||||
});
|
||||
|
||||
it('returns true otherwise', function() {
|
||||
layer.setVisible(true);
|
||||
layer.setMinResolution(3);
|
||||
layer.setMaxResolution(5);
|
||||
const layerState = layer.getLayerState();
|
||||
expect(visibleAtResolution(layerState, 4)).to.be(true);
|
||||
cases.forEach(function(c, i) {
|
||||
it('returns ' + c.inView + ' when ' + c.when, function() {
|
||||
if ('visible' in c) {
|
||||
layer.setVisible(c.visible);
|
||||
}
|
||||
if ('minZoom' in c) {
|
||||
layer.setMinZoom(c.minZoom);
|
||||
}
|
||||
if ('maxZoom' in c) {
|
||||
layer.setMaxZoom(c.maxZoom);
|
||||
}
|
||||
if ('minResolution' in c) {
|
||||
layer.setMinResolution(c.minResolution);
|
||||
}
|
||||
if ('maxResolution' in c) {
|
||||
layer.setMaxResolution(c.maxResolution);
|
||||
}
|
||||
const layerState = layer.getLayerState();
|
||||
expect(inView(layerState, c.view)).to.be(c.inView);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
@@ -189,40 +365,24 @@ describe('ol.layer.Layer', function() {
|
||||
extent: undefined,
|
||||
zIndex: 10,
|
||||
maxResolution: 500,
|
||||
minResolution: 0.25
|
||||
minResolution: 0.25,
|
||||
minZoom: -Infinity,
|
||||
maxZoom: Infinity
|
||||
});
|
||||
});
|
||||
|
||||
it('returns a layerState with clamped values', function() {
|
||||
layer.setOpacity(-1.5);
|
||||
layer.setVisible(false);
|
||||
expect(layer.getLayerState()).to.eql({
|
||||
layer: layer,
|
||||
opacity: 0,
|
||||
visible: false,
|
||||
managed: true,
|
||||
hasOverlay: false,
|
||||
sourceState: 'ready',
|
||||
extent: undefined,
|
||||
zIndex: 0,
|
||||
maxResolution: Infinity,
|
||||
minResolution: 0
|
||||
});
|
||||
let state = layer.getLayerState();
|
||||
expect(state.opacity).to.be(0);
|
||||
expect(state.visible).to.be(false);
|
||||
|
||||
layer.setOpacity(3);
|
||||
layer.setVisible(true);
|
||||
expect(layer.getLayerState()).to.eql({
|
||||
layer: layer,
|
||||
opacity: 1,
|
||||
visible: true,
|
||||
managed: true,
|
||||
hasOverlay: false,
|
||||
sourceState: 'ready',
|
||||
extent: undefined,
|
||||
zIndex: 0,
|
||||
maxResolution: Infinity,
|
||||
minResolution: 0
|
||||
});
|
||||
state = layer.getLayerState();
|
||||
expect(state.opacity).to.be(1);
|
||||
expect(state.visible).to.be(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -17,14 +17,14 @@ describe('ol.render.canvas', function() {
|
||||
render.measureTextHeight('12px sans-serif');
|
||||
});
|
||||
|
||||
const retries = 60;
|
||||
const retries = 100;
|
||||
|
||||
it('does not clear label cache and measurements for unavailable fonts', function(done) {
|
||||
this.timeout(3000);
|
||||
this.timeout(4000);
|
||||
const spy = sinon.spy();
|
||||
listen(render.labelCache, 'clear', spy);
|
||||
const interval = setInterval(function() {
|
||||
if (render.checkedFonts['foo'] == retries && render.checkedFonts['sans-serif'] == retries) {
|
||||
if (render.checkedFonts['normal\nnormal\nfoo'] == retries && render.checkedFonts['normal\nnormal\nsans-serif'] == retries) {
|
||||
clearInterval(interval);
|
||||
unlisten(render.labelCache, 'clear', spy);
|
||||
expect(spy.callCount).to.be(0);
|
||||
@@ -39,7 +39,7 @@ describe('ol.render.canvas', function() {
|
||||
const spy = sinon.spy();
|
||||
listen(render.labelCache, 'clear', spy);
|
||||
const interval = setInterval(function() {
|
||||
if (render.checkedFonts['sans-serif'] == retries) {
|
||||
if (render.checkedFonts['normal\nnormal\nsans-serif'] == retries) {
|
||||
clearInterval(interval);
|
||||
unlisten(render.labelCache, 'clear', spy);
|
||||
expect(spy.callCount).to.be(0);
|
||||
@@ -54,7 +54,7 @@ describe('ol.render.canvas', function() {
|
||||
const spy = sinon.spy();
|
||||
listen(render.labelCache, 'clear', spy);
|
||||
const interval = setInterval(function() {
|
||||
if (render.checkedFonts['monospace'] == retries) {
|
||||
if (render.checkedFonts['normal\nnormal\nmonospace'] == retries) {
|
||||
clearInterval(interval);
|
||||
unlisten(render.labelCache, 'clear', spy);
|
||||
expect(spy.callCount).to.be(0);
|
||||
@@ -67,6 +67,7 @@ describe('ol.render.canvas', function() {
|
||||
|
||||
it('clears label cache and measurements for fonts that become available', function(done) {
|
||||
head.appendChild(font);
|
||||
render.labelCache.set('dummy', {});
|
||||
listen(render.labelCache, 'clear', function() {
|
||||
expect(render.textHeights).to.eql({});
|
||||
done();
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import WebGLLayerRenderer, {
|
||||
getBlankTexture, POINT_INSTRUCTIONS_COUNT, POINT_VERTEX_STRIDE,
|
||||
colorDecodeId,
|
||||
colorEncodeId,
|
||||
getBlankImageData, POINT_INSTRUCTIONS_COUNT, POINT_VERTEX_STRIDE,
|
||||
writePointFeatureInstructions, writePointFeatureToBuffers
|
||||
} from '../../../../../src/ol/renderer/webgl/Layer.js';
|
||||
import Layer from '../../../../../src/ol/layer/Layer.js';
|
||||
@@ -237,9 +239,9 @@ describe('ol.renderer.webgl.Layer', function() {
|
||||
|
||||
});
|
||||
|
||||
describe('getBlankTexture', function() {
|
||||
describe('getBlankImageData', function() {
|
||||
it('creates a 1x1 white texture', function() {
|
||||
const texture = getBlankTexture();
|
||||
const texture = getBlankImageData();
|
||||
expect(texture.height).to.eql(1);
|
||||
expect(texture.width).to.eql(1);
|
||||
expect(texture.data[0]).to.eql(255);
|
||||
@@ -249,4 +251,35 @@ describe('ol.renderer.webgl.Layer', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('colorEncodeId and colorDecodeId', function() {
|
||||
it('correctly encodes and decodes ids', function() {
|
||||
expect(colorDecodeId(colorEncodeId(0))).to.eql(0);
|
||||
expect(colorDecodeId(colorEncodeId(1))).to.eql(1);
|
||||
expect(colorDecodeId(colorEncodeId(123))).to.eql(123);
|
||||
expect(colorDecodeId(colorEncodeId(12345))).to.eql(12345);
|
||||
expect(colorDecodeId(colorEncodeId(123456))).to.eql(123456);
|
||||
expect(colorDecodeId(colorEncodeId(91612))).to.eql(91612);
|
||||
expect(colorDecodeId(colorEncodeId(1234567890))).to.eql(1234567890);
|
||||
});
|
||||
|
||||
it('correctly reuses array', function() {
|
||||
const arr = [];
|
||||
expect(colorEncodeId(123, arr)).to.be(arr);
|
||||
});
|
||||
|
||||
it('is compatible with Uint8Array storage', function() {
|
||||
const encoded = colorEncodeId(91612);
|
||||
const typed = Uint8Array.of(encoded[0] * 255, encoded[1] * 255,
|
||||
encoded[2] * 255, encoded[3] * 255);
|
||||
const arr = [
|
||||
typed[0] / 255,
|
||||
typed[1] / 255,
|
||||
typed[2] / 255,
|
||||
typed[3] / 255
|
||||
];
|
||||
const decoded = colorDecodeId(arr);
|
||||
expect(decoded).to.eql(91612);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -6,7 +6,20 @@ import WebGLPointsLayerRenderer from '../../../../../src/ol/renderer/webgl/Point
|
||||
import {get as getProjection} from '../../../../../src/ol/proj.js';
|
||||
import ViewHint from '../../../../../src/ol/ViewHint.js';
|
||||
import {POINT_VERTEX_STRIDE, WebGLWorkerMessageType} from '../../../../../src/ol/renderer/webgl/Layer.js';
|
||||
import {create as createTransform, compose as composeTransform} from '../../../../../src/ol/transform.js';
|
||||
|
||||
const baseFrameState = {
|
||||
viewHints: [],
|
||||
viewState: {
|
||||
projection: getProjection('EPSG:3857'),
|
||||
resolution: 1,
|
||||
rotation: 0,
|
||||
center: [0, 0]
|
||||
},
|
||||
layerStatesArray: [{}],
|
||||
layerIndex: 0,
|
||||
pixelRatio: 1
|
||||
};
|
||||
|
||||
describe('ol.renderer.webgl.PointsLayer', function() {
|
||||
|
||||
@@ -43,19 +56,10 @@ describe('ol.renderer.webgl.PointsLayer', function() {
|
||||
source: new VectorSource()
|
||||
});
|
||||
renderer = new WebGLPointsLayerRenderer(layer);
|
||||
const projection = getProjection('EPSG:3857');
|
||||
frameState = {
|
||||
skippedFeatureUids: {},
|
||||
viewHints: [],
|
||||
viewState: {
|
||||
projection: projection,
|
||||
resolution: 1,
|
||||
rotation: 0,
|
||||
center: [0, 0]
|
||||
},
|
||||
frameState = Object.assign({
|
||||
size: [2, 2],
|
||||
extent: [-100, -100, 100, 100]
|
||||
};
|
||||
}, baseFrameState);
|
||||
});
|
||||
|
||||
it('calls WebGlHelper#prepareDraw', function() {
|
||||
@@ -146,4 +150,108 @@ describe('ol.renderer.webgl.PointsLayer', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#forEachFeatureAtCoordinate', function() {
|
||||
let layer, renderer, feature, feature2;
|
||||
|
||||
beforeEach(function() {
|
||||
feature = new Feature({geometry: new Point([0, 0]), id: 1});
|
||||
feature2 = new Feature({geometry: new Point([14, 14]), id: 2});
|
||||
layer = new VectorLayer({
|
||||
source: new VectorSource({
|
||||
features: [feature, feature2]
|
||||
})
|
||||
});
|
||||
renderer = new WebGLPointsLayerRenderer(layer, {
|
||||
sizeCallback: function() {
|
||||
return 4;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('correctly hit detects a feature', function(done) {
|
||||
const transform = composeTransform(createTransform(), 20, 20, 1, -1, 0, 0, 0);
|
||||
const frameState = Object.assign({
|
||||
extent: [-20, -20, 20, 20],
|
||||
size: [40, 40],
|
||||
coordinateToPixelTransform: transform
|
||||
}, baseFrameState);
|
||||
let found;
|
||||
const cb = function(feature) {
|
||||
found = feature;
|
||||
};
|
||||
|
||||
renderer.prepareFrame(frameState);
|
||||
renderer.worker_.addEventListener('message', function() {
|
||||
if (!renderer.hitRenderInstructions_) {
|
||||
return;
|
||||
}
|
||||
renderer.prepareFrame(frameState);
|
||||
renderer.renderFrame(frameState);
|
||||
|
||||
function checkHit(x, y, expected) {
|
||||
found = null;
|
||||
renderer.forEachFeatureAtCoordinate([x, y], frameState, 0, cb, null);
|
||||
expect(found).to.be(expected);
|
||||
}
|
||||
|
||||
checkHit(0, 0, feature);
|
||||
checkHit(1, -1, feature);
|
||||
checkHit(-2, 2, feature);
|
||||
checkHit(2, 0, null);
|
||||
checkHit(1, -3, null);
|
||||
|
||||
checkHit(14, 14, feature2);
|
||||
checkHit(15, 13, feature2);
|
||||
checkHit(12, 16, feature2);
|
||||
checkHit(16, 14, null);
|
||||
checkHit(13, 11, null);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('correctly hit detects with pixelratio != 1', function(done) {
|
||||
const transform = composeTransform(createTransform(), 20, 20, 1, -1, 0, 0, 0);
|
||||
const frameState = Object.assign({
|
||||
pixelRatio: 3,
|
||||
extent: [-20, -20, 20, 20],
|
||||
size: [40, 40],
|
||||
coordinateToPixelTransform: transform
|
||||
}, baseFrameState);
|
||||
let found;
|
||||
const cb = function(feature) {
|
||||
found = feature;
|
||||
};
|
||||
|
||||
renderer.prepareFrame(frameState);
|
||||
renderer.worker_.addEventListener('message', function() {
|
||||
if (!renderer.hitRenderInstructions_) {
|
||||
return;
|
||||
}
|
||||
renderer.prepareFrame(frameState);
|
||||
renderer.renderFrame(frameState);
|
||||
|
||||
function checkHit(x, y, expected) {
|
||||
found = null;
|
||||
renderer.forEachFeatureAtCoordinate([x, y], frameState, 0, cb, null);
|
||||
expect(found).to.be(expected);
|
||||
}
|
||||
|
||||
checkHit(0, 0, feature);
|
||||
checkHit(1, -1, feature);
|
||||
checkHit(-2, 2, feature);
|
||||
checkHit(2, 0, null);
|
||||
checkHit(1, -3, null);
|
||||
|
||||
checkHit(14, 14, feature2);
|
||||
checkHit(15, 13, feature2);
|
||||
checkHit(12, 16, feature2);
|
||||
checkHit(16, 14, null);
|
||||
checkHit(13, 11, null);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -201,6 +201,21 @@ describe('ol.source.IIIF', function() {
|
||||
expect(tileUrlFunction([2, 0, 0])).to.be('http://iiif.test/image-id/full/full/0/default.jpg');
|
||||
expect(tileUrlFunction([3, 0, 0])).to.be(undefined);
|
||||
|
||||
tileUrlFunction = getSource({
|
||||
version: Versions.VERSION3,
|
||||
sizes: [[2000, 1500], [1000, 750], [500, 375]]
|
||||
}).getTileUrlFunction();
|
||||
|
||||
expect(tileUrlFunction([0, 0, 0])).to.be('http://iiif.test/image-id/full/500,375/0/default.jpg');
|
||||
expect(tileUrlFunction([1, 0, 0])).to.be('http://iiif.test/image-id/full/1000,750/0/default.jpg');
|
||||
expect(tileUrlFunction([2, 0, 0])).to.be('http://iiif.test/image-id/full/max/0/default.jpg');
|
||||
expect(tileUrlFunction([3, 0, 0])).to.be(undefined);
|
||||
expect(tileUrlFunction([-1, 0, 0])).to.be(undefined);
|
||||
expect(tileUrlFunction([0, 1, 0])).to.be(undefined);
|
||||
expect(tileUrlFunction([0, 0, 1])).to.be(undefined);
|
||||
expect(tileUrlFunction([1, 1, 0])).to.be(undefined);
|
||||
expect(tileUrlFunction([1, 0, 1])).to.be(undefined);
|
||||
|
||||
});
|
||||
|
||||
it('cannot provide scaled tiles without provided tilesize or supported features', function() {
|
||||
|
||||
@@ -189,7 +189,7 @@ describe('ol.source.ImageWMS', function() {
|
||||
const source = new ImageWMS(options);
|
||||
pixelRatio = 1.325;
|
||||
const image =
|
||||
source.getImage(extent, resolution, pixelRatio, projection);
|
||||
source.getImage(extent, resolution, pixelRatio, projection);
|
||||
const uri = new URL(image.src_);
|
||||
const queryData = uri.searchParams;
|
||||
expect(queryData.get('FORMAT_OPTIONS')).to.be('dpi:119');
|
||||
@@ -330,6 +330,71 @@ describe('ol.source.ImageWMS', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getGetLegendGraphicUrl', function() {
|
||||
|
||||
it('returns the getLegendGraphic url as expected', function() {
|
||||
const source = new ImageWMS(options);
|
||||
const url = source.getGetLegendGraphicUrl(resolution);
|
||||
const uri = new URL(url);
|
||||
expect(uri.protocol).to.be('http:');
|
||||
expect(uri.hostname).to.be('example.com');
|
||||
expect(uri.pathname).to.be('/wms');
|
||||
const queryData = uri.searchParams;
|
||||
expect(queryData.get('FORMAT')).to.be('image/png');
|
||||
expect(queryData.get('LAYER')).to.be('layer');
|
||||
expect(queryData.get('REQUEST')).to.be('GetLegendGraphic');
|
||||
expect(queryData.get('SERVICE')).to.be('WMS');
|
||||
expect(queryData.get('VERSION')).to.be('1.3.0');
|
||||
expect(queryData.get('SCALE')).to.be('357.14214285714274');
|
||||
});
|
||||
|
||||
it('does not include SCALE if no resolution was provided', function() {
|
||||
const source = new ImageWMS(options);
|
||||
const url = source.getGetLegendGraphicUrl();
|
||||
const uri = new URL(url);
|
||||
const queryData = uri.searchParams;
|
||||
expect(queryData.get('SCALE')).to.be(null);
|
||||
});
|
||||
|
||||
it('adds additional params as expected', function() {
|
||||
const source = new ImageWMS(options);
|
||||
const url = source.getGetLegendGraphicUrl(resolution, {
|
||||
STYLE: 'STYLE_VALUE',
|
||||
FEATURETYPE: 'FEATURETYPE_VALUE',
|
||||
RULE: 'RULE_VALUE',
|
||||
SLD: 'SLD_VALUE',
|
||||
SLD_BODY: 'SLD_BODY_VALUE',
|
||||
FORMAT: 'FORMAT_VALUE',
|
||||
WIDTH: 'WIDTH_VALUE',
|
||||
HEIGHT: 'HEIGHT_VALUE',
|
||||
EXCEPTIONS: 'EXCEPTIONS_VALUE',
|
||||
LANGUAGE: 'LANGUAGE_VALUE'
|
||||
});
|
||||
const uri = new URL(url);
|
||||
expect(uri.protocol).to.be('http:');
|
||||
expect(uri.hostname).to.be('example.com');
|
||||
expect(uri.pathname).to.be('/wms');
|
||||
const queryData = uri.searchParams;
|
||||
expect(queryData.get('FORMAT')).to.be('FORMAT_VALUE');
|
||||
expect(queryData.get('LAYER')).to.be('layer');
|
||||
expect(queryData.get('REQUEST')).to.be('GetLegendGraphic');
|
||||
expect(queryData.get('SERVICE')).to.be('WMS');
|
||||
expect(queryData.get('VERSION')).to.be('1.3.0');
|
||||
expect(queryData.get('SCALE')).to.be('357.14214285714274');
|
||||
expect(queryData.get('STYLE')).to.be('STYLE_VALUE');
|
||||
expect(queryData.get('FEATURETYPE')).to.be('FEATURETYPE_VALUE');
|
||||
expect(queryData.get('RULE')).to.be('RULE_VALUE');
|
||||
expect(queryData.get('SLD')).to.be('SLD_VALUE');
|
||||
expect(queryData.get('SLD_BODY')).to.be('SLD_BODY_VALUE');
|
||||
expect(queryData.get('FORMAT')).to.be('FORMAT_VALUE');
|
||||
expect(queryData.get('WIDTH')).to.be('WIDTH_VALUE');
|
||||
expect(queryData.get('HEIGHT')).to.be('HEIGHT_VALUE');
|
||||
expect(queryData.get('EXCEPTIONS')).to.be('EXCEPTIONS_VALUE');
|
||||
expect(queryData.get('LANGUAGE')).to.be('LANGUAGE_VALUE');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#refresh()', function() {
|
||||
|
||||
let map, source;
|
||||
|
||||
@@ -299,6 +299,71 @@ describe('ol.source.TileWMS', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getGetLegendGraphicUrl', function() {
|
||||
|
||||
it('returns the getLegenGraphic url as expected', function() {
|
||||
const source = new TileWMS(options);
|
||||
const url = source.getGetLegendGraphicUrl(0.1);
|
||||
const uri = new URL(url);
|
||||
expect(uri.protocol).to.be('http:');
|
||||
expect(uri.hostname).to.be('example.com');
|
||||
expect(uri.pathname).to.be('/wms');
|
||||
const queryData = uri.searchParams;
|
||||
expect(queryData.get('FORMAT')).to.be('image/png');
|
||||
expect(queryData.get('LAYER')).to.be('layer');
|
||||
expect(queryData.get('REQUEST')).to.be('GetLegendGraphic');
|
||||
expect(queryData.get('SERVICE')).to.be('WMS');
|
||||
expect(queryData.get('VERSION')).to.be('1.3.0');
|
||||
expect(queryData.get('SCALE')).to.be('357.14214285714274');
|
||||
});
|
||||
|
||||
it('does not include SCALE if no resolution was provided', function() {
|
||||
const source = new TileWMS(options);
|
||||
const url = source.getGetLegendGraphicUrl();
|
||||
const uri = new URL(url);
|
||||
const queryData = uri.searchParams;
|
||||
expect(queryData.get('SCALE')).to.be(null);
|
||||
});
|
||||
|
||||
it('adds additional params as expected', function() {
|
||||
const source = new TileWMS(options);
|
||||
const url = source.getGetLegendGraphicUrl(0.1, {
|
||||
STYLE: 'STYLE_VALUE',
|
||||
FEATURETYPE: 'FEATURETYPE_VALUE',
|
||||
RULE: 'RULE_VALUE',
|
||||
SLD: 'SLD_VALUE',
|
||||
SLD_BODY: 'SLD_BODY_VALUE',
|
||||
FORMAT: 'FORMAT_VALUE',
|
||||
WIDTH: 'WIDTH_VALUE',
|
||||
HEIGHT: 'HEIGHT_VALUE',
|
||||
EXCEPTIONS: 'EXCEPTIONS_VALUE',
|
||||
LANGUAGE: 'LANGUAGE_VALUE'
|
||||
});
|
||||
const uri = new URL(url);
|
||||
expect(uri.protocol).to.be('http:');
|
||||
expect(uri.hostname).to.be('example.com');
|
||||
expect(uri.pathname).to.be('/wms');
|
||||
const queryData = uri.searchParams;
|
||||
expect(queryData.get('FORMAT')).to.be('FORMAT_VALUE');
|
||||
expect(queryData.get('LAYER')).to.be('layer');
|
||||
expect(queryData.get('REQUEST')).to.be('GetLegendGraphic');
|
||||
expect(queryData.get('SERVICE')).to.be('WMS');
|
||||
expect(queryData.get('VERSION')).to.be('1.3.0');
|
||||
expect(queryData.get('SCALE')).to.be('357.14214285714274');
|
||||
expect(queryData.get('STYLE')).to.be('STYLE_VALUE');
|
||||
expect(queryData.get('FEATURETYPE')).to.be('FEATURETYPE_VALUE');
|
||||
expect(queryData.get('RULE')).to.be('RULE_VALUE');
|
||||
expect(queryData.get('SLD')).to.be('SLD_VALUE');
|
||||
expect(queryData.get('SLD_BODY')).to.be('SLD_BODY_VALUE');
|
||||
expect(queryData.get('FORMAT')).to.be('FORMAT_VALUE');
|
||||
expect(queryData.get('WIDTH')).to.be('WIDTH_VALUE');
|
||||
expect(queryData.get('HEIGHT')).to.be('HEIGHT_VALUE');
|
||||
expect(queryData.get('EXCEPTIONS')).to.be('EXCEPTIONS_VALUE');
|
||||
expect(queryData.get('LANGUAGE')).to.be('LANGUAGE_VALUE');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#setUrl()', function() {
|
||||
it('sets the correct url', function() {
|
||||
const source = new TileWMS(options);
|
||||
|
||||