0

I want to give users the ability to find out how far they are from a Point of Interest to the edge of a radius on a map. I would also like to convert that unit to kilometers, meter or nautical mile. I understand that all polygons are drawn in meters. I am using fromCircle to convert a circle to a geometer polygon. Please help me. I remember there was a getbound() function in openlayers 2 but i can not find it anymore to use to calculate the distance form the the point of interest or center of the map to the edge. I have searched through stackoverflow for days but can not find exactly what is need or the solution that worked with the new version of openlayers.

enter image description here

 var vectorSource = vectorLayer.getSource();
    var centerLongitudeLatitude = map.getView().getCenter();
    var viewProjection = map.getView().getProjection();
    var pointResolution = olProj.getPointResolution(viewProjection, 1, centerLongitudeLatitude);
    console.log('pointResolution', pointResolution)
    function addCirclePolygon(coordinates, radius=1600) {
        var _radius = radius/pointResolution;
        // var circle = new Feature(new Circle(coordinates, _radius));
        var circle = new Feature(new Circle(coordinates, _radius));
        circle.setStyle(new Style({
            stroke: new Stroke({
                color: 'blue',
                width: 3
            }),
            fill: new Fill({
                color: 'rgba(0, 0, 255, 0.1)'
            })
        }));
        var geom=circle.get('geometry');
        if (circle instanceof Circle) {
            circle.set('geometry', fromCircle(geom));
        }
        vectorSource.addFeature(circle);
    }
Arthur Decker
  • 1,191
  • 3
  • 15
  • 45

1 Answers1

1

The distance from a point to the edge of a ctrcle is the distance from the point to the center of the circle minus the radius.

But OpenLayers has a getClosestPoint method which will work with any geometry:

var point1 = point.getGeometry().getCoordinates();

var point2 = circle.getClosestPoint(point1);

Then you can calculate a distance using Pythagoras and adjust for point resolution:

var dx = point1[0] - point2[0];
var dy = point1[1] - point2[1];

var meters = Math.sqrt(dx * dx + dy * dy) * pointResolution;

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
    <link rel="stylesheet" href="https://openlayers.org/en/v6.4.3/css/ol.css" type="text/css">
    <script src="https://openlayers.org/en/v6.4.3/build/ol.js"></script>
</script>
    <style>
      html, body, .map {
        margin: 0;
        padding: 0;
        width: 100%;
        height: 100%;
      }
    </style>
</head>
<body>
<div id="map" class="map"></div> 
<script>

var vectorLayer = new ol.layer.Vector({
      source: new ol.source.Vector()
    });

var map = new ol.Map({
  layers: [
    new ol.layer.Tile({
      source: new ol.source.OSM()
    }),
    vectorLayer
  ],
  target: 'map',
  view: new ol.View({
    center: ol.proj.fromLonLat([0, 52]),
    maxZoom: 20,
    zoom: 12,
  }),
});

 var vectorSource = vectorLayer.getSource();
    var centerLongitudeLatitude = map.getView().getCenter();
    var viewProjection = map.getView().getProjection();
    var pointResolution = ol.proj.getPointResolution(viewProjection, 1, centerLongitudeLatitude);
    console.log('pointResolution', pointResolution);
    var circle;
    function addCirclePolygon(coordinates, radius=1600) {
        var _radius = radius/pointResolution;
        circle = new ol.Feature(new ol.geom.Circle(coordinates, _radius));
        circle.setStyle(new ol.style.Style({
            stroke: new ol.style.Stroke({
                color: 'blue',
                width: 3
            }),
            fill: new ol.style.Fill({
                color: 'rgba(0, 0, 255, 0.1)'
            })
        }));
        var geom=circle.get('geometry');
        if (circle instanceof ol.geom.Circle) {
            circle.set('geometry', fromCircle(geom));
        }
        vectorSource.addFeature(circle);
    }

addCirclePolygon(centerLongitudeLatitude);

map.on(
  'click',
  function (event) {
    var point1 = event.coordinate;
    var point2 = circle.getGeometry().getClosestPoint(point1);
    console.log(point1, point2);
    var line = new ol.Feature(new ol.geom.LineString([point1, point2]));
    vectorSource.addFeature(line);
    var dx = point1[0] - point2[0];
    var dy = point1[1] - point2[1];
    var meters = Math.sqrt(dx * dx + dy * dy) * pointResolution;
    console.log('meters to edge = ' + meters);
    var dx = point1[0] - centerLongitudeLatitude[0];
    var dy = point1[1] - centerLongitudeLatitude[1];
    var toCenter = Math.sqrt(dx * dx + dy * dy) * pointResolution;
    console.log('to center = ' + toCenter);
  }
);

   </script>
</body>
</html>
Mike
  • 16,042
  • 2
  • 14
  • 30
  • What is point.getGeometry().getCoordinates();? Because if i click on the the map and get the coordinates for the center of the circle, can't i use it as the point1? @Mike – Arthur Decker Nov 24 '20 at 23:16
  • If you have a feature you need to get its coordinates. If you get coordinates from a click the click coordinates are your point1. – Mike Nov 24 '20 at 23:29
  • can you please give me a working example? I get the same coordinates when i used circle.getClosestPoint(point1) so both dx and dy resulted in zero (0). – Arthur Decker Nov 25 '20 at 00:09
  • Hi @Mike thanks for your solution but what i wanted was that on map.on the circle will be created and measure the distance from the center of the circle to the edge. The solution you provided has the circle drawn already and measures the distance for any point to the edge – Arthur Decker Nov 25 '20 at 23:29
  • is used var point2 = circle.getGeometry().getExtent() but is goes way beyond the egde of the circle – Arthur Decker Nov 25 '20 at 23:58
  • i got it. I used getFirstCoordinate and getLastCoordinate – Arthur Decker Nov 26 '20 at 00:08