使用Laravel队列实现即时Google地理编码

14

我大约有100个GPS设备,每隔10秒就会定期发送坐标。我的客户希望进行实时反向地理编码,以便在表格视图中查看车辆及其位置。我设置了一个队列,在将所有数据包保存到数据库之前,我添加了以下地理编码脚本:

  1. 使用Websocket接收TCP IP消息

public function onMessage(ConnectionInterface $conn, $msg) {
 //get the message
 // send the dispatch job to save it in db
 $this->dispatch(new SavePacketsToDb($key_1, json_encode(
                                        array(
                                            'company_id' => $key_1,
                                            'vehicle_id' => $company->vehicle_id,
                                            'tracker_id' => $company->tracker_id,
                                            'lat' => $lat,
                                            'lng' => $lng,
                                            'imei' => $imei,
                                            'datetime' => $datetime,
                                                                            )
                         )));   

  • 运行队列

    public function handle(){
            $lat=$obj->lat;
            $lng=$obj->lng;
    
    
    
    $url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=" . $lat . "," . $lng . "&key=mykey";
                    $json = file_get_contents($url);
                    $data = json_decode($json);
                    $status = $data->status;
                    $address = '';
                    if ($status == "OK") {  
                       // echo "from geocode address";
                        echo $address = $data->results[0]->formatted_address;
                    }
                    else{
                        $address=NULL;
                    }
    
         //save to db
      }
    

    如果我将此地理编码加入队列,是否可以支持1000个并发设备,我有点担心,是否有更好的方法?


  • 我认为你可以通过supervisor的配置设置numprocs=8来限制并发进程的数量。不过我不完全确定这是否符合你的要求。 - user320487
    我看到你至少可以改进几个方面,以下是一些指针: 1)当你将新的工作放入队列时,你可以检查一个工作是否仍在等待车辆,并清除任何挂起的工作。 2)你可能不想每次都调用谷歌API。例如,考虑检查坐标是否仍然相同,因为如果是这样,车辆没有移动,你已经知道位置了。 - Leentje
    3
    仔细考虑后,只有当前端需要显示实际位置时,我才会调用谷歌的API(并保存坐标)。 - Leentje
    1
    使用Google API每天和每秒钟都有限制,因此我们需要按需调用API(每当我们需要在前端显示并将坐标保存在数据库中)。 - SNG
    使用Google API是否有意义,还是在本地调用反向地理编码位置更合适?请参阅http://download.geonames.org/export/dump/或https://zipcodedownload.com - 我想答案可能取决于您需要多准确的结果? - Rob W
    2个回答

    1
    我们开发了类似的东西,最初使用谷歌地图API,但我后来放弃了,因为在我的位置(巴西)它不太准确。
    对于谷歌地图,如果你没有注意到精度方面的问题,你可以运行一个队列并处理数据,但每天有限量(我相信是2500个查询限制)的免费服务或购买所需的查询。如果需要所有设备的实时数据,您将需要支付更多的谷歌地图容量,并使用排队服务。我们正在使用RabbitMQ队列接收坐标,然后我们有小客户端/工作者从队列中获取项目并处理它们(涉及其他API)。
    我不认为您的客户会整天呆在那个屏幕前,所以也许您可以:
    - 始终存储坐标。 - 仅当他/她/某人在该页面上时才运行API调用。 - 对于屏幕上查看的区域(前端视图地图边界),使用GPS坐标的优先级系统。 - 在最佳努力窗口(基于API可用性、使用限制等),甚至在非优先级的情况下使用次要API 运行低优先级坐标。

    顺便提一下,我们正在使用HereMaps进行编程,这是需要付费的,但你可以创建一个演示/测试账户,使用三个月。


    0

    我认为对每个坐标进行反向地理编码相当低效。我宁愿尝试将一些坐标分组到某些包中,然后使用类似于thephpleague/geotools批处理API来反向地理编码这些数据,如果需要的话。

    而且我不会仅依赖谷歌地图。我认为一个好的建议是要有备用方案,因为谷歌地图并不知道每个地址,而且你很容易在速率限制(有这么多数据)下退出。看看支持许多地理编码服务的[geocoder-php/Geocoder]包。

    也许一个小提示:我是维护这个项目的人之一。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接