Temat: Przestrzenna numeracja odcinków w linii

Cześć,
mam kłopot z automatyczną numeracją wewnątrz liniowego shp'a. Jest to linia ciągła pocięta na wiele odcinków poprzez intersekcję z katastrem. Niestety nie ma obecnie atrybutów które pozwoliły by wygenerować listę w kolejności jak biegnie linia (kolejność obiektów w tabeli atrybutów jest losowa, tzn zależy od kolejności obiektów w katastrze). Czy jest jakiś sposób na numerację względem kierunku, po kolei obiektów w obrębie linii?

PS. Mam nadzieję że nie skomplikowałem za bardzo.

pozdrawiam,
Zbyszek
Marcin Kułak

Marcin Kułak Specjalista GIS,
Państwowy Instytut
Geologiczny

Temat: Przestrzenna numeracja odcinków w linii

Uwzględnienie zmiany współrzędnych? Czyli jeśli linia biegnie z SW na NE, to zarówno X, jak i Y rosną - dla każdego n+1 odcinka obie współrzędne (początku, końca albo środka linii) są większe niż dla odcinka n.

Temat: Przestrzenna numeracja odcinków w linii

Przy założeniu, że każdy segment posiada wspólny dla całej linii identyfikator, możesz spróbować następującego podejścia:
1. Dodaj 2 pola (StrtCoordX, EndCoordX) i policz w nich współrzędną X początka i końca linii (narzędzie Calculate Geometry pod PPM, z listy wybierz odpowiednią współrzędną do obliczenia).
2. Porównanie współrzędnych końca i początku sąsiadujących linii. Można to zrobić np. wykorzystując ArcGIS i słowniki w Pythonie:
import arcpy
inFC = r"C:\tmp\Shp\Lines.shp"
oidField = "FID"

#stworzenie slownika gdzie kluczem jest OID a wartosciami wspolrzedna X poczatka i konca oraz ID linii
sCur = arcpy.SearchCursor(inFC)
coordDict = dict([(row.getValue(oidField)+1, [row.StrtCoordX, row.EndCoordX, row.ID]) for row in sCur])

orderDict = {} #slownik wyjsciowy do ktorego bedzie zapis numerowania
for key in coordDict:
if not key in orderDict: #sprawdzenie, czy dla danego segmentu jest juz numerowanie
while key: #petla przechodzaca po wszystkich segmentach jednej linii
startCoord = coordDict[key][0]
endCoord = coordDict[key][1]
segmentID = coordDict[key][2]

#szukanie segmentu gdzie wsp. poczatku biezacego segmentu jest wsp. konca
#(szukanie poprzedniego segmentu)
prevSegment = [sKey for sKey, sValue in coordDict.iteritems() if sValue[1] == startCoord]
#jesli nie znaleziono segmentu ze wsp. konca, to mamy poczatek calej linii: numeracja od 1
if not prevSegment:
orderDict[key] = 1
prevSegKey = key
else:
#jesli jest segment poprzedni ale zmieniony jest ID linii, to tez numerowanie od 1
prevSegmentIDLst = []
for prevSementSng in prevSegment:
prevSegmentID = coordDict[prevSementSng][2]
prevSegmentIDLst.append(prevSegmentID)
if segmentID not in prevSegmentIDLst:
orderDict[key] = 1
prevSegKey = key

#szukanie segmentu gdzie wsp. konca biezacego segmentu jest wsp. poczatku
#(szukanie kolejnego segmentu)
nextSegment = [sKey for sKey, sValue in coordDict.iteritems() if sValue[0] == endCoord]
#jesli znaleziono kolejny segment i ma takie same ID linii jak biezacy to kontynuacja numerowania
if nextSegment:
for nextSegmentSng in nextSegment:
nextSegmentID = coordDict[nextSegmentSng][2]
if segmentID == nextSegmentID:
orderDict[nextSegmentSng] = orderDict[prevSegKey] + 1
prevSegKey = nextSegmentSng
key = nextSegmentSng
break
else:
key = False
else:
key = False #koniec petli dla jednej linii

#wpisanie wartosci ze slownika do pola
updCursor = arcpy.UpdateCursor(inFC)
for row in updCursor:
rowID = row.getValue(oidField)
row.Ordered = orderDict[(rowID+1)]
updCursor.updateRow(row)

del updCursor, row


Powyższy kod testowałem na próbce lini z rezultatami jak na obrazku:

Obrazek
Marcin Gąsior edytował(a) ten post dnia 18.07.12 o godzinie 06:52

Następna dyskusja:

Arc GIS - rozbicie linii na...




Wyślij zaproszenie do