diff --git a/georeference/proxy_models.py b/georeference/proxy_models.py index f74c7a44..26c7baec 100644 --- a/georeference/proxy_models.py +++ b/georeference/proxy_models.py @@ -220,7 +220,7 @@ def get_layer(self): try: link = GeoreferencedDocumentLink.objects.get(document=self.id) layer = Layer.objects.get(id=link.object_id) - except (GeoreferencedDocumentLink.DoesNotExist, Layer.DoesNotExist): + except (GeoreferencedDocumentLink.DoesNotExist, Layer.DoesNotExist, GeoreferencedDocumentLink.MultipleObjectsReturned): layer = None return layer @@ -454,6 +454,7 @@ def serialize(self): "status": self.status, "urls": self.get_extended_urls(), "lock": self.lock.as_dict, + "mask_coords": self.mask_coords, } def get_info_panel_content(resourceid): diff --git a/loc_insurancemaps/components/package-lock.json b/loc_insurancemaps/components/package-lock.json index d9cf240c..ab4e2dce 100644 --- a/loc_insurancemaps/components/package-lock.json +++ b/loc_insurancemaps/components/package-lock.json @@ -8,7 +8,8 @@ "name": "svelte-app", "version": "1.0.0", "dependencies": { - "ol": "^6.4.3", + "ol": "^6.15.1", + "ol-ext": "^3.2.28", "sirv-cli": "^1.0.0", "svelte-dragdroplist": "^1.1.1", "svelte-tablesort": "^1.1.0" @@ -62,15 +63,15 @@ "node_modules/@mapbox/jsonlint-lines-primitives": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz", - "integrity": "sha1-zlblOfg1UrWNENZy6k1vya3HsjQ=", + "integrity": "sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==", "engines": { "node": ">= 0.6" } }, "node_modules/@mapbox/mapbox-gl-style-spec": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-style-spec/-/mapbox-gl-style-spec-13.23.0.tgz", - "integrity": "sha512-zI26XoK0UjGOvOEUUAoKlmFKHrSD8qIMCaoQBsFxNPzGIluryT32Z1m4aq7NtxEsrfE+qc2mPPXQg+iRllqbqA==", + "version": "13.25.0", + "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-style-spec/-/mapbox-gl-style-spec-13.25.0.tgz", + "integrity": "sha512-ukBk13MyI/X4tjRfPaNCo4rJLrRJ7ZbANxjeQyGeLYJTF1DZxqkX9C8qlxnQlxYllBBDBWiYYX5lU1fIsm2jwg==", "dependencies": { "@mapbox/jsonlint-lines-primitives": "~2.0.2", "@mapbox/point-geometry": "^0.1.0", @@ -82,26 +83,26 @@ "sort-object": "^0.3.2" }, "bin": { - "gl-style-composite": "bin/gl-style-composite", - "gl-style-format": "bin/gl-style-format", - "gl-style-migrate": "bin/gl-style-migrate", - "gl-style-validate": "bin/gl-style-validate" + "gl-style-composite": "bin/gl-style-composite.js", + "gl-style-format": "bin/gl-style-format.js", + "gl-style-migrate": "bin/gl-style-migrate.js", + "gl-style-validate": "bin/gl-style-validate.js" } }, "node_modules/@mapbox/point-geometry": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz", - "integrity": "sha1-ioP5M1x4YO/6Lu7KJUMyqgru2PI=" + "integrity": "sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==" }, "node_modules/@mapbox/unitbezier": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.0.tgz", - "integrity": "sha1-FWUb1VOme4WB+zmIEMmK2Go0Uk4=" + "integrity": "sha512-HPnRdYO0WjFjRTSwO3frz1wKaU649OBFPX3Zo/2WZvuRi6zMiRGui8SnPQiQABgqCf8YikDe5t3HViTVw1WUzA==" }, "node_modules/@petamoriken/float16": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.5.11.tgz", - "integrity": "sha512-aKJaQhvWcP4XRo4eb34VygcqNsE1+Ej5687oexkK+qYWC7tejxaWRkAfE54Ze3xQGnvwXHZ5Ahx6CWq5sS4q7Q==" + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.6.5.tgz", + "integrity": "sha512-m5ox8pj4LfAoTO2GqrqCCD9hNX3I73+Dv2pvdGKFHkNHWQh9Z4q/5Du5+ZBYYotneqrliFWR8olMSdnPhmjU2w==" }, "node_modules/@polka/url": { "version": "1.0.0-next.20", @@ -273,14 +274,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "engines": { - "node": ">=6" - } - }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -360,23 +353,7 @@ "node_modules/csscolorparser": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz", - "integrity": "sha1-s085HupNqPPpgjHizNjfnAQfFxs=" - }, - "node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } + "integrity": "sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w==" }, "node_modules/deepmerge": { "version": "4.2.2", @@ -396,15 +373,6 @@ "node": ">=0.8.0" } }, - "node_modules/esm": { - "version": "3.2.25", - "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", - "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", - "optional": true, - "engines": { - "node": ">=6" - } - }, "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", @@ -455,16 +423,16 @@ "integrity": "sha512-xzVvVuMrRvINjet6x7Hlv4fbupUBuswkefe62YRejY1olzpdRNdTX655jw30ELgm5UJOMzZRoPlmVXVS0GFADQ==" }, "node_modules/geotiff": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/geotiff/-/geotiff-1.0.8.tgz", - "integrity": "sha512-3YA6NpGuuXF+WwwgA7moSHIw1U0XHxBY8W5bjjoSGBCVuw6s+DOgt7Z95Y3bf5k19RHixv6zW8KpW/yrRno43Q==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/geotiff/-/geotiff-2.0.4.tgz", + "integrity": "sha512-aG8h9bJccGusioPsEWsEqx8qdXpZN71A20WCvRKGxcnHSOWLKmC5ZmsAmodfxb9TRQvs+89KikGuPzxchhA+Uw==", "dependencies": { "@petamoriken/float16": "^3.4.7", "lerc": "^3.0.0", "lru-cache": "^6.0.0", "pako": "^2.0.4", "parse-headers": "^2.0.2", - "threads": "^1.7.0", + "web-worker": "^1.2.0", "xml-utils": "^1.0.2" }, "engines": { @@ -628,17 +596,6 @@ "node": ">=0.12.0" } }, - "node_modules/is-observable": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-2.1.0.tgz", - "integrity": "sha512-DailKdLb0WU+xX8K5w7VsJhapwHLZ9jjmazqCJq4X12CTgqq73TKnbRcnSLuXYPOoLQgV5IrD7ePiX/h1vnkBw==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-reference": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", @@ -760,9 +717,9 @@ } }, "node_modules/mapbox-to-css-font": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/mapbox-to-css-font/-/mapbox-to-css-font-2.4.0.tgz", - "integrity": "sha512-v674D0WtpxCXlA6E+sBlG1QJWdUkz/s9qAD91bJSXBGuBL5lL4tJXpoJEftecphCh2SVQCjWMS2vhylc3AIQTg==" + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/mapbox-to-css-font/-/mapbox-to-css-font-2.4.1.tgz", + "integrity": "sha512-QQ/iKiM43DM9+aujTL45Iz5o7gDeSFmy4LPl3HZmNcwCE++NxGazf+yFpY+wCb+YS23sDa1ghpo3zrNFOcHlow==" }, "node_modules/merge-stream": { "version": "2.0.0", @@ -794,9 +751,9 @@ } }, "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "node_modules/mri": { "version": "1.2.0", @@ -806,11 +763,6 @@ "node": ">=4" } }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -820,18 +772,13 @@ "node": ">=0.10.0" } }, - "node_modules/observable-fns": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/observable-fns/-/observable-fns-0.6.1.tgz", - "integrity": "sha512-9gRK4+sRWzeN6AOewNBTLXir7Zl/i3GB6Yl26gK4flxz8BXVpD3kt8amREmWNb0mxYOGDotvE5a4N+PtGGKdkg==" - }, "node_modules/ol": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/ol/-/ol-6.9.0.tgz", - "integrity": "sha512-VmU5HKHwO2O1uGgmBcng/dL1PouVB1jKiYUbiXPR5l1i/3B3qatexl4rapZAnsGx0vsOC7lI1GLx7jEZro8C8Q==", + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/ol/-/ol-6.15.1.tgz", + "integrity": "sha512-ZG2CKTpJ8Q+tPywYysVwPk+yevwJzlbwjRKhoCvd7kLVWMbfBl1O/+Kg/yrZZrhG9FNXbFH4GeOZ5yVRqo3P4w==", "dependencies": { - "geotiff": "^1.0.8", - "ol-mapbox-style": "^6.5.1", + "geotiff": "2.0.4", + "ol-mapbox-style": "^8.0.5", "pbf": "3.2.1", "rbush": "^3.0.1" }, @@ -840,14 +787,21 @@ "url": "https://opencollective.com/openlayers" } }, + "node_modules/ol-ext": { + "version": "3.2.28", + "resolved": "https://registry.npmjs.org/ol-ext/-/ol-ext-3.2.28.tgz", + "integrity": "sha512-sfY25AWztCVyLXewB6EYtjCnzl2SYISdzQlKhfFb1gXTEWSwSDvBYNCGVWKU8mc7uisjploYOMfG7hi4+DNDWQ==", + "peerDependencies": { + "ol": ">= 5.3.0" + } + }, "node_modules/ol-mapbox-style": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/ol-mapbox-style/-/ol-mapbox-style-6.5.3.tgz", - "integrity": "sha512-2SNJQ/7acgACC4nnuKCm9qeMXK2LEeUQWZWRKlXNCstjRf7SDcQvSFXrNSlDLvzhtQ0Gv3QTX5L7plE2wm7Z3Q==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ol-mapbox-style/-/ol-mapbox-style-8.2.0.tgz", + "integrity": "sha512-WyCiNUj5DiD3+MvgqXvxSf0mDUvagtlq9JQ97mHwDD1FliHt5G1333Lvqskg8psBfxijHSEWNHwqzBGnEUo1bw==", "dependencies": { - "@mapbox/mapbox-gl-style-spec": "^13.20.1", - "mapbox-to-css-font": "^2.4.0", - "webfont-matcher": "^1.1.0" + "@mapbox/mapbox-gl-style-spec": "^13.23.1", + "mapbox-to-css-font": "^2.4.1" } }, "node_modules/once": { @@ -871,9 +825,9 @@ "integrity": "sha512-v8tweI900AUkZN6heMU/4Uy4cXRc2AYNRggVmTR+dEncawDJgCdLMximOVA2p4qO57WMynangsfGRb5WD6L1Bg==" }, "node_modules/parse-headers": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.4.tgz", - "integrity": "sha512-psZ9iZoCNFLrgRjZ1d8mn0h9WRqJwFxM9q3x7iUjN/YT2OksthDJ5TiPCu2F38kS4zutqfW+YdVVkBZZx3/1aw==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", + "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==" }, "node_modules/path-is-absolute": { "version": "1.0.1", @@ -1085,7 +1039,7 @@ "node_modules/rw": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=" + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" }, "node_modules/sade": { "version": "1.7.4", @@ -1172,7 +1126,7 @@ "node_modules/sort-asc": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/sort-asc/-/sort-asc-0.1.0.tgz", - "integrity": "sha1-q3md9h/HPqCVbHnEtTHtHp53J+k=", + "integrity": "sha512-jBgdDd+rQ+HkZF2/OHCmace5dvpos/aWQpcxuyRs9QUbPRnkEJmYVo81PIGpjIdpOcsnJ4rGjStfDHsbn+UVyw==", "engines": { "node": ">=0.10.0" } @@ -1180,7 +1134,7 @@ "node_modules/sort-desc": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/sort-desc/-/sort-desc-0.1.1.tgz", - "integrity": "sha1-GYuMDN6wlcRjNBhh45JdTuNZqe4=", + "integrity": "sha512-jfZacW5SKOP97BF5rX5kQfJmRVZP5/adDUTY8fCSPvNcXDVpUEe2pr/iKGlcyZzchRJZrswnp68fgk3qBXgkJw==", "engines": { "node": ">=0.10.0" } @@ -1188,7 +1142,7 @@ "node_modules/sort-object": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/sort-object/-/sort-object-0.3.2.tgz", - "integrity": "sha1-mODRme3kDgfGGoRAPGHWw7KQ+eI=", + "integrity": "sha512-aAQiEdqFTTdsvUFxXm3umdo04J7MRljoVGbBlkH7BgNsMvVNAJyGj7C/wV1A8wHWAJj/YikeZbfuCKqhggNWGA==", "dependencies": { "sort-asc": "^0.1.0", "sort-desc": "^0.1.1" @@ -1284,32 +1238,6 @@ "node": ">=10" } }, - "node_modules/threads": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/threads/-/threads-1.7.0.tgz", - "integrity": "sha512-Mx5NBSHX3sQYR6iI9VYbgHKBLisyB+xROCBGjjWm1O9wb9vfLxdaGtmT/KCjUqMsSNW6nERzCW3T6H43LqjDZQ==", - "dependencies": { - "callsites": "^3.1.0", - "debug": "^4.2.0", - "is-observable": "^2.1.0", - "observable-fns": "^0.6.1" - }, - "funding": { - "url": "https://github.com/andywer/threads.js?sponsor=1" - }, - "optionalDependencies": { - "tiny-worker": ">= 2" - } - }, - "node_modules/tiny-worker": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tiny-worker/-/tiny-worker-2.3.0.tgz", - "integrity": "sha512-pJ70wq5EAqTAEl9IkGzA+fN0836rycEuz2Cn6yeZ6FRzlVS5IDOkFHpIoEsksPRQV34GDqXm65+OlnZqUSyK2g==", - "optional": true, - "dependencies": { - "esm": "^3.2.25" - } - }, "node_modules/tinydate": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/tinydate/-/tinydate-1.3.0.tgz", @@ -1338,10 +1266,10 @@ "node": ">=6" } }, - "node_modules/webfont-matcher": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/webfont-matcher/-/webfont-matcher-1.1.0.tgz", - "integrity": "sha1-mM6VCXsp4x++czBT4Q5XFkLRxsc=" + "node_modules/web-worker": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", + "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" }, "node_modules/wrappy": { "version": "1.0.2", @@ -1371,9 +1299,9 @@ } }, "node_modules/xml-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/xml-utils/-/xml-utils-1.0.2.tgz", - "integrity": "sha512-rEn0FvKi+YGjv9omf22oAf+0d6Ly/sgJ/CUufU/nOzS7SRLmgwSujrewc03KojXxt+aPaTRpm593TgehtUBMSQ==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xml-utils/-/xml-utils-1.1.0.tgz", + "integrity": "sha512-QyimYENdNHe6sQb+YJM+vFoAzz4ApGMnQltP7IIAMyScvWheHKayire5vD5UB6Vaazi2DwamibeehlQgnrOPXA==" }, "node_modules/yallist": { "version": "4.0.0", @@ -1411,12 +1339,12 @@ "@mapbox/jsonlint-lines-primitives": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz", - "integrity": "sha1-zlblOfg1UrWNENZy6k1vya3HsjQ=" + "integrity": "sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==" }, "@mapbox/mapbox-gl-style-spec": { - "version": "13.23.0", - "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-style-spec/-/mapbox-gl-style-spec-13.23.0.tgz", - "integrity": "sha512-zI26XoK0UjGOvOEUUAoKlmFKHrSD8qIMCaoQBsFxNPzGIluryT32Z1m4aq7NtxEsrfE+qc2mPPXQg+iRllqbqA==", + "version": "13.25.0", + "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-style-spec/-/mapbox-gl-style-spec-13.25.0.tgz", + "integrity": "sha512-ukBk13MyI/X4tjRfPaNCo4rJLrRJ7ZbANxjeQyGeLYJTF1DZxqkX9C8qlxnQlxYllBBDBWiYYX5lU1fIsm2jwg==", "requires": { "@mapbox/jsonlint-lines-primitives": "~2.0.2", "@mapbox/point-geometry": "^0.1.0", @@ -1431,17 +1359,17 @@ "@mapbox/point-geometry": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz", - "integrity": "sha1-ioP5M1x4YO/6Lu7KJUMyqgru2PI=" + "integrity": "sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==" }, "@mapbox/unitbezier": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.0.tgz", - "integrity": "sha1-FWUb1VOme4WB+zmIEMmK2Go0Uk4=" + "integrity": "sha512-HPnRdYO0WjFjRTSwO3frz1wKaU649OBFPX3Zo/2WZvuRi6zMiRGui8SnPQiQABgqCf8YikDe5t3HViTVw1WUzA==" }, "@petamoriken/float16": { - "version": "3.5.11", - "resolved": "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.5.11.tgz", - "integrity": "sha512-aKJaQhvWcP4XRo4eb34VygcqNsE1+Ej5687oexkK+qYWC7tejxaWRkAfE54Ze3xQGnvwXHZ5Ahx6CWq5sS4q7Q==" + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.6.5.tgz", + "integrity": "sha512-m5ox8pj4LfAoTO2GqrqCCD9hNX3I73+Dv2pvdGKFHkNHWQh9Z4q/5Du5+ZBYYotneqrliFWR8olMSdnPhmjU2w==" }, "@polka/url": { "version": "1.0.0-next.20", @@ -1579,11 +1507,6 @@ "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", "dev": true }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -1652,15 +1575,7 @@ "csscolorparser": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz", - "integrity": "sha1-s085HupNqPPpgjHizNjfnAQfFxs=" - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "requires": { - "ms": "2.1.2" - } + "integrity": "sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w==" }, "deepmerge": { "version": "4.2.2", @@ -1674,12 +1589,6 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, - "esm": { - "version": "3.2.25", - "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", - "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", - "optional": true - }, "estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", @@ -1720,16 +1629,16 @@ "integrity": "sha512-xzVvVuMrRvINjet6x7Hlv4fbupUBuswkefe62YRejY1olzpdRNdTX655jw30ELgm5UJOMzZRoPlmVXVS0GFADQ==" }, "geotiff": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/geotiff/-/geotiff-1.0.8.tgz", - "integrity": "sha512-3YA6NpGuuXF+WwwgA7moSHIw1U0XHxBY8W5bjjoSGBCVuw6s+DOgt7Z95Y3bf5k19RHixv6zW8KpW/yrRno43Q==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/geotiff/-/geotiff-2.0.4.tgz", + "integrity": "sha512-aG8h9bJccGusioPsEWsEqx8qdXpZN71A20WCvRKGxcnHSOWLKmC5ZmsAmodfxb9TRQvs+89KikGuPzxchhA+Uw==", "requires": { "@petamoriken/float16": "^3.4.7", "lerc": "^3.0.0", "lru-cache": "^6.0.0", "pako": "^2.0.4", "parse-headers": "^2.0.2", - "threads": "^1.7.0", + "web-worker": "^1.2.0", "xml-utils": "^1.0.2" } }, @@ -1842,11 +1751,6 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, - "is-observable": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-2.1.0.tgz", - "integrity": "sha512-DailKdLb0WU+xX8K5w7VsJhapwHLZ9jjmazqCJq4X12CTgqq73TKnbRcnSLuXYPOoLQgV5IrD7ePiX/h1vnkBw==" - }, "is-reference": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", @@ -1946,9 +1850,9 @@ } }, "mapbox-to-css-font": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/mapbox-to-css-font/-/mapbox-to-css-font-2.4.0.tgz", - "integrity": "sha512-v674D0WtpxCXlA6E+sBlG1QJWdUkz/s9qAD91bJSXBGuBL5lL4tJXpoJEftecphCh2SVQCjWMS2vhylc3AIQTg==" + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/mapbox-to-css-font/-/mapbox-to-css-font-2.4.1.tgz", + "integrity": "sha512-QQ/iKiM43DM9+aujTL45Iz5o7gDeSFmy4LPl3HZmNcwCE++NxGazf+yFpY+wCb+YS23sDa1ghpo3zrNFOcHlow==" }, "merge-stream": { "version": "2.0.0", @@ -1971,50 +1875,45 @@ } }, "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "mri": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==" }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "observable-fns": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/observable-fns/-/observable-fns-0.6.1.tgz", - "integrity": "sha512-9gRK4+sRWzeN6AOewNBTLXir7Zl/i3GB6Yl26gK4flxz8BXVpD3kt8amREmWNb0mxYOGDotvE5a4N+PtGGKdkg==" - }, "ol": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/ol/-/ol-6.9.0.tgz", - "integrity": "sha512-VmU5HKHwO2O1uGgmBcng/dL1PouVB1jKiYUbiXPR5l1i/3B3qatexl4rapZAnsGx0vsOC7lI1GLx7jEZro8C8Q==", + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/ol/-/ol-6.15.1.tgz", + "integrity": "sha512-ZG2CKTpJ8Q+tPywYysVwPk+yevwJzlbwjRKhoCvd7kLVWMbfBl1O/+Kg/yrZZrhG9FNXbFH4GeOZ5yVRqo3P4w==", "requires": { - "geotiff": "^1.0.8", - "ol-mapbox-style": "^6.5.1", + "geotiff": "2.0.4", + "ol-mapbox-style": "^8.0.5", "pbf": "3.2.1", "rbush": "^3.0.1" } }, + "ol-ext": { + "version": "3.2.28", + "resolved": "https://registry.npmjs.org/ol-ext/-/ol-ext-3.2.28.tgz", + "integrity": "sha512-sfY25AWztCVyLXewB6EYtjCnzl2SYISdzQlKhfFb1gXTEWSwSDvBYNCGVWKU8mc7uisjploYOMfG7hi4+DNDWQ==", + "requires": {} + }, "ol-mapbox-style": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/ol-mapbox-style/-/ol-mapbox-style-6.5.3.tgz", - "integrity": "sha512-2SNJQ/7acgACC4nnuKCm9qeMXK2LEeUQWZWRKlXNCstjRf7SDcQvSFXrNSlDLvzhtQ0Gv3QTX5L7plE2wm7Z3Q==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ol-mapbox-style/-/ol-mapbox-style-8.2.0.tgz", + "integrity": "sha512-WyCiNUj5DiD3+MvgqXvxSf0mDUvagtlq9JQ97mHwDD1FliHt5G1333Lvqskg8psBfxijHSEWNHwqzBGnEUo1bw==", "requires": { - "@mapbox/mapbox-gl-style-spec": "^13.20.1", - "mapbox-to-css-font": "^2.4.0", - "webfont-matcher": "^1.1.0" + "@mapbox/mapbox-gl-style-spec": "^13.23.1", + "mapbox-to-css-font": "^2.4.1" } }, "once": { @@ -2038,9 +1937,9 @@ "integrity": "sha512-v8tweI900AUkZN6heMU/4Uy4cXRc2AYNRggVmTR+dEncawDJgCdLMximOVA2p4qO57WMynangsfGRb5WD6L1Bg==" }, "parse-headers": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.4.tgz", - "integrity": "sha512-psZ9iZoCNFLrgRjZ1d8mn0h9WRqJwFxM9q3x7iUjN/YT2OksthDJ5TiPCu2F38kS4zutqfW+YdVVkBZZx3/1aw==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz", + "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==" }, "path-is-absolute": { "version": "1.0.1", @@ -2210,7 +2109,7 @@ "rw": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=" + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" }, "sade": { "version": "1.7.4", @@ -2268,17 +2167,17 @@ "sort-asc": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/sort-asc/-/sort-asc-0.1.0.tgz", - "integrity": "sha1-q3md9h/HPqCVbHnEtTHtHp53J+k=" + "integrity": "sha512-jBgdDd+rQ+HkZF2/OHCmace5dvpos/aWQpcxuyRs9QUbPRnkEJmYVo81PIGpjIdpOcsnJ4rGjStfDHsbn+UVyw==" }, "sort-desc": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/sort-desc/-/sort-desc-0.1.1.tgz", - "integrity": "sha1-GYuMDN6wlcRjNBhh45JdTuNZqe4=" + "integrity": "sha512-jfZacW5SKOP97BF5rX5kQfJmRVZP5/adDUTY8fCSPvNcXDVpUEe2pr/iKGlcyZzchRJZrswnp68fgk3qBXgkJw==" }, "sort-object": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/sort-object/-/sort-object-0.3.2.tgz", - "integrity": "sha1-mODRme3kDgfGGoRAPGHWw7KQ+eI=", + "integrity": "sha512-aAQiEdqFTTdsvUFxXm3umdo04J7MRljoVGbBlkH7BgNsMvVNAJyGj7C/wV1A8wHWAJj/YikeZbfuCKqhggNWGA==", "requires": { "sort-asc": "^0.1.0", "sort-desc": "^0.1.1" @@ -2353,27 +2252,6 @@ "source-map-support": "~0.5.20" } }, - "threads": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/threads/-/threads-1.7.0.tgz", - "integrity": "sha512-Mx5NBSHX3sQYR6iI9VYbgHKBLisyB+xROCBGjjWm1O9wb9vfLxdaGtmT/KCjUqMsSNW6nERzCW3T6H43LqjDZQ==", - "requires": { - "callsites": "^3.1.0", - "debug": "^4.2.0", - "is-observable": "^2.1.0", - "observable-fns": "^0.6.1", - "tiny-worker": ">= 2" - } - }, - "tiny-worker": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tiny-worker/-/tiny-worker-2.3.0.tgz", - "integrity": "sha512-pJ70wq5EAqTAEl9IkGzA+fN0836rycEuz2Cn6yeZ6FRzlVS5IDOkFHpIoEsksPRQV34GDqXm65+OlnZqUSyK2g==", - "optional": true, - "requires": { - "esm": "^3.2.25" - } - }, "tinydate": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/tinydate/-/tinydate-1.3.0.tgz", @@ -2393,10 +2271,10 @@ "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==" }, - "webfont-matcher": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/webfont-matcher/-/webfont-matcher-1.1.0.tgz", - "integrity": "sha1-mM6VCXsp4x++czBT4Q5XFkLRxsc=" + "web-worker": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", + "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" }, "wrappy": { "version": "1.0.2", @@ -2412,9 +2290,9 @@ "requires": {} }, "xml-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/xml-utils/-/xml-utils-1.0.2.tgz", - "integrity": "sha512-rEn0FvKi+YGjv9omf22oAf+0d6Ly/sgJ/CUufU/nOzS7SRLmgwSujrewc03KojXxt+aPaTRpm593TgehtUBMSQ==" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xml-utils/-/xml-utils-1.1.0.tgz", + "integrity": "sha512-QyimYENdNHe6sQb+YJM+vFoAzz4ApGMnQltP7IIAMyScvWheHKayire5vD5UB6Vaazi2DwamibeehlQgnrOPXA==" }, "yallist": { "version": "4.0.0", diff --git a/loc_insurancemaps/components/package.json b/loc_insurancemaps/components/package.json index 3cc271cc..65755e63 100644 --- a/loc_insurancemaps/components/package.json +++ b/loc_insurancemaps/components/package.json @@ -17,7 +17,8 @@ "svelte": "^3.0.0" }, "dependencies": { - "ol": "^6.4.3", + "ol": "^6.15.1", + "ol-ext": "^3.2.28", "sirv-cli": "^1.0.0", "svelte-dragdroplist": "^1.1.1", "svelte-tablesort": "^1.1.0" diff --git a/loc_insurancemaps/components/rollup.config.js b/loc_insurancemaps/components/rollup.config.js index 2017aa6b..c9a8e7ac 100644 --- a/loc_insurancemaps/components/rollup.config.js +++ b/loc_insurancemaps/components/rollup.config.js @@ -34,8 +34,9 @@ function componentExportDetails(componentName) { output: { sourcemap: true, format: 'iife', - name: `${componentName.toLowerCase()}`, - file: `public/build/${componentName}.js`, + name: `${componentName.toLowerCase()}`, + file: `public/build/${componentName}.js`, + inlineDynamicImports: true, }, plugins: [ svelte({ @@ -84,6 +85,7 @@ let exportable = []; "Volumes", "Volume", "VolumeSearch", + "MultiTrim", ].forEach((d) => exportable.push(componentExportDetails(d))); export default exportable; diff --git a/loc_insurancemaps/components/src/MultiTrim.svelte b/loc_insurancemaps/components/src/MultiTrim.svelte new file mode 100644 index 00000000..30c9717f --- /dev/null +++ b/loc_insurancemaps/components/src/MultiTrim.svelte @@ -0,0 +1,492 @@ + + + {if (!leaveOkay) {confirmLeave()}}}/> + + + +
+ {#if USER_TYPE == "anonymous"}

Feel free to mess around; you can't save changes unless you are logged in.

{/if} +
+
+
+
+ Main Content setMapExtent()}>🔎 +
+
+ {#each layerLookupArr as layer} +
+ {#if !layer.feature } + + {:else} + + {/if} +   + {#if currentLayer == layer.layerDef.name}
showExtent(layer)}>sheet {layer.layerDef.page_str}
+ {:else} +
zoomToLayer(layer)} on:mouseover={() => showExtent(layer)}>sheet {layer.layerDef.page_str}
+ {/if} +
+ {:else} +
No layers
+ {/each} +
+
+ + + +
+
+
+
+ + diff --git a/loc_insurancemaps/components/src/Volume.svelte b/loc_insurancemaps/components/src/Volume.svelte index 312bf36b..8d09078e 100644 --- a/loc_insurancemaps/components/src/Volume.svelte +++ b/loc_insurancemaps/components/src/Volume.svelte @@ -19,10 +19,14 @@ import XYZ from 'ol/source/XYZ'; import TileWMS from 'ol/source/TileWMS'; import VectorSource from 'ol/source/Vector'; +import Crop from 'ol-ext/filter/Crop'; + import Feature from 'ol/Feature'; import Polygon from 'ol/geom/Polygon'; import Point from 'ol/geom/Point'; +import GeoJSON from 'ol/format/GeoJSON'; + import Style from 'ol/style/Style'; import Fill from 'ol/style/Fill'; import Stroke from 'ol/style/Stroke'; @@ -38,6 +42,7 @@ export let CSRFTOKEN; export let USER_TYPE; export let GEOSERVER_WMS; export let MAPBOX_API_KEY; +export let USE_TITILER; $: sheetsLoading = VOLUME.status == "initializing..."; let loadTip = false; @@ -228,6 +233,13 @@ function makeRotateCenterLayer() { return layer } +function getTitilerXYZUrl(layername) { + const titilerUrl = "https://titiler.legiongis.com"; + const cogUrl = "https%3A%2F%2Foldinsurancemaps.net%2Fuploaded%2Fcog%2F"+ layername + ".tif"; + const xyzUrl = titilerUrl +"/cog/tiles/{z}/{x}/{y}.png?TileMatrixSetId=WebMercatorQuad&url=" + cogUrl; + return xyzUrl +} + function showRotateCenter() { if (map && centerPointLayer) { const centerCoords = map.getView().getCenter(); @@ -300,20 +312,46 @@ function setLayersFromVolume(setExtent) { }) // create the actual ol layers and add to group. - const newLayer = new TileLayer({ - source: new TileWMS({ - url: GEOSERVER_WMS, - params: { - 'LAYERS': layerDef.geoserver_id, - 'TILED': true, - }, - tileGrid: tileGrid, - }), - extent: transformExtent(layerDef.extent, "EPSG:4326", "EPSG:3857") - }); + let newLayer; + if (USE_TITILER) { + newLayer = new TileLayer({ + source: new XYZ({ + url: getTitilerXYZUrl(layerDef.name), + }), + extent: transformExtent(layerDef.extent, "EPSG:4326", "EPSG:3857") + }); + } else { + newLayer = new TileLayer({ + source: new TileWMS({ + url: GEOSERVER_WMS, + params: { + 'LAYERS': layerDef.geoserver_id, + 'TILED': true, + }, + tileGrid: tileGrid, + }), + extent: transformExtent(layerDef.extent, "EPSG:4326", "EPSG:3857") + }); + } layerRegistry[layerDef.geoserver_id] = newLayer; mainGroup.getLayers().push(newLayer) + + + if (VOLUME.multimask) { + Object.entries(VOLUME.multimask).forEach(kV => { + if (kV[0] == layerDef.name) { + const feature = new GeoJSON().readFeature(kV[1]) + feature.getGeometry().transform("EPSG:4326", "EPSG:3857") + const crop = new Crop({ + feature: feature, + wrapX: true, + inner: false + }); + newLayer.addFilter(crop); + } + }); + } }); VOLUME.ordered_layers.index_layers.forEach( function(layerDef, n) { @@ -325,17 +363,28 @@ function setLayersFromVolume(setExtent) { }) // create the actual ol layers and add to group. - const newLayer = new TileLayer({ - source: new TileWMS({ - url: GEOSERVER_WMS, - params: { - 'LAYERS': layerDef.geoserver_id, - 'TILED': true, - }, - tileGrid: tileGrid, - }), - extent: transformExtent(layerDef.extent, "EPSG:4326", "EPSG:3857") - }); + let newLayer; + if (USE_TITILER) { + newLayer = new TileLayer({ + source: new XYZ({ + url: getTitilerXYZUrl(layerDef.name), + }), + extent: transformExtent(layerDef.extent, "EPSG:4326", "EPSG:3857") + }); + } else { + newLayer = new TileLayer({ + source: new TileWMS({ + url: GEOSERVER_WMS, + params: { + 'LAYERS': layerDef.geoserver_id, + 'TILED': true, + }, + tileGrid: tileGrid, + }), + extent: transformExtent(layerDef.extent, "EPSG:4326", "EPSG:3857") + }); + } + layerRegistry[layerDef.geoserver_id] = newLayer; keyGroup.getLayers().push(newLayer) }); @@ -569,18 +618,9 @@ function handleKeyup(e) { {/if} - {#if USER_TYPE != 'anonymous'} - {/if}
diff --git a/loc_insurancemaps/components/src/Volumes.svelte b/loc_insurancemaps/components/src/Volumes.svelte index 40656b78..86f4cd32 100644 --- a/loc_insurancemaps/components/src/Volumes.svelte +++ b/loc_insurancemaps/components/src/Volumes.svelte @@ -22,6 +22,7 @@ export let STARTED_VOLUMES; P G % + MM @@ -34,6 +35,7 @@ export let STARTED_VOLUMES; {v.prepared_ct} {v.georeferenced_ct}
+ {v.mm_display} {/if} @@ -68,4 +70,4 @@ main { } } - \ No newline at end of file + diff --git a/loc_insurancemaps/components/src/css/interface.css b/loc_insurancemaps/components/src/css/interface.css new file mode 100644 index 00000000..06d64db9 --- /dev/null +++ b/loc_insurancemaps/components/src/css/interface.css @@ -0,0 +1,233 @@ +.svelte-component-main { + height: 600px; + padding: 0; + display: flex; + flex-direction: column; + border-radius: 4px; + background: rgb(235, 235, 235); + border: 1.5px solid rgb(150, 150, 150); + position: relative; +} + +.svelte-component-main nav { + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + margin: 5px 0px; + padding: 0px 5px; +} + +.svelte-component-main nav button { + height: 30px; + min-width: 25px; + color: white; + background: #2c689c; + border-radius: 4px; +} + +.svelte-component-main nav button:disabled { + color: grey; + background: rgb(235, 235, 235);; +} + +.svelte-component-main nav label { + margin: 0px; +} + +.svelte-component-main nav select:disabled { + color: grey; +} + +.signin-reminder { + background: #e6e6e6; + text-align: center; + padding: 5px; + margin: 5px; + border-radius: 4px; +} + +.signin-reminder p { + margin: 0px; +} + +.interface-mask { + height: 597px; /* 600 - 2 * 1.5px borders on the main component */ + width: 100%; + position: absolute; + background: rgba(255, 255, 255, 0.5); + border-radius: 4px; + z-index: 1000; + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + text-align: center; + padding-top: 275px; +} + +#doc-viewer { + background: url('../static/img/sandpaper-bg-vlite.jpg') +} + +.map-container { + display: flex; + /* height: calc(100% - 4em); */ + height: 100%; + justify-content: space-between; +} + +.map-item { + width: 100% +} + +.rounded-bottom { + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; +} + +/* hide on small screens */ +@media screen and (max-width: 768px){ + .hidden-small { + display: none; + } + .svelte-component-main nav { + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-between; + margin: 5px 0px; + padding: 0px 5px; + } +} + +/* pure css loading bar */ +/* from https://loading.io/css/ */ +#preview-loading { + position: absolute; + right: 25px; + width: 80px; + height: 80px; +} + +#interface-loading { + position: relative; +} + +#interface-loading div { + background: rgb(61, 61, 61); +} + +.lds-ellipsis { + display: inline-block; + /* position: absolute; + right: 25px; + width: 80px; + height: 80px; */ +} +.lds-ellipsis div { + position: absolute; + top: 33px; + width: 13px; + height: 13px; + border-radius: 50%; + background: #000; + animation-timing-function: cubic-bezier(0, 1, 1, 0); +} +.lds-ellipsis div:nth-child(1) { + left: 8px; + animation: lds-ellipsis1 0.6s infinite; +} +.lds-ellipsis div:nth-child(2) { + left: 8px; + animation: lds-ellipsis2 0.6s infinite; +} +.lds-ellipsis div:nth-child(3) { + left: 32px; + animation: lds-ellipsis2 0.6s infinite; +} +.lds-ellipsis div:nth-child(4) { + left: 56px; + animation: lds-ellipsis3 0.6s infinite; +} +@keyframes lds-ellipsis1 { + 0% { + transform: scale(0); + } + 100% { + transform: scale(1); + } +} +@keyframes lds-ellipsis3 { + 0% { + transform: scale(1); + } + 100% { + transform: scale(0); + } + } + @keyframes lds-ellipsis2 { + 0% { + transform: translate(0, 0); + } + 100% { + transform: translate(24px, 0); + } +} + +table.tablesort { + width:100%; +} + +th.sortable, td { + padding: 5px; +} + +thead tr { + background-color: #eaeaea; +} + +tbody tr:nth-child(even){ + background-color: #f6f6f6; +} + +tbody tr:nth-child(odd){ + background-color: #ffffff; +} + + /* The Modal (background) */ + .modal { + display: none; + position: fixed; /* Stay in place */ + z-index: 1500; /* Sit on top */ + left: 0; + top: 0; + width: 100%; /* Full width */ + height: 100%; /* Full height */ + overflow: auto; /* Enable scroll if needed */ + background-color: rgb(0,0,0); /* Fallback color */ + background-color: rgba(0,0,0,0.4); /* Black w/ opacity */ +} + +/* Modal Content/Box */ +.modal-content { + background-color: #fefefe; + margin: 15% auto; /* 15% from the top and centered */ + padding: 20px; + border: 1px solid #888; + width: 80%; /* Could be more or less, depending on screen size */ +} + +/* The Close Button */ +.close-modal { + color: rgb(66, 66, 66); + float: right; + font-size: 28px; + font-weight: bold; +} + +.close-modal:hover, +.close-modal:focus { + color: black; + text-decoration: none; + cursor: pointer; +} \ No newline at end of file diff --git a/loc_insurancemaps/components/src/css/ol-overrides.css b/loc_insurancemaps/components/src/css/ol-overrides.css new file mode 100644 index 00000000..3e537c0e --- /dev/null +++ b/loc_insurancemaps/components/src/css/ol-overrides.css @@ -0,0 +1,26 @@ +.ol-attribution ul li { + font-size: 2em !important; +} + +.ol-mouse-position { + background: rgba(255,255,255,0.5) !important; + padding: 1px 5px !important; + cursor: default !important; + border-radius: 4px !important; +} + +.ol-zoom-in { + background: #2c689c !important; +} + +.ol-zoom-out { + background: #2c689c !important; +} + +.ol-rotate { + top: 36px !important; +} + +.ol-rotate-reset { + background: #2c689c !important; +} diff --git a/loc_insurancemaps/components/src/js/ol-styles.js b/loc_insurancemaps/components/src/js/ol-styles.js new file mode 100644 index 00000000..a7138887 --- /dev/null +++ b/loc_insurancemaps/components/src/js/ol-styles.js @@ -0,0 +1,94 @@ +import Style from 'ol/style/Style'; +import Stroke from 'ol/style/Stroke'; +import Circle from 'ol/style/Circle'; +import Fill from 'ol/style/Fill'; +import RegularShape from 'ol/style/RegularShape'; + +const btnBlue = '#2c689c'; + +const interactionPointer = new Circle({ + fill: new Fill({ color: btnBlue, }), + stroke: new Stroke({ color: '#ffffff', width: 1, }), + radius: 5, +}) + +// this is the white outline cross that sits behind every gcp style +const gcpOutline = new Style({ + image: new RegularShape({ + radius1: 10, + radius2: 0, + points: 4, + rotation: .79, + fill: new Fill({color: "#ffffff"}), + stroke: new Stroke({ + color: "#ffffff", width: 5 + }) + }) +}); + +// create the gcp styles, essentially different fill colors to sit +// on top of the outline. +const gcpDefault = new Style({ + image: new RegularShape({ + radius1: 10, + radius2: 0, + points: 4, + rotation: .79, + stroke: new Stroke({ + color: 'black', width: 2 + }) + }) +}) +const gcpHover = new Style({ + image: new RegularShape({ + radius1: 10, + radius2: 0, + points: 4, + rotation: .79, + stroke: new Stroke({ + color: 'red', width: 2 + }) + }) +}) +const gcpHighlight = new Style({ + image: new RegularShape({ + radius1: 10, + radius2: 0, + points: 4, + rotation: .79, + // fill: new Fill({color: '#00ff00'}), + stroke: new Stroke({ + color: '#419EB6', width: 2 + }) + }) +}) + +class Styles { + + empty = new Style(); + + gcpDefault = [gcpOutline, gcpDefault]; + gcpHover = [gcpOutline, gcpHover]; + gcpHighlight = [gcpOutline, gcpHighlight]; + + splitPreviewStyle = new Style({ + fill: new Fill({ color: 'rgba(255, 29, 51, 0.1)', }), + stroke: new Stroke({ color: 'rgba(250, 226, 0, .9)', width: 7.5, }), + }); + + splitBorderStyle = new Style({ + stroke: new Stroke({ color: btnBlue, width: 2, }) + }); + + polyDraw = new Style({ + stroke: new Stroke({ color: btnBlue, width: 2, }), + image: interactionPointer, + }); + + polyModify = new Style({ + image: interactionPointer, + }); + +} + +export default Styles \ No newline at end of file diff --git a/loc_insurancemaps/components/src/js/ol-utils.js b/loc_insurancemaps/components/src/js/ol-utils.js new file mode 100644 index 00000000..701b653c --- /dev/null +++ b/loc_insurancemaps/components/src/js/ol-utils.js @@ -0,0 +1,112 @@ +import VectorSource from 'ol/source/Vector'; +import ImageStatic from 'ol/source/ImageStatic'; +import OSM from 'ol/source/OSM'; +import XYZ from 'ol/source/XYZ'; +import TileWMS from 'ol/source/TileWMS'; + +import Feature from 'ol/Feature'; +import Polygon from 'ol/geom/Polygon'; +import Point from 'ol/geom/Point'; + +import Style from 'ol/style/Style'; +import Fill from 'ol/style/Fill'; +import Stroke from 'ol/style/Stroke'; +import RegularShape from 'ol/style/RegularShape'; + +import TileLayer from 'ol/layer/Tile'; +import VectorLayer from 'ol/layer/Vector'; +import LayerGroup from 'ol/layer/Group'; + +function makeSatelliteLayer (apiKey) { + return new TileLayer({ + source: new XYZ({ + url: 'https://api.mapbox.com/styles/v1/mapbox/satellite-streets-v10/tiles/{z}/{x}/{y}?access_token='+apiKey, + tileSize: 512, + }) + }); +} + +function makeOSMLayer () { + return new TileLayer({ + source: new OSM(), + }) +} + +class Utils { + + generateFullMaskLayer = function (map) { + let projExtent = map.getView().getProjection().getExtent() + const polygon = new Polygon([[ + [projExtent[0], projExtent[1]], + [projExtent[2], projExtent[1]], + [projExtent[2], projExtent[3]], + [projExtent[0], projExtent[3]], + [projExtent[0], projExtent[1]], + ]]) + const layer = new VectorLayer({ + source: new VectorSource({ + features: [ new Feature({ geometry: polygon }) ] + }), + style: new Style({ + fill: new Fill({ color: 'rgba(255, 255, 255, 0.5)' }), + }), + zIndex: 500, + }); + layer.setVisible(false); + return layer + } + + makeRotateCenterLayer = function () { + const feature = new Feature() + const pointStyle = new Style({ + image: new RegularShape({ + radius1: 10, + radius2: 1, + points: 4, + rotateWithView: true, + fill: new Fill({color: "#FF0000" }), + stroke: new Stroke({ + color: "#FF0000", width: 2 + }) + }) + }) + const layer = new VectorLayer({ + source: new VectorSource({ + features: [ feature ] + }), + style: pointStyle, + zIndex: 501, + }); + return { + layer: layer, + feature: feature, + } + } + + showRotateCenter = function (map, layer, feature) { + if (map && layer && feature) { + const centerCoords = map.getView().getCenter(); + const point = new Point(centerCoords) + feature.setGeometry(point) + layer.setVisible(true) + } + } + + removeRotateCenter = function (layer) { + if (layer) { + layer.setVisible(false) + } + } + + makeBasemaps = function (mapboxKey) { + const osmLayer = makeOSMLayer(); + const satelliteLayer = makeSatelliteLayer(mapboxKey) + return [ + { id: "osm", layer: osmLayer, label: "Streets" }, + { id: "satellite", layer: satelliteLayer, label: "Streets+Satellite" }, + ] + } + +} + +export default Utils \ No newline at end of file diff --git a/loc_insurancemaps/components/src/main-multitrim.js b/loc_insurancemaps/components/src/main-multitrim.js new file mode 100644 index 00000000..42538d09 --- /dev/null +++ b/loc_insurancemaps/components/src/main-multitrim.js @@ -0,0 +1,12 @@ +import './css/interface.css'; +import './js/ol-styles.js'; +import './js/ol-utils.js'; +import MultiTrim from './MultiTrim.svelte'; +import './css/ol-overrides.css' + +const app = new MultiTrim({ + target: document.getElementById("multitrim-target"), + props: JSON.parse(document.getElementById("multitrim-props").textContent), +}); + +export default app; diff --git a/loc_insurancemaps/management/commands/configure.py b/loc_insurancemaps/management/commands/configure.py index 88d98273..1102ef0a 100644 --- a/loc_insurancemaps/management/commands/configure.py +++ b/loc_insurancemaps/management/commands/configure.py @@ -312,6 +312,7 @@ def write_project_uwsgi_ini(self): ("BROKER_URL", ""), ("ASYNC_SIGNALS", False), ("THEME_ACCOUNT_CONTACT_EMAIL", "admin@example.com"), + ("USE_TITILER", True), ] if self.resolve_var("EMAIL_ENABLE", False) is True: diff --git a/loc_insurancemaps/management/commands/set_cog_symlinks.py b/loc_insurancemaps/management/commands/set_cog_symlinks.py new file mode 100644 index 00000000..238057de --- /dev/null +++ b/loc_insurancemaps/management/commands/set_cog_symlinks.py @@ -0,0 +1,32 @@ +from pathlib import Path + +from django.conf import settings +from django.core.management.base import BaseCommand + +from geonode.layers.models import Layer, LayerFile, UploadSession + +class Command(BaseCommand): + help = 'command to search the Library of Congress API.' + + def add_arguments(self, parser): + pass + + def handle(self, *args, **options): + + cog_dir = Path(settings.MEDIA_ROOT, "cog") + cog_dir.mkdir(exist_ok=True) + + layers = Layer.objects.all() + + for l in layers: + path = None + us = UploadSession.objects.filter(resource=l) + if len(us) == 1: + f = LayerFile.objects.filter(upload_session=us[0]) + if len(f) == 1: + path = f[0].file.path + + if path is not None: + cog_path = Path(cog_dir, Path(path).name) + cog_path.unlink(missing_ok=True) + cog_path.symlink_to(path) diff --git a/loc_insurancemaps/migrations/0008_volume_multimask.py b/loc_insurancemaps/migrations/0008_volume_multimask.py new file mode 100644 index 00000000..583964b0 --- /dev/null +++ b/loc_insurancemaps/migrations/0008_volume_multimask.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.20 on 2022-08-04 18:26 + +import django.contrib.postgres.fields.jsonb +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('loc_insurancemaps', '0007_volume_slug'), + ] + + operations = [ + migrations.AddField( + model_name='volume', + name='multimask', + field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), + ), + ] diff --git a/loc_insurancemaps/models.py b/loc_insurancemaps/models.py index db058fad..159817ab 100644 --- a/loc_insurancemaps/models.py +++ b/loc_insurancemaps/models.py @@ -294,6 +294,7 @@ class Volume(models.Model): default=dict, ) slug = models.CharField(max_length=100, null=True, blank=True) + multimask = JSONField(null=True, blank=True) def __str__(self): display_str = f"{self.city}, {STATE_ABBREV[self.state]} | {self.year}" @@ -372,7 +373,8 @@ def get_urls(self): "doc_search": f"{settings.SITEURL}documents/?{r_facet}&{d_facet}", "loc_item": loc_item, "loc_resource": resource_url, - "summary": reverse("volume_summary", args=(self.identifier,)) + "summary": reverse("volume_summary", args=(self.identifier,)), + "trim": reverse("volume_trim", args=(self.identifier,)), } def hydrate_ordered_layers(self): @@ -445,7 +447,10 @@ def update_layer_lookup(self, layer_alternate=None, doc_proxy=None): if lp is not None: layer_json = lp.serialize() - layer_json["page_str"] = lp.title + try: + layer_json["page_str"] = lp.title.split("|")[-1].split("p")[1] + except IndexError: + layer_json["page_str"] = lp.title try: tms_url = f"https://oldinsurancemaps.net/geoserver/gwc/service/tms/1.0.0/{lp.alternate}/{{z}}/{{x}}/{{-y}}.png" @@ -529,6 +534,7 @@ def serialize(self): "loaded_by": loaded_by, "urls": self.get_urls(), "ordered_layers": ordered_layers, + "multimask": self.multimask, } def save(self, *args, **kwargs): diff --git a/loc_insurancemaps/settings.py b/loc_insurancemaps/settings.py index b1ca1093..e16772f4 100644 --- a/loc_insurancemaps/settings.py +++ b/loc_insurancemaps/settings.py @@ -54,6 +54,8 @@ PROJECT_NAME, ) +USE_TITILER = ast.literal_eval(os.getenv("USE_TITILER", True)) + # conditionally add static files from the 'georeference' app, as well as # Mapserver information, used for the georeferencing preview layer if 'georeference' in INSTALLED_APPS: diff --git a/loc_insurancemaps/templates/lc/volume_trim.html b/loc_insurancemaps/templates/lc/volume_trim.html new file mode 100644 index 00000000..ea33a44c --- /dev/null +++ b/loc_insurancemaps/templates/lc/volume_trim.html @@ -0,0 +1,19 @@ +{% extends 'index.html' %} +{% load markdownify %} +{% load i18n %} +{% load base_tags %} +{% load django_svelte %} + +{% block title %}{{ svelte_params.VOLUME.title }}{% endblock title %} + +{% block hero%} +
+ + {% display_svelte "MultiTrim.svelte" svelte_params %} + +
+{% endblock hero %} + +{% block bigsearch %}{% endblock bigsearch %} +{% block showcase %}{% endblock showcase %} +{% block datasets %}{% endblock datasets %} diff --git a/loc_insurancemaps/urls.py b/loc_insurancemaps/urls.py index 3dfeed86..6adb7519 100644 --- a/loc_insurancemaps/urls.py +++ b/loc_insurancemaps/urls.py @@ -9,6 +9,7 @@ from .views import ( SimpleAPI, VolumeDetail, + VolumeTrim, HomePage, Volumes, MRMEndpointList, @@ -19,6 +20,7 @@ path('loc/volumes/', Volumes.as_view(), name='volumes_list'), path('loc/api/', SimpleAPI.as_view() , name='lc_api'), path('loc//', VolumeDetail.as_view(), name="volume_summary"), + path('loc/trim//', VolumeTrim.as_view(), name="volume_trim"), path('mrm/', MRMEndpointList.as_view(), name="mrm_layer_list"), path('mrm//', MRMEndpointLayer.as_view(), name="mrm_get_resource"), ] diff --git a/loc_insurancemaps/views.py b/loc_insurancemaps/views.py index 00ba0e1b..e7efe1a8 100644 --- a/loc_insurancemaps/views.py +++ b/loc_insurancemaps/views.py @@ -3,10 +3,11 @@ import logging from datetime import datetime +from django.contrib.gis.geos import GEOSGeometry from django.shortcuts import render, get_object_or_404 from django.views import View from django.urls import reverse -from django.http import JsonResponse, Http404, HttpResponse +from django.http import JsonResponse, Http404, HttpResponse, HttpResponseRedirect from django.middleware import csrf from django.conf import settings @@ -82,6 +83,17 @@ def get(self, request): percent = 0 if georef_ct > 0: percent = int((georef_ct / (unprep_ct + prep_ct + georef_ct)) * 100) + + main_lyrs_ct = 0 + if vol.ordered_layers: + main_lyrs_ct = len(vol.ordered_layers['layers']) + mm_ct = 0 + mm_display = f"0/{main_lyrs_ct}" + if vol.multimask is not None: + mm_ct = len(vol.multimask) + if mm_ct > 0: + mm_display = f"{mm_ct}/{main_lyrs_ct}" + vol_content = { "identifier": vol.identifier, "city": vol.city, @@ -97,6 +109,8 @@ def get(self, request): "loaded_by_name": loaded_by_name, "loaded_by_profile": loaded_by_profile, "title": vol.__str__(), + "mm_ct": mm_ct, + "mm_display": mm_display, "urls": { "summary": reverse("volume_summary", args=(vol.identifier,)) } @@ -119,6 +133,65 @@ def get(self, request): context=context_dict ) +class VolumeTrim(View): + + def get(self, request, volumeid): + + volume = get_object_or_404(Volume, pk=volumeid) + volume_json = volume.serialize() + + volume_json['ordered_layers']['layers'].sort(key=lambda item: item.get("name")) + + gs = os.getenv("GEOSERVER_LOCATION", "http://localhost:8080/geoserver/") + gs = gs.rstrip("/") + "/" + geoserver_ows = f"{gs}ows/" + + context_dict = { + "svelte_params": { + "USE_TITILER": settings.USE_TITILER, + "SESSION_LENGTH": settings.GEOREFERENCE_SESSION_LENGTH, + "VOLUME": volume_json, + "CSRFTOKEN": csrf.get_token(request), + 'USER_TYPE': get_user_type(request.user), + 'GEOSERVER_WMS': geoserver_ows, + "MAPBOX_API_KEY": settings.MAPBOX_API_TOKEN, + } + } + return render( + request, + "lc/volume_trim.html", + context=context_dict + ) + + def post(self, request, volumeid): + + volume = get_object_or_404(Volume, pk=volumeid) + + body = json.loads(request.body) + multimask = body.get('multiMask') + + # data validation + if multimask is not None and isinstance(multimask, dict): + for k, v in multimask.items(): + try: + geom_str = json.dumps(v['geometry']) + GEOSGeometry(geom_str) + except Exception as e: + logger.error(f"{volumeid} | improper GeoJSON in multimask: {k}") + return JsonResponse({"status": "error"}) + + volume.multimask = multimask + volume.save() + + volume_json = volume.serialize() + response = { + "status": "ok", + "volume_json": volume_json + } + + return JsonResponse(response) + + class VolumeDetail(View): def get(self, request, volumeid): @@ -147,6 +220,7 @@ def get(self, request, volumeid): context_dict = { "svelte_params": { + "USE_TITILER": settings.USE_TITILER, "VOLUME": volume_json, "OTHER_VOLUMES": other_vols, "CSRFTOKEN": csrf.get_token(request), @@ -315,4 +389,4 @@ def get(self, request, layerid): raise Http404 else: - raise Http404 \ No newline at end of file + raise Http404