【问题标题】:Search closest candidates using a given location使用给定位置搜索最近的候选人
【发布时间】:2015-09-16 05:39:15
【问题描述】:

我的数据库中有一份候选人名单,其中包含他们的郊区、州和邮政编码。根据要求,我们将根据客户给我们的郊区找到最近的郊区。

问题是当前算法只计算航线距离(表示两点之间的线性距离)。在现实生活中,我们会有河流或山脉。例如。

客户在A点。B,C在我们的数据库中。 A 和 B 之间的航线距离较短,但在现实生活中,您必须过桥才能到达 B。因此,在此示例中,C 是最短的候选者。

我想知道这是否可以通过第三方 api(谷歌地图?)来完成。请记住,我们的数据库中有 3000 多个候选人,因此遍历每个候选人并与客户位置进行比较是不切实际的。

【问题讨论】:

  • 也许您可以在两个地方之间寻找方向并获得所有可能的交通工具(地铁、公共汽车、汽车、航空公司)。谷歌地图可以提供估计时间,然后选择最短时间。
  • 感谢您的评论,但目前我们只关心驾驶距离,因为他们都是使用货车或 ute 的现场技术人员。
  • 对于第二个问题,在所有候选人中寻找合适的候选人效率不高。我建议构建一个数据结构,将附近的位置存储到给定的位置。或者使用谷歌地图和查询给定范围(50 英里内)并检查返回的位置是否是您数据库中的位置之一
  • 如果您想要行驶距离,那没关系。您仍然可以使用谷歌地图来获取预计时间

标签: javascript php google-maps geolocation


【解决方案1】:

这 - Google Maps Distance API 提供您想要的,驾驶(或任何其他模式)位置之间的距离。

但有趣的问题是,有 3000 个点必须与特定目的地进行比较。一种可能的解决方案是结合使用您当前的算法和 google maps api 的多源功能。 ( google maps distance API 允许指定多个起点/目的地。)

所以:
- 使用当前算法按航线距离查找最近的 10 或 30 个郊区。
- 在一次查询中将所有这些位置作为原始参数发送到谷歌地图 API。

api 将返回目的地和所有起点之间的距离。这可能不会在 100% 的情况下给出正确的结果如果最近的郊区不在我们使用航空公司距离算法计算的 10 或 20 个最近的郊区。但这应该不太可能......

注意:

请查看 google maps API 的确切使用限制。每天的请求数和您可以提供的起点数。虽然它都记录在案

【讨论】:

    【解决方案2】:

    Google Maps API 提供可通过google.maps.DirectionsService 对象 (here is the official documentation) 访问的路线服务。

    向路线服务发送请求时,您可以指定一种出行方式(骑自行车、驾车、公交、步行),这样就可以处理与飞行距离相关的额外距离。

    这是一个演示 (Jsfiddle)。希望对您有所帮助。

    function initMap() {
      var pointA = new google.maps.LatLng(51.2750, 1.0870),
        pointC = new google.maps.LatLng(50.7700, 0.28),
        pointB = new google.maps.LatLng(51.5379, 0.7138),
        airDistAB = google.maps.geometry.spherical.computeDistanceBetween(pointA, pointB),
        airDistAC = google.maps.geometry.spherical.computeDistanceBetween(pointA, pointC),
        myOptions = {
          zoom: 5,
          center: pointA,
          mapTypeId: google.maps.MapTypeId.ROADMAP
        },
        map = new google.maps.Map(document.getElementById('map-canvas'), myOptions),
        // Instantiate a directions service.
        directionsService = new google.maps.DirectionsService,
        directionsDisplay = new google.maps.DirectionsRenderer({
          map: map
        }),
        markerA = new google.maps.Marker({
          position: pointA,
          title: "point A",
          label: "A",
          map: map
        }),
        markerB = new google.maps.Marker({
          position: pointB,
          title: "point B",
          label: "B",
          map: map
        }),
        markerC = new google.maps.Marker({
          position: pointC,
          title: "point C",
          label: "C",
          map: map
        }),
        outputAtoB = document.getElementById('a2b'),
        outputAtoC = document.getElementById('a2c');
      // calculate routes
      responseAB = calculateAndDisplayRoute(directionsService, directionsDisplay, pointA, pointB, outputAtoB, airDistAB, true);
      responseAC = calculateAndDisplayRoute(directionsService, directionsDisplay, pointA, pointC, outputAtoC, airDistAC, false);
      // click on marker B to get route from A to B
      markerB.addListener('click', function() {
        calculateAndDisplayRoute(directionsService, directionsDisplay, pointA, pointB, outputAtoB, airDistAB, true);
      });
      markerC.addListener('click', function() {
        calculateAndDisplayRoute(directionsService, directionsDisplay, pointA, pointC, outputAtoC, airDistAC, true);
      });
      document.getElementById('mode').addEventListener('change', function() {
        calculateAndDisplayRoute(directionsService, directionsDisplay, pointA, pointB, outputAtoB, airDistAB, true);
        calculateAndDisplayRoute(directionsService, directionsDisplay, pointA, pointC, outputAtoC, airDistAC, false);
      });
    
    }
    
    
    
    function calculateAndDisplayRoute(directionsService, directionsDisplay, point1, point2, outputTxt, airDist, display) {
      var selectedMode = document.getElementById('mode').value;
      directionsService.route({
        origin: point1,
        destination: point2,
        travelMode: google.maps.TravelMode[selectedMode]
      }, function(response, status) {
        if (status == google.maps.DirectionsStatus.OK) {
          if (display) {
            directionsDisplay.setDirections(response);
          }
          outputTxt.innerHTML = "~" + Math.round(response.routes[0].legs[0].distance.value / 1000) + " Km" + " (air: ~" + Math.round(airDist / 1000) + "Km)";
          return response;
        } else {
          window.alert('Directions request failed due to ' + status);
        }
      });
    }
    
    initMap();
    html,
          body {
            height: 100%;
            margin: 0;
            padding: 0;
          }
          #map-canvas {
            height: 100%;
            width: 60%;
            float: left;
          }
          #floating-panel {
            position: float top;
            top: 10px;
            left: 25%;
            z-index: 5;
            background-color: #678;
            padding: 5px;
            border: 1px solid #123;
            text-align: center;
            font-family: 'Roboto', 'sans-serif';
            line-height: 30px;
            padding-left: 10px;
          }
          #output {
            padding: 6px;
            width: 38%;
            float: right;
          }
    <script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false&v=3&libraries=geometry"></script>
    
    <div id="floating-panel"> <b>Mode of Travel: </b>
    
      <select id="mode">
        <option value="DRIVING">Driving</option>
        <option value="WALKING">Walking</option>
        <option value="BICYCLING">Bicycling</option>
        <option value="TRANSIT">Transit</option>
      </select>
    </div>
    <div id="map-canvas"></div>
    <div id="out<put">
      <h3>Distances</h3>
      <b> A to B: </b><span id="a2b"></span>
      <p> <b> A to C: </b><span id="a2c"></span>
    
    </div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-15
      • 2018-01-04
      • 1970-01-01
      • 2019-07-12
      • 2018-08-13
      • 1970-01-01
      • 2011-04-24
      • 1970-01-01
      相关资源
      最近更新 更多