Compare commits
722 Commits
v5.3.1
...
v6.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7ca396f727 | ||
|
|
f1aca67882 | ||
|
|
d7905896f7 | ||
|
|
a7af9a0697 | ||
|
|
eea67868f7 | ||
|
|
d99405feeb | ||
|
|
14831a0d61 | ||
|
|
43bc53b20b | ||
|
|
c01dee0884 | ||
|
|
6fd83b9a8e | ||
|
|
05712acfef | ||
|
|
cd17f4b0d6 | ||
|
|
7c7b43ee91 | ||
|
|
02f9411c6b | ||
|
|
1338a868e9 | ||
|
|
6b1f9e681c | ||
|
|
65d8b5f26b | ||
|
|
530e47d26c | ||
|
|
85f2312370 | ||
|
|
301b45cb7c | ||
|
|
3aa93014c0 | ||
|
|
734900f1d7 | ||
|
|
fb2ea83838 | ||
|
|
8534aaa304 | ||
|
|
36cf654f09 | ||
|
|
4e8522e696 | ||
|
|
88760de64b | ||
|
|
b5f7705e1d | ||
|
|
9efe10f747 | ||
|
|
73744de14e | ||
|
|
d6c18667f4 | ||
|
|
cd28c8a301 | ||
|
|
79c6cc5159 | ||
|
|
345607be28 | ||
|
|
767c765524 | ||
|
|
67ee5a41b0 | ||
|
|
5c280e8114 | ||
|
|
bc25097899 | ||
|
|
6ce499532c | ||
|
|
386f2dc67c | ||
|
|
90034e4d48 | ||
|
|
4166c80c6e | ||
|
|
d06d00ccbb | ||
|
|
959dba169d | ||
|
|
900adaaffb | ||
|
|
94cd126189 | ||
|
|
1416a3d162 | ||
|
|
e4873a9952 | ||
|
|
8d1022046e | ||
|
|
f40cbf2cac | ||
|
|
a0ba8dd8c6 | ||
|
|
8557bd96b5 | ||
|
|
3d4f77be51 | ||
|
|
62d82411c8 | ||
|
|
c3709ef51a | ||
|
|
071e9a4735 | ||
|
|
0c889da99c | ||
|
|
a41f51c437 | ||
|
|
4cb3e24048 | ||
|
|
4cb9b1eeb3 | ||
|
|
f0a97ee460 | ||
|
|
7c1e16abc3 | ||
|
|
84995c688c | ||
|
|
cefb5d4d32 | ||
|
|
8eadb3d04c | ||
|
|
a6023a710a | ||
|
|
33ac3e34ee | ||
|
|
3c64018b37 | ||
|
|
b01970cb86 | ||
|
|
ffa24bfd22 | ||
|
|
be17bfe85a | ||
|
|
974684ed2b | ||
|
|
f90a41a7ca | ||
|
|
df847ae35c | ||
|
|
746455a9b9 | ||
|
|
3557247b27 | ||
|
|
658a4a9194 | ||
|
|
ec6371d7a0 | ||
|
|
6bab8793a2 | ||
|
|
45b2e8885a | ||
|
|
40b5891ea7 | ||
|
|
667cadc403 | ||
|
|
08be6cf9bc | ||
|
|
fd07de39ad | ||
|
|
44942dffb5 | ||
|
|
f7b1fe07d0 | ||
|
|
9a7e5747eb | ||
|
|
e4264b94ed | ||
|
|
e9ecea3bb7 | ||
|
|
391dfc5025 | ||
|
|
3da449d77e | ||
|
|
7a66dc5774 | ||
|
|
74f7b1974d | ||
|
|
6b94aaa424 | ||
|
|
c4ed80dd92 | ||
|
|
7a73638fb2 | ||
|
|
0ece4a7dae | ||
|
|
6fe8b5c49d | ||
|
|
2ba4be2661 | ||
|
|
a2a3bda5c9 | ||
|
|
f28b7c7bcf | ||
|
|
27d025327f | ||
|
|
020f513ed5 | ||
|
|
30fb0b1ed1 | ||
|
|
40605d7c53 | ||
|
|
666c14d190 | ||
|
|
0a005527e7 | ||
|
|
c0a860a31f | ||
|
|
3e82da4beb | ||
|
|
b71d7773d3 | ||
|
|
7d5b2d8c3b | ||
|
|
dc298b8895 | ||
|
|
693c763710 | ||
|
|
680f3cde3c | ||
|
|
3ef6635c09 | ||
|
|
8028ce3ac5 | ||
|
|
3557a13147 | ||
|
|
f6e625f21a | ||
|
|
d1c71c3c61 | ||
|
|
6f8ffddace | ||
|
|
438736068e | ||
|
|
bfe8ee5309 | ||
|
|
703dadfcde | ||
|
|
fecb8de769 | ||
|
|
b3bc78daec | ||
|
|
d24ae3c2ac | ||
|
|
2879c0b6ad | ||
|
|
5ef1b51c02 | ||
|
|
41d231a4c7 | ||
|
|
f4fe1babd2 | ||
|
|
efc85ed0ed | ||
|
|
be16c2357d | ||
|
|
88c213078e | ||
|
|
ee57b197e5 | ||
|
|
2c859b1196 | ||
|
|
c4be22b1b6 | ||
|
|
b00b877ca1 | ||
|
|
168edac4a6 | ||
|
|
caa9153dd0 | ||
|
|
ba02320fcc | ||
|
|
427c73ddf9 | ||
|
|
2c3ffdfdf8 | ||
|
|
97b21145c4 | ||
|
|
2428c0984e | ||
|
|
e0aad192af | ||
|
|
e34806ad70 | ||
|
|
a0fde2b24d | ||
|
|
abfe6b4359 | ||
|
|
acd8c34535 | ||
|
|
1a1c7dec87 | ||
|
|
5e4ee77968 | ||
|
|
9f54e9cb4d | ||
|
|
83e7e3ad5c | ||
|
|
47adce4786 | ||
|
|
ce7a1b4365 | ||
|
|
0b53a3229b | ||
|
|
5318d52036 | ||
|
|
686e493288 | ||
|
|
5e16bae134 | ||
|
|
53fc082fc2 | ||
|
|
47679a9686 | ||
|
|
b76626071b | ||
|
|
37eb6de37d | ||
|
|
5e7cf6da66 | ||
|
|
c18a833880 | ||
|
|
8674da9a3e | ||
|
|
61b20da539 | ||
|
|
1ba85a11e9 | ||
|
|
59cf0c31b6 | ||
|
|
4f487c4df1 | ||
|
|
6e58796f66 | ||
|
|
26ff8899c3 | ||
|
|
fe5da2e160 | ||
|
|
862553509a | ||
|
|
164635f28c | ||
|
|
3e6425db86 | ||
|
|
09a1c1ef1b | ||
|
|
f74e56c939 | ||
|
|
592b6cf362 | ||
|
|
ba0ffea262 | ||
|
|
0a1fe16ea2 | ||
|
|
ea45068335 | ||
|
|
63c079257f | ||
|
|
8dbe8bc34e | ||
|
|
af8a22d34d | ||
|
|
ab04df8f9d | ||
|
|
e37734826c | ||
|
|
b6d115d868 | ||
|
|
a5d93117ed | ||
|
|
2078b5d355 | ||
|
|
1d4a767f86 | ||
|
|
89ca596eaf | ||
|
|
347e721025 | ||
|
|
cd6d195e3f | ||
|
|
a0de38c1f3 | ||
|
|
0daa27eab3 | ||
|
|
576fc015a6 | ||
|
|
4f51914994 | ||
|
|
3290559c1f | ||
|
|
be03ac4c50 | ||
|
|
2a07db201f | ||
|
|
13cdb8365a | ||
|
|
46494c79cc | ||
|
|
d0a9003b55 | ||
|
|
fde58ee2a2 | ||
|
|
0c63112332 | ||
|
|
1df40fe3d6 | ||
|
|
3878190b12 | ||
|
|
e4fa3f0520 | ||
|
|
48833d60e3 | ||
|
|
17ab5c2084 | ||
|
|
c05bb30183 | ||
|
|
2f0723f557 | ||
|
|
5dfda3f4bd | ||
|
|
62f270a172 | ||
|
|
2364a75f20 | ||
|
|
787fd4aa44 | ||
|
|
5389e9675c | ||
|
|
aa0bc8175b | ||
|
|
62288139d6 | ||
|
|
af74a476dc | ||
|
|
79f5283ce9 | ||
|
|
90c8fc7888 | ||
|
|
4d54ad0daf | ||
|
|
37b1cca027 | ||
|
|
7f0fc2a821 | ||
|
|
e6ca241a27 | ||
|
|
f0d3f80663 | ||
|
|
6258b6efc4 | ||
|
|
138cc55b34 | ||
|
|
4d3968d35b | ||
|
|
9372bc9157 | ||
|
|
4e8048cbd6 | ||
|
|
919cc85714 | ||
|
|
f368fa1a28 | ||
|
|
c4c6f84bca | ||
|
|
c8df836ce1 | ||
|
|
54f48e9c03 | ||
|
|
0f3c0d1af4 | ||
|
|
32696638d2 | ||
|
|
ab797b7160 | ||
|
|
523d3a4e8c | ||
|
|
831c7621c7 | ||
|
|
d426e80c6b | ||
|
|
cf6b1ca1cc | ||
|
|
0f3e410428 | ||
|
|
2e21b9f975 | ||
|
|
ad794cea14 | ||
|
|
56a60631bc | ||
|
|
3e1fce0e22 | ||
|
|
c2ffba1fda | ||
|
|
a94632376c | ||
|
|
ad84c37c86 | ||
|
|
06e30e8884 | ||
|
|
511e580c76 | ||
|
|
117f0d21fc | ||
|
|
ba49f2d2db | ||
|
|
b22b62f647 | ||
|
|
831c23d212 | ||
|
|
33c717e159 | ||
|
|
fad7c7edb1 | ||
|
|
62c7a49943 | ||
|
|
0acfd7ab59 | ||
|
|
435ef3070c | ||
|
|
a7305be824 | ||
|
|
76b31be9fc | ||
|
|
c35cc93ade | ||
|
|
8978d86f35 | ||
|
|
409c962caf | ||
|
|
a0f15e1eb6 | ||
|
|
d8156577c9 | ||
|
|
3b57de3c7a | ||
|
|
9cfb46f7a4 | ||
|
|
100e69e286 | ||
|
|
3193de0906 | ||
|
|
372cb52f83 | ||
|
|
a4fe067aad | ||
|
|
6967e5b60b | ||
|
|
016d738269 | ||
|
|
5d1c27d05d | ||
|
|
1750ff43e0 | ||
|
|
5195adea85 | ||
|
|
348186e2f8 | ||
|
|
412d9a9713 | ||
|
|
3b57f6693c | ||
|
|
483c442621 | ||
|
|
b4bd447d34 | ||
|
|
d838de32b7 | ||
|
|
b546eafeae | ||
|
|
2e1ab8234e | ||
|
|
0ec769c234 | ||
|
|
1bb1e3c542 | ||
|
|
f948577a1a | ||
|
|
193749f4fd | ||
|
|
6858a5cde7 | ||
|
|
80ebb8142c | ||
|
|
e426af29c2 | ||
|
|
68d4d244f3 | ||
|
|
39a21f177d | ||
|
|
29702e3750 | ||
|
|
056568c936 | ||
|
|
d2cae9d3b7 | ||
|
|
701e19c1c9 | ||
|
|
4010a644c0 | ||
|
|
480b064f5d | ||
|
|
daa92c105d | ||
|
|
b1602877d9 | ||
|
|
0cda18f58a | ||
|
|
89af80241e | ||
|
|
b3520f8217 | ||
|
|
bbbed30848 | ||
|
|
1be17e44a2 | ||
|
|
d0f03f1257 | ||
|
|
457e7b96dd | ||
|
|
759b317707 | ||
|
|
30947c0de8 | ||
|
|
cd3e65e3df | ||
|
|
76bd75ebb1 | ||
|
|
27b0cf18e7 | ||
|
|
bade38ecc8 | ||
|
|
8e4c66a49e | ||
|
|
2c4a959e55 | ||
|
|
b532a489d4 | ||
|
|
f177a2bcd5 | ||
|
|
a6989af00a | ||
|
|
2367fbb1ea | ||
|
|
4ce5379a4b | ||
|
|
1c4cfc9559 | ||
|
|
4bc9216e41 | ||
|
|
97ab5133a0 | ||
|
|
d00bfe8fe7 | ||
|
|
e4e0e61731 | ||
|
|
88db530c43 | ||
|
|
9cf58e412f | ||
|
|
6cabb9dd0b | ||
|
|
b71e391e3b | ||
|
|
e92e03eb1b | ||
|
|
df59b894b1 | ||
|
|
6202a0cf05 | ||
|
|
4a28155f2b | ||
|
|
a50fda5ac8 | ||
|
|
56201b9295 | ||
|
|
3ef6e39c26 | ||
|
|
8f7d0c8a4b | ||
|
|
fd0e7782ed | ||
|
|
3790007226 | ||
|
|
976863c376 | ||
|
|
4256932cee | ||
|
|
be52368006 | ||
|
|
3944f0e62b | ||
|
|
8bb7d77f68 | ||
|
|
55c36b5aab | ||
|
|
78028893e2 | ||
|
|
171f1a5bac | ||
|
|
a77ed76443 | ||
|
|
e9e804a836 | ||
|
|
1d243a7f37 | ||
|
|
fbf98a44ea | ||
|
|
9720db2041 | ||
|
|
65a10db432 | ||
|
|
e73931a9b2 | ||
|
|
d4c14da4b5 | ||
|
|
aad836dfb2 | ||
|
|
97618c8611 | ||
|
|
769d7dd732 | ||
|
|
28bdbeb869 | ||
|
|
2ce8fa6f10 | ||
|
|
82e2a84862 | ||
|
|
43759fd846 | ||
|
|
85abe3695a | ||
|
|
74225188f4 | ||
|
|
4caabee792 | ||
|
|
63de0aefbe | ||
|
|
4a3f70c09b | ||
|
|
eaa29b2e63 | ||
|
|
79c8afdba8 | ||
|
|
4b784f06e9 | ||
|
|
b03a42c81a | ||
|
|
49b1310b19 | ||
|
|
f4aec3fd01 | ||
|
|
b71a8aa006 | ||
|
|
66ec9983b2 | ||
|
|
4910933a9b | ||
|
|
8cea28e102 | ||
|
|
d1df9dae0d | ||
|
|
e66a84c897 | ||
|
|
5951e147c0 | ||
|
|
7b6f86abc7 | ||
|
|
0f5439e16e | ||
|
|
e9a30c5cb7 | ||
|
|
37c987de0a | ||
|
|
cb44775306 | ||
|
|
60b3370bba | ||
|
|
a8799e1d60 | ||
|
|
087b024a24 | ||
|
|
c6be2c7ff5 | ||
|
|
662d9122f5 | ||
|
|
a137eabc5d | ||
|
|
a9d336d0f1 | ||
|
|
1133a5bfb7 | ||
|
|
432ac856b6 | ||
|
|
0fd4af670b | ||
|
|
8b50c3c6cb | ||
|
|
e058eb3164 | ||
|
|
2131cc460c | ||
|
|
4ff7b0a379 | ||
|
|
7036064ffc | ||
|
|
9863e25f5e | ||
|
|
61baa8a4a2 | ||
|
|
e4b00be9d6 | ||
|
|
0c27cee2a6 | ||
|
|
898c349fbf | ||
|
|
5d14666376 | ||
|
|
0b23e94a2a | ||
|
|
6b82cf0b84 | ||
|
|
da8ee157b8 | ||
|
|
18eef152c4 | ||
|
|
066e5b7ed3 | ||
|
|
4b060224f2 | ||
|
|
76b1a7f96b | ||
|
|
d0e0c8fc3a | ||
|
|
eb700a3c5e | ||
|
|
5cc74ee1d2 | ||
|
|
2eeef29ab2 | ||
|
|
140e8b59bb | ||
|
|
b4b9b35ef7 | ||
|
|
a4d84b616f | ||
|
|
366588d07e | ||
|
|
d030f092a2 | ||
|
|
ba609a67ba | ||
|
|
5d528dca3b | ||
|
|
c169fec4a8 | ||
|
|
06a0a7f33b | ||
|
|
1cc49e0b23 | ||
|
|
af10f6a75c | ||
|
|
686847f491 | ||
|
|
db1f432197 | ||
|
|
63cf21b668 | ||
|
|
4a3a53c725 | ||
|
|
42a8c7983f | ||
|
|
06ae175cef | ||
|
|
93140d9495 | ||
|
|
c39471aa93 | ||
|
|
6a5651cc87 | ||
|
|
a64ca2b4bf | ||
|
|
97ed71f683 | ||
|
|
6219e31e40 | ||
|
|
7f55424fda | ||
|
|
a81c2ad995 | ||
|
|
c004e9d644 | ||
|
|
6c4845a304 | ||
|
|
358d86c33e | ||
|
|
95c16cfa11 | ||
|
|
5aa8db15f4 | ||
|
|
6cfb8f275b | ||
|
|
edbe2316ef | ||
|
|
d6add33df0 | ||
|
|
a490c658fb | ||
|
|
9eb5808844 | ||
|
|
96437e3875 | ||
|
|
3ecc6d60d2 | ||
|
|
47ecd508fa | ||
|
|
98a780e5f9 | ||
|
|
038f122d11 | ||
|
|
73ffda10db | ||
|
|
b3bcf7dac1 | ||
|
|
4a3dbb0e24 | ||
|
|
90d46cb539 | ||
|
|
7831a591f7 | ||
|
|
1dbe52d738 | ||
|
|
f73c6fab35 | ||
|
|
eafe1bf8a3 | ||
|
|
039af41af1 | ||
|
|
a924834920 | ||
|
|
3bf9a54ed5 | ||
|
|
91bd144f0e | ||
|
|
160e9e8056 | ||
|
|
c5b7c5febb | ||
|
|
3cba5ffbe2 | ||
|
|
4d54549b5f | ||
|
|
45cd573768 | ||
|
|
358f58ba3a | ||
|
|
cc9b7b6259 | ||
|
|
5ad73f8bbd | ||
|
|
832dadb3af | ||
|
|
ac3a1fb953 | ||
|
|
7a82904a3b | ||
|
|
666f57bd4c | ||
|
|
32495388b9 | ||
|
|
5bb110f157 | ||
|
|
aa4237539f | ||
|
|
ee536fb70d | ||
|
|
bc347e3eb0 | ||
|
|
65ceb9264e | ||
|
|
6c0b3f773b | ||
|
|
f90efac131 | ||
|
|
26de43de0c | ||
|
|
ed7825e13a | ||
|
|
8b077c66d8 | ||
|
|
b5378deb45 | ||
|
|
33f6d6f110 | ||
|
|
a9f98f2b1e | ||
|
|
8822690cf4 | ||
|
|
9a4e665c3b | ||
|
|
6edac64b81 | ||
|
|
f9ebb0c917 | ||
|
|
c137b68938 | ||
|
|
8eb48604e9 | ||
|
|
5fffb67242 | ||
|
|
c37b6202a0 | ||
|
|
610fcab79e | ||
|
|
489af4023d | ||
|
|
87e5bbac4d | ||
|
|
20e5841aed | ||
|
|
39a4f42e3d | ||
|
|
6234b69512 | ||
|
|
5ba8795355 | ||
|
|
433ab97d1c | ||
|
|
f416cf742d | ||
|
|
c612cce591 | ||
|
|
f2cab1fcbb | ||
|
|
b3903df156 | ||
|
|
dd23055db1 | ||
|
|
1ae1b60308 | ||
|
|
40d5f4efe7 | ||
|
|
0189e8345d | ||
|
|
72cf7b13fa | ||
|
|
66a74ac019 | ||
|
|
a84559d1fb | ||
|
|
cb77e10179 | ||
|
|
874047a928 | ||
|
|
530bcd0c88 | ||
|
|
94524fb431 | ||
|
|
716256e8f3 | ||
|
|
fb8bf785dd | ||
|
|
4a275c543a | ||
|
|
0c1424c5bb | ||
|
|
7fa2189fe9 | ||
|
|
d3294730f1 | ||
|
|
494b817f47 | ||
|
|
51becf1c2e | ||
|
|
298af9ca0f | ||
|
|
81807c5910 | ||
|
|
3c5eac13c9 | ||
|
|
154a046130 | ||
|
|
583dfb8e9d | ||
|
|
1c11dc5311 | ||
|
|
97b16be572 | ||
|
|
fc20dc986c | ||
|
|
66efee9e22 | ||
|
|
71270efa75 | ||
|
|
0a0d6c22f5 | ||
|
|
36cf7227c0 | ||
|
|
9937fd5963 | ||
|
|
8d51e0d487 | ||
|
|
981b398042 | ||
|
|
2e32ac7254 | ||
|
|
0ed7f76ad0 | ||
|
|
6cbde797be | ||
|
|
d3355f613c | ||
|
|
81d0bc21d5 | ||
|
|
2cb9d47547 | ||
|
|
e991dcc38c | ||
|
|
bf9171a689 | ||
|
|
bdbf00f055 | ||
|
|
ce44a9a3e4 | ||
|
|
89fed65f07 | ||
|
|
da92b2ab3f | ||
|
|
eaed37da96 | ||
|
|
b1a5f4855f | ||
|
|
94bf02176e | ||
|
|
178061ab9d | ||
|
|
f9c64e52af | ||
|
|
00cf75c837 | ||
|
|
f95070a34d | ||
|
|
5bbfeef12b | ||
|
|
00d9740a58 | ||
|
|
7630fafcf2 | ||
|
|
a3f9c6b724 | ||
|
|
05bf1d8f4a | ||
|
|
3ac46ad10b | ||
|
|
d5c390e726 | ||
|
|
1b8a6baa35 | ||
|
|
94bcb8a0f6 | ||
|
|
c69366ec0a | ||
|
|
4ee75359c0 | ||
|
|
adb1bd7a31 | ||
|
|
dbd6dad4f3 | ||
|
|
d7a6c4dbe3 | ||
|
|
56131cf6ea | ||
|
|
12f6ce7a44 | ||
|
|
52f4f61a6c | ||
|
|
f9dcadb982 | ||
|
|
0f5ced8483 | ||
|
|
5ecd832c92 | ||
|
|
87a1b926c9 | ||
|
|
4ba84d7926 | ||
|
|
afc946b215 | ||
|
|
c0df61468f | ||
|
|
0ece0fb002 | ||
|
|
4ce19530ce | ||
|
|
3d203f990e | ||
|
|
3170355b07 | ||
|
|
f5a8ad63f9 | ||
|
|
ba6a6fff7d | ||
|
|
951d4d5ade | ||
|
|
e299863117 | ||
|
|
f3bd08321a | ||
|
|
8097be8419 | ||
|
|
fcf470fc8d | ||
|
|
ecf79a9ec2 | ||
|
|
4988a50760 | ||
|
|
ebbb54456a | ||
|
|
081c677ea2 | ||
|
|
fc85b2ba78 | ||
|
|
d0f66b7cec | ||
|
|
40b2922b4e | ||
|
|
63b04210ab | ||
|
|
87c721b071 | ||
|
|
edeb5d3e71 | ||
|
|
3f624ec0c0 | ||
|
|
0d94b1a566 | ||
|
|
593632daea | ||
|
|
96dd5417e3 | ||
|
|
68b4ef5ec8 | ||
|
|
6e964c7934 | ||
|
|
50ae34fcc6 | ||
|
|
f295a97894 | ||
|
|
aa841c7de2 | ||
|
|
0452da92d3 | ||
|
|
7ae051c07a | ||
|
|
bed9c6b09a | ||
|
|
cac323a785 | ||
|
|
c62ebb9f61 | ||
|
|
488a104a92 | ||
|
|
7a472321c4 | ||
|
|
4adcb5ae6c | ||
|
|
19541699c3 | ||
|
|
d6e8711172 | ||
|
|
46b8f39c71 | ||
|
|
0e91365859 | ||
|
|
c74d80504e | ||
|
|
f9a7cf2251 | ||
|
|
5afd8178f4 | ||
|
|
82ab50a22b | ||
|
|
bdf98d9003 | ||
|
|
2bc0d7f2ce | ||
|
|
30909ddbcd | ||
|
|
cda23e0d53 | ||
|
|
5bfe7089af | ||
|
|
9c0a7b9ba7 | ||
|
|
391fff38aa | ||
|
|
fd0acaccd1 | ||
|
|
96cca7ac18 | ||
|
|
c3c5b3b314 | ||
|
|
22eb96637f | ||
|
|
c2c599a517 | ||
|
|
d21a88edce | ||
|
|
1e1dca5342 | ||
|
|
5eed22286b | ||
|
|
647421f07b | ||
|
|
09d87bf33d | ||
|
|
2caa74a4e9 | ||
|
|
a6f94f865b | ||
|
|
697e475ee4 | ||
|
|
4c787c7f57 | ||
|
|
d02730abc1 | ||
|
|
04077675e1 | ||
|
|
1c3e7a548f | ||
|
|
432b74d64d | ||
|
|
55a963e0a9 | ||
|
|
0c97fd63e2 | ||
|
|
edaa615333 | ||
|
|
afc64258af | ||
|
|
7274798aa1 | ||
|
|
5967bc75ba | ||
|
|
c1963ba369 | ||
|
|
58b474225c | ||
|
|
daffbde80b | ||
|
|
4a5fa1f840 | ||
|
|
8bf252e70f | ||
|
|
95c363075c | ||
|
|
a9b2952be4 | ||
|
|
dc05f48294 | ||
|
|
43ed2c1764 | ||
|
|
fc6882f146 | ||
|
|
a69eeceeba | ||
|
|
ca5b0c63a5 | ||
|
|
c50b9b2c25 | ||
|
|
f6b838c635 | ||
|
|
7374e32007 | ||
|
|
2ec509fbca | ||
|
|
ae1f3afd66 | ||
|
|
285a610c46 | ||
|
|
c9529b9acd | ||
|
|
7ffaa134c7 | ||
|
|
6c052c0dab | ||
|
|
6e27b47fc3 | ||
|
|
cbcd1fdcec | ||
|
|
b6ca51a9e6 | ||
|
|
cb9925034c | ||
|
|
767aa7b7a4 | ||
|
|
83c988eed5 | ||
|
|
f67e5642ab | ||
|
|
7dc5bf3e8d | ||
|
|
0ebc023223 | ||
|
|
14d59623aa | ||
|
|
67b08a302e | ||
|
|
93ff80449f | ||
|
|
6aed520d8f | ||
|
|
c43b0cb520 | ||
|
|
6f238a8d09 | ||
|
|
800776b6cb | ||
|
|
f444da29bc | ||
|
|
4923fac359 | ||
|
|
8c89e17618 | ||
|
|
1253558006 | ||
|
|
67ee32fdea | ||
|
|
aab9ff023c | ||
|
|
a73e9607a8 | ||
|
|
017a78d2d1 | ||
|
|
7321541de8 |
@@ -2,7 +2,7 @@ version: 2
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
- image: circleci/node:10-browsers
|
||||
- image: circleci/node:latest-browsers
|
||||
|
||||
working_directory: ~/repo
|
||||
|
||||
@@ -14,7 +14,7 @@ jobs:
|
||||
- v1-dependencies-{{ checksum "package.json" }}
|
||||
- v1-dependencies-
|
||||
|
||||
- run:
|
||||
- run:
|
||||
name: Install Dependencies
|
||||
command: npm install
|
||||
|
||||
@@ -22,12 +22,16 @@ jobs:
|
||||
paths:
|
||||
- node_modules
|
||||
key: v1-dependencies-{{ checksum "package.json" }}
|
||||
|
||||
- run:
|
||||
|
||||
- run:
|
||||
name: Run Tests
|
||||
command: npm test
|
||||
|
||||
- run:
|
||||
- store_artifacts:
|
||||
path: rendering/cases/
|
||||
destination: rendering
|
||||
|
||||
- run:
|
||||
name: Build Examples
|
||||
command: npm run build-examples
|
||||
|
||||
|
||||
@@ -11,7 +11,3 @@ insert_final_newline = true
|
||||
[*.md]
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
9
.github/ISSUE_TEMPLATE.md
vendored
9
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,9 +0,0 @@
|
||||
<!--
|
||||
Thank you for your interest in making OpenLayers better!
|
||||
|
||||
If you are reporting a bug, please link to an example that reproduces the problem. This will make it easier for people who may want to help you debug.
|
||||
|
||||
If you have a usage question, you might want to try Stack Overflow first: https://stackoverflow.com/questions/tagged/openlayers
|
||||
|
||||
Thanks
|
||||
-->
|
||||
19
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
19
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
labels:
|
||||
- bug
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
13
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
13
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
labels:
|
||||
- feature request
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
@@ -42,7 +42,7 @@ Your pull request must:
|
||||
|
||||
* Follow OpenLayers's coding style.
|
||||
|
||||
* Pass the integration tests run automatically by the Travis Continuous
|
||||
* Pass the integration tests run automatically by the CircleCI Continuous
|
||||
Integration system.
|
||||
|
||||
* Address a single issue or add a single item of functionality.
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
You will obviously start by
|
||||
[forking](https://github.com/openlayers/openlayers/fork) the OpenLayers repository.
|
||||
|
||||
### Travis CI
|
||||
### CircleCI
|
||||
|
||||
The Travis CI hook is enabled on the Github repository. This means every pull request
|
||||
The CircleCI hook is enabled on the Github repository. This means every pull request
|
||||
is run through a full test suite to ensure it compiles and passes the tests. Failing
|
||||
pull requests will not be merged.
|
||||
|
||||
|
||||
13
Makefile
13
Makefile
@@ -1,13 +0,0 @@
|
||||
SRC_GLSL := $(shell find src -type f -name '*.glsl')
|
||||
SRC_SHADER_JS := $(patsubst %shader.glsl,%shader.js,$(SRC_GLSL))
|
||||
SRC_SHADERLOCATIONS_JS := $(patsubst %shader.glsl,%shader/Locations.js,$(SRC_GLSL))
|
||||
|
||||
.PHONY: shaders
|
||||
shaders: $(SRC_SHADER_JS) $(SRC_SHADERLOCATIONS_JS)
|
||||
|
||||
%shader.js: %shader.glsl src/ol/webgl/shader.mustache tasks/glslunit.js
|
||||
@node tasks/glslunit.js --input $< | ./node_modules/.bin/mustache - src/ol/webgl/shader.mustache > $@
|
||||
|
||||
%shader/Locations.js: %shader.glsl src/ol/webgl/shaderlocations.mustache tasks/glslunit.js
|
||||
@mkdir -p $(@D)
|
||||
@node tasks/glslunit.js --input $< | ./node_modules/.bin/mustache - src/ol/webgl/shaderlocations.mustache > $@
|
||||
26
README.md
26
README.md
@@ -41,6 +41,30 @@ See the following examples for more detail on bundling OpenLayers with your appl
|
||||
* Using [Parcel](https://github.com/openlayers/ol-parcel)
|
||||
* Using [Browserify](https://github.com/openlayers/ol-browserify)
|
||||
|
||||
## IntelliSense support and type checking for VS Code
|
||||
|
||||
The `ol` package contains a `src/` folder with JSDoc annotated sources. TypeScript can get type definitions from these sources with a `jsconfig.json` config file in the project root:
|
||||
```js
|
||||
{
|
||||
"compilerOptions": {
|
||||
"checkJs": true,
|
||||
// Point to the JSDoc typed sources when using modules from the ol package
|
||||
"baseUrl": "./",
|
||||
"paths": {
|
||||
"ol": ["node_modules/ol/src"],
|
||||
"ol/*": ["node_modules/ol/src/*"]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"**/*.js",
|
||||
"node_modules/ol/**/*.js"
|
||||
]
|
||||
}
|
||||
```
|
||||
Project template with this configuration: https://gist.github.com/9a7253cb4712e8bf38d75d8ac898e36c.
|
||||
|
||||
Note that the above only works when authoring in plain JavaScript. For similar configurations with a `tsconfig.json` in TypeScript projects, your mileage may vary.
|
||||
|
||||
## Supported Browsers
|
||||
|
||||
OpenLayers runs on all modern browsers that support [HTML5](https://html.spec.whatwg.org/multipage/) and [ECMAScript 5](http://www.ecma-international.org/ecma-262/5.1/). This includes Chrome, Firefox, Safari and Edge. For older browsers and platforms like Internet Explorer (down to version 9) and Android 4.x, [polyfills](http://polyfill.io) for `requestAnimationFrame` and `Element.prototype.classList` are required, and using the KML format requires a polyfill for `URL`.
|
||||
@@ -62,4 +86,4 @@ Please see our guide on [contributing](CONTRIBUTING.md) if you're interested in
|
||||
- Need help? Find it on [Stack Overflow using the tag 'openlayers'](http://stackoverflow.com/questions/tagged/openlayers)
|
||||
- Follow [@openlayers](https://twitter.com/openlayers) on Twitter
|
||||
|
||||
[](https://travis-ci.org/openlayers/openlayers)
|
||||
[](https://circleci.com/gh/openlayers/openlayers/tree/master)
|
||||
|
||||
@@ -2,6 +2,145 @@
|
||||
|
||||
### Next version
|
||||
|
||||
#### Backwards incompatible changes
|
||||
|
||||
##### Removal of deprecated methods
|
||||
|
||||
The `inherits` function that was used to inherit the prototype methods from one constructor into another has been removed.
|
||||
The standard ECMAScript classes should be used instead.
|
||||
|
||||
The deprecated `getSnapToPixel` and `setSnapToPixel` functions from the `ImageStyle` class have been removed.
|
||||
|
||||
##### New internal tile coordinates
|
||||
|
||||
Previously, the internal tile coordinates used in the library had an unusual row order – the origin of the tile coordinate system was at the top left as expected, but the rows increased upwards. This meant that all tile coordinates within a tile grid's extent had negative `y` values.
|
||||
|
||||
Now, the internal tile coordinates used in the library have the same row order as standard (e.g. XYZ) tile coordinates. The origin is at the top left (as before), and rows or `y` values increase downward. So the top left tile of a tile grid is now `0, 0`, whereas it was `0, -1` before.
|
||||
|
||||
```
|
||||
x, y values for tile coordinates
|
||||
|
||||
origin
|
||||
*__________________________
|
||||
| | | |
|
||||
| 0, 0 | 1, 0 | 2, 0 |
|
||||
|________|________|________|
|
||||
| | | |
|
||||
| 0, 1 | 1, 1 | 2, 1 |
|
||||
|________|________|________|
|
||||
| | | |
|
||||
| 0, 2 | 1, 2 | 2, 2 |
|
||||
|________|________|________|
|
||||
```
|
||||
|
||||
This change should only affect you if you were using a custom `tileLoadFunction` or `tileUrlFunction`. For example, if you used to have a `tileUrlFunction` that looked like this:
|
||||
|
||||
```js
|
||||
// before
|
||||
function tileUrlFunction(tileCoord) {
|
||||
const z = tileCoord[0];
|
||||
const x = tileCoord[1];
|
||||
const y = -tileCoord[2] - 1;
|
||||
// do something with z, x, y
|
||||
}
|
||||
```
|
||||
|
||||
You would now do something like this:
|
||||
```js
|
||||
// after
|
||||
function tileUrlFunction(tileCoord) {
|
||||
const z = tileCoord[0];
|
||||
const x = tileCoord[1];
|
||||
const y = tileCoord[2];
|
||||
// do something with z, x, y
|
||||
}
|
||||
```
|
||||
|
||||
In addition (this should be exceedingly rare), if you previously created a `ol/tilegrid/WMTS` by hand and you were providing an array of `sizes`, you no longer have to provide a negative height if your tile origin is the top-left corner (the common case). On the other hand, if you are providing a custom array of `sizes` and your origin is the bottom of the grid (this is uncommon), your height values must now be negative.
|
||||
|
||||
##### Removal of the "vector" render mode for vector tile layers
|
||||
|
||||
If you were previously using `VectorTile` layers with `renderMode: 'vector'`, you have to remove this configuration option. That mode was removed. `'hybrid'` (default) and `'image'` are still available.
|
||||
|
||||
##### Removal of the "renderMode" option for vector layers
|
||||
|
||||
If you were previously using `Vector` layers with `renderMode: 'image'`, you have to remove this configuration option. Instead, use the new `ol/layer/VectorImage` layer with your `ol/source/Vector`.
|
||||
|
||||
##### New `prerender` and `postrender` layer events replace old `precompose`, `render` and `postcompose` events
|
||||
|
||||
If you were previously registering for `precompose` and `postcompose` events, you should now register for `prerender` and `postrender` events on layers. Instead of the previous `render` event, you should now listen for `postrender`. Layers are no longer composed to a single Canvas element. Instead, they are added to the map viewport as individual elements.
|
||||
|
||||
##### New `getVectorContext` function provides access to the immediate vector rendering API
|
||||
|
||||
Previously, render events included a `vectorContext` property that allowed you to render features or geometries directly to the map. This is still possible, but you now have to explicitly create a vector context with the `getVectorContext` function. This change makes the immediate rendering API an explicit dependency if your application uses it. If you don't use this API, your application bundle will not include the vector rendering modules (as it did before).
|
||||
|
||||
Here is an abbreviated example of how to use the `getVectorContext` function:
|
||||
|
||||
```js
|
||||
import {getVectorContext} from 'ol/render';
|
||||
|
||||
// construct your map and layers as usual
|
||||
|
||||
layer.on('postrender', function(event) {
|
||||
const vectorContext = getVectorContext(event);
|
||||
// use any of the drawing methods on the vector context
|
||||
});
|
||||
```
|
||||
|
||||
##### Layers can only be added to a single map
|
||||
|
||||
Previously, it was possible to render a single layer in two maps. Now, each layer can only belong to a single map (in the same way that a single DOM element can only have one parent).
|
||||
|
||||
##### The `OverviewMap` requires a list of layers.
|
||||
|
||||
Due to the constraint above (layers can only be added to a single map), the overview map needs to be constructed with a list of layers.
|
||||
|
||||
##### The `ol/Graticule` has been replaced by `ol/layer/Graticule`
|
||||
|
||||
Previously, a graticule was not a layer. Now it is. See the graticule example for details on how to add a graticule layer to your map.
|
||||
|
||||
##### Drop of support for the experimental WebGL renderer
|
||||
|
||||
The WebGL map and layers renderers are gone, replaced by a `WebGLHelper` function that provides a lightweight,
|
||||
low-level access to the WebGL API. This is implemented in a new `WebGLPointsLayer` which does simple rendering of large number
|
||||
of points with custom shaders.
|
||||
|
||||
This is now used in the `Heatmap` layer.
|
||||
|
||||
The removed classes and components are:
|
||||
* `WebGLMap` and `WebGLMapRenderer`
|
||||
* `WebGLLayerRenderer`
|
||||
* `WebGLImageLayer` and `WebGLImageLayerRenderer`
|
||||
* `WebGLTileLayer` and `WebGLTileLayerRenderer`
|
||||
* `WebGLVectorLayer` and `WebGLVectorLayerRenderer`
|
||||
* `WebGLReplay` and derived classes, along with associated shaders
|
||||
* `WebGLReplayGroup`
|
||||
* `WebGLImmediateRenderer`
|
||||
* `WebGLMap`
|
||||
* The shader build process using `mustache` and the `Makefile` at the root
|
||||
|
||||
##### Removal of the AtlasManager
|
||||
|
||||
Following the removal of the experimental WebGL renderer, the AtlasManager has been removed as well. The atlas was only used by this renderer.
|
||||
The non API `getChecksum` functions of the style is also removed.
|
||||
|
||||
##### Change of the behavior of the vector source's clear() and refresh() methods
|
||||
|
||||
The `ol/source/Vector#clear()` method no longer triggers a reload of the data from the server. If you were previously using `clear()` to refetch from the server, you now have to use `refresh()`.
|
||||
|
||||
The `ol/source/Vector#refresh()` method now removes all features from the source and triggers a reload of the data from the server. If you were previously using the `refresh()` method to re-render a vector layer, you should instead call `ol/layer/Vector#changed()`.
|
||||
|
||||
#### Other changes
|
||||
|
||||
##### Allow declutter in image render mode
|
||||
|
||||
It is now possible to configure vector tile layers with `declutter: true` and `renderMode: 'image'`. However, note that decluttering will be done per tile, resulting in labels and point symbols getting cut off at tile boundaries.
|
||||
Until now, using both options forced the render mode to be `hybrid`.
|
||||
|
||||
##### Always load tiles while animating or interacting
|
||||
|
||||
`ol/PluggableMap` and subclasses no longer support the `loadTilesWhileAnimating` and `loadTilesWhileInteracting` options. These options were used to enable tile loading during animations and interactions. With the new DOM composition render strategy, it is no longer necessary to postpone tile loading until after animations or interactions.
|
||||
|
||||
### v5.3.0
|
||||
|
||||
#### The `getUid` function returns string
|
||||
@@ -12,7 +151,7 @@ The `getUid` function from the `ol/util` module now returns a string instead of
|
||||
|
||||
When a map contains a layer from a `ol/source/OSM` source, the `ol/control/Attribution` control will be shown with the `collapsible: false` behavior.
|
||||
|
||||
To get the previous behavior, configure the `ol/control/Attribution` control with `collapsible: true`.
|
||||
To get the previous behavior, configure the `ol/control/Attribution` control with `collapsible: true`.
|
||||
|
||||
### v5.2.0
|
||||
|
||||
|
||||
@@ -4,12 +4,62 @@ var version = obj.packageInfo.version;
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<script>
|
||||
var gaProperty = 'UA-2577926-1';
|
||||
// Disable tracking if the opt-out cookie exists.
|
||||
var disableStr = 'ga-disable-' + gaProperty;
|
||||
if (document.cookie.indexOf(disableStr + '=true') > -1) {
|
||||
window[disableStr] = true;
|
||||
}
|
||||
function gaOptout() {
|
||||
document.cookie = disableStr + '=true; expires=Thu, 31 Dec 2099 23:59:59 UTC; path=/';
|
||||
window[disableStr] = true;
|
||||
}
|
||||
function gaOptoutRevoke() {
|
||||
document.cookie = disableStr + '=false; expires=Thu, 31 Dec 2099 23:59:59 UTC; path=/';
|
||||
window[disableStr] = false;
|
||||
}
|
||||
</script>
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-2577926-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
gtag('config', 'UA-2577926-1');
|
||||
gtag('config', 'UA-2577926-1', { 'anonymize_ip': true });
|
||||
</script>
|
||||
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.0/cookieconsent.min.css" />
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.1.0/cookieconsent.min.js"></script>
|
||||
<script>
|
||||
window.addEventListener("load", function() {
|
||||
window.cookieconsent.initialise({
|
||||
'palette': {
|
||||
'popup': {
|
||||
'background': '#eaf7f7',
|
||||
'text': '#5c7291'
|
||||
},
|
||||
'button': {
|
||||
'background': '#56cbdb',
|
||||
'text': '#ffffff'
|
||||
}
|
||||
},
|
||||
'theme': 'edgeless',
|
||||
'type': 'opt-out',
|
||||
'onInitialise': function (status) {
|
||||
if (!this.hasConsented()) {
|
||||
gaOptout()
|
||||
}
|
||||
},
|
||||
'onStatusChange': function(status, chosenBefore) {
|
||||
if (!this.hasConsented()) {
|
||||
gaOptout()
|
||||
}
|
||||
},
|
||||
'onRevokeChoice': function() {
|
||||
gaOptoutRevoke()
|
||||
}
|
||||
})
|
||||
});
|
||||
</script>
|
||||
<meta charset="utf-8">
|
||||
<title>OpenLayers v<?js= version ?> API - <?js= title ?></title>
|
||||
|
||||
64
config/tsconfig-build.json
Normal file
64
config/tsconfig-build.json
Normal file
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
/* Basic Options */
|
||||
"target": "ES5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
|
||||
"module": "es2015", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
|
||||
// "lib": [], /* Specify library files to be included in the compilation. */
|
||||
"allowJs": true, /* Allow javascript files to be compiled. */
|
||||
// "checkJs": true, /* Report errors in .js files. */
|
||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
||||
// "declaration": true, /* Generates corresponding '.d.ts' file. */
|
||||
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
||||
"sourceMap": true, /* Generates corresponding '.map' file. */
|
||||
// "outFile": "./", /* Concatenate and emit output to single file. */
|
||||
"outDir": "../build/ol", /* Redirect output structure to the directory. */
|
||||
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
||||
// "composite": true, /* Enable project compilation */
|
||||
// "removeComments": true, /* Do not emit comments to output. */
|
||||
// "noEmit": true, /* Do not emit outputs. */
|
||||
"importHelpers": false, /* Import emit helpers from 'tslib'. */
|
||||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
||||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
||||
|
||||
/* Strict Type-Checking Options */
|
||||
"strict": false, /* Enable all strict type-checking options. */
|
||||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* Enable strict null checks. */
|
||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
|
||||
/* Additional Checks */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
||||
|
||||
/* Module Resolution Options */
|
||||
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
||||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
|
||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
||||
// "types": [], /* Type declaration files to be included in compilation. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||
"esModuleInterop": false, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
||||
|
||||
/* Source Map Options */
|
||||
// "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. */
|
||||
|
||||
/* Experimental Options */
|
||||
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
||||
},
|
||||
"include": [
|
||||
"../build/ol/src/**/*.js"
|
||||
],
|
||||
"exclude": []
|
||||
}
|
||||
@@ -111,7 +111,7 @@ Features for `updates` must have an id set by the feature reader or `ol.Feature#
|
||||
|
||||
### 28
|
||||
|
||||
`renderMode` must be `'image'`, `'hybrid'` or `'vector'`.
|
||||
`renderMode` must be `'image'` or `'hybrid'`.
|
||||
|
||||
### 29
|
||||
|
||||
|
||||
29
doc/faq.md
29
doc/faq.md
@@ -21,7 +21,7 @@ Table of contents:
|
||||
* [Why aren't there any features in my source?](#why-aren-t-there-any-features-in-my-source-)
|
||||
* [How do I force a re-render of the map?](#how-do-i-force-a-re-render-of-the-map-)
|
||||
* [Why are my features not found?](#why-are-my-features-not-found-)
|
||||
|
||||
* [Why is zooming or clicking off, inaccurate?](#user-content-why-is-zooming-or-clicking-off-inaccurate)
|
||||
|
||||
## What projection is OpenLayers using?
|
||||
|
||||
@@ -371,3 +371,30 @@ const vectorLayer = new VectorLayer({
|
||||
```
|
||||
|
||||
The recommended value is the size of the largest symbol, line width or label.
|
||||
|
||||
## Why is zooming or clicking in the map off/inaccurate?
|
||||
|
||||
OpenLayers does not update the map when the container element is resized. This can be caused by progressive updates
|
||||
to CSS styles or manually resizing the map. When that happens, any interaction will become inaccurate: the map would zoom in and out, and end up not being centered on the pointer. This makes it hard to do certain interactions, e.g. selecting the desired feature.
|
||||
|
||||
There is currently no built-in way to react to element's size changes, as [Resize Observer API](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver) is only implemented in Chrome.
|
||||
|
||||
There is however an easy to use [polyfill](https://github.com/que-etc/resize-observer-polyfill):
|
||||
|
||||
```javascript
|
||||
import Map from 'ol/Map';
|
||||
import ResizeObserver from 'resize-observer-polyfill';
|
||||
|
||||
const mapElement = document.querySelector('#map')
|
||||
const map = new Map({
|
||||
target: mapElement
|
||||
})
|
||||
|
||||
const sizeObserver = new ResizeObserver(() => {
|
||||
map.updateSize()
|
||||
})
|
||||
sizeObserver.observe(mapElement)
|
||||
|
||||
// called when the map is destroyed
|
||||
// sizeObserver.disconnect()
|
||||
```
|
||||
|
||||
@@ -18,14 +18,14 @@ Below you'll find a complete working example. Create a new file, copy in the co
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link rel="stylesheet" href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/{{ latest }}/css/ol.css" type="text/css">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/{{ latest }}/css/ol.css" type="text/css">
|
||||
<style>
|
||||
.map {
|
||||
height: 400px;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/{{ latest }}/build/ol.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/{{ latest }}/build/ol.js"></script>
|
||||
<title>OpenLayers example</title>
|
||||
</head>
|
||||
<body>
|
||||
@@ -60,7 +60,7 @@ To include a map a web page you will need 3 things:
|
||||
### Include OpenLayers
|
||||
|
||||
```xml
|
||||
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/{{ latest }}/build/ol.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/{{ latest }}/build/ol.js"></script>
|
||||
```
|
||||
|
||||
The first part is to include the JavaScript library. For the purpose of this tutorial, here we simply point to the openlayers.org website to get the whole library. In a production environment, we would build a custom version of the library including only the module needed for our application.
|
||||
|
||||
@@ -17,7 +17,7 @@ OpenLayers is available as [`ol` npm package](https://npmjs.com/package/ol), whi
|
||||
|
||||
## Renderers and Browser Support
|
||||
|
||||
By default, OpenLayers uses a performance optimized Canvas renderer. An experimental WebGL renderer (without text rendering support) is also available.
|
||||
By default, OpenLayers uses a performance optimized Canvas renderer.
|
||||
|
||||
OpenLayers runs on all modern browsers that support [HTML5](https://html.spec.whatwg.org/multipage/) and [ECMAScript 5](http://www.ecma-international.org/ecma-262/5.1/). This includes Chrome, Firefox, Safari and Edge. For older browsers and platforms like Internet Explorer (down to version 9) and Android 4.x, [polyfills](http://polyfill.io), the application bundle needs to be transpiled (e.g. using [Babel](https://babeljs.io)) and bundled with polyfills for `requestAnimationFrame`, `Element.prototype.classList` and `URL`.
|
||||
|
||||
@@ -44,6 +44,6 @@ import {Tile, Vector} from 'ol/layer';
|
||||
In addition to these re-exported classes, modules with lowercase names also provide constants or functions as named exports:
|
||||
|
||||
```js
|
||||
import {inherits} from 'ol';
|
||||
import {getUid} from 'ol';
|
||||
import {fromLonLat} from 'ol/proj';
|
||||
```
|
||||
|
||||
@@ -11,9 +11,11 @@ In this tutorial, we will be using [Parcel](https://parceljs.org) to bundle our
|
||||
|
||||
## Initial steps
|
||||
|
||||
Create a new empty directory for your project and navigate to it by running `mkdir new-project && cd new-project`. Initialize your project using `npm init` and answer the questions asked.
|
||||
Create a new empty directory for your project and navigate to it by running `mkdir new-project && cd new-project`. Initialize your project with
|
||||
|
||||
Add OpenLayers as dependency to your application with
|
||||
npm init
|
||||
|
||||
This will create a `package.json` file in your working directory. Add OpenLayers as dependency to your application with
|
||||
|
||||
npm install ol
|
||||
|
||||
@@ -69,13 +71,21 @@ You will also need an `index.html` file that will use your bundle. Here is a sim
|
||||
|
||||
## Creating a bundle
|
||||
|
||||
With simple scripts you can introduce the commands `npm run build` and `npm start` to manually build your bundle and watch for changes, respectively. Add the following to the script section in `package.json`:
|
||||
With two additional lines in `package.json` you can introduce the commands `npm run build` and `npm start` to manually build your bundle and watch for changes, respectively. The final `package.json` with the two additional commands `"start"` and `"build"` should look like this:
|
||||
|
||||
```json
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "parcel index.html",
|
||||
"build": "parcel build --public-url . index.html"
|
||||
{
|
||||
"name": "test",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "parcel index.html",
|
||||
"build": "parcel build --public-url . index.html"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
||||
```
|
||||
That's it. Now to run your application, enter
|
||||
|
||||
@@ -5,10 +5,12 @@
|
||||
"common": false,
|
||||
"createMapboxStreetsV6Style": false,
|
||||
"d3": false,
|
||||
"domtoimage": false,
|
||||
"geojsonvt": false,
|
||||
"GyroNorm": false,
|
||||
"jsPDF": false,
|
||||
"jsts": false,
|
||||
"mapboxgl": false,
|
||||
"saveAs": false,
|
||||
"toastr": false,
|
||||
"topojson": false,
|
||||
|
||||
@@ -24,9 +24,6 @@ const map = new Map({
|
||||
source: new OSM()
|
||||
})
|
||||
],
|
||||
// Improve user experience by loading tiles while animating. Will make
|
||||
// animations stutter on mobile or slow devices.
|
||||
loadTilesWhileAnimating: true,
|
||||
view: view
|
||||
});
|
||||
|
||||
|
||||
@@ -12,9 +12,8 @@ cloak:
|
||||
<div id="map" class="map"></div>
|
||||
<select id="layer-select">
|
||||
<option value="Aerial">Aerial</option>
|
||||
<option value="AerialWithLabels" selected>Aerial with labels</option>
|
||||
<option value="Road">Road (static)</option>
|
||||
<option value="RoadOnDemand">Road (dynamic)</option>
|
||||
<option value="collinsBart">Collins Bart</option>
|
||||
<option value="ordnanceSurvey">Ordnance Survey</option>
|
||||
<option value="AerialWithLabelsOnDemand" selected>Aerial with labels</option>
|
||||
<option value="RoadOnDemand">Road</option>
|
||||
<option value="CanvasDark">Road dark</option>
|
||||
<option value="OrdnanceSurvey">Ordnance Survey</option>
|
||||
</select>
|
||||
|
||||
@@ -5,12 +5,11 @@ import BingMaps from '../src/ol/source/BingMaps.js';
|
||||
|
||||
|
||||
const styles = [
|
||||
'Road',
|
||||
'RoadOnDemand',
|
||||
'Aerial',
|
||||
'AerialWithLabels',
|
||||
'collinsBart',
|
||||
'ordnanceSurvey'
|
||||
'AerialWithLabelsOnDemand',
|
||||
'CanvasDark',
|
||||
'OrdnanceSurvey'
|
||||
];
|
||||
const layers = [];
|
||||
let i, ii;
|
||||
@@ -29,9 +28,6 @@ for (i = 0, ii = styles.length; i < ii; ++i) {
|
||||
}
|
||||
const map = new Map({
|
||||
layers: layers,
|
||||
// Improve user experience by loading tiles while dragging/zooming. Will make
|
||||
// zooming choppy on mobile or slow devices.
|
||||
loadTilesWhileInteracting: true,
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [-6655.5402445057125, 6709968.258934638],
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
.map{
|
||||
background-repeat: repeat;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAApSURBVBiVY7x///5/BjSgqKjIiC7GhC6ACwygQgxHMzAwMGDz4FDwDAD5/wevjSk4mwAAAABJRU5ErkJggg==);
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Blend Modes
|
||||
shortdesc: Shows how to change the canvas compositing / blending mode in post- and precompose eventhandlers.
|
||||
docs: >
|
||||
<p>This example shows how to change the canvas compositing / blending mode in
|
||||
post- and precompose event handlers. The Canvas 2D API provides the property
|
||||
<code>globalCompositeOperation</code> with which one can influence which
|
||||
composition operation will be used when drawing on the canvas. The various
|
||||
options are well described on the <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation">MDN
|
||||
documentation page</a>.</p>
|
||||
|
||||
<p>In this example three circles on the corners of an equilateral triangle are
|
||||
drawn with red, green or blue styles respectively. By setting the
|
||||
<code>globalCompositeOperation</code> you can change how these colors turn out
|
||||
when they are combined on the map.</p>
|
||||
|
||||
<p>You can select an operation in the select-field and you can also control
|
||||
which layers will be affected by the chosen operation through the layer
|
||||
checkboxes.</p>
|
||||
tags: "blendmode, blend-mode, blend mode, blendingmode, blending-mode, blending mode, composition, compositing, canvas, vector"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
<form class="form-horizontal">
|
||||
<label>
|
||||
<select id="blend-mode" class="form-control">
|
||||
<option value="source-over">source-over (default)</option>
|
||||
<option>source-in</option>
|
||||
<option>source-out</option>
|
||||
<option>source-atop</option>
|
||||
<option>destination-over</option>
|
||||
<option>destination-in</option>
|
||||
<option>destination-out</option>
|
||||
<option>destination-atop</option>
|
||||
<option>lighter</option>
|
||||
<option>copy</option>
|
||||
<option>xor</option>
|
||||
<option>multiply</option>
|
||||
<option>screen</option>
|
||||
<option>overlay</option>
|
||||
<option>darken</option>
|
||||
<option>lighten</option>
|
||||
<option>color-dodge</option>
|
||||
<option>color-burn</option>
|
||||
<option>hard-light</option>
|
||||
<option>soft-light</option>
|
||||
<option selected>difference</option>
|
||||
<option>exclusion</option>
|
||||
<option>hue</option>
|
||||
<option>saturation</option>
|
||||
<option>color</option>
|
||||
<option>luminosity</option>
|
||||
</select>
|
||||
Canvas compositing / blending mode
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" id="affect-red" checked>
|
||||
Red circle affected
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" id="affect-green" checked>
|
||||
Green circle affected
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" id="affect-blue" checked>
|
||||
Blue circle affected
|
||||
</label>
|
||||
</form>
|
||||
@@ -1,173 +0,0 @@
|
||||
import Feature from '../src/ol/Feature.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import Point from '../src/ol/geom/Point.js';
|
||||
import VectorLayer from '../src/ol/layer/Vector.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
import {Circle as CircleStyle, Fill, Stroke, Style} from '../src/ol/style.js';
|
||||
|
||||
|
||||
// Create separate layers for red, green an blue circles.
|
||||
//
|
||||
// Every layer has one feature that is styled with a circle, together the
|
||||
// features form the corners of an equilateral triangle and their styles overlap
|
||||
const redLayer = new VectorLayer({
|
||||
source: new VectorSource({
|
||||
features: [new Feature(new Point([0, 0]))]
|
||||
}),
|
||||
style: new Style({
|
||||
image: new CircleStyle({
|
||||
fill: new Fill({
|
||||
color: 'rgba(255,0,0,0.8)'
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
color: 'rgb(255,0,0)',
|
||||
width: 15
|
||||
}),
|
||||
radius: 120
|
||||
})
|
||||
})
|
||||
});
|
||||
const greenLayer = new VectorLayer({
|
||||
source: new VectorSource({
|
||||
// 433.013 is roughly 250 * Math.sqrt(3)
|
||||
features: [new Feature(new Point([250, 433.013]))]
|
||||
}),
|
||||
style: new Style({
|
||||
image: new CircleStyle({
|
||||
fill: new Fill({
|
||||
color: 'rgba(0,255,0,0.8)'
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
color: 'rgb(0,255,0)',
|
||||
width: 15
|
||||
}),
|
||||
radius: 120
|
||||
})
|
||||
})
|
||||
});
|
||||
const blueLayer = new VectorLayer({
|
||||
source: new VectorSource({
|
||||
features: [new Feature(new Point([500, 0]))]
|
||||
}),
|
||||
style: new Style({
|
||||
image: new CircleStyle({
|
||||
fill: new Fill({
|
||||
color: 'rgba(0,0,255,0.8)'
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
color: 'rgb(0,0,255)',
|
||||
width: 15
|
||||
}),
|
||||
radius: 120
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
// Create the map, the view is centered on the triangle. Zooming and panning is
|
||||
// restricted to a sane area
|
||||
const map = new Map({
|
||||
layers: [
|
||||
redLayer,
|
||||
greenLayer,
|
||||
blueLayer
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [250, 220],
|
||||
extent: [0, 0, 500, 500],
|
||||
resolution: 4,
|
||||
minResolution: 2,
|
||||
maxResolution: 32
|
||||
})
|
||||
});
|
||||
|
||||
// Get the form elements and bind the listeners
|
||||
const select = document.getElementById('blend-mode');
|
||||
const affectRed = document.getElementById('affect-red');
|
||||
const affectGreen = document.getElementById('affect-green');
|
||||
const affectBlue = document.getElementById('affect-blue');
|
||||
|
||||
|
||||
/**
|
||||
* This method sets the globalCompositeOperation to the value of the select
|
||||
* field and it is bound to the precompose event of the layers.
|
||||
*
|
||||
* @param {module:ol/render/Event~RenderEvent} evt The render event.
|
||||
*/
|
||||
const setBlendModeFromSelect = function(evt) {
|
||||
evt.context.globalCompositeOperation = select.value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This method resets the globalCompositeOperation to the default value of
|
||||
* 'source-over' and it is bound to the postcompose event of the layers.
|
||||
*
|
||||
* @param {module:ol/render/Event~RenderEvent} evt The render event.
|
||||
*/
|
||||
const resetBlendModeFromSelect = function(evt) {
|
||||
evt.context.globalCompositeOperation = 'source-over';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Bind the pre- and postcompose handlers to the passed layer.
|
||||
*
|
||||
* @param {module:ol/layer/Vector} layer The layer to bind the handlers to.
|
||||
*/
|
||||
const bindLayerListeners = function(layer) {
|
||||
layer.on('precompose', setBlendModeFromSelect);
|
||||
layer.on('postcompose', resetBlendModeFromSelect);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Unind the pre- and postcompose handlers to the passed layers.
|
||||
*
|
||||
* @param {module:ol/layer/Vector} layer The layer to unbind the handlers from.
|
||||
*/
|
||||
const unbindLayerListeners = function(layer) {
|
||||
layer.un('precompose', setBlendModeFromSelect);
|
||||
layer.un('postcompose', resetBlendModeFromSelect);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handler for the click event of the 'affect-XXX' checkboxes.
|
||||
*
|
||||
* @this {HTMLInputElement}
|
||||
*/
|
||||
const affectLayerClicked = function() {
|
||||
let layer;
|
||||
if (this.id == 'affect-red') {
|
||||
layer = redLayer;
|
||||
} else if (this.id == 'affect-green') {
|
||||
layer = greenLayer;
|
||||
} else {
|
||||
layer = blueLayer;
|
||||
}
|
||||
if (this.checked) {
|
||||
bindLayerListeners(layer);
|
||||
} else {
|
||||
unbindLayerListeners(layer);
|
||||
}
|
||||
map.render();
|
||||
};
|
||||
|
||||
|
||||
// Rerender map when blend mode changes
|
||||
select.addEventListener('change', function() {
|
||||
map.render();
|
||||
});
|
||||
|
||||
// Unbind / bind listeners depending on the checked state when the checkboxes
|
||||
// are clicked
|
||||
affectRed.addEventListener('click', affectLayerClicked);
|
||||
affectGreen.addEventListener('click', affectLayerClicked);
|
||||
affectBlue.addEventListener('click', affectLayerClicked);
|
||||
|
||||
// Initially bind listeners
|
||||
bindLayerListeners(redLayer);
|
||||
bindLayerListeners(greenLayer);
|
||||
bindLayerListeners(blueLayer);
|
||||
@@ -61,8 +61,8 @@ const style = new Style({
|
||||
* The styling function for the vector layer, will return an array of styles
|
||||
* which either contains the aboove gradient or pattern.
|
||||
*
|
||||
* @param {module:ol/Feature~Feature} feature The feature to style.
|
||||
* @return {module:ol/style/Style} The style to use for the feature.
|
||||
* @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();
|
||||
|
||||
@@ -4,10 +4,7 @@ title: Canvas Tiles
|
||||
shortdesc: Renders tiles with coordinates for debugging.
|
||||
docs: >
|
||||
The black grid tiles are generated on the client with an HTML5 canvas. The
|
||||
displayed tile coordinates are OpenLayers tile coordinates. These increase
|
||||
from bottom to top, but standard XYZ tiling scheme coordinates increase from
|
||||
top to bottom. To calculate the `y` for a standard XYZ tile coordinate, use
|
||||
`-y - 1`.
|
||||
displayed tile coordinates are the XYZ tile coordinates.
|
||||
tags: "layers, openstreetmap, canvas"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
|
||||
@@ -1,26 +1,21 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import {fromLonLat} from '../src/ol/proj.js';
|
||||
import {OSM, TileDebug} from '../src/ol/source.js';
|
||||
|
||||
|
||||
const osmSource = new OSM();
|
||||
const map = new Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: osmSource
|
||||
source: new OSM()
|
||||
}),
|
||||
new TileLayer({
|
||||
source: new TileDebug({
|
||||
projection: 'EPSG:3857',
|
||||
tileGrid: osmSource.getTileGrid()
|
||||
})
|
||||
source: new TileDebug()
|
||||
})
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: fromLonLat([-0.1275, 51.507222]),
|
||||
zoom: 10
|
||||
center: [0, 0],
|
||||
zoom: 1
|
||||
})
|
||||
});
|
||||
|
||||
@@ -50,7 +50,7 @@ const map = new Map({
|
||||
const zoomtoswitzerlandbest = document.getElementById('zoomtoswitzerlandbest');
|
||||
zoomtoswitzerlandbest.addEventListener('click', function() {
|
||||
const feature = source.getFeatures()[0];
|
||||
const polygon = /** @type {module:ol/geom/SimpleGeometry~SimpleGeometry} */ (feature.getGeometry());
|
||||
const polygon = /** @type {import("../src/ol/geom/SimpleGeometry.js").default} */ (feature.getGeometry());
|
||||
view.fit(polygon, {padding: [170, 50, 30, 150], constrainResolution: false});
|
||||
}, false);
|
||||
|
||||
@@ -58,7 +58,7 @@ const zoomtoswitzerlandconstrained =
|
||||
document.getElementById('zoomtoswitzerlandconstrained');
|
||||
zoomtoswitzerlandconstrained.addEventListener('click', function() {
|
||||
const feature = source.getFeatures()[0];
|
||||
const polygon = /** @type {module:ol/geom/SimpleGeometry~SimpleGeometry} */ (feature.getGeometry());
|
||||
const polygon = /** @type {import("../src/ol/geom/SimpleGeometry.js").default} */ (feature.getGeometry());
|
||||
view.fit(polygon, {padding: [170, 50, 30, 150]});
|
||||
}, false);
|
||||
|
||||
@@ -66,21 +66,21 @@ const zoomtoswitzerlandnearest =
|
||||
document.getElementById('zoomtoswitzerlandnearest');
|
||||
zoomtoswitzerlandnearest.addEventListener('click', function() {
|
||||
const feature = source.getFeatures()[0];
|
||||
const polygon = /** @type {module:ol/geom/SimpleGeometry~SimpleGeometry} */ (feature.getGeometry());
|
||||
const polygon = /** @type {import("../src/ol/geom/SimpleGeometry.js").default} */ (feature.getGeometry());
|
||||
view.fit(polygon, {padding: [170, 50, 30, 150], nearest: true});
|
||||
}, false);
|
||||
|
||||
const zoomtolausanne = document.getElementById('zoomtolausanne');
|
||||
zoomtolausanne.addEventListener('click', function() {
|
||||
const feature = source.getFeatures()[1];
|
||||
const point = /** @type {module:ol/geom/SimpleGeometry~SimpleGeometry} */ (feature.getGeometry());
|
||||
const point = /** @type {import("../src/ol/geom/SimpleGeometry.js").default} */ (feature.getGeometry());
|
||||
view.fit(point, {padding: [170, 50, 30, 150], minResolution: 50});
|
||||
}, false);
|
||||
|
||||
const centerlausanne = document.getElementById('centerlausanne');
|
||||
centerlausanne.addEventListener('click', function() {
|
||||
const feature = source.getFeatures()[1];
|
||||
const point = /** @type {module:ol/geom/Point~Point} */ (feature.getGeometry());
|
||||
const size = /** @type {module:ol/size~Size} */ (map.getSize());
|
||||
const point = /** @type {import("../src/ol/geom/Point.js").default} */ (feature.getGeometry());
|
||||
const size = map.getSize();
|
||||
view.centerOn(point.getCoordinates(), size, [570, 500]);
|
||||
}, false);
|
||||
|
||||
@@ -9,14 +9,11 @@ import OSM from '../src/ol/source/OSM.js';
|
||||
// Define rotate to north control.
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {module:ol/control/Control~Control}
|
||||
* @param {Object=} opt_options Control options.
|
||||
*/
|
||||
class RotateNorthControl extends Control {
|
||||
|
||||
/**
|
||||
* @param {Object=} opt_options Control options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
const options = opt_options || {};
|
||||
|
||||
|
||||
@@ -8,10 +8,6 @@ import {TileJSON, Vector as VectorSource} from '../src/ol/source.js';
|
||||
import {Fill, Icon, Stroke, Style} from '../src/ol/style.js';
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @extends {module:ol/interaction/Pointer}
|
||||
*/
|
||||
class Drag extends PointerInteraction {
|
||||
constructor() {
|
||||
super({
|
||||
@@ -22,7 +18,7 @@ class Drag extends PointerInteraction {
|
||||
});
|
||||
|
||||
/**
|
||||
* @type {module:ol/pixel~Pixel}
|
||||
* @type {import("../src/ol/coordinate.js").Coordinate}
|
||||
* @private
|
||||
*/
|
||||
this.coordinate_ = null;
|
||||
@@ -34,7 +30,7 @@ class Drag extends PointerInteraction {
|
||||
this.cursor_ = 'pointer';
|
||||
|
||||
/**
|
||||
* @type {module:ol/Feature~Feature}
|
||||
* @type {Feature}
|
||||
* @private
|
||||
*/
|
||||
this.feature_ = null;
|
||||
@@ -49,7 +45,7 @@ class Drag extends PointerInteraction {
|
||||
|
||||
|
||||
/**
|
||||
* @param {module:ol/MapBrowserEvent~MapBrowserEvent} evt Map browser event.
|
||||
* @param {import("../src/ol/MapBrowserEvent.js").default} evt Map browser event.
|
||||
* @return {boolean} `true` to start the drag sequence.
|
||||
*/
|
||||
function handleDownEvent(evt) {
|
||||
@@ -70,7 +66,7 @@ function handleDownEvent(evt) {
|
||||
|
||||
|
||||
/**
|
||||
* @param {module:ol/MapBrowserEvent~MapBrowserEvent} evt Map browser event.
|
||||
* @param {import("../src/ol/MapBrowserEvent.js").default} evt Map browser event.
|
||||
*/
|
||||
function handleDragEvent(evt) {
|
||||
const deltaX = evt.coordinate[0] - this.coordinate_[0];
|
||||
@@ -85,7 +81,7 @@ function handleDragEvent(evt) {
|
||||
|
||||
|
||||
/**
|
||||
* @param {module:ol/MapBrowserEvent~MapBrowserEvent} evt Event.
|
||||
* @param {import("../src/ol/MapBrowserEvent.js").default} evt Event.
|
||||
*/
|
||||
function handleMoveEvent(evt) {
|
||||
if (this.cursor_) {
|
||||
@@ -141,13 +137,13 @@ const map = new Map({
|
||||
features: [pointFeature, lineFeature, polygonFeature]
|
||||
}),
|
||||
style: new Style({
|
||||
image: new Icon(/** @type {module:ol/style/Icon~Options} */ ({
|
||||
image: new Icon({
|
||||
anchor: [0.5, 46],
|
||||
anchorXUnits: 'fraction',
|
||||
anchorYUnits: 'pixels',
|
||||
opacity: 0.95,
|
||||
src: 'data/icon.png'
|
||||
})),
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
width: 3,
|
||||
color: [255, 0, 0, 1]
|
||||
|
||||
4
examples/d3.css
Normal file
4
examples/d3.css
Normal file
@@ -0,0 +1,4 @@
|
||||
path.boundary {
|
||||
fill: none;
|
||||
stroke: #777;
|
||||
}
|
||||
@@ -3,7 +3,7 @@ layout: example.html
|
||||
title: d3 Integration
|
||||
shortdesc: Example of using OpenLayers and d3 together.
|
||||
docs: >
|
||||
<p>The example loads TopoJSON geometries and uses d3 (<code>d3.geo.path</code>) to render these geometries to a canvas element that is then used as the image of an OpenLayers image layer.</p>
|
||||
The example loads TopoJSON geometries and uses d3 (<code>d3.geo.path</code>) to render these geometries to a SVG element.
|
||||
tags: "d3"
|
||||
resources:
|
||||
- https://unpkg.com/d3@4.12.0/build/d3.js
|
||||
|
||||
122
examples/d3.js
vendored
122
examples/d3.js
vendored
@@ -1,10 +1,70 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {getWidth, getCenter} from '../src/ol/extent.js';
|
||||
import {Image as ImageLayer, Tile as TileLayer} from '../src/ol/layer.js';
|
||||
import {Layer, Tile as TileLayer} from '../src/ol/layer.js';
|
||||
import SourceState from '../src/ol/source/State';
|
||||
import {fromLonLat, toLonLat} from '../src/ol/proj.js';
|
||||
import {ImageCanvas as ImageCanvasSource, Stamen} from '../src/ol/source.js';
|
||||
import Stamen from '../src/ol/source/Stamen.js';
|
||||
|
||||
class CanvasLayer extends Layer {
|
||||
|
||||
constructor(options) {
|
||||
super(options);
|
||||
|
||||
this.features = options.features;
|
||||
|
||||
this.svg = d3.select(document.createElement('div')).append('svg')
|
||||
.style('position', 'absolute');
|
||||
|
||||
this.svg.append('path')
|
||||
.datum(this.features)
|
||||
.attr('class', 'boundary');
|
||||
}
|
||||
|
||||
getSourceState() {
|
||||
return SourceState.READY;
|
||||
}
|
||||
|
||||
render(frameState) {
|
||||
const width = frameState.size[0];
|
||||
const height = frameState.size[1];
|
||||
const projection = frameState.viewState.projection;
|
||||
const d3Projection = d3.geoMercator().scale(1).translate([0, 0]);
|
||||
let d3Path = d3.geoPath().projection(d3Projection);
|
||||
|
||||
const pixelBounds = d3Path.bounds(this.features);
|
||||
const pixelBoundsWidth = pixelBounds[1][0] - pixelBounds[0][0];
|
||||
const pixelBoundsHeight = pixelBounds[1][1] - pixelBounds[0][1];
|
||||
|
||||
const geoBounds = d3.geoBounds(this.features);
|
||||
const geoBoundsLeftBottom = fromLonLat(geoBounds[0], projection);
|
||||
const geoBoundsRightTop = fromLonLat(geoBounds[1], projection);
|
||||
let geoBoundsWidth = geoBoundsRightTop[0] - geoBoundsLeftBottom[0];
|
||||
if (geoBoundsWidth < 0) {
|
||||
geoBoundsWidth += getWidth(projection.getExtent());
|
||||
}
|
||||
const geoBoundsHeight = geoBoundsRightTop[1] - geoBoundsLeftBottom[1];
|
||||
|
||||
const widthResolution = geoBoundsWidth / pixelBoundsWidth;
|
||||
const heightResolution = geoBoundsHeight / pixelBoundsHeight;
|
||||
const r = Math.max(widthResolution, heightResolution);
|
||||
const scale = r / frameState.viewState.resolution;
|
||||
|
||||
const center = toLonLat(getCenter(frameState.extent), projection);
|
||||
d3Projection.scale(scale).center(center).translate([width / 2, height / 2]);
|
||||
|
||||
d3Path = d3Path.projection(d3Projection);
|
||||
d3Path(this.features);
|
||||
|
||||
this.svg.attr('width', width);
|
||||
this.svg.attr('height', height);
|
||||
|
||||
this.svg.select('path')
|
||||
.attr('d', d3Path);
|
||||
|
||||
return this.svg.node();
|
||||
}
|
||||
}
|
||||
|
||||
const map = new Map({
|
||||
layers: [
|
||||
@@ -26,62 +86,10 @@ const map = new Map({
|
||||
* Load the topojson data and create an ol/layer/Image for that data.
|
||||
*/
|
||||
d3.json('data/topojson/us.json', function(error, us) {
|
||||
const features = topojson.feature(us, us.objects.counties);
|
||||
|
||||
/**
|
||||
* This function uses d3 to render the topojson features to a canvas.
|
||||
* @param {module:ol/extent~Extent} extent Extent.
|
||||
* @param {number} resolution Resolution.
|
||||
* @param {number} pixelRatio Pixel ratio.
|
||||
* @param {module:ol/size~Size} size Size.
|
||||
* @param {module:ol/proj/Projection~Projection} projection Projection.
|
||||
* @return {HTMLCanvasElement} A canvas element.
|
||||
*/
|
||||
const canvasFunction = function(extent, resolution, pixelRatio, size, projection) {
|
||||
const canvasWidth = size[0];
|
||||
const canvasHeight = size[1];
|
||||
|
||||
const canvas = d3.select(document.createElement('canvas'));
|
||||
canvas.attr('width', canvasWidth).attr('height', canvasHeight);
|
||||
|
||||
const context = canvas.node().getContext('2d');
|
||||
|
||||
const d3Projection = d3.geoMercator().scale(1).translate([0, 0]);
|
||||
let d3Path = d3.geoPath().projection(d3Projection);
|
||||
|
||||
const pixelBounds = d3Path.bounds(features);
|
||||
const pixelBoundsWidth = pixelBounds[1][0] - pixelBounds[0][0];
|
||||
const pixelBoundsHeight = pixelBounds[1][1] - pixelBounds[0][1];
|
||||
|
||||
const geoBounds = d3.geoBounds(features);
|
||||
const geoBoundsLeftBottom = fromLonLat(geoBounds[0], projection);
|
||||
const geoBoundsRightTop = fromLonLat(geoBounds[1], projection);
|
||||
let geoBoundsWidth = geoBoundsRightTop[0] - geoBoundsLeftBottom[0];
|
||||
if (geoBoundsWidth < 0) {
|
||||
geoBoundsWidth += getWidth(projection.getExtent());
|
||||
}
|
||||
const geoBoundsHeight = geoBoundsRightTop[1] - geoBoundsLeftBottom[1];
|
||||
|
||||
const widthResolution = geoBoundsWidth / pixelBoundsWidth;
|
||||
const heightResolution = geoBoundsHeight / pixelBoundsHeight;
|
||||
const r = Math.max(widthResolution, heightResolution);
|
||||
const scale = r / (resolution / pixelRatio);
|
||||
|
||||
const center = toLonLat(getCenter(extent), projection);
|
||||
d3Projection.scale(scale).center(center)
|
||||
.translate([canvasWidth / 2, canvasHeight / 2]);
|
||||
d3Path = d3Path.projection(d3Projection).context(context);
|
||||
d3Path(features);
|
||||
context.stroke();
|
||||
|
||||
return canvas.node();
|
||||
};
|
||||
|
||||
const layer = new ImageLayer({
|
||||
source: new ImageCanvasSource({
|
||||
canvasFunction: canvasFunction,
|
||||
projection: 'EPSG:3857'
|
||||
})
|
||||
const layer = new CanvasLayer({
|
||||
features: topojson.feature(us, us.objects.counties)
|
||||
});
|
||||
|
||||
map.addLayer(layer);
|
||||
});
|
||||
|
||||
80333
examples/data/csv/ufo_sighting_data.csv
Normal file
80333
examples/data/csv/ufo_sighting_data.csv
Normal file
File diff suppressed because it is too large
Load Diff
BIN
examples/data/ufo_shapes.png
Normal file
BIN
examples/data/ufo_shapes.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.8 KiB |
@@ -29,7 +29,7 @@ gn.init().then(function() {
|
||||
gn.start(function(event) {
|
||||
const center = view.getCenter();
|
||||
const resolution = view.getResolution();
|
||||
const alpha = toRadians(event.do.beta);
|
||||
const alpha = toRadians(event.do.alpha);
|
||||
const beta = toRadians(event.do.beta);
|
||||
const gamma = toRadians(event.do.gamma);
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ layout: example.html
|
||||
title: Drag-and-Drop Image Vector
|
||||
shortdesc: Example of using the drag-and-drop interaction with image vector rendering.
|
||||
docs: >
|
||||
Example of using the drag-and-drop interaction with an `ol/layer/Vector` with `renderMode: 'image'`. Drag and drop GPX, GeoJSON, IGC, KML, or TopoJSON files on to the map. Each file is rendered to an image on the client.
|
||||
Example of using the drag-and-drop interaction with an `ol/layer/VectorImage` layer. Drag and drop GPX, GeoJSON, IGC, KML, or TopoJSON files on to the map. Each file is rendered to an image on the client.
|
||||
tags: "drag-and-drop-image-vector, gpx, geojson, igc, kml, topojson, vector, image"
|
||||
cloak:
|
||||
- key: As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5
|
||||
|
||||
@@ -2,7 +2,7 @@ import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {GPX, GeoJSON, IGC, KML, TopoJSON} from '../src/ol/format.js';
|
||||
import {defaults as defaultInteractions, DragAndDrop} from '../src/ol/interaction.js';
|
||||
import {Vector as VectorLayer, Tile as TileLayer} from '../src/ol/layer.js';
|
||||
import {VectorImage as VectorImageLayer, Tile as TileLayer} from '../src/ol/layer.js';
|
||||
import {BingMaps, Vector as VectorSource} from '../src/ol/source.js';
|
||||
|
||||
const dragAndDropInteraction = new DragAndDrop({
|
||||
@@ -36,8 +36,7 @@ dragAndDropInteraction.on('addfeatures', function(event) {
|
||||
const vectorSource = new VectorSource({
|
||||
features: event.features
|
||||
});
|
||||
map.addLayer(new VectorLayer({
|
||||
renderMode: 'image',
|
||||
map.addLayer(new VectorImageLayer({
|
||||
source: vectorSource
|
||||
}));
|
||||
map.getView().fit(vectorSource.getExtent());
|
||||
|
||||
@@ -4,14 +4,14 @@ import {MultiPoint, Point} from '../src/ol/geom.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
import {Circle as CircleStyle, Fill, Stroke, Style} from '../src/ol/style.js';
|
||||
import {getVectorContext} from '../src/ol/render.js';
|
||||
|
||||
const tileLayer = new TileLayer({
|
||||
source: new OSM()
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM()
|
||||
})
|
||||
],
|
||||
layers: [tileLayer],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
@@ -46,8 +46,8 @@ const omegaTheta = 30000; // Rotation period in ms
|
||||
const R = 7e6;
|
||||
const r = 2e6;
|
||||
const p = 2e6;
|
||||
map.on('postcompose', function(event) {
|
||||
const vectorContext = event.vectorContext;
|
||||
tileLayer.on('postrender', function(event) {
|
||||
const vectorContext = getVectorContext(event);
|
||||
const frameState = event.frameState;
|
||||
const theta = 2 * Math.PI * frameState.time / omegaTheta;
|
||||
const coordinates = [];
|
||||
|
||||
@@ -26,9 +26,8 @@ const styleFunction = function(feature) {
|
||||
scale = size / 10;
|
||||
let style = styleCache[size];
|
||||
if (!style) {
|
||||
const canvas = /** @type {HTMLCanvasElement} */ (document.createElement('canvas'));
|
||||
const vectorContext = toContext(
|
||||
/** @type {CanvasRenderingContext2D} */ (canvas.getContext('2d')),
|
||||
const canvas = document.createElement('canvas');
|
||||
const vectorContext = toContext(canvas.getContext('2d'),
|
||||
{size: [size, size], pixelRatio: 1});
|
||||
vectorContext.setStyle(new Style({
|
||||
fill: new Fill({color: 'rgba(255, 153, 0, 0.4)'}),
|
||||
|
||||
@@ -3,12 +3,12 @@ layout: example.html
|
||||
title: Map Export
|
||||
shortdesc: Example of exporting a map as a PNG image.
|
||||
docs: >
|
||||
Example of exporting a map as a PNG image. This example requires a browser
|
||||
that supports <a href="https://developer.mozilla.org/de/docs/Web/API/HTMLCanvasElement/toBlob#Browser_compatibility">
|
||||
<code>canvas.toBlob()</code></a>.
|
||||
Example of exporting a map as a PNG image. This example use the <a href="https://www.npmjs.com/package/dom-to-image-more">dom-to-image-more</a>
|
||||
library.
|
||||
tags: "export, png, openstreetmap"
|
||||
resources:
|
||||
- https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js
|
||||
- https://unpkg.com/dom-to-image-more@2.7.1/dist/dom-to-image-more.min.js
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
<a id="export-png" class="btn btn-default"><i class="fa fa-download"></i> Download PNG</a>
|
||||
<a id="image-download" download="map.png"></a>
|
||||
|
||||
@@ -24,15 +24,13 @@ const map = new Map({
|
||||
});
|
||||
|
||||
document.getElementById('export-png').addEventListener('click', function() {
|
||||
map.once('rendercomplete', function(event) {
|
||||
const canvas = event.context.canvas;
|
||||
if (navigator.msSaveBlob) {
|
||||
navigator.msSaveBlob(canvas.msToBlob(), 'map.png');
|
||||
} else {
|
||||
canvas.toBlob(function(blob) {
|
||||
saveAs(blob, 'map.png');
|
||||
map.once('rendercomplete', function() {
|
||||
domtoimage.toPng(map.getViewport().querySelector('.ol-layers'))
|
||||
.then(function(dataURL) {
|
||||
const link = document.getElementById('image-download');
|
||||
link.href = dataURL;
|
||||
link.click();
|
||||
});
|
||||
}
|
||||
});
|
||||
map.renderSync();
|
||||
});
|
||||
|
||||
@@ -7,6 +7,7 @@ docs: >
|
||||
tags: "export, pdf, openstreetmap"
|
||||
resources:
|
||||
- https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.2.61/jspdf.min.js
|
||||
- https://unpkg.com/dom-to-image-more@2.7.1/dist/dom-to-image-more.min.js
|
||||
---
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
|
||||
@@ -53,20 +53,23 @@ exportButton.addEventListener('click', function() {
|
||||
const dim = dims[format];
|
||||
const width = Math.round(dim[0] * resolution / 25.4);
|
||||
const height = Math.round(dim[1] * resolution / 25.4);
|
||||
const size = /** @type {module:ol/size~Size} */ (map.getSize());
|
||||
const size = map.getSize();
|
||||
const extent = map.getView().calculateExtent(size);
|
||||
|
||||
map.once('rendercomplete', function(event) {
|
||||
const canvas = event.context.canvas;
|
||||
const data = canvas.toDataURL('image/jpeg');
|
||||
const pdf = new jsPDF('landscape', undefined, format);
|
||||
pdf.addImage(data, 'JPEG', 0, 0, dim[0], dim[1]);
|
||||
pdf.save('map.pdf');
|
||||
// Reset original map size
|
||||
map.setSize(size);
|
||||
map.getView().fit(extent, {size});
|
||||
exportButton.disabled = false;
|
||||
document.body.style.cursor = 'auto';
|
||||
map.once('rendercomplete', function() {
|
||||
domtoimage.toJpeg(map.getViewport().querySelector('.ol-layers')).then(function(dataUrl) {
|
||||
const pdf = new jsPDF('landscape', undefined, format);
|
||||
pdf.addImage(dataUrl, 'JPEG', 0, 0, dim[0], dim[1]);
|
||||
pdf.save('map.pdf');
|
||||
// Reset original map size
|
||||
map.setSize(size);
|
||||
map.getView().fit(extent, {
|
||||
size: size,
|
||||
constrainResolution: false
|
||||
});
|
||||
exportButton.disabled = false;
|
||||
document.body.style.cursor = 'auto';
|
||||
});
|
||||
});
|
||||
|
||||
// Set print size
|
||||
|
||||
@@ -3,7 +3,7 @@ layout: example.html
|
||||
title: Custom Animation
|
||||
shortdesc: Demonstrates how to animate features.
|
||||
docs: >
|
||||
This example shows how to use <b>postcompose</b> and <b>vectorContext</b> to
|
||||
This example shows how to use <b>postrender</b> and <b>vectorContext</b> to
|
||||
animate features. Here we choose to do a flash animation each time a feature
|
||||
is added to the layer.
|
||||
tags: "animation, vector, feature, flash"
|
||||
|
||||
@@ -8,16 +8,16 @@ import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import {fromLonLat} from '../src/ol/proj.js';
|
||||
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
|
||||
import {Circle as CircleStyle, Stroke, Style} from '../src/ol/style.js';
|
||||
import {getVectorContext} from '../src/ol/render.js';
|
||||
|
||||
const tileLayer = new TileLayer({
|
||||
source: new OSM({
|
||||
wrapX: false
|
||||
})
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM({
|
||||
wrapX: false
|
||||
})
|
||||
})
|
||||
],
|
||||
layers: [tileLayer],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
@@ -44,10 +44,10 @@ function addRandomFeature() {
|
||||
const duration = 3000;
|
||||
function flash(feature) {
|
||||
const start = new Date().getTime();
|
||||
const listenerKey = map.on('postcompose', animate);
|
||||
const listenerKey = tileLayer.on('postrender', animate);
|
||||
|
||||
function animate(event) {
|
||||
const vectorContext = event.vectorContext;
|
||||
const vectorContext = getVectorContext(event);
|
||||
const frameState = event.frameState;
|
||||
const flashGeom = feature.getGeometry().clone();
|
||||
const elapsed = frameState.time - start;
|
||||
@@ -72,7 +72,7 @@ function flash(feature) {
|
||||
unByKey(listenerKey);
|
||||
return;
|
||||
}
|
||||
// tell OpenLayers to continue postcompose animation
|
||||
// tell OpenLayers to continue postrender animation
|
||||
map.render();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@ layout: example.html
|
||||
title: Marker Animation
|
||||
shortdesc: Demonstrates how to move a feature along a line.
|
||||
docs: >
|
||||
This example shows how to use <b>postcompose</b> and <b>vectorContext</b> to
|
||||
animate a (marker) feature along a line. In this example an encoded polyline
|
||||
This example shows how to use <b>postrender</b> events and a <b>vector context</b> to
|
||||
animate a marker feature along a line. In this example an encoded polyline
|
||||
is being used.
|
||||
tags: "animation, feature, postcompose, polyline"
|
||||
tags: "animation, feature, postrender, polyline"
|
||||
cloak:
|
||||
- key: As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5
|
||||
value: Your Bing Maps Key from http://www.bingmapsportal.com/ here
|
||||
|
||||
@@ -7,6 +7,7 @@ import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import BingMaps from '../src/ol/source/BingMaps.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
import {Circle as CircleStyle, Fill, Icon, Stroke, Style} from '../src/ol/style.js';
|
||||
import {getVectorContext} from '../src/ol/render.js';
|
||||
|
||||
// This long string is placed here due to jsFiddle limitations.
|
||||
// It is usually loaded with AJAX.
|
||||
@@ -52,7 +53,7 @@ const polyline = [
|
||||
'~@ym@yjA??a@cFd@kBrCgDbAUnAcBhAyAdk@et@??kF}D??OL'
|
||||
].join('');
|
||||
|
||||
const route = /** @type {module:ol/geom/LineString~LineString} */ (new Polyline({
|
||||
const route = /** @type {import("../src/ol/geom/LineString.js").default} */ (new Polyline({
|
||||
factor: 1e6
|
||||
}).readGeometry(polyline, {
|
||||
dataProjection: 'EPSG:4326',
|
||||
@@ -123,7 +124,6 @@ const vectorLayer = new VectorLayer({
|
||||
const center = [-5639523.95, -3501274.52];
|
||||
const map = new Map({
|
||||
target: document.getElementById('map'),
|
||||
loadTilesWhileAnimating: true,
|
||||
view: new View({
|
||||
center: center,
|
||||
zoom: 10,
|
||||
@@ -133,7 +133,7 @@ const map = new Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new BingMaps({
|
||||
imagerySet: 'AerialWithLabels',
|
||||
imagerySet: 'AerialWithLabelsOnDemand',
|
||||
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5'
|
||||
})
|
||||
}),
|
||||
@@ -142,7 +142,7 @@ const map = new Map({
|
||||
});
|
||||
|
||||
const moveFeature = function(event) {
|
||||
const vectorContext = event.vectorContext;
|
||||
const vectorContext = getVectorContext(event);
|
||||
const frameState = event.frameState;
|
||||
|
||||
if (animating) {
|
||||
@@ -160,7 +160,7 @@ const moveFeature = function(event) {
|
||||
const feature = new Feature(currentPoint);
|
||||
vectorContext.drawFeature(feature, styles.geoMarker);
|
||||
}
|
||||
// tell OpenLayers to continue the postcompose animation
|
||||
// tell OpenLayers to continue the postrender animation
|
||||
map.render();
|
||||
};
|
||||
|
||||
@@ -176,7 +176,7 @@ function startAnimation() {
|
||||
geoMarker.setStyle(null);
|
||||
// just in case you pan somewhere else
|
||||
map.getView().setCenter(center);
|
||||
map.on('postcompose', moveFeature);
|
||||
vectorLayer.on('postrender', moveFeature);
|
||||
map.render();
|
||||
}
|
||||
}
|
||||
@@ -191,10 +191,10 @@ function stopAnimation(ended) {
|
||||
|
||||
// if animation cancelled set the marker at the beginning
|
||||
const coord = ended ? routeCoords[routeLength - 1] : routeCoords[0];
|
||||
/** @type {module:ol/geom/Point~Point} */ (geoMarker.getGeometry())
|
||||
.setCoordinates(coord);
|
||||
const geometry = /** @type {import("../src/ol/geom/Point").default} */ (geoMarker.getGeometry());
|
||||
geometry.setCoordinates(coord);
|
||||
//remove listener
|
||||
map.un('postcompose', moveFeature);
|
||||
vectorLayer.un('postrender', moveFeature);
|
||||
}
|
||||
|
||||
startButton.addEventListener('click', startAnimation, false);
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Flight Animation
|
||||
shortdesc: Demonstrates how to animate flights with ´postcompose´.
|
||||
shortdesc: Demonstrates how to animate flights with ´postrender´.
|
||||
docs: >
|
||||
This example shows how to use <b>postcompose</b> and <b>vectorContext</b> to
|
||||
This example shows how to use <b>postrender</b> and <b>vectorContext</b> to
|
||||
animate flights. A great circle arc between two airports is calculated using
|
||||
<a href="https://github.com/springmeyer/arc.js">arc.js</a> and then the flight
|
||||
paths are animated with <b>postcompose</b>. The flight data is provided by
|
||||
paths are animated with <b>postrender</b>. The flight data is provided by
|
||||
<a href="http://openflights.org/data.html">OpenFlights</a> (a simplified data
|
||||
set from the <a href="https://www.mapbox.com/mapbox.js/example/v1.0.0/animating-flight-paths/">
|
||||
Mapbox.js documentation</a> is used).
|
||||
|
||||
@@ -6,14 +6,17 @@ import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import Stamen from '../src/ol/source/Stamen.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
import {Stroke, Style} from '../src/ol/style.js';
|
||||
import {getVectorContext} from '../src/ol/render.js';
|
||||
|
||||
const tileLayer = new TileLayer({
|
||||
source: new Stamen({
|
||||
layer: 'toner'
|
||||
})
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new Stamen({
|
||||
layer: 'toner'
|
||||
})
|
||||
})
|
||||
tileLayer
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
@@ -63,7 +66,7 @@ const flightsSource = new VectorSource({
|
||||
addLater(feature, i * 50);
|
||||
}
|
||||
}
|
||||
map.on('postcompose', animateFlights);
|
||||
tileLayer.on('postrender', animateFlights);
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -85,7 +88,7 @@ map.addLayer(flightsLayer);
|
||||
|
||||
const pointsPerMs = 0.1;
|
||||
function animateFlights(event) {
|
||||
const vectorContext = event.vectorContext;
|
||||
const vectorContext = getVectorContext(event);
|
||||
const frameState = event.frameState;
|
||||
vectorContext.setStyle(style);
|
||||
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
.map:-moz-full-screen {
|
||||
height: 100%;
|
||||
}
|
||||
.map:-webkit-full-screen {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
.fullscreen:-moz-full-screen {
|
||||
height: 100%;
|
||||
}
|
||||
.fullscreen:-webkit-full-screen {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
.map:-moz-full-screen {
|
||||
height: 100%;
|
||||
}
|
||||
.map:-webkit-full-screen {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ fetch(url).then(function(response) {
|
||||
tileLoadFunction: function(tile) {
|
||||
const format = tile.getFormat();
|
||||
const tileCoord = tile.getTileCoord();
|
||||
const data = tileIndex.getTile(tileCoord[0], tileCoord[1], -tileCoord[2] - 1);
|
||||
const data = tileIndex.getTile(tileCoord[0], tileCoord[1], tileCoord[2]);
|
||||
|
||||
const features = format.readFeatures(
|
||||
JSON.stringify({
|
||||
|
||||
@@ -13,13 +13,13 @@ const view = new View({
|
||||
zoom: 19
|
||||
});
|
||||
|
||||
const tileLayer = new TileLayer({
|
||||
source: new OSM()
|
||||
});
|
||||
|
||||
// creating the map
|
||||
const map = new Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM()
|
||||
})
|
||||
],
|
||||
layers: [tileLayer],
|
||||
target: 'map',
|
||||
view: view
|
||||
});
|
||||
@@ -36,7 +36,7 @@ map.addOverlay(marker);
|
||||
// LineString to store the different geolocation positions. This LineString
|
||||
// is time aware.
|
||||
// The Z dimension is actually used to store the rotation (heading).
|
||||
const positions = new LineString([], /** @type {module:ol/geom/GeometryLayout} */ ('XYZM'));
|
||||
const positions = new LineString([], 'XYZM');
|
||||
|
||||
// Geolocation Control
|
||||
const geolocation = new Geolocation({
|
||||
@@ -155,7 +155,7 @@ const geolocateBtn = document.getElementById('geolocate');
|
||||
geolocateBtn.addEventListener('click', function() {
|
||||
geolocation.setTracking(true); // Start position tracking
|
||||
|
||||
map.on('postcompose', updateView);
|
||||
tileLayer.on('postrender', updateView);
|
||||
map.render();
|
||||
|
||||
disableButtons();
|
||||
@@ -197,7 +197,7 @@ simulateBtn.addEventListener('click', function() {
|
||||
}
|
||||
geolocate();
|
||||
|
||||
map.on('postcompose', updateView);
|
||||
tileLayer.on('postrender', updateView);
|
||||
map.render();
|
||||
|
||||
disableButtons();
|
||||
|
||||
@@ -33,8 +33,11 @@ map.on('singleclick', function(evt) {
|
||||
evt.coordinate, viewResolution, 'EPSG:3857',
|
||||
{'INFO_FORMAT': 'text/html'});
|
||||
if (url) {
|
||||
document.getElementById('info').innerHTML =
|
||||
'<iframe seamless src="' + url + '"></iframe>';
|
||||
fetch(url)
|
||||
.then((response) => response.text())
|
||||
.then((html) => {
|
||||
document.getElementById('info').innerHTML = html;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -33,8 +33,11 @@ map.on('singleclick', function(evt) {
|
||||
evt.coordinate, viewResolution, 'EPSG:3857',
|
||||
{'INFO_FORMAT': 'text/html'});
|
||||
if (url) {
|
||||
document.getElementById('info').innerHTML =
|
||||
'<iframe seamless src="' + url + '"></iframe>';
|
||||
fetch(url)
|
||||
.then((response) => response.text())
|
||||
.then((html) => {
|
||||
document.getElementById('info').innerHTML = html;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Map Graticule
|
||||
shortdesc: This example shows how to add a graticule overlay to a map.
|
||||
shortdesc: This example shows how to add a graticule layer to a map.
|
||||
docs: >
|
||||
This example shows how to add a graticule overlay to a map.
|
||||
This example shows how to add a graticule layer to a map.
|
||||
tags: "graticule"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Graticule from '../src/ol/Graticule.js';
|
||||
import Graticule from '../src/ol/layer/Graticule.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
@@ -13,6 +13,16 @@ const map = new Map({
|
||||
source: new OSM({
|
||||
wrapX: false
|
||||
})
|
||||
}),
|
||||
new Graticule({
|
||||
// the style to use for the lines, optional.
|
||||
strokeStyle: new Stroke({
|
||||
color: 'rgba(255,120,0,0.9)',
|
||||
width: 2,
|
||||
lineDash: [0.5, 4]
|
||||
}),
|
||||
showLabels: true,
|
||||
wrapX: false
|
||||
})
|
||||
],
|
||||
target: 'map',
|
||||
@@ -21,16 +31,3 @@ const map = new Map({
|
||||
zoom: 5
|
||||
})
|
||||
});
|
||||
|
||||
// Create the graticule component
|
||||
const graticule = new Graticule({
|
||||
// the style to use for the lines, optional.
|
||||
strokeStyle: new Stroke({
|
||||
color: 'rgba(255,120,0,0.9)',
|
||||
width: 2,
|
||||
lineDash: [0.5, 4]
|
||||
}),
|
||||
showLabels: true
|
||||
});
|
||||
|
||||
graticule.setMap(map);
|
||||
|
||||
@@ -43,11 +43,14 @@ const map = new Map({
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
blur.addEventListener('input', function() {
|
||||
const blurHandler = function() {
|
||||
vector.setBlur(parseInt(blur.value, 10));
|
||||
});
|
||||
};
|
||||
blur.addEventListener('input', blurHandler);
|
||||
blur.addEventListener('change', blurHandler);
|
||||
|
||||
radius.addEventListener('input', function() {
|
||||
const radiusHandler = function() {
|
||||
vector.setRadius(parseInt(radius.value, 10));
|
||||
});
|
||||
};
|
||||
radius.addEventListener('input', radiusHandler);
|
||||
radius.addEventListener('change', radiusHandler);
|
||||
|
||||
@@ -69,9 +69,6 @@ for (i = 0, ii = hereLayers.length; i < ii; ++i) {
|
||||
|
||||
const map = new Map({
|
||||
layers: layers,
|
||||
// Improve user experience by loading tiles while dragging/zooming. Will make
|
||||
// zooming choppy on mobile or slow devices.
|
||||
loadTilesWhileInteracting: true,
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [921371.9389, 6358337.7609],
|
||||
|
||||
@@ -22,27 +22,27 @@ const madrid = new Feature({
|
||||
});
|
||||
|
||||
rome.setStyle(new Style({
|
||||
image: new Icon(/** @type {module:ol/style/Icon~Options} */ ({
|
||||
image: new Icon({
|
||||
color: '#8959A8',
|
||||
crossOrigin: 'anonymous',
|
||||
src: 'data/dot.png'
|
||||
}))
|
||||
})
|
||||
}));
|
||||
|
||||
london.setStyle(new Style({
|
||||
image: new Icon(/** @type {module:ol/style/Icon~Options} */ ({
|
||||
image: new Icon({
|
||||
color: '#4271AE',
|
||||
crossOrigin: 'anonymous',
|
||||
src: 'data/dot.png'
|
||||
}))
|
||||
})
|
||||
}));
|
||||
|
||||
madrid.setStyle(new Style({
|
||||
image: new Icon(/** @type {module:ol/style/Icon~Options} */ ({
|
||||
image: new Icon({
|
||||
color: [113, 140, 0],
|
||||
crossOrigin: 'anonymous',
|
||||
src: 'data/dot.png'
|
||||
}))
|
||||
})
|
||||
}));
|
||||
|
||||
|
||||
|
||||
@@ -11,13 +11,13 @@ import {Icon, Style} from '../src/ol/style.js';
|
||||
|
||||
function createStyle(src, img) {
|
||||
return new Style({
|
||||
image: new Icon(/** @type {module:ol/style/Icon~Options} */ ({
|
||||
image: new Icon({
|
||||
anchor: [0.5, 0.96],
|
||||
crossOrigin: 'anonymous',
|
||||
src: src,
|
||||
img: img,
|
||||
imgSize: img ? [img.width, img.height] : undefined
|
||||
}))
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Icon Sprites with WebGL
|
||||
shortdesc: Icon sprite with WebGL
|
||||
shortdesc: Rendering many icons with WebGL
|
||||
docs: >
|
||||
<p>In this example a sprite image is used for the icon styles. Using a sprite is required to get good performance with WebGL.</p>
|
||||
tags: "webgl, icon, sprite, vector, point"
|
||||
This example shows how to use `ol/renderer/webgl/PointsLayer` to render
|
||||
a very large amount of sprites. The above map is based on a dataset from the National UFO Reporting Center: each
|
||||
icon marks a UFO sighting according to its reported shape (disk, light, fireball...). The older the sighting, the redder
|
||||
the icon.
|
||||
|
||||
A very simple sprite atlas is used in the form of a PNG file containing all icons on a grid. Then, the `texCoordCallback`
|
||||
option of the `ol/renderer/webgl/PointsLayer` constructor is used to specify which sprite to use according to the sighting shape.
|
||||
|
||||
The dataset contains around 80k points and can be found here: https://www.kaggle.com/NUFORC/ufo-sightings
|
||||
tags: "webgl, icon, sprite, point, ufo"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
<div id="info"> </div>
|
||||
|
||||
@@ -1,136 +1,124 @@
|
||||
import Feature from '../src/ol/Feature.js';
|
||||
import Map from '../src/ol/WebGLMap.js';
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import Point from '../src/ol/geom/Point.js';
|
||||
import VectorLayer from '../src/ol/layer/Vector.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
import {Icon, Style} from '../src/ol/style.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import TileJSON from '../src/ol/source/TileJSON';
|
||||
import Feature from '../src/ol/Feature';
|
||||
import Point from '../src/ol/geom/Point';
|
||||
import VectorLayer from '../src/ol/layer/Vector';
|
||||
import {Vector} from '../src/ol/source';
|
||||
import {fromLonLat} from '../src/ol/proj';
|
||||
import WebGLPointsLayerRenderer from '../src/ol/renderer/webgl/PointsLayer';
|
||||
import {lerp} from '../src/ol/math';
|
||||
|
||||
const features = [];
|
||||
const vectorSource = new Vector({
|
||||
features: [],
|
||||
attributions: 'National UFO Reporting Center'
|
||||
});
|
||||
|
||||
const iconInfo = [{
|
||||
offset: [0, 0],
|
||||
opacity: 1.0,
|
||||
rotateWithView: true,
|
||||
rotation: 0.0,
|
||||
scale: 1.0,
|
||||
size: [55, 55]
|
||||
}, {
|
||||
offset: [110, 86],
|
||||
opacity: 0.75,
|
||||
rotateWithView: false,
|
||||
rotation: Math.PI / 2.0,
|
||||
scale: 1.25,
|
||||
size: [55, 55]
|
||||
}, {
|
||||
offset: [55, 0],
|
||||
opacity: 0.5,
|
||||
rotateWithView: true,
|
||||
rotation: Math.PI / 3.0,
|
||||
scale: 1.5,
|
||||
size: [55, 86]
|
||||
}, {
|
||||
offset: [212, 0],
|
||||
opacity: 1.0,
|
||||
rotateWithView: true,
|
||||
rotation: 0.0,
|
||||
scale: 1.0,
|
||||
size: [44, 44]
|
||||
}];
|
||||
const texture = document.createElement('img');
|
||||
texture.src = 'data/ufo_shapes.png';
|
||||
|
||||
let i;
|
||||
// This describes the content of the associated sprite sheet
|
||||
// coords are u0, v0, u1, v1 for a given shape
|
||||
const shapeTextureCoords = {
|
||||
'light': [0, 0.5, 0.25, 0],
|
||||
'sphere': [0.25, 0.5, 0.5, 0],
|
||||
'circle': [0.25, 0.5, 0.5, 0],
|
||||
'disc': [0.5, 0.5, 0.75, 0],
|
||||
'oval': [0.5, 0.5, 0.75, 0],
|
||||
'triangle': [0.75, 0.5, 1, 0],
|
||||
'fireball': [0, 1, 0.25, 0.5],
|
||||
'default': [0.75, 1, 1, 0.5]
|
||||
};
|
||||
|
||||
const iconCount = iconInfo.length;
|
||||
const icons = new Array(iconCount);
|
||||
for (i = 0; i < iconCount; ++i) {
|
||||
const info = iconInfo[i];
|
||||
icons[i] = new Icon({
|
||||
offset: info.offset,
|
||||
opacity: info.opacity,
|
||||
rotateWithView: info.rotateWithView,
|
||||
rotation: info.rotation,
|
||||
scale: info.scale,
|
||||
size: info.size,
|
||||
crossOrigin: 'anonymous',
|
||||
src: 'data/Butterfly.png'
|
||||
});
|
||||
const oldColor = [255, 160, 110];
|
||||
const newColor = [180, 255, 200];
|
||||
|
||||
class WebglPointsLayer extends VectorLayer {
|
||||
createRenderer() {
|
||||
return new WebGLPointsLayerRenderer(this, {
|
||||
texture: texture,
|
||||
colorCallback: function(feature, vertex, component) {
|
||||
// component at index 3 is alpha
|
||||
if (component === 3) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// color is interpolated based on year (min is 1910, max is 2013)
|
||||
// please note: most values are between 2000-2013
|
||||
const ratio = (feature.get('year') - 1950) / (2013 - 1950);
|
||||
return lerp(oldColor[component], newColor[component], ratio * ratio) / 255;
|
||||
},
|
||||
texCoordCallback: function(feature, component) {
|
||||
let coords = shapeTextureCoords[feature.get('shape')];
|
||||
if (!coords) {
|
||||
coords = shapeTextureCoords['default'];
|
||||
}
|
||||
return coords[component];
|
||||
},
|
||||
sizeCallback: function() {
|
||||
return 16;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const featureCount = 50000;
|
||||
const features = new Array(featureCount);
|
||||
let feature, geometry;
|
||||
const e = 25000000;
|
||||
for (i = 0; i < featureCount; ++i) {
|
||||
geometry = new Point(
|
||||
[2 * e * Math.random() - e, 2 * e * Math.random() - e]);
|
||||
feature = new Feature(geometry);
|
||||
feature.setStyle(
|
||||
new Style({
|
||||
image: icons[i % (iconCount - 1)]
|
||||
|
||||
function loadData() {
|
||||
const client = new XMLHttpRequest();
|
||||
client.open('GET', 'data/csv/ufo_sighting_data.csv');
|
||||
client.onload = function() {
|
||||
const csv = client.responseText;
|
||||
let curIndex;
|
||||
let prevIndex = 0;
|
||||
let line;
|
||||
while ((curIndex = csv.indexOf('\n', prevIndex)) > 0) {
|
||||
line = csv.substr(prevIndex, curIndex - prevIndex).split(',');
|
||||
prevIndex = curIndex + 1;
|
||||
|
||||
// skip header
|
||||
if (prevIndex === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const coords = fromLonLat([parseFloat(line[5]), parseFloat(line[4])]);
|
||||
|
||||
// only keep valid points
|
||||
if (isNaN(coords[0]) || isNaN(coords[1])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
features.push(new Feature({
|
||||
datetime: line[0],
|
||||
year: parseInt(/[0-9]{4}/.exec(line[0])[0]), // extract the year as int
|
||||
shape: line[2],
|
||||
duration: line[3],
|
||||
geometry: new Point(coords)
|
||||
}));
|
||||
}
|
||||
vectorSource.addFeatures(features);
|
||||
};
|
||||
client.send();
|
||||
}
|
||||
|
||||
loadData();
|
||||
|
||||
new Map({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new TileJSON({
|
||||
url: 'https://api.tiles.mapbox.com/v3/mapbox.world-dark.json?secure',
|
||||
crossOrigin: 'anonymous'
|
||||
})
|
||||
}),
|
||||
new WebglPointsLayer({
|
||||
source: vectorSource
|
||||
})
|
||||
);
|
||||
features[i] = feature;
|
||||
}
|
||||
|
||||
const vectorSource = new VectorSource({
|
||||
features: features
|
||||
});
|
||||
const vector = new VectorLayer({
|
||||
source: vectorSource
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
layers: [vector],
|
||||
],
|
||||
target: document.getElementById('map'),
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
zoom: 5
|
||||
center: [0, 4000000],
|
||||
zoom: 2
|
||||
})
|
||||
});
|
||||
|
||||
const overlayFeatures = [];
|
||||
for (i = 0; i < featureCount; i += 30) {
|
||||
const clone = features[i].clone();
|
||||
clone.setStyle(null);
|
||||
overlayFeatures.push(clone);
|
||||
}
|
||||
|
||||
new VectorLayer({
|
||||
map: map,
|
||||
source: new VectorSource({
|
||||
features: overlayFeatures
|
||||
}),
|
||||
style: new Style({
|
||||
image: icons[iconCount - 1]
|
||||
})
|
||||
});
|
||||
|
||||
map.on('click', function(evt) {
|
||||
const info = document.getElementById('info');
|
||||
info.innerHTML =
|
||||
'Hold on a second, while I catch those butterflies for you ...';
|
||||
|
||||
window.setTimeout(function() {
|
||||
const features = [];
|
||||
map.forEachFeatureAtPixel(evt.pixel, function(feature) {
|
||||
features.push(feature);
|
||||
return false;
|
||||
});
|
||||
|
||||
if (features.length === 1) {
|
||||
info.innerHTML = 'Got one butterfly';
|
||||
} else if (features.length > 1) {
|
||||
info.innerHTML = 'Got ' + features.length + ' butterflies';
|
||||
} else {
|
||||
info.innerHTML = 'Couldn\'t catch a single butterfly';
|
||||
}
|
||||
}, 1);
|
||||
});
|
||||
|
||||
map.on('pointermove', function(evt) {
|
||||
if (evt.dragging) {
|
||||
return;
|
||||
}
|
||||
const pixel = map.getEventPixel(evt.originalEvent);
|
||||
const hit = map.hasFeatureAtPixel(pixel);
|
||||
map.getTarget().style.cursor = hit ? 'pointer' : '';
|
||||
});
|
||||
|
||||
@@ -17,12 +17,12 @@ const iconFeature = new Feature({
|
||||
});
|
||||
|
||||
const iconStyle = new Style({
|
||||
image: new Icon(/** @type {module:ol/style/Icon~Options} */ ({
|
||||
image: new Icon({
|
||||
anchor: [0.5, 46],
|
||||
anchorXUnits: 'fraction',
|
||||
anchorYUnits: 'pixels',
|
||||
src: 'data/icon.png'
|
||||
}))
|
||||
})
|
||||
});
|
||||
|
||||
iconFeature.setStyle(iconStyle);
|
||||
|
||||
@@ -7,6 +7,7 @@ import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||
import OSM, {ATTRIBUTION} from '../src/ol/source/OSM.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
import {Circle as CircleStyle, Fill, Stroke, Style} from '../src/ol/style.js';
|
||||
import {getVectorContext} from '../src/ol/render.js';
|
||||
|
||||
|
||||
const colors = {
|
||||
@@ -73,6 +74,10 @@ vectorSource.on('addfeature', function(event) {
|
||||
time.duration = time.stop - time.start;
|
||||
});
|
||||
|
||||
const vectorLayer = new VectorLayer({
|
||||
source: vectorSource,
|
||||
style: styleFunction
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
layers: [
|
||||
@@ -86,10 +91,7 @@ const map = new Map({
|
||||
'?apikey=0e6fc415256d4fbb9b5166a718591d71'
|
||||
})
|
||||
}),
|
||||
new VectorLayer({
|
||||
source: vectorSource,
|
||||
style: styleFunction
|
||||
})
|
||||
vectorLayer
|
||||
],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
@@ -153,8 +155,8 @@ const style = new Style({
|
||||
stroke: stroke
|
||||
})
|
||||
});
|
||||
map.on('postcompose', function(evt) {
|
||||
const vectorContext = evt.vectorContext;
|
||||
vectorLayer.on('postrender', function(evt) {
|
||||
const vectorContext = getVectorContext(evt);
|
||||
vectorContext.setStyle(style);
|
||||
if (point !== null) {
|
||||
vectorContext.drawGeometry(point);
|
||||
@@ -181,7 +183,7 @@ document.getElementById('time').addEventListener('input', function() {
|
||||
const value = parseInt(this.value, 10) / 100;
|
||||
const m = time.start + (time.duration * value);
|
||||
vectorSource.forEachFeature(function(feature) {
|
||||
const geometry = /** @type {module:ol/geom/LineString~LineString} */ (feature.getGeometry());
|
||||
const geometry = /** @type {import("../src/ol/geom/LineString.js").default} */ (feature.getGeometry());
|
||||
const coordinate = geometry.getCoordinateAtM(m, true);
|
||||
let highlight = feature.get('highlight');
|
||||
if (highlight === undefined) {
|
||||
|
||||
@@ -3,9 +3,9 @@ layout: example.html
|
||||
title: Image Filters
|
||||
shortdesc: Apply a filter to imagery
|
||||
docs: >
|
||||
<p>Layer rendering can be manipulated in <code>precompose</code> and <code>postcompose</code> event listeners.
|
||||
<p>Layer rendering can be manipulated in <code>prerender</code> and <code>postrender</code> event listeners.
|
||||
These listeners get an event with a reference to the Canvas rendering context.
|
||||
In this example, the <code>postcompose</code> listener applies a filter to the image data.</p>
|
||||
In this example, the <code>postrender</code> listener applies a filter to the image data.</p>
|
||||
tags: "filter, image manipulation"
|
||||
cloak:
|
||||
- key: As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5
|
||||
|
||||
@@ -90,9 +90,9 @@ select.onchange = function() {
|
||||
|
||||
|
||||
/**
|
||||
* Apply a filter on "postcompose" events.
|
||||
* Apply a filter on "postrender" events.
|
||||
*/
|
||||
imagery.on('postcompose', function(event) {
|
||||
imagery.on('postrender', function(event) {
|
||||
convolve(event.context, selectedKernel);
|
||||
});
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import ImageWMS from '../src/ol/source/ImageWMS.js';
|
||||
|
||||
/**
|
||||
* Renders a progress bar.
|
||||
* @param {Element} el The target element.
|
||||
* @param {HTMLElement} el The target element.
|
||||
* @constructor
|
||||
*/
|
||||
function Progress(el) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Image Vector Layer
|
||||
shortdesc: Example of an image vector layer.
|
||||
title: Vector Image Layer
|
||||
shortdesc: Example of rendering vector data as an image layer.
|
||||
docs: >
|
||||
<p>This example uses <code>ol/layer/Vector</code> with `renderMode: 'image'`. This mode results in faster rendering during interaction and animations, at the cost of less accurate rendering.</p>
|
||||
<p>This example uses <code>ol/layer/VectorImage</code> for faster rendering during interaction and animations, at the cost of less accurate rendering.</p>
|
||||
tags: "vector, image"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import GeoJSON from '../src/ol/format/GeoJSON.js';
|
||||
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 {Fill, Stroke, Style, Text} from '../src/ol/style.js';
|
||||
@@ -19,8 +20,8 @@ const style = new Style({
|
||||
|
||||
const map = new Map({
|
||||
layers: [
|
||||
new VectorLayer({
|
||||
renderMode: 'image',
|
||||
new VectorImageLayer({
|
||||
imageRatio: 2,
|
||||
source: new VectorSource({
|
||||
url: 'data/geojson/countries.geojson',
|
||||
format: new GeoJSON()
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Layer Clipping with WebGL
|
||||
shortdesc: Layer WebGL clipping example.
|
||||
docs: >
|
||||
This example shows how to use the <code>precompose</code> and <code>postcompose</code> rendering hooks to clip layers using WebGL.
|
||||
tags: "clipping, webgl, openstreetmap"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
<div id="no-webgl" class="alert alert-danger" style="display: none">
|
||||
This example requires a browser that supports <a href="http://get.webgl.org/">WebGL</a>.
|
||||
</div>
|
||||
@@ -1,101 +0,0 @@
|
||||
import Map from '../src/ol/WebGLMap.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {WEBGL} from '../src/ol/has.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
|
||||
if (!WEBGL) {
|
||||
const info = document.getElementById('no-webgl');
|
||||
/**
|
||||
* display error message
|
||||
*/
|
||||
info.style.display = '';
|
||||
} else {
|
||||
|
||||
const osm = new TileLayer({
|
||||
source: new OSM()
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
layers: [osm],
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [0, 0],
|
||||
zoom: 2
|
||||
})
|
||||
});
|
||||
|
||||
const fragmentShaderSource = [
|
||||
'precision mediump float;',
|
||||
'void main() {',
|
||||
'}'
|
||||
].join('');
|
||||
|
||||
const vertexShaderSource = [
|
||||
'attribute vec2 a_position;',
|
||||
'void main() {',
|
||||
' gl_Position = vec4(a_position, 0, 1);',
|
||||
'}'
|
||||
].join('');
|
||||
|
||||
osm.on('precompose', function(event) {
|
||||
const context = event.glContext;
|
||||
|
||||
const gl = context.getGL();
|
||||
const program = gl.createProgram();
|
||||
|
||||
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
|
||||
gl.shaderSource(vertexShader, vertexShaderSource);
|
||||
gl.compileShader(vertexShader);
|
||||
gl.attachShader(program, vertexShader);
|
||||
|
||||
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
|
||||
gl.shaderSource(fragmentShader, fragmentShaderSource);
|
||||
gl.compileShader(fragmentShader);
|
||||
gl.attachShader(program, fragmentShader);
|
||||
|
||||
gl.linkProgram(program);
|
||||
context.useProgram(program);
|
||||
|
||||
const positionLocation = gl.getAttribLocation(program, 'a_position');
|
||||
|
||||
gl.enable(gl.STENCIL_TEST);
|
||||
gl.colorMask(false, false, false, false);
|
||||
gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
|
||||
gl.stencilFunc(gl.ALWAYS, 1, 0xff);
|
||||
|
||||
const buffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
|
||||
// first band
|
||||
-1.0, -1.0, -0.75, -1.0, -1.0, 1.0,
|
||||
-1.0, 1.0, -0.75, -1.0, -0.75, 1.0,
|
||||
// second band
|
||||
-0.5, -1.0, -0.25, -1.0, -0.5, 1.0,
|
||||
-0.5, 1.0, -0.25, -1.0, -0.25, 1.0,
|
||||
// third band
|
||||
0.0, -1.0, 0.25, -1.0, 0.0, 1.0,
|
||||
0.0, 1.0, 0.25, -1.0, 0.25, 1.0,
|
||||
// forth band
|
||||
0.5, -1.0, 0.75, -1.0, 0.5, 1.0,
|
||||
0.5, 1.0, 0.75, -1.0, 0.75, 1.0
|
||||
]), gl.STATIC_DRAW);
|
||||
|
||||
gl.enableVertexAttribArray(positionLocation);
|
||||
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, 24);
|
||||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
||||
gl.deleteBuffer(buffer);
|
||||
|
||||
gl.colorMask(true, true, true, true);
|
||||
gl.stencilFunc(gl.NOTEQUAL, 0, 0xff);
|
||||
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
|
||||
});
|
||||
|
||||
osm.on('postcompose', function(event) {
|
||||
const context = event.glContext;
|
||||
const gl = context.getGL();
|
||||
gl.disable(gl.STENCIL_TEST);
|
||||
});
|
||||
}
|
||||
@@ -16,7 +16,7 @@ const map = new Map({
|
||||
})
|
||||
});
|
||||
|
||||
osm.on('precompose', function(event) {
|
||||
osm.on('prerender', function(event) {
|
||||
const ctx = event.context;
|
||||
ctx.save();
|
||||
const pixelRatio = event.frameState.pixelRatio;
|
||||
@@ -38,7 +38,7 @@ osm.on('precompose', function(event) {
|
||||
ctx.translate(-size[0] / 2 * pixelRatio, -size[1] / 2 * pixelRatio);
|
||||
});
|
||||
|
||||
osm.on('postcompose', function(event) {
|
||||
osm.on('postrender', function(event) {
|
||||
const ctx = event.context;
|
||||
ctx.restore();
|
||||
});
|
||||
|
||||
@@ -3,9 +3,9 @@ layout: example.html
|
||||
title: Layer Spy
|
||||
shortdesc: View a portion of one layer over another
|
||||
docs: >
|
||||
<p>Layer rendering can be manipulated in <code>precompose</code> and <code>postcompose</code> event listeners.
|
||||
<p>Layer rendering can be manipulated in <code>prerender</code> and <code>postrender</code> event listeners.
|
||||
These listeners get an event with a reference to the Canvas rendering context.
|
||||
In this example, the <code>precompose</code> listener sets a clipping mask around the most
|
||||
In this example, the <code>prerender</code> listener sets a clipping mask around the most
|
||||
recent mouse position, giving you a spyglass effect for viewing one layer over another.</p>
|
||||
<p>Move around the map to see the effect. Use the ↑ up and ↓ down arrow keys to adjust the spyglass size.</p>
|
||||
tags: "spy, image manipulation"
|
||||
|
||||
@@ -7,7 +7,7 @@ import BingMaps from '../src/ol/source/BingMaps.js';
|
||||
const key = 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5';
|
||||
|
||||
const roads = new TileLayer({
|
||||
source: new BingMaps({key: key, imagerySet: 'Road'})
|
||||
source: new BingMaps({key: key, imagerySet: 'RoadOnDemand'})
|
||||
});
|
||||
|
||||
const imagery = new TileLayer({
|
||||
@@ -52,7 +52,7 @@ container.addEventListener('mouseout', function() {
|
||||
});
|
||||
|
||||
// before rendering the layer, do some clipping
|
||||
imagery.on('precompose', function(event) {
|
||||
imagery.on('prerender', function(event) {
|
||||
const ctx = event.context;
|
||||
const pixelRatio = event.frameState.pixelRatio;
|
||||
ctx.save();
|
||||
@@ -69,7 +69,7 @@ imagery.on('precompose', function(event) {
|
||||
});
|
||||
|
||||
// after rendering the layer, restore the canvas context
|
||||
imagery.on('postcompose', function(event) {
|
||||
imagery.on('postrender', function(event) {
|
||||
const ctx = event.context;
|
||||
ctx.restore();
|
||||
});
|
||||
|
||||
@@ -25,7 +25,7 @@ const map = new Map({
|
||||
|
||||
const swipe = document.getElementById('swipe');
|
||||
|
||||
bing.on('precompose', function(event) {
|
||||
bing.on('prerender', function(event) {
|
||||
const ctx = event.context;
|
||||
const width = ctx.canvas.width * (swipe.value / 100);
|
||||
|
||||
@@ -35,7 +35,7 @@ bing.on('precompose', function(event) {
|
||||
ctx.clip();
|
||||
});
|
||||
|
||||
bing.on('postcompose', function(event) {
|
||||
bing.on('postrender', function(event) {
|
||||
const ctx = event.context;
|
||||
ctx.restore();
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@ layout: example.html
|
||||
title: Magnify
|
||||
shortdesc: Show a magnified version of imager under the pointer
|
||||
docs: >
|
||||
<p>This example makes use of the <code>postcompose</code> event listener to
|
||||
<p>This example makes use of the <code>postrender</code> event listener to
|
||||
oversample imagery in a circle around the pointer location. Listeners for this event have access to the Canvas context and can manipulate image data.</p>
|
||||
<p>Move around the map to see the effect. Use the ↑ up and ↓ down arrow keys to adjust the magnified circle size.</p>
|
||||
tags: "magnify, image manipulation"
|
||||
|
||||
@@ -3,6 +3,7 @@ import View from '../src/ol/View.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import {fromLonLat} from '../src/ol/proj.js';
|
||||
import BingMaps from '../src/ol/source/BingMaps.js';
|
||||
import {getRenderPixel} from '../src/ol/render.js';
|
||||
|
||||
const key = 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5';
|
||||
|
||||
@@ -48,16 +49,17 @@ container.addEventListener('mouseout', function() {
|
||||
});
|
||||
|
||||
// after rendering the layer, show an oversampled version around the pointer
|
||||
imagery.on('postcompose', function(event) {
|
||||
imagery.on('postrender', function(event) {
|
||||
if (mousePosition) {
|
||||
const pixel = getRenderPixel(event, mousePosition);
|
||||
const offset = getRenderPixel(event, [mousePosition[0] + radius, mousePosition[1]]);
|
||||
const half = Math.sqrt(Math.pow(offset[0] - pixel[0], 2) + Math.pow(offset[1] - pixel[1], 2));
|
||||
const context = event.context;
|
||||
const pixelRatio = event.frameState.pixelRatio;
|
||||
const half = radius * pixelRatio;
|
||||
const centerX = mousePosition[0] * pixelRatio;
|
||||
const centerY = mousePosition[1] * pixelRatio;
|
||||
const centerX = pixel[0];
|
||||
const centerY = pixel[1];
|
||||
const originX = centerX - half;
|
||||
const originY = centerY - half;
|
||||
const size = 2 * half + 1;
|
||||
const size = Math.round(2 * half + 1);
|
||||
const sourceData = context.getImageData(originX, originY, size, size).data;
|
||||
const dest = context.createImageData(size, size);
|
||||
const destData = dest.data;
|
||||
@@ -82,7 +84,7 @@ imagery.on('postcompose', function(event) {
|
||||
}
|
||||
context.beginPath();
|
||||
context.arc(centerX, centerY, half, 0, 2 * Math.PI);
|
||||
context.lineWidth = 3 * pixelRatio;
|
||||
context.lineWidth = 3 * half / radius;
|
||||
context.strokeStyle = 'rgba(255,255,255,0.5)';
|
||||
context.putImageData(dest, originX, originY);
|
||||
context.stroke();
|
||||
|
||||
14
examples/mapbox-layer.html
Normal file
14
examples/mapbox-layer.html
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
layout: example.html
|
||||
title: Mapbox-gl Layer
|
||||
shortdesc: Example of a Mapbox-gl-js layer integration.
|
||||
docs: >
|
||||
Show how to add a mapbox-gl-js layer in an openlayers map. **Note**: Make sure to get your own Mapbox API key when using this example. No map will be visible when the API key has expired.
|
||||
tags: "simple, mapbox, vector, tiles"
|
||||
resources:
|
||||
- https://unpkg.com/mapbox-gl@0.51.0/dist/mapbox-gl.js
|
||||
cloak:
|
||||
- key: ER67WIiPdCQvhgsUjoWK
|
||||
value: Your Mapbox access token from http://mapbox.com/ here
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
218
examples/mapbox-layer.js
Normal file
218
examples/mapbox-layer.js
Normal file
@@ -0,0 +1,218 @@
|
||||
import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import Layer from '../src/ol/layer/Layer';
|
||||
import {assign} from '../src/ol/obj';
|
||||
import {getTransform} from '../src/ol/proj';
|
||||
import SourceState from '../src/ol/source/State';
|
||||
import {Stroke, Style} from '../src/ol/style.js';
|
||||
import VectorLayer from '../src/ol/layer/Vector.js';
|
||||
import VectorSource from '../src/ol/source/Vector.js';
|
||||
import GeoJSON from '../src/ol/format/GeoJSON.js';
|
||||
|
||||
class Mapbox extends Layer {
|
||||
|
||||
/**
|
||||
* @param {import('./Base.js').Options} options Layer options.
|
||||
*/
|
||||
constructor(options) {
|
||||
const baseOptions = assign({}, options);
|
||||
super(baseOptions);
|
||||
|
||||
this.baseOptions = baseOptions;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type boolean
|
||||
*/
|
||||
this.loaded = false;
|
||||
|
||||
this.initMap();
|
||||
}
|
||||
|
||||
initMap() {
|
||||
const map = this.map_;
|
||||
const view = map.getView();
|
||||
const transformToLatLng = getTransform(view.getProjection(), 'EPSG:4326');
|
||||
const center = transformToLatLng(view.getCenter());
|
||||
|
||||
this.centerLastRender = view.getCenter();
|
||||
this.zoomLastRender = view.getZoom();
|
||||
this.centerLastRender = view.getCenter();
|
||||
this.zoomLastRender = view.getZoom();
|
||||
|
||||
const options = assign(this.baseOptions, {
|
||||
attributionControl: false,
|
||||
boxZoom: false,
|
||||
center,
|
||||
container: map.getTargetElement(),
|
||||
doubleClickZoom: false,
|
||||
dragPan: false,
|
||||
dragRotate: false,
|
||||
interactive: false,
|
||||
keyboard: false,
|
||||
pitchWithRotate: false,
|
||||
scrollZoom: false,
|
||||
touchZoomRotate: false,
|
||||
zoom: view.getZoom() - 1
|
||||
});
|
||||
|
||||
this.mbmap = new mapboxgl.Map(options);
|
||||
this.mbmap.on('load', function() {
|
||||
this.mbmap.getCanvas().remove();
|
||||
this.loaded = true;
|
||||
this.map_.render();
|
||||
[
|
||||
'mapboxgl-control-container'
|
||||
].forEach(className => document.getElementsByClassName(className)[0].remove());
|
||||
}.bind(this));
|
||||
|
||||
this.mbmap.on('render', function() {
|
||||
// Reset offset
|
||||
if (this.centerNextRender) {
|
||||
this.centerLastRender = this.centerNextRender;
|
||||
}
|
||||
if (this.zoomNextRender) {
|
||||
this.zoomLastRender = this.zoomNextRender;
|
||||
}
|
||||
this.updateRenderedPosition([0, 0], 1);
|
||||
}.bind(this));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @inheritDoc
|
||||
*/
|
||||
render(frameState) {
|
||||
const map = this.map_;
|
||||
const view = map.getView();
|
||||
const transformToLatLng = getTransform(view.getProjection(), 'EPSG:4326');
|
||||
|
||||
this.centerNextRender = view.getCenter();
|
||||
const lastRender = map.getPixelFromCoordinate(this.centerLastRender);
|
||||
const nextRender = map.getPixelFromCoordinate(this.centerNextRender);
|
||||
const centerOffset = [lastRender[0] - nextRender[0], lastRender[1] - nextRender[1]];
|
||||
this.zoomNextRender = view.getZoom();
|
||||
const zoomOffset = Math.pow(2, this.zoomNextRender - this.zoomLastRender);
|
||||
this.updateRenderedPosition(centerOffset, zoomOffset);
|
||||
|
||||
const rotation = frameState.viewState.rotation;
|
||||
if (rotation) {
|
||||
this.mbmap.rotateTo(-rotation * 180 / Math.PI, {
|
||||
animate: false
|
||||
});
|
||||
}
|
||||
|
||||
// Re-render mbmap
|
||||
const center = transformToLatLng(this.centerNextRender);
|
||||
const zoom = view.getZoom() - 1;
|
||||
this.mbmap.jumpTo({
|
||||
center: center,
|
||||
zoom: zoom
|
||||
});
|
||||
return this.mbmap.getCanvas();
|
||||
}
|
||||
|
||||
updateRenderedPosition(centerOffset, zoomOffset) {
|
||||
const style = this.mbmap.getCanvas().style;
|
||||
style.left = Math.round(centerOffset[0]) + 'px';
|
||||
style.top = Math.round(centerOffset[1]) + 'px';
|
||||
style.transform = 'scale(' + zoomOffset + ')';
|
||||
}
|
||||
|
||||
setVisible(visible) {
|
||||
super.setVisible(visible);
|
||||
|
||||
const canvas = this.mbmap.getCanvas();
|
||||
canvas.style.display = visible ? 'block' : 'none';
|
||||
}
|
||||
|
||||
setOpacity(opacity) {
|
||||
super.setOpacity(opacity);
|
||||
const canvas = this.mbmap.getCanvas();
|
||||
canvas.style.opacity = opacity;
|
||||
}
|
||||
|
||||
setZIndex(zindex) {
|
||||
super.setZIndex(zindex);
|
||||
const canvas = this.mbmap.getCanvas();
|
||||
canvas.style.zIndex = zindex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
getSourceState() {
|
||||
return this.loaded ? SourceState.READY : SourceState.UNDEFINED;
|
||||
}
|
||||
|
||||
setMap(map) {
|
||||
this.map_ = map;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mapboxgl.Map.prototype._setupContainer = function _setupContainer() {
|
||||
const container = this._container;
|
||||
container.classList.add('mapboxgl-map');
|
||||
|
||||
const canvasContainer = this._canvasContainer = container.firstChild;
|
||||
|
||||
this._canvas = document.createElement('canvas');
|
||||
canvasContainer.insertBefore(this._canvas, canvasContainer.firstChild);
|
||||
this._canvas.style.position = 'absolute';
|
||||
this._canvas.addEventListener('webglcontextlost', this._contextLost, false);
|
||||
this._canvas.addEventListener('webglcontextrestored', this._contextRestored, false);
|
||||
this._canvas.setAttribute('tabindex', '0');
|
||||
this._canvas.setAttribute('aria-label', 'Map');
|
||||
this._canvas.className = 'mapboxgl-canvas';
|
||||
|
||||
const dimensions = this._containerDimensions();
|
||||
this._resizeCanvas(dimensions[0], dimensions[1]);
|
||||
|
||||
this._controlContainer = canvasContainer;
|
||||
const controlContainer = this._controlContainer = document.createElement('div');
|
||||
controlContainer.className = 'mapboxgl-control-container';
|
||||
container.appendChild(controlContainer);
|
||||
|
||||
const positions = this._controlPositions = {};
|
||||
['top-left', 'top-right', 'bottom-left', 'bottom-right'].forEach(function(positionName) {
|
||||
const elem = document.createElement('div');
|
||||
elem.className = 'mapboxgl-ctrl-' + positionName;
|
||||
controlContainer.appendChild(elem);
|
||||
positions[positionName] = elem;
|
||||
});
|
||||
};
|
||||
|
||||
const style = new Style({
|
||||
stroke: new Stroke({
|
||||
color: '#319FD3',
|
||||
width: 2
|
||||
})
|
||||
});
|
||||
|
||||
const vectorLayer = new VectorLayer({
|
||||
source: new VectorSource({
|
||||
url: 'data/geojson/countries.geojson',
|
||||
format: new GeoJSON()
|
||||
}),
|
||||
style: style
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
target: 'map',
|
||||
view: new View({
|
||||
center: [-10997148, 4569099],
|
||||
zoom: 4
|
||||
})
|
||||
});
|
||||
|
||||
const key = 'ER67WIiPdCQvhgsUjoWK';
|
||||
const mbLayer = new Mapbox({
|
||||
map: map,
|
||||
container: map.getTarget(),
|
||||
style: 'https://maps.tilehosting.com/styles/bright/style.json?key=' + key
|
||||
});
|
||||
|
||||
map.addLayer(mbLayer);
|
||||
map.addLayer(vectorLayer);
|
||||
32
examples/mapbox-style.html
Normal file
32
examples/mapbox-style.html
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
layout: example-verbatim.html
|
||||
title: Vector tiles created from a Mapbox Style object
|
||||
shortdesc: Example of using ol-mapbox-style with tiles from tilehosting.com.
|
||||
tags: "vector tiles, mapbox style, ol-mapbox-style"
|
||||
cloak:
|
||||
- key: lirfd6Fegsjkvs0lshxe
|
||||
value: Your API key from http://tilehosting.com/ here
|
||||
---
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
|
||||
<title>Mapbox Style objects with ol-mapbox-style</title>
|
||||
<link rel="stylesheet" href="../css/ol.css" type="text/css">
|
||||
<style type="text/css">
|
||||
html, body, .map {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="map" class="map"></div>
|
||||
<script src="common.js"></script>
|
||||
<script src="mapbox-style.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
3
examples/mapbox-style.js
Normal file
3
examples/mapbox-style.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import apply from 'ol-mapbox-style';
|
||||
|
||||
apply('map', 'https://maps.tilehosting.com/styles/topo/style.json?key=ER67WIiPdCQvhgsUjoWK');
|
||||
@@ -8,7 +8,7 @@ tags: "mapbox, vector, tiles, mobile"
|
||||
resources:
|
||||
- resources/mapbox-streets-v6-style.js
|
||||
cloak:
|
||||
- key: pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiRk1kMWZaSSJ9.E5BkluenyWQMsBLsuByrmg
|
||||
- key: pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiY2pzbmg0Nmk5MGF5NzQzbzRnbDNoeHJrbiJ9.7_-_gL8ur7ZtEiNwRfCy7Q
|
||||
value: Your Mapbox access token from http://mapbox.com/ here
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
|
||||
@@ -8,7 +8,7 @@ import {Fill, Icon, Stroke, Style, Text} from '../src/ol/style.js';
|
||||
import TileGrid from '../src/ol/tilegrid/TileGrid.js';
|
||||
|
||||
|
||||
const key = 'pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiRk1kMWZaSSJ9.E5BkluenyWQMsBLsuByrmg';
|
||||
const key = 'pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiY2pzbmg0Nmk5MGF5NzQzbzRnbDNoeHJrbiJ9.7_-_gL8ur7ZtEiNwRfCy7Q';
|
||||
|
||||
// Calculation of resolutions that match zoom levels 1, 3, 5, 7, 9, 11, 13, 15.
|
||||
const resolutions = [];
|
||||
@@ -21,7 +21,7 @@ function tileUrlFunction(tileCoord) {
|
||||
'{z}/{x}/{y}.vector.pbf?access_token=' + key)
|
||||
.replace('{z}', String(tileCoord[0] * 2 - 1))
|
||||
.replace('{x}', String(tileCoord[1]))
|
||||
.replace('{y}', String(-tileCoord[2] - 1))
|
||||
.replace('{y}', String(tileCoord[2]))
|
||||
.replace('{a-d}', 'abcd'.substr(
|
||||
((tileCoord[1] << tileCoord[0]) + tileCoord[2]) % 4, 1));
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ tags: "simple, mapbox, vector, tiles"
|
||||
resources:
|
||||
- resources/mapbox-streets-v6-style.js
|
||||
cloak:
|
||||
- key: pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiRk1kMWZaSSJ9.E5BkluenyWQMsBLsuByrmg
|
||||
- key: pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiY2pzbmg0Nmk5MGF5NzQzbzRnbDNoeHJrbiJ9.7_-_gL8ur7ZtEiNwRfCy7Q
|
||||
value: Your Mapbox access token from http://mapbox.com/ here
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
|
||||
@@ -6,7 +6,7 @@ import VectorTileSource from '../src/ol/source/VectorTile.js';
|
||||
import {Fill, Icon, Stroke, Style, Text} from '../src/ol/style.js';
|
||||
|
||||
|
||||
const key = 'pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiRk1kMWZaSSJ9.E5BkluenyWQMsBLsuByrmg';
|
||||
const key = 'pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiY2pzbmg0Nmk5MGF5NzQzbzRnbDNoeHJrbiJ9.7_-_gL8ur7ZtEiNwRfCy7Q';
|
||||
|
||||
const map = new Map({
|
||||
layers: [
|
||||
|
||||
@@ -38,35 +38,35 @@ const vector = new VectorLayer({
|
||||
|
||||
/**
|
||||
* Currently drawn feature.
|
||||
* @type {module:ol/Feature~Feature}
|
||||
* @type {import("../src/ol/Feature.js").default}
|
||||
*/
|
||||
let sketch;
|
||||
|
||||
|
||||
/**
|
||||
* The help tooltip element.
|
||||
* @type {Element}
|
||||
* @type {HTMLElement}
|
||||
*/
|
||||
let helpTooltipElement;
|
||||
|
||||
|
||||
/**
|
||||
* Overlay to show the help messages.
|
||||
* @type {module:ol/Overlay}
|
||||
* @type {Overlay}
|
||||
*/
|
||||
let helpTooltip;
|
||||
|
||||
|
||||
/**
|
||||
* The measure tooltip element.
|
||||
* @type {Element}
|
||||
* @type {HTMLElement}
|
||||
*/
|
||||
let measureTooltipElement;
|
||||
|
||||
|
||||
/**
|
||||
* Overlay to show the measurement.
|
||||
* @type {module:ol/Overlay}
|
||||
* @type {Overlay}
|
||||
*/
|
||||
let measureTooltip;
|
||||
|
||||
@@ -87,7 +87,7 @@ const continueLineMsg = 'Click to continue drawing the line';
|
||||
|
||||
/**
|
||||
* Handle pointer move.
|
||||
* @param {module:ol/MapBrowserEvent~MapBrowserEvent} evt The event.
|
||||
* @param {import("../src/ol/MapBrowserEvent").default} evt The event.
|
||||
*/
|
||||
const pointerMoveHandler = function(evt) {
|
||||
if (evt.dragging) {
|
||||
@@ -97,7 +97,7 @@ const pointerMoveHandler = function(evt) {
|
||||
let helpMsg = 'Click to start drawing';
|
||||
|
||||
if (sketch) {
|
||||
const geom = (sketch.getGeometry());
|
||||
const geom = sketch.getGeometry();
|
||||
if (geom instanceof Polygon) {
|
||||
helpMsg = continuePolygonMsg;
|
||||
} else if (geom instanceof LineString) {
|
||||
@@ -134,7 +134,7 @@ let draw; // global so we can remove it later
|
||||
|
||||
/**
|
||||
* Format length output.
|
||||
* @param {module:ol/geom/LineString~LineString} line The line.
|
||||
* @param {LineString} line The line.
|
||||
* @return {string} The formatted length.
|
||||
*/
|
||||
const formatLength = function(line) {
|
||||
@@ -153,7 +153,7 @@ const formatLength = function(line) {
|
||||
|
||||
/**
|
||||
* Format area output.
|
||||
* @param {module:ol/geom/Polygon~Polygon} polygon The polygon.
|
||||
* @param {Polygon} polygon The polygon.
|
||||
* @return {string} Formatted area.
|
||||
*/
|
||||
const formatArea = function(polygon) {
|
||||
@@ -205,7 +205,7 @@ function addInteraction() {
|
||||
// set sketch
|
||||
sketch = evt.feature;
|
||||
|
||||
/** @type {module:ol/coordinate~Coordinate|undefined} */
|
||||
/** @type {import("../src/ol/coordinate.js").Coordinate|undefined} */
|
||||
let tooltipCoord = evt.coordinate;
|
||||
|
||||
listener = sketch.getGeometry().on('change', function(evt) {
|
||||
@@ -221,7 +221,7 @@ function addInteraction() {
|
||||
measureTooltipElement.innerHTML = output;
|
||||
measureTooltip.setPosition(tooltipCoord);
|
||||
});
|
||||
}, this);
|
||||
});
|
||||
|
||||
draw.on('drawend',
|
||||
function() {
|
||||
@@ -233,7 +233,7 @@ function addInteraction() {
|
||||
measureTooltipElement = null;
|
||||
createMeasureTooltip();
|
||||
unByKey(listener);
|
||||
}, this);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ cloak:
|
||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
||||
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
|
||||
<title>Mobile full screen example</title>
|
||||
<link rel="stylesheet" href="../css/ol.css" type="text/css">
|
||||
<style type="text/css">
|
||||
html, body, .map {
|
||||
margin: 0;
|
||||
|
||||
@@ -15,7 +15,7 @@ const map = new Map({
|
||||
new TileLayer({
|
||||
source: new BingMaps({
|
||||
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5',
|
||||
imagerySet: 'Road'
|
||||
imagerySet: 'RoadOnDemand'
|
||||
})
|
||||
})
|
||||
],
|
||||
|
||||
@@ -3,7 +3,8 @@ layout: example.html
|
||||
title: Overview Map Control
|
||||
shortdesc: Example of OverviewMap control.
|
||||
docs: >
|
||||
This example demonstrates the use of the OverviewMap control.
|
||||
This example demonstrates the use of the OverviewMap control. Both the main map and the overview map are configured with layers using the same source.
|
||||
Please note that explicitly configuring layers for the overview map is mandatory.
|
||||
tags: "overview, overviewmap"
|
||||
---
|
||||
<div id="map" class="map"></div>
|
||||
|
||||
@@ -4,13 +4,22 @@ import {defaults as defaultControls, OverviewMap} from '../src/ol/control.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
|
||||
const source = new OSM();
|
||||
const overviewMapControl = new OverviewMap({
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: source
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
const map = new Map({
|
||||
controls: defaultControls().extend([
|
||||
new OverviewMap()
|
||||
overviewMapControl
|
||||
]),
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM()
|
||||
source: source
|
||||
})
|
||||
],
|
||||
target: 'map',
|
||||
|
||||
@@ -29,7 +29,7 @@ const map2 = new Map({
|
||||
preload: 0, // default value
|
||||
source: new BingMaps({
|
||||
key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5',
|
||||
imagerySet: 'AerialWithLabels'
|
||||
imagerySet: 'AerialWithLabelsOnDemand'
|
||||
})
|
||||
})
|
||||
],
|
||||
|
||||
@@ -109,7 +109,7 @@ fetch(url).then(function(response) {
|
||||
options.projection = 'EPSG:3413';
|
||||
options.wrapX = false;
|
||||
layers['wmts3413'] = new TileLayer({
|
||||
source: new WMTS(/** @type {!module:ol/source/WMTS~Options} */ (options))
|
||||
source: new WMTS(options)
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,42 +1,46 @@
|
||||
(function() {
|
||||
var clipboard = new Clipboard('#copy-button');
|
||||
clipboard.on('success', function(e) {
|
||||
|
||||
function compress(json) {
|
||||
return LZString.compressToBase64(JSON.stringify(json))
|
||||
.replace(/\+/g, `-`)
|
||||
.replace(/\//g, `_`)
|
||||
.replace(/=+$/, ``);
|
||||
}
|
||||
|
||||
var htmlClipboard = new Clipboard('#copy-html-button');
|
||||
htmlClipboard.on('success', function(e) {
|
||||
e.clearSelection();
|
||||
});
|
||||
var jsClipboard = new Clipboard('#copy-js-button');
|
||||
jsClipboard.on('success', function(e) {
|
||||
e.clearSelection();
|
||||
});
|
||||
var pkgClipboard = new Clipboard('#copy-pkg-button');
|
||||
pkgClipboard.on('success', function(e) {
|
||||
e.clearSelection();
|
||||
});
|
||||
|
||||
var codepenButton = document.getElementById('codepen-button');
|
||||
var codepenButton = document.getElementsByClassName('codepen-button')[0];
|
||||
if (codepenButton) {
|
||||
codepenButton.onclick = function(event) {
|
||||
event.preventDefault();
|
||||
var form = document.getElementById('codepen-form');
|
||||
|
||||
// Doc : https://blog.codepen.io/documentation/api/prefill/
|
||||
|
||||
var resources = form.resources.value.split(',');
|
||||
|
||||
var data = {
|
||||
title: form.title.value,
|
||||
description: form.description.value,
|
||||
layout: 'left',
|
||||
html: form.html.value,
|
||||
css: form.css.value,
|
||||
js: form.js.value,
|
||||
css_external: resources.filter(function(resource) {
|
||||
return resource.lastIndexOf('.css') === resource.length - 4;
|
||||
}).join(';'),
|
||||
js_external: resources.filter(function(resource) {
|
||||
return resource.lastIndexOf('.js') === resource.length - 3;
|
||||
}).join(';')
|
||||
};
|
||||
|
||||
// binary flags to display html, css, js and/or console tabs
|
||||
data.editors = '' + Number(data.html.length > 0) +
|
||||
Number(data.css.length > 0) +
|
||||
Number(data.js.length > 0) +
|
||||
Number(data.js.indexOf('console') > 0);
|
||||
|
||||
form.data.value = JSON.stringify(data);
|
||||
|
||||
const html = document.getElementById('example-html-source').innerText;
|
||||
const js = document.getElementById('example-js-source').innerText;
|
||||
const pkgJson = document.getElementById('example-pkg-source').innerText;
|
||||
form.parameters.value = compress({
|
||||
files: {
|
||||
'index.html': {
|
||||
content: html
|
||||
},
|
||||
'index.js': {
|
||||
content: js
|
||||
},
|
||||
"package.json": {
|
||||
content: pkgJson
|
||||
}
|
||||
}
|
||||
});
|
||||
form.submit();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -91,22 +91,27 @@ pre[class*="language-"] {
|
||||
background: #FFFFFF;
|
||||
}
|
||||
|
||||
#source-controls {
|
||||
pre>legend {
|
||||
font-size: 100%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.source-controls {
|
||||
position: absolute;
|
||||
margin-top: 20px;
|
||||
margin-top: 10px;
|
||||
right: 40px;
|
||||
}
|
||||
|
||||
#source-controls a {
|
||||
.source-controls a {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
#copy-button {
|
||||
.copy-button {
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#codepen-button {
|
||||
.codepen-button {
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -14,3 +14,19 @@ tags: "scale-line, openstreetmap"
|
||||
<option value="nautical">nautical mile</option>
|
||||
<option value="metric" selected>metric</option>
|
||||
</select>
|
||||
|
||||
<select id="type">
|
||||
<option value="scaleline">ScaleLine</option>
|
||||
<option value="scalebar">ScaleBar</option>
|
||||
</select>
|
||||
|
||||
<select id="steps" style="display:none">
|
||||
<option value=2>2 steps</option>
|
||||
<option value=4 selected>4 steps</option>
|
||||
<option value=6>6 steps</option>
|
||||
<option value=8>8 steps</option>
|
||||
</select>
|
||||
|
||||
<div id="showScaleTextDiv" style="display:none">
|
||||
<input type="checkbox" id="showScaleText" checked>Show scale text
|
||||
</div>
|
||||
|
||||
@@ -4,12 +4,36 @@ import {defaults as defaultControls, ScaleLine} from '../src/ol/control.js';
|
||||
import TileLayer from '../src/ol/layer/Tile.js';
|
||||
import OSM from '../src/ol/source/OSM.js';
|
||||
|
||||
const unitsSelect = document.getElementById('units');
|
||||
const typeSelect = document.getElementById('type');
|
||||
const stepsSelect = document.getElementById('steps');
|
||||
const scaleTextCheckbox = document.getElementById('showScaleText');
|
||||
const showScaleTextDiv = document.getElementById('showScaleTextDiv');
|
||||
|
||||
const scaleLineControl = new ScaleLine();
|
||||
let scaleType = 'scaleline';
|
||||
let scaleBarSteps = 4;
|
||||
let scaleBarText = true;
|
||||
let control;
|
||||
|
||||
function scaleControl() {
|
||||
if (scaleType === 'scaleline') {
|
||||
control = new ScaleLine({
|
||||
units: unitsSelect.value
|
||||
});
|
||||
return control;
|
||||
}
|
||||
control = new ScaleLine({
|
||||
units: unitsSelect.value,
|
||||
bar: true,
|
||||
steps: scaleBarSteps,
|
||||
text: scaleBarText,
|
||||
minWidth: 140
|
||||
});
|
||||
return control;
|
||||
}
|
||||
const map = new Map({
|
||||
controls: defaultControls().extend([
|
||||
scaleLineControl
|
||||
scaleControl()
|
||||
]),
|
||||
layers: [
|
||||
new TileLayer({
|
||||
@@ -23,10 +47,34 @@ const map = new Map({
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
const unitsSelect = document.getElementById('units');
|
||||
function onChange() {
|
||||
scaleLineControl.setUnits(unitsSelect.value);
|
||||
control.setUnits(unitsSelect.value);
|
||||
}
|
||||
function onChangeType() {
|
||||
scaleType = typeSelect.value;
|
||||
if (typeSelect.value === 'scalebar') {
|
||||
stepsSelect.style.display = 'inline';
|
||||
showScaleTextDiv.style.display = 'inline';
|
||||
map.removeControl(control);
|
||||
map.addControl(scaleControl());
|
||||
} else {
|
||||
stepsSelect.style.display = 'none';
|
||||
showScaleTextDiv.style.display = 'none';
|
||||
map.removeControl(control);
|
||||
map.addControl(scaleControl());
|
||||
}
|
||||
}
|
||||
function onChangeSteps() {
|
||||
scaleBarSteps = parseInt(stepsSelect.value, 10);
|
||||
map.removeControl(control);
|
||||
map.addControl(scaleControl());
|
||||
}
|
||||
function onChangeScaleText() {
|
||||
scaleBarText = scaleTextCheckbox.checked;
|
||||
map.removeControl(control);
|
||||
map.addControl(scaleControl());
|
||||
}
|
||||
unitsSelect.addEventListener('change', onChange);
|
||||
onChange();
|
||||
typeSelect.addEventListener('change', onChangeType);
|
||||
stepsSelect.addEventListener('change', onChangeSteps);
|
||||
scaleTextCheckbox.addEventListener('change', onChangeScaleText);
|
||||
|
||||
@@ -2,7 +2,7 @@ import Map from '../src/ol/Map.js';
|
||||
import View from '../src/ol/View.js';
|
||||
import {Image as ImageLayer, Tile as TileLayer} from '../src/ol/layer.js';
|
||||
import {fromLonLat} from '../src/ol/proj.js';
|
||||
import RasterSource from '../src/ol/source/Raster.js';
|
||||
import {Raster as RasterSource, TileJSON} from '../src/ol/source.js';
|
||||
import XYZ from '../src/ol/source/XYZ.js';
|
||||
|
||||
function flood(pixels, data) {
|
||||
@@ -37,8 +37,9 @@ const map = new Map({
|
||||
target: 'map',
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new XYZ({
|
||||
url: 'https://api.mapbox.com/styles/v1/tschaub/ciutc102t00c62js5fqd47kqw/tiles/256/{z}/{x}/{y}?access_token=' + key
|
||||
source: new TileJSON({
|
||||
url: 'https://api.tiles.mapbox.com/v3/mapbox.world-light.json?secure',
|
||||
crossOrigin: 'anonymous'
|
||||
})
|
||||
}),
|
||||
new ImageLayer({
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user