Avenue - Punkt ermitteln

Guten Morgen,
ich habe einen Punkt, der von seiner Lage aus auf dem kürzesten Weg (aShape.Distance (anotherShape))
auf eine Polylinie verschoben werden soll (aPoint.Move (moveX, moveY)). Nun überlege ich, wie ich an die Koordinaten/ den Endpunkt komme, wohin der Punkt geschoben werden soll. Der Befehl Distance gibt ja nur den Abstand aus.

Hat jemand einen Tip?

Viele Grüße
Sandra
Moin Sandra,

soll der Punkt auf den kürzesten Weg auf die Linie geschoben werden, oder genügt es, wenn er auf den nächstgelegenen Stützpunkt geschoben wird? Im letzteren Fall würde ich mir mal die Scripte ansehen, die beim Digitalisieren für das Snappen zuständig sind.

Jörg Thomsen
Vielleicht weiß es jemand besser, aber ich glaube es ist nicht so ganz trivial, einen Punkt auf die "Boundary" einer Linie zu schieben. Ich schätze, man müsste noch den Rotationswinkel des Liniensegmentes berechnen und diesen in die Punktverschiebung mit einbeziehen (denn der Punkt wird ja immer im 90°-Winkel in Richtung Linie verschoben).

Einfacher ist es, den Punkt auf den nächstgelegenen Linienvertex zu schieben, dafür könnte man die Request aShape.Snap (anotherShape, snapDistance) benutzen.

Du könntest auch mal schauen, wie das im Skript
Snap Point to nearest line based on distance gelöst wird, oder dir die Vorgehensweise in den Edit-Tools oder den Point & Polyline Tools ansehen.

Möglicherweise helfen auch die Skripte weiter, die ein Theme2Theme-Snap machen...
Hast du die Möglichkeit ArcGis zu benutzen? Da gibt es Methoden für genau diese Fragestellung.
ja, ArcGIS habe ich zur Verfügung, jedoch beherrsche ich kein VBA o.ä.

Welcher Art sind denn diese Methoden?
Hallo Jörg und Maxilla,
ja, der Punkt soll auf dem kürzesten Weg auf die Linie geschoben werden. Das macht Sinn, weil ich viele Punkte habe, die auf diese Linie müssen. Wenn ich einen Stützpunkt benutze, kann es passieren, daß zwei zu verschiebende Punkte auf dem selben Stützpunkt landen bzw. mehr zu verschiebende Punkte da sind als Stützpunkte. Mehrere Punkte mit der selben Koordinate gilt es zu vermeiden.
Welcher Art sind denn diese Methoden?

In den ET GeoWizards für ArcGIS gibt's z.B. den "Global Snap" für Punkte. Hier kannst du festlegen, ob die Punkte im Punktthema an die Vertices oder an die Begrenzung des Linienthemas geschoben werden sollen.
Mögliche Methoden sind ReturnNearestPoint oder QueryPointAndDistance. Ganz ohne VBA wirds aber schwierig. Vielleicht reicht ja der ET GeoWizards.
so, wie ich das auf der ET-Homepage sehe, ist der "Global Snap" keine von den Free-functions. vba kann ich auch nicht.Bleibt mir erst mal nur mit Avenue weiterzumachen.Und den Ansatz von Maxilla heute vormittag hatte ich auch schon im Kopf. Bin also auf der Suche, wie man das Ganze in Avenue mit konkreten Methoden umsetzen kann.

Freue mich, wenn Ihr noch Ideen für eine Avenue-Lösung haben solltet.

Viele Dank für Eure Mithilfe.

Viele Grüße
Sandra
Hallo Maxilla,
danke für den Hinweis mit dem
..Skript
Snap Point to nearest line based on distance..

Hier fand ich einen machbaren Lösungsansatz:

Ich ermittle also den kürzesten Weg zwischen Punkt und Liniensegment mit
(aShape.Distance (anotherShape)
dann erstelle ich einen Kreis (Shape) mit der ermittelten Distanz als Radius,
den Kreis verschneide ich dann mit dem LinienThema
Syntax
aShape.PointIntersection (anotherShape)

Returns
MultiPoint

In der MultiPointListe steht dann ein Koordinatenpaar, das ich auslese und wohin ich dann meinen Punkt schieben kann.

So müßte es klappen.

Viele Grüße nochmals
Sandra
Viele dank nochmal für Eure Antworten.

Habe jetzt, wie am 22.6. geschrieben,
den gesuchten Punkt über den /die tangentialen Berührungspunkte/Schnittpunkte eines Kreises am entsprechenden Liniensegment gefunden. Der Kreis hat die Ausgangskoordinaten des zu verschiebenden Punktes zum Mittelpunkt und den kürzesten Weg zum Liniensegemnt als Radius, ermittelt über (aShape.Distance (anotherShape)).
(ergänzend bitte letzten Eintrag vom 22.6. lesen)

Einziges Problem an dieser Methode. Sie funktioniert reibungslos bei Punkten in unmittelbarer Nähe zum Liniensegment. Liegt der Punkt aber über große Entfernungen gibt es manchmal keinen Berührungs- bzw. Schnittpunkt.Obwohl das ja eigentlich unlogisch ist, wenn vorher die kürzeste Strecke zum Liniensegment ermittelt wurde. Habe auch schon aufgerundet, weil ich dachte es ist ein Dezimalstellenproblem, da rundet das System ja selbst.Daran scheint es aber nicht zu liegen. Auch nach dem Aufrunden verfehlt der Kreis minimal das Liniensegment und damit greift die Methode (aShape.PointIntersection (anotherShape))ins Leere.

Habt Ihr dazu noch eine Idee?
Viele Grüße
Sandra
Hallo Sandra,

tut mir leid, keine Ahnung im Moment. Stattdessen möchte ich dich noch einmal auf eine andere Methode hinweisen, vielleicht klappt die besser. Und zwar gibt es da die Requests aPolyLine.PointPosition (aPoint) und aPolyLine.Along (aPercentage) (siehe Hilfeindex). Vielleicht probierst du das mal.
Unten ein paar Codesamples mit denen du die Requests testen kannst.

Gruß von Maxilla


' CODESKIZZE: "ZIEHT" PUNKT AUF LINIE
' Braucht aktives View und zwei aktive Themen:
' ERSTES AKTIVES THEMA: Punktthema mit einem selektierten Punkt
' ZWEITES AKTIVES THEMA: Linienthema mit einer selektierten Linie

' VORGEPLÄNKEL :

theView = av.GetActiveDoc

thePntTheme = theView.GetActiveThemes.Get(0)
theLinTheme = theView.GetActiveThemes.Get(1)

thePntVTab = thePntTheme.GetFTab
theLinVTab = theLinTheme.GetFTab

thePntShapeIn = thePntVTab.FindField("Shape")
theLinShapeIn = theLinVTab.FindField("Shape")

thePntRec = thePntVTab.GetSelection.GetNextSet(-1)
theLinRec = theLinVTab.GetSelection.GetNextSet(-1)

theDistantPnt = thePntVTab.ReturnValue(thePntShapeIn,thePntRec)
theLin = theLinVTab.ReturnValue(theLinShapeIn,theLinRec)


' POSITION DES PUNKTES ENTLANG DER POLYLINIE (PROZENT) :

thePrcntAlong = theLin.PointPosition(theDistantPnt)

' PUNKT AN DIESER POSITION AUF DER LINIE :

theSnapPnt = theLin.Along(thePrcntAlong)

' ZEICHNET DEN PUNKT:

theGraphPnt = GraphicShape.Make(theSnapPnt)
theView.GetGraphics.UnselectAll
theGraphPnt.SetSelected(TRUE)
theView.GetGraphics.Add(theGraphPnt)

' TEST: ZEICHNET LINIE ZWISCHEN DEN PUNKTEN :

'theLine = Line.Make(thePnt,theOtherPnt)
'
'theGraphLine = GraphicShape.Make(theLine)
'theView.GetGraphics.UnselectAll
'theGraphLine.SetSelected(TRUE)
'theView.GetGraphics.Add(theGraphLine)