From 7951f156cb4f1c31fb8b406ea8a22efbc9464d03 Mon Sep 17 00:00:00 2001 From: Frederic Junod Date: Mon, 4 Mar 2024 14:59:16 +0100 Subject: [PATCH] feat: add multi line support --- demos/simple/demo.js | 8 + demos/simple/simple.html | 7 +- demos/simple/style.js | 6 +- package-lock.json | 717 +--------------------- package.json | 2 +- src/interaction/TrackData.ts | 8 + src/interaction/TrackInteraction.ts | 10 +- src/interaction/TrackInteractionModify.ts | 22 +- src/interaction/TrackManager.ts | 120 +++- src/interaction/TrackUpdater.ts | 6 +- tsconfig.json | 2 +- 11 files changed, 193 insertions(+), 715 deletions(-) diff --git a/demos/simple/demo.js b/demos/simple/demo.js index 1cb46fec..664daffc 100644 --- a/demos/simple/demo.js +++ b/demos/simple/demo.js @@ -126,6 +126,14 @@ function main() { } trackManager.addPOI(poiOverlay, onAddListener) }); + + document.querySelector('#createNewPart').addEventListener('click', () => { + trackManager.createNewPart(); + }); + document.querySelector('#changeActivePart').addEventListener('click', () => { + const nextPart = (trackManager.activePart() + 1) % trackManager.partsCount(); + trackManager.workOnPart(nextPart); + }); } main(); diff --git a/demos/simple/simple.html b/demos/simple/simple.html index e73a409f..5066ab7f 100644 --- a/demos/simple/simple.html +++ b/demos/simple/simple.html @@ -56,7 +56,12 @@ - +
+
+ Add a new line string +
+ Change active line string +
diff --git a/demos/simple/style.js b/demos/simple/style.js index 5729a70a..fbada9fc 100644 --- a/demos/simple/style.js +++ b/demos/simple/style.js @@ -12,6 +12,8 @@ export const sketchControlPoint = { export const trackLine = { "stroke-width": 6, "stroke-color": "purple", + "text-value": ["concat", "", ["get", "part"]], + "text-fill-color": "#fff", }; export const trackLineModifying = { @@ -27,7 +29,7 @@ export const poiPoint = { "text-font": "bold 11px Inter", "text-fill-color": "#000", // use 'concat' to convert number to string - "text-value": ["concat", ["get", "index"], ""], + "text-value": ["concat", "", ["get", "part"]], }; export const numberedControlPoint = { @@ -35,7 +37,7 @@ export const numberedControlPoint = { "circle-fill-color": "#ffffffdd", "text-color": "blue", // use 'concat' to convert number to string - "text-value": ["concat", ["get", "index"], ""], + "text-value": ["concat", "", ["get", "part"]], }; export const snappedTrue = { diff --git a/package-lock.json b/package-lock.json index 227af2a9..aa13850b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@geoblocks/edittrack", - "version": "1.3.10", + "version": "2.0.0-beta.13", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@geoblocks/edittrack", - "version": "1.3.10", + "version": "2.0.0-beta.13", "license": "BSD-3-Clause", "devDependencies": { "@geoblocks/elevation-profile": "0.0.19", @@ -419,62 +419,6 @@ "@lit-labs/ssr-dom-shim": "^1.2.0" } }, - "node_modules/@lmdb/lmdb-darwin-arm64": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.8.5.tgz", - "integrity": "sha512-KPDeVScZgA1oq0CiPBcOa3kHIqU+pTOwRFDIhxvmf8CTNvqdZQYp5cCKW0bUk69VygB2PuTiINFWbY78aR2pQw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@lmdb/lmdb-darwin-x64": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-2.8.5.tgz", - "integrity": "sha512-w/sLhN4T7MW1nB3R/U8WK5BgQLz904wh+/SmA2jD8NnF7BLLoUgflCNxOeSPOWp8geP6nP/+VjWzZVip7rZ1ug==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@lmdb/lmdb-linux-arm": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-2.8.5.tgz", - "integrity": "sha512-c0TGMbm2M55pwTDIfkDLB6BpIsgxV4PjYck2HiOX+cy/JWiBXz32lYbarPqejKs9Flm7YVAKSILUducU9g2RVg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@lmdb/lmdb-linux-arm64": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-2.8.5.tgz", - "integrity": "sha512-vtbZRHH5UDlL01TT5jB576Zox3+hdyogvpcbvVJlmU5PdL3c5V7cj1EODdh1CHPksRl+cws/58ugEHi8bcj4Ww==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, "node_modules/@lmdb/lmdb-linux-x64": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.8.5.tgz", @@ -489,20 +433,6 @@ "linux" ] }, - "node_modules/@lmdb/lmdb-win32-x64": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.8.5.tgz", - "integrity": "sha512-4wvrf5BgnR8RpogHhtpCPJMKBmvyZPhhUtEwMJbXh0ni2BucpfF07jlmyM11zRqQ2XIq6PbC2j7W7UCCcm1rRQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@mischnic/json-sourcemap": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@mischnic/json-sourcemap/-/json-sourcemap-0.1.1.tgz", @@ -518,62 +448,6 @@ "node": ">=12.0.0" } }, - "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", - "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", - "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", - "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", - "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", @@ -588,20 +462,6 @@ "linux" ] }, - "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", - "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -1965,153 +1825,6 @@ "@parcel/watcher-win32-x64": "2.4.1" } }, - "node_modules/@parcel/watcher-android-arm64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.4.1.tgz", - "integrity": "sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.4.1.tgz", - "integrity": "sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.4.1.tgz", - "integrity": "sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.4.1.tgz", - "integrity": "sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.4.1.tgz", - "integrity": "sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.4.1.tgz", - "integrity": "sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.4.1.tgz", - "integrity": "sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/@parcel/watcher-linux-x64-glibc": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.4.1.tgz", @@ -2154,69 +1867,6 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.4.1.tgz", - "integrity": "sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-ia32": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.4.1.tgz", - "integrity": "sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-x64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.4.1.tgz", - "integrity": "sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/@parcel/workers": { "version": "2.12.0", "resolved": "https://registry.npmjs.org/@parcel/workers/-/workers-2.12.0.tgz", @@ -2250,9 +1900,9 @@ "license": "MIT" }, "node_modules/@swc/core": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.6.1.tgz", - "integrity": "sha512-Yz5uj5hNZpS5brLtBvKY0L4s2tBAbQ4TjmW8xF1EC3YLFxQRrUjMP49Zm1kp/KYyYvTkSaG48Ffj2YWLu9nChw==", + "version": "1.5.28", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.5.28.tgz", + "integrity": "sha512-muCdNIqOTURUgYeyyOLYE3ShL8SZO6dw6bhRm6dCvxWzCZOncPc5fB0kjcPXTML+9KJoHL7ks5xg+vsQK+v6ig==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", @@ -2268,16 +1918,16 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.6.1", - "@swc/core-darwin-x64": "1.6.1", - "@swc/core-linux-arm-gnueabihf": "1.6.1", - "@swc/core-linux-arm64-gnu": "1.6.1", - "@swc/core-linux-arm64-musl": "1.6.1", - "@swc/core-linux-x64-gnu": "1.6.1", - "@swc/core-linux-x64-musl": "1.6.1", - "@swc/core-win32-arm64-msvc": "1.6.1", - "@swc/core-win32-ia32-msvc": "1.6.1", - "@swc/core-win32-x64-msvc": "1.6.1" + "@swc/core-darwin-arm64": "1.5.28", + "@swc/core-darwin-x64": "1.5.28", + "@swc/core-linux-arm-gnueabihf": "1.5.28", + "@swc/core-linux-arm64-gnu": "1.5.28", + "@swc/core-linux-arm64-musl": "1.5.28", + "@swc/core-linux-x64-gnu": "1.5.28", + "@swc/core-linux-x64-musl": "1.5.28", + "@swc/core-win32-arm64-msvc": "1.5.28", + "@swc/core-win32-ia32-msvc": "1.5.28", + "@swc/core-win32-x64-msvc": "1.5.28" }, "peerDependencies": { "@swc/helpers": "*" @@ -2288,95 +1938,10 @@ } } }, - "node_modules/@swc/core-darwin-arm64": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.6.1.tgz", - "integrity": "sha512-u6GdwOXsOEdNAdSI6nWq6G2BQw5HiSNIZVcBaH1iSvBnxZvWbnIKyDiZKaYnDwTLHLzig2GuUjjE2NaCJPy4jg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-darwin-x64": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.6.1.tgz", - "integrity": "sha512-/tXwQibkDNLVbAtr7PUQI0iQjoB708fjhDDDfJ6WILSBVZ3+qs/LHjJ7jHwumEYxVq1XA7Fv2Q7SE/ZSQoWHcQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.6.1.tgz", - "integrity": "sha512-aDgipxhJTms8iH78emHVutFR2c16LNhO+NTRCdYi+X4PyIn58/DyYTH6VDZ0AeEcS5f132ZFldU5AEgExwihXA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.6.1.tgz", - "integrity": "sha512-XkJ+eO4zUKG5g458RyhmKPyBGxI0FwfWFgpfIj5eDybxYJ6s4HBT5MoxyBLorB5kMlZ0XoY/usUMobPVY3nL0g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.6.1.tgz", - "integrity": "sha512-dr6YbLBg/SsNxs1hDqJhxdcrS8dGMlOXJwXIrUvACiA8jAd6S5BxYCaqsCefLYXtaOmu0bbx1FB/evfodqB70Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=10" - } - }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.6.1.tgz", - "integrity": "sha512-A0b/3V+yFy4LXh3O9umIE7LXPC7NBWdjl6AQYqymSMcMu0EOb1/iygA6s6uWhz9y3e172Hpb9b/CGsuD8Px/bg==", + "version": "1.5.28", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.5.28.tgz", + "integrity": "sha512-ueQ9VejnQUM2Pt+vT0IAKoF4vYBWUP6n1KHGdILpoGe3LuafQrqu7RoyQ15C7/AYii7hAeNhTFdf6gLbg8cjFg==", "cpu": [ "x64" ], @@ -2391,9 +1956,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.6.1.tgz", - "integrity": "sha512-5dJjlzZXhC87nZZZWbpiDP8kBIO0ibis893F/rtPIQBI5poH+iJuA32EU3wN4/WFHeK4et8z6SGSVghPtWyk4g==", + "version": "1.5.28", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.5.28.tgz", + "integrity": "sha512-G5th8Mg0az8CbY4GQt9/m5hg2Y0kGIwvQBeVACuLQB6q2Y4txzdiTpjmFqUUhEvvl7Klyx1IHvNhfXs3zpt7PA==", "cpu": [ "x64" ], @@ -2407,57 +1972,6 @@ "node": ">=10" } }, - "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.6.1.tgz", - "integrity": "sha512-HBi1ZlwvfcUibLtT3g/lP57FaDPC799AD6InolB2KSgkqyBbZJ9wAXM8/CcH67GLIP0tZ7FqblrJTzGXxetTJQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.6.1.tgz", - "integrity": "sha512-AKqHohlWERclexar5y6ux4sQ8yaMejEXNxeKXm7xPhXrp13/1p4/I3E5bPVX/jMnvpm4HpcKSP0ee2WsqmhhPw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, - "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.6.1.tgz", - "integrity": "sha512-0dLdTLd+ONve8kgC5T6VQ2Y5G+OZ7y0ujjapnK66wpvCBM6BKYGdT/OKhZKZydrC5gUKaxFN6Y5oOt9JOFUrOQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0 AND MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=10" - } - }, "node_modules/@swc/counter": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", @@ -2763,9 +2277,9 @@ "license": "MIT" }, "node_modules/acorn": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", - "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "license": "MIT", "bin": { @@ -2786,14 +2300,11 @@ } }, "node_modules/acorn-walk": { - "version": "8.3.3", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", - "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", "dev": true, "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, "engines": { "node": ">=0.4.0" } @@ -3047,9 +2558,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001636", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001636.tgz", - "integrity": "sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==", + "version": "1.0.30001632", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001632.tgz", + "integrity": "sha512-udx3o7yHJfUxMLkGohMlVHCvFvWmirKh9JAH/d7WOLPetlH+LTL5cocMZ0t7oZx/mdlOWXti97xLZWc8uURRHg==", "dev": true, "funding": [ { @@ -3795,9 +3306,9 @@ "license": "ISC" }, "node_modules/electron-to-chromium": { - "version": "1.4.803", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.803.tgz", - "integrity": "sha512-61H9mLzGOCLLVsnLiRzCbc63uldP0AniRYPV3hbGVtONA1pI7qSGILdbofR7A8TMbOypDocEAjH/e+9k1QIe3g==", + "version": "1.4.799", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.799.tgz", + "integrity": "sha512-3D3DwWkRTzrdEpntY0hMLYwj7SeBk1138CkPE8sBDSj3WzrzOiG2rHm3luw8jucpf+WiyLBCZyU9lMHyQI9M9Q==", "dev": true, "license": "ISC" }, @@ -4249,21 +3760,6 @@ "dev": true, "license": "ISC" }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/geotiff": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/geotiff/-/geotiff-2.1.3.tgz", @@ -4936,132 +4432,6 @@ "lightningcss-win32-x64-msvc": "1.25.1" } }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.25.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.25.1.tgz", - "integrity": "sha512-G4Dcvv85bs5NLENcu/s1f7ehzE3D5ThnlWSDwE190tWXRQCQaqwcuHe+MGSVI/slm0XrxnaayXY+cNl3cSricw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.25.1", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.25.1.tgz", - "integrity": "sha512-dYWuCzzfqRueDSmto6YU5SoGHvZTMU1Em9xvhcdROpmtOQLorurUZz8+xFxZ51lCO2LnYbfdjZ/gCqWEkwixNg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.25.1", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.25.1.tgz", - "integrity": "sha512-hXoy2s9A3KVNAIoKz+Fp6bNeY+h9c3tkcx1J3+pS48CqAt+5bI/R/YY4hxGL57fWAIquRjGKW50arltD6iRt/w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.25.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.25.1.tgz", - "integrity": "sha512-tWyMgHFlHlp1e5iW3EpqvH5MvsgoN7ZkylBbG2R2LWxnvH3FuWCJOhtGcYx9Ks0Kv0eZOBud789odkYLhyf1ng==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.25.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.25.1.tgz", - "integrity": "sha512-Xjxsx286OT9/XSnVLIsFEDyDipqe4BcLeB4pXQ/FEA5+2uWCCuAEarUNQumRucnj7k6ftkAHUEph5r821KBccQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.25.1", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.25.1.tgz", - "integrity": "sha512-IhxVFJoTW8wq6yLvxdPvyHv4NjzcpN1B7gjxrY3uaykQNXPHNIpChLB52+wfH+yS58zm1PL4LemUp8u9Cfp6Bw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/lightningcss-linux-x64-gnu": { "version": "1.25.1", "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.25.1.tgz", @@ -5104,27 +4474,6 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.25.1", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.25.1.tgz", - "integrity": "sha512-9KZZkmmy9oGDSrnyHuxP6iMhbsgChUiu/NSgOx+U1I/wTngBStDf2i2aGRCHvFqj19HqqBEI4WuGVQBa2V6e0A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", diff --git a/package.json b/package.json index 0d6a3472..21d33fb7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@geoblocks/edittrack", - "version": "1.3.10", + "version": "2.0.0-beta.13", "description": "Geoblocks edittrack", "scripts": { "eslint": "eslint src test demos", diff --git a/src/interaction/TrackData.ts b/src/interaction/TrackData.ts index 253b84a0..d73899cb 100644 --- a/src/interaction/TrackData.ts +++ b/src/interaction/TrackData.ts @@ -31,10 +31,18 @@ interface DeletedControlPoint { } export default class TrackData { + private part_: number; private segments: Feature[] = []; private controlPoints: Feature[] = []; private pois: Feature[] = []; + constructor(part: number) { + this.part_ = part; + } + get part() { + return this.part_; + } + parseFeatures(features: Feature[]): ParsedFeatures { const parsed: ParsedFeatures = { segments: [], diff --git a/src/interaction/TrackInteraction.ts b/src/interaction/TrackInteraction.ts index f288f85f..347f0e65 100644 --- a/src/interaction/TrackInteraction.ts +++ b/src/interaction/TrackInteraction.ts @@ -18,7 +18,6 @@ import {Point} from 'ol/geom'; export interface Options { map: Map; trackLayer: VectorLayer - trackData: TrackData style: StyleLike | FlatStyleLike /** @@ -62,6 +61,10 @@ export default class TrackInteraction extends Interaction { private modifyTrack_: Modify; private deletePoint_: Select; + setTrackData(trackData: TrackData) { + this.modifyTrack_.setTrackData(trackData); + } + controlPointOrPOIAtPixel(pixel: Pixel): Feature|false { return this.getMap().forEachFeatureAtPixel(pixel, (f) => { @@ -86,9 +89,8 @@ export default class TrackInteraction extends Interaction { return draw; } - createModifyInteraction(trackData: TrackData, source: VectorSource, style: StyleLike | FlatStyleLike, hitTolerance: number): Modify { + createModifyInteraction(source: VectorSource, style: StyleLike | FlatStyleLike, hitTolerance: number): Modify { const modify = new Modify({ - trackData: trackData, source: source, style: style, condition: (event) => !this.deleteCondition_(event), @@ -146,7 +148,7 @@ export default class TrackInteraction extends Interaction { source.on('removefeature', () => requestAnimationFrame(() => this.modifyTrack_.updateSketchFeature())); this.drawTrack_ = this.createDrawInteraction(source); - this.modifyTrack_ = this.createModifyInteraction(options.trackData, source, options.style, options.hitTolerance); + this.modifyTrack_ = this.createModifyInteraction(source, options.style, options.hitTolerance); this.deletePoint_ = this.createSelectInteraction(options.trackLayer); this.setActive(false); diff --git a/src/interaction/TrackInteractionModify.ts b/src/interaction/TrackInteractionModify.ts index 8100acd0..3da0914e 100644 --- a/src/interaction/TrackInteractionModify.ts +++ b/src/interaction/TrackInteractionModify.ts @@ -6,7 +6,7 @@ import LineString from 'ol/geom/LineString.js'; import Point from 'ol/geom/Point.js'; import Event from 'ol/events/Event.js'; import {Geometry} from 'ol/geom'; -import TrackData from './TrackData'; +import type TrackData from './TrackData'; import {Map, MapBrowserEvent} from 'ol'; import type {StyleLike} from 'ol/style/Style.js'; import type {FlatStyleLike} from 'ol/style/flat.js'; @@ -32,7 +32,6 @@ export class ModifyEvent extends Event { export interface Options { source: VectorSource; - trackData: TrackData; style: StyleLike | FlatStyleLike; condition: (mbe: MapBrowserEvent) => boolean; addControlPointCondition: (mbe: MapBrowserEvent) => boolean; @@ -65,7 +64,7 @@ export default class Modify extends PointerInteraction { }); private overlay_: VectorLayer; private lastPixel_: Pixel = [0, 0]; - private trackData_: Options['trackData']; + private trackData_: TrackData; private pointAtCursorFeature_ = new Feature({ geometry: new Point([0, 0]), type: 'sketch', @@ -103,10 +102,16 @@ export default class Modify extends PointerInteraction { updateWhileAnimating: true, updateWhileInteracting: true }); + } - this.trackData_ = options.trackData; + setTrackData(trackData: TrackData) { + this.trackData_ = trackData; + this.overlayFeature.set('part', this.trackData_.part); } + featureInTrackData(feature: Feature | undefined) { + return feature?.get('part') === this.trackData_.part; + } setMap(map: Map) { this.overlay_.setMap(map); @@ -177,6 +182,11 @@ export default class Modify extends PointerInteraction { handleEvent(event: MapBrowserEvent): boolean { const stop = super.handleEvent(event); + // const feature = this.getFeatureAtPixel(event.pixel); + // if (feature?.get('part') !== this.trackData_.part) { + // return false; + // } + if (this.addControlPointCondition_(event)) { const feature = this.getFeatureAtPixel(event.pixel); if (feature && feature.get('type') === 'segment') { @@ -197,6 +207,10 @@ export default class Modify extends PointerInteraction { if (!this.feature_) { return false; } + if (!this.featureInTrackData(this.feature_)) { + this.feature_ = null; + return false; + } this.dragStarted = false; return true; } diff --git a/src/interaction/TrackManager.ts b/src/interaction/TrackManager.ts index d9b86200..c2e34328 100644 --- a/src/interaction/TrackManager.ts +++ b/src/interaction/TrackManager.ts @@ -1,3 +1,5 @@ +// FIXME: move pois outside of track data + import Feature from 'ol/Feature.js'; import Point from 'ol/geom/Point.js'; @@ -73,7 +75,7 @@ export default class TrackManager { private trackChangeEventListeners_: Function[] = []; // eslint-disable-next-line @typescript-eslint/ban-types private trackHoverEventListeners_: Function[] = []; - private trackData_ = new TrackData(); + private trackData_: TrackData; private router_: Router; get router(): Router { return this.router_; @@ -85,6 +87,7 @@ export default class TrackManager { private updater_: TrackUpdater; private interaction_: TrackInteraction; private historyManager_ = new HistoryManager[]>(); + private parts: TrackData[] = []; constructor(options: Options) { this.map_ = options.map; @@ -96,15 +99,14 @@ export default class TrackManager { this.router_ = options.router; this.profiler_ = options.profiler; + this.updater_ = new TrackUpdater({ profiler: this.profiler_, router: this.router_, - trackData: this.trackData_ }); this.interaction_ = new TrackInteraction({ style: options.style, - trackData: this.trackData_, trackLayer: this.trackLayer_, map: this.map_, deleteCondition: options.deleteCondition, @@ -113,6 +115,8 @@ export default class TrackManager { hitTolerance: this.hitTolerance_, }); + this.createNewPart(); + // Hack to test profile synchro // this.closestPointGeom_ = new Point([0, 0]); // this.interaction_.modifyTrack_.overlay_.getSource().addFeature(new Feature({ @@ -131,9 +135,12 @@ export default class TrackManager { if (!this.snapping) { feature.set('snapped', false); } + feature.set('part', this.trackData_.part); + // this is what we want: the new point is added to the current part const {pointFrom, pointTo, segment} = this.trackData_.pushControlPoint(feature); if (segment) { this.source_.addFeature(segment); + segment.set('part', this.trackData_.part); await this.router_.snapSegment(segment, pointFrom, pointTo); this.updater_.equalizeCoordinates(pointFrom); await this.profiler_.computeProfile(segment); @@ -145,6 +152,7 @@ export default class TrackManager { const debouncedMapToProfileUpdater = debounce( (coordinate: Coordinate, hover: boolean) => { + // FIXME multi lines: check this if (hover && this.trackData_.getSegments().length > 0) { const segments = this.trackData_.getSegments().map(feature => feature.get('profile')); const best = findClosestPointInLines(segments, coordinate, {tolerance: 1, interpolate: true}); @@ -172,22 +180,26 @@ export default class TrackManager { const type = event.feature.get('type') as FeatureType; if (type === 'POI') { - this.trackData_.updatePOIIndexes(); + // FIXME multi lines: check this + this.trackData_.updatePOIIndexes(); this.onTrackChanged_(); } else if (type === 'controlPoint') { const feature = event.feature as Feature; await this.updater_.updateAdjacentSegmentsGeometries(feature, this.snapping); this.updater_.changeAdjacentSegmentsStyling(feature, ''); await this.updater_.computeAdjacentSegmentsProfile(feature); + // FIXME multi lines: check this this.trackData_.updatePOIIndexes(); this.onTrackChanged_(); } else if (type === 'segment') { const feature = event.feature as Feature; + // FIXME multi lines: check this const indexOfSegment = this.trackData_.getSegments().indexOf(feature); console.assert(indexOfSegment >= 0); const controlPoint = new Feature({ - geometry: new Point(event.coordinate) + geometry: new Point(event.coordinate), + part: this.trackData_.part, }); this.source_.addFeature(controlPoint); const removed = this.trackData_.insertControlPointAt(controlPoint, indexOfSegment + 1); @@ -196,11 +208,14 @@ export default class TrackManager { const {before, after} = this.trackData_.getAdjacentSegments(controlPoint); console.assert(!!before && !!after); + before.set('part', this.trackData_.part); + after.set('part', this.trackData_.part); this.source_.addFeatures([before, after]); await this.updater_.updateAdjacentSegmentsGeometries(controlPoint, this.snapping); this.updater_.changeAdjacentSegmentsStyling(controlPoint, ''); await this.updater_.computeAdjacentSegmentsProfile(controlPoint); + // FIXME multi lines: check this this.trackData_.updatePOIIndexes(); this.onTrackChanged_(); } @@ -216,6 +231,7 @@ export default class TrackManager { console.assert(selected.getGeometry().getType() === 'Point'); const type = selected.get('type') as FeatureType; if (type === 'POI') { + // FIXME multi lines: check this this.trackData_.deletePOI(selected); this.source_.removeFeature(selected); this.onTrackChanged_(); @@ -228,6 +244,7 @@ export default class TrackManager { // add newly created segment to source if (newSegment) { + newSegment.set('part', this.trackData_.part); this.source_.addFeature(newSegment); } @@ -261,10 +278,11 @@ export default class TrackManager { } private pushNewStateToHistoryManager_() { - const segments = this.getSegments(); - const controlPoints = this.getControlPoints(); - const pois = this.getPOIs(); - const features = [...segments, ...controlPoints, ...pois]; + const features = [ + ...this.getAllSegments().flat(), + ...this.getAllControlPoints().flat(), + ...this.getAllPOIs().flat(), + ]; const clonedFeatures = features.map(f => { const nf = f.clone(); nf.setId(f.getId()); @@ -325,6 +343,7 @@ export default class TrackManager { deleteLastPoint() { if (this.mode_) { + // FIXME multi lines: check this if (this.trackData_.getControlPoints().length > 0) { const deletedFeatures = this.trackData_.deleteLastControlPoint(); deletedFeatures.forEach(feature => this.source_.removeFeature(feature)); @@ -358,6 +377,7 @@ export default class TrackManager { private clearInternal_() { this.source_.clear(); this.trackData_.clear(); + // FIXME multi lines: remove all parts ? } /** @@ -374,15 +394,21 @@ export default class TrackManager { */ private async restoreFeaturesInternal_(features: Feature[]): Promise { // should parse features first, compute profile, and then replace the trackdata and add history - const parsedFeatures = this.trackData_.parseFeatures(features); - this.source_.addFeatures(features); - const profileRequests = parsedFeatures.segments.map(segment => this.profiler_.computeProfile(segment)); - await Promise.all(profileRequests); - this.trackData_.restoreParsedFeatures(parsedFeatures); + const currentPart = this.activePart(); + const featuresByPart = Object.groupBy(features, f => f.get('part')); + for (const [part, featuresInPart] of Object.entries(featuresByPart)) { + const parsedFeatures = this.trackData_.parseFeatures(featuresInPart); + this.source_.addFeatures(featuresInPart); + const profileRequests = parsedFeatures.segments.map(segment => this.profiler_.computeProfile(segment)); + await Promise.all(profileRequests); + // FIXME: check if part exists + this.workOnPart(parseInt(part)); + this.trackData_.restoreParsedFeatures(parsedFeatures); + } + this.workOnPart(currentPart); } async restoreFeatures(features: Feature[]): Promise { - this.clearInternal_(); await this.restoreFeaturesInternal_(features); this.onTrackChanged_(); } @@ -419,6 +445,29 @@ export default class TrackManager { }); } + getAllSegments(): readonly Feature[][] { + const segments: Feature[][] = []; + for (const tm of this.partsGenerator()) { + segments.push(tm.getSegments() as Feature[]); + } + return segments; + } + + getAllControlPoints(): readonly Feature[][] { + const controlPoints: Feature[][] = []; + for (const tm of this.partsGenerator()) { + controlPoints.push(tm.getControlPoints() as Feature[]); + } + return controlPoints; + } + + getAllPOIs(): readonly Feature[][] { + const pois: Feature[][] = []; + for (const tm of this.partsGenerator()) { + pois.push(tm.getPOIs() as Feature[]); + } + return pois; + } /** * Add a POI and notify track change listeners. @@ -568,4 +617,43 @@ export default class TrackManager { this.source_.changed(); this.shadowTrackLayer_.getSource().changed(); } -} \ No newline at end of file + + createNewPart(): number { + this.trackData_ = new TrackData(this.parts.length); + this.parts.push(this.trackData_); + this.updater_.setTrackData(this.trackData_); + this.interaction_.setTrackData(this.trackData_); + + return this.trackData_.part; + } + + activePart(): number { + return this.trackData_.part; + } + + partsCount(): number { + return this.parts.length; + } + + workOnPart(index: number) { + this.trackData_ = this.parts[index]; + this.updater_.setTrackData(this.trackData_); + this.interaction_.setTrackData(this.trackData_); + } + + getParts(): TrackData[] { + return this.parts; + } + + // FIXME: find a better name + *partsGenerator(): Generator, void> { + const currentPart = this.activePart(); + const length = this.partsCount(); + for (let i = 0; i < length; i++) { + this.workOnPart(i); + yield this; + } + this.workOnPart(currentPart); + } + +} diff --git a/src/interaction/TrackUpdater.ts b/src/interaction/TrackUpdater.ts index 2c9ccb7d..45a04253 100644 --- a/src/interaction/TrackUpdater.ts +++ b/src/interaction/TrackUpdater.ts @@ -6,7 +6,6 @@ import type {Profiler} from '../profiler/index'; import {equals} from 'ol/coordinate'; type TrackUpdaterOptions = { - trackData: TrackData; router: Router; profiler: Profiler; }; @@ -21,11 +20,14 @@ export default class TrackUpdater { private router: Router; constructor(options: TrackUpdaterOptions) { - this.trackData = options.trackData; this.profiler = options.profiler; this.router = options.router; } + setTrackData(trackData: TrackData) { + this.trackData = trackData; + } + computeAdjacentSegmentsProfile(modifiedControlPoint: Feature): Promise { const promises = []; if (modifiedControlPoint) { diff --git a/tsconfig.json b/tsconfig.json index a1b45259..ffd1ffa2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "target": "ES2022", "module": "ES2022", - "lib": ["es2023", "dom"], + "lib": ["ESNext", "dom"], "baseUrl": "./", "skipLibCheck": true,