Skip to content

Commit

Permalink
Manually save state
Browse files Browse the repository at this point in the history
  • Loading branch information
dabreegster committed Dec 29, 2023
1 parent e7a1561 commit db92157
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 13 deletions.
9 changes: 7 additions & 2 deletions backend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,7 @@ impl LTN {
/// Takes a LineString feature
#[wasm_bindgen(js_name = addManyModalFilters)]
pub fn add_many_modal_filters(&mut self, input: JsValue) -> Result<String, JsValue> {
info!("parse it");
let gj: Feature = serde_wasm_bindgen::from_value(input)?;
info!("make it geo");
let mut linestring: LineString = gj.try_into().map_err(err_to_js)?;
self.map.mercator.to_mercator_in_place(&mut linestring);

Expand Down Expand Up @@ -176,6 +174,13 @@ impl LTN {
))
.map_err(err_to_js)?)
}

/// GJ with modal filters and optionally the neighbourhood boundary
#[wasm_bindgen(js_name = toSavefile)]
pub fn to_savefile(&self) -> Result<String, JsValue> {
// TODO Trim coordinates... in mercator?
Ok(serde_json::to_string(&self.map.to_savefile(self.neighbourhood.as_ref())).map_err(err_to_js)?)
}
}

#[derive(Deserialize)]
Expand Down
31 changes: 28 additions & 3 deletions backend/src/map_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ use std::fmt;

use anyhow::Result;
use geo::{
Closest, ClosestPoint, Coord, EuclideanLength, Intersects, Line, LineIntersection,
LineInterpolatePoint, Closest, ClosestPoint, Coord, EuclideanLength, Intersects, Line, LineIntersection,
LineLocatePoint, LineString, Point,
};
use geojson::{Feature, Geometry};
use geojson::{Feature, Geometry, GeoJson};
use serde::Serialize;

use crate::{Mercator, Tags};
use crate::{Mercator, Tags, Neighbourhood};

pub struct MapModel {
pub roads: Vec<Road>,
Expand Down Expand Up @@ -173,6 +173,31 @@ impl MapModel {
let cmd = self.do_edit(cmd);
self.undo_stack.push(cmd);
}

pub fn to_savefile(&self, neighbourhood: Option<&Neighbourhood>) -> GeoJson {
let mut features = Vec::new();

// A point per modal filter
// (When we detect existing, maybe need to instead compact edits)
for (r, modal_filter) in &self.modal_filters {
let pt = self
.get_r(*r)
.linestring
.line_interpolate_point(modal_filter.percent_along)
.unwrap();
let mut f = Feature::from(Geometry::from(&self.mercator.to_wgs84(&pt)));
f.set_property("kind", "modal_filter");
features.push(f);
}

if let Some(neighbourhood) = neighbourhood {
let mut f = Feature::from(Geometry::from(&self.mercator.to_wgs84(&neighbourhood.boundary_polygon)));
f.set_property("kind", "boundary");
features.push(f);
}

GeoJson::from(features)
}
}

impl Road {
Expand Down
12 changes: 6 additions & 6 deletions web/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,9 @@
let map: Map;
function zoomToFit() {
if (map && app) {
// TODO wasteful
let bbox = turfBbox(JSON.parse(app.render()));
map.fitBounds(bbox, { animate: false });
}
// TODO wasteful
let bbox = turfBbox(JSON.parse(app.render()));
map.fitBounds(bbox, { animate: false });
}
function gotApp(_x: LTN) {
Expand Down Expand Up @@ -83,8 +81,10 @@
<div slot="left">
{#if map}
<MapLoader {map} bind:app />
{#if app}
<div><button on:click={zoomToFit}>Zoom to fit</button></div>
{/if}
{/if}
<div><button on:click={zoomToFit}>Zoom to fit</button></div>
<div>
<label
><input type="checkbox" bind:checked={showBasemap} />Show basemap</label
Expand Down
13 changes: 11 additions & 2 deletions web/src/MapLoader.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import type { Map } from "maplibre-gl";
import init2 from "route-snapper";
import { onMount } from "svelte";
import { Loading, OverpassSelector } from "./common";
import { downloadGeneratedFile, Loading, OverpassSelector } from "./common";
export let app: LTN | undefined = undefined;
export let map: Map;
Expand All @@ -23,7 +23,7 @@
console.log("Using local cache, not od2net.org");
// For quicker dev
loadExample("bristol");
example = "bristol";
} catch (err) {}
});
Expand Down Expand Up @@ -79,6 +79,11 @@
}
msg = null;
}
function saveGj() {
let filename = example || "custom";
downloadGeneratedFile(`ltn_${filename}.geojson`, app.toSavefile());
}
</script>

<Loading {msg} />
Expand Down Expand Up @@ -117,4 +122,8 @@
on:loading={(e) => (msg = e.detail)}
on:error={(e) => window.alert(e.detail)}
/>

{#if app}
<div><button on:click={saveGj}>Save to GJ</button></div>
{/if}
</div>
12 changes: 12 additions & 0 deletions web/src/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,15 @@ export function makeColorRamp(
step.push(colorScale[colorScale.length - 1]);
return step as DataDrivenPropertyValueSpecification<string>;
}

export function downloadGeneratedFile(filename: string, textInput: string) {
let element = document.createElement("a");
element.setAttribute(
"href",
"data:text/plain;charset=utf-8, " + encodeURIComponent(textInput)
);
element.setAttribute("download", filename);
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
}

0 comments on commit db92157

Please sign in to comment.