วิธีหยุด gdalwarp ในการสร้างเอาต์พุตที่ครอบคลุมทั่วโลกใกล้กับ dateline ได้อย่างไร


11

ฉันใช้ gdalwarp เพื่อจัดการกระเบื้อง SRTM ใกล้กับ dateline (เช่น 180 °หรือที่เรียกว่า antimeridian) ไทล์ SRTM มีการทับซ้อนกันเล็กน้อย (1/2 พิกเซล) เล็กน้อยกับเมริเดียน คุณสามารถดูได้โดยใช้ gdalinfo:

gdalinfo S16W180.hgt
Driver: SRTMHGT/SRTMHGT File Format
Files: S16W180.hgt
Size is 1201, 1201
[...]
Lower Left  (-180.0004167, -16.0004167) (180d 0' 1.50"W, 16d 0' 1.50"S)
Upper Right (-178.9995833, -14.9995833) (178d59'58.50"W, 14d59'58.50"S)
[...]

ดังนั้นแหล่งขยายช่วงวันที่ด้วยจำนวนเล็กน้อย

สิ่งนี้ทำให้เกิดปัญหากับ gdalwarp ซึ่งจบลงด้วยการสร้างผลลัพธ์ที่ครอบคลุมทั่วโลก

gdalwarp -t_srs "epsg:900913" S16W180.hgt test.tif
gdalinfo test.tif
Driver: GTiff/GeoTIFF
Files: test.tif
Size is 1703, 5
[...]
Lower Left  (-20037508.330,-1806798.473) (180d 0' 0.00"W, 16d 7'13.00"S)
Upper Right (20032839.451,-1689152.120) (179d57'29.01"E, 15d 5'45.84"S)

โปรดสังเกตว่าเส้นลองจิจูดยาว (เกือบ) ทั่วทั้งโลกและจำนวนบรรทัดมีขนาดเล็กโดยไม่คาดคิด (5)

นี่เป็นข้อผิดพลาดใน gdalwarp หรือไม่? ถ้าไม่ใช่ตัวเลือกที่ถูกต้องในการส่งผ่านไปยัง gdalwarp เพื่อรับเอาต์พุตที่เหมาะสมคืออะไร


dds.cr.usgs.gov/srtm/version2_1/SRTM3/Australia/S16W180.hgt.zipในกรณีที่คุณต้องการทดลอง
แรงโน้มถ่วงใน

เพิ่มพารามิเตอร์ SOURCE_EXTRA ดูcode.google.com/p/maptiler/issues/detail?id=6 - ลอง gdalwarp -t_srs epsg: 900913 - สอง SOURCE_EXTRA = 120 S16W180.hgt test.tif
Mapperz

อาจใช้อาร์กิวเมนต์ -te สำหรับ "extents เป้าหมาย" หรือแก้ไข extents ก่อนโดยใช้ gdal_translate กับ a_ullr เพื่อเขียนทับที่มีอยู่หรือ -projwin เพื่อตัดบิตที่คุณต้องการภายในขอบเขต
mdsumner

คำตอบ:


2

วิธีแก้ปัญหาง่าย ๆ อย่างหนึ่งคือการระบุระบบพิกัด "ด้วยตนเอง" เป็นสตริง PROJ วิธีนี้ช่วยให้คุณใช้+overสวิตช์ที่ปิดใช้งานการตัดบน antimeridian

gdalwarp -t_srs \
    "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0 \
        +over +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null \
        +wktext +lon_wrap=-180 +no_defs" \
    S16W180.hgt test.tif

เมื่อฉันทำอย่างนั้นแล้วทำgdalinfoตามผลลัพธ์ฉันได้สิ่งนี้:

Corner Coordinates:
Upper Left  (-20037554.726,-1689152.120) (179d59'58.50"E, 14d59'58.50"S)
Lower Left  (-20037554.726,-1804766.925) (179d59'58.50"E, 16d 0' 1.37"S)
Upper Right (-19926099.407,-1689152.120) (178d59'57.11"W, 14d59'58.50"S)
Lower Right (-19926099.407,-1804766.925) (178d59'57.11"W, 16d 0' 1.37"S)
Center      (-19981827.066,-1746959.523) (179d29'59.30"W, 15d30' 2.12"S)

ผมได้สตริง PROJ (ไม่+over) gdalinfoจากการดูที่การส่งออกเดิมของ มันรวมอยู่ในEXTENSION[...]บล็อกของระบบพิกัด


1

มันทำงานได้ในสองขั้นตอน:

gdalwarp -te -180 -16 -179 -15 s16W180.hgt test.tif
gdalwarp -t_srs "epsg:3857" test.tif out.tif

คำสั่งแรกเริ่มจากครึ่งพิกเซลพิเศษที่ด้านผิดของเที่ยง 180 ° คุณได้รับไฟล์เอาต์พุตที่เป็น 1178P x 1222L

อีกทางเลือกหนึ่งด้วย gdal_translate:

gdal_translate -a_ullr -180 -15 -179 -16 S16W180.hgt test2.tif
gdalwarp -t_srs "epsg:3857" test2.tif out2.tif

การสร้างไฟล์เอาต์พุตที่เป็น 1179P x 1223L


1

ขณะที่ฉันกำลังเผชิญปัญหาเดียวกันฉันเขียนเชลล์สคริปต์ขนาดเล็กที่พบว่าไฟล์แรสเตอร์ข้าม dateline หรือไม่ หากเป็นจริงตัวเลือกต่อไปนี้จะถูกเพิ่มเข้าไปใน gdalwarp:

--config CENTER_LONG 180

นี่คือการทำงานของสคริปต์ทีละขั้นตอน:

  1. รับ WGS84 Extents จาก gdalinfo
  2. ถ้าเปลี่ยน ULXและLRX หรือ llxและURXค่าพลิกเมื่อเทียบกับ CRS เดิมแรสเตอร์เปลี่ยนจะข้ามวันเดือนปี
  3. หากข้ามวันที่ข้อมูล--config CENTER_LONG 180จะถูกเพิ่มใน gdalwarp

อัปเดตสคริปต์เวอร์ชันที่ดีขึ้นต้องใช้ GDAL 2.0+ และ Python: เวอร์ชันเก่าด้านล่าง

#!/bin/bash
#
# Small Script to check if input raster will
# cross dateline when converting to EPSG:4326
# 
# USAGE: ./crosses_dateline.sh infile [outfile]
# 
# if no outfile is given, the script returns "true" or "false"
# if an outfile is given, gdalwarp is executed
# 
# Needs gdal 2.0+ and Python
# 


if [ -z "${1}" ]; then
    echo -e "Error: No input rasterfile given.\n> USAGE: ./crosses_dateline.sh infile [outfile]"
    exit
fi

# Get information, save it to variable as we need it several times
gdalinfo=$(gdalinfo "${1}" -json)

# If -json switch is not available exit!
if [ ! -z $(echo $gdalinfo | grep "^Usage:") ]; then
    echo -e "Error: GDAL command failed, Version 2.0+ is needed"
    exit
fi

function jsonq {
    echo "${1}" | python -c "import json,sys; jdata = sys.stdin.read(); data = json.loads(jdata); print(data${2});"
}

ulx=$(jsonq "$gdalinfo" "['wgs84Extent']['coordinates'][0][0][0]")
llx=$(jsonq "$gdalinfo" "['wgs84Extent']['coordinates'][0][1][0]")
lrx=$(jsonq "$gdalinfo" "['wgs84Extent']['coordinates'][0][3][0]")
urx=$(jsonq "$gdalinfo" "['wgs84Extent']['coordinates'][0][2][0]")

crossing_dateline=false
test $(echo "${ulx}>${lrx}" | bc) -eq 1 && crossing_dateline=true
test $(echo "${llx}>${urx}" | bc) -eq 1 && crossing_dateline=true

if [ -z "$2" ]; then
    echo "${crossing_dateline}"
elif [ "${crossing_dateline}" == "true" ]; then
    gdalwarp -t_srs "EPSG:4326" --config CENTER_LONG 180 "${1}" "${2}"
else
    gdalwarp -t_srs "EPSG:4326" "${1}" "${2}"
fi

#!/bin/bash
#
# Check if input raster crosses dateline when converting to EPSG:4326
# 
# if no outfile is given, the script returns "true" or "false"
# if an outfile is given, gdalwarp is executed
# 

if [ -z "${1}" ]; then
    echo -e "Error: No input rasterfile given.\n> USAGE: ./crosses_dateline.sh infile [outfile]"
    exit
fi

# Get information, save it to variable as we need it several times
gdalinfo=$(gdalinfo "${1}")
# Read Source CRS
s_srs="EPSG:"$(echo "${gdalinfo}" | grep -Eo "^\s{4}AUTHORITY\[.*\]" | grep -Eo "[0-9]+")

# Transform corners to Target SRS and test if crossing dateline
t_srs="EPSG:4326"
crossing_dateline=false

if [ "${s_srs}" == "${t_srs}" ]; then
    xmin=$(echo "${gdalinfo}" | grep "Upper Left" | grep -Eo "[-0-9\.]+, +[-0-9\.]+" | grep -Eo "^[-0-9\.]*")
    xmax=$(echo "${gdalinfo}" | grep "Lower Right" | grep -Eo "[-0-9\.]+, +[-0-9\.]+" | grep -Eo "^[-0-9\.]*")
    test $(echo "(${xmax}-(${xmin})) / 1" | bc) -gt 180 && crossing_dateline=true
else
    # We need to check both diagonal lines for intersection with the dateline
    xmin=$(echo "${gdalinfo}" | grep "Upper Left" | grep -Eo "[-0-9\.]+, +[-0-9\.]+" | gdaltransform -s_srs "${s_srs}" -t_srs "${t_srs}" -output_xy | grep -Eo "^[-0-9\.]*")
    xmax=$(echo "${gdalinfo}" | grep "Lower Right" | grep -Eo "[-0-9\.]+, +[-0-9\.]+" | gdaltransform -s_srs "${s_srs}" -t_srs "${t_srs}" -output_xy | grep -Eo "^[-0-9\.]*")
    test $(echo "${xmin}>${xmax}" | bc) -eq 1 && crossing_dateline=true

    xmin=$(echo "${gdalinfo}" | grep "Lower Left" | grep -Eo "[-0-9\.]+, +[-0-9\.]+" | gdaltransform -s_srs "${s_srs}" -t_srs "${t_srs}" -output_xy | grep -Eo "^[-0-9\.]*")
    xmax=$(echo "${gdalinfo}" | grep "Upper Right" | grep -Eo "[-0-9\.]+, +[-0-9\.]+" | gdaltransform -s_srs "${s_srs}" -t_srs "${t_srs}" -output_xy | grep -Eo "^[-0-9\.]*")
    test $(echo "${xmin}>${xmax}" | bc) -eq 1 && crossing_dateline=true
fi


if [ -z "$2" ]; then
    echo "${crossing_dateline}"
elif [ "${crossing_dateline}" == "true" ]; then
    gdalwarp -t_srs "${t_srs}" --config CENTER_LONG 180 "${1}" "${2}"
else
    gdalwarp -t_srs "${t_srs}" "${1}" "${2}"
fi

-1

นี่เป็นปัญหาในห้องสมุด GDAL ดูเหมือนว่า GDALSuggestedWarpOutput () กำลังให้เอาต์พุตแปลก ๆ สำหรับความกว้างและความสูงของไฟล์เอาต์พุต

ฉันยังไม่พบวิธีแก้ไขปัญหานี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.