【问题标题】:Google Maps API V3: KML plus additional marker not zooming to fit bothGoogle Maps API V3:KML 加上额外的标记不缩放以适应两者
【发布时间】:2012-08-10 22:36:32
【问题描述】:

我有一个可以在谷歌地图中正常加载的 kml 文件。在同一页面上,我有一个文本框,用户可以在其中输入他们的位置,这将添加一个标记,这也可以。

我遇到的问题是,如果用户输入了 kml 文件范围之外的位置,则地图不会缩放以同时包含 kml 和新标记。

如果我设置了 preserveViewport=false,它将缩放以适应 kml。如果为真,它将缩放以适应新标记。

$(document).ready(function () {
  var mapOptions = {
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };

  var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
  var ctaLayer = new google.maps.KmlLayer('KMLLOCATION', { preserveViewport: false });
  ctaLayer.setMap(map);

  var marker = new google.maps.Marker({ position: new google.maps.LatLng(LAT, LONG), map: map, title: 'You are here', clickable: false, icon: '/media/youarehere.png' });

  var bounds = new google.maps.LatLngBounds();
  var ll = new google.maps.LatLng(LAT, LONG);
  bounds.extend(ll);
  map.fitBounds(bounds);
});

编辑

感谢 geocodezip 为我指明了正确的方向。这是我更新后的代码。

$(document).ready(function () {
  var mapOptions = {
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };

  var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
  var layer = new google.maps.KmlLayer('KMLLOCATION', { map: map, preserveViewport: true });

  var marker = new google.maps.Marker({ position: new google.maps.LatLng(LAT, LONG), map: map, title: 'You are here', clickable: false, icon: '/media/youarehere.png' });

  google.maps.event.addListener(layer, 'defaultviewport_changed', function() {
    var bounds = layer.getDefaultViewport();
    var ll = new google.maps.LatLng(LAT, LONG);
    bounds.extend(ll);
    map.fitBounds(bounds);
  });
});

【问题讨论】:

    标签: google-maps google-maps-api-3 kml


    【解决方案1】:

    经过多次试验和错误,这就是我想出的。您需要包含图表加载器https://www.gstatic.com/charts/loader.js 和geoxml3 https://github.com/geocodezip/geoxml3/blob/master/kmz/geoxml3.js。这张地图查看一个国家代码排序的融合表,其中包含代表国家边界的几何图形,然后将边界绘制到地图上并放大它们。如果你想添加另一个标记,只需使用bounds.extend(someLatLngClassInstanceOrLiteral)

    google.charts.load('current', {
       'packages': ['table']
    });
    google.charts.setOnLoadCallback(zoomMap);
    
    function zoomMap(){
    
        var map = new google.maps.Map(document.querySelectorAll('.single-map-selector')[0], {
            center: new google.maps.LatLng(30, 0),
            zoom: 2,
            mapTypeId: google.maps.MapTypeId.ROADMAP,
            disableDefaultUI: true,
            scrollwheel: false,
            draggable: false,
        });
    
        var CountriesServed = ['US', 'CA', 'AU'];
    
        var jointCountriesArray = CountriesServed.map(function(val, index){
            if( index < CountriesServed.length - 1 ){
                return '\'' + val + '\', ';
            }
            else{
                return '\'' + val + '\'';
            }
        });
        jointCountriesArray = jointCountriesArray.join('');
    
        var world_geometry = new google.maps.FusionTablesLayer({
            query: {
                select: 'geometry',
                from: '1N2LBk4JHwWpOY4d9fobIn27lfnZ5MDy-NoqqRpk',
                where: "ISO_2DIGIT IN (" + jointCountriesArray + ")",
            },
            heatmap: {
                enabled: false
            },
            suppressInfoWindows: true,
            map: map,
            options: {
                styleId: 2,
                templateId: 2
            },
        });
    
        var queryText = encodeURIComponent("select geometry from 1N2LBk4JHwWpOY4d9fobIn27lfnZ5MDy-NoqqRpk where 'ISO_2DIGIT' in (" + jointCountriesArray + ")");
    
        var query = new google.visualization.Query('http://www.google.com/fusiontables/gvizdata?tq=' + queryText);
    
        query.send(handleQuery);
    
        function handleQuery(response){
            if (!response) {
                console.log('no response');
                return;
            }
            if (response.isError()) {
                console.log('Error in query: ' + response.getMessage() + ' ' + response.getDetailedMessage());
                return;
            } 
            FTresponse = response;
    
            numRows = FTresponse.getDataTable().getNumberOfRows();
    
            var coordinates = [];
            var bounds = new google.maps.LatLngBounds();
    
            for(var i = 0; i < numRows; i++) {
    
                var kml = FTresponse.getDataTable().getValue(i,0);
    
                var coordEls = geoXML3.xmlParse(kml).querySelectorAll('coordinates');
                var coordinateString = '';
    
                for(var j = 0; j < coordEls.length; j++){
                    coordinateString += coordEls[j].innerHTML + ' ';
                }
    
                var unpairedCoordinates = coordinateString.split(',').map(function(val,index, arr){
                    if( val == '0.0' ){
                        arr.splice(index,1);
                    }
                    else{
                        return val.replace('0.0 ', '');
                    }
                });
                for(var k = 0; k < unpairedCoordinates.length; k++){
                    if( (k == 0 || k % 2 == 0) && k < unpairedCoordinates.length - 2 ){
                        // is even or zero and we're not at the end of the array
                        // in the coordinates element the latlngs are flipped
                        bounds.extend({
                            lat : parseFloat(unpairedCoordinates[k+1]),
                            lng : parseFloat(unpairedCoordinates[k])
                        });
                    }
                }
    
            }
    
            map.fitBounds(bounds, -300);
            map.setCenter(bounds.getCenter());
    
            //// uncomment if you want to see the rectangle of the bounds
            // var rect = new google.maps.Rectangle({
            //  strokeColor: '#FFFFFF',
            //  strokeOpacity: 0.8,
            //  strokeWeight: 2,
            //  fillColor: '#FFFFFF',
            //  fillOpacity: 0.35,
            //  map: map,
            //  bounds: bounds
            // });
        }
    }
    

    【讨论】:

      【解决方案2】:

      此外,如果您包含多个 kml 并想要缩放所有 kml,这对我有用。

      var bounds = null;
      google.maps.event.addListener(layer, 'defaultviewport_changed', function () {
        if (bounds == null)
            bounds = layer.getDefaultViewport();
        else
            bounds.union(layer.getDefaultViewport());
      
            map.fitBounds(bounds);
      
      });
      

      【讨论】:

        【解决方案3】:

        您需要获取 kml (getDefaultViewport() on the KmlLayer)、extend that with the additional marker 的边界,然后使用“扩展”边界对象调用 fitBounds(preservViewport 设置为 true,因此地图不会缩放到KmlLayer)。

        【讨论】:

        • 听起来您知道该怎么做,但我并没有完全按照您所说的去做。 (“获取 kml 的边界”和“用附加标记扩展它”)你能举个例子吗?
        • 我没有这样的例子。但我要做的是使用 preserveViewport: false 运行您的示例,在 KmlLayer 上执行 getDefaultViewport(),使用附加标记扩展该边界,然后执行 map.fitBounds()。
        猜你喜欢
        • 1970-01-01
        • 2013-07-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-25
        • 2013-04-30
        • 2012-11-16
        • 2011-02-20
        相关资源
        最近更新 更多