두 점 사이의 거리 계산(위도, 경도)
지도상의 두 위치 사이의 거리를 계산하려고 합니다.데이터: 경도, 위도, X POS, Y POS에 저장했습니다.
저는 이전에 아래의 스니펫을 사용하고 있었습니다.
DECLARE @orig_lat DECIMAL
DECLARE @orig_lng DECIMAL
SET @orig_lat=53.381538 set @orig_lng=-1.463526
SELECT *,
3956 * 2 * ASIN(
SQRT( POWER(SIN((@orig_lat - abs(dest.Latitude)) * pi()/180 / 2), 2)
+ COS(@orig_lng * pi()/180 ) * COS(abs(dest.Latitude) * pi()/180)
* POWER(SIN((@orig_lng - dest.Longitude) * pi()/180 / 2), 2) ))
AS distance
--INTO #includeDistances
FROM #orig dest
하지만 여기서 나오는 데이터는 믿을 수 없습니다만, 결과가 약간 부정확한 것 같습니다.
필요한 경우 샘플 데이터
Latitude Longitude Distance
53.429108 -2.500953 85.2981833133896
누가 내 코드를 좀 도와줄 수 있나요? 만약 당신이 이것을 할 수 있는 새로운 방법이 있다면 제가 가지고 있는 것을 고치고 싶어도 상관없습니다.
결과가 어떤 측정 단위에 속하는지 명시해 주십시오.
SQL Server 2008을 사용하고 있기 때문에 다음과 같은 종류의 데이터를 위해 설계된 데이터 유형을 사용할 수 있는 데이터 유형은 다음과 같습니다.
DECLARE @source geography = 'POINT(0 51.5)'
DECLARE @target geography = 'POINT(-3 56)'
SELECT @source.STDistance(@target)
주다
----------------------
538404.100197555
(1 row(s) affected)
런던에서 에딘버러까지는 약 538km라고 말해 준다.
물론, 우선은 많은 것을 배울 수 있지만, 일단 이것이 자신의 Haversine 계산을 구현하는 것보다 훨씬 쉽다는 것을 알게 되면, 많은 기능을 얻을 수 있습니다.
기존 데이터 구조를 유지하려면STDistance
적절한 구성을 통해geography
다음 메서드를 사용하는 인스턴스:
DECLARE @orig_lat DECIMAL(12, 9)
DECLARE @orig_lng DECIMAL(12, 9)
SET @orig_lat=53.381538 set @orig_lng=-1.463526
DECLARE @orig geography = geography::Point(@orig_lat, @orig_lng, 4326);
SELECT *,
@orig.STDistance(geography::Point(dest.Latitude, dest.Longitude, 4326))
AS distance
--INTO #includeDistances
FROM #orig dest
아래 함수는 두 위치 사이의 거리(마일)를 제공합니다.
create function [dbo].[fnCalcDistanceMiles] (@Lat1 decimal(8,4), @Long1 decimal(8,4), @Lat2 decimal(8,4), @Long2 decimal(8,4))
returns decimal (8,4) as
begin
declare @d decimal(28,10)
-- Convert to radians
set @Lat1 = @Lat1 / 57.2958
set @Long1 = @Long1 / 57.2958
set @Lat2 = @Lat2 / 57.2958
set @Long2 = @Long2 / 57.2958
-- Calc distance
set @d = (Sin(@Lat1) * Sin(@Lat2)) + (Cos(@Lat1) * Cos(@Lat2) * Cos(@Long2 - @Long1))
-- Convert to miles
if @d <> 0
begin
set @d = 3958.75 * Atan(Sqrt(1 - power(@d, 2)) / @d);
end
return @d
end
아래 함수는 두 측지 좌표 사이의 거리(km)를 제공합니다.
CREATE FUNCTION dbo.fnCalcDistanceKM(@lat1 FLOAT, @lat2 FLOAT, @lon1 FLOAT, @lon2 FLOAT)
RETURNS FLOAT
AS
BEGIN
RETURN ACOS(SIN(PI()*@lat1/180.0)*SIN(PI()*@lat2/180.0)+COS(PI()*@lat1/180.0)*COS(PI()*@lat2/180.0)*COS(PI()*@lon2/180.0-PI()*@lon1/180.0))*6371
END
아래 함수는 sql server 2008에서 도입된 지리 데이터 유형을 사용하여 2개의 지리 좌표 사이의 거리(km)를 나타냅니다.
DECLARE @g geography;
DECLARE @h geography;
SET @g = geography::STGeomFromText('LINESTRING(-122.360 47.656, -122.343 47.656)', 4326);
SET @h = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326);
SELECT @g.STDistance(@h);
사용방법:
select [dbo].[fnCalcDistanceKM](13.077085,80.262675,13.065701,80.258916)
마이크로소프트는 다른 모든 응답자들의 뇌를 침범하여 가능한 한 복잡한 해결책을 쓰게 한 것으로 보인다.다음은 추가 함수/선언문을 사용하지 않는 가장 간단한 방법입니다.
SELECT geography::Point(LATITUDE_1, LONGITUDE_1, 4326).STDistance(geography::Point(LATITUDE_2, LONGITUDE_2, 4326))
단순히 데이터를 대체하여LATITUDE_1
,LONGITUDE_1
,LATITUDE_2
,LONGITUDE_2
예:
SELECT geography::Point(53.429108, -2.500953, 4326).STDistance(geography::Point(c.Latitude, c.Longitude, 4326))
from coordinates c
Create Function [dbo].[DistanceKM]
(
@Lat1 Float(18),
@Lat2 Float(18),
@Long1 Float(18),
@Long2 Float(18)
)
Returns Float(18)
AS
Begin
Declare @R Float(8);
Declare @dLat Float(18);
Declare @dLon Float(18);
Declare @a Float(18);
Declare @c Float(18);
Declare @d Float(18);
Set @R = 6367.45
--Miles 3956.55
--Kilometers 6367.45
--Feet 20890584
--Meters 6367450
Set @dLat = Radians(@lat2 - @lat1);
Set @dLon = Radians(@long2 - @long1);
Set @a = Sin(@dLat / 2)
* Sin(@dLat / 2)
+ Cos(Radians(@lat1))
* Cos(Radians(@lat2))
* Sin(@dLon / 2)
* Sin(@dLon / 2);
Set @c = 2 * Asin(Min(Sqrt(@a)));
Set @d = @R * @c;
Return @d;
End
GO
사용방법:
dbo를 선택합니다.DistanceKM(37.84883250647, 37.84873250647, 27.83935546875, 27.83905546875)
출력:
0,02849639
주석이 달린 플로트를 사용하여 @R 파라미터를 변경할 수 있습니다.
SQL 2008 이후를 사용하는 경우 지리 데이터 유형을 확인하는 것이 좋습니다.SQL은 지리 공간 쿼리를 기본적으로 지원합니다.
예를 들어, GIGRATION 유형의 테이블에 좌표의 지리 공간적 표현으로 채워지는 열이 있을 것입니다(위에 링크된 MSDN 참조 참조 참조 참조).그런 다음 이 데이터 유형은 지리 공간 쿼리 전체 호스트(예: 두 점 사이의 거리 찾기)를 수행할 수 있는 방법을 제공합니다.
위의 답변과 더불어 SELECT 내부의 거리를 계산하는 방법이 있습니다.
CREATE FUNCTION Get_Distance
(
@La1 float , @Lo1 float , @La2 float, @Lo2 float
)
RETURNS TABLE
AS
RETURN
-- Distance in Meters
SELECT GEOGRAPHY::Point(@La1, @Lo1, 4326).STDistance(GEOGRAPHY::Point(@La2, @Lo2, 4326))
AS Distance
GO
사용방법:
select Distance
from Place P1,
Place P2,
outer apply dbo.Get_Distance(P1.latitude, P1.longitude, P2.latitude, P2.longitude)
스칼라 함수도 작동하지만 대량의 데이터를 계산할 때 매우 비효율적입니다.
이게 도움이 됐으면 좋겠어요.
언급URL : https://stackoverflow.com/questions/13026675/calculating-distance-between-two-points-latitude-longitude
'programing' 카테고리의 다른 글
지정된 사용 권한...(0xE8008016).오류 iOS 4.2 (0) | 2023.04.16 |
---|---|
Excel VBA에서 사용자 정의 필터를 저장/복원하려면 어떻게 해야 합니까? (0) | 2023.04.16 |
이 Git 경고에 대처하려면 어떻게 해야 하나요?서로 다른 브랜치를 조정하는 방법을 지정하지 않고 당기는 것은 권장되지 않습니다. (0) | 2023.04.16 |
Apache POI를 사용하여 Excel 셀에 번호 쓰기 (0) | 2023.04.16 |
텍스트 필드를 탐색하는 방법([다음]/[완료] (0) | 2023.04.16 |