The distance between Ustica Island and the coast of Palermo is about 54 thousand meters. I expect that by constructing a Circle like this new ol.geom.Circle(centerInMapProjection, 53708);
to see the perimeter of the circle touch the coast. Yet the circle is much smaller. What am I doing wrong?
Here is a working snippet with OpenLayers 3. It also has the measurement system built in.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>OpenLayers Circle and Geodetic Measurement</title>
<link rel="stylesheet" href="https://openlayers.org/en/v3.20.1/css/ol.css" type="text/css">
<style>
#map {
width: 100%;
height: 100vh;
}
.ol-tooltip {
background-color: white;
border: 1px solid black;
padding: 4px;
position: absolute;
white-space: nowrap;
}
.ol-tooltip-measure {
opacity: 0.7;
font-weight: bold;
}
</style>
</head>
<body>
<div id="map" class="map"></div>
<script src="https://openlayers.org/en/v3.20.1/build/ol.js"></script>
<script>
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: new ol.View({
center: [1468335.0056440544, 4680137.027803559],
zoom: 7
})
});
function addCircle(x, y, radiusInMeters) {
var centerInMapProjection = [x, y];
var circleGeometry = new ol.geom.Circle(centerInMapProjection, radiusInMeters);
var circleFeature = new ol.Feature(circleGeometry);
var vectorSource = new ol.source.Vector({
features: [circleFeature]
});
var vectorLayer = new ol.layer.Vector({
source: vectorSource,
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'red',
width: 2
}),
fill: new ol.style.Fill({
color: 'rgba(255, 0, 0, 0.2)'
})
})
});
map.addLayer(vectorLayer);
}
addCircle(1468335.0056440544, 4680137.027803559, 53708);
var measureSource = new ol.source.Vector();
var measureLayer = new ol.layer.Vector({
source: measureSource,
style: new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(255, 255, 255, 0.2)'
}),
stroke: new ol.style.Stroke({
color: '#ffcc33',
width: 2
}),
image: new ol.style.Circle({
radius: 7,
fill: new ol.style.Fill({
color: '#ffcc33'
})
})
})
});
map.addLayer(measureLayer);
var draw = new ol.interaction.Draw({
source: measureSource,
type: 'LineString',
style: new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(255, 255, 255, 0.2)'
}),
stroke: new ol.style.Stroke({
color: 'rgba(0, 0, 0, 0.5)',
lineDash: [10, 10],
width: 2
}),
image: new ol.style.Circle({
radius: 5,
stroke: new ol.style.Stroke({
color: 'rgba(0, 0, 0, 0.7)'
}),
fill: new ol.style.Fill({
color: 'rgba(255, 255, 255, 0.2)'
})
})
})
});
map.addInteraction(draw);
var measureTooltipElement = document.createElement('div');
measureTooltipElement.className = 'ol-tooltip ol-tooltip-measure';
var measureTooltip = new ol.Overlay({
element: measureTooltipElement,
offset: [0, -15],
positioning: 'bottom-center'
});
map.addOverlay(measureTooltip);
var formatLength = function(line) {
var wgs84Sphere = new ol.Sphere(6378137);
var coordinates = line.getCoordinates();
var length = 0;
var sourceProj = map.getView().getProjection();
for (var i = 0, ii = coordinates.length - 1; i < ii; ++i) {
var c1 = ol.proj.transform(coordinates[i], sourceProj, 'EPSG:4326');
var c2 = ol.proj.transform(coordinates[i + 1], sourceProj, 'EPSG:4326');
length += wgs84Sphere.haversineDistance(c1, c2);
}
var output;
/*if (length > 100) {
output = (Math.round(length / 1000 * 100) / 100) + ' km';
} else {*/
output = (Math.round(length * 100) / 100) + ' m';
//}
return output;
};
draw.on('drawstart', function(evt) {
measureSource.clear();
var tooltipCoord = evt.coordinate;
evt.feature.getGeometry().on('change', function(evt) {
var geom = evt.target;
var output = formatLength(geom);
tooltipCoord = geom.getLastCoordinate();
measureTooltipElement.innerHTML = output;
measureTooltip.setPosition(tooltipCoord);
});
});
draw.on('drawend', function() {
measureTooltipElement = null;
createMeasureTooltip();
});
function createMeasureTooltip() {
measureTooltipElement = document.createElement('div');
measureTooltipElement.className = 'ol-tooltip ol-tooltip-measure';
measureTooltip = new ol.Overlay({
element: measureTooltipElement,
offset: [20, -25],
positioning: 'bottom-center'
});
map.addOverlay(measureTooltip);
}
createMeasureTooltip();
</script>
</body>
</html>