Reporting

Bei vielen Vorgängen spielt die Ausgabe von Ergebnissen oder Teilergebnissen in Form von Dokumenten eine große Rolle.

Wir haben dafür eine "TemplateEngine" integriert, die für verschiedene Ausgabeformate verwendet werden kann.

Über

Im Kern basiert diese auf Scriban, einer großartigen Bibliothek, die sich an der viel verwendeten Liquid Syntax orientiert.

Der Vorgang ist dabei mehrstufig. Mit der Template Engine wird im Wesentlichen eine Textvorlage in ein anderes Textformat überführt. Das Zielformat kann bspw. HTML oder Markdown sein.

Dies entspricht dem aus cardo.Button bekannten Erstellen einer XLST Transformation von XML zu (X)HTML

Bei der Prozessierung wird dabei ein Datenobjekt übergeben. Dies kann bspw. ein Puzzle-Dokument oder ein weiteres beliebiges Objekt sein. Die genaue Spezifikation des Inhaltsobjektes ist dabei von Anwendung zu Anwendung unterschiedlich. Wir haben das Root-Objekt mit "BO" benannt, das steht für Geschäftsobjekt (Business-Object) und kann beliebige Eingenschaften enthalten

Ein Folgeprozess kann aus dem aus der Vorlage generieren Text (typischerweise HTML) dann PDF oder ggf. auch ein WordDokument erzeugen. Für Word-Dokumente ist eine erweiterte Ausgabensteuerung über Html-Tags möglich. Diese weiteren Transformationen sind ebenfalls in Pib Integriert, aber nicht Gegenstand der hier vorliegenden Übersicht.

Die folgende Beschreibung stellt die Erweiterungsmethoden dar, die vor allem im Zusammenhang mit dynamischem Datenabruf und der Kartenbildgenerierung zu sehen sind.

Beispiele

Einige Beispiele zur gängigen Syntax und vor allem unseren Erweiterungsmethoden, sind in den nachfolgenden Abschnitten genannt.

Diese können dann genutzt werden, um beispielsweise einen Kartenausschnitt mit Ebeneninformationen im Dokument darzustellen.

Die grundlegende Syntax ist auf der Scriban Homepage zu finden.

Codeblöcke werden mit {{ eingeleitet und mit }} beendet. Ein Zeilenkommentar wird mit eine # eingeleitet.

Generell werden die Methoden mit dem Namen aufgerufen, gefolgt von den Argumenten in folgender Form:

  • benannte Argumente: Methode Arg1:wert1 Arg2:wert2

  • oder über die Position: Methode wert1 wert2

  • oder gemischt: Methode wert1 Arg2:wert2

    Nach einem benanntem Argument können nur noch weiter benannte Argumente folgen.

Wir stellen einige Erweiterungsfunktionen zur Verfügung, die im folgenden aufgelistet werden.

Standard (ohne Prefix)

ToLocalDateTime

Konvertiert ein DateTime Objekt in eine lokale Zeitangabe.

Entspricht die Eigenschaft DateTime.Kind dem Wert DateTime.Kind.Unspecified, wird angenommen dass es sich dabei schon um eine lokale Zeitangabe handelt und keine Konvertierung durchgeführt (was bei der .Net Methode DateTime.ToLocalTime der Fall wäre!).

Ein Null-Objekt wird ebenso wieder zurückgegeben.

Bsp.:

{{ BO.CategoryClassData.DATUM | ToLocalDateTime | date.to_string '%d.%m.%Y' }}

GetEnumDescription

Gibt den Namen oder wenn der Enum mit System.ComponentModel.DescriptionAttribute versehen ist diesen zurück.

Zusammensetzte Enumerationswert (Flags) werden korrekt behandelt und mit Trennzeichen (Standard ist ", ") ausgegeben.

GetEnumDescription BO.EnumWert

GetEnumDescription BO.EnumWert lastSeparator:" und "

FormatByteSize

Gibt eine Zahl als Byte-Größenangabe aus (z.B. "2,5 MByte").

FormatByteSize 1024

GeoExtension (uxGeo)

LoadLayerInIwan7

uxGeo.LoadLayerInIwan7(typeName:string,layerName:String,conflictHandling:LayerNameConflictHandling,args:IDicionary<string>,throwOnError?:boolean=true ): bool

Lädt eine Ebene in Iwan7. Die Argumente entsprechen den Iwan7 Ebenentypen.

Die Ebene kann dann bspw. in GetMapImage verwendet werden.

Beispiel

	uxGeo.LoadLayerInIwan7(typeName:"WMTS", layerName:"WebAtlasSn", conflictHandling:"ReplaceIfArgumentsChanged", args:{
			url:"https://geodienste.sachsen.de/wmts_geosn_webatlas-sn/guest"
	}) ;

GetGeoSQLDataReaderResult

uxGeo.GetGeoSQLDataReaderResult(sql:string): TableSnapshotResult

Diese Methode ruft einen DataReader per GeoSql ab und liest alle Zeilen in eine Liste ein.

Beispiel:

table = uxGeo.GetGeoSQLDataReaderResult sql:"SELECT * FROM L1"

In der cardo Umgebung werden die Ebenen bei Bedarf adHoc in Iwan7 geladen, beachten Sie, dass der Ebenentyp in Iwan7 unterstüzt wird.

Der Zugriff auf die Daten des Rückgabewerts erfolgt per Zeilenindex und Spaltenname. Alternativ kann das Ergebnis auch in einer Schleife abgerufen werden.

Beispiel:

{{
   table = uxGeo.GetGeoSQLDataReaderResult sql:"SELECT * FROM L1"

  }}
    <b>Wert:</b>{{table.Rows[0]["Spalte1"]}}
  {{

}}

Abrufe aller Zeilen:

{{ 

# Die Abfrage zusammenstellen
sql="SELECT
       ST_INTERSECTION(PrimaryGeometry, OtherGeom) ins,
	   *
     FROM
	    L1
    WHERE ST_INTERSECTS(PrimaryGeometry, OtherGeom)
    AND ST_Area(ins) > 100
   ";

# Die Tabellendaten mit Parameter sql -->
table = uxGeo.GetGeoSQLDataReaderResult sql:sql

# Ein Array um ein paar Zeilendaten zu sammeln
geomArray = []

# Schleife über alle Tabellenzeilen
for row in table.Rows
  rowNum = for.index;

  # das Array füllen
  geomArray = geomArray | array.add {
    geom: row['ins'].ExtendedWellknownText,
    data: {
        sequenceNumber: rowNum,
        title: row['surname'] + row['lastname']
      }
    };
  end;
}}

GeometryFromString

GeometryFromString(anyGeom:string) => IduIT.GeoLib.Net.Geometry

Diese Methode wandelt einen Geometrie-String (bspw. EWKT) in eine Geometrie zur Weiterverarbeitung um. Damit lassen sich dann die weiteren Eigenschaften der Geometrie nutzen, bzw. kann dies als Argument für Funktionen verwendet werden die ein Geometrie-Objekt voraussetzen.

Beispiel:

{{ 
  geom = uxGeo.GeometryFromString data : 'SRID:4326;POINT(13.0 51.0)'
}}

Die Bounding-Box der Geometrie ist: {{geom.Envelope}}

BoundingBoxFromGeom

Diese Methode konvertiert serverseitig eine Geometrie in eine BBox in Json-Struktur.

type TBBox = {minx: double, miny: double, maxx: double, maxy: double, epsgCode: int};

uxGeo.BoundingBoxFromGeom(geom:IduIT.GeoLib.Net.Geometry) => TBBox;

BoundingBoxFromFeatureLayerFeatures

Diese Methode ermittelt aus einer Liste übergebener Geometrien im Format Iwan7RenderAdHocEl (welches auch im RenderMapImage zur Angabe von AdHocFeatures erwartet wird) die max. BoundingBox aller Geometrien.

type TBBox = {minx: double, miny: double, maxx: double, maxy: double, epsgCode: int};

uxGeo.BoundingBoxFromGeom(features:IList<Core.Mapping.MapServer.Iwan7.JsonTypes.JsonRenderArgs.Iwan7RenderAdHocEl>) => TBBox;

RenderMapImage

Diese Methode erstellt ein Kartenbild. Es können zusätzliche FeatureLayer hinzugefügt werden.

type TMapImageInfo = {ImageBytes:byte[],MapScale:double,...};
type TRenderArguments = {};

uxGeo.RenderMapImage(args:TRenderArguments) => TMapImageInfo

Für die weitere Verwendung wird MapImageInfo.ImageBytes : Byte[] genutzt.

TRenderArguments

Die Beschreibung der Argumente finden Sie im Bereich der Iwan7 Dokumentation- TRenderArguments = MapRenderRequest

  • targetEpsgCode: int

    • Ziel-Epsg, wenn 0, dann wir die der BBox verwendet
  • width: int

    • Bildbreite in Pixeln
  • height: int

    • Bildhöhe in Pixeln
  • scaleFactor: double

    • Die Skalierung der Objekte unter Beachtung des Maßstabs, Standard ist 1.0
    • Mit diesem Parameter kann die Auflösung (Resolution) des Bildes erhöht werden, wenn die Ausgabegröße des Bildes dann um den selben Faktor geändert wird.
    • Bsp:
      • Ziel: Ausgabe Bild 500x500 aber mit doppelter Auflösung
      • Parameter einstellen:: width: 1000, height: 1000, scaleFactor: 2
      • Ausgabe 'runterscalieren': <img style="width:500px; height:500px;" src="..." />
  • targetMapScales: double[]]

    • Mögliche Kartenmaßstäbe
    • der Maßstab mit der geringsten Abweichung zum Istwert (welcher sich aus der BBOX ergibt) wird verwendet
  • backgroundColor: string

    • die Hintergrundfarbe, Standard ist Weiß
    • die Syntax entspricht den Farbangaben wie sie bei der Css-Symbolik verwendet wird
  • bbox: {minx : double, miny : double, maxx : double, maxy : double, epsgCode : int}

    • Bounding Box der Kartenanforderung, wenn nicht angegeben die Ausdehnung der zu zeichnenden Ebenen
  • layers: Iwan7RenderLayer[] - MapRenderLayer

    • die Liste zu zeichnender Ebenen

    • Beispiel:

      [
        {name: "L123"},
        {
          features: [{
              geom: geometryObject, 
              data: {
                  title: "GeometrieTitel", 
                  sequenceNumber: 1
              }
          }]
        }  
      ]
      

      Iwan7RenderLayer

      Wichtige Eigenschaften

      • name : string
        • Name der Ebene, schließt sich mit "features" aus
      • features: Iwan7RenderAdHocEl[]
        • Ad-Hoc Features für die Darstellung zusätzlicher Geometrien, schließt sich mit "name" aus
      • css: string
      • cssFile : string
        • die Pfadangabe zu einer Datei mit css Inhalten, schließt sich mit css aus
      • scr : string
        • ScaleRangeOverride - Überschreibt den Sichtbarkeitsmaßstab, Möglich ist die Angabe "min, max" oder ",max" und "min,"

      Iwan7RenderAdHocEl - AdHocRenderLayerFeature

      Eigenschaften

      • geom : string
        • die serialisierte Geometrie, als WKT
      • data : {name : value,...}[]
        • Zusatzdaten auf welche man dann zB. per CSS wieder zugreifen kann um diese in der Karte darzustellen

Beispiel:

{{
# hier wird dass CSS für die features des Ad-Hoc-Layers erstellt -->
featureCss = '
    ordered {
        polygon {
            render-quality: antialiased;
            fill-color:black(0.1);
            fill-pattern:solid;
            border-line:
            {
                line-dash-style: dash;
                render-quality: antialiased;
                line-width: 2m;
                line-min-width: 4;
                line-max-width: 3;
                line-color: Red(1.0);
                line-join: round;
                line-cap: round;
            };
        }
    }'
# hier wird die BoundingBox einer Geometrie ermittelt

bbox = uxGeo.BoundingBoxFromGeom (uxGeo.GeometryFromString testGeomWkt) buffer:100;


# Kartenbild erstellen
mapImage = uxGeo.RenderMapImage {
  width:1000,
  height:1000,
  backgroundColor:'white(0)',
  layers:[
    # "Normale" Ebene mit Namen 
    {name:"L227"},

    # AdHoc - FeatureLayer --> Hier wird die Geometrie des Dokuments 							dargestellt
    {
    #die einzelnen Verschnittgeometrien
    features: geomArray,
    css:featureCss
    }],
   bbox:bbox,
   targetMapScales:[1000,2000,3000,5000,10000] 
 };

Unterscheidung der Geometrie-Typen

Soll im Scriban nach dem Geometrietyp unterschieden werden, z.B. um unterschiedlich zu puffern, kann das wie in folgendem Beispiel erfolgen:

    geomObject = uxGeo.GeometryFromString bauvorhabenGeom;
    case geomObject.GeometryType
        when 1, 2, 5, 6, 7 #Point, Multipoint, Line, Multiline, GeometryCollection?
            bauvorhabenGeomForIntersect = (geomObject.ST_Buffer(15)).ExtendedWellknownText;
    end;

Folgende Geometrietypen gibt es:

	public enum DetailTypeType
	{
		NullGeometry = 0,
		Point = 1,
		Multipoint = 2,
		Polygon = 3,
		MultiPolygon = 4,
		Linestring = 5,
		MultiLinestring = 6,
		GeometryCollection = 7
	}

WebExtension (uxWeb)

ToWebUrlFormat

Diese Methode wandelt Bilddaten, bspw. von usGeo.RenderMapImage in eine Data-Url um. Dies kann genutzt um das endgültige Bild direkt einem Img-Tag zuzuweisen.

uxWeb.ToWebUrlFormat(data:byte[],mimeType:string) => string

Beispiel:

<!-- Url Verweis auf das Bild erstellen -->
<img style="border:1pt solid black; width:14.5cm" 
  src="{{uxWeb.ToWebUrlFormat data:mapImage.ImageBytes mimeType:'image/png'}}"/>

PibExtension (uxPib)

GetAnyPibObjectByPibId

Diese Methode gibt ein konkretes PibObjekt anhand der PibId zurück - ohne Rechteprüfung!

Beispiel:

<!-- zugeordneter Betrieb --->
{{ el = uxPib.GetAnyPibObjectByPibId BO.betriebPibOid }}
<h2>{{ el.Betriebsnummer }} {{ el.Title }}</h2>

Drittes

Hier noch ein Beispiel, welches in Kombination mit mermaid erstellt wurde

sequenceDiagram participant Alice participant Bob Alice->>John: Hello John, how are you? loop Healthcheck John->>John: Fight against hypochondria end Note right of John: Rational thoughts <br/>prevail! John-->>Alice: Great! John->>Bob: How about you? Bob-->>John: Jolly good!

Zuletzt geändert: 26.09.2024 17:06:54 (erstmals erstellt 30.08.2024)