你可以使用线型字符串的.getCoordinateAt()方法来插值到其长度的一小部分,所以如果你计算总长度,你可以得到每公里的位置。
source.on('addfeature', function(event) {
var lineString = event.feature.getGeometry();
if (lineString.getType() == 'MultiLineString') {
lineString = lineString.getLineString(0);
}
var totalKm = ol.sphere.getLength(lineString);
var previous = lineString.getCoordinateAt(0);
for (var i = 1; i <= totalKm; i++) {
var position = lineString.getCoordinateAt(i / totalKm);
var time = position[3] - previous[3];
var elev = position[2] - previous[2];
var previous = position;
}
}
这是我用PHP和MySQL的解决方案。我在PHP中分析GPX和保存公里数到MySQL.So。
$sql_km = mysqli_query($conn, "SELECT km, elevation,time,length FROM gpx_kms WHERE gpx=".$_GET['activity']." ORDER BY km");
if(mysqli_num_rows($sql_km)>0){
echo "<h2>Kilometers:</h2>
<table>";
$i=0;
while($d=mysqli_fetch_assoc($sql_km)){
echo "<tr style='cursor:help' onmouseover='highlight_km(map, ".$d['km'].")' onmouseout='highlight_km(map, 0)'><td>".($d['length']<1 ? round($d['km']-1+$d['length'], 1) : $d['km']).".</td><td>".($d['elevation']>0 ? '▲' : '▼')." ".$d['elevation']." m</td><td>🕐 ".gmdate('H:i:s', $d['time'])."</td><td>".round(1/$d['time']*3600, 2)." km/h</td></tr>";
$i++;
}
echo "</table>";
}
标签tr有mouseover,所以。
var source = new ol.source.Vector(
{
url: '/gpx...',
format: new ol.format.GPX(),
});
function highlight_km(map, highlightKm){
if(highlightKm == 0){
map.getLayers().forEach(layer => {
if (layer && layer.get('name') === 'km') {
map.removeLayer(layer);
}
});
}
else{
window.km = highlightKm;
var highlight = new ol.layer.VectorImage(
{ source: source,
style: styleKm,
name: 'km'
});
map.addLayer(highlight);
}
}
我使用ol-ext中的这个FlowLine样式。
function styleKm(f) {
return new ol.style.FlowLine({
color: function(f, step){
var line = f.getGeometry().getLineString(0);
var km = step*line.getLength()/1527; // I don't know why /1527 but it's ok
if(km>=Math.round(window.km-1) && km<window.km){ return '#fff'; } else { return '#000'; }
},
width: 5,
geometry: function (f) {
if (f.getGeometry().getType() === 'MultiLineString') {
return f.getGeometry().getLineString(0);
} else {
return f.getGeometry();
}
}
});
}