首页 文章

谷歌 Map :在折线上选择以前的标记

提问于
浏览
-2

我正在使用谷歌 Map API进行应用程序,该应用程序具有带标记坐标的JSON . 然后我在标记之间绘制折线 . 我还使用onclick事件实现了一个函数,该函数在折线内创建一个新标记 . 此标记必须显示折线中前一个标记的信息(JSON中的标记,而不是单击的标记) . 但我不知道如何获取所选折线的前一个顶点(标记) .

enter image description here

码:

(function() {

window.onload = function() {

var options = {
zoom: 3,
center: new google.maps.LatLng(37.09, -95.71),
mapTypeId: google.maps.MapTypeId.HYBRID,
noClear: true,
panControl: true,
scaleControl: false,
streetViewControl:false,
overviewMapControl:false,
rotateControl:false,
mapTypeControl: true,
zoomControl: false,
}; 
var map = new google.maps.Map(document.getElementById('map'), options);

// JSON
$.getJSON("loc.js", function(json) {
    console.log(json);
});

//Marker type
var markers = [];
var arr = []; 
var pinColor = "FE7569";
var pinImage = new google.maps.MarkerImage("http://labs.google.com/ridefinder/images/mm_20_red.png" + pinColor,
    new google.maps.Size(21, 34),
    new google.maps.Point(0,0),
    new google.maps.Point(10, 34));

// JSON loop
for (var i = 0, length = json.length; i < length; i++) {
    var data = json[i],
    latLng = new google.maps.LatLng(data.lat, data.lng);
    arr.push(latLng);

    // Create markers
    var marker = new google.maps.Marker({
        position: latLng,
        map: map,
        icon: pinImage,
    });
    infoBox(map, marker, data);   

    //Polylines
    var flightPath = new google.maps.Polyline({
        path: json,
        geodesic: true,
        strokeColor: '#FF0000',
        strokeOpacity: 1.0,
        strokeWeight: 2,
        map:map
    });
      infoPoly(map, flightPath, data);

    //Calculate polylines distance
    google.maps.LatLng.prototype.kmTo = function(a){ 
        var e = Math, ra = e.PI/180; 
        var b = this.lat() * ra, c = a.lat() * ra, d = b - c; 
        var g = this.lng() * ra - a.lng() * ra; 
        var f = 2 * e.asin(e.sqrt(e.pow(e.sin(d/2), 2) + e.cos(b) * e.cos 
        (c) * e.pow(e.sin(g/2), 2))); 
        return f * 6378.137; 
    }
    google.maps.Polyline.prototype.inKm = function(n){ 
        var a = this.getPath(n), len = a.getLength(), dist = 0; 
        for (var i=0; i < len-1; i++) { 
           dist += a.getAt(i).kmTo(a.getAt(i+1)); 
        }
        return dist; 
    }
}

function infoBox(map, marker, data) {
    var infoWindow = new google.maps.InfoWindow();
    google.maps.event.addListener(marker, "click", function(e) {
        salta(data.tm);
    });

    (function(marker, data) {
      google.maps.event.addListener(marker, "click", function(e) {
        salta(data.tm);
      });
    })(marker, data);
}
//Create onclick marker on the polyline
function  infoPoly(map, flightPath, data){
google.maps.event.addListener(flightPath, 'click', function(event) {
      mk = new google.maps.Marker({
        map: map,
        position: event.latLng,

      });
      markers.push(mk);
      map.setZoom(17);
      map.setCenter(mk.getPosition());
    });
    }

    function drawPath() {
       var coords = [];
       for (var i = 0; i < markers.length; i++) {
        coords.push(markers[i].getPosition());
       }
       flightPath.setPath(coords);
    }  

//  Fit these bounds to the map
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < arr.length; i++) {
    bounds.extend(arr[i]);
}

map.fitBounds(bounds);
//dist polylines
distpoly = flightPath.inKm();
distpolyround = Math.round(distpoly);
};
})();

如果我单击蓝色箭头,我会在折线的该点上创建一个标记 . 我那个标记它需要前一个的值 .

2 回答

  • 0

    您可以使用geometry library .poly namespace isLocationOnEdge方法确定点击点(新标记)所在的折线的哪个部分 .

    //Create onclick marker on the polyline
    function infoPoly(map, flightPath, data) {
      google.maps.event.addListener(flightPath, 'click', function(event) {
        mk = new google.maps.Marker({
          map: map,
          position: event.latLng,
    
        });
        markers.push(mk);
        map.setZoom(17);
        map.setCenter(mk.getPosition());
    
        // find line segment.  Iterate through the polyline checking each line segment.
        // isLocationOnEdge takes a google.maps.Polyline as the second argument, so make one,
        // then use it for the test.  The default value of 10e-9 for the tolerance didn't work,
        // a tolerance of 10e-6 seems to work.
        var betweenStr = "result no found";
        var betweenStr = "result no found";
        for (var i=0; i<flightPath.getPath().getLength()-1; i++) {
           var tempPoly = new google.maps.Polyline({
             path: [flightPath.getPath().getAt(i), flightPath.getPath().getAt(i+1)]
           })
           if (google.maps.geometry.poly.isLocationOnEdge(mk.getPosition(), tempPoly, 10e-6)) {
              betweenStr = "between "+i+ " and "+(i+1);
           }
        }
    
        (function(mk, betweenStr) {
          google.maps.event.addListener(mk, "click", function(e) {
            infowindow.setContent(betweenStr+"<br>loc:" + this.getPosition().toUrlValue(6));
            infowindow.open(map, mk);
            // salta(data.tm);
          });
        })(mk, betweenStr);
    
        google.maps.event.trigger(mk,'click');
      });
    

    proof of concept fiddle

    code snippet:

    var infowindow = new google.maps.InfoWindow();
    (function() {
    
      window.onload = function() {
    
        var options = {
          zoom: 3,
          center: new google.maps.LatLng(37.09, -95.71),
          mapTypeId: google.maps.MapTypeId.HYBRID,
        };
        var map = new google.maps.Map(document.getElementById('map'), options);
    
        //Marker type
        var markers = [];
        var arr = [];
        var pinColor = "FE7569";
        var pinImage = "http://labs.google.com/ridefinder/images/mm_20_red.png";
    
        // JSON loop
        for (var i = 0, length = json.length; i < length; i++) {
          var data = json[i],
            latLng = new google.maps.LatLng(data.lat, data.lng);
          arr.push(latLng);
    
          // Create markers
          var marker = new google.maps.Marker({
            position: latLng,
            map: map,
            icon: pinImage,
          });
          infoBox(map, marker, data);
    
          //Polylines
          var flightPath = new google.maps.Polyline({
            path: json,
            geodesic: true,
            strokeColor: '#FF0000',
            strokeOpacity: 1.0,
            strokeWeight: 2,
            map: map
          });
          infoPoly(map, flightPath, data);
        }
    
        function infoBox(map, marker, data) {
            var infoWindow = new google.maps.InfoWindow();
            google.maps.event.addListener(marker, "click", function(e) {
              infowindow.setContent("tm:" + data.tm + "<br>loc:" + this.getPosition().toUrlValue(6));
              infowindow.open(map, marker);
              // salta(data.tm);
            });
    
            (function(marker, data) {
              google.maps.event.addListener(marker, "click", function(e) {
                infowindow.setContent("tm:" + data.tm + "<br>loc:" + this.getPosition().toUrlValue(6));
                infowindow.open(map, marker);
                // salta(data.tm);
              });
            })(marker, data);
          }
          //Create onclick marker on the polyline
    
        function infoPoly(map, flightPath, data) {
          google.maps.event.addListener(flightPath, 'click', function(event) {
            mk = new google.maps.Marker({
              map: map,
              position: event.latLng,
    
            });
            markers.push(mk);
            map.setZoom(17);
            map.setCenter(mk.getPosition());
    
            // find line segment.  Iterate through the polyline checking each line segment.
            // isLocationOnEdge takes a google.maps.Polyline as the second argument, so make one,
            // then use it for the test.  The default value of 10e-9 for the tolerance didn't work,
            // a tolerance of 10e-6 seems to work.
            var betweenStr = "result no found";
            for (var i = 0; i < flightPath.getPath().getLength() - 1; i++) {
              var tempPoly = new google.maps.Polyline({
                path: [flightPath.getPath().getAt(i), flightPath.getPath().getAt(i + 1)]
              })
              if (google.maps.geometry.poly.isLocationOnEdge(mk.getPosition(), tempPoly, 10e-6)) {
                betweenStr = "between " + i + " and " + (i + 1);
              }
            }
    
            (function(mk, betweenStr) {
              google.maps.event.addListener(mk, "click", function(e) {
                infowindow.setContent(betweenStr + "<br>loc:" + this.getPosition().toUrlValue(6));
                infowindow.open(map, mk);
                // salta(data.tm);
              });
            })(mk, betweenStr);
    
            google.maps.event.trigger(mk, 'click');
          });
        }
    
        function drawPath() {
          var coords = [];
          for (var i = 0; i < markers.length; i++) {
            coords.push(markers[i].getPosition());
          }
          flightPath.setPath(coords);
        }
    
        //  Fit these bounds to the map
        var bounds = new google.maps.LatLngBounds();
        for (var i = 0; i < arr.length; i++) {
          bounds.extend(arr[i]);
        }
    
        map.fitBounds(bounds);
        //dist polylines
        distpoly = flightPath.inKm();
        distpolyround = Math.round(distpoly);
      };
    })();
    
    var json = [{
      lat: 38.931808,
      lng: -74.906606,
      tm: 0
    }, {
      lat: 38.932442,
      lng: -74.905147,
      tm: 1
    }, {
      lat: 38.93311,
      lng: -74.903473,
      tm: 2
    }, {
      lat: 38.933777,
      lng: -74.901671,
      tm: 3
    }, {
      lat: 38.930739,
      lng: -74.912528,
      tm: 1000
    }];
    
    html,
    body,
    #map {
      height: 100%;
      width: 100%;
      margin: 0px;
      padding: 0px
    }
    
    <script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
    <div id="map"></div>
    
  • 0

    INITIALIZING
    for 循环中创建这些标记时,将它们添加到循环前定义(空)的map [数据结构] . 在 Map 中将存储标记 . 他们的钥匙 - 连接lat / lng .

    • var initial_markers = {}; //before for loop

    • initial_markers[data.lat+"-"+data.lng] = marker; //after each marker initialization

    • 计算它们,所以你知道有多少 initial_marker_count ,因为你无法获得 map [数据结构]的大小

    DETECTION
    当您点击折线时,我认为您不能完全获得被点击的折线部分,因此您需要自己获取折线 . 步骤是:

    • 获取点击事件的坐标

    • 循环标记

    • 拿走他们的坐标

    • 检查 Map 上点击的点是否在这两点之间的线上

    • 如果是,请取这两点中的第一点

    DETECTION PSEUDOCODE

    var prev_marker;
    for (var i=initial_markers; i<initial_marker_count-2; i++) {
        if( isPointOnLine(initial_markers[i], initial_markers[i+1], clicked_point) {
            prev_marker = initial_markers[i];
            break;
        }
    }
    

    我说这是伪代码的唯一原因是因为我不知道如果点在谷歌 Map 中的两点之间的线上 . 你应该编写 isPointOnLine() 函数 . 除此之外 - 给出了这个想法 . 希望你欣赏它 .

相关问题