คัดลอก WGS 1984 Web Mercator (EPSG: 3857) ใน Python ด้วย GDAL


17

ฉันกำลังตำหนิตัวแรสเตอร์ในไพ ธ อนโดยใช้ GDAL ฉันต้องฉายหลาย tiffs จากพิกัดทางภูมิศาสตร์ WGS 84 กับ WGS 1984 Web Mercator (Auxiliary Sphere) เพื่อใช้ในภายหลังใน Openlayers ร่วมกับ OpenStreetMap และ Google maps ฉันใช้ 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 (900913)ผลลัพธ์จะถูกอ้างอิงทางภูมิศาสตร์ แต่เลื่อนไปยังเซลล์แรสเตอร์ประมาณ 3 เซลล์ไปทางทิศเหนือ: 900913

เมื่อฉัน reproject แรสเตอร์โดยใช้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 หนึ่งฉันคิดว่าเป็นหลักการ 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) ภาพแรสเตอร์อยู่ในตำแหน่งที่ถูกต้อง ดังนั้นฉันเชื่อว่า EPSG: 3857 นั้นไม่ได้รับการจัดการอย่างถูกต้องใน GDAL รุ่นล่าสุด
ผู้ประกอบการ Web-GIS

3
หลังจากการคัดออกแรสเตอร์ไม่จำเป็นต้องเป็นรูปสี่เหลี่ยมผืนผ้าอีกต่อไป ดังนั้นการคัดแยกพิกัดมุมอาจเป็นวิธีแก้ไขที่ผิด คุณลอง gdalwarp บนบรรทัดคำสั่งแล้วหรือยัง? BTW คุณสามารถรับรุ่น GDAL ล่าสุดจาก gisinternals
AndreJ

คำตอบ:


5

ฉันจะ reproject gdalwarpไฟล์กับ

ฉันทำเช่นเดียวกันสำหรับไฟล์ใน EPSG: 3763 ที่ฉันต้องการแปลงเป็น EPSG: 3857 ฉันเปรียบเทียบผลลัพธ์โดยใช้ 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.