문제

누구든지 LAT/긴 좌표에 대한 가장 효율적인 표현을 아는 사람이 있습니까? 소비자 GPS 장치에는 정확도 수준이 충분해야합니다.

대부분의 구현이 사용되는 것 같습니다 double 각 유닛에 대해서는 의심 스럽습니다 float 또는 고정 된 포인트 형식으로 충분해야합니다. 나는이 값들의 큰 배열을 압축하거나 저장하려고 시도한 사람의 의견을 듣고 싶어합니다.

편집하다:

다시 말해, 소비자 수준 장치의 LAT/Long을 나타내는 데 필요한 최소 정확도는 얼마입니까?

도움이 되었습니까?

해결책

개인적으로 나는 Evan의 답변과 내 의견에 따라 1,000,000으로 나누는 32 비트 10 진수 고정 지점 표현을 사용합니다.

그러나 공간이 진정으로 프리미엄이라면 다음은 다음과 같은 몇 가지 아이디어가 있습니다.

  • 와이어에 26 비트 고정점 표현을 사용할 수 있습니다. 이를 위해서는 위도와 경도를 대량의 바이트로 마샬링하고 구분하지 않아야하지만 32 비트 값 표현에 비해 각 위치마다 12 비트를 절약 할 수 있으므로 거의 19% 절약 할 수 있으므로 가치가있을 수 있습니다.

  • 기둥에 가까워 질 때 경도 값이 정밀도가 적다는 사실을 활용할 수 있습니다. 적도에서 26 비트의 가치 만 필요합니다. 따라서 경도를 인코딩하는 데 사용되는 비트의 수가 위도의 가치에 따라 다릅니다.

  • 데이터가 다른 압축 가능한 속성이있는 경우 (예 : 모든 포인트가 일반적으로 매우 가깝습니다. 가리키다).

다른 팁

지구의 둘레는 약. 40.000km 또는 24900 마일.

GPS 정밀도를 크기로 능가하려면 1 미터 정확도 (3 피트)가 필요합니다.

따라서 40.000.000의 다른 값을 저장하려면 Precisiton이 필요합니다. 그것은 최소 26 비트의 정보입니다. 32 비트 플로트 또는 int가 잘 작동합니다.

편집하다: 주석의 일부 포인트가 추가되면 32 비트 값이 충분한 정밀도를 제공 할 수 있어야합니다.

32 비트 고정점 표현을 사용합니다. 값이 다음과 같은 경우

42.915512,-99.521654 나는 보관할 것이다 values * 100000 안에 int32_t'에스 (그들은 부정적 일 수 있습니다).

int32_t lat = 42915512;
int32_t lon = -99521654;

이것은 단순하고 정확한 사이의 좋은 타협입니다 (5 소수점 이하는 일반적으로 충분합니다. 항상 부딪 칠 수 있습니다. 1000000 얻기 위해 6 필요한 경우).

사용자에게 표시하려면 무엇을하십시오 CAF 제안:

... 사용자에게 표시하려면 - 정수 분할 및 모듈로 사용 printf("Lat = %d.%06d\n", lat / 1000000, abs(lat) % 1000000)

상대적 순서가 보존되기 때문에 효율적인 방식으로 비교할 수 있고 정렬 할 수 있습니다.

편집하다: 추가적인 이점은 네트워크를 통해 전송되거나 휴대용 방식으로 이진 형식으로 디스크에 저장할 수 있다는 것입니다.

소비자 수준의 GPS 장치가 주장 된 정확도 근처에있는 곳이 있더라도 Float는 GPS 좌표를 저장하기에 충분할 것입니다. 이것이 사실이라고 믿지 않는다면,이 두 가지 간단한 실험을 시도하십시오.

  1. 두 개 이상의 GPS 장치를 어딘가에서 필드의 한 지점으로 가져 가서 각 장치에서 측정 한 좌표를 jot습니다. 내부로 돌아가서지도에서 각 장치의 포인트를 플로팅하십시오 (Google 은이 작업을 수행하는 것이 있다고 생각합니다). 당신은 포인트가 얼마나 멀리 떨어져 있는지에 대해 놀랄 것입니다 (모두 같은 지점을 측정해야하지만).
  2. 가장 정확한 장치를 가져 와서 위성 수정을받을 수 있지만 비가 오지 않을 수있는 곳에 배치하고 며칠에 걸쳐 일련의 측정을 기록하십시오. 모든 판독 값을 플로팅하십시오 ( #1에서와 같이). 다시 말하지만, 포인트 (모두 동일하거나 거의 동일해야 함)가지도 전체, 때로는 몇 백 피트만큼 방황하는 방법에 놀랄 것입니다.

나는 수년간 GPS 지원 PDA에 대한 응용 프로그램을 작성해 왔으며, 모호한 고객을 위해 이것을 반복해서 확인했습니다 (이 방법으로 베팅을 이겼습니다). 이보다 더 나은 정확도를 달성하는 고품질 GPS 장치가 있지만 더 비싼 칩셋으로 더 나은 정확도가 달성되며 장치는 며칠 또는 몇 주 동안 한 지점에 남겨져 있으며, 측정 값은 시간이 지남에 따라 평균입니다.

4 바이트 플로트는 장치 자체보다 훨씬 정확합니다.. 물론 2X 팩터가 당신에게 문제가되지 않는 한, 대신 더블을 사용하는 것은 당신을 전혀 해치지 않을 것입니다.

179 도의 경도에서 23 비트의 정밀도는 10 미터의 정확도를 제공하며 이는 일반 GPS 장치가 제공하는 것이 가장 좋습니다. 적도에서 :

% gps distance "0.0, 179.0" "0.0, $((179 * (1 + 2**-23)))"
From 0.0, 179.0 to 0.0, 179.00002133846283 is 7.79 feet E
From 0.0, 179.0 to 0.0, 179.00002133846283 is 2.38 meters E

따라서 C 컴파일러에 알려진 IEEE 754 단일----------------------------------------------------프리렉션 플로팅 지점. float, 대표에 적합합니다. 확장 계산에 플로트를 사용하는 것을 조심하십시오! 반올림 오류는 점심을 먹을 수 있습니다. 수치 분석가와 상담하십시오.

Garmin의 IMG 맵 형식에서는 플로트를 사용하여 바인딩 상자 안에 좌표를 저장하여 상자의 가장자리를 설정합니다. 상자 내의 코디는 필요한 정밀도에 따라 최소와 최대 값 사이의 가변 비트 수를 사용하여 정의됩니다.

예를 들어: minlat = 49.0, maxlat = 50.0, minlon = 122.0, maxlon = 123.0, 비트 수 = 16

그래서 값 :
32768,32768은 49.5, 122.5로 변환됩니다
16384,0은 49.25, 122.0입니다

정밀도가 적은 경우 여러 비트 = 4로 동일한 출력을 생성 할 수 있습니다.
8,8은 49.5, 122.5로 변환됩니다
4,0은 49.25, 122.0입니다

이 값의 큰 배열을 저장하는 경우 델타 압축을하고 델타를 저장하는 경우 몇 가지 간단한 트릭이 있습니다. 데이터 스트림의 크기를 크게 줄일 수 있습니다. "키 포인트"에서 델타를 할 수 있습니다.

kdddddddddkdddd ...

K + D는 모든 D 포인트로 이동합니다

Deltas는 모두 이전 K를 참조하므로 모든 점을 재구성하려면 K와 A D가 필요합니다.

또는 당신은 매우 델타를 할 수 있습니다

kiiiiiiiiiik

이것은 원하는 위치에 도달하기 위해 여러 합계를 취할 수 있습니다. 그러나 데이터는 전체적으로 더 작습니다. 그래서 재구성하기 위해

K+I+I+i 4 점에 도달하려면

마지막으로 둘 다 결합 할 수 있습니다

kdiiidiiidiiik

이것은 IPB 프레임을 가진 MPEG-2와 같지만이 방법으로 당신은 어떤 위치에도 4 회 이상이되지 않으며 델타와 중대한 압축의 이점을 얻습니다.

당신은 포장 할 수 있습니다 위도와 경도 모두 a의 값 단일 32 비트 정수 재귀 타일링 시스템을 사용하는 경우 최악의 ~ 2.4 미터/픽셀 (적도)의 해상도. 레벨 당 2 비트를 사용하면 16 레벨을 32 비트로 저장할 수 있습니다. 이 기사를 보는 방법에 대한 아이디어를 얻을 수 있습니다. 가상 지구의 타일링 시스템. 이것은 Mercator를 사용하므로 극에 문제가 생길 수 있습니다. 대신 다른 투영을 사용하고 여전히 매우 유사한 결과를 얻을 수 있습니다.

이것은 또한 a에 사용될 수 있습니다 거친 필터 첫 번째 N 비트가 동일하기 때문에 주어진 부모 타일 내에서 어떤 점을 찾으려면 (따라서 검색은 약간 마스킹이됩니다).

지구가 3959 마일의 반경 'R'(또는 × 5280 ft/mi = 20903520 ft)의 완벽한 구체라고 가정하면 둘레는 131340690 피트 (2 × pi × r 사용)입니다. .

360도 경도는 131340690 피트입니다. 180도 위도는 65670345 피트를 덮습니다.

LAT/LNG를 3 피트의 정확도로 저장하려면 43780230 (131340690/3) 경도 값과 21890115 (65670345/3) 위도 값을 저장할 수 있어야합니다. 43780230은 25.38 비트 (로그 (43780230)/log (2))가 필요하며 21890115는 24.38 비트 (log (21890115)/log (2))를 보관하거나 50 비트 (또는 6.25 바이트) 미만으로 필요합니다.

따라서 명백한 질문은 위도와 경도를 6 바이트로 저장하려면 정확도는 무엇입니까? 글쎄, 6 바이트는 48 비트입니다. 이는 위도의 경우 23.5 비트와 경도의 경우 24.5 비트를 의미합니다 (경도의 값은 2 배, 이는 단 1 비트와 24.5-23.5 = 1 비트)를 의미합니다. 따라서 23.5 비트를 사용하면 0에서 11863282 (11863283 값)까지 숫자를 나타낼 수 있습니다. 11863283 값으로 나눈 65670345 피트는 5.53 피트 (및 경도의 동일한 정확도 값)입니다.

결론 : 위도와 경도 모두에 대해 5.5 피트의 정확도로 살 수 있다면 두 값을 6 바이트에만 포장 할 수 있습니다.

*부수적 참고 : 위도와 경도가 구체에 위치 정보를 저장하는 데 끔찍하다는 의견과 관련하여 (기둥에 보관할 정보가 적기 때문에) - 그 의견은 수학을 유지하지 않습니다! 알아 봅시다. 지구의 모든 평방 피트의 중앙에 땅에 스테이크를 기록하고 놓을 수있는 새로운 완벽한 시스템을 설계하고 싶다고 가정 해 봅시다. 지구의 표면적 (R은 3959 마일; 구의 표면적에 대한 공식)은 5490965469267303 sq ft입니다. 이제 기존 위도 및 경도 시스템은 직사각형 시스템을 사용합니다. 직사각형의 너비는 지구의 둘레이며 직사각형의 높이는 둘레의 1/2입니다) - 131340690 * 65670345 (위의 위 참조) 또는 86251884248380 Sq ft - (이 시스템 위치에 52.94 비트가 필요합니다. 폴란드 주변의 땅에 '너무 많은'지분이 있습니다). 따라서 충격적인 대답은 새로운 완벽한 시스템과 이전 LAT/LNG 시스템이 모두 1 피트 정확도로 단일 위치를 지구에 저장하려면 53 개의 실제 비트가 필요하다는 것입니다!

나는 Long/LAT가 구체에 데이터를 저장하는 끔찍한 방법이라는 사실을 아무도 게시하지 않았다는 사실에 놀랐습니다 (누군가는 경도가 기둥 근처에서 정밀도가 덜 필요하다고 언급했습니다).

기본적으로 데이터 위치를 미터로 X 및 Y 코드로 저장할 수 있습니다. 지구 주위에 큐브가 정확하게 맞는 큐브를 상상해보십시오 (하하 OK 거의 적합). 3-rd 코드는 지구의 Redius에서 나올 수 있기 때문에 3 개의 코드가 아니라 Store X와 Y 위치 만 필요합니다. .

따라서 LAT/Long을 미터로 X/Y로 변환하십시오. 코드 당 총 12756200m 만 필요합니다 (지구의 직경). 따라서 총 값은 0에서 25,512,400 (다른 사람이 Long/LAT를 사용하고 있었기 때문에 40,000,000 명을 주장 함)에 대해서만 +/- 0.5m에 걸쳐 있어야합니다.

이로 인해 위치 당 25 비트가됩니다. 내가 당신이라면 나는 단지 2m 이내에 정확한 일을하고 위치 당 24 비트를 사용할 것입니다.

또한 경로에 웨이 포인트 정보를 저장하는 경우 각 웨이 포인트를 마지막 웨이 포인트에서 오프셋으로 저장할 수 있습니다. 24 비트 x/y 코드로 시작합니다. 그런 다음 x/y 미터를 추가/빼기 위해 위치를 조정하는 16 비트 '업데이트'가 있습니다. 16 비트는 웨이 포인트 업데이트가 400m 이상 떨어질 수 있도록합니다. 따라서 장치가 비행기와 업데이트를 자주하는 것이 아니라는 것을 알고 있다면 이는 허용 가능할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top