অবিচ্ছিন্ন রাস্টারগুলিতে আমি কীভাবে প্রতিটি ঘরের মধ্যে পুনরাবৃত্তি করব?


13

আরও তথ্যের জন্য এই লিঙ্কটি দেখুন ।

সমস্যাটি:

আমি একটি অবিচ্ছিন্ন রাস্টার (একটিতে যার কোনও বৈশিষ্ট্য টেবিল নেই), কোষে সেল করে লুপ করতে এবং ঘরের মান পেতে চাই। আমি সেই মানগুলি গ্রহণ করতে এবং তাদের উপর শর্তসাপেক্ষে চালাতে চাই, রাস্টার ক্যালকুলেটরটি ব্যবহার না করে নীচে বিশদে মানচিত্র বীজগণিতের পদক্ষেপগুলি অনুকরণ করে।

নীচের মন্তব্যের অনুরোধ অনুসারে, আমি সমস্যার পটভূমি প্রদানের বিবরণ যুক্ত করেছি এবং নীচের অংশে "বিশ্লেষণের প্রয়োজনীয়তা:" নামক বিভাগটিতে যেমন একটি পদ্ধতি বাস্তবায়নের প্রয়োজনীয়তার ন্যায্যতা প্রমাণ করেছি।

নীচে প্রস্তাবিত বিশ্লেষণটি, পটভূমি সরবরাহ করে আমার সমস্যার সাথে প্রাসঙ্গিক হয়ে ওঠার পরে, উত্তরের কোনও প্রয়োগ করার প্রয়োজন নেই। প্রশ্নের মানটি কেবলমাত্র কক্ষের মানগুলি নির্ধারণ / সেট করার জন্য অবিচ্ছিন্ন রাস্টার দ্বারা পুনরাবৃত্তি করার সাথে সম্পর্কিত।

বিশ্লেষণের প্রয়োজন:

নিম্নলিখিত শর্তগুলির যে কোনওটি যদি পূরণ হয় তবে শর্তগুলির কোনওটি পূরণ না হলে কেবল আউটপুট সেলকে ০ এর মান দিন।

শর্ত ১: যদি কোষের মান শীর্ষ এবং নীচের ঘরগুলির চেয়ে বেশি হয় তবে 1 এর মান দিন:

Con("raster" > FocalStatistics("raster", NbrIrregular("C:\filepath\kernel_file.txt"), "MAXIMUM"), 1, 0)

যেখানে কার্নেল ফাইলটি দেখতে এরকম দেখাচ্ছে:

3 3 
0 1 0
0 0 0
0 1 0

শর্ত ২: যদি ঘরের মান বাম এবং ডান কোষের চেয়ে বেশি হয় তবে 1 এর মান দিন:

Con("raster" > FocalStatistics("raster", NbrIrregular("C:\filepath\kernel_file.txt"), "MAXIMUM"), 1, 0)

যেখানে কার্নেল ফাইলটি দেখতে এরকম দেখাচ্ছে:

3 3 
0 0 0
1 0 1
0 0 0  

শর্ত ৩: যদি সেল মানটি শীর্ষ বাম এবং নীচের অংশের কক্ষগুলির চেয়ে বেশি হয় তবে 1 এর মান দিন:

Con("raster" > FocalStatistics("raster", NbrIrregular("C:\filepath\kernel_file.txt"), "MAXIMUM"), 1, 0)

যেখানে কার্নেল ফাইলটি দেখতে এরকম দেখাচ্ছে:

3 3 
1 0 0
0 0 0
0 0 1 

শর্ত If : যদি সেল মানটি নীচে এবং শীর্ষস্থানীয় কক্ষগুলির চেয়ে বেশি হয় তবে 1 এর মান দিন:

Con("raster" > FocalStatistics("raster", NbrIrregular("C:\filepath\kernel_file.txt"), "MAXIMUM"), 1, 0)

যেখানে কার্নেল ফাইলটি দেখতে এরকম দেখাচ্ছে:

3 3 
0 0 1
0 0 0
1 0 0 

শর্ত ৫: পার্শ্ববর্তী কোষের যে কোনও একটির যদি কেন্দ্রের ঘরের কাছে EQUAL এর মান থাকে তবে আউটপুট রাস্টারটিকে 1 এর মান দিন ( দুটি নিকটবর্তী প্রতিবেশী গণনার সাথে ফোকাল বিভিন্ন ব্যবহার করে )

কেন মানচিত্র বীজগণিত ব্যবহার করবেন না?

এটি নীচে উল্লিখিত হয়েছে যে আমার সমস্যাটি মানচিত্র বীজগণিত ব্যবহার করে সমাধান করা যেতে পারে তবে উপরে যেমনটি দেখা গেছে এটি ছয়টি রাস্টার গণনা, এক সাথে তৈরি সমস্ত রাস্টারকে একত্রিত করার জন্য একটি বৃহত আকার। আমার কাছে মনে হয় যে সেল-বাই-সেল যেতে এবং প্রতিটি ঘরে আলাদা আলাদাভাবে সাত বার লুপিংয়ের পরিবর্তে একবারে একবারে সমস্ত তুলনা করা এবং সাতটি রেস্টার তৈরির জন্য বেশ কিছুটা মেমরি ব্যবহার করা অনেক বেশি দক্ষ।

কীভাবে সমস্যাটি আক্রমণ করা উচিত?

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

সংক্ষেপে:

তার কক্ষের মানগুলি অ্যাক্সেস করার জন্য একটি কন্টিনিউস রাস্টার (যার কোনও বৈশিষ্ট্য সারণী নেই ) এর প্রতিটি কক্ষের মধ্যে লুপ করার সর্বোত্তম পদ্ধতি কী ?

একটি উত্তরের উত্তরের উপরে বর্ণিত বিশ্লেষণ পদক্ষেপগুলি প্রয়োগ করতে হবে না, এটি কেবলমাত্র একজন রাস্টারের সেল মানগুলি অ্যাক্সেস করার জন্য একটি পদ্ধতি সরবরাহ করতে হবে provide


4
এটি একটি রাস্টারের প্রতিটি কক্ষের মধ্যে লুপ করা প্রায় সবসময়ই অপ্রয়োজনীয়। আপনি যা করার চেষ্টা করছেন সে সম্পর্কে আপনি আরও তথ্য সরবরাহ করতে পারেন?
ব্যবহারকারী2856

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

@ লুক আমি বিশ্লেষণের বিশদ যুক্ত করেছি।
কনর

1
কনর স্পষ্টতার জন্য আপনাকে ধন্যবাদ। আমি সম্মত হই যে আপনার জিআইএস যদি প্রতিটি রাস্টার গণনার জন্য যথেষ্ট পরিমাণে ওভারহেড অনুপ্রবেশ করে তবে আপনার নিজের লুপটি লেখা আরও কার্যকর হতে পারে। কৌতূহলের বাইরে, শর্তগুলির এই (অস্বাভাবিক) সেটটির উদ্দেশ্যমূলক ব্যাখ্যাটি কী?
হোবার

1
@ শুভ আমার রাস্টার থেকে ভেক্টর বহুভুজ তৈরি করা প্রান্ত সনাক্তকরণ অপারেশনগুলির জন্য। অ্যাপ্লিকেশনটি ধারণাটিগতভাবে ডিইএম থেকে জলবিদ্যুৎ অববাহিকা সনাক্তকরণের অনুরূপ (উপরে অবস্থিত "শীর্ষস্থান" শীর্ষে অবস্থিত আশেপাশের পরিসংখ্যানগুলির কেন্দ্র ঘরের কথা ভাবেন যে জলটি ডাউনস্লোপ প্রবাহিত হবে) তবে হাইড্রোলজির ক্ষেত্রের বাইরে। আমি আগে এই উদ্দেশ্যে ফ্লো দিকনির্দেশ এবং বেসিন রাস্টার ব্যবহার করেছি, তবে এই পদ্ধতিগুলির বৈশিষ্ট্যগুলি আমার যা প্রয়োজন ঠিক তা না করায় আমার চূড়ান্ত বিশ্লেষণে ত্রুটি হওয়ার আশঙ্কা রয়েছে।
কনার

উত্তর:


11

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

import gdal

#Set GeoTiff driver
driver = gdal.GetDriverByName("GTiff")
driver.Register()

#Open raster and read number of rows, columns, bands
dataset = gdal.Open(filepath)
cols = dataset.RasterXSize
rows = dataset.RasterYSize
allBands = dataset.RasterCount
band = dataset.GetRasterBand(1)

#Get array of raster cell values.  The two zeros tell the 
#iterator which cell to start on and the 'cols' and 'rows' 
#tell the iterator to iterate through all columns and all rows.
def get_raster_cells(band,cols,rows):
    return band.ReadAsArray(0,0,cols,rows)

ফাংশনটি এভাবে প্রয়োগ করুন:

#Bind array to a variable
rasterData = get_raster_cells(band,cols,rows)

#The array will look something like this if you print it
print rasterData
> [[ 1, 2, 3 ],
   [ 4, 5, 6 ],
   [ 7, 8, 9 ]]

তারপরে, নেস্টেড লুপের সাহায্যে আপনার ডেটাটির মাধ্যমে পুনরাবৃত্তি করুন:

for row in rasterData:
    for val in row:
        print val
> 1
  2
  3
  4...

অথবা হতে পারে আপনি একটি তালিকা বোঝার সাথে আপনার 2-ডি অ্যারে সমতল করতে চান:

flat = [val for row in rasterData for val in row]

যাইহোক, কোনও সেল-বাই-সেল ডেটা দিয়ে পুনরাবৃত্তি করার সময় মানগুলি পরিবর্তন / সম্পাদনা করার জন্য আপনার লুপে কিছু শর্তসাপেক্ষ নিক্ষেপ করা সম্ভব। এই স্ক্রিপ্টটি আমি ডেটা অ্যাক্সেস করার জন্য বিভিন্ন উপায়ে লিখেছি দেখুন: https://github.com/azgs/hazards-viewer/blob/master/python/zonal_stats.py


আমি এই সমাধানটির সরলতা এবং কমনীয়তা পছন্দ করি। আমি আরও কয়েক দিন অপেক্ষা করতে যাচ্ছি এবং যদি অন্য কেউ সমান বা বৃহত্তর মানের সমাধান নিয়ে না আসে তবে আমি সম্প্রদায়ের সুবিধার জন্য প্রশ্নের পরিধি আরও প্রশস্ত করতে ট্যাগ যুক্ত করব এবং আপনাকে অনুগ্রহ প্রদান করব।
কনার

ধন্যবাদ, @ কনার! আমরা এই সপ্তাহের শুরুতে আমার কাজের জায়গায় একই ধরণের সমস্যার মুখোমুখি হয়েছি এবং তাই আমি জিডিএল / পাইথন দিয়ে ক্লাস লিখে এটি সমাধান করেছি। বিশেষত, আমাদের ক্লায়েন্ট-সাইড অ্যাপ্লিকেশনটিতে কোনও ব্যবহারকারীর কাছ থেকে কেবল একটি বাউন্ডিং বাক্স দেওয়া একটি রাস্টারগুলির ক্ষেত্রের গড় মূল্য নির্ধারণের জন্য আমাদের একটি সার্ভার-সাইড পদ্ধতি প্রয়োজন। আপনি কি লিখেছেন যে আমি আমার লেখা ক্লাসটি যুক্ত করে রাখলে উপকার হবে?
asonnenschein

আপনার পুনরুদ্ধার করা 2-ডি অ্যারে কীভাবে পড়বেন এবং এর মানগুলি সম্পাদনা করবেন তা দেখানো কোড যুক্ত করা সহায়ক হবে।
কনার

9

হালনাগাদ! অদ্ভুত সমাধান:

import arcpy
import numpy as np

in_ras = path + "/rastername"

raster_Array = arcpy.RasterToNumPyArray(in_ras)
row_num = raster_Array.shape[0]
col_num = raster_Array.shape[1]
cell_count = row_num * row_num

row = 0
col = 0
temp_it = 0

while temp_it < cell_count:
    # Insert conditional statements
    if raster_Array[row, col] > 0:
        # Do something
        val = raster_Array[row, col]
        print val
    row+=1
    if col > col_num - 1:
        row = 0
        col+=1

সুতরাং, আরকেপি ব্যবহার করে রাস্টারগুলিতে সমাপ্ত অ্যারে ফিরে পাওয়া অসুবিধাজনক। আরকিপি.নামপাইআরাইটোরাস্টার কাঠবিড়ালি হয় এবং আপনি যদি আপনার এলএল স্থানাঙ্কগুলি খাওয়ান এমনকি এক্সটেন্টগুলি পুনরায় সংজ্ঞায়িত করতে ঝোঁক।

আমি পাঠ্য হিসাবে সংরক্ষণ করতে পছন্দ করি

np.savetxt(path + "output.txt", output, fmt='%.10f', delimiter = " ")

আমি পাইথনকে গতির জন্য bit৪ বিট হিসাবে চালাচ্ছি - এখনই এর অর্থ এই যে আমি numpy.savetxt একটি শিরোনাম খাওয়াতে পারি না। সুতরাং আমাকে আউটপুটটি খুলতে হবে এবং ASCII শিরোলেখটি যুক্ত করতে হবে যা আর্কটি ASCII কে রাস্টার রূপান্তর করার আগে চায়

File_header = "NCOLS xxx" + '\n'+ "NROWS xxx" + '\n' + "XLLCORNER xxx"+'\n'+"YLLCORNER xxx"+'\n'+"CELLSIZE xxx"+'\n'+"NODATA_VALUE xxx"+'\n'

ন্যাকি সংস্করণটি আরকিপি সংস্করণের চেয়ে আমার শিফট রাস্টার, গুণ এবং আরও দ্রুত (2 মিনিটের মধ্যে 1000 পুনরাবৃত্তি) চালায় (15 মিনিটের মধ্যে 1000 পুনরাবৃত্তি)

পুরানো সংস্করণ আমি এটি মুছে ফেলতে পারি পরে আমি ঠিক একটি অনুরূপ স্ক্রিপ্ট লিখেছি। আমি পয়েন্টগুলিতে রূপান্তর করতে এবং অনুসন্ধান কার্সারটি ব্যবহার করে চেষ্টা করেছি। আমি 12 ঘন্টা মধ্যে মাত্র 5000 পুনরাবৃত্তি পেয়েছি। সুতরাং, আমি অন্য উপায় খুঁজছি।

এটি করার আমার উপায় হ'ল প্রতিটি ঘরের সেল সেন্টার স্থানাঙ্কগুলির মাধ্যমে পুনরাবৃত্তি। আমি উপরের বাম কোণে শুরু এবং ডান থেকে বাম দিকে সরানো। সারিটির শেষে আমি একটি সারি নীচে সরিয়ে আবার বাম দিকে শুরু করি। আমার 2603 কলাম এবং 2438 টি সারি সহ 240 মিটার রাস্টার রয়েছে সুতরাং মোট 6111844 মোট ঘর রয়েছে। আমি একটি পুনরুক্তি পরিবর্তনশীল এবং একটি সময় লুপ ব্যবহার করি। নিচে দেখ

কয়েকটি নোট: 1 - আপনার সীমাটির স্থানাঙ্কগুলি জানতে হবে

2 - ঘর কেন্দ্রের জন্য পয়েন্ট স্থানাঙ্কের সাথে চালান - সীমা মান থেকে 1/2 ঘরের আকারে সরান

3 - আমার স্ক্রিপ্ট কোনও মান নির্দিষ্ট রাস্টার টানতে সেল মানটি ব্যবহার করছে, তারপরে এই রাস্টারটিকে মূল কক্ষে কেন্দ্র করে স্থানান্তর করুন। এটি একটি শূন্য রাস্টার যুক্ত করে একটি চূড়ান্ত রাস্টার যুক্ত করার আগে সীমাটি প্রসারিত করতে। এইটা শুধুমাত্র একটা উদাহরণ. আপনি এখানে আপনার শর্তযুক্ত বিবৃতি রাখতে পারেন (যখন লুপের মধ্যে বিবৃতি দ্বিতীয়)।

4 - এই স্ক্রিপ্টটি ধরে নেয় যে সমস্ত রাস্টার মানগুলি পূর্ণসংখ্যা হিসাবে কাস্ট করা যেতে পারে। এর অর্থ আপনাকে প্রথমে কোনও ডেটা থেকে মুক্তি দিতে হবে। কন ইসনুল।

6 - আমি এখনও এতে সন্তুষ্ট নই এবং আমি এটি পুরোপুরি তোরণ থেকে বের করার জন্য কাজ করছি। আমি বরং ছদ্মবেশী অ্যারে হিসাবে নিক্ষেপ করব এবং সেখানে গণিত করব তারপরে এটি আরকে ফিরিয়ে আনব।

ULx = 959415 ## coordinates for the Upper Left of the entire raster 
ULy = 2044545
x = ULx ## I redefine these if I want to run over a smaller area
y = ULy
temp_it = 0

while temp_it < 6111844: # Total cell count in the data extent
        if x <= 1583895 and y >= 1459474: # Coordinates for the lower right corner of the raster
           # Get the Cell Value
           val_result = arcpy.GetCellValue_management(inraster, str(x)+" " +str(y), "1")
           val = int(val_result.getOutput(0))
        if val > 0: ## Here you could insert your conditional statements
            val_pdf = Raster(path + "pdf_"str(val))
            shift_x  =  ULx - x # This will be a negative value
            shift_y = ULy - y # This will be a positive value
            arcpy.Shift_management(val_pdf, path+ "val_pdf_shift", str(-shift_x), str(-shift_y))
            val_pdf_shift = Raster(path + "val_pdf_shift")
            val_pdf_sh_exp = CellStatistics([zeros, val_pdf_shift], "SUM", "DATA")
            distr_days = Plus(val_pdf_sh_exp, distr_days)
        if temp_it % 20000 == 0: # Just a print statement to tell me how it's going
                print "Iteration number " + str(temp_it) +" completed at " + str(time_it)
        x += 240 # shift x over one column
        if x > 1538295: # if your at the right hand side of a row
            y = y-240 # Shift y down a row
            x = 959415 # Shift x back to the first left hand column
        temp_it+=1

distr_days.save(path + "Final_distr_days")

4

আইগ্রিড টেবিল, আইসিউসার, আইআরও ব্যবহার করে দেখুন। এই কোড স্নিপেট রাস্টার সেল মান আপডেট করার জন্য, তবে এটি পুনরুক্তির মূল বিষয়গুলি দেখায়:

আমি কীভাবে কোনও রাস্টার অ্যাট্রিবিউট টেবিলের মধ্যে একটি নতুন ক্ষেত্র যুক্ত করতে এবং এর মধ্য দিয়ে লুপ করতে পারি?

Public Sub CalculateArea(raster As IRaster, areaField As String)
    Dim bandCol As IRasterBandCollection
    Dim band As IRasterBand

    Set bandCol = raster
    Set band = bandCol.Item(0)

    Dim hasTable As Boolean
    band.hasTable hasTable
    If (hasTable = False) Then
        Exit Sub
    End If    

    If (AddVatField(raster, areaField, esriFieldTypeDouble, 38) = True) Then
        ' calculate cell size
        Dim rstProps As IRasterProps
        Set rstProps = raster

        Dim pnt As IPnt
        Set pnt = rstProps.MeanCellSize

        Dim cellSize As Double
        cellSize = (pnt.X + pnt.Y) / 2#

        ' get fields index
        Dim attTable As ITable
        Set attTable = band.AttributeTable

        Dim idxArea As Long, idxCount As Long
        idxArea = attTable.FindField(areaField)
        idxCount = attTable.FindField("COUNT")

        ' using update cursor
        Dim gridTableOp As IGridTableOp
        Set gridTableOp = New gridTableOp

        Dim cellCount As Long, cellArea As Double

        Dim updateCursor As ICursor, updateRow As IRow
        Set updateCursor = gridTableOp.Update(band.RasterDataset, Nothing, False)
        Set updateRow = updateCursor.NextRow()
        Do Until updateRow Is Nothing
            cellCount = CLng(updateRow.Value(idxCount))
            cellArea = cellCount * (cellSize * cellSize)

            updateRow.Value(idxArea) = cellArea
            updateCursor.updateRow updateRow

            Set updateRow = updateCursor.NextRow()
        Loop

    End If
End Sub

একবার আপনি টেবিলটি অতিক্রম করলে আপনি নির্দিষ্ট ক্ষেত্রের সারি মানটি ব্যবহার করে পেতে পারেন row.get_Value(yourfieldIndex)। আপনি যদি গুগল

আরকোবজেক্টস সারি.গেট_ভ্যালু

এটি দেখানো আপনার প্রচুর উদাহরণ পেতে সক্ষম হবেন।

আশা করি এইটি কাজ করবে.


1
দুর্ভাগ্যক্রমে আমি এটিকে অবহেলা করেছি এবং উপরের আমার মূল প্রশ্নে আমি সম্পাদনা করব, যে আমার রাস্টারের অনেকগুলি ধারাবাহিক মান রয়েছে যা বড় দ্বৈত মান সমন্বিত, এবং এই পদ্ধতিটি কার্যকর হবে না কারণ আমার রাস্টারের কোনও বৈশিষ্ট্য সারণির মান নেই।
কনার

4

র‌্যাডিক্যাল আইডিয়া হিসাবে এটি কীভাবে, এটি আপনাকে অজগর বা আরকোবজেক্টসে প্রোগ্রাম করা প্রয়োজন।

  1. আপনার গ্রিডকে একটি পয়েন্ট ফিচার ক্লাসে রূপান্তর করুন।
  2. এক্সওয়াই ক্ষেত্র তৈরি করুন এবং পপুলেট করুন।
  3. একটি অভিধানে পয়েন্টগুলি লোড করুন যেখানে কী , এক্স, ওয়াইয়ের একটি স্ট্রিং এবং আইটেমটি সেল মান হয় ..
  4. আপনার অভিধানটি এবং প্রতিটি পয়েন্টের জন্য পদক্ষেপ 8 টি আশেপাশের সেল এক্সওয়াইস এর কাজ করে।
  5. এগুলি আপনার অভিধান থেকে পুনরুদ্ধার করুন এবং আপনার নিয়মগুলি দিয়ে পরীক্ষা করুন, সত্যের সত্যের সাথে সাথেই আপনি বাকী পরীক্ষাগুলি বাদ দিতে পারেন।
  6. অন্য অভিধানে ফলাফল লিখুন এবং তারপরে প্রথমে একটি পয়েন্ট ফিচারক্লাস তৈরি করে গ্রিডে ফিরে রূপান্তর করুন এবং তারপরে পয়েন্টগুলি গ্রিডে রূপান্তর করুন।

2
পয়েন্ট বৈশিষ্ট্যগুলির সেটগুলিতে রূপান্তরিত করার মাধ্যমে, এই ধারণাটি রাস্টার-ভিত্তিক ডেটা উপস্থাপনের দুটি গুণকে সরিয়ে দেয় যা এটিকে এত কার্যকর করে তোলে: (1) প্রতিবেশীদের সন্ধান করা একটি অত্যন্ত সাধারণ ধ্রুবক-সময় অপারেশন এবং (২) কারণ স্পষ্টত অবস্থানগুলির সঞ্চয়স্থান হয় প্রয়োজন নেই, র‌্যাম, ডিস্ক এবং I / O প্রয়োজনীয়তাগুলি ন্যূনতম। সুতরাং, যদিও এই পদ্ধতির কাজ করবে, এটির প্রস্তাব দেওয়ার কোনও কারণ খুঁজে পাওয়া শক্ত।
হোয়বার

আপনার উত্তর Hornbydd জন্য ধন্যবাদ। আমি এর মতো একটি পদ্ধতি বাস্তবায়নের সাথে ঠিক আছি, তবে মনে হয় 4 এবং 5 ধাপগুলি খুব কার্যকর গণনাভিত্তিক হবে না। আমার রেস্টারদের সর্বনিম্ন 62,500 কোষ থাকবে (আমি যে রেস্টারটি নির্ধারণ করেছি তার নূন্যতম রেজোলিউশনটি 250 কোষ x 250 কোষ, তবে রেজোলিউশনে এবং সাধারণত আরও অনেক কিছু থাকতে পারে), এবং আমাকে একটি স্থানিক জিজ্ঞাসা করতে হবে প্রতিটি শর্তের সাথে আমার তুলনা চালানোর জন্য ... যেহেতু আমার 6 টি শর্ত রয়েছে সুতরাং এটি 6 * 62500 = 375000 স্থানিক জিজ্ঞাসা হবে। আমি মানচিত্র বীজগণিত সঙ্গে ভাল হতে হবে। তবে সমস্যাটি দেখার এই নতুন পদ্ধতির জন্য ধন্যবাদ। সম্মত।
কনার 18

আপনি কি কেবল এএসসিআইআইতে রূপান্তর করতে পারবেন না এবং তারপরে কম্পিউটারের জন্য আর এর মতো কোনও প্রোগ্রাম ব্যবহার করতে পারবেন না?
অলিভার বুর্দেকিন

প্লাস আমার জাভা অ্যাপলেট রয়েছে যা আমি লিখেছিলাম যা আপনার উপরের শর্তগুলি পূরণ করার জন্য সহজেই সংশোধন করা যেতে পারে। এটি কেবল একটি স্মুথ অ্যালগরিদম ছিল তবে আপডেটগুলি করা খুব সহজ হবে।
অলিভার বুর্দেকিন

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

2

একটি সমাধান:

আমি আজ এর আগে সমাধান করেছি। কোডটি এই পদ্ধতির একটি অভিযোজন । এর পরে ধারণাটি মারাত্মকভাবে কঠিন ছিল না যখন একবার আমি বুঝতে পেরেছিলাম যে বস্তুগুলি রাস্টারের সাথে ইন্টারফেস করতে আসলে কী করে। নীচের পদ্ধতিতে দুটি ইনপুট ডেটাসেট লাগে (ইনআরস্টারডিএস এবং আউটরেস্টারডিএস)। তারা উভয়ই একই ডেটাসেট, আমি সবেমাত্র ইনআরএসডিডিএসের একটি অনুলিপি তৈরি করে আউটআরস্টারডিএস হিসাবে পদ্ধতিতে পাস করেছি। এইভাবে উভয়ের উভয়েরই একই পরিমাণ, স্থানিক রেফারেন্স ইত্যাদি রয়েছে। পদ্ধতিটি ইনআরএসডিডিএস, কোষে সেল থেকে মানগুলি পড়ে এবং নিকটবর্তী প্রতিবেশী তাদের সাথে তুলনা করে। এটি আউটরেস্টারডিএসে সঞ্চিত মান হিসাবে সেই তুলনাগুলির ফলাফলগুলি ব্যবহার করে।

প্রক্রিয়া:

আমি পিক্সেল মানগুলি পেতে আইআরসিটারকর্সর -> আইপিক্সেলক্লক -> সেফআর্রে এবং রাস্টারগুলিতে নতুন লিখতে আইআরসিটারএডিট ব্যবহার করেছি। আপনি যখন আইপিক্সেলব্লক তৈরি করেন, আপনি মেশিনটিকে সেই অঞ্চলের আকার এবং অবস্থানের কথা বলছেন যা আপনি পড়তে / লিখতে চান। আপনি যদি কেবল কোনও রাস্টারটির নীচের অর্ধেকটি সম্পাদনা করতে চান তবে আপনি এটিকে আপনার আইপিক্সেলব্লক পরামিতি হিসাবে সেট করেছেন। আপনি যদি পুরো রাস্টারটিকে লুপ করতে চান তবে আপনাকে পুরো রাস্টার আকারের সমান আইপিক্সেলব্লক সেট করতে হবে। আমি নীচে পদ্ধতিতে আইআরসিটার কার্সারে (পিএস সাইজ) আকারটি দিয়ে রাস্টার কার্সার থেকে পিক্সেলব্লক পেয়ে যাচ্ছি।

অন্য কীটি হ'ল এই পদ্ধতির মানগুলির সাথে ইন্টারফেস করতে আপনাকে SafeArray ব্যবহার করতে হবে। আপনি আইআরস্টারকার্সার থেকে আইপিক্সেলব্লক পাবেন, তারপরে আইপিক্সেলক্লক থেকে SafeArray। তারপরে আপনি সেফআর্রে পড়ুন এবং লিখবেন। আপনি যখন SafeArray এ পড়া / লেখার কাজ শেষ করেন, তখন আপনার সম্পূর্ণ SafeArray আইপিক্সেলক্লোকে আবার লিখুন, তারপরে আপনার আইপিক্সেলক্লকটি IRasterCursor এ লিখুন, শেষে অবশেষে লেখার শুরু করার জন্য অবস্থান সেট করতে IRasterCursor ব্যবহার করুন এবং নিজেই লেখার জন্য IRasterEdit ব্যবহার করুন। এই চূড়ান্ত পদক্ষেপটি যেখানে আপনি আসলে ডেটাসেটের মানগুলি সম্পাদনা করেন।

    public static void CreateBoundaryRaster(IRasterDataset2 inRasterDS, IRasterDataset2 outRasterDS)
    {
        try
        {
            //Create a raster. 
            IRaster2 inRaster = inRasterDS.CreateFullRaster() as IRaster2; //Create dataset from input raster
            IRaster2 outRaster = outRasterDS.CreateFullRaster() as IRaster2; //Create dataset from output raster
            IRasterProps pInRasterProps = (IRasterProps)inRaster;
            //Create a raster cursor with a pixel block size matching the extent of the input raster
            IPnt pSize = new DblPnt();
            pSize.SetCoords(pInRasterProps.Width, pInRasterProps.Height); //Give the size of the raster as a IPnt to pass to IRasterCursor
            IRasterCursor inrasterCursor = inRaster.CreateCursorEx(pSize); //Create IRasterCursor to parse input raster 
            IRasterCursor outRasterCursor = outRaster.CreateCursorEx(pSize); //Create IRasterCursor to parse output raster
            //Declare IRasterEdit, used to write the new values to raster
            IRasterEdit rasterEdit = outRaster as IRasterEdit;
            IRasterBandCollection inbands = inRasterDS as IRasterBandCollection;//set input raster as IRasterBandCollection
            IRasterBandCollection outbands = outRasterDS as IRasterBandCollection;//set output raster as IRasterBandCollection
            IPixelBlock3 inpixelblock3 = null; //declare input raster IPixelBlock
            IPixelBlock3 outpixelblock3 = null; //declare output raster IPixelBlock
            long blockwidth = 0; //store # of columns of raster
            long blockheight = 0; //store # of rows of raster

            //create system array for input/output raster. System array is used to interface with values directly. It is a grid that overlays your IPixelBlock which in turn overlays your raster.
            System.Array inpixels; 
            System.Array outpixels; 
            IPnt tlc = null; //set the top left corner

            // define the 3x3 neighborhood objects
            object center;
            object topleft;
            object topmiddle;
            object topright;
            object middleleft;
            object middleright;
            object bottomleft;
            object bottommiddle;
            object bottomright;

            long bandCount = outbands.Count; //use for multiple bands (only one in this case)

            do
            {

                inpixelblock3 = inrasterCursor.PixelBlock as IPixelBlock3; //get the pixel block from raster cursor
                outpixelblock3 = outRasterCursor.PixelBlock as IPixelBlock3;
                blockwidth = inpixelblock3.Width; //set the # of columns in raster
                blockheight = inpixelblock3.Height; //set the # of rows in raster
                outpixelblock3.Mask(255); //set any NoData values

                for (int k = 0; k < bandCount; k++) //for every band in raster (will always be 1 in this case)
                {
                    //Get the pixel array.
                    inpixels = (System.Array)inpixelblock3.get_PixelData(k); //store the raster values in a System Array to read
                    outpixels = (System.Array)outpixelblock3.get_PixelData(k); //store the raster values in a System Array to write
                    for (long i = 1; i < blockwidth - 1; i++) //for every column (except outside columns)
                    {
                        for (long j = 1; j < blockheight - 1; j++) //for every row (except outside rows)
                        {
                            //Get the pixel values of center cell and  neighboring cells

                            center = inpixels.GetValue(i, j);

                            topleft = inpixels.GetValue(i - 1, j + 1);
                            topmiddle = inpixels.GetValue(i, j + 1);
                            topright = inpixels.GetValue(i + 1, j + 1);
                            middleleft = inpixels.GetValue(i - 1, j);
                            middleright = inpixels.GetValue(i + 1, j);
                            bottomleft = inpixels.GetValue(i - 1, j - 1);
                            bottommiddle = inpixels.GetValue(i, j - 1);
                            bottomright = inpixels.GetValue(i - 1, j - 1);


                            //compare center cell value with middle left cell and middle right cell in a 3x3 grid. If true, give output raster value of 1
                            if ((Convert.ToDouble(center) >= Convert.ToDouble(middleleft)) && (Convert.ToDouble(center) >= Convert.ToDouble(middleright)))
                            {
                                outpixels.SetValue(1, i, j);
                            }


                            //compare center cell value with top middle and bottom middle cell in a 3x3 grid. If true, give output raster value of 1
                            else if ((Convert.ToDouble(center) >= Convert.ToDouble(topmiddle)) && (Convert.ToDouble(center) >= Convert.ToDouble(bottommiddle)))
                            {
                                outpixels.SetValue(1, i, j);
                            }

                            //if neither conditions are true, give raster value of 0
                            else
                            {

                                outpixels.SetValue(0, i, j);
                            }
                        }
                    }
                    //Write the pixel array to the pixel block.
                    outpixelblock3.set_PixelData(k, outpixels);
                }
                //Finally, write the pixel block back to the raster.
                tlc = outRasterCursor.TopLeft;
                rasterEdit.Write(tlc, (IPixelBlock)outpixelblock3);
            }
            while (inrasterCursor.Next() == true && outRasterCursor.Next() == true);
            System.Runtime.InteropServices.Marshal.ReleaseComObject(rasterEdit);


        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }

    }

1

এএফএইসি রাস্টার ডেটা তিনভাবে পড়া যায়:

  • সেল দ্বারা (অদক্ষ);
  • চিত্র দ্বারা (বেশ দক্ষ);
  • ব্লক দ্বারা (সবচেয়ে কার্যকর উপায়)

চাকা পুনরায় উদ্ভাবন না করে, আমি ক্রিস গ্যারার্ডের এই আলোকিত স্লাইডগুলি পড়ার পরামর্শ দিই ।

সুতরাং সর্বাধিক দক্ষ পদ্ধতি হ'ল ব্লক করে ডেটা পড়া, তবে এটি ফিল্টার প্রয়োগ করার সময় ব্লকের সীমানাগুলির মধ্যে অবস্থিত পিক্সেলের চিঠিতে একটি ডেটা ক্ষতি হতে পারে। সুতরাং নিরাপদ বিকল্প উপায়টি একবারে পুরো চিত্রটি পড়ার এবং অদ্ভুত পদ্ধতির ব্যবহারের সাথে অন্তর্ভুক্ত হওয়া উচিত।

গণনার দিকে, পরিবর্তে, আমার প্রয়োজনীয় ফিল্টারগুলি প্রয়োগ করতে এবং সর্বোপরি ভারী গণনা এড়াতে gdalfilter.py এবং স্পষ্টতই VRT কার্নেল ফিল্টারসোর্স পদ্ধতির ব্যবহার করা উচিত ।

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