nakarte

Source code of https://map.sikmir.ru (fork)
git clone git://git.sikmir.ru/nakarte
Log | Files | Refs | LICENSE

commit 309c261f0a86bb4c7fea32a29c196c09c2d0c37c
parent d74b948f1c73d805967ab51e4ef304693cf04797
Author: Sergey Orlov <wladimirych@gmail.com>
Date:   Thu, 21 May 2020 22:34:20 +0200

track list: refactoring - split lines at 180 meridian outside exporters

Diffstat:
Msrc/lib/leaflet.control.track-list/lib/geo_file_exporters.js | 61+++----------------------------------------------------------
Asrc/lib/leaflet.control.track-list/lib/meridian180.js | 56++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/lib/leaflet.control.track-list/track-list.js | 2++
3 files changed, 61 insertions(+), 58 deletions(-)

diff --git a/src/lib/leaflet.control.track-list/lib/geo_file_exporters.js b/src/lib/leaflet.control.track-list/lib/geo_file_exporters.js @@ -1,60 +1,7 @@ -import L from 'leaflet'; import utf8 from 'utf8'; import escapeHtml from 'escape-html'; import {saveNktk} from './parsers/nktk'; -function getSegmentLatForLng(latLng1, latLng2, lng) { - const deltaLat = latLng2.lat - latLng1.lat; - const deltaLng = latLng2.lng - latLng1.lng; - return latLng1.lat + deltaLat / deltaLng * (lng - latLng1.lng); -} - -function splitLineAt180Meridian(latLngs) { - const wrappedLatLngs = latLngs.map((ll) => ll.wrap()); - const newLines = []; - if (latLngs.length < 2) { - return newLines; - } - - let newLine = [wrappedLatLngs[0]]; - newLines.push(newLine); - for (let i = 1; i < wrappedLatLngs.length; i++) { - let latLng = wrappedLatLngs[i]; - let prevLatLng = wrappedLatLngs[i - 1]; - if (Math.abs(latLng.lng - prevLatLng.lng) <= 180) { - newLine.push(latLng); - } else { - let positiveLng = L.Util.wrapNum(latLng.lng, [0, 360]); - let positivePrevLng = L.Util.wrapNum(prevLatLng.lng, [0, 360]); - let splitLng = 180 - 0.000001 * Math.sign(latLng.lng); - let splitPrevLng = 180 - 0.000001 * Math.sign(prevLatLng.lng); - let splitLat = getSegmentLatForLng( - L.latLng(prevLatLng.lat, positivePrevLng), - L.latLng(latLng.lat, positiveLng), - splitLng - ); - let splitPrevLat = getSegmentLatForLng( - L.latLng(prevLatLng.lat, positivePrevLng), - L.latLng(latLng.lat, positiveLng), - splitPrevLng - ); - newLine.push(L.latLng(splitPrevLat, splitPrevLng).wrap()); - newLine = [L.latLng(splitLat, splitLng).wrap(), latLng]; - newLines.push(newLine); - } - } - return newLines; -} - -function normalizeLines(lines) { - return (lines || []) - .map((segment) => splitLineAt180Meridian(segment)) - .reduce((acc, cur) => { - acc.push(...cur); - return acc; - }, []); -} - function saveGpx(segments, name, points, withElevations=false) { const gpx = []; const fakeTime = '1970-01-01T00:00:01.000Z'; @@ -77,15 +24,14 @@ function saveGpx(segments, name, points, withElevations=false) { gpx.push('\t</wpt>'); } ); - const normalizedSegments = normalizeLines(segments); - if (normalizedSegments.length > 0) { + if (segments.length > 0) { name = name || 'Track'; name = escapeHtml(name); name = utf8.encode(name); gpx.push('\t<trk>'); gpx.push('\t\t<name>' + name + '</name>'); - for (let segment of normalizedSegments) { + for (let segment of segments) { gpx.push('\t\t<trkseg>'); for (let point of segment) { let x = point.lng.toFixed(6); @@ -114,8 +60,7 @@ function saveKml(segments, name, points) { kml.push('\t<Document>'); kml.push(`\t\t<name>${name}</name>`); - const normalizedSegments = normalizeLines(segments); - for (let [i, segment] of normalizedSegments.entries()) { + for (let [i, segment] of segments.entries()) { kml.push('\t\t<Placemark>'); kml.push(`\t\t\t<name>Line ${(i + 1)}</name>`); kml.push('\t\t\t<LineString>'); diff --git a/src/lib/leaflet.control.track-list/lib/meridian180.js b/src/lib/leaflet.control.track-list/lib/meridian180.js @@ -0,0 +1,56 @@ +import L from "leaflet"; + +function getSegmentSplitPointLat(latLng1, latLng2, lng) { + const deltaLat = latLng2.lat - latLng1.lat; + const deltaLng = latLng2.lng - latLng1.lng; + return latLng1.lat + deltaLat / deltaLng * (lng - latLng1.lng); +} + +function splitLineAt180Meridian(latLngs) { + // this function also creates new LatLng object for all elements + const wrappedLatLngs = latLngs.map((ll) => ll.wrap()); + const newLines = []; + if (latLngs.length < 2) { + return newLines; + } + + let newLine = [wrappedLatLngs[0]]; + newLines.push(newLine); + for (let i = 1; i < wrappedLatLngs.length; i++) { + let latLng = wrappedLatLngs[i]; + let prevLatLng = wrappedLatLngs[i - 1]; + if (Math.abs(latLng.lng - prevLatLng.lng) <= 180) { + newLine.push(latLng); + } else { + let positiveLng = L.Util.wrapNum(latLng.lng, [0, 360]); + let positivePrevLng = L.Util.wrapNum(prevLatLng.lng, [0, 360]); + let splitLng = 180 - 0.000001 * Math.sign(latLng.lng); + let splitPrevLng = 180 - 0.000001 * Math.sign(prevLatLng.lng); + let splitLat = getSegmentSplitPointLat( + L.latLng(prevLatLng.lat, positivePrevLng), + L.latLng(latLng.lat, positiveLng), + splitLng + ); + let splitPrevLat = getSegmentSplitPointLat( + L.latLng(prevLatLng.lat, positivePrevLng), + L.latLng(latLng.lat, positiveLng), + splitPrevLng + ); + newLine.push(L.latLng(splitPrevLat, splitPrevLng).wrap()); + newLine = [L.latLng(splitLat, splitLng).wrap(), latLng]; + newLines.push(newLine); + } + } + return newLines; +} + +function splitLinesAt180Meridian(lines) { + return (lines || []) + .map((segment) => splitLineAt180Meridian(segment)) + .reduce((acc, cur) => { + acc.push(...cur); + return acc; + }, []); +} + +export {splitLinesAt180Meridian}; diff --git a/src/lib/leaflet.control.track-list/track-list.js b/src/lib/leaflet.control.track-list/track-list.js @@ -24,6 +24,7 @@ import {fetch} from '~/lib/xhr-promise'; import config from '~/config'; import md5 from 'blueimp-md5'; import {wrapLatLngToTarget, wrapLatLngBoundsToTarget} from '~/lib/leaflet.fixes/fixWorldCopyJump'; +import {splitLinesAt180Meridian} from "./lib/meridian180"; const TRACKLIST_TRACK_COLORS = ['#77f', '#f95', '#0ff', '#f77', '#f7f', '#ee5']; @@ -539,6 +540,7 @@ L.Control.TrackList = L.Control.extend({ return line.getLatLngs(); } ); + lines = splitLinesAt180Meridian(lines); var points = this.getTrackPoints(track); var name = track.name(), i = name.lastIndexOf('.');