Wie kann man verhindern, dass gdalwarp weltumspannende Ausgaben in der Nähe der Datenlinie erstellt?


11

Ich verwende gdalwarp, um SRTM-Kacheln in der Nähe der Datenlinie zu manipulieren (dh 180 °, auch bekannt als Antimeridian). SRTM-Kacheln haben eine sehr geringe Überlappung (1/2 Pixel) mit dem Meridian. Sie können dies mit gdalinfo sehen:

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

Die Quelle überspannt also die Datenlinie um einen winzigen Betrag.

Dies führt zu Problemen mit gdalwarp, was zu riesigen, weltumspannenden Ausgaben führt.

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)

Beachten Sie, dass sich die Längengrade (fast) über den gesamten Globus erstrecken und auch die Anzahl der Linien unerwartet gering ist (5).

Ist das ein Fehler in Gdalwarp? Wenn nicht, welche Optionen müssen an gdalwarp übergeben werden, um eine sinnvolle Ausgabe zu erhalten?



Fügen Sie den Parameter SOURCE_EXTRA hinzu, siehe code.google.com/p/maptiler/issues/detail?id=6 - versuchen Sie es mit gdalwarp -t_srs epsg: 900913 -wo SOURCE_EXTRA = 120 S16W180.hgt test.tif
Mapperz

Verwenden Sie möglicherweise das Argument -te für "Ziel-Extents" oder korrigieren Sie die Extents zuerst mit gdal_translate mit a_ullr, um das vorhandene Bit zu überschreiben, oder -projwin, um das gewünschte Bit innerhalb der Grenzen
auszuschneiden

Antworten:


2

Eine einfache Problemumgehung wäre, das Koordinatensystem "manuell" als PROJ-Zeichenfolge anzugeben. Auf diese Weise können Sie den +overSchalter verwenden, der das Umschließen des Antimeridians deaktiviert:

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

Wenn ich das mache und dann gdalinfodas Ergebnis mache , bekomme ich folgendes:

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)

Ich habe die PROJ-Zeichenfolge (ohne +over) erhalten, indem ich mir die ursprüngliche Ausgabe von angesehen habe gdalinfo. Es wurde in einen EXTENSION[...]Block des Koordinatensystems aufgenommen.


1

Es funktioniert in zwei Schritten:

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

Der erste Befehl startet das zusätzliche halbe Pixel auf der falschen Seite des 180 ° -Meridians. Sie erhalten eine Ausgabedatei mit der Größe 1178P x 1222L.

Alternativ mit gdal_translate:

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

Erstellen einer Ausgabedatei mit der Größe 1179P x 1223L.


1

Da ich vor dem gleichen Problem stand, schrieb ich ein kleines Shell-Skript, das herausfindet, ob die Rasterdatei die Datenlinie überschreitet. Wenn true, wird die folgende Option zu gdalwarp hinzugefügt:

--config CENTER_LONG 180

So funktioniert das Skript Schritt für Schritt:

  1. Holen Sie sich WGS84 Extents von gdalinfo
  2. Wenn die transformierten Werte für ulx und lrx OR llx und urx im Vergleich zum ursprünglichen CRS umgedreht werden, überschreitet das transformierte Raster die Datenlinie.
  3. Wenn die Datumsgrenze überschritten wird, wird --config CENTER_LONG 180 zu gdalwarp hinzugefügt.

UPDATE Bessere Version des Skripts, erfordert GDAL 2.0+ und Python: Alte Version unten.

#!/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

Dies ist ein Problem in der GDAL-Bibliothek. Es scheint, dass GDALSuggestedWarpOutput () eine seltsame Ausgabe für die Breite und Höhe der Ausgabedatei liefert.

Ich habe noch keinen Weg gefunden, dies zu umgehen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.