Làm thế nào để ngăn gdalwarp tạo đầu ra trên toàn thế giới gần đường thời gian?


11

Tôi đang sử dụng gdalwarp để thao tác các gạch SRTM gần đường dữ liệu (tức là 180 °, còn gọi là phản tuyến). Gạch SRTM có sự chồng chéo rất nhẹ (1/2 pixel) với kinh tuyến. Bạn có thể thấy điều này bằng cách sử dụng 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)
[...]

Vì vậy, nguồn kéo dài dòng thời gian bằng một lượng nhỏ.

Điều này gây ra vấn đề với gdalwarp, cuối cùng tạo ra sản lượng lớn trên toàn cầu.

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)

Lưu ý khoảng cách kinh độ (gần như) toàn bộ địa cầu và số lượng đường nhỏ bất ngờ (5)

Đây có phải là một lỗi trong gdalwarp? Nếu không, các tùy chọn chính xác để chuyển đến gdalwarp để có được một đầu ra hợp lý là gì?



thêm SOURCE_EXTRA Parameter thấy code.google.com/p/maptiler/issues/detail?id=6 - thử gdalwarp -t_srs EPSG: 900.913 -wo SOURCE_EXTRA = 120 S16W180.hgt test.tif
Mapperz

có thể sử dụng đối số -te cho "phạm vi mục tiêu" hoặc sửa lỗi phạm vi trước bằng cách sử dụng gdal_translate với a_ullr để ghi đè lên hiện tại hoặc -projwin để cắt bỏ bit bạn muốn trong giới hạn
mdsumner

Câu trả lời:


2

Một cách giải quyết dễ dàng là chỉ định hệ tọa độ "thủ công" là chuỗi PROJ. Điều này cho phép bạn sử dụng công +overtắc vô hiệu hóa gói trên 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

Khi tôi làm điều đó và sau đó làm gdalinfokết quả, tôi nhận được điều này:

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)

Tôi đã nhận được chuỗi PROJ (không có +over) khi nhìn vào đầu ra ban đầu của gdalinfo. Nó được bao gồm trong một EXTENSION[...]khối của hệ tọa độ.


1

Nó hoạt động theo hai bước:

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

Lệnh đầu tiên khởi động nửa pixel phụ ở phía bên trái của kinh tuyến 180 °. Bạn nhận được một tập tin đầu ra là 1178P x 1222L.

Ngoài ra, với gdal_translate:

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

Tạo một tệp đầu ra là 1179P x 1223L.


1

Khi tôi đang đối mặt với cùng một vấn đề, tôi đã viết một kịch bản shell nhỏ để tìm hiểu xem tệp raster có vượt qua đường dữ liệu hay không. Nếu đúng, tùy chọn sau được thêm vào gdalwarp:

--config CENTER_LONG 180

Đây là cách kịch bản hoạt động từng bước:

  1. Nhận mức độ WGS84 từ gdalinfo
  2. Nếu chuyển ULXLRX HOẶC LLXurx giá trị này được lật so với CRS gốc, raster chuyển sẽ vượt qua múi giờ.
  3. Nếu đường dữ liệu sẽ bị vượt qua, --config CENTER_LONG 180 được thêm vào gdalwarp.

CẬP NHẬT Phiên bản tốt hơn của tập lệnh, yêu cầu GDAL 2.0+ và Python: Phiên bản cũ bên dưới.

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

Đây là vấn đề trong thư viện GDAL. Dường như GDALSuggestedWarpOutput () đang đưa ra đầu ra kỳ lạ cho chiều rộng và chiều cao của tệp đầu ra.

Tôi chưa tìm ra cách nào để giải quyết vấn đề này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.