ऊंचाई प्रोफ़ाइल 10 किमी प्रत्येक रेखा के एक तरफ


15

मैं इलाके के एक बैंड के लिए एक ऊंचाई प्रोफ़ाइल कैसे प्राप्त कर सकता हूं?

10 किमी (परिभाषित लाइन के प्रत्येक तरफ) के भीतर उच्चतम ऊंचाई को ध्यान में रखा जाना चाहिए।

मुझे उम्मीद है कि मेरा प्रश्न स्पष्ट है। पहले से ही बहुत - बहुत धन्यवाद।


क्या रेखा आपकी प्रोफ़ाइल को एक सरल सीधी रेखा बता रही है, या इसमें कोनों के साथ कई खंड हैं?
जेक

लाइन में कई सेगमेंट होते हैं। लेकिन सभी सेगमेंट स्ट्रेट लाइन हैं। :) मेरा मतलब है कि कोई वक्र नहीं हैं।
कारा

बस ... जैसा कि वे कहते हैं..स्पिटबॉलिंग ... लेकिन क्या आप 10 किमी बफर के साथ लाइन को बफर कर सकते हैं। फिर बफर के भीतर सभी सुविधाओं का चयन करें ... फिर उच्चतम मूल्यों का चयन करें?
गेर

1
क्या आप एक ऐसी छवि प्रदान कर सकते हैं जिसे आप प्राप्त करना चाहते हैं?
अलेक्जेंड्रे नेटो

@ एलेक्स: मैं चाहता हूं कि परिणाम एक नियमित ऊंचाई ग्राफ है। लेकिन 10 किमी बफर के साथ क्रम में कि चयनित पथ के प्रत्येक तरफ 10 किमी का उच्चतम मूल्य ग्राफ पर दिखाया गया है।
कारा

जवाबों:


14

टिप्पणियों के बाद, यहां एक संस्करण है जो लंबवत रेखा खंडों के साथ काम करता है। कृपया सावधानी के साथ उपयोग करें क्योंकि मैंने इसे पूरी तरह से नहीं देखा है!

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

इसे चलाने के लिए आपको Shapely , Fiona और Numpy Python पैकेज (अपनी निर्भरता के साथ) स्थापित करने की आवश्यकता होगी।

#-------------------------------------------------------------------------------
# Name:        perp_lines.py
# Purpose:     Generates multiple profile lines perpendicular to an input line
#
# Author:      JamesS
#
# Created:     13/02/2013
#-------------------------------------------------------------------------------
""" Takes a shapefile containing a single line as input. Generates lines
    perpendicular to the original with the specified length and spacing and
    writes them to a new shapefile.

    The data should be in a projected co-ordinate system.
"""

import numpy as np
from fiona import collection
from shapely.geometry import LineString, MultiLineString

# ##############################################################################
# User input

# Input shapefile. Must be a single, simple line, in projected co-ordinates
in_shp = r'D:\Perp_Lines\Centre_Line.shp'

# The shapefile to which the perpendicular lines will be written
out_shp = r'D:\Perp_Lines\Output.shp'

# Profile spacing. The distance at which to space the perpendicular profiles
# In the same units as the original shapefile (e.g. metres)
spc = 100

# Length of cross-sections to calculate either side of central line
# i.e. the total length will be twice the value entered here.
# In the same co-ordinates as the original shapefile
sect_len = 1000
# ##############################################################################

# Open the shapefile and get the data
source = collection(in_shp, "r")
data = source.next()['geometry']
line = LineString(data['coordinates'])

# Define a schema for the output features. Add a new field called 'Dist'
# to uniquely identify each profile
schema = source.schema.copy()
schema['properties']['Dist'] = 'float'

# Open a new sink for the output features, using the same format driver
# and coordinate reference system as the source.
sink = collection(out_shp, "w", driver=source.driver, schema=schema,
                  crs=source.crs)

# Calculate the number of profiles to generate
n_prof = int(line.length/spc)

# Start iterating along the line
for prof in range(1, n_prof+1):
    # Get the start, mid and end points for this segment
    seg_st = line.interpolate((prof-1)*spc)
    seg_mid = line.interpolate((prof-0.5)*spc)
    seg_end = line.interpolate(prof*spc)

    # Get a displacement vector for this segment
    vec = np.array([[seg_end.x - seg_st.x,], [seg_end.y - seg_st.y,]])

    # Rotate the vector 90 deg clockwise and 90 deg counter clockwise
    rot_anti = np.array([[0, -1], [1, 0]])
    rot_clock = np.array([[0, 1], [-1, 0]])
    vec_anti = np.dot(rot_anti, vec)
    vec_clock = np.dot(rot_clock, vec)

    # Normalise the perpendicular vectors
    len_anti = ((vec_anti**2).sum())**0.5
    vec_anti = vec_anti/len_anti
    len_clock = ((vec_clock**2).sum())**0.5
    vec_clock = vec_clock/len_clock

    # Scale them up to the profile length
    vec_anti = vec_anti*sect_len
    vec_clock = vec_clock*sect_len

    # Calculate displacements from midpoint
    prof_st = (seg_mid.x + float(vec_anti[0]), seg_mid.y + float(vec_anti[1]))
    prof_end = (seg_mid.x + float(vec_clock[0]), seg_mid.y + float(vec_clock[1]))

    # Write to output
    rec = {'geometry':{'type':'LineString', 'coordinates':(prof_st, prof_end)},
           'properties':{'Id':0, 'Dist':(prof-0.5)*spc}}
    sink.write(rec)

# Tidy up
source.close()
sink.close()

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

उदाहरण स्क्रिप्ट आउटपुट

जैसा कि @whuber ने टिप्पणियों में कहा है, एक बार जब आप इस स्तर पर पहुंच जाते हैं तो बाकी काफी आसान होता है। नीचे दी गई छवि ArcMap में जोड़े गए आउटपुट के साथ एक और उदाहरण दिखाती है।

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

लंबवत रेखाओं को एक स्पष्ट रेखापुंज में बदलने के लिए फ़ीचर टू रैस्टर टूल का उपयोग करें । आउटपुट आकार फ़ील्ड में फ़ील्ड VALUEहोने के लिए रेखापुंज सेट करें Dist। इसके अलावा टूल सेट करना याद रखें Environmentsताकि Extent, Cell sizeऔर Snap rasterआपके अंतर्निहित डेम के लिए भी ऐसा ही हो। आपको अपनी पंक्तियों के रेखापुंज के साथ अंत करना चाहिए, कुछ इस तरह:

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

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

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

VALUEइस तालिका का क्षेत्र मूल प्रोफ़ाइल लाइन के प्रारंभ से दूरी देता है। प्रत्येक स्तंभ के मानों के लिए अन्य स्तंभ विभिन्न आँकड़े (अधिकतम, मध्य आदि) देते हैं। आप अपने सारांश प्रोफ़ाइल को प्लॉट करने के लिए इस तालिका का उपयोग कर सकते हैं।

एनबी: इस पद्धति के साथ एक स्पष्ट समस्या यह है कि, यदि आपकी मूल रेखा बहुत ही अस्पष्ट है, तो कुछ ट्रांज़ेक्ट लाइनें ओवरलैप हो सकती हैं। आर्कजीआईएस में जोनल स्टैटिस्टिक्स टूल ओवरलैपिंग ज़ोन से नहीं निपट सकते हैं, इसलिए जब ऐसा होता है तो आपकी एक ट्रांज़िट लाइन दूसरे पर वरीयता लेगी। आप जो कर रहे हैं उसके लिए यह समस्या हो सकती है या नहीं भी हो सकती है।

सौभाग्य!


3
+1 यह एक महान योगदान के लिए एक अच्छी शुरुआत है! यदि आप दूसरे आंकड़े को करीब से देखते हैं, तो आप कुछ छोटे बदलावों पर ध्यान देंगे: वे मोड़ के पास पार कर रहे हैं। इसका कारण यह है कि आपके एल्गोरिथ्म की गणना करने के लिए गलत तरीके से माना जाता है कि प्रत्येक खंड का विस्थापन बराबर होगा spc, लेकिन विस्थापन को छोटा करता है। इसके बजाय, आपको अनुप्रस्थ दिशा के वेक्टर को सामान्य करना चाहिए (इसके घटकों को वेक्टर की लंबाई से विभाजित करना चाहिए) और फिर उस पार के वांछित त्रिज्या से गुणा करें।
whuber

आप काफी सही हैं - प्रतिक्रिया के लिए धन्यवाद @ शुभंकर! उम्मीद है कि अब तय हो गया है ...
जेम्स

प्रिय जेम्स, मैं कोशिश करूँगा कि आपको बहुत धन्यवाद। यह समाधान पूरी तरह से सूट करता है।
कारा

11

10 किमी के भीतर उच्चतम ऊंचाई पड़ोस का अधिकतम मान है जो एक परिपत्र 10 किमी त्रिज्या के साथ गणना की जाती है, इसलिए प्रक्षेपवक्र के साथ इस पड़ोस अधिकतम ग्रिड का प्रोफाइल निकालें।

उदाहरण

यहाँ एक पहाड़ी पर एक पेचकश (काली रेखा जो नीचे से ऊपर की ओर चलती है) है:

डीईएम

यह छवि लगभग 17 किलोमीटर 10 किलोमीटर की है। मैंने विधि का वर्णन करने के लिए 10 किमी के बजाय सिर्फ 1 किमी के दायरे को चुना। इसके 1 किमी के बफर को पीले रंग में रेखांकित किया गया है।

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

पड़ोसन अधिकतम

इस नक्शे पर गहरे रंग अधिक हैं।

यहाँ मूल DEM (नीला) और पड़ोस अधिकतम (लाल) के प्रोफाइल का एक प्लॉट दिया गया है:

प्रोफाइल

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


हालांकि यह पूरी तरह से सही नहीं है, है ना? प्रत्येक बिंदु के चारों ओर एक गोल बफर के बजाय, अंतर्निहित रेखापुंज का नमूना करने के लिए 20 किमी की लंबाई वाली ऑर्थोगोनल लाइन का उपयोग नहीं किया जाना चाहिए? कम से कम यह है कि मैं कार के "लाइन के प्रत्येक किनारे पर 10 किमी के भीतर उच्चतम मूल्य" की आवश्यकता को ध्यान में रखूंगा।
जेक

4
@ जेक मैं "गलत" नहीं कहूंगा: आप केवल एक वैकल्पिक व्याख्या प्रस्तुत करते हैं। "प्रत्येक तरफ" एक अस्पष्ट शब्द है जो बेहतर योग्यता का उपयोग कर सकता है। मैं तुम्हारी तरह व्याख्याओं के लिए समाधान का प्रस्ताव कर सकता हूं; एक विधि एक आंचलिक अधिकतम का उपयोग करती है। हालांकि, यह निष्पादन में अधिक जटिल और बहुत धीमा है। हम पहले यह क्यों नहीं देखते कि ओपी इस सरल समाधान के बारे में क्या सोचता है?
whuber

शब्दों का बुरा विकल्प, मुझे "सटीक" का उपयोग नहीं करना चाहिए था - इसके बारे में खेद है
जेक

1
क्योंकि आप जानते हैं कि प्रोफ़ाइल टूल का उपयोग कैसे किया जाता है, आप लगभग पूरा कर चुके हैं। QGIS में GRASS का इंटरफेस है जिसमें पड़ोस के ऑपरेशन शामिल हैं। बस r.neighbors का उपयोग करके पड़ोस के अधिकतम संचालन को लागू करें और इसके परिणाम को प्रोफाइल करें।
whuber

1
@ नाम आप एक समानांतर बदलाव नहीं करना चाहते हैं, आप प्रत्येक क्रॉस-प्रोफाइल को केंद्र रेखा पर लंबवत बनाना चाहते हैं। (समांतर पारी दृष्टिकोण को ठीक उसी तरह लागू किया जा सकता है जैसा कि मैं यहाँ वर्णन करता हूं कि पड़ोस की अधिकतम गणना के लिए एक उपयुक्त लंबी और पतली पड़ोस का उपयोग करके।) मुझे पूरा यकीन है कि आप समान रूप से दूरी वाले लंबवत रेखा क्षेत्रों के सेट के निर्माण के लिए इस साइट पर कोड पा सकते हैं। एक पॉलीलाइन के साथ; यह कठिन हिस्सा है। बाकी सब कुछ उन खंडों के साथ डीईएम मूल्यों को निकालने और उन्हें संक्षेप में प्रस्तुत करने का एक मामला है।
whuber

6

मुझे वही समस्या थी और जेम्स एस के समाधान की कोशिश की, लेकिन फिओना के साथ काम करने के लिए GDAL नहीं मिल सका।

फिर मैंने QGIS 2.4 में SAGA एल्गोरिथम "क्रॉस प्रोफाइल" की खोज की, और मुझे जो परिणाम चाहिए था, वह बिल्कुल मिल गया और मुझे लगता है कि आप भी नीचे देख रहे हैं (नीचे देखें)।

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


नमस्ते, मैं अभी कुछ साल पहले इस पोस्ट पर आया था। मुझे थ्रेड स्टार्टर के रूप में एक ही समस्या का सामना करना पड़ रहा है, और, (क्यू) जीआईएस के लिए बहुत नया होने के नाते, मैं ऊपर की तस्वीर के रूप में दूर तक पाने के लिए खुश हूं। हालांकि, मैं डेटा के साथ कैसे काम करूं? क्रॉस प्रोफाइल की परत प्रत्येक नमूने बिंदु के लिए ऊँचाई को दिखाती है, लेकिन मैं कृपया 1 में मदद मांगूंगा) प्रत्येक क्रॉस लाइन 2 के लिए अधिकतम ऊंचाई ढूंढना) मूल पथ 3 के साथ चौराहे के लिए निर्देशांक खोजना) 1 से अधिकतम ऊंचाई को जोड़ना। निर्देशांक 2 से। क्या कोई मदद कर सकता है, कृपया? अग्रिम में ही बहुत शुक्रिया! Mal
Cpt रेनॉल्ड्स

6

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

import osgeo
from osgeo import ogr
import numpy as np

# ##############################################################################
# User input

# Input shapefile. Must be a single, simple line, in projected co-ordinates
in_shp = r'S:\line_utm_new.shp'

# The shapefile to which the perpendicular lines will be written
out_shp = r'S:\line_utm_neu_perp.shp'

# Profile spacing. The distance at which to space the perpendicular profiles
# In the same units as the original shapefile (e.g. metres)
spc = 100

# Length of cross-sections to calculate either side of central line
# i.e. the total length will be twice the value entered here.
# In the same co-ordinates as the original shapefile
sect_len = 1000
# ##############################################################################

# Open the shapefile and get the data
driverShp = ogr.GetDriverByName('ESRI Shapefile')
sourceShp = driverShp.Open(in_shp, 0)
layerIn = sourceShp.GetLayer()
layerRef = layerIn.GetSpatialRef()

# Go to first (and only) feature
layerIn.ResetReading()
featureIn = layerIn.GetNextFeature()
geomIn = featureIn.GetGeometryRef()

# Define a shp for the output features. Add a new field called 'M100' where the z-value 
# of the line is stored to uniquely identify each profile
outShp = driverShp.CreateDataSource(out_shp)
layerOut = outShp.CreateLayer('line_utm_neu_perp', layerRef, osgeo.ogr.wkbLineString)
layerDefn = layerOut.GetLayerDefn() # gets parameters of the current shapefile
layerOut.CreateField(ogr.FieldDefn('M100', ogr.OFTReal))

# Calculate the number of profiles/perpendicular lines to generate
n_prof = int(geomIn.Length()/spc)

# Define rotation vectors
rot_anti = np.array([[0, -1], [1, 0]])
rot_clock = np.array([[0, 1], [-1, 0]])

# Start iterating along the line
for prof in range(1, n_prof):
    # Get the start, mid and end points for this segment
    seg_st = geomIn.GetPoint(prof-1) # (x, y, z)
    seg_mid = geomIn.GetPoint(prof)
    seg_end = geomIn.GetPoint(prof+1)

    # Get a displacement vector for this segment
    vec = np.array([[seg_end[0] - seg_st[0],], [seg_end[1] - seg_st[1],]])    

    # Rotate the vector 90 deg clockwise and 90 deg counter clockwise
    vec_anti = np.dot(rot_anti, vec)
    vec_clock = np.dot(rot_clock, vec)

    # Normalise the perpendicular vectors
    len_anti = ((vec_anti**2).sum())**0.5
    vec_anti = vec_anti/len_anti
    len_clock = ((vec_clock**2).sum())**0.5
    vec_clock = vec_clock/len_clock

    # Scale them up to the profile length
    vec_anti = vec_anti*sect_len
    vec_clock = vec_clock*sect_len

    # Calculate displacements from midpoint
    prof_st = (seg_mid[0] + float(vec_anti[0]), seg_mid[1] + float(vec_anti[1]))
    prof_end = (seg_mid[0] + float(vec_clock[0]), seg_mid[1] + float(vec_clock[1]))

    # Write to output
    geomLine = ogr.Geometry(ogr.wkbLineString)
    geomLine.AddPoint(prof_st[0],prof_st[1])
    geomLine.AddPoint(prof_end[0],prof_end[1])
    featureLine = ogr.Feature(layerDefn)
    featureLine.SetGeometry(geomLine)
    featureLine.SetFID(prof)
    featureLine.SetField('M100',round(seg_mid[2],1))
    layerOut.CreateFeature(featureLine)

# Tidy up
outShp.Destroy()
sourceShp.Destroy()

धन्यवाद ket - मैंने यह कोशिश की है लेकिन यह दुर्भाग्य से मेरे लिए पूरी तरह से काम नहीं कर रहा है। मैंने स्क्रिप्ट को एक सिंगल पॉलीलाइन फीचर के साथ शेपफाइल दिया है, लेकिन मेरा आउटपुट "एम 100" मान के लिए बहुत सारे शून्य के साथ सिर्फ विशेषता तालिका है - मानचित्र में कोई विशेषताएं नहीं दिखा रहा है। विचार?
davehughes87

कोई बात नहीं - अब एहसास हुआ कि आपकी स्क्रिप्ट पॉलीलाइन के प्रत्येक खंड के ENDS पर लंबवत रेखाओं की गणना करती है, न कि हर "spc" मीटर पर। इसका मतलब यह है कि मैं पॉलीलाइन से बाहर काम करने के लिए दौड़ रहा था, इससे पहले कि n_prof लूप में पहुंच जाए और "नैन" मूल्यों का उत्पादन किया जा रहा था।
davehughes87
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.