nestjs rewrite
This commit is contained in:
125
client/src/components/map/MapLineTest.tsx
Normal file
125
client/src/components/map/MapLineTest.tsx
Normal file
@ -0,0 +1,125 @@
|
||||
import { useEffect, useRef } from 'react'
|
||||
import 'ol/ol.css'
|
||||
import { Container, Stack, Tabs } from '@mantine/core'
|
||||
import OlMap from 'ol/Map'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import TileLayer from 'ol/layer/Tile'
|
||||
import { OSM } from 'ol/source'
|
||||
import View from 'ol/View'
|
||||
import { transform } from 'ol/proj'
|
||||
import VectorLayer from 'ol/layer/Vector'
|
||||
import VectorSource from 'ol/source/Vector'
|
||||
import Feature from 'ol/Feature'
|
||||
import { LineString } from 'ol/geom'
|
||||
import { Stroke, Style, Text } from 'ol/style'
|
||||
|
||||
const center = [14443331.466543002, 8878970.176309839]
|
||||
|
||||
const style = new Style({
|
||||
stroke: new Stroke({ color: 'blue', width: 2 }),
|
||||
text: new Text({
|
||||
font: 'bold 14px',
|
||||
placement: 'line',
|
||||
offsetY: -14
|
||||
}),
|
||||
})
|
||||
|
||||
const MapLineTest = () => {
|
||||
const lines = [
|
||||
{ name: 'A', points: [[100, 100], [200, 200]] },
|
||||
{ name: 'B', points: [[200, 200], [300, 200]] },
|
||||
{ name: 'X', points: [[200, 200], [300, 300]] },
|
||||
{ name: 'L', points: [[300, 300], [350, 300]] },
|
||||
{ name: 'N', points: [[300, 300], [250, 300]] },
|
||||
{ name: 'I', points: [[300, 200], [300, 100]] },
|
||||
{ name: 'J', points: [[300, 100], [250, 50]] },
|
||||
{ name: 'C', points: [[300, 200], [400, 150]] },
|
||||
{ name: 'D', points: [[400, 150], [400, 100]] },
|
||||
]
|
||||
|
||||
const map = useRef<OlMap | null>(null)
|
||||
const vectorLayer = useRef(new VectorLayer({
|
||||
source: new VectorSource(),
|
||||
style: feature => {
|
||||
style.getText()?.setText(feature.get('label'))
|
||||
return style
|
||||
}
|
||||
}))
|
||||
|
||||
const mapElement = useRef<HTMLDivElement | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
map.current = new OlMap({
|
||||
controls: [],
|
||||
layers: [
|
||||
new TileLayer({ source: new OSM(), properties: { id: uuidv4(), name: 'OpenStreetMap' } }),
|
||||
vectorLayer.current
|
||||
]
|
||||
})
|
||||
map.current.setTarget(mapElement.current as HTMLDivElement)
|
||||
map.current.setView(new View({
|
||||
center: transform([129.7466541, 62.083504], 'EPSG:4326', 'EPSG:3857'),
|
||||
zoom: 16,
|
||||
maxZoom: 21,
|
||||
}))
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (map.current) {
|
||||
const graph = new Map<string, { node: string, distance: number }[]>()
|
||||
|
||||
// build graph adjacency list
|
||||
lines.forEach(({ points }) => {
|
||||
const [start, end] = points.map(pt => pt.join(','))
|
||||
const distance = Math.hypot(points[1][0] - points[0][0], points[1][1] - points[0][1])
|
||||
|
||||
if (!graph.has(start)) graph.set(start, [])
|
||||
if (!graph.has(end)) graph.set(end, [])
|
||||
|
||||
graph.get(start)?.push({ node: end, distance })
|
||||
graph.get(end)?.push({ node: start, distance })
|
||||
})
|
||||
|
||||
// perform DFS to calculate distances from "A"
|
||||
const startNode = lines[0].points[0].join(',')
|
||||
const distances = new Map<string, number>()
|
||||
const dfs = (node: string, currentDist: number) => {
|
||||
if (distances.has(node) && distances.get(node)! <= currentDist) return
|
||||
distances.set(node, currentDist)
|
||||
for (const { node: neighbor, distance } of graph.get(node) || []) {
|
||||
dfs(neighbor, currentDist + distance)
|
||||
}
|
||||
}
|
||||
dfs(startNode, 0)
|
||||
|
||||
// render features
|
||||
lines.forEach(({ name, points }) => {
|
||||
const lineCoords = points.map(point => [point[0] + center[0], point[1] + center[1]])
|
||||
const feature = new Feature(new LineString(lineCoords))
|
||||
|
||||
const lastNode = points[1].join(',')
|
||||
const label = `${name} ${feature.getGeometry()?.getLength().toFixed(2)} (${distances.get(lastNode)?.toFixed(1) ?? '∞'})`
|
||||
|
||||
feature.set('label', label)
|
||||
vectorLayer.current.getSource()?.addFeature(feature)
|
||||
})
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Container fluid w='100%' pos='relative' p={0}>
|
||||
<Tabs h='100%' variant='default' value={'map'} keepMounted={true}>
|
||||
<Stack gap={0} h='100%'>
|
||||
<Tabs.List>
|
||||
<Tabs.Tab value={'map'}>Map</Tabs.Tab>
|
||||
</Tabs.List>
|
||||
<Tabs.Panel value={'map'} h='100%' pos='relative'>
|
||||
<Container pos='absolute' fluid p={0} w='100%' h='100%' ref={mapElement}></Container>
|
||||
</Tabs.Panel>
|
||||
</Stack>
|
||||
</Tabs>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
||||
export default MapLineTest
|
Reference in New Issue
Block a user