From 47d32a5641cdb62143e4faea676134e44f5afeb9 Mon Sep 17 00:00:00 2001 From: RyanBirtch-aot Date: Fri, 11 Oct 2024 16:34:00 +0000 Subject: [PATCH 1/2] Geocoder working for BC --- app/frontend/package-lock.json | 16 +++++++++++ app/frontend/package.json | 1 + components/package-lock.json | 23 +++++++++++++++ components/package.json | 2 ++ components/src/components/Map/Component.ts | 18 ++++++++---- .../Map/editForm/Component.edit.data.ts | 7 ----- .../Map/services/BCGeocoderProvider.ts | 28 +++++++++++++++++++ .../src/components/Map/services/MapService.ts | 22 +++++++++++++++ 8 files changed, 104 insertions(+), 13 deletions(-) create mode 100644 components/src/components/Map/services/BCGeocoderProvider.ts diff --git a/app/frontend/package-lock.json b/app/frontend/package-lock.json index e3d4efeb1..250dd02a3 100644 --- a/app/frontend/package-lock.json +++ b/app/frontend/package-lock.json @@ -23,6 +23,7 @@ "keycloak-js": "^21.1.1", "leaflet": "^1.9.4", "leaflet-draw": "^1.0.4", + "leaflet-geosearch": "^4.0.0", "lodash": "^4.17.21", "mitt": "^3.0.0", "moment": "^2.29.4", @@ -592,6 +593,12 @@ "vue": ">= 3.0.0 < 4" } }, + "node_modules/@googlemaps/js-api-loader": { + "version": "1.16.8", + "resolved": "https://registry.npmjs.org/@googlemaps/js-api-loader/-/js-api-loader-1.16.8.tgz", + "integrity": "sha512-CROqqwfKotdO6EBjZO/gQGVTbeDps5V7Mt9+8+5Q+jTg5CRMi3Ii/L9PmV3USROrt2uWxtGzJHORmByxyo9pSQ==", + "optional": true + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", @@ -3705,6 +3712,15 @@ "resolved": "https://registry.npmjs.org/leaflet-draw/-/leaflet-draw-1.0.4.tgz", "integrity": "sha512-rsQ6saQO5ST5Aj6XRFylr5zvarWgzWnrg46zQ1MEOEIHsppdC/8hnN8qMoFvACsPvTioAuysya/TVtog15tyAQ==" }, + "node_modules/leaflet-geosearch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/leaflet-geosearch/-/leaflet-geosearch-4.0.0.tgz", + "integrity": "sha512-a92VNY9gxyv3oyEDqIWoCNoBllajWRYejztzOSNmpLRtzpA6JtGgy/wwl9tsB8+6Eek1fe+L6+W0MDEOaidbXA==", + "optionalDependencies": { + "@googlemaps/js-api-loader": "^1.16.6", + "leaflet": "^1.6.0" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", diff --git a/app/frontend/package.json b/app/frontend/package.json index 3759ab75c..fc3590af6 100644 --- a/app/frontend/package.json +++ b/app/frontend/package.json @@ -44,6 +44,7 @@ "keycloak-js": "^21.1.1", "leaflet": "^1.9.4", "leaflet-draw": "^1.0.4", + "leaflet-geosearch": "^4.0.0", "lodash": "^4.17.21", "mitt": "^3.0.0", "moment": "^2.29.4", diff --git a/components/package-lock.json b/components/package-lock.json index 0fc29cacb..15e0f0ea4 100644 --- a/components/package-lock.json +++ b/components/package-lock.json @@ -16,6 +16,7 @@ "formiojs": "^4.14.6", "leaflet": "^1.9.4", "leaflet-draw": "^1.0.4", + "leaflet-geosearch": "^4.0.0", "lodash": "^4.17.21", "native-promise-only": "^0.8.1", "path-browserify": "^1.0.1", @@ -24,6 +25,7 @@ "devDependencies": { "@types/chai": "^4.3.1", "@types/ejs": "^3.1.1", + "@types/google.maps": "^3.58.1", "@types/mocha": "^9.1.1", "@types/node": "^16.11.8", "@types/sinon": "^10.0.12", @@ -741,6 +743,12 @@ "resolved": "https://registry.npmjs.org/@formio/vanilla-text-mask/-/vanilla-text-mask-5.1.1.tgz", "integrity": "sha512-7MhrbMypySPi7RLchg0ys7HnS3Wqddbq/btAijKB1nA94TE7AOOLhpZJWcNm3kOlX0Y3nHfoavj/HP7vsvF34Q==" }, + "node_modules/@googlemaps/js-api-loader": { + "version": "1.16.8", + "resolved": "https://registry.npmjs.org/@googlemaps/js-api-loader/-/js-api-loader-1.16.8.tgz", + "integrity": "sha512-CROqqwfKotdO6EBjZO/gQGVTbeDps5V7Mt9+8+5Q+jTg5CRMi3Ii/L9PmV3USROrt2uWxtGzJHORmByxyo9pSQ==", + "optional": true + }, "node_modules/@gulpjs/messages": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@gulpjs/messages/-/messages-1.1.0.tgz", @@ -1013,6 +1021,12 @@ "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz", "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==" }, + "node_modules/@types/google.maps": { + "version": "3.58.1", + "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.58.1.tgz", + "integrity": "sha512-X9QTSvGJ0nCfMzYOnaVs/k6/4L+7F5uCS+4iUmkLEls6J9S/Phv+m/i3mDeyc49ZBgwab3EFO1HEoBY7k98EGQ==", + "dev": true + }, "node_modules/@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -4018,6 +4032,15 @@ "resolved": "https://registry.npmjs.org/leaflet-draw/-/leaflet-draw-1.0.4.tgz", "integrity": "sha512-rsQ6saQO5ST5Aj6XRFylr5zvarWgzWnrg46zQ1MEOEIHsppdC/8hnN8qMoFvACsPvTioAuysya/TVtog15tyAQ==" }, + "node_modules/leaflet-geosearch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/leaflet-geosearch/-/leaflet-geosearch-4.0.0.tgz", + "integrity": "sha512-a92VNY9gxyv3oyEDqIWoCNoBllajWRYejztzOSNmpLRtzpA6JtGgy/wwl9tsB8+6Eek1fe+L6+W0MDEOaidbXA==", + "optionalDependencies": { + "@googlemaps/js-api-loader": "^1.16.6", + "leaflet": "^1.6.0" + } + }, "node_modules/liftoff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-5.0.0.tgz", diff --git a/components/package.json b/components/package.json index 8961cee2d..13ce65d7d 100644 --- a/components/package.json +++ b/components/package.json @@ -54,6 +54,7 @@ "formiojs": "^4.14.6", "leaflet": "^1.9.4", "leaflet-draw": "^1.0.4", + "leaflet-geosearch": "^4.0.0", "lodash": "^4.17.21", "native-promise-only": "^0.8.1", "path-browserify": "^1.0.1", @@ -62,6 +63,7 @@ "devDependencies": { "@types/chai": "^4.3.1", "@types/ejs": "^3.1.1", + "@types/google.maps": "^3.58.1", "@types/mocha": "^9.1.1", "@types/node": "^16.11.8", "@types/sinon": "^10.0.12", diff --git a/components/src/components/Map/Component.ts b/components/src/components/Map/Component.ts index 4644c3f94..1a031b8b6 100644 --- a/components/src/components/Map/Component.ts +++ b/components/src/components/Map/Component.ts @@ -42,7 +42,7 @@ export default class Component extends (FieldComponent as any) { render() { return super.render( - `
` + `
` ); } @@ -57,13 +57,19 @@ export default class Component extends (FieldComponent as any) { const form = document.getElementsByClassName('formio'); const drawOptions = { - marker: false, - circlemarker: false, - polygon: false, - polyline: false, - circle: false, rectangle: null, + circle: false, + polyline: false, + polygon: false, + circlemarker: false, + marker: false, }; + // marker: false, + // circlemarker: false, + // polygon: false, + // polyline: false, + // circle: false, + // rectangle: null, // set marker type from user choice if (this.component.markerType) { for (const [key, value] of Object.entries(this.component.markerType)) { diff --git a/components/src/components/Map/editForm/Component.edit.data.ts b/components/src/components/Map/editForm/Component.edit.data.ts index 5a0d9e456..d047abf33 100644 --- a/components/src/components/Map/editForm/Component.edit.data.ts +++ b/components/src/components/Map/editForm/Component.edit.data.ts @@ -21,13 +21,6 @@ export default { 'This will be the value for this field, before user interaction.', input: true, }, - { - label: 'How many Markers per Submission?', - key: 'numPoints', - type: 'simplenumber', - defaultValue: 1, - input: true, - }, { label: 'Default Zoom Level', diff --git a/components/src/components/Map/services/BCGeocoderProvider.ts b/components/src/components/Map/services/BCGeocoderProvider.ts new file mode 100644 index 000000000..d8cae43b9 --- /dev/null +++ b/components/src/components/Map/services/BCGeocoderProvider.ts @@ -0,0 +1,28 @@ +import { OpenStreetMapProvider } from 'leaflet-geosearch'; +import { EndpointArgument } from 'leaflet-geosearch/dist/providers/provider'; + +export class BCGeocoderProvider extends OpenStreetMapProvider { + endpoint({ query, type }: EndpointArgument): string { + console.log(query); + return this.getUrl(import.meta.env.VITE_CHEFS_GEO_ADDRESS_APIURL, { + addressString: query as string, + }); + } + parse({ data }) { + return data.features + .filter(function (feature) { + if (!feature.geometry.coordinates) return false; + if (feature.properties.fullAddress == 'BC') return false; + return true; + }) + .map(function (feature) { + return { + x: feature.geometry.coordinates[0], + y: feature.geometry.coordinates[1], + label: feature.properties.fullAddress, + matchPrecision: feature.properties.matchPrecision, + raw: feature, + }; + }); + } +} diff --git a/components/src/components/Map/services/MapService.ts b/components/src/components/Map/services/MapService.ts index 360eee268..edfd9b732 100644 --- a/components/src/components/Map/services/MapService.ts +++ b/components/src/components/Map/services/MapService.ts @@ -1,7 +1,10 @@ import * as L from 'leaflet'; +import * as GeoSearch from 'leaflet-geosearch'; +import { BCGeocoderProvider } from '../services/BCGeocoderProvider'; import 'leaflet-draw'; import 'leaflet/dist/leaflet.css'; import 'leaflet-draw/dist/leaflet.draw-src.css'; +import 'leaflet-geosearch/dist/geosearch.css'; const DEFAULT_MAP_LAYER_URL = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'; @@ -26,6 +29,7 @@ interface MapServiceOptions { onDrawnItemsChange: (items: any) => void; // Support both single and multiple items viewMode?: boolean; myLocation?: boolean; + geocoder: any; } class MapService { @@ -146,6 +150,24 @@ class MapService { myLocationControl.addTo(map); } + //Geocoder Control + // const geoControl = new GeoSearch.GeoSearchControl({ + + // }) + const geocoderControl = new (GeoSearch.GeoSearchControl as any)({ + provider: new BCGeocoderProvider(), + style: 'bar', + position: 'bottomleft', + }); + + // const geocoderControl = new (GeoSearch.GeoSearchControl as any)({ + // provider: new GeoSearch.OpenStreetMapProvider(), + // style: 'bar', + // position: 'bottomleft', + // }); + + map.addControl(geocoderControl); + // Add Drawing Controllers if (!readOnlyMap) { if (!viewMode) { From 04a7d2fb10a907821df0cdf99b5340ed912f09ed Mon Sep 17 00:00:00 2001 From: RyanBirtch-aot Date: Tue, 15 Oct 2024 18:39:54 +0000 Subject: [PATCH 2/2] Adding form and location popups --- components/src/components/Map/Component.ts | 2 ++ .../Map/editForm/Component.edit.data.ts | 9 +++++ .../src/components/Map/services/MapService.ts | 34 +++++++++---------- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/components/src/components/Map/Component.ts b/components/src/components/Map/Component.ts index 1a031b8b6..c3fb06650 100644 --- a/components/src/components/Map/Component.ts +++ b/components/src/components/Map/Component.ts @@ -91,6 +91,7 @@ export default class Component extends (FieldComponent as any) { center, defaultValue, myLocation, + bcGeocoder, } = this.component; const { readOnly: viewMode } = this.options; @@ -114,6 +115,7 @@ export default class Component extends (FieldComponent as any) { onDrawnItemsChange: this.saveDrawnItems.bind(this), viewMode, myLocation, + bcGeocoder, }); // Load existing data if available diff --git a/components/src/components/Map/editForm/Component.edit.data.ts b/components/src/components/Map/editForm/Component.edit.data.ts index d047abf33..ac89cb0b3 100644 --- a/components/src/components/Map/editForm/Component.edit.data.ts +++ b/components/src/components/Map/editForm/Component.edit.data.ts @@ -106,5 +106,14 @@ export default { input: true, defaultValue: true, }, + { + label: 'Enable BC Address Autocomplete', + description: + 'This allows for the user to enter an address and have results appear in a dropdown. The user can then select the result which fits best and have the map center on that location', + key: 'bcGeocoder', + type: 'simplecheckboxadvanced', + input: true, + defaultValue: true, + }, ], }; diff --git a/components/src/components/Map/services/MapService.ts b/components/src/components/Map/services/MapService.ts index edfd9b732..3cccb849b 100644 --- a/components/src/components/Map/services/MapService.ts +++ b/components/src/components/Map/services/MapService.ts @@ -29,7 +29,7 @@ interface MapServiceOptions { onDrawnItemsChange: (items: any) => void; // Support both single and multiple items viewMode?: boolean; myLocation?: boolean; - geocoder: any; + bcGeocoder: boolean; } class MapService { @@ -86,6 +86,7 @@ class MapService { readOnlyMap, viewMode, myLocation, + bcGeocoder, } = options; if (drawOptions.rectangle) { @@ -150,23 +151,20 @@ class MapService { myLocationControl.addTo(map); } - //Geocoder Control - // const geoControl = new GeoSearch.GeoSearchControl({ - - // }) - const geocoderControl = new (GeoSearch.GeoSearchControl as any)({ - provider: new BCGeocoderProvider(), - style: 'bar', - position: 'bottomleft', - }); - - // const geocoderControl = new (GeoSearch.GeoSearchControl as any)({ - // provider: new GeoSearch.OpenStreetMapProvider(), - // style: 'bar', - // position: 'bottomleft', - // }); - - map.addControl(geocoderControl); + if (bcGeocoder) { + const geocoderControl = new (GeoSearch.GeoSearchControl as any)({ + provider: new BCGeocoderProvider(), + style: 'bar', + position: 'bottomleft', + }); + map.addControl(geocoderControl); + map.on('geosearch/showlocation', (e) => { + L.popup() + .setLatLng([(e as any).location.y, (e as any).location.x]) + .setContent(`${(e as any).location.label}`) + .openOn(map); + }); + } // Add Drawing Controllers if (!readOnlyMap) {