मेरे पास दो इंटरसेक्टिंग लाइन फीचरक्लासेस हैं। मैं ArcGIS 10 और पायथन का उपयोग करके चौराहे के प्रत्येक बिंदु पर कोण खोजना चाहता हूं।
क्या कोई मदद कर सकता है?
मेरे पास दो इंटरसेक्टिंग लाइन फीचरक्लासेस हैं। मैं ArcGIS 10 और पायथन का उपयोग करके चौराहे के प्रत्येक बिंदु पर कोण खोजना चाहता हूं।
क्या कोई मदद कर सकता है?
जवाबों:
अपेक्षाकृत सरल वर्कफ़्लो है। यह उन संभावित समस्याओं को खत्म करता है जो दो सुविधाओं को एक से अधिक बिंदुओं में काट सकती हैं। इसके लिए स्क्रिप्टिंग की आवश्यकता नहीं है (लेकिन आसानी से इसे स्क्रिप्ट में बदल दिया जा सकता है)। यह मुख्य रूप से आर्कगिस मेनू से किया जा सकता है।
विचार चौराहे के बिंदुओं की एक परत का दोहन करने के लिए है, प्रत्येक अलग-अलग जोड़े को पॉलीसिनेज़ के लिए एक बिंदु। आपको इन चौराहों बिंदुओं पर प्रत्येक इंटरसेक्टिंग पॉलीलाइन का एक छोटा सा टुकड़ा प्राप्त करने की आवश्यकता है । इन टुकड़ों के झुकावों का उपयोग उनके प्रतिच्छेदन कोणों की गणना करने के लिए करें।
यहाँ कदम हैं:
सुनिश्चित करें कि प्रत्येक पॉलीलाइन विशेषताओं में इसकी विशेषता तालिका के भीतर एक विशिष्ट पहचानकर्ता है। इसका उपयोग बाद में पॉलीनेस की कुछ ज्यामितीय विशेषताओं को प्रतिच्छेदन बिंदु तालिका में शामिल करने के लिए किया जाएगा।
जियोप्रोसेसिंग | इंट्रैक्ट अंक प्राप्त करता है (यह सुनिश्चित करें कि आप आउटपुट के लिए अंक चाहते हैं )।
जियोप्रोसेसिंग | बफर आपको एक छोटी राशि द्वारा अंक बफर करने देता है। इसे वास्तव में छोटा करें ताकि एक बफर के भीतर प्रत्येक पंक्ति का हिस्सा झुकता न हो।
जियोप्रोसेसिंग | क्लिप (दो बार लागू) मूल पॉलीलाइन परतों को सिर्फ बफ़र्स तक सीमित करता है। क्योंकि यह अपने आउटपुट के लिए नए डेटासेट का उत्पादन करता है, बाद के संचालन मूल डेटा (जो कि एक अच्छी बात है) को संशोधित नहीं करेगा।
यहां एक योजनाबद्ध होता है कि क्या होता है: हल्के नीले और हल्के लाल रंग में दिखाए गए दो पॉलीलाइन परतों ने अंधेरे चौराहे बिंदुओं का उत्पादन किया है। उन बिंदुओं के आसपास छोटे बफ़र्स को पीले रंग में दिखाया गया है। गहरे नीले और लाल खंडों में इन बफ़र्स की मूल विशेषताओं को क्लिप करने के परिणाम दिखाई देते हैं। बाकी एल्गोरिदम अंधेरे सेगमेंट के साथ काम करता है। (आप इसे यहाँ नहीं देख सकते हैं, लेकिन एक छोटी सी लाल पॉलीलाइन एक सामान्य बिंदु पर दो नीली रेखाओं को काटती है, जो दो नीली पॉलीलाइनों के आसपास एक बफर प्रतीत होती है। यह वास्तव में लाल-नीले चौराहे के दो अतिव्यापी बिंदुओं के आसपास दो बफ़र्स हैं। इस प्रकार , यह चित्र सभी में पाँच बफ़र्स प्रदर्शित करता है।)
प्रत्येक क्लिप्ड परतों में चार नए फ़ील्ड बनाने के लिए AddField टूल का उपयोग करें : [X0], [Y0], [X1] और [Y1]। वे बिंदु निर्देशांक धारण करेंगे, इसलिए उन्हें युगल बनाएं और उन्हें बहुत अधिक सटीकता दें।
ज्यामिति की गणना करें (प्रत्येक नए फ़ील्ड हेडर पर राइट-क्लिक करके आमंत्रित किया गया) आपको x- और y- प्रत्येक क्लिप किए गए पॉलीलाइन के प्रारंभ और अंत बिंदुओं के निर्देशांक की गणना करने में सक्षम बनाता है: इन्हें [X0], [Y0], [X1] में डालें। , और [Y1], क्रमशः। यह प्रत्येक क्लिप्ड परत के लिए किया जाता है, इसलिए 8 गणनाओं की आवश्यकता होती है।
चौराहे बिंदु परत में एक नया [कोण] क्षेत्र बनाने के लिए AddField टूल का उपयोग करें ।
सामान्य ऑब्जेक्ट आइडेंटिफ़ायर के आधार पर चौराहे के पॉइंट टेबल पर क्लैप्ड टेबल से जुड़ें । (परत नाम पर राइट-क्लिक करके और "जॉइन और रिलेट्स" का चयन करके जॉइन किया जाता है।
इस बिंदु पर प्रतिच्छेदन तालिका में 9 नए क्षेत्र हैं: दो का नाम [X0], आदि है, और एक का नाम [कोण] है। अन्य नाम [X0], [Y0], [X1] और [Y1] फ़ील्ड जो सम्मिलित तालिकाओं में से एक से संबंधित हैं। आइए इनको कॉल करें (कहें) "X0a", "Y0a", "X1a", और "Y1a"।
चौराहे की तालिका में कोण की गणना करने के लिए फ़ील्ड कैलकुलेटर का उपयोग करें। यहाँ गणना के लिए एक पायथन कोड ब्लॉक है:
dx = !x1!-!x0!
dy = !y1!-!y0!
dxa = !x1a!-!x0a!
dya = !y1a!-!y0a!
r = math.sqrt(math.pow(dx,2) + math.pow(dy,2))
ra = math.sqrt(math.pow(dxa,2) + math.pow(dya,2))
c = math.asin(abs((dx*dya - dy*dxa))/(r*ra)) / math.pi * 180
क्षेत्र गणना की अभिव्यक्ति, निश्चित रूप से, केवल है
c
इस कोड ब्लॉक की लंबाई के बावजूद, गणित सरल है: (डीएक्स, डाई) पहली पॉलीलाइन के लिए एक दिशा वेक्टर है और (डीएक्सए, डीएए) दूसरे के लिए एक दिशा वेक्टर है। उनकी लंबाई, आर और आरए (पायथागॉरियन प्रमेय के माध्यम से गणना की जाती है), उन्हें यूनिट वैक्टर को सामान्य करने के लिए उपयोग किया जाता है। (वहाँ शून्य लंबाई के साथ कोई समस्या नहीं होनी चाहिए, क्योंकि क्लिपिंग को सकारात्मक लंबाई की सुविधाओं का उत्पादन करना चाहिए।) उनके वेज उत्पाद का आकार dx dya - dydxa (r और ra द्वारा विभाजन के बाद) कोण की साइन है। (सामान्य आंतरिक उत्पाद के बजाय कील उत्पाद का उपयोग करना लगभग शून्य कोण के लिए बेहतर संख्यात्मक परिशुद्धता प्रदान करना चाहिए।) अंत में, कोण रेडियन से डिग्री में परिवर्तित हो जाता है। परिणाम 0 और 90 के बीच रहेगा। त्रिकोणमिति के परिहार पर ध्यान दें, जब तक कि अंत नहीं हो जाता: यह दृष्टिकोण विश्वसनीय और आसानी से गणना किए गए परिणामों का उत्पादन करता है।
कुछ बिंदु चौराहे की परत में कई बार दिखाई दे सकते हैं। यदि हां, तो उन्हें उनसे जुड़े कई कोण मिलेंगे।
इस समाधान में बफरिंग और क्लिपिंग अपेक्षाकृत महंगी हैं (चरण 3 और 4): आप इसे इस तरह से नहीं करना चाहते हैं जब लाखों चौराहे बिंदु शामिल होते हैं। मैंने इसकी सिफारिश की है क्योंकि (ए) इसके चौराहे के पड़ोस के भीतर प्रत्येक पॉलीलाइन के साथ दो क्रमिक बिंदुओं को खोजने की प्रक्रिया को सरल करता है और (बी) बफरिंग इतना बुनियादी है कि किसी भी जीआईएस में करना आसान है - कोई अतिरिक्त लाइसेंसिंग की आवश्यकता नहीं है मूल आर्केपॉयर स्तर से ऊपर - और आमतौर पर सही परिणाम पैदा करता है। (अन्य "जियोप्रोसेसिंग" संचालन इतना विश्वसनीय नहीं हो सकता है।)
!table1.x0!
।
मेरा मानना है कि आपको अजगर की स्क्रिप्ट बनाने की आवश्यकता है।
आप इसे जियोप्रोसेसिंग टूल और आर्कपी का उपयोग करके कर सकते हैं।
यहाँ मुख्य उपकरण और विचार हैं जो आपके लिए उपयोगी हो सकते हैं:
हो सकता है कि चरण 2 को कोड करना भी बहुत मुश्किल होगा (कुछ उपकरणों के लिए ArcInfo लाइसेंस की आवश्यकता होती है)। फिर आप हर पॉलीलाइन के वर्टिकल का विश्लेषण करने की कोशिश कर सकते हैं (उन्हें चौराहे के बाद आईडी द्वारा समूहित कर सकते हैं)।
यहाँ यह करने का तरीका है:
point_x
, point_y
)vert0_x
, vert0_y
) और दूसरे ( vert1_x
, vert1_y
) को लें।tan0 = (point_y - vert0_y) / (point_x - vert0_x)
tan1 = (vert1_y - point_y) / (vert1_x - point_x)
tan1
के बराबर है tan2
, तो आपको अपनी रेखा के दो कोने मिलेंगे, जिनके बीच में चौराहा बिंदु है और आप इस रेखा से चौराहे के कोण की गणना कर सकते हैं। अन्यथा आपको वर्धमान की दूसरी जोड़ी (दूसरी, तीसरी) और इसी तरह आगे बढ़ना होगा।हाल ही में मैं इसे अपने दम पर करने की कोशिश कर रहा था।
मेरा क्लू फ़ीचर लाइनों के चौराहों के साथ-साथ चौराहों से एक-मीटर की दूरी पर स्थित बिंदुओं के चारों ओर गोलाकार बिंदुओं पर आधारित है। आउटपुट पॉलीलाइन फीचर क्लास है जिसमें चौराहों और कोणों पर कोणों की संख्या के गुण हैं।
ध्यान दें कि चौराहों को खोजने के लिए लाइनों को योजनाबद्ध किया जाना चाहिए और स्थानिक संदर्भ को सही लाइन लंबाई प्रदर्शन (मेरा WGS_1984_Web_Mercator_Auxiliary_Sphere) के साथ सेट किया जाना है।
ArcMap कंसोल में चल रहा है लेकिन आसानी से टूलबॉक्स में स्क्रिप्ट में बदल सकता है। यह स्क्रिप्ट टीओसी में केवल लाइन लेयर का उपयोग करती है, इससे अधिक कुछ नहीं।
import arcpy
import time
mxd = arcpy.mapping.MapDocument("CURRENT")
df = mxd.activeDataFrame
line = ' * YOUR POLYLINE FEATURE LAYER * ' # paste the name of line layer here
def crossing_cors(line_layer):
mxd = arcpy.mapping.MapDocument("CURRENT")
df = mxd.activeDataFrame
arcpy.env.overwriteOutput = True
sr = arcpy.Describe(line_layer).spatialReference
dict_cors = {}
dang_list = []
with arcpy.da.UpdateCursor(line_layer, ['SHAPE@', 'OID@']) as uc:
for row in uc:
if row[0] is None:
uc.deleteRow()
with arcpy.da.UpdateCursor(line_layer, 'SHAPE@', spatial_reference = sr) as uc:
for row in uc:
line = row[0].getPart(0)
for cor in line:
coord = (cor.X, cor.Y)
try:
dict_cors[coord] += 1
except:
dict_cors[coord] = 1
cors_only = [f for f in dict_cors if dict_cors[f]!=1]
cors_layer = arcpy.CreateFeatureclass_management('in_memory', 'cross_pnt', "POINT", spatial_reference = sr)
arcpy.AddField_management(cors_layer[0], 'ANGLE_NUM', 'LONG')
with arcpy.da.InsertCursor(cors_layer[0], ['SHAPE@', 'ANGLE_NUM']) as ic:
for x in cors_only:
pnt_geom = arcpy.PointGeometry(arcpy.Point(x[0], x[1]), sr)
ic.insertRow([pnt_geom, dict_cors[x]])
return cors_layer
def one_meter_dist(line_layer):
mxd = arcpy.mapping.MapDocument("CURRENT")
df = mxd.activeDataFrame
arcpy.env.overwriteOutput = True
sr = arcpy.Describe(line_layer).spatialReference
dict_cors = {}
dang_list = []
cors_list = []
with arcpy.da.UpdateCursor(line_layer, 'SHAPE@', spatial_reference = sr) as uc:
for row in uc:
line = row[0]
length_line = line.length
if length_line > 2.0:
pnt1 = line.positionAlongLine(1.0)
pnt2 = line.positionAlongLine(length_line - 1.0)
cors_list.append(pnt1)
cors_list.append(pnt2)
else:
pnt = line.positionAlongLine(0.5, True)
cors_layer = arcpy.CreateFeatureclass_management('in_memory', 'cross_one_meter', "POINT", spatial_reference = sr)
ic = arcpy.da.InsertCursor(cors_layer[0], 'SHAPE@')
for x in cors_list:
ic.insertRow([x])
return cors_layer
def circles(pnts):
import math
mxd = arcpy.mapping.MapDocument("CURRENT")
df = mxd.activeDataFrame
arcpy.env.overwriteOutput = True
sr = df.spatialReference
circle_layer = arcpy.CreateFeatureclass_management('in_memory', 'circles', "POINT", spatial_reference = sr)
ic = arcpy.da.InsertCursor(circle_layer[0], 'SHAPE@')
with arcpy.da.SearchCursor(pnts, 'SHAPE@', spatial_reference = sr) as sc:
for row in sc:
fp = row[0].centroid
list_circle =[]
for i in xrange(0,36):
an = math.radians(i * 10)
np_x = fp.X + (1* math.sin(an))
np_y = fp.Y + (1* math.cos(an))
pnt_new = arcpy.PointGeometry(arcpy.Point(np_x,np_y), sr)
ic.insertRow([pnt_new])
del ic
return circle_layer
def angles(centers, pnts, rnd):
mxd = arcpy.mapping.MapDocument("CURRENT")
df = mxd.activeDataFrame
sr = df.spatialReference
line_lyr = arcpy.CreateFeatureclass_management('in_memory', 'line_angles', "POLYLINE", spatial_reference = sr)
arcpy.AddField_management(line_lyr[0], 'ANGLE', "DOUBLE")
arcpy.AddField_management(line_lyr[0], 'ANGLE_COUNT', "LONG")
ic = arcpy.da.InsertCursor(line_lyr[0], ['SHAPE@', 'ANGLE', 'ANGLE_COUNT'])
arcpy.AddField_management(pnts, 'ID_CENT', "LONG")
arcpy.AddField_management(pnts, 'CENT_X', "DOUBLE")
arcpy.AddField_management(pnts, 'CENT_Y', "DOUBLE")
arcpy.Near_analysis(pnts, centers,'',"LOCATION")
with arcpy.da.UpdateCursor(line, ['SHAPE@', 'OID@']) as uc:
for row in uc:
if row[0] is None:
uc.deleteRow()
with arcpy.da.UpdateCursor(pnts, [u'ID_CENT', u'CENT_X', u'CENT_Y', u'NEAR_FID', u'NEAR_DIST', u'NEAR_X', u'NEAR_Y'], spatial_reference = sr) as uc:
for row in uc:
row[0] = row[3]
row[1] = row[5]
row[2] = row[6]
uc.updateRow(row)
if row[4] > 1.1:
uc.deleteRow()
arcpy.Near_analysis(pnts, rnd,'',"LOCATION")
list_id_cent = []
with arcpy.da.UpdateCursor(pnts, [u'ID_CENT', u'CENT_X', u'CENT_Y', u'NEAR_FID', u'NEAR_DIST', u'NEAR_X', u'NEAR_Y', 'SHAPE@'], spatial_reference = sr) as uc:
for row in uc:
pnt_init = (row[-1].centroid.X, row[-1].centroid.Y)
list_id_cent.append([(row[1], row[2]), row[3], pnt_init])
list_id_cent.sort()
values = set(map(lambda x:x[0], list_id_cent))
newlist = [[y for y in list_id_cent if y[0]==x] for x in values]
dict_cent_angle = {}
for comp in newlist:
dict_ang = {}
for i, val in enumerate(comp):
curr_pnt = comp[i][2]
prev_p = comp[i-1][2]
init_p = comp[i][0]
angle_prev = math.degrees(math.atan2(prev_p[1]-init_p[1], prev_p[0]-init_p[0]))
angle_next = math.degrees(math.atan2(curr_pnt[1]-init_p[1], curr_pnt[0]-init_p[0]))
diff = abs(angle_next-angle_prev)%180
vec1 = [(curr_pnt[0] - init_p[0]), (curr_pnt[1] - init_p[1])]
vec2 = [(prev_p[0] - init_p[0]), (prev_p[1] - init_p[1])]
ab = (vec1[0] * vec2[0]) + (vec1[1] * vec2[1])
mod_ab = math.sqrt(math.pow(vec1[0], 2) + math.pow(vec1[1], 2)) * math.sqrt(math.pow(vec2[0], 2) + math.pow(vec2[1], 2))
cos_a = round(ab/mod_ab, 2)
diff = math.degrees(math.acos(cos_a))
pnt1 = arcpy.Point(prev_p[0], prev_p[1])
pnt2 = arcpy.Point(init_p[0], init_p[1])
pnt3 = arcpy.Point(curr_pnt[0], curr_pnt[1])
line_ar = arcpy.Array([pnt1, pnt2, pnt3])
line_geom = arcpy.Polyline(line_ar, sr)
ic.insertRow([line_geom , diff, len(comp)])
del ic
lyr_lst = [f.name for f in arcpy.mapping.ListLayers(mxd)]
if 'line_angles' not in lyr_lst:
arcpy.mapping.AddLayer(df, arcpy.mapping.Layer(line_lyr[0]))
centers = crossing_cors(line)
pnts = one_meter_dist(line)
rnd = circles(centers)
angle_dict = angles(centers, pnts, rnd)