@@ -20,8 +20,9 @@ import {
2020 initializeExtrasLabelStyles ,
2121 renderRouteExtras
2222} from 'maplibre/layers/geojson/route_extras'
23- import { Layer } from 'maplibre/layers/layer'
24- import { getFeature , layers } from 'maplibre/layers/layers'
23+ import { highlightFeature } from 'maplibre/feature'
24+ import { Layer , queryFeaturesNear } from 'maplibre/layers/layer'
25+ import { frontFeature , getFeature , layers } from 'maplibre/layers/layers'
2526import { addGeoJSONSource , map , mapProperties , removeGeoJSONSource } from 'maplibre/map'
2627import { pruneShapeImages } from 'maplibre/styles/circle_image'
2728import { prunePatternImages } from 'maplibre/styles/pattern_image'
@@ -78,6 +79,38 @@ export class GeoJSONLayer extends Layer {
7879 addGeoJSONSource ( this . extrusionSourceId , false )
7980 }
8081
82+ setupClickHandler ( ) {
83+ super . setupClickHandler ( )
84+
85+ // Double-click opens geometry edit mode directly
86+ this . dblClickHandler = ( e ) => {
87+ if ( window . gon . map_mode !== 'rw' ) { return }
88+ if ( draw && draw . getMode ( ) !== 'simple_select' ) { return }
89+ if ( e . defaultPrevented ) { return }
90+
91+ const feature = queryFeaturesNear ( e . point , { layers : this . getStyleLayerIds ( ) } )
92+ . find ( f => ! f . properties ?. cluster )
93+ if ( ! feature ) { return }
94+
95+ highlightFeature ( feature , true , this . sourceId )
96+ requestAnimationFrame ( ( ) => frontFeature ( feature ) )
97+ window . dispatchEvent ( new CustomEvent ( 'toggle-edit-feature' , { detail : { type : 'geometry' } } ) )
98+
99+ // Prevent map zoom on double-click
100+ e . preventDefault ( )
101+ e . originalEvent . stopPropagation ( )
102+ }
103+ map . on ( 'dblclick' , this . dblClickHandler )
104+ }
105+
106+ removeEventHandlers ( ) {
107+ super . removeEventHandlers ( )
108+ if ( this . dblClickHandler ) {
109+ map . off ( 'dblclick' , this . dblClickHandler )
110+ this . dblClickHandler = null
111+ }
112+ }
113+
81114 cleanup ( ) {
82115 super . cleanup ( )
83116 cleanupKmMarkerImages ( this . kmMarkerSourceId )
@@ -90,7 +123,7 @@ export class GeoJSONLayer extends Layer {
90123
91124 initialize ( ) {
92125 initializeViewStyles ( this . sourceId , ! ! this . layer . heatmap )
93- if ( this . layer . cluster ) { initializeClusterStyles ( this . sourceId , null ) }
126+ if ( this . clustered ) { initializeClusterStyles ( this . sourceId , null ) }
94127 initializeKmMarkerStyles ( this . kmMarkerSourceId )
95128 initializeViewStyles ( this . routeExtrasSourceId )
96129 initializeExtrasLabelStyles ( this . routeExtrasSourceId )
@@ -104,6 +137,12 @@ export class GeoJSONLayer extends Layer {
104137 map . setLayoutProperty ( `line-layer_${ this . routeExtrasSourceId } ` , 'line-cap' , 'butt' )
105138
106139 this . setupEventHandlers ( )
140+ // Showing a layer runs initialize() again. The source kept its features while hidden (updates
141+ // reach it through updateData), unless setStyle replaced it, so only then fetch them again.
142+ if ( this . renderedSource && this . renderedSource === map . getSource ( this . sourceId ) ) {
143+ this . render ( true , { sourceLoaded : true } )
144+ return Promise . resolve ( this . layer . geojson )
145+ }
107146 return this . loadData ( )
108147 }
109148
@@ -129,7 +168,7 @@ export class GeoJSONLayer extends Layer {
129168 }
130169 } )
131170
132- if ( this . layer . cluster ) {
171+ if ( this . clustered ) {
133172 clusterStyles ( null ) . forEach ( style => {
134173 const layerId = `${ style . id } _${ this . sourceId } `
135174 if ( map . getLayer ( layerId ) ) { map . setFilter ( layerId , withLevelFilter ( style . filter ) ) }
@@ -221,6 +260,7 @@ export class GeoJSONLayer extends Layer {
221260 } )
222261 }
223262
263+ this . renderedSource = source
224264 this . resetDrawFeatures ( resetDraw )
225265 pruneShapes ( )
226266 }
0 commit comments