I'm showing a map with a GPX-track using openlayers 5.3. Trackpoints in OL default to a MultiLineString geometry type. The GPX-example has a gpx-file that is double the size because all <trkpt>
tags are duplicated as <rtept>
tags. Routepoints get a Point geometry type in OL.
Now I'd like to add a layer showing the trkpt's as a Point type and to create popups showing the values of the <ele>
and <time>
tags inside the <trkpt>
tags in my "regular" gpx-file.
Is there a quick and/or dirty solution to convince OL to treat my trackpoints as routepoints so I can use them as a Point-type and read the <ele>
and <time>
features from the source? Or is some other operation required to accomplish this, and if so, what would be my options?
Any help much appreciated!
You can create points from the coordinates in the linestrings
var map = new ol.Map({
target: "map",
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: new ol.View({
center: ol.proj.fromLonLat([1.3313627, 52.1062152]),
zoom: 15
})
});
var displayFeatureInfo = function(pixel) {
var features = [];
map.forEachFeatureAtPixel(pixel, function(feature) {
features.push(feature);
}, {
layerFilter: function(candidate) { return candidate === gpxPointLayer; }
});
if (features.length > 0) {
var info = [];
var i, ii;
for (i = 0, ii = features.length; i < ii; ++i) {
// display lat, lon, ele and time from the point coordinates
var coordinates = features[i].getGeometry().getCoordinates();
var ll = ol.proj.toLonLat(coordinates.slice(0,2));
var d = new Date();
d.setTime(coordinates[3]*1000);
var llet = ll[1].toFixed(7) + ', ' + ll[0].toFixed(7) + ', ' + coordinates[2] + 'm, ' + d.toUTCString();
info.push(llet);
}
document.getElementById('info').innerHTML = info.join('<br>') || '(unknown)';
map.getTargetElement().style.cursor = 'pointer';
} else {
document.getElementById('info').innerHTML = ' ';
map.getTargetElement().style.cursor = '';
}
};
var gpxPointLayer = new ol.layer.Vector({
source: new ol.source.Vector(),
style: new ol.style.Style({
image: new ol.style.Circle({
fill: new ol.style.Fill({color: 'red'}),
radius: 4
})
})
});
gpxTrackVector = new ol.source.Vector({
url: 'https://www.mikenunn.net/data/melton2bawdsey.gpx',
format: new ol.format.GPX()
});
function addPoints(linestring) {
linestring.getCoordinates().forEach(function(coordinates) {
gpxPointLayer.getSource().addFeature(new ol.Feature(new ol.geom.Point(coordinates)));
});
}
gpxTrackVector.on('addfeature', function(evt){
// create point features from GPX linestring coordinates
if (evt.feature.getGeometry().getType() == 'LineString') {
addPoints(evt.feature.getGeometry());
} else if (evt.feature.getGeometry().getType() == 'MultiLineString') {
evt.feature.getGeometry().getLineStrings().forEach(function(linestring){
addPoints(linestring);
});
}
});
var gpxTrackLayer = new ol.layer.Vector({
source: gpxTrackVector,
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'black',
width: 4
}),
image: new ol.style.Circle({
fill: new ol.style.Fill({color: 'green'}),
radius: 6
})
})
});
map.addLayer(gpxTrackLayer);
map.addLayer(gpxPointLayer);
map.on('pointermove', function(evt) {
if (evt.dragging) {
return;
}
var pixel = map.getEventPixel(evt.originalEvent);
displayFeatureInfo(pixel);
});
html, body {
width: 100%;
height: 100%;
}
.map {
width: 100%;
height: 80%;
}
<link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet" />
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
<div id="map" class="map"></div>
<div id="info"> </div>