Skip to content

Commit

Permalink
complete save/load functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
amccafferty42 committed Jul 16, 2024
1 parent 5d1eb5d commit 78f45b5
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 104 deletions.
2 changes: 1 addition & 1 deletion src/exportRoute.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ function exportGeoJSON() {
}
}

//trimming coordinates is necessary because official GeoJSON standard states that coordinates[] should have no more than three items for [lat, long, elev]. distance needs to be appended for the elevation chart to loasdf,
//trimming coordinates is necessary because official GeoJSON standard states that coordinates[] should have no more than three items for [lat, long, elev]. distance needs to be appended for the elevation chart to load,
function trimCoordinates(featureCollection) {
for (const feature of featureCollection.features) {
if (feature.geometry != undefined && feature.geometry.coordinates != undefined) {
Expand Down
6 changes: 3 additions & 3 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8" />
<title>Itinerary Planning Tool</title>
<link rel="icon" href="resources/trailtuner-icon.png" type="image/x-icon" onclick="refresh()">
<link rel="icon" href="resources/trailtuner-icon.png" type="image/x-icon">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.3.0/font/bootstrap-icons.css">
Expand All @@ -29,7 +29,7 @@ <h4 class="modal-title change-trail-title">Upload Trail</h4>
<br>
<div class="upload">
<div class="upload-trail">
<input type="file" id="trailFile" name="filename" accept=".json" onchange="readFileTrail(this)">
<input type="file" id="trailFile" name="filename" accept=".json" onchange="readFile(this, false)">
</div>
</div>
<br>
Expand All @@ -45,7 +45,7 @@ <h4 class="modal-title change-trail-title">Upload Route</h4>
<br>
<div class="upload">
<div class="upload-trail">
<input type="file" id="trailFile" name="filename" accept=".json" onchange="readFileRoute(this)">
<input type="file" id="routeFile" name="filename" accept=".json" onchange="readFile(this, true)">
</div>
</div>
</div>
Expand Down
159 changes: 59 additions & 100 deletions src/loadTrail.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,68 @@ const toggleTrailheads = document.getElementById('toggle-trailheads');
const toggleCampsites = document.getElementById('toggle-campsites');

setTrailFromURL();
setTrailDetails(trail);
setTrailDetails();
initMap();
initChart();

function refresh() {
location.reload();
function loadTrail(geoJSON) {
trail = geoJSON;
setTrailDetails();
reset();
initMap();
initChart();
}

function loadRoute(geoJSON) {
const trail = geoJSON.properties.trail;
loadTrail(trail);
const route = geoJSON.properties.route;
for (const day of route) {
day.date = new Date(day.date);
if (!day.prev_site) day.prev_site = undefined;
if (!day.next_site) day.next_site = undefined;
}
this.route = route;
filterCampsites(campsiteFeatures);
this.isPositiveDirection = getDirection(route[0].start, route[route.length - 1].end);
displayRoute(route, true);
routeTitle.scrollIntoView({behavior: 'smooth'});
}

function onTrailSelect() {
trail = trails[selectTrail.value].geoJSON;
loadTrail(trail);
closeTrailModal();
}

function readFile(input, isRoute) {
let file = input.files[0];
let fileReader = new FileReader();
fileReader.readAsText(file);
fileReader.onload = function() {
const geoJSON = JSON.parse(fileReader.result);
if (isRoute) loadRoute(geoJSON);
else loadTrail(geoJSON);
closeTrailModal();
};
fileReader.onerror = function() {
alert(fileReader.error);
};
}

function loadRoute(file) {
const route = JSON.parse(file);
console.log(route.properties.trail);
changeTrail(route.properties.trail);
function closeTrailModal() {
document.getElementById('trailFile').value = '';
document.getElementById('routeFile').value = '';
$('#changeTrail').modal('hide');
}

function setTrailFromURL() {
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
if (urlParams.has('trail')) {
const matchTrail = trails.filter((x) => x.name == urlParams.get('trail').replaceAll("_", " "));
trail = (matchTrail === undefined || matchTrail.length === 0) ? trail = trails[0].geoJSON : matchTrail[0].geoJSON;
}
}

function toggleIconVisibility() {
Expand All @@ -50,7 +100,7 @@ function toggleIconVisibility() {
}

// Validate trail and set details
function setTrailDetails(trail) {
function setTrailDetails() {
trailFolder = undefined;
trailheadFolder = undefined;
campsiteFolder = undefined;
Expand All @@ -62,30 +112,22 @@ function setTrailDetails(trail) {
for (feature of trail.features) {
if (feature.properties.class === "Folder" && feature.properties.title.toUpperCase() === "TRAIL") {
if (!trailFolder) trailFolder = feature;
else return;
} else if (feature.properties.class === "Folder" && feature.properties.title.toUpperCase() === "TRAILHEADS") {
if (!trailheadFolder) trailheadFolder = feature;
else return;
} else if (feature.properties.class === "Folder" && feature.properties.title.toUpperCase() === "CAMPSITES") {
if (!campsiteFolder) campsiteFolder = feature;
else return;
}
}
if (!campsiteFolder || !trailheadFolder || !trailFolder) return;

for (feature of trail.features) {
if (feature.geometry && feature.geometry.type === "LineString" && feature.properties.folderId == trailFolder.id) {
if (!trailFeature) trailFeature = feature;
else return;
trailFeature = feature;
} else if (feature.geometry && feature.geometry.type === "Point" && feature.properties.folderId == trailheadFolder.id) {
trailheadFeatures.push(feature);
} else if (feature.geometry && feature.geometry.type === "Point" && feature.properties.folderId == campsiteFolder.id) {
campsiteFeatures.push(feature);
}
}
if (!trailFeature || !trailFeature.properties || !trailFeature.properties.title || trailFeature.properties.title.length > 30 || trailFeature.geometry.coordinates.length < 20) return;
if (trailheadFeatures.length <= 1) return;
if (campsiteFeatures.length <= 0) return;

trailName = trailFeature.properties.title;
trailLength = calculateLength(trailFeature.geometry.coordinates);
Expand Down Expand Up @@ -116,9 +158,6 @@ function setTrailDetails(trail) {
campsiteFeatures.sort((a, b) => {return a.properties.distance - b.properties.distance});
for (let i = 0; i < campsiteFeatures.length; i++) campsiteFeatures[i].properties.index = i;

if (trailCircuit && campsiteFeatures[0].properties.distance != 0) return;
// else if (!trailCircuit && campsiteFeatures[0].properties.distance != 0 && campsiteFeatures[campsiteFeatures.length - 1].properties.distance != trailLength) return;

console.info(trailFeature);
console.info(trailheadFeatures);
console.info(campsiteFeatures);
Expand Down Expand Up @@ -171,83 +210,6 @@ function appendDistance(feature) {
}
}

// Load selected trail and reset
function onTrailSelect() {
trail = trails[selectTrail.value].geoJSON;
setTrailDetails(trail);
reset();
initMap();
initChart();
selectTrail.value = "";
$('#changeTrail').modal('hide');
}

function setTrailFromURL() {
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
if (urlParams.has('trail')) {
const matchTrail = trails.filter((x) => x.name == urlParams.get('trail').replaceAll("_", " "));
trail = (matchTrail === undefined || matchTrail.length === 0) ? trail = trails[0].geoJSON : matchTrail[0].geoJSON;
}
}

function readFileTrail(input) {
let file = input.files[0];
let fileReader = new FileReader();
fileReader.readAsText(file);
fileReader.onload = function() {
changeTrail(fileReader.result)
};
fileReader.onerror = function() {
alert(fileReader.error);
};
}

function readFileRoute(input) {
let file = input.files[0];
let fileReader = new FileReader();
fileReader.readAsText(file);
fileReader.onload = function() {
loadRoute(fileReader.result)
};
fileReader.onerror = function() {
alert(fileReader.error);
};
}

function changeTrail(file) {
const newTrail = validJson(file);
if (newTrail) {
trail = newTrail;
reset();
initMap();
document.getElementById('trailFile').value = '';
$('#changeTrail').modal('hide');
}
}

function validJson(file) {
try {
const trail = JSON.parse(file);
let numTrailFolders = 0, numTrailheadFolders = 0, numCampsiteFolders = 0;
for (feature of trail.features) {
if (!feature.geometry) {
if (feature.properties.title === 'Trailheads') numTrailheadFolders++;
else if (feature.properties.title === 'Campsites') numCampsiteFolders++;
else if (feature.properties.title === 'Trail') numTrailFolders++;
}
}
if (numTrailFolders != 1 || numTrailheadFolders != 1 || numCampsiteFolders != 1) return false;
setTrailDetails(trail); //set trail details to verify each marker is on trail and has "distance" appended to the properties
for (campsite of campsiteFeatures) if (campsite.properties.distance === undefined) return false;
for (trailhead of trailheadFeatures) if (trailhead.properties.distance === undefined) return false;
return trail;
} catch (e) {
console.error(e);
}
return false;
}

// Return whether or not point C is on the segment of the line passing through the points A and B
function inLine(a, b, c) {
const dxc = c[0] - a[0];
Expand All @@ -267,19 +229,16 @@ function inLine(a, b, c) {
function calculateElevation(lineString) {
let elevationGain = 0;
let elevationLoss = 0;

for (let i = 1; i < lineString.coordinates.length; i++) {
const currentElevation = lineString.coordinates[i][2] || 0; // If elevation is not present, assume 0
const previousElevation = lineString.coordinates[i - 1][2] || 0;
const elevationDifference = currentElevation - previousElevation;

if (elevationDifference > 0) {
elevationGain += elevationDifference;
} else {
elevationLoss -= elevationDifference; // Using subtraction to get positive value
}
}

return { elevationGain, elevationLoss };
}

Expand Down

0 comments on commit 78f45b5

Please sign in to comment.