Compare commits
38 Commits
v6.0.0-bet
...
v6.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8b5dfa981 | ||
|
|
42f1a7ed30 | ||
|
|
f3d6456876 | ||
|
|
2ca13de4de | ||
|
|
87ae93ca2d | ||
|
|
5da32dbc5b | ||
|
|
6be2818f14 | ||
|
|
b602a6b33a | ||
|
|
20a81ceb2f | ||
|
|
3d6cf24c26 | ||
|
|
6a741d0504 | ||
|
|
aa55cce3ba | ||
|
|
a5fbbef970 | ||
|
|
25c8d93eba | ||
|
|
eb294c78d1 | ||
|
|
bd3f35eef0 | ||
|
|
f839b34594 | ||
|
|
99462d3b53 | ||
|
|
200392785d | ||
|
|
c0e5c4b7fe | ||
|
|
189ad24528 | ||
|
|
4aa11ecc94 | ||
|
|
e61c5c07bc | ||
|
|
0212ce6554 | ||
|
|
b76a0379dd | ||
|
|
e94c7b6c39 | ||
|
|
2c69ad2bb4 | ||
|
|
e8e7c46463 | ||
|
|
abda7f4f1d | ||
|
|
e8500c395c | ||
|
|
6f5a066bab | ||
|
|
08816ec9f9 | ||
|
|
fac659fa0a | ||
|
|
b0069c3c5d | ||
|
|
e7be28d2b5 | ||
|
|
15aa5ebc1f | ||
|
|
94edf32540 | ||
|
|
91d2f98774 |
@@ -236,3 +236,7 @@ A `WebGLArrayBuffer` must either be of type `ELEMENT_ARRAY_BUFFER` or `ARRAY_BUF
|
||||
### 63
|
||||
|
||||
Support for the `OES_element_index_uint` WebGL extension is mandatory for WebGL layers.
|
||||
|
||||
### 64
|
||||
|
||||
Layer opacity must be a number.
|
||||
|
||||
@@ -5,7 +5,7 @@ shortdesc: Label decluttering with a custom renderer.
|
||||
resources:
|
||||
- https://cdn.polyfill.io/v2/polyfill.min.js?features=Set"
|
||||
docs: >
|
||||
Decluttering is used to avoid overlapping labels with `overflow: true` set on the text style. For MultiPolygon geometries, only the widest polygon is selected in a custom `geometry` function.
|
||||
Decluttering is used to avoid overlapping labels. The `overflow: true` setting on the text style makes it so labels that do not fit within the bounds of a polygon are also included.
|
||||
tags: "vector, decluttering, labels"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {getWidth} from '../src/ol/extent.js';
|
||||
import GeoJSON from '../src/ol/format/GeoJSON.js';
|
||||
import VectorLayer from '../src/ol/layer/Vector.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
@@ -15,23 +14,6 @@ const map = new Map({
|
||||
});
|
||||
|
||||
const labelStyle = new Style({
|
||||
geometry: function(feature) {
|
||||
let geometry = feature.getGeometry();
|
||||
if (geometry.getType() == 'MultiPolygon') {
|
||||
// Only render label for the widest polygon of a multipolygon
|
||||
const polygons = geometry.getPolygons();
|
||||
let widest = 0;
|
||||
for (let i = 0, ii = polygons.length; i < ii; ++i) {
|
||||
const polygon = polygons[i];
|
||||
const width = getWidth(polygon.getExtent());
|
||||
if (width > widest) {
|
||||
widest = width;
|
||||
geometry = polygon;
|
||||
}
|
||||
}
|
||||
}
|
||||
return geometry;
|
||||
},
|
||||
text: new Text({
|
||||
font: '12px Calibri,sans-serif',
|
||||
overflow: true,
|
||||
|
||||
181
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ol",
|
||||
"version": "6.0.0-beta.13",
|
||||
"version": "6.0.0-beta.14",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -6571,9 +6571,9 @@
|
||||
}
|
||||
},
|
||||
"karma-chrome-launcher": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.0.0.tgz",
|
||||
"integrity": "sha512-u/PnVgDOP97AUe/gJeABlC6Wa6aQ83MZsm0JgsJQ5bGQ9XcXON/7b2aRhl59A62Zom+q3PFveBkczc7E1RT7TA==",
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.1.0.tgz",
|
||||
"integrity": "sha512-3dPs/n7vgz1rxxtynpzZTvb9y/GIaW8xjAwcIGttLbycqoFtI7yo1NGnQi6oFTherRE+GIhCAHZC4vEqWGhNvg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"which": "^1.2.1"
|
||||
@@ -6766,9 +6766,9 @@
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.11",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
|
||||
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
|
||||
"version": "4.17.15",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
|
||||
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
|
||||
"dev": true
|
||||
},
|
||||
"log-driver": {
|
||||
@@ -7219,9 +7219,9 @@
|
||||
}
|
||||
},
|
||||
"mixin-deep": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
|
||||
"integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
|
||||
"integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"for-in": "^1.0.2",
|
||||
@@ -7293,6 +7293,12 @@
|
||||
"integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
|
||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
|
||||
"dev": true
|
||||
},
|
||||
"debug": {
|
||||
"version": "3.2.6",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
|
||||
@@ -7316,6 +7322,26 @@
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"string-width": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
|
||||
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"emoji-regex": "^7.0.1",
|
||||
"is-fullwidth-code-point": "^2.0.0",
|
||||
"strip-ansi": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
|
||||
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz",
|
||||
@@ -7324,6 +7350,25 @@
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"yargs": {
|
||||
"version": "13.2.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.2.tgz",
|
||||
"integrity": "sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cliui": "^4.0.0",
|
||||
"find-up": "^3.0.0",
|
||||
"get-caller-file": "^2.0.1",
|
||||
"os-locale": "^3.1.0",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^2.0.0",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^3.0.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^4.0.0",
|
||||
"yargs-parser": "^13.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -8837,13 +8882,20 @@
|
||||
}
|
||||
},
|
||||
"rollup-pluginutils": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.7.0.tgz",
|
||||
"integrity": "sha512-FoP6L1YnMYTAR06Dpq5LE3jJtMwPE6H4VEOqFU23yoziZnqNRSiWcVy6YgEY5PdQB4G7278+8c4TvB0JKS1csA==",
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.1.tgz",
|
||||
"integrity": "sha512-J5oAoysWar6GuZo0s+3bZ6sVZAC0pfqKz68De7ZgDi5z63jOVZn1uJL/+z1jeKHNbGII8kAyHF5q8LnxSX5lQg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"estree-walker": "^0.6.0",
|
||||
"micromatch": "^3.1.10"
|
||||
"estree-walker": "^0.6.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"estree-walker": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz",
|
||||
"integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"run-async": {
|
||||
@@ -9133,9 +9185,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"set-value": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
|
||||
"integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
|
||||
"integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"extend-shallow": "^2.0.1",
|
||||
@@ -10245,38 +10297,15 @@
|
||||
"dev": true
|
||||
},
|
||||
"union-value": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
|
||||
"integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
|
||||
"integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arr-union": "^3.1.0",
|
||||
"get-value": "^2.0.6",
|
||||
"is-extendable": "^0.1.1",
|
||||
"set-value": "^0.4.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"extend-shallow": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
|
||||
"integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-extendable": "^0.1.0"
|
||||
}
|
||||
},
|
||||
"set-value": {
|
||||
"version": "0.4.3",
|
||||
"resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
|
||||
"integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"extend-shallow": "^2.0.1",
|
||||
"is-extendable": "^0.1.1",
|
||||
"is-plain-object": "^2.0.1",
|
||||
"to-object-path": "^0.3.0"
|
||||
}
|
||||
}
|
||||
"set-value": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"unique-filename": {
|
||||
@@ -10562,9 +10591,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"webpack": {
|
||||
"version": "4.39.1",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.39.1.tgz",
|
||||
"integrity": "sha512-/LAb2TJ2z+eVwisldp3dqTEoNhzp/TLCZlmZm3GGGAlnfIWDgOEE758j/9atklNLfRyhKbZTCOIoPqLJXeBLbQ==",
|
||||
"version": "4.39.2",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.39.2.tgz",
|
||||
"integrity": "sha512-AKgTfz3xPSsEibH00JfZ9sHXGUwIQ6eZ9tLN8+VLzachk1Cw2LVmy+4R7ZiwTa9cZZ15tzySjeMui/UnSCAZhA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.8.5",
|
||||
@@ -10593,9 +10622,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"acorn": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz",
|
||||
"integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==",
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz",
|
||||
"integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==",
|
||||
"dev": true
|
||||
},
|
||||
"ajv": {
|
||||
@@ -11084,22 +11113,22 @@
|
||||
"dev": true
|
||||
},
|
||||
"yargs": {
|
||||
"version": "13.2.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.2.tgz",
|
||||
"integrity": "sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==",
|
||||
"version": "14.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-14.0.0.tgz",
|
||||
"integrity": "sha512-ssa5JuRjMeZEUjg7bEL99AwpitxU/zWGAGpdj0di41pOEmJti8NR6kyUIJBkR78DTYNPZOU08luUo0GTHuB+ow==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cliui": "^4.0.0",
|
||||
"cliui": "^5.0.0",
|
||||
"decamelize": "^1.2.0",
|
||||
"find-up": "^3.0.0",
|
||||
"get-caller-file": "^2.0.1",
|
||||
"os-locale": "^3.1.0",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^2.0.0",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^3.0.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^4.0.0",
|
||||
"yargs-parser": "^13.0.0"
|
||||
"yargs-parser": "^13.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
@@ -11108,6 +11137,23 @@
|
||||
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
|
||||
"dev": true
|
||||
},
|
||||
"camelcase": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
||||
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
|
||||
"dev": true
|
||||
},
|
||||
"cliui": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
|
||||
"integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"string-width": "^3.1.0",
|
||||
"strip-ansi": "^5.2.0",
|
||||
"wrap-ansi": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"string-width": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
|
||||
@@ -11127,6 +11173,27 @@
|
||||
"requires": {
|
||||
"ansi-regex": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"wrap-ansi": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
|
||||
"integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.0",
|
||||
"string-width": "^3.0.0",
|
||||
"strip-ansi": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"yargs-parser": {
|
||||
"version": "13.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz",
|
||||
"integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ol",
|
||||
"version": "6.0.0-beta.13",
|
||||
"version": "6.0.0-beta.15",
|
||||
"description": "OpenLayers mapping library",
|
||||
"keywords": [
|
||||
"map",
|
||||
@@ -70,7 +70,7 @@
|
||||
"jsdoc": "3.6.3",
|
||||
"jsdoc-plugin-typescript": "^2.0.1",
|
||||
"karma": "^4.1.0",
|
||||
"karma-chrome-launcher": "3.0.0",
|
||||
"karma-chrome-launcher": "3.1.0",
|
||||
"karma-coverage": "^1.1.2",
|
||||
"karma-coverage-istanbul-reporter": "^2.0.5",
|
||||
"karma-firefox-launcher": "^1.1.0",
|
||||
@@ -97,11 +97,11 @@
|
||||
"typescript": "^3.4.5",
|
||||
"url-polyfill": "^1.1.5",
|
||||
"walk": "^2.3.9",
|
||||
"webpack": "4.39.1",
|
||||
"webpack": "4.39.2",
|
||||
"webpack-cli": "^3.3.2",
|
||||
"webpack-dev-middleware": "^3.6.2",
|
||||
"webpack-dev-server": "^3.3.1",
|
||||
"yargs": "^13.2.2"
|
||||
"yargs": "^14.0.0"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "openlayers",
|
||||
|
||||
BIN
rendering/cases/layer-tile-render-listener/expected.png
Normal file
|
After Width: | Height: | Size: 118 KiB |
46
rendering/cases/layer-tile-render-listener/main.js
Normal file
@@ -0,0 +1,46 @@
|
||||
import Map from '../../../src/ol/Map.js';
|
||||
import View from '../../../src/ol/View.js';
|
||||
import TileLayer from '../../../src/ol/layer/Tile.js';
|
||||
import {transform, fromLonLat} from '../../../src/ol/proj.js';
|
||||
import XYZ from '../../../src/ol/source/XYZ.js';
|
||||
import CircleStyle from '../../../src/ol/style/Circle.js';
|
||||
import Fill from '../../../src/ol/style/Fill.js';
|
||||
import Stroke from '../../../src/ol/style/Stroke.js';
|
||||
import Point from '../../../src/ol/geom/Point.js';
|
||||
import {getVectorContext} from '../../../src/ol/render.js';
|
||||
|
||||
const center = fromLonLat([8.6, 50.1]);
|
||||
|
||||
const layer = new TileLayer({
|
||||
source: new XYZ({
|
||||
url: '/data/tiles/satellite/{z}/{x}/{y}.jpg',
|
||||
transition: 0
|
||||
})
|
||||
});
|
||||
|
||||
const onRender = function(event) {
|
||||
const context = event.context;
|
||||
context.restore();
|
||||
const vectorContext = getVectorContext(event);
|
||||
vectorContext.setImageStyle(new CircleStyle({
|
||||
radius: 12,
|
||||
fill: new Fill({color: 'yellow'}),
|
||||
stroke: new Stroke({color: 'red', width: 1})
|
||||
}));
|
||||
vectorContext.drawPoint(new Point(
|
||||
transform([13, 37], 'EPSG:4326', 'EPSG:3857')));
|
||||
};
|
||||
layer.on('postrender', onRender);
|
||||
|
||||
const map = new Map({
|
||||
layers: [
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: center,
|
||||
zoom: 3
|
||||
})
|
||||
});
|
||||
map.addLayer(layer);
|
||||
|
||||
render();
|
||||
|
After Width: | Height: | Size: 5.7 KiB |
@@ -0,0 +1,55 @@
|
||||
import Map from '../../../src/ol/Map.js';
|
||||
import View from '../../../src/ol/View.js';
|
||||
import GeoJSON from '../../../src/ol/format/GeoJSON.js';
|
||||
import VectorLayer from '../../../src/ol/layer/Vector.js';
|
||||
import VectorSource from '../../../src/ol/source/Vector.js';
|
||||
import {Fill, Stroke, Style, Text} from '../../../src/ol/style.js';
|
||||
|
||||
const map = new Map({
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [-17465028, 2331736],
|
||||
zoom: 5
|
||||
})
|
||||
});
|
||||
|
||||
const labelStyle = new Style({
|
||||
text: new Text({
|
||||
font: '16px Ubuntu',
|
||||
overflow: true,
|
||||
fill: new Fill({
|
||||
color: '#000'
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
color: '#fff',
|
||||
width: 3
|
||||
})
|
||||
})
|
||||
});
|
||||
const countryStyle = new Style({
|
||||
fill: new Fill({
|
||||
color: 'rgba(255, 255, 255, 0.6)'
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
color: '#319FD3',
|
||||
width: 1
|
||||
})
|
||||
});
|
||||
const style = [countryStyle, labelStyle];
|
||||
|
||||
const vectorLayer = new VectorLayer({
|
||||
source: new VectorSource({
|
||||
url: '/data/countries.json',
|
||||
format: new GeoJSON()
|
||||
}),
|
||||
style: function(feature) {
|
||||
labelStyle.getText().setText(feature.get('name'));
|
||||
return style;
|
||||
},
|
||||
declutter: true
|
||||
});
|
||||
|
||||
map.addLayer(vectorLayer);
|
||||
|
||||
|
||||
render({tolerance: 0.007});
|
||||
@@ -6,6 +6,7 @@ import BaseObject from '../Object.js';
|
||||
import LayerProperty from './Property.js';
|
||||
import {clamp} from '../math.js';
|
||||
import {assign} from '../obj.js';
|
||||
import {assert} from '../asserts.js';
|
||||
|
||||
|
||||
/**
|
||||
@@ -52,8 +53,11 @@ class BaseLayer extends BaseObject {
|
||||
* @type {Object<string, *>}
|
||||
*/
|
||||
const properties = assign({}, options);
|
||||
|
||||
properties[LayerProperty.OPACITY] =
|
||||
options.opacity !== undefined ? options.opacity : 1;
|
||||
assert(typeof properties[LayerProperty.OPACITY] === 'number', 64); // Layer opacity must be a number
|
||||
|
||||
properties[LayerProperty.VISIBLE] =
|
||||
options.visible !== undefined ? options.visible : true;
|
||||
properties[LayerProperty.Z_INDEX] = options.zIndex;
|
||||
@@ -292,6 +296,7 @@ class BaseLayer extends BaseObject {
|
||||
* @api
|
||||
*/
|
||||
setOpacity(opacity) {
|
||||
assert(typeof opacity === 'number', 64); // Layer opacity must be a number
|
||||
this.set(LayerProperty.OPACITY, opacity);
|
||||
}
|
||||
|
||||
|
||||
@@ -106,9 +106,9 @@ class VectorContext {
|
||||
|
||||
/**
|
||||
* @param {import("../style/Text.js").default} textStyle Text style.
|
||||
* @param {import("./canvas.js").DeclutterGroup=} opt_declutterGroup Declutter.
|
||||
* @param {import("./canvas.js").DeclutterGroups=} opt_declutterGroups Declutter.
|
||||
*/
|
||||
setTextStyle(textStyle, opt_declutterGroup) {}
|
||||
setTextStyle(textStyle, opt_declutterGroups) {}
|
||||
}
|
||||
|
||||
export default VectorContext;
|
||||
|
||||
@@ -62,7 +62,6 @@ import LabelCache from './canvas/LabelCache.js';
|
||||
* @property {Array<number>} [padding]
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Container for decluttered replay instructions that need to be rendered or
|
||||
* omitted together, i.e. when styles render both an image and text, or for the
|
||||
@@ -76,6 +75,12 @@ import LabelCache from './canvas/LabelCache.js';
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Declutter groups for support of multi geometries.
|
||||
* @typedef {Array<DeclutterGroup>} DeclutterGroups
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {string}
|
||||
|
||||
@@ -40,10 +40,10 @@ class BuilderGroup {
|
||||
this.declutter_ = declutter;
|
||||
|
||||
/**
|
||||
* @type {import("../canvas.js").DeclutterGroup}
|
||||
* @type {import("../canvas.js").DeclutterGroups}
|
||||
* @private
|
||||
*/
|
||||
this.declutterGroup_ = null;
|
||||
this.declutterGroups_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -78,17 +78,17 @@ class BuilderGroup {
|
||||
|
||||
/**
|
||||
* @param {boolean} group Group with previous builder.
|
||||
* @return {Array<*>} The resulting instruction group.
|
||||
* @return {import("../canvas").DeclutterGroups} The resulting instruction groups.
|
||||
*/
|
||||
addDeclutter(group) {
|
||||
let declutter = null;
|
||||
if (this.declutter_) {
|
||||
if (group) {
|
||||
declutter = this.declutterGroup_;
|
||||
/** @type {number} */ (declutter[4])++;
|
||||
declutter = this.declutterGroups_;
|
||||
/** @type {number} */ (declutter[0][4])++;
|
||||
} else {
|
||||
declutter = this.declutterGroup_ = createEmpty();
|
||||
declutter.push(1);
|
||||
declutter = this.declutterGroups_ = [createEmpty()];
|
||||
declutter[0].push(1);
|
||||
}
|
||||
}
|
||||
return declutter;
|
||||
|
||||
@@ -535,7 +535,7 @@ class Executor extends Disposable {
|
||||
const ii = instructions.length; // end of instructions
|
||||
let d = 0; // data index
|
||||
let dd; // end of per-instruction data
|
||||
let anchorX, anchorY, prevX, prevY, roundX, roundY, declutterGroup, image, text, textKey;
|
||||
let anchorX, anchorY, prevX, prevY, roundX, roundY, declutterGroup, declutterGroups, image, text, textKey;
|
||||
let strokeKey, fillKey;
|
||||
let pendingFill = 0;
|
||||
let pendingStroke = 0;
|
||||
@@ -633,7 +633,7 @@ class Executor extends Disposable {
|
||||
// Remaining arguments in DRAW_IMAGE are in alphabetical order
|
||||
anchorX = /** @type {number} */ (instruction[4]);
|
||||
anchorY = /** @type {number} */ (instruction[5]);
|
||||
declutterGroup = featureCallback ? null : /** @type {import("../canvas.js").DeclutterGroup} */ (instruction[6]);
|
||||
declutterGroups = featureCallback ? null : instruction[6];
|
||||
let height = /** @type {number} */ (instruction[7]);
|
||||
const opacity = /** @type {number} */ (instruction[8]);
|
||||
const originX = /** @type {number} */ (instruction[9]);
|
||||
@@ -643,7 +643,6 @@ class Executor extends Disposable {
|
||||
const scale = /** @type {number} */ (instruction[13]);
|
||||
let width = /** @type {number} */ (instruction[14]);
|
||||
|
||||
|
||||
if (!image && instruction.length >= 19) {
|
||||
// create label images
|
||||
text = /** @type {string} */ (instruction[18]);
|
||||
@@ -679,25 +678,41 @@ class Executor extends Disposable {
|
||||
rotation += viewRotation;
|
||||
}
|
||||
let widthIndex = 0;
|
||||
let declutterGroupIndex = 0;
|
||||
for (; d < dd; d += 2) {
|
||||
if (geometryWidths && geometryWidths[widthIndex++] < width / this.pixelRatio) {
|
||||
continue;
|
||||
}
|
||||
if (declutterGroups) {
|
||||
const index = Math.floor(declutterGroupIndex);
|
||||
if (declutterGroups.length < index + 1) {
|
||||
declutterGroup = createEmpty();
|
||||
declutterGroup.push(declutterGroups[0][4]);
|
||||
declutterGroups.push(declutterGroup);
|
||||
}
|
||||
declutterGroup = declutterGroups[index];
|
||||
}
|
||||
this.replayImage_(context,
|
||||
pixelCoordinates[d], pixelCoordinates[d + 1], image, anchorX, anchorY,
|
||||
declutterGroup, height, opacity, originX, originY, rotation, scale,
|
||||
snapToPixel, width, padding,
|
||||
backgroundFill ? /** @type {Array<*>} */ (lastFillInstruction) : null,
|
||||
backgroundStroke ? /** @type {Array<*>} */ (lastStrokeInstruction) : null);
|
||||
}
|
||||
if (declutterGroup) {
|
||||
if (declutterGroupIndex === Math.floor(declutterGroupIndex)) {
|
||||
this.declutterItems.push(this, declutterGroup, feature);
|
||||
}
|
||||
declutterGroupIndex += 1 / declutterGroup[4];
|
||||
|
||||
}
|
||||
}
|
||||
++i;
|
||||
break;
|
||||
case CanvasInstruction.DRAW_CHARS:
|
||||
const begin = /** @type {number} */ (instruction[1]);
|
||||
const end = /** @type {number} */ (instruction[2]);
|
||||
const baseline = /** @type {number} */ (instruction[3]);
|
||||
declutterGroup = featureCallback ? null : /** @type {import("../canvas.js").DeclutterGroup} */ (instruction[4]);
|
||||
declutterGroup = featureCallback ? null : instruction[4];
|
||||
const overflow = /** @type {number} */ (instruction[5]);
|
||||
fillKey = /** @type {string} */ (instruction[6]);
|
||||
const maxAngle = /** @type {number} */ (instruction[7]);
|
||||
|
||||
@@ -16,9 +16,9 @@ class CanvasImageBuilder extends CanvasBuilder {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {import("../canvas.js").DeclutterGroup}
|
||||
* @type {import("../canvas.js").DeclutterGroups}
|
||||
*/
|
||||
this.declutterGroup_ = null;
|
||||
this.declutterGroups_ = null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -121,14 +121,14 @@ class CanvasImageBuilder extends CanvasBuilder {
|
||||
this.instructions.push([
|
||||
CanvasInstruction.DRAW_IMAGE, myBegin, myEnd, this.image_,
|
||||
// Remaining arguments to DRAW_IMAGE are in alphabetical order
|
||||
this.anchorX_, this.anchorY_, this.declutterGroup_, this.height_, this.opacity_,
|
||||
this.anchorX_, this.anchorY_, this.declutterGroups_, this.height_, this.opacity_,
|
||||
this.originX_, this.originY_, this.rotateWithView_, this.rotation_,
|
||||
this.scale_ * this.pixelRatio, this.width_
|
||||
]);
|
||||
this.hitDetectionInstructions.push([
|
||||
CanvasInstruction.DRAW_IMAGE, myBegin, myEnd, this.hitDetectionImage_,
|
||||
// Remaining arguments to DRAW_IMAGE are in alphabetical order
|
||||
this.anchorX_, this.anchorY_, this.declutterGroup_, this.height_, this.opacity_,
|
||||
this.anchorX_, this.anchorY_, this.declutterGroups_, this.height_, this.opacity_,
|
||||
this.originX_, this.originY_, this.rotateWithView_, this.rotation_,
|
||||
this.scale_, this.width_
|
||||
]);
|
||||
@@ -151,14 +151,14 @@ class CanvasImageBuilder extends CanvasBuilder {
|
||||
this.instructions.push([
|
||||
CanvasInstruction.DRAW_IMAGE, myBegin, myEnd, this.image_,
|
||||
// Remaining arguments to DRAW_IMAGE are in alphabetical order
|
||||
this.anchorX_, this.anchorY_, this.declutterGroup_, this.height_, this.opacity_,
|
||||
this.anchorX_, this.anchorY_, this.declutterGroups_, this.height_, this.opacity_,
|
||||
this.originX_, this.originY_, this.rotateWithView_, this.rotation_,
|
||||
this.scale_ * this.pixelRatio, this.width_
|
||||
]);
|
||||
this.hitDetectionInstructions.push([
|
||||
CanvasInstruction.DRAW_IMAGE, myBegin, myEnd, this.hitDetectionImage_,
|
||||
// Remaining arguments to DRAW_IMAGE are in alphabetical order
|
||||
this.anchorX_, this.anchorY_, this.declutterGroup_, this.height_, this.opacity_,
|
||||
this.anchorX_, this.anchorY_, this.declutterGroups_, this.height_, this.opacity_,
|
||||
this.originX_, this.originY_, this.rotateWithView_, this.rotation_,
|
||||
this.scale_, this.width_
|
||||
]);
|
||||
@@ -189,7 +189,7 @@ class CanvasImageBuilder extends CanvasBuilder {
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
setImageStyle(imageStyle, declutterGroup) {
|
||||
setImageStyle(imageStyle, declutterGroups) {
|
||||
const anchor = imageStyle.getAnchor();
|
||||
const size = imageStyle.getSize();
|
||||
const hitDetectionImage = imageStyle.getHitDetectionImage(1);
|
||||
@@ -197,7 +197,7 @@ class CanvasImageBuilder extends CanvasBuilder {
|
||||
const origin = imageStyle.getOrigin();
|
||||
this.anchorX_ = anchor[0];
|
||||
this.anchorY_ = anchor[1];
|
||||
this.declutterGroup_ = /** @type {import("../canvas.js").DeclutterGroup} */ (declutterGroup);
|
||||
this.declutterGroups_ = /** @type {import("../canvas.js").DeclutterGroups} */ (declutterGroups);
|
||||
this.hitDetectionImage_ = hitDetectionImage;
|
||||
this.image_ = image;
|
||||
this.height_ = size[1];
|
||||
|
||||
@@ -40,9 +40,9 @@ class CanvasTextBuilder extends CanvasBuilder {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {import("../canvas.js").DeclutterGroup}
|
||||
* @type {import("../canvas.js").DeclutterGroups}
|
||||
*/
|
||||
this.declutterGroup_;
|
||||
this.declutterGroups_;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -201,7 +201,10 @@ class CanvasTextBuilder extends CanvasBuilder {
|
||||
}
|
||||
end = this.coordinates.length;
|
||||
flatOffset = ends[o];
|
||||
this.drawChars_(begin, end, this.declutterGroup_);
|
||||
const declutterGroup = this.declutterGroups_ ?
|
||||
(o === 0 ? this.declutterGroups_[0] : [].concat(this.declutterGroups_[0])) :
|
||||
null;
|
||||
this.drawChars_(begin, end, declutterGroup);
|
||||
begin = end;
|
||||
}
|
||||
this.endGeometry(feature);
|
||||
@@ -274,7 +277,7 @@ class CanvasTextBuilder extends CanvasBuilder {
|
||||
// render time.
|
||||
const pixelRatio = this.pixelRatio;
|
||||
this.instructions.push([CanvasInstruction.DRAW_IMAGE, begin, end,
|
||||
null, NaN, NaN, this.declutterGroup_, NaN, 1, 0, 0,
|
||||
null, NaN, NaN, this.declutterGroups_, NaN, 1, 0, 0,
|
||||
this.textRotateWithView_, this.textRotation_, 1, NaN,
|
||||
textState.padding == defaultPadding ?
|
||||
defaultPadding : textState.padding.map(function(p) {
|
||||
@@ -285,7 +288,7 @@ class CanvasTextBuilder extends CanvasBuilder {
|
||||
this.textOffsetX_, this.textOffsetY_, geometryWidths
|
||||
]);
|
||||
this.hitDetectionInstructions.push([CanvasInstruction.DRAW_IMAGE, begin, end,
|
||||
null, NaN, NaN, this.declutterGroup_, NaN, 1, 0, 0,
|
||||
null, NaN, NaN, this.declutterGroups_, NaN, 1, 0, 0,
|
||||
this.textRotateWithView_, this.textRotation_, 1 / this.pixelRatio, NaN,
|
||||
textState.padding,
|
||||
!!textState.backgroundFill, !!textState.backgroundStroke,
|
||||
@@ -379,12 +382,12 @@ class CanvasTextBuilder extends CanvasBuilder {
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
setTextStyle(textStyle, declutterGroup) {
|
||||
setTextStyle(textStyle, declutterGroups) {
|
||||
let textState, fillState, strokeState;
|
||||
if (!textStyle) {
|
||||
this.text_ = '';
|
||||
} else {
|
||||
this.declutterGroup_ = /** @type {import("../canvas.js").DeclutterGroup} */ (declutterGroup);
|
||||
this.declutterGroups_ = /** @type {import("../canvas.js").DeclutterGroups} */ (declutterGroups);
|
||||
|
||||
const textFillStyle = textStyle.getFill();
|
||||
if (!textFillStyle) {
|
||||
|
||||
@@ -377,7 +377,8 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
|
||||
return;
|
||||
}
|
||||
const uid = getUid(this);
|
||||
const alpha = opacity * (transition ? tile.getAlpha(uid, frameState.time) : 1);
|
||||
const tileAlpha = transition ? tile.getAlpha(uid, frameState.time) : 1;
|
||||
const alpha = opacity * tileAlpha;
|
||||
const alphaChanged = alpha !== this.context.globalAlpha;
|
||||
if (alphaChanged) {
|
||||
this.context.save();
|
||||
@@ -389,7 +390,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer {
|
||||
if (alphaChanged) {
|
||||
this.context.restore();
|
||||
}
|
||||
if (alpha !== 1) {
|
||||
if (tileAlpha !== 1) {
|
||||
frameState.animate = true;
|
||||
} else if (transition) {
|
||||
tile.endTransition(uid);
|
||||
|
||||
@@ -299,6 +299,8 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
|
||||
|
||||
vectorSource.loadFeatures(extent, resolution, projection);
|
||||
|
||||
const squaredTolerance = getSquaredRenderTolerance(resolution, pixelRatio);
|
||||
|
||||
/**
|
||||
* @param {import("../../Feature.js").default} feature Feature.
|
||||
* @this {CanvasVectorLayerRenderer}
|
||||
@@ -310,11 +312,11 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
|
||||
styles = styleFunction(feature, resolution);
|
||||
}
|
||||
if (styles) {
|
||||
const dirty = this.renderFeature(
|
||||
feature, resolution, pixelRatio, styles, replayGroup);
|
||||
const dirty = this.renderFeature(feature, squaredTolerance, styles, replayGroup);
|
||||
this.dirty_ = this.dirty_ || dirty;
|
||||
}
|
||||
}.bind(this);
|
||||
|
||||
if (vectorLayerRenderOrder) {
|
||||
/** @type {Array<import("../../Feature.js").default>} */
|
||||
const features = [];
|
||||
@@ -350,13 +352,12 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
|
||||
|
||||
/**
|
||||
* @param {import("../../Feature.js").default} feature Feature.
|
||||
* @param {number} resolution Resolution.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {number} squaredTolerance Squared render tolerance.
|
||||
* @param {import("../../style/Style.js").default|Array<import("../../style/Style.js").default>} styles The style or array of styles.
|
||||
* @param {import("../../render/canvas/BuilderGroup.js").default} builderGroup Builder group.
|
||||
* @return {boolean} `true` if an image is loading.
|
||||
*/
|
||||
renderFeature(feature, resolution, pixelRatio, styles, builderGroup) {
|
||||
renderFeature(feature, squaredTolerance, styles, builderGroup) {
|
||||
if (!styles) {
|
||||
return false;
|
||||
}
|
||||
@@ -364,14 +365,12 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
|
||||
if (Array.isArray(styles)) {
|
||||
for (let i = 0, ii = styles.length; i < ii; ++i) {
|
||||
loading = renderFeature(
|
||||
builderGroup, feature, styles[i],
|
||||
getSquaredRenderTolerance(resolution, pixelRatio),
|
||||
builderGroup, feature, styles[i], squaredTolerance,
|
||||
this.handleStyleImageChange_, this) || loading;
|
||||
}
|
||||
} else {
|
||||
loading = renderFeature(
|
||||
builderGroup, feature, styles,
|
||||
getSquaredRenderTolerance(resolution, pixelRatio),
|
||||
builderGroup, feature, styles, squaredTolerance,
|
||||
this.handleStyleImageChange_, this);
|
||||
}
|
||||
return loading;
|
||||
|
||||
@@ -132,7 +132,7 @@ class VectorTile extends UrlTile {
|
||||
* @private
|
||||
* @type {Object<string, import("../VectorTile.js").default>}
|
||||
*/
|
||||
this.sourceTiles_ = {};
|
||||
this.sourceTileByCoordKey_ = {};
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -173,7 +173,7 @@ class VectorTile extends UrlTile {
|
||||
*/
|
||||
clear() {
|
||||
this.tileCache.clear();
|
||||
this.sourceTiles_ = {};
|
||||
this.sourceTileByCoordKey_ = {};
|
||||
this.sourceTilesByTileKey_ = {};
|
||||
}
|
||||
|
||||
@@ -199,23 +199,25 @@ class VectorTile extends UrlTile {
|
||||
const sourceZ = sourceTileGrid.getZForResolution(resolution, 1);
|
||||
const minZoom = sourceTileGrid.getMinZoom();
|
||||
|
||||
const previousSourceTiles = this.sourceTilesByTileKey_[getKey(tile.tileCoord)];
|
||||
const previousSourceTiles = this.sourceTilesByTileKey_[tile.getKey()];
|
||||
let sourceTiles, covered, empty, loadedZ;
|
||||
if (previousSourceTiles && previousSourceTiles.length > 0 && previousSourceTiles[0].tileCoord[0] === sourceZ) {
|
||||
return previousSourceTiles;
|
||||
}
|
||||
|
||||
const sourceTiles = [];
|
||||
let loadedZ = sourceZ + 1;
|
||||
let covered, empty;
|
||||
sourceTiles = previousSourceTiles;
|
||||
covered = true;
|
||||
empty = false;
|
||||
loadedZ = sourceZ;
|
||||
} else {
|
||||
sourceTiles = [];
|
||||
loadedZ = sourceZ + 1;
|
||||
do {
|
||||
--loadedZ;
|
||||
covered = true;
|
||||
empty = true;
|
||||
sourceTileGrid.forEachTileCoord(extent, loadedZ, function(sourceTileCoord) {
|
||||
const tileKey = getKey(sourceTileCoord);
|
||||
const coordKey = getKey(sourceTileCoord);
|
||||
let sourceTile;
|
||||
if (tileKey in this.sourceTiles_) {
|
||||
sourceTile = this.sourceTiles_[tileKey];
|
||||
if (coordKey in this.sourceTileByCoordKey_) {
|
||||
sourceTile = this.sourceTileByCoordKey_[coordKey];
|
||||
const state = sourceTile.getState();
|
||||
if (state === TileState.LOADED || state === TileState.ERROR || state === TileState.EMPTY) {
|
||||
empty = empty && state === TileState.EMPTY;
|
||||
@@ -230,7 +232,7 @@ class VectorTile extends UrlTile {
|
||||
sourceTile.extent = sourceTileGrid.getTileCoordExtent(sourceTileCoord);
|
||||
sourceTile.projection = projection;
|
||||
sourceTile.resolution = sourceTileGrid.getResolution(sourceTileCoord[0]);
|
||||
this.sourceTiles_[tileKey] = sourceTile;
|
||||
this.sourceTileByCoordKey_[coordKey] = sourceTile;
|
||||
empty = false;
|
||||
listen(sourceTile, EventType.CHANGE, this.handleTileChange, this);
|
||||
sourceTile.load();
|
||||
@@ -246,7 +248,7 @@ class VectorTile extends UrlTile {
|
||||
tile.loadingSourceTiles++;
|
||||
const key = listen(sourceTile, EventType.CHANGE, function() {
|
||||
const state = sourceTile.getState();
|
||||
const sourceTileKey = getKey(sourceTile.tileCoord);
|
||||
const sourceTileKey = sourceTile.getKey();
|
||||
if (state === TileState.LOADED || state === TileState.ERROR) {
|
||||
if (state === TileState.LOADED) {
|
||||
unlistenByKey(key);
|
||||
@@ -268,6 +270,8 @@ class VectorTile extends UrlTile {
|
||||
sourceTiles.length = 0;
|
||||
}
|
||||
} while (!covered && loadedZ > minZoom);
|
||||
}
|
||||
|
||||
if (!empty && tile.getState() === TileState.IDLE) {
|
||||
tile.setState(TileState.LOADING);
|
||||
}
|
||||
@@ -289,7 +293,7 @@ class VectorTile extends UrlTile {
|
||||
* @param {Array<import("../VectorTile").default>} sourceTiles Source tiles.
|
||||
*/
|
||||
addSourceTiles(tile, sourceTiles) {
|
||||
this.sourceTilesByTileKey_[getKey(tile.tileCoord)] = sourceTiles;
|
||||
this.sourceTilesByTileKey_[tile.getKey()] = sourceTiles;
|
||||
for (let i = 0, ii = sourceTiles.length; i < ii; ++i) {
|
||||
sourceTiles[i].consumers++;
|
||||
}
|
||||
@@ -299,7 +303,7 @@ class VectorTile extends UrlTile {
|
||||
* @param {VectorRenderTile} tile Tile.
|
||||
*/
|
||||
removeSourceTiles(tile) {
|
||||
const tileKey = getKey(tile.tileCoord);
|
||||
const tileKey = tile.getKey();
|
||||
if (tileKey in this.sourceTilesByTileKey_) {
|
||||
const sourceTiles = this.sourceTilesByTileKey_[tileKey];
|
||||
for (let i = 0, ii = sourceTiles.length; i < ii; ++i) {
|
||||
@@ -307,7 +311,7 @@ class VectorTile extends UrlTile {
|
||||
sourceTile.consumers--;
|
||||
if (sourceTile.consumers === 0) {
|
||||
sourceTile.dispose();
|
||||
delete this.sourceTiles_[getKey(sourceTile.tileCoord)];
|
||||
delete this.sourceTileByCoordKey_[getKey(sourceTile.tileCoord)];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -318,28 +322,27 @@ class VectorTile extends UrlTile {
|
||||
* @inheritDoc
|
||||
*/
|
||||
getTile(z, x, y, pixelRatio, projection) {
|
||||
const tileCoordKey = getKeyZXY(z, x, y);
|
||||
const coordKey = getKeyZXY(z, x, y);
|
||||
const key = this.getKey();
|
||||
let tile;
|
||||
if (this.tileCache.containsKey(tileCoordKey)) {
|
||||
tile = /** @type {!import("../Tile.js").default} */ (this.tileCache.get(tileCoordKey));
|
||||
if (this.tileCache.containsKey(coordKey)) {
|
||||
tile = /** @type {!import("../Tile.js").default} */ (this.tileCache.get(coordKey));
|
||||
if (tile.key === key) {
|
||||
return tile;
|
||||
}
|
||||
}
|
||||
const tileCoord = [z, x, y];
|
||||
let urlTileCoord = this.getTileCoordForTileUrlFunction(tileCoord, projection);
|
||||
const sourceExtent = this.getTileGrid().getExtent();
|
||||
let tileInExtent = true;
|
||||
if (sourceExtent) {
|
||||
if (urlTileCoord && sourceExtent) {
|
||||
const tileGrid = this.getTileGridForProjection(projection);
|
||||
const tileExtent = tileGrid.getTileCoordExtent(tileCoord);
|
||||
const tileExtent = tileGrid.getTileCoordExtent(urlTileCoord);
|
||||
// make extent 1 pixel smaller so we don't load tiles for < 0.5 pixel render space
|
||||
bufferExtent(tileExtent, -1 / tileGrid.getResolution(z), tileExtent);
|
||||
tileInExtent = intersects(sourceExtent, tileExtent);
|
||||
if (!intersects(sourceExtent, tileExtent)) {
|
||||
urlTileCoord = null;
|
||||
}
|
||||
}
|
||||
const urlTileCoord = tileInExtent ?
|
||||
this.getTileCoordForTileUrlFunction(tileCoord, projection) :
|
||||
null;
|
||||
const newTile = new VectorRenderTile(
|
||||
tileCoord,
|
||||
urlTileCoord !== null ? TileState.IDLE : TileState.EMPTY,
|
||||
@@ -352,9 +355,9 @@ class VectorTile extends UrlTile {
|
||||
if (tile) {
|
||||
newTile.interimTile = tile;
|
||||
newTile.refreshInterimChain();
|
||||
this.tileCache.replace(tileCoordKey, newTile);
|
||||
this.tileCache.replace(coordKey, newTile);
|
||||
} else {
|
||||
this.tileCache.set(tileCoordKey, newTile);
|
||||
this.tileCache.set(coordKey, newTile);
|
||||
}
|
||||
return newTile;
|
||||
}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="Layer_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
width="512px"
|
||||
height="512px"
|
||||
viewBox="0 0 512 512"
|
||||
enable-background="new 0 0 512 512"
|
||||
xml:space="preserve"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="me0.svg"><metadata
|
||||
id="metadata3776"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs3774" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1024"
|
||||
inkscape:window-height="1258"
|
||||
id="namedview3772"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.4609375"
|
||||
inkscape:cx="309.13338"
|
||||
inkscape:cy="256"
|
||||
inkscape:window-x="1016"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="Layer_1" />
|
||||
|
||||
<g
|
||||
id="g3754"
|
||||
style="fill:#085095;fill-opacity:1;stroke:#ffffff;stroke-opacity:1;stroke-width:25;stroke-miterlimit:4;stroke-dasharray:none;stroke-linejoin:round;stroke-linecap:round"><path
|
||||
style="stroke:#ffffff;stroke-width:25;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;fill:#085095;fill-opacity:1;stroke-linejoin:round;stroke-linecap:round"
|
||||
id="path3770"
|
||||
d="m 256,25.6 c -95.4279,0 -172.8,77.3721 -172.8,172.8 0,95.4279 144,288 172.8,288 28.8,0 172.8,-192.5721 172.8,-288 C 428.8,102.9721 351.4279,25.6 256,25.6 z m 0,288 c -63.5346,0 -115.2,-51.6942 -115.2,-115.2 0,-63.5058 51.6654,-115.2 115.2,-115.2 63.5346,0 115.2,51.6942 115.2,115.2 0,63.5058 -51.6654,115.2 -115.2,115.2 z"
|
||||
inkscape:connector-curvature="0" /><polygon
|
||||
style="fill:#085095;stroke:#ffffff;stroke-width:69.44444444;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;fill-opacity:1"
|
||||
transform="matrix(0.36,0,0,0.36,160.72934,103.79972)"
|
||||
id="polygon3"
|
||||
points="374.185,309.08 401.33,467.31 259.216,392.612 117.104,467.31 144.25,309.08 29.274,197.007 188.165,173.919 259.216,29.942 330.27,173.919 489.16,197.007 "
|
||||
stroke-miterlimit="10" /></g></svg>
|
||||
|
Before Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 6.8 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 9.0 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 806 B |
|
Before Width: | Height: | Size: 806 B |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 254 B |
|
Before Width: | Height: | Size: 392 B |
|
Before Width: | Height: | Size: 341 B |
|
Before Width: | Height: | Size: 504 B |
|
Before Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 6.6 KiB |
@@ -1,100 +0,0 @@
|
||||
import Map from '../../../../src/ol/Map.js';
|
||||
import View from '../../../../src/ol/View.js';
|
||||
import Point from '../../../../src/ol/geom/Point.js';
|
||||
import TileLayer from '../../../../src/ol/layer/Tile.js';
|
||||
import {assign} from '../../../../src/ol/obj.js';
|
||||
import {transform} from '../../../../src/ol/proj.js';
|
||||
import XYZ from '../../../../src/ol/source/XYZ.js';
|
||||
import CircleStyle from '../../../../src/ol/style/Circle.js';
|
||||
import Fill from '../../../../src/ol/style/Fill.js';
|
||||
import Stroke from '../../../../src/ol/style/Stroke.js';
|
||||
|
||||
describe('ol.rendering.layer.Tile', function() {
|
||||
|
||||
let map;
|
||||
|
||||
function createMap(renderer, opt_center, opt_size, opt_pixelRatio, opt_resolutions) {
|
||||
const MapConstructor = Map;
|
||||
const size = opt_size !== undefined ? opt_size : [50, 50];
|
||||
|
||||
map = new MapConstructor({
|
||||
pixelRatio: opt_pixelRatio || 1,
|
||||
target: createMapDiv(size[0], size[1]),
|
||||
view: new View({
|
||||
center: opt_center !== undefined ? opt_center : transform(
|
||||
[-122.416667, 37.783333], 'EPSG:4326', 'EPSG:3857'),
|
||||
resolutions: opt_resolutions,
|
||||
zoom: 5
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
afterEach(function() {
|
||||
if (map) {
|
||||
disposeMap(map);
|
||||
}
|
||||
map = null;
|
||||
});
|
||||
|
||||
function waitForTiles(renderer, sources, layerOptions, onTileLoaded) {
|
||||
const LayerConstructor = TileLayer;
|
||||
let tilesLoading = 0;
|
||||
let tileLoaded = 0;
|
||||
|
||||
const update = function() {
|
||||
if (tilesLoading === tileLoaded) {
|
||||
onTileLoaded();
|
||||
}
|
||||
};
|
||||
|
||||
sources.forEach(function(source, i) {
|
||||
source.on('tileloadstart', function(event) {
|
||||
tilesLoading++;
|
||||
});
|
||||
source.on('tileloadend', function(event) {
|
||||
tileLoaded++;
|
||||
update();
|
||||
});
|
||||
source.on('tileloaderror', function(event) {
|
||||
expect().fail('Tile failed to load');
|
||||
});
|
||||
|
||||
const options = {
|
||||
source: source
|
||||
};
|
||||
assign(options, layerOptions[i] || layerOptions);
|
||||
map.addLayer(new LayerConstructor(options));
|
||||
});
|
||||
}
|
||||
|
||||
describe('tile layer with render listener', function() {
|
||||
let source, onAddLayer;
|
||||
|
||||
beforeEach(function() {
|
||||
source = new XYZ({
|
||||
url: 'rendering/ol/data/tiles/osm/{z}/{x}/{y}.png',
|
||||
transition: 0
|
||||
});
|
||||
onAddLayer = function(evt) {
|
||||
evt.element.on('render', function(e) {
|
||||
e.vectorContext.setImageStyle(new CircleStyle({
|
||||
radius: 5,
|
||||
fill: new Fill({color: 'yellow'}),
|
||||
stroke: new Stroke({color: 'red', width: 1})
|
||||
}));
|
||||
e.vectorContext.drawPoint(new Point(
|
||||
transform([-123, 38], 'EPSG:4326', 'EPSG:3857')));
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
it('works with the canvas renderer', function(done) {
|
||||
createMap('canvas', undefined, [100, 100]);
|
||||
map.getLayers().on('add', onAddLayer);
|
||||
waitForTiles('canvas', [source], {}, function() {
|
||||
expectResemble(map, 'rendering/ol/layer/expected/render-canvas.png',
|
||||
IMAGE_TOLERANCE, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -112,6 +112,19 @@ describe('ol.layer.Layer', function() {
|
||||
layer.dispose();
|
||||
});
|
||||
|
||||
it('throws on non-numeric opacity', function() {
|
||||
function create() {
|
||||
new Layer({
|
||||
source: new Source({
|
||||
projection: 'EPSG:4326'
|
||||
}),
|
||||
opacity: 'foo'
|
||||
});
|
||||
}
|
||||
|
||||
expect(create).to.throwException();
|
||||
});
|
||||
|
||||
it('accepts a custom render function', function() {
|
||||
let called = false;
|
||||
const layer = new Layer({
|
||||
@@ -511,6 +524,13 @@ describe('ol.layer.Layer', function() {
|
||||
expect(layer.getOpacity()).to.be(0.3);
|
||||
});
|
||||
|
||||
it('throws on types other than number', function() {
|
||||
function set() {
|
||||
layer.setOpacity('foo');
|
||||
}
|
||||
expect(set).to.throwException();
|
||||
});
|
||||
|
||||
it('triggers a change event', function() {
|
||||
const listener = sinon.spy();
|
||||
layer.on('propertychange', listener);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {Map, View} from '../../../../src/ol/index.js';
|
||||
import TileLayer from '../../../../src/ol/layer/Tile.js';
|
||||
import OSM from '../../../../src/ol/source/OSM.js';
|
||||
import {OSM, XYZ} from '../../../../src/ol/source.js';
|
||||
|
||||
|
||||
describe('ol.layer.Tile', function() {
|
||||
@@ -32,4 +33,73 @@ describe('ol.layer.Tile', function() {
|
||||
|
||||
});
|
||||
|
||||
describe('frameState.animate after tile transition with layer opacity', function() {
|
||||
let target, map;
|
||||
|
||||
beforeEach(function(done) {
|
||||
target = document.createElement('div');
|
||||
Object.assign(target.style, {
|
||||
position: 'absolute',
|
||||
left: '-1000px',
|
||||
top: '-1000px',
|
||||
width: '256px',
|
||||
height: '256px'
|
||||
});
|
||||
document.body.appendChild(target);
|
||||
|
||||
map = new Map({
|
||||
target: target,
|
||||
view: new View({center: [0, 0], zoom: 1})
|
||||
});
|
||||
|
||||
map.once('rendercomplete', function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
map.dispose();
|
||||
document.body.removeChild(target);
|
||||
});
|
||||
|
||||
it('sets frameState.animate to false when opacity is 1', function(done) {
|
||||
let lastFrameState;
|
||||
const layer = new TileLayer({
|
||||
opacity: 1,
|
||||
source: new XYZ({
|
||||
url: 'spec/ol/data/osm-0-0-0.png'
|
||||
})
|
||||
});
|
||||
layer.on('postrender', function(event) {
|
||||
lastFrameState = event.frameState;
|
||||
});
|
||||
|
||||
map.once('rendercomplete', function() {
|
||||
expect(lastFrameState.animate).to.be(false);
|
||||
done();
|
||||
});
|
||||
|
||||
map.addLayer(layer);
|
||||
});
|
||||
|
||||
it('sets frameState.animate to false when opacity is 0.5', function(done) {
|
||||
let lastFrameState;
|
||||
const layer = new TileLayer({
|
||||
opacity: 0.5,
|
||||
source: new XYZ({
|
||||
url: 'spec/ol/data/osm-0-0-0.png'
|
||||
})
|
||||
});
|
||||
layer.on('postrender', function(event) {
|
||||
lastFrameState = event.frameState;
|
||||
});
|
||||
|
||||
map.once('rendercomplete', function() {
|
||||
expect(lastFrameState.animate).to.be(false);
|
||||
done();
|
||||
});
|
||||
|
||||
map.addLayer(layer);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -203,6 +203,7 @@ describe('ol.Map', function() {
|
||||
target: target,
|
||||
layers: [
|
||||
new TileLayer({
|
||||
opacity: 0.5,
|
||||
source: new XYZ({
|
||||
url: 'spec/ol/data/osm-{z}-{x}-{y}.png'
|
||||
})
|
||||
|
||||
@@ -75,11 +75,10 @@ describe('ol.renderer.canvas.VectorLayer', function() {
|
||||
style: layerStyle
|
||||
});
|
||||
map.addLayer(layer);
|
||||
const spy = sinon.spy(layer.getRenderer(),
|
||||
'renderFeature');
|
||||
const spy = sinon.spy(layer.getRenderer(), 'renderFeature');
|
||||
map.renderSync();
|
||||
expect(spy.getCall(0).args[3]).to.be(layerStyle);
|
||||
expect(spy.getCall(1).args[3]).to.be(featureStyle);
|
||||
expect(spy.getCall(0).args[2]).to.be(layerStyle);
|
||||
expect(spy.getCall(1).args[2]).to.be(featureStyle);
|
||||
document.body.removeChild(target);
|
||||
});
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import {getCenter} from '../../../../../src/ol/extent.js';
|
||||
import MVT from '../../../../../src/ol/format/MVT.js';
|
||||
import Point from '../../../../../src/ol/geom/Point.js';
|
||||
import VectorTileLayer from '../../../../../src/ol/layer/VectorTile.js';
|
||||
import {getKey} from '../../../../../src/ol/tilecoord.js';
|
||||
import {get as getProjection} from '../../../../../src/ol/proj.js';
|
||||
import {checkedFonts} from '../../../../../src/ol/render/canvas.js';
|
||||
import RenderFeature from '../../../../../src/ol/render/Feature.js';
|
||||
@@ -300,12 +301,8 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
|
||||
tileClass: TileClass,
|
||||
tileGrid: createXYZ()
|
||||
});
|
||||
source.sourceTiles_ = {
|
||||
'0/0/0': sourceTile
|
||||
};
|
||||
source.sourceTilesByTileKey_ = {
|
||||
'0/0/0': [sourceTile]
|
||||
};
|
||||
source.sourceTileByCoordKey_[getKey(sourceTile.tileCoord)] = sourceTile;
|
||||
source.sourceTilesByTileKey_[sourceTile.getKey()] = [sourceTile];
|
||||
executorGroup = {};
|
||||
source.getTile = function() {
|
||||
const tile = VectorTileSource.prototype.getTile.apply(source, arguments);
|
||||
|
||||
@@ -14,12 +14,14 @@ import TileState from '../../../../src/ol/TileState.js';
|
||||
|
||||
describe('ol.source.VectorTile', function() {
|
||||
|
||||
const format = new MVT();
|
||||
const source = new VectorTileSource({
|
||||
let format, source;
|
||||
beforeEach(function() {
|
||||
format = new MVT();
|
||||
source = new VectorTileSource({
|
||||
format: format,
|
||||
url: 'spec/ol/data/{z}-{x}-{y}.vector.pbf'
|
||||
});
|
||||
let tile;
|
||||
});
|
||||
|
||||
describe('constructor', function() {
|
||||
it('sets the format on the instance', function() {
|
||||
@@ -44,15 +46,9 @@ describe('ol.source.VectorTile', function() {
|
||||
describe('#getTile()', function() {
|
||||
|
||||
it('creates a tile with the correct tile class', function() {
|
||||
tile = source.getTile(0, 0, 0, 1, getProjection('EPSG:3857'));
|
||||
const tile = source.getTile(0, 0, 0, 1, getProjection('EPSG:3857'));
|
||||
expect(tile).to.be.a(VectorRenderTile);
|
||||
});
|
||||
|
||||
it('sets the correct tileCoord on the created tile', function() {
|
||||
expect(tile.getTileCoord()).to.eql([0, 0, 0]);
|
||||
});
|
||||
|
||||
it('fetches tile from cache when requested again', function() {
|
||||
expect(source.getTile(0, 0, 0, 1, getProjection('EPSG:3857')))
|
||||
.to.equal(tile);
|
||||
});
|
||||
@@ -99,6 +95,20 @@ describe('ol.source.VectorTile', function() {
|
||||
expect(tile.getState()).to.be(TileState.EMPTY);
|
||||
});
|
||||
|
||||
it('creates empty tiles outside the world extent when wrapX === false', function() {
|
||||
const source = new VectorTileSource({
|
||||
wrapX: false
|
||||
});
|
||||
const tile = source.getTile(0, -1, 0, 1, source.getProjection());
|
||||
expect(tile.getState()).to.be(TileState.EMPTY);
|
||||
});
|
||||
|
||||
it('creates non-empty tiles outside the world extent when wrapX === true', function() {
|
||||
const source = new VectorTileSource({});
|
||||
const tile = source.getTile(0, -1, 0, 1, source.getProjection());
|
||||
expect(tile.getState()).to.be(TileState.IDLE);
|
||||
});
|
||||
|
||||
it('creates new tile when source key changes', function() {
|
||||
source.setKey('key1');
|
||||
const tile1 = source.getTile(0, 0, 0, 1, getProjection('EPSG:3857'));
|
||||
@@ -121,7 +131,7 @@ describe('ol.source.VectorTile', function() {
|
||||
|
||||
describe('Tile load events', function() {
|
||||
it('triggers tileloadstart and tileloadend with ol.VectorTile', function(done) {
|
||||
tile = source.getTile(14, 8938, 5680, 1, getProjection('EPSG:3857'));
|
||||
const tile = source.getTile(14, 8938, 5680, 1, getProjection('EPSG:3857'));
|
||||
let started = false;
|
||||
source.on('tileloadstart', function() {
|
||||
started = true;
|
||||
@@ -203,4 +213,66 @@ describe('ol.source.VectorTile', function() {
|
||||
|
||||
});
|
||||
|
||||
it('does not fill up the tile queue', function(done) {
|
||||
const target = document.createElement('div');
|
||||
target.style.width = '100px';
|
||||
target.style.height = '100px';
|
||||
document.body.appendChild(target);
|
||||
|
||||
const urls = [
|
||||
'spec/ol/data/14-8938-5680.vector.pbf?num=0&coord={z},{x},{y}',
|
||||
'spec/ol/data/14-8938-5680.vector.pbf?num=1&coord={z},{x},{y}',
|
||||
'spec/ol/data/14-8938-5680.vector.pbf?num=2&coord={z},{x},{y}',
|
||||
'spec/ol/data/14-8938-5680.vector.pbf?num=3&coord={z},{x},{y}'
|
||||
];
|
||||
|
||||
const source = new VectorTileSource({
|
||||
format: new MVT(),
|
||||
url: urls[0]
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
target: target,
|
||||
layers: [
|
||||
new VectorTileLayer({
|
||||
source: source
|
||||
})
|
||||
],
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
zoom: 0
|
||||
})
|
||||
});
|
||||
map.renderSync();
|
||||
|
||||
|
||||
const max = urls.length + 3;
|
||||
let count = 0;
|
||||
let tile = source.getTile(0, 0, 0, 1, map.getView().getProjection());
|
||||
tile.addEventListener('change', function onTileChange(e) {
|
||||
if (e.target.getState() !== TileState.LOADED && !e.target.hifi) {
|
||||
return;
|
||||
}
|
||||
e.target.removeEventListener('change', onTileChange);
|
||||
|
||||
map.once('rendercomplete', function() {
|
||||
expect(map.tileQueue_.getTilesLoading()).to.be(0);
|
||||
|
||||
++count;
|
||||
if (count === max) {
|
||||
document.body.removeChild(target);
|
||||
map.dispose();
|
||||
done();
|
||||
return;
|
||||
}
|
||||
|
||||
source.setUrl(urls[count % urls.length]);
|
||||
tile = source.getTile(0, 0, 0, 1, map.getView().getProjection());
|
||||
tile.addEventListener('change', onTileChange);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -5,7 +5,6 @@ import {listen, listenOnce, unlistenByKey} from '../../../src/ol/events.js';
|
||||
import GeoJSON from '../../../src/ol/format/GeoJSON.js';
|
||||
import {createXYZ} from '../../../src/ol/tilegrid.js';
|
||||
import TileGrid from '../../../src/ol/tilegrid/TileGrid.js';
|
||||
import {getKey} from '../../../src/ol/tilecoord.js';
|
||||
import EventType from '../../../src/ol/events/EventType.js';
|
||||
|
||||
|
||||
@@ -107,7 +106,7 @@ describe('ol.VectorRenderTile', function() {
|
||||
tile.load();
|
||||
expect(tile.getState()).to.be(TileState.LOADING);
|
||||
tile.dispose();
|
||||
expect(source.sourceTilesByTileKey_[getKey(tile)]).to.be(undefined);
|
||||
expect(source.sourceTilesByTileKey_[tile.getKey()]).to.be(undefined);
|
||||
expect(tile.getState()).to.be(TileState.ABORT);
|
||||
});
|
||||
|
||||
|
||||