驾驶距离的医生顺序

问题描述 投票:-1回答:1

我的数据库中有一些坐标,可以通过使用GEO函数过滤最近的位置来检索。

但是它不够精确,因为它不是行驶距离。

我已经使用HERE Maps API来获取路由信息,但是加载整个列表并在此之后调用API是如此繁重。

是否有任何方法可以将Doctrine和HERE API结合使用或以其他方式对地点进行排序或过滤?

谢谢

symfony doctrine here-api here-maps-rest driving-distance
1个回答
0
投票

大约一年前,我在一个类似的项目中遇到了这个确切的问题。唯一的区别是,我使用了Google的Distance Matrix API来确定实际的行驶里程。

简短的答案是:,您不能在查询级别执行此操作,因为数据库不具备路由信息的知识。 (也不能提供这种信息。)即使您确实构建了一些抢先式路由信息,您仍然需要查询每个实体以找到其位置来做到这一点,此外,您还将对maps API施加巨大压力,这可能会导致您快速达到使用配额(并为此付费)!

如果您要查询的实体存储坐标,

您可以实际获得的最近距离首先是按照与更可行的集合(例如50)的直接距离对数据进行过滤/排序。然后在您的控制器中使用maps API通过行驶距离对结果数组进行排序。这样可以减少查询地图API所需的时间。

您可以通过以下示例查询直接距离:

public function findClostestTo(float $latitude, float $longitude, float $milesLimit = null, int $resultsLimit = 1): ?array
{
    $qb = $this->createQueryBuilder("entity")
        ->addSelect("DEGREES(ACOS((SIN(RADIANS(:latitude)) * SIN(RADIANS(entity.latitude))) + (COS(RADIANS(:latitude)) * COS(RADIANS(entity.latitude)) * COS(RADIANS(:longitude - entity.longitude))))) * :radius AS distanceMiles")
        // ->addSelect("(distanceMiles * 1.609344) AS distanceKilometres")
        // ->addSelect("(distanceMiles * 0.868976) AS distanceNauticalMiles")
        ->setParameter("latitude", $latitude)
        ->setParameter("longitude", $longitude)
        ->setParameter("radius", (60 * 1.1515))
        ->addOrderBy("distanceMiles", "ASC")
    ;

    if (is_numeric($milesLimit) && $milesLimit > 0.0) {
        $qb
            ->andWhere("distanceMiles < :milesLimit")
            ->setParameter("milesLimit", $milesLimit)
        ;
    }

    $qb->setMaxResults(max(min($resultsLimit, 50), 1));

    return $qb->getQuery()->getResult();
}

输入$latitude$longitude作为您想计算距离的起点/终点,例如搜索用户的位置

请注意,此存储库函数中数组中的每个结果将不是每个实体的直接实例。它将分为2个键:

  • [0:目标实体实例
  • distanceMiles:用于限制距离并按距离排序的额外伪字段

然后,您需要在控制器中迭代结果数组,以查询您的地图API并获取确切的行驶距离。我个人需要在drivingMiles0上添加另一个键distanceMiles,然后可以在usort()中使用它们来对整个结果集进行排序,以构建最终结果集。

[在大多数情况下,这应该效果很好,但是,在某些边缘情况下,某些结果会超出初始距离限制,这是由于道路中怪异的弯道/方向环回源头而导致的。您仍然可以通过usort()将它们从最终数组中过滤掉,如果发现最终结果集太小,则只需根据直接距离逐渐增加查询限制。

© www.soinside.com 2019 - 2024. All rights reserved.