Skip to content

Commit

Permalink
feat: implement fly to closest location and then trigger popup info
Browse files Browse the repository at this point in the history
  • Loading branch information
ntubrian committed May 29, 2024
1 parent fa95f00 commit 97870f5
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 2 deletions.
109 changes: 108 additions & 1 deletion Taipei-City-Dashboard-FE/src/components/map/MapContainer.vue
Original file line number Diff line number Diff line change
@@ -1,20 +1,33 @@
<!-- Developed by Taipei Urban Intelligence Center 2023-2024-->

<script setup>
import { onMounted, ref } from "vue";
import { onMounted, ref, computed } from "vue";
import { storeToRefs } from "pinia";

import { useMapStore } from "../../store/mapStore";
import { useDialogStore } from "../../store/dialogStore";
import { useContentStore } from "../../store/contentStore";

import MobileLayers from "../dialogs/MobileLayers.vue";

import { calculateHaversineDistance } from "../../assets/utilityFunctions/calculateHaversineDistance";

const mapStore = useMapStore();
const { getSourceByMapConfigId } = storeToRefs(mapStore);
const dialogStore = useDialogStore();
const contentStore = useContentStore();

const districtLayer = ref(false);
const villageLayer = ref(false);

const mapConfigsLength = computed(
() => Object.keys(mapStore.currentVisibleLayers).length
);
const currentVisibleLayerKey = computed(() => mapStore.currentVisibleLayers);
const mapConfigs = computed(() => {
return mapStore.mapConfigs;
});

// const newSavedLocation = ref("");

// function handleSubmitNewLocation() {
Expand All @@ -32,8 +45,64 @@ function toggleVillageLayer() {
mapStore.toggleVillageBoundaries(villageLayer.value);
}

function findClosestLocation(userCoords, locations) {
// Check if userCoords has valid latitude and longitude
if (
!userCoords ||
typeof userCoords.latitude !== "number" ||
typeof userCoords.longitude !== "number"
) {
throw new Error("Invalid user coordinates");
}

let minDistance = Infinity;
let closestLocation = null;

for (let location of locations) {
try {
// Check if location, location.geometry, and location.geometry.coordinates are valid
if (
!location ||
!location.geometry ||
!Array.isArray(location.geometry.coordinates)
) {
continue; // Skip this location if any of these are invalid
}
const [lon, lat] = location.geometry.coordinates;

// Check if longitude and latitude are valid numbers
if (typeof lon !== "number" || typeof lat !== "number") {
continue; // Skip this location if coordinates are not numbers
}

// Calculate the Haversine distance
const distance = calculateHaversineDistance(
{
latitude: userCoords.latitude,
longitude: userCoords.longitude,
},
{ latitude: lat, longitude: lon }
);

// Update the closest location if the current distance is smaller
if (distance < minDistance) {
minDistance = distance;
closestLocation = location;
}
} catch (e) {
// Catch and log any errors during processing
console.error(
`Error processing location: ${JSON.stringify(location)}`,
e
);
}
}
return closestLocation;
}

onMounted(() => {
mapStore.initializeMapBox();
mapStore.setCurrentLocation();
});
</script>

Expand Down Expand Up @@ -69,6 +138,44 @@ onMounted(() => {
>
</button>

<button
v-if="
mapConfigsLength === 1 &&
mapConfigs[currentVisibleLayerKey ?? '']?.type ===
'circle'
"
:style="{
color: villageLayer
? 'var(--color-highlight)'
: 'var(--color-component-background)',
}"
type="button"
@click="
() => {
const res = findClosestLocation(
{
longitude: mapStore.userLocation.longitude,
latitude: mapStore.userLocation.latitude,
},

{
...getSourceByMapConfigId(
`${mapConfigs[currentVisibleLayerKey].index}-circle`
),
}.features
);

mapStore.map.once('moveend', () => {
mapStore.manualTriggerPopup();
});

mapStore.flyToLocation(res.geometry.coordinates);
}
"
>
</button>
<button
class="show-if-mobile"
@click="dialogStore.showDialog('mobileLayers')"
Expand Down
18 changes: 17 additions & 1 deletion Taipei-City-Dashboard-FE/src/store/mapStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,13 @@ export const useMapStore = defineStore("map", {
// Store the user's current location,
userLocation: { latitude: null, longitude: null },
}),
getters: {},
getters: {
getSourceByMapConfigId: (state) => {
return (mapConfigId) => {
return state.map.getSource(`${mapConfigId}-source`)._data;
};
},
},
actions: {
/* Initialize Mapbox */
// 1. Creates the mapbox instance and passes in initial configs
Expand Down Expand Up @@ -647,6 +653,16 @@ export const useMapStore = defineStore("map", {
}
this.popup = null;
},
// 3. programmatically trigger the popup, instead of user click
manualTriggerPopup() {
const center = this.map.getCenter();
const point = this.map.project(center);

this.addPopup({
point: point,
lngLat: center,
});
},

/* Functions that change the viewing experience of the map */
// 1. Add new saved location that users can quickly zoom to
Expand Down

0 comments on commit 97870f5

Please sign in to comment.