gpt4 book ai didi

javascript - 对中间循环数字使用最终循环值

转载 作者:行者123 更新时间:2023-11-28 01:31:13 25 4
gpt4 key购买 nike

我希望标题能够稍微容易理解。我有一个比较两个值的函数,其中一个是第一个值的所有值的平均值。

基本上,我想找到 n 个标记的经纬度和中心标记之间的距离。我有一个循环,将“结果”变量推送到一个数组,并在循环结束时找到创建中心点的平均纬度、经度。问题是我想找到每个“结果”与中心点之间的距离,但在循环中,平均标记尚未最终确定。

解释比展示更难;我在这里设置了一个演示;要明白我的意思,请单击结果 Pane 中的“更新”按钮:http://jsfiddle.net/Cory2711/m55Ef/ 。你会看到从加利福尼亚发出的圆圈是正确的,因为它是最后一个制作的圆圈(找到了完整的平均点)。来自纽约的圆圈是在环路中进行的,因此需要测量的平均标记不完整。

我的 Javascript(问题集中在“标记”部分:

//GLOBAL VARIABLES
var gMapAPIKey = 'AIzaSyBUlnM6c7LqCR79UM9mTKvSNK6V7gzKsmE';
var namearray = document.getElementsByName("name");
var form = document.getElementById("addressform");
var addBtn = document.getElementById("addperson");


//GOOGLE MAPS API SCRIPTS
var streetarray = document.getElementsByName("street");
var cityarray = document.getElementsByName("city");
var geocoder;
var map;
var results;
var mapArray = new Array();
var AvgLat = 0;
var AvgLng = 0;
var j;
var newLatLng;
var dynamicRadius;




function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(-34.397, 150.644);
var mapOptions = {
zoom: 3,
//centered on Carrollton, Texas -- Change lat,long values to change initial map area
center: new google.maps.LatLng(32.999173, -96.897413)
}
//change Id reference to the div/container that contains the google map
map = new google.maps.Map(document.getElementById('map'), mapOptions);
}

function codeAddress() {
//Loop through and concate street and city values to find long,lat values for all fields
for (var cName = 0; cName < namearray.length; cName++) {
var address = streetarray[cName].value + cityarray[cName].value;

//start geocode copy & paste text from API reference
geocoder.geocode({
'address': address
}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var results = results[0].geometry.location;
map.setCenter(results);
console.log(results);
var marker = new google.maps.Marker({
map: map,
position: results,

});
//Push lng/lat locations to the mapArray and find AvgLat/Lngs
mapArray.push(results);
var j = mapArray.length;
AvgLat = (AvgLat + results.lat());
AvgLng = (AvgLng + results.lng());

console.log(mapArray, AvgLat, AvgLng, j)

//Begin Marker Scripts

var markerCircle = new google.maps.Circle({
center: results,
radius: 15000,
strokeColor: "#0000FF",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#0000FF",
fillOpacity: 0.4


})
var centerLocation = {
lat: AvgLat / j,
lng: AvgLng / j,
}

var newLatLng = new google.maps.LatLng(centerLocation.lat, centerLocation.lng);
var dynamicRadius = google.maps.geometry.spherical.computeDistanceBetween (results, newLatLng);
if (j == namearray.length) {

markerCircle.setRadius(dynamicRadius*1.15)
map.setCenter(newLatLng);
var centerMarker = new google.maps.Marker({
position: newLatLng,
map: map,
title: "Center Marker",
})
var centerCircle = new google.maps.Circle({
center: newLatLng,
radius: 15000,
strokeColor: "#0000FF",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#0000FF",
fillOpacity: 0.4,
map: map,
})


}
markerCircle.setRadius(dynamicRadius*1.15)
markerCircle.setMap(map);


} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});


}
}

//Initialize the first map on load -- When form is submitted geocode addresses and places markers on the map
google.maps.event.addDomListener(window, 'load', initialize);
form.addEventListener("submit", codeAddress, false);
addBtn.addEventListener("click", addPerson, false);

最佳答案

我的第一个想法是,您不限于仅循环数据一次。循环后数据仍然存在(除非您在此过程中更改或销毁它)。

因此,您将使用两个循环。

第一个循环计算中心点。

第二个循环计算距该点的所有距离。

但是当我查看你的代码时,我发现它的含义远不止于此。

在迭代 namearray 的主循环中,循环会为此数组的每个元素调用 geocoder.geocode()。然后在地理编码器回调内部完成工作。

有趣的是,这段代码实际上根本不是主循环的一部分。它出现在该循环内,但它的调用要晚得多,因为地理编码响应会一一返回。

因此,我们假设地理编码中没有错误(错误的假设,但我们将暂时使用它)。您的地理编码器回调已将每个地理编码结果推送到 mapArray 上。因此,您可以做的是让此回调代码执行此操作,而不执行任何中心/圆计算。因此,您的地理编码调用可能看起来更像这样:

    geocoder.geocode({
'address': address
}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
mapArray.push({ latLng: results[0].geometry.location });
AvgLat += results.lat();
AvgLng += results.lng();
} else {
mapArray.push({ error: status });
++nErrors;
}

// Might want to update a progress indicator here
// if the geocoding takes a while?

if( mapArray.length == namearray.length ) {
// Everything is geocoded, now get to work
drawMap();
}
});

(nErrors 应定义在使用 var nErrors = 0; 初始化其他变量的循环之上)

然后完全在当前主循环之外添加此函数:

function drawMap() {
if( nErrors ) {
// complain about error
return;
}

var center = {
lat: AvgLat / j,
lng: AvgLng / j,
};
map.setCenter( new google.maps.LatLng( center.lat, center.lng ) );

for( var i = 0; i < mapArray.length; i++ ) {
// Create marker and draw circle here
}
}

还有其他几点。首先,以这种方式计算平均纬度/经度听起来不太正确。我会对标记位于 0° 和 180° 子午线不同侧的情况进行一些思考(和测试)。你在那里可能没问题,只是我从来不指望它!

“平均”纬度/经度实际上是您想要的吗? (可能是,只是询问。)如果您有许多彼此靠近的标记,而在一定距离内只有很少的标记(例如,加利福尼亚州有 10 个标记,纽约有 1 个标记),则“平均值”将非常接近该标记簇。这可能是您想要的,但如果不是,还有其他方法可以计算各种“中心”。

例如,一种常见的方法是创建一个空的 LatLngBounds 对象,然后用您收到的每个位置扩展这些边界。因此,在顶部添加其他变量初始化:

var bounds = new google.maps.LatLngBounds;

然后在每个成功的地理编码回调中,您将替换以下内容:

            AvgLat += results.lat();
AvgLng += results.lng();

与:

            bounds.extend( results );

然后在 drawMap() 中,您将替换此内容:

    var center = {
lat: AvgLat / j,
lng: AvgLng / j,
};
map.setCenter( new google.maps.LatLng( center.lat, center.lng ) );

与:

    map.fitBounds( bounds );
var center = bounds.getCenter();

如果您需要这些单独的值,请使用 center.lat()center.lng() - 但在您有 newLatLng 的地方code> 您现在可以直接使用 center,因为它一个 LatLng 对象。

即使您确实想使用点的“平均值”进行圆计算,您也可能需要使用此边界框方法来使 map 居中,而不是使 map 以计算出的平均值为中心。

最后一件事是注意地理编码的速率限制和限制。也许您可以接受少量标记,但您可能需要在标记之间有一定时间间隔进行地理编码调用,而不是在硬循环中全部触发它们。

关于javascript - 对中间循环数字使用最终循环值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22102494/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com