Robust saving strategy and vertex editing improvement
Deploy TrassenPlaner / deploy (push) Waiting to run
Details
Deploy TrassenPlaner / deploy (push) Waiting to run
Details
This commit is contained in:
parent
bf6183ce80
commit
6e5ef89733
52
index.html
52
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); }
|
||||
|
|
|
|||
15
server.js
15
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' });
|
||||
|
|
|
|||
Loading…
Reference in New Issue