我必須在文檔丟失的財產以後出來,我想這應該是很容易...計算新的座標x米和y度從一個客場協調
如果我有一個座標,並希望得到一個新的座標在一些方向上離開X米遠。我該怎麼做呢?
我在尋找類似
-(CLLocationCoordinate2D) translateCoordinate:(CLLocationCoordinate2D)coordinate translateMeters:(int)meters translateDegrees:(double)degrees;
謝謝!
我必須在文檔丟失的財產以後出來,我想這應該是很容易...計算新的座標x米和y度從一個客場協調
如果我有一個座標,並希望得到一個新的座標在一些方向上離開X米遠。我該怎麼做呢?
我在尋找類似
-(CLLocationCoordinate2D) translateCoordinate:(CLLocationCoordinate2D)coordinate translateMeters:(int)meters translateDegrees:(double)degrees;
謝謝!
不幸的是,API中沒有提供這樣的功能,所以你必須自己編寫。
This site給出了一些涉及緯度/經度和JavaScript代碼示例的計算。具體而言,標題爲「給定距離和起始點的方位」的部分顯示瞭如何計算您要求的內容。
的JavaScript代碼是在該頁面的底部,這裏是將其轉換成Objective-C的一個可能的方式:
- (double)radiansFromDegrees:(double)degrees
{
return degrees * (M_PI/180.0);
}
- (double)degreesFromRadians:(double)radians
{
return radians * (180.0/M_PI);
}
- (CLLocationCoordinate2D)coordinateFromCoord:
(CLLocationCoordinate2D)fromCoord
atDistanceKm:(double)distanceKm
atBearingDegrees:(double)bearingDegrees
{
double distanceRadians = distanceKm/6371.0;
//6,371 = Earth's radius in km
double bearingRadians = [self radiansFromDegrees:bearingDegrees];
double fromLatRadians = [self radiansFromDegrees:fromCoord.latitude];
double fromLonRadians = [self radiansFromDegrees:fromCoord.longitude];
double toLatRadians = asin(sin(fromLatRadians) * cos(distanceRadians)
+ cos(fromLatRadians) * sin(distanceRadians) * cos(bearingRadians));
double toLonRadians = fromLonRadians + atan2(sin(bearingRadians)
* sin(distanceRadians) * cos(fromLatRadians), cos(distanceRadians)
- sin(fromLatRadians) * sin(toLatRadians));
// adjust toLonRadians to be in the range -180 to +180...
toLonRadians = fmod((toLonRadians + 3*M_PI), (2*M_PI)) - M_PI;
CLLocationCoordinate2D result;
result.latitude = [self degreesFromRadians:toLatRadians];
result.longitude = [self degreesFromRadians:toLonRadians];
return result;
}
在JS代碼,它包含this link其中顯示了距離的更精確的計算大於地球四分之一的圓周。
另請注意,上面的代碼接受以km爲單位的距離,所以務必在通過之前將儀表除以1000.0。
我發現了一種做法,不得不挖掘以找到正確的結構和功能。我最終沒有使用度數,而是用米和拉來代替。
我是這樣做的:
-(CLLocationCoordinate2D)translateCoord:(CLLocationCoordinate2D)coord MetersLat:(double)metersLat MetersLong:(double)metersLong{
CLLocationCoordinate2D tempCoord;
MKCoordinateRegion tempRegion = MKCoordinateRegionMakeWithDistance(coord, metersLat, metersLong);
MKCoordinateSpan tempSpan = tempRegion.span;
tempCoord.latitude = coord.latitude + tempSpan.latitudeDelta;
tempCoord.longitude = coord.longitude + tempSpan.longitudeDelta;
return tempCoord;
}
當然,如果我真的需要在未來的使用度,這是很容易的(我覺得...)做一些改變,上述獲得它像我實際要求的那樣工作。
簡單而有效的符合我的需求。謝謝! –
那麼你最終如何處理學位呢? –
使用MKCoordinateRegion
有一些問題 - 返回的區域可以進行調整,以適應兩個增量可能不會精確映射到該緯度的投影,如果您希望某個軸的零增量不成功,等等。
此功能使用MKMapPoint
執行座標轉換,它允許您在地圖投影的座標空間中移動點,然後從中提取座標。
CLLocationCoordinate2D MKCoordinateOffsetFromCoordinate(CLLocationCoordinate2D coordinate, CLLocationDistance offsetLatMeters, CLLocationDistance offsetLongMeters) {
MKMapPoint offsetPoint = MKMapPointForCoordinate(coordinate);
CLLocationDistance metersPerPoint = MKMetersPerMapPointAtLatitude(coordinate.latitude);
double latPoints = offsetLatMeters/metersPerPoint;
offsetPoint.y += latPoints;
double longPoints = offsetLongMeters/metersPerPoint;
offsetPoint.x += longPoints;
CLLocationCoordinate2D offsetCoordinate = MKCoordinateForMapPoint(offsetPoint);
return offsetCoordinate;
}
這個答案對我很好,並允許我轉換MapItem.placemark。區域(這是一個CLCircularRegion;它有一個以米爲單位的半徑)放入邊界框區域 –
Nicsoft的答案很棒,正是我所需要的。我創建了一個斯威夫特3-Y版本,這是一個小更簡潔,可以在CLLocationCoordinate2D
實例直接調用:
public extension CLLocationCoordinate2D {
public func transform(using latitudinalMeters: CLLocationDistance, longitudinalMeters: CLLocationDistance) -> CLLocationCoordinate2D {
let region = MKCoordinateRegionMakeWithDistance(self, latitudinalMeters, longitudinalMeters)
return CLLocationCoordinate2D(latitude: latitude + region.span.latitudeDelta, longitude: longitude + region.span.longitudeDelta)
}
}
可能會更好地命名爲「translate」,因爲它在技術上不是轉換,而是翻譯。 –
謝謝你的回答!其實,我找到了一個辦法。看到我自己的答案。 – Nicsoft
好的答案,我喜歡這個,因爲它直接處理座標,並且更全面地回答問題,因爲它考慮了方向。 – johnrechd