2014-12-22 3 views
2

나는 많은 양의 구글 맵 이미지를 필요로하는 프로젝트를 만들고있다. 필자는 이러한 기능을 이미지를 자동으로 수집하는 다른 기능에 사용되도록 정의했습니다. 위도가 멋지게 바뀌지 만, 경도가 약간 벗어난 것을 알았습니다. 그것은 대략적인 메르카토르 투영법의 유물입니까? 나는 내가 사용했던 변환이 극에 접근하는 것을 제외하고는 꽤 정확하다는 인상 아래에 있었다.메카 토르 투영 약간

import math 
import os 
import DLMaps 
#Finds the distance covered in a Static Maps image pixel 
def PixDist(zoom,scale=2): 
    earthCirc = 40075.0 #in Km's 
    base = 256 #size of google maps at zoom = 0 
    return earthCirc/(base*scale*(2**zoom)) 

#Finds the Km distance to the next google static maps image based on size of images, 
# and distance per pixel 
def DistNextImage(distpp, scale=2, size=640): 
    return distpp*scale*size 

#returns a new Lat, Lon co-ordinate given a starting point, km distance change and 
# a NESW direction, values 1-4 being used to represent corresponding direction. 
def NewLatLon(lat,lon, dist, direction): 
    if direction==1: 
     dist = dist/110.54 #approximate change in latitude mercator projection 
     lat = lat + dist #heading north 
    elif direction == 2: 
     dist = dist/(110.32 * math.cos(math.pi*lat/180.0)) #approx change in lon 
     lon = lon + dist 
    elif direction==3: 
     dist = dist/110.54 #approximate change in latitude mercator projection 
     lat = lat - dist #heading south 
    elif direction ==4: 
     dist = dist/(110.32 * math.cos(math.pi*lat/180.0)) #approx change in lon 
     lon = lon - dist 
    return lat, lon 
+0

에 WGS84에 대한 몇 가지 참고 자료를 가지고, 내가, 브리즈번 -27.4679, 153.0278을 위도 경도 좌표를 사용하고, 줌 레벨 17이지도는 명확하게 가로 질러 멀리로 이동하고, 출발점과 새로운 협조 사이에 정보를 잃어 버리게됩니다. – NathanielJPerkins

+0

제쳐두고, 어떤 정밀도의 lon, lat는 지구 표면의 점을 고유하게 지정하지 않습니다 (약 1km 이내에 있음). 포인트를 고유하게 식별하기 위해 경도가 측정 된 데이텀이 필요합니다. 어떤 경우에는 데이텀이 구형 또는 타원형이지만, 현대 데이터의 경우 실제로는 "해수면"의 불규칙성을 나타내는 격자입니다. 그러나 Google은 "투영법"에서 데이터 정보를 삭제합니다. 당신이 볼 수있는 차이점은 구형 근사 대신에 타원형 근사를 사용하는 Google 때문입니다. "정확한"근사값은 불규칙한 데이텀입니다. –

+0

어림셈은 어딘가에서 사용할 수 있습니까? 내 프로젝트는 100 % 정확할 필요는 없지만 완벽 주의자 일뿐입니다. 그래서 PixDist 함수를 북 - 남극 원주뿐만 아니라 그것과 직각을 이루도록 재정의해야할까요? – NathanielJPerkins

답변

3

(일부 극단적 인 값을 사용하는 경우 내 반드시, 버그가) 참조 한 시스템에서 다른 시스템으로 전달하는 것은 단순하지 않습니다. pyproj 잘 알려진 proj.4 라이브러리에 대한 Python 인터페이스를 Lat-Lon (WGS84 ...로 가정)에서 거의 모든 다른 좌표 (물론 Mercator 포함)로 변환 할 수 있습니다. 당신은 자신의 것을 굴리려는 시도를 할 수는 있지만, 다른 기점 meridians, 기준 타원체의 약간의 차이와 같은 많은 경고가 있으며, 정확하고 정확한 결과를 얻기를 거의 희망하지 않습니다.

하지만 참고로 wikipedia

+0

예, 제가 만든 것은 완벽한 타원체와 같이 지구를 순진하게 바라 보는 것입니다. 내가 만족 스럽지만 큰 정확도가 필요한 경우, 계산식에 추가 수식이 필요하다는 것을 이해할 수 있습니다. –

+0

흥미롭게도 Google지도 "투영법"은 WGS84 lon, lat 좌표를 사용하지만 _doesn't_는 메르카토르 투영법의 데이텀 정보 (전체, 불규칙한 데이텀이 아닌 타원체로 가정). 여하튼 일반적으로는 정확합니다 (투영은 암호와 같습니다 : 표준 라이브러리를 사용하는 것이 가장 좋습니다). 그러나 타원형 매개 변수를 사용하여 Google의 Mercator 투영법을 다시 만들 수 있습니다. 그리드 데이텀 정보를 필요로하지 않으며 올바르게 수행하고 데이텀 정보를 사용하면 실제로 "잘못된"답변을 얻습니다. –

2

비슷한 계산을하는 개체를 만들었습니다. 어쩌면 그것은 당신에게 영감을 줄 수도 있습니다. 기본적으로 저는 지구를 타원체로 취급합니다. earthCirc는 적도를 따라 지구의 earthCirc와 같지 않습니다. 나는 미터의 거리를 환산하려고 시도한다 < -> 위도가 & lng이다. 내 목적은 당신보다 더 정확한 경우

는 좌표계의 높은 숫자가, 지구가 진정한 타원체 아니다

/** 
* @file: Javascript object to help calculate with latitude, longitude, together with distances (in meter) and angles. 
* The initial goal was to calculate the end point (in lat and latitude & longitude) of a line perpendicular to another line. 
* 
* Planet Earth is approximately an ellipsoid. The circumference along the equator is 
* somewhat greater than the equator through both poles. 
* this javascript object makes calculations that are useful for Google Maps. 
* This will allow to use pythagoras for coordinates, as if earth is a flat rectangle. 
* The precision of the results decreases when the distances increase; and near the poles. 
* Any calculation where the latitude goes beyond the poles (> 90 or < -90) will probably return complete nonsence. 
* 
* @author: Emmanuel Delay, [email protected] 
* copyleft 2014. Feel free to use, copy, share, improve 
* Please send me the code, if you make improvements. 
* 
* Examples: 
<script> 
    function log(message) { 
    document.getElementById('log').innerHTML += message + '<br>'; 
    } 
    window.onload = function() {  
    var dLatLng = Earth.xy2LatLng(5000000, 5000000, 0.0); 
    latLng = [dLatLng.lat, dLatLng.lng ]; 
    log(
     'Start from 0,0 ; move 5000km to the north, 5000km to the east: ' + 
     latLng[0] +','+ latLng[1] 
    ); 

    var eifel = {lat: 48.8582186, lng: 2.2946114}; 
    var dLatLng = Earth.xy2LatLng(1000, 2000, eifel.lat); 

    latLng = [dLatLng.lat, dLatLng.lng ]; 
    var dest = [eifel.lat + latLng[0], eifel.lng + latLng[1] ]; 
    log(
     'Move 1km to the north, 2km to the east of the Eifel Tower: ' + 
     dest[0] +','+ dest[1] 
    ); 

    var dLatLng = Earth.setHeading(eifel.lat, eifel.lng, 10000, 30); 
    latLng = [dLatLng.lat, dLatLng.lng ]; 
    log(
     'Move 10km from the Eifel Tower, heading 30° (North = 0; east = 90°; ...): ' + 
     latLng[0] +','+ latLng[1] 
    ); 
    } 
</script> 
<div id="log"></div> 

    * note: 
    * - all distances are in meter. all angles are in degree 
    * - the d in dLat and dLng stands for delta, being a change in coordinates 
    * - x is along the longitude, y is along latitude 
    */ 

Earth = { 
    // @see http://www.space.com/17638-how-big-is-earth.html for the data 
    // along the equator 
    circumference_equator: 40075000,  
    // throught both poles. 
    // Note: this is basically the original definition of the meter; they were 2km off on a distance from pole to equator (http://en.wikipedia.org/wiki/History_of_the_metre) 
    circumference_poles: 40008000,    
    // given a change in latitude, how many meters did you move? 
    lat2Y: function(dLat) { 
    return this.circumference_poles/360 * dLat; 
    }, 
    // given a change in longitude and a given latitude, how many meters did you move? 
    lng2X: function(dLng, lat) { 
    return Math.cos(this.deg2rad(lat)) * (this.circumference_poles/360 * dLng); 
    }, 
    // given a distance you move due North (or South), what's the new coordinates? 
    // returns a change in latitude 
    y2Lat: function(y) { 
    return y * 360/this.circumference_poles; 
    }, 
    // given a distance you move due East (or West) and a given latitude, what's the new coordinates? 
    // returns a change in longitude 
    x2Lng: function(x, lat) { 
    return x * 360/(Math.cos(this.deg2rad(lat)) * this.circumference_poles); 
    }, 
    // (360°) degrees to radials 
    deg2rad: function(deg) { 
    return deg * Math.PI/180; 
    }, 
    // returns a change in position 
    xy2LatLng: function(y, x, lat) { 
    return { 
     lat: this.y2Lat(y), 
     lng: this.x2Lng(x, lat) 
    }; 
    }, 
    // @param heading: North = 0; east = 90°; ... 
    // returns a change in position 
    setHeading: function(lat, lng, dist, heading) { 
    var latDestination = lat + this.y2Lat(dist * Math.cos(this.deg2rad(heading))); 
    var lngDestination = lng + this.x2Lng(dist * Math.sin(this.deg2rad(heading)), lat); 
    return { 
     lat: latDestination, 
     lng: lngDestination 
    }; 
    }, 
    // returns the absolute position 
    moveByXY: function(lat, lng, x, y) { 
    var dLatLng = Earth.xy2LatLng(x, y, lat); 
    latLng = [dLatLng.lat, dLatLng.lng ]; 
    return { 
     lat: lat + latLng[0], 
     lng: lng + latLng[1] 
    } 
    } 
}