নুমপি ছাড়াই ওজিআর পয়েন্টের অধীনে জিডিএল রাস্টারটির পিক্সেল মান পাওয়া যাচ্ছে?


45

আমি একটি আড়াআড়ি জুড়ে বন্য পরাগবাহীদের প্রাচুর্যের একটি গণনামূলক মডেল নিয়ে কাজ করছি। মডেলটি নিজেই সম্পূর্ণ, এবং আমি এখন একটি পোস্ট-প্রসেসিং পদক্ষেপ নিয়ে লড়াই করছি।

আমার জিডিএএলএল পরাগরেণ্য সরবরাহকারী রেস্টার রয়েছে যা দেখতে এমন কিছু দেখায় (হালকা রঙের অর্থ পিক্সেলের উচ্চ পরাগরেণের পরিদর্শন):

ল্যান্ডস্কেপে পরাগবাহী সরবরাহের প্রতিনিধিত্বকারী গ্রেস্কেল রাস্টার

এবং আমার ল্যান্ডস্কেপে নমুনা অবস্থানগুলি উপস্থাপন করে এমন পয়েন্টগুলির একটি ওজিআর শেফফাইল রয়েছে:

এখানে চিত্র বর্ণনা লিখুন

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

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

আমি এই পোস্টটি লক্ষ্য করেছি , এটি একই রকম, তবে একটি কমান্ড-লাইন কল প্রয়োজন।


2
ReadAsArray () এবং কেবল পয়েন্টটিতে পড়া সম্পর্কে কী? আপনি কেবল আগ্রহী এমন একক সেলটি পড়ুন? আপনাকে পয়েন্টের কর্ডগুলি থেকে পিক্সেল স্পেসে রূপান্তর করতে হবে এবং প্রয়োজনীয় ঘরটি বের করতে হবে।
জে লৌরা

1
Gdalsrsinfo এর কোডটি দেখুন, এটি আপনাকে জিডিএলআইএনভার্টজিও ট্রান্সফর্ম () ব্যবহার এবং ভৌগলিক স্থান এবং পিক্সেল স্পেসের মধ্যে স্যুইচ করতে দেখায়: trac.osgeo.org/gdal/browser/trunk/gdal/apps/gdalsrsinfo.cpp

আপনি PostGIS ব্যবহার কিছু মনে না করেন, দেখুন এই । এটি অত্যন্ত দ্রুত এবং মাত্র 1 এসকিউএল লাইন।
mlt

আমি যদি এই সমস্যাটি দেখতে পাই এবং পোস্টজিআইএস ডাটাবেসে অ্যাক্সেস পেয়ে থাকি তবে তা মনে রাখব! আমি এই বিশেষ সমস্যার জন্য ছিলাম না, সুতরাং নীচের জিডিএল সমাধানটি কৌশলটি করেছে। ধন্যবাদ যদিও!
জেমস

@kyle আমি জানি না যদি জিনিস পরিবর্তিত হয়েছে কিন্তু এটি দেখে মনে হচ্ছে এটা GDALInvGeoTransform না বিপরীতমুখী এবং এই একটি উদাহরণ
mlt

উত্তর:


61

আপনি gdal.Dataset বা gdal.Band ReadRaster পদ্ধতি ব্যবহার করতে পারেন । দেখুন GDAL এবং OGR এপিআই টিউটোরিয়াল এবং নীচের উদাহরণে। রিডআাস্টারটি নম্পি ব্যবহার করে না / প্রয়োজন হয় না, ফেরতের মানটি কাঁচা বাইনারি ডেটা এবং স্ট্যান্ডার্ড পাইথন স্ট্রাক্ট মডিউলটি ব্যবহার করে প্যাক করা দরকার ।

একটি উদাহরণ:

from osgeo import gdal,ogr
import struct

src_filename = '/tmp/test.tif'
shp_filename = '/tmp/test.shp'

src_ds=gdal.Open(src_filename) 
gt=src_ds.GetGeoTransform()
rb=src_ds.GetRasterBand(1)

ds=ogr.Open(shp_filename)
lyr=ds.GetLayer()
for feat in lyr:
    geom = feat.GetGeometryRef()
    mx,my=geom.GetX(), geom.GetY()  #coord in map units

    #Convert from map to pixel coordinates.
    #Only works for geotransforms with no rotation.
    px = int((mx - gt[0]) / gt[1]) #x pixel
    py = int((my - gt[3]) / gt[5]) #y pixel

    structval=rb.ReadRaster(px,py,1,1,buf_type=gdal.GDT_UInt16) #Assumes 16 bit int aka 'short'
    intval = struct.unpack('h' , structval) #use the 'short' format code (2 bytes) not int (4 bytes)

    print intval[0] #intval is a tuple, length=1 as we only asked for 1 pixel value

বিকল্পভাবে, যেহেতু আপনি ব্যবহার না করার জন্য যে কারণটি দিয়েছিলেন তা numpyহ'ল ব্যবহারের ক্ষেত্রে পুরো অ্যারেটি পড়া এড়ানো ReadAsArray(), নীচে একটি উদাহরণ যা numpyপুরো রাস্টারটিকে ব্যবহার করে এবং না পড়ে।

from osgeo import gdal,ogr
import struct

src_filename = '/tmp/test.tif'
shp_filename = '/tmp/test.shp'

src_ds=gdal.Open(src_filename) 
gt=src_ds.GetGeoTransform()
rb=src_ds.GetRasterBand(1)

ds=ogr.Open(shp_filename)
lyr=ds.GetLayer()
for feat in lyr:
    geom = feat.GetGeometryRef()
    mx,my=geom.GetX(), geom.GetY()  #coord in map units

    #Convert from map to pixel coordinates.
    #Only works for geotransforms with no rotation.
    px = int((mx - gt[0]) / gt[1]) #x pixel
    py = int((my - gt[3]) / gt[5]) #y pixel

    intval=rb.ReadAsArray(px,py,1,1)
    print intval[0] #intval is a numpy array, length=1 as we only asked for 1 pixel value

এবং আপনি কীভাবে সিএসভি, টেবিল বা অন্যান্য অবজেক্ট হিসাবে সংরক্ষণ করতে পারেন? স্থানাঙ্ক একই দৈর্ঘ্য সহ একটি বস্তু objetct
gonzalez.ivan90

এখানে প্রশ্ন, লুক। ধন্যবাদ! gis.stackexchange.com/questions/269603/…
gonzalez.ivan90

লাইনগুলি নির্ধারণ করে px/ pyভুল হয় যে ক্ষেত্রে mx / আমার সীমানার বাইরে মিথ্যা rb, কারণ int(-0.5) == 0। আপনার প্রয়োজন floor(...), এবং তারপরে আপনার অবশ্যই পরীক্ষা করা উচিত যে px/ pyদুটিই শূন্যের চেয়ে কম নয় (বা কল করার আগে এটি করুন int()), কারণ নেতিবাচক সূচকগুলি কাজ করে (তারা অ্যারের অন্য দিকটি পায়)। আমি জানতে আগ্রহী যে এই সমস্যাটি মোকাবিলার জন্য আরও সুস্পষ্ট উপায় আছে কিনা। এছাড়াও, আপনি কীভাবে সেই লাইনগুলি পুনরায় লিখবেন যাতে তারা ঘূর্ণনগুলি সঠিকভাবে মোকাবেলা করে?
নিট 101
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.