mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2025-08-30 15:20:01 +00:00
remove dist folder
This commit is contained in:
3
gpx/.gitignore
vendored
3
gpx/.gitignore
vendored
@@ -1 +1,2 @@
|
||||
node_modules
|
||||
node_modules
|
||||
dist
|
250
gpx/dist/gpx.d.ts
vendored
250
gpx/dist/gpx.d.ts
vendored
@@ -1,250 +0,0 @@
|
||||
import { Coordinates, GPXFileAttributes, GPXFileType, LineStyleExtension, Link, Metadata, RouteType, TrackExtensions, TrackPointExtensions, TrackPointType, TrackSegmentType, TrackType, WaypointType } from "./types";
|
||||
import { immerable } from "immer";
|
||||
export declare abstract class GPXTreeElement<T extends GPXTreeElement<any>> {
|
||||
_data: {
|
||||
[key: string]: any;
|
||||
};
|
||||
abstract isLeaf(): boolean;
|
||||
abstract get children(): Array<T>;
|
||||
abstract getNumberOfTrackPoints(): number;
|
||||
abstract getStartTimestamp(): Date | undefined;
|
||||
abstract getEndTimestamp(): Date | undefined;
|
||||
abstract getStatistics(): GPXStatistics;
|
||||
abstract getSegments(): TrackSegment[];
|
||||
abstract getTrackPoints(): TrackPoint[];
|
||||
abstract toGeoJSON(): GeoJSON.Feature | GeoJSON.Feature[] | GeoJSON.FeatureCollection | GeoJSON.FeatureCollection[];
|
||||
abstract _reverse(originalNextTimestamp?: Date, newPreviousTimestamp?: Date): any;
|
||||
}
|
||||
export type AnyGPXTreeElement = GPXTreeElement<GPXTreeElement<any>>;
|
||||
declare abstract class GPXTreeNode<T extends GPXTreeElement<any>> extends GPXTreeElement<T> {
|
||||
isLeaf(): boolean;
|
||||
getNumberOfTrackPoints(): number;
|
||||
getStartTimestamp(): Date | undefined;
|
||||
getEndTimestamp(): Date | undefined;
|
||||
getStatistics(): GPXStatistics;
|
||||
getSegments(): TrackSegment[];
|
||||
getTrackPoints(): TrackPoint[];
|
||||
_reverse(originalNextTimestamp?: Date, newPreviousTimestamp?: Date): void;
|
||||
}
|
||||
declare abstract class GPXTreeLeaf extends GPXTreeElement<GPXTreeLeaf> {
|
||||
isLeaf(): boolean;
|
||||
get children(): Array<GPXTreeLeaf>;
|
||||
}
|
||||
export declare class GPXFile extends GPXTreeNode<Track> {
|
||||
[immerable]: boolean;
|
||||
attributes: GPXFileAttributes;
|
||||
metadata: Metadata;
|
||||
wpt: Waypoint[];
|
||||
trk: Track[];
|
||||
rte: RouteType[];
|
||||
constructor(gpx?: GPXFileType & {
|
||||
_data?: any;
|
||||
} | GPXFile);
|
||||
get children(): Array<Track>;
|
||||
getSegment(trackIndex: number, segmentIndex: number): TrackSegment;
|
||||
forEachSegment(callback: (segment: TrackSegment, trackIndex: number, segmentIndex: number) => void): void;
|
||||
getStyle(): MergedLineStyles;
|
||||
clone(): GPXFile;
|
||||
toGeoJSON(): GeoJSON.FeatureCollection;
|
||||
toGPXFileType(exclude?: string[]): GPXFileType;
|
||||
replaceTracks(start: number, end: number, tracks: Track[]): void;
|
||||
replaceTrackSegments(trackIndex: number, start: number, end: number, segments: TrackSegment[]): void;
|
||||
replaceTrackPoints(trackIndex: number, segmentIndex: number, start: number, end: number, points: TrackPoint[], speed?: number, startTime?: Date): void;
|
||||
replaceWaypoints(start: number, end: number, waypoints: Waypoint[]): void;
|
||||
reverse(): void;
|
||||
reverseTrack(trackIndex: number): void;
|
||||
reverseTrackSegment(trackIndex: number, segmentIndex: number): void;
|
||||
roundTrip(): void;
|
||||
roundTripTrack(trackIndex: number): void;
|
||||
roundTripTrackSegment(trackIndex: number, segmentIndex: number): void;
|
||||
crop(start: number, end: number, trackIndices?: number[], segmentIndices?: number[]): void;
|
||||
clean(bounds: [Coordinates, Coordinates], inside: boolean, deleteTrackPoints: boolean, deleteWaypoints: boolean, trackIndices?: number[], segmentIndices?: number[], waypointIndices?: number[]): void;
|
||||
changeTimestamps(startTime: Date, speed: number, ratio: number, trackIndex?: number, segmentIndex?: number): void;
|
||||
createArtificialTimestamps(startTime: Date, totalTime: number, trackIndex?: number, segmentIndex?: number): void;
|
||||
addElevation(elevations: number[], trackIndices?: number[], segmentIndices?: number[], waypointIndices?: number[]): void;
|
||||
setStyle(style: LineStyleExtension): void;
|
||||
setHidden(hidden: boolean, trackIndices?: number[], segmentIndices?: number[]): void;
|
||||
setHiddenWaypoints(hidden: boolean, waypointIndices?: number[]): void;
|
||||
}
|
||||
export declare class Track extends GPXTreeNode<TrackSegment> {
|
||||
[immerable]: boolean;
|
||||
name?: string;
|
||||
cmt?: string;
|
||||
desc?: string;
|
||||
src?: string;
|
||||
link?: Link;
|
||||
type?: string;
|
||||
extensions?: TrackExtensions;
|
||||
trkseg: TrackSegment[];
|
||||
constructor(track?: TrackType & {
|
||||
_data?: any;
|
||||
} | Track);
|
||||
get children(): Array<TrackSegment>;
|
||||
clone(): Track;
|
||||
getStyle(): LineStyleExtension | undefined;
|
||||
toGeoJSON(): GeoJSON.Feature[];
|
||||
toTrackType(exclude?: string[]): TrackType;
|
||||
replaceTrackSegments(start: number, end: number, segments: TrackSegment[]): void;
|
||||
replaceTrackPoints(segmentIndex: number, start: number, end: number, points: TrackPoint[], speed?: number, startTime?: Date): void;
|
||||
reverseTrackSegment(segmentIndex: number): void;
|
||||
roundTrip(): void;
|
||||
roundTripTrackSegment(segmentIndex: number): void;
|
||||
crop(start: number, end: number, segmentIndices?: number[]): void;
|
||||
clean(bounds: [Coordinates, Coordinates], inside: boolean, segmentIndices?: number[]): void;
|
||||
changeTimestamps(startTime: Date, speed: number, ratio: number, lastPoint?: TrackPoint, segmentIndex?: number): void;
|
||||
createArtificialTimestamps(startTime: Date, totalTime: number, lastPoint: TrackPoint | undefined, segmentIndex?: number): void;
|
||||
setStyle(style: LineStyleExtension, force?: boolean): void;
|
||||
setHidden(hidden: boolean, segmentIndices?: number[]): void;
|
||||
}
|
||||
export declare class TrackSegment extends GPXTreeLeaf {
|
||||
[immerable]: boolean;
|
||||
trkpt: TrackPoint[];
|
||||
constructor(segment?: TrackSegmentType & {
|
||||
_data?: any;
|
||||
} | TrackSegment);
|
||||
_computeStatistics(): GPXStatistics;
|
||||
_computeSmoothedElevation(): number[];
|
||||
_computeSlope(): number[];
|
||||
_computeSlopeSegments(statistics: GPXStatistics): [number[], number[]];
|
||||
getNumberOfTrackPoints(): number;
|
||||
getStartTimestamp(): Date | undefined;
|
||||
getEndTimestamp(): Date | undefined;
|
||||
getStatistics(): GPXStatistics;
|
||||
getSegments(): TrackSegment[];
|
||||
getTrackPoints(): TrackPoint[];
|
||||
toGeoJSON(): GeoJSON.Feature;
|
||||
toTrackSegmentType(exclude?: string[]): TrackSegmentType;
|
||||
clone(): TrackSegment;
|
||||
replaceTrackPoints(start: number, end: number, points: TrackPoint[], speed?: number, startTime?: Date): void;
|
||||
_reverse(originalNextTimestamp?: Date, newPreviousTimestamp?: Date): void;
|
||||
roundTrip(): void;
|
||||
crop(start: number, end: number): void;
|
||||
clean(bounds: [Coordinates, Coordinates], inside: boolean): void;
|
||||
changeTimestamps(startTime: Date, speed: number, ratio: number, lastPoint?: TrackPoint): void;
|
||||
createArtificialTimestamps(startTime: Date, totalTime: number, lastPoint: TrackPoint | undefined): void;
|
||||
setHidden(hidden: boolean): void;
|
||||
}
|
||||
export declare class TrackPoint {
|
||||
[immerable]: boolean;
|
||||
attributes: Coordinates;
|
||||
ele?: number;
|
||||
time?: Date;
|
||||
extensions?: TrackPointExtensions;
|
||||
_data: {
|
||||
[key: string]: any;
|
||||
};
|
||||
constructor(point: TrackPointType & {
|
||||
_data?: any;
|
||||
} | TrackPoint);
|
||||
getCoordinates(): Coordinates;
|
||||
setCoordinates(coordinates: Coordinates): void;
|
||||
getLatitude(): number;
|
||||
getLongitude(): number;
|
||||
getTemperature(): number;
|
||||
getHeartRate(): number;
|
||||
getCadence(): number;
|
||||
getPower(): number;
|
||||
getSurface(): string;
|
||||
setSurface(surface: string): void;
|
||||
toTrackPointType(exclude?: string[]): TrackPointType;
|
||||
clone(): TrackPoint;
|
||||
}
|
||||
export declare class Waypoint {
|
||||
[immerable]: boolean;
|
||||
attributes: Coordinates;
|
||||
ele?: number;
|
||||
time?: Date;
|
||||
name?: string;
|
||||
cmt?: string;
|
||||
desc?: string;
|
||||
link?: Link;
|
||||
sym?: string;
|
||||
type?: string;
|
||||
_data: {
|
||||
[key: string]: any;
|
||||
};
|
||||
constructor(waypoint: WaypointType & {
|
||||
_data?: any;
|
||||
} | Waypoint);
|
||||
getCoordinates(): Coordinates;
|
||||
setCoordinates(coordinates: Coordinates): void;
|
||||
getLatitude(): number;
|
||||
getLongitude(): number;
|
||||
toWaypointType(exclude?: string[]): WaypointType;
|
||||
clone(): Waypoint;
|
||||
setHidden(hidden: boolean): void;
|
||||
}
|
||||
export declare class GPXStatistics {
|
||||
global: {
|
||||
distance: {
|
||||
moving: number;
|
||||
total: number;
|
||||
};
|
||||
time: {
|
||||
start: Date | undefined;
|
||||
end: Date | undefined;
|
||||
moving: number;
|
||||
total: number;
|
||||
};
|
||||
speed: {
|
||||
moving: number;
|
||||
total: number;
|
||||
};
|
||||
elevation: {
|
||||
gain: number;
|
||||
loss: number;
|
||||
};
|
||||
bounds: {
|
||||
southWest: Coordinates;
|
||||
northEast: Coordinates;
|
||||
};
|
||||
atemp: {
|
||||
avg: number;
|
||||
count: number;
|
||||
};
|
||||
hr: {
|
||||
avg: number;
|
||||
count: number;
|
||||
};
|
||||
cad: {
|
||||
avg: number;
|
||||
count: number;
|
||||
};
|
||||
power: {
|
||||
avg: number;
|
||||
count: number;
|
||||
};
|
||||
};
|
||||
local: {
|
||||
points: TrackPoint[];
|
||||
distance: {
|
||||
moving: number[];
|
||||
total: number[];
|
||||
};
|
||||
time: {
|
||||
moving: number[];
|
||||
total: number[];
|
||||
};
|
||||
speed: number[];
|
||||
elevation: {
|
||||
smoothed: number[];
|
||||
gain: number[];
|
||||
loss: number[];
|
||||
};
|
||||
slope: {
|
||||
at: number[];
|
||||
segment: number[];
|
||||
length: number[];
|
||||
};
|
||||
};
|
||||
constructor();
|
||||
mergeWith(other: GPXStatistics): void;
|
||||
slice(start: number, end: number): GPXStatistics;
|
||||
}
|
||||
export declare function distance(coord1: TrackPoint | Coordinates, coord2: TrackPoint | Coordinates): number;
|
||||
export type MergedLineStyles = {
|
||||
color: string[];
|
||||
opacity: number[];
|
||||
weight: number[];
|
||||
};
|
||||
export {};
|
1328
gpx/dist/gpx.js
vendored
1328
gpx/dist/gpx.js
vendored
File diff suppressed because it is too large
Load Diff
4
gpx/dist/index.d.ts
vendored
4
gpx/dist/index.d.ts
vendored
@@ -1,4 +0,0 @@
|
||||
export * from './gpx';
|
||||
export { Coordinates, LineStyleExtension, WaypointType } from './types';
|
||||
export { parseGPX, buildGPX } from './io';
|
||||
export * from './simplify';
|
3
gpx/dist/index.js
vendored
3
gpx/dist/index.js
vendored
@@ -1,3 +0,0 @@
|
||||
export * from './gpx';
|
||||
export { parseGPX, buildGPX } from './io';
|
||||
export * from './simplify';
|
3
gpx/dist/io.d.ts
vendored
3
gpx/dist/io.d.ts
vendored
@@ -1,3 +0,0 @@
|
||||
import { GPXFile } from "./gpx";
|
||||
export declare function parseGPX(gpxData: string): GPXFile;
|
||||
export declare function buildGPX(file: GPXFile, exclude: string[]): string;
|
105
gpx/dist/io.js
vendored
105
gpx/dist/io.js
vendored
@@ -1,105 +0,0 @@
|
||||
import { XMLParser, XMLBuilder } from "fast-xml-parser";
|
||||
import { GPXFile } from "./gpx";
|
||||
export function parseGPX(gpxData) {
|
||||
const parser = new XMLParser({
|
||||
ignoreAttributes: false,
|
||||
attributeNamePrefix: "",
|
||||
attributesGroupName: 'attributes',
|
||||
isArray(name) {
|
||||
return name === 'trk' || name === 'trkseg' || name === 'trkpt' || name === 'wpt' || name === 'rte' || name === 'rtept' || name === 'gpxx:rpt';
|
||||
},
|
||||
attributeValueProcessor(attrName, attrValue, jPath) {
|
||||
if (attrName === 'lat' || attrName === 'lon') {
|
||||
return parseFloat(attrValue);
|
||||
}
|
||||
return attrValue;
|
||||
},
|
||||
transformTagName(tagName) {
|
||||
if (tagName === 'power') {
|
||||
// Transform the simple <power> tag to the more complex <gpxpx:PowerExtension> tag, the nested <gpxpx:PowerInWatts> tag is then handled by the tagValueProcessor
|
||||
return 'gpxpx:PowerExtension';
|
||||
}
|
||||
return tagName;
|
||||
},
|
||||
parseTagValue: false,
|
||||
tagValueProcessor(tagName, tagValue, jPath, hasAttributes, isLeafNode) {
|
||||
if (isLeafNode) {
|
||||
if (tagName === 'ele') {
|
||||
return parseFloat(tagValue);
|
||||
}
|
||||
if (tagName === 'time') {
|
||||
return new Date(tagValue);
|
||||
}
|
||||
if (tagName === 'gpxtpx:atemp' || tagName === 'gpxtpx:hr' || tagName === 'gpxtpx:cad' || tagName === 'gpxpx:PowerInWatts' || tagName === 'opacity' || tagName === 'weight') {
|
||||
return parseFloat(tagValue);
|
||||
}
|
||||
if (tagName === 'gpxpx:PowerExtension') {
|
||||
// Finish the transformation of the simple <power> tag to the more complex <gpxpx:PowerExtension> tag
|
||||
// Note that this only targets the transformed <power> tag, since it must be a leaf node
|
||||
return {
|
||||
'gpxpx:PowerInWatts': parseFloat(tagValue)
|
||||
};
|
||||
}
|
||||
}
|
||||
return tagValue;
|
||||
},
|
||||
});
|
||||
const parsed = parser.parse(gpxData).gpx;
|
||||
// @ts-ignore
|
||||
if (parsed.metadata === "") {
|
||||
parsed.metadata = {};
|
||||
}
|
||||
return new GPXFile(parsed);
|
||||
}
|
||||
export function buildGPX(file, exclude) {
|
||||
var _a;
|
||||
const gpx = file.toGPXFileType(exclude);
|
||||
const builder = new XMLBuilder({
|
||||
format: true,
|
||||
ignoreAttributes: false,
|
||||
attributeNamePrefix: "",
|
||||
attributesGroupName: 'attributes',
|
||||
suppressEmptyNode: true,
|
||||
tagValueProcessor: (tagName, tagValue) => {
|
||||
if (tagValue instanceof Date) {
|
||||
return tagValue.toISOString();
|
||||
}
|
||||
return tagValue.toString();
|
||||
},
|
||||
});
|
||||
gpx.attributes.creator = (_a = gpx.attributes.creator) !== null && _a !== void 0 ? _a : 'https://gpx.studio';
|
||||
gpx.attributes['version'] = '1.1';
|
||||
gpx.attributes['xmlns'] = 'http://www.topografix.com/GPX/1/1';
|
||||
gpx.attributes['xmlns:xsi'] = 'http://www.w3.org/2001/XMLSchema-instance';
|
||||
gpx.attributes['xsi:schemaLocation'] = 'http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd http://www.garmin.com/xmlschemas/PowerExtension/v1 http://www.garmin.com/xmlschemas/PowerExtensionv1.xsd http://www.topografix.com/GPX/gpx_style/0/2 http://www.topografix.com/GPX/gpx_style/0/2/gpx_style.xsd';
|
||||
gpx.attributes['xmlns:gpxtpx'] = 'http://www.garmin.com/xmlschemas/TrackPointExtension/v1';
|
||||
gpx.attributes['xmlns:gpxx'] = 'http://www.garmin.com/xmlschemas/GpxExtensions/v3';
|
||||
gpx.attributes['xmlns:gpxpx'] = 'http://www.garmin.com/xmlschemas/PowerExtension/v1';
|
||||
gpx.attributes['xmlns:gpx_style'] = 'http://www.topografix.com/GPX/gpx_style/0/2';
|
||||
if (gpx.trk.length === 1 && (gpx.trk[0].name === undefined || gpx.trk[0].name === '')) {
|
||||
gpx.trk[0].name = gpx.metadata.name;
|
||||
}
|
||||
return builder.build({
|
||||
"?xml": {
|
||||
attributes: {
|
||||
version: "1.0",
|
||||
encoding: "UTF-8",
|
||||
}
|
||||
},
|
||||
gpx: removeEmptyElements(gpx)
|
||||
});
|
||||
}
|
||||
function removeEmptyElements(obj) {
|
||||
for (const key in obj) {
|
||||
if (obj[key] === null || obj[key] === undefined || obj[key] === '' || (Array.isArray(obj[key]) && obj[key].length === 0)) {
|
||||
delete obj[key];
|
||||
}
|
||||
else if (typeof obj[key] === 'object' && !(obj[key] instanceof Date)) {
|
||||
removeEmptyElements(obj[key]);
|
||||
if (Object.keys(obj[key]).length === 0) {
|
||||
delete obj[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
9
gpx/dist/simplify.d.ts
vendored
9
gpx/dist/simplify.d.ts
vendored
@@ -1,9 +0,0 @@
|
||||
import { TrackPoint } from "./gpx";
|
||||
import { Coordinates } from "./types";
|
||||
export type SimplifiedTrackPoint = {
|
||||
point: TrackPoint;
|
||||
distance?: number;
|
||||
};
|
||||
export declare function ramerDouglasPeucker(points: TrackPoint[], epsilon?: number, measure?: (a: TrackPoint, b: TrackPoint, c: TrackPoint) => number): SimplifiedTrackPoint[];
|
||||
export declare function crossarcDistance(point1: TrackPoint, point2: TrackPoint, point3: TrackPoint | Coordinates): number;
|
||||
export declare function projectedPoint(point1: TrackPoint, point2: TrackPoint, point3: TrackPoint | Coordinates): Coordinates;
|
126
gpx/dist/simplify.js
vendored
126
gpx/dist/simplify.js
vendored
@@ -1,126 +0,0 @@
|
||||
import { TrackPoint } from "./gpx";
|
||||
const earthRadius = 6371008.8;
|
||||
export function ramerDouglasPeucker(points, epsilon = 50, measure = crossarcDistance) {
|
||||
if (points.length == 0) {
|
||||
return [];
|
||||
}
|
||||
else if (points.length == 1) {
|
||||
return [{
|
||||
point: points[0]
|
||||
}];
|
||||
}
|
||||
let simplified = [{
|
||||
point: points[0]
|
||||
}];
|
||||
ramerDouglasPeuckerRecursive(points, epsilon, measure, 0, points.length - 1, simplified);
|
||||
simplified.push({
|
||||
point: points[points.length - 1]
|
||||
});
|
||||
return simplified;
|
||||
}
|
||||
function ramerDouglasPeuckerRecursive(points, epsilon, measure, start, end, simplified) {
|
||||
let largest = {
|
||||
index: 0,
|
||||
distance: 0
|
||||
};
|
||||
for (let i = start + 1; i < end; i++) {
|
||||
let distance = measure(points[start], points[end], points[i]);
|
||||
if (distance > largest.distance) {
|
||||
largest.index = i;
|
||||
largest.distance = distance;
|
||||
}
|
||||
}
|
||||
if (largest.distance > epsilon && largest.index != 0) {
|
||||
ramerDouglasPeuckerRecursive(points, epsilon, measure, start, largest.index, simplified);
|
||||
simplified.push({ point: points[largest.index], distance: largest.distance });
|
||||
ramerDouglasPeuckerRecursive(points, epsilon, measure, largest.index, end, simplified);
|
||||
}
|
||||
}
|
||||
export function crossarcDistance(point1, point2, point3) {
|
||||
return crossarc(point1.getCoordinates(), point2.getCoordinates(), point3 instanceof TrackPoint ? point3.getCoordinates() : point3);
|
||||
}
|
||||
function crossarc(coord1, coord2, coord3) {
|
||||
// Calculates the shortest distance in meters
|
||||
// between an arc (defined by p1 and p2) and a third point, p3.
|
||||
// Input lat1,lon1,lat2,lon2,lat3,lon3 in degrees.
|
||||
const rad = Math.PI / 180;
|
||||
const lat1 = coord1.lat * rad;
|
||||
const lat2 = coord2.lat * rad;
|
||||
const lat3 = coord3.lat * rad;
|
||||
const lon1 = coord1.lon * rad;
|
||||
const lon2 = coord2.lon * rad;
|
||||
const lon3 = coord3.lon * rad;
|
||||
// Prerequisites for the formulas
|
||||
const bear12 = bearing(lat1, lon1, lat2, lon2);
|
||||
const bear13 = bearing(lat1, lon1, lat3, lon3);
|
||||
let dis13 = distance(lat1, lon1, lat3, lon3);
|
||||
let diff = Math.abs(bear13 - bear12);
|
||||
if (diff > Math.PI) {
|
||||
diff = 2 * Math.PI - diff;
|
||||
}
|
||||
// Is relative bearing obtuse?
|
||||
if (diff > (Math.PI / 2)) {
|
||||
return dis13;
|
||||
}
|
||||
// Find the cross-track distance.
|
||||
let dxt = Math.asin(Math.sin(dis13 / earthRadius) * Math.sin(bear13 - bear12)) * earthRadius;
|
||||
// Is p4 beyond the arc?
|
||||
let dis12 = distance(lat1, lon1, lat2, lon2);
|
||||
let dis14 = Math.acos(Math.cos(dis13 / earthRadius) / Math.cos(dxt / earthRadius)) * earthRadius;
|
||||
if (dis14 > dis12) {
|
||||
return distance(lat2, lon2, lat3, lon3);
|
||||
}
|
||||
else {
|
||||
return Math.abs(dxt);
|
||||
}
|
||||
}
|
||||
function distance(latA, lonA, latB, lonB) {
|
||||
// Finds the distance between two lat / lon points.
|
||||
return Math.acos(Math.sin(latA) * Math.sin(latB) + Math.cos(latA) * Math.cos(latB) * Math.cos(lonB - lonA)) * earthRadius;
|
||||
}
|
||||
function bearing(latA, lonA, latB, lonB) {
|
||||
// Finds the bearing from one lat / lon point to another.
|
||||
return Math.atan2(Math.sin(lonB - lonA) * Math.cos(latB), Math.cos(latA) * Math.sin(latB) - Math.sin(latA) * Math.cos(latB) * Math.cos(lonB - lonA));
|
||||
}
|
||||
export function projectedPoint(point1, point2, point3) {
|
||||
return projected(point1.getCoordinates(), point2.getCoordinates(), point3 instanceof TrackPoint ? point3.getCoordinates() : point3);
|
||||
}
|
||||
function projected(coord1, coord2, coord3) {
|
||||
// Calculates the point on the line defined by p1 and p2
|
||||
// that is closest to the third point, p3.
|
||||
// Input lat1,lon1,lat2,lon2,lat3,lon3 in degrees.
|
||||
const rad = Math.PI / 180;
|
||||
const lat1 = coord1.lat * rad;
|
||||
const lat2 = coord2.lat * rad;
|
||||
const lat3 = coord3.lat * rad;
|
||||
const lon1 = coord1.lon * rad;
|
||||
const lon2 = coord2.lon * rad;
|
||||
const lon3 = coord3.lon * rad;
|
||||
// Prerequisites for the formulas
|
||||
const bear12 = bearing(lat1, lon1, lat2, lon2);
|
||||
const bear13 = bearing(lat1, lon1, lat3, lon3);
|
||||
let dis13 = distance(lat1, lon1, lat3, lon3);
|
||||
let diff = Math.abs(bear13 - bear12);
|
||||
if (diff > Math.PI) {
|
||||
diff = 2 * Math.PI - diff;
|
||||
}
|
||||
// Is relative bearing obtuse?
|
||||
if (diff > (Math.PI / 2)) {
|
||||
return coord1;
|
||||
}
|
||||
// Find the cross-track distance.
|
||||
let dxt = Math.asin(Math.sin(dis13 / earthRadius) * Math.sin(bear13 - bear12)) * earthRadius;
|
||||
// Is p4 beyond the arc?
|
||||
let dis12 = distance(lat1, lon1, lat2, lon2);
|
||||
let dis14 = Math.acos(Math.cos(dis13 / earthRadius) / Math.cos(dxt / earthRadius)) * earthRadius;
|
||||
if (dis14 > dis12) {
|
||||
return coord2;
|
||||
}
|
||||
else {
|
||||
// Determine the closest point (p4) on the great circle
|
||||
const f = dis14 / earthRadius;
|
||||
const lat4 = Math.asin(Math.sin(lat1) * Math.cos(f) + Math.cos(lat1) * Math.sin(f) * Math.cos(bear12));
|
||||
const lon4 = lon1 + Math.atan2(Math.sin(bear12) * Math.sin(f) * Math.cos(lat1), Math.cos(f) - Math.sin(lat1) * Math.sin(lat4));
|
||||
return { lat: lat4 / rad, lon: lon4 / rad };
|
||||
}
|
||||
}
|
108
gpx/dist/types.d.ts
vendored
108
gpx/dist/types.d.ts
vendored
@@ -1,108 +0,0 @@
|
||||
export type GPXFileType = {
|
||||
attributes: GPXFileAttributes;
|
||||
metadata: Metadata;
|
||||
wpt: WaypointType[];
|
||||
trk: TrackType[];
|
||||
rte: RouteType[];
|
||||
};
|
||||
export type GPXFileAttributes = {
|
||||
creator?: string;
|
||||
[key: string]: string;
|
||||
};
|
||||
export type Metadata = {
|
||||
name?: string;
|
||||
desc?: string;
|
||||
author?: Author;
|
||||
link?: Link;
|
||||
time?: Date;
|
||||
};
|
||||
export type Link = {
|
||||
attributes: LinkAttributes;
|
||||
text?: string;
|
||||
type?: string;
|
||||
};
|
||||
export type LinkAttributes = {
|
||||
href: string;
|
||||
};
|
||||
export type WaypointType = {
|
||||
attributes: Coordinates;
|
||||
ele?: number;
|
||||
time?: Date;
|
||||
name?: string;
|
||||
cmt?: string;
|
||||
desc?: string;
|
||||
link?: Link;
|
||||
sym?: string;
|
||||
type?: string;
|
||||
extensions?: WaypointExtensions;
|
||||
};
|
||||
export type WaypointExtensions = {
|
||||
'gpxx:RoutePointExtension'?: RoutePointExtension;
|
||||
};
|
||||
export type Coordinates = {
|
||||
lat: number;
|
||||
lon: number;
|
||||
};
|
||||
export type TrackType = {
|
||||
name?: string;
|
||||
cmt?: string;
|
||||
desc?: string;
|
||||
src?: string;
|
||||
link?: Link;
|
||||
type?: string;
|
||||
extensions?: TrackExtensions;
|
||||
trkseg: TrackSegmentType[];
|
||||
};
|
||||
export type TrackExtensions = {
|
||||
'gpx_style:line'?: LineStyleExtension;
|
||||
};
|
||||
export type LineStyleExtension = {
|
||||
color?: string;
|
||||
opacity?: number;
|
||||
weight?: number;
|
||||
};
|
||||
export type TrackSegmentType = {
|
||||
trkpt: TrackPointType[];
|
||||
};
|
||||
export type TrackPointType = {
|
||||
attributes: Coordinates;
|
||||
ele?: number;
|
||||
time?: Date;
|
||||
extensions?: TrackPointExtensions;
|
||||
};
|
||||
export type TrackPointExtensions = {
|
||||
'gpxtpx:TrackPointExtension'?: TrackPointExtension;
|
||||
'gpxpx:PowerExtension'?: PowerExtension;
|
||||
};
|
||||
export type TrackPointExtension = {
|
||||
'gpxtpx:atemp'?: number;
|
||||
'gpxtpx:hr'?: number;
|
||||
'gpxtpx:cad'?: number;
|
||||
'gpxtpx:Extensions'?: {
|
||||
surface?: string;
|
||||
};
|
||||
};
|
||||
export type PowerExtension = {
|
||||
'gpxpx:PowerInWatts'?: number;
|
||||
};
|
||||
export type Author = {
|
||||
name?: string;
|
||||
email?: string;
|
||||
link?: Link;
|
||||
};
|
||||
export type RouteType = {
|
||||
name?: string;
|
||||
cmt?: string;
|
||||
desc?: string;
|
||||
src?: string;
|
||||
link?: Link;
|
||||
type?: string;
|
||||
extensions?: TrackExtensions;
|
||||
rtept: WaypointType[];
|
||||
};
|
||||
export type RoutePointExtension = {
|
||||
'gpxx:rpt'?: GPXXRoutePoint[];
|
||||
};
|
||||
export type GPXXRoutePoint = {
|
||||
attributes: Coordinates;
|
||||
};
|
1
gpx/dist/types.js
vendored
1
gpx/dist/types.js
vendored
@@ -1 +0,0 @@
|
||||
export {};
|
@@ -15,12 +15,13 @@
|
||||
"immer": "^10.1.1",
|
||||
"ts-node": "^10.9.2"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/geojson": "^7946.0.14",
|
||||
"@types/node": "^20.14.6",
|
||||
"typescript": "^5.4.5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"postinstall": "npm run build"
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user