问题描述
我有一个与 this one 类似的问题。使用 geodjango
,我想在地图上绘制一个以公里为单位的特定半径的圆。但是,建议的解决方案
a) 不使用公里而是使用度数,并且
b) 进一步向北或向南变成椭圆形。
这是我所做的:
from django.contrib.gis import geos
lat = 49.17
lng = -123.96
center = geos.Point(lng,lat)
radius = 0.01
circle = center.buffer(radius)
# And I then use folium to show a map on-screen:
map = folium.Map(
location=[lat,lng],zoom_start=14,attr="MapBox"
)
folium.GeoJson(
circle.geojson,name="geojson",).add_to(map)
结果如下:
我该怎么办
a) 画一个半径始终为 3 公里的圆,与地球上的位置无关,并且
b) 确保在所有纬度都是圆形而不是椭圆形?
解决方法
这是代码
from django.contrib.gis import geos
import folium
lat = 49.17
lng = -123.96
center = geos.Point(x=lng,y=lat,srid=4326)
center.transform(3857) # Transform Projection to Web Mercator
radius = 3000 # now you can use meters
circle = center.buffer(radius)
circle.transform(4326) # Transform back to WGS84 to create geojson
# And I then use folium to show a map on-screen:
map = folium.Map(
location=[lat,lng],zoom_start=14,attr="Mapbox"
)
geojson = folium.GeoJson(
circle.geojson,name="geojson",)
geojson.add_to(map)
说明
这个问题是由地图投影引起的。
纬度/经度坐标由地图投影 WGS84 表示。值以度为单位。
您在 folium 中看到的地图有另一个地图投影 (Web Mercator)。它试图将世界表示为一个平面,从而产生向北和向南的扭曲。坐标值以米为单位。
在地球上,您创建的圆看起来完全是圆的,但由于 folium 使用了另一个投影,所以它会变形。
了解每个投影都由一个数字(EPSG 代码)表示也很重要。使用此 epsg 代码,您可以将坐标从一种投影转换为另一种投影。
- Web 墨卡托 -> EPSG 3857
- WGS84 -> EPSG 4326
使用我的代码,您现在可以在 Web Mercator 中获得一个圆形的大叶圆,但请注意,在地球上看它时,它会看起来是椭圆形和扭曲的。
这只是一个非常简单的解释。您可以查看 Map Projections 以更好地理解问题。 本指南提供了一个很好的概述: Map Projections
,试试这个
folium.Circle(
radius=3000,location=[lat,popup="Whatever name",color="#3186cc",fill=True,fill_color="#3186cc",).add_to(m)