[英]Finding the longitudes and latitudes within a perimeter using SQLAlchemy
我正在使用SQLalchemy定义表。 这些表描述了地震事件,这些事件按事件,原点,幅度,实数和时间量排列。 他们很好地遵循QuakeML的标准。 事件表是通过.preferredOriginID和.publicID与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)
事件:id | publicID | preferredOriginID | preferredMagnitudeID | 输入| ....
来源:id | publicID | time_id | latitude_id | longitude_id | depth_id | ...
实数:id | 价值| ....
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)
。 您可以轻松计算最小和最大纬度; 最小和最大经度也可以完成,尽管数学有些棘手。
如果您已按纬度和经度正确索引了原始表,则可以对min_lat <= lat <= max_lat and min_lon <= lon <= max_lon
进行非常快速(通常比较便宜)的初始框选择,这应该会丢弃min_lat <= lat <= max_lat and min_lon <= lon <= max_lon
99%的条目(取决于原点的半径和群集度); 其余条目应该大约有80%的机会属于您所需的数据集,并且您只需要对其余条目进行昂贵的计算。
我强烈建议将其编写为存储过程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.