简体   繁体   English

使用纬度和经度按距离存储和分类Symfony2学说

[英]Store and sort by distance using latitude and longitude Symfony2 Doctrine

I am working in Symfony2 with Doctrine. 我正在使用Symctony2和Doctrine。

I have a database of entities named Landmarks where each entity has a 1:many relationship with a MapMarker entity, and it is the MapMarker entity which has a latitude and longitude field, eg "Central Park" might be a Landmark with many "entrances" which would be stored as MapMarkers . 我有一个名为Landmarks的实体数据库,其中每个实体与MapMarker实体具有1:many关系,而MapMarker实体具有一个latitudelongitude字段,例如“中央公园”可能是具有许多“入口”的Landmark它将存储为MapMarkers

I then have another entity named Property , which has a 1:1 relationship with a MapMarker . 然后,我还有一个名为Property实体,它与MapMarker具有1:1关系。

For any given Property , What is the best way to find all the nearby Landmarks in the database, sorted by the Landmark's closest MapMarker ? 对于任何给定的Property ,按地标最近的MapMarker排序的最佳方法是在数据库中查找所有附近的Landmarks标?

In a legacy version of this application, without Doctrine or Symfony2, I was doing it this way: 在没有Doctrine或Symfony2的此应用程序的旧版本中,我这样做是这样的:

  1. Retrieve all the Landmarks in database 检索数据库中的所有Landmarks

  2. For each Landmark , go through each of its MapMarkers in a PHP function and calculate the distance between the P roperty's MapMarker's lat,lng and the Landmarks MapMarker's lat,lng . 对于每个Landmark ,请在PHP函数中遍历其每个MapMarkers ,然后计算P roperty's MapMarker's lat,lngLandmarks MapMarker's lat,lng之间的距离。

  3. If any of the calculated distances was less than or equal to some pre-determined constant I had chosen (say 3km) then I made linked the Property to the Landmark in a many:many relatioship. 如果计算出的距离中的任何一个小于或等于我选择的某个预定常数(例如3公里),那么我将PropertyLandmark联系起来的原因有many:many

  4. Later, when querying the database for a Property's nearby Landmarks , it would go through only the linked Landmarks ' MapMarkers and then calculate, again, the nearest MapMarker and distance for presentation like such: 稍后,当在数据库中查询Property's附近的Landmarks ,它将仅通过链接的Landmarks MapMarkers ,然后再次计算最接近的MapMarker和显示距离,例如:

Nearby Landmarks to your Property: 您的物业附近的地标:

  • Central Park , Main Gate - 2.4km 中央公园正门-2.4公里
  • etc. 等等

The benefits of this were that it by creating a permanent link between the Property and the Landmark , I automatically had a "short-list" of nearby Landmarks for which to calculate the expensive distance formula. 这样做的好处是,它通过在PropertyLandmark之间创建永久链接,自动为附近的Landmarks创建了一个“短列表”,可以为其计算昂贵的距离公式。

However as you likely noticed, problems arise when a new Landmark is added, or the MapMarkers of a Landmark change. 但是,您可能已经注意到,添加新的Landmark或更改Landmark MapMarkers时会出现问题。 Also, it is still quite slow to be calculating the distance every time a Property is searched (or reverse if finding all Properties by Landmark ). 同样,每次搜索Property时计算距离仍然很慢(如果通过Landmark查找所有Properties ,则相反)。

Really hoping to come up with a better way now that I am migrating to Symfony2 and Doctrine. 我现在要迁移到Symfony2和Doctrine时,真希望能找到更好的方法。

Any ideas? 有任何想法吗?

Well Symfony2 and Doctrine won't free you from your usual database / PHP constraints so it is pretty much a matter of adapting your existing logic to it. 好吧,Symfony2和Doctrine不会使您摆脱通常的数据库/ PHP约束,因此,将现有逻辑适应于此几乎是一个问题。

With that said and of the top of my head I would probably do something like: 如此说来,在我的脑海中,我可能会做类似的事情:

  • Join Query the database with a BETWEEN on latitude/longitude (ie: lat between marker_lat + X / marker_lat - X and long between marker_long + X / marker_long - X) to get a short list of close by mapmarkers 在纬度/经度上使用BETWEEN联接查询数据库(即:marker_lat + X / marker_lat-X之间的lat和marker_long + X / marker_long-X之间的long)以获取mapmarkers的关闭的简短列表
  • Write a function to calculate distance and keep the closest 编写函数以计算距离并保持最接近

Rather than make a whole new table with number of markers * X entries which makes for poor scalability if you ask me but obviously it depends on your application constraints so I can't really think that through for you. 而不是用标记* X条目创建一个全新的表,如果您问的话,这会导致可伸缩性较差,但是显然,这取决于您的应用程序约束,因此我无法真正为您解决这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM