Google Maps API& geoxml 3 - 缩放到地图上的点击/中心地标上的地标

时间:2016-04-15 10:48:56

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

更新后的脚本 - 点击和缩放/中心

仍然不太正确,首先点击显示infoWindow put不缩放/中心

// 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 Maps 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;
};

非常感谢任何帮助。

6 个答案:

答案 0 :(得分:1)

要将地图置于侧边栏上单击的标记上,请将代码添加到所调用的函数(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="http://maps.google.com/maps/api/js"></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>

答案 1 :(得分:0)

Test to change your function makeSidebar() as:

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());
        });
  }
}
  }
}

答案 2 :(得分:0)

尝试将您的功能Kmlclick更改为:

 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");
       }
    }

approch就是当你在地图中创建标记时,你必须添加一个列表器“click”我跳,它可以帮助你

答案 3 :(得分:0)

在@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()

返回参考错误

我仍然遇到问题,只有先点击侧边栏才能使用,而不是先点击地图上的地标。

答案 4 :(得分:0)

测试将测试后的代码移动为:

 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());
                    });
        }

告诉我他是否为你工作,并感谢回答标记投票。

答案 5 :(得分:0)

I try to test this code in my machine but i don't have "test.kml.xml"; any way you try to change your function 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;
};

I hope that this is one is the best