选择折线部分 - Google Maps Api

时间:2016-02-09 08:39:21

标签: javascript jquery google-maps google-maps-api-3

是否可以在Google地图中仅选择折线的一部分?我有标记,由用户添加,并在标记之间绘制折线。两个标记之间的折线表示两个地方之间的路线。我希望用户能够点击折线,该部分改变颜色然后插入另一个点。我还希望获得折线连接的标记ID(在添加标记时设置)。

这是我的代码所依据的谷歌示例代码,因为我的代码非常混乱,我会发布此代码。

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Complex Polylines</title>
<style>
    html, body
    {
        height: 100%;
        margin: 0;
        padding: 0;
    }
    #map
    {
        height: 100%;
    }
</style>
</head>
<body>
<div id="map">
</div>
   <script>
       var poly;
       var map;

    function initMap() {
        map = new google.maps.Map(document.getElementById('map'), {
            zoom: 7,
            center: { lat: 41.879, lng: -87.624}  // Center the map on Chicago, USA.
        });

        poly = new google.maps.Polyline({
            strokeColor: '#000000',
            strokeOpacity: 1.0,
            strokeWeight: 3
        });
        poly.setMap(map);

        // Add a listener for the click event
        map.addListener('click', addLatLng);
    }

    // Handles click events on a map, and adds a new point to the Polyline.
    function addLatLng(event) {
        var path = poly.getPath();

        // Because path is an MVCArray, we can simply append a new coordinate
        // and it will automatically appear.
        path.push(event.latLng);

        // Add a new marker at the new plotted point on the polyline.
        var marker = new google.maps.Marker({
            position: event.latLng,
            title: '#' + path.getLength(),
            map: map
        });
    }

 </script>
 <script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&signed_in=true&callback=initMap"></script>
</body>
</html>

到目前为止,我只设法在整个折线上添加了一个点击事件监听器:

 google.maps.event.addListener(poly, 'click', function() {
   poly.setOptions({strokeColor: '#76EE00'});
 });

1 个答案:

答案 0 :(得分:0)

要获得最接近的折线,我使用三角形依赖关系,因此对于每一对标记,我计算点之间的距离(d^ = (x2-x1)^ + (y2-y1)^)接下来得到Heron's formula的三角形区域,而不是来自p=(a*h)/2得到的区域三角形的高度,这是我们对折线距离的指向。 我还在距离很远的地方留下了关闭标记点以获得最近的部分 - 它不是完美的但是工作得很好。

当我们得到我们的部分必须恢复完整路径时,更改标记顺序及其完成。

因此,当您点击折线时,它应突出显示,如果再次点击,则会出现新标记,并且将删除突出显示,并且主路径可以从最后一个标记继续。

这是有效的JSFiddle

var poly, map, 
markers = {}, // here we handle all markers
tmp_path = null, // temporary path for select sections
id_i = 1, // initial value for marker id
MD = []; // selection section markers id

function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    zoom: 7,
    center: { lat: 41.879, lng: -87.624}  // Center the map on Chicago, USA.
  });

  poly = new google.maps.Polyline({
    strokeColor: '#000000',
    strokeOpacity: 1.0,
    strokeWeight: 3
  });
  poly.setMap(map);

  // Add a listener for the click event
  map.addListener('click', addLatLng);
  poly.addListener('click', polyOnClick);

}



function polyOnClick(event) {
    if(tmp_path !== null) tmp_path.setMap(null);
    tmp_path = null;

    var
    p_x = event.latLng.lat(),
    p_y = event.latLng.lng(),
    min_dist = 999999;


    $.each(markers, function(k, v) {
      if(typeof markers[(v.id+1)] == 'undefined') return false;

      var 
      m_x = v.x,
      m_y = v.y,
      m2_x = markers[(v.id+1)].x,
      m2_y = markers[(v.id+1)].y;


      var
      a = getDist(m_x, m2_x, m_y, m2_y), 
            b = getDist(m_x, p_x, m_y, p_y),
      c = getDist(p_x, m2_x, p_y, m2_y);
      var h = getHgh(a, b, c);

      var min_mark_dist = (c > b)? b : c;

      console.info(h/min_mark_dist);

      if((h/min_mark_dist) < min_dist) {
        min_dist = (h/min_mark_dist);
        MD = [v.id, markers[(v.id+1)].id];
      }

    });


    // append temporary path to haighlight section
    tmp_path = new google.maps.Polyline({
      path: [{lat: markers[MD[0]].x, lng: markers[MD[0]].y},{lat: markers[MD[1]].x, lng: markers[MD[1]].y}],
      geodesic: true,
      strokeColor: '#76EE00',
      strokeOpacity: 1,
      strokeWeight: 6
    });

    tmp_path.addListener('click', tmp_pathOnClick);
    tmp_path.setMap(map);
}

function tmp_pathOnClick(event) {
    tmp_path.setMap(null);
    tmp_path = null;

    /* restore markers order and path */
   var tmp_markers = {}, 
   ctx_marker_id = 0; // here we handle pushed marker id
   var full_path = [], flag = false;
   id_i = 1; 

    $.each(markers, function(k, v) {
      if(MD[0] < v.id && !flag) {
        flag = true;
        full_path.push(event.latLng);
        ctx_marker_id = id_i;
        tmp_markers[id_i] = {id: id_i, x: event.latLng.lat(), y: event.latLng.lng()};
        id_i++;
      }

      full_path.push({lat: v.x, lng: v.y});
      tmp_markers[id_i] = {id: id_i, x: v.x, y: v.y, marker: v.marker};
      v.marker.setTitle('#'+id_i);
      id_i++;
    });

    markers = tmp_markers;

    // create new marker
    var marker = new google.maps.Marker({
      position: event.latLng,
      title: '#' + ctx_marker_id,
      map: map,
      id: ctx_marker_id
    });

    markers[ctx_marker_id].marker = marker;


    /* restore main path */
    poly.setMap(null); // clear view
    poly = null; // delete object

    poly = new google.maps.Polyline({
      strokeColor: '#000000',
      strokeOpacity: 1.0,
      strokeWeight: 3,
      path: full_path
    });
    poly.setMap(map); 

    poly.addListener('click', polyOnClick);
    MD = []; // clear selected section markers id
}

// get distance between two points
function getDist(x1, x2, y1, y2) {
    return Math.sqrt(Math.pow((x2 - x1), 2) + Math.pow((y2 - y1), 2));
}

// get hight from abc triangle 
function getHgh(a, b, c) {
    var p = (a+b+c)/2;
  var F = Math.sqrt((p * (p-a) * (p-b) * (p-c)), 2);
  return 2*F/a; 
}



// Handles click events on a map, and adds a new point to the Polyline.
function addLatLng(event) {
    console.log('addLatLng');

  if(MD.length) return false;
  if(tmp_path !== null) tmp_path.setMap(null);
  tmp_path = null;

  var path = poly.getPath();

  // Because path is an MVCArray, we can simply append a new coordinate
  // and it will automatically appear.
  path.push(event.latLng);


  // Add a new marker at the new plotted point on the polyline.
  var marker = new google.maps.Marker({
    position:  event.latLng,
    title: '#' + path.getLength(),
    map: map,
    id: id_i
  });

  markers[id_i++] = {id: marker.id, x: marker.position.lat(), y: marker.position.lng(), marker: marker};
}