2015-05-19 13 views
14

Próbuję przekonwertować kod mapowania Apple na Javę. Większość z nich została przekonwertowana poprawnie, z wyjątkiem kilku połączeń z MKMetersPerMapPointAtLatitudeMath Behind MKMetersPerMapPointAtLatitude

Mam bardzo bliskie rozwiązanie ... ale nie jest to dokładne i nie jestem pewien, dlaczego nie. Jakieś pomysły?

#import <Foundation/Foundation.h> 
#import <Math.h> 
@import MapKit; 

#define MERCATOR_OFFSET 268435456.0/2.0 
#define MERCATOR_RADIUS (MERCATOR_OFFSET/M_PI) 
#define WGS84_RADIUS 6378137.0 
#define POINTS_PER_METER (MERCATOR_RADIUS/WGS84_RADIUS) 

double MyMetersPerMapPointAtLatitude(double latitude) { 
    return 1.0/(POINTS_PER_METER/cos(latitude * M_PI/180.0)); 
} 

int main(int argc, const char * argv[]) { 
    @autoreleasepool { 
     double latitude = 33.861315; 
     for (int i = 0; i < 100; i++) { 
      double a = MKMetersPerMapPointAtLatitude(latitude); 
      double b = MyMetersPerMapPointAtLatitude(latitude); 

      NSLog(@"%f %f", a, b); 
      latitude += .1; 
     } 
    } 
    return 0; 
} 

Drukuje następujące

2015-05-19 09:13:00.334 Test[92619:5369062] 0.123522 0.123969 
2015-05-19 09:13:00.335 Test[92619:5369062] 0.123379 0.123824 
2015-05-19 09:13:00.335 Test[92619:5369062] 0.123236 0.123678 
2015-05-19 09:13:00.335 Test[92619:5369062] 0.123092 0.123532 
2015-05-19 09:13:00.335 Test[92619:5369062] 0.122948 0.123386 
2015-05-19 09:13:00.335 Test[92619:5369062] 0.122804 0.123239 
2015-05-19 09:13:00.335 Test[92619:5369062] 0.122659 0.123092 
...etc 
+1

Co dokładnie uważasz, że nie działa? – jny

+0

Cóż, nie jest to dokładne, ale nie jestem pewien dlaczego. Wygląda na to, że moja funkcja jest prawie dokładna, jeśli dodaję 0,3 do szerokości geograficznej ... – Shaun

+0

Przypuszczam, że ma to coś wspólnego z faktem, że Ziemia jest elipsoidą spłaszczoną, a nie idealną? Jest grubszy wokół równika. – Tommy

Odpowiedz

4

na początek, możemy zmienić swoją funkcję, aby to nieco bardziej czytelny:

double MyMetersPerMapPointAtLatitude(double latitude) { 
    return cos(latitude * M_PI/180.0)/POINTS_PER_METER; 
} 

Teraz problem jest, jako punkty Tommy że nie uwzględniacie spłaszczenia Ziemi. Możesz to zrobić za pomocą:

double f = 1/298.257223563; // WGS84 flattening 
double MyMetersPerMapPointAtLatitude(double latitude) { 
    return (1-f) * cos(latitude * M_PI/180.0)/POINTS_PER_METER; 
} 

To powoduje błąd do momentu, w którym przypisałbym to zaokrągleniu i obcięciu.