你能在 GeoDjango 中本地进行方位角等距投影吗?

Can you do Azimuthal Equidistant projections natively in GeoDjango?

我正在转换我编写的一个小项目,以查找特定点半径内形状文件的重叠边界。这个原始项目是我使用 Shapely 和 GeoPandas 编写的模型项目,为了使其更适合生产,我将其全部转换为 GeoDjango。

有一件事对这个程序至关重要,那就是在地图上创建一个圆的等距投影。我能够使用 pyproj 和 functools 对形状优美的对象执行此操作。

请注意,此解决方案是在 Whosebug 上找到的,并非我的原始解决方案。

from shapely import geometry
from functools import partial

def createGeoCircle(lat, lng, mi):
    proj_wgs84 = pyproj.Proj(init='epsg:4326')
    aeqd_proj = '+proj=aeqd +lat_0={lat} +lon_0={lng} +x_0=0 +y_0=0'
    project = partial(
        pyproj.transform,
        pyproj.Proj(aeqd_proj.format(lat=lat, lng=lng)),
        proj_wgs84)
    buf = geometry.Point(0, 0).buffer(mi * 1.60934 * 1000)

    circle = transform(project, buf)
    return circle

我尝试再次使用此解决方案并从形状对象创建一个 geoDjango MultiPolygon 对象,但它导致放置和形状不正确。

这是我用来转换来自上述函数的形状对象的代码。

shape_model(geometry=geos.MultiPolygon(geos.GEOSGeometry(createGeoCircle(41.378397, -81.2446768, 1).wkt)), state="CircleTest").save()

这是 Django Admin 中的输出。这张照片被放大以显示形状,但位置在南极洲中部。给出的坐标是为了在俄亥俄州显示。

为了澄清一些事情,我的模型如下:

class shape_model(geo_models.Model):
    state    = geo_models.CharField('State Territory ID', max_length=80)
    aFactor  = geo_models.FloatField()
    bFactor  = geo_models.FloatField()
    geometry = geo_models.MultiPolygonField(srid=4326)

我可以通过简单地使用 geodjango 点和缓冲区来获得正确的位置,但它显示为椭圆形,因为它不是等距的。如果有人有任何建议或提示,我将不胜感激!

好的,我找到了解决这个问题的方法。我使用等距投影代码并将其扩展以将其转换回 EPSG:4326。更新后的函数如下:

def createGeoCircle(lat, lng, mi):
    point = geometry.Point(lat, lng)

    local_azimuthal_projection = f"+proj=aeqd +lat_0={lat} +lon_0={lng} +x_0=0 +y_0=0"
    proj_wgs84 = pyproj.Proj('epsg:4326')

    wgs84_to_aeqd = partial(
        pyproj.transform,
        proj_wgs84,
        pyproj.Proj(local_azimuthal_projection),
    )

    aeqd_to_wgs84 = partial(
        pyproj.transform,
        pyproj.Proj(local_azimuthal_projection),
        proj_wgs84,
    )

    point_transformed = transform(wgs84_to_aeqd, point)

    buffer = point_transformed.buffer(mi * 1.60934 * 1000)

    buffer_wgs84 = transform(aeqd_to_wgs84, buffer)

    return json.dumps(geometry.mapping(buffer_wgs84))

我还转储了此函数的几何映射,因此现在可以将其直接加载到 geos MultiPolygon 中,而不是使用对象的 wkt。我将圆加载到模型中并使用以下方法保存它:

shape_model(geometry=geos.MultiPolygon(geos.GEOSGeometry(createGeoCircle(41.378397, -81.2446768, 1))), state="CircleTest", aFactor=1.0, bFactor=1.0).save()

仅供参考 这不是原生的 geodjango 解决方案并且依赖于许多其他包。如果有人有本地解决方案,我会非常喜欢!