python / gdal을 사용하여 x 축에서 래스터 데이터 배열 출력을 뒤집 었습니까?


9

파이썬 gdal 라이브러리를 사용하여 래스터를 만들려고하는데 데이터가 출력되는 지점에 도달했지만 출력 데이터는 원점 의 x 축 에서 뒤집 힙니다 . 나는 무언가를 간과해야한다는 것을 알고 있지만, 내가 어디로 잘못 가고 있는지 파악할 수 없습니다. 어떤 아이디어?

래스터를 만들 때 왼쪽 상단 x / y 값을 설정하면 배열이 왼쪽 상단에서 색인화되어 오른쪽 하단으로 계속 표시됩니다. 아래 코드에서는 배열 값을 행 값으로 채우고 있습니다.

배열을 출력 할 때 다음과 같이 보입니다 :

[[  1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.
    1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.
    1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.   1.
    1.   1.   1.   1.   1.   1.]
 [  2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.
    2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.
    2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.   2.
    2.   2.   2.   2.   2.   2.]
 [  3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.
    3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.
    3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.   3.
    3.   3.   3.   3.   3.   3.]
 [  4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.
    4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.
    4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.   4.
    4.   4.   4.   4.   4.   4.]
...

그리고이 데이터는 래스터 밴드에 성공적으로 기록됩니다. 그러나 MapWindow GIS 에서 볼 때 데이터는 원래 왼쪽 상단 원점 과 반대 방향으로 이동하여 왼쪽 하단 값 으로 나타납니다 .

다시 말해, 데이터는 원점 의 x 축 에서 뒤집 힙니다 .

import gdal
import osr
import numpy

OUTPUT_FORMAT = "GTiff"
def create_raster(filename="test.tif"):
    driver = gdal.GetDriverByName(OUTPUT_FORMAT)
    band_type = gdal.GDT_Byte
    number_of_bands = 1

    x_rotation = 0 # not supported
    y_rotation = 0 # not supported
    cell_width_meters = 50
    cell_height_meters = 50

    (min_lon, min_lat, max_lon, max_lat) = _get_point_bounds() # retrieve bounds for point data        
    srs = osr.SpatialReference()
    srs.SetWellKnownGeogCS("WGS84") # Set geographic coordinate system to handle lat/lon        
    srs.SetUTM( 54, True) # Set projected coordinate system  to handle meters        

    # create transforms for point conversion
    wgs84_coordinate_system = srs.CloneGeogCS() # clone only the geographic coordinate system
    wgs84_to_utm_transform = osr.CoordinateTransformation(wgs84_coordinate_system, srs)

    # convert to UTM
    top_left_x, top_left_y, z = wgs84_to_utm_transform.TransformPoint(min_lon, max_lat, 0)     
    lower_right_x, lower_right_y, z = wgs84_to_utm_transform.TransformPoint(max_lon, min_lat, 0) 

    cols, rows = _get_raster_size(top_left_x, lower_right_y, lower_right_x, top_left_y, cell_width_meters, cell_height_meters)
    dataset = driver.Create(filename, cols, rows, number_of_bands, band_type) #

    # GeoTransform parameters
    # --> need to know the area that will be covered to define the geo tranform
    # top left x, w-e pixel resolution, rotation, top left y, rotation, n-s pixel resolution
    geo_transform = [ top_left_x, cell_width_meters, x_rotation, top_left_y, y_rotation, cell_height_meters ]
    dataset.SetGeoTransform(geo_transform)
    dataset.SetProjection(srs.ExportToWkt())

    dataset_band = dataset.GetRasterBand(1)
    data = dataset_band.ReadAsArray(0, 0, cols, rows).astype(numpy.float32) # returns empty array 

    for row in xrange(rows):
        for col in xrange(cols):
            data[row][ col] = row + 1

    dataset_band.WriteArray(data, 0, 0)
    dataset_band.SetNoDataValue(0.0)
    dataset_band.FlushCache()
    dataset = None # Close file

I가, 화소 위치를 계산할 때, I는 발견 한 특정 위도 / 경도 y 값의 정렬의 정확한 배열에서 것을 고려 같다 네거티브 지수 결과 상단 왼쪽 하는 하향 - 권리 .

inverse_geo_transform = gdal.InvGeoTransform(self.geo_transform)[1] # for mapping lat/lon to pixel
pixel_x, pixel_y = gdal.ApplyGeoTransform(self.inverse_geo_transform, utm_x, utm_y)

답변:


10

나는 문제를 발견했다.…

문제는 geo_transform을 정의하는 데 있습니다. 나는 다음을 가졌다 :

x_rotation = 0 
y_rotation = 0 
cell_width_meters = 50
cell_height_meters = 50

geo_transform = [ top_left_x, cell_width_meters, x_rotation, top_left_y, y_rotation, cell_height_meters ]
dataset.SetGeoTransform(geo_transform)

Gdal 문서는 이러한 값이 무엇인지 명확하지 않습니다. ( SetGeoTransform 참조 ) 전달 된 값이 (순서대로) 인터넷에서 검색했습니다.

  • top_left_x
  • cell_width_meters
  • x_rotation
  • top_left_y
  • y_rotation
  • cell_height_meters

어느 것이 올바른 것 같다, 하지만 다시 재조사 GDAL API 튜토리얼 나는 마지막 값, 눈치 cell_height_metersA의 주어지고 보였다 음의 값입니다. 이것은 예상 된 방향으로 데이터를 올바르게 출력하는 데 필요한 모든 것 같습니다.

이제 geo_transform 정의 행을 다음 과 같이 변경 했습니다.

(추가 된 "-"에 유의하십시오)

geo_transform = [ top_left_x, cell_width_meters, x_rotation, top_left_y, y_rotation, -cell_height_meters ]

이것은 왼쪽 상단의 원점과 같은 이미지 세계를 처리하는 전통적인 방법이며 왼쪽 하단을 사용하는 지리의 방법입니다.
Ian Turton

일단 알면 이해가되지만 코드 예제에서 문제에 접근하면 추론하기가 어렵습니다. ArcGIS 문서에는 래스터에 대한 설명이 포함되어 있습니다. webhelp.esri.com/arcgisdesktop/9.3/…
monkut
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.