From 8ded69edba72e7717455de8525248a5aac004ea2 Mon Sep 17 00:00:00 2001 From: Nicole Iftekhar Date: Thu, 8 Aug 2024 13:35:08 -0700 Subject: [PATCH 01/23] Edits are saved across layer/level switches and edited geojson files are downloadable --- package-lock.json | 191 +++++++++++++-- package.json | 2 + .../download-edits-button/index.js | 31 +++ .../conversion/places-preview-map/index.js | 220 +++++++++++------- 4 files changed, 343 insertions(+), 101 deletions(-) create mode 100644 src/pages/conversion/places-preview-map/download-edits-button/index.js diff --git a/package-lock.json b/package-lock.json index 699fa39..0b7010b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,8 @@ "file-saver": "^2.0.5", "i18next": "^23.7.6", "i18next-browser-languagedetector": "^7.2.0", + "json-edit-react": "^1.15.4", + "jszip": "^3.10.1", "papaparse": "^5.4.1", "react": "^18.2.0", "react-azure-maps": "^1.0.0", @@ -11028,8 +11030,7 @@ "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" }, "node_modules/cosmiconfig": { "version": "7.1.0", @@ -15438,6 +15439,11 @@ "node": ">= 4" } }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" + }, "node_modules/immer": { "version": "9.0.18", "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.18.tgz", @@ -15519,8 +15525,7 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/ini": { "version": "2.0.0", @@ -20379,6 +20384,18 @@ "node": ">=4" } }, + "node_modules/json-edit-react": { + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/json-edit-react/-/json-edit-react-1.15.4.tgz", + "integrity": "sha512-DxuIcBJ0FsuNrYzODDMc/C5TNP3sGpLR1Iq6UFtbYTKWJhOAt6BVncQdNZlwJ7lYO0HY0pjNyAUiWQCX3Sbayw==", + "dependencies": { + "object-property-assigner": "^1.3.0", + "object-property-extractor": "^1.0.11" + }, + "peerDependencies": { + "react": ">=16.0.0" + } + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -20474,6 +20491,49 @@ "node": ">=4.0" } }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/jszip/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "node_modules/jszip/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/jszip/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/jszip/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/keyborg": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/keyborg/-/keyborg-2.2.0.tgz", @@ -20552,6 +20612,14 @@ "node": ">= 0.8.0" } }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dependencies": { + "immediate": "~3.0.5" + } + }, "node_modules/lilconfig": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", @@ -21596,6 +21664,16 @@ "node": ">= 0.4" } }, + "node_modules/object-property-assigner": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object-property-assigner/-/object-property-assigner-1.3.0.tgz", + "integrity": "sha512-19A0RsC9rP9klCKHDPL/MeERxeopV9wyMNfP+eD2uKOafzLjF+OUEN4FoP6RAlCFHmerBPJ4ohNv/WrgaNpeIA==" + }, + "node_modules/object-property-extractor": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-property-extractor/-/object-property-extractor-1.0.11.tgz", + "integrity": "sha512-VnDQcyN0FTXZ0hMZS/CTb2QkIssZ9XKB8zlf5rnFh1HjFQX1P73EHawavSztBOiPDGqAPNXebv4agjhF9eACAw==" + }, "node_modules/object.assign": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", @@ -21953,6 +22031,11 @@ "node": ">=6" } }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, "node_modules/papaparse": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.4.1.tgz", @@ -23973,8 +24056,7 @@ "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "node_modules/proj4": { "version": "2.8.1", @@ -28602,8 +28684,7 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/util.promisify": { "version": "1.0.1", @@ -38057,8 +38138,7 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" }, "cosmiconfig": { "version": "7.1.0", @@ -41358,6 +41438,11 @@ "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, + "immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==" + }, "immer": { "version": "9.0.18", "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.18.tgz", @@ -41414,8 +41499,7 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { "version": "2.0.0", @@ -45188,6 +45272,15 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, + "json-edit-react": { + "version": "1.15.4", + "resolved": "https://registry.npmjs.org/json-edit-react/-/json-edit-react-1.15.4.tgz", + "integrity": "sha512-DxuIcBJ0FsuNrYzODDMc/C5TNP3sGpLR1Iq6UFtbYTKWJhOAt6BVncQdNZlwJ7lYO0HY0pjNyAUiWQCX3Sbayw==", + "requires": { + "object-property-assigner": "^1.3.0", + "object-property-extractor": "^1.0.11" + } + }, "json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -45266,6 +45359,51 @@ "object.assign": "^4.1.3" } }, + "jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "requires": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + }, + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "keyborg": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/keyborg/-/keyborg-2.2.0.tgz", @@ -45326,6 +45464,14 @@ "type-check": "~0.4.0" } }, + "lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "requires": { + "immediate": "~3.0.5" + } + }, "lilconfig": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", @@ -46090,6 +46236,16 @@ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" }, + "object-property-assigner": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object-property-assigner/-/object-property-assigner-1.3.0.tgz", + "integrity": "sha512-19A0RsC9rP9klCKHDPL/MeERxeopV9wyMNfP+eD2uKOafzLjF+OUEN4FoP6RAlCFHmerBPJ4ohNv/WrgaNpeIA==" + }, + "object-property-extractor": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/object-property-extractor/-/object-property-extractor-1.0.11.tgz", + "integrity": "sha512-VnDQcyN0FTXZ0hMZS/CTb2QkIssZ9XKB8zlf5rnFh1HjFQX1P73EHawavSztBOiPDGqAPNXebv4agjhF9eACAw==" + }, "object.assign": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", @@ -46344,6 +46500,11 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, "papaparse": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.4.1.tgz", @@ -47649,8 +47810,7 @@ "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "proj4": { "version": "2.8.1", @@ -51165,8 +51325,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "util.promisify": { "version": "1.0.1", diff --git a/package.json b/package.json index 9f0fd49..c2f3130 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,8 @@ "file-saver": "^2.0.5", "i18next": "^23.7.6", "i18next-browser-languagedetector": "^7.2.0", + "json-edit-react": "^1.15.4", + "jszip": "^3.10.1", "papaparse": "^5.4.1", "react": "^18.2.0", "react-azure-maps": "^1.0.0", diff --git a/src/pages/conversion/places-preview-map/download-edits-button/index.js b/src/pages/conversion/places-preview-map/download-edits-button/index.js new file mode 100644 index 0000000..a3bdd6c --- /dev/null +++ b/src/pages/conversion/places-preview-map/download-edits-button/index.js @@ -0,0 +1,31 @@ +import React from 'react'; +import JSZip from 'jszip'; +import { saveAs } from 'file-saver'; +import { DefaultButton } from '@fluentui/react'; +// import { logsButton } from '.../style'; + +export const YourComponent = ({ imdfPackageLocation, units, levels, footprint}) => { + const handleUpdateZip = () => { + fetch(imdfPackageLocation) + .then(response => response.arrayBuffer()) + .then(data => { + const zip = new JSZip(); + return zip.loadAsync(data); + }) + .then(zip => { + zip.file('unit.geojson', JSON.stringify(units, null, 2)); + zip.file('level.geojson', JSON.stringify(levels, null, 2)); + zip.file('footprint.geojson', JSON.stringify(footprint, null, 2)); + return zip.generateAsync({ type: 'blob' }); + }) + .then(updatedZip => { + saveAs(updatedZip, 'updated_imdf_package.zip'); + }); + }; + + return ( +
+ Download Updated IMDF +
+ ); + }; \ No newline at end of file diff --git a/src/pages/conversion/places-preview-map/index.js b/src/pages/conversion/places-preview-map/index.js index 1807348..70361a6 100644 --- a/src/pages/conversion/places-preview-map/index.js +++ b/src/pages/conversion/places-preview-map/index.js @@ -2,14 +2,14 @@ import { Map, layer, source, control } from 'azure-maps-control'; import { control as draw_control, drawing } from 'azure-maps-drawing-tools'; import { getDomain, useConversionStore, useLevelsStore, useUserStore } from 'common/store'; import { useEffect, useMemo, useState } from 'react'; -import { DefaultButton } from '@fluentui/react'; -import { logsButton } from '../style'; import { imdfPreviewMap, imdfPreviewMapWrapper, layerSelect, textWrapper, textArea, mapTextWrapper, saveButtonWrapper } from './indes.style'; import LevelSelector from './level-selector'; import LayerSelector from './layer-selector'; import MapNotification from './map-notification'; import { calculateBoundingBox, getFeatureLabel, getFillStyles, getLineStyles, getTextStyle, processZip } from './utils'; import { currentEditData, groupAndSort, drawingModeChanged, writeToInfoPanel, grabToPointer } from './imdf-model-helpers'; +// import { JsonEditor } from 'json-edit-react' +import { YourComponent } from './download-edits-button'; import 'azure-maps-drawing-tools/dist/atlas-drawing.min.css'; import 'azure-maps-control/dist/atlas.min.css'; @@ -70,6 +70,7 @@ const PlacesPreviewMap = ({ style }) => { map.events.add('ready', () => { var drawingToolbar; + document.getElementById('infoPanel-json').value = ''; if(selectedLayerId === 'unitButton') { drawingToolbar = new draw_control.DrawingToolbar({ position: 'bottom-right', @@ -148,80 +149,84 @@ const PlacesPreviewMap = ({ style }) => { } // Entry point when "unit.geojson" is pressed; the following code should be refactored due to redundancy - function unitInteractions(units, drawingManager, map) { - var unitLayer, unitLines, polygonHoverLayer, unitSymbols; - var layersAdded = [unitLayer, unitLines, polygonHoverLayer, unitSymbols]; - const groupedFeatures = groupAndSort(units, language, selectedLevel); - const keys = Object.keys(groupedFeatures); - - keys.forEach(category => { - const features = groupedFeatures[category].features; - - const dataSource = new source.DataSource(); - map.sources.add(dataSource); - dataSource.add(features); - - unitLayer = new layer.PolygonLayer(dataSource, 'unitClick', getFillStyles('unit', category)); - unitLines = new layer.LineLayer(dataSource, null, getLineStyles('unit', category)); - polygonHoverLayer = new layer.PolygonLayer(dataSource, null, { - fillColor: 'rgba(150, 50, 255, 0.2)', - filter: ['==', ['get', 'id'], ''] - }); - - unitSymbols = new layer.SymbolLayer(dataSource, null, getTextStyle(category)); - - map.layers.add([unitLayer, polygonHoverLayer, unitLines, unitSymbols], 'roomPolygons'); - - grabToPointer([unitLayer, polygonHoverLayer], map); - featureHover(unitLayer, polygonHoverLayer); - - // map.layers.add(new layer.SymbolLayer(dataSource, null, getTextStyle(category)), 'roomLabels'); - - var drawingSource = drawingManager.getSource(); - drawingSource.add(features); - - let dmLayers = drawingManager.getLayers(); - dmLayers.polygonLayer.setOptions({ visible: false }); - dmLayers.polygonOutlineLayer.setOptions({ visible: false }); - layersAdded = [unitLayer, unitLines, polygonHoverLayer, unitSymbols]; - - map.events.add('drawingmodechanged', drawingManager, (e) => { - let dmLayers = drawingManager.getLayers(); - layersAdded = [unitLayer, unitLines, polygonHoverLayer, unitSymbols]; - - if (e === 'idle') { - dmLayers.polygonLayer.setOptions({ visible: false }); - dmLayers.polygonOutlineLayer.setOptions({ visible: false }); - map.layers.remove([unitLayer, unitLines, polygonHoverLayer]); - - unitLayer = new layer.PolygonLayer(drawingManager.getSource(), 'unitClick', getFillStyles('unit', category)); - unitLines = new layer.LineLayer(drawingManager.getSource(), null, getLineStyles('unit', category)); - polygonHoverLayer = new layer.PolygonLayer(drawingManager.getSource(), null, { - fillColor: 'rgba(150, 50, 255, 0.2)', - filter: ['==', ['get', 'id'], ''] + function unitInteractions(units, drawingManager, map) { + var unitLayer, unitLines, polygonHoverLayer, unitSymbols; + var layersAdded = [unitLayer, unitLines, polygonHoverLayer, unitSymbols]; + const groupedFeatures = groupAndSort(units, language, selectedLevel); + const keys = Object.keys(groupedFeatures); + + keys.forEach(category => { + var features = groupedFeatures[category].features; + const dataSource = new source.DataSource(); + map.sources.add(dataSource); + dataSource.add(features); + + unitLayer = new layer.PolygonLayer(dataSource, 'unitClick', getFillStyles('unit', category)); + unitLines = new layer.LineLayer(dataSource, null, getLineStyles('unit', category)); + polygonHoverLayer = new layer.PolygonLayer(dataSource, null, { + fillColor: 'rgba(150, 50, 255, 0.2)', + filter: ['==', ['get', 'id'], ''] + }); + + unitSymbols = new layer.SymbolLayer(dataSource, null, getTextStyle(category)); + map.layers.add([unitLayer, polygonHoverLayer, unitLines, unitSymbols], 'roomPolygons'); + grabToPointer([unitLayer, polygonHoverLayer], map); + featureHover(unitLayer, polygonHoverLayer); + + var drawingSource = drawingManager.getSource(); + drawingSource.add(features); + + let dmLayers = drawingManager.getLayers(); + dmLayers.polygonLayer.setOptions({ visible: false }); + dmLayers.polygonOutlineLayer.setOptions({ visible: false }); + layersAdded = [unitLayer, unitLines, polygonHoverLayer, unitSymbols]; + + map.events.add('drawingmodechanged', drawingManager, (e) => { + let dmLayers = drawingManager.getLayers(); + layersAdded = [unitLayer, unitLines, polygonHoverLayer, unitSymbols]; + + if (e === 'idle') { + let updatedFeatures = drawingManager.getSource().shapes; + + deleteUnitPrevEdits(units, selectedLevel); + updatedFeatures.forEach((feature, index) => { + if(isNaN(feature.data.properties.ordinal)) { + setFields(feature); + units.features.push(feature.data); + } }); - unitSymbols = new layer.SymbolLayer(drawingManager.getSource(), null, getTextStyle(category)); - - map.layers.add([unitLayer, polygonHoverLayer, unitLines, unitSymbols], 'roomPolygons'); - - grabToPointer([unitLayer, polygonHoverLayer], map); - featureHover(unitLayer, polygonHoverLayer); - layersAdded = [unitLayer, unitLines, polygonHoverLayer, unitSymbols]; - } - else if (e === 'edit-geometry' || e === 'erase-geometry' || e === 'draw-polygon') { - drawingModeChanged(layersAdded); - dmLayers.polygonLayer.setOptions({ visible: true }); - dmLayers.polygonOutlineLayer.setOptions({ visible: true }); - } - else { - // This will eventually be a visible pop-up - console.log('Not a valid drawing toolbar option.'); - } - }); - - currentEditData(map, drawingManager); - }); - } + + dmLayers.polygonLayer.setOptions({ visible: false }); + dmLayers.polygonOutlineLayer.setOptions({ visible: false }); + map.layers.remove([unitLayer, unitLines, polygonHoverLayer]); + + unitLayer = new layer.PolygonLayer(drawingManager.getSource(), 'unitClick', getFillStyles('unit', category)); + unitLines = new layer.LineLayer(drawingManager.getSource(), null, getLineStyles('unit', category)); + polygonHoverLayer = new layer.PolygonLayer(drawingManager.getSource(), null, { + fillColor: 'rgba(150, 50, 255, 0.2)', + filter: ['==', ['get', 'id'], ''] + }); + unitSymbols = new layer.SymbolLayer(drawingManager.getSource(), null, getTextStyle(category)); + + map.layers.add([unitLayer, polygonHoverLayer, unitLines, unitSymbols], 'roomPolygons'); + grabToPointer([unitLayer, polygonHoverLayer], map); + featureHover(unitLayer, polygonHoverLayer); + layersAdded = [unitLayer, unitLines, polygonHoverLayer, unitSymbols]; + } + else if (e === 'edit-geometry' || e === 'erase-geometry' || e === 'draw-polygon') { + drawingModeChanged(layersAdded); + dmLayers.polygonLayer.setOptions({ visible: true }); + dmLayers.polygonOutlineLayer.setOptions({ visible: true }); + } + else { + // This will eventually be a visible pop-up + console.log('Not a valid drawing toolbar option.'); + } + + }); + currentEditData(map, drawingManager); + }); + } // Entry point when "level.geojson" is pressed; the following code should be refactored due to redundancy function levelInteractions(levels, drawingManager, map) { @@ -269,6 +274,10 @@ const PlacesPreviewMap = ({ style }) => { grabToPointer([lineLayer, lineHoverLayer], map); layersAdded = [lineLayer, lineHoverLayer]; featureHover(lineLayer, lineHoverLayer); + + let updatedFeatures = drawingManager.getSource().shapes; + + setLevels(prevLevels => updateLevels(prevLevels, selectedLevel, (updatedFeatures[0]).data)); } else if (e === 'edit-geometry' || e === 'erase-geometry' || e === 'draw-polygon') { drawingModeChanged(layersAdded); @@ -279,7 +288,9 @@ const PlacesPreviewMap = ({ style }) => { // This will eventually be a visible pop-up console.log('Not a valid drawing toolbar option.'); } - }); + }); + + currentEditData(map, drawingManager); } // Entry point when "footprint.geojson" is pressed; the following code should be refactored due to redundancy @@ -332,6 +343,9 @@ const PlacesPreviewMap = ({ style }) => { grabToPointer([footprintLayer, footprintHoverLayer], map); featureHover(footprintLayer, footprintHoverLayer); layersAdded = [footprintLayer, footprintLines, footprintHoverLayer]; + + let updatedFeatures = drawingManager.getSource().shapes; + footprint.features[0] = updatedFeatures[0].data; } else if (e === 'edit-geometry' || e === 'erase-geometry' || e === 'draw-polygon') { drawingModeChanged(layersAdded); @@ -342,21 +356,60 @@ const PlacesPreviewMap = ({ style }) => { // This will eventually be a visible pop-up console.log('Not a valid drawing toolbar option.'); } - }); + }); + + currentEditData(map, drawingManager); } // Entry point when "full view" is pressed; the following code may need to be changed to allow fill color of units while editing - // Needs to be given edit properties function fullViewInteractions(units, levels, drawingManager, map) { - unitInteractions(units, drawingManager, map); levelInteractions(levels, drawingManager, map); + unitInteractions(units, drawingManager, map); + } + + function updateLevels(levels, selectedLevel, newValue) { + levels.features = levels.features.map(item => + item.id === selectedLevel.id ? newValue : item + ); + + return levels; + } + + function setFields(feature) { + if (!feature.data.properties.name) { + feature.data.properties.name = {}; + feature.data.properties.name.en = ''; + } + + if(!feature.data.properties.category) { + feature.data.properties.category = 'unspecified'; + } + + if(!feature.data.properties.level_id) { + feature.data.properties.level_id = selectedLevel.id; + } + + if(!feature.data.properties.display_point) { + feature.data.properties.display_point = {}; + feature.data.properties.display_point.type = 'Point'; + feature.data.properties.display_point.coordinates = []; + } + + if(!feature.data.properties.label) { + feature.data.properties.label = ''; + } + } + + function deleteUnitPrevEdits(units, selectedLevel) { + // let new_features = units.features.filter(item => item.properties.level_id === selectedLevel.id); + units.features = units.features.filter(item => item.properties.level_id !== selectedLevel.id); } // Cleanup function to remove the map instance when component unmounts or reinitializes return () => { map.dispose(); }; - }, [units, levels, footprint, selectedLevel, selectedLayerId, subscriptionKey, geography, language]); + }, [units, levels, footprint, selectedLevel, selectedLayerId, subscriptionKey, geography, language, imdfPackageLocation]); const handleLevelChange = levelId => { setSelectedLevelId(levelId); @@ -376,7 +429,6 @@ const PlacesPreviewMap = ({ style }) => { options={levels.features.map(level => ({ key: level.id, text: getFeatureLabel(level, language) }))} /> -
{
-
- Save Changes +
- - + ); }; From 9d5bd2c29f1ec1536019d51d4fbe22053b7382e6 Mon Sep 17 00:00:00 2001 From: Nicole Iftekhar Date: Thu, 8 Aug 2024 14:42:02 -0700 Subject: [PATCH 02/23] Added more features to download IMDF edits button --- .../download-edits-button/index.js | 64 +++++++++++-------- .../imdf-model-helpers/index.js | 42 +++++++++++- .../conversion/places-preview-map/index.js | 46 ++----------- 3 files changed, 81 insertions(+), 71 deletions(-) diff --git a/src/pages/conversion/places-preview-map/download-edits-button/index.js b/src/pages/conversion/places-preview-map/download-edits-button/index.js index a3bdd6c..b971199 100644 --- a/src/pages/conversion/places-preview-map/download-edits-button/index.js +++ b/src/pages/conversion/places-preview-map/download-edits-button/index.js @@ -1,31 +1,39 @@ -import React from 'react'; +import React, { useState } from 'react'; import JSZip from 'jszip'; import { saveAs } from 'file-saver'; -import { DefaultButton } from '@fluentui/react'; -// import { logsButton } from '.../style'; +import { PrimaryButton } from '@fluentui/react'; -export const YourComponent = ({ imdfPackageLocation, units, levels, footprint}) => { - const handleUpdateZip = () => { - fetch(imdfPackageLocation) - .then(response => response.arrayBuffer()) - .then(data => { - const zip = new JSZip(); - return zip.loadAsync(data); - }) - .then(zip => { - zip.file('unit.geojson', JSON.stringify(units, null, 2)); - zip.file('level.geojson', JSON.stringify(levels, null, 2)); - zip.file('footprint.geojson', JSON.stringify(footprint, null, 2)); - return zip.generateAsync({ type: 'blob' }); - }) - .then(updatedZip => { - saveAs(updatedZip, 'updated_imdf_package.zip'); - }); - }; - - return ( -
- Download Updated IMDF -
- ); - }; \ No newline at end of file +export const DownloadEditsButton = ({ imdfPackageLocation, units, levels, footprint }) => { + const [isLoading, setIsLoading] = useState(false); + + const handleUpdateZip = () => { + setIsLoading(true); + fetch(imdfPackageLocation) + .then(response => response.arrayBuffer()) + .then(data => { + const zip = new JSZip(); + return zip.loadAsync(data); + }) + .then(zip => { + zip.file('unit.geojson', JSON.stringify(units, null, 2)); + zip.file('level.geojson', JSON.stringify(levels, null, 2)); + zip.file('footprint.geojson', JSON.stringify(footprint, null, 2)); + return zip.generateAsync({ type: 'blob' }); + }) + .then(updatedZip => { + saveAs(updatedZip, 'updated_imdf_package.zip'); + setIsLoading(false); + }) + .catch(() => { + setIsLoading(false); + }); + }; + + return ( +
+ + {isLoading ? 'Downloading..' : 'Download Updated IMDF'} + +
+ ); +}; \ No newline at end of file diff --git a/src/pages/conversion/places-preview-map/imdf-model-helpers/index.js b/src/pages/conversion/places-preview-map/imdf-model-helpers/index.js index 3c3a29b..f58fba3 100644 --- a/src/pages/conversion/places-preview-map/imdf-model-helpers/index.js +++ b/src/pages/conversion/places-preview-map/imdf-model-helpers/index.js @@ -51,10 +51,50 @@ function grabToPointer(layerName, map) { }); } +function updateLevels(levels, selectedLevel, newValue) { + levels.features = levels.features.map(item => + item.id === selectedLevel.id ? newValue : item + ); + + return levels; +} + +function setFields(feature, selectedLevel) { + if (!feature.data.properties.name) { + feature.data.properties.name = {}; + feature.data.properties.name.en = ''; + } + + if(!feature.data.properties.category) { + feature.data.properties.category = 'unspecified'; + } + + if(!feature.data.properties.level_id) { + feature.data.properties.level_id = selectedLevel.id; + } + + if(!feature.data.properties.display_point) { + feature.data.properties.display_point = {}; + feature.data.properties.display_point.type = 'Point'; + feature.data.properties.display_point.coordinates = []; + } + + if(!feature.data.properties.label) { + feature.data.properties.label = ''; + } +} + +function deleteUnitPrevEdits(units, selectedLevel) { + units.features = units.features.filter(item => item.properties.level_id !== selectedLevel.id); +} + export { currentEditData, groupAndSort, drawingModeChanged, writeToInfoPanel, - grabToPointer + grabToPointer, + updateLevels, + setFields, + deleteUnitPrevEdits }; \ No newline at end of file diff --git a/src/pages/conversion/places-preview-map/index.js b/src/pages/conversion/places-preview-map/index.js index 70361a6..43dbfb2 100644 --- a/src/pages/conversion/places-preview-map/index.js +++ b/src/pages/conversion/places-preview-map/index.js @@ -7,9 +7,9 @@ import LevelSelector from './level-selector'; import LayerSelector from './layer-selector'; import MapNotification from './map-notification'; import { calculateBoundingBox, getFeatureLabel, getFillStyles, getLineStyles, getTextStyle, processZip } from './utils'; -import { currentEditData, groupAndSort, drawingModeChanged, writeToInfoPanel, grabToPointer } from './imdf-model-helpers'; +import { currentEditData, groupAndSort, drawingModeChanged, writeToInfoPanel, grabToPointer, updateLevels, setFields, deleteUnitPrevEdits } from './imdf-model-helpers'; // import { JsonEditor } from 'json-edit-react' -import { YourComponent } from './download-edits-button'; +import { DownloadEditsButton } from './download-edits-button'; import 'azure-maps-drawing-tools/dist/atlas-drawing.min.css'; import 'azure-maps-control/dist/atlas.min.css'; @@ -191,7 +191,7 @@ const PlacesPreviewMap = ({ style }) => { deleteUnitPrevEdits(units, selectedLevel); updatedFeatures.forEach((feature, index) => { if(isNaN(feature.data.properties.ordinal)) { - setFields(feature); + setFields(feature, selectedLevel); units.features.push(feature.data); } }); @@ -367,44 +367,6 @@ const PlacesPreviewMap = ({ style }) => { unitInteractions(units, drawingManager, map); } - function updateLevels(levels, selectedLevel, newValue) { - levels.features = levels.features.map(item => - item.id === selectedLevel.id ? newValue : item - ); - - return levels; - } - - function setFields(feature) { - if (!feature.data.properties.name) { - feature.data.properties.name = {}; - feature.data.properties.name.en = ''; - } - - if(!feature.data.properties.category) { - feature.data.properties.category = 'unspecified'; - } - - if(!feature.data.properties.level_id) { - feature.data.properties.level_id = selectedLevel.id; - } - - if(!feature.data.properties.display_point) { - feature.data.properties.display_point = {}; - feature.data.properties.display_point.type = 'Point'; - feature.data.properties.display_point.coordinates = []; - } - - if(!feature.data.properties.label) { - feature.data.properties.label = ''; - } - } - - function deleteUnitPrevEdits(units, selectedLevel) { - // let new_features = units.features.filter(item => item.properties.level_id === selectedLevel.id); - units.features = units.features.filter(item => item.properties.level_id !== selectedLevel.id); - } - // Cleanup function to remove the map instance when component unmounts or reinitializes return () => { map.dispose(); @@ -446,7 +408,7 @@ const PlacesPreviewMap = ({ style }) => {
- +
); From 3a9f5e6ec2c8a73453426a25d43184d5ea8febce Mon Sep 17 00:00:00 2001 From: Nicole Iftekhar Date: Fri, 9 Aug 2024 15:21:08 -0700 Subject: [PATCH 03/23] Shifted download IMDF button to original only --- src/pages/conversion/download-imdf.js | 44 ++++++++++++++++--- src/pages/conversion/imdf-conversion.js | 21 ++++++++- .../download-edits-button/index.js | 39 ---------------- .../places-preview-map/indes.style.js | 7 +-- .../conversion/places-preview-map/index.js | 15 +++---- 5 files changed, 64 insertions(+), 62 deletions(-) delete mode 100644 src/pages/conversion/places-preview-map/download-edits-button/index.js diff --git a/src/pages/conversion/download-imdf.js b/src/pages/conversion/download-imdf.js index 7a3b863..fc64310 100644 --- a/src/pages/conversion/download-imdf.js +++ b/src/pages/conversion/download-imdf.js @@ -1,11 +1,41 @@ -import { cx } from '@emotion/css'; -import { PrimaryButton } from '@fluentui/react'; -import { failedLogsButton, logsButton } from './style'; +import { cx } from '@emotion/css'; +import { PrimaryButton } from '@fluentui/react'; +import { logsButton } from './style'; +import React, { useState } from 'react'; +import JSZip from 'jszip'; +import { saveAs } from 'file-saver'; + +export const DownloadIMDF = ({ imdfPackageLocation, units, levels, footprint }) => { + const [isLoading, setIsLoading] = useState(false); + + const handleUpdateZip = () => { + setIsLoading(true); + fetch(imdfPackageLocation) + .then(response => response.arrayBuffer()) + .then(data => { + const zip = new JSZip(); + return zip.loadAsync(data); + }) + .then(zip => { + zip.file('unit.geojson', JSON.stringify(units, null, 2)); + zip.file('level.geojson', JSON.stringify(levels, null, 2)); + zip.file('footprint.geojson', JSON.stringify(footprint, null, 2)); + return zip.generateAsync({ type: 'blob' }); + }) + .then(updatedZip => { + saveAs(updatedZip, 'updated_imdf_package.zip'); + setIsLoading(false); + }) + .catch(() => { + setIsLoading(false); + }); + }; -export const DownloadIMDF = ({ isFailed, link }) => { return ( - - Download IMDF - +
+ + {isLoading ? 'Downloading..' : 'Download IMDF'} + +
); }; diff --git a/src/pages/conversion/imdf-conversion.js b/src/pages/conversion/imdf-conversion.js index db513ed..25e7b44 100644 --- a/src/pages/conversion/imdf-conversion.js +++ b/src/pages/conversion/imdf-conversion.js @@ -1,4 +1,5 @@ import { cx } from '@emotion/css'; +import { useState } from 'react'; import { MessageBar, MessageBarType } from '@fluentui/react'; import { Icon } from '@fluentui/react/lib/Icon'; import { PATHS } from 'common'; @@ -16,6 +17,22 @@ import StepButton from './step-button'; import { container, content, enabledStep, step as stepStyle, stepTitle, stepsContainer } from './style'; const ImdfConversion = () => { + const [units, setUnits] = useState({ features: [] }); + const [levels, setLevels] = useState({ features: [] }); + const [footprint, setFootprint] = useState({ features: [] }); + + const handleUnitsChange = (editedUnits) => { + setUnits(editedUnits); + }; + + const handleLevelsChange = (editedLevels) => { + setLevels(editedLevels); + }; + + const handleFootprintChange = (editedFootprint) => { + setFootprint(editedFootprint); + }; + const { t } = useTranslation(); const navigate = useCustomNavigate(); @@ -76,7 +93,7 @@ const ImdfConversion = () => {
{imdfConversionStatus === conversionStatuses.finishedSuccessfully && ( - + )}
@@ -84,7 +101,7 @@ const ImdfConversion = () => {
{imdfConversionStatus === conversionStatuses.finishedSuccessfully && ( - {({ height }) => } + {({ height }) => } )} diff --git a/src/pages/conversion/places-preview-map/download-edits-button/index.js b/src/pages/conversion/places-preview-map/download-edits-button/index.js deleted file mode 100644 index b971199..0000000 --- a/src/pages/conversion/places-preview-map/download-edits-button/index.js +++ /dev/null @@ -1,39 +0,0 @@ -import React, { useState } from 'react'; -import JSZip from 'jszip'; -import { saveAs } from 'file-saver'; -import { PrimaryButton } from '@fluentui/react'; - -export const DownloadEditsButton = ({ imdfPackageLocation, units, levels, footprint }) => { - const [isLoading, setIsLoading] = useState(false); - - const handleUpdateZip = () => { - setIsLoading(true); - fetch(imdfPackageLocation) - .then(response => response.arrayBuffer()) - .then(data => { - const zip = new JSZip(); - return zip.loadAsync(data); - }) - .then(zip => { - zip.file('unit.geojson', JSON.stringify(units, null, 2)); - zip.file('level.geojson', JSON.stringify(levels, null, 2)); - zip.file('footprint.geojson', JSON.stringify(footprint, null, 2)); - return zip.generateAsync({ type: 'blob' }); - }) - .then(updatedZip => { - saveAs(updatedZip, 'updated_imdf_package.zip'); - setIsLoading(false); - }) - .catch(() => { - setIsLoading(false); - }); - }; - - return ( -
- - {isLoading ? 'Downloading..' : 'Download Updated IMDF'} - -
- ); -}; \ No newline at end of file diff --git a/src/pages/conversion/places-preview-map/indes.style.js b/src/pages/conversion/places-preview-map/indes.style.js index 0f78087..05bc033 100644 --- a/src/pages/conversion/places-preview-map/indes.style.js +++ b/src/pages/conversion/places-preview-map/indes.style.js @@ -18,7 +18,7 @@ export const imdfPreviewMap = css` export const layerSelect = css ` position: relative; - top: 65%; + top: 48%; `; export const textWrapper = css ` @@ -35,10 +35,5 @@ export const textArea = css ` resize: none; `; -export const saveButtonWrapper = css ` - display: flex; - flex-direction: row; - justify-content: flex-end; -`; diff --git a/src/pages/conversion/places-preview-map/index.js b/src/pages/conversion/places-preview-map/index.js index 43dbfb2..3d45232 100644 --- a/src/pages/conversion/places-preview-map/index.js +++ b/src/pages/conversion/places-preview-map/index.js @@ -2,18 +2,17 @@ import { Map, layer, source, control } from 'azure-maps-control'; import { control as draw_control, drawing } from 'azure-maps-drawing-tools'; import { getDomain, useConversionStore, useLevelsStore, useUserStore } from 'common/store'; import { useEffect, useMemo, useState } from 'react'; -import { imdfPreviewMap, imdfPreviewMapWrapper, layerSelect, textWrapper, textArea, mapTextWrapper, saveButtonWrapper } from './indes.style'; +import { imdfPreviewMap, imdfPreviewMapWrapper, layerSelect, textWrapper, textArea, mapTextWrapper } from './indes.style'; import LevelSelector from './level-selector'; import LayerSelector from './layer-selector'; import MapNotification from './map-notification'; import { calculateBoundingBox, getFeatureLabel, getFillStyles, getLineStyles, getTextStyle, processZip } from './utils'; import { currentEditData, groupAndSort, drawingModeChanged, writeToInfoPanel, grabToPointer, updateLevels, setFields, deleteUnitPrevEdits } from './imdf-model-helpers'; // import { JsonEditor } from 'json-edit-react' -import { DownloadEditsButton } from './download-edits-button'; import 'azure-maps-drawing-tools/dist/atlas-drawing.min.css'; import 'azure-maps-control/dist/atlas.min.css'; -const PlacesPreviewMap = ({ style }) => { +const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged }) => { const [geography, subscriptionKey] = useUserStore(s => [s.geography, s.subscriptionKey]); const [imdfPackageLocation] = useConversionStore(s => [s.imdfPackageLocation]); const [language] = useLevelsStore(s => [s.language]); @@ -196,6 +195,8 @@ const PlacesPreviewMap = ({ style }) => { } }); + unitsChanged(units); + dmLayers.polygonLayer.setOptions({ visible: false }); dmLayers.polygonOutlineLayer.setOptions({ visible: false }); map.layers.remove([unitLayer, unitLines, polygonHoverLayer]); @@ -278,6 +279,7 @@ const PlacesPreviewMap = ({ style }) => { let updatedFeatures = drawingManager.getSource().shapes; setLevels(prevLevels => updateLevels(prevLevels, selectedLevel, (updatedFeatures[0]).data)); + levelsChanged(levels); } else if (e === 'edit-geometry' || e === 'erase-geometry' || e === 'draw-polygon') { drawingModeChanged(layersAdded); @@ -346,6 +348,7 @@ const PlacesPreviewMap = ({ style }) => { let updatedFeatures = drawingManager.getSource().shapes; footprint.features[0] = updatedFeatures[0].data; + footprintChanged(footprint); } else if (e === 'edit-geometry' || e === 'erase-geometry' || e === 'draw-polygon') { drawingModeChanged(layersAdded); @@ -371,7 +374,7 @@ const PlacesPreviewMap = ({ style }) => { return () => { map.dispose(); }; - }, [units, levels, footprint, selectedLevel, selectedLayerId, subscriptionKey, geography, language, imdfPackageLocation]); + }, [units, levels, footprint, selectedLevel, selectedLayerId, subscriptionKey, geography, language, imdfPackageLocation, unitsChanged, levelsChanged, footprintChanged]); const handleLevelChange = levelId => { setSelectedLevelId(levelId); @@ -406,10 +409,6 @@ const PlacesPreviewMap = ({ style }) => { - -
- -
); }; From 575eee57a6b8d8aef4e40397cea150b975ddff04 Mon Sep 17 00:00:00 2001 From: Nicole Iftekhar Date: Fri, 9 Aug 2024 15:28:48 -0700 Subject: [PATCH 04/23] Added comments to new code --- src/pages/conversion/download-imdf.js | 2 ++ src/pages/conversion/places-preview-map/indes.style.js | 3 --- src/pages/conversion/places-preview-map/index.js | 8 +++++++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/pages/conversion/download-imdf.js b/src/pages/conversion/download-imdf.js index fc64310..e53f699 100644 --- a/src/pages/conversion/download-imdf.js +++ b/src/pages/conversion/download-imdf.js @@ -5,9 +5,11 @@ import React, { useState } from 'react'; import JSZip from 'jszip'; import { saveAs } from 'file-saver'; +// This component downloads the updated IMDF zip file and is triggered by users clicking "Download IMDF" button export const DownloadIMDF = ({ imdfPackageLocation, units, levels, footprint }) => { const [isLoading, setIsLoading] = useState(false); + // Fetches current zip file, updates the geojson files and downloads the updated zip const handleUpdateZip = () => { setIsLoading(true); fetch(imdfPackageLocation) diff --git a/src/pages/conversion/places-preview-map/indes.style.js b/src/pages/conversion/places-preview-map/indes.style.js index 05bc033..a1ae104 100644 --- a/src/pages/conversion/places-preview-map/indes.style.js +++ b/src/pages/conversion/places-preview-map/indes.style.js @@ -34,6 +34,3 @@ export const textArea = css ` white-space: nowrap; resize: none; `; - - - diff --git a/src/pages/conversion/places-preview-map/index.js b/src/pages/conversion/places-preview-map/index.js index 3d45232..d5c4829 100644 --- a/src/pages/conversion/places-preview-map/index.js +++ b/src/pages/conversion/places-preview-map/index.js @@ -69,6 +69,8 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged map.events.add('ready', () => { var drawingToolbar; + + // Resets text area when a different layer is selected document.getElementById('infoPanel-json').value = ''; if(selectedLayerId === 'unitButton') { drawingToolbar = new draw_control.DrawingToolbar({ @@ -195,6 +197,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged } }); + // Update the units state with the edited features (for updating zip) unitsChanged(units); dmLayers.polygonLayer.setOptions({ visible: false }); @@ -277,8 +280,9 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged featureHover(lineLayer, lineHoverLayer); let updatedFeatures = drawingManager.getSource().shapes; - setLevels(prevLevels => updateLevels(prevLevels, selectedLevel, (updatedFeatures[0]).data)); + + // Update the levels state with the edited features (for updating zip) levelsChanged(levels); } else if (e === 'edit-geometry' || e === 'erase-geometry' || e === 'draw-polygon') { @@ -348,6 +352,8 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged let updatedFeatures = drawingManager.getSource().shapes; footprint.features[0] = updatedFeatures[0].data; + + // Update the footprint state with the edited features (for updating zip) footprintChanged(footprint); } else if (e === 'edit-geometry' || e === 'erase-geometry' || e === 'draw-polygon') { From deedae3572cc90405db12f75cd2bb7e171baed71 Mon Sep 17 00:00:00 2001 From: Nicole Iftekhar Date: Fri, 9 Aug 2024 17:30:57 -0700 Subject: [PATCH 05/23] Added map pop-up notification when user is in drawing polygon edit mode --- src/pages/conversion/imdf-conversion.js | 2 ++ src/pages/conversion/places-preview-map/index.js | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/src/pages/conversion/imdf-conversion.js b/src/pages/conversion/imdf-conversion.js index 25e7b44..4af5d04 100644 --- a/src/pages/conversion/imdf-conversion.js +++ b/src/pages/conversion/imdf-conversion.js @@ -15,6 +15,7 @@ import { ImdfDiagnostics } from './imdf-diagnostics'; import PlacesPreviewMap from './places-preview-map'; import StepButton from './step-button'; import { container, content, enabledStep, step as stepStyle, stepTitle, stepsContainer } from './style'; +// import { JsonEditor } from 'json-edit-react'; const ImdfConversion = () => { const [units, setUnits] = useState({ features: [] }); @@ -104,6 +105,7 @@ const ImdfConversion = () => { {({ height }) => } )} + {/* */} )} diff --git a/src/pages/conversion/places-preview-map/index.js b/src/pages/conversion/places-preview-map/index.js index d5c4829..52210d7 100644 --- a/src/pages/conversion/places-preview-map/index.js +++ b/src/pages/conversion/places-preview-map/index.js @@ -51,6 +51,8 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged const [selectedLayerId, setSelectedLayerId] = useState(null); + const [drawNotif, setDrawNotif] = useState(false); + useEffect(() => { var drawingManager; @@ -187,6 +189,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged layersAdded = [unitLayer, unitLines, polygonHoverLayer, unitSymbols]; if (e === 'idle') { + setDrawNotif(false); let updatedFeatures = drawingManager.getSource().shapes; deleteUnitPrevEdits(units, selectedLevel); @@ -221,6 +224,10 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged drawingModeChanged(layersAdded); dmLayers.polygonLayer.setOptions({ visible: true }); dmLayers.polygonOutlineLayer.setOptions({ visible: true }); + + if(e === 'draw-polygon') { + setDrawNotif(true); + } } else { // This will eventually be a visible pop-up @@ -408,6 +415,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged Zoom in to see labels and icons. + {drawNotif && To connect the final lines of current drawing, press 'c'.}
From 4d0a67065aa9c6c4d789402a376498ff672c3c2d Mon Sep 17 00:00:00 2001 From: Nicole Iftekhar Date: Mon, 12 Aug 2024 15:52:34 -0700 Subject: [PATCH 06/23] Improved geojson editor view, responds to clicks on features in viewing mode --- src/pages/conversion/imdf-conversion.js | 1 - .../places-preview-map/indes.style.js | 3 +- .../conversion/places-preview-map/index.js | 36 ++++++++++++++----- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/pages/conversion/imdf-conversion.js b/src/pages/conversion/imdf-conversion.js index 4af5d04..dc73570 100644 --- a/src/pages/conversion/imdf-conversion.js +++ b/src/pages/conversion/imdf-conversion.js @@ -105,7 +105,6 @@ const ImdfConversion = () => { {({ height }) => } )} - {/* */} )} diff --git a/src/pages/conversion/places-preview-map/indes.style.js b/src/pages/conversion/places-preview-map/indes.style.js index a1ae104..7a85737 100644 --- a/src/pages/conversion/places-preview-map/indes.style.js +++ b/src/pages/conversion/places-preview-map/indes.style.js @@ -22,10 +22,9 @@ export const layerSelect = css ` `; export const textWrapper = css ` - flex: 1 1 4rem; + flex: 1 1 5rem; position: relative; display: inline; - margin-top: 1%; `; export const textArea = css ` diff --git a/src/pages/conversion/places-preview-map/index.js b/src/pages/conversion/places-preview-map/index.js index 52210d7..e5df00c 100644 --- a/src/pages/conversion/places-preview-map/index.js +++ b/src/pages/conversion/places-preview-map/index.js @@ -2,13 +2,13 @@ import { Map, layer, source, control } from 'azure-maps-control'; import { control as draw_control, drawing } from 'azure-maps-drawing-tools'; import { getDomain, useConversionStore, useLevelsStore, useUserStore } from 'common/store'; import { useEffect, useMemo, useState } from 'react'; -import { imdfPreviewMap, imdfPreviewMapWrapper, layerSelect, textWrapper, textArea, mapTextWrapper } from './indes.style'; +import { imdfPreviewMap, imdfPreviewMapWrapper, layerSelect, textWrapper, mapTextWrapper } from './indes.style'; import LevelSelector from './level-selector'; import LayerSelector from './layer-selector'; import MapNotification from './map-notification'; import { calculateBoundingBox, getFeatureLabel, getFillStyles, getLineStyles, getTextStyle, processZip } from './utils'; -import { currentEditData, groupAndSort, drawingModeChanged, writeToInfoPanel, grabToPointer, updateLevels, setFields, deleteUnitPrevEdits } from './imdf-model-helpers'; -// import { JsonEditor } from 'json-edit-react' +import { currentEditData, groupAndSort, drawingModeChanged, grabToPointer, updateLevels, setFields, deleteUnitPrevEdits } from './imdf-model-helpers'; +import { JsonEditor } from 'json-edit-react' import 'azure-maps-drawing-tools/dist/atlas-drawing.min.css'; import 'azure-maps-control/dist/atlas.min.css'; @@ -20,6 +20,8 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged const [units, setUnits] = useState({ features: [] }); const [levels, setLevels] = useState({ features: [] }); + const [jsonData, setJsonData] = useState({}); + // const [building, setBuilding] = useState({ features: [] }); // building will be used eventually const [footprint, setFootprint] = useState({ features: [] }); @@ -50,10 +52,10 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged }, [levels, selectedLevelId]); const [selectedLayerId, setSelectedLayerId] = useState(null); - const [drawNotif, setDrawNotif] = useState(false); useEffect(() => { + var drawingManager; const map = new Map('azure-maps-container', { @@ -73,7 +75,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged var drawingToolbar; // Resets text area when a different layer is selected - document.getElementById('infoPanel-json').value = ''; + // document.getElementById('infoPanel-json').value = ''; if(selectedLayerId === 'unitButton') { drawingToolbar = new draw_control.DrawingToolbar({ position: 'bottom-right', @@ -136,7 +138,8 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged features = map.layers.getRenderedShapes(e.position, ['unitClick', 'levelClick']); features.forEach(function (feature) { - writeToInfoPanel(feature.data); + // writeToInfoPanel(feature.data); + setJsonData(feature.data); }); }); @@ -387,7 +390,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged return () => { map.dispose(); }; - }, [units, levels, footprint, selectedLevel, selectedLayerId, subscriptionKey, geography, language, imdfPackageLocation, unitsChanged, levelsChanged, footprintChanged]); + }, [units, levels, footprint, selectedLevel, selectedLayerId, subscriptionKey, geography, language, imdfPackageLocation, unitsChanged, levelsChanged, footprintChanged ]); const handleLevelChange = levelId => { setSelectedLevelId(levelId); @@ -397,6 +400,10 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged setSelectedLayerId(layerId); }; + const updateJsonData = (newData) => { + setJsonData(newData); + }; + return (
@@ -419,8 +426,19 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged
-
- +
+
From 158c389baaad9db7fb665a088aafe356c7386d78 Mon Sep 17 00:00:00 2001 From: Nicole Iftekhar Date: Tue, 13 Aug 2024 09:46:54 -0700 Subject: [PATCH 07/23] Certain fields are editable + fields rearranged to fit same format --- .../imdf-model-helpers/index.js | 18 +++++++------ .../places-preview-map/indes.style.js | 8 +----- .../conversion/places-preview-map/index.js | 25 +++++++++++++------ 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/pages/conversion/places-preview-map/imdf-model-helpers/index.js b/src/pages/conversion/places-preview-map/imdf-model-helpers/index.js index f58fba3..ac54721 100644 --- a/src/pages/conversion/places-preview-map/imdf-model-helpers/index.js +++ b/src/pages/conversion/places-preview-map/imdf-model-helpers/index.js @@ -13,7 +13,7 @@ function currentEditData(map, drawingManager) { if(f?.data) { var shapeId = f.data.id; var geojsonData = drawingManager.getSource().getShapeById(shapeId).data; - document.getElementById('infoPanel-json').value = JSON.stringify(geojsonData, null, 2); + return geojsonData; } }); } @@ -35,11 +35,6 @@ function groupAndSort(units, language, selectedLevel) { return groupedFeatures; } -function writeToInfoPanel(geojsonData) { - const { map, ...obj } = geojsonData; - document.getElementById('infoPanel-json').value = JSON.stringify(obj, null, 2); -} - // Changes the cursor to be a pointer when a clickable feature is hovered over function grabToPointer(layerName, map) { map.events.add('mouseover', layerName, function () { @@ -82,6 +77,16 @@ function setFields(feature, selectedLevel) { if(!feature.data.properties.label) { feature.data.properties.label = ''; } + + if(feature.data.properties._azureMapsShapeId) { + let savedAzureId = feature.data.properties._azureMapsShapeId; + delete feature.data.properties._azureMapsShapeId; + feature.data.properties._azureMapsShapeId = savedAzureId; + } + + if ('bbox' in feature.data.geometry) { + delete feature.data.geometry.bbox; + } } function deleteUnitPrevEdits(units, selectedLevel) { @@ -92,7 +97,6 @@ export { currentEditData, groupAndSort, drawingModeChanged, - writeToInfoPanel, grabToPointer, updateLevels, setFields, diff --git a/src/pages/conversion/places-preview-map/indes.style.js b/src/pages/conversion/places-preview-map/indes.style.js index 7a85737..0a3ddcd 100644 --- a/src/pages/conversion/places-preview-map/indes.style.js +++ b/src/pages/conversion/places-preview-map/indes.style.js @@ -18,7 +18,7 @@ export const imdfPreviewMap = css` export const layerSelect = css ` position: relative; - top: 48%; + top: 60%; `; export const textWrapper = css ` @@ -27,9 +27,3 @@ export const textWrapper = css ` display: inline; `; -export const textArea = css ` - width: 95%; - height: 95%; - white-space: nowrap; - resize: none; -`; diff --git a/src/pages/conversion/places-preview-map/index.js b/src/pages/conversion/places-preview-map/index.js index e5df00c..b92a78b 100644 --- a/src/pages/conversion/places-preview-map/index.js +++ b/src/pages/conversion/places-preview-map/index.js @@ -55,7 +55,6 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged const [drawNotif, setDrawNotif] = useState(false); useEffect(() => { - var drawingManager; const map = new Map('azure-maps-container', { @@ -73,9 +72,8 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged map.events.add('ready', () => { var drawingToolbar; + setJsonData({}); - // Resets text area when a different layer is selected - // document.getElementById('infoPanel-json').value = ''; if(selectedLayerId === 'unitButton') { drawingToolbar = new draw_control.DrawingToolbar({ position: 'bottom-right', @@ -138,8 +136,8 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged features = map.layers.getRenderedShapes(e.position, ['unitClick', 'levelClick']); features.forEach(function (feature) { - // writeToInfoPanel(feature.data); - setJsonData(feature.data); + const newData = feature.data || {}; + setJsonData(newData); }); }); @@ -238,7 +236,8 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged } }); - currentEditData(map, drawingManager); + let editData = currentEditData(map, drawingManager) || {}; + setJsonData(editData); }); } @@ -426,7 +425,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged
-
+
{ + const allowedFields = [ + 'properties.name.en', + 'properties.label' + ]; + return !allowedFields.includes(path.join('.')) + }} + restrictTypeSelection={ ({ path, type }) => { + if (typeof type === 'string') return ['string'] + return ['string', 'number', 'boolean', 'array', 'object']; + }} rootFontSize={12} indent={2} theme="githubLight" From ea572e9fa4787c62a275fe161e275a944490b906 Mon Sep 17 00:00:00 2001 From: Nicole Iftekhar Date: Tue, 13 Aug 2024 16:13:29 -0700 Subject: [PATCH 08/23] Edits made to properties are now displayed and saved to downloadable IMDF zip --- src/pages/conversion/imdf-conversion.js | 22 +++++++- .../imdf-model-helpers/index.js | 8 +-- .../conversion/places-preview-map/index.js | 52 ++++++++++++++----- 3 files changed, 63 insertions(+), 19 deletions(-) diff --git a/src/pages/conversion/imdf-conversion.js b/src/pages/conversion/imdf-conversion.js index dc73570..f24e33f 100644 --- a/src/pages/conversion/imdf-conversion.js +++ b/src/pages/conversion/imdf-conversion.js @@ -1,5 +1,5 @@ import { cx } from '@emotion/css'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { MessageBar, MessageBarType } from '@fluentui/react'; import { Icon } from '@fluentui/react/lib/Icon'; import { PATHS } from 'common'; @@ -14,8 +14,8 @@ import { actionButtonsLeft, actionButtonsWrapper, messageWrapper } from './imdf- import { ImdfDiagnostics } from './imdf-diagnostics'; import PlacesPreviewMap from './places-preview-map'; import StepButton from './step-button'; +import { processZip } from './places-preview-map/utils'; import { container, content, enabledStep, step as stepStyle, stepTitle, stepsContainer } from './style'; -// import { JsonEditor } from 'json-edit-react'; const ImdfConversion = () => { const [units, setUnits] = useState({ features: [] }); @@ -46,7 +46,25 @@ const ImdfConversion = () => { s.imdfPackageLocation, s.diagnosticPackageLocation, ]); + + useEffect(() => { + if (!imdfPackageLocation) return; + processZip(imdfPackageLocation).then(files => { + const unitFile = files.find(file => file.filename === 'unit.geojson'); + const levelFile = files.find(file => file.filename === 'level.geojson'); + // const buildingFile = files.find(file => file.filename === 'building.geojson'); + const footprintFile = files.find(file => file.filename === 'footprint.geojson'); + + if (unitFile && levelFile && footprintFile) { + setUnits(unitFile.content); + setLevels(levelFile.content); + // setBuilding(buildingFile.content); + setFootprint(footprintFile.content); + } + }); + }, [imdfPackageLocation]); + const { isRunningIMDFConversion, hasCompletedIMDFConversion, imdfConversionStatus, errorList } = useIMDFConversionStatus(); diff --git a/src/pages/conversion/places-preview-map/imdf-model-helpers/index.js b/src/pages/conversion/places-preview-map/imdf-model-helpers/index.js index ac54721..a40892a 100644 --- a/src/pages/conversion/places-preview-map/imdf-model-helpers/index.js +++ b/src/pages/conversion/places-preview-map/imdf-model-helpers/index.js @@ -8,12 +8,12 @@ function drawingModeChanged(allLayers) { } // Displays information of a feature that is being drawn/edited, at time of click -function currentEditData(map, drawingManager) { +function currentEditData(map, drawingManager, setJsonData) { map.events.add('drawingstarted', drawingManager, (f) => { if(f?.data) { - var shapeId = f.data.id; - var geojsonData = drawingManager.getSource().getShapeById(shapeId).data; - return geojsonData; + var shapeId = f.data.id; + var geojsonData = drawingManager.getSource().getShapeById(shapeId).data; + setJsonData(geojsonData); } }); } diff --git a/src/pages/conversion/places-preview-map/index.js b/src/pages/conversion/places-preview-map/index.js index b92a78b..4c70aad 100644 --- a/src/pages/conversion/places-preview-map/index.js +++ b/src/pages/conversion/places-preview-map/index.js @@ -143,6 +143,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged // Shows change in corresponding feature color when mouse hovers over that feature function featureHover(layerName, polygonHoverLayer) { + // let selectedFeatureId = null; map.events.add('mousemove', layerName, function (e) { polygonHoverLayer.setOptions({ filter: ['==', ['get', '_azureMapsShapeId'], e.shapes[0].getProperties()['_azureMapsShapeId']] }); }); @@ -229,6 +230,10 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged if(e === 'draw-polygon') { setDrawNotif(true); } + + if(e === 'edit-geometry') { + currentEditData(map, drawingManager, setJsonData); + } } else { // This will eventually be a visible pop-up @@ -236,8 +241,6 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged } }); - let editData = currentEditData(map, drawingManager) || {}; - setJsonData(editData); }); } @@ -294,18 +297,18 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged // Update the levels state with the edited features (for updating zip) levelsChanged(levels); } - else if (e === 'edit-geometry' || e === 'erase-geometry' || e === 'draw-polygon') { + else if (e === 'edit-geometry') { drawingModeChanged(layersAdded); dmLayers.polygonOutlineLayer.setOptions({ visible: true }); dmLayers.polygonLayer.setOptions({ visible: false }); + + currentEditData(map, drawingManager, setJsonData); } else { // This will eventually be a visible pop-up console.log('Not a valid drawing toolbar option.'); } }); - - currentEditData(map, drawingManager); } // Entry point when "footprint.geojson" is pressed; the following code should be refactored due to redundancy @@ -365,18 +368,18 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged // Update the footprint state with the edited features (for updating zip) footprintChanged(footprint); } - else if (e === 'edit-geometry' || e === 'erase-geometry' || e === 'draw-polygon') { + else if (e === 'edit-geometry') { drawingModeChanged(layersAdded); dmLayers.polygonLayer.setOptions({ visible: true }); dmLayers.polygonOutlineLayer.setOptions({ visible: true }); + + currentEditData(map, drawingManager, setJsonData); } else { // This will eventually be a visible pop-up console.log('Not a valid drawing toolbar option.'); } }); - - currentEditData(map, drawingManager); } // Entry point when "full view" is pressed; the following code may need to be changed to allow fill color of units while editing @@ -403,6 +406,26 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged setJsonData(newData); }; + const handleUpdate = ({ newData, currentData, newValue, currentValue, name, path }) => { + if (newData.properties.name && isNaN(newData.properties.ordinal)) { + // if name and NO ordinal -> unit + let editedIndex = units.features.findIndex(unit => unit.id === currentData.id); + if (editedIndex !== -1) { + units.features[editedIndex] = newData; + unitsChanged(units); + } + else { + console.log('Invalid property change.'); + } + } + else if (newData.properties.name) { + // if name and ordinal -> level + console.log('Level'); + } + + return true; + }; + return (
@@ -436,17 +459,20 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged restrictEdit={({ path }) => { const allowedFields = [ 'properties.name.en', - 'properties.label' + 'properties.category' ]; - return !allowedFields.includes(path.join('.')) + return !allowedFields.includes(path.join('.')); }} - restrictTypeSelection={ ({ path, type }) => { - if (typeof type === 'string') return ['string'] - return ['string', 'number', 'boolean', 'array', 'object']; + restrictTypeSelection={ ({ path, value }) => { + if (typeof value === 'string') + return ['string']; + else + return ['string', 'number', 'boolean', 'array', 'object']; }} rootFontSize={12} indent={2} theme="githubLight" + onUpdate={handleUpdate} />
From dab85a44b02e35000499e6167bf4a5e963f2603a Mon Sep 17 00:00:00 2001 From: Nicole Iftekhar Date: Tue, 13 Aug 2024 17:42:35 -0700 Subject: [PATCH 09/23] Edits made to properties in level.geojson are now displayed + saved to downloadable IMDF zip --- .../conversion/places-preview-map/index.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/pages/conversion/places-preview-map/index.js b/src/pages/conversion/places-preview-map/index.js index 4c70aad..77264f2 100644 --- a/src/pages/conversion/places-preview-map/index.js +++ b/src/pages/conversion/places-preview-map/index.js @@ -406,11 +406,13 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged setJsonData(newData); }; + // Handles updates when a property is changed in the JSON editor const handleUpdate = ({ newData, currentData, newValue, currentValue, name, path }) => { if (newData.properties.name && isNaN(newData.properties.ordinal)) { - // if name and NO ordinal -> unit + // Unit let editedIndex = units.features.findIndex(unit => unit.id === currentData.id); if (editedIndex !== -1) { + // Replace the old data with the new data for specific feature, then save to zip units.features[editedIndex] = newData; unitsChanged(units); } @@ -419,8 +421,16 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged } } else if (newData.properties.name) { - // if name and ordinal -> level - console.log('Level'); + // Level + let editedIndex = levels.features.findIndex(level => level.id === currentData.id); + if (editedIndex !== -1) { + // Replace the old data with the new data for specific feature, then save to zip + levels.features[editedIndex] = newData; + levelsChanged(levels); + } + else { + console.log('Invalid property change.'); + } } return true; @@ -444,7 +454,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged
Zoom in to see labels and icons. - {drawNotif && To connect the final lines of current drawing, press 'c'.} + {drawNotif && Click to draw a point. To connect the final lines of current drawing, press 'c'.}
From 4962b63096ed7de6f171fcb05417369d6852365b Mon Sep 17 00:00:00 2001 From: Nicole Iftekhar Date: Tue, 13 Aug 2024 20:19:12 -0700 Subject: [PATCH 10/23] If a feature is clicked, color stays changed to indicate its chosen --- .../conversion/places-preview-map/index.js | 109 ++++++++++++------ .../conversion/places-preview-map/utils.js | 4 - 2 files changed, 74 insertions(+), 39 deletions(-) diff --git a/src/pages/conversion/places-preview-map/index.js b/src/pages/conversion/places-preview-map/index.js index 77264f2..19d2cd6 100644 --- a/src/pages/conversion/places-preview-map/index.js +++ b/src/pages/conversion/places-preview-map/index.js @@ -142,21 +142,32 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged }); // Shows change in corresponding feature color when mouse hovers over that feature - function featureHover(layerName, polygonHoverLayer) { - // let selectedFeatureId = null; + function featureHover(layerName, hoverLayer, clickLayer) { + let selectedFeatureId = null; map.events.add('mousemove', layerName, function (e) { - polygonHoverLayer.setOptions({ filter: ['==', ['get', '_azureMapsShapeId'], e.shapes[0].getProperties()['_azureMapsShapeId']] }); + hoverLayer.setOptions({ filter: ['==', ['get', '_azureMapsShapeId'], e.shapes[0].getProperties()['_azureMapsShapeId']] }); }); map.events.add('mouseleave', layerName, function (e) { - polygonHoverLayer.setOptions({ filter: ['==', ['get', '_azureMapsShapeId'], ''] }); + hoverLayer.setOptions({ filter: ['==', ['get', '_azureMapsShapeId'], ''] }); + }); + + map.events.add('click', layerName, function (e) { + const featureId = e.shapes[0].getProperties()['_azureMapsShapeId']; + + if (selectedFeatureId !== featureId) { + selectedFeatureId = featureId; + clickLayer.setOptions({ + filter: ['==', ['get', '_azureMapsShapeId'], featureId] + }); + } }); } // Entry point when "unit.geojson" is pressed; the following code should be refactored due to redundancy function unitInteractions(units, drawingManager, map) { - var unitLayer, unitLines, polygonHoverLayer, unitSymbols; - var layersAdded = [unitLayer, unitLines, polygonHoverLayer, unitSymbols]; + var unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols; + var layersAdded = [unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols]; const groupedFeatures = groupAndSort(units, language, selectedLevel); const keys = Object.keys(groupedFeatures); @@ -169,14 +180,20 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged unitLayer = new layer.PolygonLayer(dataSource, 'unitClick', getFillStyles('unit', category)); unitLines = new layer.LineLayer(dataSource, null, getLineStyles('unit', category)); polygonHoverLayer = new layer.PolygonLayer(dataSource, null, { - fillColor: 'rgba(150, 50, 255, 0.2)', + fillColor: 'rgba(135, 206, 250, 0.8)', + filter: ['==', ['get', 'id'], ''] + }); + + polygonClickLayer = new layer.PolygonLayer(dataSource, null, { + fillColor: 'rgba(75, 146, 210, 0.8)', filter: ['==', ['get', 'id'], ''] }); + unitSymbols = new layer.SymbolLayer(dataSource, null, getTextStyle(category)); - map.layers.add([unitLayer, polygonHoverLayer, unitLines, unitSymbols], 'roomPolygons'); + map.layers.add([unitLayer, polygonHoverLayer, unitLines, polygonClickLayer, unitSymbols], 'roomPolygons'); grabToPointer([unitLayer, polygonHoverLayer], map); - featureHover(unitLayer, polygonHoverLayer); + featureHover(unitLayer, polygonHoverLayer, polygonClickLayer); var drawingSource = drawingManager.getSource(); drawingSource.add(features); @@ -188,7 +205,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged map.events.add('drawingmodechanged', drawingManager, (e) => { let dmLayers = drawingManager.getLayers(); - layersAdded = [unitLayer, unitLines, polygonHoverLayer, unitSymbols]; + layersAdded = [unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols]; if (e === 'idle') { setDrawNotif(false); @@ -215,12 +232,16 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged fillColor: 'rgba(150, 50, 255, 0.2)', filter: ['==', ['get', 'id'], ''] }); + polygonClickLayer = new layer.PolygonLayer(dataSource, null, { + fillColor: 'rgba(150, 90, 255, 0.2)', + filter: ['==', ['get', 'id'], ''] + }); unitSymbols = new layer.SymbolLayer(drawingManager.getSource(), null, getTextStyle(category)); - map.layers.add([unitLayer, polygonHoverLayer, unitLines, unitSymbols], 'roomPolygons'); + map.layers.add([unitLayer, polygonHoverLayer, polygonClickLayer, unitLines, unitSymbols], 'roomPolygons'); grabToPointer([unitLayer, polygonHoverLayer], map); - featureHover(unitLayer, polygonHoverLayer); - layersAdded = [unitLayer, unitLines, polygonHoverLayer, unitSymbols]; + featureHover(unitLayer, polygonHoverLayer, polygonClickLayer); + layersAdded = [unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols]; } else if (e === 'edit-geometry' || e === 'erase-geometry' || e === 'draw-polygon') { drawingModeChanged(layersAdded); @@ -248,8 +269,8 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged function levelInteractions(levels, drawingManager, map) { // Retrieve information about the level currently chosen by user const selectedLevelDetails = levels.features.filter(item => item.id === selectedLevel.id); - var lineLayer, lineHoverLayer; - var layersAdded = [lineLayer, lineHoverLayer]; + var lineLayer, lineHoverLayer, lineClickLayer; + var layersAdded = [lineLayer, lineHoverLayer, lineClickLayer]; const dataSource = new source.DataSource(); map.sources.add(dataSource); @@ -258,14 +279,19 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged // Displays outline of level + change in color when cursor is hovering lineLayer = new layer.LineLayer(dataSource, 'levelClick', getLineStyles('level', 'walkway')); lineHoverLayer = new layer.LineLayer(dataSource, null, { - fillColor: 'rgba(150, 50, 255, 0.2)', + fillColor: 'rgba(135, 206, 250, 0.8)', filter: ['==', ['get', '_azureMapsShapeId'], ''] }); - map.layers.add([lineLayer, lineHoverLayer], 'walkwayPolygons'); - grabToPointer([lineLayer, lineHoverLayer], map); - layersAdded = [lineLayer, lineHoverLayer]; - featureHover(lineLayer, lineHoverLayer); + lineClickLayer = new layer.LineLayer(dataSource, null, { + fillColor: 'rgba(75, 146, 210, 0.8)', + filter: ['==', ['get', 'id'], ''] + }); + + map.layers.add([lineLayer, lineHoverLayer, lineClickLayer], 'walkwayPolygons'); + grabToPointer([lineLayer, lineHoverLayer, lineClickLayer], map); + layersAdded = [lineLayer, lineHoverLayer, lineClickLayer]; + featureHover(lineLayer, lineHoverLayer, lineClickLayer); var drawingSource = drawingManager.getSource(); drawingSource.add(selectedLevelDetails); @@ -282,14 +308,18 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged var lineLayer = new layer.LineLayer(drawingManager.getSource(), 'levelClick', getLineStyles('level', 'walkway')); lineHoverLayer = new layer.LineLayer(drawingManager.getSource(), null, { - fillColor: 'rgba(150, 50, 255, 0.2)', + fillColor: 'rgba(135, 206, 250, 1)', filter: ['==', ['get', '_azureMapsShapeId'], ''] }); + lineClickLayer = new layer.LineLayer(dataSource, null, { + fillColor: 'rgba(75, 146, 210, 0.7)', + filter: ['==', ['get', 'id'], ''] + }); - map.layers.add([lineLayer, lineHoverLayer], 'walkwayPolygons'); - grabToPointer([lineLayer, lineHoverLayer], map); - layersAdded = [lineLayer, lineHoverLayer]; - featureHover(lineLayer, lineHoverLayer); + map.layers.add([lineLayer, lineHoverLayer, lineClickLayer], 'walkwayPolygons'); + grabToPointer([lineLayer, lineHoverLayer, lineClickLayer], map); + layersAdded = [lineLayer, lineHoverLayer, lineClickLayer]; + featureHover(lineLayer, lineHoverLayer, lineClickLayer); let updatedFeatures = drawingManager.getSource().shapes; setLevels(prevLevels => updateLevels(prevLevels, selectedLevel, (updatedFeatures[0]).data)); @@ -313,8 +343,8 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged // Entry point when "footprint.geojson" is pressed; the following code should be refactored due to redundancy function footprintInteractions(footprint, drawingManager, map) { - var footprintLayer, footprintLines, footprintHoverLayer; - var layersAdded = [footprintLayer, footprintLines, footprintHoverLayer]; + var footprintLayer, footprintLines, footprintHoverLayer, footprintClickLayer; + var layersAdded = [footprintLayer, footprintLines, footprintHoverLayer, footprintClickLayer]; const groupedFeatures = {}; const keys = Object.keys(groupedFeatures); @@ -327,14 +357,19 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged footprintLines = new layer.LineLayer(dataSource, null, getLineStyles('footprint', 'walkway')); footprintLayer = new layer.PolygonLayer(dataSource, 'footprintClick', getFillStyles('footprint', keys.category)); footprintHoverLayer = new layer.PolygonLayer(dataSource, null, { - fillColor: 'rgba(150, 50, 255, 0.2)', + fillColor: 'rgba(135, 206, 250, 0.8)', filter: ['==', ['get', '_azureMapsShapeId'], ''] }); - map.layers.add([footprintLayer, footprintHoverLayer, footprintLines], 'roomPolygons'); + footprintClickLayer = new layer.PolygonLayer(dataSource, null, { + fillColor: 'rgba(75, 146, 210, 0.8)', + filter: ['==', ['get', 'id'], ''] + }); + + map.layers.add([footprintLayer, footprintHoverLayer, footprintLines, footprintClickLayer], 'roomPolygons'); grabToPointer([footprintLayer, footprintHoverLayer], map); - featureHover(footprintLayer, footprintHoverLayer); - layersAdded = [footprintLayer, footprintLines, footprintHoverLayer]; + featureHover(footprintLayer, footprintHoverLayer, footprintClickLayer); + layersAdded = [footprintLayer, footprintLines, footprintHoverLayer, footprintClickLayer]; var drawingSource = drawingManager.getSource(); @@ -353,14 +388,18 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged footprintLines = new layer.LineLayer(drawingManager.getSource(), null, getLineStyles('footprint', 'walkway')); footprintLayer = new layer.PolygonLayer(drawingManager.getSource(), 'footprintClick', getFillStyles('footprint', keys.category)); footprintHoverLayer = new layer.PolygonLayer(drawingManager.getSource(), null, { - fillColor: 'rgba(150, 50, 255, 0.2)', + fillColor: 'rgba(135, 206, 250, 0.8)', filter: ['==', ['get', '_azureMapsShapeId'], ''] }); + footprintClickLayer = new layer.PolygonLayer(dataSource, null, { + fillColor: 'rgba(75, 146, 210, 0.8)', + filter: ['==', ['get', 'id'], ''] + }); - map.layers.add([footprintLayer, footprintHoverLayer, footprintLines], 'roomPolygons'); + map.layers.add([footprintLayer, footprintHoverLayer, footprintLines, footprintClickLayer], 'roomPolygons'); grabToPointer([footprintLayer, footprintHoverLayer], map); - featureHover(footprintLayer, footprintHoverLayer); - layersAdded = [footprintLayer, footprintLines, footprintHoverLayer]; + featureHover(footprintLayer, footprintHoverLayer, footprintClickLayer); + layersAdded = [footprintLayer, footprintLines, footprintHoverLayer, footprintClickLayer]; let updatedFeatures = drawingManager.getSource().shapes; footprint.features[0] = updatedFeatures[0].data; diff --git a/src/pages/conversion/places-preview-map/utils.js b/src/pages/conversion/places-preview-map/utils.js index 037fa07..d79eb39 100644 --- a/src/pages/conversion/places-preview-map/utils.js +++ b/src/pages/conversion/places-preview-map/utils.js @@ -7,10 +7,6 @@ import stairs from './assets/stairs.svg'; import { categoryToFillColor, defaultFillColor, levelStyles, levelOnlyStyles, textStyles, footprintStyles, unitStyles } from './theme/floorPlanStyles'; export function getFillStyles(featureType, category) { - if (featureType !== 'unit') { - return {}; - } - var fillStyle = { fillColor: categoryToFillColor.has(category) ? categoryToFillColor.get(category) : defaultFillColor, fillOpacity: 1, From d2ddf7190658428eb29d53c2c2cb4cf30df7f36c Mon Sep 17 00:00:00 2001 From: Nicole Iftekhar Date: Tue, 13 Aug 2024 21:20:45 -0700 Subject: [PATCH 11/23] Provided an option to deselect --- src/pages/conversion/places-preview-map/index.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/pages/conversion/places-preview-map/index.js b/src/pages/conversion/places-preview-map/index.js index 19d2cd6..4afff3f 100644 --- a/src/pages/conversion/places-preview-map/index.js +++ b/src/pages/conversion/places-preview-map/index.js @@ -161,6 +161,13 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged filter: ['==', ['get', '_azureMapsShapeId'], featureId] }); } + else { + selectedFeatureId = null; + clickLayer.setOptions({ + filter: ['==', ['get', '_azureMapsShapeId'], ''] + }); + setJsonData({}); + } }); } From 563814cb6895ddfddadd297026a9dfa043c241e5 Mon Sep 17 00:00:00 2001 From: Nicole Iftekhar Date: Tue, 13 Aug 2024 21:46:17 -0700 Subject: [PATCH 12/23] Fixed bug regarding clicking newly edited features --- .../conversion/places-preview-map/index.js | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/pages/conversion/places-preview-map/index.js b/src/pages/conversion/places-preview-map/index.js index 4afff3f..e48e8c7 100644 --- a/src/pages/conversion/places-preview-map/index.js +++ b/src/pages/conversion/places-preview-map/index.js @@ -141,8 +141,8 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged }); }); - // Shows change in corresponding feature color when mouse hovers over that feature - function featureHover(layerName, hoverLayer, clickLayer) { + // Shows change in corresponding feature color when mouse hovers over OR clicks on that feature + function featureHoverClick(layerName, hoverLayer, clickLayer) { let selectedFeatureId = null; map.events.add('mousemove', layerName, function (e) { hoverLayer.setOptions({ filter: ['==', ['get', '_azureMapsShapeId'], e.shapes[0].getProperties()['_azureMapsShapeId']] }); @@ -156,12 +156,14 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged const featureId = e.shapes[0].getProperties()['_azureMapsShapeId']; if (selectedFeatureId !== featureId) { + // If feature is clicked, change color of feature selectedFeatureId = featureId; clickLayer.setOptions({ filter: ['==', ['get', '_azureMapsShapeId'], featureId] }); } else { + // If feature clicked is currently chosen, change color of feature back to original selectedFeatureId = null; clickLayer.setOptions({ filter: ['==', ['get', '_azureMapsShapeId'], ''] @@ -173,6 +175,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged // Entry point when "unit.geojson" is pressed; the following code should be refactored due to redundancy function unitInteractions(units, drawingManager, map) { + unitsChanged(units); var unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols; var layersAdded = [unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols]; const groupedFeatures = groupAndSort(units, language, selectedLevel); @@ -200,7 +203,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged unitSymbols = new layer.SymbolLayer(dataSource, null, getTextStyle(category)); map.layers.add([unitLayer, polygonHoverLayer, unitLines, polygonClickLayer, unitSymbols], 'roomPolygons'); grabToPointer([unitLayer, polygonHoverLayer], map); - featureHover(unitLayer, polygonHoverLayer, polygonClickLayer); + featureHoverClick(unitLayer, polygonHoverLayer, polygonClickLayer); var drawingSource = drawingManager.getSource(); drawingSource.add(features); @@ -208,7 +211,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged let dmLayers = drawingManager.getLayers(); dmLayers.polygonLayer.setOptions({ visible: false }); dmLayers.polygonOutlineLayer.setOptions({ visible: false }); - layersAdded = [unitLayer, unitLines, polygonHoverLayer, unitSymbols]; + layersAdded = [unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols]; map.events.add('drawingmodechanged', drawingManager, (e) => { let dmLayers = drawingManager.getLayers(); @@ -236,18 +239,18 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged unitLayer = new layer.PolygonLayer(drawingManager.getSource(), 'unitClick', getFillStyles('unit', category)); unitLines = new layer.LineLayer(drawingManager.getSource(), null, getLineStyles('unit', category)); polygonHoverLayer = new layer.PolygonLayer(drawingManager.getSource(), null, { - fillColor: 'rgba(150, 50, 255, 0.2)', + fillColor: 'rgba(135, 206, 250, 0.8)', filter: ['==', ['get', 'id'], ''] }); - polygonClickLayer = new layer.PolygonLayer(dataSource, null, { - fillColor: 'rgba(150, 90, 255, 0.2)', + polygonClickLayer = new layer.PolygonLayer(drawingManager.getSource(), null, { + fillColor: 'rgba(75, 146, 210, 0.8)', filter: ['==', ['get', 'id'], ''] }); unitSymbols = new layer.SymbolLayer(drawingManager.getSource(), null, getTextStyle(category)); map.layers.add([unitLayer, polygonHoverLayer, polygonClickLayer, unitLines, unitSymbols], 'roomPolygons'); grabToPointer([unitLayer, polygonHoverLayer], map); - featureHover(unitLayer, polygonHoverLayer, polygonClickLayer); + featureHoverClick(unitLayer, polygonHoverLayer, polygonClickLayer); layersAdded = [unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols]; } else if (e === 'edit-geometry' || e === 'erase-geometry' || e === 'draw-polygon') { @@ -298,7 +301,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged map.layers.add([lineLayer, lineHoverLayer, lineClickLayer], 'walkwayPolygons'); grabToPointer([lineLayer, lineHoverLayer, lineClickLayer], map); layersAdded = [lineLayer, lineHoverLayer, lineClickLayer]; - featureHover(lineLayer, lineHoverLayer, lineClickLayer); + featureHoverClick(lineLayer, lineHoverLayer, lineClickLayer); var drawingSource = drawingManager.getSource(); drawingSource.add(selectedLevelDetails); @@ -318,7 +321,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged fillColor: 'rgba(135, 206, 250, 1)', filter: ['==', ['get', '_azureMapsShapeId'], ''] }); - lineClickLayer = new layer.LineLayer(dataSource, null, { + lineClickLayer = new layer.LineLayer(drawingManager.getSource(), null, { fillColor: 'rgba(75, 146, 210, 0.7)', filter: ['==', ['get', 'id'], ''] }); @@ -326,7 +329,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged map.layers.add([lineLayer, lineHoverLayer, lineClickLayer], 'walkwayPolygons'); grabToPointer([lineLayer, lineHoverLayer, lineClickLayer], map); layersAdded = [lineLayer, lineHoverLayer, lineClickLayer]; - featureHover(lineLayer, lineHoverLayer, lineClickLayer); + featureHoverClick(lineLayer, lineHoverLayer, lineClickLayer); let updatedFeatures = drawingManager.getSource().shapes; setLevels(prevLevels => updateLevels(prevLevels, selectedLevel, (updatedFeatures[0]).data)); @@ -375,7 +378,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged map.layers.add([footprintLayer, footprintHoverLayer, footprintLines, footprintClickLayer], 'roomPolygons'); grabToPointer([footprintLayer, footprintHoverLayer], map); - featureHover(footprintLayer, footprintHoverLayer, footprintClickLayer); + featureHoverClick(footprintLayer, footprintHoverLayer, footprintClickLayer); layersAdded = [footprintLayer, footprintLines, footprintHoverLayer, footprintClickLayer]; @@ -398,14 +401,14 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged fillColor: 'rgba(135, 206, 250, 0.8)', filter: ['==', ['get', '_azureMapsShapeId'], ''] }); - footprintClickLayer = new layer.PolygonLayer(dataSource, null, { + footprintClickLayer = new layer.PolygonLayer(drawingManager.getSource(), null, { fillColor: 'rgba(75, 146, 210, 0.8)', filter: ['==', ['get', 'id'], ''] }); map.layers.add([footprintLayer, footprintHoverLayer, footprintLines, footprintClickLayer], 'roomPolygons'); grabToPointer([footprintLayer, footprintHoverLayer], map); - featureHover(footprintLayer, footprintHoverLayer, footprintClickLayer); + featureHoverClick(footprintLayer, footprintHoverLayer, footprintClickLayer); layersAdded = [footprintLayer, footprintLines, footprintHoverLayer, footprintClickLayer]; let updatedFeatures = drawingManager.getSource().shapes; @@ -460,6 +463,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged if (editedIndex !== -1) { // Replace the old data with the new data for specific feature, then save to zip units.features[editedIndex] = newData; + units.features[editedIndex].properties.label = newData.properties.name.en; unitsChanged(units); } else { From e171e647a1597a67253f70b3f3a294549be7c8a1 Mon Sep 17 00:00:00 2001 From: Nicole Iftekhar Date: Wed, 14 Aug 2024 14:46:35 -0700 Subject: [PATCH 13/23] Ensured all features are deselected (color change) when a new feature is selected --- .../conversion/places-preview-map/index.js | 38 +++++++++++++------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/pages/conversion/places-preview-map/index.js b/src/pages/conversion/places-preview-map/index.js index e48e8c7..e69f7a6 100644 --- a/src/pages/conversion/places-preview-map/index.js +++ b/src/pages/conversion/places-preview-map/index.js @@ -1,7 +1,7 @@ import { Map, layer, source, control } from 'azure-maps-control'; import { control as draw_control, drawing } from 'azure-maps-drawing-tools'; import { getDomain, useConversionStore, useLevelsStore, useUserStore } from 'common/store'; -import { useEffect, useMemo, useState } from 'react'; +import { useEffect, useMemo, useState, useRef } from 'react'; import { imdfPreviewMap, imdfPreviewMapWrapper, layerSelect, textWrapper, mapTextWrapper } from './indes.style'; import LevelSelector from './level-selector'; import LayerSelector from './layer-selector'; @@ -25,6 +25,8 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged // const [building, setBuilding] = useState({ features: [] }); // building will be used eventually const [footprint, setFootprint] = useState({ features: [] }); + const newDataRef = useRef(false); + useEffect(() => { if (!imdfPackageLocation) return; @@ -142,8 +144,8 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged }); // Shows change in corresponding feature color when mouse hovers over OR clicks on that feature - function featureHoverClick(layerName, hoverLayer, clickLayer) { - let selectedFeatureId = null; + let selectedFeatureId = null; + function featureHoverClick(layerName, hoverLayer, clickLayer, unitSelected=false) { map.events.add('mousemove', layerName, function (e) { hoverLayer.setOptions({ filter: ['==', ['get', '_azureMapsShapeId'], e.shapes[0].getProperties()['_azureMapsShapeId']] }); }); @@ -161,9 +163,22 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged clickLayer.setOptions({ filter: ['==', ['get', '_azureMapsShapeId'], featureId] }); + + // Handles the change in color of the feature when clicked (for full view) + if(unitSelected) { + const lineLayer = map.layers.getLayerById('lineClickLayer'); + lineLayer.setOptions({strokeColor: 'hsla(0, 0%, 0%, 0)'}); + const unitLayer = map.layers.getLayerById('unitClickChange'); + unitLayer.setOptions({fillColor: 'rgba(75, 146, 210, 0.8)'}); + } else { + const polygonLayer = map.layers.getLayerById('lineClickLayer'); + polygonLayer.setOptions({strokeColor: 'rgba(75, 146, 210, 0.8)'}); + const unitLayer = map.layers.getLayerById('unitClickChange'); + unitLayer.setOptions({fillColor: 'hsla(0, 0%, 0%, 0)'}); + } } else { - // If feature clicked is currently chosen, change color of feature back to original + // If feature clicked is currently chosen OR it is another feature, change color of feature back to original selectedFeatureId = null; clickLayer.setOptions({ filter: ['==', ['get', '_azureMapsShapeId'], ''] @@ -175,7 +190,6 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged // Entry point when "unit.geojson" is pressed; the following code should be refactored due to redundancy function unitInteractions(units, drawingManager, map) { - unitsChanged(units); var unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols; var layersAdded = [unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols]; const groupedFeatures = groupAndSort(units, language, selectedLevel); @@ -194,16 +208,15 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged filter: ['==', ['get', 'id'], ''] }); - polygonClickLayer = new layer.PolygonLayer(dataSource, null, { + polygonClickLayer = new layer.PolygonLayer(dataSource, 'unitClickChange', { fillColor: 'rgba(75, 146, 210, 0.8)', filter: ['==', ['get', 'id'], ''] }); - unitSymbols = new layer.SymbolLayer(dataSource, null, getTextStyle(category)); map.layers.add([unitLayer, polygonHoverLayer, unitLines, polygonClickLayer, unitSymbols], 'roomPolygons'); grabToPointer([unitLayer, polygonHoverLayer], map); - featureHoverClick(unitLayer, polygonHoverLayer, polygonClickLayer); + featureHoverClick(unitLayer, polygonHoverLayer, polygonClickLayer, true); var drawingSource = drawingManager.getSource(); drawingSource.add(features); @@ -242,7 +255,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged fillColor: 'rgba(135, 206, 250, 0.8)', filter: ['==', ['get', 'id'], ''] }); - polygonClickLayer = new layer.PolygonLayer(drawingManager.getSource(), null, { + polygonClickLayer = new layer.PolygonLayer(drawingManager.getSource(), 'unitClickChange', { fillColor: 'rgba(75, 146, 210, 0.8)', filter: ['==', ['get', 'id'], ''] }); @@ -250,7 +263,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged map.layers.add([unitLayer, polygonHoverLayer, polygonClickLayer, unitLines, unitSymbols], 'roomPolygons'); grabToPointer([unitLayer, polygonHoverLayer], map); - featureHoverClick(unitLayer, polygonHoverLayer, polygonClickLayer); + featureHoverClick(unitLayer, polygonHoverLayer, polygonClickLayer, true); layersAdded = [unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols]; } else if (e === 'edit-geometry' || e === 'erase-geometry' || e === 'draw-polygon') { @@ -293,7 +306,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged filter: ['==', ['get', '_azureMapsShapeId'], ''] }); - lineClickLayer = new layer.LineLayer(dataSource, null, { + lineClickLayer = new layer.LineLayer(dataSource, 'lineClickLayer', { fillColor: 'rgba(75, 146, 210, 0.8)', filter: ['==', ['get', 'id'], ''] }); @@ -321,7 +334,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged fillColor: 'rgba(135, 206, 250, 1)', filter: ['==', ['get', '_azureMapsShapeId'], ''] }); - lineClickLayer = new layer.LineLayer(drawingManager.getSource(), null, { + lineClickLayer = new layer.LineLayer(drawingManager.getSource(), 'lineClickLayer', { fillColor: 'rgba(75, 146, 210, 0.7)', filter: ['==', ['get', 'id'], ''] }); @@ -465,6 +478,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged units.features[editedIndex] = newData; units.features[editedIndex].properties.label = newData.properties.name.en; unitsChanged(units); + newDataRef.current = true; } else { console.log('Invalid property change.'); From 7ab4f01e6e278d2cd1bdfb4aaa1c69dff7da0a75 Mon Sep 17 00:00:00 2001 From: Nicole Iftekhar Date: Wed, 14 Aug 2024 20:25:23 -0700 Subject: [PATCH 14/23] Fixed bug with not being able to see geojson info immediately after editing + popup before deletion --- .../places-preview-map/indes.style.js | 8 +++ .../conversion/places-preview-map/index.js | 50 ++++++++++++++----- .../layer-selector/index.js | 6 +-- .../conversion/places-preview-map/utils.js | 1 + 4 files changed, 50 insertions(+), 15 deletions(-) diff --git a/src/pages/conversion/places-preview-map/indes.style.js b/src/pages/conversion/places-preview-map/indes.style.js index 0a3ddcd..3e541a0 100644 --- a/src/pages/conversion/places-preview-map/indes.style.js +++ b/src/pages/conversion/places-preview-map/indes.style.js @@ -27,3 +27,11 @@ export const textWrapper = css ` display: inline; `; +export const toolbar = css ` + backgroundColor: #f0f0f0, + border: 2px solid #0078d4, + color: #0078d4, + cursor: not-allowed, + pointerEvents: none +`; + diff --git a/src/pages/conversion/places-preview-map/index.js b/src/pages/conversion/places-preview-map/index.js index e69f7a6..dd685fd 100644 --- a/src/pages/conversion/places-preview-map/index.js +++ b/src/pages/conversion/places-preview-map/index.js @@ -123,6 +123,9 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged fullViewInteractions(units, levels, drawingManager, map); } + + var layers = drawingManager.getLayers(); + map.events.add('mousedown', layers.polygonLayer, handleDeletion); }); // Recognizes which layer button is clicked and sets features data to display accordingly @@ -144,7 +147,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged }); // Shows change in corresponding feature color when mouse hovers over OR clicks on that feature - let selectedFeatureId = null; + let selectedFeatureID = null; function featureHoverClick(layerName, hoverLayer, clickLayer, unitSelected=false) { map.events.add('mousemove', layerName, function (e) { hoverLayer.setOptions({ filter: ['==', ['get', '_azureMapsShapeId'], e.shapes[0].getProperties()['_azureMapsShapeId']] }); @@ -155,13 +158,13 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged }); map.events.add('click', layerName, function (e) { - const featureId = e.shapes[0].getProperties()['_azureMapsShapeId']; + const clickedFeatureID = e.shapes[0].getProperties()['_azureMapsShapeId']; - if (selectedFeatureId !== featureId) { + if (selectedFeatureID !== clickedFeatureID) { // If feature is clicked, change color of feature - selectedFeatureId = featureId; + selectedFeatureID = clickedFeatureID; clickLayer.setOptions({ - filter: ['==', ['get', '_azureMapsShapeId'], featureId] + filter: ['==', ['get', '_azureMapsShapeId'], clickedFeatureID] }); // Handles the change in color of the feature when clicked (for full view) @@ -172,14 +175,29 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged unitLayer.setOptions({fillColor: 'rgba(75, 146, 210, 0.8)'}); } else { const polygonLayer = map.layers.getLayerById('lineClickLayer'); - polygonLayer.setOptions({strokeColor: 'rgba(75, 146, 210, 0.8)'}); + polygonLayer.setOptions({strokeColor: 'rgba(75, 146, 210, 0.8)'}) const unitLayer = map.layers.getLayerById('unitClickChange'); unitLayer.setOptions({fillColor: 'hsla(0, 0%, 0%, 0)'}); } + + var features; + if(selectedLayerId === 'unitButton') + features = map.layers.getRenderedShapes(e.position, 'unitClick'); + else if(selectedLayerId === 'levelButton') + features = map.layers.getRenderedShapes(e.position, 'levelClick'); + else if(selectedLayerId === 'footprintButton') + features = map.layers.getRenderedShapes(e.position, 'footprintClick'); + else + features = map.layers.getRenderedShapes(e.position, ['unitClick', 'levelClick']); + + features.forEach(function (feature) { + const newData = feature.data || {}; + setJsonData(newData); + }); } else { // If feature clicked is currently chosen OR it is another feature, change color of feature back to original - selectedFeatureId = null; + selectedFeatureID = null; clickLayer.setOptions({ filter: ['==', ['get', '_azureMapsShapeId'], ''] }); @@ -188,6 +206,14 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged }); } + function handleDeletion(e) { + if (drawingManager.getOptions().mode === 'erase-geometry') { + if (window.confirm('Do you want to proceed with removing this feature?')) { + drawingManager.getSource().remove(e.shapes[0]); + } + } + } + // Entry point when "unit.geojson" is pressed; the following code should be refactored due to redundancy function unitInteractions(units, drawingManager, map) { var unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols; @@ -264,7 +290,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged map.layers.add([unitLayer, polygonHoverLayer, polygonClickLayer, unitLines, unitSymbols], 'roomPolygons'); grabToPointer([unitLayer, polygonHoverLayer], map); featureHoverClick(unitLayer, polygonHoverLayer, polygonClickLayer, true); - layersAdded = [unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols]; + layersAdded = [unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols]; } else if (e === 'edit-geometry' || e === 'erase-geometry' || e === 'draw-polygon') { drawingModeChanged(layersAdded); @@ -302,12 +328,12 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged // Displays outline of level + change in color when cursor is hovering lineLayer = new layer.LineLayer(dataSource, 'levelClick', getLineStyles('level', 'walkway')); lineHoverLayer = new layer.LineLayer(dataSource, null, { - fillColor: 'rgba(135, 206, 250, 0.8)', + strokeColor: 'rgba(135, 206, 250, 0.8)', filter: ['==', ['get', '_azureMapsShapeId'], ''] }); lineClickLayer = new layer.LineLayer(dataSource, 'lineClickLayer', { - fillColor: 'rgba(75, 146, 210, 0.8)', + strokeColor: 'rgba(75, 146, 210, 0.8)', filter: ['==', ['get', 'id'], ''] }); @@ -331,11 +357,11 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged var lineLayer = new layer.LineLayer(drawingManager.getSource(), 'levelClick', getLineStyles('level', 'walkway')); lineHoverLayer = new layer.LineLayer(drawingManager.getSource(), null, { - fillColor: 'rgba(135, 206, 250, 1)', + strokeColor: 'rgba(135, 206, 250, 1)', filter: ['==', ['get', '_azureMapsShapeId'], ''] }); lineClickLayer = new layer.LineLayer(drawingManager.getSource(), 'lineClickLayer', { - fillColor: 'rgba(75, 146, 210, 0.7)', + strokeColor: 'rgba(75, 146, 210, 0.7)', filter: ['==', ['get', 'id'], ''] }); diff --git a/src/pages/conversion/places-preview-map/layer-selector/index.js b/src/pages/conversion/places-preview-map/layer-selector/index.js index 62b1592..aea7e50 100644 --- a/src/pages/conversion/places-preview-map/layer-selector/index.js +++ b/src/pages/conversion/places-preview-map/layer-selector/index.js @@ -4,10 +4,10 @@ import { buttonStyle, layerSelectorWrapper, selectedButtonStyle } from './index. const layerButtons = [ // will need to add a "buildingButton" once basemap is loaded - {id: 'fullViewButton', text: 'full view'}, - {id: 'footprintButton', text: 'footprint.geojson'}, - {id: 'levelButton', text: 'level.geojson'}, {id: 'unitButton', text: 'unit.geojson'}, + {id: 'levelButton', text: 'level.geojson'}, + {id: 'footprintButton', text: 'footprint.geojson'}, + {id: 'fullViewButton', text: 'full view'}, ]; const LayerSelector = props => { diff --git a/src/pages/conversion/places-preview-map/utils.js b/src/pages/conversion/places-preview-map/utils.js index d79eb39..7668c51 100644 --- a/src/pages/conversion/places-preview-map/utils.js +++ b/src/pages/conversion/places-preview-map/utils.js @@ -37,6 +37,7 @@ export function getLineStyles(featureType, category) { strokeWidth: levelStyles.lineWidth, lineJoin: 'round', lineCap: 'round', + fillColor: 'hsla(0, 0%, 0%, 0)', }; } From ae474105c36ca67bb6f3d16091df97a0e9dd4ff7 Mon Sep 17 00:00:00 2001 From: Nicole Iftekhar Date: Wed, 14 Aug 2024 20:27:55 -0700 Subject: [PATCH 15/23] Caught errors for code not applicable to full view --- .../conversion/places-preview-map/index.js | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/pages/conversion/places-preview-map/index.js b/src/pages/conversion/places-preview-map/index.js index dd685fd..36efc2d 100644 --- a/src/pages/conversion/places-preview-map/index.js +++ b/src/pages/conversion/places-preview-map/index.js @@ -170,14 +170,30 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged // Handles the change in color of the feature when clicked (for full view) if(unitSelected) { const lineLayer = map.layers.getLayerById('lineClickLayer'); - lineLayer.setOptions({strokeColor: 'hsla(0, 0%, 0%, 0)'}); + try { + lineLayer.setOptions({strokeColor: 'hsla(0, 0%, 0%, 0)'}); + } catch { + console.log('No line layer to change color of.') + } const unitLayer = map.layers.getLayerById('unitClickChange'); - unitLayer.setOptions({fillColor: 'rgba(75, 146, 210, 0.8)'}); + try { + unitLayer.setOptions({fillColor: 'rgba(75, 146, 210, 0.8)'}); + } catch { + console.log('No unit layer to change color of.') + } } else { const polygonLayer = map.layers.getLayerById('lineClickLayer'); - polygonLayer.setOptions({strokeColor: 'rgba(75, 146, 210, 0.8)'}) + try { + polygonLayer.setOptions({strokeColor: 'rgba(75, 146, 210, 0.8)'}); + } catch { + console.log('No unit layer to change color of.') + } const unitLayer = map.layers.getLayerById('unitClickChange'); - unitLayer.setOptions({fillColor: 'hsla(0, 0%, 0%, 0)'}); + try { + unitLayer.setOptions({fillColor: 'hsla(0, 0%, 0%, 0)'}); + } catch { + console.log('No unit layer to change color of.') + } } var features; From 202aa28665597d62428ffdee466ba9e4d3d35ff8 Mon Sep 17 00:00:00 2001 From: Nicole Iftekhar Date: Wed, 14 Aug 2024 20:45:38 -0700 Subject: [PATCH 16/23] Handling all deletion events --- src/pages/conversion/places-preview-map/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pages/conversion/places-preview-map/index.js b/src/pages/conversion/places-preview-map/index.js index 36efc2d..3b1b301 100644 --- a/src/pages/conversion/places-preview-map/index.js +++ b/src/pages/conversion/places-preview-map/index.js @@ -126,6 +126,8 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged var layers = drawingManager.getLayers(); map.events.add('mousedown', layers.polygonLayer, handleDeletion); + map.events.add('touchstart', layers.polygonLayer, handleDeletion); + map.events.add('click', layers.polygonLayer, handleDeletion); }); // Recognizes which layer button is clicked and sets features data to display accordingly From 3f1a52a8e5c02fe55f1411fd15b031b044f459d9 Mon Sep 17 00:00:00 2001 From: Nicole Iftekhar Date: Thu, 15 Aug 2024 09:19:49 -0700 Subject: [PATCH 17/23] Fixed issues of map not refreshing on change by triggering useEffect --- .../conversion/places-preview-map/index.js | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/pages/conversion/places-preview-map/index.js b/src/pages/conversion/places-preview-map/index.js index 3b1b301..3e4810e 100644 --- a/src/pages/conversion/places-preview-map/index.js +++ b/src/pages/conversion/places-preview-map/index.js @@ -269,22 +269,33 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged dmLayers.polygonLayer.setOptions({ visible: false }); dmLayers.polygonOutlineLayer.setOptions({ visible: false }); layersAdded = [unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols]; + + console.log('hi'); map.events.add('drawingmodechanged', drawingManager, (e) => { let dmLayers = drawingManager.getLayers(); layersAdded = [unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols]; if (e === 'idle') { + console.log('hey'); setDrawNotif(false); let updatedFeatures = drawingManager.getSource().shapes; deleteUnitPrevEdits(units, selectedLevel); - updatedFeatures.forEach((feature, index) => { - if(isNaN(feature.data.properties.ordinal)) { - setFields(feature, selectedLevel); - units.features.push(feature.data); + + const newFeatures = updatedFeatures.reduce((acc, feature) => { + if (isNaN(feature.data.properties.ordinal)) { + setFields(feature, selectedLevel); + acc.push(feature.data); } - }); + return acc; + }, []); + + setUnits(prevUnits => ({ + ...prevUnits, + features: [...prevUnits.features, ...newFeatures], + })); + // Update the units state with the edited features (for updating zip) unitsChanged(units); From c34de01f8451b5193e9b961acbb847332daa1041 Mon Sep 17 00:00:00 2001 From: Nicole Iftekhar Date: Thu, 15 Aug 2024 09:56:23 -0700 Subject: [PATCH 18/23] Fixed downloading IMDF bug --- src/pages/conversion/places-preview-map/indes.style.js | 3 ++- src/pages/conversion/places-preview-map/index.js | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/pages/conversion/places-preview-map/indes.style.js b/src/pages/conversion/places-preview-map/indes.style.js index 3e541a0..1d24040 100644 --- a/src/pages/conversion/places-preview-map/indes.style.js +++ b/src/pages/conversion/places-preview-map/indes.style.js @@ -18,9 +18,10 @@ export const imdfPreviewMap = css` export const layerSelect = css ` position: relative; - top: 60%; + bottom: -60%; `; + export const textWrapper = css ` flex: 1 1 5rem; position: relative; diff --git a/src/pages/conversion/places-preview-map/index.js b/src/pages/conversion/places-preview-map/index.js index 3e4810e..d713447 100644 --- a/src/pages/conversion/places-preview-map/index.js +++ b/src/pages/conversion/places-preview-map/index.js @@ -234,6 +234,9 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged // Entry point when "unit.geojson" is pressed; the following code should be refactored due to redundancy function unitInteractions(units, drawingManager, map) { + // Update the units state with the edited features (for updating zip) + unitsChanged(units); + var unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols; var layersAdded = [unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols]; const groupedFeatures = groupAndSort(units, language, selectedLevel); @@ -346,6 +349,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged // Entry point when "level.geojson" is pressed; the following code should be refactored due to redundancy function levelInteractions(levels, drawingManager, map) { // Retrieve information about the level currently chosen by user + levelsChanged(levels); const selectedLevelDetails = levels.features.filter(item => item.id === selectedLevel.id); var lineLayer, lineHoverLayer, lineClickLayer; var layersAdded = [lineLayer, lineHoverLayer, lineClickLayer]; @@ -421,6 +425,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged // Entry point when "footprint.geojson" is pressed; the following code should be refactored due to redundancy function footprintInteractions(footprint, drawingManager, map) { + footprintChanged(footprint); var footprintLayer, footprintLines, footprintHoverLayer, footprintClickLayer; var layersAdded = [footprintLayer, footprintLines, footprintHoverLayer, footprintClickLayer]; From 39c4d2355c2b81dc13aa613d413cd6cb7f0b1fcc Mon Sep 17 00:00:00 2001 From: Nicole Iftekhar Date: Thu, 15 Aug 2024 10:21:37 -0700 Subject: [PATCH 19/23] Fixed bugs with map labels not updating --- .../conversion/places-preview-map/index.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/pages/conversion/places-preview-map/index.js b/src/pages/conversion/places-preview-map/index.js index d713447..ca2b725 100644 --- a/src/pages/conversion/places-preview-map/index.js +++ b/src/pages/conversion/places-preview-map/index.js @@ -272,15 +272,12 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged dmLayers.polygonLayer.setOptions({ visible: false }); dmLayers.polygonOutlineLayer.setOptions({ visible: false }); layersAdded = [unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols]; - - console.log('hi'); map.events.add('drawingmodechanged', drawingManager, (e) => { let dmLayers = drawingManager.getLayers(); layersAdded = [unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols]; if (e === 'idle') { - console.log('hey'); setDrawNotif(false); let updatedFeatures = drawingManager.getSource().shapes; @@ -535,9 +532,17 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged let editedIndex = units.features.findIndex(unit => unit.id === currentData.id); if (editedIndex !== -1) { // Replace the old data with the new data for specific feature, then save to zip - units.features[editedIndex] = newData; - units.features[editedIndex].properties.label = newData.properties.name.en; - unitsChanged(units); + const updatedFeatures = [...units.features]; + updatedFeatures[editedIndex] = { + ...newData, + properties: { + ...newData.properties, + label: newData.properties.name.en, + }, + }; + + setUnits({ features: updatedFeatures }); // To update state to trigger map refresh + unitsChanged(units); // To update zip newDataRef.current = true; } else { From c311dc7a3b9e61e69010f64461faf497d4780c12 Mon Sep 17 00:00:00 2001 From: Nicole Iftekhar Date: Tue, 20 Aug 2024 15:34:42 -0700 Subject: [PATCH 20/23] Added in basemap, building.geojson view, and fixed cursor styling --- .../imdf-model-helpers/index.js | 11 +- .../places-preview-map/indes.style.js | 2 +- .../conversion/places-preview-map/index.js | 100 +++++++++++++----- .../layer-selector/index.js | 1 + .../layer-selector/index.style.js | 1 + .../conversion/places-preview-map/utils.js | 1 + 6 files changed, 85 insertions(+), 31 deletions(-) diff --git a/src/pages/conversion/places-preview-map/imdf-model-helpers/index.js b/src/pages/conversion/places-preview-map/imdf-model-helpers/index.js index a40892a..92f9f12 100644 --- a/src/pages/conversion/places-preview-map/imdf-model-helpers/index.js +++ b/src/pages/conversion/places-preview-map/imdf-model-helpers/index.js @@ -36,13 +36,14 @@ function groupAndSort(units, language, selectedLevel) { } // Changes the cursor to be a pointer when a clickable feature is hovered over -function grabToPointer(layerName, map) { - map.events.add('mouseover', layerName, function () { - map.getCanvasContainer().style.cursor = 'pointer'; +function grabToPointer(layer, map) { + console.log(layer); + map.events.add('mouseover', layer, () => { + map.getCanvas().style.cursor = 'pointer'; }); - map.events.add('mouseout', layerName, function () { - map.getCanvasContainer().style.cursor = 'grab'; + map.events.add('mouseout', layer, () => { + map.getCanvas().style.cursor = ''; }); } diff --git a/src/pages/conversion/places-preview-map/indes.style.js b/src/pages/conversion/places-preview-map/indes.style.js index 1d24040..6179d5d 100644 --- a/src/pages/conversion/places-preview-map/indes.style.js +++ b/src/pages/conversion/places-preview-map/indes.style.js @@ -18,7 +18,7 @@ export const imdfPreviewMap = css` export const layerSelect = css ` position: relative; - bottom: -60%; + bottom: -55%; `; diff --git a/src/pages/conversion/places-preview-map/index.js b/src/pages/conversion/places-preview-map/index.js index ca2b725..f93af63 100644 --- a/src/pages/conversion/places-preview-map/index.js +++ b/src/pages/conversion/places-preview-map/index.js @@ -1,4 +1,4 @@ -import { Map, layer, source, control } from 'azure-maps-control'; +import { Map, layer, source, control, HtmlMarker } from 'azure-maps-control'; import { control as draw_control, drawing } from 'azure-maps-drawing-tools'; import { getDomain, useConversionStore, useLevelsStore, useUserStore } from 'common/store'; import { useEffect, useMemo, useState, useRef } from 'react'; @@ -7,7 +7,7 @@ import LevelSelector from './level-selector'; import LayerSelector from './layer-selector'; import MapNotification from './map-notification'; import { calculateBoundingBox, getFeatureLabel, getFillStyles, getLineStyles, getTextStyle, processZip } from './utils'; -import { currentEditData, groupAndSort, drawingModeChanged, grabToPointer, updateLevels, setFields, deleteUnitPrevEdits } from './imdf-model-helpers'; +import { currentEditData, groupAndSort, drawingModeChanged, updateLevels, setFields, deleteUnitPrevEdits } from './imdf-model-helpers'; import { JsonEditor } from 'json-edit-react' import 'azure-maps-drawing-tools/dist/atlas-drawing.min.css'; import 'azure-maps-control/dist/atlas.min.css'; @@ -22,7 +22,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged const [jsonData, setJsonData] = useState({}); - // const [building, setBuilding] = useState({ features: [] }); // building will be used eventually + const [building, setBuilding] = useState({ features: [] }); // building will be used eventually const [footprint, setFootprint] = useState({ features: [] }); const newDataRef = useRef(false); @@ -39,7 +39,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged if (unitFile && levelFile && buildingFile && footprintFile) { setUnits(unitFile.content); setLevels(levelFile.content); - // setBuilding(buildingFile.content); + setBuilding(buildingFile.content); setFootprint(footprintFile.content); } }); @@ -65,7 +65,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged language: 'en-US', domain: getDomain(geography), staticAssetsDomain: getDomain(geography), - style: 'blank', + style: 'dark', }); map.controls.add([new control.ZoomControl()], { @@ -73,6 +73,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged }); map.events.add('ready', () => { + map.getCanvasContainer().style.setProperty('cursor', 'pointer', '!important'); var drawingToolbar; setJsonData({}); @@ -110,6 +111,8 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged }); footprintInteractions(footprint, drawingManager, map); + } else if(selectedLayerId === 'buildingButton') { + buildingInteractions(building, map); } else { drawingToolbar = new draw_control.DrawingToolbar({ position: 'bottom-right', @@ -124,10 +127,12 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged fullViewInteractions(units, levels, drawingManager, map); } - var layers = drawingManager.getLayers(); - map.events.add('mousedown', layers.polygonLayer, handleDeletion); - map.events.add('touchstart', layers.polygonLayer, handleDeletion); - map.events.add('click', layers.polygonLayer, handleDeletion); + if(selectedLayerId !== 'buildingButton') { + var layers = drawingManager.getLayers(); + map.events.add('mousedown', layers.polygonLayer, handleDeletion); + map.events.add('touchstart', layers.polygonLayer, handleDeletion); + map.events.add('click', layers.polygonLayer, handleDeletion); + } }); // Recognizes which layer button is clicked and sets features data to display accordingly @@ -139,13 +144,26 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged features = map.layers.getRenderedShapes(e.position, 'levelClick'); else if(selectedLayerId === 'footprintButton') features = map.layers.getRenderedShapes(e.position, 'footprintClick'); + else if(selectedLayerId === 'buildingButton') { + + } else features = map.layers.getRenderedShapes(e.position, ['unitClick', 'levelClick']); - features.forEach(function (feature) { - const newData = feature.data || {}; - setJsonData(newData); - }); + if(selectedLayerId !== 'buildingButton') { + features.forEach(function (feature) { + const newData = feature.data || {}; + setJsonData(newData); + }); + } + }); + + map.events.add('mousedown', function (e) { + map.getCanvas().style.cursor = 'grabbing'; + }); + + map.events.add('mouseup', function (e) { + map.getCanvas().style.cursor = 'grab'; }); // Shows change in corresponding feature color when mouse hovers over OR clicks on that feature @@ -153,14 +171,21 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged function featureHoverClick(layerName, hoverLayer, clickLayer, unitSelected=false) { map.events.add('mousemove', layerName, function (e) { hoverLayer.setOptions({ filter: ['==', ['get', '_azureMapsShapeId'], e.shapes[0].getProperties()['_azureMapsShapeId']] }); + map.getCanvas().style.cursor = 'pointer'; }); map.events.add('mouseleave', layerName, function (e) { hoverLayer.setOptions({ filter: ['==', ['get', '_azureMapsShapeId'], ''] }); + map.getCanvas().style.cursor = 'grab'; + }); + + map.events.add(['mousedown', 'mouseup'], layerName, function (e) { + map.getCanvas().style.cursor = 'pointer'; }); map.events.add('click', layerName, function (e) { const clickedFeatureID = e.shapes[0].getProperties()['_azureMapsShapeId']; + map.getCanvas().style.cursor = 'pointer'; if (selectedFeatureID !== clickedFeatureID) { // If feature is clicked, change color of feature @@ -231,7 +256,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged } } } - + // Entry point when "unit.geojson" is pressed; the following code should be refactored due to redundancy function unitInteractions(units, drawingManager, map) { // Update the units state with the edited features (for updating zip) @@ -252,17 +277,18 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged unitLines = new layer.LineLayer(dataSource, null, getLineStyles('unit', category)); polygonHoverLayer = new layer.PolygonLayer(dataSource, null, { fillColor: 'rgba(135, 206, 250, 0.8)', - filter: ['==', ['get', 'id'], ''] + filter: ['==', ['get', 'id'], ''], + cursor: 'pointer !important', }); polygonClickLayer = new layer.PolygonLayer(dataSource, 'unitClickChange', { fillColor: 'rgba(75, 146, 210, 0.8)', - filter: ['==', ['get', 'id'], ''] + filter: ['==', ['get', 'id'], ''] , + cursor: 'pointer !important', }); unitSymbols = new layer.SymbolLayer(dataSource, null, getTextStyle(category)); map.layers.add([unitLayer, polygonHoverLayer, unitLines, polygonClickLayer, unitSymbols], 'roomPolygons'); - grabToPointer([unitLayer, polygonHoverLayer], map); featureHoverClick(unitLayer, polygonHoverLayer, polygonClickLayer, true); var drawingSource = drawingManager.getSource(); @@ -291,6 +317,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged return acc; }, []); + // double check units state (restructuring accident) setUnits(prevUnits => ({ ...prevUnits, features: [...prevUnits.features, ...newFeatures], @@ -308,16 +335,17 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged unitLines = new layer.LineLayer(drawingManager.getSource(), null, getLineStyles('unit', category)); polygonHoverLayer = new layer.PolygonLayer(drawingManager.getSource(), null, { fillColor: 'rgba(135, 206, 250, 0.8)', - filter: ['==', ['get', 'id'], ''] + filter: ['==', ['get', 'id'], ''], + cursor: 'pointer', }); polygonClickLayer = new layer.PolygonLayer(drawingManager.getSource(), 'unitClickChange', { fillColor: 'rgba(75, 146, 210, 0.8)', - filter: ['==', ['get', 'id'], ''] + filter: ['==', ['get', 'id'], ''], + cursor: 'pointer', }); unitSymbols = new layer.SymbolLayer(drawingManager.getSource(), null, getTextStyle(category)); map.layers.add([unitLayer, polygonHoverLayer, polygonClickLayer, unitLines, unitSymbols], 'roomPolygons'); - grabToPointer([unitLayer, polygonHoverLayer], map); featureHoverClick(unitLayer, polygonHoverLayer, polygonClickLayer, true); layersAdded = [unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols]; } @@ -368,7 +396,6 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged }); map.layers.add([lineLayer, lineHoverLayer, lineClickLayer], 'walkwayPolygons'); - grabToPointer([lineLayer, lineHoverLayer, lineClickLayer], map); layersAdded = [lineLayer, lineHoverLayer, lineClickLayer]; featureHoverClick(lineLayer, lineHoverLayer, lineClickLayer); @@ -396,7 +423,6 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged }); map.layers.add([lineLayer, lineHoverLayer, lineClickLayer], 'walkwayPolygons'); - grabToPointer([lineLayer, lineHoverLayer, lineClickLayer], map); layersAdded = [lineLayer, lineHoverLayer, lineClickLayer]; featureHoverClick(lineLayer, lineHoverLayer, lineClickLayer); @@ -411,6 +437,12 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged dmLayers.polygonOutlineLayer.setOptions({ visible: true }); dmLayers.polygonLayer.setOptions({ visible: false }); + // handleKeyDown = (event) => { + // if (event.key === 'Delete') { + // event.preventDefault(); + // } + // }; + currentEditData(map, drawingManager, setJsonData); } else { @@ -447,7 +479,6 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged }); map.layers.add([footprintLayer, footprintHoverLayer, footprintLines, footprintClickLayer], 'roomPolygons'); - grabToPointer([footprintLayer, footprintHoverLayer], map); featureHoverClick(footprintLayer, footprintHoverLayer, footprintClickLayer); layersAdded = [footprintLayer, footprintLines, footprintHoverLayer, footprintClickLayer]; @@ -477,7 +508,6 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged }); map.layers.add([footprintLayer, footprintHoverLayer, footprintLines, footprintClickLayer], 'roomPolygons'); - grabToPointer([footprintLayer, footprintHoverLayer], map); featureHoverClick(footprintLayer, footprintHoverLayer, footprintClickLayer); layersAdded = [footprintLayer, footprintLines, footprintHoverLayer, footprintClickLayer]; @@ -501,6 +531,26 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged }); } + function buildingInteractions(building, map) { + var buildingLayer = new HtmlMarker({ position: building.features[0].properties.display_point.coordinates }); + map.markers.add(buildingLayer); + map.events.add('click', buildingLayer, highlight); + map.events.add('mouseover', buildingLayer, () => { + map.getCanvas().style.cursor = 'pointer'; + }); + // map.events.add('mouseout', buildingLayer, () => { + // map.getCanvas().style.cursor = 'grab'; + // }); + + function highlight(e) { + setJsonData(building.features[0]); + } + + map.setCamera({ + zoom: 12 + }); + } + // Entry point when "full view" is pressed; the following code may need to be changed to allow fill color of units while editing function fullViewInteractions(units, levels, drawingManager, map) { levelInteractions(levels, drawingManager, map); @@ -511,7 +561,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged return () => { map.dispose(); }; - }, [units, levels, footprint, selectedLevel, selectedLayerId, subscriptionKey, geography, language, imdfPackageLocation, unitsChanged, levelsChanged, footprintChanged ]); + }, [ units, levels, footprint, building, selectedLevel, selectedLayerId, subscriptionKey, geography, language, imdfPackageLocation, unitsChanged, levelsChanged, footprintChanged ]); const handleLevelChange = levelId => { setSelectedLevelId(levelId); diff --git a/src/pages/conversion/places-preview-map/layer-selector/index.js b/src/pages/conversion/places-preview-map/layer-selector/index.js index aea7e50..821da13 100644 --- a/src/pages/conversion/places-preview-map/layer-selector/index.js +++ b/src/pages/conversion/places-preview-map/layer-selector/index.js @@ -7,6 +7,7 @@ const layerButtons = [ {id: 'unitButton', text: 'unit.geojson'}, {id: 'levelButton', text: 'level.geojson'}, {id: 'footprintButton', text: 'footprint.geojson'}, + {id: 'buildingButton', text: 'building.geojson'}, {id: 'fullViewButton', text: 'full view'}, ]; diff --git a/src/pages/conversion/places-preview-map/layer-selector/index.style.js b/src/pages/conversion/places-preview-map/layer-selector/index.style.js index c66977a..29a46a3 100644 --- a/src/pages/conversion/places-preview-map/layer-selector/index.style.js +++ b/src/pages/conversion/places-preview-map/layer-selector/index.style.js @@ -32,6 +32,7 @@ export const buttonStyle = css` background-repeat: no-repeat; overflow: hidden; + &:hover { color: #31acce; } diff --git a/src/pages/conversion/places-preview-map/utils.js b/src/pages/conversion/places-preview-map/utils.js index 7668c51..fb06013 100644 --- a/src/pages/conversion/places-preview-map/utils.js +++ b/src/pages/conversion/places-preview-map/utils.js @@ -10,6 +10,7 @@ export function getFillStyles(featureType, category) { var fillStyle = { fillColor: categoryToFillColor.has(category) ? categoryToFillColor.get(category) : defaultFillColor, fillOpacity: 1, + cursor: 'pointer !important', }; return fillStyle; From 38b7599bc2e85ff82417e2bdeeb07a424174107c Mon Sep 17 00:00:00 2001 From: Nicole Iftekhar Date: Wed, 21 Aug 2024 12:12:35 -0700 Subject: [PATCH 21/23] Ensured FeatureCollection is in geojson --- src/pages/conversion/imdf-conversion.js | 4 + .../conversion/places-preview-map/index.js | 97 ++++++++++++------- 2 files changed, 66 insertions(+), 35 deletions(-) diff --git a/src/pages/conversion/imdf-conversion.js b/src/pages/conversion/imdf-conversion.js index f24e33f..554941b 100644 --- a/src/pages/conversion/imdf-conversion.js +++ b/src/pages/conversion/imdf-conversion.js @@ -23,6 +23,10 @@ const ImdfConversion = () => { const [footprint, setFootprint] = useState({ features: [] }); const handleUnitsChange = (editedUnits) => { + if(!editedUnits.type) { + editedUnits.type = 'FeatureCollection'; + } + console.log(editedUnits); setUnits(editedUnits); }; diff --git a/src/pages/conversion/places-preview-map/index.js b/src/pages/conversion/places-preview-map/index.js index f93af63..f6ebe74 100644 --- a/src/pages/conversion/places-preview-map/index.js +++ b/src/pages/conversion/places-preview-map/index.js @@ -19,12 +19,10 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged const [units, setUnits] = useState({ features: [] }); const [levels, setLevels] = useState({ features: [] }); - - const [jsonData, setJsonData] = useState({}); - - const [building, setBuilding] = useState({ features: [] }); // building will be used eventually + const [building, setBuilding] = useState({ features: [] }); const [footprint, setFootprint] = useState({ features: [] }); + const [jsonData, setJsonData] = useState({}); const newDataRef = useRef(false); useEffect(() => { @@ -114,17 +112,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged } else if(selectedLayerId === 'buildingButton') { buildingInteractions(building, map); } else { - drawingToolbar = new draw_control.DrawingToolbar({ - position: 'bottom-right', - style: 'light', - buttons: ['edit-geometry'] - }); - - drawingManager = new drawing.DrawingManager(map, { - toolbar: drawingToolbar - }); - - fullViewInteractions(units, levels, drawingManager, map); + fullViewInteractions(units, levels, map); } if(selectedLayerId !== 'buildingButton') { @@ -323,9 +311,8 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged features: [...prevUnits.features, ...newFeatures], })); - // Update the units state with the edited features (for updating zip) - unitsChanged(units); + // unitsChanged(units); dmLayers.polygonLayer.setOptions({ visible: false }); dmLayers.polygonOutlineLayer.setOptions({ visible: false }); @@ -366,7 +353,6 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged // This will eventually be a visible pop-up console.log('Not a valid drawing toolbar option.'); } - }); }); } @@ -437,12 +423,6 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged dmLayers.polygonOutlineLayer.setOptions({ visible: true }); dmLayers.polygonLayer.setOptions({ visible: false }); - // handleKeyDown = (event) => { - // if (event.key === 'Delete') { - // event.preventDefault(); - // } - // }; - currentEditData(map, drawingManager, setJsonData); } else { @@ -532,15 +512,13 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged } function buildingInteractions(building, map) { - var buildingLayer = new HtmlMarker({ position: building.features[0].properties.display_point.coordinates }); - map.markers.add(buildingLayer); - map.events.add('click', buildingLayer, highlight); - map.events.add('mouseover', buildingLayer, () => { - map.getCanvas().style.cursor = 'pointer'; + console.log(building); + var buildingLayer = new HtmlMarker({ + position: building.features[0].properties.display_point.coordinates, }); - // map.events.add('mouseout', buildingLayer, () => { - // map.getCanvas().style.cursor = 'grab'; - // }); + map.events.add('click', buildingLayer, highlight); + map.markers.add(buildingLayer); + function highlight(e) { setJsonData(building.features[0]); @@ -552,9 +530,58 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged } // Entry point when "full view" is pressed; the following code may need to be changed to allow fill color of units while editing - function fullViewInteractions(units, levels, drawingManager, map) { - levelInteractions(levels, drawingManager, map); - unitInteractions(units, drawingManager, map); + function fullViewInteractions(units, levels, map) { + unitsChanged(units); + levelsChanged(levels); + + var unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols, lineLayer, lineHoverLayer, lineClickLayer; + // var layersAdded = [unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols, lineLayer, lineHoverLayer, lineClickLayer]; + const groupedFeatures = groupAndSort(units, language, selectedLevel); + const keys = Object.keys(groupedFeatures); + + keys.forEach(category => { + var features = groupedFeatures[category].features; + const dataSource = new source.DataSource(); + map.sources.add(dataSource); + dataSource.add(features); + + unitLayer = new layer.PolygonLayer(dataSource, 'unitClick', getFillStyles('unit', category)); + unitLines = new layer.LineLayer(dataSource, null, getLineStyles('unit', category)); + polygonHoverLayer = new layer.PolygonLayer(dataSource, null, { + fillColor: 'rgba(135, 206, 250, 0.8)', + filter: ['==', ['get', 'id'], ''], + cursor: 'pointer !important', + }); + + polygonClickLayer = new layer.PolygonLayer(dataSource, 'unitClickChange', { + fillColor: 'rgba(75, 146, 210, 0.8)', + filter: ['==', ['get', 'id'], ''] , + cursor: 'pointer !important', + }); + + unitSymbols = new layer.SymbolLayer(dataSource, null, getTextStyle(category)); + map.layers.add([unitLayer, polygonHoverLayer, unitLines, polygonClickLayer, unitSymbols], 'roomPolygons'); + featureHoverClick(unitLayer, polygonHoverLayer, polygonClickLayer, true); + }); + + const selectedLevelDetails = levels.features.filter(item => item.id === selectedLevel.id); + const dataSource = new source.DataSource(); + map.sources.add(dataSource); + dataSource.add(selectedLevelDetails); + + // Displays outline of level + change in color when cursor is hovering + lineLayer = new layer.LineLayer(dataSource, 'levelClick', getLineStyles('level', 'walkway')); + lineHoverLayer = new layer.LineLayer(dataSource, null, { + strokeColor: 'rgba(135, 206, 250, 0.8)', + filter: ['==', ['get', '_azureMapsShapeId'], ''] + }); + lineClickLayer = new layer.LineLayer(dataSource, 'lineClickLayer', { + strokeColor: 'rgba(75, 146, 210, 0.8)', + filter: ['==', ['get', 'id'], ''] + }); + + map.layers.add([lineLayer, lineHoverLayer, lineClickLayer], 'walkwayPolygons'); + featureHoverClick(lineLayer, lineHoverLayer, lineClickLayer, false); } // Cleanup function to remove the map instance when component unmounts or reinitializes From 687d0c37a92d6ac5bd01b5b17459307c04596f27 Mon Sep 17 00:00:00 2001 From: Nicole Iftekhar Date: Fri, 23 Aug 2024 17:06:18 -0700 Subject: [PATCH 22/23] Added comments, cleaned up code, and added functionality for saving edits made to building name --- src/pages/conversion/download-imdf.js | 3 +- src/pages/conversion/imdf-conversion.js | 14 +- .../imdf-model-helpers/index.js | 60 ++++++++- .../conversion/places-preview-map/index.js | 127 +++++------------- 4 files changed, 100 insertions(+), 104 deletions(-) diff --git a/src/pages/conversion/download-imdf.js b/src/pages/conversion/download-imdf.js index e53f699..ba991ab 100644 --- a/src/pages/conversion/download-imdf.js +++ b/src/pages/conversion/download-imdf.js @@ -6,7 +6,7 @@ import JSZip from 'jszip'; import { saveAs } from 'file-saver'; // This component downloads the updated IMDF zip file and is triggered by users clicking "Download IMDF" button -export const DownloadIMDF = ({ imdfPackageLocation, units, levels, footprint }) => { +export const DownloadIMDF = ({ imdfPackageLocation, units, levels, footprint, building }) => { const [isLoading, setIsLoading] = useState(false); // Fetches current zip file, updates the geojson files and downloads the updated zip @@ -22,6 +22,7 @@ export const DownloadIMDF = ({ imdfPackageLocation, units, levels, footprint }) zip.file('unit.geojson', JSON.stringify(units, null, 2)); zip.file('level.geojson', JSON.stringify(levels, null, 2)); zip.file('footprint.geojson', JSON.stringify(footprint, null, 2)); + zip.file('building.geojson', JSON.stringify(building, null, 2)); return zip.generateAsync({ type: 'blob' }); }) .then(updatedZip => { diff --git a/src/pages/conversion/imdf-conversion.js b/src/pages/conversion/imdf-conversion.js index 554941b..6367e43 100644 --- a/src/pages/conversion/imdf-conversion.js +++ b/src/pages/conversion/imdf-conversion.js @@ -21,12 +21,12 @@ const ImdfConversion = () => { const [units, setUnits] = useState({ features: [] }); const [levels, setLevels] = useState({ features: [] }); const [footprint, setFootprint] = useState({ features: [] }); + const [building, setBuilding] = useState({ features: [] }); const handleUnitsChange = (editedUnits) => { if(!editedUnits.type) { editedUnits.type = 'FeatureCollection'; } - console.log(editedUnits); setUnits(editedUnits); }; @@ -38,6 +38,10 @@ const ImdfConversion = () => { setFootprint(editedFootprint); }; + const handleBuildingChange = (editedBuilding) => { + setBuilding(editedBuilding); + }; + const { t } = useTranslation(); const navigate = useCustomNavigate(); @@ -57,13 +61,13 @@ const ImdfConversion = () => { processZip(imdfPackageLocation).then(files => { const unitFile = files.find(file => file.filename === 'unit.geojson'); const levelFile = files.find(file => file.filename === 'level.geojson'); - // const buildingFile = files.find(file => file.filename === 'building.geojson'); + const buildingFile = files.find(file => file.filename === 'building.geojson'); const footprintFile = files.find(file => file.filename === 'footprint.geojson'); if (unitFile && levelFile && footprintFile) { setUnits(unitFile.content); setLevels(levelFile.content); - // setBuilding(buildingFile.content); + setBuilding(buildingFile.content); setFootprint(footprintFile.content); } }); @@ -116,7 +120,7 @@ const ImdfConversion = () => {
{imdfConversionStatus === conversionStatuses.finishedSuccessfully && ( - + )}
@@ -124,7 +128,7 @@ const ImdfConversion = () => {
{imdfConversionStatus === conversionStatuses.finishedSuccessfully && ( - {({ height }) => } + {({ height }) => } )}
diff --git a/src/pages/conversion/places-preview-map/imdf-model-helpers/index.js b/src/pages/conversion/places-preview-map/imdf-model-helpers/index.js index 92f9f12..ef5b068 100644 --- a/src/pages/conversion/places-preview-map/imdf-model-helpers/index.js +++ b/src/pages/conversion/places-preview-map/imdf-model-helpers/index.js @@ -36,15 +36,61 @@ function groupAndSort(units, language, selectedLevel) { } // Changes the cursor to be a pointer when a clickable feature is hovered over -function grabToPointer(layer, map) { - console.log(layer); - map.events.add('mouseover', layer, () => { +function grabToPointer(layerName, hoverLayer, map) { + map.events.add('mousemove', layerName, function (e) { + hoverLayer.setOptions({ filter: ['==', ['get', '_azureMapsShapeId'], e.shapes[0].getProperties()['_azureMapsShapeId']] }); map.getCanvas().style.cursor = 'pointer'; }); - map.events.add('mouseout', layer, () => { - map.getCanvas().style.cursor = ''; + map.events.add('mouseleave', layerName, function (e) { + hoverLayer.setOptions({ filter: ['==', ['get', '_azureMapsShapeId'], ''] }); + map.getCanvas().style.cursor = 'grab'; }); + + map.events.add(['mousedown', 'mouseup'], layerName, function (e) { + map.getCanvas().style.cursor = 'pointer'; + }); +} + +// Changes cursor between grabbing and grabbing when map is clicked and dragged +function grabAndGrabbing(map) { + map.events.add('mousedown', () => { + map.getCanvas().style.cursor = 'grabbing'; + }); + + map.events.add('mouseup', () => { + map.getCanvas().style.cursor = 'grab'; + }); +} + +function updateSelectedColor(map, unitSelected) { + if(unitSelected) { + const lineLayer = map.layers.getLayerById('lineClickLayer'); + try { + lineLayer.setOptions({strokeColor: 'hsla(0, 0%, 0%, 0)'}); + } catch { + console.log('No line layer to change color of.') + } + const unitLayer = map.layers.getLayerById('unitClickChange'); + try { + unitLayer.setOptions({fillColor: 'rgba(75, 146, 210, 0.8)'}); + } catch { + console.log('No unit layer to change color of.') + } + } else { + const polygonLayer = map.layers.getLayerById('lineClickLayer'); + try { + polygonLayer.setOptions({strokeColor: 'rgba(75, 146, 210, 0.8)'}); + } catch { + console.log('No unit layer to change color of.') + } + const unitLayer = map.layers.getLayerById('unitClickChange'); + try { + unitLayer.setOptions({fillColor: 'hsla(0, 0%, 0%, 0)'}); + } catch { + console.log('No unit layer to change color of.') + } + } } function updateLevels(levels, selectedLevel, newValue) { @@ -101,5 +147,7 @@ export { grabToPointer, updateLevels, setFields, - deleteUnitPrevEdits + deleteUnitPrevEdits, + grabAndGrabbing, + updateSelectedColor }; \ No newline at end of file diff --git a/src/pages/conversion/places-preview-map/index.js b/src/pages/conversion/places-preview-map/index.js index f6ebe74..d695d22 100644 --- a/src/pages/conversion/places-preview-map/index.js +++ b/src/pages/conversion/places-preview-map/index.js @@ -7,17 +7,17 @@ import LevelSelector from './level-selector'; import LayerSelector from './layer-selector'; import MapNotification from './map-notification'; import { calculateBoundingBox, getFeatureLabel, getFillStyles, getLineStyles, getTextStyle, processZip } from './utils'; -import { currentEditData, groupAndSort, drawingModeChanged, updateLevels, setFields, deleteUnitPrevEdits } from './imdf-model-helpers'; +import { currentEditData, groupAndSort, drawingModeChanged, updateLevels, setFields, deleteUnitPrevEdits, grabAndGrabbing, grabToPointer, updateSelectedColor } from './imdf-model-helpers'; import { JsonEditor } from 'json-edit-react' import 'azure-maps-drawing-tools/dist/atlas-drawing.min.css'; import 'azure-maps-control/dist/atlas.min.css'; -const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged }) => { +const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged, buildingChanged }) => { const [geography, subscriptionKey] = useUserStore(s => [s.geography, s.subscriptionKey]); const [imdfPackageLocation] = useConversionStore(s => [s.imdfPackageLocation]); const [language] = useLevelsStore(s => [s.language]); - const [units, setUnits] = useState({ features: [] }); + const [units, setUnits] = useState({ features: [], type: 'FeatureCollection' }); const [levels, setLevels] = useState({ features: [] }); const [building, setBuilding] = useState({ features: [] }); const [footprint, setFootprint] = useState({ features: [] }); @@ -25,6 +25,8 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged const [jsonData, setJsonData] = useState({}); const newDataRef = useRef(false); + // const [prevStates, setPrevStates] = useState([]); // Tracking previous changes for Undo feature + useEffect(() => { if (!imdfPackageLocation) return; @@ -44,6 +46,8 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged }, [imdfPackageLocation]); const [selectedLevelId, setSelectedLevelId] = useState(null); + const [selectedLayerId, setSelectedLayerId] = useState(null); + const [drawNotif, setDrawNotif] = useState(false); // Triggers drawing tip if true const selectedLevel = useMemo(() => { const level = levels.features.find(item => item.id === selectedLevelId) || levels.features[0] || {}; @@ -51,9 +55,6 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged return level; }, [levels, selectedLevelId]); - const [selectedLayerId, setSelectedLayerId] = useState(null); - const [drawNotif, setDrawNotif] = useState(false); - useEffect(() => { var drawingManager; @@ -71,7 +72,6 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged }); map.events.add('ready', () => { - map.getCanvasContainer().style.setProperty('cursor', 'pointer', '!important'); var drawingToolbar; setJsonData({}); @@ -146,30 +146,12 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged } }); - map.events.add('mousedown', function (e) { - map.getCanvas().style.cursor = 'grabbing'; - }); - - map.events.add('mouseup', function (e) { - map.getCanvas().style.cursor = 'grab'; - }); + grabAndGrabbing(map); // Shows change in corresponding feature color when mouse hovers over OR clicks on that feature let selectedFeatureID = null; function featureHoverClick(layerName, hoverLayer, clickLayer, unitSelected=false) { - map.events.add('mousemove', layerName, function (e) { - hoverLayer.setOptions({ filter: ['==', ['get', '_azureMapsShapeId'], e.shapes[0].getProperties()['_azureMapsShapeId']] }); - map.getCanvas().style.cursor = 'pointer'; - }); - - map.events.add('mouseleave', layerName, function (e) { - hoverLayer.setOptions({ filter: ['==', ['get', '_azureMapsShapeId'], ''] }); - map.getCanvas().style.cursor = 'grab'; - }); - - map.events.add(['mousedown', 'mouseup'], layerName, function (e) { - map.getCanvas().style.cursor = 'pointer'; - }); + grabToPointer(layerName, hoverLayer, map); map.events.add('click', layerName, function (e) { const clickedFeatureID = e.shapes[0].getProperties()['_azureMapsShapeId']; @@ -183,33 +165,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged }); // Handles the change in color of the feature when clicked (for full view) - if(unitSelected) { - const lineLayer = map.layers.getLayerById('lineClickLayer'); - try { - lineLayer.setOptions({strokeColor: 'hsla(0, 0%, 0%, 0)'}); - } catch { - console.log('No line layer to change color of.') - } - const unitLayer = map.layers.getLayerById('unitClickChange'); - try { - unitLayer.setOptions({fillColor: 'rgba(75, 146, 210, 0.8)'}); - } catch { - console.log('No unit layer to change color of.') - } - } else { - const polygonLayer = map.layers.getLayerById('lineClickLayer'); - try { - polygonLayer.setOptions({strokeColor: 'rgba(75, 146, 210, 0.8)'}); - } catch { - console.log('No unit layer to change color of.') - } - const unitLayer = map.layers.getLayerById('unitClickChange'); - try { - unitLayer.setOptions({fillColor: 'hsla(0, 0%, 0%, 0)'}); - } catch { - console.log('No unit layer to change color of.') - } - } + updateSelectedColor(map, unitSelected) var features; if(selectedLayerId === 'unitButton') @@ -239,11 +195,11 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged function handleDeletion(e) { if (drawingManager.getOptions().mode === 'erase-geometry') { - if (window.confirm('Do you want to proceed with removing this feature?')) { - drawingManager.getSource().remove(e.shapes[0]); - } + if (window.confirm('Do you want to proceed with removing this feature?')) { + drawingManager.getSource().remove(e.shapes[0]); + } } - } + } // Entry point when "unit.geojson" is pressed; the following code should be refactored due to redundancy function unitInteractions(units, drawingManager, map) { @@ -286,6 +242,11 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged dmLayers.polygonLayer.setOptions({ visible: false }); dmLayers.polygonOutlineLayer.setOptions({ visible: false }); layersAdded = [unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols]; + + // Saving previous states for undo functionality + // if(prevStates.length === 0 || units.features !== prevStates[prevStates.length - 1].features) { + // setPrevStates(prev => [...prev, {...units}]); + // } map.events.add('drawingmodechanged', drawingManager, (e) => { let dmLayers = drawingManager.getLayers(); @@ -305,36 +266,9 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged return acc; }, []); - // double check units state (restructuring accident) setUnits(prevUnits => ({ - ...prevUnits, features: [...prevUnits.features, ...newFeatures], })); - - // Update the units state with the edited features (for updating zip) - // unitsChanged(units); - - dmLayers.polygonLayer.setOptions({ visible: false }); - dmLayers.polygonOutlineLayer.setOptions({ visible: false }); - map.layers.remove([unitLayer, unitLines, polygonHoverLayer]); - - unitLayer = new layer.PolygonLayer(drawingManager.getSource(), 'unitClick', getFillStyles('unit', category)); - unitLines = new layer.LineLayer(drawingManager.getSource(), null, getLineStyles('unit', category)); - polygonHoverLayer = new layer.PolygonLayer(drawingManager.getSource(), null, { - fillColor: 'rgba(135, 206, 250, 0.8)', - filter: ['==', ['get', 'id'], ''], - cursor: 'pointer', - }); - polygonClickLayer = new layer.PolygonLayer(drawingManager.getSource(), 'unitClickChange', { - fillColor: 'rgba(75, 146, 210, 0.8)', - filter: ['==', ['get', 'id'], ''], - cursor: 'pointer', - }); - unitSymbols = new layer.SymbolLayer(drawingManager.getSource(), null, getTextStyle(category)); - - map.layers.add([unitLayer, polygonHoverLayer, polygonClickLayer, unitLines, unitSymbols], 'roomPolygons'); - featureHoverClick(unitLayer, polygonHoverLayer, polygonClickLayer, true); - layersAdded = [unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols]; } else if (e === 'edit-geometry' || e === 'erase-geometry' || e === 'draw-polygon') { drawingModeChanged(layersAdded); @@ -343,8 +277,14 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged if(e === 'draw-polygon') { setDrawNotif(true); + map.events.add('mousedown', function (e) { + map.getCanvas().style.cursor = 'crosshair'; + }); + + map.events.add('mouseup', function (e) { + map.getCanvas().style.cursor = 'crosshair'; + }); } - if(e === 'edit-geometry') { currentEditData(map, drawingManager, setJsonData); } @@ -512,14 +452,12 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged } function buildingInteractions(building, map) { - console.log(building); var buildingLayer = new HtmlMarker({ position: building.features[0].properties.display_point.coordinates, }); map.events.add('click', buildingLayer, highlight); map.markers.add(buildingLayer); - function highlight(e) { setJsonData(building.features[0]); } @@ -535,7 +473,6 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged levelsChanged(levels); var unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols, lineLayer, lineHoverLayer, lineClickLayer; - // var layersAdded = [unitLayer, unitLines, polygonHoverLayer, polygonClickLayer, unitSymbols, lineLayer, lineHoverLayer, lineClickLayer]; const groupedFeatures = groupAndSort(units, language, selectedLevel); const keys = Object.keys(groupedFeatures); @@ -604,7 +541,12 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged // Handles updates when a property is changed in the JSON editor const handleUpdate = ({ newData, currentData, newValue, currentValue, name, path }) => { - if (newData.properties.name && isNaN(newData.properties.ordinal)) { + if(newData.feature_type === 'building') { + // Building + building.features = [newData]; + buildingChanged(building); + } + else if (newData.properties.name && isNaN(newData.properties.ordinal)) { // Unit let editedIndex = units.features.findIndex(unit => unit.id === currentData.id); if (editedIndex !== -1) { @@ -641,6 +583,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged return true; }; + return (
@@ -665,7 +608,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged
- + />
From 3991972ea89f9a771cf0fe394de76ed68b84b01c Mon Sep 17 00:00:00 2001 From: Nicole Iftekhar Date: Mon, 26 Aug 2024 14:22:45 -0700 Subject: [PATCH 23/23] Added level polygon layer --- .../conversion/places-preview-map/index.js | 50 +++++++++++-------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/src/pages/conversion/places-preview-map/index.js b/src/pages/conversion/places-preview-map/index.js index d695d22..d90d4ec 100644 --- a/src/pages/conversion/places-preview-map/index.js +++ b/src/pages/conversion/places-preview-map/index.js @@ -171,7 +171,7 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged if(selectedLayerId === 'unitButton') features = map.layers.getRenderedShapes(e.position, 'unitClick'); else if(selectedLayerId === 'levelButton') - features = map.layers.getRenderedShapes(e.position, 'levelClick'); + features = map.layers.getRenderedShapes(e.position, 'levelFill'); else if(selectedLayerId === 'footprintButton') features = map.layers.getRenderedShapes(e.position, 'footprintClick'); else @@ -302,8 +302,8 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged // Retrieve information about the level currently chosen by user levelsChanged(levels); const selectedLevelDetails = levels.features.filter(item => item.id === selectedLevel.id); - var lineLayer, lineHoverLayer, lineClickLayer; - var layersAdded = [lineLayer, lineHoverLayer, lineClickLayer]; + var lineLayer, lineHoverLayer, lineClickLayer, linePolygonLayer; + var layersAdded = [lineLayer, lineHoverLayer, lineClickLayer, linePolygonLayer]; const dataSource = new source.DataSource(); map.sources.add(dataSource); @@ -311,19 +311,20 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged // Displays outline of level + change in color when cursor is hovering lineLayer = new layer.LineLayer(dataSource, 'levelClick', getLineStyles('level', 'walkway')); - lineHoverLayer = new layer.LineLayer(dataSource, null, { - strokeColor: 'rgba(135, 206, 250, 0.8)', + linePolygonLayer = new layer.PolygonLayer(dataSource, 'levelFill', getFillStyles('level', 'unspecified')); + lineHoverLayer = new layer.PolygonLayer(dataSource, null, { + fillColor: 'rgba(135, 206, 250, 0.8)', filter: ['==', ['get', '_azureMapsShapeId'], ''] }); - lineClickLayer = new layer.LineLayer(dataSource, 'lineClickLayer', { - strokeColor: 'rgba(75, 146, 210, 0.8)', + lineClickLayer = new layer.PolygonLayer(dataSource, 'lineClickLayer', { + fillColor: 'rgba(75, 146, 210, 0.8)', filter: ['==', ['get', 'id'], ''] }); - - map.layers.add([lineLayer, lineHoverLayer, lineClickLayer], 'walkwayPolygons'); - layersAdded = [lineLayer, lineHoverLayer, lineClickLayer]; - featureHoverClick(lineLayer, lineHoverLayer, lineClickLayer); + + map.layers.add([lineLayer, linePolygonLayer, lineHoverLayer, lineClickLayer], 'walkwayPolygons'); + layersAdded = [lineLayer, lineHoverLayer, lineClickLayer, linePolygonLayer]; + featureHoverClick(linePolygonLayer, lineHoverLayer, lineClickLayer); var drawingSource = drawingManager.getSource(); drawingSource.add(selectedLevelDetails); @@ -339,18 +340,20 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged dmLayers.polygonOutlineLayer.setOptions({ visible: false }); var lineLayer = new layer.LineLayer(drawingManager.getSource(), 'levelClick', getLineStyles('level', 'walkway')); - lineHoverLayer = new layer.LineLayer(drawingManager.getSource(), null, { - strokeColor: 'rgba(135, 206, 250, 1)', + linePolygonLayer = new layer.PolygonLayer(drawingManager.getSource(), 'levelFill', getFillStyles('level', 'unspecified')); + lineHoverLayer = new layer.PolygonLayer(drawingManager.getSource(), null, { + fillColor: 'rgba(135, 206, 250, 0.8)', filter: ['==', ['get', '_azureMapsShapeId'], ''] }); - lineClickLayer = new layer.LineLayer(drawingManager.getSource(), 'lineClickLayer', { - strokeColor: 'rgba(75, 146, 210, 0.7)', + + lineClickLayer = new layer.PolygonLayer(drawingManager.getSource(), 'lineClickLayer', { + fillColor: 'rgba(75, 146, 210, 0.8)', filter: ['==', ['get', 'id'], ''] }); - - map.layers.add([lineLayer, lineHoverLayer, lineClickLayer], 'walkwayPolygons'); - layersAdded = [lineLayer, lineHoverLayer, lineClickLayer]; - featureHoverClick(lineLayer, lineHoverLayer, lineClickLayer); + + map.layers.add([lineLayer, lineHoverLayer, lineClickLayer, linePolygonLayer], 'walkwayPolygons'); + layersAdded = [lineLayer, lineHoverLayer, lineClickLayer, linePolygonLayer]; + featureHoverClick(linePolygonLayer, lineHoverLayer, lineClickLayer); let updatedFeatures = drawingManager.getSource().shapes; setLevels(prevLevels => updateLevels(prevLevels, selectedLevel, (updatedFeatures[0]).data)); @@ -361,9 +364,16 @@ const PlacesPreviewMap = ({ style, unitsChanged, levelsChanged, footprintChanged else if (e === 'edit-geometry') { drawingModeChanged(layersAdded); dmLayers.polygonOutlineLayer.setOptions({ visible: true }); - dmLayers.polygonLayer.setOptions({ visible: false }); + dmLayers.polygonLayer.setOptions({ visible: true }); currentEditData(map, drawingManager, setJsonData); + + document.addEventListener('keydown', function (e) { + // Check if the delete or backspace key is pressed + if (e.key === 'Delete' || e.key === 'Backspace') { + drawingManager.setOptions({ mode: 'idle' }); + } + }); } else { // This will eventually be a visible pop-up