Startseite / Blog / Neue Möglichkeiten für Popups in map.apps Linie 4

Neue Möglichkeiten für Popups in map.apps Linie 4

Dennis Payk 7. März 2018

Wo finde ich weitere Informationen zu diesem Bebauungsplan? Wie alt ist dieses Naturdenkmal? Welche Informationen gibt es zu dieser Schule? Diese Aufzählung ließe sich beliebig lang forsetzen und zeigt, dass der Zugriff auf detaillierte Informationen zu einem einzelnen Geo-Objekt eine zentrale Funktion in fast allen Apps ist, die mit map.apps erstellt werden. In der neuen Linie 4 von map.apps stehen neue und mächtige Werkzeuge bereit, um dem Nutzer diese Informationen bestmöglich zukommen zu lassen. Diese neuen Möglichkeiten werden in diesem Artikel vorgestellt.

Inhalt dieses Artikels:

In diesem Artikel werden die Möglichkeiten beschrieben, die mit map.apps 4.3.0 zur Verfügung stehen. Wir arbeiten bereits an weiteren Neuerungen, zu denen die einfache Aktivierung von vorkonfigurierten Standard-Popups und die Möglichkeit zur Implementierung eigener Popup-Inhalte und -Aktionen gehören werden.

Popups aktivieren

Um beim Klick auf ein Geobjekt (Punkt, Linie, Fläche) ein Popup mit weitergehenden Informationen zu öffnen, muss zunächst ein sog. PopupTemplate für den jeweiligen Karten-Layer definiert werden. Dazu wird die folgende Konfiguration an der Layer-Definition ergänzt:

"map-init": {
    "Config": {
        "map": {
            "basemap": "topo-vector",
            "layers": [
                {
                    "id": "bundeslaender",
                    "url": "https://services.arcgis.com/OLiydejKCZTGhvWg/arcgis/rest/services/Bev%C3%B6lkerungAlter2A/FeatureServer/0",
                    "type": "AGS_FEATURE",
                    "visible": true,
                    "opacity": 0.5,
                    "outFields": ["*"],
                    "popupTemplate": {
                        "title": "{Name}",
                        "content": []
                    }
                  }
               ]
        },
        "view": {
            "viewmode": "2D",
            "extent": {
                "xmin": 600000,
                "ymin": 5800000,
                "xmax": 1700000,
                "ymax": 7600000,
                "spatialReference": 3857
            }
        }
    }
},

Der Parameter outFields sorgt in diesem Beispiel dafür, dass sämtliche Attribut-Informaionen vom Server abgefragt werden. Verfügt ein Layer über sehr viele Attribute, von denen nicht alle in der App angezeigt werden sollen, dann können hier die relevanten Attribute aufgelistet und so die Performance beim Abruf der Informationen optimiert werden.

Das eigentliche Popup wird mit dem Parameter popupTemplate definiert. Im Beispiel wird zunächst der Titel eines Popup-Fensters mit dem Attribut Name belegt.

Inhalt von Popups gestalten

Im Abschnitt content können nun die eigentlichen Inhalte des Popups festgelegt werden. Hierzu stehen vier verschiedene Elemente bereit:

  • text - frei definierbarer Fließtext
  • fields - Tabelle
  • media - Diagramm
  • attachments - Dateianhänge wie z.B. Fotos

Die verschiedenen Elemente können beliebig oft und in frei definierbarer Reihenfolge in einem Popup verwendet werden.

Text

Um unserem Beispiel-Popup ein Text-Element hinzuzufügen, wird folgende Konfiguration verwendet:

"popupTemplate": {
    "title": "{Name}",
    "content": [
        {
            "type": "text",
            "text": "Das Land {Name} hat {EWZ} Einwohner."
        }
    ]
}

Tabelle

Um mehrere Attribute eines Geoobjekts übersichtlich darzustellen, empfiehlt sich häufig die Verwendung einer Tabelle. Mit folgender Konfiguration wird eine Tabelle zur Darstellung der männlichen und weiblichen Einwohner ergänzt:

"popupTemplate": {
    "title": "{Name}",
    "content": [
    {
        "type": "text",
        "text": "Das Land {Name} hat {EWZ} Einwohner."
    },
    {
        "type": "fields",
        "fieldInfos": [
        {
            "fieldName": "Gesamt_Weiblich",
            "label": "Weibliche Einwohner",
            "format": {
                "places": 0,
                "digitSeparator": true
            }
        },
        {
            "fieldName": "Gesamt_Maennlich",
            "label": "Männliche Einwohner",
            "format": {
                "places": 0,
                "digitSeparator": true
            }
        }]
    }]
}

Mit dem Feld label wird die Beschriftung des Tabellenfelds festgelegt. Lässt man diese Angabe weg, wird der Name des Attributs verwendet. Durch den Abschnitt format können die Anzahl der Nachkommastellen (places) definiert und Tausender-Trennzeichen (digitSeparator) aktiviert werden.

Diagramme und Fotos

Um eine bessere und schnellere Vergleichbarkeit von Zahlenwerten zu schaffen, können Diagramme in Popups genutzt werden. Durch folgende Konfiguration wird ein Balken-Diagramm zur Darstellung der Altersstruktur ergänzt:

"popupTemplate": {
    "title": "{Name}",
    "content": [
        {
            "type": "text",
            "text": "Das Land {Name} hat {EWZ} Einwohner."
        },
        {
            "type": "fields",
            "fieldInfos": [
                {
                    "fieldName": "Gesamt_Weiblich",
                    "label": "Weibliche Einwohner",
                    "format": {
                        "places": 0,
                        "digitSeparator": true
                    }
                },
                {
                    "fieldName": "Gesamt_Maennlich",
                    "label": "Männliche Einwohner",
                    "format": {
                        "places": 0,
                        "digitSeparator": true
                    }
                }
            ]
        },
        {
            "type": "media",
            "mediaInfos": [
                {
                    "title": "Altersstruktur weiblicher Einwohner",
                    "type": "bar-chart",
                    "caption": "",
                    "value": {
                        "fields": [
                            "W_Unter_3",
                            "W_3_bis_5",
                            "W_6_bis_14",
                            "W_15_bis_17",
                            "W_18_bis_24",
                            "W_25_bis_29",
                            "W_30_bis_39",
                            "W_40_bis_49",
                            "W_50_bis_64",
                            "W_65_bis_74",
                            "W_75_und_aelter"
                        ],
                        "normalizeField": null
                    }
                }
            ]
        }
    ]
}

Folgende Diagramm-Typen stehen zur Verfügung:

  • Kreis-Diagramm (pie-chart)
  • Balken-Diagramm (bar-chart)
  • Säulen-Diagramm (column-chart)
  • Linien-Diagramm (line-chart)

Neben Diagrammen können mit dem Typ media auch Fotos in einem Popup angezeigt werden. Die Konfiguration des media Objekts wird dazu mit einem Typ image erweitert:

{
    "type": "media",
    "mediaInfos": [
        {
            "title": "Altersstruktur weiblicher Einwohner",
            "type": "bar-chart",
            "caption": "",
            "value": {
                "fields": ["W_Unter_3","W_3_bis_5","W_6_bis_14","W_15_bis_17","W_18_bis_24","W_25_bis_29","W_30_bis_39","W_40_bis_49","W_50_bis_64","W_65_bis_74","W_75_und_aelter"],
                "normalizeField": null
            }
        },
        {
            "title": "<b>Fotos aus {Name}</b>",
            "type": "image",
            "value": {
                "sourceURL": "https://picsum.photos/300/200"
            }
        }
    ]
}

In der URL-Konfiguration des Bildes können Attribute verwendet werden, wenn z.B. in einem Attribut eine URL zu einem Bild hinterlegt ist oder z.B. Bilder zu jeder ID eines Objekts auf einem Server hinterlegt sind (Beispiel "sourceURL": "https://meinserver.de/images/{id}.jpg").

Wie im Screenshot zu sehen ist, werden Zähler für die Anzahl von Fotos und Diagrammen ergänzt, sobald mehrere Inhalte dieser Art konfiguriert sind.

Datei-Anhänge

Verfügt ein Layer über die Möglichkeit Datei-Anhänge zu verwalten, können diese sehr einfach in einem Popup aufgelistet und so dem Nutzer zur Verfügung gestellt werden. Im folgenden Beispiel wird die entsprechende Konfiguration für einen Beispiel-Dienst dargestellt:

{
    "id": "brachen",
    "url": "https://services.conterra.de/arcgis/rest/services/mapapps/brachen/FeatureServer/0",
    "type": "AGS_FEATURE",
    "visible": true,
    "outFields": ["*"],
    "popupTemplate": {
        "title": "{beschreibung}",
        "content": [
            {
                "type": "attachments"
            }
        ]
    }
}

Wie in den Beispielen zuvor gesehen, kann dieses content Element auch mit anderen content Elementen (text, fields, media) kombiniert werden.

Dynamische Inhalte mit ArcGIS Arcade Expressions

Mit ArcGIS Arcade stellt Esri eine Ausdrucksprache für die ArcGIS Plattform zur Verfügung, die für vielfältige Anwendungsfälle genutzt werden kann. Neben der dynamischen Beschriftung von Objekten oder dem Rendering von Karteninhalten (beides wird in einem kommenden Blog-Artikel separat dargestellt) können Arcade Expressions auch für die dynamische Gestaltung von Inhalten in Popups genutzt werden.

Wenn wir auf das oben verwendete Beispiel der Einwohner-Struktur deutscher Bundesländer zurückblicken, fallen drei Missstände auf:

  1. Die Gesamteinwohnerzahl im Text ist nicht mit Tausender-Trennzeichen versehen
  2. In den Daten liegen keine Attribute zur prozentualen Verteilung männlicher und weiblicher Einwohner vor
  3. Die Altesstruktur kann anhand der Attribute nur geschlechterspezifisch analysiert werden

Alle drei Misstände können mithilfe von Arcade Expressions behoben werden.

Attributwerte formatieren

Um die Gesamtzahl der Einwohner mit einem Tausendertrennzeichen zu versehen, kann die Text-Funktion der Arcade Expressions verwendet werden. Mit folgender Konfiguration wird das Feld EWZ formatiert und im Text des Popups der neue Ausdruck verwendet:

{
    "id": "bundeslaender",
    "url": "https://services.arcgis.com/OLiydejKCZTGhvWg/arcgis/rest/services/Bev%C3%B6lkerungAlter2A/FeatureServer/0",
    "type": "AGS_FEATURE",
    "visible": true,
    "outFields": ["*"],
    "opacity": 0.5,
    "popupTemplate": {
        "title": "{Name}",
        "content": [{
            "type": "text",
            "text": "Das Land {Name} hat {expression/EWZ} Einwohner."
        }],
        "expressionInfos": [{
            "name": "EWZ",
            "expression": "Text($feature.EWZ, '#,###')"
        }]
    }
}

Attributwerte berechnen

Im folgenden soll eine Angabe zur prozentuellen Verteilung der männlichen und weiblichen Bevölkerung im jeweiligen Bundesland angezeigt werden. Die Daten des Kartenlayers geben hierzu direkt keine Auskunft, es können nur die absoluten Werte der weiblichen und männlichen Einwohner abgerufen werden. Mit Hilfe folgender Arcade Expression können dynamisch die prozentualen Werte berechnet werden:

"popupTemplate": {
    "title": "{Name}",
    "content": [{
        "type": "text",
        "text": "Das Land {Name} hat {expression/EWZ} Einwohner. {expression/weiblich-rel} Prozent der Einwohner sind weiblich."
    }],
    "expressionInfos": [{
        "name": "EWZ",
        "expression": "Text($feature.EWZ, '#,###')"
    }, {
        "name": "weiblich-rel",
        "expression": "Round($feature.Gesamt_Weiblich / $feature.EWZ, 3) * 100"
    }]
}

Mit gleichem Vorgehen können die Werte der verschiedenen Altersgruppen für weibliche und männliche Einwohner addiert werden und im Media-Objekt verwendet werden, um die Altersstruktur der gesamten Bevölkerung anzuzeigen.

Aktuelles Datum zur Altersbestimmung nutzen

Häufig wird für verschiedene Geoobjekte ein Datum in einem Attribut erstellt, welches z.B. den Start einer Maßnahme, die Erstellung des Objekts o.ä. bezeichnet. Mit Hilfe von Arcade Expressions kann anhand des aktuellen Datums die zeitliche Differenz zu diesem Datum berechnet werden. So kann z.B. das Alter eines Objekts angegeben werden, wie in folgendem Beispiel ersichtlich ist:

{
    "id": "stoerungen",
    "url": "https://services.conterra.de/arcgis/rest/services/mapapps/stoerung/FeatureServer/1",
    "type": "AGS_FEATURE",
    "visible": true,
    "outFields": ["*"],
    "popupTemplate": {
        "title": "{details}",
        "content": [{
            "type": "text",
            "text": "Diese Störung wurde vor {expression/alter} Tagen erfasst."
        }],
        "expressionInfos": [{
            "name": "alter",
            "expression": "Round(DateDiff(Date(),Date($feature.Zeitpunkt),'days'),0)"
        }]
    }
}

Weitere Funktionen der Arcade Expressions nutzen

Für Arcade Expressions können eine Vielzahl weiterer Funktionen genutzt werden. Interessant ist z.B. die IsEmpty Funktion, mit der dynamisch auf das Vorhandensein von Werten in einem bestimmten Attribut reagiert werden kann. (Beispiel: Wenn das Feld "url" gesetzt ist, dann zeigen den Text "Weitere Informationen finden Sie auf dieser Webseite...".) Eine vollständige Übersicht der verfügbaren Funktionen ist hier verfügbar.

Gesamte Beispiel-Konfiguration

Abschließend finden Sie hier noch einmal die komplette Konfiguration der hier verwendeten Beispiele:

"map-init": {
    "Config": {
        "map": {
            "basemap": "topo-vector",
            "layers": [{
                "id": "brachen",
                "url": "https://services.conterra.de/arcgis/rest/services/mapapps/brachen/FeatureServer/0",
                "type": "AGS_FEATURE",
                "visible": false,
                "outFields": ["*"],
                "popupTemplate": {
                    "title": "{beschreibung}",
                    "content": [{
                        "type": "attachments"
                    }]
                }
            }, {
                "id": "bundeslaender",
                "url": "https://services.arcgis.com/OLiydejKCZTGhvWg/arcgis/rest/services/Bev%C3%B6lkerungAlter2A/FeatureServer/0",
                "type": "AGS_FEATURE",
                "visible": true,
                "outFields": ["*"],
                "opacity": 0.5,
                "popupTemplate": {
                    "title": "{Name}",
                    "content": [{
                        "type": "text",
                        "text": "Das Land {Name} hat {expression/EWZ} Einwohner. {expression/weiblich-rel} Prozent der Einwohner sind weiblich."
                    }, {
                        "type": "fields",
                        "fieldInfos": [{
                            "fieldName": "Gesamt_Weiblich",
                            "label": "Weibliche Einwohner",
                            "format": {
                                "places": 0,
                                "digitSeparator": true
                            }
                        }, {
                            "fieldName": "Gesamt_Maennlich",
                            "label": "Männliche Einwohner",
                            "format": {
                                "places": 0,
                                "digitSeparator": true
                            }
                        }]
                    }, {
                        "type": "media",
                        "mediaInfos": [{
                            "title": "Altersstruktur weiblicher Einwohner",
                            "type": "bar-chart",
                            "value": {
                                "fields": ["W_Unter_3", "W_3_bis_5", "W_6_bis_14", "W_15_bis_17", "W_18_bis_24", "W_25_bis_29", "W_30_bis_39", "W_40_bis_49", "W_50_bis_64", "W_65_bis_74", "W_75_und_aelter"],
                                "normalizeField": null
                            }
                        }, {
                            "title": "<b>Fotos aus {Name}</b>",
                            "type": "image",
                            "value": {
                                "sourceURL": "https://picsum.photos/300/200"
                            }
                        }]
                    }],
                    "expressionInfos": [{
                        "name": "EWZ",
                        "expression": "Text($feature.EWZ, '#,###')"
                    }, {
                        "name": "weiblich-rel",
                        "expression": "Round($feature.Gesamt_Weiblich / $feature.EWZ, 3) * 100"
                    }]
                }
            },
            {
                "id": "stoerungen",
                "url": "https://services.conterra.de/arcgis/rest/services/mapapps/stoerung/FeatureServer/1",
                "type": "AGS_FEATURE",
                "visible": true,
                "outFields": ["*"],
                "popupTemplate": {
                    "title": "{details}",
                    "content": [{
                        "type": "text",
                        "text": "Diese Störung wurde vor {expression/alter} Tagen erfasst."
                    }],
                    "expressionInfos": [{
                        "name": "alter",
                        "expression": "Round(DateDiff(Date(),Date($feature.Zeitpunkt),'days'),0)"
                    }]
                }
            }]  
        },
        "view": {
            "viewmode": "2D",
            "extent": {
                "xmin": 600000,
                "ymin": 5800000,
                "xmax": 1700000,
                "ymax": 7600000,
                "spatialReference": 3857
            }
        }
    }
}