nakarte

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

commit 75c2e5775c42c574e3091d44f823601ae3d8bdf0
parent 7512c5f0ee46810240ca9c1eb9d32345bbb707fa
Author: Sergej Orlov <wladimirych@gmail.com>
Date:   Mon, 19 Mar 2018 20:50:21 +0300

Revert "[tracks] temporary disable creating new links"

This reverts commit 7512c5f0ee46810240ca9c1eb9d32345bbb707fa.

Diffstat:
Msrc/lib/leaflet.control.track-list/lib/nktk.js | 133+++++++++++++++++++++++++------------------------------------------------------
Msrc/lib/leaflet.control.track-list/track-list.js | 19++++++++++++++++++-
2 files changed, 59 insertions(+), 93 deletions(-)

diff --git a/src/lib/leaflet.control.track-list/lib/nktk.js b/src/lib/leaflet.control.track-list/lib/nktk.js @@ -120,103 +120,52 @@ function deltaDecodeSegment(deltaLats, deltaLons) { return points; } -function packNumber(n) { - var bytes = []; - if (n >= -64 && n <= 63) { - n += 64; - bytes.push(n); - } else if (n >= -8192 && n <= 8191) { - n += 8192; - bytes.push((n & 0x7f) | 0x80); - bytes.push(n >> 7); - /* } else if (n >= -2097152 && n <= 2097151) { - n += 2097152; - bytes.push((n & 0x7f) | 0x80); - bytes.push(((n >> 7) & 0x7f) | 0x80); - bytes.push(n >> 14); - */ - } else if (n >= -1048576 && n <= 1048575) { - n += 1048576; - bytes.push((n & 0x7f) | 0x80); - bytes.push(((n >> 7) & 0x7f) | 0x80); - bytes.push(n >> 14); - } else if (n >= -268435456 && n <= 268435455) { - n += 268435456; - bytes.push((n & 0x7f) | 0x80); - bytes.push(((n >> 7) & 0x7f) | 0x80); - bytes.push(((n >> 14) & 0x7f) | 0x80); - bytes.push(n >> 21); - } else { - throw new Error('Number ' + n + ' too big to pack in 29 bits'); - } - return String.fromCharCode.apply(null, bytes); -} - -function saveNktk(segments, name, color, measureTicksShown, wayPoints, trackHidden) { - var stringified = []; - stringified.push(packNumber(3)); // version - name = utf8.encode(name); - stringified.push(packNumber(name.length)); - stringified.push(name); - - var arcUnit = ((1 << 24) - 1) / 360; - segments = segments.filter(function(segment) { - return segment.length > 1; +function saveNktk(segments, name, color, measureTicksShown, waypoints, trackHidden) { + const trackView = { + view: { + color, + shown: !trackHidden, + ticksShown: measureTicksShown, } - ); - - stringified.push(packNumber(segments.length)); - segments.forEach(function(points) { - var lastX = 0, - lastY = 0, - x, y, - deltaX, deltaY, - p; - stringified.push(packNumber(points.length)); - for (var i = 0, len = points.length; i < len; i++) { - p = points[i]; - x = Math.round(p.lng * arcUnit); - y = Math.round(p.lat * arcUnit); - deltaX = x - lastX; - deltaY = y - lastY; - stringified.push(packNumber(deltaX)); - stringified.push(packNumber(deltaY)); - lastX = x; - lastY = y; - } + }; + const track = trackView.track = {name}; + if (segments && segments.length) { + let deltaEncodedSegments = []; + for (let segment of segments) { + let {deltaLats, deltaLons} = deltaEncodeSegment(segment); + deltaEncodedSegments.push({lats: deltaLats, lons: deltaLons}); } - ); - stringified.push(packNumber(+color || 0)); - stringified.push(packNumber(measureTicksShown ? 1 : 0)); - stringified.push(packNumber(trackHidden ? 1 : 0)); - - stringified.push(packNumber(wayPoints.length)); - if (wayPoints.length) { - var midX = 0, midY = 0; - wayPoints.forEach(function(p) { - midX += p.latlng.lng; - midY += p.latlng.lat; - } - ); - midX = Math.round(midX * arcUnit / wayPoints.length); - midY = Math.round(midY * arcUnit / wayPoints.length); - stringified.push(packNumber(midX)); - stringified.push(packNumber(midY)); - wayPoints.forEach(function(p) { - var deltaX = Math.round(p.latlng.lng * arcUnit) - midX, - deltaY = Math.round(p.latlng.lat * arcUnit) - midY, - symbol = 1, - name = utf8.encode(p.label); - stringified.push(packNumber(name.length)); - stringified.push(name); - stringified.push(packNumber(symbol)); - stringified.push(packNumber(deltaX)); - stringified.push(packNumber(deltaY)); + track.segments = deltaEncodedSegments; + } + if (waypoints && waypoints.length) { + let midLon = 0, + midLat = 0; + waypoints.forEach((wp) => { + midLon += wp.latlng.lng; + midLat += wp.latlng.lat; } ); + midLon = Math.round(midLon * arcUnit / waypoints.length); + midLat = Math.round(midLat * arcUnit / waypoints.length); + track.waypoints = { + midLat, midLon + }; + + let packedWaypoints = []; + for (let waypoint of waypoints) { + packedWaypoints.push({ + name: waypoint.label, + lat: Math.round(waypoint.latlng.lat * arcUnit) - midLat, + lon: Math.round(waypoint.latlng.lng * arcUnit) - midLon + }); + } + track.waypoints.waypoints = packedWaypoints; } - - return encodeUrlSafeBase64(stringified.join('')); + const pbf = new Pbf(); + const versionStr = String.fromCharCode(4 + 64); + TrackView.write(trackView, pbf); + const s = versionStr + arrayBufferToString(pbf.finish()); + return encodeUrlSafeBase64(s); } function parseTrackUrlData(s) { diff --git a/src/lib/leaflet.control.track-list/track-list.js b/src/lib/leaflet.control.track-list/track-list.js @@ -20,6 +20,9 @@ import 'lib/leaflet.polyline-edit'; import 'lib/leaflet.polyline-measure'; import logging from 'lib/logging'; import {notify} from 'lib/notifications'; +import {fetch} from 'lib/xhr-promise'; +import config from 'config'; +import md5 from './lib/md5'; const TrackSegment = L.MeasuredLine.extend({ includes: L.Polyline.EditMixin, @@ -463,8 +466,22 @@ L.Control.TrackList = L.Control.extend({ return; } let serialized = tracks.map((track) => this.trackToString(track)).join('/'); - const url = window.location + '&nktk=' + serialized; + const hashDigest = md5(serialized, null, true); + const key = btoa(hashDigest).replace(/\//g, '_').replace(/\+/g, '-').replace(/=/g, ''); + const url = window.location + '&nktl=' + key; copyToClipboard(url, mouseEvent); + fetch(`${config.tracksStorageServer}/track/${key}`, {method: 'POST', data: serialized}).then((xhr) => { + }, + (e) => { + let message = e.message || e; + if (e.xhr.status == 413) { + message = 'track is too big'; + } + logging.captureMessage('Failed to save track to server', + {extra: {status: e.xhr.status, response: e.xhr.responseText}}); + alert('Error making link: ' + message); + } + ); }, copyTrackLinkToClipboard: function(track, mouseEvent) {