我从事GIS项目,遇到数学问题。 我想做与该算法相同的过程:How to generate coordinates in between two known points,但要修改它以便根据百分比计算地理点的坐标(%表示A到B的点)。
你能帮助我在javascript中调整这个算法吗?
谢谢!
答案 0 :(得分:2)
对该主题的回答包含指向Destination point given distance and bearing from start point的链接,该链接提供了JavaScript代码 所以你需要:
关注loxodrome:
1.从A点到B点找到距离d
并承载b
(在同一页面上)
2.使用'目的地点'代码具有相同的方位b
和距离d * x / 100,其中x是百分比值
跟随orthodrome(最短路径,大圆弧):
上述页面的中间点部分。没有代码,但有公式。
答案 1 :(得分:1)
考虑这些Blend
和this fiddle:
functions
因此,如果你想计算一个新的坐标,它可以是这样的:
var gis = {
/**
* All coordinates expected EPSG:4326
* @param {Array} start Expected [lon, lat]
* @param {Array} end Expected [lon, lat]
* @return {number} Distance - meter.
*/
calculateDistance: function(start, end) {
var lat1 = parseFloat(start[1]),
lon1 = parseFloat(start[0]),
lat2 = parseFloat(end[1]),
lon2 = parseFloat(end[0]);
return gis.sphericalCosinus(lat1, lon1, lat2, lon2);
},
/**
* All coordinates expected EPSG:4326
* @param {number} lat1 Start Latitude
* @param {number} lon1 Start Longitude
* @param {number} lat2 End Latitude
* @param {number} lon2 End Longitude
* @return {number} Distance - meters.
*/
sphericalCosinus: function(lat1, lon1, lat2, lon2) {
var radius = 6371e3; // meters
var dLon = gis.toRad(lon2 - lon1),
lat1 = gis.toRad(lat1),
lat2 = gis.toRad(lat2),
distance = Math.acos(Math.sin(lat1) * Math.sin(lat2) +
Math.cos(lat1) * Math.cos(lat2) * Math.cos(dLon)) * radius;
return distance;
},
/**
* @param {Array} coord Expected [lon, lat] EPSG:4326
* @param {number} bearing Bearing in degrees
* @param {number} distance Distance in meters
* @return {Array} Lon-lat coordinate.
*/
createCoord: function(coord, bearing, distance) {
/** http://www.movable-type.co.uk/scripts/latlong.html
* φ is latitude, λ is longitude,
* θ is the bearing (clockwise from north),
* δ is the angular distance d/R;
* d being the distance travelled, R the earth’s radius*
**/
var
radius = 6371e3, // meters
δ = Number(distance) / radius, // angular distance in radians
θ = gis.toRad(Number(bearing));
φ1 = gis.toRad(coord[1]),
λ1 = gis.toRad(coord[0]);
var φ2 = Math.asin(Math.sin(φ1)*Math.cos(δ) +
Math.cos(φ1)*Math.sin(δ)*Math.cos(θ));
var λ2 = λ1 + Math.atan2(Math.sin(θ) * Math.sin(δ)*Math.cos(φ1),
Math.cos(δ)-Math.sin(φ1)*Math.sin(φ2));
// normalise to -180..+180°
λ2 = (λ2 + 3 * Math.PI) % (2 * Math.PI) - Math.PI;
return [gis.toDeg(λ2), gis.toDeg(φ2)];
},
/**
* All coordinates expected EPSG:4326
* @param {Array} start Expected [lon, lat]
* @param {Array} end Expected [lon, lat]
* @return {number} Bearing in degrees.
*/
getBearing: function(start, end){
var
startLat = gis.toRad(start[1]),
startLong = gis.toRad(start[0]),
endLat = gis.toRad(end[1]),
endLong = gis.toRad(end[0]),
dLong = endLong - startLong;
var dPhi = Math.log(Math.tan(endLat/2.0 + Math.PI/4.0) /
Math.tan(startLat/2.0 + Math.PI/4.0));
if (Math.abs(dLong) > Math.PI) {
dLong = (dLong > 0.0) ? -(2.0 * Math.PI - dLong) : (2.0 * Math.PI + dLong);
}
return (gis.toDeg(Math.atan2(dLong, dPhi)) + 360.0) % 360.0;
},
toDeg: function(n) { return n * 180 / Math.PI; },
toRad: function(n) { return n * Math.PI / 180; }
};