रेखापुंज बनाना जहां प्रत्येक सेल समुद्र से दूरी रिकॉर्ड करता है?


10

मैं 25 मीटर × 25 मीटर के संकल्प के साथ एक रेखापुंज बनाना चाहता हूं, जहां प्रत्येक सेल में निकटतम तट रेखा से दूरी होती है, जैसा कि सेल के केंद्र से गणना की जाती है। ऐसा करने के लिए, मेरे पास न्यूजीलैंड के समुद्र तटों की आकृति है

मैंने डोमिनिक रॉय के ट्यूटोरियल को आर में करने के लिए अनुसरण करने की कोशिश की है जो काम करता है ... तरह का। यह लगभग 1 किमी × 1 किमी रिज़ॉल्यूशन के लिए ठीक है, लेकिन अगर मैं किसी भी उच्च रैम पर जाने की कोशिश करता हूं, तो इसके लिए मेरे पीसी (~ 70 जीबी रैम की आवश्यकता) या किसी अन्य की आवश्यकता होती है जो मेरे पास भी है। यह कहते हुए कि, मुझे लगता है कि यह R की एक सीमा है और मुझे संदेह है कि QGIS के पास इस रेखापुंज को बनाने का अधिक कम्प्यूटेशनल रूप से कुशल तरीका हो सकता है, लेकिन मैं इसके लिए नया हूं और मैं यह पता नहीं लगा सकता कि इसे कैसे किया जाए।

मैंने QGIS के उपयोग से दूरी बनाने के लिए रेखापुंज बनाने की कोशिश की है ? QGIS में इसे बनाने के लिए, लेकिन यह इस त्रुटि को लौटाता है:

_core.QgsProcessingException: INPUT के लिए स्रोत परत को लोड नहीं किया जा सका: C: /..../ कोलाइन / nz-Coastlines और और-polygons-topo-150k.shp नहीं मिला

और मुझे यकीन नहीं है कि क्यों।

क्या किसी के पास कोई सुझाव है जो गलत हो सकता है या ऐसा करने का एक वैकल्पिक तरीका हो सकता है?

संपादित करें:

मैं जिस रैस्टर का उत्पादन करने की उम्मीद कर रहा हूं उसमें लगभग 59684 पंक्तियां और 40827 कॉलम होंगे ताकि यह LINZ के वार्षिक पानी की कमी वाले रैस्टर के साथ ओवरलैप हो जाए । यदि उत्पन्न होने वाला रैस्टर वार्षिक पानी की कमी के रैस्टर से बड़ा है, तो मैं इसे R में स्निप कर सकता हूं ...

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


1
क्या आप ऐसा करने के लिए स्क्रिप्ट चला रहे हैं? या आप क्यूजीआईएस में उपकरणों का उपयोग कर रहे हैं? जांच करने के लिए कुछ, भले ही यह ऐसा लगता है - फ़ाइल की जांच करें वास्तव में मौजूद है जहां आप कहते हैं कि यह करता है ... यह भी जांचें कि आपने उस विशेष फ़ोल्डर तक पहुंच पढ़ी और लिखी है।
केगन एलन

वर्तमान में टूल का उपयोग कर रहा हूं लेकिन मैं स्क्रिप्ट सीखने के लिए काफी उत्सुक हूं, बस यह सुनिश्चित नहीं है कि कहां से शुरू करें। मुझे यकीन है कि फ़ाइल मौजूद है, क्योंकि मैंने .shp फ़ाइल को QGIS में लोड किया है और यह एक छवि के रूप में पॉप अप करता है। मुझे एक्सेस पढ़ना / लिखना चाहिए क्योंकि मैं मशीन पर एक व्यवस्थापक हूं और यह सिर्फ मेरे ड्रॉपबॉक्स में है।
एंड्रे। बी।

इसे ड्रॉपबॉक्स से स्थानीय ड्राइव पर ले जाने का प्रयास करें। पथ के साथ कोई समस्या हो सकती है जिसके कारण QGIS इसे अस्वीकार कर सकता है। आप जो करना चाहते हैं, वह QGIS में बहुत सरल होना चाहिए। QGIS के किस संस्करण का आप उपयोग कर रहे हैं?
केगन एलन

1
ठीक है, पॉलीलाइन को एक रेखापुंज में परिवर्तित करने का प्रयास करें। QGIS में निकटता उपकरण को एक रेखापुंज इनपुट की आवश्यकता होती है। उपकरण की सहायता के अनुसार सेटिंग्स के साथ खेलें: docs.qgis.org/2.8/en/docs/user_manual/processing_algs/gdalogr/… । ध्यान दें, यह अभी भी एक गहन प्रक्रिया है, मैं इसे अभी मज़े के लिए परीक्षण कर रहा हूं और यह 30mins के लिए चल रहा है और अभी भी चल रहा है ...
Keagan Allan

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

जवाबों:


9

साथ PyQGIS और GDAL अजगर पुस्तकालय करने के लिए बहुत मुश्किल नहीं है। आपको जियो ट्रांसफॉर्म पैरामीटर्स (टॉप लेफ्ट x, x पिक्सेल रेजोल्यूशन, रोटेशन, टॉप लेफ्ट वाई, रोटेशन, एनएस पिक्सल रेजोल्यूशन) और परिणामस्वरूप रिस्टर बनाने के लिए रो और कॉलम नंबर की आवश्यकता है। निकटतम तट रेखा से दूरी की गणना के लिए, समुद्र तट का प्रतिनिधित्व करने के लिए एक वेक्टर परत आवश्यक है।

PyQGIS के साथ , सेल के केंद्र के रूप में प्रत्येक रेखापुंज बिंदु की गणना की जाती है और इसकी दूरी तटरेखा को QgsGeometry वर्ग से 'निकटतम सेपमेंटविथ कॉन्टेक्स्ट' विधि का उपयोग करके मापा जाता है । GDAL पायथन लाइब्रेरी का उपयोग पंक्तियों के स्तंभ स्तंभों में इन दूरी मूल्यों के साथ एक रेखापुंज बनाने के लिए किया जाता है।

निम्नलिखित बिंदु (397106.7689872353, 4499634.06675821) में शुरू होने वाली दूरी रेखापुंज (25 मीटर × 25 मीटर रिज़ॉल्यूशन और 1000 पंक्तियों x 1000 कॉलम) बनाने के लिए उपयोग किया गया था; संयुक्त राज्य अमेरिका के पश्चिमी तट के पास।

from osgeo import gdal, osr
import numpy as np
from math import sqrt

registry = QgsProject.instance()

line = registry.mapLayersByName('shoreline_10N')

crs = line[0].crs()

wkt = crs.toWkt()

feats_line = [ feat for feat in line[0].getFeatures()]

pt = QgsPoint(397106.7689872353, 4499634.06675821)

xSize = 25
ySize = 25

rows = 1000
cols = 1000

raster = [ [] for i in range(cols) ]

x =   xSize/2
y = - ySize/2

for i in range(rows):
    for j in range(cols):
        point = QgsPointXY(pt.x() + x, pt.y() + y)
        tupla = feats_line[0].geometry().closestSegmentWithContext(point)
        raster[i].append(sqrt(tupla[0]))

        x += xSize
    x =  xSize/2
    y -= ySize

data = np.array(raster)

# Create gtif file 
driver = gdal.GetDriverByName("GTiff")

output_file = "/home/zeito/pyqgis_data/distance_raster.tif"

dst_ds = driver.Create(output_file, 
                       cols, 
                       rows, 
                       1, 
                       gdal.GDT_Float32)

#writting output raster
dst_ds.GetRasterBand(1).WriteArray( data )

transform = (pt.x(), xSize, 0, pt.y(), 0, -ySize)

#setting extension of output raster
# top left x, w-e pixel resolution, rotation, top left y, rotation, n-s pixel resolution
dst_ds.SetGeoTransform(transform)

# setting spatial reference of output raster 
srs = osr.SpatialReference()
srs.ImportFromWkt(wkt)
dst_ds.SetProjection( srs.ExportToWkt() )

dst_ds = None

कोड से ऊपर चलने के बाद, परिणामी रेखापुंज QGIS में लोड किया गया था और यह निम्न छवि (5 वर्गों और स्पेक्ट्रल रैंप के साथ छद्म चॉकलेट) के रूप में दिखता है। प्रोजेक्शन UTM 10 N (EPSG: 32610) है

यहां छवि विवरण दर्ज करें


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

अग्रिम में माफी अगर यह एक गूंगा सवाल है, लेकिन मैं न्यूजीलैंड में एक नया प्रारंभिक बिंदु कैसे चुनूं जिस तरह से आप राज्यों के लिए निर्देशांक निर्धारित करते हैं? मैं इसे EPSG: 2193 में कैसे रख सकता हूँ?
एंड्रे.बी।

7

कोशिश करने के लिए एक समाधान हो सकता है:

  1. एक ग्रिड उत्पन्न करें (टाइप करें "बिंदु", एल्गोरिथ्म "ग्रिड बनाएँ")
  2. एल्गोरिथ्म के साथ अपने बिंदुओं (ग्रिड) और अपनी रेखा (तट) के बीच निकटतम दूरी की गणना करें "निकटतम द्वारा विशेषता शामिल करें"। केवल 1 निकटतम पड़ोसी का चयन करने के लिए लापरवाह रहें।

अब आपके पास इस उदाहरण में तट की दूरी के साथ एक नई बिंदु परत होनी चाहिए यहां छवि विवरण दर्ज करें

  1. यदि आवश्यक हो, तो आप अपनी नई बिंदु परत को एक रेखापुंज में बदल सकते हैं (एल्गोरिथ्म "रैस्टराइज़")

यहां छवि विवरण दर्ज करें


2

QGIS के भीतर आप GRASS प्लगइन की कोशिश कर सकते हैं। जहाँ तक मुझे पता है कि यह आर की तुलना में बेहतर स्मृति का प्रबंधन करता है, और मुझे उम्मीद है कि अन्य समाधान बड़े क्षेत्रों पर विफल होंगे।

GRASS कमांड को r.grow.distance कहा जाता है, जिसे आप प्रोसेसिंग टूलबार में पा सकते हैं। ध्यान दें कि आपको पहले अपनी लाइन को रेखापुंज में बदलने की आवश्यकता है।

यहां छवि विवरण दर्ज करें

आपका एक मुद्दा आउटपुट का आकार हो सकता है, इसलिए आप कुछ उपयोगी निर्माण विकल्प जोड़ सकते हैं जैसे (एक tif फ़ाइल के लिए) BIGTIFF = YES, TILED = YES, COMPRESS = LZW, PREDICOROR = 3


क्या कोई ऐसा तरीका है जिससे मैं किसी भी समुद्री क्षेत्र को समाप्त कर सकता हूं ताकि आकार / गणना समय को कम किया जा सके?
एंड्रे.बी।

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

0

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

आशा है कि यह कम से कम थोड़ी मदद कर सकता है :)


0

मैं मूल रूप से अपने स्वयं के प्रश्न का उत्तर नहीं दे रहा था, लेकिन मेरे एक सहयोगी (जो इस साइट का उपयोग नहीं करता है), ने मुझे जो कुछ भी करने के लिए किया है, उसे अजगर कोड का एक गुच्छा लिखा; कोशिकाओं को सीमित करने के लिए केवल स्थलीय कोशिकाओं के लिए तट की दूरी और समुद्र आधारित कोशिकाओं को NAs के रूप में छोड़ना शामिल है। निम्नलिखित कोड को किसी भी अजगर कंसोल से चलाने में सक्षम होना चाहिए, जिसमें केवल चीजों को बदलने की आवश्यकता है:

1) स्क्रिप्ट फ़ाइल को उसी फ़ोल्डर में रखें जिसमें ब्याज की आकृति फ़ाइल है;

2) अपने आकार का नाम जो भी हो, पाइथन लिपि में शेपफाइल का नाम बदलें;

3) वांछित संकल्प सेट करें, और;

4) अन्य चूहों से मिलान करने के लिए सीमा बदलें।

मेरे द्वारा उपयोग किए जा रहे बड़े आकार की बड़ी मात्रा में रैम की आवश्यकता होगी, लेकिन अन्यथा स्क्रिप्ट को चलाने के लिए तेज है (लगभग 50 मिनट के लिए 50 मीटर रिजोल्यूशन और 25 मीटर रिजोल्यूशन के लिए दस मिनट का उत्पादन करने के लिए)।

#------------------------------------------------------------------------------

from osgeo import gdal, ogr
import numpy as np
from scipy import ndimage
import matplotlib.pyplot as plt
import time

startTime = time.perf_counter()

#------------------------------------------------------------------------------

# Define spatial footprint for new raster
cellSize = 50 # ANDRE CHANGE THIS!!
noData = -9999
xMin, xMax, yMin, yMax = [1089000, 2092000, 4747000, 6224000]
nCol = int((xMax - xMin) / cellSize)
nRow = int((yMax - yMin) / cellSize)
gdal.AllRegister()
rasterDriver = gdal.GetDriverByName('GTiff')
NZTM = 'PROJCS["NZGD2000 / New Zealand Transverse Mercator 2000",GEOGCS["NZGD2000",DATUM["New_Zealand_Geodetic_Datum_2000",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6167"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4167"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",173],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",1600000],PARAMETER["false_northing",10000000],AUTHORITY["EPSG","2193"],AXIS["Easting",EAST],AXIS["Northing",NORTH]]'

#------------------------------------------------------------------------------ 

inFile = "new_zealand.shp" # CHANGE THIS!!

# Import vector file and extract information
vectorData = ogr.Open(inFile)
vectorLayer = vectorData.GetLayer()
vectorSRS = vectorLayer.GetSpatialRef()
x_min, x_max, y_min, y_max = vectorLayer.GetExtent()

# Create raster file and write information
rasterFile = 'nz.tif'
rasterData = rasterDriver.Create(rasterFile, nCol, nRow, 1, gdal.GDT_Int32, options=['COMPRESS=LZW'])
rasterData.SetGeoTransform((xMin, cellSize, 0, yMax, 0, -cellSize))
rasterData.SetProjection(vectorSRS.ExportToWkt())
band = rasterData.GetRasterBand(1)
band.WriteArray(np.zeros((nRow, nCol)))
band.SetNoDataValue(noData)
gdal.RasterizeLayer(rasterData, [1], vectorLayer, burn_values=[1])
array = band.ReadAsArray()
del(rasterData)

#------------------------------------------------------------------------------

distance = ndimage.distance_transform_edt(array)
distance = distance * cellSize
np.place(distance, array==0, noData)

# Create raster file and write information
rasterFile = 'nz-coast-distance.tif'
rasterData = rasterDriver.Create(rasterFile, nCol, nRow, 1, gdal.GDT_Float32, options=['COMPRESS=LZW'])
rasterData.SetGeoTransform((xMin, cellSize, 0, yMax, 0, -cellSize))
rasterData.SetProjection(vectorSRS.ExportToWkt())
band = rasterData.GetRasterBand(1)
band.WriteArray(distance)
band.SetNoDataValue(noData)
del(rasterData)

#------------------------------------------------------------------------------

endTime = time.perf_counter()

processTime = endTime - startTime

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