1
- import { useEffect , useState } from 'react' ;
2
- import {
3
- Feature ,
4
- Geometry ,
5
- Position , FeatureCollection ,
6
- } from 'geojson' ;
1
+ import { useEffect , useState } from 'react' ;
2
+ import { Feature , FeatureCollection , } from 'geojson' ;
7
3
import { featureCollection as createCollection } from "@turf/turf" ;
8
- import { LayerSpecification } from 'maplibre-gl' ;
9
- import createPolygonAroundLine from '../utils/lineToPolygonconverter' ;
4
+ import { LayerSpecification } from 'maplibre-gl' ;
10
5
import { MlGeoJsonLayer } from "@mapcomponents/react-maplibre" ;
11
6
import { MlGeoJsonLayerProps } from "@mapcomponents/react-maplibre/dist/components/MlGeoJsonLayer/MlGeoJsonLayer" ;
12
7
13
8
export interface MlHighlightFeatureProps {
14
- /**
15
- * id of the target MapLibre instance in mapContext
16
- */
17
- mapId ?: string ;
18
- /**
19
- * The Feature or FeatureCollection to be highlighted by the component.
20
- */
21
- features : Feature [ ] | undefined ;
22
- /**
23
- * Distance between the original and the highlighted Features.
24
- *
25
- * For polygon features (line and polygon inputs), a positive value results in an inset, while a negative value results in an outset.
26
- * For circle features (point input), negative values are not allowed; therefore, the absolute value will be used.
27
- * Default value: -5
28
- */
29
- offset ?: number ;
30
- /**
31
- * Paint properties of the config object that is passed to the MapLibreGl.addLayer call.
32
- * The paint properties must be compatible with the output type:
33
- * For polygon and line inputs ---> Line Type
34
- * For circle inputs ----> circle Type
35
- * All available properties are documented in the MapLibreGl documentation
36
- * https://maplibre.org/maplibre-style-spec/layers/#paint
37
- */
38
-
39
- paint ?: LayerSpecification [ 'paint' ] ;
40
-
41
- insertBeforeLayer ?: string ;
42
-
43
- variant ?: 'dark' | 'hell' | 'outline' ;
9
+ /**
10
+ * id of the target MapLibre instance in mapContext
11
+ */
12
+ mapId ?: string ;
13
+ /**
14
+ * The Feature or FeatureCollection to be highlighted by the component.
15
+ */
16
+ features : Feature [ ] | undefined ;
17
+ /**
18
+ * Distance between the original and the highlighted Features.
19
+ *
20
+ * For polygon features (line and polygon inputs), a positive value results in an inset, while a negative value results in an outset.
21
+ * For circle features (point input), negative values are not allowed; therefore, the absolute value will be used.
22
+ * Default value: -5
23
+ */
24
+ offset ?: number ;
25
+ /**
26
+ * Paint properties of the config object that is passed to the MapLibreGl.addLayer call.
27
+ * The paint properties must be compatible with the output type:
28
+ * For polygon and line inputs ---> Line Type
29
+ * For circle inputs ----> circle Type
30
+ * All available properties are documented in the MapLibreGl documentation
31
+ * https://maplibre.org/maplibre-style-spec/layers/#paint
32
+ */
33
+
34
+ paint ?: LayerSpecification [ 'paint' ] ;
35
+
36
+ insertBeforeLayer ?: string ;
37
+
38
+ variant ?: 'dark' | 'hell' | 'outline' ;
44
39
}
45
40
46
41
/**
@@ -49,120 +44,113 @@ export interface MlHighlightFeatureProps {
49
44
*/
50
45
51
46
const MlHighlightFeature = ( props : MlHighlightFeatureProps ) => {
52
- const selectedVariant = props . variant || 'outline' ;
53
- const [ geojson , setGeojson ] = useState < FeatureCollection > ( ) ;
54
- const [ paint , setPaint ] = useState < any > ( ) ;
55
- const [ layerType , setLayerType ] = useState < MlGeoJsonLayerProps [ 'type' ] > ( 'circle' ) ;
56
-
57
- const defaultColor = '#40e0d0' ;
58
-
59
- const variant = {
60
- dark : { color : '#555555' , opacity : 0.5 } ,
61
- outline : { color : defaultColor , lineColor : '#40e0d0' , lineWidth : 6 , opacity : 1 } ,
62
- hell : { color : '#40e0d0' , opacity : 1 } ,
63
- } ;
64
-
65
- function getHighlightedFeature ( feature : Feature ) {
66
- const newFeature : Feature = feature ;
67
-
68
- switch ( feature . geometry . type ) {
69
- case 'Polygon' :
70
- if ( props . variant == 'outline' ) {
71
- setPaint ( {
72
- 'line-color' : variant . outline . color ,
73
- 'line-width' : variant . outline . lineWidth ,
74
- 'line-offset' : props . offset ,
75
- ...props . paint ,
76
- } ) ;
77
- setLayerType ( 'line' ) ;
78
- } else {
79
- setPaint ( {
80
- 'fill-color' : variant [ selectedVariant ] . color ,
81
- 'fill-opacity' : variant [ selectedVariant ] . opacity ,
82
- ...props . paint ,
83
- } ) ;
84
- setLayerType ( 'fill' ) ;
85
- }
86
- break ;
87
-
88
- case 'LineString' :
89
- if ( selectedVariant == 'outline' ) {
90
- setPaint ( { 'line-color' : variant [ selectedVariant ] . lineColor , 'line-offset' : props . offset , ...props . paint } ) ;
91
- setLayerType ( 'line' ) ;
92
- // transform newFeature into a polygon that surrounds the line
93
- newFeature . geometry = createPolygonAroundLine (
94
- ( newFeature . geometry as Geometry ) . coordinates as Position [ ] ,
95
- props . offset ? props . offset * 1e-5 : - 1 * 1e-5
96
- ) ;
97
- } else {
98
- setPaint ( {
99
- 'line-color' : variant [ selectedVariant ] . color ,
100
- 'line-opacity' : variant [ selectedVariant ] . opacity ,
101
- ...props . paint ,
102
- } ) ;
103
-
104
- setLayerType ( 'line' ) ;
105
- }
106
- break ;
107
-
108
-
109
- case 'Point' :
110
- if ( selectedVariant == 'outline' ) {
111
-
112
- setLayerType ( 'circle' ) ;
113
- setPaint ( {
114
- 'circle-stroke-color' : variant [ selectedVariant ] . lineColor ,
115
- 'circle-opacity' : 0 ,
116
- 'circle-stroke-width' : 2 ,
117
- 'circle-radius' : props . offset && Math . abs ( props . offset ) ,
118
- ...props . paint ,
119
- } ) ;
120
- } else {
121
- setPaint ( {
122
- 'circle-color' : variant [ selectedVariant ] . color ,
123
- 'circle-opacity' : variant [ selectedVariant ] . opacity ,
124
- ...props . paint ,
125
- } ) ;
126
-
127
- setLayerType ( 'circle' ) ;
128
- }
129
-
130
- break ;
131
- }
132
- return newFeature ;
133
- }
134
-
135
- useEffect ( ( ) => {
136
- if ( ! props . features ) {
137
- setGeojson ( undefined ) ;
138
- return ;
139
- }
140
- const highlightedFeatures : Feature [ ] = [ ] ;
141
- props . features . forEach ( ( feature : Feature ) =>
142
- highlightedFeatures . push ( getHighlightedFeature ( feature ) )
143
- ) ;
144
- setGeojson ( createCollection ( highlightedFeatures ) ) ;
145
- } , [ props . features ] ) ;
146
-
147
- return (
148
- < >
149
- { geojson && (
150
- < MlGeoJsonLayer
151
- mapId = { props . mapId }
152
- geojson = { geojson }
153
- layerId = "MlHighlightFeature"
154
- type = { layerType }
155
- options = { { paint : paint } }
156
- insertBeforeLayer = { props . insertBeforeLayer }
157
- />
158
- ) }
159
- </ >
160
- ) ;
47
+ const selectedVariant = props . variant || 'outline' ;
48
+ const [ geojson , setGeojson ] = useState < FeatureCollection > ( ) ;
49
+ const [ paint , setPaint ] = useState < any > ( ) ;
50
+ const [ layerType , setLayerType ] = useState < MlGeoJsonLayerProps [ 'type' ] > ( 'circle' ) ;
51
+
52
+ const defaultColor = '#40e0d0' ;
53
+
54
+ const variant = {
55
+ dark : { color : '#555555' , opacity : 0.5 } ,
56
+ outline : { color : defaultColor , lineColor : '#40e0d0' , lineWidth : 6 , opacity : 1 } ,
57
+ hell : { color : '#40e0d0' , opacity : 1 } ,
58
+ } ;
59
+
60
+ function getHighlightedFeature ( feature : Feature ) {
61
+ const newFeature : Feature = feature ;
62
+
63
+ switch ( feature . geometry . type ) {
64
+ case 'Polygon' :
65
+ if ( props . variant == 'outline' ) {
66
+ setPaint ( {
67
+ 'line-color' : variant . outline . color ,
68
+ 'line-width' : variant . outline . lineWidth ,
69
+ 'line-offset' : props . offset ,
70
+ ...props . paint ,
71
+ } ) ;
72
+ setLayerType ( 'line' ) ;
73
+ } else {
74
+ setPaint ( {
75
+ 'fill-color' : variant [ selectedVariant ] . color ,
76
+ 'fill-opacity' : variant [ selectedVariant ] . opacity ,
77
+ ...props . paint ,
78
+ } ) ;
79
+ setLayerType ( 'fill' ) ;
80
+ }
81
+ break ;
82
+
83
+ case 'LineString' :
84
+ if ( selectedVariant != 'outline' ) {
85
+
86
+ setPaint ( {
87
+ 'line-color' : variant [ selectedVariant ] . color ,
88
+ 'line-opacity' : variant [ selectedVariant ] . opacity ,
89
+ ...props . paint ,
90
+ } ) ;
91
+
92
+ setLayerType ( 'line' ) ;
93
+ }
94
+ break ;
95
+
96
+
97
+ case 'Point' :
98
+ if ( selectedVariant == 'outline' ) {
99
+
100
+ setLayerType ( 'circle' ) ;
101
+ setPaint ( {
102
+ 'circle-stroke-color' : variant [ selectedVariant ] . lineColor ,
103
+ 'circle-opacity' : 0 ,
104
+ 'circle-stroke-width' : 2 ,
105
+ 'circle-radius' : props . offset && Math . abs ( props . offset ) ,
106
+ ...props . paint ,
107
+ } ) ;
108
+ } else {
109
+ setPaint ( {
110
+ 'circle-color' : variant [ selectedVariant ] . color ,
111
+ 'circle-opacity' : variant [ selectedVariant ] . opacity ,
112
+ ...props . paint ,
113
+ } ) ;
114
+
115
+ setLayerType ( 'circle' ) ;
116
+ }
117
+
118
+ break ;
119
+ }
120
+ return newFeature ;
121
+ }
122
+
123
+ useEffect ( ( ) => {
124
+ if ( ! props . features ) {
125
+ setGeojson ( undefined ) ;
126
+ return ;
127
+ }
128
+ const highlightedFeatures : Feature [ ] = [ ] ;
129
+ props . features . forEach ( ( feature : Feature ) =>
130
+ highlightedFeatures . push ( getHighlightedFeature ( feature ) )
131
+ ) ;
132
+ setGeojson ( createCollection ( highlightedFeatures ) ) ;
133
+ } , [ props . features ] ) ;
134
+
135
+ return (
136
+ < >
137
+ { geojson && (
138
+ < MlGeoJsonLayer
139
+ mapId = { props . mapId }
140
+ geojson = { geojson }
141
+ layerId = "MlHighlightFeature"
142
+ type = { layerType }
143
+ options = { { paint : paint } }
144
+ insertBeforeLayer = { props . insertBeforeLayer }
145
+ />
146
+ ) }
147
+ </ >
148
+ ) ;
161
149
} ;
162
150
163
151
MlHighlightFeature . defaultProps = {
164
- mapId : undefined ,
165
- offset : 0 ,
166
- variant : 'outlined' ,
152
+ mapId : undefined ,
153
+ offset : 0 ,
154
+ variant : 'outlined' ,
167
155
} ;
168
156
export default MlHighlightFeature ;
0 commit comments