无法在 OpenLayers 中获得正确的圆半径
Cannot get circle radius correct in OpenLayers
我在下面有一个 jsfiddle,我试图在其中创建一个半径为 1600 米的圆。我不认为我的投影正确,因为这个圆肯定小于 1600 米。在 Google 地图上测量我认为它在 1000 米左右。请问我需要做些什么来纠正这个问题>
谢谢。
var centerLongitudeLatitude = ol.proj.fromLonLat([-1.733014, 51.982989]);
var layer = new ol.layer.Vector({
source: new ol.source.Vector({
projection: 'EPSG:4326',
features: [new ol.Feature(new ol.geom.Circle(centerLongitudeLatitude, 1600))]
}),
style: [
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 map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
layer
],
view: new ol.View({
center: ol.proj.fromLonLat([-1.733014, 51.982989]),
zoom: 14
})
});
html,
body {
height: 100%;
width: 100%;
padding: 0px;
margin: 0px;
}
.map {
height: 100%;
width: 100%;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.2.1/css/ol.css">
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.2.1/build/ol.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="map" class="map"></div>
矢量图层 (EPSG:4326
) 的 SRS 与圆心 (EPSG:3857
) 的 SRS 不一致。你需要以上之一,而不是两者。
尝试在不指定 projection
的情况下创建图层,它将使用默认视图投影,在本例中 EPSG:3857
(因为 OSM)。
更新:
构建下面的代码片段后,我意识到建议的更改不会影响结果,不知道为什么现在,所以我建议使用 Polygon.circular
作为替代方案。
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/css/ol.css" type="text/css">
<style>
.map {
height: 400px;
width: 100%;
}
</style>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/build/ol.js"></script>
<title>Circle features</title>
</head>
<body>
<div id="map" class="map"></div>
<script type="text/javascript">
// features
var radius = 1600;
var center = [-1.733014, 51.982989]
var fcircle = new ol.Feature({
geometry: new ol.geom.Circle(
ol.proj.fromLonLat(center),
radius
)
});
fcircle.setStyle(new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'blue',
width: 2
})
}));
var fcircular = new ol.Feature({
geometry: ol.geom.Polygon.circular(center, radius, 64).transform('EPSG:4326', 'EPSG:3857')
});
fcircular.setStyle(new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'red',
width: 1
})
}));
// map
var view = new ol.View({
center: ol.proj.fromLonLat(center),
zoom: 14
});
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
new ol.layer.Vector({
source: new ol.source.Vector({
features: [fcircle, fcircular]
})
})
],
view
});
</script>
</body>
</html>
感谢 Mike 和 cabesuon 我有一个解决方案,发布在这里供未来的读者使用。
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: new ol.View({
center: ol.proj.fromLonLat([-1.733014, 51.982989]),
zoom: 14
})
});
var centerLongitudeLatitude = ol.proj.fromLonLat([-1.733014, 51.982989]);
var viewProjection = map.getView().getProjection();
var pointResolution = ol.proj.getPointResolution(viewProjection , 1, centerLongitudeLatitude );
var radius = 1600 / pointResolution;
var layer = new ol.layer.Vector({
source: new ol.source.Vector({
projection: 'EPSG:4326',
features: [new ol.Feature(new ol.geom.Circle(centerLongitudeLatitude, radius))]
}),
style: [
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)'
})
})
]
});
map.addLayer(layer);
html,
body {
height: 100%;
width: 100%;
padding: 0px;
margin: 0px;
}
.map {
height: 100%;
width: 100%;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.2.1/css/ol.css">
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.2.1/build/ol.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="map" class="map"></div>
我在下面有一个 jsfiddle,我试图在其中创建一个半径为 1600 米的圆。我不认为我的投影正确,因为这个圆肯定小于 1600 米。在 Google 地图上测量我认为它在 1000 米左右。请问我需要做些什么来纠正这个问题>
谢谢。
var centerLongitudeLatitude = ol.proj.fromLonLat([-1.733014, 51.982989]);
var layer = new ol.layer.Vector({
source: new ol.source.Vector({
projection: 'EPSG:4326',
features: [new ol.Feature(new ol.geom.Circle(centerLongitudeLatitude, 1600))]
}),
style: [
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 map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
layer
],
view: new ol.View({
center: ol.proj.fromLonLat([-1.733014, 51.982989]),
zoom: 14
})
});
html,
body {
height: 100%;
width: 100%;
padding: 0px;
margin: 0px;
}
.map {
height: 100%;
width: 100%;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.2.1/css/ol.css">
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.2.1/build/ol.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="map" class="map"></div>
矢量图层 (EPSG:4326
) 的 SRS 与圆心 (EPSG:3857
) 的 SRS 不一致。你需要以上之一,而不是两者。
尝试在不指定 projection
的情况下创建图层,它将使用默认视图投影,在本例中 EPSG:3857
(因为 OSM)。
更新:
构建下面的代码片段后,我意识到建议的更改不会影响结果,不知道为什么现在,所以我建议使用 Polygon.circular
作为替代方案。
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/css/ol.css" type="text/css">
<style>
.map {
height: 400px;
width: 100%;
}
</style>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/build/ol.js"></script>
<title>Circle features</title>
</head>
<body>
<div id="map" class="map"></div>
<script type="text/javascript">
// features
var radius = 1600;
var center = [-1.733014, 51.982989]
var fcircle = new ol.Feature({
geometry: new ol.geom.Circle(
ol.proj.fromLonLat(center),
radius
)
});
fcircle.setStyle(new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'blue',
width: 2
})
}));
var fcircular = new ol.Feature({
geometry: ol.geom.Polygon.circular(center, radius, 64).transform('EPSG:4326', 'EPSG:3857')
});
fcircular.setStyle(new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'red',
width: 1
})
}));
// map
var view = new ol.View({
center: ol.proj.fromLonLat(center),
zoom: 14
});
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
new ol.layer.Vector({
source: new ol.source.Vector({
features: [fcircle, fcircular]
})
})
],
view
});
</script>
</body>
</html>
感谢 Mike 和 cabesuon 我有一个解决方案,发布在这里供未来的读者使用。
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: new ol.View({
center: ol.proj.fromLonLat([-1.733014, 51.982989]),
zoom: 14
})
});
var centerLongitudeLatitude = ol.proj.fromLonLat([-1.733014, 51.982989]);
var viewProjection = map.getView().getProjection();
var pointResolution = ol.proj.getPointResolution(viewProjection , 1, centerLongitudeLatitude );
var radius = 1600 / pointResolution;
var layer = new ol.layer.Vector({
source: new ol.source.Vector({
projection: 'EPSG:4326',
features: [new ol.Feature(new ol.geom.Circle(centerLongitudeLatitude, radius))]
}),
style: [
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)'
})
})
]
});
map.addLayer(layer);
html,
body {
height: 100%;
width: 100%;
padding: 0px;
margin: 0px;
}
.map {
height: 100%;
width: 100%;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.2.1/css/ol.css">
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.2.1/build/ol.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="map" class="map"></div>