Как отображать отметки расстояния на линии (Mapbox-gl)?

Я хочу отображать маркировку километров вдоль маршрута, нарисованного с помощью addlayer: line. С помощью @turf/along я могу рассчитать координаты меток расстояний, но как лучше всего отобразить их на карте? Методы, не связанные с газоном, также приветствуются.

Я хочу отображать координаты либо на самой линии маршрута, либо ниже линии между определенным пролетом метра, например, на 100 м.


person Oskar Gusgård    schedule 14.12.2018    source источник


Ответы (2)


Вы можете создать новый слой типа symbol. для вашей метки расстояния.

Поскольку вы уже умеете вычислять его координаты, все, что вам осталось сделать, это создать источник с этими координатами и подключить его к макету со следующими полями:

  • text-field со строкой расстояния (например, 'text-field': '{distance}km', если вы задали расстояние в свойствах источника)
  • text-offset с относительным смещением относительно его центра. NB: единицей измерения является ems, а не метры.

Пример (не проверено):

{
  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,
  }
}
person MeltedPenguin    schedule 14.12.2018
comment
Спасибо MeltedPenguin, это очень помогло! - person Oskar Gusgård; 19.12.2018

Для моих целей я хотел отображать метку расстояния вдоль линии маршрута для каждого полного километра (поэтому routeDistance является напольным).

//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)

  }
},
person Oskar Gusgård    schedule 19.12.2018
comment
У вас есть рабочий пример того, как вы этого добились, или вы разместили этот код? Я тоже пытаюсь сделать что-то подобное. - person FabricioG; 20.02.2020