पायथन का उपयोग कर एक रेखापुंज में प्रत्येक पिक्सेल के XY निर्देशांक और सेल मान कैसे प्राप्त करें?


16

मैं वास्तव में पायथन के लिए नया हूं और मैं जानना चाहूंगा कि क्या पिक्सेल में एक रास्टर पिक्सेल के सेल वैल्यू प्राप्त करने की एक त्वरित विधि है और ArcGIS 10 में पायथन का उपयोग करके निर्देशांक (प्रत्येक पिक्सेल के केंद्र के XY समन्वय का नक्शा) है?

इसके आगे वर्णन करने के लिए, मुझे पहले पिक्सेल का मैप X, मैप Y और सेल वैल्यू प्राप्त करने की आवश्यकता है और उन तीन वैल्यू को तीन वेरिएबल्स में असाइन करना है और बाकी के अन्य पिक्सल (पूरे रैस्टर के माध्यम से लूप) के लिए इस चरण को दोहराना है।


मुझे लगता है कि मुझे अपने प्रश्न का अधिक वर्णन करने की आवश्यकता है। समस्या यह है, मुझे पहले रैस्टर के एक पिक्सेल का XY स्थान प्राप्त करने और उस XY स्थान के अनुरूप कई अन्य चूहों के सेल मान प्राप्त करने की आवश्यकता है। इस प्रक्रिया को बिना किसी मध्यवर्ती बिंदु आकार के बनाए हुए पहले रेखापुंज के प्रत्येक पिक्सेल के माध्यम से लूप किया जाना चाहिए क्योंकि यह वास्तव में वास्तव में समय लेने वाला है क्योंकि मुझे लगभग 8 बिलियन पिक्सेल के साथ रेखापुंज करना है। इसके अलावा, मुझे ArcGIS 10 में पायथन का उपयोग करके ऐसा करने की आवश्यकता है।

@ जेम्स: आपके सुझाव के लिए बहुत बहुत धन्यवाद। हाँ, यह एक रेखापुंज के लिए काम करेगा लेकिन मुझे कई अन्य चूहों के लिए भी सेल वैल्यू एकत्र करने की आवश्यकता है। समस्या यह है कि पहले रैस्टर के पहले पिक्सेल के एक्स और वाई कोऑर्डिनेट करने के बाद, मुझे उस एक्स के वाई, जबकि पहले रैस्टर की लोकेशन, उसके बाद तीसरे रैस्टर और इसी तरह दूसरे रैस्टर की सेल वैल्यू मिलनी चाहिए। इसलिए, मुझे लगता है कि पहले रैस्टर के माध्यम से लूपिंग करते समय, एक पिक्सेल का एक्स और वाई स्थान प्राप्त करना और उस स्थान के अनुरूप अन्य रेखापुंज के सेल मान प्राप्त करना एक साथ किया जाना चाहिए, लेकिन मुझे यकीन नहीं है। यह पहले रैस्टर को एक पॉइंट शेपफाइल में कनवर्ट करके और आर्कजीआईएस 10 में प्वाइंट फंक्शन के लिए एक्सट्रैक्ट मल्टीवल्यूस को प्रदर्शन करके किया जा सकता है लेकिन मैं '

@ धन्यवाद: धन्यवाद, हां यह विधि (रैस्टेनपम्पायरैरे) काम करेगी अगर मुझे किसी ज्ञात पंक्ति और सरणी के स्तंभ मान का समन्वय मिल सकता है।

@ व्यक्ति: मैं कोई गणना नहीं करना चाहता, मुझे केवल एक पाठ फ़ाइल में XY निर्देशांक और सेल मान लिखना है और वह सब है


शायद आप पूरे रैस्टर पर कुछ गणित करना चाहते हैं? रेखापुंज कैलकुलेटर पिक्सेल द्वारा पिक्सेल का काम करते हैं।
बाविल

1
कृपया अपने उद्देश्य का अधिक विस्तार से वर्णन करें।
BWill

आमतौर पर, कुशल और विश्वसनीय समाधान अंक से अधिक लूपिंग के बजाय मैप बीजगणित संचालन का उपयोग करके प्राप्त किए जाते हैं। स्थानिक विश्लेषक के नक्शे बीजगणित कार्यान्वयन में सीमाएं इस दृष्टिकोण को हर मामले में काम करने से रोकती हैं, लेकिन आश्चर्यजनक रूप से बड़ी संख्या में स्थितियों में आपको लूप कोड नहीं करना पड़ता है। आपको गणना करने के लिए किस गणना की आवश्यकता है?
व्हीबर

अपने संपादित करें: बेशक यह एक वैध उद्देश्य है। हो सकता है कि पाइपलाइन के नीचे सॉफ़्टवेयर की जरूरतों के द्वारा प्रारूप आप पर थोपा जाए। लेकिन यह देखते हुए कि 8 बिलियन (X, Y, value1, ..., वैल्यू 3) को लिखने के लिए 224 बिलियन बाइट्स (बाइनरी में) और शायद 400 बिलियन बाइट्स (ASCII में) के बीच ट्यूपल की आवश्यकता होगी, जिनमें से कोई एक बड़ा डेटासेट है, यह जो कुछ भी आप अंततः पूरा करने की कोशिश कर रहे हैं, उसके लिए वैकल्पिक दृष्टिकोण खोजने लायक हो सकता है!
व्हीबर

जवाबों:


11

@ डांगो के विचार के बाद मैंने निम्न कोड और उसी आकार और सेल आकार के साथ छोटे चूहों पर परीक्षण किया है:

import arcpy, numpy

inRaster = r"C:\tmp\RastersArray.gdb\InRaster"
inRaster2 = r"C:\tmp\RastersArray.gdb\InRaster2"

##Get properties of the input raster
inRasterDesc = arcpy.Describe(inRaster)

#coordinates of the lower left corner
rasXmin = inRasterDesc.Extent.Xmin
rasYmin = inRasterDesc.Extent.Ymin

# Cell size, raster size
rasMeanCellHeight = inRasterDesc.MeanCellHeight
rasMeanCellWidth = inRasterDesc.MeanCellWidth
rasHeight = inRasterDesc.Height
rasWidth = inRasterDesc.Width

##Calculate coordinates basing on raster properties
#create numpy array of coordinates of cell centroids
def rasCentrX(rasHeight, rasWidth):
    coordX = rasXmin + (0.5*rasMeanCellWidth + rasWidth)
    return coordX
inRasterCoordX = numpy.fromfunction(rasCentrX, (rasHeight,rasWidth)) #numpy array of X coord

def rasCentrY(rasHeight, rasWidth):
    coordY = rasYmin + (0.5*rasMeanCellHeight + rasHeight)
    return coordY
inRasterCoordY = numpy.fromfunction(rasCentrY, (rasHeight,rasWidth)) #numpy array of Y coord

#combine arrays of coordinates (although array for Y is before X, dstack produces [X, Y] pairs)
inRasterCoordinates = numpy.dstack((inRasterCoordY,inRasterCoordX))


##Raster conversion to NumPy Array
#create NumPy array from input rasters 
inRasterArrayTopLeft = arcpy.RasterToNumPyArray(inRaster)
inRasterArrayTopLeft2 = arcpy.RasterToNumPyArray(inRaster2)

#flip array upside down - then lower left corner cells has the same index as cells in coordinates array
inRasterArray = numpy.flipud(inRasterArrayTopLeft)
inRasterArray2 = numpy.flipud(inRasterArrayTopLeft2)


# combine coordinates and value
inRasterFullArray = numpy.dstack((inRasterCoordinates, inRasterArray.T))

#add values from second raster
rasterValuesArray = numpy.dstack((inRasterFullArray, inRasterArray2.T))

@ स्फटिक कोड के आधार पर, आप वांछित मूल्यों तक पहुँच प्राप्त कर सकते हैं:

(height, width, dim )=rasterValuesArray.shape
for row in range(0,height):
    for col in range(0,width):
        #now you have access to single array of values for one cell location

दुर्भाग्य से वहाँ एक 'लेकिन' - कोड NumPy सरणियों के लिए सही है जिसे सिस्टम मेमोरी द्वारा नियंत्रित किया जा सकता है। मेरे सिस्टम (8 जीबी) के लिए, सबसे बड़ी सरणी लगभग 9000,9000 थी।

जैसा कि मेरा अनुभव मुझे और अधिक सहायता प्रदान नहीं करता है, आप बड़ी सरणियों से निपटने के बारे में कुछ सुझावों पर विचार कर सकते हैं: /programming/1053928/python-numpy-very-large-matrices

arcpy.RasterToNumPyArrayविधि NumPy सरणी ( ArcGIS10 सहायता पृष्ठ ) में कनवर्ट किए गए रेखापुंज के सबसेट को निर्दिष्ट करने की अनुमति देती है जब बड़े डेटासेट को सबमेट्रिक्स में चून करने पर क्या उपयोगी हो सकता है।


Marcin का कोड सुपर है! धन्यवाद, लेकिन यह रैस्टर के X, Y को रस्टर के समान रिज़ॉल्यूशन के साथ नहीं लिखता है। मेरा मतलब है कि x और y 1 मीटर बढ़ते हैं, उदाहरण के लिए) 100 मीटर .... क्या आपको ठीक करने का सुझाव है? धन्यवाद

7

यदि आप केवल पिक्सेल मानों को प्राप्त करना चाहते हैं (पंक्ति, स्तंभ), तो आप इस तरह से एक चापलूसी स्क्रिप्ट लिख सकते हैं:

import arcpy
raster = arcpy.Raster("yourfilepath")
array = arcpy.RasterToNumPyArray(raster)
(height, width)=array.shape
for row in range(0,height):
    for col in range(0,width):
        print str(row)+","+str(col)+":"+str(array.item(row,col))

लेकिन, यदि आप पिक्सेल का समन्वय प्राप्त करना चाहते हैं, तो NumPyArray आपकी मदद नहीं कर सकता है। आप रेखापुंज को RasterToPoint टूल द्वारा इंगित करने के लिए परिवर्तित कर सकते हैं, और फिर आप आकृति द्वारा दायर समन्वय प्राप्त कर सकते हैं।


7

आर्कगिस 10 में एक टेक्स्ट फ़ाइल के लिए निर्देशांक और सेल वैल्यू को आउटपुट करने का सबसे सरल तरीका नमूना फ़ंक्शन है , कोड की कोई आवश्यकता नहीं है और विशेष रूप से प्रत्येक सेल पर लूप की आवश्यकता नहीं है। में ArcGIS <= 9.3x रेखापुंज कैलकुलेटर यह उतना ही आसान के रूप में हुआ करता थाoutfile.csv = sample(someraster) जो होगा उत्पादन सब (गैर नल) सेल मूल्यों और निर्देशांक के एक पाठ फ़ाइल (जेड, एक्स, वाई प्रारूप में)। आर्कजीआईएस 10 में, ऐसा लगता है कि "in_location_data" तर्क अब अनिवार्य है, इसलिए आपको सिंटैक्स का उपयोग करने की आवश्यकता है Sample(someraster, someraster, outcsvfile)

संपादित करें: आप कई आपदाओं को भी निर्दिष्ट कर सकते हैं: Sample([someraster, anotherraster, etc], someraster, outcsvfile) :। यह 8 बिलियन सेल्स पर काम करेगा या नहीं, मुझे नहीं पता ...

संपादित करें: ध्यान दें, मैंने आर्कजीआईएस 10 में इसका परीक्षण नहीं किया है, लेकिन <= 9.3 (और वर्कस्टेशन) में वर्षों तक नमूना फ़ंक्शन का उपयोग किया है।

संपादित करें: मैंने अब ArcGIS 10 में परीक्षण किया है और यह एक पाठ फ़ाइल में आउटपुट नहीं करेगा। उपकरण स्वचालित रूप से ".dbf" फ़ाइल एक्सटेंशन को बदल देता है। हालाँकि ... निम्नलिखित अजगर कोड SOMA और MOMA के रूप में काम करता है बीजगणित विवरण अभी भी ArcGIS 5 में समर्थित हैं:

import arcgisscripting
gp=arcgisscripting.create()
gp.multioutputmapalgebra(r'%s=sample(%s)' % (outputcsv,inputraster))

बहुत अच्छा। इसे इंगित करने के लिए धन्यवाद - मैंने पहले इस उपकरण पर ध्यान नहीं दिया था। निश्चित रूप से मेरे समाधान की तुलना में बहुत अधिक बकवास और सरल!
जेम्स एसआर

6

एक तरह से यह करने के लिए उपयोग करने के लिए किया जाएगा Raster_To_Point के बाद उपकरण Add_XY_Coordinates उपकरण। आप एक आकृति के साथ समाप्त हो जाएंगे जहां विशेषता तालिका में प्रत्येक पंक्ति X_Coord , Y_Coord और Cell_Value के स्तंभों के साथ आपके रेखापुंज से एक पिक्सेल का प्रतिनिधित्व करती है । फिर आप एक कर्सर का उपयोग करके इस तालिका पर लूप कर सकते हैं (या यदि आप चाहें तो इसे एक्सेल की तरह निर्यात कर सकते हैं)।

यदि आपके पास संसाधित करने के लिए केवल एक रेखापुंज है, तो यह संभवतः स्क्रिप्टिंग के लायक नहीं है - बस आर्कटबॉक्‍स से उपकरण का उपयोग करें। यदि आपको कई आपदाओं के लिए ऐसा करने की आवश्यकता है, तो आप कुछ इस तरह की कोशिश कर सकते हैं:

[ नोट: मेरे पास ArcGIS 10 नहीं है और मैं ArcPy से परिचित नहीं हूं, इसलिए यह सिर्फ एक बहुत ही कठिन रूपरेखा है। यह अप्रयुक्त है और इसे काम करने के लिए लगभग निश्चित रूप से ट्विकिंग की आवश्यकता होगी।]

import arcpy, os
from arcpy import env

# User input
ras_fold = r'path/to/my/data'           # The folder containing the rasters
out_fold = r'path/to/output/shapefiles' # The folder in which to create the shapefiles

# Set the workspace
env.workspace = ras_fold

# Get a list of raster datasets in the raster folder
raster_list = arcpy.ListRasters("*", "All")

# Loop over the rasters
for raster in raster_list:
    # Get the name of the raster dataset without the file extension
    dataset_name = os.path.splitext(raster)[0]

    # Build a path for the output shapefile
    shp_path = os.path.join(out_fold, '%s.shp' % dataset_name)

    # Convert the raster to a point shapefile
    arcpy.RasterToPoint_conversion(raster, shp_path, "VALUE")

    # Add columns to the shapefile containing the X and Y co-ordinates
    arcpy.AddXY_management(shp_path)

फिर आप खोज कर्सर का उपयोग करके या संभवतः ( dbfpy का उपयोग करके) सरल आकार की विशेषता तालिकाओं पर लूप कर सकते हैं । यह आपको अपने रेखापुंज (अब एक आकृति में .dbf तालिका में संग्रहीत) से डेटा को पार्थिव चर में पढ़ने की अनुमति देगा।

from dbfpy import dbf

# Path to shapefile .dbf
dbf_path = r'path\to\my\dbf_file.dbf'

# Open the dbf file
db = dbf.Dbf(dbf_path)

# Loop over the records
for rec in db:
    cell_no = rec['POINTID'] # Numbered from top left, running left to right along each row
    cell_x = rec['POINT_X']
    cell_y = rec['POINT_Y']
    cell_val = rec['GRID_CODE']

    # Print values
    print cell_no, cell_x, cell_y, cell_val

3

शायद आप रेखापुंज के लिए एक विश्व फ़ाइल बना सकते हैं, रेखापुंज को एक सुव्यवस्थित सरणी में शामिल कर सकते हैं। फिर यदि आप सरणी पर लूप करते हैं, तो आपको सेल वैल्यू मिल जाएगी और यदि आप LGmentaly x, y को विश्व फ़ाइल से अपडेट करते हैं, तो आपके पास प्रत्येक सेल मान के लिए निर्देशांक भी होंगे। आशा है कि उपयोगी है।


यदि आप जेम्सस्टर द्वारा सुझाई गई रैस्टर टू प्वाइंट टूल विधि में रुचि नहीं रखते हैं, तो मैं कहूंगा कि यह रास्ता है।
नैम्पेटेरसन

3

मार्सिन के कोड ने rasCentrX और rasCentrY फ़ंक्शंस में एक समस्या को छोड़कर ठीक काम किया, जिससे एक अलग रिज़ॉल्यूशन (ग्राज़िया मनाया गया) के रूप में ouput निर्देशांक दिखाई दे रहे थे। मेरा फिक्स बदलना था

coordX = rasXmin + (0.5*rasMeanCellWidth + rasWidth)

सेवा

coordX = rasXmin + ((0.5 + rasWidth) * rasMeanCellWidth)

तथा

  coordY = rasYmin + (0.5*rasMeanCellHeight + rasHeight)

सेवा

  coordY = rasYmin + ((0.5 + rasHeight) * rasMeanCellHeight)

मैंने एक ESRI ग्रिड को CSV फ़ाइल में बदलने के लिए कोड का उपयोग किया। यह inRaster2 के संदर्भ को हटाकर प्राप्त किया गया था, फिर निर्देशांक और मानों को आउटपुट करने के लिए csv.writer का उपयोग करते हुए:

out = csv.writer(open(outputCSV,"wb"), delimiter=',', quoting=csv.QUOTE_NONNUMERIC)
out.writerow(['X','Y','Value'])
(height, width, dim )=inRasterFullArray.shape
for row in range(0,height):
    for col in range(0,width):
        out.writerow(inRasterFullArray[row,col])

मुझे यह भी नहीं पता था कि संक्रमण की आवश्यकता थी

inRasterFullArray = numpy.dstack((inRasterCoordinates, inRasterArray.T))

इतना परिवर्तित करने के लिए

inRasterFullArray = numpy.dstack((inRasterCoordinates, inRasterArray))

2

बदसूरत लेकिन अत्यधिक प्रभावी:

  1. प्रश्न में रेखापुंज के कोनों के बाहर 4 बिंदुओं के साथ एक नई बिंदु सुविधा बनाएं। प्रश्न में रेखापुंज के रूप में एक ही समन्वय प्रणाली में सुनिश्चित करें।
  2. 'Xcor' और 'ycor' डबल फ़ील्ड्स जोड़ें
  3. इन क्षेत्रों के लिए निर्देशांक प्राप्त करने के लिए ज्यामिति की गणना करें
  4. स्थानिक विश्लेषक-> अंतर्वेशन-> प्रवृत्ति -> रेखीय प्रतिगमन
  5. पर्यावरण सेटिंग्स: स्नैप रेखापुंज और सेल आकार प्रश्न में रेखापुंज के समान
  6. 'Xcor' और 'ycor' के लिए अलग से निष्पादित करें
  7. सेल मूल्यों के रूप में निर्देशांक के साथ रैटर्स आते हैं, स्क्रिप्ट के लिए इनपुट के रूप में उपयोग करते हैं।

2

खुले स्रोत अजगर पैकेज का उपयोग कर एक सरल समाधान:

import fiona
import rasterio
from pprint import pprint


def raster_point_coords(raster, points):

    # initialize dict to hold data
    pt_data = {}

    with fiona.open(points, 'r') as src:
        for feature in src:
            # create dict entry for each feature
            pt_data[feature['id']] = feature

    with rasterio.open(raster, 'r') as src:
        # read raster into numpy array
        arr = src.read()
        # rasterio always reads into 3d array, this is 2d, so reshape
        arr = arr.reshape(arr.shape[1], arr.shape[2])
        # get affine, i.e. data needed to work between 'image' and 'raster' coords
        a = src.affine

    for key, val in pt_data.items():
        # get coordinates
        x, y = val['geometry']['coordinates'][0], val['geometry']['coordinates'][1]
        # use affine to convert to row, column
        col, row = ~a * (x, y)
        # remember numpy array is indexed array[row, column] ie. y, x
        val['raster_value'] = arr[int(row), int(col)]

    pprint(pt_data) 

if __name__ == '__main__':
    # my Landsat raster
    ras = '/data01/images/sandbox/LT05_040028_B1.tif'
    # my shapefile with two points which overlap raster area
    pts = '/data01/images/sandbox/points.shp'
    # call function
    raster_point_coords(ras, pts)

फियोना आसान है क्योंकि आप एक आकृति को खोल सकते हैं, सुविधाओं के माध्यम से पुनरावृति कर सकते हैं, और (जैसा कि मेरे पास है) उन्हें एक dictवस्तु में जोड़ सकते हैं । वास्तव में फियोना featureअपने आप में एक जैसी हैdict जैसा है, इसलिए गुणों तक पहुंचना आसान है। यदि मेरे बिंदुओं में कोई विशेषता है, तो वे निर्देशांक, आईडी आदि के साथ इस तानाशाही में दिखाई देंगे।

रैस्टेरियो आसान है क्योंकि यह रैस्टर में एक सुपीरियर एरे, एक लाइट और फास्ट डेटा टाइप के रूप में पढ़ना आसान है। हमारे पास dictरास्टर प्रॉपर्टीज की भी पहुंच है affine, जिसमें वो सभी डेटा हैं जिन्हें हमें रैस्टर x में बदलने की जरूरत है, y निर्देशांक को एरो रो, कोऑर्ड कोऑर्डिनेशंस में बदलते हैं। @ Perrygeo की उत्कृष्ट व्याख्या यहाँ देखें

हम एक pt_dataप्रकार के साथ समाप्त होते हैं dictजिसमें प्रत्येक बिंदु और निकाले गए डेटा होते हैं raster_value। हम आसानी से निकाले गए डेटा के साथ आकृति को फिर से लिख सकते हैं और यदि हम चाहते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.