Reputation: 477
I want to display kilometers markings along a route drawn with addlayer: line. With @turf/along, I can calculate the coordinates for the distance markings, but what would be a good way of displaying them on the map? Non-turf related methods are also welcome.
I want to display the coordinates either on the route line itself, or below the line between a certain meter span, like per 100m.
Upvotes: 2
Views: 2476
Reputation: 477
For my purposes, I wanted to display a distance label along the route line for each full kilometer (that's why routeDistance is floored).
//distanceLabel object
var distanceLabels = {
"type": "FeatureCollection",
"features": []
}
//added it as a map source
map.addSource('distanceLabels', {
"type": "geojson",
"data": distanceLabels
})
//added distancLabels as a map layer
map.addLayer({
"id": "distanceLabels",
"type": "symbol",
"source": "distanceLabels",
"paint": {
'text-color': '#000000'
},
"layout": {
'symbol-placement': 'point',
'text-font': ['Open Sans Regular','Arial Unicode MS Regular'],
'text-field': '{distance}\n{unit}',
'text-anchor': 'center',
'text-justify': 'center',
'text-size': 13,
'icon-allow-overlap': true,
'icon-ignore-placement': true
}
})
//render labels function
renderDistanceMarkers() {
var unit = this.isMetric == true ? 'kilometers' : 'miles'
var unitShort = this.isMetric == true ? 'km' : 'mi'
//calculate line distance to determine the placement of the labels
var routeDistance = turf.length(route.features[0], {units: unit})
//rounding down kilometers (11.76km -> 11km)
routeDistance = Math.floor(routeDistance)
var points = []
//only draw labels if route is longer than 1km
if(routeDistance !== 0) {
// Draw an arc between the `origin` & `destination` of the two points
for (var i = 0; i < routeDistance + 1; i++) {
var segment = turf.along(route.features[0], i, {units: unit})
if(i !== 0) { //Skip the initial point (start coordinate)
points.push({
"type": "Feature",
"properties": {'unit': unitShort},
"geometry": {
"type": "Point",
"coordinates": segment.geometry.coordinates
}
})
}
}
distanceLabels.features = points
//update distances for the label texts
for(var i = 0; i < points.length; i++) {
distanceLabels.features[i].properties.distance = i + 1 //First one would be 0
}
//render now labels
map.getSource('distanceLabels').setData(distanceLabels)
}
},
Upvotes: 2
Reputation: 797
You can create a new layer of type symbol
for your distance label.
Since you already are able to calculate its coordinates, all you have left to do is create a source with these coordinates and connect it to a layout with the following fields:
text-field
with the distance string (eg. 'text-field': '{distance}km'
if you set the distance in the source properties)text-offset
with the relative offset relative to its center. NB: the unit is ems
, not meters.Example (not tested):
{
id: 'distance-label',
type: 'symbol',
source: 'distance-labels',
paint: {
'text-color': '#00f'
},
layout: {
'symbol-placement': 'point',
'text-font': ['Open Sans Regular','Arial Unicode MS Regular'],
'text-field': '{distance}km',
'text-offset': [0, -0.6],
'text-anchor': 'center',
'text-justify': 'center',
'text-size': 12,
}
}
Upvotes: 1