Skip to content

Commit

Permalink
Add ability to move selected coordinate
Browse files Browse the repository at this point in the history
  • Loading branch information
hvangeffen authored and wkramer committed May 30, 2024
1 parent aeaccb8 commit 858d036
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 45 deletions.
10 changes: 2 additions & 8 deletions src/components/spatialdisplay/SpatialDisplay.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import { computed, ref, watch } from 'vue'
import SpatialDisplayComponent from '@/components/spatialdisplay/SpatialDisplayComponent.vue'
import { useDisplay } from 'vuetify'
import type { MapLayerMouseEvent, MapLayerTouchEvent } from 'maplibre-gl'
import { configManager } from '@/services/application-config'
import { useRoute, useRouter } from 'vue-router'
import { findParentRoute } from '@/router'
Expand Down Expand Up @@ -174,13 +173,8 @@ function openLocationTimeSeriesDisplay(locationId: string) {
})
}
function onCoordinateClick(
event: MapLayerMouseEvent | MapLayerTouchEvent,
): void {
openCoordinatesTimeSeriesDisplay(
+event.lngLat.lat.toFixed(3),
+event.lngLat.lng.toFixed(3),
)
function onCoordinateClick(latitude: number, longitude: number): void {
openCoordinatesTimeSeriesDisplay(latitude, longitude)
}
function openCoordinatesTimeSeriesDisplay(latitude: number, longitude: number) {
Expand Down
26 changes: 20 additions & 6 deletions src/components/spatialdisplay/SpatialDisplayComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@
v-model:range="colourScalesStore.currentScale.range"
/>
</div>
<SelectedCoordinateLayer :geoJson="selectedCoordinateGeoJson" />
<SelectedCoordinateLayer
:coordinate="selectedCoordinate"
@coordinate-moved="onCoordinateMoved"
/>
<LocationsLayer
v-if="showLocationsLayer && hasLocations"
:locationsGeoJson="geojson"
Expand Down Expand Up @@ -118,11 +121,14 @@ import BoundingBoxControl from '@/components/map/BoundingBoxControl.vue'
import { DateController } from '@/lib/TimeControl/DateController.ts'
import debounce from 'lodash-es/debounce'
import { useUserSettingsStore } from '@/stores/userSettings'
import type { MapLayerMouseEvent, MapLayerTouchEvent } from 'maplibre-gl'
import {
LngLat,
type MapLayerMouseEvent,
type MapLayerTouchEvent,
} from 'maplibre-gl'
import { configManager } from '@/services/application-config'
import type { Layer, Style } from '@deltares/fews-wms-requests'
import { LayerKind } from '@/lib/streamlines'
import { pointToGeoJson } from '@/lib/topology/coordinates'
import { useColourScalesStore } from '@/stores/colourScales'
import { useDisplay } from 'vuetify'
import { useFilterLocations } from '@/services/useFilterLocations'
Expand Down Expand Up @@ -279,10 +285,10 @@ watch(
{ immediate: true },
)
const selectedCoordinateGeoJson = computed(() => {
const selectedCoordinate = computed(() => {
if (props.latitude === undefined || props.longitude === undefined) return
return pointToGeoJson(+props.latitude, +props.longitude)
return new LngLat(+props.longitude, +props.latitude)
})
const hasLocations = computed(() => {
Expand Down Expand Up @@ -413,7 +419,15 @@ function setLayerOptions(): void {
function onCoordinateClick(
event: MapLayerMouseEvent | MapLayerTouchEvent,
): void {
emit('coordinateClick', event)
emit(
'coordinateClick',
+event.lngLat.lat.toFixed(3),
+event.lngLat.lng.toFixed(3),
)
}
function onCoordinateMoved(lat: number, lng: number): void {
emit('coordinateClick', +lat.toFixed(3), +lng.toFixed(3))
}
</script>
Expand Down
98 changes: 87 additions & 11 deletions src/components/wms/SelectedCoordinateLayer.vue
Original file line number Diff line number Diff line change
@@ -1,25 +1,60 @@
<template>
<mgl-geo-json-source :source-id="sourceId" :data="props.geoJson">
<mgl-circle-layer :layer-id="layerId" :paint="paintSpecification" />
<mgl-geo-json-source :source-id="sourceId" :data="geoJson">
<mgl-circle-layer
:layer-id="layerId"
:paint="paintSpecification"
@mouseenter="mouseenter"
@mouseleave="mouseleave"
@mousedown="mousedown"
@touchstart="touchstart"
/>
</mgl-geo-json-source>
</template>

<script setup lang="ts">
import { MglGeoJsonSource, MglCircleLayer } from 'vue-maplibre-gl'
import { LngLat, MapMouseEvent, MapTouchEvent } from 'maplibre-gl'
import { computed, ref, watch } from 'vue'
import { MglGeoJsonSource, MglCircleLayer, useMap } from 'vue-maplibre-gl'
interface Props {
geoJson?:
| GeoJSON.Feature<GeoJSON.Geometry>
| GeoJSON.FeatureCollection<GeoJSON.Geometry>
coordinate?: LngLat
}
const props = withDefaults(defineProps<Props>(), {
geoJson: () => ({
type: 'FeatureCollection',
features: [],
}),
const props = defineProps<Props>()
const emit = defineEmits(['coordinate-moved'])
const coordinate = ref<LngLat>()
watch(
() => props.coordinate,
() => {
coordinate.value = props.coordinate
},
{ immediate: true },
)
type DataType = InstanceType<typeof MglGeoJsonSource>['data']
const geoJson = computed<DataType>(() => {
if (!coordinate.value) {
return {
type: 'FeatureCollection',
features: [],
}
}
return {
type: 'Feature',
properties: {},
geometry: {
type: 'Point',
coordinates: coordinate.value.toArray(),
},
}
})
const { map } = useMap()
if (!map) throw new Error('Map is not available to show selected coordinate')
const canvas = map.getCanvasContainer()
const layerId = 'selected-coordinate-layer'
const sourceId = 'selected-coordinate-source'
Expand All @@ -29,4 +64,45 @@ const paintSpecification = {
'circle-stroke-color': 'white',
'circle-stroke-width': 2.5,
}
const onMove = (e: MapMouseEvent) => {
coordinate.value = e.lngLat
canvas.style.cursor = 'grabbing'
}
const onUp = (e: MapMouseEvent) => {
map.off('mousemove', onMove)
map.off('touchmove', onMove)
canvas.style.cursor = ''
const coords = e.lngLat
emit('coordinate-moved', coords.lat, coords.lng)
}
const mouseenter = () => {
canvas.style.cursor = 'move'
}
const mouseleave = () => {
canvas.style.cursor = ''
}
const mousedown = (e: MapMouseEvent) => {
e.preventDefault()
canvas.style.cursor = 'grab'
map.on('mousemove', onMove)
map.once('mouseup', onUp)
}
const touchstart = (e: MapTouchEvent) => {
if (e.points.length !== 1) return
e.preventDefault()
map.on('touchmove', onMove)
map.once('touchend', onUp)
}
</script>
20 changes: 0 additions & 20 deletions src/lib/topology/coordinates.ts

This file was deleted.

0 comments on commit 858d036

Please sign in to comment.