पायथन / गदल का उपयोग करके एक्स-अक्ष पर रेखापुंज डेटा सरणी आउटपुट फ़्लिप किया गया?


9

मैं अजगर गल्ड पुस्तकालयों का उपयोग करके एक रेखापुंज बनाने की कोशिश कर रहा हूं और मैं उस बिंदु पर पहुंच गया हूं जहां डेटा आउटपुट हो रहा है, लेकिन आउटपुट डेटा मूल बिंदु के एक्स-एक्सिस पर फ़्लिप किया गया है। मुझे पता है कि मुझे कुछ अनदेखी करनी चाहिए, लेकिन मैं यह पता नहीं लगा सकता कि मैं गलत कहाँ जा रहा हूँ। कोई विचार?

रस्टर बनाते समय मैंने ऊपरी-बाएँ 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 में देखा जाता है , तो डेटा मूल रूप से ऊपरी-बाएँ मूल बिंदु के साथ विपरीत दिशा में जाता है, जो निचले-बाएँ मान के रूप में प्रदर्शित होता है ।

दूसरे शब्दों में, डेटा मूल बिंदु के एक्स-एक्सिस पर फ़्लिप होता है।

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

मैंने यह भी देखा है कि जब मैं किसी दिए गए lat / lon के लिए पिक्सेल स्थिति की गणना करता है तो 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

मुझे समस्या मिल गई…।

समस्या जियो_ट्रांसफॉर्म को परिभाषित करने में है। मेरे पास निम्नलिखित थे:

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)

गदल प्रलेखन इन मूल्यों के बारे में स्पष्ट नहीं है। ( SetGeoTransform देखें ) मेरे द्वारा प्राप्त किए गए इंटर्नेट के आसपास खोज करना कि पारित मूल्य (क्रम में) होना चाहिए:

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

जो सही लगता है, लेकिन GDAL API ट्यूटोरियल मैंने फिर से समीक्षा की कि मैंने देखा कि अंतिम मूल्य, cell_height_metersएक नकारात्मक मूल्य में दिखाया जा रहा था । ऐसा लगता है कि अपेक्षित अभिविन्यास में डेटा को ठीक से आउटपुट करने के लिए यह सब आवश्यक था।

इसलिए अब मैंने जियो_ट्रांसफॉर्म परिभाषा लाइन को इसमें बदल दिया है:

(नोटिस "-" जोड़ा गया)

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

यह शीर्ष बाईं ओर की उत्पत्ति और निचले बाएँ का उपयोग करने के भूगोल के तरीके की तरह छवि दुनिया से निपटने का पारंपरिक तरीका है।
इयान Turton

यह समझ में आता है एक बार जब आप जानते हैं, लेकिन कोड उदाहरणों से समस्या का दृष्टिकोण करना तर्क को चुनना मुश्किल है। मैंने पाया है कि आर्कगिस के
monkut
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.