按类别选择标记和可选标记到可见标记

时间:2016-01-24 10:08:03

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

我有一个代码可以按类别切换标记的可见性,效果很好(参见下面的代码)。

我现在要添加的内容并不知道如何:

每次显示/隐藏标记组后,我希望调整地图的缩放和中心以显示所有可见的标记。
我找到了fitBounds()的另一个代码,但是没有设法使这两个代码一起工作(我对Javascript完全不熟悉)。

我找到了仅适用于可见标记的边界的示例,但没有按类别显示/隐藏标记。 (例如Center/Set Zoom of Map to cover all visible Markers?

这里有两个代码示例:

按类别显示/隐藏标记:

function xmlParse(str) {
    if (typeof ActiveXObject != 'undefined' && typeof GetObject != 'undefined') {
        var doc = new ActiveXObject('Microsoft.XMLDOM');
        doc.loadXML(str);
        return doc;
    }

    if (typeof DOMParser != 'undefined') {
        return (new DOMParser()).parseFromString(str, 'text/xml');
    }

    return createElement('div', null);
}
var infoWindow = new google.maps.InfoWindow();
var customIcons = {
    monumento: {
        icon: 'http://maps.google.com/mapfiles/ms/icons/blue.png'
    },
    hotel: {
        icon: 'http://maps.google.com/mapfiles/ms/icons/green.png'
    },
    restaurantes: {
        icon: 'http://maps.google.com/mapfiles/ms/icons/yellow.png'
    },
    museus: {
        icon: 'http://maps.google.com/mapfiles/ms/icons/purple.png'
    }
};

var markerGroups = {
    "museus": [],
    "monumentos": [],
    "restaurantes": [],
    "hotel": []
};

function load() {
    var map = new google.maps.Map(document.getElementById("mapCanvas"), {
        center: new google.maps.LatLng(38.639104, -8.210413),
        zoom: 12,
        mapTypeId: 'satellite'
    });
    var infoWindow = new google.maps.InfoWindow();



    map.set('styles', [{
        zoomControl: false
    }, {
        featureType: "road.highway",
        elementType: "geometry.fill",
        stylers: [{
            color: "#ffd986"
        }]
    }, {
        featureType: "road.arterial",
        elementType: "geometry.fill",
        stylers: [{
            color: "#9e574f"
        }]
    }, {
        featureType: "road.local",
        elementType: "geometry.fill",
        stylers: [{
                color: "#d0cbc0"
            }, {
                weight: 1.1
            }

        ]
    }, {
        featureType: 'road',
        elementType: 'labels',
        stylers: [{
            saturation: -100
        }]
    }, {
        featureType: 'landscape',
        elementType: 'geometry',
        stylers: [{
            hue: '#ffff00'
        }, {
            gamma: 1.4
        }, {
            saturation: 82
        }, {
            lightness: 96
        }]
    }, {
        featureType: 'poi.school',
        elementType: 'geometry',
        stylers: [{
            hue: '#fff700'
        }, {
            lightness: -15
        }, {
            saturation: 99
        }]
    }]);

    //         downloadUrl("markers.xml", function (data) {
    var xml = xmlParse('<markers><marker name="Castelo" address="Rua da Condessa de Valença" lat="38.64351973190569" lng="-8.216521812152905" type="monumento" /><marker name="Anta 1 de Tourais" address="Estrada Nacional 114" lat="38.64260059929888" lng="-8.159376865959189" type="monumento" /><marker name="Hotel da Ameira" address="Herdade da Ameira" lat="38.64109640475479" lng="-8.180432206726096" type="hotel" /><marker name="Hotel Montemor" address="Avenida Gago Coutinho 8, 7050-248 Montemor-o-Novo" lat="38.64925541964039" lng="-8.216489625644726" type="hotel" /><marker name="Restaurante Monte Alentejano" address="Av. Gago Coutinho 8" lat="38.6492329" lng="-8.216665" type="restaurantes" /><marker name="Restaurante A Ribeira" address="Rua de São Domingos" lat="38.6347498199708" lng="-8.206468892765088" type="restaurantes" /><marker name="Núcleo Museológico do Convento de S. Domingos" address="" lat="38.643139" lng="-8.212732" type="museus" /><marker name="Centro Interpretativo do Castelo de Montemor-o-Novo" address="Rua Condessa de Valença" lat="38.64258748216167" lng="-8.21467108793263" type="museus" /></markers>');
    // var xml = data.responseXML;
    var markers = xml.documentElement.getElementsByTagName("marker");
    for (var i = 0; i < markers.length; i++) {
        var name = markers[i].getAttribute("name");
        var address = markers[i].getAttribute("address");
        var type = markers[i].getAttribute("type");

        var point = new google.maps.LatLng(
            parseFloat(markers[i].getAttribute("lat")),
            parseFloat(markers[i].getAttribute("lng")));
        var html = "<b>" + name + "</b> <br/>" + address;
        // var icon = customIcons[type] || {};
        var marker = createMarker(point, name, address, type, map);
        bindInfoWindow(marker, map, infoWindow, html);
    }
    // });
}

function createMarker(point, name, address, type, map) {
    var icon = customIcons[type] || {};
    var marker = new google.maps.Marker({
        map: map,
        position: point,
        icon: icon.icon,
        // shadow: icon.shadow,
        type: type
    });
    if (!markerGroups[type]) markerGroups[type] = [];
    markerGroups[type].push(marker);
    var html = "<b>" + name + "</b> <br/>" + address;
    bindInfoWindow(marker, map, infoWindow, html);
    return marker;
}

function toggleGroup(type) {
    for (var i = 0; i < markerGroups[type].length; i++) {
        var marker = markerGroups[type][i];
        if (!marker.getVisible()) {
            marker.setVisible(true);
        } else {
            marker.setVisible(false);
        }
    }
}


function bindInfoWindow(marker, map, infoWindow, html) {
    google.maps.event.addListener(marker, 'click', function() {
        infoWindow.setContent(html);
        infoWindow.open(map, marker);

    });
}

function downloadUrl(url, callback) {
    var request = window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest();

    request.onreadystatechange = function() {
        if (request.readyState == 4) {
            request.onreadystatechange = doNothing;
            callback(request, request.status);
        }
    };

    request.open('GET', url, true);
    request.send(null);
}

function doNothing() {}
google.maps.event.addDomListener(window, 'load', load);

fitBounds()到可见标记:

function fitBoundsToVisibleMarkers() {

   var bounds = new google.maps.LatLngBounds();

   for (var i = 0; i < markers.length; i++) {
       if (markers[i].getVisible()) {
           bounds.extend(markers[i].getPosition());
       }
   }

   map.fitBounds(bounds);
}

2 个答案:

答案 0 :(得分:0)

只需稍微调整一下你的toggleGroup函数即可。此时您已经设置了标记可见性;只需在那里添加几行,也可以将这些可见标记添加到LatLngBounds对象中。然后在调整完所有标记后,更新地图以适应新的边界。

- res/layouts
    - layout
        - layout1.xml
    - layouts_category2
        - layout
            - layout2.xml

您唯一需要做的就是让您的a 4-byte value representing the seconds since the Unix epoch, a 3-byte machine identifier, a 2-byte process id, and a 3-byte counter, starting with a random value. 变量全局化;现在它只是function toggleGroup(type) { var bounds = new google.maps.LatLngBounds(); for (var i = 0; i < markerGroups[type].length; i++) { var marker = markerGroups[type][i]; if (!marker.getVisible()) { marker.setVisible(true); bounds.extend(marker.getPosition()); } else { marker.setVisible(false); } } map.fitBounds(bounds); } 函数的本地。

答案 1 :(得分:0)

您的代码存在一些问题:

  1. 您收到了错误消息:Uncaught TypeError: map.fitBounds is not a function。那是因为您需要将map变量设置为函数load
  2. 您需要收集所有可见标记,然后在其上运行map.fitBounds
  3. 工作代码:

    function xmlParse(str) {
      if (typeof ActiveXObject != 'undefined' && typeof GetObject != 'undefined') {
        var doc = new ActiveXObject('Microsoft.XMLDOM');
        doc.loadXML(str);
        return doc;
      }
    
      if (typeof DOMParser != 'undefined') {
        return (new DOMParser()).parseFromString(str, 'text/xml');
      }
    
      return createElement('div', null);
    }
    var infoWindow = new google.maps.InfoWindow();
    var customIcons = {
      monumento: {
        icon: 'http://maps.google.com/mapfiles/ms/icons/blue.png'
      },
      hotel: {
        icon: 'http://maps.google.com/mapfiles/ms/icons/green.png'
      },
      restaurantes: {
        icon: 'http://maps.google.com/mapfiles/ms/icons/yellow.png'
      },
      museus: {
        icon: 'http://maps.google.com/mapfiles/ms/icons/purple.png'
      }
    };
    
    var markerGroups = {
      "museus": [],
      "monumentos": [],
      "restaurantes": [],
      "hotel": []
    };
    
    var ctr = new google.maps.LatLng(38.639104, -8.210413),
        zoom = 12;
    
    var map;
    function load() {
      map = new google.maps.Map(document.getElementById("map"), {
        center: ctr,
        zoom: zoom,
        mapTypeId: 'roadmap'
      });
    
      var infoWindow = new google.maps.InfoWindow();
    
      map.set('styles', [{
        zoomControl: false
      }, {
        featureType: "road.highway",
        elementType: "geometry.fill",
        stylers: [{
          color: "#ffd986"
        }]
      }, {
        featureType: "road.arterial",
        elementType: "geometry.fill",
        stylers: [{
          color: "#9e574f"
        }]
      }, {
        featureType: "road.local",
        elementType: "geometry.fill",
        stylers: [{
          color: "#d0cbc0"
        }, {
          weight: 1.1
        }]
      }, {
        featureType: 'road',
        elementType: 'labels',
        stylers: [{
          saturation: -100
        }]
      }, {
        featureType: 'landscape',
        elementType: 'geometry',
        stylers: [{
          hue: '#ffff00'
        }, {
          gamma: 1.4
        }, {
          saturation: 82
        }, {
          lightness: 96
        }]
      }, {
        featureType: 'poi.school',
        elementType: 'geometry',
        stylers: [{
          hue: '#fff700'
        }, {
          lightness: -15
        }, {
          saturation: 99
        }]
      }]);
    
      //         downloadUrl("markers.xml", function (data) {
      var xml = xmlParse('<markers><marker name="Castelo" address="Rua da Condessa de Valença" lat="38.64351973190569" lng="-8.216521812152905" type="monumento" /><marker name="Anta 1 de Tourais" address="Estrada Nacional 114" lat="38.64260059929888" lng="-8.159376865959189" type="monumento" /><marker name="Hotel da Ameira" address="Herdade da Ameira" lat="38.64109640475479" lng="-8.180432206726096" type="hotel" /><marker name="Hotel Montemor" address="Avenida Gago Coutinho 8, 7050-248 Montemor-o-Novo" lat="38.64925541964039" lng="-8.216489625644726" type="hotel" /><marker name="Restaurante Monte Alentejano" address="Av. Gago Coutinho 8" lat="38.6492329" lng="-8.216665" type="restaurantes" /><marker name="Restaurante A Ribeira" address="Rua de São Domingos" lat="38.6347498199708" lng="-8.206468892765088" type="restaurantes" /><marker name="Núcleo Museológico do Convento de S. Domingos" address="" lat="38.643139" lng="-8.212732" type="museus" /><marker name="Centro Interpretativo do Castelo de Montemor-o-Novo" address="Rua Condessa de Valença" lat="38.64258748216167" lng="-8.21467108793263" type="museus" /></markers>');
      // var xml = data.responseXML;
      var markers = xml.documentElement.getElementsByTagName("marker");
      for (var i = 0; i < markers.length; i++) {
        var name = markers[i].getAttribute("name");
        var address = markers[i].getAttribute("address");
        var type = markers[i].getAttribute("type");
    
        var point = new google.maps.LatLng(
          parseFloat(markers[i].getAttribute("lat")),
          parseFloat(markers[i].getAttribute("lng")));
        var html = "<b>" + name + "</b> <br/>" + address;
        // var icon = customIcons[type] || {};
        var marker = createMarker(point, name, address, type, map);
        bindInfoWindow(marker, map, infoWindow, html);
      }
      // });
      //fitMap();
    }
    
    function createMarker(point, name, address, type, map) {
      var icon = customIcons[type] || {};
      var marker = new google.maps.Marker({
        map: map,
        position: point,
        icon: icon.icon,
        // shadow: icon.shadow,
        type: type,
        visible:false
      });
      if (!markerGroups[type]) markerGroups[type] = [];
      markerGroups[type].push(marker);
      var html = "<b>" + name + "</b> <br/>" + address;
      bindInfoWindow(marker, map, infoWindow, html);
      return marker;
    }
    
    function toggleGroup(type) {
      for (var i = 0; i < markerGroups[type].length; i++) {
        var marker = markerGroups[type][i];
        if (!marker.getVisible()) {
          marker.setVisible(true);
        } else {
          marker.setVisible(false);
        }
      }
    
      if (document.querySelectorAll(':checked').length == 0) {
        map.setCenter(ctr);
        map.setZoom(zoom);
      }
      else {
        fitMap();
      }
    }
    
    
    function fitMap() {
      var visibleMarkers = [];
      for (var i in markerGroups) {
        for (var j = 0; j < markerGroups[i].length; j++) {
          var marker = markerGroups[i][j];
          if (marker.getVisible()) {
            visibleMarkers.push(marker);
          }
        }
      }
    
      var bounds = new google.maps.LatLngBounds();
      for (var i = 0; i < visibleMarkers.length; i++) {
        bounds.extend(visibleMarkers[i].getPosition());
      }
    
      map.fitBounds(bounds);  
    }
    
    function bindInfoWindow(marker, map, infoWindow, html) {
      google.maps.event.addListener(marker, 'click', function () {
        infoWindow.setContent(html);
        infoWindow.open(map, marker);
      });
    }
    
    function downloadUrl(url, callback) {
      var request = window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest();
    
      request.onreadystatechange = function () {
        if (request.readyState == 4) {
          request.onreadystatechange = doNothing;
          callback(request, request.status);
        }
      };
    
      request.open('GET', url, true);
      request.send(null);
    }
    
    function doNothing() {}
    google.maps.event.addDomListener(window, 'load', load);
    html, body, #map, #map_wrap {
      height: 100%;
      width:100%;
    }
    <script src="https://maps.googleapis.com/maps/api/js?v=3&ext=.js"></script>
    <div class="map_wrap">
      <div class="siderbarmap">
        <ul>
          <input id="monumentoCheckbox" type="checkbox" onclick="toggleGroup('monumento')" />
          <input id="museusCheckbox" type="checkbox" onclick="toggleGroup('museus')"  />
          <input id="restaurantesCheckbox" type="checkbox" onclick="toggleGroup('restaurantes')" />
          <input id="hotelCheckbox" type="checkbox" onclick="toggleGroup('hotel')" />
        </ul>
      </div>
      <div id="map" style="width:100%;height:585px; z-index: 1;"></div>
    </div>

    <强>更新

    1. 我稍微更改了代码,所以现在找到可见标记的函数是独立的,所以我们可以在页面加载中调用它并在复选框被更改后(现在在注释中要求2.要使用它,只需删除评论//)。
    2. 在用户点击markers
    3. 之后,checkbox在开始时都不可见
    4. 如果所有复选框都不是:checked,则地图将重置为开始zoomcenter