为啥我的覆盖线没有根据极坐标公式(swift,ios)产生我在地图中的期望?
Posted
技术标签:
【中文标题】为啥我的覆盖线没有根据极坐标公式(swift,ios)产生我在地图中的期望?【英文标题】:Why is the my overlay line not resulting how I expect in the map based on a polar formulae (swift, ios)?为什么我的覆盖线没有根据极坐标公式(swift,ios)产生我在地图中的期望? 【发布时间】:2016-09-02 13:01:13 【问题描述】:我的目标
根据三位数据绘制一条线:给定坐标、距离、方位。
我想从我当前的位置沿方位方向、距离的终点画一条线。
只考虑
我确实在地图上得到了一条线,每次当前位置更新时都会更新,所以从这个意义上说没有问题(我显示的代码可能不包括所有定义 - 但假设没有编译错误,等)
问题
我的线出现了,但总是在同一个方向,在整个世界的距离(而不是 1 公里!)。我尝试更改标题输入,但仍然得到相同的行。
代码
func drawHeadingLine(currentLocation: [Double], heading: Double)
//to radians
let headingR = heading * 0.0174533;
if viewLine != nil
mapView.removeOverlay(viewLine);
// setup data for polar formulae
let pi = M_PI;
let currentLONG = currentLocation[0];
let currentLAT = currentLocation[1];
let currentLongRadian = currentLocation[0] * (pi * 180);
let currentLatRadian = currentLocation[1] * (pi * 180);
let lineDistance: Double = 1; //km
let earthRadius: Double = 6378.1; //km
let angularDistance: Double = lineDistance / earthRadius;
//use polar formulae (given point, distance, bearing) for line end point
let latitude2 = asin( sin(currentLatRadian) * cos(angularDistance)
+ cos(currentLatRadian) * sin(angularDistance) * cos(headingR) );
let longitude2 = currentLongRadian + atan2( cos(angularDistance) - sin(currentLatRadian) * sin(latitude2),
sin(headingR) * sin(angularDistance) * cos(currentLatRadian));
var coordinates1 = CLLocationCoordinate2D();
coordinates1.longitude = currentLONG;
coordinates1.latitude = currentLAT;
var coordinates2 = CLLocationCoordinate2D();
coordinates2.longitude = longitude2;
coordinates2.latitude = latitude2;
var lineCoords = [ coordinates1,coordinates2];
viewLine = MKPolyline(coordinates: &lineCoords, count: lineCoords.count);
self.mapView.addOverlay(viewLine);
func mapView(mapView: MKMapView!, viewForOverlay overlay: MKOverlay!) -> MKOverlayRenderer!
if (overlay is MKPolyline)
viewLine = overlay;
let line = MKPolylineRenderer(overlay: viewLine);
line.strokeColor = UIColor.redColor().colorWithAlphaComponent(0.5);
line.lineWidth = 5;
return line;
return nil
如果您需要更多信息,请说。感谢您的帮助。
【问题讨论】:
您添加MKPolyline
的代码似乎是正确的。尝试检查您对第二个坐标的计算。
【参考方案1】:
你的数学错了。试试这个:
func drawHeadingLine(currentLocation: [Double], heading: Double)
if viewLine != nil
mapView.removeOverlay(viewLine!)
let (lat, long) = (currentLocation[0], currentLocation[1])
let headingR = heading * M_PI / 180.0
let lineDistance = 1.0 //km
let latDelta = cos(headingR) * lineDistance / EarthMeasurement.lengthOfLatitude(at: lat)
let longDelta = sin(headingR) * lineDistance / EarthMeasurement.lengthOfLongitude(at: lat)
let pointA = CLLocationCoordinate2D(latitude: lat, longitude: long)
let pointB = CLLocationCoordinate2D(latitude: lat + latDelta, longitude: long + longDelta)
// For debugging, let's calculate a geodesic distance between these 2 points
// Results are in meters
let locationA = CLLocation(latitude: lat, longitude: long)
let locationB = CLLocation(latitude: lat + latDelta, longitude: long + longDelta)
print("heading = \(heading), distance = \(locationA.distanceFromLocation(locationB)")
var coordinates = [pointA, pointB]
let polyline = MKPolyline(coordinates: &coordinates, count: 2)
self.mapView.addOverlay(polyline)
还有EarthMeasurement
类:
final class EarthMeasurement
static func lengthOfLatitude(at latitude: Double) -> Double
return 110.574
static func lengthOfLongitude(at latitude: Double) -> Double
let latitudeR = latitude * M_PI / 180.0
return cos(latitudeR) * 111.320
这个想法是 Map Kit 处理纬度和经度,而不是公里,所以我们需要知道纬度/经度有多少公里。这远非简单,因为地球不是一个完美的球体。但我们可以做出近似:
当您接近两极时,纬度 1 度的长度确实会变长,但差异很小:赤道和两极之间的距离约为 1 公里(或 1%)。我们可以忽略它并使用赤道的长度,根据Wikipedia 是111.574km。 1纬度长度公式取自this question。由于我们使用的近似值,这并没有给出正好 1 公里外的点。误差在赤道附近的纬度较小,并且随着您接近两极(~10m)而逐渐增加。如果您想要更准确的结果,请相应地调整 EarthMeasurement
类。
【讨论】:
原来有很多问题 - 但这有帮助。非常感谢。以上是关于为啥我的覆盖线没有根据极坐标公式(swift,ios)产生我在地图中的期望?的主要内容,如果未能解决你的问题,请参考以下文章