Skip to content

Commit

Permalink
-
Browse files Browse the repository at this point in the history
  • Loading branch information
BB committed Nov 15, 2023
1 parent 848a0cc commit 9e23c4a
Show file tree
Hide file tree
Showing 3 changed files with 325 additions and 0 deletions.
57 changes: 57 additions & 0 deletions path/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
crossorigin=""/>
<link rel="stylesheet" href="../bbmain.css">
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1548953794786292"
crossorigin="anonymous"></script>
</head>

<script src="https://unpkg.com/[email protected]/dist/leaflet.js"
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
crossorigin=""></script>

<script src="../common.js"></script>
<script src="path.js"></script>
<script src="polyline.js"></script>

<body onload='init()'>

<div class="bbheader">
<h1><a href="..">BBApps</a></h1>
<p>Path</p>
</div>

<div id="bbmain">

From
<input id="coordfr" type="text" name="coordfr" placeholder="latitude,longitude"/>
<button onclick="setCurrentFrom()">Use Current</button>
<button onclick="setPickerFrom()">Use Picker</button>
<br/>
<br/>

To &nbsp;&nbsp;&nbsp;&nbsp;
<input id="coordto" type="text" name="coordto" placeholder="latitude,longitude"/>
<button onclick="setCurrentTo()">Use Current</button>
<button onclick="setPickerTo()">Use Picker</button>
<br/>
<br/>
<button onclick="shortest()">Path</button>
<button onclick="markLocation()">Mark</button>

<br/>

<div id="map"></div>

<div><br/><a href="../index.html">Up</a></div>

</div>

</body>

</html>

107 changes: 107 additions & 0 deletions path/path.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@

var LeafIcon = L.Icon.extend({
options: {
shadowUrl: '../travel/marker-shadow.png',
iconSize: [20, 40],
shadowSize: [25, 30],
iconAnchor: [10, 45],
shadowAnchor: [2, 30],
popupAnchor: [-1, -30]
}
});

var currLocMarker = null;

function markLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(markLocationCallback);
}
}

function markLocationCallback(position) {
lat = position.coords.latitude;
lon = position.coords.longitude;
var orangeIcon = new LeafIcon({iconUrl: '../travel/marker-icon-2x-orange.png'});
if (typeof lat !== 'undefined') {
if (currLocMarker != null) {
map.removeLayer(currLocMarker);
}
currLocMarker = L.marker([lat,lon], {icon: orangeIcon});
currLocMarker.addTo(map);
}

}

function setCurrentFrom() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(setCurrentFromCallback);
}
}

function setCurrentFromCallback(position) {
lat = position.coords.latitude;
lon = position.coords.longitude;
document.getElementById("coordfr").value = lat + "," + lon;
}

function setCurrentTo() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(setCurrentToCallback);
}
}

function setCurrentToCallback(position) {
lat = position.coords.latitude;
lon = position.coords.longitude;
document.getElementById("coordto").value = lat + "," + lon;
}

function setPickerFrom() {
coords = prefs['picker']['coord'].split(" ");
lat = parseFloat(coords[0]);
lon = parseFloat(coords[1]);
document.getElementById("coordfr").value = lat + "," + lon;
}

function setPickerTo() {
coords = prefs['picker']['coord'].split(" ");
lat = parseFloat(coords[0]);
lon = parseFloat(coords[1]);
document.getElementById("coordto").value = lat + "," + lon;
}

function init() {
init_cookies();
}

function shortest() {

//var [lat1, lon1] = [40.976010662280586, 29.081443051759983];
//var [lat2, lon2] = [37.377289145215066, 27.295607731239233];
coords = document.getElementById("coordfr").value.split(",");
var [lat1, lon1] = coords;
coords = document.getElementById("coordto").value.split(",");
var [lat2, lon2] = coords;

url = `http://router.project-osrm.org/route/v1/car/${lon1},${lat1};${lon2},${lat2}?alternatives=false`;

var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", url = url, false );
xmlHttp.send( null );
result = JSON.parse(xmlHttp.responseText);
encoded = result['routes'][0]['geometry'];
var coordinates = polyline.decode(encoded);
var c = coordinates[0];

map = L.map('map').setView([c[0],c[1]], 7);

L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: 'OSM'
}).addTo(map);

var line = new L.Polyline(coordinates, {
color: 'red', weight: 2, opacity: 0.5, smoothFactor: 1
});
line.addTo(map);
}
161 changes: 161 additions & 0 deletions path/polyline.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
'use strict';

/**
* Based off of [the offical Google document](https://developers.google.com/maps/documentation/utilities/polylinealgorithm)
*
* Some parts from [this implementation](http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/PolylineEncoder.js)
* by [Mark McClure](http://facstaff.unca.edu/mcmcclur/)
*
* @module polyline
*/

var polyline = {};

function py2_round(value) {
// Google's polyline algorithm uses the same rounding strategy as Python 2, which is different from JS for negative values
return Math.floor(Math.abs(value) + 0.5) * (value >= 0 ? 1 : -1);
}

function encode(current, previous, factor) {
current = py2_round(current * factor);
previous = py2_round(previous * factor);
var coordinate = (current - previous) * 2;
if (coordinate < 0) {
coordinate = -coordinate - 1
}
var output = '';
while (coordinate >= 0x20) {
output += String.fromCharCode((0x20 | (coordinate & 0x1f)) + 63);
coordinate /= 32;
}
output += String.fromCharCode((coordinate | 0) + 63);
return output;
}

/**
* Decodes to a [latitude, longitude] coordinates array.
*
* This is adapted from the implementation in Project-OSRM.
*
* @param {String} str
* @param {Number} precision
* @returns {Array}
*
* @see https://github.com/Project-OSRM/osrm-frontend/blob/master/WebContent/routing/OSRM.RoutingGeometry.js
*/
polyline.decode = function(str, precision) {
var index = 0,
lat = 0,
lng = 0,
coordinates = [],
shift = 0,
result = 0,
byte = null,
latitude_change,
longitude_change,
factor = Math.pow(10, Number.isInteger(precision) ? precision : 5);

// Coordinates have variable length when encoded, so just keep
// track of whether we've hit the end of the string. In each
// loop iteration, a single coordinate is decoded.
while (index < str.length) {

// Reset shift, result, and byte
byte = null;
shift = 1;
result = 0;

do {
byte = str.charCodeAt(index++) - 63;
result += (byte & 0x1f) * shift;
shift *= 32;
} while (byte >= 0x20);

latitude_change = (result & 1) ? ((-result - 1) / 2) : (result / 2);

shift = 1;
result = 0;

do {
byte = str.charCodeAt(index++) - 63;
result += (byte & 0x1f) * shift;
shift *= 32;
} while (byte >= 0x20);

longitude_change = (result & 1) ? ((-result - 1) / 2) : (result / 2);

lat += latitude_change;
lng += longitude_change;

coordinates.push([lat / factor, lng / factor]);
}

return coordinates;
};

/**
* Encodes the given [latitude, longitude] coordinates array.
*
* @param {Array.<Array.<Number>>} coordinates
* @param {Number} precision
* @returns {String}
*/
polyline.encode = function(coordinates, precision) {
if (!coordinates.length) { return ''; }

var factor = Math.pow(10, Number.isInteger(precision) ? precision : 5),
output = encode(coordinates[0][0], 0, factor) + encode(coordinates[0][1], 0, factor);

for (var i = 1; i < coordinates.length; i++) {
var a = coordinates[i], b = coordinates[i - 1];
output += encode(a[0], b[0], factor);
output += encode(a[1], b[1], factor);
}

return output;
};

function flipped(coords) {
var flipped = [];
for (var i = 0; i < coords.length; i++) {
var coord = coords[i].slice();
flipped.push([coord[1], coord[0]]);
}
return flipped;
}

/**
* Encodes a GeoJSON LineString feature/geometry.
*
* @param {Object} geojson
* @param {Number} precision
* @returns {String}
*/
polyline.fromGeoJSON = function(geojson, precision) {
if (geojson && geojson.type === 'Feature') {
geojson = geojson.geometry;
}
if (!geojson || geojson.type !== 'LineString') {
throw new Error('Input must be a GeoJSON LineString');
}
return polyline.encode(flipped(geojson.coordinates), precision);
};

/**
* Decodes to a GeoJSON LineString geometry.
*
* @param {String} str
* @param {Number} precision
* @returns {Object}
*/
polyline.toGeoJSON = function(str, precision) {
var coords = polyline.decode(str, precision);
return {
type: 'LineString',
coordinates: flipped(coords)
};
};

if (typeof module === 'object' && module.exports) {
module.exports = polyline;
}

0 comments on commit 9e23c4a

Please sign in to comment.