GDAL을 사용하여 Python에서 WGS 1984 Web Mercator (EPSG : 3857) 재 투영


17

GDAL을 사용하여 파이썬으로 래스터를 다시 투영하고 있습니다. 나중에 OpenStreetMap 및 Google지도와 함께 Openlayers에서 사용하려면 지리적 WGS 84 좌표에서 WGS 1984 Web Mercator (Auxiliary Sphere)로 여러 가지 강성을 투영해야합니다. 여기 에서 Python 2.7.5 및 GDAL 1.10.1을 사용하고 여기 에서 조언을 사용하여 좌표를 변환하고 있습니다 (내 코드는 다음과 같습니다). 즉, 나는 수입 osgeo.osr 및 사용 ImportFromEPSG (코드) 와 (에,에서) CoordinateTransformation을 .

내가 먼저 시도 EPSG (32629) 코드가 올바른 것 같다, 그래서 UTM 구역 (29)이며,이 투영 된 래스터 (더 많거나 적은 미세) 도착 : utm 그럼 난 사용 EPSG (3857)를 내가 읽은 때문에 이 와 이 질문에 발견을 올바른 최근 유효한 코드 입니다. 그러나 래스터는 공간 참조없이 생성됩니다. WGS 84 데이터 프레임에서 멀리 떨어져 있지만 데이터 프레임을 Web Mercator로 전환해도 괜찮습니다. 3857

함께 EPSG (900,913) 의 출력은 참조 된되지만 북쪽 3 개 래스터 셀에 대해 시프트 : 900913

ArcGIS (WGS_1984_Web_Mercator_Auxiliary_Sphere로 내보내기)를 사용하여 래스터를 재 투영하면 결과가 거의 좋습니다. Arcgis

그리고 이전 코드 102113 (41001,54004)을 사용 하면 결과가 완벽합니다. 54004

모든 코드를 사용한 테스트 요약 :

3857: far away up (missing georeference)
3785: far away up (like 3857)
3587: far away right
900913: slightly jumped up
102100: python error
102113: perfect
41001: perfect
54004: perfect
ArcGIS (web merc. aux.): good

그래서 내 질문은 :

  • 올바른 EPSG 코드가 왜 잘못된 결과를 줍니까?
  • 왜 이전 코드가 제대로 작동합니까, 더 이상 사용되지 않습니까?
  • 어쩌면 내 GDAL 버전이 좋지 않거나 파이썬 코드에 오류가 있습니까?

코드:

    yres = round(lons[1]-lons[0], 4)  # pixel size, degrees
    xres = round(lats[1]-lats[0], 4)
    ysize = len(lats)-1  # number of pixels
    xsize = len(lons)-1
    ulx = round(lons[0], 4)
    uly = round(lats[-1], 4)  # last
    driver = gdal.GetDriverByName(fileformat)
    ds = driver.Create(filename, xsize, ysize, 2, gdal.GDT_Float32)  # 2 bands
    #--- Geographic ---
    srs = osr.SpatialReference()
    srs.ImportFromEPSG(4326)  # Geographic lat/lon WGS 84
    ds.SetProjection(srs.ExportToWkt())
    gt = [ulx, xres, 0, uly, 0, -yres]  # the affine transformation coeffs (ulx, pixel, angle(skew), uly, angle, -pixel)
    ds.SetGeoTransform(gt)  # coords of top left corner of top left pixel (w-file - center of the pixel!)
    outband = ds.GetRasterBand(1)
    outband.WriteArray(data)
    outband2 = ds.GetRasterBand(2)
    outband2.WriteArray(data3)
    #--- REPROJECTION ---
    utm29 = osr.SpatialReference()
#    utm29.ImportFromEPSG(32629)  # utm 29
    utm29.ImportFromEPSG(900913)  # web mercator 3857
    wgs84 = osr.SpatialReference()
    wgs84.ImportFromEPSG(4326)
    tx = osr.CoordinateTransformation(wgs84,utm29)
    # Get the Geotransform vector
    # Work out the boundaries of the new dataset in the target projection
    (ulx29, uly29, ulz29) = tx.TransformPoint(ulx, uly)  # corner coords in utm meters
    (lrx29, lry29, lrz29) = tx.TransformPoint(ulx + xres*xsize, uly - yres*ysize )
    filenameutm = filename[0:-4] + '_web.tif'
    dest = driver.Create(filenameutm, xsize, ysize, 2, gdal.GDT_Float32)
    xres29 = round((lrx29 - ulx29)/xsize, 2) # pixel size, utm meters
    yres29 = abs(round((lry29 - uly29)/ysize, 2))
    new_gt = [ulx29, xres29, 0, uly29, 0, -yres29]
    dest.SetGeoTransform(new_gt)
    dest.SetProjection(utm29.ExportToWkt())
    gdal.ReprojectImage(ds, dest, wgs84.ExportToWkt(), utm29.ExportToWkt(), gdal.GRA_Bilinear)
    dest.GetRasterBand(1).SetNoDataValue(0.0)
    dest.GetRasterBand(2).SetNoDataValue(0.0)
    dest = None  # Flush the dataset to the disk
    ds = None  # only after the reprojected!
    print 'Image Created'

EPSG : 3042에서 Google Mercator One으로 래스터를 다시 투영하고 있는데 원칙적으로 3857이라고 생각했지만 시도 할 때 gdal_translate -a_srs EPSG : 3857 input.tif output.tif에서 출력은 멀리 떨어져 있습니다 (GDAL 1.11.2). 다행히도 ArcGIS 10.2 및 WGS_1984_Web_Mercator_Auxiliary_Sphere (WKID : 3857 Authority : EPSG)를 사용하여 래프 이미지가 올바른 위치에있을 때 출력이 멀리 떨어집니다 (GDAL 1.11.2). 따라서 EPSG : 3857이 최신 버전의 GDAL에서 제대로 처리되지 않았다고 생각합니다.
— Web-GIS 기업가

3
재 투영 후 래스터는 더 이상 사각형 일 필요가 없습니다. 따라서 코너 좌표를 다시 투영하면 잘못된 해결책이 될 수 있습니다. 커맨드 라인에서 gdalwarp를 사용해 보셨습니까? BTW는 gisinternals에서 최신 GDAL 버전을 얻을 수 있습니다.
— AndreJ

답변:


5

로 파일을 다시 투영합니다 gdalwarp.

EPSG : 3757로 변환하려는 EPSG : 3763 파일에 대해서도 동일한 작업을 수행했습니다. QGIS와 Geoserver를 사용하여 결과를 비교 한 결과 생성 된 이미지가 양호했습니다. 이미지에 작은 회전이 적용되므로 테두리에 검은 선이 생길 수 있습니다 (그러나이 선은 나중에 투명하게 만들 수 있습니다).

여러 tif이미지 가 있으므로 기존 파일을 변경하지 않고 다음과 같은 스크립트를 사용 하여 생성 된 파일을 3857이라는 폴더에 넣을 수 있습니다.

#!/bin/bash
mkdir 3857
for file in $(ls *.tif); do
    gdalwarp -s_srs EPSG:3763 -t_srs EPSG:3857 $file 3857/$file;
    listgeo -tfw 3857/$file;
done

.twf파일 을 생성하려면을 추가했습니다 listgeo.

이 스크립트는 Linux 용이지만 Windows와 비슷한 것을 작성할 수 있습니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.