mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2026-10-27 02:27:18 +00:00
route full support
This commit is contained in:
1 parent
c842da8dc1
commit
b6c0f5190a
91 files changed
+2523
-847
No files matched your search
@@ -18,6 +18,11 @@ pub fn style(color: Option<String>, opacity: Option<f64>, width: Option<f64>) ->
|
||||
run(|e| api::style(e, color.as_deref(), opacity, width))
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn new_route() -> Outcome {
|
||||
run(api::new_route)
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn new_track() -> Outcome {
|
||||
run(api::new_track)
|
||||
|
||||
@@ -45,10 +45,8 @@ pub fn selection_statistics() -> GlobalStatistics {
|
||||
}
|
||||
|
||||
/// A file as GPX (UTF-8 bytes), `undefined` if it does not exist. The options say which data of the trackpoints
|
||||
/// to keep, and with `as_route` that the segments are written as routes (`rte`) instead of tracks:
|
||||
/// the anchors are the route points, and the trackpoints between them the points of their path.
|
||||
/// to keep.
|
||||
#[wasm_bindgen]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn export_file(
|
||||
file_id: &str,
|
||||
time: bool,
|
||||
@@ -57,7 +55,6 @@ pub fn export_file(
|
||||
atemp: bool,
|
||||
power: bool,
|
||||
osm: bool,
|
||||
as_route: bool,
|
||||
) -> Option<Vec<u8>> {
|
||||
let id = parse_uuid(file_id)?;
|
||||
let options = ExportOptions {
|
||||
@@ -67,7 +64,6 @@ pub fn export_file(
|
||||
atemp,
|
||||
power,
|
||||
osm,
|
||||
as_route,
|
||||
};
|
||||
with_engine(|e| api::export_file(e, id, options)).flatten()
|
||||
}
|
||||
|
||||
@@ -41,6 +41,14 @@ pub fn arrow_select(down: bool, add: bool) -> Outcome {
|
||||
// with the selection when it holds elements of the same kind in the same place (same file, same
|
||||
// track for segments), otherwise they replace it.
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn select_routes(file_id: &str, route_ids_bytes: &[u8], mode: SelectMode) -> Outcome {
|
||||
match parse_uuid(file_id).zip(uuid_list(route_ids_bytes)) {
|
||||
Some((file_id, ids)) => run(|e| api::select_routes(e, file_id, &ids, mode.into())),
|
||||
None => fail("the ids are not UUIDs"),
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn select_tracks(file_id: &str, track_ids_bytes: &[u8], mode: SelectMode) -> Outcome {
|
||||
match parse_uuid(file_id).zip(uuid_list(track_ids_bytes)) {
|
||||
|
||||
+10
-14
@@ -16,6 +16,7 @@ use crate::types::*;
|
||||
const SIMPLE: &[u8] = include_bytes!("../../gpx-rs/data/simple.gpx");
|
||||
const WITH_TIME: &[u8] = include_bytes!("../../gpx-rs/data/with_time.gpx");
|
||||
const WITH_SURFACE: &[u8] = include_bytes!("../../gpx-rs/data/with_surface.gpx");
|
||||
const WITH_ROUTES: &[u8] = include_bytes!("../../gpx-rs/data/with_routes.gpx");
|
||||
|
||||
thread_local! {
|
||||
static LAST: std::cell::RefCell<JsValue> = const { std::cell::RefCell::new(JsValue::UNDEFINED) };
|
||||
@@ -112,10 +113,7 @@ fn test_unknown_file_has_no_structure() {
|
||||
assert!(crate::queries::files::file_structure(&id).is_undefined());
|
||||
assert!(crate::queries::files::file_structure("not an id").is_undefined());
|
||||
assert!(crate::queries::files::file_statistics(&id).is_undefined());
|
||||
assert!(
|
||||
crate::queries::files::export_file(&id, true, true, true, true, true, true, false)
|
||||
.is_none()
|
||||
);
|
||||
assert!(crate::queries::files::export_file(&id, true, true, true, true, true, true).is_none());
|
||||
assert_eq!(
|
||||
crate::queries::coordinates::segment_coordinates(&id).length(),
|
||||
0
|
||||
@@ -279,8 +277,7 @@ fn test_export_and_exportable_data() {
|
||||
let ids = order();
|
||||
|
||||
let bytes =
|
||||
crate::queries::files::export_file(&ids[0], true, true, true, true, true, true, false)
|
||||
.unwrap();
|
||||
crate::queries::files::export_file(&ids[0], true, true, true, true, true, true).unwrap();
|
||||
assert!(String::from_utf8(bytes).unwrap().contains("<gpx"));
|
||||
|
||||
// the time is the first bit
|
||||
@@ -300,18 +297,17 @@ fn test_export_and_exportable_data() {
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn test_export_as_route() {
|
||||
started_with(&[(SIMPLE, "plain")]);
|
||||
let id = order().remove(0);
|
||||
let text = |as_route| {
|
||||
fn test_export_tracks_and_routes() {
|
||||
started_with(&[(SIMPLE, "track"), (WITH_ROUTES, "routes")]);
|
||||
let text = |id: &str| {
|
||||
let bytes =
|
||||
crate::queries::files::export_file(&id, true, true, true, true, true, true, as_route)
|
||||
.unwrap();
|
||||
crate::queries::files::export_file(id, true, true, true, true, true, true).unwrap();
|
||||
String::from_utf8(bytes).unwrap()
|
||||
};
|
||||
let tracks = text(false);
|
||||
let ids = order();
|
||||
let tracks = text(&ids[0]);
|
||||
assert!(tracks.contains("<trk>") && !tracks.contains("<rte>"));
|
||||
let routes = text(true);
|
||||
let routes = text(&ids[1]);
|
||||
assert!(routes.contains("<rte>") && !routes.contains("<trk>"));
|
||||
assert!(routes.contains("<rtept"));
|
||||
}
|
||||
|
||||
+18
-5
@@ -28,16 +28,19 @@ const FILE_STRUCTURE_TS: &str = r#"
|
||||
export type Selection =
|
||||
| { type: 'empty' }
|
||||
| { type: 'file'; fileIds: string[] }
|
||||
| { type: 'route'; fileId: string; routeIds: string[] }
|
||||
| { type: 'track'; fileId: string; trackIds: string[] }
|
||||
| { type: 'segment'; fileId: string; trackId: string; segmentIds: string[] }
|
||||
| { type: 'waypoints'; fileId: string }
|
||||
| { type: 'waypoint'; fileId: string; waypointIds: string[] };
|
||||
/**
|
||||
* Where moved elements go: a list of the file tree and the position in it, counted among the
|
||||
* elements of the list that are not moved.
|
||||
* elements of the list that are not moved. Routes and tracks keep their kind: moved among the
|
||||
* other kind, routes go after the routes, tracks before the tracks.
|
||||
*/
|
||||
export type MoveTarget =
|
||||
| { type: 'files'; index: number }
|
||||
| { type: 'routes'; fileId: string; index: number }
|
||||
| { type: 'tracks'; fileId: string; index: number }
|
||||
| { type: 'segments'; fileId: string; trackId: string; index: number }
|
||||
| { type: 'waypoints'; fileId: string; index: number };
|
||||
@@ -83,7 +86,7 @@ export interface SelectionPoint {
|
||||
}
|
||||
/** What was copied or cut, to be pasted: the kind of the elements and their ids. */
|
||||
export interface Clipboard {
|
||||
type: 'files' | 'tracks' | 'segments' | 'waypoints';
|
||||
type: 'files' | 'routes' | 'tracks' | 'segments' | 'waypoints';
|
||||
ids: string[];
|
||||
cut: boolean;
|
||||
}
|
||||
@@ -119,6 +122,8 @@ export interface FileStructure {
|
||||
id: string;
|
||||
name: string;
|
||||
desc?: string;
|
||||
/** The routes come before the tracks, in the file and in the statistics. */
|
||||
routes: RouteNode[];
|
||||
tracks: TrackNode[];
|
||||
waypoints: WaypointNode[];
|
||||
/** Changes when the waypoints of the file change: refetch their coordinates. */
|
||||
@@ -146,14 +151,22 @@ export interface GlobalStatistics {
|
||||
/** Absent when there are no trackpoints. */
|
||||
bounds?: { west: number; south: number; east: number; north: number };
|
||||
}
|
||||
export interface TrackNode {
|
||||
id: string;
|
||||
/** The name, description and style of a route or a track. */
|
||||
export interface PathInfo {
|
||||
name?: string;
|
||||
desc?: string;
|
||||
/** Style of the track, only present when the file defines it. */
|
||||
/** Style, only present when the file defines it. */
|
||||
color?: string;
|
||||
opacity?: number;
|
||||
width?: number;
|
||||
}
|
||||
/** A route: like a track, with a single segment. */
|
||||
export interface RouteNode extends PathInfo {
|
||||
id: string;
|
||||
segment: SegmentNode;
|
||||
}
|
||||
export interface TrackNode extends PathInfo {
|
||||
id: string;
|
||||
segments: SegmentNode[];
|
||||
}
|
||||
export interface SegmentNode {
|
||||
|
||||
@@ -15,6 +15,7 @@ pub enum MergeType {
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum SplitType {
|
||||
Files,
|
||||
Routes,
|
||||
Tracks,
|
||||
Segments,
|
||||
}
|
||||
@@ -23,6 +24,7 @@ impl From<SplitType> for engine::SplitType {
|
||||
fn from(t: SplitType) -> Self {
|
||||
match t {
|
||||
SplitType::Files => Self::Files,
|
||||
SplitType::Routes => Self::Routes,
|
||||
SplitType::Tracks => Self::Tracks,
|
||||
SplitType::Segments => Self::Segments,
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user