ارتباطات بین خطوط بااستفاده از VB.NET و ArcGIS 10
شاید برای شما هم پیش آمده باشید که یک لایه خطی- مثلا شبکه معابر، راه ها، رودخانه ها و…- داشته و بخواهید بدانید هر کدام از خطوط این لایه با چه خطوطی ارتباط دارد و به چه خطوطی وصل است. اما لایه خطی به خودی خود هیچ اطلاعی در این زمینه در اختیار شما قرار نمی دهد.
البته در بسیاری از موارد که به چنین اطلاعی نیاز هست معمولا پای یک آنالیز شبکه در میان است و چون آنالیزهای شبکه را می توان با ساخت یک شبکه هندسی (Geometric Network) از روی لایه خطی مورد نظر در ArcCatalog یا ArcMap و سپس استفاده از این شبکه هندسی در آنالیز به انجام رساند طبیعتا نیاز شما به دانستن ارتباطات بین خطوط مرتفع می شود؛ چرا که شبکه هندسی همه این ارتباطات را درون خود دارد.
اما شبکه هندسی این ارتباطات را در اختیار شما قرار نمی دهد بلکه به طور ضمنی درون خود ذخیره می کند. شما از شبکه هندسی تنها یک لایه خطی و یک لایه نقطه ای مربوط به گره ها را خواهید دید. (گره محل تقاطع خطوط است که می تواند نمایانگر چهارراه، میدان، …. باشد). کاری که اینجا برای حل مشکل در پی انجام آن هستیم افزودن دو فیلد به لایه خطی است که گره ابتدایی و گره انتهایی هر خط را مشخص می کنند. با وجود این دو فیلد- ولو که لایه گره ها را نداشته باشید- باز می توانید ارتباطات بین خطوط را تعیین کنید. کافی است در جدول مقدار گره ابتدایی و انتهایی خط مورد نظر را خوانده و سپس با انجام یک تحلیل Select By Attribute ببینید چه عوارضی در فیلد گره ابتدایی و انتهایی مقدار این دو گره وجود دارد. این عوارض همان خطوطی هستند که به خط موردنظر ما متصل هستند.
اما فیلد گره ابتدایی (From_Node) و گره انتهایی (To_Node) را چگونه باید ساخت؟ اینجاست که کد زیر که در ArcObjects 10 نوشته شده است به کمک شما می آید. اما قبل از پرداختن به کد:
۱- از دستور Planarize Lines در نوارابزار Toplogy برای شکستن خطوط در جایی که اتصال وجود دارد استفاده کنید. این دستور باعث می شود که خطوطی که از روی همدیگر عبور کرده اند در محل تقاطع به خطوط کوچکتری شکسته شوند. (برای استفاده از این گزینه باید Start Editing از تولبار Editing را فعال کرده و سپس تمام عوارض درون لایه را انتخاب کنید تا دکمه Planarize فعال شود.)
۲- یک Network Dataset از روی لایه خطی بسازید. با این عمل شما یک لایه نقطه ای به نام Junctions دارید که محل تقاطع ها را به شما نشان می دهید. از این لایه نقطه ای یک خروجی Shapefile بگیرید. در ادامه از این لایه استفاده خواهیم کرد.
اصل برنامه که در محیط VB.NET و ArcGIS 10 نوشته شده به شکل زیر است:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
Dim pMxDoc As ESRI.ArcGIS.ArcMapUI.IMxDocument = My.ArcMap.Application.Document Dim pMap As IMap = pMxDoc.FocusMap
Dim pointFtrLyr As IFeatureLayer pointFtrLyr = pMap.Layer(0) Dim lineFtrLyr As IFeatureLayer lineFtrLyr = pMap.Layer(1)
Dim lineFC As IFeatureClass lineFC = lineFtrLyr.FeatureClass Dim fromNodeIndex As Integer fromNodeIndex = lineFC.FindField("FROM_NODE") Dim toNodeIndex As Integer toNodeIndex = lineFC.FindField("TO_NODE")
Dim pFI2 As IFeatureIndex2 pFI2 = New FeatureIndex
pFI2.FeatureClass = pointFtrLyr.FeatureClass pFI2.OutputSpatialReference("Shape") = pMxDoc.FocusMap.SpatialReference pFI2.Index(Nothing, pointFtrLyr.AreaOfInterest)
Dim m_IQ2 As IIndexQuery2 m_IQ2 = pFI2
Dim pLineCursor As IFeatureCursor pLineCursor = lineFtrLyr.Search(Nothing, False)
Dim pLineFeature As IFeature pLineFeature = pLineCursor.NextFeature
Dim foid As Long Dim toid As Long Dim fdist As Double Dim tdist As Double
While Not pLineFeature Is Nothing
Dim pLine As IPolyline pLine = pLineFeature.Shape m_IQ2.NearestFeature(pLine.FromPoint, foid, fdist)
If Math.Round(fdist, 0) = 0 Then
pLineFeature.Value(pLineFeature.Fields.FindField("FROM_NODE")) = foid pLineFeature.Store()
End If
m_IQ2.NearestFeature(pLine.ToPoint, toid, tdist) If Math.Round(tdist, 0) = 0 Then pLineFeature.Value(pLineFeature.Fields.FindField("TO_NODE")) = toid pLineFeature.Store() End If
pLineFeature = pLineCursor.NextFeature Loop
MsgBox("Features updated!!") |
در این کد فرض شده که در محیط ArcGIS، لایه گره ها (Nodes.shp) لایه اول و لایه خطی شما لایه دوم از فهرست لایه هاست. این کد برای قالب AddIn و در Visual Studio 2008 نوشته شده است و در محیط ArcObjects قابل استفاده است. برای محیط ArcEngine کد فوق نیاز به تغییراتی جزئی در بخش معرفی نقشه و لایه ها در ابتدای برنامه خواهد داشت.
همچنین برای اجرای کد فوق نیاز دارید تا ارجاعاتی (Reerences) را به کتابخانه های Carto ، Geodatabase و Geometry به پروژه خود در Visual Studio اضافه کرده و این کتابخانه در بالای کلاس خود تعریف کنید. تعریف این کلاس ها در VB.NET با دستورات زیر انجام می شود که قبل از اولین خط تعریف کلاس قرار می گیرند:
|
1 2 3 4 5 |
Imports ESRI.ArcGIS.Carto
Imports ESRI.ArcGIS.Geodatabase
Imports ESRI.ArcGIS.Geometry |
کد فوق دو فیلد From_Node و To_Node به لایه خطی شما اضافه می کند که حاوی FID گره ابتدایی و انتهایی هر خط هستند. حال می توانید لایه گره ها را حذف کرده و از لایه خطی خود برای انجام آنالیزهایی که نیاز دارید استفاده کنید.
حمیدرضاحسن آبادی هستم