-
-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathgeojson-layer.tsx
More file actions
121 lines (108 loc) · 3.34 KB
/
geojson-layer.tsx
File metadata and controls
121 lines (108 loc) · 3.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
'use client'
import { useEffect } from 'react'
import type mapboxgl from 'mapbox-gl'
import { useMap } from './map-context'
import type { FeatureCollection } from 'geojson'
interface GeoJsonLayerProps {
id: string;
data: FeatureCollection;
}
export function GeoJsonLayer({ id, data }: GeoJsonLayerProps) {
const { map } = useMap()
useEffect(() => {
if (!map || !data) return
const sourceId = `geojson-source-${id}`
const pointLayerId = `geojson-point-layer-${id}`
const polygonLayerId = `geojson-polygon-layer-${id}`
const polygonOutlineLayerId = `geojson-polygon-outline-layer-${id}`
const lineStringLayerId = `geojson-linestring-layer-${id}`
const onMapLoad = () => {
// Add source if it doesn't exist
if (!map.getSource(sourceId)) {
map.addSource(sourceId, {
type: 'geojson',
data: data
})
} else {
// If source exists, just update the data
const source = map.getSource(sourceId) as mapboxgl.GeoJSONSource;
source.setData(data);
}
// Add polygon layer for fill
if (!map.getLayer(polygonLayerId)) {
map.addLayer({
id: polygonLayerId,
type: 'fill',
source: sourceId,
filter: ['==', '$type', 'Polygon'],
paint: {
'fill-color': '#088',
'fill-opacity': 0.4
}
})
}
// Add polygon layer for outline
if (!map.getLayer(polygonOutlineLayerId)) {
map.addLayer({
id: polygonOutlineLayerId,
type: 'line',
source: sourceId,
filter: ['==', '$type', 'Polygon'],
paint: {
'line-color': '#088',
'line-width': 2
}
})
}
// Add linestring layer for routes
if (!map.getLayer(lineStringLayerId)) {
map.addLayer({
id: lineStringLayerId,
type: 'line',
source: sourceId,
filter: ['any', ['==', '$type', 'LineString'], ['==', '$type', 'MultiLineString']],
layout: {
'line-join': 'round',
'line-cap': 'round'
},
paint: {
'line-color': '#3b82f6', // blue-500
'line-width': 4,
'line-opacity': 0.8
}
})
}
// Add point layer for circles
if (!map.getLayer(pointLayerId)) {
map.addLayer({
id: pointLayerId,
type: 'circle',
source: sourceId,
filter: ['==', '$type', 'Point'],
paint: {
'circle-radius': 6,
'circle-color': '#B42222',
'circle-stroke-width': 2,
'circle-stroke-color': '#ffffff'
}
})
}
}
if (map.isStyleLoaded()) {
onMapLoad()
} else {
map.on('load', onMapLoad)
}
// Cleanup function
return () => {
if (map.isStyleLoaded()) {
if (map.getLayer(pointLayerId)) map.removeLayer(pointLayerId)
if (map.getLayer(polygonLayerId)) map.removeLayer(polygonLayerId)
if (map.getLayer(polygonOutlineLayerId)) map.removeLayer(polygonOutlineLayerId)
if (map.getLayer(lineStringLayerId)) map.removeLayer(lineStringLayerId)
if (map.getSource(sourceId)) map.removeSource(sourceId)
}
}
}, [map, id, data])
return null // This component does not render any DOM elements itself
}