Google 地图 API & geoxml 3 - 缩放至地图上 click/Center 地标上的地标

Google Maps API & geoxml 3 - Zoom to placemark on click/Center placemark on map

更新的脚本 - 单击并 zoom/center

还是不太对,先点击显示infoWindow放不上zoom/center

// When the window has finished loading create our google map below
    google.maps.event.addDomListener(window, 'load', initialize);

var geoXml = null;
var geoXmlDoc = null;
var map = null;
var myLatLng = null;
var myGeoXml3Zoom = false;
var sidebarHtml = "";
var infowindow = null;
var kmlLayer = null;
var filename = "test.kml.xml";

    function initialize() {
      myLatLng = new google.maps.LatLng(52.60426, 1.72764);
      // these set the initial center and zoom for the map
      // if it is not specified in the query string
      var lat = 52.60426;
      var lng = 1.72764;
      var zoom = 16;

      if (!isNaN(lat) && !isNaN(lng)) {
        myLatLng = new google.maps.LatLng(lat, lng);
      }
                var myOptions = {
                    zoom: zoom,
                    center: myLatLng,
                    streetViewControl: false,
                    mapTypeControl: false,
                    zoomControl: true,
                    // How you would like to style the map.
                    // This is where you would paste any style found on Snazzy Maps.
                    styles: [{"featureType":"all","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"administrative.country","elementType":"labels.text","stylers":[{"visibility":"off"}]},{"featureType":"administrative.province","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"administrative.locality","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"administrative.neighborhood","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"administrative.land_parcel","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"landscape.man_made","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"landscape.natural","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"road","elementType":"labels","stylers":[{"visibility":"on"}]},{"featureType":"road.arterial","elementType":"labels.text","stylers":[{"visibility":"on"}]},{"featureType":"transit","elementType":"labels","stylers":[{"visibility":"off"}]}]
                    // zoom: 16,
                    // center: myLatlng,
                };
                map = new google.maps.Map(document.getElementById("map"),
                      myOptions);
                infowindow = new google.maps.InfoWindow({});

   geoXml = new geoXML3.parser({
                    map: map,
                    infoWindow: infowindow,
                    singleInfoWindow: true,
                    zoom: myGeoXml3Zoom,
                    afterParse: useTheData
                });
                geoXml.parse(filename);
        };

function kmlClick(pm) {
       if (geoXml.docs[0].placemarks[pm].marker.getMap()) {
          google.maps.event.trigger(geoXml.docs[0].placemarks[pm].marker,"click");
       } else {
          geoXmlDoc.placemarks[pm].marker.setMap(map);
          google.maps.event.trigger(geoXmlDoc.placemarks[pm].marker,"click");
       }

    google.maps.event.addListener(geoXml.docs[0].placemarks[pm].marker, "click", function (e) {
        map.setZoom(19);
        //infoWindow.open(map, marker);

        map.panTo(geoXml.docs[0].placemarks[pm].marker.getPosition());
    });
}

function showAll() {
        map.setZoom(16);
        map.panTo(myLatLng);
}

// == builds the sidebar ==

function makeSidebarEntry(i) {
  var name = geoXmlDoc.placemarks[i].name;
   if (!name  || (name.length == 0)) name = "marker #"+i;
   // alert(name);
   sidebarHtml += '<tr id="row'+i+'"><td><img src='+geoXmlDoc.placemarks[i].style.href+' height="20" alt="icon" /></td><td><a href="javascript:kmlClick('+i+');">'+name+'</a></td></tr>';
}

function makeSidebar() {
  sidebarHtml = '<table><tr></tr>';
  var currentBounds = map.getBounds();
// if bounds not yet available, just use the empty bounds object;
if (!currentBounds) currentBounds=new google.maps.LatLngBounds();
if (geoXmlDoc) {
  for (var i=0; i<geoXmlDoc.placemarks.length; i++) {
    if (geoXmlDoc.placemarks[i].marker) {
      if (currentBounds.contains(geoXmlDoc.placemarks[i].marker.getPosition())) {
         makeSidebarEntry(i);
      }
    }
  }
}
  sidebarHtml += "</table>";
  document.getElementById("sidebar").innerHTML = sidebarHtml;
}

function useTheData(doc){
  var currentBounds = map.getBounds();
  if (!currentBounds) currentBounds=new google.maps.LatLngBounds();
  // Geodata handling goes here, using JSON properties of the doc object
  sidebarHtml = '<table><tr></tr>';
//  var sidebarHtml = '<table>';
  geoXmlDoc = doc[0];
  for (var i = 0; i < geoXmlDoc.placemarks.length; i++) {
    // console.log(doc[0].markers[i].title);
    var placemark = geoXmlDoc.placemarks[i];
    if (placemark.marker) {
      if (currentBounds.contains(placemark.marker.getPosition())) {
         makeSidebarEntry(i);
      }
    }

/*    doc[0].markers[i].setVisible(false); */
  }
  sidebarHtml += "</table>";
  document.getElementById("sidebar").innerHTML = sidebarHtml;
};

XML:

<?xml version='1.0' encoding='UTF-8'?>
<kml xmlns='http://www.opengis.net/kml/2.2'>
    <Document>
        <name>Map</name>
        <description></description>
        <Folder>
            <name>Points</name>
            <Placemark>
                <name>Placemark 1</name>
                <description>Description</description>
                <styleUrl>#icon-1239</styleUrl>
                <Point>
                    <coordinates>1.7275818,52.6043317,0.0</coordinates>
                </Point>
            </Placemark>
            <Placemark>
                <name>Placemark 2</name>
                <description>Description</description>
                <styleUrl>#icon-1279</styleUrl>
                <Point>
                    <coordinates>1.73041,52.60436,0.0</coordinates>
                </Point>
            </Placemark>
        </Folder>
        <Style id='icon-1239'>
            <IconStyle>
                <scale>1.1</scale>
                <Icon>
                    <href>http://www.gstatic.com/mapspro/images/stock/1239-poi-civic.png</href>
                </Icon>
            </IconStyle>
        </Style>
        <Style id='icon-1279'>
            <IconStyle>
                <scale>1.1</scale>
                <Icon>
                    <href>http://www.gstatic.com/mapspro/images/stock/1279-poi-library.png</href>
                </Icon>
            </IconStyle>
        </Style>
    </Document>
</kml>

您好,我正在尝试使用 Google 地图 API 和 geoxml3 创建自定义地图。我已经设法设置了地图并添加了一个自定义侧边栏,其中包含从外部 KML.xml 文件加载的地标列表。

我想要它,这样当您从边栏或地图上单击地标时,地图将自动以地标为中心并放大。

这是我目前的 HTML 和脚本,

HTML:

<head>
    <title>Test Map</title>
    <link rel="stylesheet" href="css/style.css" type="text/css">
</head>

<body>

    <div class="map">
        <div id="map"></div>
        <div id="side_bar">
            <h3>Locations</h3>
            <div id="sidebar"></div>
            <p>*Click to show location on map</p>
        </div>
    </div>

    <!-- Scripts -->
    <script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAWj4S3HGnCZ2ZzlRg4bfb4Z7HcpJ82tl8&"></script>
    <script src="js/map.js"></script>
    <script src="js/geoxml3.js"></script>
    <!-- jQuery -->
    <script src="js/jquery.js"></script>

</body>

脚本:

// When the window has finished loading create our google map below
    google.maps.event.addDomListener(window, 'load', initialize);

var geoXml = null;
var geoXmlDoc = null;
var map = null;
var myLatLng = null;
var myGeoXml3Zoom = false;
var sidebarHtml = "";
var infowindow = null;
var kmlLayer = null;
var filename = "test.kml.xml";

    function initialize() {
      myLatLng = new google.maps.LatLng(52.60426, 1.72764);
      // these set the initial center and zoom for the map
      // if it is not specified in the query string
      var lat = 52.60426;
      var lng = 1.72764;
      var zoom = 16;

      if (!isNaN(lat) && !isNaN(lng)) {
        myLatLng = new google.maps.LatLng(lat, lng);
      }
                var myOptions = {
                    zoom: zoom,
                    center: myLatLng,
                    streetViewControl: false,
                    mapTypeControl: false,
                    zoomControl: true,
                    // How you would like to style the map.
                    // This is where you would paste any style found on Snazzy Maps.
                    styles: [{"featureType":"all","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"administrative.country","elementType":"labels.text","stylers":[{"visibility":"off"}]},{"featureType":"administrative.province","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"administrative.locality","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"administrative.neighborhood","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"administrative.land_parcel","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"landscape.man_made","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"landscape.natural","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"road","elementType":"labels","stylers":[{"visibility":"on"}]},{"featureType":"road.arterial","elementType":"labels.text","stylers":[{"visibility":"on"}]},{"featureType":"transit","elementType":"labels","stylers":[{"visibility":"off"}]}]
                    // zoom: 16,
                    // center: myLatlng,
                };
                map = new google.maps.Map(document.getElementById("map"),
                      myOptions);
                infowindow = new google.maps.InfoWindow({});

   geoXml = new geoXML3.parser({
                    map: map,
                    infoWindow: infowindow,
                    singleInfoWindow: true,
                    zoom: myGeoXml3Zoom,
                    afterParse: useTheData
                });
                geoXml.parse(filename);
        };

function kmlClick(pm) {
   if (geoXml.docs[0].placemarks[pm].marker.getMap()) {
      google.maps.event.trigger(geoXml.docs[0].placemarks[pm].marker,"click");
   } else {
      geoXmlDoc.placemarks[pm].marker.setMap(map);
      google.maps.event.trigger(geoXmlDoc.placemarks[pm].marker,"click");
   }
}

// == builds the sidebar ==

function makeSidebarEntry(i) {
  var name = geoXmlDoc.placemarks[i].name;
   if (!name  || (name.length == 0)) name = "marker #"+i;
   // alert(name);
   sidebarHtml += '<tr id="row'+i+'"><td><img src='+geoXmlDoc.placemarks[i].style.href+' height="20" alt="icon" /></td><td><a href="javascript:kmlClick('+i+');">'+name+'</a></td></tr>';
}

function makeSidebar() {
  sidebarHtml = '<table><tr></tr>';
  var currentBounds = map.getBounds();
// if bounds not yet available, just use the empty bounds object;
if (!currentBounds) currentBounds=new google.maps.LatLngBounds();
if (geoXmlDoc) {
  for (var i=0; i<geoXmlDoc.placemarks.length; i++) {
    if (geoXmlDoc.placemarks[i].marker) {
      if (currentBounds.contains(geoXmlDoc.placemarks[i].marker.getPosition())) {
         makeSidebarEntry(i);
      }
    }
  }
}
  sidebarHtml += "</table>";
  document.getElementById("sidebar").innerHTML = sidebarHtml;
}

function useTheData(doc){
  var currentBounds = map.getBounds();
  if (!currentBounds) currentBounds=new google.maps.LatLngBounds();
  // Geodata handling goes here, using JSON properties of the doc object
  sidebarHtml = '<table><tr></tr>';
//  var sidebarHtml = '<table>';
  geoXmlDoc = doc[0];
  for (var i = 0; i < geoXmlDoc.placemarks.length; i++) {
    // console.log(doc[0].markers[i].title);
    var placemark = geoXmlDoc.placemarks[i];
    if (placemark.marker) {
      if (currentBounds.contains(placemark.marker.getPosition())) {
         makeSidebarEntry(i);
      }
    }

/*    doc[0].markers[i].setVisible(false); */
  }
  sidebarHtml += "</table>";
  document.getElementById("sidebar").innerHTML = sidebarHtml;
};

如有任何帮助,我们将不胜感激。

测试将您的函数 makeSidebar() 更改为:

function makeSidebar() {
  sidebarHtml = '<table><tr></tr>';
  var currentBounds = map.getBounds();
if (!currentBounds) currentBounds=new google.maps.LatLngBounds();
if (geoXmlDoc) {
  for (var i=0; i<geoXmlDoc.placemarks.length; i++) {
    if (geoXmlDoc.placemarks[i].marker) {
  if (currentBounds.contains(geoXmlDoc.placemarks[i].marker.getPosition())) {
     makeSidebarEntry(i);

        google.maps.event.addListener(geoXmlDoc.placemarks[i].marker, "click", function (e) {
            map.setZoom(16);
            //infoWindow.open(map, marker);

            map.setCenter(marker.getPosition());
        });
  }
}
  }
}

尝试将您的函数 Onclick 更改为:

 function kmlClick(pm) {
    google.maps.event.addListener(geoXml.docs[0].placemarks[pm].marker, "click", function (e) {
                    map.setZoom(16);
                    //infoWindow.open(map, marker);

                    map.setCenter(marker.getPosition());
                });
       if (geoXml.docs[0].placemarks[pm].marker.getMap()) {
          google.maps.event.trigger(geoXml.docs[0].placemarks[pm].marker,"click");
       } else {
          geoXmlDoc.placemarks[pm].marker.setMap(map);
          google.maps.event.trigger(geoXmlDoc.placemarks[pm].marker,"click");
       }
    }

方法是当您在地图中创建标记时,您必须为其添加一个侦听器"click"希望对您有所帮助

在@BLD_Sys

的帮助下,我已经设法使居中和缩放几乎可以正常工作
function kmlClick(pm) {
    google.maps.event.addListener(geoXml.docs[0].placemarks[pm].marker, "click", function (e) {
                    map.setZoom(19);
                    //infoWindow.open(map, marker);

                    map.panTo(geoXml.docs[0].placemarks[pm].marker.getPosition());
                });
       if (geoXml.docs[0].placemarks[pm].marker.getMap()) {
          google.maps.event.trigger(geoXml.docs[0].placemarks[pm].marker,"click");
       } else {
          geoXmlDoc.placemarks[pm].marker.setMap(map);
          google.maps.event.trigger(geoXmlDoc.placemarks[pm].marker,"click");
       }
    }

我必须添加 geoXML.docs[0].placemarks[pm] 位,因为它仅使用 marker.getPosition()

返回引用错误

我仍然有一个问题,只有先单击侧边栏而不是先单击地图上的地标才能正常工作。

test 测试后将代码移动为:

 function kmlClick(pm) {

          if (geoXml.docs[0].placemarks[pm].marker.getMap()) {
              google.maps.event.trigger(geoXml.docs[0].placemarks[pm].marker,"click");
           } else {
              geoXmlDoc.placemarks[pm].marker.setMap(map);
              google.maps.event.trigger(geoXmlDoc.placemarks[pm].marker,"click");
           }


        google.maps.event.addListener(geoXml.docs[0].placemarks[pm].marker, "click", function (e) {
                        map.setZoom(19);
                        //infoWindow.open(map, marker);

                        map.panTo(geoXml.docs[0].placemarks[pm].marker.getPosition());
                    });
        }

如果他为你工作,请告诉我,感谢马克投票回答。

我尝试在我的机器上测试这段代码,但我没有"test.kml.xml"; 您尝试以任何方式更改函数 useTheData as :

function useTheData(doc){
  var currentBounds = map.getBounds();
  if (!currentBounds) currentBounds=new google.maps.LatLngBounds();
  // Geodata handling goes here, using JSON properties of the doc object
  sidebarHtml = '<table><tr></tr>';
//  var sidebarHtml = '<table>';
  geoXmlDoc = doc[0];
  for (var i = 0; i < geoXmlDoc.placemarks.length; i++) {
    // console.log(doc[0].markers[i].title);
    var placemark = geoXmlDoc.placemarks[i];
    if (placemark.marker) {
      if (currentBounds.contains(placemark.marker.getPosition())) {
         makeSidebarEntry(i);
 google.maps.event.addListener(placemark.marker, "click", function (e) {
        map.setZoom(19);
        //infoWindow.open(map, marker);

        map.panTo(geoXml.docs[0].placemarks[pm].marker.getPosition());

      }
    }

/*    doc[0].markers[i].setVisible(false); */
  }
  sidebarHtml += "</table>";
  document.getElementById("sidebar").innerHTML = sidebarHtml;
};

我希望这是最好的

要使地图在侧边栏上单击的标记居中,请将代码添加到调用的函数中(kmlClick):

function kmlClick(pm) {
  // center the map on the marker and change the zoom to 18
  if (geoXml.docs[0].placemarks[pm].marker.getPosition){
     map.setCenter(geoXml.docs[0].placemarks[pm].marker.getPosition());
     map.setZoom(19);
  }
     
  if (geoXml.docs[0].placemarks[pm].marker.getMap()) {
    // if map is not null (marker is on the map), trigger a click on it
     google.maps.event.trigger(geoXml.docs[0].placemarks[pm].marker,"click");
  } else {
    // if map is null (marker is not on the map), add it to the map,
    // then trigger a click on it
    geoXmlDoc.placemarks[pm].marker.setMap(map);
    google.maps.event.trigger(geoXmlDoc.placemarks[pm].marker,"click");
  }
}

如果您希望它在单击标记或从侧边栏触发单击时居中和缩放,请将该功能放入标记单击侦听器中。一种方法是向 useTheData:

中的标记添加标记点击侦听器
function useTheData(doc){
  var currentBounds = map.getBounds();
  if (!currentBounds) currentBounds=new google.maps.LatLngBounds();
  sidebarHtml = '<table><tr></tr>';
  geoXmlDoc = doc[0];
  for (var i = 0; i < geoXmlDoc.placemarks.length; i++) {
    var placemark = geoXmlDoc.placemarks[i];
    if (placemark.marker) {
      google.maps.event.addListener(placemark.marker,'click',function(evt) {
        this.getMap().setCenter(this.getPosition());
        this.getMap().setZoom(19);
      });
      if (currentBounds.contains(placemark.marker.getPosition())) {
         makeSidebarEntry(i);
      }
    }
  }
  sidebarHtml += "</table>";
  document.getElementById("sidebar").innerHTML = sidebarHtml;
};

proof of concept

代码片段:

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

var geoXml = null;
var geoXmlDoc = null;
var map = null;
var myLatLng = null;
var myGeoXml3Zoom = false;
var sidebarHtml = "";
var infowindow = null;
var kmlLayer = null;
var filename = "kml/SO_20160415_placemarks.kml";

function initialize() {
  myLatLng = new google.maps.LatLng(52.60426, 1.72764);
  var lat = 52.60426;
  var lng = 1.72764;
  var zoom = 16;

  if (!isNaN(lat) && !isNaN(lng)) {
    myLatLng = new google.maps.LatLng(lat, lng);
  }
  var myOptions = {
    zoom: zoom,
    center: myLatLng,
    streetViewControl: false,
    mapTypeControl: false,
    zoomControl: true
  };
  map = new google.maps.Map(document.getElementById("map"),
    myOptions);
  infowindow = new google.maps.InfoWindow({});

  geoXml = new geoXML3.parser({
    map: map,
    infoWindow: infowindow,
    singleInfoWindow: true,
    zoom: myGeoXml3Zoom,
    afterParse: useTheData
  });
  geoXml.parseKmlString(kmlStr);
  google.maps.event.addListener(map, "bounds_changed", makeSidebar);
  google.maps.event.addListener(map, "center_changed", makeSidebar);
  google.maps.event.addListener(map, "zoom_changed", makeSidebar);
  google.maps.event.addListenerOnce(map, "idle", makeSidebar);
};

function kmlClick(pm) {
  if (geoXml.docs[0].placemarks[pm].marker.getMap()) {
    google.maps.event.trigger(geoXml.docs[0].placemarks[pm].marker, "click");
  } else {
    geoXmlDoc.placemarks[pm].marker.setMap(map);
    google.maps.event.trigger(geoXmlDoc.placemarks[pm].marker, "click");
  }
}

function showAll() {
  map.setZoom(16);
  map.panTo(myLatLng);
}

// == builds the sidebar ==
function makeSidebarEntry(i) {
  var name = geoXmlDoc.placemarks[i].name;
  if (!name || (name.length == 0)) name = "marker #" + i;
  sidebarHtml += '<tr id="row' + i + '"><td><img src=' + geoXmlDoc.placemarks[i].style.href + ' height="20" alt="icon" /></td><td><a href="javascript:kmlClick(' + i + ');">' + name + '</a></td></tr>';
}

function makeSidebar() {
  sidebarHtml = '<table><tr></tr>';
  var currentBounds = map.getBounds();
  // if bounds not yet available, just use the empty bounds object;
  if (!currentBounds) currentBounds = new google.maps.LatLngBounds();
  if (geoXmlDoc) {
    for (var i = 0; i < geoXmlDoc.placemarks.length; i++) {
      if (geoXmlDoc.placemarks[i].marker) {
        if (currentBounds.contains(geoXmlDoc.placemarks[i].marker.getPosition())) {
          makeSidebarEntry(i);
        }
      }
    }
  }
  sidebarHtml += "</table>";
  document.getElementById("sidebar").innerHTML = sidebarHtml;
}

function useTheData(doc) {
  var currentBounds = map.getBounds();
  if (!currentBounds) currentBounds = new google.maps.LatLngBounds();
  sidebarHtml = '<table><tr></tr>';
  geoXmlDoc = doc[0];
  for (var i = 0; i < geoXmlDoc.placemarks.length; i++) {
    var placemark = geoXmlDoc.placemarks[i];
    if (placemark.marker) {
      google.maps.event.addListener(placemark.marker, 'click', function(evt) {
        this.getMap().setCenter(this.getPosition());
        this.getMap().setZoom(19);
      });

      if (currentBounds.contains(placemark.marker.getPosition())) {
        makeSidebarEntry(i);
      }
    }
  }
  sidebarHtml += "</table>";
  document.getElementById("sidebar").innerHTML = sidebarHtml;
};

var kmlStr = "<?xml version='1.0' encoding='UTF-8'?><kml xmlns='http://www.opengis.net/kml/2.2'><Document><name>Map</name><description></description><Folder><name>Points</name><Placemark><name>Placemark 1</name><description>Description</description><styleUrl>#icon-1239</styleUrl><Point><coordinates>1.7275818,52.6043317,0.0</coordinates></Point></Placemark><Placemark><name>Placemark 2</name><description>Description</description><styleUrl>#icon-1279</styleUrl><Point><coordinates>1.73041,52.60436,0.0</coordinates></Point></Placemark></Folder><Style id='icon-1239'><IconStyle><scale>1.1</scale><Icon><href>http://www.gstatic.com/mapspro/images/stock/1239-poi-civic.png</href></Icon></IconStyle></Style><Style id='icon-1279'><IconStyle><scale>1.1</scale><Icon><href>http://www.gstatic.com/mapspro/images/stock/1279-poi-library.png</href></Icon></IconStyle></Style></Document></kml>";
html,
body,
#map,
.map {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}
<script src="https://rawgit.com/geocodezip/geoxml3/master/polys/geoxml3.js"></script>
<script src="https://maps.google.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div class="map">
  <div id="side_bar">
    <h3>Locations</h3>
    <div id="sidebar"></div>
    <p>*Click to show location on map</p>
  </div>
  <div id="map"></div>
</div>