Gdalwarp'ı dateline yakınında dünyaya yayılan çıktılar oluşturmayı nasıl durdurabilirim?


11

Ben dateline yakınındaki SRTM fayans manipüle etmek için gdalwarp kullanıyorum (yani 180 °, yani antimeridian). SRTM karolarının meridyenle çok hafif (1/2 piksel) çakışması vardır. Bunu gdalinfo kullanarak görebilirsiniz:

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)
[...]

Böylece kaynak datelini küçük bir miktarda yayıyor.

Bu, gdalwarp ile ilgili sorunlara neden olur ve bu da dünya çapında büyük çıktılar oluşturur.

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)

Boylamların (neredeyse) tüm dünyayı kapsadığını ve ayrıca satır sayısının beklenmedik şekilde az olduğunu unutmayın (5)

Bu gdalwarp bir hata mı? Değilse, mantıklı bir çıktı almak için gdalwarp'a geçmek için doğru seçenekler nelerdir?



SOURCE_EXTRA Parametresini ekleyin code.google.com/p/maptiler/issues/detail?id=6 adresini ziyaret edin - gdalwarp -t_srs epsg: 900913 -wo SOURCE_EXTRA = 120 S16W180.hgt test.tif'yi deneyin
Mapperz

"hedef uzantılar" için -te argümanını kullanabilir veya varolanların üzerine yazmak için önce gdal_translate ile a_ullr kullanarak uzantıları düzeltebilir veya sınırlar içinde istediğiniz biti kesmek için -projwin'i kullanabilirsiniz
mdsumner

Yanıtlar:


2

Kolay bir çözüm, koordinat sistemini "manuel olarak" PROJ dizesi olarak belirtmektir. Bu +over, antimeridianın sarılmasını devre dışı bırakan anahtarı kullanmanıza izin verir :

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

Bunu yapmak ve sonra gdalinfosonuç yapmak , bunu elde:

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 dize (olmadan +over) orijinal çıktı bakmak aldım gdalinfo. EXTENSION[...]Koordinat sisteminin bir bloğuna dahil edildi .


1

İki adımda çalışır:

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

İlk komut 180 ° meridyenin yanlış tarafındaki fazladan yarım pikseli başlatır. 1178P x 1222L olan bir çıktı dosyası alırsınız.

Alternatif olarak, gdal_translate ile:

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

1179P x 1223L olan bir çıktı dosyası oluşturma.


1

Aynı sorunla karşı karşıya olduğum için, raster dosyasının datelini geçip geçmediğini öğrenen küçük bir kabuk komut dosyası yazdım. True olursa, gdalwarp'e aşağıdaki seçenek eklenir:

--config CENTER_LONG 180

Komut dosyası adım adım şu şekilde çalışır:

  1. Gdalinfo'dan WGS84 Uzantıları Alın
  2. Eğer dönüştürülmüş ULX ve LRX VEYA llx ve URX değerleri orijinal CRS kıyasla çevrilmiş edilir dönüştürülmüş raster dateline geçecek.
  3. Eğer datelin geçilecekse, gdalwarp'e --config CENTER_LONG 180 eklenir.

Betiğin UPDATE Daha İyi Sürümü için aşağıdaki GDAL 2.0+ ve Python: Eski sürüm gereklidir.

#!/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 kütüphanesinde bu sorun var. GDALSuggestedWarpOutput () yöntemi, çıktı dosyasının genişliği ve yüksekliği için garip çıktılar veriyor gibi görünüyor.

Bu sorunu çözmek için henüz bir yol bulamadım.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.