This is an automated email from the ASF dual-hosted git repository. riemer pushed a commit to branch support-vector-maps in repository https://gitbox.apache.org/repos/asf/streampipes.git
commit a63edefa6910f37370b1663bd115462c8c3bfb4c Author: Dominik Riemer <[email protected]> AuthorDate: Thu Dec 4 17:43:54 2025 +0100 feat: Support vector maps in addition to tile servers --- .../model/configuration/LocationConfig.java | 9 +- .../{LocationConfig.java => MapLayerType.java} | 10 +- .../model/configuration/SpCoreConfiguration.java | 2 +- ui/package-lock.json | 280 ++++++++++++++++++++- ui/package.json | 2 + .../src/lib/model/gen/streampipes-model.ts | 35 ++- .../manage-site/manage-site-dialog.component.ts | 5 +- .../location-features-configuration.component.html | 23 +- .../location-features-configuration.component.ts | 7 + .../core-ui/services/map-layer-provider.service.ts | 47 ++++ .../single-marker-map.component.ts | 20 +- 11 files changed, 414 insertions(+), 26 deletions(-) diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/configuration/LocationConfig.java b/streampipes-model/src/main/java/org/apache/streampipes/model/configuration/LocationConfig.java index 573e9abe70..c4d59615ea 100644 --- a/streampipes-model/src/main/java/org/apache/streampipes/model/configuration/LocationConfig.java +++ b/streampipes-model/src/main/java/org/apache/streampipes/model/configuration/LocationConfig.java @@ -22,5 +22,12 @@ import org.apache.streampipes.model.shared.annotation.TsModel; @TsModel public record LocationConfig(boolean locationEnabled, + MapLayerType mapLayerType, String tileServerUrl, - String attributionText) {} + String attributionText) { + + @Override + public MapLayerType mapLayerType() { + return mapLayerType != null ? this.mapLayerType : MapLayerType.TILE; + } +} diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/configuration/LocationConfig.java b/streampipes-model/src/main/java/org/apache/streampipes/model/configuration/MapLayerType.java similarity index 78% copy from streampipes-model/src/main/java/org/apache/streampipes/model/configuration/LocationConfig.java copy to streampipes-model/src/main/java/org/apache/streampipes/model/configuration/MapLayerType.java index 573e9abe70..c512d25b71 100644 --- a/streampipes-model/src/main/java/org/apache/streampipes/model/configuration/LocationConfig.java +++ b/streampipes-model/src/main/java/org/apache/streampipes/model/configuration/MapLayerType.java @@ -18,9 +18,7 @@ package org.apache.streampipes.model.configuration; -import org.apache.streampipes.model.shared.annotation.TsModel; - -@TsModel -public record LocationConfig(boolean locationEnabled, - String tileServerUrl, - String attributionText) {} +public enum MapLayerType { + TILE, + VECTOR +} diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/configuration/SpCoreConfiguration.java b/streampipes-model/src/main/java/org/apache/streampipes/model/configuration/SpCoreConfiguration.java index 788ecbf1e7..88c8a56e1e 100644 --- a/streampipes-model/src/main/java/org/apache/streampipes/model/configuration/SpCoreConfiguration.java +++ b/streampipes-model/src/main/java/org/apache/streampipes/model/configuration/SpCoreConfiguration.java @@ -45,7 +45,7 @@ public class SpCoreConfiguration { private List<ExportProviderSettings> exportProviderSettings; public SpCoreConfiguration() { - this.locationConfig = new LocationConfig(false, "", ""); + this.locationConfig = new LocationConfig(false, MapLayerType.TILE, "", ""); } public String getRev() { diff --git a/ui/package-lock.json b/ui/package-lock.json index 1049ed3bb5..3822857d85 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -25,6 +25,7 @@ "@fortawesome/fontawesome-free": "6.5.1", "@gradle-tech/develocity-agent": "^2.0.2", "@jsplumb/browser-ui": "^6.2.10", + "@maplibre/maplibre-gl-leaflet": "^0.1.3", "@ngbracket/ngx-layout": "^19.0.0", "@ngx-loading-bar/core": "6.0.2", "@ngx-loading-bar/http-client": "6.0.2", @@ -46,6 +47,7 @@ "jshint": "^2.13.6", "leaflet": "1.9.3", "lodash.clonedeep": "^4.5.0", + "maplibre-gl": "^5.14.0", "marked": "^15.0.12", "material-icons": "^1.13.1", "ngx-color-picker": "^19.0.0", @@ -4766,6 +4768,132 @@ "win32" ] }, + "node_modules/@mapbox/geojson-rewind": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@mapbox/geojson-rewind/-/geojson-rewind-0.5.2.tgz", + "integrity": "sha512-tJaT+RbYGJYStt7wI3cq4Nl4SXxG8W7JDG5DMJu97V25RnbNg3QtQtf+KD+VLjNpWKYsRvXDNmNrBgEETr1ifA==", + "license": "ISC", + "dependencies": { + "get-stream": "^6.0.1", + "minimist": "^1.2.6" + }, + "bin": { + "geojson-rewind": "geojson-rewind" + } + }, + "node_modules/@mapbox/geojson-rewind/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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": "sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@mapbox/point-geometry": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-1.1.0.tgz", + "integrity": "sha512-YGcBz1cg4ATXDCM/71L9xveh4dynfGmcLDqufR+nQQy3fKwsAZsWd/x4621/6uJaeB9mwOHE6hPeDgXz9uViUQ==", + "license": "ISC" + }, + "node_modules/@mapbox/tiny-sdf": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-2.0.7.tgz", + "integrity": "sha512-25gQLQMcpivjOSA40g3gO6qgiFPDpWRoMfd+G/GoppPIeP6JDaMMkMrEJnMZhKyyS6iKwVt5YKu02vCUyJM3Ug==", + "license": "BSD-2-Clause" + }, + "node_modules/@mapbox/unitbezier": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.1.tgz", + "integrity": "sha512-nMkuDXFv60aBr9soUG5q+GvZYL+2KZHVvsqFCzqnkGEf46U2fvmytHaEVc1/YZbiLn8X+eR3QzX1+dwDO1lxlw==", + "license": "BSD-2-Clause" + }, + "node_modules/@mapbox/vector-tile": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-2.0.4.tgz", + "integrity": "sha512-AkOLcbgGTdXScosBWwmmD7cDlvOjkg/DetGva26pIRiZPdeJYjYKarIlb4uxVzi6bwHO6EWH82eZ5Nuv4T5DUg==", + "license": "BSD-3-Clause", + "dependencies": { + "@mapbox/point-geometry": "~1.1.0", + "@types/geojson": "^7946.0.16", + "pbf": "^4.0.1" + } + }, + "node_modules/@mapbox/whoots-js": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz", + "integrity": "sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==", + "license": "ISC", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@maplibre/maplibre-gl-leaflet": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-leaflet/-/maplibre-gl-leaflet-0.1.3.tgz", + "integrity": "sha512-9+hp1PSJcxuuj5/Zta9zbQ8+ZvN4doWXPtlY7ikNtUZY1VbkamY0uTqzHp9kxRPqpgeKGrI7MjzXvwzU88wWCw==", + "license": "ISC", + "peerDependencies": { + "@types/leaflet": "^1.9.0", + "leaflet": "^1.9.3", + "maplibre-gl": "^2.4.0 || ^3.3.1 || ^4.3.2 || ^5.0.0" + } + }, + "node_modules/@maplibre/maplibre-gl-style-spec": { + "version": "24.3.1", + "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-24.3.1.tgz", + "integrity": "sha512-TUM5JD40H2mgtVXl5IwWz03BuQabw8oZQLJTmPpJA0YTYF+B+oZppy5lNMO6bMvHzB+/5mxqW9VLG3wFdeqtOw==", + "license": "ISC", + "dependencies": { + "@mapbox/jsonlint-lines-primitives": "~2.0.2", + "@mapbox/unitbezier": "^0.0.1", + "json-stringify-pretty-compact": "^4.0.0", + "minimist": "^1.2.8", + "quickselect": "^3.0.0", + "rw": "^1.3.3", + "tinyqueue": "^3.0.0" + }, + "bin": { + "gl-style-format": "dist/gl-style-format.mjs", + "gl-style-migrate": "dist/gl-style-migrate.mjs", + "gl-style-validate": "dist/gl-style-validate.mjs" + } + }, + "node_modules/@maplibre/mlt": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@maplibre/mlt/-/mlt-1.1.2.tgz", + "integrity": "sha512-SQKdJ909VGROkA6ovJgtHNs9YXV4YXUPS+VaZ50I2Mt951SLlUm2Cv34x5Xwc1HiFlsd3h2Yrs5cn7xzqBmENw==", + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "@mapbox/point-geometry": "^1.1.0" + } + }, + "node_modules/@maplibre/vt-pbf": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@maplibre/vt-pbf/-/vt-pbf-4.1.0.tgz", + "integrity": "sha512-9LjFAoWtxdGRns8RK9vG3Fcw/fb3eHMxvAn2jffwn3jnVO1k49VOv6+FEza70rK7WzF8GnBiKa0K39RyfevKUw==", + "license": "MIT", + "dependencies": { + "@mapbox/point-geometry": "^1.1.0", + "@mapbox/vector-tile": "^2.0.4", + "@types/geojson-vt": "3.2.5", + "@types/supercluster": "^7.1.3", + "geojson-vt": "^4.0.2", + "pbf": "^4.0.1", + "supercluster": "^8.0.1" + } + }, "node_modules/@mermaid-js/parser": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.3.0.tgz", @@ -6867,9 +6995,17 @@ "version": "7946.0.16", "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", - "devOptional": true, "license": "MIT" }, + "node_modules/@types/geojson-vt": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/@types/geojson-vt/-/geojson-vt-3.2.5.tgz", + "integrity": "sha512-qDO7wqtprzlpe8FfQ//ClPV9xiuoh2nkIgiouIptON9w5jvD/fA4szvP9GBlDVdJ5dldAl0kX/sy3URbWwLx0g==", + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, "node_modules/@types/http-errors": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", @@ -6932,7 +7068,6 @@ "version": "1.9.16", "resolved": "https://registry.npmjs.org/@types/leaflet/-/leaflet-1.9.16.tgz", "integrity": "sha512-wzZoyySUxkgMZ0ihJ7IaUIblG8Rdc8AbbZKLneyn+QjYsj5q1QU7TEKYqwTr10BGSzY5LI7tJk9Ifo+mEjdFRw==", - "dev": true, "license": "MIT", "dependencies": { "@types/geojson": "*" @@ -7203,6 +7338,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/supercluster": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/supercluster/-/supercluster-7.1.3.tgz", + "integrity": "sha512-Z0pOY34GDFl3Q6hUFYf3HkTwKEE02e7QgtJppBt+beEAxnyOpJua+voGFvxINBHa06GwLFFym7gRPY2SiKIfIA==", + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, "node_modules/@types/tern": { "version": "0.23.9", "resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.9.tgz", @@ -10879,6 +11023,12 @@ "node": ">= 0.4" } }, + "node_modules/earcut": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.2.tgz", + "integrity": "sha512-X7hshQbLyMJ/3RPhyObLARM2sNxxmRALLKx1+NVFFnQ9gKzmCrxm9+uLIAdBcvc8FNLpctqlQ2V6AE92Ol9UDQ==", + "license": "ISC" + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -12312,6 +12462,12 @@ "node": ">=6.9.0" } }, + "node_modules/geojson-vt": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-4.0.2.tgz", + "integrity": "sha512-AV9ROqlNqoZEIJGfm1ncNjEXfkz2hdFlZf0qkVfmkwdKa8vj7H16YUOT81rJw1rdFhyEDlN2Tds91p/glzbl5A==", + "license": "ISC" + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -12423,6 +12579,12 @@ "safe-buffer": "^5.2.1" } }, + "node_modules/gl-matrix": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.4.tgz", + "integrity": "sha512-latSnyDNt/8zYUB6VIJ6PCh2jBjJX6gnDsoCZ7LyW7GkqrD51EWwa9qCoGixj8YqBtETQK/xY7OmpTF8xz1DdQ==", + "license": "MIT" + }, "node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -14035,6 +14197,12 @@ "dev": true, "license": "MIT" }, + "node_modules/json-stringify-pretty-compact": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-4.0.0.tgz", + "integrity": "sha512-3CNZ2DnrpByG9Nqj6Xo8vqbjT4F6N+tb4Gb28ESAZjYZ5yqvmc56J+/kuIwkaAMOyblTQhUW7PxMkUb8Q36N3Q==", + "license": "MIT" + }, "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -14507,6 +14675,12 @@ "node": ">= 12" } }, + "node_modules/kdbush": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-4.0.2.tgz", + "integrity": "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==", + "license": "ISC" + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -15487,6 +15661,44 @@ "node": "^18.17.0 || >=20.5.0" } }, + "node_modules/maplibre-gl": { + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-5.14.0.tgz", + "integrity": "sha512-O2ok6N/bQ9NA9nJ22r/PRQQYkUe9JwfDMjBPkQ+8OwsVH4TpA5skIAM2wc0k+rni5lVbAVONVyBvgi1rF2vEPA==", + "license": "BSD-3-Clause", + "dependencies": { + "@mapbox/geojson-rewind": "^0.5.2", + "@mapbox/jsonlint-lines-primitives": "^2.0.2", + "@mapbox/point-geometry": "^1.1.0", + "@mapbox/tiny-sdf": "^2.0.7", + "@mapbox/unitbezier": "^0.0.1", + "@mapbox/vector-tile": "^2.0.4", + "@mapbox/whoots-js": "^3.1.0", + "@maplibre/maplibre-gl-style-spec": "^24.3.1", + "@maplibre/mlt": "^1.1.2", + "@maplibre/vt-pbf": "^4.1.0", + "@types/geojson": "^7946.0.16", + "@types/geojson-vt": "3.2.5", + "@types/supercluster": "^7.1.3", + "earcut": "^3.0.2", + "geojson-vt": "^4.0.2", + "gl-matrix": "^3.4.4", + "kdbush": "^4.0.2", + "murmurhash-js": "^1.0.0", + "pbf": "^4.0.1", + "potpack": "^2.1.0", + "quickselect": "^3.0.0", + "supercluster": "^8.0.1", + "tinyqueue": "^3.0.0" + }, + "engines": { + "node": ">=16.14.0", + "npm": ">=8.1.0" + }, + "funding": { + "url": "https://github.com/maplibre/maplibre-gl-js?sponsor=1" + } + }, "node_modules/marked": { "version": "15.0.12", "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.12.tgz", @@ -15772,7 +15984,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -16114,6 +16325,12 @@ "multicast-dns": "cli.js" } }, + "node_modules/murmurhash-js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", + "integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==", + "license": "MIT" + }, "node_modules/mustache": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", @@ -17384,6 +17601,18 @@ "license": "MIT", "optional": true }, + "node_modules/pbf": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pbf/-/pbf-4.0.1.tgz", + "integrity": "sha512-SuLdBvS42z33m8ejRbInMapQe8n0D3vN/Xd5fmWM3tufNgRQFBpaW2YVJxQZV4iPNqb0vEFvssMEo5w9c6BTIA==", + "license": "BSD-3-Clause", + "dependencies": { + "resolve-protobuf-schema": "^2.1.0" + }, + "bin": { + "pbf": "bin/pbf" + } + }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -17747,6 +17976,12 @@ "dev": true, "license": "MIT" }, + "node_modules/potpack": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/potpack/-/potpack-2.1.0.tgz", + "integrity": "sha512-pcaShQc1Shq0y+E7GqJqvZj8DTthWV1KeHGdi0Z6IAin2Oi3JnLCOfwnCo84qc+HAp52wT9nK9H7FAJp5a44GQ==", + "license": "ISC" + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -17837,6 +18072,12 @@ "node": ">=10" } }, + "node_modules/protocol-buffers-schema": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", + "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==", + "license": "MIT" + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -17941,6 +18182,12 @@ ], "license": "MIT" }, + "node_modules/quickselect": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz", + "integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==", + "license": "ISC" + }, "node_modules/quill": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/quill/-/quill-2.0.3.tgz", @@ -18219,6 +18466,15 @@ "node": ">=4" } }, + "node_modules/resolve-protobuf-schema": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz", + "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==", + "license": "MIT", + "dependencies": { + "protocol-buffers-schema": "^3.3.1" + } + }, "node_modules/resolve-url-loader": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz", @@ -18479,8 +18735,7 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", - "license": "BSD-3-Clause", - "optional": true + "license": "BSD-3-Clause" }, "node_modules/rxjs": { "version": "7.8.1", @@ -19707,6 +19962,15 @@ "license": "MIT", "optional": true }, + "node_modules/supercluster": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-8.0.1.tgz", + "integrity": "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ==", + "license": "ISC", + "dependencies": { + "kdbush": "^4.0.2" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -19989,6 +20253,12 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, + "node_modules/tinyqueue": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-3.0.0.tgz", + "integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==", + "license": "ISC" + }, "node_modules/tldts": { "version": "6.1.86", "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", diff --git a/ui/package.json b/ui/package.json index de4d772674..e10fe12949 100644 --- a/ui/package.json +++ b/ui/package.json @@ -46,6 +46,7 @@ "@fortawesome/fontawesome-free": "6.5.1", "@gradle-tech/develocity-agent": "^2.0.2", "@jsplumb/browser-ui": "^6.2.10", + "@maplibre/maplibre-gl-leaflet": "^0.1.3", "@ngbracket/ngx-layout": "^19.0.0", "@ngx-loading-bar/core": "6.0.2", "@ngx-loading-bar/http-client": "6.0.2", @@ -69,6 +70,7 @@ "lodash.clonedeep": "^4.5.0", "marked": "^15.0.12", "material-icons": "^1.13.1", + "maplibre-gl": "^5.14.0", "ngx-color-picker": "^19.0.0", "ngx-echarts": "^19.0.0", "ngx-markdown": "^19.1.1", diff --git a/ui/projects/streampipes/platform-services/src/lib/model/gen/streampipes-model.ts b/ui/projects/streampipes/platform-services/src/lib/model/gen/streampipes-model.ts index c9e29a27a6..edb971862f 100644 --- a/ui/projects/streampipes/platform-services/src/lib/model/gen/streampipes-model.ts +++ b/ui/projects/streampipes/platform-services/src/lib/model/gen/streampipes-model.ts @@ -16,10 +16,11 @@ * specific language governing permissions and limitations * under the License. */ + /* tslint:disable */ /* eslint-disable */ // @ts-nocheck -// Generated using typescript-generator version 3.2.1263 on 2025-12-02 15:38:14. +// Generated using typescript-generator version 3.2.1263 on 2025-12-04 17:41:18. export class NamedStreamPipesEntity implements Storable { '@class': @@ -179,6 +180,23 @@ export class AdapterEventPreview { } } +export class AdapterType { + code: string; + description: string; + label: string; + + static fromData(data: AdapterType, target?: AdapterType): AdapterType { + if (!data) { + return data; + } + const instance = target || new AdapterType(); + instance.code = data.code; + instance.description = data.description; + instance.label = data.label; + return instance; + } +} + export class TransformationRuleDescription { '@class': | 'org.apache.streampipes.model.connect.rules.value.ValueTransformationRuleDescription' @@ -1180,11 +1198,18 @@ export class DashboardEntity implements Storable, SpResource { export class DashboardItem { cols: number; component: string; + dataViewElementId: string; + h: number; id: string; name: string; rows: number; settings: string[]; timeSettings: { [index: string]: any }; + w: number; + /** + * @deprecated since 0.99.0, for removal + */ + widgetId: string; x: number; y: number; @@ -1198,6 +1223,8 @@ export class DashboardItem { const instance = target || new DashboardItem(); instance.cols = data.cols; instance.component = data.component; + instance.dataViewElementId = data.dataViewElementId; + instance.h = data.h; instance.id = data.id; instance.name = data.name; instance.rows = data.rows; @@ -1207,6 +1234,8 @@ export class DashboardItem { instance.timeSettings = __getCopyObjectFn(__identity<any>())( data.timeSettings, ); + instance.w = data.w; + instance.widgetId = data.widgetId; instance.x = data.x; instance.y = data.y; return instance; @@ -2419,6 +2448,7 @@ export class ListOutputStrategy extends OutputStrategy { export class LocationConfig { attributionText: string; locationEnabled: boolean; + mapLayerType: MapLayerType; tileServerUrl: string; static fromData( @@ -2431,6 +2461,7 @@ export class LocationConfig { const instance = target || new LocationConfig(); instance.attributionText = data.attributionText; instance.locationEnabled = data.locationEnabled; + instance.mapLayerType = data.mapLayerType; instance.tileServerUrl = data.tileServerUrl; return instance; } @@ -4471,6 +4502,8 @@ export type Isa95Type = | 'STORAGE_UNIT' | 'OTHER'; +export type MapLayerType = 'TILE' | 'VECTOR'; + export type MappingPropertyUnion = MappingPropertyNary | MappingPropertyUnary; export type OneOfStaticPropertyUnion = RuntimeResolvableOneOfStaticProperty; diff --git a/ui/src/app/configuration/dialog/manage-site/manage-site-dialog.component.ts b/ui/src/app/configuration/dialog/manage-site/manage-site-dialog.component.ts index 389c9bd5e0..cf89f35901 100644 --- a/ui/src/app/configuration/dialog/manage-site/manage-site-dialog.component.ts +++ b/ui/src/app/configuration/dialog/manage-site/manage-site-dialog.component.ts @@ -65,7 +65,10 @@ export class ManageSiteDialogComponent implements OnInit { appDocType: AssetConstants.ASSET_SITES_APP_DOC_NAME, _id: undefined, label: '', - location: { coordinates: { latitude: 0, longitude: 0 }, zoom: 10 }, + location: { + coordinates: { latitude: 49.00689, longitude: 8.40365 }, + zoom: 10, + }, areas: [], }; this.createMode = true; diff --git a/ui/src/app/configuration/sites-configuration/location-features-configuration/location-features-configuration.component.html b/ui/src/app/configuration/sites-configuration/location-features-configuration/location-features-configuration.component.html index cb2faae401..b8c61d46a7 100644 --- a/ui/src/app/configuration/sites-configuration/location-features-configuration/location-features-configuration.component.html +++ b/ui/src/app/configuration/sites-configuration/location-features-configuration/location-features-configuration.component.html @@ -33,8 +33,29 @@ @if (showLocationDetails) { <div class="mt-10"> <div class="subsection-title"> + {{ 'Layer type' | translate }} + </div> + <mat-radio-group + formControlName="mapLayerType" + fxLayout="row" + > + <mat-radio-button + value="TILE" + data-cy="sites-location-config-layer-type-tile" + > + {{ 'Tile' | translate }} + </mat-radio-button> + <mat-radio-button + value="VECTOR" + class="ml-20" + data-cy="sites-location-config-layer-type-vector" + > + {{ 'Vector' | translate }} + </mat-radio-button> + </mat-radio-group> + <div class="subsection-title mt-10"> {{ - 'Tile server URL(use placeholders for x, y and z coordinates)' + 'Style/Tile server URL (for tile server, use placeholders for x, y and z coordinates)' | translate }} </div> diff --git a/ui/src/app/configuration/sites-configuration/location-features-configuration/location-features-configuration.component.ts b/ui/src/app/configuration/sites-configuration/location-features-configuration/location-features-configuration.component.ts index 68583fd1df..1189cb87a3 100644 --- a/ui/src/app/configuration/sites-configuration/location-features-configuration/location-features-configuration.component.ts +++ b/ui/src/app/configuration/sites-configuration/location-features-configuration/location-features-configuration.component.ts @@ -60,6 +60,10 @@ export class LocationFeaturesConfigurationComponent 'locationFeaturesEnabled', new UntypedFormControl(this.locationConfig.locationEnabled), ); + this.locationForm.addControl( + 'mapLayerType', + new UntypedFormControl(this.locationConfig.mapLayerType), + ); this.locationForm.addControl( 'tileServerUrl', new UntypedFormControl( @@ -67,6 +71,7 @@ export class LocationFeaturesConfigurationComponent this.showLocationDetails ? Validators.required : [], ), ); + this.locationForm.addControl( 'attributionText', new UntypedFormControl(this.locationConfig.attributionText || ''), @@ -89,6 +94,8 @@ export class LocationFeaturesConfigurationComponent this.locationConfig.locationEnabled = this.locationForm.get( 'locationFeaturesEnabled', ).value; + this.locationConfig.mapLayerType = + this.locationForm.get('mapLayerType').value; if (this.locationConfig.locationEnabled) { this.locationConfig.tileServerUrl = this.locationForm.get('tileServerUrl').value; diff --git a/ui/src/app/core-ui/services/map-layer-provider.service.ts b/ui/src/app/core-ui/services/map-layer-provider.service.ts new file mode 100644 index 0000000000..1896a5975a --- /dev/null +++ b/ui/src/app/core-ui/services/map-layer-provider.service.ts @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import { Injectable } from '@angular/core'; +import { LocationConfig } from '@streampipes/platform-services'; +import * as L from 'leaflet'; +import '@maplibre/maplibre-gl-leaflet'; + +@Injectable({ providedIn: 'root' }) +export class MapLayerProviderService { + getMapLayers(locationConfig: LocationConfig): L.Layer[] { + if (locationConfig?.locationEnabled) { + if (locationConfig.mapLayerType === 'TILE') { + return [ + L.tileLayer(locationConfig.tileServerUrl, { + maxZoom: 18, + attribution: locationConfig.attributionText, + }), + ]; + } else { + return [ + (L as any).maplibreGL({ + style: locationConfig.tileServerUrl, + attribution: locationConfig.attributionText, + }), + ]; + } + } else { + return []; + } + } +} diff --git a/ui/src/app/core-ui/single-marker-map/single-marker-map.component.ts b/ui/src/app/core-ui/single-marker-map/single-marker-map.component.ts index 417b489c9d..561a690471 100644 --- a/ui/src/app/core-ui/single-marker-map/single-marker-map.component.ts +++ b/ui/src/app/core-ui/single-marker-map/single-marker-map.component.ts @@ -16,7 +16,7 @@ * */ -import { Component, forwardRef, Input, OnInit } from '@angular/core'; +import { Component, forwardRef, inject, Input, OnInit } from '@angular/core'; import { icon, Layer, @@ -33,6 +33,7 @@ import { LocationConfig, } from '@streampipes/platform-services'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; +import { MapLayerProviderService } from '../services/map-layer-provider.service'; @Component({ selector: 'sp-single-marker-map', @@ -47,6 +48,8 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; standalone: false, }) export class SingleMarkerMapComponent implements OnInit, ControlValueAccessor { + private mapLayerProviderService = inject(MapLayerProviderService); + @Input() locationConfig: LocationConfig; @@ -67,18 +70,15 @@ export class SingleMarkerMapComponent implements OnInit, ControlValueAccessor { ngOnInit() { this.assetLocation ??= { coordinates: { - latitude: 0, - longitude: 0, + latitude: 49.00689, + longitude: 8.40365, }, - zoom: 1, + zoom: 8, }; this.mapOptions = { - layers: [ - tileLayer(this.locationConfig.tileServerUrl, { - maxZoom: 18, - attribution: this.locationConfig.attributionText, - }), - ], + layers: this.mapLayerProviderService.getMapLayers( + this.locationConfig, + ), zoom: this.assetLocation.zoom || 1, center: { lat: this.assetLocation.coordinates.latitude,
