Skip to content

Commit b26ce49

Browse files
authored
Merge pull request #207 from Esri/tschie/export-vector-tiles-sample
Tschie/export vector tiles sample
2 parents 060ee24 + 44eb630 commit b26ce49

File tree

4 files changed

+301
-0
lines changed

4 files changed

+301
-0
lines changed
317 KB
Loading
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
/*
2+
* Copyright 2018 Esri.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
5+
* use this file except in compliance with the License. You may obtain a copy of
6+
* the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13+
* License for the specific language governing permissions and limitations under
14+
* the License.
15+
*/
16+
17+
package com.esri.samples.tiledlayers.export_vector_tiles;
18+
19+
import java.io.File;
20+
import java.io.IOException;
21+
import java.nio.file.Files;
22+
import java.util.concurrent.ExecutionException;
23+
24+
import javafx.application.Application;
25+
import javafx.application.Platform;
26+
import javafx.geometry.Point2D;
27+
import javafx.geometry.Pos;
28+
import javafx.scene.Scene;
29+
import javafx.scene.control.Alert;
30+
import javafx.scene.control.Button;
31+
import javafx.scene.control.ProgressBar;
32+
import javafx.scene.layout.StackPane;
33+
import javafx.stage.Stage;
34+
35+
import com.esri.arcgisruntime.concurrent.Job;
36+
import com.esri.arcgisruntime.concurrent.ListenableFuture;
37+
import com.esri.arcgisruntime.data.VectorTileCache;
38+
import com.esri.arcgisruntime.geometry.Envelope;
39+
import com.esri.arcgisruntime.geometry.Point;
40+
import com.esri.arcgisruntime.layers.ArcGISVectorTiledLayer;
41+
import com.esri.arcgisruntime.layers.Layer;
42+
import com.esri.arcgisruntime.loadable.LoadStatus;
43+
import com.esri.arcgisruntime.mapping.ArcGISMap;
44+
import com.esri.arcgisruntime.mapping.Basemap;
45+
import com.esri.arcgisruntime.mapping.ItemResourceCache;
46+
import com.esri.arcgisruntime.mapping.view.Graphic;
47+
import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
48+
import com.esri.arcgisruntime.mapping.view.MapView;
49+
import com.esri.arcgisruntime.portal.Portal;
50+
import com.esri.arcgisruntime.portal.PortalItem;
51+
import com.esri.arcgisruntime.security.AuthenticationManager;
52+
import com.esri.arcgisruntime.security.DefaultAuthenticationChallengeHandler;
53+
import com.esri.arcgisruntime.symbology.SimpleLineSymbol;
54+
import com.esri.arcgisruntime.tasks.vectortilecache.ExportVectorTilesJob;
55+
import com.esri.arcgisruntime.tasks.vectortilecache.ExportVectorTilesParameters;
56+
import com.esri.arcgisruntime.tasks.vectortilecache.ExportVectorTilesResult;
57+
import com.esri.arcgisruntime.tasks.vectortilecache.ExportVectorTilesTask;
58+
59+
public class ExportVectorTilesSample extends Application {
60+
61+
private MapView mapView;
62+
63+
@Override
64+
public void start(Stage stage) throws Exception {
65+
66+
try {
67+
// create stack pane and application scene
68+
StackPane stackPane = new StackPane();
69+
Scene scene = new Scene(stackPane);
70+
71+
// set title, size, and add scene to stage
72+
stage.setTitle("Export Vector Tiles Sample");
73+
stage.setWidth(800);
74+
stage.setHeight(700);
75+
stage.setScene(scene);
76+
stage.show();
77+
78+
// set the map to the map view
79+
mapView = new MapView();
80+
81+
// authenticate with an organization account on arcgis.com
82+
AuthenticationManager.setAuthenticationChallengeHandler(new DefaultAuthenticationChallengeHandler());
83+
84+
// get the portal item of the vector tile service
85+
Portal portal = new Portal("http://www.arcgis.com", true);
86+
PortalItem portalItem = new PortalItem(portal, "86f556a2d1fd468181855a35e344567f");
87+
portalItem.addDoneLoadingListener(() -> {
88+
if (portalItem.getLoadStatus() == LoadStatus.LOADED) {
89+
// loading the vector tiled layer will invoke the authentication challenge
90+
ArcGISVectorTiledLayer vectorTiledLayer = new ArcGISVectorTiledLayer(portalItem);
91+
ArcGISMap map = new ArcGISMap(new Basemap(vectorTiledLayer));
92+
mapView.setMap(map);
93+
} else {
94+
Alert alert = new Alert(Alert.AlertType.ERROR, portalItem.getLoadError().getCause().getMessage());
95+
alert.show();
96+
}
97+
});
98+
portalItem.loadAsync();
99+
100+
// create a graphics overlay for the map view
101+
GraphicsOverlay graphicsOverlay = new GraphicsOverlay();
102+
mapView.getGraphicsOverlays().add(graphicsOverlay);
103+
104+
// create a graphic to show a box around the tiles we want to download
105+
Graphic downloadArea = new Graphic();
106+
graphicsOverlay.getGraphics().add(downloadArea);
107+
SimpleLineSymbol simpleLineSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, 0xFFFF0000, 2);
108+
downloadArea.setSymbol(simpleLineSymbol);
109+
110+
// update the box whenever the viewpoint changes
111+
mapView.addViewpointChangedListener(viewpointChangedEvent -> {
112+
if (mapView.getMap().getLoadStatus() == LoadStatus.LOADED) {
113+
// upper left corner of the downloaded tile cache area
114+
Point2D minScreenPoint = new Point2D(50, 50);
115+
// lower right corner of the downloaded tile cache area
116+
Point2D maxScreenPoint = new Point2D(mapView.getWidth() - 50, mapView.getHeight() - 50);
117+
// convert screen points to map points
118+
Point minPoint = mapView.screenToLocation(minScreenPoint);
119+
Point maxPoint = mapView.screenToLocation(maxScreenPoint);
120+
// use the points to define and return an envelope
121+
if (minPoint != null && maxPoint != null) {
122+
Envelope envelope = new Envelope(minPoint, maxPoint);
123+
downloadArea.setGeometry(envelope);
124+
}
125+
}
126+
});
127+
128+
// create button to export tiles
129+
Button exportTilesButton = new Button("Export Vector Tiles");
130+
131+
// create progress bar to show task progress
132+
ProgressBar progressBar = new ProgressBar();
133+
progressBar.setProgress(0.0);
134+
progressBar.setVisible(false);
135+
136+
// when the button is clicked, export the tiles to a temporary file
137+
exportTilesButton.setOnAction(e -> {
138+
try {
139+
File vtpkFile = File.createTempFile("tiles", ".vtpk");
140+
File resDir = Files.createTempDirectory("StyleItemResources").toFile();
141+
progressBar.setVisible(true);
142+
Layer layer = mapView.getMap().getBasemap().getBaseLayers().get(0);
143+
double maxScale = layer.getMaxScale();
144+
ExportVectorTilesTask task = new ExportVectorTilesTask((PortalItem) layer.getItem());
145+
ListenableFuture<ExportVectorTilesParameters> createParams = task
146+
.createDefaultExportVectorTilesParametersAsync(downloadArea.getGeometry(), maxScale);
147+
createParams.addDoneListener(() -> {
148+
try {
149+
ExportVectorTilesParameters params = createParams.get();
150+
ExportVectorTilesJob job = task.exportVectorTiles(params, vtpkFile.getAbsolutePath(), resDir
151+
.getAbsolutePath());
152+
job.start();
153+
job.addProgressChangedListener(() -> progressBar.setProgress(job.getProgress() / 100.0));
154+
job.addJobDoneListener(() -> {
155+
if (job.getStatus() == Job.Status.SUCCEEDED) {
156+
// show preview of exported tiles in alert
157+
ExportVectorTilesResult tilesResult = job.getResult();
158+
VectorTileCache tileCache = tilesResult.getVectorTileCache();
159+
ItemResourceCache resourceCache = tilesResult.getItemResourceCache();
160+
Alert preview = new Alert(Alert.AlertType.INFORMATION);
161+
preview.setTitle("Preview");
162+
preview.setHeaderText("Exported tiles to " + tileCache.getPath() + "\nExported resources to " +
163+
resourceCache.getPath());
164+
MapView mapPreview = new MapView();
165+
mapPreview.setMinSize(400, 400);
166+
ArcGISVectorTiledLayer tiledLayerPreview = new ArcGISVectorTiledLayer(tileCache, resourceCache);
167+
ArcGISMap previewMap = new ArcGISMap(new Basemap(tiledLayerPreview));
168+
mapPreview.setMap(previewMap);
169+
preview.getDialogPane().setContent(mapPreview);
170+
preview.show();
171+
} else {
172+
Alert alert = new Alert(Alert.AlertType.ERROR, job.getError().getAdditionalMessage());
173+
alert.show();
174+
}
175+
Platform.runLater(() -> progressBar.setVisible(false));
176+
});
177+
} catch (InterruptedException | ExecutionException ex) {
178+
Alert alert = new Alert(Alert.AlertType.ERROR, ex.getMessage());
179+
alert.show();
180+
progressBar.setVisible(false);
181+
progressBar.setProgress(0);
182+
}
183+
});
184+
} catch (IOException ex) {
185+
Alert alert = new Alert(Alert.AlertType.ERROR, "Failed to create temporary file");
186+
alert.show();
187+
}
188+
});
189+
190+
// add the map view, button, and progress bar to stack pane
191+
stackPane.getChildren().addAll(mapView, exportTilesButton, progressBar);
192+
StackPane.setAlignment(exportTilesButton, Pos.TOP_LEFT);
193+
StackPane.setAlignment(progressBar, Pos.TOP_RIGHT);
194+
} catch (Exception e) {
195+
// on any error, display the stack trace.
196+
e.printStackTrace();
197+
}
198+
}
199+
200+
/**
201+
* Stops and releases all resources used in application.
202+
*/
203+
@Override
204+
public void stop() throws Exception {
205+
206+
if (mapView != null) {
207+
mapView.dispose();
208+
}
209+
}
210+
211+
/**
212+
* Opens and runs application.
213+
*
214+
* @param args arguments passed to this application
215+
*/
216+
public static void main(String[] args) {
217+
218+
Application.launch(args);
219+
}
220+
221+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<h1>Export Vector Tiles</h1>
2+
3+
<p>Demonstrates how to export vector tiles with its style from a vector tiled layer.</p>
4+
5+
<p><img src="ExportVectorTiles.png"/></p>
6+
7+
<h2>How to use the sample</h2>
8+
9+
<p>First, a dialog will appear prompting for authentication credentials to arcgis.com. When the vector tiled layer
10+
loads, zoom in to the extent you want to export. The red box shows the extent that will be exported. Click the
11+
"Export Vector Tiles" button to start the job. A progress indicator will show. The larger the extent, the longer it
12+
will take to export. An error will show if the extent is larger than the maximum limit allowed. When finished, a
13+
dialog will show the exported result in a new map view.</p>
14+
15+
<h2>How it works</h2>
16+
17+
<p>To export tiles from an <code>ArcGISVectorTiledLayer</code>:</p>
18+
<ol>
19+
<li>Create an <code>ExportVectorTilesTask</code>, passing in the <code>PortalItem</code> for the vector tiled layer.
20+
Since vector tiled layers are premium content, you must first authenticate with the Portal.</li>
21+
<li>Create default <code>ExportTilesParameters</code> with <code>task.createDefaultExportTilesParametersAsync(extent, maxScale)</code>.</li>
22+
<li>Call <code>task.exportVectorTilesAsync(defaultParams, vtpkPath, resourcePath)</code> to create the
23+
<code>ExportVectorTilesJob</code>. The resource path is required if you want to export the tiles with the style.</li>
24+
<li>Call <code>job.start()</code> to start the export job.</li>
25+
<li>When the job is done, use <code>job.getResult()</code> to get the resulting
26+
<code>ExportVectorTilesResult</code>.</li>
27+
<li>You can load the result as a <code>ArcGISVectorTiledLayer</code> with <code>new ArcGISVectorTiledLayer(result.getVectorTileCache(), result.getItemResourceCache())</code>.</li>
28+
</ol>
29+
30+
<h2>Features</h2>
31+
32+
<ul>
33+
<li>ArcGISVectorTiledLayer</li>
34+
<li>ExportVectorTilesJob</li>
35+
<li>ExportVectorTilesParamters</li>
36+
<li>ExportVectorTilesResult</li>
37+
<li>ExportVectorTilesTask</li>
38+
<li>ItemResourceCache</li>
39+
<li>Portal</li>
40+
<li>PortalItem</li>
41+
<li>UserCredential</li>
42+
<li>VectorTileCache</li>
43+
</ul>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Copyright 2018 Esri.
4+
~
5+
~ Licensed under the Apache License, Version 2.0 (the "License"); you may not
6+
~ use this file except in compliance with the License. You may obtain a copy of
7+
~ the License at
8+
~
9+
~ http://www.apache.org/licenses/LICENSE-2.0
10+
~
11+
~ Unless required by applicable law or agreed to in writing, software
12+
~ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
~ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
~ License for the specific language governing permissions and limitations under
15+
~ the License.
16+
-->
17+
18+
<?import javafx.scene.control.ButtonType?>
19+
<?import javafx.scene.control.Dialog?>
20+
<?import javafx.scene.control.DialogPane?>
21+
<?import javafx.scene.control.PasswordField?>
22+
<?import javafx.scene.control.TextField?>
23+
<?import javafx.scene.layout.VBox?>
24+
<fx:root type="javafx.scene.control.Dialog" xmlns:fx="http://javafx.com/fxml">
25+
<dialogPane>
26+
<DialogPane>
27+
<content>
28+
<VBox spacing="10">
29+
<TextField fx:id="username" promptText="username"/>
30+
<PasswordField fx:id="password" promptText="password"/>
31+
</VBox>
32+
</content>
33+
<ButtonType fx:id="cancelButton" buttonData="CANCEL_CLOSE" text="Cancel"/>
34+
<ButtonType fx:id="continueButton" buttonData="FINISH" text="Continue"/>
35+
</DialogPane>
36+
</dialogPane>
37+
</fx:root>

0 commit comments

Comments
 (0)