2017-01-18 3 views
4

전체 목표 : 주어진 지퍼로부터 30 마일 이내에있는 모든 우편 번호를 찾습니다.Haversine 수식 단위 오류 - PL/SQL

데이터 원본 : 위도와 경도가 'x'인 & 'y'인 우편 번호 목록.

예 :

create or replace view zips as 
select 37171 zip, 36.362704 y, -87.30434 x,'Southside' City, 'TN' State from dual 
union 
select 37212, 36.133012, -86.802764, 'Nashville', 'TN' from dual 
union 
select 37027, 36.00245, -86.791159, 'Brentwood', 'TN' from dual 
union 
select 37191, 36.501196, -87.539057, 'Woodlawn', 'TN' from dual 
union 
select 37067, 35.928406, -86.805538, 'Franklin', 'TN' from dual ; 

내가을 시도했다 : 그것은 나에게 펑키 번호를주고 있었다, 그러나

CREATE OR REPLACE FUNCTION distance (Lat1 IN NUMBER, 
            Lon1 IN NUMBER, 
            Lat2 IN NUMBER, 
            Lon2 IN NUMBER, 
            Radius IN NUMBER DEFAULT 3963) RETURN NUMBER IS 
-- Convert degrees to radians 
DegToRad NUMBER := 57.29577951; 

BEGIN 
    RETURN(NVL(Radius,0) * ACOS((sin(NVL(Lat1,0)/DegToRad) * SIN(NVL(Lat2,0)/DegToRad)) + 
     (COS(NVL(Lat1,0)/DegToRad) * COS(NVL(Lat2,0)/DegToRad) * 
     COS(NVL(Lon2,0)/DegToRad - NVL(Lon1,0)/ DegToRad)))); 
END; 

- 일관성 : 나는 그것을처럼 보였다 뭔가 solve all my problems에 가고 있었다 발견 너무 작습니다 (프랭클린에서 내쉬빌까지 1 마일이 아니라는 것을 압니다). 그러나 내가 결정할 수있는 일정한 요소가 아닙니다. (코드 내가 테스트하는 데 사용 아래입니다 -이 거리와 Google지도에서 나는 단지 비해 거리) 그래서

select b.zip 
    ,b.city 
    ,b.state 
    ,distance(a.x,a.y,b.x,b.y) distance 
from zips a, zips b 
where a.zip=37067 
order by distance; 

, 나는 지리 그룹이 & 긴 LAT 녹화의 다른 방법을 가지고 있었다 어쩌면 생각 나는 Wikipedia's Haversine formula을 발견 및 설정 그 기능에

CREATE OR REPLACE FUNCTION distance (Lat1_d IN NUMBER, 
            Lon1_d IN NUMBER, 
            Lat2_d IN NUMBER, 
            Lon2_d IN NUMBER, 
            Radius IN NUMBER DEFAULT 3959) RETURN NUMBER IS 
-- Convert degrees to radians 
DegToRad NUMBER := .0174532925; 
Lat1 NUMBER := Lat1_d * DegToRad; 
Lon1 NUMBER := Lon1_d * DegToRad; 
Lat2 NUMBER := Lat2_d * DegToRad; 
Lon2 NUMBER := Lon2_d * DegToRad; 

BEGIN 

    RETURN 2*Radius * 
    asin(
     sqrt(
     power(sin((Lat2-Lat1)/2),2) + cos(Lat1) * cos(Lat2) * power(sin((Lon2-Lon1)/2),2) 
    ) 
    ) 
     ; 
END; 

같은 문제 - 결과는 거의 동일합니다, 어떤 문제가 궁금 날 단풍. 나는 어떤 변화를 보이지 않습니까? 내가 뭘 놓치고 있니?

평평한 지구를 가정하고 피타고라스 거리를 사용하게되어 기쁩니다. 내가보기에는 각 우편 번호 집합에 대해 30-50 마일을 조사 할 것이기 때문에 나는 알아낼 필요가 있습니다 위도/경도 변환이 잘못되어있는 것은 어떨까요?

+1

위대한 첫 번째 IMHO. 오른쪽 태그, 데이터 샘플, 코드 및 데이터 형식, 참조, ... SO! – Aleksej

답변

2

매개 변수 문제 같습니다.

CREATE OR REPLACE FUNCTION distance (Lat1 IN NUMBER, 
            Lon1 IN NUMBER, 
            Lat2 IN NUMBER, 
            Lon2 IN NUMBER, 

그리고 다음과 같이 당신이 그것을 호출하고 있습니다 : 헤더는

distance(a.x,a.y,b.x,b.y) 

를하지만보기는 다음과 같습니다 뷰에 따르면

create or replace view zips as 
select 37171 zip, 36.362704 y, -87.30434 x,'Southside' City, 'TN' State from dual 
union 
select 37212, 36.133012, -86.802764, 'Nashville', 'TN' from dual 
union 
select 37027, 36.00245, -86.791159, 'Brentwood', 'TN' from dual 
union 
select 37191, 36.501196, -87.539057, 'Woodlawn', 'TN' from dual 
union 
select 37067, 35.928406, -86.805538, 'Franklin', 'TN' from dual ; 

, x는 경도와 y이다 위도입니다. 따라서 함수 호출은 다음과 같아야합니다

distance(a.y,a.x,b.y,b.x) 

또는, "X"와 뷰에서 "Y"별명을 교환하고 같이 다른 모든 것들을 남길 수 있습니다.

+1

나는 때때로 당신의 손바닥으로 이마를 때리는 것이 좋다고 들었습니다. 쉐이크. 저에게 기회를 주셔서 감사합니다. – Maggie

+0

@Maggie, 문제가 없습니다. 나는 같은 생각을하고 세미콜론을 잊어 버린 채 여러 해 동안 내 두개골에 움푹 들어간 것 같아. – tilper

+0

괜찮은 이름의 가치에 대한 중요한 교훈. 뷰 컬럼이'x'와'y'보다는'longitude'와'latitude'라면 즉시 이것을 발견했을 것입니다. – APC