Skip to content

Commit 59e9bf8

Browse files
author
Rachael Ellen
committed
Merge branch 'master' into dev
2 parents 6430c1e + 7c7e1f9 commit 59e9bf8

File tree

5 files changed

+159
-36
lines changed

5 files changed

+159
-36
lines changed
131 KB
Loading
Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Custom dictionary style
22

3-
Use a custom dictionary style (.stylx) to symbolize features using a variety of attribute values.
3+
Use a custom dictionary style created from a web style or local style file (.stylx) to symbolize features using a variety of attribute values.
44

55
![Image of custom dictionary style](CustomDictionaryStyle.png)
66

@@ -10,27 +10,35 @@ When symbolizing geoelements in your map, you may need to convey several pieces
1010

1111
## How to use the sample
1212

13-
Pan and zoom the map to see the symbology from the custom dictionary style.
13+
Use the radio buttons to toggle between the dictionary symbols from the web style and style file. Pan and zoom around the map to see the symbology from the chosen dictionary symbol style. The web style and style file are slightly different to each other to give a visual indication of the switch between the two.
1414

1515
## How it works
1616

17-
1. Create a new `DictionarySymbolStyle` by passing in the path to the custom style file (.stylx).
18-
2. Create a new `DictionaryRenderer`, providing the dictionary symbol style.
19-
3. Apply the dictionary renderer to a feature layer using `layer.setRenderer(dictionaryRenderer)`.
17+
1. Create a `PortalItem`, referring to a `Portal` and the item ID of the web style.
18+
2. Based on the style selected:
19+
* If the web style toggle has been selected, create a new `DictionarySymbolStyle` from the portal item using `new DictionarySymbolStyle(portalItem)`, and load it
20+
* If the file style toggle has been selected, create a new `DictionarySymbolStyle` using `DictionarySymbolStyle.createFromFile(stylxFile.getAbsolutePath())`
21+
3. Create a new `DictionaryRenderer`, providing the dictionary symbol style.
22+
4. Apply the dictionary renderer to a feature layer using `featureLayer.setRenderer(dictionaryRenderer)`.
23+
5. Add the feature layer to the map's operational layers using `getOperationalLayers().add(featureLayer)`.
2024

2125
## Relevant API
2226

2327
* DictionaryRenderer
2428
* DictionarySymbolStyle
29+
* Portal
30+
* PortalItem
2531

2632
## About the data
2733

28-
The data used in this sample is from a feature layer showing a subset of [restaurants in Redlands, CA](https://services2.arcgis.com/ZQgQTuoyBrtmoGdP/arcgis/rest/services/Redlands_Restaurants/FeatureServer) hosted as a feature service with attributes for rating, style, health score, and open hours. The feature layer is symbolized using a dictionary renderer that displays a single symbol for all of these variables. The renderer uses symbols from a custom [restaurant dictionary style](https://arcgisruntime.maps.arcgis.com/home/item.html?id=751138a2e0844e06853522d54103222a), available as an item from ArcGIS Online, to show unique symbols based on several feature attributes. The symbols it contains were created using ArcGIS Pro. The logic used to apply the symbols comes from an Arcade script embedded in the stylx file (which is a SQLite database), along with a JSON string that defines expected attribute names and configuration properties.
34+
The data used in this sample is from a feature layer showing a subset of [restaurants in Redlands, CA](https://services2.arcgis.com/ZQgQTuoyBrtmoGdP/arcgis/rest/services/Redlands_Restaurants/FeatureServer) hosted as a feature service with attributes for rating, style, health score, and open hours.
35+
36+
The feature layer is symbolized using a dictionary renderer that displays a single symbol for all of these variables. The renderer uses symbols from a custom restaurant dictionary style created from a [stylx file](https://arcgis.com/home/item.html?id=751138a2e0844e06853522d54103222a) and a [web style](https://arcgis.com/home/item.html?id=adee951477014ec68d7cf0ea0579c800), available as items from ArcGIS Online, to show unique symbols based on several feature attributes. The symbols it contains were created using ArcGIS Pro. The logic used to apply the symbols comes from an Arcade script embedded in the stylx file (which is a SQLite database), along with a JSON string that defines expected attribute names and configuration properties.
2937

3038
## Additional information
3139

3240
For information about creating your own custom dictionary style, see the open source [dictionary renderer toolkit](https://esriurl.com/DictionaryToolkit) on *GitHub*.
3341

3442
## Tags
3543

36-
dictionary, military, renderer, style, stylx, unique value, visualization
44+
dictionary, military, portal, portal item, renderer, style, stylx, unique value, visualization

symbology/custom-dictionary-style/README.metadata.json

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,31 @@
11
{
22
"category": "Symbology",
3-
"description": "Use a custom dictionary style (.stylx) to symbolize features using a variety of attribute values.",
3+
"description": "Use a custom dictionary style created from a web style or local style file (.stylx) to symbolize features using a variety of attribute values.",
44
"ignore": false,
55
"images": [
66
"CustomDictionaryStyle.png"
77
],
88
"keywords": [
99
"dictionary",
1010
"military",
11+
"portal",
12+
"portal item",
1113
"renderer",
1214
"style",
1315
"stylx",
1416
"unique value",
1517
"visualization",
1618
"DictionaryRenderer",
17-
"DictionarySymbolStyle"
19+
"DictionarySymbolStyle",
20+
"Portal",
21+
"PortalItem"
1822
],
1923
"redirect_from": "",
2024
"relevant_apis": [
2125
"DictionaryRenderer",
22-
"DictionarySymbolStyle"
26+
"DictionarySymbolStyle",
27+
"Portal",
28+
"PortalItem"
2329
],
2430
"snippets": [
2531
"src/main/java/com/esri/samples/custom_dictionary_style/CustomDictionaryStyleSample.java"

symbology/custom-dictionary-style/src/main/java/com/esri/samples/custom_dictionary_style/CustomDictionaryStyleSample.java

Lines changed: 131 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,51 @@
1717
package com.esri.samples.custom_dictionary_style;
1818

1919
import javafx.application.Application;
20+
import javafx.geometry.Insets;
21+
import javafx.geometry.Pos;
2022
import javafx.scene.Scene;
23+
import javafx.scene.control.Alert;
24+
import javafx.scene.control.Label;
25+
import javafx.scene.control.ProgressIndicator;
26+
import javafx.scene.control.RadioButton;
27+
import javafx.scene.control.ToggleGroup;
28+
import javafx.scene.layout.Background;
29+
import javafx.scene.layout.BackgroundFill;
30+
import javafx.scene.layout.CornerRadii;
2131
import javafx.scene.layout.StackPane;
32+
import javafx.scene.layout.VBox;
33+
import javafx.scene.paint.Paint;
2234
import javafx.stage.Stage;
2335

2436
import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
2537
import com.esri.arcgisruntime.data.ServiceFeatureTable;
2638
import com.esri.arcgisruntime.geometry.Point;
2739
import com.esri.arcgisruntime.layers.FeatureLayer;
40+
import com.esri.arcgisruntime.loadable.LoadStatus;
2841
import com.esri.arcgisruntime.mapping.ArcGISMap;
2942
import com.esri.arcgisruntime.mapping.BasemapStyle;
3043
import com.esri.arcgisruntime.mapping.Viewpoint;
3144
import com.esri.arcgisruntime.mapping.view.MapView;
45+
import com.esri.arcgisruntime.portal.Portal;
46+
import com.esri.arcgisruntime.portal.PortalItem;
3247
import com.esri.arcgisruntime.symbology.DictionaryRenderer;
3348
import com.esri.arcgisruntime.symbology.DictionarySymbolStyle;
49+
import com.esri.arcgisruntime.symbology.Renderer;
3450

3551
import java.io.File;
52+
import java.util.HashMap;
3653

3754
public class CustomDictionaryStyleSample extends Application {
3855

3956
private MapView mapView;
57+
private DictionarySymbolStyle dictSymbStyleFromPortal; // keep loadables in scope to avoid garbage collection
58+
private DictionaryRenderer webStyleDictionaryRenderer;
59+
60+
private VBox controlsVBox;
61+
private ToggleGroup toggleGroup;
62+
private RadioButton webStyleButton;
63+
private RadioButton fileStyleButton;
64+
private ProgressIndicator progressIndicator;
4065

4166
@Override
4267
public void start(Stage stage) {
@@ -57,41 +82,125 @@ public void start(Stage stage) {
5782
String yourAPIKey = System.getProperty("apiKey");
5883
ArcGISRuntimeEnvironment.setApiKey(yourAPIKey);
5984

60-
// create a map with the streets basemap style
61-
ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_STREETS);
85+
// create a map with the topographic basemap style
86+
ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC);
6287

6388
// create a map view and set the map to it
6489
mapView = new MapView();
6590
mapView.setMap(map);
6691

6792
// set the initial viewpoint to the Esri Redlands campus
68-
map.setInitialViewpoint(new Viewpoint(new Point(-1.304630524635E7, 4036698.1412000023, map.getSpatialReference()), 5000));
69-
70-
// create the restaurants feature table from the feature service
71-
ServiceFeatureTable restaurantFeatureTable = new ServiceFeatureTable("https://services2.arcgis.com/ZQgQTuoyBrtmoGdP/arcgis/rest/services/Redlands_Restaurants/FeatureServer/0");
72-
73-
// create the restaurants layer and add it to the map
74-
FeatureLayer restaurantLayer = new FeatureLayer(restaurantFeatureTable);
93+
map.setInitialViewpoint(
94+
new Viewpoint(new Point(-13046305, 4036698.1412000, map.getSpatialReference()), 5000));
95+
96+
// set up the UI
97+
setupUI();
98+
99+
// enable UI interactions once the map has loaded
100+
map.addDoneLoadingListener(() -> {
101+
if (map.getLoadStatus() == LoadStatus.LOADED) {
102+
controlsVBox.setDisable(false);
103+
} else {
104+
new Alert(Alert.AlertType.ERROR, "Map failed to load").show();
105+
}
106+
});
107+
108+
// create a stylex file from a local location
109+
File stylxFile = new File(System.getProperty("data.dir"), "./samples-data/stylx/Restaurant.stylx");
110+
// create a dictionary symbol style from the stylx file, and create a new dictionary renderer from it
111+
DictionarySymbolStyle dictSymbStyleFromFile = DictionarySymbolStyle.createFromFile(stylxFile.getAbsolutePath());
112+
DictionaryRenderer dictRendFromFile = new DictionaryRenderer(dictSymbStyleFromFile);
113+
// set the renderer from the style file to the UI
114+
fileStyleButton.setUserData(dictRendFromFile);
115+
116+
// create a portal item using the portal and the item id of the dictionary web style
117+
Portal portal = new Portal("https://arcgisruntime.maps.arcgis.com");
118+
PortalItem portalItem = new PortalItem(portal, "adee951477014ec68d7cf0ea0579c800");
119+
120+
// map the input fields in the feature layer to the dictionary symbol style's expected fields for symbols and text
121+
HashMap<String, String> fieldMap = new HashMap<>();
122+
fieldMap.put("healthgrade", "Inspection");
123+
124+
// create a new dictionary symbol style from the web style in the portal item
125+
dictSymbStyleFromPortal = new DictionarySymbolStyle(portalItem);
126+
// load the symbol dictionary
127+
dictSymbStyleFromPortal.loadAsync();
128+
129+
dictSymbStyleFromPortal.addDoneLoadingListener(() -> {
130+
if (dictSymbStyleFromPortal.getLoadStatus() == LoadStatus.LOADED) {
131+
// enable the UI
132+
controlsVBox.setDisable(false);
133+
// create a dictionary renderer with the dictionary symbol style,
134+
// and manually map the feature layer's attribute name to those expected by the dictionary symbol style
135+
webStyleDictionaryRenderer = new DictionaryRenderer(dictSymbStyleFromPortal, fieldMap, fieldMap);
136+
// set the renderer from web style to the UI
137+
webStyleButton.setUserData(webStyleDictionaryRenderer);
138+
progressIndicator.setVisible(false);
139+
} else {
140+
new Alert(Alert.AlertType.ERROR, "Dictionary symbol style failed to load!").show();
141+
}
142+
});
143+
144+
// create a service feature table and create a feature layer from it (restaurant data)
145+
var serviceFeatureTable =
146+
new ServiceFeatureTable("https://services2.arcgis.com/ZQgQTuoyBrtmoGdP/ArcGIS/rest/services/Redlands_Restaurants/FeatureServer/0");
147+
FeatureLayer restaurantLayer = new FeatureLayer(serviceFeatureTable);
75148
map.getOperationalLayers().add(restaurantLayer);
76149

77-
// open the custom style file
78-
String styleFilePath = new File(System.getProperty("data.dir"), "./samples-data/stylx/Restaurant.stylx").getAbsolutePath();
79-
DictionarySymbolStyle restaurantStyle = DictionarySymbolStyle.createFromFile(styleFilePath);
80-
81-
// create a dictionary renderer
82-
DictionaryRenderer dictionaryRenderer = new DictionaryRenderer(restaurantStyle);
83-
84-
// set the dictionary renderer to the restaurant layer
85-
restaurantLayer.setRenderer(dictionaryRenderer);
86-
87-
// add the map view and control panel to stack pane
88-
stackPane.getChildren().add(mapView);
89-
150+
// add a listener to the radio button toggle group to change the dictionary renderer
151+
toggleGroup.selectedToggleProperty().addListener((observable -> {
152+
if (toggleGroup.getSelectedToggle() != null) {
153+
// set the chosen dictionary renderer to the feature layer
154+
restaurantLayer.setRenderer((Renderer) toggleGroup.getSelectedToggle().getUserData());
155+
}
156+
})
157+
);
158+
159+
// show the style file symbols by default
160+
toggleGroup.selectToggle(fileStyleButton);
161+
162+
// add the control panel, map view, and progress indicator to the stack pane
163+
stackPane.getChildren().addAll(mapView, controlsVBox, progressIndicator);
164+
StackPane.setAlignment(controlsVBox, Pos.TOP_LEFT);
165+
StackPane.setAlignment(progressIndicator, Pos.CENTER);
166+
StackPane.setMargin(controlsVBox, new Insets(10, 0, 0, 10));
90167
} catch (Exception e) {
91168
e.printStackTrace();
92169
}
93170
}
94171

172+
/**
173+
* Sets up control panel with radio buttons to toggle between the dictionary symbol styles.
174+
*/
175+
public void setupUI() {
176+
// create a label
177+
Label symbolStyleLabel = new Label("Choose a Dictionary Symbol Style:");
178+
179+
// create radio buttons for toggling between the web and file styles
180+
webStyleButton = new RadioButton("Web style");
181+
fileStyleButton = new RadioButton("Local style file");
182+
183+
// set the radio buttons to a toggle group
184+
toggleGroup = new ToggleGroup();
185+
toggleGroup.getToggles().addAll(webStyleButton, fileStyleButton);
186+
187+
// show progress indicator when the dictionary symbol styles are loading
188+
progressIndicator = new ProgressIndicator();
189+
progressIndicator.setMaxWidth(30);
190+
progressIndicator.setVisible(true);
191+
192+
// create a control panel
193+
controlsVBox = new VBox(6);
194+
controlsVBox.setBackground(new Background(new BackgroundFill(Paint.valueOf("rgba(0,0,0,0.3)"), CornerRadii.EMPTY,
195+
Insets.EMPTY)));
196+
controlsVBox.setPadding(new Insets(10.0));
197+
controlsVBox.setMaxSize(210, 80);
198+
controlsVBox.getStyleClass().add("panel-region");
199+
controlsVBox.setDisable(true);
200+
// add the label and radio buttons to the control panel
201+
controlsVBox.getChildren().addAll(symbolStyleLabel, webStyleButton, fileStyleButton);
202+
}
203+
95204
/**
96205
* Stops and releases all resources used in application.
97206
*/
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
.panel-region .label {
1+
.label {
22
-fx-text-fill: white;
33
}
44

5-
.panel-region .check-box {
6-
-fx-text-fill: white;
7-
}
5+
.radio-button {
6+
-fx-text-fill: white;
7+
}

0 commit comments

Comments
 (0)