Skip to content

Commit

Permalink
wasm + html demo: add click to measure functionality
Browse files Browse the repository at this point in the history
Signed-off-by: Baptiste Prevot <pro.baptiste.prevot@gmail.com>
  • Loading branch information
Castavo committed Oct 18, 2024
1 parent 04d4cc9 commit 45d7e6f
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 10 deletions.
55 changes: 48 additions & 7 deletions wasm/html_demo/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
'use strict';
import 'maplibre-gl/dist/maplibre-gl.css';
import Bbox from '@turf/bbox';
import * as turf from '@turf/helpers';
import Alpine from 'alpinejs';
import * as maplibregl from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';
import { Protocol } from 'pmtiles';
import { Lrs, LrmScaleMeasure, set_panic_hook } from '../pkg/liblrs_wasm';
import * as turf from '@turf/helpers';
import Bbox from '@turf/bbox'
import Alpine from 'alpinejs'
import { LrmScaleMeasure, Lrs, Point, set_panic_hook } from '../pkg/liblrs_wasm';

// For the rust bindings: this allows us to have nice error messages
set_panic_hook()
Expand Down Expand Up @@ -65,6 +65,17 @@ async function file_selected(el) {
}
});


map.addLayer({
'id': 'lrms-hitbox',
'type': 'line',
'source': 'lrms',
'paint': {
'line-width': 10,
'line-opacity': 0
}
});

map.addLayer({
'id': 'lrms-hover',
'type': 'line',
Expand Down Expand Up @@ -156,6 +167,34 @@ async function file_selected(el) {
}
});



map.on('mouseenter', 'lrms-hitbox', () => {
map.getCanvas().style.cursor = 'pointer'
})
map.on('mouseleave', 'lrms-hitbox', () => {
map.getCanvas().style.cursor = ''
})


map.on('click', 'lrms-hitbox', (e) => {

let lrm_id = e.features[0].id;
let clicked_point = new Point(e.lngLat.lng, e.lngLat.lat);

let projection = lrs.lookup(clicked_point, lrm_id)[0];

let window_lrms = window.Alpine.store('lrms')

window_lrms.selectedFeature = curves_features[lrm_id];
window_lrms.pkStart = projection.measure.anchor_name + '+' + Math.round(projection.measure.scale_offset);

window_lrms.startMeasure = projection.measure;
let point = lrs.resolve(lrm_id, projection.measure)
window_lrms.pkStartPoint = turf.point([point.x, point.y]);
window_lrms.handlePks(false)
});

return {
features: curves_features,
filename: file.name,
Expand Down Expand Up @@ -271,12 +310,14 @@ Alpine.store('lrms', {
this.endMeasure = null;
}
},
handlePks() {
handlePks(move_window = true) {
const points = [this.pkStartPoint, this.pkEndPoint].filter(p => p !== null)
const geojson = turf.featureCollection(points);
map.getSource('pr').setData(geojson);
if (points.length === 1) {
map.flyTo({ center: points[0].geometry.coordinates, zoom: 15 })
if (move_window) {
map.flyTo({ center: points[0].geometry.coordinates, zoom: 15 })
}
} else {
map.fitBounds(Bbox(geojson), { padding: 30 })
const range = this.lrs.resolve_range(this.selectedFeature.id, this.startMeasure, this.endMeasure)
Expand Down
52 changes: 49 additions & 3 deletions wasm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
//! High level extensions meant for an easy usage
//! Those functions are exposed in wasm-bindings
use liblrs::lrs_ext::*;
use liblrs::{
lrs::{LrmHandle, LrsBase},
lrs_ext::*,
};
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
Expand All @@ -20,6 +23,15 @@ pub struct Point {
pub y: f64,
}

#[wasm_bindgen]
impl Point {
/// Build a new [`LrmMeasure`] from an [`Anchor`] `name` and the `offset` on the [`LrmScale`].
#[wasm_bindgen(constructor)]
pub fn new(x: f64, y: f64) -> Self {
Self { x, y }
}
}

impl From<geo_types::Point> for Point {
fn from(value: geo_types::Point) -> Self {
Self {
Expand All @@ -29,6 +41,12 @@ impl From<geo_types::Point> for Point {
}
}

impl From<Point> for geo_types::Point<f64> {
fn from(value: Point) -> Self {
Self::new(value.x, value.y)
}
}

impl From<geo_types::Coord> for Point {
fn from(value: geo_types::Coord) -> Self {
Self {
Expand All @@ -39,12 +57,13 @@ impl From<geo_types::Coord> for Point {
}

#[wasm_bindgen(getter_with_clone)]
#[derive(Clone)]
/// Represent a position on an [`LrmScale`] relative as an `offset` to an [`Anchor`].
pub struct LrmScaleMeasure {
/// `name` of the reference [`Anchor`].
anchor_name: String,
pub anchor_name: String,
/// `offset` to the reference [`Anchor`].
scale_offset: f64,
pub scale_offset: f64,
}

#[wasm_bindgen]
Expand Down Expand Up @@ -102,6 +121,15 @@ impl From<&liblrs::lrm_scale::Anchor> for Anchor {
}
}

#[wasm_bindgen(getter_with_clone)]
/// The result of a projection onto an [`LrmScale`].
pub struct LrmProjection {
/// Contains `measure` ([`LrmScaleMeasure`]) and `lrm` ([`LrmHandle`]).
pub measure: LrmScaleMeasure,
/// How far from the [`Lrm`] is the [`Point`] that has been projected.
pub orthogonal_offset: f64,
}

#[wasm_bindgen]
impl Lrs {
/// Load the data.
Expand Down Expand Up @@ -155,6 +183,24 @@ impl Lrs {
.resolve_range(lrm_index, &from.into(), &to.into())
.map(|coords| coords.into_iter().map(|coord| coord.into()).collect())
}

/// Projects a [`Point`] on all applicable [`Traversal`]s to a given [`Lrm`].
/// The [`Point`] must be in the bounding box of the [`Curve`] of the [`Traversal`].
/// The result is sorted by `orthogonal_offset`: the nearest [`Lrm`] to the [`Point`] is the first item.
pub fn lookup(&self, point: Point, lrm_handle: usize) -> Vec<LrmProjection> {
self.lrs
.lrs
.lookup(point.into(), LrmHandle(lrm_handle))
.iter()
.map(|p| LrmProjection {
measure: LrmScaleMeasure {
anchor_name: p.measure.measure.anchor_name.to_owned(),
scale_offset: p.measure.measure.scale_offset,
},
orthogonal_offset: p.orthogonal_offset,
})
.collect()
}
}

#[wasm_bindgen]
Expand Down

0 comments on commit 45d7e6f

Please sign in to comment.