Skip to content

Commit

Permalink
Mapper Frontend: routing to feature (#1963)
Browse files Browse the repository at this point in the history
* feat(entities): store selected entity coordinate to store

* feat(maplibre-gl-directions): package add for maplibre routing feature

* feat(main): store clicked entity coordinate to store

* feat(geolocation): route path add from user location to selected entity

* fix(icon): icon add

* fix(button): add css for button type link

* feat(dialog-entities-actions): navigate btn add, other button syling update

* fix(geolocation): ts type add

* feat(entities): entityToNavigate & toggleGeolocation state add to store

* fix(dialog-entities-actions): navigate to entity function trigger on btn click

* refactor(main): geolocation status handle on child component, select payload for setSelectedEntityCoordinate action

* fix(geolocation): handle toggle geolocation on geolocation component itself

* feat(location): location img add

* fix(main): upate entity fill-color

* feat(maplibre-directions): custom styling for direction routes

* fix(geolocation): load destination location image, custom layer style load

* fix(entities): turn off geolocation by default

* feat(geolocation): show tooltip popup to users indicating geolocation feature to be turned on

* fix(main): remove zoom buttons from map
  • Loading branch information
NSUWAL123 authored Dec 23, 2024
1 parent c5f2e63 commit 3e418b5
Show file tree
Hide file tree
Showing 11 changed files with 398 additions and 99 deletions.
1 change: 1 addition & 0 deletions src/mapper/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"@electric-sql/client": "^0.8.0",
"@electric-sql/pglite": "^0.2.14",
"@hotosm/ui": "0.2.0-b5",
"@maplibre/maplibre-gl-directions": "^0.7.1",
"@tiptap/core": "^2.10.3",
"@tiptap/pm": "^2.10.3",
"@tiptap/starter-kit": "^2.10.3",
Expand Down
32 changes: 32 additions & 0 deletions src/mapper/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added src/mapper/src/assets/images/location.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
68 changes: 68 additions & 0 deletions src/mapper/src/assets/maplibre-directions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// snapline: line from waypoint to road
export const layers = [
{
id: 'maplibre-gl-directions-snapline',
type: 'line',
source: 'maplibre-gl-directions',
layout: {
'line-cap': 'round',
'line-join': 'round',
},
paint: {
'line-dasharray': [2, 2],
'line-color': '#000000',
'line-opacity': 0.65,
'line-width': 2,
},
filter: ['==', ['get', 'type'], 'SNAPLINE'],
},

// primary route
{
id: 'maplibre-gl-directions-routeline',
type: 'line',
source: 'maplibre-gl-directions',
layout: {
'line-cap': 'butt',
'line-join': 'round',
},
paint: {
'line-width': 12,
'line-opacity': 1,
'line-color': '#4285f4',
},
filter: ['==', ['get', 'route'], 'SELECTED'],
},

// alternative route
{
id: 'maplibre-gl-directions-alt-routeline',
type: 'line',
source: 'maplibre-gl-directions',
layout: {
'line-cap': 'butt',
'line-join': 'round',
},
paint: {
'line-width': 12,
'line-opacity': 0.8,
'line-color': '#547fff',
},
filter: ['==', ['get', 'route'], 'ALT'],
},

// only apply icon-style to the destination waypoint as we have icon for the origin
{
id: 'maplibre-gl-directions-waypoint',
type: 'symbol',
source: 'maplibre-gl-directions',
layout: {
'icon-image': 'location',
'icon-anchor': 'bottom',
'icon-ignore-placement': true,
'icon-overlap': 'always',
'icon-size': 0.5,
},
filter: ['all', ['==', ['get', 'type'], 'WAYPOINT'], ['==', ['get', 'category'], 'DESTINATION']],
},
];
75 changes: 56 additions & 19 deletions src/mapper/src/lib/components/dialog-entities-actions.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
const selectedEntity = $derived(
entitiesStore.entitiesStatusList?.find((entity) => entity.osmid === selectedEntityOsmId),
);
const selectedEntityCoordinate = $derived(entitiesStore.selectedEntityCoordinate);
const entityToNavigate = $derived(entitiesStore.entityToNavigate);
const mapFeature = () => {
const xformId = projectData?.odk_form_id;
Expand All @@ -43,6 +45,13 @@
alertStore.setAlert({ message: 'Requires a mobile phone with ODK Collect.', variant: 'warning' });
}
};
const navigateToEntity = () => {
if (!entitiesStore.toggleGeolocation) {
entitiesStore.setToggleGeolocation(true);
}
entitiesStore.setEntityToNavigate(selectedEntityCoordinate);
};
</script>

{#if isTaskActionModalOpen && selectedTab === 'map' && selectedEntity}
Expand All @@ -68,7 +77,6 @@
<div class="flex items-center justify-between">
<p class="text-[#333] text-xl font-barlow-semibold">Feature {selectedEntity?.osmid}</p>
<sl-button
loading={entitiesStore.syncEntityStatusLoading}
onclick={async () => {
await entitiesStore.syncEntityStatus(projectData?.id);
}}
Expand All @@ -78,8 +86,14 @@
role="button"
tabindex="0"
size="small"
class="secondary w-fit ml-auto"
class="link w-fit ml-auto"
disabled={entitiesStore.syncEntityStatusLoading}
>
<hot-icon
slot="prefix"
name="arrow-repeat"
class={`!text-[1rem] cursor-pointer duration-200 ${entitiesStore.syncEntityStatusLoading && 'animate-spin'}`}
></hot-icon>
<span class="font-barlow-medium text-SM uppercase">SYNC STATUS</span>
</sl-button>
</div>
Expand All @@ -92,24 +106,47 @@
</p>
</div>
{#if selectedEntity?.status !== 'SURVEY_SUBMITTED'}
<sl-button
loading={entitiesStore.updateEntityStatusLoading}
variant="default"
size="small"
class="primary"
onclick={() => {
mapFeature();
}}
onkeydown={(e: KeyboardEvent) => {
if (e.key === 'Enter') {
<div class="flex gap-2">
<sl-button
disabled={entityToNavigate?.entityId === selectedEntity?.osmid}
variant="default"
size="small"
class="secondary flex-grow"
onclick={() => {
navigateToEntity();
}}
onkeydown={(e: KeyboardEvent) => {
if (e.key === 'Enter') {
navigateToEntity();
}
}}
role="button"
tabindex="0"
>
<hot-icon slot="prefix" name="direction" class="!text-[1rem] cursor-pointer duration-200"></hot-icon>
<span class="font-barlow-medium text-sm">NAVIGATE HERE</span>
</sl-button>
<sl-button
loading={entitiesStore.updateEntityStatusLoading}
variant="default"
size="small"
class="primary flex-grow"
onclick={() => {
mapFeature();
}
}}
role="button"
tabindex="0"
>
<span class="font-barlow-medium text-sm">MAP FEATURE IN ODK</span>
</sl-button>
}}
onkeydown={(e: KeyboardEvent) => {
if (e.key === 'Enter') {
mapFeature();
}
}}
role="button"
tabindex="0"
>
<hot-icon slot="prefix" name="location" class="!text-[1rem] text-white cursor-pointer duration-200"
></hot-icon>
<span class="font-barlow-medium text-sm">MAP FEATURE IN ODK</span>
</sl-button>
</div>
{/if}
</div>
</div>
Expand Down
Loading

0 comments on commit 3e418b5

Please sign in to comment.