Nachbarn festlegen

Hallo Forum,

ich habe folgendes Problem:
Für ein Polygonthema (Gemeindegrenzen) möchte ich gern eine Tabelle erzeugen, in der für jedes Polygon steht, wer Nachbar ist. D.h. 1. Spalte ID (des Polygons), 2. Spalte ID (des 1. Nachbars), 3. Spalte ID (des 2. Nachbars etc.
Kann mir jemand einen Hinweis geben, wie man so etwas macht oder ob es gar eine Extention gibt oder ???

Als kleine Herausforderung hat Schleswig-Holstein auch noch Inseln. D.h. Es gibt Polygone, die nur über das Wasser Nachbarn sind.

Gruß Ron
Hallo Ron,

hier ist erstmal ein Skript, das dir die Nachbarn notiert:

' View.PolygonNoteNeighbors

' Schreibt die ID (Zahl oder Name) aller Nachbarn
' eines jeden Polygons des ersten aktiven Polygon-
' themas im View in eine neue Tabelle:

' [Class] [Neighbor]
' PlgA PlgB
' PlgA PlgC
' PlgA PlgF
' PlgB PlgA
' PlgB PlgC
' ... ...

' In der Tabelle des Polygonthemas wird ein Feld benötigt, das
' die Polygone eindeutig identifiziert (RecNo, Name, o.ä.)

'--------------------------------------------------
' GET VIEW, THEME AND TABLE

theView = av.GetActiveDoc
if (theView.Is(View).Not) then return NIL end

theActThms = theView.GetActiveThemes
if (theActThms.Count = 0) then return NIL end

theThm = theActThms.Get(0)
if (theThm.Is(FTheme).Not) then return NIL end

theVTab = theThm.GetFTab
theCN = theVTab.GetShapeClass.GetClassName
if (theCN <> "Polygon") then return NIL end
nRecs = theVTab.GetNumRecords
'--------------------------------------------------
' GET THE IDENTIFIER FIELD, OBTAIN SOME INFO

theFlds = theVTab.GetFields
theIDFld = MsgBox.List(theFlds,"Feld auswaehlen, "+
"das die Polygone eindeutig identifieziert",
"Identifier:"++theThm.GetName)
if (theIDFld = NIL) then return NIL end
theIDName = theIDFld.GetName
theIDType = theIDFld.GetType
theIDWdth = theIDFld.GetWidth
theIDPrec = theIDFld.GetPrecision

'--------------------------------------------------
' GET SHAPE FIELD

theShpFld = theVTab.FindField("Shape")
if (theShpFld = NIL) then return NIL end
'--------------------------------------------------
' CREATE OUTPUT VTAB WITH FIELDS

theCWD = FileName.getCWD

if (File.isWritable(theCWD).not) then
av.GetProject.GetWorkDIR.setCWD
theCWD = FileName.getCWD
end

theDefNm = theCWD.MakeTMP("Nachb","dbf")

theOutFN = FileDialog.Put(theDefNm,"*.dbf","Output table")
if (theOutFN = nil) then return NIL end

theClassFld = Field.Make(theIDName,theIDType,theIDWdth,theIDPrec)
theParaFld = Field.Make(theIDName.Left(7)+"_NB",theIDType,theIDWdth,theIDPrec)

theNuVTab = VTab.MakeNew(theOutFN,dBase)
theNuVTab.AddFields({theClassFld,theParaFld})

'--------------------------------------------------
' FIND NEIGHBORS

i = 0
for each rec in theVTab
progress = (i/nRecs) * 100
av.ShowMsg("Besuche Nachbarn...")
goesAhead = av.setStatus(progress)
if (not goesAhead) then break end
av.ShowStopButton

theID = theVTab.ReturnValue(theIDFld,rec)
theShp = theVTab.ReturnValue(theShpFld,rec)

theThm.SelectByShapes({theShp},#VTAB_SELTYPE_NEW)

for each theSel in theVTab.GetSelection
theID2 = theVTab.ReturnValue(theIDFld,theSel)
if (theID = theID2) then continue end
theNuRec = theNuVTab.AddRecord
theNuVTab.SetValue(theClassFld,theNuRec,theID)
theNuVTab.SetValue(theParaFld,theNuRec,theID2)
end
i = i + 1
end
'--------------------------------------------------
' TIDY UP AND CREATE TABLE FROM VTAB

av.ClearStatus
av.ShowMsg("Fertig...")

theVTab.GetSelection.ClearAll
theNuVTab.SetEditable(FALSE)
theNuTab = Table.Make(theNuVTab)
theNuTab.SetName(theNuVTab.GetName)
theNuTab.GetWin.Open
'--------------------------------------------------

'THE END

Nun hast du eine Tabelle im Format

[CL], [NB]
PlgA, PlgB
PlgA, PlgC
PlgA, PlgF
PlgB, PlgA
PlgB, PlgC
...

Auf diese Tabelle kannst du jetzt die Memo-Tools Funktion "Feld in Datensatz schreiben" anwenden, wobei du [CL] als Klassenfeld und [NB] als Parameterfeld definierst.

Das ergibt eine weitere Tabelle im Format

[CL], [NB1], [NB2], [NB3],
PlgA, PlgB, PlgC, PlgF
PlgB, PlgA, PlgC
...

d.h. eine Tabelle, in der jede Polygon-ID eindeutig mit seinen Nachbarn in Feldern aufgeführt ist. Diese Tabelle kannst du nun über das [CL] bzw. ID-Feld mittels 'Tabelle | Verbinden' an das Polygonshape hängen.
Fertig...

Gruß von Maxilla

Ach ja, die Inseln: Alle Polygone, die eine Küste haben (also das Meer selber als Nachbarpolygon) sind automatisch "Wassernachbarn"... Aber ich wohne in Hannover, und denke, Hannover ist weit genug von der Küste entfernt, um das für einen Scherz zu halten ;o)
Hallo Maxilla,

vielen Dank für die Hilfe. Ich werde es ausprobieren und mich dann wieder melden. Ich finde es fastzinierend, daß Du tatsächlich für jedes Problem schon ein Script hast.

Die Geschichte mit den Inseln war nicht als Scherz gemeint. Ich bin davon ausgegangen, daß ein Script z.B. nach gemeinsamen Linien zwischen Nachbarn sucht und das ist bei den Inseln ja nun nicht gegeben.

Nochmals danke
Ron
Hi Ron,

na jut, also kein Scherz mit Inseln... Dann frag ich mich aber, wer z.B. die Nachbarn von Amrum sind? Nur Föhr (als nearest neighbour)? Oder auch Sylt? Was ist mit Dagebüll? Oder Brunsbüttel? Und nach Fehmarn kommt man auch, ohne eine andere Gemeinde zu durchqueren...

Ich meine: Bedarfs da nicht einer (Neu-)Definition von "Nachbarschaft" - oder gibt's die schon?

Gruß von gannnz kurz oberhalb des Weißwurstäquators
M.
soso, aus Hannover. Kuck an
NochNKlaus
NochNSherlock ;o)
Hallo Maxilla,

nach einer Weile anderer Dinge konnte ich mich nun endlich wieder meinen Nachbarn widmen. Zunächst einmal bin ich begeistert von dem Script. Läuft super. Dann habe ich natürlich das Problem mit den Inseln. Ich bin mir aber noch nicht sicher, ob ich wirklich ein "Wasserpolygon" einbauen möchte. Eine Nachbarschaft von Glücksburg-Fehmarn-Lübeck bzw. List/Sylt-St.Peter-Ording-Helgoland finde ich irgendwie nicht gerechtfertigt. Möglicherweise baue ich da die Nachbarschaft per Hand ein.
Noch eine Frage zu den Memotools. Bisher habe ich die o.g. Funktion "Feld in Datensatz schreiben" in meiner englichen Version (5.7)nicht gefunden. Ich habe zwar viele andere Funktionen getestet und gefunden, von denen mich manche in Euphorie ausbrechen ließen und von anderen habe ich keine Ahnung wozu man so etwas braucht. Insgesamt war es aber sehr lehrreich. Nur das eigentliche Problem konnte ich nicht lösen. Hast Du vielleicht mal den Funktionsnamen der englischen Version.
Viele Grüße und schöne Weihnachten
Ron
Hallo,

manche Dinge erledigen sich von selbst. In den neuen Memo-Tools (6.0) hab' ich die entsprechende Funktion gefunden.
Viele Grüße
Ron
Hallo Forum,

trotz meiner gestrigen Euphorie hat sich jetzt doch noch einmal das Inselproblem ergeben. In meiner Kartengrundlage existieren nur die Polygone für die administrativen Einheiten (Ämter oder Gemeinden). Das Meer gibt es nicht als Polygon. Auf Ebene der Ämter kann man das Problem der Nachbarn noch per Hand lösen, aber als ich mich gerade auf die Gemeindeebene begeben wollte, ist mir aufgefallen, daß jetzt eine erhebliche Arbeit auf mich zukommt.

Ist es irgendwie möglich, das ich für bestimmte Meeresbereiche auch (Meeres)Polygone definiere, so daß Gemeindepolygone innerhalb dieses Meerespolygons als Nachbarn festgelegt werden?

Welche Besonderheit muß das Meerespolygon aufweisen, daß nicht das Meer als Nachbar von Insel A definiert wird, sondern Insel B Nachbar ist? Ist das Meerespolygon Teil des gleichen Themas, wie die Gemeinden?

Und da ich schon beim Fragen bin: Zum Erstellen des Meerespolygons habe ich gedacht, erstelle ein Thema mit einem großen Rechteck (Meer)über alle Inseln und Küstengebiete und subtrahiere dann einfach z.B. per X-Tools alles was Land ist. Fertig. Aber natürlich erhalte ich als Ergebnis immer (mit Intersect und Clip) nur die Landflächen. Gibt es keine andere Lösung als mit "Convert to Graphic" , "Combine Graphics" und "Convert to Shapefile" zu arbeiten?

Viele Weihnachtsgrüße
Ron
Hallo,

auch wenn ich jetzt zum vierten Mal hintereinander hier poste, ich würde dieses Nachbarschaftsthema aus dem Weihnachtsloch gern noch einmal nach oben holen.
Ein Teil hat sich erledigt, mittlerweile hab ich ERASE gefunden.
Mit dem Meer als Polygon hab ich aber immer noch Schwierigkeiten. Wie schaffe ich es, daß statt des Meeres als Nachbar einer Insel das Land hinter dem Meer als Nachbar angegeben wird???
Maxilla, wie werden Polygone mit Küste automatisch "Wassernachbarn"?

Ron
Hallo Ron,

ich meinte, es käme darauf an, zu schauen welche Nachbarn deine Meerespolygone selber haben:

Angenommen du hast ein Meerespolygon mit einem dir zur Nachbarschaftsbestimmung angemessen erscheinenden (?) Radius erstellt, das z.B. alle Nachbarn Amrums definieren soll und dieses in dein Gemeindeshape eingebaut. Die Nachbarschaftsanalyse ergibt nun für dieses Wasserpolygon die Nachbarn Föhr, Sylt und Amrum. So hat also Amrum die "Wassernachbarn" Föhr und Sylt, Föhr hat wiederum die Nachbarn Sylt und Amrum uswusf - d.h. alle Nachbarpolygone, die für das zugehörige Wasserpolygon notiert wurden sind automatisch "Wassernachbarn" (if you know what I mean :)

Maxilla
Hallo Maxilla,

ich verstehe, dann bin ich ja am Ziel. Vielen Dank noch einmal für alle Hilfe hier.
Da Wasser nicht in der Nachbarschaftsmatrix auftauchen darf, werde ich die Tabelle mal mit SPSS nachbehandeln und die Wassernachbarn miteinander vereinen. Die Wasserpolygone werde ich wohl eher prakmatisch definieren müssen, aber das klappt schon.

Grüße aus HL nach H
Hallo Ron, Hallo Maxilla,

ich bin eher durch Zufall auf diesen Thread gestossen. Er schien mir sehr hilfreich da gelegentlich benachbarte Flurstücke gesucht werden müssen.

Die Suche nach den Nachbarn verlief sehr schnell aber die Funktion "Feld in Datensatz schreiben" läuft jetzt schon fast einen Tag. Bisher wurden aber erst 10% der Tabelleneinträge gefüllt. Läuft das bei euch auch sol langsam? Kann man das Verfahren beschleuningen? Ich kann doch meinen Rechner nicht 2 Wochen durchlaufen lassen (Prozessorlast: 100%)

Gruß
GisMoe
Hallo GisMoe,

ich hab' es gerade noch einmal getestet. Für meine Tabelle mit 7035 Zeilen hat mein Rechner ziemlich genau 4 Minuten gebraucht. Also entweder ist Dein Datensatz erheblich größer oder es liegt an etwas anderem, dann kann ich Dir vermutlich aber nicht weiterhelfen.

Gruß
Ron
Also die Ergebnistabelle des Skriptes hat ca. 500.000 Einträge. Das würde die etwas längere Laufzeit begründen ;-)))

Gibt es nach erfolgreichem Durchlauf die Möglichkeit das man sich per einfachem Klick alle Nachbarn anzeigen/markieren lassen kann?

Ich habe es mit verbundenen Tabellen versucht. Aber die Richtung die benötige liefert mir eine 1:n - Verbindung!

Gruß GisMoe
Dafür gibt's den Eintrag 'Tabelle | Verknüpfen'