不会引发“未知SRID”异常

2024-06-02 08:14:04 发布

您现在位置:Python中文网/ 问答频道 /正文

以这个模型为例:

from django.contrib.gis.db import models


class Location(models.Model):
    point = models.PointField(null=True, blank=True)

然后尝试执行此操作,故意给它一个错误的SRID:

from django.contrib.gis.geos import Point
from testpoint.models import Location

some_location = Location()
some_location.point = Point(x=15, y=16, srid=210)
some_location.save()

在执行最后一条语句some_location.save()时,控制台上将显示消息“unknown SRID:210”。到现在为止,一直都还不错。问题是.save()返回成功,null存储在point;但是我想要的是不保存任何内容并引发异常。你知道吗

Django似乎将此SQL发送到spatialite:

INSERT INTO "testpoint_location" ("point")
VALUES (Transform(GeomFromText('POINT(15.0 16.0)', 210), 4326))

spatialite似乎执行了它(控制台上打印了警告),但从未告诉Django出了什么问题。你知道吗

当SRID错误时,如何告诉spatialite失败并返回错误?你知道吗


Tags: djangofromimportmodelssave错误locationsome
1条回答
网友
1楼 · 发布于 2024-06-02 08:14:04

在GeoDjango上Database API documentation指出:

Moreover, if the GEOSGeometry is in a different coordinate system (has a different SRID value) than that of the field, then it will be implicitly transformed into the SRID of the model’s field, using the spatial database’s transform procedure.

^{}上,它是PointField的基础,默认srid设置为4326。它警告您srid=210不存在,并继续将(x,y)对转换为EPSG:4326。你知道吗

我认为有两种方法可以解决这个问题(至少目前是这样):

  1. 简单的解决方法:强迫一切转化为EPSG:2100(希腊网格)通过在模型定义中定义它:

    class Location(models.Model):
        point = models.PointField(null=True, blank=True, srid=2100)
    
  2. 更复杂的方法:创建自定义异常和接受的srid列表:SRIDS=[2100, 4326, 3857,...],对照该列表检查传入的srid,如果不匹配,则引发自定义异常:

    my_app/exceptions.py

    class UnknownSRID(Exception):
        def __init__(self, message=None):
            self.message = message
    

    my_app/my_test.py

    from django.conf import settings
    from django.contrib.gis.geos import Point
    
    from testpoint.exceptions import UnknownSRID
    from testpoint.models import Location
    
    some_location = Location()
    test_srid=210
    if test_srid not in settings.SRIDS:
        raise UnknownSRID(
            'SRID {} not in list of acceptable SRIDs'.format(test_srid)
        )
    
    some_location.point = Point(x=15, y=16, srid=test_srid)
    some_location.save()
    

相关问题 更多 >