【GeoDjango】空间方法的ORM查询

原文作者:我辈理想
版权声明:文章原创,转载时请务必加上原文超链接、作者信息和本声明。

Django数据操作-ORM

【Django开发入门】ORM的增删改查和批量操作
【Django开发入门】ORM查询分页以及返回Json格式
【GeoDjango框架解析】空间方法的ORM查询



前言

通过前面的ORM使用,我们看到ORM在开发中可以提供很大便利,基于国内讲解Geodjango使用的教程比较少,我这里整理了基于postgis数据库的orm空间查询的相关方法。
如果使用的是其他数据库,不能保障空间方法生效。


一、开发环境搭建

开发环境很是重要,尤其是geodjango环境搭建会出现很多问题,我在其他博客中已经给出相关介绍,可以参考。

【GeoDjango框架解析】配置geodjango开发环境
【Linux安装数据库】Ubuntu安装postgresql并连接navicat添加链接描述
【GeoDjango框架解析】conda环境下安装psycopy2版本问题

二、参数查询空间方法

因为业务的关系,我这里主要介绍的都是包含的处理方法,包括点、圆、多边范围查询。

1.点的查询

search_dict = {}
# point是history表的一个字段 models.PointField("点", null=True)
q = Q(geom__contains=history.point)
A.objects.filter(**search_dict).filter(q)

2.圆的查询

search_dict = {}
# point是history表的一个字段 models.PointField("点", null=True)
# diameter是圆的半径,单位m
q = Q(geom__distance_lte=(history.point, str(history.diameter)))
A.objects.filter(**search_dict).filter(q)

3.多边和多多边

search_dict = {}
# geometrycollection是history表的一个字段 
# geometrycollection = models.GeometryCollectionField('混合数据', null=True)
q = Q(geom__intersects=history.geometrycollection)
A.objects.filter(**search_dict).filter(q)

三、聚合的空间方法

在geodjango中使用的空间方法都是基于aggregate的方法,这里需要掌握django的聚合方法

其实django官网给出了相关方法,但是没有相关样例,使用过程中很难嵌入orm查询。我这里找到一个中文版的文档。接下来我会以我实际使用的相关功能来介绍。
在这里插入图片描述

1.IsValid是否是有效图形

cover = pics.aggregate(isv=IsValid('geom'))
print(cover.isv)  # 结果是True或False

2.MakeValid建立有效几何图形

cover = pics.aggregate(un=MakeValid('geom'))

3.Envelope确认外接多边形

geodjango中确认最小外接多边形的方法是envelope,在geodjango中一共有4种。

django.contrib.gis.db.models.functions.Envelope (Python 类, in 地理数据库功能)
django.contrib.gis.gdal.Envelope (Python 类, in GDAL API)
django.contrib.gis.gdal.OGRGeometry.envelope (Python 属性, in GDAL API)
django.contrib.gis.geos.GEOSGeometry.envelope (Python 属性, in 地理信息系统API)

# 第一种
from django.contrib.gis.db.models.functions import Envelope
pic = PicData.objects.annotate(g=Envelope('geom')).get(id=26497)
pic.geom = pic.g
pic.save()
# 第二种
from django.contrib.gis.gdal import Envelope 
g = Envelope(pic.geom)
# 第三种和第四种
g= OGRGeometry(str(pic_data["geom"]), srid=4326).envelope
g= GEOSGeometry(str(pic_data["geom"]), srid=4326).envelope

4.Union建立2个图形并集

django.contrib.gis.db.models.functions.Union (Python 类, in 地理数据库功能)
django.contrib.gis.db.models.Union (Python 类, in GIS查询集API参考)
django.contrib.gis.gdal.OGRGeometry.union (Python 方法, in GDAL API)
django.contrib.gis.geos.GEOSGeometry.union (Python 方法, in 地理信息系统API)

# 第一种
from django.contrib.gis.db.models.functions import Union
cover = pics.aggregate(un=Union(MakeValid('geom')))
# 第二种,search_geom是GEOSGeometry类型
from django.contrib.gis.db.models import Union 
cover = pics.aggregate(un=Union(MakeValid('geom'), search_geom))
# 第三种和第四种,search_geom是GEOSGeometry类型
g= OGRGeometry(str(pic_data["geom"]), srid=4326).union(search_geom)
g= GEOSGeometry(str(pic_data["geom"]), srid=4326).union(search_geom)

5.Intersection建立2个图形交集

django.contrib.gis.db.models.functions.Intersection (Python 类, in 地理数据库功能)
django.contrib.gis.gdal.OGRGeometry.intersection (Python 方法, in GDAL API)
django.contrib.gis.geos.GEOSGeometry.intersection (Python 方法, in 地理信息系统API)

# 第一种,search_geom是GEOSGeometry类型
cover = pics.aggregate(it=Intersection(Union(MakeValid('geom')), search_geom))
# 第二种和第三种
cover = OGRGeometry(str(pic_data["geom"]), srid=4326).intersection(search_geom)
cover = GEOSGeometry(str(pic_data["geom"]), srid=4326).intersection(search_geom)

6.Transform转换SRID坐标系,面积计算

虽然官方文档提供了相关函数,但是那个给出的面积不是真实的面积,需要使用Transform转换为3857坐标系后的面积

每条数据geom字段计算面积

cover = pics.aggregate(tf=Transform(Intersection(Union(MakeValid('geom')), search_geom), srid=3857))
cover_area = cover['tf'].area

合并geom字段计算面积

cover = pics.aggregate(tf=Transform(Intersection(Union(MakeValid('geom')), search_geom), srid=3857))
cover_area = cover['tf'].area

7.Buffer建立缓冲区

country = County.objects.filter(name='中华人民共和国', type='country').first()
# 判断点是否在国界线内,point_ 的结果是True 和False
point = 'POINT(116 38)'
point_ = country.geom.contains(point)

# 因为country的几何图形可能存在不规则,需要用buffer,width的单位是度数(经纬度)
point_ = country.geom.buffer(width=0.01).contains(point)

8.simplify矢量简化

simplify是GEOSGeometry的方法,根据tolerance参数获取简化的几何图形,返回依然是GEOSGeometry,tolerance的参数范围是0-1,参数越小,越接近原几何图形,默认值为0。

history = HistoryData.objects.annotate(gt=MakeValid('geometrycollection'),
                                       tf=Transform('gt', srid=3857)).get(
    id=request.query_params.get('hid'))
history.geometrycollection.simplify(tolerance=0.05)

9.其他

pic_in = pics.aggregate(in_area=Area(Intersection(Union(MakeValid('geom')), search_geom)))
print('pic_in', pic_in['in_area'])
cover_area = pic_in['in_area'].sq_km
cover_area = pic_in['in_area'].sq_m
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我辈李想

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值