Added some new geo math utilities

This commit is contained in:
Zakary Timson 2019-08-30 14:09:09 -04:00
parent b1b0cfabe1
commit 6eaf84d9e2
3 changed files with 38 additions and 15 deletions

View File

@ -10,7 +10,7 @@ export class DimensionsDialogComponent {
dimensionsOut: number[];
constructor(private ref: MatDialogRef<DimensionsDialogComponent>, @Inject(MAT_DIALOG_DATA) public dimensions: string[]) {
this.dimensionsOut = Array(dimensions.length).fill(0);
this.dimensionsOut = Array(dimensions.length).fill(null);
}
close() {

View File

@ -1,5 +1,5 @@
import {BehaviorSubject} from "rxjs";
import {distanceInM} from "../utils";
import {latLngDistance} from "../utils";
import {environment} from "../../environments/environment";
import {Circle, LatLng, Marker, Measurement} from "../models/mapSymbol";
@ -146,7 +146,7 @@ export class MapService {
let group = L.layerGroup([line, decoration]).addTo(this.map);
group.symbol = m;
line.on('click', e => this.click.next({event: e, symbol: group}));
let distance = distanceInM(m.latlng.lat, m.latlng.lng, m.latlng2.lat, m.latlng2.lng);
let distance = latLngDistance(m.latlng, m.latlng2);
line.bindPopup(`${distance > 1000 ? Math.round(distance / 100) / 10 : Math.round(distance)} ${distance > 1000 ? 'k' : ''}m`, {autoClose: false, closeOnClick: false}).openPopup();
return group;
}

View File

@ -1,3 +1,7 @@
import {LatLng} from "./models/mapSymbol";
export const R = 6_371; // Radius of the Earth
export function copyToClipboard(value: string) {
let el = document.createElement('textarea');
el.value = value;
@ -10,18 +14,37 @@ export function copyToClipboard(value: string) {
}
export function deg2rad(deg) {
return deg * (Math.PI/180);
return deg * Math.PI / 180;
}
export function distanceInM(lat1: number, lon1: number, lat2: number, lon2: number) {
const R = 6371; // Radius of the earth in km
let dLat = deg2rad(lat2-lat1); // deg2rad below
let dLon = deg2rad(lon2-lon1);
let a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2)
;
let c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R * c * 1000
export function latLngBearing(latLng, latLng2) {
let dLng = (latLng2.lng - latLng.lng);
let y = Math.sin(dLng) * Math.cos(latLng2.lat);
let x = Math.cos(latLng.lat) * Math.sin(latLng2.lat) - Math.sin(latLng.lat) * Math.cos(latLng2.lat) * Math.cos(dLng);
return (360 - ((rad2deg(Math.atan2(y, x)) + 360) % 360));
}
export function latLngDistance(latLng, latLng2) {
let dLat = deg2rad(latLng2.lat - latLng.lat);
let dLng = deg2rad(latLng2.lng - latLng.lng);
let a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(deg2rad(latLng.lat)) * Math.cos(deg2rad(latLng2.lat)) * Math.sin(dLng/2) * Math.sin(dLng/2);
return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)) * 1000
}
export function rad2deg(rad) {
return rad * 180 / Math.PI
}
export function relativeLatLng(latLng: LatLng, meters: number, deg: number) {
let brng = deg2rad(deg);
let d = meters / 1000;
let lat = deg2rad(latLng.lat);
let lng = deg2rad(latLng.lng);
let latOut = Math.asin(Math.sign(lat) * Math.cos(d / R) + Math.cos(lat) * Math.sin(d / R) * Math.cos(brng));
let lngOut = lng + Math.atan2(Math.sin(brng) * Math.sin(d / R) * Math.cos(lat), Math.cos(d / R) - Math.sin(lat) * Math.sin(latOut));
latOut = rad2deg(latOut);
lngOut = rad2deg(lngOut);
return {lat: latOut, lng: lngOut};
}