Polygonobjekte in Draw-Dokumenten identifizieren

Programmierung unter AOO/LO (StarBasic, Python, Java, ...)

Moderator: Moderatoren

sarotti
****
Beiträge: 105
Registriert: So, 12.03.2006 17:40
Wohnort: Nähe Krefeld

Polygonobjekte in Draw-Dokumenten identifizieren

Beitrag von sarotti »

Hallo zusammen,

habe folgendes kleine Makro geschrieben, um die Flächen von Polygonen in Draw Seiten zu berechnen. Leider kommt es zu einem Fehler, wenn sich andere Zeichenobjekte (außer Polygonen) in dem Dokument befinden. Also frage ich mich, wie ich bei dem jeweiligen Zeichenobjekt feststellen kann, ob es sich um ein Polygon-Objekt handelt.... Hat jemand einen Tipp ???

Hier der Code für die Polygonflächen:

Code: Alles auswählen


Sub Polygon_Flaeche_berechnen
	
	Dim Flaeche as double
	
	oDoc = thisComponent 
   	oPage = oDoc.drawPages(0)
for n=0 to oPage.Count-1	
  	oShape = oPage.getByIndex(n)
   	aArray1 = oShape.PolyPolygon 
   	aPunkte = aArray1(0)
   	for i=0 to Ubound(aPunkte)-1
     oPunkt1 = aPunkte(i)
			if i<>Ubound(aPunkte) then
			     oPunkt2 = aPunkte(i+1)
			else
				oPunkt2 = aPunkte(Ubound(aPunkte))
			end if
		xDiff = (oPunkt2.X - oPunkt1.X)/1000
		yDiff = (oPunkt2.Y + oPunkt1.Y)/1000

			Flaeche(n) = Flaeche(n) + (xDiff*yDiff/2)
	next
   msgbox "(Nr. " + n + ") " +"''" + oShape.UINameSingular + "'': " + Format(Abs(Flaeche(n)), "###0.000") + " cm²",0,"Berechnung der Fläche eines Polygons"
next

End Sub

Danke für die Hilfe. :D

Gruss
sarotti
Toxitom
********
Beiträge: 3769
Registriert: Di, 12.08.2003 18:07
Wohnort: Wiesbaden
Kontaktdaten:

Beitrag von Toxitom »

Hey Sarotti,

das einfachste wäre: dem Objekt einen Namen geben (in den Eigenschatten), dann kannst du es über den Namen eindeutig identifizieren.

Der zweite weg: Prüfe, ob das Objekt den entsprechenden Service unterstützt., also zum Beispiel den com.sun,star.drawing.PolyPolygonShape (Vieleck).
Das versagt alerdings immer dann, wenn du mehrere "Vielecke" im Dokument hast, also wirklich am besten einen Namen vergeben :-)

Gruss
Thomas
Unterstützer LibreOffice, zertifizierter Trainer und Berater
Bücher: LibreOffice 6- Einstieg und Umstieg
Makros Grundlagen - LibreOffice / OpenOffice Basic
sarotti
****
Beiträge: 105
Registriert: So, 12.03.2006 17:40
Wohnort: Nähe Krefeld

Beitrag von sarotti »

Hallo Thomas,

Danke für Deine Antwort, aber weder die eine noch die andere Idee ist das was ich Suche. :(

Ich hatte gehofft, dass man die Existens der Eigenschaft eines Objektes abfragen kann, ähnlich wie "hasByName" oder "hasElements"....Habe die API Hilfe schon durchsucht und bin aber leider nicht fündig geworden.

Deine Idee:
Das Prüfen, ob der entsprechende Service
"com.sun,star.drawing.PolyPolygonShape"
angeboten wird, habe ich auch schon versucht... Hat aber die von Dir genannten Einschränkungen sofern andere Elemente vorhanden sind, die ich eben nicht berechnen möchte....

Die Vergabe von Namen für die Polygone wollte ich ebenfalls vermeiden...ist schon wieder lästige Handarbeit, die ich wegen der anderen User umgehen wollte.

Als eine Idee hatte ich das Auslesen des Objektnamens mit "oShape.UINameSingular", der ja immer dann mit "Polgon" (left("oShape.UINameSingular",7)) anfängt... Ist nicht besonders elegant, funktioniert aber.

Solltest Du noch einen Vorschlag zur Prüfung der Existenz einer Objekteigenschaft haben, würde ich mich freuen von Dir zu hören...

Gruss
sarotti[/quote]
Stephan
********
Beiträge: 12368
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Beitrag von Stephan »

Ich hatte gehofft, dass man die Existens der Eigenschaft eines Objektes abfragen kann, ähnlich wie "hasByName" oder "hasElements"....
Du verwendest doch bereits:

Code: Alles auswählen

aArray1 = oShape.PolyPolygon
und hast festgestellt das die Zeile einen Fehler liefert wenn es sich nicht um ein Polygon handelt weil diese Eigenschaft nur für das gewünschte Polygon existiert. Also frage deren Vorhandensein über eine Schleife ab, z.B.:

Code: Alles auswählen

'...
oShape = oPage.getByIndex(n) 
     x = "PolyPolygon nicht vorhanden"
     for i = LBOUND(oShape.getPropertySetInfo.Properties) To UBOUND(oShape.getPropertySetInfo.Properties)
	     If oShape.getPropertySetInfo.Properties(i).Name = "PolyPolygon" Then
		     x = "PolyPolygon vorhanden"
		     exit For
	     End If
     Next
     msgbox x
'...
"hasByName" oder "hasElements" existieren meines Erachtens nur für Objektauflistungen und nicht für eine Property in Form eines Arrays

Deine Idee:
Das Prüfen, ob der entsprechende Service Zitat:
"com.sun,star.drawing.PolyPolygonShape"
angeboten wird, habe ich auch schon versucht... Hat aber die von Dir genannten Einschränkungen sofern andere Elemente vorhanden sind, die ich eben nicht berechnen möchte....
Und welche Einschränkungen sind das? Ich kann keine feststellen.

Oder verstehe ich da was falsch - hier ist ein Draw-Dokument mit 5 Polygonen und 2 Vierecken und ich kann problemlos prüfen welches der 7 Objekte den Service com.sun.star.drawing.PolyPolygonShape unterstützt und welches nicht.

OOo 2.0.4

Solltest Du noch einen Vorschlag zur Prüfung der Existenz einer Objekteigenschaft haben
s.o.

Warum fragst Du stattdessen nicht den Wert einer charakteristischen Eigenschaft ab, beispielsweise:

Code: Alles auswählen

.ShapeType()
denn Obenstehendes ist zeitaufwändig.




Gruß
Stephan
sarotti
****
Beiträge: 105
Registriert: So, 12.03.2006 17:40
Wohnort: Nähe Krefeld

Beitrag von sarotti »

Hallo Stephan,

hey, manchmal sind die kleinen Dinge die Besten... Der Vorschlag es mit .ShapeType() zu versuchen ist sehr gut. Grundsätzlich wäre (konjunktiv :) )das Problem damit gelöst.

Zu Deiner Frage bzgl. welche Nachteile "com.sun,star.drawing.PolyPolygonShape" hat, möchte ich Dir sagen (auch Oo 2.0.4), dass das bei mir nicht von Erfolg gekrönt war. Wenn ich z.B. Polygone und andere Shapes in einem Draw Dokument mische, dann hat diese Funktion dazu geführt, dass ich die verschiedenen Elemente alle Elemente ausgelesen habe. Nur bei einem einzelnen Element hat´s problemlos geklappt...

So, nun aber zu meinem konjunktiv von oben:

Dank Deiner Hilfe funktioniert die Polygonberechnung nun einwandfrei in einem einzelnen Draw Dokument. Wenn aber ein weiteres Draw Dokument geöffnet wird, funktioniert das Makro nicht in dem zweiten, sondern es arbeitet noch immer in dem im Hintergrund liegenden ersten Dokument. Sofern das erste Draw Dokument ganz geschlossen wird, gibt´s dann noch einen Abbruch. Bereits bei "oDoc=ThisComponent" versagt das ganze. Erst ein kompletter Neustart von Oo (inkl. Schnellstarter) sorgt wieder für das Laufen des Makros.

Kennst Du das ??? Offensichtlich wird, das eine Draw Dokument als "ThisComponent" belegt und nach dem Schließen des Dokumentes steht dies nicht mehr zur Verfügung... Sonderbar.... :cry:


Gruss
sarotti
Stephan
********
Beiträge: 12368
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Beitrag von Stephan »

Wenn ich z.B. Polygone und andere Shapes in einem Draw Dokument mische, dann hat diese Funktion dazu geführt, dass ich die verschiedenen Elemente alle Elemente ausgelesen habe.


Also ich verstehe es nicht. Bisher war ich ja noch der Hoffnung das es an der OOo-Version liegen könnte. Was passiert denn - sind nun alles PolyPolygonShapes?

Bestätige bitte das dieser Code tatsächlich nicht funktioniert:

Code: Alles auswählen

Sub Polygon_test
oDoc = thisComponent
oPage = oDoc.drawPages(0) 
for n=0 to oPage.Count-1    
	oShape = oPage.getByIndex(n)
	If oShape.supportsService("com.sun.star.drawing.PolyPolygonShape") Then
			msgbox "PolyPolygonShape"
		Else
			msgbox "kein PolyPolygonShape"
	End If
Next n
End Sub
Kennst Du das ???
Ich verstehe ja nicht einmal Deine Problembeschreibung.
Offensichtlich wird, das eine Draw Dokument als "ThisComponent" belegt und nach dem Schließen des Dokumentes steht dies nicht mehr zur Verfügung
ThisComponent bezieht sich auf das letzte aktive oder das gerade aktuelle Dokument - das gerade aktuelle Dokument ist das was du siehst und das letzte aktive ist das was zu sehen war bevor die Basic-IDE den Fokus bekam, siehe: aktueller Developersguide (siehe erster Thread hier im Basic-Forum) Kapitel 11.3.2.



Gruß
Stephan
sarotti
****
Beiträge: 105
Registriert: So, 12.03.2006 17:40
Wohnort: Nähe Krefeld

Beitrag von sarotti »

Hallo Stephan,

zunächst einmal Danke für Deine Mühe. Habe Deinen Code getestet und der läuft einwandfrei... Ich weiss im Nachhinein nicht mehr, was ich anders gemacht habe, denn mein Ansatz war genauso (glaube ich :oops: ) ...!!??

Und nun zu dem Problem, welches Du nicht verstanden hast (habe mich vielleicht ein wenig krumm ausgedrückt, Sorry):
Ich habe noch ein wenig getestet und es lag an OO 2.0.0 (habe ich in meiner Firma installiert) während ich zu Hause bei 2.0.4 bin. Scheint ein inzwischen behobener Bug aus 2.0.0 zu sein, welcher behoben ist, denn das hat definitiv nicht geklappt (habe schon an mir gezweifelt = Fruststufe 7 :lol: ).

ThisComponent bezieht sich auf das letzte aktive oder das gerade aktuelle Dokument - das gerade aktuelle Dokument ist das was du siehst und das letzte aktive ist das was zu sehen war bevor die Basic-IDE den Fokus bekam, siehe: aktueller Developersguide (siehe erster Thread hier im Basic-Forum) Kapitel 11.3.2.
...das hatte ich auch so verstanden und funktionierte mit anderen Dokumenten immer einwandfrei. Scheint aber offensichtlich der Vergangenheit anzugehören.


Hier noch einmal für alle die es interessiert das vollständige Makro zur Polygonflächenberechnung:

Code: Alles auswählen

Sub Polygon_Flaeche_berechnen
	
	Dim Flaeche as double
	oDoc = thisComponent 
   	oPage = oDoc.drawPages(0)
for n=0 to oPage.Count-1	'//Zähler für alle Graphikelemente
 	oShape = oPage.getByIndex(n)
	if oShape.ShapeType()=("com.sun.star.drawing.PolyPolygonShape") then
 		x=x+1 '// Zähler für Polygone
   		aArray1 = oShape.PolyPolygon 
   		aPunkte = aArray1(0)
	   		for i=0 to Ubound(aPunkte)-1 '//hier erfolgt das Auslesen der Punkte des Polygons
    	 		oPunkt1 = aPunkte(i)
				oPunkt2 = aPunkte(i+1)
				xDiff = (oPunkt1.X - oPunkt2.X)/1000 '//Berechnung der x Koordinate (dividiert /1000=cm)
				yDiff = (oPunkt2.Y + oPunkt1.Y)/1000 '//Berechnung der y Koordinate
				Flaeche(n) = Flaeche(n) + (xDiff*yDiff/2) '//Polygonberechnung
			next
			SummeFlaechen = Summeflaechen + Flaeche(n)
 	end if

'// es folgt die Beschriftung der Polygone mit der Fläche und laufender Nummer 	

	if oShape.ShapeType()=("com.sun.star.drawing.PolyPolygonShape") then
 		Summe = Summe + "(Nr. " + x + ") " +"''" + oShape.UINameSingular + "'': " + Format(Abs(Flaeche(n)), "###0.000") + " cm²" + chr(13)
 		oShape.Start.CharHeight=6
 		oShape.End.CharHeight=6
 		Einzelflaeche=Format(Abs(Flaeche(n)), "###0.000") + " cm²"
 		oShape.String="("+ x + "): " + Einzelflaeche '+ ", " + Prozentflaeche
	end if
	Flaeche=0 '//Fläche muß wieder auf Null gesetzt werden, damit der Wert nicht in der Schleife addiert wird
next
msgbox Summe,0,"Berechnung Polygonfläche"
End Sub
Danke nochmals

Gruss
sarotti
Antworten