পাইথন ব্যবহার করে কোনও রাস্টারে এক্স পিসের এক্সওয়াই স্থানাঙ্ক এবং সেল মান কীভাবে পাবেন?


16

আমি পাইথনে সত্যিই নতুন এবং আমি জানতে চাই যে পিক্সেল দ্বারা রাস্টার পিক্সেলের সেল মানগুলি পাওয়ার জন্য কী দ্রুত পদ্ধতি আছে এবং আরকিজিআইএস 10-তে পাইথন ব্যবহার করে স্থানাঙ্কগুলি (প্রতিটি পিক্সেলের কেন্দ্রের মানচিত্র এক্সওয়াই স্থানাঙ্ক) আছে কিনা তা জানতে চাই?

এটি আরও বর্ণনা করার জন্য, আমাকে প্রথম পিক্সেলের মানচিত্র এক্স, মানচিত্র ওয়াই এবং সেল মান পেতে হবে এবং এই তিনটি মানকে তিনটি ভেরিয়েবলের মধ্যে নির্ধারণ করা হবে এবং বাকী অন্যান্য পিক্সেলের জন্য এই পদক্ষেপটি পুনরাবৃত্তি করতে হবে (পুরো রাস্টার দিয়ে লুপ)।


আমার মনে হয় আমার প্রশ্নটি আরও বর্ণনা করা দরকার। সমস্যাটি হ'ল, আমার প্রথম রাস্টারটির একটি পিক্সেলের XY অবস্থান এবং সেই XY অবস্থানের সাথে সম্পর্কিত অন্যান্য বেশ কয়েকটি রাস্টারগুলির সেল মান পেতে হবে। এই প্রসেসটি কোনও মধ্যবর্তী পয়েন্টের শেফফিল তৈরি না করেই প্রথম রাস্টারটির প্রতিটি পিক্সেলের মধ্য দিয়ে লুপ হওয়া উচিত কারণ এটি প্রায় 8 বিলিয়ন পিক্সেল সহ একটি রাস্টারকে হ্যান্ডেল করতে হওয়ায় এটি সত্যই সময়সাপেক্ষ হতে চলেছে। এছাড়াও, আরকজিআইএস 10-তে পাইথন ব্যবহার করে আমার এটি করা দরকার।

@ জেমস: আপনার পরামর্শের জন্য আপনাকে অনেক ধন্যবাদ। হ্যাঁ এটি একজন রাস্টারের পক্ষে কাজ করবে তবে অন্যান্য বেশ কয়েকটি রাস্টারদের জন্য আমার সেল মানগুলিও সংগ্রহ করতে হবে। সমস্যাটি হ'ল, প্রথম রাস্টারটির প্রথম পিক্সেলের এক্স এবং ওয়াই সমন্বয় পাওয়ার পরে, আমাকে দ্বিতীয় রেস্টারটির সেল মানটি প্রথম রেস্টারটির ওয়াই লোকেশন, তৃতীয় রাস্টার এবং তারপরে পাওয়া দরকার। সুতরাং, আমি মনে করি যখন প্রথম রাস্টারটি লুপ করার সময়, পিক্সেলের এক্স এবং ওয়াই অবস্থান এবং সেই অবস্থানের সাথে সম্পর্কিত অন্যান্য রাস্টারগুলির সেল মানগুলি একই সাথে করা উচিত তবে আমি নিশ্চিত নই। এটি প্রথম রাস্টারটিকে বিন্দু শেফফিলের মধ্যে রূপান্তর করে আর্টজিআইএস 10 তবে আমি 'এর বিন্দু ফাংশনে এক্সট্র্যাক্ট মাল্টিভালুগুলি সম্পাদন করে করা যেতে পারে

@ এইচএমফ্লাই: ধন্যবাদ, হ্যাঁ এই পদ্ধতিটি (রাস্টার্টো নম্পায়ার্য) কাজ করবে যদি আমি অ্যারের পরিচিত সারি এবং কলাম মানের সমন্বয় পেতে পারি।

@ হুবার: আমি কোনও গণনা সম্পাদন করতে চাই না, আমাকে কেবল একটি টেক্সট ফাইলে XY স্থানাঙ্ক এবং সেল মান লিখতে হবে এবং এগুলিই


সম্ভবত আপনি পুরো রাস্টার উপর কিছু গণিত করতে চান? রাস্টার ক্যালকুলেটরগুলি পিক্সেল দ্বারা পিক্সেল কাজ করে।
বিউইলে

1
আরও বিস্তারিতভাবে আপনার উদ্দেশ্য বর্ণনা করুন।
বিউইলে

সাধারণত, দক্ষ ও নির্ভরযোগ্য সমাধানগুলি পয়েন্টগুলি লুপ করার পরিবর্তে মানচিত্র বীজগণিত ক্রিয়াকলাপগুলি ব্যবহার করে প্রাপ্ত হয়। স্থানিক বিশ্লেষকের মানচিত্রের বীজগণিতের প্রয়োগের সীমাবদ্ধতা প্রতিটি ক্ষেত্রেই এই পদ্ধতির কাজ করা থেকে বিরত রাখে, তবে আশ্চর্যজনকভাবে বড় সংখ্যক পরিস্থিতিতে আপনাকে লুপ কোড করতে হবে না। ঠিক কোন হিসাব সম্পাদন করা দরকার?
শুক্র

আপনার সম্পাদনা পুনরায়: অবশ্যই এটি একটি বৈধ উদ্দেশ্য। ফর্ম্যাটটি আরও পাইপলাইনের নিচে সফ্টওয়্যারগুলির প্রয়োজনীয়তার দ্বারা চাপিয়ে দেওয়া হতে পারে। তবে 8 বিলিয়ন (এক্স, ওয়াই, মান 1, ..., মান 3) রচনাগুলি বিবেচনা করে 224 বিলিয়ন বাইট (বাইনারি) এবং সম্ভবত 400 বিলিয়ন বাইট (এএসসিআইআইতে) এর মধ্যে প্রয়োজন হবে, যার মধ্যে একটি বরং একটি বড় ডেটাসেট, এটি আপনি শেষ পর্যন্ত সম্পন্ন করার চেষ্টা করছেন তা যাই হোক না কেন বিকল্প পদ্ধতির সন্ধান করা মূল্যবান হতে পারে!
শুক্র

উত্তর:


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))

@Hmfly কোডের ভিত্তিতে আপনার পছন্দসই মানগুলিতে অ্যাক্সেস থাকতে পারে:

(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

দুর্ভাগ্যক্রমে একটি আছে 'তবে' - কোডটি নম্পপি অ্যারেগুলির জন্য সঠিক যা সিস্টেম মেমরির দ্বারা পরিচালিত হতে পারে। আমার সিস্টেমের জন্য (8 জিবি), বৃহত্তম অ্যারেটি ছিল প্রায় 9000,9000।

যেহেতু আমার অভিজ্ঞতা আমাকে আরও সহায়তা সরবরাহ করতে দেয় না, আপনি এর সাথে বড় অ্যারেগুলি সম্পর্কে কিছু পরামর্শ বিবেচনা করতে পারেন: /programming/1053928/python-numpy-very-large-matrices

arcpy.RasterToNumPyArrayপদ্ধতিটি বৃহত্তর ডেটাসেটকে সাবম্যাট্রিকগুলিতে চুনক করার সময় কী কার্যকর হতে পারে তা নম্পপি অ্যারে ( আর্কজিআইএস 10 সহায়তা পৃষ্ঠা ) তে রূপান্তরিত রাস্টারটির উপসেটটি নির্দিষ্ট করতে দেয় ।


মার্সিনের কোডটি সুপার! ধন্যবাদ, তবে এটি রেস্টারটির একই রেজোলিউশনের সাথে রেস্টারটির এক্স, ওয়াইটি লিখেনি আমি 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 আপনাকে সহায়তা করতে পারে না। আপনি রাস্টারকে রাস্টারটওপয়েন্ট সরঞ্জাম দ্বারা বিন্দুতে রূপান্তর করতে পারেন এবং তারপরে আপনি শেপ ফাইল করে স্থানাঙ্কটি পেতে পারেন।


7

আরকজিআইএস 10-এ কোনও পাঠ্য ফাইলে স্থানাঙ্ক এবং সেল মানগুলি আউটপুট দেওয়ার সহজতম পদ্ধতি হ'ল নমুনা ফাংশন , কোডের প্রয়োজন নেই এবং বিশেষত প্রতিটি কক্ষের লুপের প্রয়োজন নেই। ইন ArcGIS <= 9.3x রাস্টার ক্যালকুলেটর এটা সহজ হিসাবে হিসাবে ব্যবহার করা হয় outfile.csv = sample(someraster)যা would আউটপুট সমস্ত (অ নাল) সেল মূল্যবোধ ও স্থানাঙ্ক একটি টেক্সট ফাইল (য x, y বিন্যাসে)। আরকজিআইএস 10-এ, "ইন_লোকেশন_ডাটা" যুক্তিটি এখন বাধ্যতামূলক বলে মনে হচ্ছে তাই আপনাকে সিনট্যাক্সটি ব্যবহার করা দরকার Sample(someraster, someraster, outcsvfile)

সম্পাদনা: এছাড়াও আপনি একাধিক rasters নির্দিষ্ট করতে পারেন: Sample([someraster, anotherraster, etc], someraster, outcsvfile)। এটি 8 বিলিয়ন কোষে কাজ করবে কিনা, আমার ধারণা নেই ...

সম্পাদনা: দ্রষ্টব্য, আমি এটি আরকিজিআইএস 10 তে পরীক্ষা করে দেখিনি, তবে বছরের পর বছর ধরে <= 9.3 (এবং ওয়ার্কস্টেশন) নমুনা ফাংশনটি ব্যবহার করেছি।

সম্পাদনা: আমি এখন আরকজিআইএস 10-এ পরীক্ষা করেছি এবং এটি কোনও পাঠ্য ফাইলে আউটপুট পাবে না। সরঞ্জামটি স্বয়ংক্রিয়ভাবে ফাইল এক্সটেনশানটিকে ".dbf" এ পরিবর্তন করে। তবে ... নিম্নলিখিত পাইথন কোডটি SOMA হিসাবে কাজ করে এবং MOMA মানচিত্রের বীজগণিত বিবৃতি এখনও আরকিজিআইএস 10 তে সমর্থিত:

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

খুব সুন্দর. এটি নির্দেশ করার জন্য ধন্যবাদ - আমি এই সরঞ্জামটি আগে লক্ষ্য করি নি। আমার সমাধানের চেয়ে অবশ্যই আরও পরিষ্কার এবং সহজ!
জেমস

6

এটি করার একটি উপায় হ'ল রাস্টার_পো_পয়েন্ট সরঞ্জামটি ব্যবহার করা হবে তারপরে অ্যাড_এক্সওয়াই_কর্ডিনেটস সরঞ্জাম। আপনি এমন একটি শেফফিল দিয়ে শেষ করবেন যেখানে অ্যাট্রিবিউট টেবিলের প্রতিটি সারিটি আপনার রাস্টার থেকে এক্স_কর্ড , ওয়াই_কর্ড এবং সেল_ভ্যালুর কলাম সহ পিক্সেল উপস্থাপন করে । তারপরে আপনি কার্সার ব্যবহার করে এই টেবিলটি লুপ করতে পারেন (বা এটি যদি এক্সেল হিসাবে পছন্দ করেন তবে এটি রফতানি করুন)।

প্রক্রিয়া করার জন্য যদি আপনার কাছে কেবল একজন রাস্টার থাকে তবে এটি সম্ভবত স্ক্রিপ্টিংয়ের পক্ষে উপযুক্ত নয় - কেবল আর্কটুলবক্সের সরঞ্জামগুলি ব্যবহার করুন। আপনার যদি অনেক রাস্টারদের জন্য এটি করার দরকার হয় তবে আপনি এরকম কিছু চেষ্টা করতে পারেন:

[ দ্রষ্টব্য: আমার কাছে আরকিজিআইএস 10 নেই এবং আরকপাইয়ের সাথে আমি পরিচিত নই, সুতরাং এটি কেবল একটি খুব রুক্ষ রূপরেখা। এটি অপরিবর্তিত এবং এটি কাজ করার জন্য প্রায় অবশ্যই টুইট করার প্রয়োজন হবে।]

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)

তারপরে আপনি সার্চ কার্সার ব্যবহার করে বা (সম্ভবত আরও সহজ) ডিবিএফপি ব্যবহার করে শেপফাইল অ্যাট্রিবিউট টেবিলগুলি লুপ করতে পারেন । এটি আপনাকে রাস্টার থেকে ডেটা পড়তে দেয় (এখন একটি শেফফাইল .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

হতে পারে আপনি রাস্টারটির জন্য একটি ওয়ার্ল্ড ফাইল তৈরি করতে পারেন, রাস্টারটিকে একটি অদ্ভুত অ্যারেতে প্রচ্ছন্ন করতে পারেন। তারপরে যদি আপনি অ্যারের উপরে লুপ করেন তবে আপনি সেল মান পাবেন এবং যদি আপনি বিশ্ব ফাইল থেকে এক্স, ওয়াই আপডেট করে থাকেন তবে আপনার প্রতিটি ঘর মানের জন্য স্থানাঙ্কও থাকবে। আশা করি তা কার্যকর।


আপনি যদি জেমসএস দ্বারা প্রস্তাবিত রাস্টার টু পয়েন্ট সরঞ্জাম পদ্ধতিতে আগ্রহী না হন, তবে আমি বলব এটিই যাওয়ার উপায়।
nmpeterson

3

মার্সিনের কোডটি রাসসেন্ট্রএক্স এবং রাসসেন্ট্রি ফাংশনগুলির সমস্যা ব্যতীত সূক্ষ্মভাবে কাজ করেছিল এবং আউটপুট স্থানাঙ্ককে অন্য রেজোলিউশনে হাজির করার কারণ ছিল (গ্রাজিয়া পর্যবেক্ষণ হিসাবে)। আমার ফিক্স পরিবর্তন ছিল

coordX = rasXmin + (0.5*rasMeanCellWidth + rasWidth)

প্রতি

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

এবং

  coordY = rasYmin + (0.5*rasMeanCellHeight + rasHeight)

প্রতি

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

আমি একটি ইএসআরআই গ্রিডকে একটি সিএসভি ফাইলে রূপান্তর করতে কোডটি ব্যবহার করেছি। এটি 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, তাই বৈশিষ্ট্য অ্যাক্সেস করা সহজ। যদি আমার পয়েন্টগুলির কোনও বৈশিষ্ট্য থাকে তবে তারা স্থানাঙ্ক, আইডি ইত্যাদির সাথে এই ডিকটিতে উপস্থিত হবে would

রাস্টারিও সুবিধাজনক কারণ রাস্টারগুলিতে নাম্পি অ্যারে, হালকা এবং দ্রুত ডেটা টাইপ হিসাবে পড়া সহজ। আমরা রাস্টার এক্স, ওয়াই স্থানাঙ্কগুলিকে অ্যারে সারিতে, কর্নাল স্থানাঙ্কগুলিতে রূপান্তর করতে প্রয়োজনীয় সমস্ত ডেটা dictসহ আমরা বেশ কয়েকটি রাস্টার বৈশিষ্ট্যে অ্যাক্সেসও affineপেয়েছি। এখানে @ পেরিজিওর দুর্দান্ত ব্যাখ্যা দেখুন ।

আমরা pt_dataএক প্রকারের সাথে শেষ করি dictযার প্রতিটি পয়েন্ট এবং এক্সট্রাক্টের জন্য ডেটা থাকে raster_value। আমরা চাইলে এক্সট্রাক্ট করা ডেটা সহ সহজেই শেফফাইলটি আবার লিখতে পারি।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.