Bagaimana cara menghentikan gdalwarp membuat output yang menjangkau dunia dekat dateline?

11

Saya menggunakan gdalwarp untuk memanipulasi ubin SRTM dekat dateline (yaitu 180 °, alias antimeridian). Ubin SRTM memiliki sedikit (1/2 piksel) tumpang tindih dengan meridian. Anda dapat melihat ini menggunakan 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)
[...]

Jadi sumber tersebut merentang dateline dengan jumlah kecil.

Ini menyebabkan masalah dengan gdalwarp, yang pada akhirnya menciptakan keluaran globe-spanning besar.

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)

Perhatikan rentang garis bujur (hampir) seluruh bola dunia, dan juga jumlah garis sangat kecil (5)

Apakah ini bug di gdalwarp? Jika tidak, apa saja pilihan yang benar untuk dilewatkan ke gdalwarp untuk mendapatkan hasil yang masuk akal?

badai gravitasi
sumber
dds.cr.usgs.gov/srtm/version2_1/SRTM3/Australia/S16W180.hgt.zip jika Anda ingin bereksperimen.
gravitystorm
tambahkan Parameter SOURCE_EXTRA lihat code.google.com/p/maptiler/issues/detail?id=6 - coba gdalwarp -t_srs epsg: 900913 -dua SOURCE_EXTRA = 120 S16W180.hgt test.tif
Mapperz
mungkin menggunakan argumen -te untuk "target extents", atau memperbaiki luasan pertama menggunakan gdal_translate dengan a_ullr untuk menimpa yang sudah ada, atau -projwin untuk memotong bit yang Anda inginkan dalam batasan
mdsumner

Jawaban:

2

Salah satu solusi yang mudah adalah dengan menentukan sistem koordinat "secara manual" sebagai string PROJ. Ini memungkinkan Anda menggunakan +oversakelar yang menonaktifkan pembungkus 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

Ketika saya melakukan itu dan kemudian melakukan gdalinfohasilnya, saya mendapatkan ini:

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)

Saya mendapatkan string PROJ (tanpa +over) dari melihat output asli gdalinfo. Itu dimasukkan dalam EXTENSION[...]blok sistem koordinat.

csd
sumber
1

Ini bekerja dalam dua langkah:

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

Perintah pertama memulai setengah piksel tambahan di sisi 180 ° meridian yang salah. Anda mendapatkan file output yaitu 1178P x 1222L.

Atau, dengan gdal_translate:

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

Membuat file output yang 1179P x 1223L.

AndreJ
sumber
1

Ketika saya menghadapi masalah yang sama, saya menulis skrip shell kecil yang mencari tahu apakah file raster melintasi dateline. Jika benar, opsi berikut ditambahkan ke gdalwarp:

--config CENTER_LONG 180

Beginilah cara skrip bekerja langkah demi langkah:

  1. Dapatkan WGS84 Extents dari gdalinfo
  2. Jika berubah ULX dan LRX OR llx dan URX nilai-nilai yang membalik dibandingkan dengan CRS asli, raster diubah akan menyeberangi batas waktu tersebut.
  3. Jika dateline akan dilintasi, --config CENTER_LONG 180 ditambahkan ke gdalwarp.

MEMPERBARUI Versi naskah yang lebih baik, membutuhkan GDAL 2.0+ dan Python: Versi lama di bawah ini.

#!/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
pLumo
sumber
-1

Ini masalah di perpustakaan GDAL. Tampaknya GDALSuggestedWarpOutput () memberikan output aneh untuk lebar dan tinggi file output.

Saya belum menemukan cara untuk mengatasi ini.

Kode Man Vs
sumber