mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2026-11-01 20:19:39 +00:00
Migration to new Rust-based engine (#401)
* wasm first steps * parsing start * parsing continued * progress * progress * progress * progress * progress * progress * progress * progress * fixes * reorganize * change type * fix * progress * refactoring * progress * progress * progress * keep style info * progress * progress * remove (copy) in name * progress * merge methods into 1 * splice * progress * progress * progress * cleaning * progress * progress * progress * visibility * progress * progress * progress * progress * progress * fixes * progress * fix markers * fix * progress * progress * progress * progress * progress * progress * small fix * use engine info * fix popups * small fix * progress * progress * progress * clean tool * handle self closing elements * reduce data exchanges across boundary * copy on wasm side to avoid any data corruption * speed fix * routing * refactoring * reverse * reverse * crop * split * merge * progress * time tool * fix bounds for waypoints * reduce * fix reactivity * handle corrupt time data * export * progress * remove gpx js package * remove todo * update readme * cleaning * progress * fix link fields * remove unused fields * refactoring and tests * import and export of routes, ref #192 * per-chunk categories storage * cross-tab sync * outdated state * refactoring * reorder methods * refactoring * fix * improve flow * renaming * progress * progress * fix * progress * per file history * keep original flag * use history variant * fix * progress * file explorer * progress * fix * sticky folders * improved sticky folders * fix sortable * fix sortable * fix * fix tab size * no file delete on desktop * fix routing on other file * fix sorting * remember language * open links in browser * commit missing changes * avoid selecting on resize * clarify filename * explorer actions * fix folder styling * drop anywhere in folder * cleaning * fixes * remove focus-ring * full screen * small fix * consistent highlight color * improved preview * performance improvements * sparser data transfers * sparser data transfers * show popup once data is loaded * fix routing control size * fix * sparse desktop build * remove custom ign styles * use new endpoint for openhikingmap * strip native menu * reorder context menu items * route full support * route - track conversion * create route file action * route export, filter out anchors at high zoom level * clarify name handling * move hide & center to view * routes continued * update docs * fix power format, closes #378 * lint fixes * fix display of additional data with gaps, closes #361 * fix linting issues * fix import modules * fix multidrag * change base to resolve * fix type errors * fix layer typings * fix last type error * each keys * improve typings * deploy to cloudflare --------- Co-authored-by: vcoppe <vcoppe@hexaly.com>
This commit is contained in:
1 parent
6a0d434371
commit
8fe7d8d64d
484 files changed
+53949
-41152
No files matched your search
@@ -0,0 +1,40 @@
|
||||
//! Editing the metadata, the style and the structure of the files.
|
||||
|
||||
use gpx_engine::api;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
use crate::session::*;
|
||||
use crate::ts::Outcome;
|
||||
|
||||
// Edit commands
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn metadata(name: &str, desc: &str) -> Outcome {
|
||||
run(|e| api::metadata(e, name, desc))
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn style(color: Option<String>, opacity: Option<f64>, width: Option<f64>) -> Outcome {
|
||||
run(|e| api::style(e, color.as_deref(), opacity, width))
|
||||
}
|
||||
|
||||
/// Converts the selected routes to tracks, or the selected tracks or segments to routes.
|
||||
#[wasm_bindgen]
|
||||
pub fn convert() -> Outcome {
|
||||
run(api::convert)
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn new_route() -> Outcome {
|
||||
run(api::new_route)
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn new_track() -> Outcome {
|
||||
run(api::new_track)
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn new_track_segment() -> Outcome {
|
||||
run(api::new_track_segment)
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
//! Creating, loading, deleting, moving, copying and pasting files and their elements.
|
||||
|
||||
use gpx_engine::api;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
use crate::convert::*;
|
||||
use crate::ids::*;
|
||||
use crate::session::*;
|
||||
use crate::ts::*;
|
||||
|
||||
// File commands
|
||||
|
||||
/// Creates a file and selects it. With `route`, it starts with a route. With `lng` and `lat`, it
|
||||
/// starts with a segment that holds that trackpoint (at `ele`, 0 by default): the one of its route
|
||||
/// with `route`, of a track otherwise.
|
||||
#[wasm_bindgen]
|
||||
pub fn new_file(
|
||||
name: &str,
|
||||
lng: Option<f64>,
|
||||
lat: Option<f64>,
|
||||
ele: Option<f64>,
|
||||
route: bool,
|
||||
) -> Outcome {
|
||||
run(|e| api::new_file(e, name, lng, lat, ele, route))
|
||||
}
|
||||
|
||||
/// Loads files as a single command (one undo step). The files are in `data`, one after the
|
||||
/// other, `lengths` being the number of bytes of each one. `names`: the name of each file when
|
||||
/// its data has none (the name on disk, without extension). The files that cannot be read are
|
||||
/// skipped, the first one that was read is selected.
|
||||
#[wasm_bindgen]
|
||||
pub fn load_files(data: &[u8], lengths: &[u32], names: Vec<String>) -> Outcome {
|
||||
let lengths: Vec<usize> = lengths.iter().map(|length| *length as usize).collect();
|
||||
run(|e| api::load_files(e, data, &lengths, &names))
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn duplicate() -> Outcome {
|
||||
run(api::duplicate)
|
||||
}
|
||||
|
||||
/// Deletes the selected elements. With `whole_files`, the files holding the selected elements are
|
||||
/// deleted instead, even if only a track or a waypoint is selected.
|
||||
#[wasm_bindgen]
|
||||
pub fn delete(whole_files: bool) -> Outcome {
|
||||
run(|e| api::delete(e, whole_files))
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn delete_all() -> Outcome {
|
||||
run(api::delete_all)
|
||||
}
|
||||
|
||||
/// Moves the files to `index` among the other files, in the given order (not undoable).
|
||||
/// `file_ids_bytes`: concatenated 16-byte UUIDs.
|
||||
#[wasm_bindgen]
|
||||
pub fn reorder(file_ids_bytes: &[u8], index: usize) -> Outcome {
|
||||
match uuid_list(file_ids_bytes) {
|
||||
Some(ids) => run(|e| api::reorder(e, &ids, index)),
|
||||
None => fail("the file ids are not a list of UUIDs"),
|
||||
}
|
||||
}
|
||||
|
||||
// Clipboard
|
||||
|
||||
/// Puts the selected elements in the clipboard. Nothing happens when nothing is selected.
|
||||
#[wasm_bindgen]
|
||||
pub fn copy() -> Outcome {
|
||||
run(api::copy)
|
||||
}
|
||||
|
||||
/// Like `copy`, but the elements are moved when they are pasted.
|
||||
#[wasm_bindgen]
|
||||
pub fn cut() -> Outcome {
|
||||
run(api::cut)
|
||||
}
|
||||
|
||||
/// Pastes the clipboard according to the selection (see `can_paste`). What is pasted is always
|
||||
/// the elements as they were when they were copied or cut, even if they were changed or deleted
|
||||
/// since. It can be pasted several times: what was copied is copied again, what was cut is moved
|
||||
/// the first time (and the clipboard is not cut after that), then it is copied.
|
||||
#[wasm_bindgen]
|
||||
pub fn paste() -> Outcome {
|
||||
run(api::paste)
|
||||
}
|
||||
|
||||
/// Whether the clipboard can be pasted with the current selection.
|
||||
#[wasm_bindgen]
|
||||
pub fn can_paste() -> bool {
|
||||
with_engine(api::can_paste).unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Moves elements (given as a `Selection`) to a place of the file tree, keeping their ids, like
|
||||
/// dragging and dropping them does. The moved elements are selected.
|
||||
///
|
||||
/// Files can only go among the files; tracks among the files (each becomes a file) or the tracks
|
||||
/// of a file; segments among the files (each becomes a file), the tracks of a file (each becomes
|
||||
/// a track) or the segments of a track; waypoints, or all the waypoints of a file, among the
|
||||
/// waypoints of a file.
|
||||
#[wasm_bindgen]
|
||||
pub fn move_elements(what: Selection, to: MoveTarget) -> Outcome {
|
||||
// a negative index is the start, an infinite one is the end
|
||||
match from_js::<api::Selection>(&what).zip(from_js::<api::MoveTarget>(&to)) {
|
||||
Some((what, to)) => run(|e| api::move_elements(e, what, to)),
|
||||
None => fail("the elements or the target are not valid"),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
//! Undo and redo.
|
||||
|
||||
use gpx_engine::api;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
use crate::session::*;
|
||||
use crate::ts::Outcome;
|
||||
|
||||
// Undo-redo
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn undo() -> Outcome {
|
||||
run(api::undo)
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn redo() -> Outcome {
|
||||
run(api::redo)
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn can_undo() -> bool {
|
||||
with_engine(api::can_undo).unwrap_or(false)
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn can_redo() -> bool {
|
||||
with_engine(api::can_redo).unwrap_or(false)
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
pub(crate) mod edit;
|
||||
pub(crate) mod files;
|
||||
pub(crate) mod history;
|
||||
pub(crate) mod routing;
|
||||
pub(crate) mod tools;
|
||||
pub(crate) mod waypoints;
|
||||
@@ -0,0 +1,66 @@
|
||||
//! The commands that refer to trackpoints by their index in the routing buffers.
|
||||
|
||||
use gpx_engine::api;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
use crate::convert::*;
|
||||
use crate::ids::*;
|
||||
use crate::session::*;
|
||||
use crate::ts::*;
|
||||
use crate::types::*;
|
||||
|
||||
// Routing
|
||||
//
|
||||
// The indices of the trackpoints and of the anchors are the ones of the routing buffers: they only
|
||||
// mean something for the `revision` they were read with (`routing_revision`), and the commands
|
||||
// that use them do nothing if the selection is not the one of that revision anymore.
|
||||
|
||||
/// Replaces the trackpoints `start..end` of the selection by the given ones, in a single segment
|
||||
/// (see `RoutingBuffer`). A pure insertion if `start == end`, a pure removal without new points.
|
||||
/// `attributes` holds the surface, highway, SAC scale and MTB scale of the new points, as
|
||||
/// intervals, and `anchors` the indices among the new points of the ones that become anchors.
|
||||
/// Does nothing, and says why, if the revision of the routing buffers is not the given one.
|
||||
#[wasm_bindgen]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn route(
|
||||
revision: u32,
|
||||
start: u32,
|
||||
end: u32,
|
||||
lng: &[f64],
|
||||
lat: &[f64],
|
||||
ele: &[f64],
|
||||
attributes: RouteAttributes,
|
||||
anchors: &[u32],
|
||||
) -> Outcome {
|
||||
let Some(attributes) = from_js::<api::RouteAttributes>(&attributes) else {
|
||||
return fail("the attributes of the route are not valid");
|
||||
};
|
||||
if !same_len(lng, lat, ele) {
|
||||
return fail("lng, lat and ele differ in length");
|
||||
}
|
||||
run(|e| api::route(e, revision, start, end, lng, lat, ele, &attributes, anchors))
|
||||
}
|
||||
|
||||
/// Makes an anchor of the point of the selected segments that is the closest to the coordinates,
|
||||
/// inserting a trackpoint on the path if none is there. Does nothing, and says why, if the
|
||||
/// revision of the routing buffers is not the given one.
|
||||
#[wasm_bindgen]
|
||||
pub fn insert_anchor(revision: u32, lng: f64, lat: f64) -> Outcome {
|
||||
run(|e| api::insert_anchor(e, revision, lng, lat))
|
||||
}
|
||||
|
||||
/// Makes the trackpoint `index` of the selection the start of its segment, which is a loop (the
|
||||
/// trackpoints before it go to the end, and the loop closes on it). Does nothing, and says why, if the revision of the
|
||||
/// routing buffers is not the given one.
|
||||
#[wasm_bindgen]
|
||||
pub fn change_loop_start(revision: u32, index: u32) -> Outcome {
|
||||
run(|e| api::change_loop_start(e, revision, index))
|
||||
}
|
||||
|
||||
/// Cuts the file, the track or the segment (see `SplitType`) of the trackpoint `at` of the
|
||||
/// selection in two, there: the trackpoint ends the first part and starts the second one. Does
|
||||
/// nothing, and returns false, if the revision of the routing buffers is not the given one.
|
||||
#[wasm_bindgen]
|
||||
pub fn split(revision: u32, at: u32, split_type: SplitType) -> Outcome {
|
||||
run(|e| api::split(e, revision, at, split_type.into()))
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
//! The tools: reversing, cropping, reducing, timestamps, merging, cleaning...
|
||||
|
||||
use gpx_engine::api;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
use crate::ts::Outcome;
|
||||
|
||||
use crate::session::*;
|
||||
use crate::types::*;
|
||||
|
||||
// Tools
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn reverse() -> Outcome {
|
||||
run(api::reverse)
|
||||
}
|
||||
|
||||
/// Adds to each selected segment a reversed copy of itself (without repeating its last point), so that it goes back to where it
|
||||
/// started.
|
||||
#[wasm_bindgen]
|
||||
pub fn round_trip() -> Outcome {
|
||||
run(api::round_trip)
|
||||
}
|
||||
|
||||
/// Keeps the trackpoints `start` to `end` (both included) of the selection, counted over its
|
||||
/// segments one after the other, and removes the others (and what is left empty).
|
||||
#[wasm_bindgen]
|
||||
pub fn crop(start: u32, end: u32) -> Outcome {
|
||||
run(|e| api::crop(e, start, end))
|
||||
}
|
||||
|
||||
/// Removes the trackpoints of the selection that are less than `tolerance` meters away from the
|
||||
/// line of their neighbours, except the ends of the segments.
|
||||
#[wasm_bindgen]
|
||||
pub fn reduce(tolerance: f64) -> Outcome {
|
||||
run(|e| api::reduce(e, tolerance))
|
||||
}
|
||||
|
||||
/// Sets the timestamps of the selection, which starts at `start_time` (ms since the epoch): the
|
||||
/// trackpoints that have some keep their durations multiplied by `ratio`, the others follow the
|
||||
/// previous one at `speed` (km/h).
|
||||
#[wasm_bindgen(js_name = changeTimestamps)]
|
||||
pub fn change_timestamps(start_time: f64, speed: f64, ratio: f64) -> Outcome {
|
||||
run(|e| api::change_timestamps(e, start_time, speed, ratio))
|
||||
}
|
||||
|
||||
/// Makes up timestamps for the selection, which starts at `start_time` (ms since the epoch) and
|
||||
/// lasts `total_time` seconds.
|
||||
#[wasm_bindgen(js_name = createArtificialTimestamps)]
|
||||
pub fn create_artificial_timestamps(start_time: f64, total_time: f64) -> Outcome {
|
||||
run(|e| api::create_artificial_timestamps(e, start_time, total_time))
|
||||
}
|
||||
|
||||
/// Merges the selection into its first element (see `MergeType`). `remove_gaps` brings the parts
|
||||
/// that are connected closer in time, if they have timestamps.
|
||||
#[wasm_bindgen]
|
||||
pub fn merge(type_: MergeType, remove_gaps: bool) -> Outcome {
|
||||
run(|e| api::merge(e, type_.into(), remove_gaps))
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn extract() -> Outcome {
|
||||
run(api::extract)
|
||||
}
|
||||
|
||||
/// Sets the elevation of the trackpoints of the selection, one elevation per trackpoint.
|
||||
#[wasm_bindgen]
|
||||
pub fn elevation(ele: &[f64]) -> Outcome {
|
||||
run(|e| api::elevation(e, ele))
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn clean(
|
||||
west: f64,
|
||||
south: f64,
|
||||
east: f64,
|
||||
north: f64,
|
||||
type_: CleanType,
|
||||
trkpt: bool,
|
||||
wpt: bool,
|
||||
) -> Outcome {
|
||||
run(|e| api::clean(e, west, south, east, north, type_.into(), trkpt, wpt))
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
//! Creating, editing, moving and deleting waypoints.
|
||||
|
||||
use gpx_engine::api;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
use crate::ts::Outcome;
|
||||
|
||||
use crate::ids::*;
|
||||
use crate::session::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn new_waypoint(
|
||||
lng: f64,
|
||||
lat: f64,
|
||||
ele: f64,
|
||||
name: &str,
|
||||
desc: &str,
|
||||
icon: &str,
|
||||
link: &str,
|
||||
) -> Outcome {
|
||||
run(|e| api::new_waypoint(e, lng, lat, ele, name, desc, icon, link))
|
||||
}
|
||||
|
||||
/// Moves a waypoint of a file, whatever is selected.
|
||||
#[wasm_bindgen]
|
||||
pub fn move_waypoint(file_id: &str, waypoint_id: &str, lng: f64, lat: f64, ele: f64) -> Outcome {
|
||||
match parse_uuid(file_id).zip(parse_uuid(waypoint_id)) {
|
||||
Some((file_id, waypoint_id)) => {
|
||||
run(|e| api::move_waypoint(e, file_id, waypoint_id, lng, lat, ele))
|
||||
}
|
||||
None => fail("the file or waypoint id is not a UUID"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Deletes a waypoint of a file, whatever is selected.
|
||||
#[wasm_bindgen]
|
||||
pub fn delete_waypoint(file_id: &str, waypoint_id: &str) -> Outcome {
|
||||
match parse_uuid(file_id).zip(parse_uuid(waypoint_id)) {
|
||||
Some((file_id, waypoint_id)) => run(|e| api::delete_waypoint(e, file_id, waypoint_id)),
|
||||
None => fail("the file or waypoint id is not a UUID"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Changes a waypoint of a file, whatever is selected: its name, description, icon, link, position
|
||||
/// and elevation. The strings that are empty remove the field.
|
||||
#[wasm_bindgen]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn update_waypoint(
|
||||
file_id: &str,
|
||||
waypoint_id: &str,
|
||||
lng: f64,
|
||||
lat: f64,
|
||||
ele: f64,
|
||||
name: &str,
|
||||
desc: &str,
|
||||
icon: &str,
|
||||
link: &str,
|
||||
) -> Outcome {
|
||||
match parse_uuid(file_id).zip(parse_uuid(waypoint_id)) {
|
||||
Some((file_id, waypoint_id)) => run(|e| {
|
||||
api::update_waypoint(
|
||||
e,
|
||||
file_id,
|
||||
waypoint_id,
|
||||
lng,
|
||||
lat,
|
||||
ele,
|
||||
name,
|
||||
desc,
|
||||
icon,
|
||||
link,
|
||||
)
|
||||
}),
|
||||
None => fail("the file or waypoint id is not a UUID"),
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user