mirror of
https://github.com/muerwre/orchidmap-front.git
synced 2025-04-25 11:06:40 +07:00
added gpx dialog
This commit is contained in:
parent
947ec69e60
commit
e995b46641
33 changed files with 11687 additions and 131 deletions
|
@ -7,3 +7,8 @@ export const getStyle = (oElm: any, strCssRule: string): string => {
|
|||
|
||||
return '';
|
||||
};
|
||||
|
||||
|
||||
export const getRandomColor = () => {
|
||||
return `hsl(${(Math.floor(Math.random() * 360))}, 100%, 50%)`
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
import { LatLng, LatLngLiteral, point, Point, PointExpression } from 'leaflet';
|
||||
import { LatLng, LatLngLiteral, point, Point, PointExpression, latLng } from 'leaflet';
|
||||
|
||||
interface ILatLng {
|
||||
lat: number;
|
||||
lng: number;
|
||||
}
|
||||
// interface LatLng {
|
||||
// lat: number;
|
||||
// lng: number;
|
||||
// }
|
||||
|
||||
export const middleCoord = (l1: ILatLng, l2: ILatLng): ILatLng => ({
|
||||
export const middleCoord = (l1: LatLng, l2: LatLng): LatLng => latLng({
|
||||
lat: l2.lat + (l1.lat - l2.lat) / 2,
|
||||
lng: l2.lng + (l1.lng - l2.lng) / 2,
|
||||
});
|
||||
|
|
110
src/utils/gpx.ts
110
src/utils/gpx.ts
|
@ -1,52 +1,110 @@
|
|||
import saveAs from 'file-saver';
|
||||
import GPX from 'gpx-parser-builder';
|
||||
import { LatLng } from 'leaflet';
|
||||
|
||||
export interface IRoutePoint {
|
||||
lat: number,
|
||||
lng: number,
|
||||
}
|
||||
type GpxImportTrkPt = {
|
||||
$: { lat: string; lon: string }[];
|
||||
name: string;
|
||||
};
|
||||
|
||||
type GpxImportTrkSeg = {
|
||||
trkpt: { trkpt: GpxImportTrkPt }[];
|
||||
};
|
||||
|
||||
type GpxImportRaw = {
|
||||
metadata: { name: string };
|
||||
trk: {
|
||||
name: string;
|
||||
trkseg: GpxImportTrkSeg[];
|
||||
}[];
|
||||
};
|
||||
// export interface IRoutePoint {
|
||||
// lat: number;
|
||||
// lng: number;
|
||||
// }
|
||||
|
||||
interface IGPXSticker {
|
||||
latlng: IRoutePoint,
|
||||
text?: string,
|
||||
latlng: LatLng;
|
||||
text?: string;
|
||||
}
|
||||
|
||||
interface IGetGPXString {
|
||||
route: Array<IRoutePoint>,
|
||||
stickers?: Array<IGPXSticker>
|
||||
title?: string,
|
||||
route: Array<LatLng>;
|
||||
stickers?: Array<IGPXSticker>;
|
||||
title?: string;
|
||||
}
|
||||
|
||||
export const getGPXString = ({ route, title, stickers }: IGetGPXString): string => (`<?xml version="1.0" encoding="UTF-8"?>
|
||||
export const getGPXString = ({
|
||||
route,
|
||||
title,
|
||||
stickers,
|
||||
}: IGetGPXString): string => `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
|
||||
<metadata>
|
||||
<name>${title || 'GPX Track'}</name>
|
||||
</metadata>
|
||||
${
|
||||
stickers.reduce((cat, { latlng: { lat, lng }, text }) => (
|
||||
`${cat}
|
||||
${stickers.reduce(
|
||||
(cat, { latlng: { lat, lng }, text }) =>
|
||||
`${cat}
|
||||
<wpt lat="${lat}" lon="${lng}">
|
||||
<name>${text}</name>
|
||||
<sym>generic</sym>
|
||||
<type>${title}</type>
|
||||
</wpt>`), '')
|
||||
}
|
||||
</wpt>`,
|
||||
''
|
||||
)}
|
||||
<trk>
|
||||
<name>${title || 'GPX Track'}</name>
|
||||
<trkseg>
|
||||
${
|
||||
route.reduce((cat, { lat, lng }) => (
|
||||
` ${cat}
|
||||
<trkpt lat="${lat}" lon="${lng}" />`
|
||||
), '')
|
||||
}
|
||||
${route.reduce(
|
||||
(cat, { lat, lng }) =>
|
||||
` ${cat}
|
||||
<trkpt lat="${lat}" lon="${lng}" />`,
|
||||
''
|
||||
)}
|
||||
</trkseg>
|
||||
</trk>
|
||||
</gpx>
|
||||
`);
|
||||
`;
|
||||
|
||||
export const downloadGPXTrack = ({ track, title }: { track: string, title?: string }): void => (
|
||||
export const downloadGPXTrack = ({ track, title }: { track: string; title?: string }): void =>
|
||||
saveAs(
|
||||
new Blob([track], { type: 'application/gpx+xml;charset=utf-8' }),
|
||||
`${(title || 'track').replace(/\./ig, ' ')}.gpx`
|
||||
)
|
||||
);
|
||||
`${(title || 'track').replace(/\./gi, ' ')}.gpx`
|
||||
);
|
||||
|
||||
export const importGpxTrack = async (file: File) => {
|
||||
const reader = new FileReader();
|
||||
const content = await new Promise(resolve => {
|
||||
reader.readAsText(file);
|
||||
|
||||
reader.onload = () => {
|
||||
resolve(reader.result);
|
||||
};
|
||||
|
||||
reader.onerror = () => {
|
||||
resolve(null);
|
||||
};
|
||||
});
|
||||
|
||||
const gpx: GpxImportRaw = GPX.parse(content);
|
||||
console.log(gpx);
|
||||
|
||||
if (!gpx || !gpx.trk) return null;
|
||||
|
||||
const latlngs: LatLng[] = gpx.trk.reduce((trk_res, trk) => {
|
||||
return trk.trkseg.reduce((trkseg_res, trkseg) => {
|
||||
return [
|
||||
...trkseg_res,
|
||||
...trkseg.trkpt.map(pnt => ({ lat: pnt['$'].lat, lng: pnt['$'].lon })),
|
||||
];
|
||||
}, trk_res);
|
||||
}, []);
|
||||
|
||||
return [
|
||||
{
|
||||
name: gpx.metadata.name || '',
|
||||
latlngs,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
|
|
@ -3,7 +3,7 @@ import { COLORS, CLIENT } from '~/config/frontend';
|
|||
import saveAs from 'file-saver';
|
||||
import { replaceProviderUrl } from '~/constants/providers';
|
||||
import { STICKERS } from '~/constants/stickers';
|
||||
import { ILatLng, IRoute } from '~/redux/map/types';
|
||||
import { IRoute } from '~/redux/map/types';
|
||||
import { IStickerDump } from '~/redux/map/types';
|
||||
import { IRootState } from '~/redux/user';
|
||||
import {
|
||||
|
@ -12,7 +12,7 @@ import {
|
|||
findDistancePx,
|
||||
middleCoordPx,
|
||||
} from '~/utils/geom';
|
||||
import { Point } from 'leaflet';
|
||||
import { Point, LatLng, latLng } from 'leaflet';
|
||||
import { MainMap } from '~/constants/map';
|
||||
|
||||
export interface ITilePlacement {
|
||||
|
@ -55,14 +55,14 @@ const latLngToTile = (latlng: {
|
|||
return { x: xtile, y: ytile, z: zoom };
|
||||
};
|
||||
|
||||
const tileToLatLng = (point: { x: number; y: number }): ILatLng => {
|
||||
const tileToLatLng = (point: { x: number; y: number }): LatLng => {
|
||||
const map = MainMap;
|
||||
const z = map.getZoom();
|
||||
const lng = (point.x / Math.pow(2, z)) * 360 - 180;
|
||||
const n = Math.PI - (2 * Math.PI * point.y) / Math.pow(2, z);
|
||||
const lat = (180 / Math.PI) * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)));
|
||||
|
||||
return { lat, lng };
|
||||
return latLng({ lat, lng });
|
||||
};
|
||||
|
||||
export const getTilePlacement = (): ITilePlacement => {
|
||||
|
@ -102,7 +102,7 @@ export const getTilePlacement = (): ITilePlacement => {
|
|||
};
|
||||
};
|
||||
|
||||
export const getPolyPlacement = (latlngs: ILatLng[]): Point[] =>
|
||||
export const getPolyPlacement = (latlngs: LatLng[]): Point[] =>
|
||||
latlngs.length === 0
|
||||
? []
|
||||
: latlngs.map(latlng => (MainMap.latLngToContainerPoint(latlng)));
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Map, LineUtil } from 'leaflet';
|
||||
import { ILatLng } from "~/redux/map/types";
|
||||
import { Map, LineUtil, LatLng } from 'leaflet';
|
||||
// import { ILatLng } from "~/redux/map/types";
|
||||
|
||||
export const simplify = ({ map, latlngs }: { map: Map, latlngs: ILatLng[] }): ILatLng[] => {
|
||||
export const simplify = ({ map, latlngs }: { map: Map, latlngs: LatLng[] }): LatLng[] => {
|
||||
const zoom = 12;
|
||||
const mul = 0.7; // 0 - not simplifying, 1 - very rude.
|
||||
const points = latlngs.map(({ lat, lng }) => map.project({ lat, lng }, zoom));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue