我正在尝试使用指定出发时间(timeStamp)中的持续时间流量值(n1,n2,n3)查找中点,以便所有三人都具有相同的旅行时间(中点乘以时间)。我正在使用Google距离矩阵。
我已经根据三个位置的距离通过了所有三个位置(a,b,c)和中点(d)。
我尝试通过减法(全部三个),平均值(其中三个)并用(n1,n2,n3的最大值和最小值)相减来找到它们的中点,以使行进时间等于或小于指定时间( maxTime距离黑白,其中三个)。然后点变成中点 但是我找不到解决方案。建议非常感谢。
const maxTime = 5000;
var i = 0;
z = 0;
j = 0
//Distance Matrix Api
function getDistanceMatrix(a, b, c, d, timeStamp, googleWarnings, copyRights) {
clientMap.post(config_KEYS.DISTANCE_MATRIX_API + a + "|" + b + "|" + c + "&destinations=" + d.lat + "," + d.lng + "+&key=" + config_KEYS.GOOGLE_API_KEY + "&departure_time=" + timeStamp + "", function(gotDistanceResp, err) {
if (err) {
res.status(400).json(gotDistanceResp)
} else {
let n1 = gotDistanceResp.rows[0].elements[0].duration_in_traffic.value
let n2 = gotDistanceResp.rows[1].elements[0].duration_in_traffic.value
let n3 = gotDistanceResp.rows[2].elements[0].duration_in_traffic.value
// let minTime = Math.abs(n2 - n1)
let minTime = Math.round((n3 + n2 + n1) / 3)
if (n1 >= n2 && n1 >= n3) {
if (minTime <= maxTime) {
res.send(gotDistanceResp)
} else {
i++;
let arrayPoints = getDirectionApi(a, d, timeStamp, i)
}
} else {
if (n2 >= n1 && n2 >= n3) {
if (minTime <= maxTime) {
res.send(gotDistanceResp)
} else {
j++;
let arrayPoints = getDirectionApi(b, d, timeStamp, j)
}
} else {
if (n3 >= n1 && n3 >= n1) {
if (minTime <= maxTime) {
res.send(gotDistanceResp)
} else {
z++;
let arrayPoints = getDirectionApi(c, d, timeStamp, z)
}
} else {
res.send(gotDistanceResp)
}
}
}
}
})
}
//Get Direction Api
function getDirectionApi(a, b, timeStamp, r) {
clientMap.post(config_KEYS.DIRECTION_API + a + "&destination=" + b.lat + "," + b.lng + "&key=" + config_KEYS.GOOGLE_API_KEY + "&departure_time=" + timeStamp + "", function(route, error) {
if (route.geocoder_status == "ZERO_RESULTS" | route.status == "INVALID_REQUEST") {
res.status(400).send(route)
} else {
let googleWarnings = route.routes[0].warnings
let copyRights = route.routes[0].copyrights
let polyline = route.routes[0].overview_polyline.points
let decoded = decode(polyline)
let midPointCha = getDistanceMatrix(Location1, Location2, Location3, reversedMidArra[r])
}
})
}
答案 0 :(得分:7)
下面,我创建了一个算法(用伪代码),该算法最大程度地减少了最长的旅行时间:
问题: 给定起点A,B和C: 查找中心位置D 这样从每个点到D的行进时间是相似的。 (其中“相似”被定义为“在指定的公差范围内……例如,可以将其设置为1分钟。)
准备工作:
Determine a candidate location for D: the "center of gravity" or geographic midpoint. (Average the x coordinates and the y coordinates.) Set _Converged_ to false.
执行:
While (not _Converged_) { Query the travel time from each start location to point D. If all three travel times are within the specified tolerance: Then _Converged_ = true // current point D is returned as acceptable Else Average the three travel times: avg Identify the starting point with the longest travel time: where Q is A, B, or C and t is the travel time. Divide the average by t: where p is avg/t Compute a new point E between Q and D based on percentage p (for example, if p is .66, then new point is 66% along the vector from Q to D) E = p(D - Q) + Q Set D to this new point E D = E } return D
编辑:我已经在CodePen上实现了概念证明演示。 下面是代码示例:
else { // Minimize the longest duration
// First, find the average duration
let avg = (n[0]+n[1]+n[2])/3;
// Divide the average by longest travel time
let p = avg / n[maxN];
// Compute a new point E between Q and D based on percentage p
// E = p(D - Q) + Q
// D = E
destination[0].lat = lerp(origins[maxN].lat,destination[0].lat,p);
destination[0].lng = lerp(origins[maxN].lng,destination[0].lng,p);
// Cycle again, waiting a bit to prevent server overload
setTimeout(calculateDistances, 500+Math.random()*100);
}
请参见DEMO
答案 1 :(得分:5)
您可以尝试以下一种方法,它比James的建议更纤细,但我的观点是找到A和D之间的路径,然后在其中找到“ p”点(平均avg / n [maxN] * 100)解码路径。
ex:如果p为73,则找到A和D解码之间的路径,例如它有235个点,则(Math.round((235/100)* 73)= 172)在解码后的位置选择172个位置的经度和纬度A,D的路径)并重复执行过程。
let arrOfMid = [];
//Distance Matrix Api
function getDistanceMatrix(a, b, c, d, timeStamp, i) {
clientMap.post(config_KEYS.DISTANCE_MATRIX_API + a + "|" + b + "|" + c + "&destinations=" + d.lat + "," + d.lng + "+&key=" + config_KEYS.GOOGLE_API_KEY + "&departure_time=" + timeStamp + "", function (gotDistanceResp, err) {
if (gotDistanceResp.status == "OVER_QUERY_LIMIT" | gotDistanceResp.status == "REQUEST_DENIED") {
res.status(400).json(gotDistanceResp)
}
else {
let n1 = gotDistanceResp.rows[0].elements[0].duration_in_traffic.value
let n2 = gotDistanceResp.rows[1].elements[0].duration_in_traffic.value
let n3 = gotDistanceResp.rows[2].elements[0].duration_in_traffic.value
let maxValue = Math.max(n1, n2, n3)
let minTime = Math.abs(n2 - n1)
let avg = Math.round((n3 + n2 + n1) / 3)
let value = (avg / maxValue) * 100
if (n1 >= n2 && n1 >= n3) {
if (arrOfMid.includes(gotDistanceResp.destination_addresses[0]) == true) {
res.send(gotDistanceResp)
}
else {
arrOfMid.push(d)
i++;
let arrayForTenPerc = getDirectionApi(a, d, timeStamp, value, i)
}
}
else {
if (n2 >= n1 && n2 >= n3) {
if (arrOfMid.includes(gotDistanceResp.destination_addresses[0]) == true) {
res.send(gotDistanceResp)
}
else {
arrOfMid.push(gotDistanceResp.destination_addresses[0])
j++;
let arrayPoints = getDirectionApi(b, d, timeStamp, value, j)
}
}
else {
if (n3 >= n1 && n3 >= n1) {
if (arrOfMid.includes(gotDistanceResp.destination_addresses[0]) === true) {
res.send(gotDistanceResp)
}
else {
arrOfMid.push(gotDistanceResp.destination_addresses[0])
z++;
let arrayPoints = getDirectionApi(c, d, timeStamp, value, z)
}
}
else {
res.send(gotDistanceResp)
}
}
}
}
})
}
//Get Direction Api
function getDirectionApi(a, b, timeStamp, r, i) {
clientMap.post(config_KEYS.DIRECTION_API + a + "&destination=" + b.lat + "," + b.lng + "&key=" + config_KEYS.GOOGLE_API_KEY + "&departure_time=" + timeStamp + "", function (route, error) {
if (route.geocoder_status == "ZERO_RESULTS" | route.status == "INVALID_REQUEST") {
res.status(400).send(route)
}
else {
let polyline = route.routes[0].overview_polyline.points
let decoded = decode(polyline)
let x = Math.round(decoded.length / 100 * r)
let midPointCha = getDistanceMatrix(Location1, Location2, Location3, decoded[x], timeStamp, i)
}
})
}