嘿伙计,所以我试图使用谷歌地图API V3从默认的起点绘制一条线,并给定距离给定的方向。例如,假设我的默认起点是旧金山并且用户输入了一段距离,我希望能够根据输入距离绘制一条直线穿过美国。我遇到了这个称为轴承的东西,但我不确定如何正确使用它。这是我正在使用的代码:
function initializeMap(){
var mapOptions = {
center: new google.maps.LatLng(36.033036, -93.8655744),
zoom: 4,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
var R = 6378137;
var dis = parseInt(document.form['input']['val'].value);
var bearing = 80;
var lat2 = Math.asin( Math.sin(37.470625)*Math.cos(dis/R)+Math.cos(37.470625)*Math.sin(dis/R)*Math.cos(bearing) );
var lon2 = -122.266823 + Math.atan2(Math.sin(bearing)*Math.sin(dis/R)*Math.cos(37.470625),Math.cos(dis/R)-Math.sin(37.470625)*Math.sin(-122.266823));
var impactP = new google.maps.Polyline({
path: new google.maps.LatLng(lat2,lon2),
strokeColor: "#FF0000",
strokeOpacity: 1.0,
strokeWeight: 2
});
impactP.setMap(map);
}
请有人帮帮我。我真的想让它发挥作用。
答案 0 :(得分:2)
这里的数学解释都是:http://www.movable-type.co.uk/scripts/latlong.html#destPoint
var lat2 = Math.asin( Math.sin(lat1)*Math.cos(d/R) +
Math.cos(lat1)*Math.sin(d/R)*Math.cos(brng) );
var lon2 = lon1 + Math.atan2(Math.sin(brng)*Math.sin(d/R)*Math.cos(lat1),
Math.cos(d/R)-Math.sin(lat1)*Math.sin(lat2));
请注意,lat1,lon1
(您的起点)和lat2,lon2
(终点)位于弧度而非度数。 d
是行进的距离,R
是地球的半径。只要它们都是相同的单位,它们可以是任何单位。
如果你以弧度工作,看起来问题中的代码可以正常工作。
如果你从北半球的90°轴承开始,你将会向南稍微前进(你的最终轴承将超过90°)。球面几何是一件很棒的事情!
如果你想要一条恒定轴承线,那么在地图上90°直线是水平的,你需要Rhumb线:http://www.movable-type.co.uk/scripts/latlong.html#rhumblines。这更加复杂,但是该页面允许从距离和方位计算终点,并解释数学和必要的Javascript。
同一页建议在Number中添加方法,将度数转换为弧度,然后再转回:
/** Converts numeric degrees to radians */
if (typeof(Number.prototype.toRad) === "undefined") {
Number.prototype.toRad = function() {
return this * Math.PI / 180;
}
}
/** Converts radians to numeric (signed) degrees */
if (typeof(Number.prototype.toDeg) === "undefined") {
Number.prototype.toDeg = function() {
return this * 180 / Math.PI;
}
}
因此(78).toRad()
为1.3613568
。
答案 1 :(得分:0)
我放入谷歌地图脚手架http://jsfiddle.net/khwLd/,但我的数学已关闭:(你可以看到这些线转向南方。谷歌搜索"找到一个轴承和距离的终端坐标& #34; 给了我一个python函数,我转换并检查了但仍然没有给出预期的结果。
Calculating coordinates given a bearing and a distance
您需要做的是在开头修复所有数学运算,以便:
getDestination(origin_lat, origin_lng, bearing, distance)
返回 google.maps.LatLng(destination_lat, destination_lng)
抱歉,我无法提供完整的解决方案:(
答案 2 :(得分:0)
您可以使用Chris Veness的库https://github.com/chrisveness/geodesy中的rhumbDestinationPoint
方法,另请参阅此处http://www.movable-type.co.uk/scripts/latlong.html
LatLon
应用于0
个对象,并将距离以米为单位作为第一个参数,将第二个参数作为性别度数的方位,即90
为北,{{1} }是东方,180
是南方,270
是西方。
我刚刚将rhumbDestinationPoint
从https://raw.githubusercontent.com/chrisveness/geodesy/master/latlon-spherical.js粘贴到下面的代码段(改编自OP http://jsfiddle.net/X25dZ/1/)
function initializeMap() {
mapCenter = new google.maps.LatLng(36.033036, -93.8655744);
defaultStart = new google.maps.LatLng(37.470625, -122.266823);
var mapOptions = {
center: mapCenter,
zoom: 2,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
var distance_in_meter = 600000;
var bearing = 90;
var start = new LatLon(defaultStart.lat(), defaultStart.lng());
var destination = start.rhumbDestinationPoint(distance_in_meter, bearing);
var impactP = new google.maps.Polyline({
map: map,
path: [defaultStart,
new google.maps.LatLng(destination.lat, destination.lon)
],
strokeColor: "#FF0000",
strokeOpacity: 1.0,
strokeWeight: 2
});
}
google.maps.event.addDomListener(window, 'load', initializeMap);

html {
height: 100%
}
body {
height: 100%;
margin: 0;
padding: 0
}
#map-canvas {
height: 100%
}
#menu {
position: absolute;
top: 0px;
left: 0px;
padding: 0px;
font-family: Arial, sans-serif;
}

<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
// Taken from https://raw.githubusercontent.com/chrisveness/geodesy/master/latlon-spherical.js
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Latitude/longitude spherical geodesy tools (c) Chris Veness 2002-2016 */
/* MIT Licence */
/* www.movable-type.co.uk/scripts/latlong.html */
/* www.movable-type.co.uk/scripts/geodesy/docs/module-latlon-spherical.html */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
'use strict';
if (typeof module!='undefined' && module.exports) var Dms = require('./dms'); // ≡ import Dms from 'dms.js'
/**
* Library of geodesy functions for operations on a spherical earth model.
*
* @module latlon-spherical
* @requires dms
*/
/**
* Creates a LatLon point on the earth's surface at the specified latitude / longitude.
*
* @constructor
* @param {number} lat - Latitude in degrees.
* @param {number} lon - Longitude in degrees.
*
* @example
* var p1 = new LatLon(52.205, 0.119);
*/
function LatLon(lat, lon) {
// allow instantiation without 'new'
if (!(this instanceof LatLon)) return new LatLon(lat, lon);
this.lat = Number(lat);
this.lon = Number(lon);
}
/**
* Returns the destination point having travelled along a rhumb line from ‘this’ point the given
* distance on the given bearing.
*
* @param {number} distance - Distance travelled, in same units as earth radius (default: metres).
* @param {number} bearing - Bearing in degrees from north.
* @param {number} [radius=6371e3] - (Mean) radius of earth (defaults to radius in metres).
* @returns {LatLon} Destination point.
*
* @example
* var p1 = new LatLon(51.127, 1.338);
* var p2 = p1.rhumbDestinationPoint(40300, 116.7); // 50.9642°N, 001.8530°E
*/
LatLon.prototype.rhumbDestinationPoint = function(distance, bearing, radius) {
radius = (radius === undefined) ? 6371e3 : Number(radius);
var δ = Number(distance) / radius; // angular distance in radians
var φ1 = this.lat.toRadians(), λ1 = this.lon.toRadians();
var θ = Number(bearing).toRadians();
var Δφ = δ * Math.cos(θ);
var φ2 = φ1 + Δφ;
// check for some daft bugger going past the pole, normalise latitude if so
if (Math.abs(φ2) > Math.PI/2) φ2 = φ2>0 ? Math.PI-φ2 : -Math.PI-φ2;
var Δψ = Math.log(Math.tan(φ2/2+Math.PI/4)/Math.tan(φ1/2+Math.PI/4));
var q = Math.abs(Δψ) > 10e-12 ? Δφ / Δψ : Math.cos(φ1); // E-W course becomes ill-conditioned with 0/0
var Δλ = δ*Math.sin(θ)/q;
var λ2 = λ1 + Δλ;
return new LatLon(φ2.toDegrees(), (λ2.toDegrees()+540) % 360 - 180); // normalise to −180..+180°
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/**
* Checks if another point is equal to ‘this’ point.
*
* @param {LatLon} point - Point to be compared against this point.
* @returns {bool} True if points are identical.
*
* @example
* var p1 = new LatLon(52.205, 0.119);
* var p2 = new LatLon(52.205, 0.119);
* var equal = p1.equals(p2); // true
*/
LatLon.prototype.equals = function(point) {
if (!(point instanceof LatLon)) throw new TypeError('point is not LatLon object');
if (this.lat != point.lat) return false;
if (this.lon != point.lon) return false;
return true;
};
/**
* Returns a string representation of ‘this’ point, formatted as degrees, degrees+minutes, or
* degrees+minutes+seconds.
*
* @param {string} [format=dms] - Format point as 'd', 'dm', 'dms'.
* @param {number} [dp=0|2|4] - Number of decimal places to use - default 0 for dms, 2 for dm, 4 for d.
* @returns {string} Comma-separated latitude/longitude.
*/
LatLon.prototype.toString = function(format, dp) {
return Dms.toLat(this.lat, format, dp) + ', ' + Dms.toLon(this.lon, format, dp);
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/** Extend Number object with method to convert numeric degrees to radians */
if (Number.prototype.toRadians === undefined) {
Number.prototype.toRadians = function() { return this * Math.PI / 180; };
}
/** Extend Number object with method to convert radians to numeric (signed) degrees */
if (Number.prototype.toDegrees === undefined) {
Number.prototype.toDegrees = function() { return this * 180 / Math.PI; };
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
if (typeof module != 'undefined' && module.exports) module.exports = LatLon; // ≡ export default LatLon </script>
<div id="map-canvas"></div>
&#13;