added gpx dialog

This commit is contained in:
Fedor Katurov 2020-01-24 16:53:47 +07:00
parent 947ec69e60
commit e995b46641
33 changed files with 11687 additions and 131 deletions

View file

@ -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%)`
}

View file

@ -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,
});

View file

@ -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,
},
];
};

View file

@ -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)));

View file

@ -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));