Compare commits
467 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b04d542a3a | ||
|
|
f43df3c1e2 | ||
|
|
c96fee5ba2 | ||
|
|
0a439b0129 | ||
|
|
ff5b4177c8 | ||
|
|
b5196a65a1 | ||
|
|
ec2e3f4f23 | ||
|
|
1c81f60fec | ||
|
|
89f632fa7e | ||
|
|
11329bb776 | ||
|
|
b98a95d1b4 | ||
|
|
0fbe83edf7 | ||
|
|
2dfef3f125 | ||
|
|
1a8df049e4 | ||
|
|
f511209789 | ||
|
|
e71a8b65e1 | ||
|
|
647a0d8ece | ||
|
|
71f737b58a | ||
|
|
1f761d943f | ||
|
|
0816746505 | ||
|
|
430f354406 | ||
|
|
48ce451f53 | ||
|
|
2f9a9af809 | ||
|
|
bad590d0de | ||
|
|
6a26ff4204 | ||
|
|
cd840aaf88 | ||
|
|
e98607e344 | ||
|
|
7c9822b9e7 | ||
|
|
ed758f7655 | ||
|
|
ff60daaa49 | ||
|
|
f47b332512 | ||
|
|
1c0b6e2fe8 | ||
|
|
3d8c98c865 | ||
|
|
acb2c2a69d | ||
|
|
b717d63b4c | ||
|
|
dbba580f82 | ||
|
|
866c641c87 | ||
|
|
076fc70b6c | ||
|
|
a1643783c5 | ||
|
|
28ca752a64 | ||
|
|
bd8a454df1 | ||
|
|
6de9c828ab | ||
|
|
f13838470e | ||
|
|
a9210db25c | ||
|
|
85d5e5dfad | ||
|
|
0e93a3118c | ||
|
|
449cfd15b1 | ||
|
|
07ebc48516 | ||
|
|
a963ab7d1d | ||
|
|
39b2de829e | ||
|
|
38d4a8f13f | ||
|
|
197dd2e06d | ||
|
|
4ce7f77749 | ||
|
|
7f0b6b3f7a | ||
|
|
a64102f097 | ||
|
|
22609f7a7d | ||
|
|
35e1d29d6b | ||
|
|
eed400ca1c | ||
|
|
73f54c1e6c | ||
|
|
71af0eee43 | ||
|
|
43e06a7d57 | ||
|
|
73f36adaaf | ||
|
|
2d96c92ac8 | ||
|
|
9024867893 | ||
|
|
9aa3c00879 | ||
|
|
faddbf098b | ||
|
|
539eae1398 | ||
|
|
e0aa161302 | ||
|
|
9c955bc86d | ||
|
|
ad7b95667f | ||
|
|
fc535ab4d0 | ||
|
|
c785c2813b | ||
|
|
a2388756f2 | ||
|
|
69c02aa6c8 | ||
|
|
f6496aa409 | ||
|
|
2893b78302 | ||
|
|
9553396c31 | ||
|
|
13101e3ab4 | ||
|
|
2dd4f71b51 | ||
|
|
9db298987b | ||
|
|
766a336650 | ||
|
|
d85be48da2 | ||
|
|
ae629301e9 | ||
|
|
7639eff49a | ||
|
|
654929bae2 | ||
|
|
7dd45c66ed | ||
|
|
1193476442 | ||
|
|
83d3bbf0ab | ||
|
|
665da47437 | ||
|
|
00b7bc60ac | ||
|
|
93abfe78a3 | ||
|
|
3506176328 | ||
|
|
275ecca473 | ||
|
|
9b0878a94a | ||
|
|
c500fdc4ad | ||
|
|
b1b09619bb | ||
|
|
d63a7ae497 | ||
|
|
bc2969fd78 | ||
|
|
37f117b782 | ||
|
|
c8a7a83e1f | ||
|
|
e8b4011cf4 | ||
|
|
d6d4b878c2 | ||
|
|
6570416343 | ||
|
|
02c1f4914a | ||
|
|
f0d488c549 | ||
|
|
e2883fb658 | ||
|
|
bec4b3028a | ||
|
|
8d8632bff7 | ||
|
|
3edb5d6ddc | ||
|
|
6e8ae4a714 | ||
|
|
8ab025a77d | ||
|
|
c5ce37b484 | ||
|
|
dabebdf9ff | ||
|
|
0058ea021a | ||
|
|
5c848eb697 | ||
|
|
46a630eb9a | ||
|
|
e03366feb2 | ||
|
|
a48f50b249 | ||
|
|
d0741d628d | ||
|
|
6ac4b66655 | ||
|
|
2d510e71a9 | ||
|
|
45c38eabc4 | ||
|
|
a4ee7eee10 | ||
|
|
f4906b83c9 | ||
|
|
71fc4be2eb | ||
|
|
59186f2afd | ||
|
|
0c11a7514d | ||
|
|
351ca5866b | ||
|
|
bdb7b9740b | ||
|
|
61f05fae74 | ||
|
|
4fe091c02d | ||
|
|
792f937aa5 | ||
|
|
4acb45dc78 | ||
|
|
4f7cadd17d | ||
|
|
5267e30d6d | ||
|
|
abdb313ad7 | ||
|
|
ff22f9ace9 | ||
|
|
e5a32f533e | ||
|
|
28bc9650d7 | ||
|
|
bb3140550d | ||
|
|
2e03069440 | ||
|
|
dbd4dda0cd | ||
|
|
76e294566e | ||
|
|
1f2ce78567 | ||
|
|
1413a13385 | ||
|
|
c307df47fa | ||
|
|
386671f5ef | ||
|
|
dbe7358b52 | ||
|
|
2e2bfeb708 | ||
|
|
7fbe54686c | ||
|
|
bb0470ef8b | ||
|
|
74c7e21c6f | ||
|
|
d53ce74027 | ||
|
|
6e4f862a3d | ||
|
|
2664733ea8 | ||
|
|
89bcfd068c | ||
|
|
c33adb1035 | ||
|
|
4700e8a17b | ||
|
|
34c84cf107 | ||
|
|
568327e693 | ||
|
|
c75e127734 | ||
|
|
7efb9e3ba7 | ||
|
|
0cc3bae8fe | ||
|
|
c8cfbfccf8 | ||
|
|
ae637bf683 | ||
|
|
0e3477ec24 | ||
|
|
a8baab7561 | ||
|
|
628e5c1c90 | ||
|
|
68ea485e69 | ||
|
|
f6cb4c296d | ||
|
|
848965b25c | ||
|
|
3f73a2f04f | ||
|
|
3643144108 | ||
|
|
6958ca3101 | ||
|
|
35a6825f74 | ||
|
|
4f6f66f966 | ||
|
|
288411f86c | ||
|
|
056f6c30fb | ||
|
|
2494bee7c8 | ||
|
|
96b2e88c5f | ||
|
|
427317fa42 | ||
|
|
14e9b83954 | ||
|
|
d4e057bc10 | ||
|
|
fc2cb2e876 | ||
|
|
d6e47de6ea | ||
|
|
15a6eda515 | ||
|
|
c1fc7db3f7 | ||
|
|
762d0768b4 | ||
|
|
fc4a05ccf4 | ||
|
|
78bf0a3679 | ||
|
|
fafcb65fff | ||
|
|
01c81373b3 | ||
|
|
6dff267272 | ||
|
|
fa80e2d064 | ||
|
|
e79d9d386b | ||
|
|
1cb6465702 | ||
|
|
db99de6903 | ||
|
|
8de93330b5 | ||
|
|
c59047c965 | ||
|
|
238695a107 | ||
|
|
5db09b3817 | ||
|
|
431a054a7d | ||
|
|
9e8ee1c05d | ||
|
|
3f4f922106 | ||
|
|
30ecf117ac | ||
|
|
7f6a479805 | ||
|
|
0326447611 | ||
|
|
ce751f26dc | ||
|
|
be205b325d | ||
|
|
3ebd1d7f1d | ||
|
|
72c78e3e92 | ||
|
|
6c7d8f6af9 | ||
|
|
28fc19e6ae | ||
|
|
f5803ad6ca | ||
|
|
67c183958a | ||
|
|
3638df90f8 | ||
|
|
4ed1226411 | ||
|
|
60c4268569 | ||
|
|
747967e797 | ||
|
|
d86464a812 | ||
|
|
acea9dc822 | ||
|
|
686a6f147d | ||
|
|
c2fc800fc1 | ||
|
|
d95e507af3 | ||
|
|
b24f0c9f1b | ||
|
|
9d94485b48 | ||
|
|
f73a891797 | ||
|
|
004f429ee2 | ||
|
|
bad0105352 | ||
|
|
cea1c79803 | ||
|
|
8e8d8598b9 | ||
|
|
ed07d60314 | ||
|
|
2d92756f84 | ||
|
|
eb76d072a9 | ||
|
|
544e55fe1a | ||
|
|
04ac30009b | ||
|
|
38bff05e43 | ||
|
|
43c40eb6d6 | ||
|
|
3a57a873bc | ||
|
|
3ef40f8e22 | ||
|
|
3bf1aef8e2 | ||
|
|
a788c9bd1e | ||
|
|
eaea5b3bdc | ||
|
|
b678c51234 | ||
|
|
2e755764ec | ||
|
|
dbec83b8d9 | ||
|
|
ad21ed7840 | ||
|
|
68332c48b5 | ||
|
|
7d8afea8a7 | ||
|
|
6432a16a98 | ||
|
|
7fa8081226 | ||
|
|
dcc7c27ec0 | ||
|
|
8e6f451553 | ||
|
|
b9b1b535dd | ||
|
|
cafba311de | ||
|
|
e00d005088 | ||
|
|
87d37937c5 | ||
|
|
243d466ece | ||
|
|
104e3364bd | ||
|
|
a9bd6cd00e | ||
|
|
2960668698 | ||
|
|
9636e4ddd7 | ||
|
|
d684cb01e6 | ||
|
|
5853dc2d19 | ||
|
|
100c4a2baf | ||
|
|
e2daac9c4e | ||
|
|
14b254aeb6 | ||
|
|
7c59869549 | ||
|
|
b91f8398d2 | ||
|
|
ce3b1dc371 | ||
|
|
c10af22f27 | ||
|
|
a6c869f8f2 | ||
|
|
c96ce1d9c3 | ||
|
|
3058b3730a | ||
|
|
e4cb2aae12 | ||
|
|
9e7d3fd07b | ||
|
|
ea2e87c563 | ||
|
|
8665cee8cc | ||
|
|
f6f34f82e5 | ||
|
|
332672ca1e | ||
|
|
89baa4aa01 | ||
|
|
b88a466601 | ||
|
|
fcb39c84ce | ||
|
|
5ccea03e04 | ||
|
|
036d9bf310 | ||
|
|
611d455708 | ||
|
|
dc7303967c | ||
|
|
6665b3325b | ||
|
|
f2023cda96 | ||
|
|
a715b1f5c6 | ||
|
|
6f80ba93c8 | ||
|
|
224f4c5c7f | ||
|
|
d4cc76f3f1 | ||
|
|
26d5b2163a | ||
|
|
6f2afe0088 | ||
|
|
79285ab7dd | ||
|
|
871dd0c3c6 | ||
|
|
f336cf30b0 | ||
|
|
71020bb5e4 | ||
|
|
996a6af6a3 | ||
|
|
088ba698ee | ||
|
|
aa2b55aefe | ||
|
|
0d0808fda1 | ||
|
|
45c8ad37c8 | ||
|
|
1160b4f720 | ||
|
|
3b12f1456e | ||
|
|
92c7e6e9e8 | ||
|
|
adf814a99c | ||
|
|
82ae25e008 | ||
|
|
c864de9fd1 | ||
|
|
fc40e87f89 | ||
|
|
f9365d5a8e | ||
|
|
55e14cff55 | ||
|
|
d2939fa9e7 | ||
|
|
00ac4b60b7 | ||
|
|
2e6f55f83f | ||
|
|
7ae3d34859 | ||
|
|
281841eeb6 | ||
|
|
ec6ad7d2d6 | ||
|
|
e709095b18 | ||
|
|
c8da29cdec | ||
|
|
a2f3c02ac5 | ||
|
|
a1b8f08bca | ||
|
|
c47fac19b5 | ||
|
|
03efc13357 | ||
|
|
d366d283b1 | ||
|
|
ba6a769917 | ||
|
|
92826bd0fc | ||
|
|
0dfbedb099 | ||
|
|
12cdaed2c5 | ||
|
|
883f22d6fe | ||
|
|
1d94477ed3 | ||
|
|
371bb85350 | ||
|
|
080fe8ca67 | ||
|
|
70dbe21520 | ||
|
|
924b85f4ca | ||
|
|
e5dc6588ad | ||
|
|
bc0ad8e8c9 | ||
|
|
fff8506e35 | ||
|
|
b86f9df8bd | ||
|
|
4e8736d9f0 | ||
|
|
0f5102b249 | ||
|
|
32a3ef78aa | ||
|
|
656014dbc4 | ||
|
|
0209827b90 | ||
|
|
ceb7192a63 | ||
|
|
4a80ebe1fc | ||
|
|
f4134b873b | ||
|
|
55af918a0e | ||
|
|
f0c6dff14e | ||
|
|
d4eb473252 | ||
|
|
7679128245 | ||
|
|
5addb14e60 | ||
|
|
e9d0323e90 | ||
|
|
6a0d0c1eeb | ||
|
|
10aa3d16ab | ||
|
|
2ec760d9a5 | ||
|
|
57eaf69c1a | ||
|
|
58806aaec1 | ||
|
|
6e5e94a447 | ||
|
|
655a49de7b | ||
|
|
fa2f730442 | ||
|
|
6bfef64e89 | ||
|
|
1697d1b647 | ||
|
|
07fa1adfe8 | ||
|
|
12de93b397 | ||
|
|
cbac16e21f | ||
|
|
a10bc713f2 | ||
|
|
ca9fc92f70 | ||
|
|
46d9e8db8e | ||
|
|
8cff620691 | ||
|
|
50dc9f1f88 | ||
|
|
9a6bb4d751 | ||
|
|
f74cd62827 | ||
|
|
7bed63bf3f | ||
|
|
5149224354 | ||
|
|
f2f9f68840 | ||
|
|
f353d52da3 | ||
|
|
f4739df907 | ||
|
|
8f24467ea4 | ||
|
|
770f53b5e3 | ||
|
|
a807af75f1 | ||
|
|
c799cf0cfd | ||
|
|
d1560176ba | ||
|
|
86801d1151 | ||
|
|
7a74ba606a | ||
|
|
bc064aba36 | ||
|
|
b51d16b575 | ||
|
|
7d3abbd5ca | ||
|
|
d1930d4a3f | ||
|
|
9da64fd73b | ||
|
|
37ddae4349 | ||
|
|
0645ea909e | ||
|
|
166175b4ed | ||
|
|
b0312b7bc9 | ||
|
|
e9bf7ccc61 | ||
|
|
2e9f41ce34 | ||
|
|
2feb88cd20 | ||
|
|
01bf4c32d9 | ||
|
|
f9db2c3845 | ||
|
|
e4baee4c0c | ||
|
|
b7cd60a7d4 | ||
|
|
c2877d56cb | ||
|
|
0e19c9aa2b | ||
|
|
fdba3ecf0e | ||
|
|
2adf74ece4 | ||
|
|
26c6538531 | ||
|
|
aff751bdf0 | ||
|
|
1b17f347c0 | ||
|
|
3bc28f2125 | ||
|
|
f1c0781eb2 | ||
|
|
d742c38163 | ||
|
|
687cffb5d9 | ||
|
|
dc8c9cfabb | ||
|
|
660f646d1a | ||
|
|
30054879e8 | ||
|
|
856066d05c | ||
|
|
380cfd12cb | ||
|
|
bfdd566bef | ||
|
|
bf20ab4367 | ||
|
|
06a083adda | ||
|
|
062096b641 | ||
|
|
0064b3c18e | ||
|
|
8703ddfab6 | ||
|
|
cbc2fd2997 | ||
|
|
74e8522509 | ||
|
|
96565935f8 | ||
|
|
0c8821a01a | ||
|
|
a169aaab37 | ||
|
|
6ae34e6590 | ||
|
|
bc1f1773fe | ||
|
|
a1166fe9a8 | ||
|
|
7d4b931909 | ||
|
|
6640d2d069 | ||
|
|
f16482b420 | ||
|
|
eb0bfc970e | ||
|
|
a0da16e4e9 | ||
|
|
9267d2994d | ||
|
|
1249ecee45 | ||
|
|
855fc6f5bc | ||
|
|
658f55d03f | ||
|
|
fc03078e2a | ||
|
|
c72101ff2e | ||
|
|
2c757bc8fa | ||
|
|
635a236ab8 | ||
|
|
ac65eed669 | ||
|
|
5ac9dbeb89 | ||
|
|
cc30a38d7d | ||
|
|
ba6d6f3bb4 | ||
|
|
36f94f57ce | ||
|
|
f849595dfd | ||
|
|
c55f882e49 | ||
|
|
106c114914 | ||
|
|
5faf95b9fb | ||
|
|
b0bb7846db | ||
|
|
243629510d | ||
|
|
2f713775d0 | ||
|
|
94a125357e | ||
|
|
895749707f | ||
|
|
b39f403641 | ||
|
|
ed379f4c0e | ||
|
|
52576a4485 | ||
|
|
d8686598df | ||
|
|
d52392dabe | ||
|
|
a2291abf1d | ||
|
|
bbc99e729b | ||
|
|
d3138e4e98 |
4
.github/codeql/config.yml
vendored
4
.github/codeql/config.yml
vendored
@@ -1,4 +0,0 @@
|
||||
name: "OpenLayers CodeQL Config"
|
||||
|
||||
paths:
|
||||
- src
|
||||
29
.github/workflows/build-preview.yml
vendored
Normal file
29
.github/workflows/build-preview.yml
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
name: Build Preview
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build-preview:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '16'
|
||||
- run: npm ci
|
||||
- run: npm run build-site
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: site
|
||||
path: build/site
|
||||
- name: Store pull request number for later use
|
||||
run: |
|
||||
mkdir -p build/pr
|
||||
echo ${{github.event.number}} > build/pr/number
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: pr
|
||||
path: build/pr
|
||||
102
.github/workflows/deploy-preview.yml
vendored
Normal file
102
.github/workflows/deploy-preview.yml
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
name: Deploy Preview
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["Build Preview"]
|
||||
types:
|
||||
- completed
|
||||
|
||||
jobs:
|
||||
deploy-preview:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'}}
|
||||
steps:
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '16'
|
||||
- run: npm install --global netlify-cli@6
|
||||
- run: npm install unzipper@0.10
|
||||
|
||||
- name: Get pull request number
|
||||
uses: actions/github-script@v5
|
||||
id: pull-request-number
|
||||
with:
|
||||
result-encoding: string
|
||||
script: |
|
||||
const unzipper = require('unzipper');
|
||||
|
||||
const artifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
run_id: ${{github.event.workflow_run.id}}
|
||||
});
|
||||
|
||||
const artifact = artifacts.data.artifacts.filter(
|
||||
artifact => artifact.name === 'pr'
|
||||
)[0];
|
||||
|
||||
if (!artifact) {
|
||||
throw new Error('No pr artifact found');
|
||||
}
|
||||
|
||||
const download = await github.rest.actions.downloadArtifact({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
artifact_id: artifact.id,
|
||||
archive_format: 'zip'
|
||||
});
|
||||
|
||||
const directory = await unzipper.Open.buffer(Buffer.from(download.data));
|
||||
const file = directory.files.find(d => d.path === 'number');
|
||||
const content = await file.buffer();
|
||||
return content.toString();
|
||||
|
||||
- uses: dawidd6/action-download-artifact@v2
|
||||
with:
|
||||
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||
workflow: build-preview.yml
|
||||
pr: ${{steps.pull-request-number.outputs.result}}
|
||||
name: site
|
||||
path: build/site
|
||||
|
||||
- name: Deploy to Netlify
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{secrets.NETLIFY_AUTH_TOKEN}}
|
||||
NETLIFY_SITE_ID: ${{secrets.NETLIFY_SITE_ID}}
|
||||
run: netlify deploy --dir=build/site --alias=deploy-preview-${{steps.pull-request-number.outputs.result}}
|
||||
|
||||
- name: Add comment to pull request
|
||||
uses: actions/github-script@v5
|
||||
with:
|
||||
script: |
|
||||
const pullRequestNumber = parseInt(${{steps.pull-request-number.outputs.result}}, 10);
|
||||
|
||||
const start = ':package:';
|
||||
const author = 'github-actions[bot]';
|
||||
|
||||
const comments = await github.rest.issues.listComments({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: pullRequestNumber
|
||||
});
|
||||
|
||||
const commentExists = comments.data.some(
|
||||
comment => comment.user.login === author && comment.body.startsWith(start)
|
||||
);
|
||||
|
||||
if (!commentExists) {
|
||||
const body = [
|
||||
`${start} Preview the [examples](https://deploy-preview-${pullRequestNumber}--ol-site.netlify.app/examples/) and`,
|
||||
`[docs](https://deploy-preview-${pullRequestNumber}--ol-site.netlify.app/apidoc/) from this branch`,
|
||||
`here: https://deploy-preview-${pullRequestNumber}--ol-site.netlify.app/.`
|
||||
].join(' ');
|
||||
|
||||
await github.rest.issues.createComment({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: pullRequestNumber,
|
||||
body: body
|
||||
});
|
||||
} else {
|
||||
console.log(`Preview URL comment already added to PR #${pullRequestNumber}`);
|
||||
}
|
||||
10
.github/workflows/publish.yml
vendored
10
.github/workflows/publish.yml
vendored
@@ -9,11 +9,11 @@ jobs:
|
||||
publish-npm:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/setup-node@v1
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16
|
||||
registry-url: https://registry.npmjs.org/
|
||||
node-version: '16'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Publish
|
||||
@@ -24,4 +24,4 @@ jobs:
|
||||
cd build/ol
|
||||
npm publish --tag dev
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
|
||||
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
||||
|
||||
11
.github/workflows/security.yml
vendored
11
.github/workflows/security.yml
vendored
@@ -15,20 +15,13 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
# Must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head of the pull request.
|
||||
# Only include this option if you are running this workflow on pull requests.
|
||||
fetch-depth: 2
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: javascript
|
||||
config-file: ./.github/codeql/config.yml
|
||||
source-root: src
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
|
||||
85
.github/workflows/test.yml
vendored
85
.github/workflows/test.yml
vendored
@@ -24,22 +24,9 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set Node.js Version
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- name: Determine Cache Directory
|
||||
id: npm-cache
|
||||
run: |
|
||||
echo "::set-output name=dir::$(npm config get cache)"
|
||||
|
||||
- name: Configure Job Cache
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ steps.npm-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node-
|
||||
node-version: '16'
|
||||
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
@@ -59,22 +46,9 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set Node.js Version
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- name: Determine Cache Directory
|
||||
id: npm-cache
|
||||
run: |
|
||||
echo "::set-output name=dir::$(npm config get cache)"
|
||||
|
||||
- name: Configure Job Cache
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ steps.npm-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node-
|
||||
node-version: '16'
|
||||
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
@@ -94,22 +68,9 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set Node.js Version
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- name: Determine Cache Directory
|
||||
id: npm-cache
|
||||
run: |
|
||||
echo "::set-output name=dir::$(npm config get cache)"
|
||||
|
||||
- name: Configure Job Cache
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ steps.npm-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node-
|
||||
node-version: '16'
|
||||
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
@@ -129,22 +90,9 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set Node.js Version
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- name: Determine Cache Directory
|
||||
id: npm-cache
|
||||
run: |
|
||||
echo "::set-output name=dir::$(npm config get cache)"
|
||||
|
||||
- name: Configure Job Cache
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ steps.npm-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node-
|
||||
node-version: '16'
|
||||
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
@@ -167,22 +115,9 @@ jobs:
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set Node.js Version
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- name: Determine Cache Directory
|
||||
id: npm-cache
|
||||
run: |
|
||||
echo "::set-output name=dir::$(npm config get cache)"
|
||||
|
||||
- name: Configure Job Cache
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ steps.npm-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-node-
|
||||
node-version: '16'
|
||||
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
|
||||
@@ -26,6 +26,28 @@ To run the examples you first need to start the dev server:
|
||||
|
||||
Then, load <http://localhost:8080/> in your browser.
|
||||
|
||||
## Linking Package
|
||||
|
||||
The `ol` package is published from the `build/ol` folder of the `openlayers` repo.
|
||||
|
||||
After you've cloned the `openlayers` repo locally run the `npm build-package` to prepare the build then use the `npm link` command to connect it your project.
|
||||
|
||||
Below is an example of how to build and link it to "sample-project"
|
||||
|
||||
|
||||
$ cd openlayers
|
||||
$ npm run build-package
|
||||
$ cd build/ol
|
||||
$ npm link
|
||||
$ cd /sample-project
|
||||
$ npm link ol
|
||||
|
||||
To remove the link run the following commands
|
||||
|
||||
$ cd sample-project
|
||||
$ npm unlink --no-save ol
|
||||
$ cd ../openlayers
|
||||
$ npm unlink
|
||||
## Running tests
|
||||
|
||||
To run the tests once:
|
||||
|
||||
@@ -36,10 +36,10 @@ new Map({
|
||||
|
||||
See the following examples for more detail on bundling OpenLayers with your application:
|
||||
|
||||
* Using [Vite](https://github.com/openlayers/ol-vite)
|
||||
* Using [Rollup](https://github.com/openlayers/ol-rollup)
|
||||
* Using [Webpack](https://github.com/openlayers/ol-webpack)
|
||||
* Using [webpack](https://github.com/openlayers/ol-webpack)
|
||||
* Using [Parcel](https://github.com/openlayers/ol-parcel)
|
||||
* Using [Browserify](https://github.com/openlayers/ol-browserify)
|
||||
|
||||
## Sponsors
|
||||
|
||||
@@ -97,9 +97,10 @@ For older browsers and platforms (Internet Explorer, Android 4.x, iOS v12 and ol
|
||||
* [`fetch`](https://caniuse.com/fetch): Available from [polyfill.io](https://polyfill.io/).
|
||||
* [`requestAnimationFrame`](https://caniuse.com/requestanimationframe): Available from [polyfill.io](https://polyfill.io/).
|
||||
* [`element.prototype.classList` (`add`/`remove`)](https://caniuse.com/classlist): Available from [polyfill.io](https://polyfill.io/).
|
||||
* [`URL` API](https://caniuse.com/url): Available from [polyfill.io](https://polyfill.io/).
|
||||
* [`URL` API](https://caniuse.com/url): Available from [polyfill.io](https://polyfill.io/) or [core-js](https://cdnjs.com/libraries/core-js/).
|
||||
* [`TextDecoder`](https://caniuse.com/textencoder): Available from [polyfill.io](https://polyfill.io/).
|
||||
* [`Number.isInteger`](https://caniuse.com/isInteger): Available from [polyfill.io](https://polyfill.io/).
|
||||
* [`Number.isInteger`](https://caniuse.com/isInteger): Available from [polyfill.io](https://polyfill.io/) or [core-js](https://cdnjs.com/libraries/core-js/).
|
||||
* [`Reflect`](https://caniuse.com/mdn-javascript_builtins_reflect): Available from [core-js](https://cdnjs.com/libraries/core-js/).
|
||||
* [Pointer events](https://caniuse.com/pointer): Use [elm-pep](https://npmjs.com/package/elm-pep) (lightweight) or [pepjs](https://npmjs.com/package/pepjs) (for really, really old browsers).
|
||||
|
||||
[`ol/source/GeoTIFF`](https://openlayers.org/en/latest/apidoc/module-ol_source_GeoTIFF-GeoTIFFSource.html) requires a browser that supports [ECMAScript 6](https://262.ecma-international.org/6.0/). Additionally a polyfill for [`Promise.allSettled`](https://caniuse.com/mdn-javascript_builtins_promise_allsettled) may be needed.
|
||||
|
||||
@@ -1,5 +1,37 @@
|
||||
## Upgrade notes
|
||||
|
||||
### v6.12.0
|
||||
|
||||
No special changes are required when upgrading to the 6.12.0 release.
|
||||
|
||||
### v6.11.0
|
||||
|
||||
No special changes are required when upgrading to the 6.11.0 release.
|
||||
|
||||
### v6.10.0
|
||||
|
||||
#### New `interpolate` option for sources
|
||||
|
||||
Sources now have an `interpolate` option. This option controls whether data from the source is interpolated when resampling.
|
||||
|
||||
For `ol/source/DataTile` sources, the default is `interpolate: false`. This means that when a data tile source is used with a WebGL tile layer renderer, your style expression will have access to pixel values in the data tiles without interpolation. If this option is set to true, linear interpolation will be used when over- or under-sampling the data.
|
||||
|
||||
#### Deprecation of the `imageSmoothing` option for sources
|
||||
|
||||
The `imageSmoothing` option for sources has been deprecated and will be removed in the next major release. Use the `interpolate` option instead.
|
||||
|
||||
```js
|
||||
// if you were using `imageSmoothing`
|
||||
const before = new TileSource({
|
||||
imageSmoothing: false
|
||||
});
|
||||
|
||||
// use the `interpolate` option instead
|
||||
const after = new TileSource({
|
||||
interpolate: false
|
||||
});
|
||||
```
|
||||
|
||||
### v6.9.0
|
||||
|
||||
There should be nothing special required when upgrading from v6.8 to v6.9.
|
||||
|
||||
200
changelog/v6.10.0.md
Normal file
200
changelog/v6.10.0.md
Normal file
@@ -0,0 +1,200 @@
|
||||
# 6.10.0
|
||||
|
||||
Just in time for the new year, the 6.10 release brings another great batch of features and fixes for your OpenLayers applications.
|
||||
|
||||
#### WebGL rendering
|
||||
|
||||
You can now update the style for your WebGL tile layers with `layer.setStyle()`. Keep in mind that it is more efficient to use style variables if you want to adjust styling on every render frame. However, in cases where you want to completely reconfigure the style, you can use the new `layer.setStyle()` method.
|
||||
|
||||
Additional WebGL tile layer rendering enhancements:
|
||||
* A new `palette` operator was added that allows styling raster data based on a colormap.
|
||||
* The `band` operator accepts expressions for the band number (in addition to numeric literals) – allowing for bands to be set by user provided style variables, for example.
|
||||
* Tile layers now dispatch `prerender`, `postrender`, `precompose` and `postcompose` events with access to the WebGL rendering context.
|
||||
* Layers that are adjacent to one another now share a single canvas element and rendering context – allowing for more layers in your maps before exhausting the browser's context limit.
|
||||
|
||||
#### Vector tiles
|
||||
|
||||
The Mapbox vector layer now works more easily with other vector tile providers. In addition, vector tile layers can now be configured with a background color.
|
||||
|
||||
#### New `interpolate` option for sources
|
||||
|
||||
Sources now have an `interpolate` option. This option controls whether data from the source is interpolated when resampling.
|
||||
|
||||
For `ol/source/DataTile` sources, the default is `interpolate: false`. This means that when a data tile source is used with a WebGL tile layer renderer, your style expression will have access to pixel values in the data tiles without interpolation. If this option is set to true, linear interpolation will be used when over- or under-sampling the data.
|
||||
|
||||
#### Deprecation of the `imageSmoothing` option for sources
|
||||
|
||||
The `imageSmoothing` option for sources has been deprecated and will be removed in the next major release. Use the `interpolate` option instead.
|
||||
|
||||
```js
|
||||
// if you were using `imageSmoothing`
|
||||
const before = new TileSource({
|
||||
imageSmoothing: false
|
||||
});
|
||||
|
||||
// use the `interpolate` option instead
|
||||
const after = new TileSource({
|
||||
interpolate: false
|
||||
});
|
||||
```
|
||||
|
||||
#### List of all changes
|
||||
|
||||
See below for more features and fixes.
|
||||
|
||||
* [#13155](https://github.com/openlayers/openlayers/pull/13155) - Allow interpolation to be configured for data tile sources ([@tschaub](https://github.com/tschaub))
|
||||
* [#13165](https://github.com/openlayers/openlayers/pull/13165) - Do not exceed maximum call stack when parsing TopoJSON ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#13158](https://github.com/openlayers/openlayers/pull/13158) - Add example for dynamic clusters ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#13156](https://github.com/openlayers/openlayers/pull/13156) - Ensure that tile range covers all pixels ([@tschaub](https://github.com/tschaub))
|
||||
* [#13154](https://github.com/openlayers/openlayers/pull/13154) - Update Export Map example to handle WebGL ([@mike-000](https://github.com/mike-000))
|
||||
* [#13147](https://github.com/openlayers/openlayers/pull/13147) - Support rendering with a palette in WebGL ([@tschaub](https://github.com/tschaub))
|
||||
* [#13142](https://github.com/openlayers/openlayers/pull/13142) - Include transpacific flights in Flight Animation example ([@mike-000](https://github.com/mike-000))
|
||||
* [#13150](https://github.com/openlayers/openlayers/pull/13150) - Include layer opacity in Heatmap shader ([@mike-000](https://github.com/mike-000))
|
||||
* [#13149](https://github.com/openlayers/openlayers/pull/13149) - Add layer also for programmatically selected features ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#13151](https://github.com/openlayers/openlayers/pull/13151) - Avoid error accessing attributes when context is lost ([@mike-000](https://github.com/mike-000))
|
||||
* [#13144](https://github.com/openlayers/openlayers/pull/13144) - Replace deprecated syntax in example ([@mike-000](https://github.com/mike-000))
|
||||
* [#13131](https://github.com/openlayers/openlayers/pull/13131) - Unset canvas css in stylesheet ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#13130](https://github.com/openlayers/openlayers/pull/13130) - Allow WebGL tile layers to be constructed without a source ([@tschaub](https://github.com/tschaub))
|
||||
* [#13126](https://github.com/openlayers/openlayers/pull/13126) - Preserve the drawing buffer by default for WebGL layers ([@tschaub](https://github.com/tschaub))
|
||||
* [#13127](https://github.com/openlayers/openlayers/pull/13127) - Fix for range slider on IE ([@mike-000](https://github.com/mike-000))
|
||||
* [#13095](https://github.com/openlayers/openlayers/pull/13095) - Render is only complete when no tiles are queued ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#13120](https://github.com/openlayers/openlayers/pull/13120) - Populate view's object properties ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#13102](https://github.com/openlayers/openlayers/pull/13102) - update line-arrows example ([@jipexu](https://github.com/jipexu))
|
||||
* [#13119](https://github.com/openlayers/openlayers/pull/13119) - Dispatch precompose and postcompose events for WebGL layers ([@tschaub](https://github.com/tschaub))
|
||||
* [#13118](https://github.com/openlayers/openlayers/pull/13118) - Add a layer opacity example ([@tschaub](https://github.com/tschaub))
|
||||
* [#13115](https://github.com/openlayers/openlayers/pull/13115) - Lazily create resources for worker ([@tschaub](https://github.com/tschaub))
|
||||
* [#13103](https://github.com/openlayers/openlayers/pull/13103) - Assume limited precision when rounding ([@tschaub](https://github.com/tschaub))
|
||||
* [#13097](https://github.com/openlayers/openlayers/pull/13097) - Use correct terrain-rgb tile size and update max zoom ([@mike-000](https://github.com/mike-000))
|
||||
* [#13101](https://github.com/openlayers/openlayers/pull/13101) - Fix View set center to undefined ([@M393](https://github.com/M393))
|
||||
* [#13085](https://github.com/openlayers/openlayers/pull/13085) - Add layer background ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#13083](https://github.com/openlayers/openlayers/pull/13083) - Support expressions for band arguments ([@tschaub](https://github.com/tschaub))
|
||||
* [#13084](https://github.com/openlayers/openlayers/pull/13084) - Normalize relative sprite and glyph urls for style url ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#13020](https://github.com/openlayers/openlayers/pull/13020) - Allow WebGL tile layer style to be updated ([@tschaub](https://github.com/tschaub))
|
||||
* [#13073](https://github.com/openlayers/openlayers/pull/13073) - Fall back to standard load handling when decode fails ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#13077](https://github.com/openlayers/openlayers/pull/13077) - update draw and modify features example ([@jipexu](https://github.com/jipexu))
|
||||
* [#13069](https://github.com/openlayers/openlayers/pull/13069) - Normalize based on GDAL stats metadata ([@tschaub](https://github.com/tschaub))
|
||||
* [#13070](https://github.com/openlayers/openlayers/pull/13070) - Use source minzoom if not configured otherwise ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#13065](https://github.com/openlayers/openlayers/pull/13065) - Fix typo in example ([@jipexu](https://github.com/jipexu))
|
||||
* [#13060](https://github.com/openlayers/openlayers/pull/13060) - Avoid fetching data outside the grid extent ([@tschaub](https://github.com/tschaub))
|
||||
* [#13054](https://github.com/openlayers/openlayers/pull/13054) - Updates for newer version of the OGC API spec draft ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#13045](https://github.com/openlayers/openlayers/pull/13045) - Fix tiles and background handling ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#13030](https://github.com/openlayers/openlayers/pull/13030) - Correctly set popover position in geographic example ([@MoonE](https://github.com/MoonE))
|
||||
* [#13031](https://github.com/openlayers/openlayers/pull/13031) - Allow data tile source loader to return a value or a promise ([@tschaub](https://github.com/tschaub))
|
||||
* [#13026](https://github.com/openlayers/openlayers/pull/13026) - Fix strokeStyle documentation ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#13027](https://github.com/openlayers/openlayers/pull/13027) - Restore the security scan workflow ([@openlayers](https://github.com/openlayers))
|
||||
* [#13025](https://github.com/openlayers/openlayers/pull/13025) - Add background to MapboxVector layer ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#13013](https://github.com/openlayers/openlayers/pull/13013) - Use appropriate UNPACK_ALIGNMENT for data textures ([@mike-000](https://github.com/mike-000))
|
||||
* [#13021](https://github.com/openlayers/openlayers/pull/13021) - Add the renderer type to generic layer template variables ([@tschaub](https://github.com/tschaub))
|
||||
* [#13022](https://github.com/openlayers/openlayers/pull/13022) - Update the security scan task ([@tschaub](https://github.com/tschaub))
|
||||
* [#13015](https://github.com/openlayers/openlayers/pull/13015) - Additional types for WebGL renderer, sources, and tiles ([@tschaub](https://github.com/tschaub))
|
||||
* [#13012](https://github.com/openlayers/openlayers/pull/13012) - Remove unused dependencies ([@tschaub](https://github.com/tschaub))
|
||||
* [#12976](https://github.com/openlayers/openlayers/pull/12976) - Handle ReprojTile in ol/layer/WebGLTile ([@mike-000](https://github.com/mike-000))
|
||||
* [#13011](https://github.com/openlayers/openlayers/pull/13011) - Use registry URL when publishing ([@tschaub](https://github.com/tschaub))
|
||||
* [#13009](https://github.com/openlayers/openlayers/pull/13009) - Use workflow_run event to deploy pull request previews ([@tschaub](https://github.com/tschaub))
|
||||
* [#12965](https://github.com/openlayers/openlayers/pull/12965) - Allow canvas reuse for WebGL layers ([@tschaub](https://github.com/tschaub))
|
||||
* [#12999](https://github.com/openlayers/openlayers/pull/12999) - Fix style related apidoc issues ([@MoonE](https://github.com/MoonE))
|
||||
* [#12978](https://github.com/openlayers/openlayers/pull/12978) - Add null to style jsdoc of VectorImage ([@EvertEt](https://github.com/EvertEt))
|
||||
* [#12997](https://github.com/openlayers/openlayers/pull/12997) - Lazily create the WebGL helper ([@tschaub](https://github.com/tschaub))
|
||||
* [#12996](https://github.com/openlayers/openlayers/pull/12996) - Align labels with the Select elements in the Raster Reprojection example ([@mike-000](https://github.com/mike-000))
|
||||
* [#12994](https://github.com/openlayers/openlayers/pull/12994) - Add a map property to layers ([@tschaub](https://github.com/tschaub))
|
||||
* [#12987](https://github.com/openlayers/openlayers/pull/12987) - Browser test config update ([@tschaub](https://github.com/tschaub))
|
||||
* [#12939](https://github.com/openlayers/openlayers/pull/12939) - Example that demonstrates a color expression using variables ([@tschaub](https://github.com/tschaub))
|
||||
* [#12962](https://github.com/openlayers/openlayers/pull/12962) - No context sharing when layer opacity is set ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#12964](https://github.com/openlayers/openlayers/pull/12964) - Updated Bing Maps key ([@tschaub](https://github.com/tschaub))
|
||||
* [#12958](https://github.com/openlayers/openlayers/pull/12958) - Reuse temporary canvas in getDataAtPixel() ([@mike-000](https://github.com/mike-000))
|
||||
* [#12893](https://github.com/openlayers/openlayers/pull/12893) - Allow map target to be an external window ([@andrewcoder002](https://github.com/andrewcoder002))
|
||||
* [#12955](https://github.com/openlayers/openlayers/pull/12955) - Make MapboxVector layer work in more access key scenarios ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#12935](https://github.com/openlayers/openlayers/pull/12935) - fix bug #12913 ([@mrpan](https://github.com/mrpan))
|
||||
* [#12933](https://github.com/openlayers/openlayers/pull/12933) - Include WebGL context in render events for WebGL layers ([@tschaub](https://github.com/tschaub))
|
||||
* [#12917](https://github.com/openlayers/openlayers/pull/12917) - Make removeFeature consistent with other remove methods ([@mike-000](https://github.com/mike-000))
|
||||
* [#12918](https://github.com/openlayers/openlayers/pull/12918) - Add setDisplacement method to ol/style/Image and subclasses ([@mike-000](https://github.com/mike-000))
|
||||
* [#12930](https://github.com/openlayers/openlayers/pull/12930) - Fix flaky view animation test ([@MoonE](https://github.com/MoonE))
|
||||
* [#12915](https://github.com/openlayers/openlayers/pull/12915) - Test the new pull request deploy previews ([@tschaub](https://github.com/tschaub))
|
||||
* [#12916](https://github.com/openlayers/openlayers/pull/12916) - Updates to deploy-preview job ([@openlayers](https://github.com/openlayers))
|
||||
* [#12914](https://github.com/openlayers/openlayers/pull/12914) - Build site preview as a GitHub action ([@tschaub](https://github.com/tschaub))
|
||||
* [#12891](https://github.com/openlayers/openlayers/pull/12891) - Restore browser compatibility where possible ([@mike-000](https://github.com/mike-000))
|
||||
* [#12899](https://github.com/openlayers/openlayers/pull/12899) - Update docs to mention Vite ([@tschaub](https://github.com/tschaub))
|
||||
* [#12890](https://github.com/openlayers/openlayers/pull/12890) - Release 6.9.0 ([@openlayers](https://github.com/openlayers))
|
||||
|
||||
|
||||
<details>
|
||||
<summary>Dependency Updates</summary>
|
||||
|
||||
* [#13162](https://github.com/openlayers/openlayers/pull/13162) - Bump yargs from 17.3.0 to 17.3.1 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13163](https://github.com/openlayers/openlayers/pull/13163) - Bump rollup from 2.61.1 to 2.62.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13161](https://github.com/openlayers/openlayers/pull/13161) - Bump webpack-dev-server from 4.6.0 to 4.7.1 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13160](https://github.com/openlayers/openlayers/pull/13160) - Bump puppeteer from 13.0.0 to 13.0.1 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13140](https://github.com/openlayers/openlayers/pull/13140) - Bump @rollup/plugin-node-resolve from 13.0.6 to 13.1.1 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13132](https://github.com/openlayers/openlayers/pull/13132) - Bump copy-webpack-plugin from 10.1.0 to 10.2.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13141](https://github.com/openlayers/openlayers/pull/13141) - Bump webpack-dev-middleware from 5.2.2 to 5.3.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13133](https://github.com/openlayers/openlayers/pull/13133) - Bump eslint from 8.4.1 to 8.5.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13139](https://github.com/openlayers/openlayers/pull/13139) - Bump @babel/core from 7.16.0 to 7.16.5 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13136](https://github.com/openlayers/openlayers/pull/13136) - Bump @babel/preset-env from 7.16.4 to 7.16.5 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13137](https://github.com/openlayers/openlayers/pull/13137) - Bump express from 4.17.1 to 4.17.2 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13138](https://github.com/openlayers/openlayers/pull/13138) - Bump ol-mapbox-style from 6.7.0 to 6.8.1 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13134](https://github.com/openlayers/openlayers/pull/13134) - Bump marked from 4.0.7 to 4.0.8 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13106](https://github.com/openlayers/openlayers/pull/13106) - Bump webpack from 5.64.4 to 5.65.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13108](https://github.com/openlayers/openlayers/pull/13108) - Bump rollup from 2.60.2 to 2.61.1 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13107](https://github.com/openlayers/openlayers/pull/13107) - Bump copy-webpack-plugin from 10.0.0 to 10.1.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13105](https://github.com/openlayers/openlayers/pull/13105) - Bump eslint from 8.4.0 to 8.4.1 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13109](https://github.com/openlayers/openlayers/pull/13109) - Bump marked from 4.0.6 to 4.0.7 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13110](https://github.com/openlayers/openlayers/pull/13110) - Bump puppeteer from 12.0.1 to 13.0.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13111](https://github.com/openlayers/openlayers/pull/13111) - Bump clean-css-cli from 5.4.2 to 5.5.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13091](https://github.com/openlayers/openlayers/pull/13091) - Bump rollup from 2.60.1 to 2.60.2 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13089](https://github.com/openlayers/openlayers/pull/13089) - Bump eslint from 8.3.0 to 8.4.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13090](https://github.com/openlayers/openlayers/pull/13090) - Bump marked from 4.0.5 to 4.0.6 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13093](https://github.com/openlayers/openlayers/pull/13093) - Bump yargs from 17.2.1 to 17.3.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13092](https://github.com/openlayers/openlayers/pull/13092) - Bump puppeteer from 12.0.0 to 12.0.1 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13088](https://github.com/openlayers/openlayers/pull/13088) - Bump geotiff from 1.0.8 to 1.0.9 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13057](https://github.com/openlayers/openlayers/pull/13057) - Bump puppeteer from 11.0.0 to 12.0.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13055](https://github.com/openlayers/openlayers/pull/13055) - Bump webpack from 5.64.2 to 5.64.4 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13056](https://github.com/openlayers/openlayers/pull/13056) - Bump webpack-dev-server from 4.5.0 to 4.6.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13058](https://github.com/openlayers/openlayers/pull/13058) - Bump marked from 4.0.4 to 4.0.5 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13032](https://github.com/openlayers/openlayers/pull/13032) - Bump webpack from 5.64.0 to 5.64.2 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13033](https://github.com/openlayers/openlayers/pull/13033) - Bump webpack-sources from 3.2.1 to 3.2.2 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13034](https://github.com/openlayers/openlayers/pull/13034) - Bump rollup from 2.60.0 to 2.60.1 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13035](https://github.com/openlayers/openlayers/pull/13035) - Bump copy-webpack-plugin from 9.1.0 to 10.0.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13036](https://github.com/openlayers/openlayers/pull/13036) - Bump webpack-dev-middleware from 5.2.1 to 5.2.2 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13037](https://github.com/openlayers/openlayers/pull/13037) - Bump @babel/preset-env from 7.16.0 to 7.16.4 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13038](https://github.com/openlayers/openlayers/pull/13038) - Bump marked from 4.0.3 to 4.0.4 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13039](https://github.com/openlayers/openlayers/pull/13039) - Bump eslint from 8.2.0 to 8.3.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13040](https://github.com/openlayers/openlayers/pull/13040) - Bump ol-mapbox-style from 6.5.2 to 6.5.3 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13041](https://github.com/openlayers/openlayers/pull/13041) - Bump karma from 6.3.8 to 6.3.9 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13001](https://github.com/openlayers/openlayers/pull/13001) - Bump webpack from 5.62.1 to 5.64.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13002](https://github.com/openlayers/openlayers/pull/13002) - Bump terser-webpack-plugin from 5.2.4 to 5.2.5 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13003](https://github.com/openlayers/openlayers/pull/13003) - Bump copy-webpack-plugin from 9.0.1 to 9.1.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13004](https://github.com/openlayers/openlayers/pull/13004) - Bump rollup from 2.59.0 to 2.60.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13005](https://github.com/openlayers/openlayers/pull/13005) - Bump webpack-dev-server from 4.4.0 to 4.5.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13006](https://github.com/openlayers/openlayers/pull/13006) - Bump ol-mapbox-style from 6.5.1 to 6.5.2 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13007](https://github.com/openlayers/openlayers/pull/13007) - Bump marked from 4.0.0 to 4.0.3 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13008](https://github.com/openlayers/openlayers/pull/13008) - Bump glob from 7.1.7 to 7.2.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12968](https://github.com/openlayers/openlayers/pull/12968) - Bump sinon from 11.1.2 to 12.0.1 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12969](https://github.com/openlayers/openlayers/pull/12969) - Bump marked from 3.0.8 to 4.0.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12973](https://github.com/openlayers/openlayers/pull/12973) - Bump eslint from 8.1.0 to 8.2.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12972](https://github.com/openlayers/openlayers/pull/12972) - Bump karma-firefox-launcher from 2.1.1 to 2.1.2 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12971](https://github.com/openlayers/openlayers/pull/12971) - Bump puppeteer from 10.4.0 to 11.0.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12970](https://github.com/openlayers/openlayers/pull/12970) - Bump karma from 6.3.6 to 6.3.8 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12967](https://github.com/openlayers/openlayers/pull/12967) - Bump webpack from 5.61.0 to 5.62.1 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12948](https://github.com/openlayers/openlayers/pull/12948) - Bump webpack from 5.59.1 to 5.61.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12945](https://github.com/openlayers/openlayers/pull/12945) - Bump rollup from 2.58.3 to 2.59.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12946](https://github.com/openlayers/openlayers/pull/12946) - Bump @babel/preset-env from 7.15.8 to 7.16.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12947](https://github.com/openlayers/openlayers/pull/12947) - Bump @babel/core from 7.15.8 to 7.16.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12949](https://github.com/openlayers/openlayers/pull/12949) - Bump karma from 6.3.5 to 6.3.6 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12944](https://github.com/openlayers/openlayers/pull/12944) - Bump webpack-dev-server from 4.3.1 to 4.4.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12923](https://github.com/openlayers/openlayers/pull/12923) - Bump @rollup/plugin-commonjs from 21.0.0 to 21.0.1 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12922](https://github.com/openlayers/openlayers/pull/12922) - Bump webpack-cli from 4.9.0 to 4.9.1 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12929](https://github.com/openlayers/openlayers/pull/12929) - Bump rollup from 2.58.0 to 2.58.3 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12920](https://github.com/openlayers/openlayers/pull/12920) - Bump marked from 3.0.7 to 3.0.8 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12924](https://github.com/openlayers/openlayers/pull/12924) - Bump clean-css-cli from 5.4.1 to 5.4.2 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12926](https://github.com/openlayers/openlayers/pull/12926) - Bump @rollup/plugin-node-resolve from 13.0.5 to 13.0.6 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12928](https://github.com/openlayers/openlayers/pull/12928) - Bump babel-loader from 8.2.2 to 8.2.3 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12921](https://github.com/openlayers/openlayers/pull/12921) - Bump webpack from 5.58.2 to 5.59.1 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12927](https://github.com/openlayers/openlayers/pull/12927) - Bump eslint from 8.0.1 to 8.1.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12919](https://github.com/openlayers/openlayers/pull/12919) - Bump karma from 6.3.4 to 6.3.5 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12902](https://github.com/openlayers/openlayers/pull/12902) - Bump eslint from 7.32.0 to 8.0.1 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12904](https://github.com/openlayers/openlayers/pull/12904) - Bump mocha from 9.1.2 to 9.1.3 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12905](https://github.com/openlayers/openlayers/pull/12905) - Bump glob from 7.1.7 to 7.2.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#12903](https://github.com/openlayers/openlayers/pull/12903) - Bump webpack from 5.58.1 to 5.58.2 ([@openlayers](https://github.com/openlayers))
|
||||
|
||||
|
||||
</details>
|
||||
32
changelog/v6.11.0.md
Normal file
32
changelog/v6.11.0.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# 6.11.0
|
||||
|
||||
This release follows up on the 6.10 release with a fix for Mapbox vector layers rendered over other layers. A handful of other fixes and features are included. See below for more detail.
|
||||
|
||||
* [#13195](https://github.com/openlayers/openlayers/pull/13195) - Use getFeaturesInExtent ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#13200](https://github.com/openlayers/openlayers/pull/13200) - Use interpolate option in Sea Level example ([@mike-000](https://github.com/mike-000))
|
||||
* [#13201](https://github.com/openlayers/openlayers/pull/13201) - Fix typo in example description ([@mike-000](https://github.com/mike-000))
|
||||
* [#13177](https://github.com/openlayers/openlayers/pull/13177) - Use ecoregions data ([@tschaub](https://github.com/tschaub))
|
||||
* [#13198](https://github.com/openlayers/openlayers/pull/13198) - Avoid failure if existing target has no background color ([@tschaub](https://github.com/tschaub))
|
||||
* [#13186](https://github.com/openlayers/openlayers/pull/13186) - Add getDataAtPixel() method for WebGL ([@mike-000](https://github.com/mike-000))
|
||||
* [#13196](https://github.com/openlayers/openlayers/pull/13196) - typo fix for cog-stretch example ([@bradh](https://github.com/bradh))
|
||||
* [#13190](https://github.com/openlayers/openlayers/pull/13190) - Fix base vector layer template generics ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#13180](https://github.com/openlayers/openlayers/pull/13180) - Always use ES modules from geotiff.js ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#13179](https://github.com/openlayers/openlayers/pull/13179) - Use Buffer and data uri when Blob is not available ([@ahocevar](https://github.com/ahocevar))
|
||||
* [#13178](https://github.com/openlayers/openlayers/pull/13178) - Use background property for vector layers ([@tschaub](https://github.com/tschaub))
|
||||
* [#13175](https://github.com/openlayers/openlayers/pull/13175) - Allow nodejs 12 to build the examples again ([@MoonE](https://github.com/MoonE))
|
||||
* [#13176](https://github.com/openlayers/openlayers/pull/13176) - Add `attributions` and `attributionsCollapsible` options to `ol/source/DataTile` ([@mike-000](https://github.com/mike-000))
|
||||
* [#13171](https://github.com/openlayers/openlayers/pull/13171) - Correct scale bar in EPSG:4326 ([@mike-000](https://github.com/mike-000))
|
||||
* [#13168](https://github.com/openlayers/openlayers/pull/13168) - Release 6.10.0 ([@openlayers](https://github.com/openlayers))
|
||||
|
||||
|
||||
<details>
|
||||
<summary>Dependency Updates</summary>
|
||||
|
||||
* [#13182](https://github.com/openlayers/openlayers/pull/13182) - Bump eslint from 8.5.0 to 8.6.0 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13184](https://github.com/openlayers/openlayers/pull/13184) - Bump @rollup/plugin-node-resolve from 13.1.1 to 13.1.2 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13183](https://github.com/openlayers/openlayers/pull/13183) - Bump @babel/core from 7.16.5 to 7.16.7 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13185](https://github.com/openlayers/openlayers/pull/13185) - Bump webpack-dev-server from 4.7.1 to 4.7.2 ([@openlayers](https://github.com/openlayers))
|
||||
* [#13181](https://github.com/openlayers/openlayers/pull/13181) - Bump @babel/preset-env from 7.16.5 to 7.16.7 ([@openlayers](https://github.com/openlayers))
|
||||
|
||||
|
||||
</details>
|
||||
30
changelog/v6.12.0.md
Normal file
30
changelog/v6.12.0.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# 6.12.0
|
||||
|
||||
The 6.12 release brings a few small fixes and enhancements. See below for a complete list.
|
||||
|
||||
* Transitive dependency update (by @openlayers in https://github.com/openlayers/openlayers/pull/13240)
|
||||
* Re-enable image smoothing after rendering (by @mike-000 in https://github.com/openlayers/openlayers/pull/13236)
|
||||
* Describe use of className with declutter (by @mike-000 in https://github.com/openlayers/openlayers/pull/13237)
|
||||
* added run to npm command (by @lklepner in https://github.com/openlayers/openlayers/pull/13231)
|
||||
* Document how to link package during development (by @lklepner in https://github.com/openlayers/openlayers/pull/13228)
|
||||
* Default CORS mode for WebGL rendered sources (by @tschaub in https://github.com/openlayers/openlayers/pull/13227)
|
||||
* Support the wrapX option for WebGL rendered tile sources (by @tschaub in https://github.com/openlayers/openlayers/pull/13226)
|
||||
* Update ol-mapbox-style (by @tschaub in https://github.com/openlayers/openlayers/pull/13224)
|
||||
* Do not fire modifyend event when nothing was modified (by @ahocevar in https://github.com/openlayers/openlayers/pull/13219)
|
||||
* Draw VectorTiles with interpolate in hybrid mode again (by @M393 in https://github.com/openlayers/openlayers/pull/13221)
|
||||
* Fix some typos in ModifyInteraction documentation (by @EvertEt in https://github.com/openlayers/openlayers/pull/13216)
|
||||
* Fix MVT incorrect feature data handling (by @EvertEt in https://github.com/openlayers/openlayers/pull/13217)
|
||||
* Format the changelog so contributors can be highlighted (by @tschaub in https://github.com/openlayers/openlayers/pull/13205)
|
||||
|
||||
|
||||
<details>
|
||||
<summary>Dependency Updates</summary>
|
||||
|
||||
* Bump karma from 6.3.9 to 6.3.10 (by @openlayers in https://github.com/openlayers/openlayers/pull/13209)
|
||||
* Bump shx from 0.3.3 to 0.3.4 (by @openlayers in https://github.com/openlayers/openlayers/pull/13211)
|
||||
* Bump @rollup/plugin-node-resolve from 13.1.2 to 13.1.3 (by @openlayers in https://github.com/openlayers/openlayers/pull/13210)
|
||||
* Bump rollup from 2.62.0 to 2.63.0 (by @openlayers in https://github.com/openlayers/openlayers/pull/13208)
|
||||
* Bump marked from 4.0.8 to 4.0.9 (by @openlayers in https://github.com/openlayers/openlayers/pull/13207)
|
||||
|
||||
|
||||
</details>
|
||||
@@ -9,7 +9,7 @@
|
||||
* works around an issue with `~` characters in module paths by escaping them.
|
||||
*/
|
||||
|
||||
const marked = require('marked');
|
||||
const {marked} = require('marked');
|
||||
const format = require('util').format;
|
||||
|
||||
const tags = [
|
||||
|
||||
@@ -51,8 +51,8 @@
|
||||
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
|
||||
"inlineSources": false /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
|
||||
|
||||
"inlineSources": false, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
|
||||
"skipLibCheck": true
|
||||
/* Experimental Options */
|
||||
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
title: Basic project setup using NPM and Parcel
|
||||
title: Basic project setup using NPM and Vite
|
||||
layout: doc.hbs
|
||||
---
|
||||
|
||||
@@ -7,7 +7,7 @@ layout: doc.hbs
|
||||
|
||||
Modern JavaScript works best when using and authoring modules. The recommended way of using OpenLayers is installing the [`ol`](https://npmjs.com/package/ol) package. This tutorial walks you through setting up a simple dev environment, which requires [node](https://nodejs.org) for everything to work.
|
||||
|
||||
In this tutorial, we will be using [Parcel](https://parceljs.org) to bundle our application. There are several other options, some of which are linked from the [README](https://npmjs.com/package/ol).
|
||||
In this tutorial, we will be using [Vite](https://vitejs.dev/) as a development tool and to bundle our application for production. There are several other options, some of which are linked from the [README](https://npmjs.com/package/ol).
|
||||
|
||||
## Application setup
|
||||
|
||||
@@ -15,15 +15,15 @@ Create a new empty directory for your project and navigate to it by running `mkd
|
||||
|
||||
npx create-ol-app
|
||||
|
||||
*You will need to have `git` installed for the above command to work. If you receive an error, make that [Git is installed](https://github.com/git-guides/install-git) on your system.*
|
||||
*You will need to have `git` installed for the above command to work. If you receive an error, make sure that [Git is installed](https://github.com/git-guides/install-git) on your system.*
|
||||
|
||||
This will install the `ol` package, set up a development environment with additional dependencies, and give you an `index.html` and `main.js` starting point for your application. By default, [Parcel](https://parceljs.org) will be used as a module loader and bundler. See the [`create-ol-app`](https://github.com/openlayers/create-ol-app) documentation for details on using another bundler.
|
||||
This will install the `ol` package, set up a development environment with additional dependencies, and give you an `index.html` and `main.js` starting point for your application. By default, [Vite](https://vitejs.dev/) will be used as a module loader and bundler. See the [`create-ol-app`](https://github.com/openlayers/create-ol-app) documentation for details on using another bundler.
|
||||
|
||||
To start the development server
|
||||
|
||||
npm start
|
||||
|
||||
You can now visit http://localhost:1234/ to view your application. Begin making changes to the `index.html` and `main.js` files to add additional functionality.
|
||||
You can now visit http://localhost:3000/ to view your application. Begin making changes to the `index.html` and `main.js` files to add additional functionality.
|
||||
|
||||
To create a production bundle of your application, simply type
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"$": false,
|
||||
"arc": false,
|
||||
"common": false,
|
||||
"chroma": false,
|
||||
"createMapboxStreetsV6Style": false,
|
||||
"d3": false,
|
||||
"html2canvas": false,
|
||||
@@ -13,6 +14,7 @@
|
||||
"jsts": false,
|
||||
"JSZip": false,
|
||||
"mapboxgl": false,
|
||||
"monotoneChainConvexHull": false,
|
||||
"NumpyLoader": false,
|
||||
"saveAs": false,
|
||||
"toastr": false,
|
||||
|
||||
@@ -6,7 +6,7 @@ docs: >
|
||||
<p>When the Bing Maps tile service doesn't have tiles for a given resolution and region it returns "placeholder" tiles indicating that. Zoom the map beyond level 19 to see the "placeholder" tiles. If you want OpenLayers to display stretched tiles in place of "placeholder" tiles beyond zoom level 19 then set <code>maxZoom</code> to <code>19</code> in the options passed to <code>ol/source/BingMaps</code>.</p>
|
||||
tags: "bing, bing-maps"
|
||||
cloak:
|
||||
- key: ApTJzdkyN1DdFKkRAE6QIDtzihNaf6IWJsT-nQ_2eMoO4PN__0Tzhl2-WgJtXFSp
|
||||
- key: AlEoTLTlzFB6Uf4Sy-ugXcRO21skQO7K8eObA5_L-8d20rjqZJLs2nkO1RMjGSPN
|
||||
value: Your Bing Maps Key from https://www.bingmapsportal.com/ here
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
|
||||
@@ -18,7 +18,7 @@ for (i = 0, ii = styles.length; i < ii; ++i) {
|
||||
visible: false,
|
||||
preload: Infinity,
|
||||
source: new BingMaps({
|
||||
key: 'ApTJzdkyN1DdFKkRAE6QIDtzihNaf6IWJsT-nQ_2eMoO4PN__0Tzhl2-WgJtXFSp',
|
||||
key: 'AlEoTLTlzFB6Uf4Sy-ugXcRO21skQO7K8eObA5_L-8d20rjqZJLs2nkO1RMjGSPN',
|
||||
imagerySet: styles[i],
|
||||
// use maxZoom 19 to see stretched tiles instead of the BingMaps
|
||||
// "no photos at this zoom level" tiles
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
.ol-dragbox {
|
||||
background-color: rgba(255,255,255,0.4);
|
||||
border-color: rgba(100,150,0,1);
|
||||
}
|
||||
@@ -9,4 +9,4 @@ docs: >
|
||||
tags: "DragBox, feature, selection, box"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
<div id="info">No countries selected</div>
|
||||
<div>Selected regions: <span id="info">None</span></div>
|
||||
|
||||
@@ -1,23 +1,33 @@
|
||||
import GeoJSON from '../src/ol/format/GeoJSON.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import VectorLayer from '../src/ol/layer/Vector.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {DragBox, Select} from '../src/ol/interaction.js';
|
||||
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {Fill, Stroke, Style} from '../src/ol/style.js';
|
||||
import {platformModifierKeyOnly} from '../src/ol/events/condition.js';
|
||||
|
||||
const vectorSource = new VectorSource({
|
||||
url: 'data/geojson/countries.geojson',
|
||||
url: 'https://openlayers.org/data/vector/ecoregions.json',
|
||||
format: new GeoJSON(),
|
||||
});
|
||||
|
||||
const style = new Style({
|
||||
fill: new Fill({
|
||||
color: '#eeeeee',
|
||||
}),
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM(),
|
||||
}),
|
||||
new VectorLayer({
|
||||
source: vectorSource,
|
||||
background: '#1a2b39',
|
||||
style: function (feature) {
|
||||
const color = feature.get('COLOR_BIO') || '#eeeeee';
|
||||
style.getFill().setColor(color);
|
||||
return style;
|
||||
},
|
||||
}),
|
||||
],
|
||||
target: 'map',
|
||||
@@ -28,8 +38,24 @@ const map = new Map({
|
||||
}),
|
||||
});
|
||||
|
||||
const selectedStyle = new Style({
|
||||
fill: new Fill({
|
||||
color: 'rgba(255, 255, 255, 0.6)',
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
color: 'rgba(255, 255, 255, 0.7)',
|
||||
width: 2,
|
||||
}),
|
||||
});
|
||||
|
||||
// a normal select interaction to handle click
|
||||
const select = new Select();
|
||||
const select = new Select({
|
||||
style: function (feature) {
|
||||
const color = feature.get('COLOR_BIO') || '#eeeeee';
|
||||
selectedStyle.getFill().setColor(color);
|
||||
return selectedStyle;
|
||||
},
|
||||
});
|
||||
map.addInteraction(select);
|
||||
|
||||
const selectedFeatures = select.getFeatures();
|
||||
@@ -42,6 +68,11 @@ const dragBox = new DragBox({
|
||||
map.addInteraction(dragBox);
|
||||
|
||||
dragBox.on('boxend', function () {
|
||||
const extent = dragBox.getGeometry().getExtent();
|
||||
const boxFeatures = vectorSource
|
||||
.getFeaturesInExtent(extent)
|
||||
.filter((feature) => feature.getGeometry().intersectsExtent(extent));
|
||||
|
||||
// features that intersect the box geometry are added to the
|
||||
// collection of selected features
|
||||
|
||||
@@ -50,11 +81,6 @@ dragBox.on('boxend', function () {
|
||||
// be added directly to the collection
|
||||
const rotation = map.getView().getRotation();
|
||||
const oblique = rotation % (Math.PI / 2) !== 0;
|
||||
const candidateFeatures = oblique ? [] : selectedFeatures;
|
||||
const extent = dragBox.getGeometry().getExtent();
|
||||
vectorSource.forEachFeatureIntersectingExtent(extent, function (feature) {
|
||||
candidateFeatures.push(feature);
|
||||
});
|
||||
|
||||
// when the view is obliquely rotated the box extent will
|
||||
// exceed its geometry so both the box and the candidate
|
||||
@@ -66,13 +92,15 @@ dragBox.on('boxend', function () {
|
||||
const geometry = dragBox.getGeometry().clone();
|
||||
geometry.rotate(-rotation, anchor);
|
||||
const extent = geometry.getExtent();
|
||||
candidateFeatures.forEach(function (feature) {
|
||||
boxFeatures.forEach(function (feature) {
|
||||
const geometry = feature.getGeometry().clone();
|
||||
geometry.rotate(-rotation, anchor);
|
||||
if (geometry.intersectsExtent(extent)) {
|
||||
selectedFeatures.push(feature);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
selectedFeatures.extend(boxFeatures);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -85,11 +113,11 @@ const infoBox = document.getElementById('info');
|
||||
|
||||
selectedFeatures.on(['add', 'remove'], function () {
|
||||
const names = selectedFeatures.getArray().map(function (feature) {
|
||||
return feature.get('name');
|
||||
return feature.get('ECO_NAME');
|
||||
});
|
||||
if (names.length > 0) {
|
||||
infoBox.innerHTML = names.join(', ');
|
||||
} else {
|
||||
infoBox.innerHTML = 'No countries selected';
|
||||
infoBox.innerHTML = 'None';
|
||||
}
|
||||
});
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,13 +1,11 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Styling feature with CanvasGradient or CanvasPattern
|
||||
shortdesc: Example showing the countries vector layer styled with patterns and gradients.
|
||||
shortdesc: Example showing a vector layer styled with a gradient.
|
||||
docs: >
|
||||
This example creates a [`CanvasPattern`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasPattern)
|
||||
and a [`CanvasGradient`](https://developer.mozilla.org/en/docs/Web/API/CanvasGradient). The countries are loaded from
|
||||
a GeoJSON file. A style function determines for each country whether to use a fill with the
|
||||
CanvasGradient (rainbow colors) or a CanvasPattern (repeating stacked circles). **Note**: For seamless repeat patterns,
|
||||
image width and height of the pattern image must be a factor of two (2, 4, 8, ..., 512).
|
||||
This example creates a [`CanvasGradient`](https://developer.mozilla.org/en/docs/Web/API/CanvasGradient).
|
||||
The vector data is loaded from a file and features are filled with the gradient.
|
||||
The same technique can be used with a [`CanvasPattern`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasPattern).
|
||||
tags: "canvas, gradient, pattern, style"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import GeoJSON from '../src/ol/format/GeoJSON.js';
|
||||
import KML from '../src/ol/format/KML.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import VectorLayer from '../src/ol/layer/Vector.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
@@ -7,84 +7,42 @@ import {DEVICE_PIXEL_RATIO} from '../src/ol/has.js';
|
||||
import {Fill, Stroke, Style} from '../src/ol/style.js';
|
||||
import {fromLonLat} from '../src/ol/proj.js';
|
||||
|
||||
const canvas = document.createElement('canvas');
|
||||
const context = canvas.getContext('2d');
|
||||
|
||||
// Gradient and pattern are in canvas pixel space, so we adjust for the
|
||||
// renderer's pixel ratio
|
||||
const pixelRatio = DEVICE_PIXEL_RATIO;
|
||||
|
||||
// Generate a rainbow gradient
|
||||
const gradient = (function () {
|
||||
const grad = context.createLinearGradient(0, 0, 512 * pixelRatio, 0);
|
||||
grad.addColorStop(0, 'red');
|
||||
grad.addColorStop(1 / 6, 'orange');
|
||||
grad.addColorStop(2 / 6, 'yellow');
|
||||
grad.addColorStop(3 / 6, 'green');
|
||||
grad.addColorStop(4 / 6, 'aqua');
|
||||
grad.addColorStop(5 / 6, 'blue');
|
||||
grad.addColorStop(1, 'purple');
|
||||
return grad;
|
||||
})();
|
||||
const canvas = document.createElement('canvas');
|
||||
const context = canvas.getContext('2d');
|
||||
const gradient = context.createLinearGradient(0, 0, 1024 * pixelRatio, 0);
|
||||
gradient.addColorStop(0, 'red');
|
||||
gradient.addColorStop(1 / 6, 'orange');
|
||||
gradient.addColorStop(2 / 6, 'yellow');
|
||||
gradient.addColorStop(3 / 6, 'green');
|
||||
gradient.addColorStop(4 / 6, 'aqua');
|
||||
gradient.addColorStop(5 / 6, 'blue');
|
||||
gradient.addColorStop(1, 'purple');
|
||||
|
||||
// Generate a canvasPattern with two circles on white background
|
||||
const pattern = (function () {
|
||||
canvas.width = 8 * pixelRatio;
|
||||
canvas.height = 8 * pixelRatio;
|
||||
// white background
|
||||
context.fillStyle = 'white';
|
||||
context.fillRect(0, 0, canvas.width, canvas.height);
|
||||
// outer circle
|
||||
context.fillStyle = 'rgba(102, 0, 102, 0.5)';
|
||||
context.beginPath();
|
||||
context.arc(4 * pixelRatio, 4 * pixelRatio, 3 * pixelRatio, 0, 2 * Math.PI);
|
||||
context.fill();
|
||||
// inner circle
|
||||
context.fillStyle = 'rgb(55, 0, 170)';
|
||||
context.beginPath();
|
||||
context.arc(4 * pixelRatio, 4 * pixelRatio, 1.5 * pixelRatio, 0, 2 * Math.PI);
|
||||
context.fill();
|
||||
return context.createPattern(canvas, 'repeat');
|
||||
})();
|
||||
|
||||
// Generate style for gradient or pattern fill
|
||||
const fill = new Fill();
|
||||
const style = new Style({
|
||||
fill: fill,
|
||||
stroke: new Stroke({
|
||||
color: '#333',
|
||||
width: 2,
|
||||
}),
|
||||
});
|
||||
|
||||
/**
|
||||
* The styling function for the vector layer, will return an array of styles
|
||||
* which either contains the aboove gradient or pattern.
|
||||
*
|
||||
* @param {import("../src/ol/Feature.js").default} feature The feature to style.
|
||||
* @return {Style} The style to use for the feature.
|
||||
*/
|
||||
const getStackedStyle = function (feature) {
|
||||
const id = feature.getId();
|
||||
fill.setColor(id > 'J' ? gradient : pattern);
|
||||
return style;
|
||||
};
|
||||
|
||||
// Create a vector layer that makes use of the style function above…
|
||||
const vectorLayer = new VectorLayer({
|
||||
background: 'white',
|
||||
source: new VectorSource({
|
||||
url: 'data/geojson/countries.geojson',
|
||||
format: new GeoJSON(),
|
||||
url: 'data/kml/states.kml',
|
||||
format: new KML({extractStyles: false}),
|
||||
}),
|
||||
style: new Style({
|
||||
fill: new Fill({color: gradient}),
|
||||
stroke: new Stroke({
|
||||
color: '#333',
|
||||
width: 1,
|
||||
}),
|
||||
}),
|
||||
style: getStackedStyle,
|
||||
});
|
||||
|
||||
// … finally create a map with that layer.
|
||||
const map = new Map({
|
||||
layers: [vectorLayer],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: fromLonLat([16, 48]),
|
||||
zoom: 3,
|
||||
center: fromLonLat([-100, 38.5]),
|
||||
zoom: 4,
|
||||
}),
|
||||
});
|
||||
|
||||
16
examples/clusters-dynamic.html
Normal file
16
examples/clusters-dynamic.html
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Dynamic clusters
|
||||
shortdesc: Clusters with zoom-to-cluster, hull view, and uncluttering of overlapping features.
|
||||
docs: >
|
||||
<p>This example shows open data of subsidized photovoltaic installations in Vienna. Different style functions
|
||||
are used for cluster display, single feature display, convex hull of a cluster, and an expanded view of
|
||||
overlapping features. Hovering over a cluster shows its convex hull. Clicking on a cluster zooms to the
|
||||
extent of the contained features. Clicking on a cluster consisting of features that are very close to each other reveals an expanded view
|
||||
of the features, along a circle around the cluster.</p>
|
||||
<p>Features are styled differently depending on the power of the photovoltaic installation.</p>
|
||||
tags: "marker, cluster, vector, style, convex hull"
|
||||
resources:
|
||||
- https://unpkg.com/monotone-chain-convex-hull@1.0.0/lib/index.js
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
278
examples/clusters-dynamic.js
Normal file
278
examples/clusters-dynamic.js
Normal file
@@ -0,0 +1,278 @@
|
||||
import Feature from '../src/ol/Feature.js';
|
||||
import GeoJSON from '../src/ol/format/GeoJSON.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {
|
||||
Circle as CircleStyle,
|
||||
Fill,
|
||||
Icon,
|
||||
Stroke,
|
||||
Style,
|
||||
Text,
|
||||
} from '../src/ol/style.js';
|
||||
import {Cluster, Vector as VectorSource, XYZ} from '../src/ol/source.js';
|
||||
import {LineString, Point, Polygon} from '../src/ol/geom.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {createEmpty, extend, getWidth} from '../src/ol/extent.js';
|
||||
import {fromLonLat} from '../src/ol/proj.js';
|
||||
|
||||
const circleDistanceMultiplier = 1;
|
||||
const circleFootSeparation = 28;
|
||||
const circleStartAngle = Math.PI / 2;
|
||||
|
||||
const convexHullFill = new Fill({
|
||||
color: 'rgba(255, 153, 0, 0.4)',
|
||||
});
|
||||
const convexHullStroke = new Stroke({
|
||||
color: 'rgba(204, 85, 0, 1)',
|
||||
width: 1.5,
|
||||
});
|
||||
const outerCircleFill = new Fill({
|
||||
color: 'rgba(255, 153, 102, 0.3)',
|
||||
});
|
||||
const innerCircleFill = new Fill({
|
||||
color: 'rgba(255, 165, 0, 0.7)',
|
||||
});
|
||||
const textFill = new Fill({
|
||||
color: '#fff',
|
||||
});
|
||||
const textStroke = new Stroke({
|
||||
color: 'rgba(0, 0, 0, 0.6)',
|
||||
width: 3,
|
||||
});
|
||||
const innerCircle = new CircleStyle({
|
||||
radius: 14,
|
||||
fill: innerCircleFill,
|
||||
});
|
||||
const outerCircle = new CircleStyle({
|
||||
radius: 20,
|
||||
fill: outerCircleFill,
|
||||
});
|
||||
const darkIcon = new Icon({
|
||||
src: 'data/icons/emoticon-cool.svg',
|
||||
});
|
||||
const lightIcon = new Icon({
|
||||
src: 'data/icons/emoticon-cool-outline.svg',
|
||||
});
|
||||
|
||||
/**
|
||||
* Single feature style, users for clusters with 1 feature and cluster circles.
|
||||
* @param {Feature} clusterMember A feature from a cluster.
|
||||
* @return {Style} An icon style for the cluster member's location.
|
||||
*/
|
||||
function clusterMemberStyle(clusterMember) {
|
||||
return new Style({
|
||||
geometry: clusterMember.getGeometry(),
|
||||
image: clusterMember.get('LEISTUNG') > 5 ? darkIcon : lightIcon,
|
||||
});
|
||||
}
|
||||
|
||||
let clickFeature, clickResolution;
|
||||
/**
|
||||
* Style for clusters with features that are too close to each other, activated on click.
|
||||
* @param {Feature} cluster A cluster with overlapping members.
|
||||
* @param {number} resolution The current view resolution.
|
||||
* @return {Style} A style to render an expanded view of the cluster members.
|
||||
*/
|
||||
function clusterCircleStyle(cluster, resolution) {
|
||||
if (cluster !== clickFeature || resolution !== clickResolution) {
|
||||
return;
|
||||
}
|
||||
const clusterMembers = cluster.get('features');
|
||||
const centerCoordinates = cluster.getGeometry().getCoordinates();
|
||||
return generatePointsCircle(
|
||||
clusterMembers.length,
|
||||
cluster.getGeometry().getCoordinates(),
|
||||
resolution
|
||||
).reduce((styles, coordinates, i) => {
|
||||
const point = new Point(coordinates);
|
||||
const line = new LineString([centerCoordinates, coordinates]);
|
||||
styles.unshift(
|
||||
new Style({
|
||||
geometry: line,
|
||||
stroke: convexHullStroke,
|
||||
})
|
||||
);
|
||||
styles.push(
|
||||
clusterMemberStyle(
|
||||
new Feature({
|
||||
...clusterMembers[i].getProperties(),
|
||||
geometry: point,
|
||||
})
|
||||
)
|
||||
);
|
||||
return styles;
|
||||
}, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* From
|
||||
* https://github.com/Leaflet/Leaflet.markercluster/blob/31360f2/src/MarkerCluster.Spiderfier.js#L55-L72
|
||||
* Arranges points in a circle around the cluster center, with a line pointing from the center to
|
||||
* each point.
|
||||
* @param {number} count Number of cluster members.
|
||||
* @param {Array<number>} clusterCenter Center coordinate of the cluster.
|
||||
* @param {number} resolution Current view resolution.
|
||||
* @return {Array<Array<number>>} An array of coordinates representing the cluster members.
|
||||
*/
|
||||
function generatePointsCircle(count, clusterCenter, resolution) {
|
||||
const circumference =
|
||||
circleDistanceMultiplier * circleFootSeparation * (2 + count);
|
||||
let legLength = circumference / (Math.PI * 2); //radius from circumference
|
||||
const angleStep = (Math.PI * 2) / count;
|
||||
const res = [];
|
||||
let angle;
|
||||
|
||||
legLength = Math.max(legLength, 35) * resolution; // Minimum distance to get outside the cluster icon.
|
||||
|
||||
for (let i = 0; i < count; ++i) {
|
||||
// Clockwise, like spiral.
|
||||
angle = circleStartAngle + i * angleStep;
|
||||
res.push([
|
||||
clusterCenter[0] + legLength * Math.cos(angle),
|
||||
clusterCenter[1] + legLength * Math.sin(angle),
|
||||
]);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
let hoverFeature;
|
||||
/**
|
||||
* Style for convex hulls of clusters, activated on hover.
|
||||
* @param {Feature} cluster The cluster feature.
|
||||
* @return {Style} Polygon style for the convex hull of the cluster.
|
||||
*/
|
||||
function clusterHullStyle(cluster) {
|
||||
if (cluster !== hoverFeature) {
|
||||
return;
|
||||
}
|
||||
const originalFeatures = cluster.get('features');
|
||||
const points = originalFeatures.map((feature) =>
|
||||
feature.getGeometry().getCoordinates()
|
||||
);
|
||||
return new Style({
|
||||
geometry: new Polygon([monotoneChainConvexHull(points)]),
|
||||
fill: convexHullFill,
|
||||
stroke: convexHullStroke,
|
||||
});
|
||||
}
|
||||
|
||||
function clusterStyle(feature) {
|
||||
const size = feature.get('features').length;
|
||||
if (size > 1) {
|
||||
return [
|
||||
new Style({
|
||||
image: outerCircle,
|
||||
}),
|
||||
new Style({
|
||||
image: innerCircle,
|
||||
text: new Text({
|
||||
text: size.toString(),
|
||||
fill: textFill,
|
||||
stroke: textStroke,
|
||||
}),
|
||||
}),
|
||||
];
|
||||
} else {
|
||||
const originalFeature = feature.get('features')[0];
|
||||
return clusterMemberStyle(originalFeature);
|
||||
}
|
||||
}
|
||||
|
||||
const vectorSource = new VectorSource({
|
||||
format: new GeoJSON(),
|
||||
url: 'data/geojson/photovoltaic.json',
|
||||
});
|
||||
|
||||
const clusterSource = new Cluster({
|
||||
attributions:
|
||||
'Data: <a href="https://www.data.gv.at/auftritte/?organisation=stadt-wien">Stadt Wien</a>',
|
||||
distance: 35,
|
||||
source: vectorSource,
|
||||
});
|
||||
|
||||
// Layer displaying the convex hull of the hovered cluster.
|
||||
const clusterHulls = new VectorLayer({
|
||||
source: clusterSource,
|
||||
style: clusterHullStyle,
|
||||
});
|
||||
|
||||
// Layer displaying the clusters and individual features.
|
||||
const clusters = new VectorLayer({
|
||||
source: clusterSource,
|
||||
style: clusterStyle,
|
||||
});
|
||||
|
||||
// Layer displaying the expanded view of overlapping cluster members.
|
||||
const clusterCircles = new VectorLayer({
|
||||
source: clusterSource,
|
||||
style: clusterCircleStyle,
|
||||
});
|
||||
|
||||
const raster = new TileLayer({
|
||||
source: new XYZ({
|
||||
attributions:
|
||||
'Base map: <a target="_blank" href="https://basemap.at/">basemap.at</a>',
|
||||
url: 'https://maps{1-4}.wien.gv.at/basemap/bmapgrau/normal/google3857/{z}/{y}/{x}.png',
|
||||
}),
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
layers: [raster, clusterHulls, clusters, clusterCircles],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
zoom: 2,
|
||||
maxZoom: 19,
|
||||
extent: [
|
||||
...fromLonLat([16.1793, 48.1124]),
|
||||
...fromLonLat([16.5559, 48.313]),
|
||||
],
|
||||
showFullExtent: true,
|
||||
}),
|
||||
});
|
||||
|
||||
map.on('pointermove', (event) => {
|
||||
clusters.getFeatures(event.pixel).then((features) => {
|
||||
if (features[0] !== hoverFeature) {
|
||||
// Display the convex hull on hover.
|
||||
hoverFeature = features[0];
|
||||
clusterHulls.setStyle(clusterHullStyle);
|
||||
// Change the cursor style to indicate that the cluster is clickable.
|
||||
map.getTargetElement().style.cursor =
|
||||
hoverFeature && hoverFeature.get('features').length > 1
|
||||
? 'pointer'
|
||||
: '';
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
map.on('click', (event) => {
|
||||
clusters.getFeatures(event.pixel).then((features) => {
|
||||
if (features.length > 0) {
|
||||
const clusterMembers = features[0].get('features');
|
||||
if (clusterMembers.length > 1) {
|
||||
// Calculate the extent of the cluster members.
|
||||
const extent = createEmpty();
|
||||
clusterMembers.forEach((feature) =>
|
||||
extend(extent, feature.getGeometry().getExtent())
|
||||
);
|
||||
const view = map.getView();
|
||||
const resolution = map.getView().getResolution();
|
||||
if (
|
||||
view.getZoom() === view.getMaxZoom() ||
|
||||
(getWidth(extent) < resolution && getWidth(extent) < resolution)
|
||||
) {
|
||||
// Show an expanded view of the cluster members.
|
||||
clickFeature = features[0];
|
||||
clickResolution = resolution;
|
||||
clusterCircles.setStyle(clusterCircleStyle);
|
||||
} else {
|
||||
// Zoom to the extent of the cluster members.
|
||||
view.fit(extent, {duration: 500, padding: [50, 50, 50, 50]});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
10
examples/cog-colors.css
Normal file
10
examples/cog-colors.css
Normal file
@@ -0,0 +1,10 @@
|
||||
.data {
|
||||
text-align: right;
|
||||
font-family: monospace;
|
||||
}
|
||||
td {
|
||||
padding-right: 10px;
|
||||
}
|
||||
input[type="range"] {
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
32
examples/cog-colors.html
Normal file
32
examples/cog-colors.html
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: NDVI with a Dynamic Color Ramp
|
||||
shortdesc: NDVI from a COG with a dynamic color ramp
|
||||
docs: >
|
||||
The GeoTIFF layer in this example draws from two Sentinel 2 sources: a red band and a near infrared band.
|
||||
The layer style includes a `color` expression that calculates the Normalized Difference Vegetation Index (NDVI)
|
||||
from values in the two bands. The `interpolate` expression is used to map NDVI values to colors. The "stop" values
|
||||
for the color ramp are derived from application provided style variables. Using the inputs above, the min and max
|
||||
colors and values can be adjusted. The `layer.updateStyleVariables()` method is called to update the
|
||||
variables used in the interpolated color expression.
|
||||
tags: "cog, ndvi"
|
||||
resources:
|
||||
- https://cdnjs.cloudflare.com/ajax/libs/chroma-js/2.1.2/chroma.min.js
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Min NDVI</td>
|
||||
<td><input type="range" id="min-value-input" min="-1.0" max="-0.1" step="0.01"></td>
|
||||
<td class="data" id="min-value-output"></td>
|
||||
<td><input type="color" id="min-color"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Max NDVI</td>
|
||||
<td><input type="range" id="max-value-input" min="0.1" max="1.0" step="0.01"></td>
|
||||
<td class="data" id="max-value-output"></td>
|
||||
<td><input type="color" id="max-color"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
106
examples/cog-colors.js
Normal file
106
examples/cog-colors.js
Normal file
@@ -0,0 +1,106 @@
|
||||
import GeoTIFF from '../src/ol/source/GeoTIFF.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import TileLayer from '../src/ol/layer/WebGLTile.js';
|
||||
|
||||
const segments = 10;
|
||||
|
||||
const defaultMinColor = '#0300AD';
|
||||
const defaultMaxColor = '#00ff00';
|
||||
|
||||
const defaultMinValue = -0.5;
|
||||
const defaultMaxValue = 0.7;
|
||||
|
||||
const minColorInput = document.getElementById('min-color');
|
||||
minColorInput.value = defaultMinColor;
|
||||
|
||||
const maxColorInput = document.getElementById('max-color');
|
||||
maxColorInput.value = defaultMaxColor;
|
||||
|
||||
const minValueOutput = document.getElementById('min-value-output');
|
||||
const minValueInput = document.getElementById('min-value-input');
|
||||
minValueInput.value = defaultMinValue.toString();
|
||||
|
||||
const maxValueOutput = document.getElementById('max-value-output');
|
||||
const maxValueInput = document.getElementById('max-value-input');
|
||||
maxValueInput.value = defaultMaxValue.toString();
|
||||
|
||||
function getVariables() {
|
||||
const variables = {};
|
||||
|
||||
const minColor = minColorInput.value;
|
||||
const maxColor = maxColorInput.value;
|
||||
const scale = chroma.scale([minColor, maxColor]).mode('lab');
|
||||
|
||||
const minValue = parseFloat(minValueInput.value);
|
||||
const maxValue = parseFloat(maxValueInput.value);
|
||||
const delta = (maxValue - minValue) / segments;
|
||||
|
||||
for (let i = 0; i <= segments; ++i) {
|
||||
const color = scale(i / segments).rgb();
|
||||
const value = minValue + i * delta;
|
||||
variables[`value${i}`] = value;
|
||||
variables[`red${i}`] = color[0];
|
||||
variables[`green${i}`] = color[1];
|
||||
variables[`blue${i}`] = color[2];
|
||||
}
|
||||
return variables;
|
||||
}
|
||||
|
||||
function colors() {
|
||||
const stops = [];
|
||||
for (let i = 0; i <= segments; ++i) {
|
||||
stops[i * 2] = ['var', `value${i}`];
|
||||
const red = ['var', `red${i}`];
|
||||
const green = ['var', `green${i}`];
|
||||
const blue = ['var', `blue${i}`];
|
||||
stops[i * 2 + 1] = ['color', red, green, blue];
|
||||
}
|
||||
return stops;
|
||||
}
|
||||
|
||||
const ndvi = [
|
||||
'/',
|
||||
['-', ['band', 2], ['band', 1]],
|
||||
['+', ['band', 2], ['band', 1]],
|
||||
];
|
||||
|
||||
const source = new GeoTIFF({
|
||||
sources: [
|
||||
{
|
||||
// visible red, band 1 in the style expression above
|
||||
url: 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/2020/S2A_36QWD_20200701_0_L2A/B04.tif',
|
||||
max: 10000,
|
||||
},
|
||||
{
|
||||
// near infrared, band 2 in the style expression above
|
||||
url: 'https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/2020/S2A_36QWD_20200701_0_L2A/B08.tif',
|
||||
max: 10000,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const layer = new TileLayer({
|
||||
style: {
|
||||
variables: getVariables(),
|
||||
color: ['interpolate', ['linear'], ndvi, ...colors()],
|
||||
},
|
||||
source: source,
|
||||
});
|
||||
|
||||
function update() {
|
||||
layer.updateStyleVariables(getVariables());
|
||||
minValueOutput.innerText = parseFloat(minValueInput.value).toFixed(1);
|
||||
maxValueOutput.innerText = parseFloat(maxValueInput.value).toFixed(1);
|
||||
}
|
||||
|
||||
minColorInput.addEventListener('input', update);
|
||||
maxColorInput.addEventListener('input', update);
|
||||
minValueInput.addEventListener('input', update);
|
||||
maxValueInput.addEventListener('input', update);
|
||||
update();
|
||||
|
||||
const map = new Map({
|
||||
target: 'map',
|
||||
layers: [layer],
|
||||
view: source.getView(),
|
||||
});
|
||||
6
examples/cog-stretch.css
Normal file
6
examples/cog-stretch.css
Normal file
@@ -0,0 +1,6 @@
|
||||
.controls {
|
||||
display: grid;
|
||||
grid-template-columns: auto auto 1fr;
|
||||
align-items: baseline;
|
||||
gap: 0 1em;
|
||||
}
|
||||
44
examples/cog-stretch.html
Normal file
44
examples/cog-stretch.html
Normal file
@@ -0,0 +1,44 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Band Contrast Stretch
|
||||
shortdesc: Choosing bands and applying contrast stretch
|
||||
docs: >
|
||||
This example uses the `layer.updateStyleVariables()` method to update the rendering
|
||||
of a GeoTIFF based on user selected bands and contrast stretch parameters.
|
||||
tags: "cog, webgl, style"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
<div class="controls">
|
||||
<label for="red">Red channel</label>
|
||||
<select id="red">
|
||||
<option value="1" selected>visible red</option>
|
||||
<option value="2">visible green</option>
|
||||
<option value="3">visible blue</option>
|
||||
<option value="4">near infrared</option>
|
||||
</select>
|
||||
<label>max
|
||||
<input type="range" id="redMax" value="3000" min="2000" max="5000">
|
||||
</label>
|
||||
|
||||
<label for="green">Green channel</label>
|
||||
<select id="green">
|
||||
<option value="1">visible red</option>
|
||||
<option value="2" selected>visible green</option>
|
||||
<option value="3">visible blue</option>
|
||||
<option value="4">near infrared</option>
|
||||
</select>
|
||||
<label>max
|
||||
<input type="range" id="greenMax" value="3000" min="2000" max="5000">
|
||||
</label>
|
||||
|
||||
<label for="blue">Blue channel</label>
|
||||
<select id="blue">
|
||||
<option value="1">visible red</option>
|
||||
<option value="2">visible green</option>
|
||||
<option value="3" selected>visible blue</option>
|
||||
<option value="4">near infrared</option>
|
||||
</select>
|
||||
<label>max
|
||||
<input type="range" id="blueMax" value="3000" min="2000" max="5000">
|
||||
</label>
|
||||
</div>
|
||||
62
examples/cog-stretch.js
Normal file
62
examples/cog-stretch.js
Normal file
@@ -0,0 +1,62 @@
|
||||
import GeoTIFF from '../src/ol/source/GeoTIFF.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import TileLayer from '../src/ol/layer/WebGLTile.js';
|
||||
import View from '../src/ol/View.js';
|
||||
|
||||
const channels = ['red', 'green', 'blue'];
|
||||
for (const channel of channels) {
|
||||
const selector = document.getElementById(channel);
|
||||
selector.addEventListener('change', update);
|
||||
|
||||
const input = document.getElementById(`${channel}Max`);
|
||||
input.addEventListener('input', update);
|
||||
}
|
||||
|
||||
function getVariables() {
|
||||
const variables = {};
|
||||
for (const channel of channels) {
|
||||
const selector = document.getElementById(channel);
|
||||
variables[channel] = parseInt(selector.value, 10);
|
||||
|
||||
const inputId = `${channel}Max`;
|
||||
const input = document.getElementById(inputId);
|
||||
variables[inputId] = parseInt(input.value, 10);
|
||||
}
|
||||
return variables;
|
||||
}
|
||||
|
||||
const layer = new TileLayer({
|
||||
style: {
|
||||
variables: getVariables(),
|
||||
color: [
|
||||
'array',
|
||||
['/', ['band', ['var', 'red']], ['var', 'redMax']],
|
||||
['/', ['band', ['var', 'green']], ['var', 'greenMax']],
|
||||
['/', ['band', ['var', 'blue']], ['var', 'blueMax']],
|
||||
1,
|
||||
],
|
||||
},
|
||||
source: new GeoTIFF({
|
||||
normalize: false,
|
||||
sources: [
|
||||
{
|
||||
url: 'https://s2downloads.eox.at/demo/EOxCloudless/2020/rgbnir/s2cloudless2020-16bits_sinlge-file_z0-4.tif',
|
||||
},
|
||||
],
|
||||
}),
|
||||
});
|
||||
|
||||
function update() {
|
||||
layer.updateStyleVariables(getVariables());
|
||||
}
|
||||
|
||||
const map = new Map({
|
||||
target: 'map',
|
||||
layers: [layer],
|
||||
view: new View({
|
||||
projection: 'EPSG:4326',
|
||||
center: [0, 0],
|
||||
zoom: 2,
|
||||
maxZoom: 6,
|
||||
}),
|
||||
});
|
||||
20
examples/cog-style.html
Normal file
20
examples/cog-style.html
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Change Tile Layer Style
|
||||
shortdesc: Updating the style of a WebGL tile layer
|
||||
docs: >
|
||||
When you want to change the style of a WebGL tile layer based on some change in your
|
||||
application state, you should use the `layer.updateStyleVariables()` method. A layer can
|
||||
be efficiently rendered even if style variables are changed on every render frame.
|
||||
In cases where you need to completely replace the style of a layer, you can call the
|
||||
`layer.setStyle()` method. This method should not be called in response to frequent
|
||||
user events (e.g. mouse movement, dragging a slider, etc.).
|
||||
tags: "cog, webgl, style"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
Set the layer style
|
||||
<select id="style">
|
||||
<option value="trueColor">True Color</option>
|
||||
<option value="falseColor">False Color</option>
|
||||
<option value="ndvi">NDVI</option>
|
||||
</select>
|
||||
105
examples/cog-style.js
Normal file
105
examples/cog-style.js
Normal file
@@ -0,0 +1,105 @@
|
||||
import GeoTIFF from '../src/ol/source/GeoTIFF.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import TileLayer from '../src/ol/layer/WebGLTile.js';
|
||||
import View from '../src/ol/View.js';
|
||||
|
||||
const max = 3000;
|
||||
function normalize(value) {
|
||||
return ['/', value, max];
|
||||
}
|
||||
|
||||
const red = normalize(['band', 1]);
|
||||
const green = normalize(['band', 2]);
|
||||
const blue = normalize(['band', 3]);
|
||||
const nir = normalize(['band', 4]);
|
||||
|
||||
const trueColor = {
|
||||
color: ['array', red, green, blue, 1],
|
||||
gamma: 1.1,
|
||||
};
|
||||
|
||||
const falseColor = {
|
||||
color: ['array', nir, red, green, 1],
|
||||
gamma: 1.1,
|
||||
};
|
||||
|
||||
const ndvi = {
|
||||
color: [
|
||||
'interpolate',
|
||||
['linear'],
|
||||
['/', ['-', nir, red], ['+', nir, red]],
|
||||
// color ramp for NDVI values, ranging from -1 to 1
|
||||
-0.2,
|
||||
[191, 191, 191],
|
||||
-0.1,
|
||||
[219, 219, 219],
|
||||
0,
|
||||
[255, 255, 224],
|
||||
0.025,
|
||||
[255, 250, 204],
|
||||
0.05,
|
||||
[237, 232, 181],
|
||||
0.075,
|
||||
[222, 217, 156],
|
||||
0.1,
|
||||
[204, 199, 130],
|
||||
0.125,
|
||||
[189, 184, 107],
|
||||
0.15,
|
||||
[176, 194, 97],
|
||||
0.175,
|
||||
[163, 204, 89],
|
||||
0.2,
|
||||
[145, 191, 82],
|
||||
0.25,
|
||||
[128, 179, 71],
|
||||
0.3,
|
||||
[112, 163, 64],
|
||||
0.35,
|
||||
[97, 150, 54],
|
||||
0.4,
|
||||
[79, 138, 46],
|
||||
0.45,
|
||||
[64, 125, 36],
|
||||
0.5,
|
||||
[48, 110, 28],
|
||||
0.55,
|
||||
[33, 97, 18],
|
||||
0.6,
|
||||
[15, 84, 10],
|
||||
0.65,
|
||||
[0, 69, 0],
|
||||
],
|
||||
};
|
||||
|
||||
const layer = new TileLayer({
|
||||
style: trueColor,
|
||||
source: new GeoTIFF({
|
||||
normalize: false,
|
||||
sources: [
|
||||
{
|
||||
url: 'https://s2downloads.eox.at/demo/EOxCloudless/2020/rgbnir/s2cloudless2020-16bits_sinlge-file_z0-4.tif',
|
||||
},
|
||||
],
|
||||
}),
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
target: 'map',
|
||||
layers: [layer],
|
||||
view: new View({
|
||||
projection: 'EPSG:4326',
|
||||
center: [0, 0],
|
||||
zoom: 2,
|
||||
maxZoom: 6,
|
||||
}),
|
||||
});
|
||||
|
||||
const styles = {trueColor, falseColor, ndvi};
|
||||
const styleSelector = document.getElementById('style');
|
||||
|
||||
function update() {
|
||||
const style = styles[styleSelector.value];
|
||||
layer.setStyle(style);
|
||||
}
|
||||
styleSelector.addEventListener('change', update);
|
||||
@@ -32,7 +32,7 @@ const map = new Map({
|
||||
context.strokeRect(0, 0, size, size);
|
||||
const data = context.getImageData(0, 0, size, size).data;
|
||||
// converting to Uint8Array for increased browser compatibility
|
||||
return Promise.resolve(new Uint8Array(data.buffer));
|
||||
return new Uint8Array(data.buffer);
|
||||
},
|
||||
// disable opacity transition to avoid overlapping labels during tile loading
|
||||
transition: 0,
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
examples/data/geojson/photovoltaic.json
Normal file
1
examples/data/geojson/photovoltaic.json
Normal file
File diff suppressed because one or more lines are too long
1
examples/data/icons/emoticon-cool-outline.svg
Normal file
1
examples/data/icons/emoticon-cool-outline.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M19,10C19,11.38 16.88,12.5 15.5,12.5C14.12,12.5 12.75,11.38 12.75,10H11.25C11.25,11.38 9.88,12.5 8.5,12.5C7.12,12.5 5,11.38 5,10H4.25C4.09,10.64 4,11.31 4,12A8,8 0 0,0 12,20A8,8 0 0,0 20,12C20,11.31 19.91,10.64 19.75,10H19M12,4C9.04,4 6.45,5.61 5.07,8H18.93C17.55,5.61 14.96,4 12,4M22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2A10,10 0 0,1 22,12M12,17.23C10.25,17.23 8.71,16.5 7.81,15.42L9.23,14C9.68,14.72 10.75,15.23 12,15.23C13.25,15.23 14.32,14.72 14.77,14L16.19,15.42C15.29,16.5 13.75,17.23 12,17.23Z" /></svg>
|
||||
|
After Width: | Height: | Size: 812 B |
1
examples/data/icons/emoticon-cool.svg
Normal file
1
examples/data/icons/emoticon-cool.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path d="M3.22,7.22C4.91,4.11 8.21,2 12,2C15.79,2 19.09,4.11 20.78,7.22L20,8H4L3.22,7.22M21.4,8.6C21.78,9.67 22,10.81 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12C2,10.81 2.22,9.67 2.6,8.6L4,10H5C5,11.38 7.12,12.5 8.5,12.5C9.88,12.5 11.25,11.38 11.25,10H12.75C12.75,11.38 14.12,12.5 15.5,12.5C16.88,12.5 19,11.38 19,10H20L21.4,8.6M16.19,15.42L14.77,14C14.32,14.72 13.25,15.23 12,15.23C10.75,15.23 9.68,14.72 9.23,14L7.81,15.42C8.71,16.5 10.25,17.23 12,17.23C13.75,17.23 15.29,16.5 16.19,15.42Z" /></svg>
|
||||
|
After Width: | Height: | Size: 775 B |
1
examples/data/openweather/weather.json
Normal file
1
examples/data/openweather/weather.json
Normal file
File diff suppressed because one or more lines are too long
@@ -4,6 +4,7 @@ import {Circle as CircleStyle, Fill, Stroke, Style} from '../src/ol/style.js';
|
||||
import {Draw, Modify, Snap} from '../src/ol/interaction.js';
|
||||
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {get} from '../src/ol/proj.js';
|
||||
|
||||
const raster = new TileLayer({
|
||||
source: new OSM(),
|
||||
@@ -29,12 +30,18 @@ const vector = new VectorLayer({
|
||||
}),
|
||||
});
|
||||
|
||||
// Limit multi-world panning to one world east and west of the real world.
|
||||
// Geometry coordinates have to be within that range.
|
||||
const extent = get('EPSG:3857').getExtent().slice();
|
||||
extent[0] += extent[0];
|
||||
extent[2] += extent[2];
|
||||
const map = new Map({
|
||||
layers: [raster, vector],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [-11000000, 4600000],
|
||||
zoom: 4,
|
||||
extent,
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@@ -1,30 +1,28 @@
|
||||
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 {Draw, Modify, Select, Snap} from '../src/ol/interaction.js';
|
||||
import {Map, View} from '../src/ol/index.js';
|
||||
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {useGeographic} from '../src/ol/proj.js';
|
||||
|
||||
useGeographic();
|
||||
|
||||
const source = new VectorSource({
|
||||
url: 'data/geojson/countries.geojson',
|
||||
url: 'https://openlayers.org/data/vector/us-states.json',
|
||||
format: new GeoJSON(),
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
target: 'map',
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM(),
|
||||
}),
|
||||
new VectorLayer({
|
||||
background: 'white',
|
||||
source: source,
|
||||
}),
|
||||
],
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
zoom: 2,
|
||||
center: [-100, 38.5],
|
||||
zoom: 4,
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@@ -1,20 +1,46 @@
|
||||
import GeoJSON from '../src/ol/format/GeoJSON.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {Fill, Style} from '../src/ol/style.js';
|
||||
import {
|
||||
Heatmap as HeatmapLayer,
|
||||
Vector as VectorLayer,
|
||||
} from '../src/ol/layer.js';
|
||||
import {asArray} from '../src/ol/color.js';
|
||||
|
||||
const style = new Style({
|
||||
fill: new Fill({
|
||||
color: '#eeeeee',
|
||||
}),
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM(),
|
||||
}),
|
||||
new VectorLayer({
|
||||
source: new VectorSource({
|
||||
url: 'data/geojson/countries.geojson',
|
||||
url: 'https://openlayers.org/data/vector/ecoregions.json',
|
||||
format: new GeoJSON(),
|
||||
}),
|
||||
opacity: 0.5,
|
||||
background: 'white',
|
||||
style: function (feature) {
|
||||
const color = asArray(feature.get('COLOR_NNH') || '#eeeeee');
|
||||
color[3] = 0.75;
|
||||
style.getFill().setColor(color);
|
||||
return style;
|
||||
},
|
||||
}),
|
||||
new HeatmapLayer({
|
||||
source: new VectorSource({
|
||||
url: 'data/geojson/world-cities.geojson',
|
||||
format: new GeoJSON(),
|
||||
}),
|
||||
weight: function (feature) {
|
||||
return feature.get('population') / 1e7;
|
||||
},
|
||||
radius: 15,
|
||||
blur: 15,
|
||||
opacity: 0.75,
|
||||
}),
|
||||
],
|
||||
target: 'map',
|
||||
@@ -32,17 +58,37 @@ document.getElementById('export-png').addEventListener('click', function () {
|
||||
mapCanvas.height = size[1];
|
||||
const mapContext = mapCanvas.getContext('2d');
|
||||
Array.prototype.forEach.call(
|
||||
document.querySelectorAll('.ol-layer canvas'),
|
||||
map.getViewport().querySelectorAll('.ol-layer canvas, canvas.ol-layer'),
|
||||
function (canvas) {
|
||||
if (canvas.width > 0) {
|
||||
const opacity = canvas.parentNode.style.opacity;
|
||||
const opacity =
|
||||
canvas.parentNode.style.opacity || canvas.style.opacity;
|
||||
mapContext.globalAlpha = opacity === '' ? 1 : Number(opacity);
|
||||
|
||||
const backgroundColor = canvas.parentNode.style.backgroundColor;
|
||||
if (backgroundColor) {
|
||||
mapContext.fillStyle = backgroundColor;
|
||||
mapContext.fillRect(0, 0, canvas.width, canvas.height);
|
||||
}
|
||||
|
||||
let matrix;
|
||||
const transform = canvas.style.transform;
|
||||
// Get the transform parameters from the style's transform matrix
|
||||
const matrix = transform
|
||||
.match(/^matrix\(([^\(]*)\)$/)[1]
|
||||
.split(',')
|
||||
.map(Number);
|
||||
if (transform) {
|
||||
// Get the transform parameters from the style's transform matrix
|
||||
matrix = transform
|
||||
.match(/^matrix\(([^\(]*)\)$/)[1]
|
||||
.split(',')
|
||||
.map(Number);
|
||||
} else {
|
||||
matrix = [
|
||||
parseFloat(canvas.style.width) / canvas.width,
|
||||
0,
|
||||
0,
|
||||
parseFloat(canvas.style.height) / canvas.height,
|
||||
0,
|
||||
0,
|
||||
];
|
||||
}
|
||||
// Apply the transform to the export map context
|
||||
CanvasRenderingContext2D.prototype.setTransform.apply(
|
||||
mapContext,
|
||||
|
||||
@@ -1,24 +1,15 @@
|
||||
import ExtentInteraction from '../src/ol/interaction/Extent.js';
|
||||
import GeoJSON from '../src/ol/format/GeoJSON.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {shiftKeyOnly} from '../src/ol/events/condition.js';
|
||||
|
||||
const vectorSource = new VectorSource({
|
||||
url: 'data/geojson/countries.geojson',
|
||||
format: new GeoJSON(),
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM(),
|
||||
}),
|
||||
new VectorLayer({
|
||||
source: vectorSource,
|
||||
}),
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
|
||||
13
examples/external-map.html
Normal file
13
examples/external-map.html
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: External map
|
||||
shortdesc: Move a map to a seperate window.
|
||||
docs: >
|
||||
Move a map to a seperate window.
|
||||
tags: "external, window"
|
||||
sources:
|
||||
- path: resources/external-map-map.html
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
<input id="external-map-button" type="button" value="Open external map"></input>
|
||||
<span id="blocker-notice" hidden>Could not open map in external window. If you are using a popup or ad blocker you may need to disable it for this example.</span>
|
||||
112
examples/external-map.js
Normal file
112
examples/external-map.js
Normal file
@@ -0,0 +1,112 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {
|
||||
Control,
|
||||
FullScreen,
|
||||
defaults as defaultControls,
|
||||
} from '../src/ol/control.js';
|
||||
import {fromLonLat} from '../src/ol/proj.js';
|
||||
|
||||
class UnusableMask extends Control {
|
||||
constructor() {
|
||||
super({
|
||||
element: document.createElement('div'),
|
||||
});
|
||||
this.element.setAttribute('hidden', 'hidden');
|
||||
this.element.className = 'ol-mask';
|
||||
this.element.innerHTML = '<div>Map not usable</div>';
|
||||
}
|
||||
}
|
||||
|
||||
const localMapTarget = document.getElementById('map');
|
||||
|
||||
const map = new Map({
|
||||
target: localMapTarget,
|
||||
controls: defaultControls().extend([new FullScreen(), new UnusableMask()]),
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM(),
|
||||
}),
|
||||
],
|
||||
view: new View({
|
||||
center: fromLonLat([37.41, 8.82]),
|
||||
zoom: 4,
|
||||
}),
|
||||
});
|
||||
|
||||
let mapWindow;
|
||||
function closeMapWindow() {
|
||||
if (mapWindow) {
|
||||
mapWindow.close();
|
||||
mapWindow = undefined;
|
||||
}
|
||||
}
|
||||
// Close external window in case the main page is closed or reloaded
|
||||
window.addEventListener('pagehide', closeMapWindow);
|
||||
|
||||
const button = document.getElementById('external-map-button');
|
||||
|
||||
function resetMapTarget() {
|
||||
localMapTarget.style.height = '';
|
||||
map.setTarget(localMapTarget);
|
||||
button.disabled = false;
|
||||
}
|
||||
|
||||
function updateOverlay() {
|
||||
if (!mapWindow) {
|
||||
return;
|
||||
}
|
||||
const externalMapTarget = mapWindow.document.getElementById('map');
|
||||
if (!externalMapTarget) {
|
||||
return;
|
||||
}
|
||||
if (document.visibilityState === 'visible') {
|
||||
// Show controls and enable keyboard input
|
||||
externalMapTarget.classList.remove('unusable');
|
||||
externalMapTarget.setAttribute('tabindex', '0');
|
||||
externalMapTarget.focus();
|
||||
} else {
|
||||
// Hide all controls and disable keyboard input
|
||||
externalMapTarget.removeAttribute('tabindex');
|
||||
externalMapTarget.classList.add('unusable');
|
||||
}
|
||||
}
|
||||
window.addEventListener('visibilitychange', updateOverlay);
|
||||
|
||||
button.addEventListener('click', function () {
|
||||
const blockerNotice = document.getElementById('blocker-notice');
|
||||
blockerNotice.setAttribute('hidden', 'hidden');
|
||||
button.disabled = true;
|
||||
|
||||
// Reset button and map target in case window did not load or open
|
||||
let timeoutKey = setTimeout(function () {
|
||||
closeMapWindow();
|
||||
resetMapTarget();
|
||||
blockerNotice.removeAttribute('hidden');
|
||||
timeoutKey = undefined;
|
||||
}, 3000);
|
||||
|
||||
mapWindow = window.open(
|
||||
'resources/external-map-map.html',
|
||||
'MapWindow',
|
||||
'toolbar=0,location=0,menubar=0,width=800,height=600'
|
||||
);
|
||||
mapWindow.addEventListener('DOMContentLoaded', function () {
|
||||
const externalMapTarget = mapWindow.document.getElementById('map');
|
||||
localMapTarget.style.height = '0px';
|
||||
map.setTarget(externalMapTarget);
|
||||
|
||||
if (timeoutKey) {
|
||||
timeoutKey = clearTimeout(timeoutKey);
|
||||
}
|
||||
mapWindow.addEventListener('pagehide', function () {
|
||||
resetMapTarget();
|
||||
// Close window in case user does a page reload
|
||||
closeMapWindow();
|
||||
});
|
||||
|
||||
updateOverlay();
|
||||
});
|
||||
});
|
||||
@@ -7,6 +7,7 @@ import View from '../src/ol/View.js';
|
||||
import {Stroke, Style} from '../src/ol/style.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {getVectorContext} from '../src/ol/render.js';
|
||||
import {getWidth} from '../src/ol/extent.js';
|
||||
|
||||
const tileLayer = new TileLayer({
|
||||
source: new Stamen({
|
||||
@@ -18,7 +19,7 @@ const map = new Map({
|
||||
layers: [tileLayer],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
center: [-11000000, 4600000],
|
||||
zoom: 2,
|
||||
}),
|
||||
});
|
||||
@@ -31,7 +32,6 @@ const style = new Style({
|
||||
});
|
||||
|
||||
const flightsSource = new VectorSource({
|
||||
wrapX: false,
|
||||
attributions:
|
||||
'Flight data by ' +
|
||||
'<a href="https://openflights.org/data.html">OpenFlights</a>,',
|
||||
@@ -55,18 +55,23 @@ const flightsSource = new VectorSource({
|
||||
);
|
||||
|
||||
const arcLine = arcGenerator.Arc(100, {offset: 10});
|
||||
if (arcLine.geometries.length === 1) {
|
||||
const line = new LineString(arcLine.geometries[0].coords);
|
||||
// paths which cross the -180°/+180° meridian are split
|
||||
// into two sections which will be animated sequentially
|
||||
const features = [];
|
||||
arcLine.geometries.forEach(function (geometry) {
|
||||
const line = new LineString(geometry.coords);
|
||||
line.transform('EPSG:4326', 'EPSG:3857');
|
||||
|
||||
const feature = new Feature({
|
||||
geometry: line,
|
||||
finished: false,
|
||||
});
|
||||
// add the feature with a delay so that the animation
|
||||
// for all features does not start at the same time
|
||||
addLater(feature, i * 50);
|
||||
}
|
||||
features.push(
|
||||
new Feature({
|
||||
geometry: line,
|
||||
finished: false,
|
||||
})
|
||||
);
|
||||
});
|
||||
// add the features with a delay so that the animation
|
||||
// for all features does not start at the same time
|
||||
addLater(features, i * 50);
|
||||
}
|
||||
tileLayer.on('postrender', animateFlights);
|
||||
});
|
||||
@@ -88,7 +93,7 @@ const flightsLayer = new VectorLayer({
|
||||
|
||||
map.addLayer(flightsLayer);
|
||||
|
||||
const pointsPerMs = 0.1;
|
||||
const pointsPerMs = 0.02;
|
||||
function animateFlights(event) {
|
||||
const vectorContext = getVectorContext(event);
|
||||
const frameState = event.frameState;
|
||||
@@ -101,26 +106,41 @@ function animateFlights(event) {
|
||||
// only draw the lines for which the animation has not finished yet
|
||||
const coords = feature.getGeometry().getCoordinates();
|
||||
const elapsedTime = frameState.time - feature.get('start');
|
||||
const elapsedPoints = elapsedTime * pointsPerMs;
|
||||
if (elapsedTime >= 0) {
|
||||
const elapsedPoints = elapsedTime * pointsPerMs;
|
||||
|
||||
if (elapsedPoints >= coords.length) {
|
||||
feature.set('finished', true);
|
||||
if (elapsedPoints >= coords.length) {
|
||||
feature.set('finished', true);
|
||||
}
|
||||
|
||||
const maxIndex = Math.min(elapsedPoints, coords.length);
|
||||
const currentLine = new LineString(coords.slice(0, maxIndex));
|
||||
|
||||
// animation is needed in the current and nearest adjacent wrapped world
|
||||
const worldWidth = getWidth(map.getView().getProjection().getExtent());
|
||||
const offset = Math.floor(map.getView().getCenter()[0] / worldWidth);
|
||||
|
||||
// directly draw the lines with the vector context
|
||||
currentLine.translate(offset * worldWidth, 0);
|
||||
vectorContext.drawGeometry(currentLine);
|
||||
currentLine.translate(worldWidth, 0);
|
||||
vectorContext.drawGeometry(currentLine);
|
||||
}
|
||||
|
||||
const maxIndex = Math.min(elapsedPoints, coords.length);
|
||||
const currentLine = new LineString(coords.slice(0, maxIndex));
|
||||
|
||||
// directly draw the line with the vector context
|
||||
vectorContext.drawGeometry(currentLine);
|
||||
}
|
||||
}
|
||||
// tell OpenLayers to continue the animation
|
||||
map.render();
|
||||
}
|
||||
|
||||
function addLater(feature, timeout) {
|
||||
function addLater(features, timeout) {
|
||||
window.setTimeout(function () {
|
||||
feature.set('start', Date.now());
|
||||
flightsSource.addFeature(feature);
|
||||
let start = Date.now();
|
||||
features.forEach(function (feature) {
|
||||
feature.set('start', start);
|
||||
flightsSource.addFeature(feature);
|
||||
const duration =
|
||||
(feature.getGeometry().getCoordinates().length - 1) / pointsPerMs;
|
||||
start += duration;
|
||||
});
|
||||
}, timeout);
|
||||
}
|
||||
|
||||
@@ -63,10 +63,15 @@ map.on('moveend', function () {
|
||||
});
|
||||
|
||||
map.on('click', function (event) {
|
||||
$(element).popover('dispose');
|
||||
|
||||
const feature = map.getFeaturesAtPixel(event.pixel)[0];
|
||||
if (feature) {
|
||||
const coordinate = feature.getGeometry().getCoordinates();
|
||||
popup.setPosition(coordinate);
|
||||
popup.setPosition([
|
||||
coordinate[0] + Math.round(event.coordinate[0] / 360) * 360,
|
||||
coordinate[1],
|
||||
]);
|
||||
$(element).popover({
|
||||
container: element.parentElement,
|
||||
html: true,
|
||||
@@ -75,8 +80,6 @@ map.on('click', function (event) {
|
||||
placement: 'top',
|
||||
});
|
||||
$(element).popover('show');
|
||||
} else {
|
||||
$(element).popover('dispose');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,60 +1,67 @@
|
||||
import GeoJSON from '../src/ol/format/GeoJSON.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
import Projection from '../src/ol/proj/Projection.js';
|
||||
import VectorTileLayer from '../src/ol/layer/VectorTile.js';
|
||||
import VectorTileSource from '../src/ol/source/VectorTile.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {
|
||||
Tile as TileLayer,
|
||||
VectorTile as VectorTileLayer,
|
||||
} from '../src/ol/layer.js';
|
||||
import {Fill, Style} from '../src/ol/style.js';
|
||||
|
||||
// Converts geojson-vt data to GeoJSON
|
||||
const replacer = function (key, value) {
|
||||
if (value.geometry) {
|
||||
let type;
|
||||
const rawType = value.type;
|
||||
let geometry = value.geometry;
|
||||
|
||||
if (rawType === 1) {
|
||||
type = 'MultiPoint';
|
||||
if (geometry.length == 1) {
|
||||
type = 'Point';
|
||||
geometry = geometry[0];
|
||||
}
|
||||
} else if (rawType === 2) {
|
||||
type = 'MultiLineString';
|
||||
if (geometry.length == 1) {
|
||||
type = 'LineString';
|
||||
geometry = geometry[0];
|
||||
}
|
||||
} else if (rawType === 3) {
|
||||
type = 'Polygon';
|
||||
if (geometry.length > 1) {
|
||||
type = 'MultiPolygon';
|
||||
geometry = [geometry];
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
'type': 'Feature',
|
||||
'geometry': {
|
||||
'type': type,
|
||||
'coordinates': geometry,
|
||||
},
|
||||
'properties': value.tags,
|
||||
};
|
||||
} else {
|
||||
if (!value || !value.geometry) {
|
||||
return value;
|
||||
}
|
||||
|
||||
let type;
|
||||
const rawType = value.type;
|
||||
let geometry = value.geometry;
|
||||
if (rawType === 1) {
|
||||
type = 'MultiPoint';
|
||||
if (geometry.length == 1) {
|
||||
type = 'Point';
|
||||
geometry = geometry[0];
|
||||
}
|
||||
} else if (rawType === 2) {
|
||||
type = 'MultiLineString';
|
||||
if (geometry.length == 1) {
|
||||
type = 'LineString';
|
||||
geometry = geometry[0];
|
||||
}
|
||||
} else if (rawType === 3) {
|
||||
type = 'Polygon';
|
||||
if (geometry.length > 1) {
|
||||
type = 'MultiPolygon';
|
||||
geometry = [geometry];
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
'type': 'Feature',
|
||||
'geometry': {
|
||||
'type': type,
|
||||
'coordinates': geometry,
|
||||
},
|
||||
'properties': value.tags,
|
||||
};
|
||||
};
|
||||
|
||||
const style = new Style({
|
||||
fill: new Fill({
|
||||
color: '#eeeeee',
|
||||
}),
|
||||
});
|
||||
|
||||
const layer = new VectorTileLayer({
|
||||
background: '#1a2b39',
|
||||
style: function (feature) {
|
||||
const color = feature.get('COLOR') || '#eeeeee';
|
||||
style.getFill().setColor(color);
|
||||
return style;
|
||||
},
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM(),
|
||||
}),
|
||||
],
|
||||
layers: [layer],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
@@ -62,7 +69,7 @@ const map = new Map({
|
||||
}),
|
||||
});
|
||||
|
||||
const url = 'data/geojson/countries.geojson';
|
||||
const url = 'https://openlayers.org/data/vector/ecoregions.json';
|
||||
fetch(url)
|
||||
.then(function (response) {
|
||||
return response.json();
|
||||
@@ -106,8 +113,5 @@ fetch(url)
|
||||
tile.setFeatures(features);
|
||||
},
|
||||
});
|
||||
const vectorLayer = new VectorTileLayer({
|
||||
source: vectorSource,
|
||||
});
|
||||
map.addLayer(vectorLayer);
|
||||
layer.setSource(vectorSource);
|
||||
});
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Vector Layer Hit Detection
|
||||
shortdesc: Example of hit detection on a countries vector layer with country information.
|
||||
shortdesc: Example of hit detection on an ecoregions vector layer with protection status.
|
||||
docs: >
|
||||
The countries are loaded from a GeoJSON file. Information about countries is
|
||||
on hover and click is retrieved using the layer's `getFeatures()` method. For
|
||||
The ecoregions are loaded from a GeoJSON file. Information about features is
|
||||
retrieved using the layer's `getFeatures()` method on hover and click. For
|
||||
vector layers, this function resolves with an array of only the topmost
|
||||
feature. It uses a very efficient hit detection algorithm, at the cost of
|
||||
feature. It uses an efficient hit detection algorithm, at the cost of
|
||||
accuracy. For pixel exact hit detection, when performance is not a concern,
|
||||
use the map's `getFeaturesAtPixel()` or `forEachFeatureAtPixel()` methods.
|
||||
tags: "vector, geojson, click, hover, hit detection"
|
||||
|
||||
@@ -3,35 +3,23 @@ import Map from '../src/ol/Map.js';
|
||||
import VectorLayer from '../src/ol/layer/Vector.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {Fill, Stroke, Style, Text} from '../src/ol/style.js';
|
||||
import {Fill, Stroke, Style} from '../src/ol/style.js';
|
||||
|
||||
const style = new Style({
|
||||
fill: new Fill({
|
||||
color: 'rgba(255, 255, 255, 0.6)',
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
color: '#319FD3',
|
||||
width: 1,
|
||||
}),
|
||||
text: new Text({
|
||||
font: '12px Calibri,sans-serif',
|
||||
fill: new Fill({
|
||||
color: '#000',
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
color: '#fff',
|
||||
width: 3,
|
||||
}),
|
||||
color: '#eeeeee',
|
||||
}),
|
||||
});
|
||||
|
||||
const vectorLayer = new VectorLayer({
|
||||
background: '#1a2b39',
|
||||
source: new VectorSource({
|
||||
url: 'data/geojson/countries.geojson',
|
||||
url: 'https://openlayers.org/data/vector/ecoregions.json',
|
||||
format: new GeoJSON(),
|
||||
}),
|
||||
style: function (feature) {
|
||||
style.getText().setText(feature.get('name'));
|
||||
const color = feature.get('COLOR_NNH') || '#eeeeee';
|
||||
style.getFill().setColor(color);
|
||||
return style;
|
||||
},
|
||||
});
|
||||
@@ -47,31 +35,15 @@ const map = new Map({
|
||||
|
||||
const highlightStyle = new Style({
|
||||
stroke: new Stroke({
|
||||
color: '#f00',
|
||||
width: 1,
|
||||
}),
|
||||
fill: new Fill({
|
||||
color: 'rgba(255,0,0,0.1)',
|
||||
}),
|
||||
text: new Text({
|
||||
font: '12px Calibri,sans-serif',
|
||||
fill: new Fill({
|
||||
color: '#000',
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
color: '#f00',
|
||||
width: 3,
|
||||
}),
|
||||
color: 'rgba(255, 255, 255, 0.7)',
|
||||
width: 2,
|
||||
}),
|
||||
});
|
||||
|
||||
const featureOverlay = new VectorLayer({
|
||||
source: new VectorSource(),
|
||||
map: map,
|
||||
style: function (feature) {
|
||||
highlightStyle.getText().setText(feature.get('name'));
|
||||
return highlightStyle;
|
||||
},
|
||||
style: highlightStyle,
|
||||
});
|
||||
|
||||
let highlight;
|
||||
@@ -80,7 +52,7 @@ const displayFeatureInfo = function (pixel) {
|
||||
const feature = features.length ? features[0] : undefined;
|
||||
const info = document.getElementById('info');
|
||||
if (features.length) {
|
||||
info.innerHTML = feature.getId() + ': ' + feature.get('name');
|
||||
info.innerHTML = feature.get('ECO_NAME') + ': ' + feature.get('NNH_NAME');
|
||||
} else {
|
||||
info.innerHTML = ' ';
|
||||
}
|
||||
|
||||
@@ -4,33 +4,30 @@ import VectorImageLayer from '../src/ol/layer/VectorImage.js';
|
||||
import VectorLayer from '../src/ol/layer/Vector.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {Fill, Stroke, Style, Text} from '../src/ol/style.js';
|
||||
import {Fill, Stroke, Style} from '../src/ol/style.js';
|
||||
|
||||
const style = new Style({
|
||||
fill: new Fill({
|
||||
color: 'rgba(255, 255, 255, 0.6)',
|
||||
color: '#eeeeee',
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
color: '#319FD3',
|
||||
width: 1,
|
||||
});
|
||||
|
||||
const vectorLayer = new VectorImageLayer({
|
||||
background: '#1a2b39',
|
||||
imageRatio: 2,
|
||||
source: new VectorSource({
|
||||
url: 'https://openlayers.org/data/vector/ecoregions.json',
|
||||
format: new GeoJSON(),
|
||||
}),
|
||||
text: new Text(),
|
||||
style: function (feature) {
|
||||
const color = feature.get('COLOR') || '#eeeeee';
|
||||
style.getFill().setColor(color);
|
||||
return style;
|
||||
},
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
layers: [
|
||||
new VectorImageLayer({
|
||||
imageRatio: 2,
|
||||
source: new VectorSource({
|
||||
url: 'data/geojson/countries.geojson',
|
||||
format: new GeoJSON(),
|
||||
}),
|
||||
style: function (feature) {
|
||||
style.getText().setText(feature.get('name'));
|
||||
return style;
|
||||
},
|
||||
}),
|
||||
],
|
||||
layers: [vectorLayer],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
@@ -43,47 +40,42 @@ const featureOverlay = new VectorLayer({
|
||||
map: map,
|
||||
style: new Style({
|
||||
stroke: new Stroke({
|
||||
color: '#f00',
|
||||
width: 1,
|
||||
}),
|
||||
fill: new Fill({
|
||||
color: 'rgba(255,0,0,0.1)',
|
||||
color: 'rgba(255, 255, 255, 0.7)',
|
||||
width: 2,
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
let highlight;
|
||||
const displayFeatureInfo = function (pixel) {
|
||||
map
|
||||
.getLayers()
|
||||
.item(0)
|
||||
.getFeatures(pixel)
|
||||
.then(function (features) {
|
||||
const feature = features.length > 0 ? features[0] : undefined;
|
||||
const feature = map.forEachFeatureAtPixel(pixel, function (feature) {
|
||||
return feature;
|
||||
});
|
||||
|
||||
const info = document.getElementById('info');
|
||||
if (feature) {
|
||||
info.innerHTML = feature.getId() + ': ' + feature.get('name');
|
||||
} else {
|
||||
info.innerHTML = ' ';
|
||||
}
|
||||
const info = document.getElementById('info');
|
||||
if (feature) {
|
||||
info.innerHTML = feature.get('ECO_NAME') || ' ';
|
||||
} else {
|
||||
info.innerHTML = ' ';
|
||||
}
|
||||
|
||||
if (feature !== highlight) {
|
||||
if (highlight) {
|
||||
featureOverlay.getSource().removeFeature(highlight);
|
||||
}
|
||||
if (feature) {
|
||||
featureOverlay.getSource().addFeature(feature);
|
||||
}
|
||||
highlight = feature;
|
||||
}
|
||||
});
|
||||
if (feature !== highlight) {
|
||||
if (highlight) {
|
||||
featureOverlay.getSource().removeFeature(highlight);
|
||||
}
|
||||
if (feature) {
|
||||
featureOverlay.getSource().addFeature(feature);
|
||||
}
|
||||
highlight = feature;
|
||||
}
|
||||
};
|
||||
|
||||
map.on('pointermove', function (evt) {
|
||||
if (!evt.dragging) {
|
||||
displayFeatureInfo(evt.pixel);
|
||||
if (evt.dragging) {
|
||||
return;
|
||||
}
|
||||
const pixel = map.getEventPixel(evt.originalEvent);
|
||||
displayFeatureInfo(pixel);
|
||||
});
|
||||
|
||||
map.on('click', function (evt) {
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Disable Image Smoothing
|
||||
shortdesc: Example of disabling image smoothing
|
||||
title: Interpolation
|
||||
shortdesc: Example of data interpolation
|
||||
docs: >
|
||||
Example of disabling image smoothing when using raster DEM (digital elevation model) data.
|
||||
The <code>imageSmoothing: false</code> setting is used to disable canvas image smoothing during
|
||||
Example of data resampling when using raster DEM (digital elevation model) data.
|
||||
The <code>interpolate: false</code> setting is used to disable interpolation of data values during
|
||||
reprojection and rendering. Elevation data is
|
||||
calculated from the pixel value returned by <b>forEachLayerAtPixel</b>. For comparison a second map
|
||||
with smoothing enabled returns inaccuate elevations which are very noticeable close to 3107 meters
|
||||
with interpolation enabled returns inaccurate elevations which are very noticeable close to 3107 meters
|
||||
due to how elevation is calculated from the pixel value.
|
||||
tags: "disable image smoothing, xyz, maptiler, reprojection"
|
||||
tags: "disable image interpolation, xyz, maptiler, reprojection"
|
||||
cloak:
|
||||
- key: get_your_own_D6rA4zTHduk6KOKTXzGB
|
||||
value: Get your own API key at https://www.maptiler.com/cloud/
|
||||
---
|
||||
<div class="wrapper">
|
||||
<div class="half">
|
||||
<h4>Smoothing Disabled</h4>
|
||||
<h4>Not Interpolated</h4>
|
||||
<div id="map1" class="map"></div>
|
||||
<div>
|
||||
<label>
|
||||
@@ -24,16 +24,9 @@ cloak:
|
||||
<span id="info1">0.0</span> meters
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label>
|
||||
Imagery opacity
|
||||
<input id="opacity" type="range" min="0" max="100" value="80" />
|
||||
<span id="output"></span> %
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="half">
|
||||
<h4>Uncorrected Comparison</h4>
|
||||
<h4>Interpolated</h4>
|
||||
<div id="map2" class="map"></div>
|
||||
<div>
|
||||
<label>
|
||||
@@ -8,63 +8,31 @@ const attributions =
|
||||
'<a href="https://www.maptiler.com/copyright/" target="_blank">© MapTiler</a> ' +
|
||||
'<a href="https://www.openstreetmap.org/copyright" target="_blank">© OpenStreetMap contributors</a>';
|
||||
|
||||
const disabledLayer = new TileLayer({
|
||||
const notInterpolated = new TileLayer({
|
||||
// specify className so forEachLayerAtPixel can distinguish layers
|
||||
className: 'ol-layer-dem',
|
||||
source: new XYZ({
|
||||
attributions: attributions,
|
||||
url:
|
||||
'https://api.maptiler.com/tiles/terrain-rgb/{z}/{x}/{y}.png?key=' + key,
|
||||
maxZoom: 10,
|
||||
tileSize: 512,
|
||||
maxZoom: 12,
|
||||
crossOrigin: '',
|
||||
imageSmoothing: false,
|
||||
interpolate: false,
|
||||
}),
|
||||
});
|
||||
|
||||
const imagery = new TileLayer({
|
||||
className: 'ol-layer-imagery',
|
||||
source: new XYZ({
|
||||
attributions: attributions,
|
||||
url: 'https://api.maptiler.com/tiles/satellite/{z}/{x}/{y}.jpg?key=' + key,
|
||||
maxZoom: 20,
|
||||
crossOrigin: '',
|
||||
}),
|
||||
});
|
||||
|
||||
const enabledLayer = new TileLayer({
|
||||
const interpolated = new TileLayer({
|
||||
source: new XYZ({
|
||||
attributions: attributions,
|
||||
url:
|
||||
'https://api.maptiler.com/tiles/terrain-rgb/{z}/{x}/{y}.png?key=' + key,
|
||||
maxZoom: 10,
|
||||
tileSize: 512,
|
||||
maxZoom: 12,
|
||||
crossOrigin: '',
|
||||
}),
|
||||
});
|
||||
|
||||
imagery.on('prerender', function (evt) {
|
||||
// use opaque background to conceal DEM while fully opaque imagery renders
|
||||
if (imagery.getOpacity() === 1) {
|
||||
evt.context.fillStyle = 'white';
|
||||
evt.context.fillRect(
|
||||
0,
|
||||
0,
|
||||
evt.context.canvas.width,
|
||||
evt.context.canvas.height
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
const control = document.getElementById('opacity');
|
||||
const output = document.getElementById('output');
|
||||
const listener = function () {
|
||||
output.innerText = control.value;
|
||||
imagery.setOpacity(control.value / 100);
|
||||
};
|
||||
control.addEventListener('input', listener);
|
||||
control.addEventListener('change', listener);
|
||||
output.innerText = control.value;
|
||||
imagery.setOpacity(control.value / 100);
|
||||
|
||||
const view = new View({
|
||||
center: [6.893, 45.8295],
|
||||
zoom: 16,
|
||||
@@ -73,13 +41,13 @@ const view = new View({
|
||||
|
||||
const map1 = new Map({
|
||||
target: 'map1',
|
||||
layers: [disabledLayer, imagery],
|
||||
layers: [notInterpolated],
|
||||
view: view,
|
||||
});
|
||||
|
||||
const map2 = new Map({
|
||||
target: 'map2',
|
||||
layers: [enabledLayer],
|
||||
layers: [interpolated],
|
||||
view: view,
|
||||
});
|
||||
|
||||
@@ -99,7 +67,7 @@ const showElevations = function (evt) {
|
||||
},
|
||||
{
|
||||
layerFilter: function (layer) {
|
||||
return layer === disabledLayer;
|
||||
return layer === notInterpolated;
|
||||
},
|
||||
}
|
||||
);
|
||||
@@ -112,7 +80,7 @@ const showElevations = function (evt) {
|
||||
},
|
||||
{
|
||||
layerFilter: function (layer) {
|
||||
return layer === enabledLayer;
|
||||
return layer === interpolated;
|
||||
},
|
||||
}
|
||||
);
|
||||
@@ -18,7 +18,7 @@ cloak:
|
||||
<li><span>OSM layer</span>
|
||||
<fieldset id="layer0">
|
||||
<label class="checkbox" for="visible0">
|
||||
visibile <input id="visible0" class="visible" type="checkbox"/>
|
||||
visible <input id="visible0" class="visible" type="checkbox"/>
|
||||
</label>
|
||||
<label>
|
||||
opacity <input class="opacity" type="range" min="0" max="1" step="0.01"/>
|
||||
@@ -29,7 +29,7 @@ cloak:
|
||||
<span>Layer group</span>
|
||||
<fieldset id="layer1">
|
||||
<label class="checkbox" for="visible1">
|
||||
visibile <input id="visible1" class="visible" type="checkbox"/>
|
||||
visible <input id="visible1" class="visible" type="checkbox"/>
|
||||
</label>
|
||||
<label>
|
||||
opacity <input class="opacity" type="range" min="0" max="1" step="0.01"/>
|
||||
@@ -40,7 +40,7 @@ cloak:
|
||||
<span>Food insecurity layer</span>
|
||||
<fieldset id="layer10">
|
||||
<label class="checkbox" for="visible10">
|
||||
visibile <input id="visible10" class="visible" type="checkbox"/>
|
||||
visible <input id="visible10" class="visible" type="checkbox"/>
|
||||
</label>
|
||||
<label>
|
||||
opacity <input class="opacity" type="range" min="0" max="1" step="0.01"/>
|
||||
@@ -51,7 +51,7 @@ cloak:
|
||||
<span>World borders layer</span>
|
||||
<fieldset id="layer11">
|
||||
<label class="checkbox" for="visible11">
|
||||
visibile <input id="visible11" class="visible" type="checkbox"/>
|
||||
visible <input id="visible11" class="visible" type="checkbox"/>
|
||||
</label>
|
||||
<label>
|
||||
opacity <input class="opacity" type="range" min="0" max="1" step="0.01"/>
|
||||
|
||||
17
examples/layer-opacity.html
Normal file
17
examples/layer-opacity.html
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Layer Opacity
|
||||
shortdesc: Adjust layer opacity based on user input
|
||||
docs: >
|
||||
The `layer.setOpacity()` method can be called to adjust the opacity of a layer.
|
||||
tags: "opacity"
|
||||
cloak:
|
||||
- key: get_your_own_D6rA4zTHduk6KOKTXzGB
|
||||
value: Get your own API key at https://www.maptiler.com/cloud/
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
<label>
|
||||
Layer opacity
|
||||
<input id="opacity-input" type="range" min="0" max="1" step="0.01" value="1" />
|
||||
<span id="opacity-output"></span>
|
||||
</label>
|
||||
42
examples/layer-opacity.js
Normal file
42
examples/layer-opacity.js
Normal file
@@ -0,0 +1,42 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
import TileLayer from '../src/ol/layer/WebGLTile.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import XYZ from '../src/ol/source/XYZ.js';
|
||||
|
||||
const key = 'get_your_own_D6rA4zTHduk6KOKTXzGB';
|
||||
|
||||
const imagery = new TileLayer({
|
||||
className: 'ol-layer-imagery',
|
||||
source: new XYZ({
|
||||
attributions:
|
||||
'<a href="https://www.maptiler.com/copyright/" target="_blank">© MapTiler</a> ',
|
||||
url: 'https://api.maptiler.com/tiles/satellite/{z}/{x}/{y}.jpg?key=' + key,
|
||||
maxZoom: 20,
|
||||
crossOrigin: '',
|
||||
}),
|
||||
});
|
||||
|
||||
const osm = new TileLayer({
|
||||
source: new OSM(),
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
layers: [imagery, osm],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
zoom: 2,
|
||||
}),
|
||||
});
|
||||
|
||||
const opacityInput = document.getElementById('opacity-input');
|
||||
const opacityOutput = document.getElementById('opacity-output');
|
||||
function update() {
|
||||
const opacity = parseFloat(opacityInput.value);
|
||||
osm.setOpacity(opacity);
|
||||
opacityOutput.innerText = opacity.toFixed(2);
|
||||
}
|
||||
opacityInput.addEventListener('input', update);
|
||||
opacityInput.addEventListener('change', update);
|
||||
update();
|
||||
@@ -5,6 +5,7 @@ import View from '../src/ol/View.js';
|
||||
import {Icon, Stroke, Style} from '../src/ol/style.js';
|
||||
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {get} from '../src/ol/proj.js';
|
||||
|
||||
const raster = new TileLayer({
|
||||
source: new OSM(),
|
||||
@@ -49,12 +50,19 @@ const vector = new VectorLayer({
|
||||
style: styleFunction,
|
||||
});
|
||||
|
||||
// Limit multi-world panning to one world east and west of the real world.
|
||||
// Geometry coordinates have to be within that range.
|
||||
const extent = get('EPSG:3857').getExtent().slice();
|
||||
extent[0] += extent[0];
|
||||
extent[2] += extent[2];
|
||||
|
||||
const map = new Map({
|
||||
layers: [raster, vector],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [-11000000, 4600000],
|
||||
zoom: 4,
|
||||
extent,
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import GeoJSON from '../src/ol/format/GeoJSON.js';
|
||||
import HeatmapLayer from '../src/ol/layer/Heatmap.js';
|
||||
import Layer from '../src/ol/layer/Layer.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import Source from '../src/ol/source/Source.js';
|
||||
import VectorLayer from '../src/ol/layer/Vector.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {Stroke, Style} from '../src/ol/style.js';
|
||||
import {fromLonLat, toLonLat} from '../src/ol/proj.js';
|
||||
|
||||
const center = [-98.8, 37.9];
|
||||
@@ -34,6 +33,7 @@ const mbLayer = new Layer({
|
||||
|
||||
const visible = mbLayer.getVisible();
|
||||
canvas.style.display = visible ? 'block' : 'none';
|
||||
canvas.style.position = 'absolute';
|
||||
|
||||
const opacity = mbLayer.getOpacity();
|
||||
canvas.style.opacity = opacity;
|
||||
@@ -66,19 +66,16 @@ const mbLayer = new Layer({
|
||||
}),
|
||||
});
|
||||
|
||||
const style = new Style({
|
||||
stroke: new Stroke({
|
||||
color: '#319FD3',
|
||||
width: 2,
|
||||
}),
|
||||
});
|
||||
|
||||
const vectorLayer = new VectorLayer({
|
||||
const cities = new HeatmapLayer({
|
||||
source: new VectorSource({
|
||||
url: 'data/geojson/countries.geojson',
|
||||
url: 'data/geojson/world-cities.geojson',
|
||||
format: new GeoJSON(),
|
||||
}),
|
||||
style: style,
|
||||
weight: function (feature) {
|
||||
return feature.get('population') / 1e7;
|
||||
},
|
||||
radius: 15,
|
||||
blur: 15,
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
@@ -87,5 +84,5 @@ const map = new Map({
|
||||
center: fromLonLat(center),
|
||||
zoom: 4,
|
||||
}),
|
||||
layers: [mbLayer, vectorLayer],
|
||||
layers: [mbLayer, cities],
|
||||
});
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
.map {
|
||||
background: #f8f4f0;
|
||||
}
|
||||
@@ -4,7 +4,7 @@ title: Full-Screen Mobile
|
||||
shortdesc: Example of a full screen map.
|
||||
tags: "fullscreen, geolocation, mobile"
|
||||
cloak:
|
||||
- key: ApTJzdkyN1DdFKkRAE6QIDtzihNaf6IWJsT-nQ_2eMoO4PN__0Tzhl2-WgJtXFSp
|
||||
- key: AlEoTLTlzFB6Uf4Sy-ugXcRO21skQO7K8eObA5_L-8d20rjqZJLs2nkO1RMjGSPN
|
||||
value: Your Bing Maps Key from https://www.bingmapsportal.com/ here
|
||||
---
|
||||
<!doctype html>
|
||||
|
||||
@@ -13,7 +13,7 @@ const map = new Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new BingMaps({
|
||||
key: 'ApTJzdkyN1DdFKkRAE6QIDtzihNaf6IWJsT-nQ_2eMoO4PN__0Tzhl2-WgJtXFSp ',
|
||||
key: 'AlEoTLTlzFB6Uf4Sy-ugXcRO21skQO7K8eObA5_L-8d20rjqZJLs2nkO1RMjGSPN',
|
||||
imagerySet: 'RoadOnDemand',
|
||||
}),
|
||||
}),
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
import GeoJSON from '../src/ol/format/GeoJSON.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import VectorLayer from '../src/ol/layer/Vector.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {
|
||||
Modify,
|
||||
Select,
|
||||
defaults as defaultInteractions,
|
||||
} from '../src/ol/interaction.js';
|
||||
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
|
||||
const raster = new TileLayer({
|
||||
source: new OSM(),
|
||||
});
|
||||
import {fromLonLat} from '../src/ol/proj.js';
|
||||
|
||||
const vector = new VectorLayer({
|
||||
background: 'white',
|
||||
source: new VectorSource({
|
||||
url: 'data/geojson/countries.geojson',
|
||||
url: 'https://openlayers.org/data/vector/us-states.json',
|
||||
format: new GeoJSON(),
|
||||
wrapX: false,
|
||||
}),
|
||||
@@ -31,10 +29,10 @@ const modify = new Modify({
|
||||
|
||||
const map = new Map({
|
||||
interactions: defaultInteractions().extend([select, modify]),
|
||||
layers: [raster, vector],
|
||||
layers: [vector],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
zoom: 2,
|
||||
center: fromLonLat([-100, 38.5]),
|
||||
zoom: 4,
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -6,10 +6,12 @@ docs: >
|
||||
The map in this example is rendered in a web worker, using `OffscreenCanvas`. **Note:** This is currently only supported in Chrome and Edge.
|
||||
tags: "worker, offscreencanvas, vector-tiles"
|
||||
experimental: true
|
||||
sources:
|
||||
- path: offscreen-canvas.worker.js
|
||||
as: worker.js
|
||||
cloak:
|
||||
- key: get_your_own_D6rA4zTHduk6KOKTXzGB
|
||||
value: Get your own API key at https://www.maptiler.com/cloud/
|
||||
|
||||
---
|
||||
<div id="map" class="map">
|
||||
<pre id="info" class="info"/>
|
||||
|
||||
@@ -18,9 +18,10 @@ const closer = document.getElementById('popup-closer');
|
||||
*/
|
||||
const overlay = new Overlay({
|
||||
element: container,
|
||||
autoPan: true,
|
||||
autoPanAnimation: {
|
||||
duration: 250,
|
||||
autoPan: {
|
||||
animation: {
|
||||
duration: 250,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ docs: >
|
||||
<p>The map on the top preloads low resolution tiles. The map on the bottom does not use any preloading. Try zooming out and panning to see the difference.</p>
|
||||
tags: "preload, bing"
|
||||
cloak:
|
||||
- key: ApTJzdkyN1DdFKkRAE6QIDtzihNaf6IWJsT-nQ_2eMoO4PN__0Tzhl2-WgJtXFSp
|
||||
- key: AlEoTLTlzFB6Uf4Sy-ugXcRO21skQO7K8eObA5_L-8d20rjqZJLs2nkO1RMjGSPN
|
||||
value: Your Bing Maps Key from https://www.bingmapsportal.com/ here
|
||||
---
|
||||
<div id="map1" class="map"></div>
|
||||
|
||||
@@ -13,7 +13,7 @@ const map1 = new Map({
|
||||
new TileLayer({
|
||||
preload: Infinity,
|
||||
source: new BingMaps({
|
||||
key: 'ApTJzdkyN1DdFKkRAE6QIDtzihNaf6IWJsT-nQ_2eMoO4PN__0Tzhl2-WgJtXFSp',
|
||||
key: 'AlEoTLTlzFB6Uf4Sy-ugXcRO21skQO7K8eObA5_L-8d20rjqZJLs2nkO1RMjGSPN',
|
||||
imagerySet: 'Aerial',
|
||||
}),
|
||||
}),
|
||||
@@ -27,7 +27,7 @@ const map2 = new Map({
|
||||
new TileLayer({
|
||||
preload: 0, // default value
|
||||
source: new BingMaps({
|
||||
key: 'ApTJzdkyN1DdFKkRAE6QIDtzihNaf6IWJsT-nQ_2eMoO4PN__0Tzhl2-WgJtXFSp',
|
||||
key: 'AlEoTLTlzFB6Uf4Sy-ugXcRO21skQO7K8eObA5_L-8d20rjqZJLs2nkO1RMjGSPN',
|
||||
imagerySet: 'AerialWithLabelsOnDemand',
|
||||
}),
|
||||
}),
|
||||
|
||||
18
examples/projection-and-scale.html
Normal file
18
examples/projection-and-scale.html
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Projection and Scale
|
||||
shortdesc: Example of maintaining scale when changing projection.
|
||||
docs: >
|
||||
Example of maintaining scale when changing projection.
|
||||
`getPointResolution()` is used to calculate the resolution for the
|
||||
new projection which corresponds to that for the old projection.
|
||||
tags: "projection, scale"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
<div>
|
||||
<label for="view-projection">View projection</label>
|
||||
<select id="view-projection">
|
||||
<option value="EPSG:3857">Spherical Mercator (EPSG:3857)</option>
|
||||
<option value="EPSG:4326" selected>WGS 84 (EPSG:4326)</option>
|
||||
</select>
|
||||
</div>
|
||||
68
examples/projection-and-scale.js
Normal file
68
examples/projection-and-scale.js
Normal file
@@ -0,0 +1,68 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {ScaleLine, defaults as defaultControls} from '../src/ol/control.js';
|
||||
import {
|
||||
getPointResolution,
|
||||
get as getProjection,
|
||||
transform,
|
||||
} from '../src/ol/proj.js';
|
||||
|
||||
const viewProjSelect = document.getElementById('view-projection');
|
||||
const projection = getProjection(viewProjSelect.value);
|
||||
|
||||
const scaleControl = new ScaleLine({
|
||||
units: 'metric',
|
||||
bar: true,
|
||||
steps: 4,
|
||||
text: true,
|
||||
minWidth: 140,
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
controls: defaultControls().extend([scaleControl]),
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM(),
|
||||
}),
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: transform([0, 52], 'EPSG:4326', projection),
|
||||
zoom: 6,
|
||||
projection: projection,
|
||||
}),
|
||||
});
|
||||
|
||||
function onChangeProjection() {
|
||||
const currentView = map.getView();
|
||||
const currentProjection = currentView.getProjection();
|
||||
const newProjection = getProjection(viewProjSelect.value);
|
||||
const currentResolution = currentView.getResolution();
|
||||
const currentCenter = currentView.getCenter();
|
||||
const currentRotation = currentView.getRotation();
|
||||
const newCenter = transform(currentCenter, currentProjection, newProjection);
|
||||
const currentPointResolution = getPointResolution(
|
||||
currentProjection,
|
||||
1,
|
||||
currentCenter,
|
||||
'm'
|
||||
);
|
||||
const newPointResolution = getPointResolution(
|
||||
newProjection,
|
||||
1,
|
||||
newCenter,
|
||||
'm'
|
||||
);
|
||||
const newResolution =
|
||||
(currentResolution * currentPointResolution) / newPointResolution;
|
||||
const newView = new View({
|
||||
center: newCenter,
|
||||
resolution: newResolution,
|
||||
rotation: currentRotation,
|
||||
projection: newProjection,
|
||||
});
|
||||
map.setView(newView);
|
||||
}
|
||||
viewProjSelect.addEventListener('change', onChangeProjection);
|
||||
@@ -8,6 +8,6 @@ tags: "reprojection, projection, proj4js, image, imagestatic"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
<div>
|
||||
<input type="checkbox" id="imageSmoothing" checked />
|
||||
<label for="imageSmoothing">Image smoothing</label>
|
||||
<input type="checkbox" id="interpolate" checked />
|
||||
<label for="interpolate">Interpolate</label>
|
||||
</div>
|
||||
|
||||
@@ -34,7 +34,7 @@ const map = new Map({
|
||||
}),
|
||||
});
|
||||
|
||||
const imageSmoothing = document.getElementById('imageSmoothing');
|
||||
const interpolate = document.getElementById('interpolate');
|
||||
|
||||
function setSource() {
|
||||
const source = new Static({
|
||||
@@ -44,10 +44,10 @@ function setSource() {
|
||||
crossOrigin: '',
|
||||
projection: 'EPSG:27700',
|
||||
imageExtent: imageExtent,
|
||||
imageSmoothing: imageSmoothing.checked,
|
||||
interpolate: interpolate.checked,
|
||||
});
|
||||
imageLayer.setSource(source);
|
||||
}
|
||||
setSource();
|
||||
|
||||
imageSmoothing.addEventListener('change', setSource);
|
||||
interpolate.addEventListener('change', setSource);
|
||||
|
||||
3
examples/reprojection.css
Normal file
3
examples/reprojection.css
Normal file
@@ -0,0 +1,3 @@
|
||||
.form-inline label {
|
||||
justify-content: left;
|
||||
}
|
||||
@@ -37,8 +37,12 @@ tags: "reprojection, projection, proj4js, osm, wms, wmts, hidpi, grid"
|
||||
<option value="EPSG:5479">RSRGD2000 / MSLC2000 (EPSG:5479)</option>
|
||||
</select>
|
||||
</div>
|
||||
<label>
|
||||
Render reprojection edges
|
||||
<input type="checkbox" id="render-edges">
|
||||
</label>
|
||||
</form>
|
||||
<form class="form-inline">
|
||||
<div class="col-md-auto">
|
||||
<label>
|
||||
Render reprojection edges:
|
||||
<input type="checkbox" id="render-edges" />
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
if (typeof Promise !== 'undefined' && !Promise.allSettled && Array.from) {
|
||||
Promise.allSettled =
|
||||
function (promises) {
|
||||
return Promise.all(
|
||||
Array.from(
|
||||
promises,
|
||||
function (p) {
|
||||
return p.then (
|
||||
function (value) {
|
||||
return {status: 'fulfilled', value: value};
|
||||
}
|
||||
).catch(
|
||||
function (reason) {
|
||||
return {status: 'rejected', reason: reason};
|
||||
}
|
||||
);
|
||||
}
|
||||
)
|
||||
)
|
||||
};
|
||||
}
|
||||
30
examples/resources/external-map-map.html
Normal file
30
examples/resources/external-map-map.html
Normal file
@@ -0,0 +1,30 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../css/ol.css" type="text/css">
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
.map {
|
||||
height: 100%;
|
||||
}
|
||||
.map.unusable .ol-mask {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
user-select: none;
|
||||
background-color: rgba(0, 0, 0, .7);
|
||||
color: white;
|
||||
font: bold 3rem 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
}
|
||||
.map.unusable .ol-control {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="map" class="map"></div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -8,11 +8,6 @@ docs: >
|
||||
<a href="https://blog.mapbox.com/styling-mapbox-terrain-rgb-c75d1cd71471">Mapbox Terrain-RGB tiles</a>
|
||||
to "flood" areas below the elevation shown on the sea level slider.
|
||||
</p>
|
||||
<p>
|
||||
<code>ol/source/Raster</code> can take either a tile source or layer.
|
||||
In this case a layer is used to allow disabling at the <code>prerender</code> event
|
||||
of image smoothing which would change the precise elevation values set in the pixels.
|
||||
</p>
|
||||
tags: "raster, pixel operation, flood"
|
||||
cloak:
|
||||
- key: get_your_own_D6rA4zTHduk6KOKTXzGB
|
||||
|
||||
@@ -26,17 +26,14 @@ const attributions =
|
||||
'<a href="https://www.maptiler.com/copyright/" target="_blank">© MapTiler</a> ' +
|
||||
'<a href="https://www.openstreetmap.org/copyright" target="_blank">© OpenStreetMap contributors</a>';
|
||||
|
||||
const elevation = new TileLayer({
|
||||
source: new XYZ({
|
||||
url:
|
||||
'https://api.maptiler.com/tiles/terrain-rgb/{z}/{x}/{y}.png?key=' + key,
|
||||
maxZoom: 10,
|
||||
crossOrigin: '',
|
||||
}),
|
||||
});
|
||||
elevation.on('prerender', function (evt) {
|
||||
evt.context.imageSmoothingEnabled = false;
|
||||
evt.context.msImageSmoothingEnabled = false;
|
||||
const elevation = new XYZ({
|
||||
// The RGB values in the source collectively represent elevation.
|
||||
// Interpolation of individual colors would produce incorrect evelations and is disabled.
|
||||
url: 'https://api.maptiler.com/tiles/terrain-rgb/{z}/{x}/{y}.png?key=' + key,
|
||||
tileSize: 512,
|
||||
maxZoom: 12,
|
||||
crossOrigin: '',
|
||||
interpolate: false,
|
||||
});
|
||||
|
||||
const raster = new RasterSource({
|
||||
@@ -52,6 +49,7 @@ const map = new Map({
|
||||
attributions: attributions,
|
||||
url: 'https://api.maptiler.com/maps/streets/{z}/{x}/{y}.png?key=' + key,
|
||||
tileSize: 512,
|
||||
maxZoom: 22,
|
||||
}),
|
||||
}),
|
||||
new ImageLayer({
|
||||
|
||||
@@ -1,25 +1,33 @@
|
||||
import GeoJSON from '../src/ol/format/GeoJSON.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
import Select from '../src/ol/interaction/Select.js';
|
||||
import VectorLayer from '../src/ol/layer/Vector.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {Fill, Stroke, Style} from '../src/ol/style.js';
|
||||
import {altKeyOnly, click, pointerMove} from '../src/ol/events/condition.js';
|
||||
|
||||
const raster = new TileLayer({
|
||||
source: new OSM(),
|
||||
const style = new Style({
|
||||
fill: new Fill({
|
||||
color: '#eeeeee',
|
||||
}),
|
||||
});
|
||||
|
||||
const vector = new VectorLayer({
|
||||
source: new VectorSource({
|
||||
url: 'data/geojson/countries.geojson',
|
||||
url: 'https://openlayers.org/data/vector/ecoregions.json',
|
||||
format: new GeoJSON(),
|
||||
}),
|
||||
background: 'white',
|
||||
style: function (feature) {
|
||||
const color = feature.get('COLOR') || '#eeeeee';
|
||||
style.getFill().setColor(color);
|
||||
return style;
|
||||
},
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
layers: [raster, vector],
|
||||
layers: [vector],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
@@ -29,20 +37,39 @@ const map = new Map({
|
||||
|
||||
let select = null; // ref to currently selected interaction
|
||||
|
||||
const selected = new Style({
|
||||
fill: new Fill({
|
||||
color: '#eeeeee',
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
color: 'rgba(255, 255, 255, 0.7)',
|
||||
width: 2,
|
||||
}),
|
||||
});
|
||||
|
||||
function selectStyle(feature) {
|
||||
const color = feature.get('COLOR') || '#eeeeee';
|
||||
selected.getFill().setColor(color);
|
||||
return selected;
|
||||
}
|
||||
|
||||
// select interaction working on "singleclick"
|
||||
const selectSingleClick = new Select();
|
||||
const selectSingleClick = new Select({style: selectStyle});
|
||||
|
||||
// select interaction working on "click"
|
||||
const selectClick = new Select({
|
||||
condition: click,
|
||||
style: selectStyle,
|
||||
});
|
||||
|
||||
// select interaction working on "pointermove"
|
||||
const selectPointerMove = new Select({
|
||||
condition: pointerMove,
|
||||
style: selectStyle,
|
||||
});
|
||||
|
||||
const selectAltClick = new Select({
|
||||
style: selectStyle,
|
||||
condition: function (mapBrowserEvent) {
|
||||
return click(mapBrowserEvent) && altKeyOnly(mapBrowserEvent);
|
||||
},
|
||||
|
||||
@@ -7,4 +7,4 @@ docs: >
|
||||
tags: "select, vector"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
<span id="status"></span>
|
||||
<span id="status"> </span>
|
||||
|
||||
@@ -1,36 +1,33 @@
|
||||
import Fill from '../src/ol/style/Fill.js';
|
||||
import GeoJSON from '../src/ol/format/GeoJSON.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
import Stroke from '../src/ol/style/Stroke.js';
|
||||
import Style from '../src/ol/style/Style.js';
|
||||
import VectorLayer from '../src/ol/layer/Vector.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
|
||||
const raster = new TileLayer({
|
||||
source: new OSM(),
|
||||
});
|
||||
|
||||
const highlightStyle = new Style({
|
||||
const style = new Style({
|
||||
fill: new Fill({
|
||||
color: 'rgba(255,255,255,0.7)',
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
color: '#3399CC',
|
||||
width: 3,
|
||||
color: '#eeeeee',
|
||||
}),
|
||||
});
|
||||
|
||||
const vector = new VectorLayer({
|
||||
source: new VectorSource({
|
||||
url: 'data/geojson/countries.geojson',
|
||||
url: 'https://openlayers.org/data/vector/ecoregions.json',
|
||||
format: new GeoJSON(),
|
||||
}),
|
||||
background: 'white',
|
||||
style: function (feature) {
|
||||
const color = feature.get('COLOR') || '#eeeeee';
|
||||
style.getFill().setColor(color);
|
||||
return style;
|
||||
},
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
layers: [raster, vector],
|
||||
layers: [vector],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
@@ -38,9 +35,19 @@ const map = new Map({
|
||||
}),
|
||||
});
|
||||
|
||||
let selected = null;
|
||||
const selectStyle = new Style({
|
||||
fill: new Fill({
|
||||
color: '#eeeeee',
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
color: 'rgba(255, 255, 255, 0.7)',
|
||||
width: 2,
|
||||
}),
|
||||
});
|
||||
|
||||
const status = document.getElementById('status');
|
||||
|
||||
let selected = null;
|
||||
map.on('pointermove', function (e) {
|
||||
if (selected !== null) {
|
||||
selected.setStyle(undefined);
|
||||
@@ -49,12 +56,13 @@ map.on('pointermove', function (e) {
|
||||
|
||||
map.forEachFeatureAtPixel(e.pixel, function (f) {
|
||||
selected = f;
|
||||
f.setStyle(highlightStyle);
|
||||
selectStyle.getFill().setColor(f.get('COLOR') || '#eeeeee');
|
||||
f.setStyle(selectStyle);
|
||||
return true;
|
||||
});
|
||||
|
||||
if (selected) {
|
||||
status.innerHTML = ' Hovering: ' + selected.get('name');
|
||||
status.innerHTML = selected.get('ECO_NAME');
|
||||
} else {
|
||||
status.innerHTML = ' ';
|
||||
}
|
||||
|
||||
@@ -1,40 +1,37 @@
|
||||
import Fill from '../src/ol/style/Fill.js';
|
||||
import GeoJSON from '../src/ol/format/GeoJSON.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
import Stroke from '../src/ol/style/Stroke.js';
|
||||
import Style from '../src/ol/style/Style.js';
|
||||
import VectorLayer from '../src/ol/layer/Vector.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
|
||||
const raster = new TileLayer({
|
||||
source: new OSM(),
|
||||
});
|
||||
import {fromLonLat} from '../src/ol/proj.js';
|
||||
|
||||
const highlightStyle = new Style({
|
||||
fill: new Fill({
|
||||
color: 'rgba(255,255,255,0.7)',
|
||||
color: '#EEE',
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
color: '#3399CC',
|
||||
width: 3,
|
||||
width: 2,
|
||||
}),
|
||||
});
|
||||
|
||||
const vector = new VectorLayer({
|
||||
background: 'white',
|
||||
source: new VectorSource({
|
||||
url: 'data/geojson/countries.geojson',
|
||||
url: 'https://openlayers.org/data/vector/us-states.json',
|
||||
format: new GeoJSON(),
|
||||
}),
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
layers: [raster, vector],
|
||||
layers: [vector],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
zoom: 2,
|
||||
center: fromLonLat([-100, 38.5]),
|
||||
zoom: 4,
|
||||
multiWorld: true,
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -6,6 +6,7 @@ import VectorLayer from '../src/ol/layer/Vector.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import proj4 from 'proj4';
|
||||
import {Fill, Style} from '../src/ol/style.js';
|
||||
import {register} from '../src/ol/proj/proj4.js';
|
||||
|
||||
proj4.defs(
|
||||
@@ -26,14 +27,25 @@ const sphereMollweideProjection = new Projection({
|
||||
worldExtent: [-179, -89.99, 179, 89.99],
|
||||
});
|
||||
|
||||
const style = new Style({
|
||||
fill: new Fill({
|
||||
color: '#eeeeee',
|
||||
}),
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
keyboardEventTarget: document,
|
||||
layers: [
|
||||
new VectorLayer({
|
||||
source: new VectorSource({
|
||||
url: 'data/geojson/countries-110m.geojson',
|
||||
url: 'https://openlayers.org/data/vector/ecoregions.json',
|
||||
format: new GeoJSON(),
|
||||
}),
|
||||
style: function (feature) {
|
||||
const color = feature.get('COLOR_BIO') || '#eeeeee';
|
||||
style.getFill().setColor(color);
|
||||
return style;
|
||||
},
|
||||
}),
|
||||
new Graticule(),
|
||||
],
|
||||
@@ -41,6 +53,6 @@ const map = new Map({
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
projection: sphereMollweideProjection,
|
||||
zoom: 1,
|
||||
zoom: 2,
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -68,8 +68,8 @@
|
||||
<link rel="stylesheet" href="./css/ol.css" type="text/css">
|
||||
<link rel="stylesheet" href="./resources/layout.css" type="text/css">
|
||||
<script src="https://unpkg.com/elm-pep"></script>
|
||||
<script src="https://cdn.polyfill.io/v3/polyfill.min.js?features=fetch,requestAnimationFrame,Element.prototype.classList,URL,TextDecoder,Number.isInteger"></script>
|
||||
<script src="./resources/Promise.allSettled.js"></script>
|
||||
<script src="https://cdn.polyfill.io/v3/polyfill.min.js?features=fetch,requestAnimationFrame,Element.prototype.classList,TextDecoder"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/3.18.3/minified.js"></script>
|
||||
{{{ extraHead.local }}}
|
||||
{{{ css.tag }}}
|
||||
<title>{{ title }}</title>
|
||||
@@ -194,8 +194,9 @@
|
||||
<title>{{ title }}</title>
|
||||
<!-- Pointer events polyfill for old browsers, see https://caniuse.com/#feat=pointer -->
|
||||
<script src="https://unpkg.com/elm-pep"></script>
|
||||
<!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
|
||||
<script src="https://cdn.polyfill.io/v3/polyfill.min.js?features=fetch,requestAnimationFrame,Element.prototype.classList,URL,TextDecoder,Number.isInteger"></script>{{#if extraHead.remote}}
|
||||
<!-- The lines below are only needed for old environments like Internet Explorer and Android 4.x -->
|
||||
<script src="https://cdn.polyfill.io/v3/polyfill.min.js?features=fetch,requestAnimationFrame,Element.prototype.classList,TextDecoder"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/3.18.3/minified.js"></script>{{#if extraHead.remote}}
|
||||
{{ indent extraHead.remote spaces=4 }}{{/if}}
|
||||
<style>
|
||||
.map {
|
||||
@@ -210,13 +211,12 @@
|
||||
</html></code></pre>
|
||||
</div>
|
||||
|
||||
{{#if worker.source}}
|
||||
<div class="row-fluid">
|
||||
<h5 class="source-heading">worker.js</h5>
|
||||
<pre><code id="example-worker-source" class="language-js">{{ worker.source }}</code></pre>
|
||||
{{#each extraSources}}
|
||||
<div class="row-fluid extra-source">
|
||||
<h5 class="source-heading">{{./name}}</h5>
|
||||
<pre><code class="language-{{./type}}">{{ ./source }}</code></pre>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{/each}}
|
||||
<div class="row-fluid">
|
||||
<h5 class="source-heading">package.json</h5>
|
||||
<pre><code id="example-pkg-source" class="language-json">{{ pkgJson }}</code></pre>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import GeoJSON from '../src/ol/format/GeoJSON.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
import VectorLayer from '../src/ol/layer/Vector.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {
|
||||
@@ -8,15 +8,12 @@ import {
|
||||
Translate,
|
||||
defaults as defaultInteractions,
|
||||
} from '../src/ol/interaction.js';
|
||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
|
||||
const raster = new TileLayer({
|
||||
source: new OSM(),
|
||||
});
|
||||
import {fromLonLat} from '../src/ol/proj.js';
|
||||
|
||||
const vector = new VectorLayer({
|
||||
background: 'white',
|
||||
source: new VectorSource({
|
||||
url: 'data/geojson/countries.geojson',
|
||||
url: 'https://openlayers.org/data/vector/us-states.json',
|
||||
format: new GeoJSON(),
|
||||
}),
|
||||
});
|
||||
@@ -29,10 +26,10 @@ const translate = new Translate({
|
||||
|
||||
const map = new Map({
|
||||
interactions: defaultInteractions().extend([select, translate]),
|
||||
layers: [raster, vector],
|
||||
layers: [vector],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
zoom: 2,
|
||||
center: fromLonLat([-100, 38.5]),
|
||||
zoom: 4,
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -4,12 +4,13 @@ import VectorLayer from '../src/ol/layer/Vector.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {Fill, Stroke, Style, Text} from '../src/ol/style.js';
|
||||
import {fromLonLat} from '../src/ol/proj.js';
|
||||
|
||||
const map = new Map({
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
zoom: 1,
|
||||
center: fromLonLat([-100, 38.5]),
|
||||
zoom: 4,
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -38,12 +39,14 @@ const countryStyle = new Style({
|
||||
const style = [countryStyle, labelStyle];
|
||||
|
||||
const vectorLayer = new VectorLayer({
|
||||
background: 'white',
|
||||
source: new VectorSource({
|
||||
url: 'data/geojson/countries.geojson',
|
||||
url: 'https://openlayers.org/data/vector/us-states.json',
|
||||
format: new GeoJSON(),
|
||||
}),
|
||||
style: function (feature) {
|
||||
labelStyle.getText().setText(feature.get('name'));
|
||||
const label = feature.get('name').split(' ').join('\n');
|
||||
labelStyle.getText().setText(label);
|
||||
return style;
|
||||
},
|
||||
declutter: true,
|
||||
|
||||
@@ -3,35 +3,23 @@ import Map from '../src/ol/Map.js';
|
||||
import VectorLayer from '../src/ol/layer/Vector.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {Fill, Stroke, Style, Text} from '../src/ol/style.js';
|
||||
import {Fill, Stroke, Style} from '../src/ol/style.js';
|
||||
|
||||
const style = new Style({
|
||||
fill: new Fill({
|
||||
color: 'rgba(255, 255, 255, 0.6)',
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
color: '#319FD3',
|
||||
width: 1,
|
||||
}),
|
||||
text: new Text({
|
||||
font: '12px Calibri,sans-serif',
|
||||
fill: new Fill({
|
||||
color: '#000',
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
color: '#fff',
|
||||
width: 3,
|
||||
}),
|
||||
color: '#eeeeee',
|
||||
}),
|
||||
});
|
||||
|
||||
const vectorLayer = new VectorLayer({
|
||||
background: '#1a2b39',
|
||||
source: new VectorSource({
|
||||
url: 'data/geojson/countries.geojson',
|
||||
url: 'https://openlayers.org/data/vector/ecoregions.json',
|
||||
format: new GeoJSON(),
|
||||
}),
|
||||
style: function (feature) {
|
||||
style.getText().setText(feature.get('name'));
|
||||
const color = feature.get('COLOR') || '#eeeeee';
|
||||
style.getFill().setColor(color);
|
||||
return style;
|
||||
},
|
||||
});
|
||||
@@ -45,33 +33,15 @@ const map = new Map({
|
||||
}),
|
||||
});
|
||||
|
||||
const highlightStyle = new Style({
|
||||
stroke: new Stroke({
|
||||
color: '#f00',
|
||||
width: 1,
|
||||
}),
|
||||
fill: new Fill({
|
||||
color: 'rgba(255,0,0,0.1)',
|
||||
}),
|
||||
text: new Text({
|
||||
font: '12px Calibri,sans-serif',
|
||||
fill: new Fill({
|
||||
color: '#000',
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
color: '#f00',
|
||||
width: 3,
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
const featureOverlay = new VectorLayer({
|
||||
source: new VectorSource(),
|
||||
map: map,
|
||||
style: function (feature) {
|
||||
highlightStyle.getText().setText(feature.get('name'));
|
||||
return highlightStyle;
|
||||
},
|
||||
style: new Style({
|
||||
stroke: new Stroke({
|
||||
color: 'rgba(255, 255, 255, 0.7)',
|
||||
width: 2,
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
let highlight;
|
||||
@@ -82,7 +52,7 @@ const displayFeatureInfo = function (pixel) {
|
||||
|
||||
const info = document.getElementById('info');
|
||||
if (feature) {
|
||||
info.innerHTML = feature.getId() + ': ' + feature.get('name');
|
||||
info.innerHTML = feature.get('ECO_NAME') || ' ';
|
||||
} else {
|
||||
info.innerHTML = ' ';
|
||||
}
|
||||
|
||||
16
examples/webgl-layer-swipe.html
Normal file
16
examples/webgl-layer-swipe.html
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Layer Swipe (WebGL)
|
||||
shortdesc: Cropping a WebGL tile layer
|
||||
docs: >
|
||||
The <code>prerender</code> and <code>postrender</code> events on a WebGL tile layer can be
|
||||
used to manipulate the WebGL context before and after rendering. In this case, the
|
||||
<a href="https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/scissor"><code>gl.scissor()</code></a>
|
||||
method is called to clip the top layer based on the position of a slider.
|
||||
tags: "swipe, webgl"
|
||||
cloak:
|
||||
- key: get_your_own_D6rA4zTHduk6KOKTXzGB
|
||||
value: Get your own API key at https://www.maptiler.com/cloud/
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
<input id="swipe" type="range" style="width: 100%">
|
||||
60
examples/webgl-layer-swipe.js
Normal file
60
examples/webgl-layer-swipe.js
Normal file
@@ -0,0 +1,60 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
import TileLayer from '../src/ol/layer/WebGLTile.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import XYZ from '../src/ol/source/XYZ.js';
|
||||
import {getRenderPixel} from '../src/ol/render.js';
|
||||
|
||||
const osm = new TileLayer({
|
||||
source: new OSM({wrapX: true}),
|
||||
});
|
||||
|
||||
const key = 'get_your_own_D6rA4zTHduk6KOKTXzGB';
|
||||
|
||||
const imagery = new TileLayer({
|
||||
source: new XYZ({
|
||||
url: 'https://api.maptiler.com/tiles/satellite/{z}/{x}/{y}.jpg?key=' + key,
|
||||
attributions:
|
||||
'<a href="https://www.maptiler.com/copyright/" target="_blank">© MapTiler</a> ' +
|
||||
'<a href="https://www.openstreetmap.org/copyright" target="_blank">© OpenStreetMap contributors</a>',
|
||||
maxZoom: 20,
|
||||
}),
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
layers: [osm, imagery],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
zoom: 2,
|
||||
}),
|
||||
});
|
||||
|
||||
const swipe = document.getElementById('swipe');
|
||||
|
||||
imagery.on('prerender', function (event) {
|
||||
const gl = event.context;
|
||||
gl.enable(gl.SCISSOR_TEST);
|
||||
|
||||
const mapSize = map.getSize(); // [width, height] in CSS pixels
|
||||
|
||||
// get render coordinates and dimensions given CSS coordinates
|
||||
const bottomLeft = getRenderPixel(event, [0, mapSize[1]]);
|
||||
const topRight = getRenderPixel(event, [mapSize[0], 0]);
|
||||
|
||||
const width = Math.round((topRight[0] - bottomLeft[0]) * (swipe.value / 100));
|
||||
const height = topRight[1] - bottomLeft[1];
|
||||
|
||||
gl.scissor(bottomLeft[0], bottomLeft[1], width, height);
|
||||
});
|
||||
|
||||
imagery.on('postrender', function (event) {
|
||||
const gl = event.context;
|
||||
gl.disable(gl.SCISSOR_TEST);
|
||||
});
|
||||
|
||||
const listener = function () {
|
||||
map.render();
|
||||
};
|
||||
swipe.addEventListener('input', listener);
|
||||
swipe.addEventListener('change', listener);
|
||||
@@ -31,9 +31,8 @@ const layer = new TileLayer({
|
||||
source: new XYZ({
|
||||
url:
|
||||
'https://api.maptiler.com/tiles/terrain-rgb/{z}/{x}/{y}.png?key=' + key,
|
||||
maxZoom: 10,
|
||||
tileSize: 512,
|
||||
crossOrigin: 'anonymous',
|
||||
maxZoom: 12,
|
||||
}),
|
||||
style: {
|
||||
variables: {
|
||||
@@ -56,8 +55,8 @@ const map = new Map({
|
||||
source: new XYZ({
|
||||
url: 'https://api.maptiler.com/maps/streets/{z}/{x}/{y}.png?key=' + key,
|
||||
attributions: attributions,
|
||||
crossOrigin: 'anonymous',
|
||||
tileSize: 512,
|
||||
maxZoom: 22,
|
||||
}),
|
||||
}),
|
||||
layer,
|
||||
|
||||
@@ -50,7 +50,6 @@ const shadedRelief = new TileLayer({
|
||||
opacity: 0.3,
|
||||
source: new XYZ({
|
||||
url: 'https://{a-d}.tiles.mapbox.com/v3/aj.sf-dem/{z}/{x}/{y}.png',
|
||||
crossOrigin: 'anonymous',
|
||||
}),
|
||||
style: {
|
||||
variables: variables,
|
||||
|
||||
@@ -22,7 +22,6 @@ const layer = new TileLayer({
|
||||
variables: variables,
|
||||
},
|
||||
source: new XYZ({
|
||||
crossOrigin: 'anonymous', // TODO: determine if we can avoid this
|
||||
attributions: attributions,
|
||||
url: 'https://api.maptiler.com/tiles/satellite/{z}/{x}/{y}.jpg?key=' + key,
|
||||
maxZoom: 20,
|
||||
|
||||
@@ -26,7 +26,7 @@ export default {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /^((?!es2015-)[\s\S])*\.js$/,
|
||||
test: /^((?!es2015-)[\s\S])*\.m?js$/,
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
|
||||
@@ -3,17 +3,17 @@ import frontMatter from 'front-matter';
|
||||
import fs from 'fs';
|
||||
import fse from 'fs-extra';
|
||||
import handlebars from 'handlebars';
|
||||
import marked from 'marked';
|
||||
import path, {dirname} from 'path';
|
||||
import sources from 'webpack-sources';
|
||||
import {fileURLToPath} from 'url';
|
||||
import {marked} from 'marked';
|
||||
|
||||
const RawSource = sources.RawSource;
|
||||
const baseDir = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
const isCssRegEx = /\.css(\?.*)?$/;
|
||||
const isJsRegEx = /\.js(\?.*)?$/;
|
||||
const importRegEx = /^import .* from '(.*)';$/;
|
||||
const importRegEx = /(?:^|\n)import .* from '(.*)';(?:\n|$)/g;
|
||||
const isTemplateJs =
|
||||
/\/(jquery(-\d+\.\d+\.\d+)?|(bootstrap(\.bundle)?))(\.min)?\.js(\?.*)?$/;
|
||||
const isTemplateCss = /\/bootstrap(\.min)?\.css(\?.*)?$/;
|
||||
@@ -134,26 +134,18 @@ function createWordIndex(exampleData) {
|
||||
* @return {Object<string, string>} dependencies
|
||||
*/
|
||||
function getDependencies(jsSource, pkg) {
|
||||
const lines = jsSource.split('\n');
|
||||
const dependencies = {
|
||||
ol: pkg.version,
|
||||
};
|
||||
for (let i = 0, ii = lines.length; i < ii; ++i) {
|
||||
const line = lines[i];
|
||||
const importMatch = line.match(importRegEx);
|
||||
if (importMatch) {
|
||||
const imp = importMatch[1];
|
||||
if (!imp.startsWith('ol/') && imp != 'ol') {
|
||||
const parts = imp.split('/');
|
||||
let dep;
|
||||
if (imp.startsWith('@')) {
|
||||
dep = parts.slice(0, 2).join('/');
|
||||
} else {
|
||||
dep = parts[0];
|
||||
}
|
||||
if (dep in pkg.devDependencies) {
|
||||
dependencies[dep] = pkg.devDependencies[dep];
|
||||
}
|
||||
|
||||
let importMatch;
|
||||
while ((importMatch = importRegEx.exec(jsSource))) {
|
||||
const imp = importMatch[1];
|
||||
if (!imp.startsWith('ol/') && imp != 'ol') {
|
||||
const parts = imp.split('/');
|
||||
const dep = imp.startsWith('@') ? parts.slice(0, 2).join('/') : parts[0];
|
||||
if (dep in pkg.devDependencies) {
|
||||
dependencies[dep] = pkg.devDependencies[dep];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -279,80 +271,79 @@ export default class ExampleBuilder {
|
||||
data.jsSource = jsSource;
|
||||
|
||||
// process tags
|
||||
if (data.tags) {
|
||||
data.tags = data.tags.replace(/[\s"]+/g, '').split(',');
|
||||
} else {
|
||||
data.tags = [];
|
||||
}
|
||||
data.tags = data.tags ? data.tags.replace(/[\s"]+/g, '').split(',') : [];
|
||||
return data;
|
||||
}
|
||||
|
||||
transformJsSource(source) {
|
||||
return (
|
||||
source
|
||||
// remove "../src/" prefix and ".js" to have the same import syntax as the documentation
|
||||
.replace(/'\.\.\/src\//g, "'")
|
||||
.replace(/\.js';/g, "';")
|
||||
// Remove worker loader import and modify `new Worker()` to add source
|
||||
.replace(/import Worker from 'worker-loader![^\n]*\n/g, '')
|
||||
.replace('new Worker()', "new Worker('./worker.js', {type: 'module'})")
|
||||
);
|
||||
}
|
||||
|
||||
cloakSource(source, cloak) {
|
||||
if (cloak) {
|
||||
for (const entry of cloak) {
|
||||
source = source.replace(new RegExp(entry.key, 'g'), entry.value);
|
||||
}
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
async render(data) {
|
||||
const assets = {};
|
||||
const readOptions = {encoding: 'utf8'};
|
||||
|
||||
// add in script tag
|
||||
const jsName = `${data.name}.js`;
|
||||
|
||||
// remove "../src/" prefix and ".js" to have the same import syntax as the documentation
|
||||
let jsSource = data.jsSource.replace(/'\.\.\/src\//g, "'");
|
||||
jsSource = jsSource.replace(/\.js';/g, "';");
|
||||
if (data.cloak) {
|
||||
for (const entry of data.cloak) {
|
||||
jsSource = jsSource.replace(new RegExp(entry.key, 'g'), entry.value);
|
||||
}
|
||||
}
|
||||
// Remove worker loader import and modify `new Worker()` to add source
|
||||
jsSource = jsSource.replace(
|
||||
/import Worker from 'worker-loader![^\n]*\n/g,
|
||||
''
|
||||
const jsSource = this.transformJsSource(
|
||||
this.cloakSource(data.jsSource, data.cloak)
|
||||
);
|
||||
jsSource = jsSource.replace('new Worker()', "new Worker('./worker.js')");
|
||||
|
||||
data.js = {
|
||||
tag: `<script src="${this.common}.js"></script>
|
||||
<script src="${jsName}"></script>`,
|
||||
source: jsSource,
|
||||
};
|
||||
|
||||
// check for worker js
|
||||
const workerName = `${data.name}.worker.js`;
|
||||
const workerPath = path.join(data.dir, workerName);
|
||||
let workerSource;
|
||||
try {
|
||||
workerSource = await fse.readFile(workerPath, readOptions);
|
||||
} catch (err) {
|
||||
// pass
|
||||
}
|
||||
if (workerSource) {
|
||||
// remove "../src/" prefix and ".js" to have the same import syntax as the documentation
|
||||
workerSource = workerSource.replace(/'\.\.\/src\//g, "'");
|
||||
workerSource = workerSource.replace(/\.js';/g, "';");
|
||||
if (data.cloak) {
|
||||
for (const entry of data.cloak) {
|
||||
workerSource = workerSource.replace(
|
||||
new RegExp(entry.key, 'g'),
|
||||
entry.value
|
||||
);
|
||||
}
|
||||
}
|
||||
data.worker = {
|
||||
source: workerSource,
|
||||
};
|
||||
assets[workerName] = workerSource;
|
||||
let jsSources = jsSource;
|
||||
if (data.sources) {
|
||||
data.extraSources = await Promise.all(
|
||||
data.sources.map(async (sourceConfig) => {
|
||||
const fileName = sourceConfig.path;
|
||||
const extraSourcePath = path.join(data.dir, fileName);
|
||||
let source = await fse.readFile(extraSourcePath, readOptions);
|
||||
let ext = fileName.match(/\.(\w+)$/)[1];
|
||||
if (ext === 'mjs') {
|
||||
ext = 'js';
|
||||
}
|
||||
if (ext === 'js') {
|
||||
source = this.transformJsSource(source);
|
||||
jsSources += '\n' + source;
|
||||
}
|
||||
source = this.cloakSource(source, data.cloak);
|
||||
assets[fileName] = source;
|
||||
return {
|
||||
name: sourceConfig.as || fileName,
|
||||
source: source,
|
||||
type: ext,
|
||||
};
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
const pkg = await getPackageInfo();
|
||||
|
||||
data.pkgJson = JSON.stringify(
|
||||
{
|
||||
name: data.name,
|
||||
dependencies: getDependencies(
|
||||
jsSource + (workerSource ? `\n${workerSource}` : ''),
|
||||
pkg
|
||||
),
|
||||
dependencies: getDependencies(jsSources, pkg),
|
||||
devDependencies: {
|
||||
parcel: '^2.0.0-beta.1',
|
||||
parcel: '^2.0.0',
|
||||
},
|
||||
scripts: {
|
||||
start: 'parcel index.html',
|
||||
|
||||
13
examples/wind-arrows.html
Normal file
13
examples/wind-arrows.html
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Wind Arrows
|
||||
shortdesc: Example of Wind Arrows styled using Regular Shapes.
|
||||
docs: >
|
||||
This example shows wind arrows styled using regular shapes for the
|
||||
arrow shaft and head. The shaft is scaled based on the wind speed
|
||||
and a corresponding displacement is used to position the unscaled
|
||||
arrow head at the end of the scaled shaft.
|
||||
The weather data is provided by <a href="https://openweathermap.org/current">OpenWeather</a>.
|
||||
tags: "vector, symbol, regularshape, style, arrow"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
83
examples/wind-arrows.js
Normal file
83
examples/wind-arrows.js
Normal file
@@ -0,0 +1,83 @@
|
||||
import Feature from '../src/ol/Feature.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
import Point from '../src/ol/geom/Point.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import VectorLayer from '../src/ol/layer/Vector.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {Fill, RegularShape, Stroke, Style} from '../src/ol/style.js';
|
||||
import {fromLonLat} from '../src/ol/proj.js';
|
||||
|
||||
const shaft = new RegularShape({
|
||||
points: 2,
|
||||
radius: 5,
|
||||
stroke: new Stroke({
|
||||
width: 2,
|
||||
color: 'black',
|
||||
}),
|
||||
rotateWithView: true,
|
||||
});
|
||||
|
||||
const head = new RegularShape({
|
||||
points: 3,
|
||||
radius: 5,
|
||||
fill: new Fill({
|
||||
color: 'black',
|
||||
}),
|
||||
rotateWithView: true,
|
||||
});
|
||||
|
||||
const styles = [new Style({image: shaft}), new Style({image: head})];
|
||||
|
||||
const source = new VectorSource({
|
||||
attributions:
|
||||
'Weather data by <a href="https://openweathermap.org/current">OpenWeather</a>',
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM(),
|
||||
}),
|
||||
new VectorLayer({
|
||||
source: source,
|
||||
style: function (feature) {
|
||||
const wind = feature.get('wind');
|
||||
// rotate arrow away from wind origin
|
||||
const angle = ((wind.deg - 180) * Math.PI) / 180;
|
||||
const scale = wind.speed / 10;
|
||||
shaft.setScale([1, scale]);
|
||||
shaft.setRotation(angle);
|
||||
head.setDisplacement([
|
||||
0,
|
||||
head.getRadius() / 2 + shaft.getRadius() * scale,
|
||||
]);
|
||||
head.setRotation(angle);
|
||||
return styles;
|
||||
},
|
||||
}),
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
zoom: 2,
|
||||
}),
|
||||
});
|
||||
|
||||
fetch('data/openweather/weather.json')
|
||||
.then(function (response) {
|
||||
return response.json();
|
||||
})
|
||||
.then(function (data) {
|
||||
const features = [];
|
||||
data.list.forEach(function (report) {
|
||||
const feature = new Feature(
|
||||
new Point(fromLonLat([report.coord.lon, report.coord.lat]))
|
||||
);
|
||||
feature.setProperties(report);
|
||||
features.push(feature);
|
||||
});
|
||||
source.addFeatures(features);
|
||||
map.getView().fit(source.getExtent());
|
||||
});
|
||||
6523
package-lock.json
generated
6523
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
33
package.json
33
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ol",
|
||||
"version": "6.9.0",
|
||||
"version": "6.12.0",
|
||||
"description": "OpenLayers mapping library",
|
||||
"keywords": [
|
||||
"map",
|
||||
@@ -46,7 +46,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"geotiff": "^1.0.8",
|
||||
"ol-mapbox-style": "^6.5.1",
|
||||
"ol-mapbox-style": "^6.8.2",
|
||||
"pbf": "3.2.1",
|
||||
"rbush": "^3.0.1"
|
||||
},
|
||||
@@ -63,48 +63,41 @@
|
||||
"@types/topojson-specification": "^1.0.1",
|
||||
"babel-loader": "^8.2.2",
|
||||
"chaikin-smooth": "^1.0.4",
|
||||
"clean-css-cli": "5.4.1",
|
||||
"copy-webpack-plugin": "^9.0.0",
|
||||
"coverage-istanbul-loader": "^3.0.5",
|
||||
"coveralls": "3.1.1",
|
||||
"clean-css-cli": "5.5.0",
|
||||
"copy-webpack-plugin": "^10.0.0",
|
||||
"es-main": "^1.0.2",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint": "^8.0.1",
|
||||
"eslint-config-openlayers": "^16.0.1",
|
||||
"expect.js": "0.3.1",
|
||||
"express": "^4.17.1",
|
||||
"front-matter": "^4.0.0",
|
||||
"fs-extra": "^10.0.0",
|
||||
"glob": "^7.1.5",
|
||||
"globby": "^12.0.0",
|
||||
"handlebars": "4.7.7",
|
||||
"istanbul": "0.4.5",
|
||||
"jquery": "3.6.0",
|
||||
"jsdoc": "3.6.7",
|
||||
"jsdoc-plugin-typescript": "^2.0.5",
|
||||
"json-stringify-safe": "^5.0.1",
|
||||
"karma": "^6.3.2",
|
||||
"karma-chrome-launcher": "3.1.0",
|
||||
"karma-coverage-istanbul-reporter": "^3.0.0",
|
||||
"karma-firefox-launcher": "^2.0.0",
|
||||
"karma": "^6.3.8",
|
||||
"karma-chrome-launcher": "^3.1.0",
|
||||
"karma-firefox-launcher": "^2.1.2",
|
||||
"karma-mocha": "2.0.1",
|
||||
"karma-sourcemap-loader": "^0.3.8",
|
||||
"karma-source-map-support": "^1.4.0",
|
||||
"karma-webpack": "^5.0.0",
|
||||
"loglevelnext": "^5.0.5",
|
||||
"marked": "3.0.7",
|
||||
"mocha": "9.1.2",
|
||||
"marked": "4.0.9",
|
||||
"mocha": "9.1.3",
|
||||
"pixelmatch": "^5.1.0",
|
||||
"pngjs": "^6.0.0",
|
||||
"proj4": "^2.7.5",
|
||||
"puppeteer": "10.4.0",
|
||||
"puppeteer": "13.0.1",
|
||||
"regenerator-runtime": "^0.13.9",
|
||||
"rollup": "^2.42.3",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"serve-static": "^1.14.0",
|
||||
"shx": "^0.3.2",
|
||||
"sinon": "^11.1.1",
|
||||
"terser-webpack-plugin": "^5.1.1",
|
||||
"sinon": "^12.0.1",
|
||||
"threads": "^1.6.5",
|
||||
"url-polyfill": "^1.1.5",
|
||||
"walk": "^2.3.9",
|
||||
"webpack": "^5.27.2",
|
||||
"webpack-cli": "^4.5.0",
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>OpenLayers</title>
|
||||
<link href='https://fonts.googleapis.com/css?family=Quattrocento+Sans:400,400italic,700' rel='stylesheet' type='text/css'>
|
||||
<link href='https://openlayers.org/assets/theme/site.css' rel='stylesheet' type='text/css'>
|
||||
<link href="./legacy/ol.css" rel='stylesheet' type='text/css'>
|
||||
<!-- Pointer events polyfill for old browsers, see https://caniuse.com/#feat=pointer -->
|
||||
<script src="https://unpkg.com/elm-pep"></script>
|
||||
<!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
|
||||
<script src="https://cdn.polyfill.io/v3/polyfill.min.js?features=fetch,requestAnimationFrame,Element.prototype.classList,URL,TextDecoder,Number.isInteger"></script>
|
||||
<!-- The lines below are only needed for old environments like Internet Explorer and Android 4.x -->
|
||||
<script src="https://cdn.polyfill.io/v3/polyfill.min.js?features=fetch,requestAnimationFrame,Element.prototype.classList,TextDecoder"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/3.18.3/minified.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<ul>
|
||||
@@ -32,4 +34,4 @@
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user