Public
Edited
Dec 31, 2023
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
await visibility();
let container = DOM.element("div", {
style: `width:${width *0.75}px;height:${width * 0.75}px`
});
yield container;

const map = L.map(container, {
renderer: L.canvas()
});

// basemap tile
tileProviders(selectedTile).addTo(map);

//gpx layer
let geojsonlayer = L.geoJson(gpxToGeoJson(tracksUploaded), {
// change the style
style: function (feature) {
return {
color: trackColor,
weight: 3
// dashArray: "10, 5"
};
},
// add icons
onEachFeature: function (feature, layer) {
// Create a custom icon
let endIcon = L.icon({
iconUrl: end_icon,
iconSize: [50, 50]
});
let startIcon = L.icon({
iconUrl: start_icon,
iconSize: [50, 50]
});

let firstPoint = feature.geometry.coordinates[0];
let lastPoint =
feature.geometry.coordinates[feature.geometry.coordinates.length - 1];

// L.marker([firstPoint[1], firstPoint[0]], { icon: startIcon }).addTo(map);
// L.marker([lastPoint[1], lastPoint[0]], { icon: endIcon }).addTo(map);
}
});
geojsonlayer.addTo(map);

map.fitBounds(geojsonlayer.getBounds());
map.zoomOut(1);

// legend
let legend = L.control({ position: "bottomleft" });
legend.onAdd = function (map) {
let div = L.DomUtil.create("div", "legend");
// Append the SVG from Plot to the div
div.appendChild(graph);
return div;
};
legend.addTo(map);

invalidation.then(() => {
map.remove();
});
}
Insert cell
// use observable plot to get elevation chart
graph = Plot.plot({
x: {
ticks: 8,
tickFormat: d3.utcFormat("%H:%M")
},

width: 300,
height: 100,
marks: [Plot.ruleY([140]), Plot.lineY(data, { x: "time", y: "elevation" })]
})
Insert cell
Insert cell
Type Markdown, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

Insert cell
Insert cell
// extract chart data from geojson
data = {
let geoJsonData = gpxToGeoJson(tracksUploaded);

// Extract the data
let data = geoJsonData.features[0].properties.elevations.map(
(elevation, i) => {
return {
time: new Date(geoJsonData.features[0].properties.times[i]),
elevation: elevation
};
}
);
return data;
}
Insert cell
// extract GPX data to geojson
function gpxToGeoJson(gpxFile) {
const parser = new DOMParser();
const gpx = parser.parseFromString(gpxFile, "application/xml");

const geojson = {
type: "FeatureCollection",
features: []
};

const trkpts = gpx.documentElement.getElementsByTagName("trkpt");
const coordinates = [];
const elevations = [];
const times = [];
for (let i = 0; i < trkpts.length; i++) {
const trkpt = trkpts[i];
const lat = trkpt.getAttribute("lat");
const lon = trkpt.getAttribute("lon");
const ele = trkpt.getElementsByTagName("ele")[0].childNodes[0].nodeValue;
const time = trkpt.getElementsByTagName("time")[0].childNodes[0].nodeValue;
coordinates.push([parseFloat(lon), parseFloat(lat)]);
elevations.push(parseFloat(ele));
times.push(time);
}

const feature = {
type: "Feature",
geometry: {
type: "LineString",
coordinates: coordinates
},
properties: {
elevations: elevations,
times: times
}
};
geojson.features.push(feature);

return geojson;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more