Openlayers 3 Радиус на кръга в метри

Как да получа радиус на окръжност в метри Може да е това съществува въпрос, но не получавам правилен резултат. Опитвам се да създам Polygon в postgis със същия радиус и център, получавайки се от кръга на openlayers.

За да получа радиус в метри, последвах това. Изпълняваща се примерна връзка.

var radiusInMeters = circleRadius * ol.proj.METERS_PER_UNIT['m'];

След получаване на център, радиус (в метри) се опитвам да генерирам многоъгълник (WKT) с postgis (сървърна работа) и чертая тази функция в карта като това.

select st_astext(st_buffer('POINT(79.25887485937808 17.036647682474722 0)'::geography, 365.70644956827164));

Но и двете не покриват една и съща област. Може ли някой да ме уведоми къде греша?

По принцип моят вход/изход към/от Circle ще бъде само в метри.


person Dyapa Srikanth    schedule 25.08.2015    source източник


Отговори (2)


ol.geom.Circle може да не представлява кръг

Геометриите на OpenLayers Circle се дефинират върху проектираната равнина. Това означава, че те винаги са кръгли на картата, но покритата област може да не представлява действителен кръг на земята. Действителната форма и размер на площта, покрита от кръга, ще зависи от използваната проекция.

Това може да се визуализира чрез индикатриса на Тисо, която показва как кръглите зони на земното кълбо се трансформират, когато се проектират върху равнина. Използвайки проекцията EPSG:3857, това ще изглежда така:

„Индикатриса

Изображението е от пример Tissot на OpenLayer 3 и показва области, които всички имат радиус от 800 000 метра. Ако тези кръгове бяха начертани като ol.geom.Circle с радиус 800 000 (използвайки EPSG:3857), всички те биха били с еднакъв размер на картата, но тези, които са по-близо до полюсите, ще представляват много по-малка площ от земното кълбо.

Това е вярно за повечето неща с геометриите на OpenLayers. Радиусът, дължината или площта на дадена геометрия се отчитат в проектираната равнина.

Така че, ако имате ol.geom.Circle, получаването на действителния радиус на повърхността ще зависи от проекцията и местоположението на елементите. За някои прогнози (като EPSG:4326) няма да има точен отговор, тъй като геометрията може дори да не представлява кръгла област.

Въпреки това, ако приемем, че използвате EPSG:3857 и не рисувате изключително големи кръгове или много близо до полюсите, кръгът ще бъде добро представяне на кръгла област.

ol.proj.METERS_PER_UNIT

ol.proj.METERS_PER_UNIT е просто таблица за преобразуване между метри и някои други единици. ol.proj.METERS_PER_UNIT['m'] винаги ще връща 1, тъй като единицата 'm' е метри. EPSG:3857 използва метри като единици, но както беше отбелязано, те са изкривени към полюсите.

Решение (използвайте, след като прочетете и разберете горното)

За да получите действителния земен радиус на ol.geom.Circle, трябва да намерите разстоянието между центъра на кръга и точка на неговия ръб. Това може да стане с помощта на ol.Sphere:

var center = geometry.getCenter()
var radius = geometry.getRadius()
var edgeCoordinate = [center[0] + radius, center[1]];
var wgs84Sphere = new ol.Sphere(6378137);
var groundRadius = wgs84Sphere.haversineDistance(
    ol.proj.transform(center, 'EPSG:3857', 'EPSG:4326'), 
    ol.proj.transform(edgeCoordinate, 'EPSG:3857', 'EPSG:4326')
);

Още опции

Ако искате да добавите геометрия, представляваща кръгла област на земното кълбо, трябва да обмислите използването на метода, използван в примера на Tissot по-горе. Тоест дефиниране на правилен многоъгълник с достатъчно точки, за да изглежда гладък. Това би го направило прехвърляем между проекции и изглежда, че е това, което правите от страна на сървъра. OpenLayers 3 позволява това чрез ol.geom.Polygon.circular:

var circularPolygon = ol.geom.Polygon.circular(wgs84Sphere, center, radius, 64);

Има и ol.geom.Polygon.fromCircle, който взема ol.geom.Circle и го трансформира в многоъгълник, представляващ същата област.

person Alvin Lindstam    schedule 27.08.2015

Моят отговор е допълнение към страхотния отговор на Алвин.

Представете си, че искате да начертаете кръг с даден радиус (в метри) около точка. В моя конкретен случай кръг от 200 метра около движещо се превозно средство.

Ако този кръг има малък диаметър (‹ няколко километра), можете да пренебрегнете грапавостта на земята. След това можете да използвате маркера Circle във функцията за стил на вашата точка.

Ето моята стилова функция:

private pointStyle(feature: Feature, resolution: number): Array<Style> {
  const viewProjection = map.getView().getProjection();      
  const coordsInViewProjection = (<Point>(feature.getGeometry())).getCoordinates();
  const longLat = toLonLat(coordsInViewProjection, viewProjection);
  const latitude_rad = longLat[1] * Math.PI / 180.;
  const circle = new Style({
     image: new CircleStyle({
          stroke: new Stroke({color: '#7c8692'});,
          radius: this._circleRadius_m / (resolution / viewProjection.getMetersPerUnit() * Math.cos(latitude_rad)),
        }),
      });
   
  return [circle];
}

Номерът е да мащабирате радиуса по косинус на географската ширина. Това ще деактивира локално ефекта на изкривяване, който можем да наблюдаваме в примера на Tissot.

person Adrien BARRAL    schedule 18.05.2021