Skip to content

Commit

Permalink
Contours imperial preview working
Browse files Browse the repository at this point in the history
  • Loading branch information
pierotofy committed May 9, 2024
1 parent 75678b7 commit d76eaca
Show file tree
Hide file tree
Showing 6 changed files with 242 additions and 62 deletions.
8 changes: 8 additions & 0 deletions app/static/app/js/classes/Storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ class Storage{
console.warn("Failed to call setItem " + key, e);
}
}

static removeItem(key){
try{
localStorage.removeItem(key);
}catch(e){
console.warn("Failed to call removeItem " + key, e);
}
}
}

export default Storage;
155 changes: 126 additions & 29 deletions app/static/app/js/classes/Units.js
Original file line number Diff line number Diff line change
@@ -1,112 +1,156 @@
import { _ } from './gettext';

const types = {
LENGTH: 1,
AREA: 2,
VOLUME: 3
};

const units = {
acres: {
factor: (1 / (0.3048 * 0.3048)) / 43560,
abbr: 'ac',
round: 5
round: 5,
label: _("Acres"),
type: types.AREA
},
acres_us: {
factor: Math.pow(3937 / 1200, 2) / 43560,
abbr: 'ac (US)',
round: 5
round: 5,
label: _("Acres"),
type: types.AREA
},
feet: {
factor: 1 / 0.3048,
abbr: 'ft',
round: 4
round: 4,
label: _("Feet"),
type: types.LENGTH
},
feet_us:{
factor: 3937 / 1200,
abbr: 'ft (US)',
round: 4
round: 4,
label: _("Feet"),
type: types.LENGTH
},
hectares: {
factor: 0.0001,
abbr: 'ha',
round: 4
round: 4,
label: _("Hectares"),
type: types.AREA
},
meters: {
factor: 1,
abbr: 'm',
round: 3
round: 3,
label: _("Meters"),
type: types.LENGTH
},
kilometers: {
factor: 0.001,
abbr: 'km',
round: 5
round: 5,
label: _("Kilometers"),
type: types.LENGTH
},
centimeters: {
factor: 100,
abbr: 'cm',
round: 1
round: 1,
label: _("Centimeters"),
type: types.LENGTH
},
miles: {
factor: (1 / 0.3048) / 5280,
abbr: 'mi',
round: 5
},
round: 5,
label: _("Miles"),
type: types.LENGTH
},
miles_us: {
factor: (3937 / 1200) / 5280,
abbr: 'mi (US)',
round: 5
round: 5,
label: _("Miles"),
type: types.LENGTH
},
sqfeet: {
factor: 1 / (0.3048 * 0.3048),
abbr: 'ft²',
round: 2
round: 2,
label: _("Squared Feet"),
type: types.AREA
},
sqfeet_us: {
factor: Math.pow(3937 / 1200, 2),
abbr: 'ft² (US)',
round: 2
round: 2,
label: _("Squared Feet"),
type: types.AREA
},
sqmeters: {
factor: 1,
abbr: 'm²',
round: 2
round: 2,
label: _("Squared Meters"),
type: types.AREA
},
sqkilometers: {
factor: 0.000001,
abbr: 'km²',
round: 5
round: 5,
label: _("Squared Kilometers"),
type: types.AREA
},
sqmiles: {
factor: Math.pow((1 / 0.3048) / 5280, 2),
abbr: 'mi²',
round: 5
round: 5,
label: _("Squared Miles"),
type: types.AREA
},
sqmiles_us: {
factor: Math.pow((3937 / 1200) / 5280, 2),
abbr: 'mi² (US)',
round: 5
round: 5,
label: _("Squared Miles"),
type: types.AREA
},
cbmeters:{
factor: 1,
abbr: 'm³',
round: 4
round: 4,
label: _("Cubic Meters"),
type: types.VOLUME
},
cbyards:{
factor: Math.pow(1/(0.3048*3), 3),
abbr: 'yd³',
round: 4
round: 4,
label: _("Cubic Yards"),
type: types.VOLUME
},
cbyards_us:{
factor: Math.pow(3937/3600, 3),
abbr: 'yd³ (US)',
round: 4
round: 4,
label: _("Cubic Yards"),
type: types.VOLUME
}
};

class ValueUnit{
constructor(val, unit){
this.val = val;
constructor(value, unit){
this.value = value;
this.unit = unit;
}

toString(){
const mul = Math.pow(10, this.unit.round);
const rounded = (Math.round(this.val * mul) / mul).toString();
const rounded = (Math.round(this.value * mul) / mul).toString();

let withCommas = "";
let parts = rounded.split(".");
Expand All @@ -117,6 +161,12 @@ class ValueUnit{
}
}

class NanUnit{
toString(){
return "NaN";
}
}

class UnitSystem{
lengthUnit(meters){ throw new Error("Not implemented"); }
areaUnit(sqmeters){ throw new Error("Not implemented"); }
Expand All @@ -125,24 +175,55 @@ class UnitSystem{
getName(){ throw new Error("Not implemented"); }

area(sqmeters){
sqmeters = parseFloat(sqmeters);
if (isNaN(sqmeters)) return NanUnit();

const unit = this.areaUnit(sqmeters);
const val = unit.factor * sqmeters;
return new ValueUnit(val, unit);
}

length(meters){
meters = parseFloat(meters);
if (isNaN(meters)) return NanUnit();

const unit = this.lengthUnit(meters);
const val = unit.factor * meters;
return new ValueUnit(val, unit);
}

volume(cbmeters){
cbmeters = parseFloat(cbmeters);
if (isNaN(cbmeters)) return NanUnit();

const unit = this.volumeUnit(cbmeters);
const val = unit.factor * cbmeters;
return new ValueUnit(val, unit);
}
};

function toMetric(valueUnit, unit){
let value = NaN;
if (typeof valueUnit === "object" && unit === undefined){
value = valueUnit.value;
unit = valueUnit.unit;
}else{
value = parseFloat(valueUnit);
}
if (isNaN(value)) return NanUnit();

const val = value / unit.factor;
if (unit.type === types.LENGTH){
return new ValueUnit(val, units.meters);
}else if (unit.type === types.AREA){
return new ValueUnit(val, unit.sqmeters);
}else if (unit.type === types.VOLUME){
return new ValueUnit(val, unit.cbmeters);
}else{
throw new Error(`Unrecognized unit type: ${unit.type}`);
}
}

class MetricSystem extends UnitSystem{
getName(){
return _("Metric");
Expand Down Expand Up @@ -249,16 +330,32 @@ const systems = {
}

// Expose to allow every part of the app to access this information
function getPreferredUnitSystem(){
return localStorage.getItem("preferred_unit_system") || "metric";
function getUnitSystem(){
return localStorage.getItem("_unit_system") || "metric";
}
function setPreferredUnitSystem(system){
localStorage.setItem("preferred_unit_system", system);
function setUnitSystem(system){
let prevSystem = getUnitSystem();
localStorage.setItem("_unit_system", system);
if (prevSystem !== system){
document.dispatchEvent(new CustomEvent("onUnitSystemChanged", { detail: system }));
}
}

function onUnitSystemChanged(callback){
document.addEventListener("onUnitSystemChanged", callback);
}

function offUnitSystemChanged(callback){
document.removeEventListener("onUnitSystemChanged", callback);
}

export {
systems,
getPreferredUnitSystem,
setPreferredUnitSystem
types,
toMetric,
getUnitSystem,
setUnitSystem,
onUnitSystemChanged,
offUnitSystemChanged
};

6 changes: 3 additions & 3 deletions app/static/app/js/components/UnitSelector.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { systems, getPreferredUnitSystem, setPreferredUnitSystem } from '../classes/Units';
import { systems, getUnitSystem, setUnitSystem } from '../classes/Units';
import '../css/UnitSelector.scss';

class UnitSelector extends React.Component {
Expand All @@ -11,13 +11,13 @@ class UnitSelector extends React.Component {
super(props);

this.state = {
system: getPreferredUnitSystem()
system: getUnitSystem()
}
}

handleChange = e => {
this.setState({system: e.target.value});
setPreferredUnitSystem(e.target.value);
setUnitSystem(e.target.value);
};

render() {
Expand Down
26 changes: 23 additions & 3 deletions app/static/app/js/components/tests/Units.test.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { systems } from '../../classes/Units';
import { systems, toMetric } from '../../classes/Units';

describe('Metric system', () => {
it('it should display units properly', () => {
Expand Down Expand Up @@ -94,5 +94,25 @@ describe('Imperial systems', () => {
expect(imperial.volume(v[0]).toString()).toBe(v[1]);
expect(imperialUS.volume(v[0]).toString()).toBe(v[2]);
});
})
});
});
});

describe('Metric conversion', () => {
it('it should convert units properly', () => {
const { metric, imperial } = systems;

const km = metric.length(2000);
const mi = imperial.length(3220);

expect(km.unit.abbr).toBe("km");
expect(km.value).toBe(2);
expect(mi.unit.abbr).toBe("mi");
expect(Math.round(mi.value)).toBe(2)

expect(toMetric(km).toString()).toBe("2,000 m");
expect(toMetric(mi).toString()).toBe("3,220 m");

expect(toMetric(km).value).toBe(2000);
expect(toMetric(mi).value).toBe(3220);
});
});
4 changes: 2 additions & 2 deletions coreplugins/contours/manifest.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"name": "Contours",
"webodmMinVersion": "0.9.0",
"webodmMinVersion": "2.4.3",
"description": "Compute, preview and export contours from DEMs",
"version": "1.0.0",
"version": "1.1.0",
"author": "Piero Toffanin",
"email": "[email protected]",
"repository": "https://github.com/OpenDroneMap/WebODM",
Expand Down
Loading

0 comments on commit d76eaca

Please sign in to comment.