|
16 | 16 |
|
17 | 17 | package com.esri.samples.display_layer_view_state;
|
18 | 18 |
|
| 19 | +import java.util.ArrayList; |
| 20 | +import java.util.EnumSet; |
| 21 | +import java.util.List; |
| 22 | + |
19 | 23 | import javafx.application.Application;
|
20 | 24 | import javafx.geometry.Insets;
|
21 | 25 | import javafx.geometry.Pos;
|
22 | 26 | import javafx.scene.Scene;
|
| 27 | +import javafx.scene.control.Alert; |
| 28 | +import javafx.scene.control.Button; |
| 29 | +import javafx.scene.control.CheckBox; |
23 | 30 | import javafx.scene.control.Label;
|
24 | 31 | import javafx.scene.layout.Background;
|
25 | 32 | import javafx.scene.layout.BackgroundFill;
|
|
29 | 36 | import javafx.scene.paint.Paint;
|
30 | 37 | import javafx.stage.Stage;
|
31 | 38 |
|
32 |
| -import com.esri.arcgisruntime.data.ServiceFeatureTable; |
| 39 | +import com.esri.arcgisruntime.ArcGISRuntimeException; |
33 | 40 | import com.esri.arcgisruntime.geometry.Point;
|
34 | 41 | import com.esri.arcgisruntime.geometry.SpatialReferences;
|
35 |
| -import com.esri.arcgisruntime.layers.ArcGISMapImageLayer; |
36 |
| -import com.esri.arcgisruntime.layers.ArcGISTiledLayer; |
37 | 42 | import com.esri.arcgisruntime.layers.FeatureLayer;
|
38 |
| -import com.esri.arcgisruntime.layers.Layer; |
| 43 | +import com.esri.arcgisruntime.loadable.LoadStatus; |
39 | 44 | import com.esri.arcgisruntime.mapping.ArcGISMap;
|
| 45 | +import com.esri.arcgisruntime.mapping.Basemap; |
40 | 46 | import com.esri.arcgisruntime.mapping.Viewpoint;
|
| 47 | +import com.esri.arcgisruntime.mapping.view.LayerViewStatus; |
41 | 48 | import com.esri.arcgisruntime.mapping.view.MapView;
|
| 49 | +import com.esri.arcgisruntime.portal.Portal; |
| 50 | +import com.esri.arcgisruntime.portal.PortalItem; |
42 | 51 |
|
43 | 52 | public class DisplayLayerViewStateSample extends Application {
|
44 | 53 |
|
45 | 54 | private MapView mapView;
|
46 |
| - |
47 |
| - private static final int MIN_SCALE = 40000000; |
48 |
| - private static final int TILED_LAYER = 0; |
49 |
| - private static final int IMAGE_LAYER = 1; |
50 |
| - private static final int FEATURE_LAYER = 2; |
51 |
| - |
52 |
| - private static final String SERVICE_TIME_ZONES = |
53 |
| - "https://sampleserver6.arcgisonline.com/arcgis/rest/services/WorldTimeZones/MapServer"; |
54 |
| - private static final String SERVICE_CENSUS = |
55 |
| - "https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer"; |
56 |
| - private static final String SERVICE_RECREATION = |
57 |
| - "https://sampleserver6.arcgisonline.com/arcgis/rest/services/Recreation/FeatureServer/0"; |
| 55 | + private FeatureLayer featureLayer; |
58 | 56 |
|
59 | 57 | @Override
|
60 | 58 | public void start(Stage stage) {
|
61 | 59 |
|
62 | 60 | try {
|
63 |
| - // create stack pane and application scene |
| 61 | + // create the stack pane and the application scene |
64 | 62 | StackPane stackPane = new StackPane();
|
65 | 63 | Scene scene = new Scene(stackPane);
|
66 | 64 | scene.getStylesheets().add(getClass().getResource("/display_layer_view_state/style.css").toExternalForm());
|
67 | 65 |
|
68 |
| - // set title, size, and add scene to stage |
| 66 | + // set a title, size, and add the scene to the stage |
69 | 67 | stage.setTitle("Display Layer View State Sample");
|
70 | 68 | stage.setWidth(800);
|
71 | 69 | stage.setHeight(700);
|
72 | 70 | stage.setScene(scene);
|
73 | 71 | stage.show();
|
74 | 72 |
|
75 |
| - // create a control panel |
76 |
| - VBox controlsVBox = new VBox(6); |
77 |
| - controlsVBox.setBackground(new Background(new BackgroundFill(Paint.valueOf("rgba(0,0,0,0.3)"), CornerRadii.EMPTY, |
78 |
| - Insets.EMPTY))); |
79 |
| - controlsVBox.setPadding(new Insets(10.0)); |
80 |
| - controlsVBox.setMaxSize(220, 90); |
81 |
| - controlsVBox.getStyleClass().add("panel-region"); |
| 73 | + // create an ArcGISMap with the topographic basemap |
| 74 | + ArcGISMap map = new ArcGISMap(Basemap.createTopographic()); |
82 | 75 |
|
83 |
| - // create labels to display the view status of each layer |
84 |
| - Label worldTimeZonesLabel = new Label("World Time Zones: "); |
85 |
| - Label censusLabel = new Label("Census: "); |
86 |
| - Label facilitiesLabel = new Label("Facilities: "); |
| 76 | + // create a map view and set the ArcGISMap to it |
| 77 | + mapView = new MapView(); |
| 78 | + mapView.setMap(map); |
87 | 79 |
|
88 |
| - worldTimeZonesLabel.getStyleClass().add("panel-label"); |
89 |
| - censusLabel.getStyleClass().add("panel-label"); |
90 |
| - facilitiesLabel.getStyleClass().add("panel-label"); |
| 80 | + // set the initial viewpoint for the map view |
| 81 | + mapView.setViewpoint(new Viewpoint(new Point(-11e6, 45e5, SpatialReferences.getWebMercator()), 40000000)); |
91 | 82 |
|
92 |
| - // add labels to the control panel |
93 |
| - controlsVBox.getChildren().addAll(worldTimeZonesLabel, censusLabel, facilitiesLabel); |
| 83 | + // create a label to display the view status |
| 84 | + Label layerViewStatusLabel = new Label("Current view status: "); |
94 | 85 |
|
95 |
| - // create three layers to add to the ArcGISMap |
96 |
| - final ArcGISTiledLayer tiledLayer = new ArcGISTiledLayer(SERVICE_TIME_ZONES); |
| 86 | + // create a checkbox UI that toggles the visibility of the feature layer |
| 87 | + CheckBox visibilityCheckBox = new CheckBox(); |
| 88 | + visibilityCheckBox.setText("Layer visible"); |
| 89 | + visibilityCheckBox.setSelected(true); |
| 90 | + visibilityCheckBox.setDisable(true); |
| 91 | + visibilityCheckBox.setOnAction(event -> featureLayer.setVisible(visibilityCheckBox.isSelected())); |
97 | 92 |
|
98 |
| - // this layer will be OUT_OF_SCALE outside of its set min/max scales |
99 |
| - final ArcGISMapImageLayer imageLayer = new ArcGISMapImageLayer(SERVICE_CENSUS); |
100 |
| - imageLayer.setMinScale(MIN_SCALE); |
101 |
| - imageLayer.setMaxScale(MIN_SCALE / 10); |
| 93 | + // create a button and a listener to load a feature layer |
| 94 | + Button loadLayerButton = new Button("Load Layer"); |
| 95 | + loadLayerButton.setOnAction(event -> { |
102 | 96 |
|
103 |
| - // creating a layer from a service feature table |
104 |
| - final ServiceFeatureTable featureTable = new ServiceFeatureTable(SERVICE_RECREATION); |
105 |
| - final FeatureLayer featureLayer = new FeatureLayer(featureTable); |
| 97 | + // disable the checkbox when loading/reloading the feature layer, and, if it exists, remove it by clearing the map's operational layers |
| 98 | + if (!visibilityCheckBox.isDisabled()) { |
| 99 | + visibilityCheckBox.setDisable(true); |
| 100 | + } |
106 | 101 |
|
107 |
| - // adding layers to the ArcGISMaps' layer list |
108 |
| - final ArcGISMap map = new ArcGISMap(); |
109 |
| - map.getOperationalLayers().add(tiledLayer); |
110 |
| - map.getOperationalLayers().add(imageLayer); |
111 |
| - map.getOperationalLayers().add(featureLayer); |
| 102 | + if (featureLayer != null) { |
| 103 | + map.getOperationalLayers().clear(); |
| 104 | + } |
112 | 105 |
|
113 |
| - // create a view and set ArcGISMap to it |
114 |
| - mapView = new MapView(); |
115 |
| - mapView.setMap(map); |
| 106 | + // create a new feature layer from a portal item |
| 107 | + final PortalItem portalItem = new PortalItem(new Portal("https://runtime.maps.arcgis.com/"), |
| 108 | + "b8f4033069f141729ffb298b7418b653"); |
| 109 | + featureLayer = new FeatureLayer(portalItem, 0); |
| 110 | + // set a minimum and a maximum scale for the visibility of the feature layer |
| 111 | + featureLayer.setMinScale(40000000); |
| 112 | + featureLayer.setMaxScale(4000000); |
| 113 | + // add the feature layer to the map |
| 114 | + map.getOperationalLayers().add(featureLayer); |
| 115 | + |
| 116 | + // enable UI interactions once the feature layer has loaded |
| 117 | + featureLayer.addDoneLoadingListener(() -> { |
| 118 | + if (featureLayer.getLoadStatus() == LoadStatus.LOADED) { |
| 119 | + visibilityCheckBox.setDisable(false); |
| 120 | + featureLayer.setVisible(visibilityCheckBox.isSelected()); |
| 121 | + loadLayerButton.setText("Reload Layer"); |
| 122 | + } else { |
| 123 | + new Alert(Alert.AlertType.ERROR, "Feature layer failed to load").show(); |
| 124 | + } |
| 125 | + }); |
| 126 | + }); |
116 | 127 |
|
117 |
| - // set viewpoint |
118 |
| - mapView.setViewpoint(new Viewpoint(new Point(-11e6, 45e5, SpatialReferences.getWebMercator()), MIN_SCALE)); |
119 |
| - |
120 |
| - // fires every time a layers' view status has changed |
121 |
| - mapView.addLayerViewStateChangedListener(e -> { |
122 |
| - // holds the label that needs to be changed |
123 |
| - Layer layer = e.getLayer(); |
124 |
| - |
125 |
| - String viewStatus = e.getLayerViewStatus().iterator().next().toString(); |
126 |
| - final int layerIndex = map.getOperationalLayers().indexOf(layer); |
127 |
| - |
128 |
| - // finding and updating label that needs to be changed |
129 |
| - switch (layerIndex) { |
130 |
| - case TILED_LAYER: |
131 |
| - worldTimeZonesLabel.setText("World Time Zones: " + viewStatus); |
132 |
| - break; |
133 |
| - case IMAGE_LAYER: |
134 |
| - censusLabel.setText("Census: " + viewStatus); |
135 |
| - break; |
136 |
| - case FEATURE_LAYER: |
137 |
| - facilitiesLabel.setText("Facilities: " + viewStatus); |
| 128 | + // create a listener that fires every time a layer's view status changes |
| 129 | + mapView.addLayerViewStateChangedListener(statusChangeEvent -> { |
| 130 | + |
| 131 | + // check the layer whose state has changed is the feature layer |
| 132 | + if (statusChangeEvent.getLayer() == featureLayer) { |
| 133 | + |
| 134 | + // get the layer's view status and display the status |
| 135 | + EnumSet<LayerViewStatus> layerViewStatus = statusChangeEvent.getLayerViewStatus(); |
| 136 | + List<String> stringList = new ArrayList<>(); |
| 137 | + if (layerViewStatus.contains(LayerViewStatus.ACTIVE)) { |
| 138 | + stringList.add("Active"); |
| 139 | + } |
| 140 | + if (layerViewStatus.contains(LayerViewStatus.ERROR)) { |
| 141 | + stringList.add("Error"); |
| 142 | + } |
| 143 | + if (layerViewStatus.contains(LayerViewStatus.LOADING)) { |
| 144 | + stringList.add("Loading"); |
| 145 | + } |
| 146 | + if (layerViewStatus.contains(LayerViewStatus.NOT_VISIBLE)) { |
| 147 | + stringList.add("Not Visible"); |
| 148 | + } |
| 149 | + if (layerViewStatus.contains(LayerViewStatus.OUT_OF_SCALE)) { |
| 150 | + stringList.add("Out of Scale"); |
| 151 | + } |
| 152 | + if (layerViewStatus.contains(LayerViewStatus.WARNING)) { |
| 153 | + stringList.add("Warning"); |
| 154 | + } |
| 155 | + layerViewStatusLabel.setText("Current view status: " + String.join(", ", stringList)); |
| 156 | + |
| 157 | + // show an alert if a warning is detected from the state change |
| 158 | + ArcGISRuntimeException statusError = statusChangeEvent.getError(); |
| 159 | + if (statusError != null) { |
| 160 | + new Alert(Alert.AlertType.ERROR, "Unable to update layer view status").show(); |
| 161 | + } |
138 | 162 | }
|
139 | 163 | });
|
140 | 164 |
|
141 |
| - // add the map view and control panel to stack pane |
| 165 | + // create a control panel and add the label, checkbox and button UI components |
| 166 | + VBox controlsVBox = new VBox(15); |
| 167 | + controlsVBox.setBackground(new Background(new BackgroundFill(Paint.valueOf("rgba(0,0,0,0.5)"), CornerRadii.EMPTY, |
| 168 | + Insets.EMPTY))); |
| 169 | + controlsVBox.setPadding(new Insets(10.0)); |
| 170 | + controlsVBox.setMaxSize(320, 120); |
| 171 | + controlsVBox.getStyleClass().add("panel-region"); |
| 172 | + controlsVBox.getChildren().addAll(layerViewStatusLabel, visibilityCheckBox, loadLayerButton); |
| 173 | + |
| 174 | + // add the map view and control panel to the stack pane |
142 | 175 | stackPane.getChildren().addAll(mapView, controlsVBox);
|
143 | 176 | StackPane.setAlignment(controlsVBox, Pos.TOP_LEFT);
|
144 | 177 | StackPane.setMargin(controlsVBox, new Insets(10, 0, 0, 10));
|
|
0 commit comments