@@ -253,29 +253,53 @@ function createLayer(
253253 } ) ;
254254 }
255255
256+ // Zusatz-Layer (Mittelpunkt-Punkt, Beschriftung) — dem Kreis/der Fläche
257+ // beigelegt, ohne sie selbst zu mutieren (Invariante #1: reiner Render-Pfad).
258+ const extras : L . Layer [ ] = [ ] ;
259+
260+ // Mittelpunkt bei Kreisen (#186): kleiner, gleichfarbiger, nicht-interaktiver
261+ // Punkt am Zentrum — macht das exakte Zentrum sichtbar (radius in Pixeln).
262+ if ( feature . shape === "circle" && feature . geometry [ 0 ] ) {
263+ extras . push (
264+ L . circleMarker ( feature . geometry [ 0 ] , {
265+ radius : 3 ,
266+ color : feature . color ,
267+ fillColor : feature . color ,
268+ fillOpacity : 1 ,
269+ weight : 1 ,
270+ interactive : false ,
271+ } ) ,
272+ ) ;
273+ }
274+
256275 const label = feature . label ?. trim ( ) ;
257- if ( ! labelsVisible || ! label ) return shape ;
258-
259- const labelElement = document . createElement ( "div" ) ;
260- labelElement . className = "lagekarte-area-label__text" ;
261- labelElement . textContent = label ;
262- labelElement . style . backgroundColor = `color-mix(in srgb, ${ feature . color } 14%, transparent)` ;
263- labelElement . style . color = `color-mix(in srgb, ${ feature . color } 72%, black)` ;
264- labelElement . style . borderColor = feature . color ;
265- const center =
266- feature . shape === "circle" ? feature . geometry [ 0 ] : shape . getBounds ( ) . getCenter ( ) ;
267- if ( ! center ) return shape ;
268- const labelMarker = L . marker ( center , {
269- icon : L . divIcon ( {
270- className : "lagekarte-area-label" ,
271- html : labelElement ,
272- iconAnchor : [ 0 , 0 ] ,
273- iconSize : [ 0 , 0 ] ,
274- } ) ,
275- interactive : false ,
276- keyboard : false ,
277- } ) ;
278- return L . featureGroup ( [ shape , labelMarker ] ) ;
276+ if ( labelsVisible && label ) {
277+ const labelElement = document . createElement ( "div" ) ;
278+ labelElement . className = "lagekarte-area-label__text" ;
279+ labelElement . textContent = label ;
280+ labelElement . style . backgroundColor = `color-mix(in srgb, ${ feature . color } 14%, transparent)` ;
281+ labelElement . style . color = `color-mix(in srgb, ${ feature . color } 72%, black)` ;
282+ labelElement . style . borderColor = feature . color ;
283+ const center =
284+ feature . shape === "circle" ? feature . geometry [ 0 ] : shape . getBounds ( ) . getCenter ( ) ;
285+ if ( center ) {
286+ extras . push (
287+ L . marker ( center , {
288+ icon : L . divIcon ( {
289+ className : "lagekarte-area-label" ,
290+ html : labelElement ,
291+ iconAnchor : [ 0 , 0 ] ,
292+ iconSize : [ 0 , 0 ] ,
293+ } ) ,
294+ interactive : false ,
295+ keyboard : false ,
296+ } ) ,
297+ ) ;
298+ }
299+ }
300+
301+ if ( extras . length === 0 ) return shape ;
302+ return L . featureGroup ( [ shape , ...extras ] ) ;
279303 }
280304
281305 const tip = buildTooltip ( feature ) ;
@@ -332,6 +356,8 @@ export function Lagekarte({
332356 const [ areaColor , setAreaColor ] = useState ( "#d5372b" ) ;
333357 const [ areaOpacity , setAreaOpacity ] = useState ( 0.3 ) ;
334358 const [ areaDash , setAreaDash ] = useState ( "" ) ;
359+ // Radius des ausgewählten Kreises in Metern, im Editor bearbeitbar (#186).
360+ const [ areaRadius , setAreaRadius ] = useState ( 0 ) ;
335361 const [ label , setLabel ] = useState ( "" ) ;
336362 const [ description , setDescription ] = useState ( "" ) ;
337363 // Ausrichtung des ausgewählten Symbols (0–359°, 0 = Norden). Pro Symbol, nicht global
@@ -568,6 +594,7 @@ export function Lagekarte({
568594 setAreaColor ( selectedFeature . color ) ;
569595 setAreaOpacity ( selectedFeature . opacity ) ;
570596 setAreaDash ( selectedFeature . dashArray ?? "" ) ;
597+ setAreaRadius ( Math . round ( selectedFeature . radiusM ?? 0 ) ) ;
571598 } else {
572599 setRotation ( selectedFeature . rotation ?? 0 ) ;
573600 }
@@ -673,6 +700,9 @@ export function Lagekarte({
673700 color : areaColor ,
674701 opacity : areaOpacity ,
675702 dashArray : areaDash || "" ,
703+ // Radius nur bei Kreisen mitschreiben (#186); >0 erzwingen, damit ein
704+ // versehentlich geleertes Feld den Kreis nicht kollabieren lässt.
705+ ...( current . shape === "circle" ? { radiusM : Math . max ( 1 , areaRadius ) } : { } ) ,
676706 label,
677707 description,
678708 updatedAt,
@@ -1753,6 +1783,19 @@ export function Lagekarte({
17531783 < button type = "button" title = "Gestrichelt" aria-pressed = { areaDash === "5,5" } onClick = { ( ) => setAreaDash ( "5,5" ) } > ╌</ button >
17541784 < button type = "button" title = "Gepunktet" aria-pressed = { areaDash === "2,4" } onClick = { ( ) => setAreaDash ( "2,4" ) } > ┄</ button >
17551785 </ fieldset >
1786+ { selectedFeature . shape === "circle" && (
1787+ < label className = "lagekarte-field" >
1788+ < span > Radius { formatDistance ( Math . max ( 1 , areaRadius ) ) } </ span >
1789+ < input
1790+ type = "number"
1791+ min = "1"
1792+ step = "10"
1793+ value = { areaRadius }
1794+ aria-label = "Radius in Metern"
1795+ onChange = { ( event ) => setAreaRadius ( Math . max ( 0 , Number ( event . target . value ) ) ) }
1796+ />
1797+ </ label >
1798+ ) }
17561799 </ >
17571800 ) }
17581801 { selectedFeature . kind === "symbol" && (
0 commit comments