Как правильно установить радиус круга в OpenLayers для конкретной единицы измерения? - PullRequest
1 голос
/ 23 сентября 2019

Я пытаюсь создать круг с определенным радиусом на земле в OpenLayers v5.Но я, кажется, не понимаю, как создать его с определенной единицей измерения, такой как метры, мили и т. Д. Аргумент радиуса в конструкторе выглядит как неуказанная единица карты, как отмечено в этой проблеме , что завершается использованием метода getMetersPerUnit из проекции.Однако каждый раз, когда вызывается этот метод, кажется, что он всегда возвращает 1. Я также смотрел, как что-то делать с экспортом METERS_PER_UNIT в библиотеке проекций, но, опять же, значение для метров равно 1.

Мой рисунок пытается дать хорошую отправную точку, основанную на экстенте текущего вида.Предыдущая работа использовала 1/8 бокового расстояния текущего вида.

function getRoundedEigthedDistanceBetweenPoints(coordinateA, coordinateB) {
  /**
   * Distance between bottom right and left corners in meters
   * We want 1/8 of the distance, rounded to nearest 10?
   * Why? /shrug ?‍♂️
   */
  return (getDistanceBetweenPoints(coordinateA, coordinateB) / 8 / 10) * 10;
}

/**
 * @link https://stackoverflow.com/a/28454386/168005
 * @param coordA
 * @param coordB
 */
function getDistanceBetweenPoints(coordA, coordB) {
  return (new LineString([coordA, coordB]).getLength() * 100) / 100;
}

const [minX, _, maxX, __] = map.getView().calculateExtent();

// Since all I want is a straight line, I just give it the minX and maxX values, and zero out the "Y"s. 
const startingDistance = getRoundedEigthedDistanceBetweenPoints([minX, 0], [maxX, 0]);

Учитывая вышеизложенное, я предполагал, что результат startingDistance был в метрах.Но если я сравниваю значения моих кругов с нормальной длиной LineString, цифры немного сбиваются.

Проблема усугубляется, когда я пытаюсь изменить радиус позже по сравнению с пользовательским вводом, потому что я думал, что работаю в метрах (очевидно, это не так), поэтому я преобразую предоставленные значения в метры и устанавливаю егопрямо как радиус.

enum Units {
  Meters = "m",
  Miles = "mi",
  Kilometers = "km",
  Feet = "ft",
}

const METERS_PER_FEET = 0.3048;
const FEET_PER_MILE = 5280;
const METERS_PER_KILO = 1000;

function convertFeetToMeters(feet) {
  return feet * METERS_PER_FEET;
}

function convertMilesToMeters(miles) {
  return miles * METERS_PER_MILE;
}

function convertMetersToKilometers(meters) {
  return meters / METERS_PER_KILO;
}

function convertUnitToMeters(unit: Units, value: number) {
  switch (unit) {
    case Units.Feet:
      return convertFeetToMeters(value);
    case Units.Miles:
      return convertMilesToMeters(value);
    case Units.Kilometers:
      return convertKilometersToMeters(value);
    default:
      return value;
  }
}

function updateFeature({ type, feature, unit, value }) {
  /**
   * Mutably make the change
   */
  if (type === "radius" || type === "unit") {
    // Take in the units listed in the UI and convert the value, respectively.
    const computedRadius = convertUnitToMeters(unit.value, parseFloat(value));
    feature.getGeometry().setRadius(computedRadius);
  }
}

Я знаю, что это целое бизнес искажения Web Mercator , и использование чего-то вроде getLength из модуля ol/sphere преобразует радиус из уже созданного круга, но как насчет установки радиуса круга?Есть ли инструмент для этого?

1 Ответ

0 голосов
/ 24 сентября 2019

Если радиус будет таким маленьким, как 100км - 1000км, тогда может возникнуть проблема с проекцией.Я решил это, разделив радиус на

ol.proj.getPointResolution('EPSG:3857', 1, centerLongitudeLatitude)

, где centerLongitudeLatitude - центр круга.Вот код для отображения круга на карте

geometry:new ol.geom.Circle(centerLongitudeLatitude,200*1000/ol.proj.getPointResolution('EPSG:3857', 1, centerLongitudeLatitude)),
...