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' ;
73import { featureCollection as createCollection } from "@turf/turf" ;
8- import { LayerSpecification } from 'maplibre-gl' ;
9- import createPolygonAroundLine from '../utils/lineToPolygonconverter' ;
4+ import { LayerSpecification } from 'maplibre-gl' ;
105import { MlGeoJsonLayer } from "@mapcomponents/react-maplibre" ;
116import { MlGeoJsonLayerProps } from "@mapcomponents/react-maplibre/dist/components/MlGeoJsonLayer/MlGeoJsonLayer" ;
127
138export 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' ;
4439}
4540
4641/**
@@ -49,120 +44,113 @@ export interface MlHighlightFeatureProps {
4944 */
5045
5146const 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+ ) ;
161149} ;
162150
163151MlHighlightFeature . defaultProps = {
164- mapId : undefined ,
165- offset : 0 ,
166- variant : 'outlined' ,
152+ mapId : undefined ,
153+ offset : 0 ,
154+ variant : 'outlined' ,
167155} ;
168156export default MlHighlightFeature ;
0 commit comments