Skip to content

Commit 14aff50

Browse files
Jonathan Lavijenmerritt
authored andcommitted
Update create and edit geometries sample with scale/rotate/shapes (#797)
Updates the CreateAndEditGeometries sample with the new functionality for the upcoming release. Includes rotation/scaling of existing geometries, as well as use of the ShapeTool to create polylines/polygons of various shapes
1 parent de2e62c commit 14aff50

File tree

10 files changed

+122
-68
lines changed

10 files changed

+122
-68
lines changed
-5.64 KB
Loading

geometry/create-and-edit-geometries/README.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@ A field worker can mark features of interest on a map using an appropriate geome
1010

1111
## How to use the sample
1212

13-
To create a new geometry, press the button appropriate for the geometry type you want to create (i.e. points, multipoints, polyline, or polygon) and interactively tap and drag on the map view to create the geometry. To edit an existing geometry, tap the geometry to be edited in the map to select it and then edit the geometry by tapping and dragging elements of the geometry. If creating or editing polyline or polygon geometries, choose the desired creation/editing tool (i.e. `VertexTool` or `FreehandTool`).
13+
To create a new geometry, press the button appropriate for the geometry type you want to create (i.e. points, multipoints, polyline, or polygon) and interactively tap and drag on the map view to create the geometry.
14+
15+
To edit an existing geometry, tap the geometry to be edited in the map to select it and then edit the geometry by tapping and dragging elements of the geometry.
16+
17+
When the whole geometry is selected, you can use the control handles to scale and rotate the geometry.
18+
19+
If creating or editing polyline or polygon geometries, choose the desired creation/editing tool from the combo box.
1420

1521
Use the control panel to undo or redo changes made to the geometry, delete a selected element, save the geometry, stop the editing session and discard any edits, and remove all geometries from the map.
1622

@@ -24,10 +30,11 @@ Use the control panel to undo or redo changes made to the geometry, delete a sel
2430
* Find the desired graphic in the `result.getGraphics()` list.
2531
* Access the geometry associated with the `Graphic` using `graphic.getGeometry()` - this will be used in the `geometryEditor.start(Geometry)` method.
2632

27-
3. Create `VertexTool` or `FreehandTool` objects which define how the user interacts with the view to create or edit geometries, using `geometryEditor.setTool(geometryEditorTool)`.
28-
4. Check to see if undo and redo are possible during an editing session using `GeometryEditor.getCanUndo()` and `GeometryEditor.getCanRedo()`. If it's possible, use `GeometryEditor.undo()` and `GeometryEditor.redo()`.
29-
5. Check whether the currently selected `GeometryEditorElement` can be deleted (`GeometryEditor.getSelectedElement().getCanDelete()`). If the element can be deleted, delete using `GeometryEditor.deleteSelectedElement()`.
30-
6. Call `GeometryEditor.stop()` to finish the editing session. The `GeometryEditor` does not automatically handle the visualization of a geometry output from an editing session. This must be done manually by propagating the geometry returned by `GeometryEditor.stop()` into a `Graphic` and a `GraphicsOverlay`.
33+
3. Create `VertexTool`, `FreehandTool`, or `ShapeTool` objects which define how the user interacts with the view to create or edit geometries, using `geometryEditor.setTool(geometryEditorTool)`.
34+
4. Edit a tool's `InteractionConfiguration` to set the `GeometryEditorScaleMode` to allow either uniform or stretch scale mode.
35+
5. Check to see if undo and redo are possible during an editing session using `GeometryEditor.getCanUndo()` and `GeometryEditor.getCanRedo()`. If it's possible, use `GeometryEditor.undo()` and `GeometryEditor.redo()`.
36+
6. Check whether the currently selected `GeometryEditorElement` can be deleted (`GeometryEditor.getSelectedElement().getCanDelete()`). If the element can be deleted, delete using `GeometryEditor.deleteSelectedElement()`.
37+
7. Call `GeometryEditor.stop()` to finish the editing session. The `GeometryEditor` does not automatically handle the visualization of a geometry output from an editing session. This must be done manually by propagating the geometry returned by `GeometryEditor.stop()` into a `Graphic` and a `GraphicsOverlay`.
3138
* To create a new `Graphic` in the `GraphicsOverlay`:
3239
* Using `Graphic(Geometry)`, create a new Graphic with the geometry returned by the `GeometryEditor.stop()` method.
3340
* Append the `Graphic` to the `GraphicsOverlay`'s `GraphicListModel` (i.e. `GraphicsOverlay.getGraphics().add(Graphic)`).

geometry/create-and-edit-geometries/src/main/java/com/esri/samples/create_and_edit_geometries/CreateAndEditGeometriesController.java

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@
3434
import com.esri.arcgisruntime.mapping.view.geometryeditor.FreehandTool;
3535
import com.esri.arcgisruntime.mapping.view.geometryeditor.GeometryEditor;
3636
import com.esri.arcgisruntime.mapping.view.geometryeditor.GeometryEditorTool;
37+
import com.esri.arcgisruntime.mapping.view.geometryeditor.ShapeTool;
38+
import com.esri.arcgisruntime.mapping.view.geometryeditor.ShapeToolType;
3739
import com.esri.arcgisruntime.mapping.view.geometryeditor.VertexTool;
40+
import com.esri.arcgisruntime.mapping.view.geometryeditor.GeometryEditorScaleMode;
3841
import com.esri.arcgisruntime.symbology.SimpleFillSymbol;
3942
import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
4043
import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol;
@@ -45,6 +48,7 @@
4548
import javafx.scene.control.Alert;
4649
import javafx.scene.control.Button;
4750
import javafx.scene.control.ComboBox;
51+
import javafx.scene.control.CheckBox;
4852
import javafx.scene.input.MouseButton;
4953
import javafx.scene.paint.Color;
5054
import javafx.util.StringConverter;
@@ -60,6 +64,7 @@ public class CreateAndEditGeometriesController {
6064
@FXML private Button multipointButton;
6165
@FXML private Button polylineButton;
6266
@FXML private Button polygonButton;
67+
@FXML private CheckBox scaleModeUniformCheckBox;
6368
@FXML private Button redoButton;
6469
@FXML private Button undoButton;
6570
@FXML private Button deleteSelectedElementButton;
@@ -71,6 +76,10 @@ public class CreateAndEditGeometriesController {
7176
private GeometryEditor geometryEditor;
7277
private VertexTool vertexTool;
7378
private FreehandTool freehandTool;
79+
private ShapeTool arrowShapeTool;
80+
private ShapeTool ellipseShapeTool;
81+
private ShapeTool rectangleShapeTool;
82+
private ShapeTool triangleShapeTool;
7483
private GraphicsOverlay graphicsOverlay;
7584
private Graphic selectedGraphic;
7685
private SimpleFillSymbol fillSymbol;
@@ -101,14 +110,40 @@ public void initialize() {
101110
geometryEditor = new GeometryEditor();
102111
mapView.setGeometryEditor(geometryEditor);
103112

104-
// create vertex and freehand tools for the geometry editor and add to combo box
113+
// create vertex, freehand, and shape tools for the geometry editor and add to combo box
105114
vertexTool = new VertexTool();
106115
freehandTool = new FreehandTool();
116+
arrowShapeTool = ShapeTool.create(ShapeToolType.ARROW);
117+
ellipseShapeTool = ShapeTool.create(ShapeToolType.ELLIPSE);
118+
rectangleShapeTool = ShapeTool.create(ShapeToolType.RECTANGLE);
119+
triangleShapeTool = ShapeTool.create(ShapeToolType.TRIANGLE);
107120
toolComboBox.setConverter(new ComboBoxStringConverter());
108-
toolComboBox.getItems().addAll(vertexTool, freehandTool);
121+
toolComboBox.getItems().addAll(vertexTool, freehandTool, arrowShapeTool, ellipseShapeTool, rectangleShapeTool, triangleShapeTool);
122+
// initially configure the geometry editor with the vertex tool
123+
geometryEditor.setTool(vertexTool);
109124
// bidirectionally bind the geometry editor tool to the tool selected in the combo box
110125
toolComboBox.valueProperty().bindBidirectional(geometryEditor.toolProperty());
111126

127+
// bind the tool's scale mode property to the 'selected' property of the checkbox
128+
toolComboBox.getItems().forEach(tool -> {
129+
if (tool instanceof VertexTool){
130+
((VertexTool) tool).getConfiguration().scaleModeProperty().bind(
131+
Bindings.when(scaleModeUniformCheckBox.selectedProperty())
132+
.then(GeometryEditorScaleMode.UNIFORM)
133+
.otherwise(GeometryEditorScaleMode.STRETCH));
134+
} else if (tool instanceof FreehandTool) {
135+
((FreehandTool) tool).getConfiguration().scaleModeProperty().bind(
136+
Bindings.when(scaleModeUniformCheckBox.selectedProperty())
137+
.then(GeometryEditorScaleMode.UNIFORM)
138+
.otherwise(GeometryEditorScaleMode.STRETCH));
139+
} else if (tool instanceof ShapeTool) {
140+
((ShapeTool) tool).getConfiguration().scaleModeProperty().bind(
141+
Bindings.when(scaleModeUniformCheckBox.selectedProperty())
142+
.then(GeometryEditorScaleMode.UNIFORM)
143+
.otherwise(GeometryEditorScaleMode.STRETCH));
144+
}
145+
});
146+
112147
// create symbols for displaying new geometries
113148
// orange-red square for points
114149
pointSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.SQUARE, Color.ORANGERED, 10);
@@ -141,6 +176,9 @@ public void initialize() {
141176
Bindings.createBooleanBinding(() -> geometryEditor.getGeometry().getGeometryType().equals(GeometryType.MULTIPOINT)),
142177
Bindings.createBooleanBinding(() -> geometryEditor.getGeometry().getGeometryType().equals(GeometryType.POINT))
143178
));
179+
// disable the scaling mode checkbox when the geometry editor is editing Point geometries
180+
scaleModeUniformCheckBox.disableProperty().bind(Bindings.createBooleanBinding(() ->
181+
geometryEditor.getGeometry().getGeometryType().equals(GeometryType.POINT)));
144182
} else {
145183
// when the geometry editor is not started (and so the geometry is null) enable all geometry buttons
146184
pointButton.disableProperty().unbind();
@@ -155,6 +193,9 @@ public void initialize() {
155193
// disable combo box when geometry editor is not started
156194
toolComboBox.disableProperty().unbind();
157195
toolComboBox.setDisable(true);
196+
// disable the scaling mode checkbox when geometry editor is not started
197+
scaleModeUniformCheckBox.disableProperty().unbind();
198+
scaleModeUniformCheckBox.setDisable(true);
158199
}
159200
});
160201

@@ -366,18 +407,10 @@ private void createNewGraphic() {
366407

367408
// set graphic style based on geometry type
368409
switch (geometry.getGeometryType()) {
369-
case POINT:
370-
graphic.setSymbol(pointSymbol);
371-
break;
372-
case MULTIPOINT:
373-
graphic.setSymbol(multipointSymbol);
374-
break;
375-
case POLYLINE:
376-
graphic.setSymbol(lineSymbol);
377-
break;
378-
case POLYGON:
379-
graphic.setSymbol(fillSymbol);
380-
break;
410+
case POINT -> graphic.setSymbol(pointSymbol);
411+
case MULTIPOINT -> graphic.setSymbol(multipointSymbol);
412+
case POLYLINE -> graphic.setSymbol(lineSymbol);
413+
case POLYGON -> graphic.setSymbol(fillSymbol);
381414
}
382415

383416
// add new graphic to the graphics overlay
@@ -429,7 +462,15 @@ private static class ComboBoxStringConverter extends StringConverter<GeometryEdi
429462
public String toString(GeometryEditorTool geometryEditorTool) {
430463
if (geometryEditorTool != null) {
431464
if (geometryEditorTool instanceof VertexTool) return "Vertex Tool";
432-
else if (geometryEditorTool instanceof FreehandTool) return "Freehand Tool";
465+
if (geometryEditorTool instanceof FreehandTool) return "Freehand Tool";
466+
if (geometryEditorTool instanceof ShapeTool){
467+
return switch (((ShapeTool) geometryEditorTool).getShapeType()) {
468+
case ARROW -> "Arrow Shape Tool";
469+
case ELLIPSE -> "Ellipse Shape Tool";
470+
case RECTANGLE -> "Rectangle Shape Tool";
471+
case TRIANGLE -> "Triangle Shape Tool";
472+
};
473+
}
433474
}
434475
return "";
435476
}

geometry/create-and-edit-geometries/src/main/resources/create_and_edit_geometries/main.fxml

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<?import com.esri.arcgisruntime.mapping.view.MapView?>
2020
<?import javafx.geometry.Insets?>
2121
<?import javafx.scene.control.Button?>
22+
<?import javafx.scene.control.CheckBox?>
2223
<?import javafx.scene.control.ComboBox?>
2324
<?import javafx.scene.control.Label?>
2425
<?import javafx.scene.control.Separator?>
@@ -100,9 +101,10 @@
100101
</Button>
101102
<ComboBox fx:id="toolComboBox" disable="true" GridPane.rowIndex="3" GridPane.columnIndex="0"
102103
GridPane.columnSpan="2"/>
103-
<Separator GridPane.rowIndex="4" GridPane.columnIndex="0" GridPane.columnSpan="2" maxWidth="100"/>
104-
<Label GridPane.rowIndex="5" GridPane.columnSpan="2" GridPane.halignment="CENTER" text="Edit"/>
105-
<Button fx:id="undoButton" onAction="#handleUndoButtonClicked" GridPane.rowIndex="6"
104+
<CheckBox fx:id="scaleModeUniformCheckBox" disable="true" text="Uniform Scale" GridPane.rowIndex="4" GridPane.columnSpan="2"/>
105+
<Separator GridPane.rowIndex="5" GridPane.columnIndex="0" GridPane.columnSpan="2" maxWidth="100"/>
106+
<Label GridPane.rowIndex="6" GridPane.columnSpan="2" GridPane.halignment="CENTER" text="Edit"/>
107+
<Button fx:id="undoButton" onAction="#handleUndoButtonClicked" GridPane.rowIndex="7"
106108
GridPane.columnIndex="0" text="Undo">
107109
<graphic>
108110
<ImageView>
@@ -113,7 +115,7 @@
113115
<Tooltip text="Undo"/>
114116
</tooltip>
115117
</Button>
116-
<Button fx:id="redoButton" onAction="#handleRedoButtonClicked" GridPane.rowIndex="6"
118+
<Button fx:id="redoButton" onAction="#handleRedoButtonClicked" GridPane.rowIndex="7"
117119
GridPane.columnIndex="1" text="Redo">
118120
<graphic>
119121
<ImageView>
@@ -125,7 +127,7 @@
125127
</tooltip>
126128
</Button>
127129
<Button fx:id="deleteSelectedElementButton" onAction="#handleDeleteSelectedElementButtonClicked"
128-
disable="true" GridPane.rowIndex="7" GridPane.columnIndex="0" GridPane.columnSpan="2"
130+
disable="true" GridPane.rowIndex="8" GridPane.columnIndex="0" GridPane.columnSpan="2"
129131
text="Delete selected element">
130132
<graphic>
131133
<ImageView>
@@ -136,7 +138,7 @@
136138
<Tooltip text="Delete selected element"/>
137139
</tooltip>
138140
</Button>
139-
<Button fx:id="stopAndSaveButton" onAction="#handleStopAndSaveButtonClicked" GridPane.rowIndex="8"
141+
<Button fx:id="stopAndSaveButton" onAction="#handleStopAndSaveButtonClicked" GridPane.rowIndex="9"
140142
GridPane.columnIndex="0" GridPane.columnSpan="2" text="Stop and save edits">
141143
<graphic>
142144
<ImageView>
@@ -147,7 +149,7 @@
147149
<Tooltip text="Stop and save edits"/>
148150
</tooltip>
149151
</Button>
150-
<Button fx:id="stopAndDiscardButton" onAction="#handleStopAndDiscardButtonClicked" GridPane.rowIndex="9"
152+
<Button fx:id="stopAndDiscardButton" onAction="#handleStopAndDiscardButtonClicked" GridPane.rowIndex="10"
151153
GridPane.columnIndex="0" GridPane.columnSpan="2" text="Stop (discards edits)">
152154
<graphic>
153155
<ImageView>
@@ -160,7 +162,7 @@
160162
</tooltip>
161163
</Button>
162164
<Button fx:id="deleteAllGeometriesButton" onAction="#handleDeleteAllGeometriesButtonClicked"
163-
GridPane.rowIndex="10" GridPane.columnIndex="0" GridPane.columnSpan="2" text="Delete all geometries">
165+
GridPane.rowIndex="11" GridPane.columnIndex="0" GridPane.columnSpan="2" text="Delete all geometries">
164166
<graphic>
165167
<ImageView>
166168
<Image url="@icons/trash-32.png" requestedHeight="24" preserveRatio="true" smooth="true"/>
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
2-
"points":[[-9.59386587, 53.08289651], [-9.59370896, 53.08234917],
3-
[-9.59330546, 53.082564], [-9.59341755, 53.08286662],
4-
[-9.59326997, 53.08304595], [-9.59246485, 53.08294507],
5-
[-9.59250034, 53.08286101], [-9.59241815, 53.08284607],
6-
[-9.59286835, 53.08311506], [-9.59307943, 53.08234731]],
7-
"spatialReference":{"wkid":4326}
8-
}
2+
"points":[[-1067984.26,6998346.28],[-1067966.80,6998244.84],
3+
[-1067921.88,6998284.65],[-1067934.36,6998340.74],
4+
[-1067917.93,6998373.97],[-1067828.30,6998355.28],
5+
[-1067832.25,6998339.70],[-1067823.10,6998336.93],
6+
[-1067873.22,6998386.78],[-1067896.72,6998244.49]],
7+
"spatialReference":{"latestWkid":3857,"wkid":102100}
8+
}
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"x": -9.59309629,
3-
"y": 53.0830063,
4-
"spatialReference":{"wkid":4326}
5-
}
2+
"x":-1067898.59,
3+
"y":6998366.62,
4+
"spatialReference":{"latestWkid":3857,"wkid":102100}
5+
}
Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
{
2-
"rings": [[[-9.59350122, 53.08320723], [-9.59345177, 53.08333534],
3-
[-9.59309789, 53.08327198], [-9.59300344, 53.08317992],
4-
[-9.59221827, 53.08304034], [-9.59220706, 53.08287782],
5-
[-9.59229486, 53.08280871], [-9.59236398, 53.08268915],
6-
[-9.59255263, 53.08256769], [-9.59265165, 53.08237906],
7-
[-9.59287552, 53.08241478], [-9.59292812, 53.0823012],
8-
[-9.5932294, 53.08235022], [-9.59342188, 53.08260009],
9-
[-9.59354382, 53.08238728], [-9.59365852, 53.08203535],
10-
[-9.59408443, 53.08210446], [-9.59448232, 53.08224456],
11-
[-9.5943609, 53.08243697], [-9.59458319, 53.08245939],
12-
[-9.59439639, 53.08264619], [-9.59433288, 53.0827975],
13-
[-9.59404707, 53.08323649], [-9.59350122, 53.08320723]]],
14-
"spatialReference":{"wkid":4326}
15-
}
2+
"rings":[[[-1067943.67,6998403.86],[-1067938.17,6998427.60],
3+
[-1067898.77,6998415.86],[-1067888.26,6998398.80],
4+
[-1067800.85,6998372.93],[-1067799.61,6998342.81],
5+
[-1067809.38,6998330.00],[-1067817.07,6998307.85],
6+
[-1067838.07,6998285.34],[-1067849.10,6998250.38],
7+
[-1067874.02,6998256.00],[-1067879.87,6998235.95],
8+
[-1067913.41,6998245.03],[-1067934.84,6998291.34],
9+
[-1067948.41,6998251.90],[-1067961.18,6998186.68],
10+
[-1068008.59,6998199.49],[-1068052.89,6998225.45],
11+
[-1068039.37,6998261.11],[-1068064.12,6998265.26],
12+
[-1068043.32,6998299.88],[-1068036.25,6998327.93],
13+
[-1068004.43,6998409.28],[-1067943.67,6998403.86]]],
14+
"spatialReference":{"latestWkid":3857,"wkid":102100}
15+
}
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
{
2-
"paths":[[[-9.59486423, 53.08169453], [-9.5947812, 53.08175431],
3-
[-9.59475464, 53.08189379], [-9.59494393, 53.08213622],
4-
[-9.59464173, 53.08240521], [-9.59413694, 53.08260115],
5-
[-9.59357903, 53.0829266], [-9.59335984, 53.08311589],
6-
[-9.59318051, 53.08316903], [-9.59301779, 53.08322216],
7-
[-9.59264252, 53.08370038], [-9.59250636, 53.08383986]]],
8-
"spatialReference":{"wkid":4326}
9-
}
2+
"paths":[[[-1068095.40,6998123.52],[-1068086.16,6998134.60],
3+
[-1068083.20,6998160.44],[-1068104.27,6998205.37],
4+
[-1068070.63,6998255.22],[-1068014.44,6998291.54],
5+
[-1067952.33,6998351.85],[-1067927.93,6998386.93],
6+
[-1067907.97,6998396.78],[-1067889.86,6998406.63],
7+
[-1067848.08,6998495.26],[-1067832.92,6998521.11]]],
8+
"spatialReference":{"latestWkid":3857,"wkid":102100}
9+
}
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
2-
"paths":[[[-9.59400079, 53.08136244], [-9.59395761, 53.08149528],
3-
[-9.59368862, 53.0817045], [-9.59358235, 53.08219267],
4-
[-9.59331667, 53.08290335], [-9.59314398, 53.08314246],
5-
[-9.5930676, 53.08330519], [-9.59303439, 53.08351109],
6-
[-9.59301447, 53.08363728], [-9.59293809, 53.08387307]]],
7-
"spatialReference":{"wkid":4326}
8-
}
2+
"paths":[[[-1067999.28,6998061.97],[-1067994.48,6998086.59],
3+
[-1067964.53,6998125.37],[-1067952.70,6998215.84],
4+
[-1067923.13,6998347.54],[-1067903.90,6998391.86],
5+
[-1067895.40,6998422.02],[-1067891.70,6998460.18],
6+
[-1067889.49,6998483.56],[-1067880.98,6998527.26]]],
7+
"spatialReference":{"latestWkid":3857,"wkid":102100}
8+
}

geometry/create-and-edit-geometries/src/main/resources/create_and_edit_geometries/style.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,7 @@ Button {
1111
ComboBox {
1212
-fx-font-size: 10px;
1313
}
14+
15+
.panel-region .check-box {
16+
-fx-text-fill: white;
17+
}

0 commit comments

Comments
 (0)