Zum Hauptinhalt springen
Version: 25.2

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 ()
{

//100 = Breite des Bildauschnittes in Meter
//50 = Höhe des Bildauschnittes in Meter
string bbox = this.Report.Record.CreateMapBoundingBoxFromCenter("A.GEOM", 100, 50, "EPSG: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:

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";
}

public string CreateMapUrl ()
{

//100 = Breite des Bildauschnittes in Meter
//50 = Höhe des Bildauschnittes in Meter
//ESPG Code der Datenbank/Karte
string bbox = this.Report.Record.CreateMapBoundingBoxFromCenter("A.GEOM", 100, 50, "EPSG: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 "";
}
}

}
}

Nun können wahlweise die Parameter der Funktion "CreateMapBoundingBoxFromCenter" angepasst werden.
Es muss er Name der GEOM-Spalte: A.GEOM angegeben werden,
die Spalte GEOM muss im SQL des Berichts vorhanden sein.
Die Spalte muss nicht in den Bericht eingefügt werden.

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".

Größe des Bildes aus der Ausdehnung des Geometrie Objektes berechnen

Wenn Sie Flächen oder Linien Geometrien haben können Sie statt einer Fixen Höhe/Breite auch diese aus der Geometrie des Objektes berechnen lassen.

Benutzen Sie dazu anstelle der Funktion "CreateMapBoundingBoxFromCenter" die Funktion "CreateMapBoundingBox".

CreateMapBoundingBox(columnName, widthPixel, heightPixel, minWidthMeter, minHeightMeter, bufferInPercent, epsgCode)

Beispiel:

string bbox = this.Report.Record.CreateMapBoundingBox("A.GEOM", 500, 250, 100, 90, 20, "EPSG:31467");

Es gibt folgende Parameter:
Breite und Höhe des Bildes in Pixel: 500, 250
Mindest Höhe und Bereits des Bildes in Meter: 100, 90
Prozentsatz des Buffers um das Geometrie Objekt: 20 Im Beispiel wird um das Objekt ein 20% Buffer gebildet.
Wenn man 0% setzt dann nimmt das Objekt die gesamte Karte ein.
Setzt man es auf 50% dann nimmt das Objekt 50% der Karte ein.
EPSG Code = Der EPSG Code der Karte und Datenbank.

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. Wenn 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.

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 genutzt werden um automatisch eine MapGuide URL erzeugen lassen die den Massstab (scale)
anhand der Groesse des Objektes berechnet.

Bei Punktobjekten kann diese auch genutzt werden in dem man den minScale auf den gewünschten Massstab 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 "";
}
}

Mehrere Karten zu einem Bild kombinieren

Sie können mehrere transparente Kartenbilder zu einem Kartenbild kombinieren in dem Sie in die URL des Bild Steuerelements mehrere URLs durch vier Pluszeichen getrennt eintragen.

Beispiel:

http://test/test1.png++++http://test/test2.png
Bitte beachten

Das übereinander setzen von mehreren Bild Steuerelementen funktioniert nicht da transparente Bilder nicht unterstützt werden.

Ich bekomme keine Karte

Klicken Sie im Berichtsdesigner auf den Knopf "More" in der Gruppe "Weitere" und dann "Vorschau PDFs (mit Logs)"

Scrollen Sie zum Ende des Berichtes, dort sehen sie die URLs von fehlgeschlagene Bilder.

Eine weitere Möglichkeit ist die URL direkt in dem Bericht als Text anzuzeigen. Fügen Sie dazu dem Bericht ein "Text" Steuerelement hinzu und geben Sie dann ein:

{Fun.CreateMapUrl()}

Andere Möglichkeit ist die URL via Berichtsfunktion "this.Report.WriteLog" ausgeben zu lassen.

Beispiel:

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=";
this.Report.WriteLog("Url=" + url);
return url;
}
else
{
return "";
}
}
Bitte beachten

In beiden Fällen werden lange URLs auf meherer Zeilen verteilt und müssen dann erst wieder händisch zusammengefügt werden.