Skip to content

Commit 180f351

Browse files
Update dictionary renderer samples to use new Ordered Anchor Points (#675)
* update dictionary renderer graphics overlay 2D * Update DictionaryRendererGraphicsOverlay.png * update graphics overlay dictionary renderer 3d * Update symbology/graphics-overlay-dictionary-renderer-3D/README.md Co-authored-by: Jen Merritt <[email protected]> * Update symbology/graphics-overlay-dictionary-renderer-3D/src/main/java/com/esri/samples/graphics_overlay_dictionary_renderer_3D/GraphicsOverlayDictionaryRenderer3DSample.java Co-authored-by: Jen Merritt <[email protected]> * Update symbology/graphics-overlay-dictionary-renderer-3D/src/main/java/com/esri/samples/graphics_overlay_dictionary_renderer_3D/GraphicsOverlayDictionaryRenderer3DSample.java Co-authored-by: Jen Merritt <[email protected]> * review comments Co-authored-by: Jen Merritt <[email protected]>
1 parent 4ac7bf2 commit 180f351

File tree

11 files changed

+204
-125
lines changed

11 files changed

+204
-125
lines changed
-203 KB
Loading

display_information/dictionary-renderer-graphics-overlay/README.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Dictionary renderer with graphics overlay
22

3-
Create graphics using a local mil2525d style file and an XML file with key/value pairs for each graphic.
3+
Create graphics from an XML file with key-value pairs for each graphic, and display the military symbols using a MIL-STD-2525D web style in 2D.
44

55
![Image of dictionary renderer graphics overlay](DictionaryRendererGraphicsOverlay.png)
66

@@ -14,9 +14,9 @@ Run the sample and view the military symbols on the map.
1414

1515
## How it works
1616

17-
1. Create a new `SymbolDictionary(specificationType, dictionaryPath)`.
18-
2. Create a new `DictionaryRenderer(symbolDictionary)`.
19-
3. Create a new `GraphicsOverlay`
17+
1. Create a new `DictionarySymbolStyle(portalItem)` with a portal item containing a MIL-STD-2525D dictionary web style.
18+
2. Create a new `DictionaryRenderer` from the dictionary symbol style.
19+
3. Create a new `GraphicsOverlay`.
2020
4. Set the dictionary renderer to the graphics overlay.
2121
5. Parse through the local XML file creating a map of key/value pairs for each block of attributes.
2222
6. Create a `Graphic` for each attribute.
@@ -30,6 +30,10 @@ Run the sample and view the military symbols on the map.
3030
* DictionarySymbolStyle
3131
* GraphicsOverlay
3232

33+
## About the data
34+
35+
The dictionary symbol style in this sample is constructed from a portal item containing a [MIL-STD-2525D symbol dictionary web style](https://arcgis.com/home/item.html?id=d815f3bdf6e6452bb8fd153b654c94ca). This ArcGIS Web Style is used to build custom applications that incorporate the MIL-STD-2525D symbol dictionary. This style supports a configuration for modeling locations as ordered anchor points or full geometries.
36+
3337
## Tags
3438

35-
visualization
39+
defense, military, situational awareness, tactical, visualization

display_information/dictionary-renderer-graphics-overlay/README.metadata.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
{
22
"category": "Display information",
3-
"description": "Create graphics using a local mil2525d style file and an XML file with key/value pairs for each graphic.",
3+
"description": "Create graphics from an XML file with key-value pairs for each graphic, and display the military symbols using a MIL-STD-2525D web style in 2D.",
44
"ignore": false,
55
"images": [
66
"DictionaryRendererGraphicsOverlay.png"
77
],
88
"keywords": [
9+
"defense",
10+
"military",
11+
"situational awareness",
12+
"tactical",
913
"visualization",
1014
"DictionaryRenderer",
1115
"DictionarySymbolStyle",

display_information/dictionary-renderer-graphics-overlay/settings.gradle

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,12 @@ def ant = new groovy.util.AntBuilder()
66
if (!file("./samples-data").exists()) {
77
file("./samples-data/xml").mkdirs()
88
ant.get(
9-
src: "https://arcgisruntime.maps.arcgis.com/sharing/rest/content/items/1e4ea99af4b440c092e7959cf3957bfa/data",
9+
src: "https://arcgisruntime.maps.arcgis.com/sharing/rest/content/items/623382e0113d40698538f249e3bcb1c0/data",
1010
dest: file("./data.zip")
1111
)
1212
ant.unzip(
1313
src: file("./data.zip"),
1414
dest: file("./samples-data/xml")
1515
)
1616
delete file("./data.zip")
17-
file("./samples-data/stylx").mkdirs()
18-
ant.get(
19-
src: "https://arcgisruntime.maps.arcgis.com/sharing/rest/content/items/c78b149a1d52414682c86a5feeb13d30/data",
20-
dest: file("./samples-data/stylx/mil2525d.stylx")
21-
)
2217
}

display_information/dictionary-renderer-graphics-overlay/src/main/java/com/esri/samples/dictionary_renderer_graphics_overlay/DictionaryRendererGraphicsOverlaySample.java

Lines changed: 86 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
/*
22
* Copyright 2017 Esri.
3-
*
3+
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
55
* use this file except in compliance with the License. You may obtain a copy of
66
* the License at
7-
*
7+
*
88
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
9+
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
1212
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -16,35 +16,33 @@
1616

1717
package com.esri.samples.dictionary_renderer_graphics_overlay;
1818

19-
import javax.xml.parsers.DocumentBuilder;
20-
import javax.xml.parsers.DocumentBuilderFactory;
21-
import org.w3c.dom.Document;
19+
import javafx.application.Application;
20+
import javafx.scene.Scene;
21+
import javafx.scene.control.Alert;
22+
import javafx.scene.layout.StackPane;
23+
import javafx.stage.Stage;
2224
import org.w3c.dom.Node;
2325
import org.w3c.dom.NodeList;
2426

27+
import javax.xml.parsers.DocumentBuilderFactory;
2528
import java.io.File;
26-
import java.util.ArrayList;
27-
import java.util.HashMap;
28-
import java.util.List;
29-
import java.util.Map;
29+
import java.util.*;
3030
import java.util.stream.Collectors;
3131
import java.util.stream.Stream;
3232

33-
import javafx.application.Application;
34-
import javafx.scene.Scene;
35-
import javafx.scene.layout.StackPane;
36-
import javafx.stage.Stage;
37-
3833
import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
3934
import com.esri.arcgisruntime.geometry.Multipoint;
4035
import com.esri.arcgisruntime.geometry.Point;
4136
import com.esri.arcgisruntime.geometry.PointCollection;
4237
import com.esri.arcgisruntime.geometry.SpatialReference;
38+
import com.esri.arcgisruntime.loadable.LoadStatus;
4339
import com.esri.arcgisruntime.mapping.ArcGISMap;
4440
import com.esri.arcgisruntime.mapping.BasemapStyle;
4541
import com.esri.arcgisruntime.mapping.view.Graphic;
4642
import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
4743
import com.esri.arcgisruntime.mapping.view.MapView;
44+
import com.esri.arcgisruntime.portal.Portal;
45+
import com.esri.arcgisruntime.portal.PortalItem;
4846
import com.esri.arcgisruntime.symbology.DictionaryRenderer;
4947
import com.esri.arcgisruntime.symbology.DictionarySymbolStyle;
5048

@@ -54,10 +52,11 @@ public class DictionaryRendererGraphicsOverlaySample extends Application {
5452
private GraphicsOverlay graphicsOverlay;
5553

5654
@Override
57-
public void start(Stage stage) throws Exception {
58-
mapView = new MapView();
59-
StackPane appWindow = new StackPane(mapView);
60-
Scene scene = new Scene(appWindow);
55+
public void start(Stage stage) {
56+
try {
57+
// create stack pane and application scene
58+
var stackPane = new StackPane();
59+
var scene = new Scene(stackPane);
6160

6261
// set title, size, and add scene to stage
6362
stage.setTitle("Dictionary Renderer Graphics Overlay Sample");
@@ -70,36 +69,73 @@ public void start(Stage stage) throws Exception {
7069
String yourAPIKey = System.getProperty("apiKey");
7170
ArcGISRuntimeEnvironment.setApiKey(yourAPIKey);
7271

73-
// create a map with the topographic basemap style and set it to the map view
72+
// create a map view
73+
mapView = new MapView();
74+
// create a map with the topographic basemap style
7475
ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC);
75-
mapView.setMap(map);
7676

7777
graphicsOverlay = new GraphicsOverlay();
7878
// graphics no longer show after zooming passed this scale
7979
graphicsOverlay.setMinScale(1000000);
8080
mapView.getGraphicsOverlays().add(graphicsOverlay);
8181

82-
// create symbol dictionary from style file
83-
File stylxFile = new File(System.getProperty("data.dir"), "./samples-data/stylx/mil2525d.stylx");
84-
DictionarySymbolStyle symbolDictionary = DictionarySymbolStyle.createFromFile(stylxFile.getAbsolutePath());
85-
86-
// tells graphics overlay how to render graphics with symbol dictionary attributes set
87-
DictionaryRenderer renderer = new DictionaryRenderer(symbolDictionary);
88-
graphicsOverlay.setRenderer(renderer);
89-
90-
// parse graphic attributes from a XML file
91-
List<Map<String, Object>> messages = parseMessages();
82+
// create the dictionary symbol style from the Joint Military Symbology MIL-STD-2525D portal item
83+
var portalItem = new PortalItem(new Portal("https://www.arcgis.com/", false), "d815f3bdf6e6452bb8fd153b654c94ca");
84+
var dictionarySymbolStyle = new DictionarySymbolStyle(portalItem);
85+
86+
// add done loading listeners to the map and dictionary symbol style and check they have loaded
87+
map.addDoneLoadingListener(() -> {
88+
if (map.getLoadStatus() == LoadStatus.LOADED) {
89+
dictionarySymbolStyle.addDoneLoadingListener(() -> {
90+
if (dictionarySymbolStyle.getLoadStatus() == LoadStatus.LOADED) {
91+
92+
// find the first configuration setting which has the property name "model",
93+
// and set its value to "ORDERED ANCHOR POINT"
94+
dictionarySymbolStyle.getConfigurations().stream()
95+
.filter(configuration -> configuration.getName().equals("model"))
96+
.findFirst()
97+
.ifPresent(modelConfiguration -> modelConfiguration.setValue("ORDERED ANCHOR POINT"));
98+
99+
// create a new dictionary renderer from the dictionary symbol style to render graphics
100+
// with symbol dictionary attributes and set it to the graphics overlay renderer
101+
var dictionaryRenderer = new DictionaryRenderer(dictionarySymbolStyle);
102+
graphicsOverlay.setRenderer(dictionaryRenderer);
103+
104+
// parse graphic attributes from an XML file following the mil2525d specification
105+
try {
106+
List<Map<String, Object>> messages = parseMessages();
107+
108+
// create graphics with attributes and add to graphics overlay
109+
List<Graphic> graphics = messages.stream()
110+
.map(DictionaryRendererGraphicsOverlaySample::createGraphic)
111+
.collect(Collectors.toList());
112+
graphicsOverlay.getGraphics().addAll(graphics);
113+
// set the viewpoint to the extent of the graphics overlay
114+
mapView.setViewpointGeometryAsync(graphicsOverlay.getExtent());
115+
116+
} catch (Exception e) {
117+
e.printStackTrace();
118+
}
119+
} else {
120+
new Alert(Alert.AlertType.ERROR,
121+
"Failed to load symbol style " + dictionarySymbolStyle.getLoadError().getCause().getMessage()).show();
122+
}
123+
});
124+
} else {
125+
new Alert(Alert.AlertType.ERROR, "Map failed to load" + map.getLoadError().getCause().getMessage()).show();
126+
}
127+
// load the dictionary symbol style once the map has loaded
128+
dictionarySymbolStyle.loadAsync();
129+
});
92130

93-
// create graphics with attributes and add to graphics overlay
94-
messages.stream()
95-
.map(DictionaryRendererGraphicsOverlaySample::createGraphic)
96-
.collect(Collectors.toCollection(() -> graphicsOverlay.getGraphics()));
131+
// set the map to the map view and add the map view to the stack pane
132+
mapView.setMap(map);
133+
stackPane.getChildren().add(mapView);
97134

98-
// once view has loaded
99-
mapView.addSpatialReferenceChangedListener(e -> {
100-
// set initial viewpoint
101-
mapView.setViewpointGeometryAsync(graphicsOverlay.getExtent());
102-
});
135+
} catch (Exception ex) {
136+
// on any exception, print the stacktrace
137+
ex.printStackTrace();
138+
}
103139
}
104140

105141
/**
@@ -108,20 +144,20 @@ public void start(Stage stage) throws Exception {
108144
private List<Map<String, Object>> parseMessages() throws Exception {
109145

110146
File mil2525dFile = new File(System.getProperty("data.dir"), "./samples-data/xml/Mil2525DMessages.xml");
111-
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
112-
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
113-
Document document = documentBuilder.parse(mil2525dFile);
147+
var documentBuilderFactory = DocumentBuilderFactory.newInstance();
148+
var documentBuilder = documentBuilderFactory.newDocumentBuilder();
149+
var document = documentBuilder.parse(mil2525dFile);
114150
document.getDocumentElement().normalize();
115151

116152
final List<Map<String, Object>> messages = new ArrayList<>();
117153

118-
for (int i = 0; i < document.getElementsByTagName("message").getLength() ; i++) {
154+
for (int i = 0; i < document.getElementsByTagName("message").getLength(); i++) {
119155
Node message = document.getElementsByTagName("message").item(i);
120156

121157
Map<String, Object> attributes = new HashMap<>();
122158

123159
NodeList childNodes = message.getChildNodes();
124-
for (int j = 0; j < childNodes.getLength() ; j++) {
160+
for (int j = 0; j < childNodes.getLength(); j++) {
125161
attributes.put(childNodes.item(j).getNodeName(), childNodes.item(j).getTextContent());
126162
}
127163
messages.add(attributes);
@@ -132,7 +168,7 @@ private List<Map<String, Object>> parseMessages() throws Exception {
132168

133169
/**
134170
* Creates a graphic using a symbol dictionary and the attributes that were passed.
135-
*
171+
*
136172
* @param attributes tells symbol dictionary what symbol to apply to graphic
137173
*/
138174
private static Graphic createGraphic(Map<String, Object> attributes) {
@@ -141,13 +177,13 @@ private static Graphic createGraphic(Map<String, Object> attributes) {
141177
int wkid = Integer.parseInt((String) attributes.get("_wkid"));
142178
SpatialReference sr = SpatialReference.create(wkid);
143179

144-
// get points from coordinates' string
180+
// get points from the coordinate string in the "_control_points" attribute (delimited with ';')
145181
PointCollection points = new PointCollection(sr);
146182
String[] coordinates = ((String) attributes.get("_control_points")).split(";");
147183
Stream.of(coordinates)
148-
.map(cs -> cs.split(","))
149-
.map(c -> new Point(Double.valueOf(c[0]), Double.valueOf(c[1]), sr))
150-
.collect(Collectors.toCollection(() -> points));
184+
.map(cs -> cs.split(","))
185+
.map(c -> new Point(Double.parseDouble(c[0]), Double.parseDouble(c[1]), sr))
186+
.collect(Collectors.toCollection(() -> points));
151187

152188
// return a graphic with multipoint geometry
153189
return new Graphic(new Multipoint(points), attributes);
-188 KB
Loading

symbology/graphics-overlay-dictionary-renderer-3D/README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Graphics overlay dictionary renderer 3D
22

3-
Display MIL-STD-2525. military symbology in 3D.
3+
Create graphics from an XML file with key-value pairs for each graphic, and display the military symbols using a MIL-STD-2525D web style in 3D.
44

55
![Image of graphics overlay dictionary renderer 3D](GraphicsOverlayDictionaryRenderer3D.png)
66

@@ -14,24 +14,24 @@ When launched, this sample displays a scene with a dictionary renderer. Pan and
1414

1515
## How it works
1616

17-
1. Create a `SymbolDictionary` from a dictionary (stylx) file.
18-
2. Create a `DictionaryRenderer` with the symbol dictionary.
17+
1. Create a new `DictionarySymbolStyle(portalItem)` with a portal item containing a MIL-STD-2525D dictionary web style.
18+
2. Create a new `DictionaryRenderer` from the dictionary symbol style.
1919
3. Set the renderer on a graphics overlay with `graphicsOverlay.setRenderer(dictionaryRenderer)`.
20-
4. Parse an XML file conforming to the specification. It should have key-value pairs to use as attributes for each graphic:
20+
4. Parse through the local XML file creating a map of key/value pairs for each block of attributes:
2121
* Use the name of the XML node as the attribute key and the content of the node as the attribute value.
2222
* Get the WKID and coordinates from the XML to create the graphic's geometry.
2323
5. The other attributes such as "symbolentity" and "symbolset" will describe the symbology for the graphic.
2424
6. Create the graphic with the geometry and attributes and add it to the graphics overlay.
2525

2626
## Relevant API
2727

28-
* GraphicsOverlay
2928
* DictionaryRenderer
3029
* DictionarySymbolStyle
30+
* GraphicsOverlay
3131

3232
## Additional information
3333

34-
The dictionary renderer creates these graphics using a local mil2525d style file included in the SDK's resources/symbols directory plus an XML file with key-value attributes for each graphic.
34+
The dictionary symbol style in this sample is constructed from a portal item containing a [MIL-STD-2525D symbol dictionary web style](https://arcgis.com/home/item.html?id=d815f3bdf6e6452bb8fd153b654c94ca). This ArcGIS Web Style is used to build custom applications that incorporate the MIL-STD-2525D symbol dictionary. This style supports a configuration for modeling locations as ordered anchor points or full geometries.
3535

3636
## Tags
3737

symbology/graphics-overlay-dictionary-renderer-3D/README.metadata.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"category": "Symbology",
3-
"description": "Display MIL-STD-2525. military symbology in 3D.",
3+
"description": "Create graphics from an XML file with key-value pairs for each graphic, and display the military symbols using a MIL-STD-2525D web style in 3D.",
44
"ignore": false,
55
"images": [
66
"GraphicsOverlayDictionaryRenderer3D.png"

symbology/graphics-overlay-dictionary-renderer-3D/build.gradle

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@ dependencies {
3939
implementation 'org.jooq:joox:1.4.0'
4040
}
4141

42+
task createGradlePropertiesAndWriteApiKey {
43+
description = "Creates a new gradle.properties file with an empty API key variable in the user home ./gradle folder, if the file doesn't already exist."
44+
group = "build"
45+
def propertiesFile = new File("${System.properties.getProperty("user.home")}/.gradle/gradle.properties")
46+
if (!propertiesFile.exists()) {
47+
print("Go to " + new URL("https://developers.arcgis.com/dashboard") + " to get an API key.")
48+
print(" Add your API key to ${System.properties.getProperty("user.home")}\\.gradle\\gradle.properties.")
49+
propertiesFile.write("apiKey = ")
50+
}
51+
}
52+
4253
task copyNatives(type: Copy) {
4354
description = "Copies the arcgis native libraries into the project build directory for development."
4455
group = "build"
@@ -50,6 +61,10 @@ task copyNatives(type: Copy) {
5061
}
5162

5263
run {
64+
doFirst {
65+
// sets the API key from the gradle.properties file as a Java system property
66+
systemProperty 'apiKey', apiKey
67+
}
5368
dependsOn copyNatives
5469
mainClassName = 'com.esri.samples.graphics_overlay_dictionary_renderer_3D.GraphicsOverlayDictionaryRenderer3DLauncher'
5570
}

symbology/graphics-overlay-dictionary-renderer-3D/settings.gradle

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,12 @@ def ant = new groovy.util.AntBuilder()
66
if (!file("./samples-data").exists()) {
77
file("./samples-data/xml/").mkdirs()
88
ant.get(
9-
src: "https://arcgisruntime.maps.arcgis.com/sharing/rest/content/items/1e4ea99af4b440c092e7959cf3957bfa/data",
9+
src: "https://arcgisruntime.maps.arcgis.com/sharing/rest/content/items/623382e0113d40698538f249e3bcb1c0/data",
1010
dest: file("./data.zip")
1111
)
1212
ant.unzip(
1313
src: file("./data.zip"),
1414
dest: file("./samples-data/xml/")
1515
)
1616
delete file("./data.zip")
17-
file("./samples-data/stylx").mkdirs()
18-
ant.get(
19-
src: "https://arcgisruntime.maps.arcgis.com/sharing/rest/content/items/c78b149a1d52414682c86a5feeb13d30/data",
20-
dest: file("./samples-data/stylx/mil2525d.stylx")
21-
)
2217
}

0 commit comments

Comments
 (0)