আমার দুটি ছেদযুক্ত রেখার বৈশিষ্ট্যযুক্ত ক্লাস রয়েছে। আমি আর্কজিআইএস 10 এবং পাইথন ব্যবহার করে চৌরাস্তার প্রতিটি বিন্দুতে কোণটি খুঁজতে চাই।
কেউ সাহায্য করতে পারেন?
আমার দুটি ছেদযুক্ত রেখার বৈশিষ্ট্যযুক্ত ক্লাস রয়েছে। আমি আর্কজিআইএস 10 এবং পাইথন ব্যবহার করে চৌরাস্তার প্রতিটি বিন্দুতে কোণটি খুঁজতে চাই।
কেউ সাহায্য করতে পারেন?
উত্তর:
অপেক্ষাকৃত সরল কর্মপ্রবাহ রয়েছে। এটি দুটি সম্ভাব্য সমস্যাগুলি কাটিয়ে উঠেছে যে দুটি বৈশিষ্ট্য একের বেশি পয়েন্টে ছেদ করতে পারে। এর জন্য স্ক্রিপ্টিংয়ের প্রয়োজন নেই (তবে সহজেই স্ক্রিপ্টে রূপান্তরিত করা যেতে পারে)। এটি প্রাথমিকভাবে আরকজিআইএস মেনু থেকে করা যেতে পারে।
ধারণাটি হল ছেদ বিন্দুগুলির একটি স্তরটি ব্যবহার করা, প্রতিটি পৃথক ছেদক পলিনগুলির জন্য একটি বিন্দু। এই ছেদ পয়েন্টগুলিতে আপনাকে প্রতিটি ছেদকারী পললাইনগুলির একটি ছোট টুকরো অর্জন করতে হবে । তাদের ছেদ কোণগুলি গণনা করতে এই টুকরোগুলির অরিয়েন্টেশনগুলি ব্যবহার করুন।
পদক্ষেপগুলি এখানে:
নিশ্চিত করুন যে পললাইন বৈশিষ্ট্যগুলির প্রত্যেকটিরই এর বৈশিষ্ট্য সারণির মধ্যে একটি অনন্য শনাক্তকারী রয়েছে। ছেদটি পয়েন্ট টেবিলের পলাইনগুলির কিছু জ্যামিতিক বৈশিষ্ট্যে যোগদানের জন্য এটি পরে ব্যবহার করা হবে।
জিওপ্রোসেসিং | ছেদগুলি পয়েন্টগুলি গ্রহণ করে ( আউটপুটটির জন্য আপনাকে পয়েন্টগুলি নির্দিষ্ট করতে হবে তা নিশ্চিত করুন )।
জিওপ্রসেসিং | বাফার আপনাকে অল্প পরিমাণে পয়েন্টগুলি বাফার করতে দেয়। এটি তৈরি করতে সত্যিই অতি ক্ষুদ্র, যাতে একটি বাফার মধ্যে প্রতিটি লাইনের অংশ বক্র করে না।
জিওপ্রসেসিং | ক্লিপ (দুবার প্রয়োগ করা হয়েছে) মূল পললাইন স্তরগুলিকে কেবল বাফারগুলিতে সীমাবদ্ধ করে। কারণ এটি এর আউটপুট জন্য নতুন ডেটাসেট উত্পাদন করে, পরবর্তী ক্রিয়াকলাপগুলি মূল ডেটা (যা একটি ভাল জিনিস) পরিবর্তন করবে না।
যা ঘটে তার একটি পরিকল্পনাকারী: হালকা নীল এবং হালকা লাল দেখানো দুটি পললাইন স্তর অন্ধকার ছেদ পয়েন্ট তৈরি করেছে। এই পয়েন্টগুলির চারপাশে ক্ষুদ্র বাফারগুলি হলদে দেখানো হয়। গাer় নীল এবং লাল বিভাগগুলি এই বাফারগুলিতে মূল বৈশিষ্ট্যগুলি ক্লিপ করার ফলাফলগুলি দেখায়। বাকি অ্যালগোরিদম অন্ধকার অংশগুলির সাথে কাজ করে। (আপনি এটি এখানে দেখতে পাচ্ছেন না, তবে একটি ছোট্ট লাল পললাইন দুটি নীল লাইনের দুটিকে একটি সাধারণ পয়েন্টে ছেদ করে, যা দুটি নীল পলিনগুলির চারপাশে একটি বাফার হিসাবে প্রদর্শিত হয় red এটি সত্যই দুটি নীল লাল নীল ছেদগুলির দুটি ওভারল্যাপিং পয়েন্টের প্রায় দুটি বাফার Thus , এই চিত্রটি পাঁচটিতে বাফার প্রদর্শন করে)
এই ক্লিপড স্তরগুলির প্রত্যেকটিতে চারটি নতুন ক্ষেত্র তৈরি করতে অ্যাডফিল্ড সরঞ্জামটি ব্যবহার করুন : [এক্স0], [ওয়াই0], [এক্স 1], এবং [ওয়াই 1] তারা পয়েন্ট স্থানাঙ্কগুলি ধরে রাখবে, তাই এগুলিকে দ্বিগুণ করে তুলবে এবং তাদের প্রচুর নির্ভুলতা দেবে।
জ্যামিতি গণনা করুন (প্রতিটি নতুন ক্ষেত্রের শিরোনামে ডান-ক্লিক করে অনুরোধ করা) আপনাকে প্রতিটি ক্লিপড পললাইনটির শুরু এবং শেষ পয়েন্টগুলির এক্স- এবং y- স্থানাঙ্কগুলি গণনা করতে সক্ষম করে: এগুলিকে [X0], [Y0], [X1] এ রাখুন , এবং [Y1] যথাক্রমে। এটি প্রতিটি ক্লিপড লেয়ারের জন্য করা হয়, সুতরাং 8 টি গণনা প্রয়োজন।
ছেদ বিন্দু স্তরে একটি নতুন [কোণ] ক্ষেত্র তৈরি করতে অ্যাডফিল্ড সরঞ্জামটি ব্যবহার করুন ।
সাধারণ অবজেক্ট শনাক্তকারীদের উপর ভিত্তি করে ছেদযুক্ত টেবিলগুলিকে ছেদ বিন্দু টেবিলটিতে যোগ দিন । (যোগদানের স্তরের নামটিতে ডান ক্লিক করে এবং "যোগদান ও সংযুক্তি" নির্বাচন করে সম্পাদনা করা হয়))
এই মুহুর্তে পয়েন্ট ছেদ টেবিলের 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, dy) প্রথম পললাইনটির জন্য একটি দিক ভেক্টর এবং (dxa, dya) দ্বিতীয়টির জন্য একটি দিক ভেক্টর। তাদের দৈর্ঘ্য, আর এবং রা (পাইথাগোরিয়ান উপপাদ্য দিয়ে গণনা করা) এগুলি ইউনিট ভেক্টরগুলিতে স্বাভাবিক করার জন্য ব্যবহৃত হয়। (শূন্য দৈর্ঘ্যের ক্ষেত্রে কোনও সমস্যা হওয়ার দরকার নেই, কারণ ক্লিপিংয়ের ফলে ইতিবাচক দৈর্ঘ্যের বৈশিষ্ট্য তৈরি হওয়া উচিত)) তাদের কীলক পণ্য dx dya - dydxa (r এবং ra দ্বারা বিভাজনের পরে) হ'ল কোণটির সাইন। (স্বাভাবিক অভ্যন্তরীণ পণ্যের চেয়ে কীলক পণ্যটি ব্যবহার করা কাছাকাছি-শূন্য কোণগুলির জন্য আরও ভাল সংখ্যাগত নির্ভুলতা সরবরাহ করা উচিত)) অবশেষে, কোণটি রেডিয়ান থেকে ডিগ্রীতে রূপান্তরিত হয়। ফলাফলটি 0 এবং 90 এর মধ্যে থাকবে very ত্রৈমাসিকের এড়াতে খুব শেষ অবধি নোট করুন: এই পদ্ধতিটি নির্ভরযোগ্য এবং সহজেই গণনার ফলাফল উত্পন্ন করে।
কিছু পয়েন্ট ছেদ স্তরটিতে একাধিকবার প্রদর্শিত হতে পারে। যদি তা হয় তবে তারা তাদের সাথে যুক্ত একাধিক কোণ পাবে।
এই সমাধানটিতে বাফারিং এবং ক্লিপিং তুলনামূলকভাবে ব্যয়বহুল (3 এবং 4 ধাপ): যখন লক্ষ লক্ষ ছেদ পয়েন্ট জড়িত থাকে আপনি এইভাবে এটি করতে চান না। আমি এটি সুপারিশ করেছি কারণ (ক) এটি তার ছেদ বিন্দুর আশেপাশের প্রতিটি পললাইন বরাবর দুটি ধারাবাহিক পয়েন্ট সন্ধানের প্রক্রিয়াটিকে সহজতর করে এবং (খ) বাফারিং এতটা মৌলিক যে কোনও জিআইএসে করা সহজ - কোনও অতিরিক্ত লাইসেন্সিংয়ের দরকার নেই বেসিক আরক্যাম্যাপ স্তরের উপরে - এবং সাধারণত সঠিক ফলাফল দেয়। (অন্যান্য "জিওপ্রসেসিং" অপারেশনগুলি এত নির্ভরযোগ্য নাও হতে পারে))
!table1.x0!
।
আমি বিশ্বাস করি আপনার পাইথন স্ক্রিপ্ট তৈরি করা দরকার।
আপনি জিওপ্রসেসিং সরঞ্জাম এবং আরকিপি ব্যবহার করে এটি করতে পারেন।
এখানে আপনার জন্য দরকারী হতে পারে যে প্রধান সরঞ্জাম এবং ধারণা:
পদক্ষেপ 2 কোড করা খুব কঠিন হয়ে উঠতে পারে (কিছু সরঞ্জামের জন্য আর্কইনফো লাইসেন্স প্রয়োজন)। তারপরে আপনি প্রতিটি পললাইনের প্রান্তগুলি বিশদ বিশ্লেষণ করার চেষ্টা করতে পারেন (ছেদ করার পরে তাদের আইডি দ্বারা গোষ্ঠীকরণ)।
এটি করার উপায় এখানে:
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)।
আর্কম্যাপ কনসোলে চলছে তবে সহজেই টুলবক্সের স্ক্রিপ্টে রূপান্তরিত করা যেতে পারে। এই স্ক্রিপ্টটি কেবলমাত্র টিওসি-তে কেবল লাইন স্তর ব্যবহার করে।
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)