Zum Hauptinhalt springen

Karten in Berichte

Beispiel Druckvorschau eines Berichts mit einer MapServer Karte

Zum erzeugen eines solchen Berichtes wird ein Bild Steuerelement in Kombination mit einer C# Funktion verwendet. C# Kenntnisse sind hierbei von Vorteil. Sollten Sie Probleme haben wenden Sie sich bitte an unsere Hotline oder einen C# Entwickler.

Sie benötigen dazu eine URL die die Karte erzeugt.

Erzeugen sie zuerst eine Script Funktion, in dem Sie oben auf den Script-Knopf klicken.

Im Script Code Fenster sehen sie folgenden Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using XSystem;
using Mum.Geo.ReportDesigner;

namespace Report
{
public class MyReportPlugIn : ReportPlugIn
{
public MyReportPlugIn(IReportApiHost host) : base(host)
{
//
}

public string MyFunction()
{
return "Test";
}
//HIER NEUEN CODE EINFUEGEN
}
}

Fügen Sie nun am Ende, aber vor den letzten zwei geschweiften Klammern eine neue Funktion zur Erzeugung der Karte ein.

Hier ein Beispiel Code für eine solche Funktion

public string CreateMapUrl ()
{
string bbox = Report.Record.CreateMapBoundingBox("A.GEOM", 500, 250, 20, "31467");
//string bbox = Report.Record.CreateMapBoundingBoxFromCenter("A.GEOM", 100, 50, "31467");

if (bbox.Length>0)
{
var url = "https://topowiki.mum.de/mapserver/mapserv.exe" +
"?map=C:\\inetpub\\wwwroot\\MapEdit_2019R1\\MumGeoData\\MapServer\\alkisdemo.map" +
"&REQUEST=GetMap" +
"&SERVICE=WMS" +
"&VERSION=1.3.0" +
"&FORMAT=image/png" +
"&Layers=ax_weg_tbl,ax_flurstueck_tbl,v_grenzpunkt,ax_flurstueck_l,ax_flurstueck_a,ax_gebaeude_l,ax_gebaeude_a,ax_gebaeude_tbl_m,ax_lagbezmithnr_tbl,ax_lagbezohnehnr_tbl" +
"&CRS=EPSG:31467" +
"&BBOX=" + bbox +
"&Width=1000" +
"&Height=500" +
"&TRANSPARENT=TRUE" +
"&Styles=";
return url;
}
else
{
return "";
}
}

Im Code Editor gibt es eine Option Example Code hier stehen diverse Code Beispiele, unter anderem auch CreateMapUrl , diesen Beispiel Code können sie kopieren und und anpassen. Am ende sollte es so aussehen:

Nun muss die Funktion angepasst werden. Der Teil string bbox = Report.Record.CreateMapBoundingBox("A.GEOM", 500, 250, 20, true); erzeugt den Koordinaten Bereich (Bounding Box) der in der Karte dargestellt werden soll. Es gibt folgende Parameter: Der Name der GEOM-Spalte: A.GEOM (die Spalte GEOM muss im SQL des Berichts vorhanden sein!!) Breite und Höhe des Bildes in Pixel: 500, 250 Prozentsatz des Buffers um das Flurstueck: 20 Im Beispiel wird um das Flurstueck ein 20% Buffer gebildet. Wenn man 0% setzt dann nimmt das Flurstueck die gesammte Karte ein. Setzt man es auf 50% dann nimmt das Flurstueck 50% der Karte ein. Der letzte, optionale Parameter gibt an in welcher Reihenfolge die Koordinaten der Bounding Box geliefert werden sollen. Mögliche Werte: false = zuerst X dann Y true = zuerst Y dann X "EPSG Code" = Die Reihenfolge wird aus dem EPSG Code ermittelt für MapServer ermittelt.

Darunter tragen sie in der Variable url die WMS URL ein mit der die Karte vom Server abgerufen werden soll. Hierbei wird die variable bbox an der stelle eingesetzt wo der Bounding Box Wert eingefügt werden soll.

Achtung

Die XY Reihenfolge in der die Koordinaten angegeben werden müssen ist nicht bei allen Karten Server Produkten einheitlich. Testen Sie deswegen die URL vorab immer im Web Browser. Wenn sie kein Kartenbild zurück bekommen dann muss die XY Reihenfolge mittels des Parameters angepasst werden.

Achtung

In der Url und der Funktion gibt es eine Width und Height. Diese Angaben sind die Breite/Höhe des vom Kartenserver angeforderten Bildes in Pixel. Diese müssen nicht gleich der Höhe und Breite des Bildes im Bericht sein. Mit diesen Angaben kann man die Qualität des Bildes steuern. d.h. wenn man diese grösser wählt dann wird das Bild schärfer. Was übereinstimmen muss ist das Verhältnis von Höhe zu Breite. Wwenn das Bild im Bericht 200 Breit und 100 Hoch ist, ist das Verhältnis 2:1 . das bedeutet dass die Angabe in der URL/Funktion auch 2:1 sein muss.

Nach dem definieren der C# Funktion fügen sie ein Bild Steuerelement in ihren Bericht ein. Statt einer URL geben sie einen Platzhalter für die gerade eben erzeugte Funktion an. In diesem Fall:

{Fun.CreateMapUrl()}

Achtung

Ein Bericht mit vielen Karten kann unter Umständen sehr sehr lange dauern. Das kann daran liegen das MapGuide/MapServer lange braucht um diese zu erzeugen. Des weiteren werden solche Berichte auch sehr gross wenn sie viele Bilder haben und dadurch dauert das Erzeugen und Herunterladen sehr lange. Am besten die Anzahl der Datensätze mit LIMIT / Rownum beschränken damit der Endanwender nicht tausende von Karten erzeugt und damit den Server lahm legt.

Hinweis

Wenn die URL sehr lange ist kann es sein das der Aufruf fehlschlägt. Sie können dann mit dem Commando POST ein HTTP POST erzwingen.
siehe POST unter "Bilder in Berichten".

MapGuide Karte einbinden

Das vorgehen ist gleich wie oben Beschrieben jedoch benötigt MapGuide eine andere URL und Funktion.

Dieses Beispiel benutzt die Map Guide spezifische Funktion "OPERATION=GETMAPIMAGE" zum erzeugen der Karte.

siehe: https://trac.osgeo.org/mapguide/wiki/HttpApi/RenderingService

Beispiel URL:

http://localhost/mapguide/mapagent/mapagent.fcgi?
OPERATION=GETMAPIMAGE
&SETDISPLAYDPI=75
&SETDISPLAYWIDTH=1300
&SETDISPLAYHEIGHT=1300
&SETVIEWSCALE=500
&SETVIEWCENTERX=32123456
&SETVIEWCENTERY=54725632
&FORMAT=PNG&VERSION=3.0.0&LOCALE=en
&MAPDEFINITION=Library%3A%2F%Osnabrueck%2FMapOsnab.MapDefinition
&Username=Anonymous&Password=

Die Hilfsfunktion CreateMapGuideUrl kann genuzt werden um automatisch eine MapGuide URL erzeugen lassen die den Massstab (scale)
anhand der Groesse des Objektes berechnet.

Bei Punktobjekten kann diese auch genutz werden in dem man den minScale auf den gewünschten Masstab setzt.

public string CreateMapUrlMapGuide()
{
//Example for a MapGuide Map

var serverUrl = "http://localhost/mapguide/mapagent/mapagent.fcgi";
var mapDefinition = "Library://Osnabrueck/MapOsnab.MapDefinition";
var urlParameter = "&FORMAT=PNG&VERSION=3.0.0&LOCALE=en&Username=Anonymous&Password=";
var geomColumnName = "A.GEOM";
var minScale = 1;
var maxScale = 1000000;
var dpi = 96;
var widthMillimeter = 150;
var heightMillimeter = 80;
var bufferInPercent = 50;
var useXY = true;

return this.Report.Record.CreateMapGuideUrl(serverUrl, mapDefinition, urlParameter, geomColumnName, minScale, maxScale, dpi, widthMillimeter, heightMillimeter, bufferInPercent, useXY);

}

MapGuide WMS Layer einbinden

Man kann einzelne MapGuide Layer auch via WMS einbinden. Für MapGuide muss man zuerst MapGuide als WMS Server definieren.

Wie das geht ist hier erklärt: https://geospatialnavigator.typepad.com/geospatial_navigator/2010/02/mapguide-wms-publizieren.html

Dann muss man bei jedem Layer den man sehen will in Maestro jeweils auf die Layerdefinition gehen, rechte Maus und "Properties/Eigenschaften" dann auf den Reiter "WMS" gehen. Dann bei Titel/Keywords/Abstract und Metadata jeweils den Layernamen reinschrieben.

Was die einzelnen Felder bedeuten ist leider in der MapGuide Doku nicht zu finden. Es funktioniert wenn man einfach in alle Felder den Layernamen reinschreibt.

Dann Available/Queryable und Opaque ankreuzen. Und bei "Bounds" kann man den Knopf unten rechts neben der box drücken und es erzeugt einem den Ausdruck. Man muss jedoch noch händisch den EPSG Code eintragen. Man kann das ganze dann bei allen Layern verwenden (sofern einem die Ausdehnung passt) Dann den Layer speichern.

Ob es noch andere Wege gibt wo man eine ganze Karte gleich als WMS aufsetzen kann ohne das einzeln für jeden Layer zu machen kann noch nicht gesagt werden.

Danach kann man in den AppBuilder gehen und zum Test den Layer als WMS in der Kartenverwaltung einbinden und mit dem Client testen.

In der Kartenverwaltung "Karte hinzufügen" vom Typ "URL/WMS" dann auf Wizzard gehen.

Dann die Url mapagent url von MapGuide eingeben.

Beispiel

https://gisdemo.mum.de/mapguide/mapagent/mapagent.fcgi?

Die Url ist der Name des Mapguide Servers (wie man es im AppBuilder unter der Karten Server Konfiguration eingestellt hat) plus "mapagent/mapagent.fcgi?" Wenn alles richtig aufgesetzt ist sieht man in der Liste dann die Layer und kann einen auswählen.

Speichern und im Client testen ob der Layer kommt.

Danach kann man die URL die man in der Kartenverwaltung sieht kopieren und umändern.

Aus

&BBOX={YMin},{XMin},{YMax},{XMax}

wird:

"&BBOX=" + bbox +

Und bei Width und Height dann die fixen werte für Höhe und Breite in Pixel angeben statt den Parametern.

&Width={DisplayWidthPixel}
&Height={DisplayHeightPixel}

Wenn man mehrere Layer haben will muss man bei

&Layers=

Alle Layer mit Komma getrennt auflisten.

Beispiel Url für MapGuide

public string CreateMapUrl ()
{
string bbox = Report.Record.CreateMapBoundingBox("A.GEOM", 500, 250, 20, true);
//string bbox = Report.Record.CreateMapBoundingBoxFromCenter("A.GEOM", 100, 50, false);

if (bbox.Length>0)
{
var url = "https://gisdemo.mum.de/mapguide/mapagent/mapagent.fcgi?" +
"REQUEST=GetMap" +
"&SERVICE=WMS" +
"&VERSION=1.3.0" +
"&FORMAT=image/png" +
"&Layers=" +
"ALKIS_DEMO/ALKISBW/Layers/ALKIS%20LK%20Farbig/Flurstuecke%20und%20Grenzpunkte/Flurstuecksgrenzen" +
",ALKIS_DEMO/ALKISBW/Layers/ALKIS%20LK%20Farbig/Flurstuecke%20und%20Grenzpunkte/Flurstuecksnummer" +
"&CRS=EPSG:31467" +
"&BBOX=" + bbox +
"&Width=1000" +
"&Height=500" +
"&TRANSPARENT=TRUE" +
"&Styles=";
return url;
}
else
{
return "";
}
}