Extrusion is the process of stretching a flat, 2D shape vertically to create a 3D object in a scene. For example, you can extrude building polygons by a height value to create three-dimensional building shapes.
How to use the sample
Press the button to switch between using population density and total population for extrusion. Higher extrusion directly corresponds to higher attribute values.
How it works
Create a ServiceFeatureTable from a URL.
Create a feature layer from the service feature table.
Make sure to set the rendering mode to dynamic using statesFeatureLayer.setRenderingMode(FeatureLayer.RenderingMode.DYNAMIC).
Apply a SimpleRenderer to the feature layer.
Set the extrusion mode of the render using renderer.getSceneProperties().setExtrusionMode(SceneProperties.ExtrusionMode.ABSOLUTE_HEIGHT).
Set the extrusion expression of the renderer using renderer.getSceneProperties().setExtrusionExpression(expression).
Relevant API
ExtrusionExpression
ExtrusionMode
FeatureLayer
FeatureLayer
SceneProperties
ServiceFeatureTable
SimpleRenderer
Tags
3D, extrude, extrusion, extrusion expression, height, renderer, scene
Sample Code
FeatureLayerExtrusionSample.java
Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*
* Copyright 2017 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.
*/package com.esri.samples.feature_layer_extrusion;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ListCell;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import com.esri.arcgisruntime.ArcGISRuntimeEnvironment;
import com.esri.arcgisruntime.data.ServiceFeatureTable;
import com.esri.arcgisruntime.geometry.Point;
import com.esri.arcgisruntime.geometry.SpatialReferences;
import com.esri.arcgisruntime.layers.FeatureLayer;
import com.esri.arcgisruntime.mapping.ArcGISScene;
import com.esri.arcgisruntime.mapping.BasemapStyle;
import com.esri.arcgisruntime.mapping.view.Camera;
import com.esri.arcgisruntime.mapping.view.SceneView;
import com.esri.arcgisruntime.symbology.Renderer;
import com.esri.arcgisruntime.symbology.SimpleFillSymbol;
import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
import com.esri.arcgisruntime.symbology.SimpleRenderer;
publicclassFeatureLayerExtrusionSampleextendsApplication{
private SceneView sceneView;
@Overridepublicvoidstart(Stage stage){
StackPane stackPane = new StackPane();
Scene fxScene = new Scene(stackPane);
// for adding styling to any controls that are added fxScene.getStylesheets().add(getClass().getResource("/feature_layer_extrusion/style.css").toExternalForm());
// set title, size, and add scene to stage stage.setTitle("Feature Layer Extrusion Sample");
stage.setWidth(800);
stage.setHeight(700);
stage.setScene(fxScene);
stage.show();
// authentication with an API key or named user is required to access basemaps and other location services String yourAPIKey = System.getProperty("apiKey");
ArcGISRuntimeEnvironment.setApiKey(yourAPIKey);
// create a scene with a basemap style and set it to the scene view ArcGISScene scene = new ArcGISScene(BasemapStyle.ARCGIS_TOPOGRAPHIC);
sceneView = new SceneView();
sceneView.setArcGISScene(scene);
stackPane.getChildren().add(sceneView);
// get us census data as a service feature table ServiceFeatureTable statesServiceFeatureTable = new ServiceFeatureTable("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3");
// creates feature layer from table and add to scenefinal FeatureLayer statesFeatureLayer = new FeatureLayer(statesServiceFeatureTable);
// feature layer must be rendered dynamically for extrusion to work statesFeatureLayer.setRenderingMode(FeatureLayer.RenderingMode.DYNAMIC);
scene.getOperationalLayers().add(statesFeatureLayer);
// symbols are used to display features (US states) from table SimpleLineSymbol lineSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, 0xFF000000, 1.0f);
SimpleFillSymbol fillSymbol = new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, 0xFF0000FF, lineSymbol);
final SimpleRenderer renderer = new SimpleRenderer(fillSymbol);
// set the extrusion mode to absolute height renderer.getSceneProperties().setExtrusionMode(Renderer.SceneProperties.ExtrusionMode.ABSOLUTE_HEIGHT);
statesFeatureLayer.setRenderer(renderer);
// set camera to focus on state features Point lookAtPoint = new Point(-10974490, 4814376, 0, SpatialReferences.getWebMercator());
sceneView.setViewpointCamera(new Camera(lookAtPoint, 10000000, 0, 20, 0));
// create a combo box to choose between different expressions/attributes to extrude by ComboBox<ExtrusionAttribute> attributeComboBox = new ComboBox<>();
attributeComboBox.setCellFactory(list -> new ListCell<ExtrusionAttribute> (){
@OverrideprotectedvoidupdateItem(ExtrusionAttribute attribute, boolean bln){
super.updateItem(attribute, bln);
if (attribute != null) {
setText(attribute.getName());
}
}
});
attributeComboBox.setConverter(new StringConverter<ExtrusionAttribute>() {
@Overridepublic String toString(ExtrusionAttribute travelMode){
return travelMode != null ? travelMode.getName() : "";
}
@Overridepublic ExtrusionAttribute fromString(String fileName){
returnnull;
}
});
// scale down outlier populations ExtrusionAttribute populationDensity = new ExtrusionAttribute("Population Density","[POP07_SQMI] * 5000 + 100000");
// scale up density ExtrusionAttribute totalPopulation = new ExtrusionAttribute("Total Population", "[POP2007]/ 10");
attributeComboBox.setItems(FXCollections.observableArrayList(populationDensity, totalPopulation));
stackPane.getChildren().add(attributeComboBox);
StackPane.setAlignment(attributeComboBox, Pos.TOP_LEFT);
StackPane.setMargin(attributeComboBox, new Insets(10, 0, 0, 10));
// set the extrusion expression on the renderer when one is chosen in the combo box attributeComboBox.getSelectionModel().selectedItemProperty().addListener(e -> {
ExtrusionAttribute selectedAttribute = attributeComboBox.getSelectionModel().getSelectedItem();
renderer.getSceneProperties().setExtrusionExpression(selectedAttribute.getExpression());
});
// start with total population selected attributeComboBox.getSelectionModel().select(totalPopulation);
}
/**
* Create a helper class for showing the extrusion attribute name in a ComboBox.
*/privateclassExtrusionAttribute{
private String name;
private String expression;
publicExtrusionAttribute(String name, String expression){
this.name = name;
this.expression = expression;
}
public String getName(){
return name;
}
public String getExpression(){
return expression;
}
}
/**
* Stops and releases all resources used in application.
*/@Overridepublicvoidstop(){
if (sceneView != null) {
sceneView.dispose();
}
}
/**
* Opens and runs application.
*
* @param args arguments passed to this application
*/publicstaticvoidmain(String[] args){
Application.launch(args);
}
}