#javascript #node.js #npm #gpx #openlayers-5
#javascript #node.js #npm #gpx #openlayers-5
Вопрос:
Я показываю карту с GPX-дорожкой, используя openlayers 5.3. Точки отслеживания в OL по умолчанию имеют тип геометрии MultiLineString. В примере GPX размер gpx-файла в два раза больше, поскольку все <trkpt>
теги дублируются как <rtept>
теги. Routepoints получает тип геометрии Point в OL.
Теперь я хотел бы добавить слой, показывающий trkpt в виде точечного типа, и создать всплывающие окна, показывающие значения <ele>
и <time>
тегов внутри <trkpt>
тегов в моем «обычном» gpx-файле.
Есть ли быстрое и / или грязное решение, чтобы убедить OL рассматривать мои точки отслеживания как точки маршрута, чтобы я мог использовать их как тип точки и читать <ele>
и <time>
функции из источника? Или для выполнения этого требуется какая-то другая операция, и если да, то каковы будут мои варианты?
Любая помощь очень ценится!
Ответ №1:
Вы можете создавать точки на основе координат в 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 = 'amp;nbsp;';
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">amp;nbsp;</div>
Комментарии:
1. Это не быстро / грязно, это продуманно и чисто! И работает!