【问题标题】:Get latLng by clicking on a kml marker's infoWindow, for DirectionsService()通过单击 kml 标记的 infoWindow 获取 latLng,用于 DirectionsService()
【发布时间】:2018-03-09 20:47:58
【问题描述】:

我有一个简单的 JS 脚本,通过读取带有地标列表的 kml 文件在谷歌地图上显示标记,并显示用户的当前位置。 默认情况下,单击标记会在 infoWindow 中显示每个地标的名称和描述。

我的问题是如何添加一个选项来运行directionsService.route(directionsRequest, ...) 任何选定的标记都是目的地,当前位置是起点(双击标记或在infoWindow 中添加链接似乎是最直观的方式,但也许有人有更好的主意)...

这是当前的基本 JS 脚本(现在工作正常,API 调用 https://maps.googleapis.com/maps/api/js?key=IDXXX 但它消除了只查看标记信息的可能性,因为单击标记会立即触发路线渲染):

var map;
function initialize() {
    var center_map = new google.maps.LatLng(45,-4);
    var mapOptions = {
        zoom: zoomvalue,    // defined on the page
        center: center_map,
        mapTypeId: google.maps.MapTypeId.SATELLITE,
        scaleControl: true
    };
    map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
    var ctaLayer = new google.maps.KmlLayer({
        url: urlkmlfile,    // defini sur page qui appelle ce script
        preserveViewport: false
    });
    ctaLayer.setMap(map);

    if(navigator.geolocation) {
        navigator.geolocation.watchPosition(function(position) {
            var pos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
            if(typeof pos_infowindow == "undefined") {
                pos_infowindow = new google.maps.InfoWindow({
                    disableAutoPan: true,
                    map: map,
                    position: pos,
                    content: 'Votre position'
                });
            }
            else {
                pos_infowindow.setPosition(pos);
            }
    // add code here
        },
        function() {
            // alert('no geolocation');

        },
        { timeout: 15000, enableHighAccuracy: true }
        );
    }
};

google.maps.event.addDomListener(window, 'load', initialize);

然后通过单击任何 kml 标记来获取 latLng,以显示要遵循的路线,但我想要另一个选项而不是“单击”,以保持在不触发路线的情况下查看 infowindows 数据的可能性(如果我放'dblClick' 在下面的addListener 事件中,它仍然只是放大):

if (pos) google.maps.event.addListener(ctaLayer, 'click', function(kmlEvent) {
    var name_marker = kmlEvent.featureData.name;
    var text_marker = kmlEvent.featureData.description;
    var pos_marker = kmlEvent.latLng;
    var offset_marker = kmlEvent.pixelOffset;
    var directionsService = new google.maps.DirectionsService();
    var directionsRequest = {
    origin: pos,
    destination: pos_marker,
    travelMode: google.maps.DirectionsTravelMode.DRIVING,
    unitSystem: google.maps.UnitSystem.METRIC
    };
    // alert('start ' + pos + ' destination ' + pos_marker);
    directionsService.route( directionsRequest, function(response, status)
    {
        if (status == google.maps.DirectionsStatus.OK)
        {
            new google.maps.DirectionsRenderer({
                map: map,
                directions: response
            });
        }
        else{
  // alert ('problem');
        }
    }); 
});

有没有简单的方法来做到这一点?我想保留 'click' 事件以读取每个标记的数据,并保留 'dblClick' 事件或添加到 infoWindow 中的链接,以触发 directionsRequest 我想保持简单。

【问题讨论】:

  • 发布的代码包含语法错误(pos_infowindow 不是构造函数)。请提供一个 minimal reproducible example 来证明您的问题。
  • 对不起,我想知道为什么没有地理定位了!经过一些更正后,我得到状态“REQUEST_DENIED”,所以DirectionsRenderer 不适用。 (我也知道 Firefox 不接受没有 SSL/https 的 navigator.geolocation.watchPosition)。
  • 这些听起来像是完全不同的问题,但已经有了答案。
  • 不是一个不同的问题,我想通过双击标记或单击信息窗口中的链接来呈现这条路线(无论如何都不会触发)。我刚刚发布了这段代码作为我正在尝试做的一个例子。如果太复杂,没问题!
  • 您能否添加 kml 数据 - 如果这是实时的,则可以添加指向它的链接?

标签: javascript google-maps kml marker infowindow


【解决方案1】:

KmlLayer 不支持双击事件(它唯一支持的鼠标事件是单击)。

一种选择是在信息窗口中为呈现的 HTML 添加一个“获取路线”链接,然后使用该点击事件的event.latLng 作为目的地:

ctaLayer.addListener("click", function(event) {
  infowindow.setContent(event.featureData.infoWindowHtml+"<br><a href='javascript:getDirections("+event.latLng.toUrlValue(6)+");'>get directions</a>");
  infowindow.setOptions({pixelOffset: event.pixelOffset});
  infowindow.setPosition(event.latLng);
  infowindow.open(map);
});

function getDirections(lat, lng) {
  start = pos_infowindow.getPosition(); // current position as defined in the geolocation function
  var latLng = new google.maps.LatLng(lat, lng);
  destination = latLng; // position of the marker clicked, as defined by the kml file
  var directionsService = new google.maps.DirectionsService();
  var directionsRequest = {
    origin: start,
    destination: destination,
    travelMode: google.maps.DirectionsTravelMode.DRIVING,
    unitSystem: google.maps.UnitSystem.METRIC
  };
  directionsService.route(directionsRequest, function(response, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      directionsDisplay.setDirections(response);
    } else
      alert('Directions Request failed: ' + status);
  });
}

proof of concept fiddle

代码 sn-p:

var map;
var pos_infowindow;
var infowindow;
var directionsDisplay;

function initialize() {
  var center_map = new google.maps.LatLng(45, -4);
  var infowindow = new google.maps.InfoWindow();
  var mapOptions = {
    zoom: 5, // defined on the page
    center: {
      lat: 0,
      lng: 0
    },
    mapTypeId: google.maps.MapTypeId.SATELLITE,
    scaleControl: true
  };
  map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
  directionsDisplay = new google.maps.DirectionsRenderer({
    map: map
  });
  var ctaLayer = new google.maps.KmlLayer({
    url: "http://www.geocodezip.com/state_capitals.xml", // defini sur page qui appelle ce script
    preserveViewport: false,
    suppressInfoWindows: true
  });
  ctaLayer.setMap(map);
  ctaLayer.addListener("click", function(event) {
    infowindow.setContent(event.featureData.infoWindowHtml + "<br><a href='javascript:getDirections(" + event.latLng.toUrlValue(6) + ");'>get directions</a>");
    infowindow.setOptions({
      pixelOffset: event.pixelOffset
    });
    infowindow.setPosition(event.latLng);
    infowindow.open(map);
  });

  if (navigator.geolocation) {
    navigator.geolocation.watchPosition(function(position) {
        var pos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
        if (typeof pos_infowindow == "undefined") {
          pos_infowindow = new google.maps.InfoWindow({
            disableAutoPan: true,
            map: map,
            position: pos,
            content: 'Votre position'
          });
        } else {
          pos_infowindow.setPosition(pos);
        }
        // add code here
      },
      function() {
        alert('no geolocation');
        pos_infowindow = new google.maps.InfoWindow({
          disableAutoPan: true,
          map: map,
          position: {
            lat: 39.011902,
            lng: -98.4842465
          }, // default to Kansas
          content: 'Votre position'
        });
      }, {
        timeout: 15000,
        enableHighAccuracy: true
      }
    );
  }
}

google.maps.event.addDomListener(window, 'load', initialize);

function getDirections(lat, lng) {
  start = pos_infowindow.getPosition(); // current position as defined in the geolocation function
  var latLng = new google.maps.LatLng(lat, lng);
  destination = latLng; // position of the marker clicked, as defined by the kml file
  var directionsService = new google.maps.DirectionsService();
  var directionsRequest = {
    origin: start,
    destination: destination,
    travelMode: google.maps.DirectionsTravelMode.DRIVING,
    unitSystem: google.maps.UnitSystem.METRIC
  };
  directionsService.route(directionsRequest, function(response, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      directionsDisplay.setDirections(response);
    } else
      alert('Directions Request failed: ' + status);
  });
}
html,
body,
#map-canvas {
  height: 90%;
  width: 100%;
  padding: 0px;
  margin: 0px;
}
<script src="https://maps.googleapis.com/maps/api/js?libraries=geometry"></script>
<div id='map-canvas'></div>

【讨论】:

    猜你喜欢
    • 2012-07-22
    • 1970-01-01
    • 2016-10-06
    • 2015-04-26
    • 1970-01-01
    • 1970-01-01
    • 2021-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多