python - 使用 SQLAlchemy 查找周长内的经度和纬度

标签 python mysql sqlalchemy latitude-longitude

我正在使用 SQLalchemy 来定义我的表。这些表描述了地震事件,按事件、起源、震级、实际数量和时间数量排列。它们很好地遵循了 QuakeML 的标准。 Event表通过.preferredOriginID和.publicID与Origin建立关系,Origin通过.latitude_id和.id与Real_Quantity建立关系。

我想查找指定半径内的所有经度和纬度,但问题是纬度和经度都在同一个 Real_Quantity 列中,而 Origin 表指定了哪些是不同的。

这是我想要实现的代码,但它在MySQL中

SELECT
    id,
    (
        acos(
            (
                cos(radians(37))
                * cos(radians(lat))
                * cos(radians(lng) - radians(-122))
            )
          + (
                sin(radians(37))
                * sin(radians(lat))
            )
        ) * 3959
    ) AS distance
FROM markers
HAVING distance < 25
ORDER BY distance
LIMIT 0, 20;

这就是我所做的,但只有您可以使用纬度,而我想使用带有经度的纬度

z = self.session.query(Event) \
    .join(Origin) \
    .join(RealQuantity, Origin.latitude) \
    .filter(
        Event.preferredOriginID == Origin.publicID,
        RealQuantity.id == Origin.latitude_id
    ) \
    .group_by(Event, Origin.latitude, RealQuantity.value) \
    .having(func.cos(RealQuantity.value) < 50)

事件: 编号|公共(public) ID | | 首选来源 ID | | 首选MagnitudeID |输入 |....

来源: 编号|公共(public) ID |时间_id |纬度_id |经度_id |深度_id |...

实际数量: 编号|值(value)| ....

Origin 只是指针,其值在 Real_Quantity 中

我的模型是:

class Event(Base):
__tablename__ = 'event'

id = Column(Integer, primary_key=True) 
publicID = Column(String)

preferredOriginID = Column(String)
preferredMagnitudeID = Column(String)

type = Column(String)  
typeCertainty = Column(String)

creationInfo_id = Column(Integer, ForeignKey('creation_info.id'))
creationInfo = relationship(CreationInfo, backref=backref('event', uselist=False))


class Origin(Base):
__tablename__ = 'origin'

id = Column(Integer, primary_key=True)
publicID = Column(String)

time_id = Column(Integer, ForeignKey('time_quantity.id'))
time = relationship(TimeQuantity, backref=backref('origin', uselist=False))

latitude_id = Column(Integer, ForeignKey('real_quantity.id'))
latitude = relationship(RealQuantity, foreign_keys=[latitude_id]
                        , backref=backref('origin_lat', uselist=False))

longitude_id = Column(Integer, ForeignKey('real_quantity.id'))
longitude = relationship(RealQuantity, foreign_keys=[longitude_id]
                         , backref=backref('origin_lon', uselist=False))

depth_id = Column(Integer, ForeignKey('real_quantity.id'))
depth = relationship(RealQuantity, foreign_keys=[depth_id],
                     backref=backref('origin_depth', uselist=False))

creationInfo_id = Column(Integer, ForeignKey('creation_info.id'))
creationInfo = relationship(CreationInfo, backref=backref('origin', uselist=False))

event_id = Column(Integer, ForeignKey('event.id'))
event = relationship('Event', backref=backref('origin', uselist=True))


class RealQuantity(Base):
__tablename__ = 'real_quantity'
id = Column(Integer, primary_key=True)
value = Column(Float)
uncertainty = Column(Float)
lowerUncertainty = Column(Float)
upperUncertainty = Column(Float)
confidenceLevel = Column(Float)

最佳答案

还不是解决方案,只是一些评论:

对于每个查询,您都会对 Origin 表中的每个条目进行复杂的计算。随着条目数量的增加,这将变得非常慢(计算成本昂贵)。

想一个圆(x=lon, y=lat, r=distance)投影到地球上。您可以轻松计算最小和最大纬度;最小和最大经度也可以完成,尽管数学有点棘手。

如果您已按纬度和经度正确索引 Origin 表,则可以在 min_lat <= lat <= max_lat and min_lon <= lon <= max_lon 上执行非常快速(计算成本低)的初始框选择它应该简单地丢弃 99% 的条目(取决于原点的半径和聚类程度);剩余条目应该有大约 80% 的机会属于您想要的数据集,并且您只需对剩余条目运行昂贵的计算即可。

我强烈建议将其编写为存储过程。

关于python - 使用 SQLAlchemy 查找周长内的经度和纬度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27985692/

相关文章:

python - pyodbc 在 sp_prepexec 之后调用 sp_unprepare。这会影响参数化查询的性能吗?

python - 如何在 Django 中使用变量重定向?

Python奇怪的TypeError : stream_changes() takes exactly 1 argument (2 given)

mysql - 存储过程变量未在 MySQL 中返回预期值?

mysql导入转储文件ubuntu 10.10

python - sqlalchemy 序列化器合并

python - TensorFlow 'global_step' 变量未针对指数衰减进行更新

python - AppEngine HTTPS CName 似乎挂起

MySQL 根据时间戳按月计算记录

python - 在哪里可以找到 Flask SQLAlchemy 列类型和选项的列表?