फ़ाइल को रेखापुंज करने के लिए संख्यात्मक सरणी लिखना


30

मैं जीआईएस के लिए नया हूं।

मेरे पास कुछ कोड हैं जो मंगल की अवरक्त छवियों को थर्मल जड़त्वीय मानचित्रों में परिवर्तित करते हैं, जो बाद में 2 डी के रूप में संग्रहीत होते हैं। मैं इन मानचित्रों को hdf5 फ़ाइलों के रूप में सहेज रहा हूं, लेकिन मैं वास्तव में उन्हें रेखापुंज चित्रों के रूप में सहेजना चाहूंगा ताकि मैं उन्हें QGIS में संसाधित कर सकूं। मैं यह करने के लिए कई खोजों के माध्यम से गया हूं कि यह कैसे करना है लेकिन कोई भाग्य के साथ नहीं। मैंने http://www.gis.usu.edu/~chrisg/python/ पर ट्यूटोरियल के निर्देशों का पालन करने की कोशिश की है, लेकिन जब मैं उनके उदाहरण कोड का उपयोग करके फाइल तैयार करता हूं, तो मैं उन्हें क्यूजीआईएस में आयात करता हूं। मुझे ऐसा लगता है कि अगर कोई व्यक्ति जो मैं करना चाहता हूं उसके एक सरल उदाहरण के लिए सबसे सरल संभव प्रक्रिया का सुझाव दे सकता हूं तो मैं कुछ प्रगति करने में सक्षम हो सकता हूं। मेरे पास क्यूजीआईएस और जीडीएएल है, मैं अन्य फ्रेमवर्क स्थापित करने में बहुत खुश हूं जो किसी की भी सिफारिश कर सकते हैं। मैं मैक ओएस 10.7 का उपयोग करता हूं।

इसलिए अगर उदाहरण के लिए मेरे पास थर्मल जड़ता का एक बहुत बड़ा सरणी है जो दिखता है:

TI = ( (0.1, 0.2, 0.3, 0.4),
       (0.2, 0.3, 0.4, 0.5),
       (0.3, 0.4, 0.5, 0.6),
       (0.4, 0.5, 0.6, 0.7) )

और प्रत्येक पिक्सेल के लिए मेरे पास अक्षांश और देशांतर है:

lat = ( (10.0, 10.0, 10.0, 10.0),
        ( 9.5,  9.5,  9.5,  9.5),
        ( 9.0,  9.0,  9.0,  9.0),
        ( 8.5,  8.5,  8.5,  8.5) )
lon = ( (20.0, 20.5, 21.0, 21.5),
        (20.0, 20.5, 21.0, 21.5),
        (20.0, 20.5, 21.0, 21.5),
        (20.0, 20.5, 21.0, 21.5) ) 

लोग इस डेटा को एक रेखापुंज फ़ाइल में बदलने की सलाह देंगे, जिसे मैं QGIS में खोल सकता हूं?


आप किस ट्यूटोरियल की बात कर रहे हैं?
आरके

जवाबों:


23

आपकी समस्या का एक संभावित समाधान: इसे ASCII रेखापुंज में परिवर्तित करें , जिसके लिए दस्तावेज़ीकरण यहाँ है । यह अजगर के साथ करने के लिए काफी आसान होना चाहिए।

तो ऊपर दिए गए आपके उदाहरण डेटा के साथ, आप निम्नलिखित .asc फ़ाइल के साथ समाप्त करेंगे:

ncols 4
nrows 4
xllcorner 20
yllcorner 8.5
cellsize 0.5
nodata_value -9999
0.1 0.2 0.3 0.4
0.2 0.3 0.4 0.5
0.3 0.4 0.5 0.6
0.4 0.5 0.6 0.7

यह सफलतापूर्वक QGIS और ArcGIS दोनों को जोड़ता है, और ArcGIS में शैलीबद्ध है यह इस तरह दिखता है: ऊपर का रेखापुंज संस्करण

परिशिष्ट: जब आप इसे QGIS में जोड़ सकते हैं, जैसा कि आप कोशिश करते हैं, यदि आप इसके लिए गुणों में जाते हैं (इसे स्टाइल करने के लिए), QGIS 1.8.0 हैंग हो जाता है। मैं एक बग के रूप में रिपोर्ट करने वाला हूं। अगर आपके साथ भी ऐसा होता है, तो जीआईएस के बहुत सारे विकल्प मौजूद हैं।


यह शानदार है, धन्यवाद। और मुझे लगता है कि एक एसेसी फाइल के रूप में मेरे एरे को लिखने के बाद मैं इसे पूर्व-लिखित रूपांतरण फ़ंक्शन का उपयोग करके बाइनरी प्रारूप में बदल सकता हूं।
एडी। बी

FYI करें, QGIS के साथ मेरे पास फांसी का मुद्दा नहीं था, मेरे पास संस्करण 1.8.0 भी है।
EddyTheB

31

नीचे एक उदाहरण है जो मैंने एक कार्यशाला के लिए लिखा था जो कि खस्ता और गदल पायथन मॉड्यूल का उपयोग करता है। यह डेटा को एक .tif फ़ाइल से एक संख्यात्मक सरणी में पढ़ता है, सरणी में मानों की एक पुनरावृत्ति करता है और फिर इसे वापस .tif पर लिखता है।

आपके स्पष्टीकरण से, ऐसा लगता है कि आप एक मान्य फ़ाइल लिखने में सफल हो गए होंगे, लेकिन आपको बस इसे QGIS में प्रतीक बनाने की आवश्यकता है। यदि मुझे सही ढंग से याद है, जब आप पहली बार एक रेखापुंज जोड़ते हैं, तो यह अक्सर सभी एक रंग दिखाता है यदि आपके पास पहले से मौजूद रंग का नक्शा नहीं है।

import numpy, sys
from osgeo import gdal
from osgeo.gdalconst import *


# register all of the GDAL drivers
gdal.AllRegister()

# open the image
inDs = gdal.Open("c:/workshop/examples/raster_reclass/data/cropland_40.tif")
if inDs is None:
  print 'Could not open image file'
  sys.exit(1)

# read in the crop data and get info about it
band1 = inDs.GetRasterBand(1)
rows = inDs.RasterYSize
cols = inDs.RasterXSize

cropData = band1.ReadAsArray(0,0,cols,rows)

listAg = [1,5,6,22,23,24,41,42,28,37]
listNotAg = [111,195,141,181,121,122,190,62]

# create the output image
driver = inDs.GetDriver()
#print driver
outDs = driver.Create("c:/workshop/examples/raster_reclass/output/reclass_40.tif", cols, rows, 1, GDT_Int32)
if outDs is None:
    print 'Could not create reclass_40.tif'
    sys.exit(1)

outBand = outDs.GetRasterBand(1)
outData = numpy.zeros((rows,cols), numpy.int16)


for i in range(0, rows):
    for j in range(0, cols):

    if cropData[i,j] in listAg:
        outData[i,j] = 100
    elif cropData[i,j] in listNotAg:
        outData[i,j] = -100
    else:
        outData[i,j] = 0


# write the data
outBand.WriteArray(outData, 0, 0)

# flush data to disk, set the NoData value and calculate stats
outBand.FlushCache()
outBand.SetNoDataValue(-99)

# georeference the image and set the projection
outDs.SetGeoTransform(inDs.GetGeoTransform())
outDs.SetProjection(inDs.GetProjection())

del outData

1
+1 निस्तब्धता के लिए - दीवार के खिलाफ मेरे सिर को पीटने की कोशिश कर रहा था ताकि यह पता लगाया जा सके कि चीज़ को 'कैसे' बचाया जाए!
badgley

मुझे outDs = Noneइसे सहेजने के लिए जोड़ना पड़ा
JaakL

23

मैं आखिरकार इस समाधान पर हिट हूं, जिसे मैंने इस चर्चा ( http://osgeo-org.1560.n6.nabble.com/gdal-dev-numpy-array-to-raster-td4354924.html ) से प्राप्त किया है । मुझे यह पसंद है क्योंकि मैं एक संख्यात्मक सरणी से एक tif raster फ़ाइल में सीधे जा सकता हूं। मैं उन टिप्पणियों के लिए बहुत आभारी हूं जो समाधान पर सुधार कर सकते हैं। यदि कोई अन्य समान उत्तर खोजता है तो मैं इसे यहाँ पोस्ट करूँगा।

import numpy as np
from osgeo import gdal
from osgeo import gdal_array
from osgeo import osr
import matplotlib.pylab as plt

array = np.array(( (0.1, 0.2, 0.3, 0.4),
                   (0.2, 0.3, 0.4, 0.5),
                   (0.3, 0.4, 0.5, 0.6),
                   (0.4, 0.5, 0.6, 0.7),
                   (0.5, 0.6, 0.7, 0.8) ))
# My image array      
lat = np.array(( (10.0, 10.0, 10.0, 10.0),
                 ( 9.5,  9.5,  9.5,  9.5),
                 ( 9.0,  9.0,  9.0,  9.0),
                 ( 8.5,  8.5,  8.5,  8.5),
                 ( 8.0,  8.0,  8.0,  8.0) ))
lon = np.array(( (20.0, 20.5, 21.0, 21.5),
                 (20.0, 20.5, 21.0, 21.5),
                 (20.0, 20.5, 21.0, 21.5),
                 (20.0, 20.5, 21.0, 21.5),
                 (20.0, 20.5, 21.0, 21.5) ))
# For each pixel I know it's latitude and longitude.
# As you'll see below you only really need the coordinates of
# one corner, and the resolution of the file.

xmin,ymin,xmax,ymax = [lon.min(),lat.min(),lon.max(),lat.max()]
nrows,ncols = np.shape(array)
xres = (xmax-xmin)/float(ncols)
yres = (ymax-ymin)/float(nrows)
geotransform=(xmin,xres,0,ymax,0, -yres)   
# That's (top left x, w-e pixel resolution, rotation (0 if North is up), 
#         top left y, rotation (0 if North is up), n-s pixel resolution)
# I don't know why rotation is in twice???

output_raster = gdal.GetDriverByName('GTiff').Create('myraster.tif',ncols, nrows, 1 ,gdal.GDT_Float32)  # Open the file
output_raster.SetGeoTransform(geotransform)  # Specify its coordinates
srs = osr.SpatialReference()                 # Establish its coordinate encoding
srs.ImportFromEPSG(4326)                     # This one specifies WGS84 lat long.
                                             # Anyone know how to specify the 
                                             # IAU2000:49900 Mars encoding?
output_raster.SetProjection( srs.ExportToWkt() )   # Exports the coordinate system 
                                                   # to the file
output_raster.GetRasterBand(1).WriteArray(array)   # Writes my array to the raster

output_raster.FlushCache()

3
"रोटेशन दो बार में है" x पर y के घुमाए हुए बिट के प्रभाव और खाते पर x के घुमाए हुए बिट के प्रभाव के लिए। Lists.osgeo.org/pipermail/gdal-dev/2011-July/029449.html देखें जो "रोटेशन" मापदंडों के बीच अंतर्संबंधों को समझाने की कोशिश करता है।
डेव एक्स

यह पोस्ट वास्तव में उपयोगी है, धन्यवाद। मेरे मामले में, हालाँकि, मुझे एक tif फ़ाइल मिल रही है जो पूरी तरह से काली है जब मैं इसे ArcGIS के बाहर की छवि के रूप में खोलता हूं। मेरा स्थानिक संदर्भ ब्रिटिश राष्ट्रीय ग्रिड (EPSG = 27700) है, और इकाइयां मीटर हैं।
फ़ॉफ़ी

मैंने यहां एक प्रश्न पोस्ट किया है: gis.stackexchange.com/questions/232301/…
FaCfish

क्या आपको पता है कि IAU2000: 49900 मार्स एन्कोडिंग कैसे सेट करें?
के-माइकल ऐ

4

पायथन के लिए आधिकारिक GDAL / OGR कुकबुक में एक अच्छा समाधान भी है ।

यह नुस्खा एक सरणी से एक रेखापुंज बनाता है

import gdal, ogr, os, osr
import numpy as np


def array2raster(newRasterfn,rasterOrigin,pixelWidth,pixelHeight,array):

    cols = array.shape[1]
    rows = array.shape[0]
    originX = rasterOrigin[0]
    originY = rasterOrigin[1]

    driver = gdal.GetDriverByName('GTiff')
    outRaster = driver.Create(newRasterfn, cols, rows, 1, gdal.GDT_Byte)
    outRaster.SetGeoTransform((originX, pixelWidth, 0, originY, 0, pixelHeight))
    outband = outRaster.GetRasterBand(1)
    outband.WriteArray(array)
    outRasterSRS = osr.SpatialReference()
    outRasterSRS.ImportFromEPSG(4326)
    outRaster.SetProjection(outRasterSRS.ExportToWkt())
    outband.FlushCache()


def main(newRasterfn,rasterOrigin,pixelWidth,pixelHeight,array):
    reversed_arr = array[::-1] # reverse array so the tif looks like the array
    array2raster(newRasterfn,rasterOrigin,pixelWidth,pixelHeight,reversed_arr) # convert array to raster


if __name__ == "__main__":
    rasterOrigin = (-123.25745,45.43013)
    pixelWidth = 10
    pixelHeight = 10
    newRasterfn = 'test.tif'
    array = np.array([[ 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, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1],
                      [ 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1],
                      [ 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1],
                      [ 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1],
                      [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])


    main(newRasterfn,rasterOrigin,pixelWidth,pixelHeight,array)

यह नुस्खा अच्छा है लेकिन अंतिम टिफ़ फ़ाइल के साथ एक समस्या है। पिक्सल के लेट-लोन मान उचित नहीं हैं।
शुभम_गो


मेरे द्वारा सामना की गई एक बात, आपके द्वारा बताए गए तरीके से निश्चित रूप से सरणी को आसानी से बदल दिया जाएगा। लेकिन हमें इस रेखापुंज को gdal_translate के उपयोग से ऊपर बाएँ और नीचे दाएँ दाएँ समन्वित करने की आवश्यकता है। ऐसा करने का एक तरीका दो चरणों का पालन कर रहा है: 1) पहले गेलडिनफो के माध्यम से शीर्ष-बाएँ और नीचे दाएँ दाएँ-चपटे मानों को खोजें) 2, फिर, gdal_translate के माध्यम से जियोटीफ़ का उपयोग करें (रेखापुंज के लिए सरणी बदलने के उपर्युक्त दृष्टिकोण के साथ) इसे ऊपर-बाएँ और नीचे दाएं लेट-लोन कोऑर्डिनेट करने के लिए इसे जियोरेफेरेंस करें।
शुभम्_गेओ

0

अन्य उत्तरों में सुझाए गए दृष्टिकोण का एक विकल्प rasterioपैकेज का उपयोग करना है। मेरे पास इनका उपयोग करने वाले मुद्दे थे gdalऔर इस साइट को उपयोगी पाया गया ।

मान लें कि आपके पास एक और tif फ़ाइल ( other_file.tif) और एक numpy अरै ( numpy_array) है जिसमें इस फ़ाइल के समान रिज़ॉल्यूशन और सीमा है, यह वह दृष्टिकोण है जो मेरे लिए काम किया है:

import rasterio as rio    

with rio.open('other_file.tif') as src:
    ras_data = src.read()
    ras_meta = src.profile

# make any necessary changes to raster properties, e.g.:
ras_meta['dtype'] = "int32"
ras_meta['nodata'] = -99

with rio.open('outname.tif', 'w', **ras_meta) as dst:
    dst.write(numpy_array, 1)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.