Consolidate note-drawing into Measure; add edit/delete
Measure already draws distance lines and area polygons by hand — a second click-to-draw UI in the notes tool (Point/Area mode, from the previous commit) duplicated that. Replaced it with a "Save as note" button on the Measure panel that saves whatever shape is currently drawn there; NotesControl goes back to being just a one-click point pin. Both share a single NoteSaveForm (notes.js) for the note-text + target-layer-file UI instead of two copies of it. gpx.js: the "lines" source now also renders a note-flagged LineString (dashed, popup-on-click) alongside the Polygon fill/outline from before — the plain track-line layer excludes category:"Note" features so a saved distance note doesn't also get the track hover-summary/ profile-panel treatment. Notes are now individually editable/deletable from their own popup (logged-in only): Edit swaps the popup content for an inline textarea, Delete confirms and removes. Both target the feature by a new client-generated properties.id rather than array position (new GpxStore#update_feature/#delete_feature, PUT/DELETE /api/gpx/notes), since neither array index nor the note's own text (the thing being edited) is a stable identifier. Verified live: Measure's Save button (disabled/enabled state, saves the exact on-screen shape), the popup's Edit/Delete buttons and inline edit form. Full test suite: 115 runs, 0 failures (new coverage for update_feature/delete_feature and the PUT/DELETE routes).
This commit is contained in:
1 parent
db58468187
commit
aafb4cb4a0
9 files changed
+499
-239
No files matched your search
@@ -254,6 +254,45 @@ module Maptool
|
||||
json path: path, tree: GPX_STORE.tree
|
||||
end
|
||||
|
||||
# Editing/deleting one note (see the popup's Edit/Delete actions,
|
||||
# gpx.js) — targets a feature by properties["id"], not array position
|
||||
# (see GpxStore#update_feature/#delete_feature for why).
|
||||
put "/api/gpx/notes" do
|
||||
require_login!
|
||||
begin
|
||||
feature = JSON.parse(params[:feature].to_s)
|
||||
rescue JSON::ParserError
|
||||
halt 400, json(error: "invalid feature")
|
||||
end
|
||||
halt 400, json(error: "invalid feature") unless feature.is_a?(Hash) && feature["geometry"]
|
||||
halt 400, json(error: "path and id are required") if params[:path].to_s.empty? || params[:id].to_s.empty?
|
||||
|
||||
begin
|
||||
GPX_STORE.update_feature(path: params[:path], id: params[:id], feature: feature)
|
||||
rescue GpxStore::InvalidPath
|
||||
halt 400, json(error: "invalid path")
|
||||
rescue Errno::ENOENT
|
||||
halt 404, json(error: "note not found")
|
||||
end
|
||||
|
||||
json ok: true
|
||||
end
|
||||
|
||||
delete "/api/gpx/notes" do
|
||||
require_login!
|
||||
halt 400, json(error: "path and id are required") if params[:path].to_s.empty? || params[:id].to_s.empty?
|
||||
|
||||
begin
|
||||
GPX_STORE.delete_feature(path: params[:path], id: params[:id])
|
||||
rescue GpxStore::InvalidPath
|
||||
halt 400, json(error: "invalid path")
|
||||
rescue Errno::ENOENT
|
||||
halt 404, json(error: "note not found")
|
||||
end
|
||||
|
||||
json ok: true
|
||||
end
|
||||
|
||||
# ?download=geojson exports the file's GeoJSON as an attachment instead
|
||||
# of rendering it on the map — the only way to get a .gpx/.fit's
|
||||
# converted form out of the app, since GpxStore#geojson's cache is
|
||||
|
||||
Reference in new issue
Block a user