diff --git a/index.html b/index.html
index 474310c..ea68c6f 100644
--- a/index.html
+++ b/index.html
@@ -1720,8 +1720,8 @@
middleMarkers: true,
pane: 'trassenPane',
lineOptions: { color: '#cca300', weight: 6 },
- vertexOptions: { color: '#cca300', radius: 5 },
- middleMarkerOptions: { color: '#cca300', opacity: 0.5, radius: 3 }
+ vertexOptions: { color: '#cca300', radius: 6 },
+ middleMarkerOptions: { color: '#cca300', opacity: 0.6, radius: 4 }
});
drillingLayers[v.id] = L.featureGroup({ interactive: false, pane: 'drillingPane' });
labelLayers[v.id] = L.featureGroup({ interactive: false, pane: 'labelPane' });
@@ -1732,8 +1732,29 @@
labelLayers[v.id].addTo(map);
}
- // Allow vertex insertion by clicking the polyline itself
- routeLayers[v.id].on('click', handleVertexInsertion);
+ // Allow vertex insertion by clicking anywhere on the polyline
+ routeLayers[v.id].on('click', (e) => {
+ if (!v.active) return;
+ if (!map.editTools) return;
+
+ // Prevent the default map click from bubbling
+ L.DomEvent.stopPropagation(e);
+
+ const layer = routeLayers[v.id];
+ // Find the closest segment and insert a point
+ const point = map.mouseEventToLatLng(e.originalEvent);
+ const vertexIndex = findClosestSegmentIndex(layer.getLatLngs(), point);
+
+ if (vertexIndex !== -1) {
+ const latlngs = layer.getLatLngs();
+ latlngs.splice(vertexIndex + 1, 0, point);
+ layer.setLatLngs(latlngs);
+ layer.editor.refresh(); // Tell the Leaflet.Editable editor to update markers
+
+ // Trigger all the sync events manually
+ map.fire('editable:vertex:inserted', { layer: layer });
+ }
+ });
}
const layer = routeLayers[v.id];
@@ -1892,13 +1913,27 @@
calculateStats(activeV);
updateVariantStatsUI(activeV);
updateVariantStatsUI(activeV);
- if (e.type.includes('end') || e.type === 'editable:created' || e.type.includes('dragend')) {
+ if (e.type.includes('end') || e.type === 'editable:created' || e.type.includes('dragend') || e.type === 'editable:vertex:inserted') {
renderVariants();
const _activeV = state.variants.find(v => v.active);
if (_activeV) saveVariantToDB(_activeV);
}
});
+ // Helper to find the best spot to insert a new vertex
+ function findClosestSegmentIndex(latlngs, point) {
+ let minDistance = Infinity;
+ let index = -1;
+ for (let i = 0; i < latlngs.length - 1; i++) {
+ const distance = L.LineUtil.closestPointOnSegment(map.latLngToLayerPoint(point), map.latLngToLayerPoint(latlngs[i]), map.latLngToLayerPoint(latlngs[i+1])).distanceTo(map.latLngToLayerPoint(point));
+ if (distance < minDistance) {
+ minDistance = distance;
+ index = i;
+ }
+ }
+ return index;
+ }
+
function getFlattenedCoords(raw) {
if (!raw) return [];
// If it's a flat array of LatLngs already
@@ -2787,7 +2822,11 @@
if (slot && f.geometry && f.geometry.coordinates) {
slot.id = f.id || p.id || slot.id;
slot.routes = f.geometry.coordinates.map(c => ({ lat: c[1], lng: c[0] }));
- console.log(`[V3-Sync] ${slot.name} erfolgreich gemappt.`);
+
+ // Re-sync the polyline layer if it exists
+ if (routeLayers[slot.id]) {
+ routeLayers[slot.id].setLatLngs(slot.routes);
+ }
}
});
@@ -2825,6 +2864,7 @@
if (Math.abs(firstCoord) > 1000) gj = transformGeoJSON(gj, "EPSG:25832", "EPSG:4326");
}
state.usage = gj;
+ cachedObstacles = null; // IMPORTANT: Reset cache to trigger new calculation
updateUsageLayer();
}
} catch (e) { console.error("[V3-Sync] Usage Error:", e); }
diff --git a/server.js b/server.js
index 9aa76df..4e7dc84 100644
--- a/server.js
+++ b/server.js
@@ -187,7 +187,7 @@ app.get('/api/variants', async (req, res) => {
await setSchema(client);
const query = `
SELECT
- id, name, "Variante",
+ COALESCE(id, fid) AS id, name, "Variante",
ST_AsGeoJSON(ST_Transform(geom, 4326)) as geometry
FROM kabeltrasse
ORDER BY id DESC
@@ -227,22 +227,21 @@ app.post('/api/variants', async (req, res) => {
const varianteValue = properties.Variante || (properties.name ? properties.name.replace('Variante ', '') : 'A');
const geoJsonStr = JSON.stringify(geometry);
- const upsertQuery = `
+ // Delete existing variant if it exists (Manual UPSERT to bypass missing index permissions)
+ await client.query('DELETE FROM kabeltrasse WHERE "Variante" = $1 OR name = $2', [varianteValue, routeName]);
+
+ const insertQuery = `
INSERT INTO kabeltrasse (geom, name, "Variante")
VALUES (
ST_MakeValid(ST_Transform(ST_GeomFromGeoJSON($1), 25832)),
$2,
$3
)
- ON CONFLICT ("Variante")
- DO UPDATE SET
- geom = EXCLUDED.geom,
- name = EXCLUDED.name
RETURNING id
`;
- const upsertRes = await client.query(upsertQuery, [geoJsonStr, routeName, varianteValue]);
- res.json({ success: true, id: upsertRes.rows[0].id });
+ const insertRes = await client.query(insertQuery, [geoJsonStr, routeName, varianteValue]);
+ res.json({ success: true, id: insertRes.rows[0].id });
} catch (err) {
console.error("SQL-FEHLER (SAVE):", err.message);
res.status(500).json({ error: 'Failed to save variant' });