This sample demonstrates applying a dictionary renderer to graphics, in order to display military symbology without the need for a feature table.
Use case
Use a dictionary renderer on a graphics overlay to display more transient data, such as military messages coming through a local tactical network.
How to use the sample
Run the sample and view the military symbols on the map.
How it works
- Create a new
GraphicsOverlay
. - Create a new
DictionaryRenderer
and set it to the graphics overlay. - Create a new
DictionarySymbolStyle
. - Parse through the XML and create a
Graphic
for each element:
i. Use the _wkid
key to get the geometry's spatial reference. ii. Use the _control_points
key to get the geometry's shape. iii. Create a geometry using the shape and spatial reference from above. iv. Create a Graphic
for each attribute, utilizing its defined geometry. v. Add the graphic to the graphics overlay.
Relevant API
- DictionaryRenderer
- DictionarySymbolStyle
- GraphicsOverlay
Offline data
To set up the sample's offline data, see the Use offline data in the samples section of the Qt Samples repository overview.
Link | Local Location |
---|---|
Mil2525d Stylx File | <userhome> /ArcGIS/Runtime/Data/styles/arcade_style/mil2525d.stylx |
MIL-STD-2525D XML Message File | <userhome> /ArcGIS/Runtime/Data/xml/arcade_style/Mil2525DMessages.xml |
About the data
The sample opens to a view of the county Wiltshire, United Kingdom. It displays military symbols illustrating a simulated combat situation in the area.
Tags
defense, military, situational awareness, tactical, visualization
Sample Code
// [WriteFile Name=GODictionaryRenderer, Category=DisplayInformation]
// [Legal]
// Copyright 2016 Esri.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// [Legal]
import QtQuick 2.6
import QtQuick.Controls 2.2
import QtQuick.XmlListModel 2.0
import Esri.ArcGISRuntime 100.15
import Esri.ArcGISExtras 1.1
Rectangle {
width: 800
height: 600
readonly property url dataPath: System.userHomePath + "/ArcGIS/Runtime/Data"
property bool graphicsLoaded: false
Map {
id: map
Basemap {
initStyle: Enums.BasemapStyleArcGISTopographic
}
}
// Create MapView that a GraphicsOverlay
// for the military symbols.
MapView {
id: mapView
anchors.fill: parent
Component.onCompleted: {
// Set the focus on MapView to initially enable keyboard navigation
forceActiveFocus();
}
// The GraphicsOverlay does not have a valid extent until it has been added
// to a MapView with a valid SpatialReference
onSpatialReferenceChanged: {
setViewpointGeometryAndPadding( graphicsOverlay.extent, 20 );
}
//! [Apply Dictionary Renderer Graphics Overlay QML]
GraphicsOverlay {
id: graphicsOverlay
DictionaryRenderer {
id: dictionaryRenderer
dictionarySymbolStyle: Factory.DictionarySymbolStyle.createFromFile(dataPath + "/styles/arcade_style/mil2525d.stylx")
Component.onCompleted: {
dictionarySymbolStyle.loadStatusChanged.connect(() => {
if (dictionarySymbolStyle.loadStatus === Enums.LoadStatusLoaded) {
const dictionarySymbolStyleConfigurations = dictionarySymbolStyle.configurations;
for (let i = 0; i < dictionarySymbolStyleConfigurations.length; i++) {
if (dictionarySymbolStyleConfigurations[i].name === "model") {
dictionarySymbolStyleConfigurations[i].value = "ORDERED ANCHOR POINTS";
}
}
}
});
}
}
}
//! [Apply Dictionary Renderer Graphics Overlay QML]
}
ProgressBar {
id: progressBar_loading
anchors {
horizontalCenter: parent.horizontalCenter
bottom: parent.bottom
margins: 5
}
indeterminate: true
visible: !graphicsLoaded
}
// Use XmlListModel to parse the XML messages file.
XmlListModel {
id: xmlParser
source: dataPath + "/xml/arcade_style/Mil2525DMessages.xml"
query: "/messages/message"
// These are the fields we need for MIL-STD-2525D symbology.
XmlRole { name: "_control_points"; query: "_control_points/string()" }
XmlRole { name: "_wkid"; query: "_wkid/number()" }
XmlRole { name: "identity"; query: "identity/number()" }
XmlRole { name: "symbolset"; query: "symbolset/number()" }
XmlRole { name: "symbolentity"; query: "symbolentity/number()" }
XmlRole { name: "echelon"; query: "echelon/number()" }
XmlRole { name: "specialentitysubtype"; query: "specialentitysubtype/number()" }
XmlRole { name: "indicator"; query: "indicator/number()" }
XmlRole { name: "modifier2"; query: "modifier2/number()" }
XmlRole { name: "uniquedesignation"; query: "uniquedesignation/string()" }
XmlRole { name: "additionalinformation"; query: "additionalinformation/string()" }
onStatusChanged: {
if (status === XmlListModel.Ready) {
for (let i = 0; i < count; i++) {
const element = get(i);
let wkid = element._wkid;
if (!wkid) {
// If _wkid was absent, use WGS 1984 (4326) by default.
wkid = 4326;
}
const pointStrings = element._control_points.split(";");
const sr = ArcGISRuntimeEnvironment.createObject("SpatialReference", { wkid: wkid });
let geom;
if (pointStrings.length === 1) {
// It's a point
const pointBuilder = ArcGISRuntimeEnvironment.createObject("PointBuilder");
pointBuilder.spatialReference = sr;
const coords = pointStrings[0].split(",");
pointBuilder.setXY(coords[0], coords[1]);
geom = pointBuilder.geometry;
} else {
const builder = ArcGISRuntimeEnvironment.createObject("MultipointBuilder");
builder.spatialReference = sr;
for (let ptIndex = 0; ptIndex < pointStrings.length; ptIndex++) {
const coords = pointStrings[ptIndex].split(",");
builder.points.addPointXY(coords[0], coords[1]);
}
geom = builder.geometry;
}
if (geom) {
// Get rid of _control_points and _wkid. They are not needed in the graphic's
// attributes.
element._control_points = undefined;
element._wkid = undefined;
const graphic = ArcGISRuntimeEnvironment.createObject("Graphic", { geometry: geom });
graphic.attributes.attributesJson = element;
graphicsOverlay.graphics.append(graphic);
}
}
graphicsLoaded = true;
mapView.map = map;
}
}
}
}