【问题标题】:Google Maps API, Javascript, return distance Geocoder use as radius for CircleGoogle Maps API,Javascript,返回距离 Geocoder 用作 Circle 的半径
【发布时间】:2014-01-01 10:14:10
【问题描述】:

我正在尝试使用距城市/地铁边界的最短距离作为要在该特定城市的 Google 地图上绘制的圆圈的大小。但是,该值仍未定义,尽管我相信我考虑了与 AJAX 相关的请求响应问题。 我在这里做错了什么。

function initialize() {
    autoComplete();

    map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);

    for (var i=0;i<5;i++) {            

        var centerLocation = new google.maps.LatLng(myLat[i],myLng[i]);
        var address = myMetro[i] + "," + myCountry[i];
        var testRadius = 500000;

        Geocode(address, function(distance) {
            myRadius = distance;   
            console.log("it works here " + myRadius);         
        });

        console.log("it is undefined here " + myRadius);

        circleMetroBounds = new google.maps.Circle({
            strokeColor: 'rgb(255,255,255)', //sets the color for the border of the circle
            strokeOpacity: 0.8, //sets the opacity for the border
            strokeWeight: 2, //sets the border size in pixels
            fillColor: 'rgb(166,116,178)', //sets the fill color for the circle (should become a variable, like center)
            fillOpacity: 0.4, //sets the opacity for the fill color
            center: centerLocation, //sets the coordinates for the location of the circle
            map: map,
            radius: myRadius
        });
    }       
}

function Geocode(address, cb){
    geocoder = new google.maps.Geocoder();
    geocoder.geocode({ 'address': address }, function (results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            var boundMetroNE = results[0].geometry.bounds.getNorthEast(); // NE bound for Metro
            var boundMetroSE = new google.maps.LatLng(results[0].geometry.bounds.getSouthWest().lat(), results[0].geometry.bounds.getNorthEast().lng()); // SE
            var boundMetroNW = new google.maps.LatLng(results[0].geometry.bounds.getNorthEast().lat(), results[0].geometry.bounds.getSouthWest().lng()); // NW
            var boundMetroSW = results[0].geometry.bounds.getSouthWest(); // SW bound for Metro

            var distanceMetroNS = google.maps.geometry.spherical.computeDistanceBetween(boundMetroNE,boundMetroSE);
            var distanceMetroEW = google.maps.geometry.spherical.computeDistanceBetween(boundMetroNE,boundMetroNW);

            if (distanceMetroNS<distanceMetroEW) {
                distanceMetroBounds = distanceMetroNS;
            } else {
                distanceMetroBounds = distanceMetroEW;
            }
        } else {
            console.log("Geocoding failed: " + status);
        }
        console.log("distance Shortest: " + distanceMetroBounds + " meters");
        cb(distanceMetroBounds);
    });
}

还找到包含 Javascript 控制台的输出

this goes wrong it undefined (index):84
this goes wrong it undefined (index):84
this goes wrong it undefined (index):84
this goes wrong it undefined (index):84
this goes wrong it undefined (index):84
distance Shortest: 89152.91926541901 meters (index):119
this goes wrong it 89152.91926541901 (index):81
distance Shortest: 62673.31119262365 meters (index):119
this goes wrong it 62673.31119262365 (index):81
distance Shortest: 78080.76940877317 meters (index):119
this goes wrong it 78080.76940877317 (index):81
distance Shortest: 12077.897792227775 meters (index):119
this goes wrong it 12077.897792227775 (index):81
distance Shortest: 13643.316791625093 meters (index):119
this goes wrong it 13643.316791625093

编辑:

完成这项工作的最终代码 :)

function initialize() {
    autoComplete();

    map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);

    for (var i=0;i<5;i++) {        
        var address = myMetro[i] + "," + myCountry[i];    
        var centerLocation = new google.maps.LatLng(myLat[i],myLng[i]);

        Geocode(address, centerLocation, function(callbackDistance, callbackCenterlocation) {
            circleMetroBounds = new google.maps.Circle({
                strokeColor: 'rgb(255,255,255)', //sets the color for the border of the circle
                strokeOpacity: 0.8, //sets the opacity for the border
                strokeWeight: 2, //sets the border size in pixels
                fillColor: 'rgb(166,116,178)', //sets the fill color for the circle (should become a variable, like center)
                fillOpacity: 0.4, //sets the opacity for the fill color
                center: callbackCenterlocation, //sets the coordinates for the location of the circle
                map: map,
                radius: callbackDistance
            });         
        });   
    }       
}

function Geocode(address, centerlocation, cb){
    geocoder = new google.maps.Geocoder();
    geocoder.geocode({ 'address': address }, function (results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            var boundMetroNE = results[0].geometry.bounds.getNorthEast(); // NE bound for Metro
            var boundMetroSE = new google.maps.LatLng(results[0].geometry.bounds.getSouthWest().lat(), results[0].geometry.bounds.getNorthEast().lng()); // SE
            var boundMetroNW = new google.maps.LatLng(results[0].geometry.bounds.getNorthEast().lat(), results[0].geometry.bounds.getSouthWest().lng()); // NW
            var boundMetroSW = results[0].geometry.bounds.getSouthWest(); // SW bound for Metro

            var distanceMetroNS = google.maps.geometry.spherical.computeDistanceBetween(boundMetroNE,boundMetroSE);
            var distanceMetroEW = google.maps.geometry.spherical.computeDistanceBetween(boundMetroNE,boundMetroNW);

            if (distanceMetroNS<distanceMetroEW) {
                distanceMetroBounds = distanceMetroNS;
            } else {
                distanceMetroBounds = distanceMetroEW;
            }
            // else if solves QUERY LIMIT
            } else if (status === google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {    
                    setTimeout(function() {
                        Geocode(address, centerlocation, cb);
                    }, 200);
            } else {
            console.log("Geocoding failed: " + status);
        }
        console.log("distance Shortest: " + distanceMetroBounds + " meters");
        cb(distanceMetroBounds, centerlocation);
    });
}

【问题讨论】:

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


    【解决方案1】:

    地理编码是异步的。当回调函数可用时,您必须使用返回值。

    请注意,地理编码受到速率限制和配额的限制,如果您尝试对循环中的太多点进行地理编码,则会因 OVER_QUERY_LIMIT 失败。

    function initialize() {
        autoComplete();
    
        map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
    
        for (var i=0;i<5;i++) {            
    
            var centerLocation = new google.maps.LatLng(myLat[i],myLng[i]);
            var address = myMetro[i] + "," + myCountry[i];
            var testRadius = 500000;
    
            Geocode(address, function(distance) {
                myRadius = distance;   
                console.log("it works here " + myRadius);         
                circleMetroBounds = new google.maps.Circle({
                  strokeColor: 'rgb(255,255,255)', //sets the color for the border of the circle
                  strokeOpacity: 0.8, //sets the opacity for the border
                  strokeWeight: 2, //sets the border size in pixels
                  fillColor: 'rgb(166,116,178)', //sets the fill color for the circle (should become a variable, like center)
                  fillOpacity: 0.4, //sets the opacity for the fill color
                  center: centerLocation, //sets the coordinates for the location of the circle
                  map: map,
                  radius: myRadius
                });
            });
    
            console.log("it is undefined here " + myRadius);
    
        }       
    }
    
    function Geocode(address, cb){
        geocoder = new google.maps.Geocoder();
        geocoder.geocode({ 'address': address }, function (results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                var boundMetroNE = results[0].geometry.bounds.getNorthEast(); // NE bound for Metro
                var boundMetroSE = new google.maps.LatLng(results[0].geometry.bounds.getSouthWest().lat(), results[0].geometry.bounds.getNorthEast().lng()); // SE
                var boundMetroNW = new google.maps.LatLng(results[0].geometry.bounds.getNorthEast().lat(), results[0].geometry.bounds.getSouthWest().lng()); // NW
                var boundMetroSW = results[0].geometry.bounds.getSouthWest(); // SW bound for Metro
    
                var distanceMetroNS = google.maps.geometry.spherical.computeDistanceBetween(boundMetroNE,boundMetroSE);
                var distanceMetroEW = google.maps.geometry.spherical.computeDistanceBetween(boundMetroNE,boundMetroNW);
    
                if (distanceMetroNS<distanceMetroEW) {
                    distanceMetroBounds = distanceMetroNS;
                } else {
                    distanceMetroBounds = distanceMetroEW;
                }
            } else {
                console.log("Geocoding failed: " + status);
            }
            console.log("distance Shortest: " + distanceMetroBounds + " meters");
            cb(distanceMetroBounds);
        });
    }
    

    【讨论】:

    • 谢谢 :),这解决了距离问题,但确实引入了与位置相关的新问题。我设法通过将位置与功能一起发送来解决这个问题。这是学校项目的一部分,因此几个地点的概念证明就足够了。
    • 对于大量位置来说,这不是一个好的概念证明(它不会扩展)。
    • 您绝对正确,我会考虑一个可扩展的解决方案并在找到时发布。由于这些界限是固定的(不太可能随时间改变),因此将它们保存在数据库中可能是合适的。
    猜你喜欢
    • 1970-01-01
    • 2017-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多