How to measure the distance from center of a circle to the edge in openlayers

899 views Asked by At

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);
    }
1

There are 1 answers

6
Mike On BEST ANSWER

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>