diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..fe182873e6 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,26 @@ +## Description + +## Links and Data + +## What To Review + + +## How to Test + + + + + diff --git a/README.md b/README.md index 0ffe5dc6df..55fcdf0064 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Overview -ArcGIS Runtime API for Android v100.13.0 samples. The `main` branch of this repository contains sample app modules for the latest available version of the [ArcGIS Runtime API for Android](https://developers.arcgis.com/android/). Samples released under older versions can be found through the [git tags](https://github.com/Esri/arcgis-runtime-samples-android/tags). Please read our [wiki](https://github.com/Esri/arcgis-runtime-samples-android/wiki) for help with working with this repository. +ArcGIS Runtime API for Android v100.14.0 samples. The `main` branch of this repository contains sample app modules for the latest available version of the [ArcGIS Runtime API for Android](https://developers.arcgis.com/android/). Samples released under older versions can be found through the [git tags](https://github.com/Esri/arcgis-runtime-samples-android/tags). Please read our [wiki](https://github.com/Esri/arcgis-runtime-samples-android/wiki) for help with working with this repository. # Prerequisites * The samples are building with `compileSdkVersion 31` diff --git a/java/README.md b/java/README.md index 13600c2ae7..7e5e217eb6 100644 --- a/java/README.md +++ b/java/README.md @@ -1,7 +1,7 @@ # ArcGIS Android Java Samples ## Requirements -- [Android Plugin for Gradle 3.0.0](https://developer.android.com/studio/build/gradle-plugin-3-0-0.html) +- [Android Plugin for Gradle 7.0.2](https://developer.android.com/studio/releases/gradle-plugin#7-0-0) ## Import Java Samples into Android Studio diff --git a/java/add-enc-exchange-set/src/main/java/com/esri/arcgisruntime/sample/addencexchangeset/MainActivity.java b/java/add-enc-exchange-set/src/main/java/com/esri/arcgisruntime/sample/addencexchangeset/MainActivity.java index ed65bb7743..9f610b479f 100644 --- a/java/add-enc-exchange-set/src/main/java/com/esri/arcgisruntime/sample/addencexchangeset/MainActivity.java +++ b/java/add-enc-exchange-set/src/main/java/com/esri/arcgisruntime/sample/addencexchangeset/MainActivity.java @@ -59,7 +59,7 @@ protected void onCreate(Bundle savedInstanceState) { // get a reference to the map view mMapView = findViewById(R.id.mapView); - // create a map with the BasemapType topographic + // create a map with the Basemap Style topographic ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_OCEANS); // set the map to be displayed in this view mMapView.setMap(map); diff --git a/java/add-features-feature-service/src/main/java/com/esri/arcgisruntime/sample/addfeaturesfeatureservice/MainActivity.java b/java/add-features-feature-service/src/main/java/com/esri/arcgisruntime/sample/addfeaturesfeatureservice/MainActivity.java index 75b24a1919..7086016e41 100644 --- a/java/add-features-feature-service/src/main/java/com/esri/arcgisruntime/sample/addfeaturesfeatureservice/MainActivity.java +++ b/java/add-features-feature-service/src/main/java/com/esri/arcgisruntime/sample/addfeaturesfeatureservice/MainActivity.java @@ -32,7 +32,9 @@ import com.esri.arcgisruntime.concurrent.ListenableFuture; import com.esri.arcgisruntime.data.Feature; import com.esri.arcgisruntime.data.FeatureEditResult; +import com.esri.arcgisruntime.data.FeatureTableEditResult; import com.esri.arcgisruntime.data.ServiceFeatureTable; +import com.esri.arcgisruntime.data.ServiceGeodatabase; import com.esri.arcgisruntime.geometry.Point; import com.esri.arcgisruntime.layers.FeatureLayer; import com.esri.arcgisruntime.mapping.ArcGISMap; @@ -62,15 +64,20 @@ public class MainActivity extends AppCompatActivity { // create a map with streets basemap ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_STREETS); - // create service feature table from URL - mServiceFeatureTable = new ServiceFeatureTable(getString(R.string.service_layer_url)); - - // create a feature layer from table - FeatureLayer featureLayer = new FeatureLayer(mServiceFeatureTable); - - // add the layer to the map - map.getOperationalLayers().add(featureLayer); - + // create and load the service geodatabase + ServiceGeodatabase serviceGeodatabase = new ServiceGeodatabase(getString(R.string.service_layer_url)); + serviceGeodatabase.loadAsync(); + serviceGeodatabase.addDoneLoadingListener(() -> { + // create a feature layer using the first layer in the ServiceFeatureTable + mServiceFeatureTable = serviceGeodatabase.getTable(0); + // create a feature layer from table + FeatureLayer featureLayer = new FeatureLayer(mServiceFeatureTable); + // add the layer to the map + map.getOperationalLayers().add(featureLayer); + // set map to be displayed in map view + mMapView.setMap(map); + mMapView.setViewpoint(new Viewpoint( 40.0, -95.0, 10000000.0)); + }); // add a listener to the MapView to detect when a user has performed a single tap to add a new feature to // the service feature table mMapView.setOnTouchListener(new DefaultMapViewOnTouchListener(this, mMapView) { @@ -86,10 +93,6 @@ public class MainActivity extends AppCompatActivity { return super.onSingleTapConfirmed(event); } }); - - // set map to be displayed in map view - mMapView.setMap(map); - mMapView.setViewpoint(new Viewpoint( 40.0, -95.0, 10000000.0)); } /** @@ -126,17 +129,13 @@ private void addFeature(Point mapPoint, final ServiceFeatureTable featureTable) private void applyEdits(ServiceFeatureTable featureTable) { // apply the changes to the server - final ListenableFuture> editResult = featureTable.applyEditsAsync(); + final ListenableFuture> editResult = featureTable.getServiceGeodatabase().applyEditsAsync(); editResult.addDoneListener(() -> { try { - List editResults = editResult.get(); + List editResults = editResult.get(); // check if the server edit was successful if (editResults != null && !editResults.isEmpty()) { - if (!editResults.get(0).hasCompletedWithErrors()) { - runOnUiThread(() -> logToUser(false, getString(R.string.feature_added))); - } else { - throw editResults.get(0).getError(); - } + runOnUiThread(() -> logToUser(false, getString(R.string.feature_added))); } } catch (InterruptedException | ExecutionException e) { runOnUiThread(() -> logToUser(true, getString(R.string.error_applying_edits, e.getCause().getMessage()))); diff --git a/java/add-features-feature-service/src/main/res/values/strings.xml b/java/add-features-feature-service/src/main/res/values/strings.xml index c9ef1a14e5..34ea1e7a4e 100644 --- a/java/add-features-feature-service/src/main/res/values/strings.xml +++ b/java/add-features-feature-service/src/main/res/values/strings.xml @@ -1,7 +1,7 @@ Add Features - Feature Service - https://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/FeatureServer/0 + https://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/FeatureServer Feature successfully added Cannot add a feature to this feature table diff --git a/java/add-graphics-renderer/src/main/java/com/esri/arcgisruntime/sample/addgraphicsrenderer/MainActivity.java b/java/add-graphics-renderer/src/main/java/com/esri/arcgisruntime/sample/addgraphicsrenderer/MainActivity.java index b44f4e3ab7..82f3f61d7d 100644 --- a/java/add-graphics-renderer/src/main/java/com/esri/arcgisruntime/sample/addgraphicsrenderer/MainActivity.java +++ b/java/add-graphics-renderer/src/main/java/com/esri/arcgisruntime/sample/addgraphicsrenderer/MainActivity.java @@ -58,7 +58,7 @@ protected void onCreate(Bundle savedInstanceState) { // create MapView from layout mMapView = findViewById(R.id.mapView); - // create a map with the Basemap Type topographic + // create a map with the Basemap Style topographic ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC); // add graphics overlay addGraphicsOverlay(); diff --git a/java/add-graphics-with-symbols/src/main/java/com/esri/arcgisruntime/sample/addgraphicswithsymbols/MainActivity.java b/java/add-graphics-with-symbols/src/main/java/com/esri/arcgisruntime/sample/addgraphicswithsymbols/MainActivity.java index 594bf54a4a..589c767b6e 100644 --- a/java/add-graphics-with-symbols/src/main/java/com/esri/arcgisruntime/sample/addgraphicswithsymbols/MainActivity.java +++ b/java/add-graphics-with-symbols/src/main/java/com/esri/arcgisruntime/sample/addgraphicswithsymbols/MainActivity.java @@ -54,7 +54,7 @@ protected void onCreate(Bundle savedInstanceState) { // inflate MapView from layout mMapView = findViewById(R.id.mapView); - // create a map with the BasemapType topographic + // create a map with the Basemap Style topographic ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_OCEANS); // set the map to be displayed in this view mMapView.setMap(map); diff --git a/java/add-point-scene-layer/build.gradle b/java/add-point-scene-layer/build.gradle index 846f8478e3..f130d2a89d 100644 --- a/java/add-point-scene-layer/build.gradle +++ b/java/add-point-scene-layer/build.gradle @@ -9,6 +9,7 @@ android { targetSdkVersion rootProject.ext.targetSdkVersion versionCode rootProject.ext.versionCode versionName rootProject.ext.versionName + buildConfigField("String", "API_KEY", API_KEY) } buildTypes { diff --git a/java/add-point-scene-layer/src/main/java/com/esri/arcgisruntime/sample/addpointscenelayer/MainActivity.java b/java/add-point-scene-layer/src/main/java/com/esri/arcgisruntime/sample/addpointscenelayer/MainActivity.java index 1921e8ef97..a81f40b6dc 100644 --- a/java/add-point-scene-layer/src/main/java/com/esri/arcgisruntime/sample/addpointscenelayer/MainActivity.java +++ b/java/add-point-scene-layer/src/main/java/com/esri/arcgisruntime/sample/addpointscenelayer/MainActivity.java @@ -19,10 +19,12 @@ import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; +import com.esri.arcgisruntime.ArcGISRuntimeEnvironment; import com.esri.arcgisruntime.layers.ArcGISSceneLayer; import com.esri.arcgisruntime.mapping.ArcGISScene; import com.esri.arcgisruntime.mapping.ArcGISTiledElevationSource; import com.esri.arcgisruntime.mapping.Basemap; +import com.esri.arcgisruntime.mapping.BasemapStyle; import com.esri.arcgisruntime.mapping.Surface; import com.esri.arcgisruntime.mapping.view.SceneView; @@ -35,10 +37,14 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); + // authentication with an API key or named user is required to access basemaps and other + // location services + ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY); + mSceneView = findViewById(R.id.sceneView); // create a scene with a basemap and add it to the scene view - ArcGISScene scene = new ArcGISScene(Basemap.Type.IMAGERY); + ArcGISScene scene = new ArcGISScene(BasemapStyle.ARCGIS_IMAGERY); mSceneView.setScene(scene); // set the base surface with world elevation diff --git a/java/analyze-hotspots/src/main/java/com/esri/arcgisruntime/sample/analyzehotspots/MainActivity.java b/java/analyze-hotspots/src/main/java/com/esri/arcgisruntime/sample/analyzehotspots/MainActivity.java index e3ce4fa65a..dce99470b0 100644 --- a/java/analyze-hotspots/src/main/java/com/esri/arcgisruntime/sample/analyzehotspots/MainActivity.java +++ b/java/analyze-hotspots/src/main/java/com/esri/arcgisruntime/sample/analyzehotspots/MainActivity.java @@ -90,7 +90,7 @@ protected void onCreate(Bundle savedInstanceState) { // inflate MapView from layout mMapView = findViewById(R.id.mapView); - // create a map with the BasemapType topographic + // create a map with the Basemap Style topographic ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC); // set the map to the map view diff --git a/java/animate-3d-graphic/src/main/java/com/esri/arcgisruntime/sample/animate3dgraphic/MainActivity.java b/java/animate-3d-graphic/src/main/java/com/esri/arcgisruntime/sample/animate3dgraphic/MainActivity.java index a022481833..0e8aac9650 100644 --- a/java/animate-3d-graphic/src/main/java/com/esri/arcgisruntime/sample/animate3dgraphic/MainActivity.java +++ b/java/animate-3d-graphic/src/main/java/com/esri/arcgisruntime/sample/animate3dgraphic/MainActivity.java @@ -391,9 +391,9 @@ private void animate(int keyFrame) { // update the HUD runOnUiThread(() -> { mCurrAltitude.setText(String.format("%.2f", position.getZ())); - mCurrHeading.setText(String.format("%.2f", (float) datum.get("HEADING"))); - mCurrPitch.setText(String.format("%.2f", (float) datum.get("PITCH"))); - mCurrRoll.setText(String.format("%.2f", (float) datum.get("ROLL"))); + mCurrHeading.setText(String.format("%.2f", datum.get("HEADING"))); + mCurrPitch.setText(String.format("%.2f", datum.get("PITCH"))); + mCurrRoll.setText(String.format("%.2f", datum.get("ROLL"))); }); // update mission progress seek bar diff --git a/java/arcgis-map-image-layer-url/src/main/java/com/esri/arcgisruntime/sample/arcgismapimagelayerurl/MainActivity.java b/java/arcgis-map-image-layer-url/src/main/java/com/esri/arcgisruntime/sample/arcgismapimagelayerurl/MainActivity.java index ba651b8aaf..86a389b352 100644 --- a/java/arcgis-map-image-layer-url/src/main/java/com/esri/arcgisruntime/sample/arcgismapimagelayerurl/MainActivity.java +++ b/java/arcgis-map-image-layer-url/src/main/java/com/esri/arcgisruntime/sample/arcgismapimagelayerurl/MainActivity.java @@ -35,7 +35,7 @@ protected void onCreate(Bundle savedInstanceState) { // get a reference to the map view mMapView = findViewById(R.id.mapView); // create a MapImageLayer with dynamically generated map images - ArcGISMapImageLayer mapImageLayer = new ArcGISMapImageLayer(getString(R.string.world_elevation_service)); + ArcGISMapImageLayer mapImageLayer = new ArcGISMapImageLayer("https://sampleserver5.arcgisonline.com/arcgis/rest/services/Elevation/WorldElevations/MapServer"); // create an empty map instance ArcGISMap map = new ArcGISMap(); // add map image layer as operational layer diff --git a/java/arcgis-map-image-layer-url/src/main/res/values/strings.xml b/java/arcgis-map-image-layer-url/src/main/res/values/strings.xml index d201e304a1..3344ec87a7 100644 --- a/java/arcgis-map-image-layer-url/src/main/res/values/strings.xml +++ b/java/arcgis-map-image-layer-url/src/main/res/values/strings.xml @@ -1,6 +1,3 @@ ArcGIS Map Image Layer (URL) - - - https://sampleserver5.arcgisonline.com/arcgis/rest/services/Elevation/WorldElevations/MapServer diff --git a/java/blend-renderer/src/main/java/com/esri/arcgisruntime/sample/blendrenderer/MainActivity.java b/java/blend-renderer/src/main/java/com/esri/arcgisruntime/sample/blendrenderer/MainActivity.java index df1b3d37cf..9cec2da801 100644 --- a/java/blend-renderer/src/main/java/com/esri/arcgisruntime/sample/blendrenderer/MainActivity.java +++ b/java/blend-renderer/src/main/java/com/esri/arcgisruntime/sample/blendrenderer/MainActivity.java @@ -76,7 +76,7 @@ protected void onCreate(Bundle savedInstanceState) { mPixelSizePower = 1; mOutputBitDepth = 8; // retrieve the MapView from layout - mMapView = (MapView) findViewById(R.id.mapView); + mMapView = findViewById(R.id.mapView); mFragmentManager = getSupportFragmentManager(); // create raster files diff --git a/java/blend-renderer/src/main/java/com/esri/arcgisruntime/sample/blendrenderer/ParametersDialogFragment.java b/java/blend-renderer/src/main/java/com/esri/arcgisruntime/sample/blendrenderer/ParametersDialogFragment.java index 72d89f1e43..831802f781 100644 --- a/java/blend-renderer/src/main/java/com/esri/arcgisruntime/sample/blendrenderer/ParametersDialogFragment.java +++ b/java/blend-renderer/src/main/java/com/esri/arcgisruntime/sample/blendrenderer/ParametersDialogFragment.java @@ -88,8 +88,8 @@ public void onClick(DialogInterface dialog, int which) { } }); - mCurrAltitudeTextView = (TextView) dialogView.findViewById(R.id.curr_altitude_text); - SeekBar altitudeSeekBar = (SeekBar) dialogView.findViewById(R.id.altitude_seek_bar); + mCurrAltitudeTextView = dialogView.findViewById(R.id.curr_altitude_text); + SeekBar altitudeSeekBar = dialogView.findViewById(R.id.altitude_seek_bar); altitudeSeekBar.setMax(90); //altitude is restricted to 0 - 90 //set initial altitude value updateAltitudeSeekBar(altitudeSeekBar); @@ -109,8 +109,8 @@ public void onStopTrackingTouch(SeekBar seekBar) { } }); - mCurrAzimuthTextView = (TextView) dialogView.findViewById(R.id.curr_azimuth_text); - SeekBar azimuthSeekBar = (SeekBar) dialogView.findViewById(R.id.azimuth_seek_bar); + mCurrAzimuthTextView = dialogView.findViewById(R.id.curr_azimuth_text); + SeekBar azimuthSeekBar = dialogView.findViewById(R.id.azimuth_seek_bar); azimuthSeekBar.setMax(360); //azimuth measured in degrees 0 - 360 //set initial azimuth value updateAzimuthSeekBar(azimuthSeekBar); @@ -141,7 +141,7 @@ public void onStopTrackingTouch(SeekBar seekBar) { R.layout.spinner_text_view, slopeTypeArray); - Spinner slopeTypeSpinner = (Spinner) dialogView.findViewById(R.id.slope_type_spinner); + Spinner slopeTypeSpinner = dialogView.findViewById(R.id.slope_type_spinner); slopeTypeSpinner.setAdapter(slopeTypeSpinnerAdapter); slopeTypeSpinner.setSelection(mSlopeType.ordinal()); slopeTypeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @@ -179,7 +179,7 @@ public void onNothingSelected(AdapterView parent) { R.layout.spinner_text_view, colorRampTypeArray); - Spinner colorRampSpinner = (Spinner) dialogView.findViewById(R.id.color_ramp_spinner); + Spinner colorRampSpinner = dialogView.findViewById(R.id.color_ramp_spinner); colorRampSpinner.setAdapter(colorRampSpinnerAdapter); colorRampSpinner.setSelection(mColorRampType.ordinal()); colorRampSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { diff --git a/java/browse-wfs-layers/src/main/java/com/esri/arcgisruntime/sample/browsewfslayers/WfsLayerInfoAdapter.java b/java/browse-wfs-layers/src/main/java/com/esri/arcgisruntime/sample/browsewfslayers/WfsLayerInfoAdapter.java index 86d8b44029..144fbf7b6c 100644 --- a/java/browse-wfs-layers/src/main/java/com/esri/arcgisruntime/sample/browsewfslayers/WfsLayerInfoAdapter.java +++ b/java/browse-wfs-layers/src/main/java/com/esri/arcgisruntime/sample/browsewfslayers/WfsLayerInfoAdapter.java @@ -37,7 +37,7 @@ public class WfsLayerInfoAdapter extends RecyclerView.Adapter mWfsLayerInfos = new ArrayList<>(); + private final List mWfsLayerInfos = new ArrayList<>(); private WfsLayerInfo mSelectedWfsLayerInfo; WfsLayerInfoAdapter(OnItemSelectedListener onItemSelectedListener) { @@ -85,7 +85,7 @@ void addLayer(WfsLayerInfo wfsLayerInfo) { */ class ViewHolder extends RecyclerView.ViewHolder { - private TextView mTextView; + private final TextView mTextView; ViewHolder(@NonNull View itemView) { super(itemView); diff --git a/java/change-basemaps/README.md b/java/change-basemaps/README.md index b8532ec60f..f6567da36d 100644 --- a/java/change-basemaps/README.md +++ b/java/change-basemaps/README.md @@ -16,7 +16,7 @@ Use the navigation drawer to select the active basemap from the list of availabl 1. Create an `ArcGISMap` object. 2. Set the map to the `MapView` object. -3. Choose a new basemap type and set it on the map. +3. Choose a new basemap style and set it on the map. ## Relevant API * ArcGISMap diff --git a/java/change-basemaps/src/main/java/com/esri/arcgisruntime/sample/switchbasemaps/MainActivity.java b/java/change-basemaps/src/main/java/com/esri/arcgisruntime/sample/switchbasemaps/MainActivity.java index 86840e8571..d05092c64a 100644 --- a/java/change-basemaps/src/main/java/com/esri/arcgisruntime/sample/switchbasemaps/MainActivity.java +++ b/java/change-basemaps/src/main/java/com/esri/arcgisruntime/sample/switchbasemaps/MainActivity.java @@ -31,6 +31,7 @@ import com.esri.arcgisruntime.mapping.ArcGISMap; import com.esri.arcgisruntime.mapping.Basemap; import com.esri.arcgisruntime.mapping.BasemapStyle; +import com.esri.arcgisruntime.mapping.Viewpoint; import com.esri.arcgisruntime.mapping.view.MapView; public class MainActivity extends AppCompatActivity { @@ -56,7 +57,7 @@ protected void onCreate(Bundle savedInstanceState) { ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY); // inflate navigation drawer - mNavigationDrawerItemTitles = getResources().getStringArray(R.array.basemap_types); + mNavigationDrawerItemTitles = getResources().getStringArray(R.array.basemap_styles); mDrawerList = findViewById(R.id.navList); mDrawerLayout = findViewById(R.id.drawer_layout); // get app title @@ -75,9 +76,11 @@ protected void onCreate(Bundle savedInstanceState) { // inflate MapView from layout mMapView = findViewById(R.id.mapView); // create a map with Topographic Basemap - mMap = new ArcGISMap(Basemap.Type.TOPOGRAPHIC, 47.6047381, -122.3334255, 12); + mMap = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC); // set the map to be displayed in this view mMapView.setMap(mMap); + // set a viewpoint around Seattle + mMapView.setViewpoint(new Viewpoint( 47.6047381, -122.3334255, 100000)); } /** diff --git a/java/change-basemaps/src/main/res/values/strings.xml b/java/change-basemaps/src/main/res/values/strings.xml index ea806c0700..f1d98bae2e 100644 --- a/java/change-basemaps/src/main/res/values/strings.xml +++ b/java/change-basemaps/src/main/res/values/strings.xml @@ -4,7 +4,7 @@ Open navigation drawer Close navigation drawer - + Streets Navigation Topographic diff --git a/java/change-sublayer-renderer/src/main/java/com/esri/arcgisruntime/sample/changesublayerrenderer/MainActivity.java b/java/change-sublayer-renderer/src/main/java/com/esri/arcgisruntime/sample/changesublayerrenderer/MainActivity.java index 9441d017c1..acb2a79629 100644 --- a/java/change-sublayer-renderer/src/main/java/com/esri/arcgisruntime/sample/changesublayerrenderer/MainActivity.java +++ b/java/change-sublayer-renderer/src/main/java/com/esri/arcgisruntime/sample/changesublayerrenderer/MainActivity.java @@ -56,7 +56,7 @@ protected void onCreate(Bundle savedInstanceState) { // inflate mapView from layout mMapView = findViewById(R.id.mapView); - // create a map with a BasemapType STREETS + // create a map with a Basemap Style STREETS ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_STREETS); // set the map to be displayed in this view mMapView.setMap(map); diff --git a/java/change-sublayer-visibility/src/main/java/com/esri/arcgisruntime/sample/mapimagelayersublayervisibility/MainActivity.java b/java/change-sublayer-visibility/src/main/java/com/esri/arcgisruntime/sample/mapimagelayersublayervisibility/MainActivity.java index 6c90daff5c..d30faa577a 100644 --- a/java/change-sublayer-visibility/src/main/java/com/esri/arcgisruntime/sample/mapimagelayersublayervisibility/MainActivity.java +++ b/java/change-sublayer-visibility/src/main/java/com/esri/arcgisruntime/sample/mapimagelayersublayervisibility/MainActivity.java @@ -46,7 +46,7 @@ protected void onCreate(Bundle savedInstanceState) { // inflate MapView from layout mMapView = findViewById(R.id.mapView); - // create a map with the Basemap Type topographic + // create a map ArcGISMap map = new ArcGISMap(); // create a MapImageLayer with dynamically generated map images mMapImageLayer = new ArcGISMapImageLayer(getResources().getString(R.string.world_cities_service)); diff --git a/java/create-and-save-map/src/main/java/com/esri/arcgisruntime/sample/createandsavemap/MainActivity.java b/java/create-and-save-map/src/main/java/com/esri/arcgisruntime/sample/createandsavemap/MainActivity.java index c57b3d21b6..afa951fafa 100644 --- a/java/create-and-save-map/src/main/java/com/esri/arcgisruntime/sample/createandsavemap/MainActivity.java +++ b/java/create-and-save-map/src/main/java/com/esri/arcgisruntime/sample/createandsavemap/MainActivity.java @@ -331,11 +331,7 @@ public boolean onOptionsItemSelected(MenuItem item) { @Override public boolean onPrepareOptionsMenu(Menu menu) { // if nav drawer is opened, hide the action items - if (mDrawerLayout.isDrawerOpen(GravityCompat.START)) { - menu.findItem(R.id.action_save).setVisible(false); - } else { - menu.findItem(R.id.action_save).setVisible(true); - } + menu.findItem(R.id.action_save).setVisible(!mDrawerLayout.isDrawerOpen(GravityCompat.START)); return super.onPrepareOptionsMenu(menu); } diff --git a/java/create-geometries/src/main/java/com/esri/arcgisruntime/sample/creategeometries/MainActivity.java b/java/create-geometries/src/main/java/com/esri/arcgisruntime/sample/creategeometries/MainActivity.java index 87256ace86..dab8d8f32e 100644 --- a/java/create-geometries/src/main/java/com/esri/arcgisruntime/sample/creategeometries/MainActivity.java +++ b/java/create-geometries/src/main/java/com/esri/arcgisruntime/sample/creategeometries/MainActivity.java @@ -119,7 +119,7 @@ protected void onCreate(Bundle savedInstanceState) { // get MapView from layout mMapView = findViewById(R.id.mapView); - // create a map with the BasemapType topographic + // create a map with the Basemap Style topographic final ArcGISMap mMap = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC); // set the map to be displayed in this view diff --git a/java/cut-geometry/src/main/java/com/esri/arcgisruntime/sample/cutgeometry/MainActivity.java b/java/cut-geometry/src/main/java/com/esri/arcgisruntime/sample/cutgeometry/MainActivity.java index 1c2c02cb33..d35c6fe08b 100644 --- a/java/cut-geometry/src/main/java/com/esri/arcgisruntime/sample/cutgeometry/MainActivity.java +++ b/java/cut-geometry/src/main/java/com/esri/arcgisruntime/sample/cutgeometry/MainActivity.java @@ -56,7 +56,7 @@ protected void onCreate(Bundle savedInstanceState) { mMapView = findViewById(R.id.mapView); Button cutButton = findViewById(R.id.cutButton); - // create a map with the BasemapType topographic + // create a map with the Basemap Style topographic ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC); // set the map to be displayed in this view diff --git a/java/delete-features-feature-service/src/main/java/com/esri/arcgisruntime/samples/deletefeaturesfeatureservice/ConfirmDeleteFeatureDialog.java b/java/delete-features-feature-service/src/main/java/com/esri/arcgisruntime/samples/deletefeaturesfeatureservice/ConfirmDeleteFeatureDialog.java index ae28952707..da9e7128b6 100644 --- a/java/delete-features-feature-service/src/main/java/com/esri/arcgisruntime/samples/deletefeaturesfeatureservice/ConfirmDeleteFeatureDialog.java +++ b/java/delete-features-feature-service/src/main/java/com/esri/arcgisruntime/samples/deletefeaturesfeatureservice/ConfirmDeleteFeatureDialog.java @@ -30,7 +30,7 @@ public class ConfirmDeleteFeatureDialog extends DialogFragment { private String featureId; - private DialogInterface.OnClickListener mOnClickListener = (dialog, which) -> { + private final DialogInterface.OnClickListener mOnClickListener = (dialog, which) -> { if (getContext() instanceof OnButtonClickedListener) { if (which == DialogInterface.BUTTON_POSITIVE) { ((OnButtonClickedListener) getContext()).onDeleteFeatureClicked(featureId); diff --git a/java/delete-features-feature-service/src/main/java/com/esri/arcgisruntime/samples/deletefeaturesfeatureservice/MainActivity.java b/java/delete-features-feature-service/src/main/java/com/esri/arcgisruntime/samples/deletefeaturesfeatureservice/MainActivity.java index 4cb9e867db..020ef469f5 100644 --- a/java/delete-features-feature-service/src/main/java/com/esri/arcgisruntime/samples/deletefeaturesfeatureservice/MainActivity.java +++ b/java/delete-features-feature-service/src/main/java/com/esri/arcgisruntime/samples/deletefeaturesfeatureservice/MainActivity.java @@ -33,8 +33,10 @@ import com.esri.arcgisruntime.data.Feature; import com.esri.arcgisruntime.data.FeatureEditResult; import com.esri.arcgisruntime.data.FeatureQueryResult; +import com.esri.arcgisruntime.data.FeatureTableEditResult; import com.esri.arcgisruntime.data.QueryParameters; import com.esri.arcgisruntime.data.ServiceFeatureTable; +import com.esri.arcgisruntime.data.ServiceGeodatabase; import com.esri.arcgisruntime.geometry.Point; import com.esri.arcgisruntime.layers.FeatureLayer; import com.esri.arcgisruntime.mapping.ArcGISMap; @@ -69,14 +71,20 @@ public class MainActivity extends AppCompatActivity implements ConfirmDeleteFeat // create a map with streets basemap ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_STREETS); - // create service feature table from URL - mFeatureTable = new ServiceFeatureTable(getString(R.string.feature_layer_url)); - - // create a feature layer from table - mFeatureLayer = new FeatureLayer(mFeatureTable); - - // add the layer to the map - map.getOperationalLayers().add(mFeatureLayer); + // create and load the service geodatabase + ServiceGeodatabase serviceGeodatabase = new ServiceGeodatabase(getString(R.string.feature_layer_url)); + serviceGeodatabase.loadAsync(); + serviceGeodatabase.addDoneLoadingListener(() -> { + // create a feature layer using the first layer in the ServiceFeatureTable + mFeatureTable = serviceGeodatabase.getTable(0); + // create a feature layer from table + mFeatureLayer = new FeatureLayer(mFeatureTable); + // add the layer to the map + map.getOperationalLayers().add(mFeatureLayer); + // set map to be displayed in map view + mMapView.setMap(map); + mMapView.setViewpoint(new Viewpoint( 40, -95, 100000000)); + }); mMapView.setOnTouchListener(new DefaultMapViewOnTouchListener(this, mMapView) { @Override public boolean onSingleTapConfirmed(MotionEvent event) { @@ -104,10 +112,6 @@ public class MainActivity extends AppCompatActivity implements ConfirmDeleteFeat return super.onSingleTapConfirmed(event); } }); - - // set map to be displayed in map view - mMapView.setMap(map); - mMapView.setViewpoint(new Viewpoint( 40, -95, 100000000)); } /** @@ -189,20 +193,12 @@ private void deleteFeature(Feature feature, ServiceFeatureTable featureTable, */ private void applyEdits(ServiceFeatureTable featureTable) { // apply the changes to the server - ListenableFuture> featureEditsFuture = featureTable.applyEditsAsync(); + ListenableFuture> featureEditsFuture = featureTable.getServiceGeodatabase().applyEditsAsync(); featureEditsFuture.addDoneListener(() -> { try { // check result has an edit - if (featureEditsFuture.get().iterator().hasNext()) { - // attempt to get first edit from result as it should be the only edit - FeatureEditResult edit = featureEditsFuture.get().iterator().next(); - // check if the server edit was successful - if (!edit.hasCompletedWithErrors()) { - logToUser(false, getString(R.string.success_feature_deleted)); - } else { - throw edit.getError(); - } - } + if (featureEditsFuture.get().iterator().hasNext()) + logToUser(false, getString(R.string.success_feature_deleted)); } catch (InterruptedException | ExecutionException e) { logToUser(true, getString(R.string.error_applying_edits, e.getCause().getMessage())); } diff --git a/java/delete-features-feature-service/src/main/res/values/strings.xml b/java/delete-features-feature-service/src/main/res/values/strings.xml index 11676b995b..fb95283065 100644 --- a/java/delete-features-feature-service/src/main/res/values/strings.xml +++ b/java/delete-features-feature-service/src/main/res/values/strings.xml @@ -1,7 +1,7 @@ Delete Features - Feature Service - https://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/FeatureServer/0 + https://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/FeatureServer Are you sure you wish to delete feature %s? Delete diff --git a/java/display-device-location/src/main/java/com/esri/arcgisruntime/sample/displaydevicelocation/MainActivity.java b/java/display-device-location/src/main/java/com/esri/arcgisruntime/sample/displaydevicelocation/MainActivity.java index 8e515154d4..81d7ca4eae 100644 --- a/java/display-device-location/src/main/java/com/esri/arcgisruntime/sample/displaydevicelocation/MainActivity.java +++ b/java/display-device-location/src/main/java/com/esri/arcgisruntime/sample/displaydevicelocation/MainActivity.java @@ -60,7 +60,7 @@ protected void onCreate(Bundle savedInstanceState) { // Get the Spinner from layout mSpinner = findViewById(R.id.spinner); - // Get the MapView from layout and set a map with the BasemapType Imagery + // Get the MapView from layout and set a map with the Basemap Style Imagery mMapView = findViewById(R.id.mapView); ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_IMAGERY); mMapView.setMap(map); diff --git a/java/display-device-location/src/main/java/com/esri/arcgisruntime/sample/spinner/SpinnerAdapter.java b/java/display-device-location/src/main/java/com/esri/arcgisruntime/sample/spinner/SpinnerAdapter.java index cae9882cbe..b8a0e5ba65 100644 --- a/java/display-device-location/src/main/java/com/esri/arcgisruntime/sample/spinner/SpinnerAdapter.java +++ b/java/display-device-location/src/main/java/com/esri/arcgisruntime/sample/spinner/SpinnerAdapter.java @@ -44,9 +44,9 @@ public SpinnerAdapter(Activity context, int groupid, int id, ArrayList public View getView(int position, View convertView, ViewGroup parent) { View itemView = inflater.inflate(groupid, parent, false); - ImageView imageView = (ImageView) itemView.findViewById(R.id.img); + ImageView imageView = itemView.findViewById(R.id.img); imageView.setImageResource(list.get(position).getImageId()); - TextView textView = (TextView) itemView.findViewById(R.id.txt); + TextView textView = itemView.findViewById(R.id.txt); textView.setText(list.get(position).getText()); return itemView; } diff --git a/java/display-drawing-status/src/main/java/com/esri/arcgisruntime/sample/displaydrawingstatus/MainActivity.java b/java/display-drawing-status/src/main/java/com/esri/arcgisruntime/sample/displaydrawingstatus/MainActivity.java index 9f0fd8c51a..b8018f7249 100644 --- a/java/display-drawing-status/src/main/java/com/esri/arcgisruntime/sample/displaydrawingstatus/MainActivity.java +++ b/java/display-drawing-status/src/main/java/com/esri/arcgisruntime/sample/displaydrawingstatus/MainActivity.java @@ -49,7 +49,7 @@ protected void onCreate(Bundle savedInstanceState) { // inflate MapView from layout mMapView = findViewById(R.id.mapView); - // create a map with the Basemap Type topographic + // create a map with the Basemap Style topographic ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC); // create a feature table from a service url diff --git a/java/display-layer-view-state/src/main/java/com/esri/arcgisruntime/sample/displaylayerviewstate/MainActivity.java b/java/display-layer-view-state/src/main/java/com/esri/arcgisruntime/sample/displaylayerviewstate/MainActivity.java index e6ac393562..590fc272dc 100644 --- a/java/display-layer-view-state/src/main/java/com/esri/arcgisruntime/sample/displaylayerviewstate/MainActivity.java +++ b/java/display-layer-view-state/src/main/java/com/esri/arcgisruntime/sample/displaylayerviewstate/MainActivity.java @@ -62,7 +62,7 @@ protected void onCreate(Bundle savedInstanceState) { // inflate MapView from layout mMapView = findViewById(R.id.mapView); - // create a map with the BasemapType topographic + // create a map with the Basemap Style topographic final ArcGISMap mMap = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC); // add the map to the map view mMapView.setMap(mMap); diff --git a/java/display-scene/src/main/java/com/esri/arcgisruntime/sample/displayscene/MainActivity.java b/java/display-scene/src/main/java/com/esri/arcgisruntime/sample/displayscene/MainActivity.java index aa4db30fa0..e991529296 100644 --- a/java/display-scene/src/main/java/com/esri/arcgisruntime/sample/displayscene/MainActivity.java +++ b/java/display-scene/src/main/java/com/esri/arcgisruntime/sample/displayscene/MainActivity.java @@ -45,7 +45,7 @@ protected void onCreate(Bundle savedInstanceState) { //[DocRef: Name=Display Scene-android, Category=Work with 3D, Topic=Display a scene] // create SceneView from layout - mSceneView = (SceneView) findViewById(R.id.sceneView); + mSceneView = findViewById(R.id.sceneView); mSceneView.setScene(scene); //[DocRef: END] diff --git a/java/download-preplanned-map-area/src/main/java/com/esri/arcgisruntime/sample/downloadpreplannedmaparea/MainActivity.java b/java/download-preplanned-map-area/src/main/java/com/esri/arcgisruntime/sample/downloadpreplannedmaparea/MainActivity.java index d56b27430a..906eee9958 100644 --- a/java/download-preplanned-map-area/src/main/java/com/esri/arcgisruntime/sample/downloadpreplannedmaparea/MainActivity.java +++ b/java/download-preplanned-map-area/src/main/java/com/esri/arcgisruntime/sample/downloadpreplannedmaparea/MainActivity.java @@ -69,7 +69,7 @@ public class MainActivity extends AppCompatActivity implements ProgressDialogFra private ListView mDownloadedMapAreasListView; private List mDownloadedMapAreaNames; private ArrayAdapter mDownloadedMapAreasAdapter; - private List mDownloadedMapAreas = new ArrayList<>(); + private final List mDownloadedMapAreas = new ArrayList<>(); private Button mDownloadButton; private PreplannedMapArea mSelectedPreplannedMapArea; @@ -265,12 +265,8 @@ private void createPreplannedAreasListView(ArcGISMap onlineMap, OfflineMapTask o .getExtent(); mMapView.setViewpointAsync(new Viewpoint(areaOfInterest), 1.5f); // enable download button only for those map areas which have not been downloaded already - if (new File(getCacheDir() + getString(R.string.preplanned_offline_map_dir) + File.separator - + mSelectedPreplannedMapArea.getPortalItem().getTitle()).exists()) { - mDownloadButton.setEnabled(false); - } else { - mDownloadButton.setEnabled(true); - } + mDownloadButton.setEnabled(!new File(getCacheDir() + getString(R.string.preplanned_offline_map_dir) + File.separator + + mSelectedPreplannedMapArea.getPortalItem().getTitle()).exists()); } else { mDownloadButton.setEnabled(false); } diff --git a/java/edit-feature-attachments/src/main/res/layout/attachment_entry.xml b/java/edit-feature-attachments/src/main/res/layout/attachment_entry.xml index 69599dc847..51f882e3b8 100644 --- a/java/edit-feature-attachments/src/main/res/layout/attachment_entry.xml +++ b/java/edit-feature-attachments/src/main/res/layout/attachment_entry.xml @@ -1,4 +1,5 @@ @@ -8,6 +9,6 @@ android:layout_height="wrap_content" android:paddingTop="5dp" android:maxLines="1" - android:drawableStart="@android:drawable/ic_menu_add" - android:padding="5dp"/> + android:padding="5dp" + app:drawableStartCompat="@android:drawable/ic_menu_add" /> \ No newline at end of file diff --git a/java/export-tiles/src/main/java/com/esri/arcgisruntime/sample/exporttiles/MainActivity.java b/java/export-tiles/src/main/java/com/esri/arcgisruntime/sample/exporttiles/MainActivity.java index c2cad7abab..6cfe0286a0 100644 --- a/java/export-tiles/src/main/java/com/esri/arcgisruntime/sample/exporttiles/MainActivity.java +++ b/java/export-tiles/src/main/java/com/esri/arcgisruntime/sample/exporttiles/MainActivity.java @@ -54,7 +54,6 @@ public class MainActivity extends AppCompatActivity { private MapView mMapView; private MapView mTileCachePreview; - private ArcGISTiledLayer mTiledLayer; private ExportTileCacheJob mExportTileCacheJob; private ExportTileCacheTask mExportTileCacheTask; @@ -141,9 +140,9 @@ private void clearPreview() { */ private void initiateDownload() { - mTiledLayer = (ArcGISTiledLayer) mMapView.getMap().getBasemap().getBaseLayers().get(0); + ArcGISTiledLayer tiledLayer = (ArcGISTiledLayer) mMapView.getMap().getBasemap().getBaseLayers().get(0); // initialize the export task - mExportTileCacheTask = new ExportTileCacheTask(mTiledLayer.getUri()); + mExportTileCacheTask = new ExportTileCacheTask(tiledLayer.getUri()); final ListenableFuture parametersFuture = mExportTileCacheTask .createDefaultExportTileCacheParametersAsync(viewToExtent(), mMapView.getMapScale(), mMapView.getMapScale() * 0.1); parametersFuture.addDoneListener(() -> { diff --git a/java/feature-layer-geopackage/src/main/java/com/esri/arcgisruntime/sample/featurelayergeopackage/MainActivity.java b/java/feature-layer-geopackage/src/main/java/com/esri/arcgisruntime/sample/featurelayergeopackage/MainActivity.java index d40795a7c6..faabbd1d85 100644 --- a/java/feature-layer-geopackage/src/main/java/com/esri/arcgisruntime/sample/featurelayergeopackage/MainActivity.java +++ b/java/feature-layer-geopackage/src/main/java/com/esri/arcgisruntime/sample/featurelayergeopackage/MainActivity.java @@ -51,7 +51,7 @@ protected void onCreate(Bundle savedInstanceState) { // inflate MapView from layout mMapView = findViewById(R.id.mapView); - // create a map with the BasemapType topographic + // create a map with the Basemap Style topographic mMap = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC); // set the map to be displayed in this view mMapView.setMap(mMap); diff --git a/java/feature-layer-update-attributes/src/main/java/com/esri/arcgisruntime/sample/featurelayerupdateattributes/DamageTypesListActivity.java b/java/feature-layer-update-attributes/src/main/java/com/esri/arcgisruntime/sample/featurelayerupdateattributes/DamageTypesListActivity.java index 3eb45efabf..81a3436ffa 100644 --- a/java/feature-layer-update-attributes/src/main/java/com/esri/arcgisruntime/sample/featurelayerupdateattributes/DamageTypesListActivity.java +++ b/java/feature-layer-update-attributes/src/main/java/com/esri/arcgisruntime/sample/featurelayerupdateattributes/DamageTypesListActivity.java @@ -35,7 +35,7 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.damage_types_listview); final String[] damageTypes = getResources().getStringArray(R.array.damage_types); - ListView listView = (ListView) findViewById(R.id.listview); + ListView listView = findViewById(R.id.listview); listView.setAdapter(new ArrayAdapter<>(this, R.layout.damage_types, damageTypes)); diff --git a/java/feature-layer-update-attributes/src/main/java/com/esri/arcgisruntime/sample/featurelayerupdateattributes/MainActivity.java b/java/feature-layer-update-attributes/src/main/java/com/esri/arcgisruntime/sample/featurelayerupdateattributes/MainActivity.java index 44e9487293..8835df8d0b 100644 --- a/java/feature-layer-update-attributes/src/main/java/com/esri/arcgisruntime/sample/featurelayerupdateattributes/MainActivity.java +++ b/java/feature-layer-update-attributes/src/main/java/com/esri/arcgisruntime/sample/featurelayerupdateattributes/MainActivity.java @@ -16,8 +16,6 @@ package com.esri.arcgisruntime.sample.featurelayerupdateattributes; -import java.util.List; - import android.app.ProgressDialog; import android.content.Intent; import android.graphics.Color; @@ -32,11 +30,13 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.core.content.ContextCompat; + import com.esri.arcgisruntime.ArcGISRuntimeEnvironment; import com.esri.arcgisruntime.concurrent.ListenableFuture; import com.esri.arcgisruntime.data.ArcGISFeature; -import com.esri.arcgisruntime.data.FeatureEditResult; +import com.esri.arcgisruntime.data.FeatureTableEditResult; import com.esri.arcgisruntime.data.ServiceFeatureTable; +import com.esri.arcgisruntime.data.ServiceGeodatabase; import com.esri.arcgisruntime.layers.FeatureLayer; import com.esri.arcgisruntime.loadable.LoadStatus; import com.esri.arcgisruntime.mapping.ArcGISMap; @@ -49,6 +49,8 @@ import com.esri.arcgisruntime.mapping.view.MapView; import com.google.android.material.snackbar.Snackbar; +import java.util.List; + public class MainActivity extends AppCompatActivity { private static final String TAG = MainActivity.class.getSimpleName(); @@ -97,12 +99,17 @@ protected void onCreate(Bundle savedInstanceState) { mProgressDialog.setTitle(getResources().getString(R.string.progress_title)); mProgressDialog.setMessage(getResources().getString(R.string.progress_message)); - // create feature layer with from the service feature table - mServiceFeatureTable = new ServiceFeatureTable(getResources().getString(R.string.sample_service_url)); - mFeatureLayer = new FeatureLayer(mServiceFeatureTable); - - // add the layer to the map - map.getOperationalLayers().add(mFeatureLayer); + // create and load the service geodatabase + ServiceGeodatabase serviceGeodatabase = new ServiceGeodatabase(getString(R.string.sample_service_url)); + serviceGeodatabase.loadAsync(); + serviceGeodatabase.addDoneLoadingListener(() -> { + // create a feature layer using the first layer in the ServiceFeatureTable + mServiceFeatureTable = serviceGeodatabase.getTable(0); + // create a feature layer from table + mFeatureLayer = new FeatureLayer(mServiceFeatureTable); + // add the layer to the map + map.getOperationalLayers().add(mFeatureLayer); + }); // set an on touch listener to listen for click events mMapView.setOnTouchListener(new DefaultMapViewOnTouchListener(this, mMapView) { @@ -203,7 +210,7 @@ private boolean updateAttributes(final String typeDamage) { @Override public void run() { // apply change to the server - final ListenableFuture> serverResult = mServiceFeatureTable.applyEditsAsync(); + final ListenableFuture> serverResult = mServiceFeatureTable.getServiceGeodatabase().applyEditsAsync(); serverResult.addDoneListener(new Runnable() { @Override @@ -211,13 +218,11 @@ public void run() { try { // check if server result successful - List edits = serverResult.get(); + List edits = serverResult.get(); if (!edits.isEmpty()) { - if (!edits.get(0).hasCompletedWithErrors()) { - Log.e(TAG, "Feature successfully updated"); - mSnackbarSuccess.show(); - mFeatureUpdated = true; - } + Log.e(TAG, "Feature successfully updated"); + mSnackbarSuccess.show(); + mFeatureUpdated = true; } else { Log.e(TAG, "The attribute type was not changed"); mSnackbarFailure.show(); diff --git a/java/feature-layer-update-attributes/src/main/res/values/strings.xml b/java/feature-layer-update-attributes/src/main/res/values/strings.xml index 6622c05275..39596cc2fd 100644 --- a/java/feature-layer-update-attributes/src/main/res/values/strings.xml +++ b/java/feature-layer-update-attributes/src/main/res/values/strings.xml @@ -6,7 +6,7 @@ Please wait… - https://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/FeatureServer/0 + https://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/FeatureServer Destroyed diff --git a/java/feature-layer-update-geometry/src/main/java/com/esri/arcgisruntime/samples/featurelayerupdategeometry/MainActivity.java b/java/feature-layer-update-geometry/src/main/java/com/esri/arcgisruntime/samples/featurelayerupdategeometry/MainActivity.java index 82ed30168f..21e0122e09 100644 --- a/java/feature-layer-update-geometry/src/main/java/com/esri/arcgisruntime/samples/featurelayerupdategeometry/MainActivity.java +++ b/java/feature-layer-update-geometry/src/main/java/com/esri/arcgisruntime/samples/featurelayerupdategeometry/MainActivity.java @@ -24,8 +24,9 @@ import com.esri.arcgisruntime.ArcGISRuntimeEnvironment; import com.esri.arcgisruntime.concurrent.ListenableFuture; import com.esri.arcgisruntime.data.ArcGISFeature; -import com.esri.arcgisruntime.data.FeatureEditResult; +import com.esri.arcgisruntime.data.FeatureTableEditResult; import com.esri.arcgisruntime.data.ServiceFeatureTable; +import com.esri.arcgisruntime.data.ServiceGeodatabase; import com.esri.arcgisruntime.geometry.GeometryEngine; import com.esri.arcgisruntime.geometry.Point; import com.esri.arcgisruntime.layers.FeatureLayer; @@ -68,12 +69,17 @@ protected void onCreate(Bundle savedInstanceState) { // set an initial viewpoint mMapView.setViewpoint(new Viewpoint(34.057386, -117.191455, 100000000)); - // create feature layer with its service feature table - final ServiceFeatureTable serviceFeatureTable = new ServiceFeatureTable(getString(R.string.sample_service_url)); - mFeatureLayer = new FeatureLayer(serviceFeatureTable); - - // add the layer to the map - map.getOperationalLayers().add(mFeatureLayer); + // create and load the service geodatabase + ServiceGeodatabase serviceGeodatabase = new ServiceGeodatabase(getString(R.string.sample_service_url)); + serviceGeodatabase.loadAsync(); + serviceGeodatabase.addDoneLoadingListener(() -> { + // create a feature layer using the first layer in the ServiceFeatureTable + ServiceFeatureTable serviceFeatureTable = serviceGeodatabase.getTable(0); + // create a feature layer from table + mFeatureLayer = new FeatureLayer(serviceFeatureTable); + // add the layer to the map + mMapView.getMap().getOperationalLayers().add(mFeatureLayer); + }); Toast.makeText(getApplicationContext(), "Tap on a feature to select it.", Toast.LENGTH_LONG).show(); @@ -147,17 +153,15 @@ public boolean onSingleTapConfirmed(MotionEvent motionEvent) { * Applies edits to the FeatureService */ private void applyEditsToServer() { - final ListenableFuture> applyEditsFuture = ((ServiceFeatureTable) mFeatureLayer - .getFeatureTable()).applyEditsAsync(); + final ListenableFuture> applyEditsFuture = ((ServiceFeatureTable) mFeatureLayer + .getFeatureTable()).getServiceGeodatabase().applyEditsAsync(); applyEditsFuture.addDoneListener(() -> { try { // get results of edit - List featureEditResultsList = applyEditsFuture.get(); - if (!featureEditResultsList.get(0).hasCompletedWithErrors()) { - Toast.makeText(this, - "Applied Geometry Edits to Server. ObjectID: " + featureEditResultsList.get(0).getObjectId(), - Toast.LENGTH_SHORT).show(); - } + List featureEditResultsList = applyEditsFuture.get(); + Toast.makeText(this, + "Applied Geometry Edits to Server. ObjectID: " + featureEditResultsList.get(0).getEditResult().get(0).getObjectId(), + Toast.LENGTH_SHORT).show(); } catch (InterruptedException | ExecutionException e) { Log.e(TAG, "Update feature failed: " + e.getMessage()); } diff --git a/java/feature-layer-update-geometry/src/main/res/values/strings.xml b/java/feature-layer-update-geometry/src/main/res/values/strings.xml index cc0a1c0737..d56046f725 100644 --- a/java/feature-layer-update-geometry/src/main/res/values/strings.xml +++ b/java/feature-layer-update-geometry/src/main/res/values/strings.xml @@ -1,5 +1,5 @@ Feature Layer Update Geometry - https://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/FeatureServer/0 + https://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/FeatureServer diff --git a/java/find-address/src/main/java/com/esri/arcgisruntime/sample/findaddress/MainActivity.java b/java/find-address/src/main/java/com/esri/arcgisruntime/sample/findaddress/MainActivity.java index 3a0fc7e4be..cdc72a9e10 100644 --- a/java/find-address/src/main/java/com/esri/arcgisruntime/sample/findaddress/MainActivity.java +++ b/java/find-address/src/main/java/com/esri/arcgisruntime/sample/findaddress/MainActivity.java @@ -98,7 +98,7 @@ protected void onCreate(Bundle savedInstanceState) { mLocatorTask = new LocatorTask("https://geocode-api.arcgis.com/arcgis/rest/services/World/GeocodeServer"); // inflate MapView from layout - mMapView = (MapView) findViewById(R.id.mapView); + mMapView = findViewById(R.id.mapView); // create a map with the BasemapType topographic final ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_STREETS); map.setInitialViewpoint(new Viewpoint(40,-100,100000000)); diff --git a/java/find-place/src/main/java/com/esri/arcgisruntime/sample/findplace/MainActivity.java b/java/find-place/src/main/java/com/esri/arcgisruntime/sample/findplace/MainActivity.java index 1326aa2f83..96ff1076d3 100644 --- a/java/find-place/src/main/java/com/esri/arcgisruntime/sample/findplace/MainActivity.java +++ b/java/find-place/src/main/java/com/esri/arcgisruntime/sample/findplace/MainActivity.java @@ -148,7 +148,7 @@ protected void onCreate(Bundle savedInstanceState) { mMapView = findViewById(R.id.mapView); // disable map wraparound mMapView.setWrapAroundMode(WrapAroundMode.DISABLED); - // create a map with the BasemapType topographic + // create a map with the Basemap Style topographic final ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC); // set the map to be displayed in this view mMapView.setMap(map); diff --git a/java/find-route/src/main/res/menu/menu_main.xml b/java/find-route/src/main/res/menu/menu_main.xml index 357fcbadcd..79e1d4a141 100644 --- a/java/find-route/src/main/res/menu/menu_main.xml +++ b/java/find-route/src/main/res/menu/menu_main.xml @@ -1,2 +1,2 @@ \ No newline at end of file + tools:context=".MainActivity" /> \ No newline at end of file diff --git a/java/group-layers/src/main/java/com/esri/arcgisruntime/sample/grouplayers/LayersAdapter.java b/java/group-layers/src/main/java/com/esri/arcgisruntime/sample/grouplayers/LayersAdapter.java index fb69057359..cce27a39a9 100644 --- a/java/group-layers/src/main/java/com/esri/arcgisruntime/sample/grouplayers/LayersAdapter.java +++ b/java/group-layers/src/main/java/com/esri/arcgisruntime/sample/grouplayers/LayersAdapter.java @@ -44,8 +44,8 @@ public class LayersAdapter extends RecyclerView.Adapter mLayers = new ArrayList<>(); - private OnLayerCheckedChangedListener mOnLayerCheckedChangedListener; + private final List mLayers = new ArrayList<>(); + private final OnLayerCheckedChangedListener mOnLayerCheckedChangedListener; LayersAdapter(OnLayerCheckedChangedListener onLayerCheckedChangedListener) { mOnLayerCheckedChangedListener = onLayerCheckedChangedListener; @@ -112,8 +112,8 @@ void addLayer(Layer layer) { */ class ParentViewHolder extends ViewHolder { - private CheckBox mParentCheckbox; - private TextView mParentTextView; + private final CheckBox mParentCheckbox; + private final TextView mParentTextView; private final ViewGroup mChildLayout; private RadioGroup mRadioGroup; @@ -193,7 +193,7 @@ private void addChildLayer(Layer childLayer) { radioButton.setChecked(childLayer.isVisible()); radioButton.setOnCheckedChangeListener( ((buttonView, isChecked) -> mOnLayerCheckedChangedListener.layerCheckedChanged(childLayer, isChecked))); - TextView textView = (TextView) view.findViewById(R.id.layerNameTextView); + TextView textView = view.findViewById(R.id.layerNameTextView); textView.setText(childLayer.getName()); if (mRadioGroup.findViewWithTag(childLayer) == null) { // remove the view from the existing parent and add it to the radio group @@ -208,7 +208,7 @@ private void addChildLayer(Layer childLayer) { checkBox.setChecked(childLayer.isVisible()); checkBox.setOnCheckedChangeListener( (buttonView, isChecked) -> mOnLayerCheckedChangedListener.layerCheckedChanged(childLayer, isChecked)); - TextView textView = (TextView) view.findViewById(R.id.layerNameTextView); + TextView textView = view.findViewById(R.id.layerNameTextView); textView.setText(childLayer.getName()); if (mChildLayout.findViewWithTag(childLayer) == null) { mChildLayout.addView(view); @@ -222,8 +222,8 @@ private void addChildLayer(Layer childLayer) { */ class LayerViewHolder extends ViewHolder { - private CheckBox mCheckbox; - private TextView mTextView; + private final CheckBox mCheckbox; + private final TextView mTextView; LayerViewHolder(@NonNull View itemView, OnLayerCheckedChangedListener onLayerCheckedChangedListener) { super(itemView, onLayerCheckedChangedListener); diff --git a/java/hillshade-renderer/src/main/java/com/esri/arcgisruntime/sample/hillshaderenderer/MainActivity.java b/java/hillshade-renderer/src/main/java/com/esri/arcgisruntime/sample/hillshaderenderer/MainActivity.java index 79cfa4b231..8232dffd25 100644 --- a/java/hillshade-renderer/src/main/java/com/esri/arcgisruntime/sample/hillshaderenderer/MainActivity.java +++ b/java/hillshade-renderer/src/main/java/com/esri/arcgisruntime/sample/hillshaderenderer/MainActivity.java @@ -70,7 +70,7 @@ protected void onCreate(Bundle savedInstanceState) { mPixelSizePower = 1; mOutputBitDepth = 8; // retrieve the MapView from layout - mMapView = (MapView) findViewById(R.id.mapView); + mMapView = findViewById(R.id.mapView); mFragmentManager = getSupportFragmentManager(); // create raster diff --git a/java/identify-graphics/src/main/java/com/esri/arcgisruntime/sample/identifygraphics/MainActivity.java b/java/identify-graphics/src/main/java/com/esri/arcgisruntime/sample/identifygraphics/MainActivity.java index f8bd66e844..4f081d4339 100644 --- a/java/identify-graphics/src/main/java/com/esri/arcgisruntime/sample/identifygraphics/MainActivity.java +++ b/java/identify-graphics/src/main/java/com/esri/arcgisruntime/sample/identifygraphics/MainActivity.java @@ -59,7 +59,7 @@ protected void onCreate(Bundle savedInstanceState) { // inflate MapView from layout mMapView = findViewById(R.id.mapView); - // create a map with the BasemapType topographic + // create a map with the Basemap Style topographic ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC); // set the map to be displayed in this view mMapView.setMap(map); diff --git a/java/manage-bookmarks/src/main/java/com/esri/arcgisruntime/sample/managebookmarks/MainActivity.java b/java/manage-bookmarks/src/main/java/com/esri/arcgisruntime/sample/managebookmarks/MainActivity.java index 770f253724..8782aa98fc 100644 --- a/java/manage-bookmarks/src/main/java/com/esri/arcgisruntime/sample/managebookmarks/MainActivity.java +++ b/java/manage-bookmarks/src/main/java/com/esri/arcgisruntime/sample/managebookmarks/MainActivity.java @@ -60,7 +60,7 @@ protected void onCreate(Bundle savedInstanceState) { // inflate MapView from layout mMapView = findViewById(R.id.mapView); - // create a map with the BasemapType imagery with labels + // create a map with the Basemap Style imagery with labels ArcGISMap mMap = new ArcGISMap(BasemapStyle.ARCGIS_IMAGERY); // set the map to be displayed in this view mMapView.setMap(mMap); diff --git a/java/manage-operational-layers/src/main/java/com/esri/arcgisruntime/sample/listviewdragginganimation/DynamicListView.java b/java/manage-operational-layers/src/main/java/com/esri/arcgisruntime/sample/listviewdragginganimation/DynamicListView.java index 5f5b00df55..1bbe06728e 100644 --- a/java/manage-operational-layers/src/main/java/com/esri/arcgisruntime/sample/listviewdragginganimation/DynamicListView.java +++ b/java/manage-operational-layers/src/main/java/com/esri/arcgisruntime/sample/listviewdragginganimation/DynamicListView.java @@ -121,7 +121,7 @@ public void init(Context context) { * Listens for long clicks on any items in the listview. When a cell has * been selected, the hover cell is created and set up. */ - private OnItemLongClickListener mOnItemLongClickListener = + private final OnItemLongClickListener mOnItemLongClickListener = new OnItemLongClickListener() { public boolean onItemLongClick(AdapterView arg0, View arg1, int pos, long id) { mTotalOffset = 0; @@ -511,7 +511,7 @@ public void setLayerList(ArrayList layerList) { * scrolling takes place, the listview continuously checks if new cells became visible * and determines whether they are potential candidates for a cell swap. */ - private OnScrollListener mScrollListener = new OnScrollListener () { + private final OnScrollListener mScrollListener = new OnScrollListener () { private int mPreviousFirstVisibleItem = -1; private int mPreviousVisibleItemCount = -1; diff --git a/java/manage-operational-layers/src/main/java/com/esri/arcgisruntime/sample/manageoperationallayers/MainActivity.java b/java/manage-operational-layers/src/main/java/com/esri/arcgisruntime/sample/manageoperationallayers/MainActivity.java index 3fea95a44d..7afd7016ff 100644 --- a/java/manage-operational-layers/src/main/java/com/esri/arcgisruntime/sample/manageoperationallayers/MainActivity.java +++ b/java/manage-operational-layers/src/main/java/com/esri/arcgisruntime/sample/manageoperationallayers/MainActivity.java @@ -58,7 +58,7 @@ protected void onCreate(Bundle savedInstanceState) { // inflate operational layer selection button from the layout Button selectLayers = findViewById(R.id.operationallayer); - // create a map with the BasemapType topographic + // create a map with the Basemap Style topographic ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC); ArcGISMapImageLayer imageLayerElevation = new ArcGISMapImageLayer(getResources().getString(R.string.imagelayer_elevation_url)); diff --git a/java/manage-operational-layers/src/main/java/com/esri/arcgisruntime/sample/manageoperationallayers/OperationalLayers.java b/java/manage-operational-layers/src/main/java/com/esri/arcgisruntime/sample/manageoperationallayers/OperationalLayers.java index 7fe476ae4d..3c72ad5ff0 100644 --- a/java/manage-operational-layers/src/main/java/com/esri/arcgisruntime/sample/manageoperationallayers/OperationalLayers.java +++ b/java/manage-operational-layers/src/main/java/com/esri/arcgisruntime/sample/manageoperationallayers/OperationalLayers.java @@ -39,7 +39,7 @@ public class OperationalLayers extends AppCompatActivity { private ArrayList mAddedLayerList, mRemovedLayerList; private LayerList mMapOperationalLayers; - private ArrayList mRemovedLayers = new ArrayList<>(); + private final ArrayList mRemovedLayers = new ArrayList<>(); private StableArrayAdapter mOperationalLayerAdapter; private ArrayAdapter mRemovedLayerAdapter; private int mOperationalLayersListViewId; @@ -52,7 +52,7 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_operational_layers); // inflate Button from the layout - Button doneButton = (Button) findViewById(R.id.donebutton); + Button doneButton = findViewById(R.id.donebutton); // listviewids to reuse one dialogbox between the two listview onItemClickListeners mOperationalLayersListViewId = getResources().getIdentifier("dynamiclistview", "id", this.getPackageName()); @@ -74,7 +74,7 @@ protected void onCreate(Bundle savedInstanceState) { // initialize the adapter for the list of layer added to the Map mOperationalLayerAdapter = new StableArrayAdapter(this, R.layout.text_view, mAddedLayerList); // inflate the operationalLayers listview - DynamicListView operationalLayersListView = (DynamicListView) findViewById(R.id.dynamiclistview); + DynamicListView operationalLayersListView = findViewById(R.id.dynamiclistview); operationalLayersListView.setLayerList(mAddedLayerList); operationalLayersListView.setAdapter(mOperationalLayerAdapter); @@ -84,7 +84,7 @@ protected void onCreate(Bundle savedInstanceState) { mRemovedLayerAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, mRemovedLayerList); // inflate the removedlayers listview - ListView removedLayerListView = (ListView) findViewById(R.id.listView); + ListView removedLayerListView = findViewById(R.id.listView); removedLayerListView.setAdapter(mRemovedLayerAdapter); doneButton.setOnClickListener(new View.OnClickListener() { diff --git a/java/map-load-status/src/main/java/com/esri/arcgisruntime/sample/maploaded/MainActivity.java b/java/map-load-status/src/main/java/com/esri/arcgisruntime/sample/maploaded/MainActivity.java index 6322b5d31a..46cedc9e88 100644 --- a/java/map-load-status/src/main/java/com/esri/arcgisruntime/sample/maploaded/MainActivity.java +++ b/java/map-load-status/src/main/java/com/esri/arcgisruntime/sample/maploaded/MainActivity.java @@ -79,7 +79,7 @@ private void loadMap() { //clear the current map load status of the TextView mMapLoadStatusTextView.setText(""); - // create a map with the BasemapType National Geographic + // create a map with the Basemap Style Light Gray ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_LIGHT_GRAY); // Listener on change in map load status diff --git a/java/map-rotation/src/main/java/com/esri/arcgisruntime/sample/maprotation/MainActivity.java b/java/map-rotation/src/main/java/com/esri/arcgisruntime/sample/maprotation/MainActivity.java index aa7dd97acd..5af6fc644f 100644 --- a/java/map-rotation/src/main/java/com/esri/arcgisruntime/sample/maprotation/MainActivity.java +++ b/java/map-rotation/src/main/java/com/esri/arcgisruntime/sample/maprotation/MainActivity.java @@ -44,7 +44,7 @@ protected void onCreate(Bundle savedInstanceState) { // create MapView from layout mMapView = findViewById(R.id.mapView); - // create a map with the Basemap.Type topographic + // create a map with the BasemapStyle topographic ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC); // set the map to be displayed in this view mMapView.setMap(map); diff --git a/java/mobile-map-search-and-route/src/main/java/com/esri/arcgisruntime/sample/mobilemapsearchandroute/MainActivity.java b/java/mobile-map-search-and-route/src/main/java/com/esri/arcgisruntime/sample/mobilemapsearchandroute/MainActivity.java index 9dcb0c55d6..8ca80936c2 100755 --- a/java/mobile-map-search-and-route/src/main/java/com/esri/arcgisruntime/sample/mobilemapsearchandroute/MainActivity.java +++ b/java/mobile-map-search-and-route/src/main/java/com/esri/arcgisruntime/sample/mobilemapsearchandroute/MainActivity.java @@ -74,7 +74,7 @@ public class MainActivity extends AppCompatActivity { private GraphicsOverlay mRouteGraphicsOverlay; private RouteTask mRouteTask; private RouteParameters mRouteParameters; - private ArrayList mMapPreviews = new ArrayList<>(); + private final ArrayList mMapPreviews = new ArrayList<>(); private MobileMapPackage mMobileMapPackage; private MapView mMapView; private String mMMPkTitle; @@ -91,7 +91,7 @@ protected void onCreate(Bundle savedInstanceState) { mReverseGeocodeParameters.setMaxResults(1); mReverseGeocodeParameters.getResultAttributeNames().add("*"); // retrieve the MapView from layout - mMapView = (MapView) findViewById(R.id.mapView); + mMapView = findViewById(R.id.mapView); // add route and marker overlays to map view mMarkerGraphicsOverlay = new GraphicsOverlay(); mRouteGraphicsOverlay = new GraphicsOverlay(); diff --git a/java/mobile-map-search-and-route/src/main/java/com/esri/arcgisruntime/sample/mobilemapsearchandroute/MapChooserActivity.java b/java/mobile-map-search-and-route/src/main/java/com/esri/arcgisruntime/sample/mobilemapsearchandroute/MapChooserActivity.java index 304d7227c5..5a6f894fd0 100755 --- a/java/mobile-map-search-and-route/src/main/java/com/esri/arcgisruntime/sample/mobilemapsearchandroute/MapChooserActivity.java +++ b/java/mobile-map-search-and-route/src/main/java/com/esri/arcgisruntime/sample/mobilemapsearchandroute/MapChooserActivity.java @@ -52,7 +52,7 @@ protected void onCreate(Bundle savedInstanceState) { mMapPreviews = (List) intentExtras.get("map_previews"); mMMPkTitle = (String) intentExtras.get("MMPk_title"); } - TextView nameMMPkView = (TextView) findViewById(R.id.MMPk_title); + TextView nameMMPkView = findViewById(R.id.MMPk_title); nameMMPkView.setText(mMMPkTitle); } @@ -60,7 +60,7 @@ protected void onCreate(Bundle savedInstanceState) { protected void onResume() { super.onResume(); //setup recycler view - mMapPreviewRecyclerView = (RecyclerView) findViewById(R.id.map_preview_list); + mMapPreviewRecyclerView = findViewById(R.id.map_preview_list); mMapPreviewRecyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext())); loadMapPreviews(); } @@ -95,11 +95,11 @@ private class MapPreviewHolder extends RecyclerView.ViewHolder implements View.O private MapPreviewHolder(LayoutInflater inflater, ViewGroup parent) { super(inflater.inflate(R.layout.map_preview, parent, false)); itemView.setOnClickListener(this); - mTitleTextView = (TextView) itemView.findViewById(R.id.mapTitle); - mTransportView = (TextView) itemView.findViewById(R.id.mapTransportNetwork); - mGeotaggingView = (TextView) itemView.findViewById(R.id.mapGeotagging); - mDescTextView = (TextView) itemView.findViewById(R.id.mapDesc); - mThumbnailImageView = (ImageView) itemView.findViewById(R.id.mapThumbnail); + mTitleTextView = itemView.findViewById(R.id.mapTitle); + mTransportView = itemView.findViewById(R.id.mapTransportNetwork); + mGeotaggingView = itemView.findViewById(R.id.mapGeotagging); + mDescTextView = itemView.findViewById(R.id.mapDesc); + mThumbnailImageView = itemView.findViewById(R.id.mapThumbnail); } /** diff --git a/java/open-mobile-map-package/README.md b/java/open-mobile-map-package/README.md index 477a418910..39f4d2fa91 100644 --- a/java/open-mobile-map-package/README.md +++ b/java/open-mobile-map-package/README.md @@ -2,7 +2,7 @@ Display a map from a mobile map package. -![Image of open mobile map package](open-mobile-mappackage.png) +![Image of open mobile map package](open-mobile-map-package.png) ## Use case diff --git a/java/openstreetmap-layer/README.md b/java/openstreetmap-layer/README.md index 55945406c2..87ced6b03f 100644 --- a/java/openstreetmap-layer/README.md +++ b/java/openstreetmap-layer/README.md @@ -14,7 +14,7 @@ When the sample opens, it will automatically display the map with the OpenStreet ## How it works -1. Instantiate an `ArcGISMap` with a `Basemap.Type.OPEN_STREET_MAP` +1. Instantiate an `ArcGISMap` with a `BasemapStyle.OSM_STANDARD` 2. Show the map in a map view using `MapView.setMap(map)`. ## Relevant API diff --git a/java/portal-user-info/src/main/java/com/esri/arcgisruntime/sample/portaluserinfo/MainActivity.java b/java/portal-user-info/src/main/java/com/esri/arcgisruntime/sample/portaluserinfo/MainActivity.java index ada2de4350..77e1396e76 100644 --- a/java/portal-user-info/src/main/java/com/esri/arcgisruntime/sample/portaluserinfo/MainActivity.java +++ b/java/portal-user-info/src/main/java/com/esri/arcgisruntime/sample/portaluserinfo/MainActivity.java @@ -71,7 +71,7 @@ protected void onCreate(Bundle savedInstanceState) { // Get the portal information PortalInfo portalInformation = mPortal.getPortalInfo(); String portalName = portalInformation.getPortalName(); - mPortalNameText = (TextView) findViewById(R.id.portal); + mPortalNameText = findViewById(R.id.portal); mPortalNameText.setText(portalName); // this portal does not require authentication, if null send toast message @@ -114,7 +114,7 @@ protected void onCreate(Bundle savedInstanceState) { Bitmap itemThumbnail = BitmapFactory .decodeByteArray(itemThumbnailData, 0, itemThumbnailData.length); // set the Bitmap onto the ImageView - mUserImage = (ImageView) findViewById(R.id.userImage); + mUserImage = findViewById(R.id.userImage); mUserImage.setImageBitmap(itemThumbnail); } } catch (InterruptedException | ExecutionException e) { diff --git a/java/raster-function-service/src/main/java/com/esri/arcgisruntime/sample/rasterfunctionservice/MainActivity.java b/java/raster-function-service/src/main/java/com/esri/arcgisruntime/sample/rasterfunctionservice/MainActivity.java index a93a134092..b155172f0a 100644 --- a/java/raster-function-service/src/main/java/com/esri/arcgisruntime/sample/rasterfunctionservice/MainActivity.java +++ b/java/raster-function-service/src/main/java/com/esri/arcgisruntime/sample/rasterfunctionservice/MainActivity.java @@ -55,7 +55,7 @@ protected void onCreate(Bundle savedInstanceState) { mMapView = findViewById(R.id.mapView); mRasterFunctionButton = findViewById(R.id.rasterButton); mRasterFunctionButton.setEnabled(false); - // create a map with the BasemapType topographic + // create a map with the Basemap Style topographic ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_DARK_GRAY); final ImageServiceRaster imageServiceRaster = new ImageServiceRaster(getString(R.string.image_service_raster_url)); final RasterLayer imageRasterLayer = new RasterLayer(imageServiceRaster); diff --git a/java/raster-layer-geopackage/src/main/java/com/esri/arcgisruntime/sample/rasterlayergeopackage/MainActivity.java b/java/raster-layer-geopackage/src/main/java/com/esri/arcgisruntime/sample/rasterlayergeopackage/MainActivity.java index 461091bfc3..91fcfb6b0c 100644 --- a/java/raster-layer-geopackage/src/main/java/com/esri/arcgisruntime/sample/rasterlayergeopackage/MainActivity.java +++ b/java/raster-layer-geopackage/src/main/java/com/esri/arcgisruntime/sample/rasterlayergeopackage/MainActivity.java @@ -50,7 +50,7 @@ protected void onCreate(Bundle savedInstanceState) { // get a reference to the map view mMapView = findViewById(R.id.mapView); - // create a map with the BasemapType light gray canvas + // create a map with the Basemap Style light gray canvas ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_LIGHT_GRAY); // set the map to be displayed in this view mMapView.setMap(map); diff --git a/java/raster-layer-service/src/main/res/values/strings.xml b/java/raster-layer-service/src/main/res/values/strings.xml index 6e27287e90..edd3b7bd2a 100644 --- a/java/raster-layer-service/src/main/res/values/strings.xml +++ b/java/raster-layer-service/src/main/res/values/strings.xml @@ -1,4 +1,4 @@ Raster Layer Service - https://gis.ngdc.noaa.gov/arcgis/rest/services/bag_hillshades/ImageServer + https://gis.ngdc.noaa.gov/arcgis/rest/services/bag_hillshades_subsets/ImageServer diff --git a/java/rgb-renderer/src/main/java/com/esri/arcgisruntime/sample/rgbrenderer/ParametersDialogFragment.java b/java/rgb-renderer/src/main/java/com/esri/arcgisruntime/sample/rgbrenderer/ParametersDialogFragment.java index a5a5e4af39..6cb9a52b28 100644 --- a/java/rgb-renderer/src/main/java/com/esri/arcgisruntime/sample/rgbrenderer/ParametersDialogFragment.java +++ b/java/rgb-renderer/src/main/java/com/esri/arcgisruntime/sample/rgbrenderer/ParametersDialogFragment.java @@ -127,30 +127,30 @@ public void onClick(DialogInterface dialog, int which) { } }); // min max ui elements - mMinRedTextView = (TextView) dialogView.findViewById(R.id.min_red_value_text_view); - mMaxRedTextView = (TextView) dialogView.findViewById(R.id.max_red_value_text_view); - mMinGreenTextView = (TextView) dialogView.findViewById(R.id.min_green_value_text_view); - mMaxGreenTextView = (TextView) dialogView.findViewById(R.id.max_green_value_text_view); - mMinBlueTextView = (TextView) dialogView.findViewById(R.id.min_blue_value_text_view); - mMaxBlueTextView = (TextView) dialogView.findViewById(R.id.max_blue_value_text_view); - mMinRedSeekBar = (SeekBar) dialogView.findViewById(R.id.min_red_seek_bar); - mMaxRedSeekBar = (SeekBar) dialogView.findViewById(R.id.max_red_seek_bar); - mMinGreenSeekBar = (SeekBar) dialogView.findViewById(R.id.min_green_seek_bar); - mMaxGreenSeekBar = (SeekBar) dialogView.findViewById(R.id.max_green_seek_bar); - mMinBlueSeekBar = (SeekBar) dialogView.findViewById(R.id.min_blue_seek_bar); - mMaxBlueSeekBar = (SeekBar) dialogView.findViewById(R.id.max_blue_seek_bar); + mMinRedTextView = dialogView.findViewById(R.id.min_red_value_text_view); + mMaxRedTextView = dialogView.findViewById(R.id.max_red_value_text_view); + mMinGreenTextView = dialogView.findViewById(R.id.min_green_value_text_view); + mMaxGreenTextView = dialogView.findViewById(R.id.max_green_value_text_view); + mMinBlueTextView = dialogView.findViewById(R.id.min_blue_value_text_view); + mMaxBlueTextView = dialogView.findViewById(R.id.max_blue_value_text_view); + mMinRedSeekBar = dialogView.findViewById(R.id.min_red_seek_bar); + mMaxRedSeekBar = dialogView.findViewById(R.id.max_red_seek_bar); + mMinGreenSeekBar = dialogView.findViewById(R.id.min_green_seek_bar); + mMaxGreenSeekBar = dialogView.findViewById(R.id.max_green_seek_bar); + mMinBlueSeekBar = dialogView.findViewById(R.id.min_blue_seek_bar); + mMaxBlueSeekBar = dialogView.findViewById(R.id.max_blue_seek_bar); mMinRedSeekBar.setMax(255); mMaxRedSeekBar.setMax(255); mMinGreenSeekBar.setMax(255); mMaxGreenSeekBar.setMax(255); mMinBlueSeekBar.setMax(255); mMaxBlueSeekBar.setMax(255); - mCurrMinRedTextView = (TextView) dialogView.findViewById(R.id.curr_min_red_text_view); - mCurrMaxRedTextView = (TextView) dialogView.findViewById(R.id.curr_max_red_text_view); - mCurrMinGreenTextView = (TextView) dialogView.findViewById(R.id.curr_min_green_text_view); - mCurrMaxGreenTextView = (TextView) dialogView.findViewById(R.id.curr_max_green_text_view); - mCurrMinBlueTextView = (TextView) dialogView.findViewById(R.id.curr_min_blue_text_view); - mCurrMaxBlueTextView = (TextView) dialogView.findViewById(R.id.curr_max_blue_text_view); + mCurrMinRedTextView = dialogView.findViewById(R.id.curr_min_red_text_view); + mCurrMaxRedTextView = dialogView.findViewById(R.id.curr_max_red_text_view); + mCurrMinGreenTextView = dialogView.findViewById(R.id.curr_min_green_text_view); + mCurrMaxGreenTextView = dialogView.findViewById(R.id.curr_max_green_text_view); + mCurrMinBlueTextView = dialogView.findViewById(R.id.curr_min_blue_text_view); + mCurrMaxBlueTextView = dialogView.findViewById(R.id.curr_max_blue_text_view); //update seek bar positions with current mMinMax values updateSeekBar(mMinRedSeekBar, mMinR, mCurrMinRedTextView); updateSeekBar(mMaxRedSeekBar, mMaxR, mCurrMaxRedTextView); @@ -159,22 +159,22 @@ public void onClick(DialogInterface dialog, int which) { updateSeekBar(mMinBlueSeekBar, mMinB, mCurrMinBlueTextView); updateSeekBar(mMaxBlueSeekBar, mMaxB, mCurrMaxBlueTextView); // percent clip ui elements - mPercentClipMinTextView = (TextView) dialogView.findViewById(R.id.percent_clip_min_value_text_view); - mPercentClipMaxTextView = (TextView) dialogView.findViewById(R.id.percent_clip_max_value_text_view); - mPercentClipMinSeekBar = (SeekBar) dialogView.findViewById(R.id.percent_clip_min_seek_bar); - mPercentClipMaxSeekBar = (SeekBar) dialogView.findViewById(R.id.percent_clip_max_seek_bar); + mPercentClipMinTextView = dialogView.findViewById(R.id.percent_clip_min_value_text_view); + mPercentClipMaxTextView = dialogView.findViewById(R.id.percent_clip_max_value_text_view); + mPercentClipMinSeekBar = dialogView.findViewById(R.id.percent_clip_min_seek_bar); + mPercentClipMaxSeekBar = dialogView.findViewById(R.id.percent_clip_max_seek_bar); mPercentClipMinSeekBar.setMax(99); mPercentClipMaxSeekBar.setMax(99); - mCurrPercentClipMinTextView = (TextView) dialogView.findViewById(R.id.curr_percent_clip_min_text_view); - mCurrPercentClipMaxTextView = (TextView) dialogView.findViewById(R.id.curr_percent_clip_max_text_view); + mCurrPercentClipMinTextView = dialogView.findViewById(R.id.curr_percent_clip_min_text_view); + mCurrPercentClipMaxTextView = dialogView.findViewById(R.id.curr_percent_clip_max_text_view); //update seek bar positions with current PercentClip updateSeekBar(mPercentClipMinSeekBar, mPercentClipMin, mCurrPercentClipMinTextView); updateSeekBar(mPercentClipMaxSeekBar, mPercentClipMax, mCurrPercentClipMaxTextView); // standard deviation ui elements - mStdDevTextView = (TextView) dialogView.findViewById(R.id.std_dev_text_view); - mStdDevSeekBar = (SeekBar) dialogView.findViewById(R.id.std_dev_seek_bar); + mStdDevTextView = dialogView.findViewById(R.id.std_dev_text_view); + mStdDevSeekBar = dialogView.findViewById(R.id.std_dev_seek_bar); mStdDevSeekBar.setMax(3); - mCurrStdDevTextView = (TextView) dialogView.findViewById(R.id.curr_std_dev_text_view); + mCurrStdDevTextView = dialogView.findViewById(R.id.curr_std_dev_text_view); //update seek bar position with current StandardDeviation updateSeekBar(mStdDevSeekBar, mStdDevFactor, mCurrStdDevTextView); @@ -359,7 +359,7 @@ public void onStopTrackingTouch(SeekBar seekBar) { } stretchTypeArray.add(MainActivity.StretchType.STANDARD_DEVIATION.toString()); //2 ArrayAdapter stretchTypeSpinnerAdapter = new ArrayAdapter<>(getContext(), R.layout.rgb_spinner_text_view, stretchTypeArray); - Spinner stretchTypeSpinner = (Spinner) dialogView.findViewById(R.id.stretch_type_spinner); + Spinner stretchTypeSpinner = dialogView.findViewById(R.id.stretch_type_spinner); stretchTypeSpinner.setAdapter(stretchTypeSpinnerAdapter); stretchTypeSpinner.setSelection(mStretchType.ordinal()); stretchTypeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { diff --git a/java/scene-property-expressions/src/main/java/com/esri/arcgisruntime/sample/scenepropertyexpressions/MainActivity.java b/java/scene-property-expressions/src/main/java/com/esri/arcgisruntime/sample/scenepropertyexpressions/MainActivity.java index 37bcc4c938..54d5b89c34 100644 --- a/java/scene-property-expressions/src/main/java/com/esri/arcgisruntime/sample/scenepropertyexpressions/MainActivity.java +++ b/java/scene-property-expressions/src/main/java/com/esri/arcgisruntime/sample/scenepropertyexpressions/MainActivity.java @@ -25,6 +25,7 @@ import com.esri.arcgisruntime.geometry.SpatialReferences; import com.esri.arcgisruntime.mapping.ArcGISScene; import com.esri.arcgisruntime.mapping.Basemap; +import com.esri.arcgisruntime.mapping.BasemapStyle; import com.esri.arcgisruntime.mapping.view.Camera; import com.esri.arcgisruntime.mapping.view.Graphic; import com.esri.arcgisruntime.mapping.view.GraphicsOverlay; @@ -51,7 +52,7 @@ protected void onCreate(Bundle savedInstanceState) { mSceneView = findViewById(R.id.sceneView); // create a scene with an imagery basemap - ArcGISScene scene = new ArcGISScene(Basemap.Type.IMAGERY); + ArcGISScene scene = new ArcGISScene(BasemapStyle.ARCGIS_IMAGERY); // add the SceneView to the stack pane mSceneView.setScene(scene); diff --git a/java/service-feature-table-cache/README.md b/java/service-feature-table-cache/README.md deleted file mode 100755 index ef33de5448..0000000000 --- a/java/service-feature-table-cache/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# Service feature table (Cache) - -Display a feature layer from a service using the **on interaction cache** feature request mode. - -![Image of service feature table on interaction cache](service-feature-table-cache.png) - -## Use case - -Service feature tables support three request modes, which define how features are requested from the service and stored in the local table. The feature request modes have different performance characteristics. Use **On interaction cache** in scenarios with large amounts of infrequently edited data. - -## How to use the sample - -Run the sample and pan and zoom around the map. With each interaction, features will be requested and stored in a local cache. Each subsequent interaction will display features from the cache and only request new features from the service. - -## How it works - -1. Set the `ServiceFeatureTable.setFeatureRequestMode(...)` property of the service feature table to `ON_INTERACTION_CACHE` before the table is loaded. -2. Add the table to the map using a `FeatureLayer`; features will be requested for the visible extent as the user pans and zooms. - -## Relevant API - -* FeatureLayer -* FeatureRequestMode.ON_INTERACTION_CACHE -* ServiceFeatureTable -* ServiceFeatureTable.setFeatureRequestMode - -## About the data - -The sample opens with an initial visible extent centered over pool permit statuses in California. - -## Additional information - -**On interaction cache** is the default feature request mode. Features are requested automatically for the visible extent as the users pans and zooms the map. If the user returns to an area where features have previously been requested, those features won't be requested again. - -## Tags - -cache, feature request mode, performance diff --git a/java/service-feature-table-cache/README.metadata.json b/java/service-feature-table-cache/README.metadata.json deleted file mode 100644 index 5dd8fedaad..0000000000 --- a/java/service-feature-table-cache/README.metadata.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "category": "Edit and Manage Data", - "description": "Display a feature layer from a service using the **on interaction cache** feature request mode.", - "formal_name": "ServiceFeatureTableCache", - "ignore": false, - "images": [ - "service-feature-table-cache.png" - ], - "keywords": [ - "cache", - "feature request mode", - "performance" - ], - "language": "java", - "redirect_from": [ - "/android/latest/sample-code/service-feature-table-cache.htm" - ], - "relevant_apis": [ - "FeatureLayer", - "FeatureRequestMode.ON_INTERACTION_CACHE", - "ServiceFeatureTable", - "ServiceFeatureTable.setFeatureRequestMode" - ], - "snippets": [ - "src/main/java/com/esri/arcgisruntime/sample/servicefeaturetablecache/MainActivity.java" - ], - "title": "Service feature table (Cache)" -} diff --git a/java/service-feature-table-cache/build.gradle b/java/service-feature-table-cache/build.gradle deleted file mode 100644 index 0734c03083..0000000000 --- a/java/service-feature-table-cache/build.gradle +++ /dev/null @@ -1,24 +0,0 @@ -apply plugin: 'com.android.application' - -android { - compileSdkVersion rootProject.ext.compileSdkVersion - - defaultConfig { - applicationId "com.esri.arcgisruntime.sample.servicefeaturetablecache" - minSdkVersion rootProject.ext.minSdkVersion - targetSdkVersion rootProject.ext.targetSdkVersion - versionCode rootProject.ext.versionCode - versionName rootProject.ext.versionName - buildConfigField("String", "API_KEY", API_KEY) - } - buildTypes { - release { - minifyEnabled false - proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - } - } -} - -dependencies { - // arcgis-android & appcompat lib dependencies from rootProject build.gradle -} diff --git a/java/service-feature-table-cache/proguard-rules.pro b/java/service-feature-table-cache/proguard-rules.pro deleted file mode 100644 index 077819abdb..0000000000 --- a/java/service-feature-table-cache/proguard-rules.pro +++ /dev/null @@ -1,17 +0,0 @@ -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in /Users/will6489/Tools/android-sdk-mac_x86/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the proguardFiles -# directive in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/java/service-feature-table-cache/service-feature-table-cache.png b/java/service-feature-table-cache/service-feature-table-cache.png deleted file mode 100644 index 979b7f6565..0000000000 Binary files a/java/service-feature-table-cache/service-feature-table-cache.png and /dev/null differ diff --git a/java/service-feature-table-cache/src/main/AndroidManifest.xml b/java/service-feature-table-cache/src/main/AndroidManifest.xml deleted file mode 100644 index 3e1b86e18b..0000000000 --- a/java/service-feature-table-cache/src/main/AndroidManifest.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/java/service-feature-table-cache/src/main/java/com/esri/arcgisruntime/sample/servicefeaturetablecache/MainActivity.java b/java/service-feature-table-cache/src/main/java/com/esri/arcgisruntime/sample/servicefeaturetablecache/MainActivity.java deleted file mode 100644 index 73c8034be0..0000000000 --- a/java/service-feature-table-cache/src/main/java/com/esri/arcgisruntime/sample/servicefeaturetablecache/MainActivity.java +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright 2016 ESRI - * - * All rights reserved under the copyright laws of the United States - * and applicable international laws, treaties, and conventions. - * - * You may freely redistribute and use this sample code, with or - * without modification, provided you include the original copyright - * notice and use restrictions. - * - * See the Sample code usage restrictions document for further information. - * - */ - -package com.esri.arcgisruntime.sample.servicefeaturetablecache; - -import android.os.Bundle; - -import androidx.appcompat.app.AppCompatActivity; -import com.esri.arcgisruntime.ArcGISRuntimeEnvironment; -import com.esri.arcgisruntime.data.ServiceFeatureTable; -import com.esri.arcgisruntime.geometry.Envelope; -import com.esri.arcgisruntime.geometry.SpatialReferences; -import com.esri.arcgisruntime.layers.FeatureLayer; -import com.esri.arcgisruntime.mapping.ArcGISMap; -import com.esri.arcgisruntime.mapping.BasemapStyle; -import com.esri.arcgisruntime.mapping.Viewpoint; -import com.esri.arcgisruntime.mapping.view.MapView; - -public class MainActivity extends AppCompatActivity { - - MapView mMapView; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - // authentication with an API key or named user is required to access basemaps and other - // location services - ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY); - - // inflate MapView from layout - mMapView = findViewById(R.id.mapView); - - // create a map with the light grey canvas basemap - ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_LIGHT_GRAY); - - // create feature layer with its service feature table - // create the service feature table - ServiceFeatureTable serviceFeatureTable = new ServiceFeatureTable( - getResources().getString(R.string.sample_service_url)); - - //explicitly set the mode to on interaction cache (which is also the default mode for service feature tables) - serviceFeatureTable.setFeatureRequestMode(ServiceFeatureTable.FeatureRequestMode.ON_INTERACTION_CACHE); - - // create the feature layer using the service feature table - FeatureLayer featureLayer = new FeatureLayer(serviceFeatureTable); - - // add the layer to the map - map.getOperationalLayers().add(featureLayer); - - // set the map to be displayed in the mapview - mMapView.setMap(map); - - // set an initial viewpoint - mMapView.setViewpoint(new Viewpoint( - new Envelope(-1.30758164047166E7, 4014771.46954516, -1.30730056797177E7, 4016869.78617381, - SpatialReferences.getWebMercator()))); - } - - @Override - protected void onPause() { - super.onPause(); - // pause MapView - mMapView.pause(); - } - - @Override - protected void onResume() { - super.onResume(); - // resume MapView - mMapView.resume(); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - // dispose MapView - mMapView.dispose(); - } -} diff --git a/java/service-feature-table-cache/src/main/res/layout/activity_main.xml b/java/service-feature-table-cache/src/main/res/layout/activity_main.xml deleted file mode 100644 index f39188dc71..0000000000 --- a/java/service-feature-table-cache/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - diff --git a/java/service-feature-table-cache/src/main/res/mipmap-hdpi/ic_launcher.png b/java/service-feature-table-cache/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index cde69bccce..0000000000 Binary files a/java/service-feature-table-cache/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/java/service-feature-table-cache/src/main/res/mipmap-mdpi/ic_launcher.png b/java/service-feature-table-cache/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index c133a0cbd3..0000000000 Binary files a/java/service-feature-table-cache/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/java/service-feature-table-cache/src/main/res/mipmap-xhdpi/ic_launcher.png b/java/service-feature-table-cache/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index bfa42f0e7b..0000000000 Binary files a/java/service-feature-table-cache/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/java/service-feature-table-cache/src/main/res/mipmap-xxhdpi/ic_launcher.png b/java/service-feature-table-cache/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 324e72cdd7..0000000000 Binary files a/java/service-feature-table-cache/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/java/service-feature-table-cache/src/main/res/values-w820dp/dimens.xml b/java/service-feature-table-cache/src/main/res/values-w820dp/dimens.xml deleted file mode 100644 index 63fc816444..0000000000 --- a/java/service-feature-table-cache/src/main/res/values-w820dp/dimens.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - 64dp - diff --git a/java/service-feature-table-cache/src/main/res/values/dimens.xml b/java/service-feature-table-cache/src/main/res/values/dimens.xml deleted file mode 100644 index 47c8224673..0000000000 --- a/java/service-feature-table-cache/src/main/res/values/dimens.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - 16dp - 16dp - diff --git a/java/service-feature-table-cache/src/main/res/values/strings.xml b/java/service-feature-table-cache/src/main/res/values/strings.xml deleted file mode 100644 index bad7fefe1f..0000000000 --- a/java/service-feature-table-cache/src/main/res/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - Service Feature Table (Cache) - https://sampleserver6.arcgisonline.com/arcgis/rest/services/PoolPermits/FeatureServer/0 - diff --git a/java/service-feature-table-manual-cache/README.md b/java/service-feature-table-manual-cache/README.md deleted file mode 100755 index 017ca7c8a2..0000000000 --- a/java/service-feature-table-manual-cache/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# Service feature table (manual cache) - -Display a feature layer from a service using the **manual cache** feature request mode. - -![Image of service feature table manual cache](service-feature-table-manual-cache.png) - -## Use case - -Service feature tables support three request modes, which define how features are requested from the service and stored in the local table. The feature request modes have different performance characteristics. Use **manual cache** in scenarios where you want to explicitly control requests for features. - -## How to use the sample - -Run the sample and pan and zoom around the map. Features will be requested and displayed automatically. - -## How it works - -1. Set the `ServiceFeatureTable.setFeatureRequestMode(...)` property of the service feature table to `MANUAL_CACHE` before the table is loaded. -2. Load the table with `serviceFeatureTable.loadAsync()`. -3. Call `populateFromServiceAsync()` on the table to request features. - -## Relevant API - -* FeatureLayer -* FeatureRequestMode.MANUAL_CACHE -* ServiceFeatureTable -* ServiceFeatureTable.populateFromServiceAsync -* ServiceFeatureTable.setFeatureRequestMode - -## About the data - -The sample opens with a tree maintenance feature layer centered over San Francisco. - -## Additional information - -In **manual cache** mode, features are never automatically populated from the service. All features are loaded manually using calls to `populateFromServiceAsync`. - -## Tags - -cache, feature request mode, performance diff --git a/java/service-feature-table-manual-cache/README.metadata.json b/java/service-feature-table-manual-cache/README.metadata.json deleted file mode 100644 index 3096f66757..0000000000 --- a/java/service-feature-table-manual-cache/README.metadata.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "category": "Edit and Manage Data", - "description": "Display a feature layer from a service using the **manual cache** feature request mode.", - "formal_name": "ServiceFeatureTableManualCache", - "ignore": false, - "images": [ - "service-feature-table-manual-cache.png" - ], - "keywords": [ - "cache", - "feature request mode", - "performance" - ], - "language": "java", - "redirect_from": [ - "/android/latest/sample-code/service-feature-table-manual-cache.htm" - ], - "relevant_apis": [ - "FeatureLayer", - "FeatureRequestMode.MANUAL_CACHE", - "ServiceFeatureTable", - "ServiceFeatureTable.populateFromServiceAsync", - "ServiceFeatureTable.setFeatureRequestMode" - ], - "snippets": [ - "src/main/java/com/esri/arcgisruntime/samples/servicefeaturetablemanualcache/MainActivity.java" - ], - "title": "Service feature table (manual cache)" -} diff --git a/java/service-feature-table-manual-cache/proguard-rules.pro b/java/service-feature-table-manual-cache/proguard-rules.pro deleted file mode 100644 index 077819abdb..0000000000 --- a/java/service-feature-table-manual-cache/proguard-rules.pro +++ /dev/null @@ -1,17 +0,0 @@ -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in /Users/will6489/Tools/android-sdk-mac_x86/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the proguardFiles -# directive in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/java/service-feature-table-manual-cache/service-feature-table-manual-cache.png b/java/service-feature-table-manual-cache/service-feature-table-manual-cache.png deleted file mode 100644 index 823259538e..0000000000 Binary files a/java/service-feature-table-manual-cache/service-feature-table-manual-cache.png and /dev/null differ diff --git a/java/service-feature-table-manual-cache/src/main/java/com/esri/arcgisruntime/samples/servicefeaturetablemanualcache/MainActivity.java b/java/service-feature-table-manual-cache/src/main/java/com/esri/arcgisruntime/samples/servicefeaturetablemanualcache/MainActivity.java deleted file mode 100644 index 3f8de66a11..0000000000 --- a/java/service-feature-table-manual-cache/src/main/java/com/esri/arcgisruntime/samples/servicefeaturetablemanualcache/MainActivity.java +++ /dev/null @@ -1,148 +0,0 @@ -/* Copyright 2016 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.arcgisruntime.samples.servicefeaturetablemanualcache; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import android.os.Bundle; -import android.util.Log; -import android.widget.Toast; - -import androidx.appcompat.app.AppCompatActivity; -import com.esri.arcgisruntime.ArcGISRuntimeEnvironment; -import com.esri.arcgisruntime.concurrent.ListenableFuture; -import com.esri.arcgisruntime.data.Feature; -import com.esri.arcgisruntime.data.FeatureQueryResult; -import com.esri.arcgisruntime.data.QueryParameters; -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.ArcGISMap; -import com.esri.arcgisruntime.mapping.BasemapStyle; -import com.esri.arcgisruntime.mapping.Viewpoint; -import com.esri.arcgisruntime.mapping.view.MapView; - -public class MainActivity extends AppCompatActivity { - - private MapView mMapView; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - // authentication with an API key or named user is required to access basemaps and other - // location services - ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY); - - // inflate MapView from layout - mMapView = findViewById(R.id.mapView); - - // create a map with the topographic basemap - ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC); - - // create feature layer with its service feature table - // create the service feature table - final ServiceFeatureTable serviceFeatureTable = new ServiceFeatureTable( - getResources().getString(R.string.sample_service_url)); - - //explicitly set the mode to on manual cache (which means you need to call populate from service) - serviceFeatureTable.setFeatureRequestMode(ServiceFeatureTable.FeatureRequestMode.MANUAL_CACHE); - - // create the feature layer using the service feature table - FeatureLayer featureLayer = new FeatureLayer(serviceFeatureTable); - - // add the layer to the map - map.getOperationalLayers().add(featureLayer); - - // load the table - serviceFeatureTable.loadAsync(); - // add a done loading listener to call populate from service when the table is loaded is done - serviceFeatureTable.addDoneLoadingListener(new Runnable() { - @Override - public void run() { - - // set up the query parameters - QueryParameters params = new QueryParameters(); - // for a specific 311 request type - params.setWhereClause("req_type = 'Tree Maintenance or Damage'"); - // set all outfields - List outFields = new ArrayList<>(); - outFields.add("*"); - //populate the table based on the query, listen for result in a listenable future - final ListenableFuture future = serviceFeatureTable - .populateFromServiceAsync(params, true, outFields); - //add done listener to the future which fires when the async method is complete - future.addDoneListener(new Runnable() { - @Override - public void run() { - try { - //call get on the future to get the result - FeatureQueryResult result = future.get(); - // create an Iterator - Iterator iterator = result.iterator(); - Feature feature; - // cycle through selections - int counter = 0; - while (iterator.hasNext()) { - feature = iterator.next(); - counter++; - Log.d(getResources().getString(R.string.app_name), - "Selection #: " + counter + " Table name: " + feature.getFeatureTable().getTableName()); - } - Toast.makeText(getApplicationContext(), counter + " features returned", Toast.LENGTH_SHORT).show(); - - } catch (Exception e) { - Log.e(getResources().getString(R.string.app_name), "Populate from service failed: " + e.getMessage()); - } - } - }); - } - }); - - // set the map to be displayed in the mapview - mMapView.setMap(map); - - //set a viewpoint on the mapview so it zooms to the features once they are cached. - mMapView.setViewpoint(new Viewpoint(new Point(-13630484, 4545415, SpatialReferences.getWebMercator()), 500000)); - - } - - @Override - protected void onPause() { - super.onPause(); - // pause MapView - mMapView.pause(); - } - - @Override - protected void onResume() { - super.onResume(); - // resume MapView - mMapView.resume(); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - // dispose MapView - mMapView.dispose(); - } -} diff --git a/java/service-feature-table-manual-cache/src/main/res/layout/activity_main.xml b/java/service-feature-table-manual-cache/src/main/res/layout/activity_main.xml deleted file mode 100644 index 814da09b85..0000000000 --- a/java/service-feature-table-manual-cache/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - diff --git a/java/service-feature-table-manual-cache/src/main/res/mipmap-hdpi/ic_launcher.png b/java/service-feature-table-manual-cache/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index cde69bccce..0000000000 Binary files a/java/service-feature-table-manual-cache/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/java/service-feature-table-manual-cache/src/main/res/mipmap-mdpi/ic_launcher.png b/java/service-feature-table-manual-cache/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index c133a0cbd3..0000000000 Binary files a/java/service-feature-table-manual-cache/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/java/service-feature-table-manual-cache/src/main/res/mipmap-xhdpi/ic_launcher.png b/java/service-feature-table-manual-cache/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index bfa42f0e7b..0000000000 Binary files a/java/service-feature-table-manual-cache/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/java/service-feature-table-manual-cache/src/main/res/mipmap-xxhdpi/ic_launcher.png b/java/service-feature-table-manual-cache/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 324e72cdd7..0000000000 Binary files a/java/service-feature-table-manual-cache/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/java/service-feature-table-manual-cache/src/main/res/values-w820dp/dimens.xml b/java/service-feature-table-manual-cache/src/main/res/values-w820dp/dimens.xml deleted file mode 100644 index 63fc816444..0000000000 --- a/java/service-feature-table-manual-cache/src/main/res/values-w820dp/dimens.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - 64dp - diff --git a/java/service-feature-table-manual-cache/src/main/res/values/dimens.xml b/java/service-feature-table-manual-cache/src/main/res/values/dimens.xml deleted file mode 100644 index 47c8224673..0000000000 --- a/java/service-feature-table-manual-cache/src/main/res/values/dimens.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - 16dp - 16dp - diff --git a/java/service-feature-table-manual-cache/src/main/res/values/strings.xml b/java/service-feature-table-manual-cache/src/main/res/values/strings.xml deleted file mode 100644 index d0a326cab3..0000000000 --- a/java/service-feature-table-manual-cache/src/main/res/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - Service feature table (manual cache) - https://sampleserver6.arcgisonline.com/arcgis/rest/services/SF311/FeatureServer/0 - diff --git a/java/service-feature-table-manual-cache/src/main/res/values/styles.xml b/java/service-feature-table-manual-cache/src/main/res/values/styles.xml deleted file mode 100644 index 5885930df6..0000000000 --- a/java/service-feature-table-manual-cache/src/main/res/values/styles.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - diff --git a/java/service-feature-table-no-cache/.gitignore b/java/service-feature-table-no-cache/.gitignore deleted file mode 100644 index 796b96d1c4..0000000000 --- a/java/service-feature-table-no-cache/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/java/service-feature-table-no-cache/README.md b/java/service-feature-table-no-cache/README.md deleted file mode 100755 index 4271104b94..0000000000 --- a/java/service-feature-table-no-cache/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# Service feature table (no cache) - -Display a feature layer from a service using the **no cache** feature request mode. - -![Image of service feature table no cache](service-feature-table-no-cache.png) - -## Use case - -Service feature tables support three request modes, which define how features are requested from the service and stored in the local table. The feature request modes have different performance characteristics. Use **no cache** in scenarios where you always want the freshest data. - -## How to use the sample - -Run the sample and pan and zoom around the map. With each interaction, new features will be requested from the service and displayed on the map. - -## How it works - -1. Set the `ServiceFeatureTable.setFeatureRequestMode(...)` property of the service feature table to `ON_INTERACTION_NO_CACHE` before the table is loaded. -2. Add the table to the map using a `FeatureLayer`; features will be requested for the visible extent as the user pans and zooms. - -## Relevant API - -* FeatureLayer -* FeatureRequestMode.ON_INTERACTION_NO_CACHE -* ServiceFeatureTable -* ServiceFeatureTable.setFeatureRequestMode - -## About the data - -The sample opens with an initial visible extent centered over pool permit statuses in California. - -## Additional information - -In **no cache** mode, features are automatically populated from the service for the visible extent. Each time the user pans and zooms, features are downloaded for the visible extent. Features are still cached in a local geodatabase for display, but the cache will always be populated with the latest data after navigation. - -> **NOTE**: **No cache** does not guarantee that features won't be cached locally; feature request mode is a performance concept unrelated to data security. - -## Tags - -cache, feature request mode, performance diff --git a/java/service-feature-table-no-cache/README.metadata.json b/java/service-feature-table-no-cache/README.metadata.json deleted file mode 100644 index 454e48d1fd..0000000000 --- a/java/service-feature-table-no-cache/README.metadata.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "category": "Edit and Manage Data", - "description": "Display a feature layer from a service using the **no cache** feature request mode.", - "formal_name": "ServiceFeatureTableNoCache", - "ignore": false, - "images": [ - "service-feature-table-no-cache.png" - ], - "keywords": [ - "cache", - "feature request mode", - "performance" - ], - "language": "java", - "redirect_from": [ - "/android/latest/sample-code/service-feature-table-no-cache.htm" - ], - "relevant_apis": [ - "FeatureLayer", - "FeatureRequestMode.ON_INTERACTION_NO_CACHE", - "ServiceFeatureTable", - "ServiceFeatureTable.setFeatureRequestMode" - ], - "snippets": [ - "src/main/java/com/esri/arcgisruntime/samples/servicefeaturetablenocache/MainActivity.java" - ], - "title": "Service feature table (no cache)" -} diff --git a/java/service-feature-table-no-cache/proguard-rules.pro b/java/service-feature-table-no-cache/proguard-rules.pro deleted file mode 100644 index 077819abdb..0000000000 --- a/java/service-feature-table-no-cache/proguard-rules.pro +++ /dev/null @@ -1,17 +0,0 @@ -# Add project specific ProGuard rules here. -# By default, the flags in this file are appended to flags specified -# in /Users/will6489/Tools/android-sdk-mac_x86/tools/proguard/proguard-android.txt -# You can edit the include path and order by changing the proguardFiles -# directive in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# Add any project specific keep options here: - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} diff --git a/java/service-feature-table-no-cache/service-feature-table-no-cache.png b/java/service-feature-table-no-cache/service-feature-table-no-cache.png deleted file mode 100644 index d48c092122..0000000000 Binary files a/java/service-feature-table-no-cache/service-feature-table-no-cache.png and /dev/null differ diff --git a/java/service-feature-table-no-cache/src/main/java/com/esri/arcgisruntime/samples/servicefeaturetablenocache/MainActivity.java b/java/service-feature-table-no-cache/src/main/java/com/esri/arcgisruntime/samples/servicefeaturetablenocache/MainActivity.java deleted file mode 100644 index 247673aab5..0000000000 --- a/java/service-feature-table-no-cache/src/main/java/com/esri/arcgisruntime/samples/servicefeaturetablenocache/MainActivity.java +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright 2016 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.arcgisruntime.samples.servicefeaturetablenocache; - -import android.os.Bundle; - -import androidx.appcompat.app.AppCompatActivity; -import com.esri.arcgisruntime.ArcGISRuntimeEnvironment; -import com.esri.arcgisruntime.data.ServiceFeatureTable; -import com.esri.arcgisruntime.geometry.Envelope; -import com.esri.arcgisruntime.geometry.SpatialReferences; -import com.esri.arcgisruntime.layers.FeatureLayer; -import com.esri.arcgisruntime.mapping.ArcGISMap; -import com.esri.arcgisruntime.mapping.BasemapStyle; -import com.esri.arcgisruntime.mapping.Viewpoint; -import com.esri.arcgisruntime.mapping.view.MapView; - -public class MainActivity extends AppCompatActivity { - - private MapView mMapView; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - // authentication with an API key or named user is required to access basemaps and other - // location services - ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY); - - // inflate MapView from layout - mMapView = findViewById(R.id.mapView); - - // create a map with the topographic basemap - ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC); - - // create feature layer with its service feature table - // create the service feature table - ServiceFeatureTable serviceFeatureTable = new ServiceFeatureTable(getString(R.string.sample_service_url)); - - // explicitly set the mode to on interaction no cache (every interaction (pan, query etc) new features will be - // requested - serviceFeatureTable.setFeatureRequestMode(ServiceFeatureTable.FeatureRequestMode.ON_INTERACTION_NO_CACHE); - - // create the feature layer using the service feature table - FeatureLayer featureLayer = new FeatureLayer(serviceFeatureTable); - - // add the layer to the map - map.getOperationalLayers().add(featureLayer); - - // set the map to be displayed in the map view - mMapView.setMap(map); - - // set an initial viewpoint - mMapView.setViewpoint(new Viewpoint( - new Envelope(-1.30758164047166E7, 4014771.46954516, -1.30730056797177E7, 4016869.78617381, - SpatialReferences.getWebMercator()))); - } - - @Override - protected void onPause() { - super.onPause(); - // pause MapView - mMapView.pause(); - } - - @Override - protected void onResume() { - super.onResume(); - // resume MapView - mMapView.resume(); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - // dispose MapView - mMapView.dispose(); - } -} diff --git a/java/service-feature-table-no-cache/src/main/res/layout/activity_main.xml b/java/service-feature-table-no-cache/src/main/res/layout/activity_main.xml deleted file mode 100644 index 814da09b85..0000000000 --- a/java/service-feature-table-no-cache/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - diff --git a/java/service-feature-table-no-cache/src/main/res/mipmap-hdpi/ic_launcher.png b/java/service-feature-table-no-cache/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index cde69bccce..0000000000 Binary files a/java/service-feature-table-no-cache/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/java/service-feature-table-no-cache/src/main/res/mipmap-mdpi/ic_launcher.png b/java/service-feature-table-no-cache/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index c133a0cbd3..0000000000 Binary files a/java/service-feature-table-no-cache/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/java/service-feature-table-no-cache/src/main/res/mipmap-xhdpi/ic_launcher.png b/java/service-feature-table-no-cache/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index bfa42f0e7b..0000000000 Binary files a/java/service-feature-table-no-cache/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/java/service-feature-table-no-cache/src/main/res/mipmap-xxhdpi/ic_launcher.png b/java/service-feature-table-no-cache/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 324e72cdd7..0000000000 Binary files a/java/service-feature-table-no-cache/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/java/service-feature-table-no-cache/src/main/res/values-w820dp/dimens.xml b/java/service-feature-table-no-cache/src/main/res/values-w820dp/dimens.xml deleted file mode 100644 index 63fc816444..0000000000 --- a/java/service-feature-table-no-cache/src/main/res/values-w820dp/dimens.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - 64dp - diff --git a/java/service-feature-table-no-cache/src/main/res/values/colors.xml b/java/service-feature-table-no-cache/src/main/res/values/colors.xml deleted file mode 100644 index 36f5fca4f2..0000000000 --- a/java/service-feature-table-no-cache/src/main/res/values/colors.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - #2196F3 - #1976D2 - #4CAF50 - \ No newline at end of file diff --git a/java/service-feature-table-no-cache/src/main/res/values/dimens.xml b/java/service-feature-table-no-cache/src/main/res/values/dimens.xml deleted file mode 100644 index 47c8224673..0000000000 --- a/java/service-feature-table-no-cache/src/main/res/values/dimens.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - 16dp - 16dp - diff --git a/java/service-feature-table-no-cache/src/main/res/values/strings.xml b/java/service-feature-table-no-cache/src/main/res/values/strings.xml deleted file mode 100644 index 08a935e0f4..0000000000 --- a/java/service-feature-table-no-cache/src/main/res/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - Service Feature Table (No Cache) - https://sampleserver6.arcgisonline.com/arcgis/rest/services/PoolPermits/FeatureServer/0 - diff --git a/java/set-initial-map-location/README.md b/java/set-initial-map-location/README.md index 8fe562ca0f..dd93c8ac17 100644 --- a/java/set-initial-map-location/README.md +++ b/java/set-initial-map-location/README.md @@ -14,7 +14,7 @@ When the map loads, note the specific location and scale of the initial map view ## How it works -1. Create an `ArcGISMap`, specifying a basemap type, latitude and longitude in WGS84, and a level of detail. +1. Create an `ArcGISMap`, specifying a basemap style, latitude and longitude in WGS84, and a level of detail. 2. Display the map in a map view with `MapView.setMap(map)`. ## Relevant API diff --git a/java/set-initial-map-location/src/main/java/com/esri/arcgisruntime/sample/setinitialmaplocation/MainActivity.java b/java/set-initial-map-location/src/main/java/com/esri/arcgisruntime/sample/setinitialmaplocation/MainActivity.java index 4e4fc6150e..67271ef8d5 100644 --- a/java/set-initial-map-location/src/main/java/com/esri/arcgisruntime/sample/setinitialmaplocation/MainActivity.java +++ b/java/set-initial-map-location/src/main/java/com/esri/arcgisruntime/sample/setinitialmaplocation/MainActivity.java @@ -40,7 +40,7 @@ protected void onCreate(Bundle savedInstanceState) { // create MapView from layout mMapView = findViewById(R.id.mapView); - // create a map with the BasemapType topographic + // create a map with the BasemapStyle topographic ArcGISMap mMap = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC); // set the map to be displayed in this view mMapView.setMap(mMap); diff --git a/java/settings.gradle b/java/settings.gradle index db7c8015aa..b56e0cccb9 100644 --- a/java/settings.gradle +++ b/java/settings.gradle @@ -122,9 +122,6 @@ include ':add-enc-exchange-set', ':scene-layer-selection', ':scene-property-expressions', ':search-for-webmap', - ':service-feature-table-cache', - ':service-feature-table-manual-cache', - ':service-feature-table-no-cache', ':set-initial-map-area', ':set-initial-map-location', ':set-map-spatial-reference', diff --git a/java/show-callout/src/main/java/com/esri/arcgisruntime/samples/showcallout/MainActivity.java b/java/show-callout/src/main/java/com/esri/arcgisruntime/samples/showcallout/MainActivity.java index ce1ff8f928..ec0ecdb374 100644 --- a/java/show-callout/src/main/java/com/esri/arcgisruntime/samples/showcallout/MainActivity.java +++ b/java/show-callout/src/main/java/com/esri/arcgisruntime/samples/showcallout/MainActivity.java @@ -50,7 +50,7 @@ protected void onCreate(Bundle savedInstanceState) { // inflate MapView from layout mMapView = findViewById(R.id.mapView); - // create a map with the Basemap Type topographic + // create a map with the Basemap Style topographic final ArcGISMap mMap = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC); // set the map to be displayed in this view mMapView.setMap(mMap); diff --git a/java/show-magnifier/src/main/java/com/esri/arcgisruntime/sample/showmagnifier/MainActivity.java b/java/show-magnifier/src/main/java/com/esri/arcgisruntime/sample/showmagnifier/MainActivity.java index a9c6b4554d..14413c7ba9 100644 --- a/java/show-magnifier/src/main/java/com/esri/arcgisruntime/sample/showmagnifier/MainActivity.java +++ b/java/show-magnifier/src/main/java/com/esri/arcgisruntime/sample/showmagnifier/MainActivity.java @@ -40,7 +40,7 @@ protected void onCreate(Bundle savedInstanceState) { // inflate MapView from layout mMapView = findViewById(R.id.mapView); - // create a map with the Basemap Type topographic + // create a map with the Basemap Style topographic ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC); // set the map to be displayed in this view mMapView.setMap(map); diff --git a/java/sketch-editor/src/main/java/com/esri/arcgisruntime/sample/sketcheditor/MainActivity.java b/java/sketch-editor/src/main/java/com/esri/arcgisruntime/sample/sketcheditor/MainActivity.java index f013357444..e6efb05265 100644 --- a/java/sketch-editor/src/main/java/com/esri/arcgisruntime/sample/sketcheditor/MainActivity.java +++ b/java/sketch-editor/src/main/java/com/esri/arcgisruntime/sample/sketcheditor/MainActivity.java @@ -75,7 +75,7 @@ protected void onCreate(Bundle savedInstanceState) { // inflate map view from layout mMapView = findViewById(R.id.mapView); - // create a map with the Basemap Type topographic + // create a map with the Basemap Style topographic ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_LIGHT_GRAY); // set the map to be displayed in this view mMapView.setMap(map); diff --git a/java/spatial-relationships/src/main/res/layout/results_expandable_list.xml b/java/spatial-relationships/src/main/res/layout/results_expandable_list.xml index 3af0222a7f..eb728bc3ec 100644 --- a/java/spatial-relationships/src/main/res/layout/results_expandable_list.xml +++ b/java/spatial-relationships/src/main/res/layout/results_expandable_list.xml @@ -1,12 +1,16 @@ - + + android:layout_height="match_parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> diff --git a/java/statistical-query-group-and-sort/src/main/java/com/esri/arcgisruntime/sample/statisticalquerygroupandsort/RecyclerViewAdapter.java b/java/statistical-query-group-and-sort/src/main/java/com/esri/arcgisruntime/sample/statisticalquerygroupandsort/RecyclerViewAdapter.java index aa3dda3abd..14bed1d0b7 100644 --- a/java/statistical-query-group-and-sort/src/main/java/com/esri/arcgisruntime/sample/statisticalquerygroupandsort/RecyclerViewAdapter.java +++ b/java/statistical-query-group-and-sort/src/main/java/com/esri/arcgisruntime/sample/statisticalquerygroupandsort/RecyclerViewAdapter.java @@ -37,7 +37,7 @@ class RecyclerViewAdapter extends RecyclerView.Adapter private final LayoutInflater mInflater; private final boolean mHasCheckbox; private final boolean[] mCheckedList; - private List mFields; + private final List mFields; private int mSelectedPosition = 0; public RecyclerViewAdapter(Context context, List fields, boolean hasCheckbox) { diff --git a/java/stretch-renderer/src/main/java/com/esri/arcgisruntime/sample/stretchrenderer/ParametersDialogFragment.java b/java/stretch-renderer/src/main/java/com/esri/arcgisruntime/sample/stretchrenderer/ParametersDialogFragment.java index 6982769693..3f421b7b4c 100644 --- a/java/stretch-renderer/src/main/java/com/esri/arcgisruntime/sample/stretchrenderer/ParametersDialogFragment.java +++ b/java/stretch-renderer/src/main/java/com/esri/arcgisruntime/sample/stretchrenderer/ParametersDialogFragment.java @@ -104,32 +104,32 @@ public void onClick(DialogInterface dialog, int which) { } }); // min max ui elements - mMinTextView = (TextView) dialogView.findViewById(R.id.min_value_text_view); - mMaxTextView = (TextView) dialogView.findViewById(R.id.max_value_text_view); - mMinSeekBar = (SeekBar) dialogView.findViewById(R.id.min_seek_bar); - mMaxSeekBar = (SeekBar) dialogView.findViewById(R.id.max_seek_bar); + mMinTextView = dialogView.findViewById(R.id.min_value_text_view); + mMaxTextView = dialogView.findViewById(R.id.max_value_text_view); + mMinSeekBar = dialogView.findViewById(R.id.min_seek_bar); + mMaxSeekBar = dialogView.findViewById(R.id.max_seek_bar); mMinSeekBar.setMax(255); mMaxSeekBar.setMax(255); - mCurrMinTextView = (TextView) dialogView.findViewById(R.id.curr_min_text_view); - mCurrMaxTextView = (TextView) dialogView.findViewById(R.id.curr_max_text_view); + mCurrMinTextView = dialogView.findViewById(R.id.curr_min_text_view); + mCurrMaxTextView = dialogView.findViewById(R.id.curr_max_text_view); updateSeekBar(mMinSeekBar, mMin, mCurrMinTextView); updateSeekBar(mMaxSeekBar, mMax, mCurrMaxTextView); // percent clip ui elements - mPercentClipMinTextView = (TextView) dialogView.findViewById(R.id.percent_clip_min_value_text_view); - mPercentClipMaxTextView = (TextView) dialogView.findViewById(R.id.percent_clip_max_value_text_view); - mPercentClipMinSeekBar = (SeekBar) dialogView.findViewById(R.id.percent_clip_min_seek_bar); - mPercentClipMaxSeekBar = (SeekBar) dialogView.findViewById(R.id.percent_clip_max_seek_bar); + mPercentClipMinTextView = dialogView.findViewById(R.id.percent_clip_min_value_text_view); + mPercentClipMaxTextView = dialogView.findViewById(R.id.percent_clip_max_value_text_view); + mPercentClipMinSeekBar = dialogView.findViewById(R.id.percent_clip_min_seek_bar); + mPercentClipMaxSeekBar = dialogView.findViewById(R.id.percent_clip_max_seek_bar); mPercentClipMinSeekBar.setMax(99); mPercentClipMaxSeekBar.setMax(99); - mCurrPercentClipMinTextView = (TextView) dialogView.findViewById(R.id.curr_percent_clip_min_text_view); - mCurrPercentClipMaxTextView = (TextView) dialogView.findViewById(R.id.curr_percent_clip_max_text_view); + mCurrPercentClipMinTextView = dialogView.findViewById(R.id.curr_percent_clip_min_text_view); + mCurrPercentClipMaxTextView = dialogView.findViewById(R.id.curr_percent_clip_max_text_view); updateSeekBar(mPercentClipMinSeekBar, mPercentClipMin, mCurrPercentClipMinTextView); updateSeekBar(mPercentClipMaxSeekBar, mPercentClipMax, mCurrPercentClipMaxTextView); // standard deviation ui elements - mStdDevTextView = (TextView) dialogView.findViewById(R.id.std_dev_text_view); - mStdDevSeekBar = (SeekBar) dialogView.findViewById(R.id.std_dev_seek_bar); + mStdDevTextView = dialogView.findViewById(R.id.std_dev_text_view); + mStdDevSeekBar = dialogView.findViewById(R.id.std_dev_seek_bar); mStdDevSeekBar.setMax(3); - mCurrStdDevTextView = (TextView) dialogView.findViewById(R.id.curr_std_dev_text_view); + mCurrStdDevTextView = dialogView.findViewById(R.id.curr_std_dev_text_view); updateSeekBar(mStdDevSeekBar, mStdDevFactor, mCurrStdDevTextView); // set ui to previous selection if (mStretchType == MainActivity.StretchType.MIN_MAX) { @@ -240,7 +240,7 @@ public void onStopTrackingTouch(SeekBar seekBar) { } stretchTypeArray.add(MainActivity.StretchType.STANDARD_DEVIATION.toString()); //2 ArrayAdapter stretchTypeSpinnerAdapter = new ArrayAdapter<>(getContext(), R.layout.stretch_spinner_text_view, stretchTypeArray); - Spinner stretchTypeSpinner = (Spinner) dialogView.findViewById(R.id.stretch_type_spinner); + Spinner stretchTypeSpinner = dialogView.findViewById(R.id.stretch_type_spinner); stretchTypeSpinner.setAdapter(stretchTypeSpinnerAdapter); stretchTypeSpinner.setSelection(mStretchType.ordinal()); stretchTypeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { diff --git a/java/symbolize-shapefile/src/main/java/com/esri/arcgisruntime/sample/symbolizeshapefile/MainActivity.java b/java/symbolize-shapefile/src/main/java/com/esri/arcgisruntime/sample/symbolizeshapefile/MainActivity.java index 4d40b6403a..a9477c89eb 100644 --- a/java/symbolize-shapefile/src/main/java/com/esri/arcgisruntime/sample/symbolizeshapefile/MainActivity.java +++ b/java/symbolize-shapefile/src/main/java/com/esri/arcgisruntime/sample/symbolizeshapefile/MainActivity.java @@ -48,7 +48,7 @@ protected void onCreate(Bundle savedInstanceState) { // inflate MapView from layout mMapView = findViewById(R.id.mapView); - // create a map with the BasemapType topographic + // create a map with the Basemap Style topographic ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC); // set the map to be displayed in this view mMapView.setMap(map); diff --git a/java/take-screenshot/src/main/java/com/esri/arcgisruntime/sample/takescreenshot/MainActivity.java b/java/take-screenshot/src/main/java/com/esri/arcgisruntime/sample/takescreenshot/MainActivity.java index cf4164d4f4..9d9004aaaf 100644 --- a/java/take-screenshot/src/main/java/com/esri/arcgisruntime/sample/takescreenshot/MainActivity.java +++ b/java/take-screenshot/src/main/java/com/esri/arcgisruntime/sample/takescreenshot/MainActivity.java @@ -61,7 +61,7 @@ protected void onCreate(Bundle savedInstanceState) { // inflate MapView from layout mMapView = findViewById(R.id.mapView); - // create a map with the BasemapType Imagery with Labels + // create a map with the Basemap Style Imagery with Labels ArcGISMap map = new ArcGISMap(BasemapStyle.ARCGIS_IMAGERY); // set the map to be displayed in this view mMapView.setMap(map); diff --git a/java/terrain-exaggeration/src/main/java/com/esri/arcgisruntime/sample/terrainexaggeration/MainActivity.java b/java/terrain-exaggeration/src/main/java/com/esri/arcgisruntime/sample/terrainexaggeration/MainActivity.java index 67c094080f..f28b1934c2 100644 --- a/java/terrain-exaggeration/src/main/java/com/esri/arcgisruntime/sample/terrainexaggeration/MainActivity.java +++ b/java/terrain-exaggeration/src/main/java/com/esri/arcgisruntime/sample/terrainexaggeration/MainActivity.java @@ -25,6 +25,7 @@ import com.esri.arcgisruntime.mapping.ArcGISScene; import com.esri.arcgisruntime.mapping.ArcGISTiledElevationSource; import com.esri.arcgisruntime.mapping.Basemap; +import com.esri.arcgisruntime.mapping.BasemapStyle; import com.esri.arcgisruntime.mapping.Surface; import com.esri.arcgisruntime.mapping.view.Camera; import com.esri.arcgisruntime.mapping.view.SceneView; @@ -41,7 +42,7 @@ protected void onCreate(Bundle savedInstanceState) { // get a reference to the scene view mSceneView = findViewById(R.id.sceneView); // create a scene and add it to the scene view - ArcGISScene scene = new ArcGISScene(Basemap.Type.NATIONAL_GEOGRAPHIC); + ArcGISScene scene = new ArcGISScene(BasemapStyle.ARCGIS_TOPOGRAPHIC); mSceneView.setScene(scene); // add base surface for elevation data diff --git a/java/unique-value-renderer/README.md b/java/unique-value-renderer/README.md index 62ba6c6f40..a51e210cb5 100755 --- a/java/unique-value-renderer/README.md +++ b/java/unique-value-renderer/README.md @@ -2,7 +2,7 @@ Render features in a layer using a distinct symbol for each unique attribute value. -![Image of unique value renderer](unique-value-renderer.jpg) +![Image of unique value renderer](unique-value-renderer.png) ## Use case diff --git a/java/update-related-features/src/main/java/com/esri/arcgisruntime/sample/updaterelatedfeatures/MainActivity.java b/java/update-related-features/src/main/java/com/esri/arcgisruntime/sample/updaterelatedfeatures/MainActivity.java index ee793c4728..230ad57002 100644 --- a/java/update-related-features/src/main/java/com/esri/arcgisruntime/sample/updaterelatedfeatures/MainActivity.java +++ b/java/update-related-features/src/main/java/com/esri/arcgisruntime/sample/updaterelatedfeatures/MainActivity.java @@ -34,9 +34,10 @@ import com.esri.arcgisruntime.concurrent.ListenableFuture; import com.esri.arcgisruntime.data.ArcGISFeature; import com.esri.arcgisruntime.data.Feature; -import com.esri.arcgisruntime.data.FeatureEditResult; +import com.esri.arcgisruntime.data.FeatureTableEditResult; import com.esri.arcgisruntime.data.RelatedFeatureQueryResult; import com.esri.arcgisruntime.data.ServiceFeatureTable; +import com.esri.arcgisruntime.data.ServiceGeodatabase; import com.esri.arcgisruntime.layers.FeatureLayer; import com.esri.arcgisruntime.loadable.LoadStatus; import com.esri.arcgisruntime.mapping.ArcGISMap; @@ -87,15 +88,21 @@ protected void onCreate(Bundle savedInstanceState) { Callout.Style calloutStyle = new Callout.Style(this, R.xml.callout_style); mCallout.setStyle(calloutStyle); - // set up feature tables and layers - mParksFeatureTable = new ServiceFeatureTable(getString(R.string.parks_feature_table)); - mParksFeatureLayer = new FeatureLayer(mParksFeatureTable); - mPreservesFeatureTable = new ServiceFeatureTable(getString(R.string.preserves_feature_table)); - FeatureLayer preservesFeatureLayer = new FeatureLayer(mPreservesFeatureTable); + // create and load the service geodatabase + ServiceGeodatabase preservesServiceGeodatabase = new ServiceGeodatabase(getString(R.string.alaska_parks_feature_service)); + preservesServiceGeodatabase.loadAsync(); + preservesServiceGeodatabase.addDoneLoadingListener(() -> { + // create a feature layer using the first two layers in the ServiceFeatureTable + mPreservesFeatureTable = preservesServiceGeodatabase.getTable(0); + mParksFeatureTable = preservesServiceGeodatabase.getTable(1); + // create a feature layer from table + FeatureLayer preservesFeatureLayer = new FeatureLayer(mPreservesFeatureTable); + mParksFeatureLayer = new FeatureLayer(mParksFeatureTable); - // add feature layers to map - map.getOperationalLayers().add(mParksFeatureLayer); - map.getOperationalLayers().add(preservesFeatureLayer); + // add the layers to the map + mMapView.getMap().getOperationalLayers().add(preservesFeatureLayer); + mMapView.getMap().getOperationalLayers().add(mParksFeatureLayer); + }); // set the mArcGISMap to be displayed in this view mMapView.setMap(map); @@ -239,14 +246,14 @@ private void updateRelatedFeature(final String visitors) { .updateFeatureAsync(mSelectedRelatedFeature); updateFeature.addDoneListener(() -> { // apply update to the server - final ListenableFuture> serverResult = mPreservesFeatureTable - .applyEditsAsync(); + final ListenableFuture> serverResult = mPreservesFeatureTable + .getServiceGeodatabase().applyEditsAsync(); serverResult.addDoneListener(() -> { try { // check if server result successful - List edits = serverResult.get(); + List edits = serverResult.get(); if (!edits.isEmpty()) { - if (!edits.get(0).hasCompletedWithErrors()) { + if (!edits.get(0).getEditResult().get(0).hasCompletedWithErrors()) { mParksFeatureLayer.clearSelection(); Toast.makeText(this, getString(R.string.update_success), Toast.LENGTH_SHORT) .show(); diff --git a/java/update-related-features/src/main/res/values/strings.xml b/java/update-related-features/src/main/res/values/strings.xml index 37a2cd0154..d455259fe3 100644 --- a/java/update-related-features/src/main/res/values/strings.xml +++ b/java/update-related-features/src/main/res/values/strings.xml @@ -15,11 +15,8 @@ 500,000+ - - - https://services2.arcgis.com/ZQgQTuoyBrtmoGdP/ArcGIS/rest/services/AlaskaNationalParksPreserves_Update/FeatureServer/1 - - - https://services2.arcgis.com/ZQgQTuoyBrtmoGdP/ArcGIS/rest/services/AlaskaNationalParksPreserves_Update/FeatureServer/0 + + + https://services2.arcgis.com/ZQgQTuoyBrtmoGdP/ArcGIS/rest/services/AlaskaNationalParksPreserves_Update/FeatureServer diff --git a/kotlin/README.md b/kotlin/README.md index 42bed9b0ca..396fdee04d 100644 --- a/kotlin/README.md +++ b/kotlin/README.md @@ -1,8 +1,8 @@ # ArcGIS Android Kotlin Samples ## Requirements -- [Android Plugin for Gradle 3.0.0](https://developer.android.com/studio/build/gradle-plugin-3-0-0.html) -- [Kotlin 1.2-M2](https://blog.jetbrains.com/kotlin/2017/08/kotlin-1-2-m2-is-out/) +- [Android Plugin for Gradle 7.0.2](https://developer.android.com/studio/releases/gradle-plugin#7-0-0) +- [Kotlin 1.5.20](https://blog.jetbrains.com/kotlin/2021/06/kotlin-1-5-20-released/) ## Import Kotlin Samples into Android Studio diff --git a/kotlin/add-features-feature-service/src/main/java/com/esri/arcgisruntime/sample/addfeaturesfeatureservice/MainActivity.kt b/kotlin/add-features-feature-service/src/main/java/com/esri/arcgisruntime/sample/addfeaturesfeatureservice/MainActivity.kt index 6bc79048c7..76b6914a77 100644 --- a/kotlin/add-features-feature-service/src/main/java/com/esri/arcgisruntime/sample/addfeaturesfeatureservice/MainActivity.kt +++ b/kotlin/add-features-feature-service/src/main/java/com/esri/arcgisruntime/sample/addfeaturesfeatureservice/MainActivity.kt @@ -25,6 +25,7 @@ import androidx.appcompat.app.AppCompatActivity import com.esri.arcgisruntime.ArcGISRuntimeEnvironment import com.esri.arcgisruntime.ArcGISRuntimeException import com.esri.arcgisruntime.data.ServiceFeatureTable +import com.esri.arcgisruntime.data.ServiceGeodatabase import com.esri.arcgisruntime.geometry.Point import com.esri.arcgisruntime.layers.FeatureLayer import com.esri.arcgisruntime.mapping.ArcGISMap @@ -36,132 +37,132 @@ import com.esri.arcgisruntime.sample.addfeaturesfeatureservice.databinding.Activ class MainActivity : AppCompatActivity() { - private val activityMainBinding by lazy { - ActivityMainBinding.inflate(layoutInflater) - } - - private val mapView: MapView by lazy { - activityMainBinding.mapView - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(activityMainBinding.root) - - // authentication with an API key or named user is required to access basemaps and other - // location services - ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY) - - // create a map with streets basemap - ArcGISMap(BasemapStyle.ARCGIS_STREETS).let { map -> - - // create service feature table from URL - ServiceFeatureTable(getString(R.string.service_layer_url)).let { serviceFeatureTable -> - - // add a listener to the MapView to detect when a user has performed a single tap to add a new feature to - // the service feature table - mapView.onTouchListener = object : DefaultMapViewOnTouchListener(this, mapView) { - override fun onSingleTapConfirmed(motionEvent: MotionEvent?): Boolean { - motionEvent?.let { event -> - // create a point from where the user clicked - android.graphics.Point(event.x.toInt(), event.y.toInt()).let { point -> - // create a map point from a point - mapView.screenToLocation(point) - }.let { mapPoint -> - // add a new feature to the service feature table - addFeature(mapPoint, serviceFeatureTable) - } + private val activityMainBinding by lazy { + ActivityMainBinding.inflate(layoutInflater) + } + + private val mapView: MapView by lazy { + activityMainBinding.mapView + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(activityMainBinding.root) + + // authentication with an API key or named user is required to access basemaps and other + // location services + ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY) + + // create a map with streets basemap + ArcGISMap(BasemapStyle.ARCGIS_STREETS).let { map -> + // create and load the service geodatabase + ServiceGeodatabase(getString(R.string.service_layer_url)).apply { + loadAsync() + addDoneLoadingListener { + // create a feature layer using the first layer in the geodatabase + val serviceFeatureTable = getTable(0) + // add a listener to the MapView to detect when a user has performed a single tap to add a new feature to + // the service feature table + mapView.onTouchListener = + object : DefaultMapViewOnTouchListener(this@MainActivity, mapView) { + override fun onSingleTapConfirmed(motionEvent: MotionEvent?): Boolean { + motionEvent?.let { event -> + // create a point from where the user clicked + android.graphics.Point(event.x.toInt(), event.y.toInt()) + .let { point -> + // create a map point from a point + mapView.screenToLocation(point) + }.let { mapPoint -> + // add a new feature to the service feature table + addFeature(mapPoint, serviceFeatureTable) + } + } + return super.onSingleTapConfirmed(motionEvent) + } + } + // create a feature layer from table + val featureLayer = FeatureLayer(serviceFeatureTable) + // add the layer to the map + map.operationalLayers.add(featureLayer) + } } - return super.onSingleTapConfirmed(motionEvent) - } + // set map to be displayed in map view + mapView.map = map + + // set an initial view point + mapView.setViewpoint(Viewpoint(40.0, -95.0, 10000000.0)) } + } - // create a feature layer from table - FeatureLayer(serviceFeatureTable) - }.let { featureLayer -> + /** + * Adds a new Feature to a ServiceFeatureTable and applies the changes to the + * server. + * + * @param mapPoint location to add feature + * @param featureTable service feature table to add feature + */ + private fun addFeature(mapPoint: Point, featureTable: ServiceFeatureTable) { + // create default attributes for the feature + hashMapOf( + "typdamage" to "Destroyed", + "primcause" to "Earthquake" + ).let { attributes -> + // creates a new feature using default attributes and point + featureTable.createFeature(attributes, mapPoint) + }.let { feature -> + // check if feature can be added to feature table + if (featureTable.canAdd()) { + // add the new feature to the feature table and to server + featureTable.addFeatureAsync(feature).addDoneListener { applyEdits(featureTable) } + } else { + logToUser(true, getString(R.string.error_cannot_add_to_feature_table)) + } + } - // add the layer to the map - map.operationalLayers.add(featureLayer) - } + } - // set map to be displayed in map view - mapView.map = map + /** + * Sends any edits on the ServiceFeatureTable to the server. + * + * @param featureTable service feature table + */ + private fun applyEdits(featureTable: ServiceFeatureTable) { + + // apply the changes to the server + featureTable.serviceGeodatabase.applyEditsAsync().let { editResult -> + editResult.addDoneListener { + try { + editResult.get()?.let { edits -> + // check if the server edit was successful + edits.firstOrNull()?.let { + if (!it.editResult[0].hasCompletedWithErrors()) { + logToUser(false, getString(R.string.feature_added)) + } else { + it.editResult[0].error + } + } + } + } catch (e: ArcGISRuntimeException) { + logToUser(true, getString(R.string.error_applying_edits, e.cause?.message)) + } + } + } + } - // set an initial view point - mapView.setViewpoint(Viewpoint(40.0, -95.0, 10000000.0)) + override fun onResume() { + super.onResume() + mapView.resume() } - } - - /** - * Adds a new Feature to a ServiceFeatureTable and applies the changes to the - * server. - * - * @param mapPoint location to add feature - * @param featureTable service feature table to add feature - */ - private fun addFeature(mapPoint: Point, featureTable: ServiceFeatureTable) { - - // create default attributes for the feature - hashMapOf( - "typdamage" to "Destroyed", - "primcause" to "Earthquake" - ).let { attributes -> - // creates a new feature using default attributes and point - featureTable.createFeature(attributes, mapPoint) - }.let { feature -> - // check if feature can be added to feature table - if (featureTable.canAdd()) { - // add the new feature to the feature table and to server - featureTable.addFeatureAsync(feature).addDoneListener { applyEdits(featureTable) } - } else { - logToUser(true, getString(R.string.error_cannot_add_to_feature_table)) - } + + override fun onPause() { + mapView.pause() + super.onPause() } - } - - /** - * Sends any edits on the ServiceFeatureTable to the server. - * - * @param featureTable service feature table - */ - private fun applyEdits(featureTable: ServiceFeatureTable) { - - // apply the changes to the server - featureTable.applyEditsAsync().let { editResult -> - editResult.addDoneListener { - try { - editResult.get()?.let { edits -> - // check if the server edit was successful - edits.firstOrNull()?.let { - if (!it.hasCompletedWithErrors()) { - logToUser(false, getString(R.string.feature_added)) - } else { - it.error - } - } - } - } catch (e: ArcGISRuntimeException) { - logToUser(true, getString(R.string.error_applying_edits, e.cause?.message)) - } - } + override fun onDestroy() { + mapView.dispose() + super.onDestroy() } - } - - override fun onResume() { - super.onResume() - mapView.resume() - } - - override fun onPause() { - mapView.pause() - super.onPause() - } - - override fun onDestroy() { - mapView.dispose() - super.onDestroy() - } } /* @@ -175,10 +176,10 @@ class MainActivity : AppCompatActivity() { * @param message message to display */ fun AppCompatActivity.logToUser(isError: Boolean, message: String) { - Toast.makeText(this, message, Toast.LENGTH_LONG).show() - if (isError) { - Log.e(this::class.java.simpleName, message) - } else { - Log.d(this::class.java.simpleName, message) - } + Toast.makeText(this, message, Toast.LENGTH_LONG).show() + if (isError) { + Log.e(this::class.java.simpleName, message) + } else { + Log.d(this::class.java.simpleName, message) + } } diff --git a/kotlin/add-features-feature-service/src/main/res/values/strings.xml b/kotlin/add-features-feature-service/src/main/res/values/strings.xml index c9ef1a14e5..34ea1e7a4e 100644 --- a/kotlin/add-features-feature-service/src/main/res/values/strings.xml +++ b/kotlin/add-features-feature-service/src/main/res/values/strings.xml @@ -1,7 +1,7 @@ Add Features - Feature Service - https://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/FeatureServer/0 + https://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/FeatureServer Feature successfully added Cannot add a feature to this feature table diff --git a/java/service-feature-table-cache/.gitignore b/kotlin/add-features-with-contingent-values/.gitignore similarity index 100% rename from java/service-feature-table-cache/.gitignore rename to kotlin/add-features-with-contingent-values/.gitignore diff --git a/kotlin/add-features-with-contingent-values/README.md b/kotlin/add-features-with-contingent-values/README.md new file mode 100644 index 0000000000..f5600930f9 --- /dev/null +++ b/kotlin/add-features-with-contingent-values/README.md @@ -0,0 +1,72 @@ +# Add features with contingent values + +Create and add features whose attribute values satisfy a predefined set of contingencies. + +![Add features with contingent values](add-features-with-contingent-values.png) ![Add contingent feature](add-contingent-feature.png) + +## Use case + +Contingent values are a data design feature that allow you to make values in one field dependent on values in another field. Your choice for a value on one field further constrains the domain values that can be placed on another field. In this way, contingent values enforce data integrity by applying additional constraints to reduce the number of valid field inputs. + +For example, a field crew working in a sensitive habitat area may be required to stay a certain distance away from occupied bird nests, but the size of that exclusion area differs depending on the bird's level of protection according to presiding laws. Surveyors can add points of bird nests in the work area and their selection of the size of the exclusion area will be contingent on the values in other attribute fields. + +## How to use the sample + +Tap on the map to add a feature symbolizing a bird's nest. Then choose values describing the nest's status, protection, and buffer size. Notice how different values are available depending on the values of preceding fields. Once the contingent values are validated, tap "Done" to add the feature to the map. + +## How it works + +1. Create and load the `Geodatabase` from the mobile geodatabase location on file. +2. Load the first `GeodatabaseFeatureTables` as an `ArcGISFeatureTable`. +3. Load the `ContingentValuesDefinition` from the feature table. +4. Create a new `FeatureLayer` from the feature table and add it to the map. +5. Create a new `ArcGISFeature` using `ArcGISFeature.createFeature()` +6. Get the first field by name using `ArcGISFeatureTable.fields.find{ }`. +7. Then get the `Field.domain` as an `CodedValueDomain`. +8. Get the coded value domain's `codedValues` to get an array of `CodedValue`'s. +9. After selecting a value from the initial coded values for the first field, retrieve the remaining valid contingent values for each field as you select the values for the attributes. + i. Get the `ContingentValueResult`s by using `ArcGISFeatureTable.getContingentValues(ArcGISFeature, "field_name")` with the feature and the target field by name. + ii. Get an array of valid `ContingentValues` from `ContingentValuesResult.contingentValuesByFieldGroup` dictionary with the name of the relevant field group. + iii. Iterate through the array of valid contingent values to create an array of `ContingentCodedValue` names or the minimum and maximum values of a `ContingentRangeValue` depending on the type of `ContingentValue` returned. +10. Validate the feature's contingent values by using `validateContingencyConstraints(feature)` with the current feature. If the resulting array is empty, the selected values are valid. + +## Relevant API + +* ArcGISFeatureTable +* CodedValue +* CodedValueDomain +* ContingencyConstraintViolation +* ContingentCodedValue +* ContingentRangeValue +* ContingentValuesDefinition +* ContingentValuesResult + +## Offline data + +This sample uses the [Contingent values birds nests](https://arcgis.com/home/item.html?id=e12b54ea799f4606a2712157cf9f6e41) mobile geodatabase and the [Fillmore topographic map](https://arcgis.com/home/item.html?id=b5106355f1634b8996e634c04b6a930a) vector tile package for the basemap. + +1. Download the mobile geodatabase from [ArcGIS Online](https://arcgis.com/home/item.html?id=e12b54ea799f4606a2712157cf9f6e41). +2. Download the vector tile package from [ArcGIS Online](https://arcgis.com/home/item.html?id=b5106355f1634b8996e634c04b6a930a). +3. Open your command prompt and navigate to the folder where you extracted the contents of the data from step 1. +4. Execute the following command: +`adb push FillmoreTopographicMap.vtpk /Android/data/com.esri.arcgisruntime.sample.addfeatureswithcontingentvalues/files/FillmoreTopographicMap.vtpk` +5. Execute the following command: +`adb push ContingentValuesBirdNests.geodatabase /Android/data/com.esri.arcgisruntime.sample.addfeatureswithcontingentvalues/files/ContingentValuesBirdNests.geodatabase` + +Link | Local Location +:-------------------------:|:-------------------------: +|[FillmoreTopographicMap.vtpk](https://arcgisruntime.maps.arcgis.com/home/item.html?id=e12b54ea799f4606a2712157cf9f6e41) | ``/Android/data/com.esri.arcgisruntime.sample.addfeatureswithcontingentvalues/files/FillmoreTopographicMap.vtpk +|[ContingentValuesBirdNests.geodatabase](https://arcgisruntime.maps.arcgis.com/home/item.html?id=b5106355f1634b8996e634c04b6a930a) | ``/Android/data/com.esri.arcgisruntime.sample.addfeatureswithcontingentvalues/files/ContingentValuesBirdNests.geodatabase + + +## About the data + +The mobile geodatabase contains birds nests in the Fillmore area, defined with contingent values. Each feature contains information about its status, protection, and buffer size. + +## Additional information + +Learn more about contingent values and how to utilize them on the [ArcGIS Pro documentation](https://pro.arcgis.com/en/pro-app/latest/help/data/geodatabases/overview/contingent-values.htm). + +## Tags + +coded values, contingent values, feature table, geodatabase diff --git a/kotlin/add-features-with-contingent-values/README.metadata.json b/kotlin/add-features-with-contingent-values/README.metadata.json new file mode 100644 index 0000000000..2f31c8b309 --- /dev/null +++ b/kotlin/add-features-with-contingent-values/README.metadata.json @@ -0,0 +1,46 @@ +{ + "category": "Edit & Manage Data", + "description": "Create and add features whose attribute values satisfy a predefined set of contingencies.", + "formal_name": "AddFeaturesWithContingentValues", + "ignore": false, + "images": [ + "add-features-with-contingent-values.png" + ], + "keywords": [ + "coded values", + "contingent values", + "feature table", + "geodatabase", + "ArcGISFeatureTable", + "CodedValue", + "CodedValueDomain", + "ContingencyConstraintViolation", + "ContingentCodedValue", + "ContingentRangeValue", + "ContingentValuesDefinition", + "ContingentValuesResult" + ], + "language": "kotlin", + "provision_from": [ + "https://www.arcgis.com/home/item.html?id=e12b54ea799f4606a2712157cf9f6e41", + "https://www.arcgis.com/home/item.html?id=b5106355f1634b8996e634c04b6a930a" + ], + "provision_to": [ + "/ContingentValuesBirdNests.geodatabase", + "/FillmoreTopographicMap.vtpk" + ], + "relevant_apis": [ + "ArcGISFeatureTable", + "CodedValue", + "CodedValueDomain", + "ContingencyConstraintViolation", + "ContingentCodedValue", + "ContingentRangeValue", + "ContingentValuesDefinition", + "ContingentValuesResult" + ], + "snippets": [ + "src/main/java/com/esri/arcgisruntime/sample/addfeatureswithcontingentvalues/MainActivity.kt" + ], + "title": "Add features with contingent values" +} diff --git a/kotlin/add-features-with-contingent-values/add-contingent-feature.png b/kotlin/add-features-with-contingent-values/add-contingent-feature.png new file mode 100644 index 0000000000..a4c44157f2 Binary files /dev/null and b/kotlin/add-features-with-contingent-values/add-contingent-feature.png differ diff --git a/kotlin/add-features-with-contingent-values/add-features-with-contingent-values.png b/kotlin/add-features-with-contingent-values/add-features-with-contingent-values.png new file mode 100644 index 0000000000..095140cb86 Binary files /dev/null and b/kotlin/add-features-with-contingent-values/add-features-with-contingent-values.png differ diff --git a/java/service-feature-table-no-cache/build.gradle b/kotlin/add-features-with-contingent-values/build.gradle similarity index 60% rename from java/service-feature-table-no-cache/build.gradle rename to kotlin/add-features-with-contingent-values/build.gradle index 695bcf6362..ba49ae62fa 100644 --- a/java/service-feature-table-no-cache/build.gradle +++ b/kotlin/add-features-with-contingent-values/build.gradle @@ -1,24 +1,32 @@ apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' android { compileSdkVersion rootProject.ext.compileSdkVersion defaultConfig { - applicationId "com.esri.arcgisruntime.samples.servicefeaturetablenocache" + applicationId "com.esri.arcgisruntime.sample.addfeatureswithcontingentvalues" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode rootProject.ext.versionCode versionName rootProject.ext.versionName buildConfigField("String", "API_KEY", API_KEY) } + buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + + buildFeatures { + viewBinding true + } } dependencies { - // arcgis-android & appcompat lib dependencies from rootProject build.gradle + // lib dependencies from rootProject build.gradle + implementation "androidx.constraintlayout:constraintlayout:$constraintLayoutVersion" + implementation "com.google.android.material:material:$materialVersion" } diff --git a/kotlin/add-features-with-contingent-values/proguard-rules.pro b/kotlin/add-features-with-contingent-values/proguard-rules.pro new file mode 100644 index 0000000000..f1b424510d --- /dev/null +++ b/kotlin/add-features-with-contingent-values/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/java/service-feature-table-manual-cache/src/main/AndroidManifest.xml b/kotlin/add-features-with-contingent-values/src/main/AndroidManifest.xml similarity index 81% rename from java/service-feature-table-manual-cache/src/main/AndroidManifest.xml rename to kotlin/add-features-with-contingent-values/src/main/AndroidManifest.xml index 66cbca943e..20288789d8 100644 --- a/java/service-feature-table-manual-cache/src/main/AndroidManifest.xml +++ b/kotlin/add-features-with-contingent-values/src/main/AndroidManifest.xml @@ -1,17 +1,15 @@ + package="com.esri.arcgisruntime.sample.addfeatureswithcontingentvalues"> - - - diff --git a/kotlin/add-features-with-contingent-values/src/main/java/com/esri/arcgisruntime/sample/addfeatureswithcontingentvalues/MainActivity.kt b/kotlin/add-features-with-contingent-values/src/main/java/com/esri/arcgisruntime/sample/addfeatureswithcontingentvalues/MainActivity.kt new file mode 100644 index 0000000000..f760e2a24c --- /dev/null +++ b/kotlin/add-features-with-contingent-values/src/main/java/com/esri/arcgisruntime/sample/addfeatureswithcontingentvalues/MainActivity.kt @@ -0,0 +1,470 @@ +/* Copyright 2022 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.arcgisruntime.sample.addfeatureswithcontingentvalues + +import android.graphics.Color +import android.os.Bundle +import android.util.Log +import android.view.MotionEvent +import android.view.ViewGroup +import android.widget.ArrayAdapter +import android.widget.AutoCompleteTextView +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import com.esri.arcgisruntime.ArcGISRuntimeEnvironment +import com.esri.arcgisruntime.data.ArcGISFeature +import com.esri.arcgisruntime.data.ArcGISFeatureTable +import com.esri.arcgisruntime.data.CodedValue +import com.esri.arcgisruntime.data.CodedValueDomain +import com.esri.arcgisruntime.data.ContingentCodedValue +import com.esri.arcgisruntime.data.ContingentRangeValue +import com.esri.arcgisruntime.data.Feature +import com.esri.arcgisruntime.data.Geodatabase +import com.esri.arcgisruntime.data.QueryParameters +import com.esri.arcgisruntime.geometry.GeometryEngine +import com.esri.arcgisruntime.geometry.Point +import com.esri.arcgisruntime.layers.ArcGISVectorTiledLayer +import com.esri.arcgisruntime.layers.FeatureLayer +import com.esri.arcgisruntime.loadable.LoadStatus +import com.esri.arcgisruntime.mapping.ArcGISMap +import com.esri.arcgisruntime.mapping.Basemap +import com.esri.arcgisruntime.mapping.Viewpoint +import com.esri.arcgisruntime.mapping.view.DefaultMapViewOnTouchListener +import com.esri.arcgisruntime.mapping.view.Graphic +import com.esri.arcgisruntime.mapping.view.GraphicsOverlay +import com.esri.arcgisruntime.mapping.view.MapView +import com.esri.arcgisruntime.sample.addfeatureswithcontingentvalues.databinding.ActivityMainBinding +import com.esri.arcgisruntime.sample.addfeatureswithcontingentvalues.databinding.AddFeatureLayoutBinding +import com.esri.arcgisruntime.symbology.SimpleFillSymbol +import com.esri.arcgisruntime.symbology.SimpleLineSymbol +import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol +import com.google.android.material.bottomsheet.BottomSheetBehavior +import com.google.android.material.bottomsheet.BottomSheetDialog +import java.io.File + +class MainActivity : AppCompatActivity() { + + private val TAG: String = MainActivity::class.java.simpleName + + private val activityMainBinding by lazy { + ActivityMainBinding.inflate(layoutInflater) + } + + private val bottomSheetBinding by lazy { + AddFeatureLayoutBinding.inflate(layoutInflater) + } + + private val mapView: MapView by lazy { + activityMainBinding.mapView + } + + // graphic overlay instance to add the feature graphic to the map + private val graphicsOverlay = GraphicsOverlay() + + // mobile database containing offline feature data. GeoDatabase is closed on app exit + private var geoDatabase: Geodatabase? = null + + // instance of the contingent feature to be added to the map + private var feature: ArcGISFeature? = null + + // instance of the feature table retrieved from the GeoDatabase, updates when new feature is added + private var featureTable: ArcGISFeatureTable? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(activityMainBinding.root) + + // authentication with an API key or named user is required to access basemaps and other location services + ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY) + + // create a temporary directory to use the geodatabase file + createGeodatabaseCacheDirectory() + + // use the offline vector tiled layer as a basemap + val fillmoreVectorTiledLayer = ArcGISVectorTiledLayer( + getExternalFilesDir(null)?.path + "/FillmoreTopographicMap.vtpk" + ) + mapView.apply { + // set the basemap layer and the graphic overlay to the MapView + map = ArcGISMap(Basemap(fillmoreVectorTiledLayer)) + graphicsOverlays.add(graphicsOverlay) + + // add a listener to the MapView to detect when a user has performed a single tap to add a new feature + onTouchListener = object : DefaultMapViewOnTouchListener(this@MainActivity, this) { + override fun onSingleTapConfirmed(motionEvent: MotionEvent?): Boolean { + motionEvent?.let { event -> + // create a point from where the user clicked + android.graphics.Point(event.x.toInt(), event.y.toInt()).let { point -> + // create a map point and add a new feature to the service feature table + openBottomSheetView(screenToLocation(point)) + } + } + performClick() + return super.onSingleTapConfirmed(motionEvent) + } + } + } + + // retrieve and load the offline mobile GeoDatabase file from the cache directory + geoDatabase = Geodatabase(cacheDir.path + "/ContingentValuesBirdNests.geodatabase") + geoDatabase?.loadAsync() + geoDatabase?.addDoneLoadingListener { + if (geoDatabase?.loadStatus == LoadStatus.LOADED) { + (geoDatabase?.geodatabaseFeatureTables?.first() as? ArcGISFeatureTable)?.let { featureTable -> + this.featureTable = featureTable + featureTable.loadAsync() + featureTable.addDoneLoadingListener { + // create and load the feature layer from the feature table + val featureLayer = FeatureLayer(featureTable) + // add the feature layer to the map + mapView.map.operationalLayers.add(featureLayer) + // set the map's viewpoint to the feature layer's full extent + val extent = featureLayer.fullExtent + mapView.setViewpoint(Viewpoint(extent)) + // add buffer graphics for the feature layer + queryFeatures() + } + } + + } else { + val error = "Error loading GeoDatabase: " + geoDatabase?.loadError?.message + Toast.makeText(this, error, Toast.LENGTH_SHORT).show() + Log.e(TAG, error) + } + } + } + + /** + * Geodatabase creates and uses various temporary files while processing a database, + * which will need to be cleared before looking up the [geoDatabase] again. A copy of the original geodatabase + * file is created in the cache folder. + */ + private fun createGeodatabaseCacheDirectory() { + try{ + // clear cache directory + File(cacheDir.path).deleteRecursively() + // copy over the original Geodatabase file to be used in the temp cache directory + File(getExternalFilesDir(null)?.path + "/ContingentValuesBirdNests.geodatabase").copyTo( + File(cacheDir.path + "/ContingentValuesBirdNests.geodatabase") + ) + }catch (e: Exception){ + val message = "Error setting .geodatabase file: " + e.message + Log.e(TAG, message) + Toast.makeText(this, message, Toast.LENGTH_SHORT).show() + } + } + + /** + * Create buffer graphics for the features and adds the graphics to + * the [graphicsOverlay] + */ + private fun queryFeatures() { + // create buffer graphics for the features + val queryParameters = QueryParameters().apply { + // set the where clause to filter for buffer sizes greater than 0 + whereClause = "BufferSize > 0" + } + // query the features using the queryParameters on the featureTable + val queryFeaturesFuture = featureTable?.queryFeaturesAsync(queryParameters) + queryFeaturesFuture?.addDoneListener { + try { + // clear the existing graphics + graphicsOverlay.graphics.clear() + // call get on the future to get the result + val resultIterator = queryFeaturesFuture.get().iterator() + if (resultIterator.hasNext()) { + // create an array of graphics to add to the graphics overlay + val graphics = mutableListOf() + // create graphic for each query result by calling createGraphic(feature) + //while (resultIterator.hasNext()) graphics.add(createGraphic(resultIterator.next())) + queryFeaturesFuture.get().iterator().forEach { + graphics.add(createGraphic(it)) + } + // add the graphics to the graphics overlay + graphicsOverlay.graphics.addAll(graphics) + } else { + val message = "No features found with BufferSize > 0" + Toast.makeText(this, message, Toast.LENGTH_LONG).show() + Log.d(TAG, message) + } + } catch (e: Exception) { + val message = "Error querying features: " + e.message + Log.e(TAG, message) + Toast.makeText(this, message, Toast.LENGTH_SHORT).show() + } + } + } + + /** + * Create a graphic for the given [feature] and returns a Graphic with the features attributes + */ + private fun createGraphic(feature: Feature): Graphic { + // get the feature's buffer size + val bufferSize = feature.attributes["BufferSize"] as Int + // get a polygon using the feature's buffer size and geometry + val polygon = GeometryEngine.buffer(feature.geometry, bufferSize.toDouble()) + // create the outline for the buffers + val lineSymbol = SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.BLACK, 2F) + // create the buffer symbol + val bufferSymbol = SimpleFillSymbol( + SimpleFillSymbol.Style.FORWARD_DIAGONAL, Color.RED, lineSymbol + ) + // create an a graphic and add it to the array. + return Graphic(polygon, bufferSymbol) + } + + /** + * Open BottomSheetDialog view to handle contingent value interaction. + * Once the contingent values have been set and the apply button is clicked, + * the function will call validateContingency() to add the feature to the map. + */ + private fun openBottomSheetView(mapPoint: Point) { + // creates a new BottomSheetDialog + val dialog = BottomSheetDialog(this) + dialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED + + // set up the first content value attribute + setUpStatusAttributes() + + bottomSheetBinding.apply { + // reset bottom sheet values, this is needed to showcase contingent values behavior + statusInputLayout.editText?.setText("") + protectionInputLayout.editText?.setText("") + selectedBuffer.text = "" + protectionInputLayout.isEnabled = false + bufferSeekBar.isEnabled = false + bufferSeekBar.value = bufferSeekBar.valueFrom + + // set apply button to validate and apply contingency feature on map + applyTv.setOnClickListener { + // check if the contingent features set is valid and set it to the map if valid + validateContingency(mapPoint) + dialog.dismiss() + } + // dismiss on cancel clicked + cancelTv.setOnClickListener { dialog.dismiss() } + } + // clear and set bottom sheet content view to layout, to be able to set the content view on each bottom sheet draw + if (bottomSheetBinding.root.parent != null) { + (bottomSheetBinding.root.parent as ViewGroup).removeAllViews() + } + // set the content view to the root of the binding layout + dialog.setContentView(bottomSheetBinding.root) + // display the bottom sheet view + dialog.show() + } + + /** + * Retrieve the status fields, add the fields to a ContingentValueDomain, and set the values to the spinner + * When status attribute selected, createFeature() is called. + */ + private fun setUpStatusAttributes() { + // get the first field by name + val statusField = featureTable?.fields?.find { field -> field.name.equals("Status") } + // get the field's domains as coded value domain + val codedValueDomain = statusField?.domain as CodedValueDomain + // get the coded value domain's coded values + val statusCodedValues = codedValueDomain.codedValues + // get the selected index if applicable + val statusNames = mutableListOf() + statusCodedValues.forEach { + statusNames.add(it.name) + } + // get the items to be added to the spinner adapter + val adapter = ArrayAdapter(bottomSheetBinding.root.context, R.layout.list_item, statusNames) + (bottomSheetBinding.statusInputLayout.editText as? AutoCompleteTextView)?.apply { + setAdapter(adapter) + setOnItemClickListener { _, _, position, _ -> + // get the CodedValue of the item selected, and create a feature needed for feature attributes + createFeature(statusCodedValues[position]) + } + } + } + + /** + * Set up the [feature] using the status attribute's coded value + * by loading the [featureTable]'s Contingent Value Definition. + * This function calls setUpProtectionAttributes() once the [feature] has been set + */ + private fun createFeature(codedValue: CodedValue) { + // get the contingent values definition from the feature table + val contingentValueDefinition = featureTable?.contingentValuesDefinition + if (contingentValueDefinition != null) { + // load the contingent values definition + contingentValueDefinition.loadAsync() + contingentValueDefinition.addDoneLoadingListener { + // create a feature from the feature table and set the initial attribute + feature = featureTable?.createFeature() as ArcGISFeature + feature?.attributes?.set("Status", codedValue.code) + setUpProtectionAttributes() + } + } else { + val message = "Error retrieving ContingentValuesDefinition from the FeatureTable" + Toast.makeText(this, message, Toast.LENGTH_SHORT).show() + Log.e(TAG, message) + } + } + + /** + * Retrieve the protection attribute fields, add the fields to a ContingentCodedValue, and set the values to the spinner + * When status attribute selected, showBufferSeekbar() is called. + */ + private fun setUpProtectionAttributes() { + // set the bottom sheet view to enable the Protection attribute, and disable input elsewhere + bottomSheetBinding.apply { + protectionInputLayout.isEnabled = true + bufferSeekBar.isEnabled = false + bufferSeekBar.value = bufferSeekBar.valueFrom + protectionInputLayout.editText?.setText("") + selectedBuffer.text = "" + } + + // get the contingent value results with the feature for the protection field + val contingentValuesResult = featureTable?.getContingentValues(feature, "Protection") + if (contingentValuesResult != null) { + // get contingent coded values by field group + // convert the list of ContingentValues to a list of CodedValue + val protectionCodedValues = mutableListOf() + contingentValuesResult.contingentValuesByFieldGroup["ProtectionFieldGroup"]?.forEach { contingentValue -> + protectionCodedValues.add((contingentValue as ContingentCodedValue).codedValue) + } + // set the items to be added to the spinner adapter + val adapter = ArrayAdapter( + bottomSheetBinding.root.context, + R.layout.list_item, + protectionCodedValues.map { it.name }) + (bottomSheetBinding.protectionInputLayout.editText as? AutoCompleteTextView)?.apply { + setAdapter(adapter) + setOnItemClickListener { _, _, position, _ -> + // set the protection CodedValue of the item selected, and then enable buffer seekbar + feature?.attributes?.set("Protection", protectionCodedValues[position].code) + showBufferSeekbar() + } + } + } else { + val message = "Error loading ContingentValuesResult from the FeatureTable" + Log.e(TAG, message) + Toast.makeText(this, message, Toast.LENGTH_SHORT).show() + } + } + + /** + * Retrieve the buffer attribute fields, add the fields to a ContingentRangeValue, + * and set the values to a SeekBar + */ + private fun showBufferSeekbar() { + // set the bottom sheet view to enable the buffer attribute + bottomSheetBinding.apply { + bufferSeekBar.isEnabled = true + selectedBuffer.text = "" + } + + // get the contingent value results using the feature and field + val contingentValueResult = featureTable?.getContingentValues(feature, "BufferSize") + val bufferSizeGroupContingentValues = + (contingentValueResult?.contingentValuesByFieldGroup?.get("BufferSizeFieldGroup")?.get(0) as ContingentRangeValue) + // set the minimum and maximum possible buffer sizes + val minValue = bufferSizeGroupContingentValues.minValue as Int + val maxValue = bufferSizeGroupContingentValues.maxValue as Int + // check if there can be a max value, if not disable SeekBar & set value to attribute size to 0 + if (maxValue > 0) { + // get SeekBar instance from the binding layout + bottomSheetBinding.bufferSeekBar.apply { + // set the min, max and current value of the SeekBar + valueFrom = minValue.toFloat() + valueTo = maxValue.toFloat() + value = valueFrom + // set the initial attribute and the text to the min of the ContingentRangeValue + feature?.attributes?.set("BufferSize", value.toInt()) + bottomSheetBinding.selectedBuffer.text = value.toInt().toString() + // set the change listener to update the attribute value and the displayed value to the SeekBar position + addOnChangeListener { _, value, _ -> + feature?.attributes?.set("BufferSize", value.toInt()) + bottomSheetBinding.selectedBuffer.text = value.toInt().toString() + } + } + } else { + // max value is 0, so disable seekbar and update the attribute value accordingly + bottomSheetBinding.apply { + bufferSeekBar.isEnabled = false + selectedBuffer.text = "0" + } + feature?.attributes?.set("BufferSize", 0) + } + } + + /** + * Ensure that the selected values are a valid combination. + * If contingencies are valid, then display [feature] on the [mapPoint] + */ + private fun validateContingency(mapPoint: Point) { + // check if all the features have been set + if (featureTable == null) { + val message = "Input all values to add a feature to the map" + Toast.makeText(this, message, Toast.LENGTH_SHORT).show() + Log.e(TAG, message) + return + } + + try { + // validate the feature's contingencies + val contingencyViolations = featureTable?.validateContingencyConstraints(feature) + if (contingencyViolations?.isEmpty() == true) { + // if there are no contingency violations in the array, + // the feature is valid and ready to add to the feature table + // create a symbol to represent a bird's nest + val symbol = SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, Color.BLACK, 11F) + // add the graphic to the graphics overlay + graphicsOverlay.graphics.add(Graphic(mapPoint, symbol)) + feature?.geometry = mapPoint + val graphic = feature?.let { createGraphic(it) } + // add the feature to the feature table + featureTable?.addFeatureAsync(feature) + featureTable?.addDoneLoadingListener { + // add the graphic to the graphics overlay + graphicsOverlay.graphics.add(graphic) + } + } else { + val message = "Invalid contingent values: " + (contingencyViolations?.size?: 0) + " violations found." + Toast.makeText(this, message, Toast.LENGTH_SHORT).show() + Log.e(TAG, message) + } + } catch (e: Exception) { + val message = "Invalid contingent values: " + e.message + Toast.makeText(this, message, Toast.LENGTH_SHORT).show() + Log.e(TAG, message) + } + } + + override fun onPause() { + mapView.pause() + super.onPause() + } + + override fun onResume() { + super.onResume() + mapView.resume() + } + + override fun onDestroy() { + mapView.dispose() + // closing the GeoDatabase will commit the transactions made to the temporary ".geodatabase" file + // then removes the temporary ".geodatabase-wal" and ".geodatabase-shm" files from the cache dir + geoDatabase?.close() + super.onDestroy() + } +} diff --git a/kotlin/add-features-with-contingent-values/src/main/res/drawable-v24/ic_launcher_foreground.xml b/kotlin/add-features-with-contingent-values/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000000..c7bd21dbd8 --- /dev/null +++ b/kotlin/add-features-with-contingent-values/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/kotlin/add-features-with-contingent-values/src/main/res/drawable/ic_launcher_background.xml b/kotlin/add-features-with-contingent-values/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000000..6d8cae1033 --- /dev/null +++ b/kotlin/add-features-with-contingent-values/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kotlin/add-features-with-contingent-values/src/main/res/layout/activity_main.xml b/kotlin/add-features-with-contingent-values/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000000..842b0c537c --- /dev/null +++ b/kotlin/add-features-with-contingent-values/src/main/res/layout/activity_main.xml @@ -0,0 +1,7 @@ + + diff --git a/kotlin/add-features-with-contingent-values/src/main/res/layout/add_feature_layout.xml b/kotlin/add-features-with-contingent-values/src/main/res/layout/add_feature_layout.xml new file mode 100644 index 0000000000..ae370a4c53 --- /dev/null +++ b/kotlin/add-features-with-contingent-values/src/main/res/layout/add_feature_layout.xml @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kotlin/add-features-with-contingent-values/src/main/res/layout/list_item.xml b/kotlin/add-features-with-contingent-values/src/main/res/layout/list_item.xml new file mode 100644 index 0000000000..a52f61631e --- /dev/null +++ b/kotlin/add-features-with-contingent-values/src/main/res/layout/list_item.xml @@ -0,0 +1,8 @@ + diff --git a/kotlin/add-features-with-contingent-values/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000000..6b78462d61 --- /dev/null +++ b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/kotlin/add-features-with-contingent-values/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000000..6b78462d61 --- /dev/null +++ b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/kotlin/add-features-with-contingent-values/src/main/res/mipmap-hdpi/ic_launcher.png b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000..a2f5908281 Binary files /dev/null and b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/kotlin/add-features-with-contingent-values/src/main/res/mipmap-hdpi/ic_launcher_round.png b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000000..1b52399808 Binary files /dev/null and b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/kotlin/add-features-with-contingent-values/src/main/res/mipmap-mdpi/ic_launcher.png b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000..ff10afd6e1 Binary files /dev/null and b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/kotlin/add-features-with-contingent-values/src/main/res/mipmap-mdpi/ic_launcher_round.png b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000000..115a4c768a Binary files /dev/null and b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/kotlin/add-features-with-contingent-values/src/main/res/mipmap-xhdpi/ic_launcher.png b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000000..dcd3cd8083 Binary files /dev/null and b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/kotlin/add-features-with-contingent-values/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000000..459ca609d3 Binary files /dev/null and b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/kotlin/add-features-with-contingent-values/src/main/res/mipmap-xxhdpi/ic_launcher.png b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000..8ca12fe024 Binary files /dev/null and b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/kotlin/add-features-with-contingent-values/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000000..8e19b410a1 Binary files /dev/null and b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/kotlin/add-features-with-contingent-values/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000..b824ebdd48 Binary files /dev/null and b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/kotlin/add-features-with-contingent-values/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000000..4c19a13c23 Binary files /dev/null and b/kotlin/add-features-with-contingent-values/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/java/service-feature-table-cache/src/main/res/values/colors.xml b/kotlin/add-features-with-contingent-values/src/main/res/values/colors.xml similarity index 65% rename from java/service-feature-table-cache/src/main/res/values/colors.xml rename to kotlin/add-features-with-contingent-values/src/main/res/values/colors.xml index 36f5fca4f2..3cfd32ed02 100644 --- a/java/service-feature-table-cache/src/main/res/values/colors.xml +++ b/kotlin/add-features-with-contingent-values/src/main/res/values/colors.xml @@ -3,4 +3,6 @@ #2196F3 #1976D2 #4CAF50 - \ No newline at end of file + #FF6200EE + #FFFFFFFF + diff --git a/kotlin/add-features-with-contingent-values/src/main/res/values/strings.xml b/kotlin/add-features-with-contingent-values/src/main/res/values/strings.xml new file mode 100644 index 0000000000..61b9c5372a --- /dev/null +++ b/kotlin/add-features-with-contingent-values/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ + + Add features with contingent values + The options will vary depending on which values are selected + diff --git a/java/service-feature-table-no-cache/src/main/res/values/styles.xml b/kotlin/add-features-with-contingent-values/src/main/res/values/styles.xml similarity index 52% rename from java/service-feature-table-no-cache/src/main/res/values/styles.xml rename to kotlin/add-features-with-contingent-values/src/main/res/values/styles.xml index 5885930df6..0e990a01fd 100644 --- a/java/service-feature-table-no-cache/src/main/res/values/styles.xml +++ b/kotlin/add-features-with-contingent-values/src/main/res/values/styles.xml @@ -1,11 +1,15 @@ - + + diff --git a/kotlin/add-graphics-renderer/src/main/java/com/esri/arcgisruntime/sample/addgraphicsrenderer/MainActivity.kt b/kotlin/add-graphics-renderer/src/main/java/com/esri/arcgisruntime/sample/addgraphicsrenderer/MainActivity.kt index 7644b896ae..267dd4cf8d 100644 --- a/kotlin/add-graphics-renderer/src/main/java/com/esri/arcgisruntime/sample/addgraphicsrenderer/MainActivity.kt +++ b/kotlin/add-graphics-renderer/src/main/java/com/esri/arcgisruntime/sample/addgraphicsrenderer/MainActivity.kt @@ -74,12 +74,13 @@ class MainActivity : AppCompatActivity() { // add graphics overlays mapView.graphicsOverlays.addAll( - arrayOf( - renderedPointGraphicsOverlay(), - renderedLineGraphicsOverlay(), - renderedPolygonGraphicsOverlay(), - renderedCurvedPolygonGraphicsOverlay(), - renderedEllipseGraphicsOverlay()) + arrayOf( + renderedPointGraphicsOverlay(), + renderedLineGraphicsOverlay(), + renderedPolygonGraphicsOverlay(), + renderedCurvedPolygonGraphicsOverlay(), + renderedEllipseGraphicsOverlay() + ) ) } @@ -200,7 +201,8 @@ class MainActivity : AppCompatActivity() { val polygonGraphic = Graphic(curvedPolygonGeometry) // create a simple fill symbol with outline val curvedLineSymbol = SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.BLACK, 1f) - val curvedFillSymbol = SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, Color.RED, curvedLineSymbol) + val curvedFillSymbol = + SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, Color.RED, curvedLineSymbol) // create simple renderer val polygonRenderer = SimpleRenderer(curvedFillSymbol) @@ -280,7 +282,9 @@ class MainActivity : AppCompatActivity() { add(rightCurve) } return Polygon(heart, spatialReference) - }override fun onPause() { + } + + override fun onPause() { mapView.pause() super.onPause() } diff --git a/kotlin/add-graphics-renderer/src/main/res/layout/activity_main.xml b/kotlin/add-graphics-renderer/src/main/res/layout/activity_main.xml index 09e942c766..7800a8af33 100644 --- a/kotlin/add-graphics-renderer/src/main/res/layout/activity_main.xml +++ b/kotlin/add-graphics-renderer/src/main/res/layout/activity_main.xml @@ -1,12 +1,12 @@ - + android:layout_height="match_parent" /> \ No newline at end of file diff --git a/kotlin/add-graphics-with-symbols/src/main/java/com/esri/arcgisruntime/sample/addgraphicswithsymbols/MainActivity.kt b/kotlin/add-graphics-with-symbols/src/main/java/com/esri/arcgisruntime/sample/addgraphicswithsymbols/MainActivity.kt index 73b709ca2a..f4c12eba95 100644 --- a/kotlin/add-graphics-with-symbols/src/main/java/com/esri/arcgisruntime/sample/addgraphicswithsymbols/MainActivity.kt +++ b/kotlin/add-graphics-with-symbols/src/main/java/com/esri/arcgisruntime/sample/addgraphicswithsymbols/MainActivity.kt @@ -36,268 +36,268 @@ import com.esri.arcgisruntime.symbology.TextSymbol class MainActivity : AppCompatActivity() { - private val activityMainBinding by lazy { - ActivityMainBinding.inflate(layoutInflater) - } + private val activityMainBinding by lazy { + ActivityMainBinding.inflate(layoutInflater) + } + + private val mapView: MapView by lazy { + activityMainBinding.mapView + } + + private val wgs84 = SpatialReferences.getWgs84() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(activityMainBinding.root) + + // authentication with an API key or named user is required to access basemaps and other + // location services + ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY) + + // create the graphics overlay + val graphicsOverlay = GraphicsOverlay() + + mapView.apply { + // create a map with the BasemapStyle Oceans and display it in this view + map = ArcGISMap(BasemapStyle.ARCGIS_OCEANS) + setViewpoint(Viewpoint(56.075844, -2.681572, 100000.0)) + // add the overlay to the map view + graphicsOverlays.add(graphicsOverlay) + } - private val mapView: MapView by lazy { - activityMainBinding.mapView - } + // add some buoy positions to the graphics overlay + val buoyPoints = createBuoyGraphics() + graphicsOverlay.graphics.addAll(buoyPoints) - private val wgs84 = SpatialReferences.getWgs84() + // add boat trip polyline to graphics overlay + val tripRouteGraphic = createRoute() + graphicsOverlay.graphics.add(tripRouteGraphic) - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(activityMainBinding.root) + // add nesting ground polygon to graphics overlay + val nestingGround = createNestingGround() + graphicsOverlay.graphics.add(nestingGround) - // authentication with an API key or named user is required to access basemaps and other - // location services - ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY) + // add text symbols and points to graphics overlay + val textGraphics = createTextGraphics() + graphicsOverlay.graphics.addAll(textGraphics) + } + + /** + * Create Graphics for some points. + * + * @return a new graphic + */ + private fun createBuoyGraphics(): Array { + // define the buoy locations + val buoy1Loc = Point(-2.712642647560347, 56.06281256681154, wgs84) + val buoy2Loc = Point(-2.690841695957230, 56.06444173689877, wgs84) + val buoy3Loc = Point(-2.669727388499094, 56.06425007340287, wgs84) + val buoy4Loc = Point(-2.639515046119973, 56.06127916736989, wgs84) + + // create a marker symbol + val buoyMarker = + SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, Color.RED, 10.0f) + + // create graphics + return arrayOf( + Graphic(buoy1Loc, buoyMarker), + Graphic(buoy2Loc, buoyMarker), + Graphic(buoy3Loc, buoyMarker), + Graphic(buoy4Loc, buoyMarker) + ) + } - // create the graphics overlay - val graphicsOverlay = GraphicsOverlay() + /** + * Create graphics which display text at specific locations. + * + * @return a new graphic + */ + private fun createTextGraphics(): Array { + // create a point geometry + val bassLocation = + Point(-2.640631, 56.078083, wgs84) + val craigleithLocation = + Point(-2.720324, 56.073569, wgs84) + + // create text symbols + val bassRockSymbol = TextSymbol( + 10.0f, getString(R.string.bassrock), Color.rgb(0, 0, 230), + TextSymbol.HorizontalAlignment.LEFT, TextSymbol.VerticalAlignment.BOTTOM + ) + val craigleithSymbol = TextSymbol( + 10.0f, getString(R.string.craigleith), Color.rgb(0, 0, 230), + TextSymbol.HorizontalAlignment.RIGHT, TextSymbol.VerticalAlignment.TOP + ) + + // define graphics from each geometry and symbol + val bassRockGraphic = Graphic(bassLocation, bassRockSymbol) + val craigleithGraphic = Graphic(craigleithLocation, craigleithSymbol) + + return arrayOf(bassRockGraphic, craigleithGraphic) + } - mapView.apply { - // create a map with the BasemapType Oceans and display it in this view - map = ArcGISMap(BasemapStyle.ARCGIS_OCEANS) - setViewpoint(Viewpoint(56.075844, -2.681572, 100000.0)) - // add the overlay to the map view - graphicsOverlays.add(graphicsOverlay) + /** + * Create a graphic which displays a polyline. + * + * @return a new graphic + */ + private fun createRoute(): Graphic { + // define a polyline for the boat trip + val boatRoute: Polyline = getBoatTripGeometry() + // define a line symbol + val lineSymbol = + SimpleLineSymbol(SimpleLineSymbol.Style.DASH, Color.rgb(128, 0, 128), 4.0f) + + // create and return a new graphic + return Graphic(boatRoute, lineSymbol) } - // add some buoy positions to the graphics overlay - val buoyPoints = createBuoyGraphics() - graphicsOverlay.graphics.addAll(buoyPoints) - - // add boat trip polyline to graphics overlay - val tripRouteGraphic = createRoute() - graphicsOverlay.graphics.add(tripRouteGraphic) - - // add nesting ground polygon to graphics overlay - val nestingGround = createNestingGround() - graphicsOverlay.graphics.add(nestingGround) - - // add text symbols and points to graphics overlay - val textGraphics = createTextGraphics() - graphicsOverlay.graphics.addAll(textGraphics) - } - - /** - * Create Graphics for some points. - * - * @return a new graphic - */ - private fun createBuoyGraphics(): Array { - // define the buoy locations - val buoy1Loc = Point(-2.712642647560347, 56.06281256681154, wgs84) - val buoy2Loc = Point(-2.690841695957230, 56.06444173689877, wgs84) - val buoy3Loc = Point(-2.669727388499094, 56.06425007340287, wgs84) - val buoy4Loc = Point(-2.639515046119973, 56.06127916736989, wgs84) - - // create a marker symbol - val buoyMarker = - SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, Color.RED, 10.0f) - - // create graphics - return arrayOf( - Graphic(buoy1Loc, buoyMarker), - Graphic(buoy2Loc, buoyMarker), - Graphic(buoy3Loc, buoyMarker), - Graphic(buoy4Loc, buoyMarker) - ) - } - - /** - * Create graphics which display text at specific locations. - * - * @return a new graphic - */ - private fun createTextGraphics(): Array { - // create a point geometry - val bassLocation = - Point(-2.640631, 56.078083, wgs84) - val craigleithLocation = - Point(-2.720324, 56.073569, wgs84) - - // create text symbols - val bassRockSymbol = TextSymbol( - 10.0f, getString(R.string.bassrock), Color.rgb(0, 0, 230), - TextSymbol.HorizontalAlignment.LEFT, TextSymbol.VerticalAlignment.BOTTOM - ) - val craigleithSymbol = TextSymbol( - 10.0f, getString(R.string.craigleith), Color.rgb(0, 0, 230), - TextSymbol.HorizontalAlignment.RIGHT, TextSymbol.VerticalAlignment.TOP - ) - - // define graphics from each geometry and symbol - val bassRockGraphic = Graphic(bassLocation, bassRockSymbol) - val craigleithGraphic = Graphic(craigleithLocation, craigleithSymbol) - - return arrayOf(bassRockGraphic, craigleithGraphic) - } - - /** - * Create a graphic which displays a polyline. - * - * @return a new graphic - */ - private fun createRoute(): Graphic { - // define a polyline for the boat trip - val boatRoute: Polyline = getBoatTripGeometry() - // define a line symbol - val lineSymbol = - SimpleLineSymbol(SimpleLineSymbol.Style.DASH, Color.rgb(128, 0, 128), 4.0f) - - // create and return a new graphic - return Graphic(boatRoute, lineSymbol) - } - - /** - * Create a graphic which displays a polygon. - * - * @return a new graphic - */ - private fun createNestingGround(): Graphic { - // define the polygon for the nesting ground - val nestingGround = getNestingGroundGeometry() - // define the fill symbol and outline - val outlineSymbol = - SimpleLineSymbol(SimpleLineSymbol.Style.DASH, Color.rgb(0, 0, 128), 1.0f) - val fillSymbol = SimpleFillSymbol( - SimpleFillSymbol.Style.DIAGONAL_CROSS, Color.rgb(0, 80, 0), - outlineSymbol - ) - - // create and return a new graphic - return Graphic(nestingGround, fillSymbol) - } - - /** - * Create a polyline representing the route of the boat trip. - * - * @return a new polyline - */ - private fun getBoatTripGeometry(): Polyline { - // a new point collection to make up the polyline - val boatPositions = PointCollection(wgs84).apply { - // add positions to the point collection - add(Point(-2.718479122792677, 56.06147084563517)) - add(Point(-2.719680750046392, 56.06147084563517)) - add(Point(-2.722084004553823, 56.06214171205971)) - add(Point(-2.726375530459948, 56.06386674355254)) - add(Point(-2.726890513568683, 56.06607083814320)) - add(Point(-2.727062174604927, 56.06779569383808)) - add(Point(-2.725517225278723, 56.06875391365391)) - add(Point(-2.723113970771293, 56.06942465335233)) - add(Point(-2.719165766937657, 56.07028701581465)) - add(Point(-2.713672613777817, 56.07057446568132)) - add(Point(-2.709381087871692, 56.07095772883556)) - add(Point(-2.704402917820587, 56.07153261642126)) - add(Point(-2.698223120515766, 56.07239493172226)) - add(Point(-2.692386645283435, 56.07325722773041)) - add(Point(-2.686721831087350, 56.07335303720707)) - add(Point(-2.681228677927500, 56.07354465544585)) - add(Point(-2.676422168912640, 56.07421531177896)) - add(Point(-2.669899049535339, 56.07488595644139)) - add(Point(-2.664749218447989, 56.07574819671591)) - add(Point(-2.659427726324393, 56.07613140842321)) - add(Point(-2.654792878345778, 56.07622721075461)) - add(Point(-2.651359657620878, 56.07651461631978)) - add(Point(-2.647754775859732, 56.07708942101955)) - add(Point(-2.645008199279812, 56.07814320736718)) - add(Point(-2.643291588917362, 56.08025069360931)) - add(Point(-2.638656740938747, 56.08044227755186)) - add(Point(-2.636940130576297, 56.07881378367495)) - add(Point(-2.636425147467562, 56.07728102068079)) - add(Point(-2.637798435757522, 56.07661041769850)) - add(Point(-2.638656740938747, 56.07507756705851)) - add(Point(-2.641231656482422, 56.07479015077557)) - add(Point(-2.642776605808628, 56.07574819671591)) - add(Point(-2.645694843424792, 56.07546078543464)) - add(Point(-2.647239792750997, 56.07459853872940)) - add(Point(-2.649299725185938, 56.07268236586862)) - add(Point(-2.653076267983328, 56.07182005699860)) - add(Point(-2.655479522490758, 56.07086191340429)) - add(Point(-2.658741082179413, 56.07047864929729)) - add(Point(-2.663375930158029, 56.07028701581465)) - add(Point(-2.666637489846684, 56.07009538137926)) - add(Point(-2.670070710571584, 56.06990374599109)) - add(Point(-2.674190575441464, 56.06913719491074)) - add(Point(-2.678310440311345, 56.06808316228391)) - add(Point(-2.682086983108735, 56.06789151689155)) - add(Point(-2.686893492123596, 56.06760404701653)) - add(Point(-2.691185018029721, 56.06722075051504)) - add(Point(-2.695133221863356, 56.06702910083509)) - add(Point(-2.698223120515766, 56.06683745020233)) - add(Point(-2.701656341240667, 56.06645414607839)) - add(Point(-2.706119528183037, 56.06607083814320)) - add(Point(-2.710067732016672, 56.06559169786458)) - add(Point(-2.713329291705327, 56.06520838135397)) - add(Point(-2.716762512430227, 56.06453756828941)) - add(Point(-2.718307461756433, 56.06348340989081)) - add(Point(-2.719165766937657, 56.06281256681154)) - add(Point(-2.719852411082638, 56.06204587471371)) - add(Point(-2.719165766937657, 56.06166252294756)) - add(Point(-2.718307461756433, 56.06147084563517)) + /** + * Create a graphic which displays a polygon. + * + * @return a new graphic + */ + private fun createNestingGround(): Graphic { + // define the polygon for the nesting ground + val nestingGround = getNestingGroundGeometry() + // define the fill symbol and outline + val outlineSymbol = + SimpleLineSymbol(SimpleLineSymbol.Style.DASH, Color.rgb(0, 0, 128), 1.0f) + val fillSymbol = SimpleFillSymbol( + SimpleFillSymbol.Style.DIAGONAL_CROSS, Color.rgb(0, 80, 0), + outlineSymbol + ) + + // create and return a new graphic + return Graphic(nestingGround, fillSymbol) } - // create the polyline from the point collection - return Polyline(boatPositions) - } - - /** - * Create a polygon from a point collection. - * - * @return a new polygon - */ - private fun getNestingGroundGeometry(): Polygon { - // a new point collection to make up the polygon - val points = PointCollection(wgs84).apply { - // add points to the point collection - add(Point(-2.643077012566659, 56.07712534604447)) - add(Point(-2.642819521015944, 56.07717324600376)) - add(Point(-2.642540571836003, 56.07774804087097)) - add(Point(-2.642712232869812, 56.07792766250863)) - add(Point(-2.642454741319098, 56.07829887790651)) - add(Point(-2.641853927700763, 56.07852639525372)) - add(Point(-2.640974164902487, 56.07880180919243)) - add(Point(-2.639987113958079, 56.07881378366685)) - add(Point(-2.639407757968971, 56.07908919555142)) - add(Point(-2.638764029092183, 56.07917301616904)) - add(Point(-2.638485079912242, 56.07896945149566)) - add(Point(-2.638570910429147, 56.07820308072684)) - add(Point(-2.638785486721410, 56.07756841839600)) - add(Point(-2.639193181676709, 56.07719719596109)) - add(Point(-2.639944198699627, 56.07675411934114)) - add(Point(-2.640652300464093, 56.07673016910844)) - add(Point(-2.640673758093319, 56.07632301287509)) - add(Point(-2.640180232621116, 56.07599967986049)) - add(Point(-2.640244605508794, 56.07584400003405)) - add(Point(-2.640416266542604, 56.07578412301025)) - add(Point(-2.640888334385582, 56.07580807383093)) - add(Point(-2.641768097183858, 56.07623918605773)) - add(Point(-2.642197249768383, 56.07625116132851)) - add(Point(-2.642840978645171, 56.07661041772168)) - add(Point(-2.643077012566659, 56.07712534604447)) + /** + * Create a polyline representing the route of the boat trip. + * + * @return a new polyline + */ + private fun getBoatTripGeometry(): Polyline { + // a new point collection to make up the polyline + val boatPositions = PointCollection(wgs84).apply { + // add positions to the point collection + add(Point(-2.718479122792677, 56.06147084563517)) + add(Point(-2.719680750046392, 56.06147084563517)) + add(Point(-2.722084004553823, 56.06214171205971)) + add(Point(-2.726375530459948, 56.06386674355254)) + add(Point(-2.726890513568683, 56.06607083814320)) + add(Point(-2.727062174604927, 56.06779569383808)) + add(Point(-2.725517225278723, 56.06875391365391)) + add(Point(-2.723113970771293, 56.06942465335233)) + add(Point(-2.719165766937657, 56.07028701581465)) + add(Point(-2.713672613777817, 56.07057446568132)) + add(Point(-2.709381087871692, 56.07095772883556)) + add(Point(-2.704402917820587, 56.07153261642126)) + add(Point(-2.698223120515766, 56.07239493172226)) + add(Point(-2.692386645283435, 56.07325722773041)) + add(Point(-2.686721831087350, 56.07335303720707)) + add(Point(-2.681228677927500, 56.07354465544585)) + add(Point(-2.676422168912640, 56.07421531177896)) + add(Point(-2.669899049535339, 56.07488595644139)) + add(Point(-2.664749218447989, 56.07574819671591)) + add(Point(-2.659427726324393, 56.07613140842321)) + add(Point(-2.654792878345778, 56.07622721075461)) + add(Point(-2.651359657620878, 56.07651461631978)) + add(Point(-2.647754775859732, 56.07708942101955)) + add(Point(-2.645008199279812, 56.07814320736718)) + add(Point(-2.643291588917362, 56.08025069360931)) + add(Point(-2.638656740938747, 56.08044227755186)) + add(Point(-2.636940130576297, 56.07881378367495)) + add(Point(-2.636425147467562, 56.07728102068079)) + add(Point(-2.637798435757522, 56.07661041769850)) + add(Point(-2.638656740938747, 56.07507756705851)) + add(Point(-2.641231656482422, 56.07479015077557)) + add(Point(-2.642776605808628, 56.07574819671591)) + add(Point(-2.645694843424792, 56.07546078543464)) + add(Point(-2.647239792750997, 56.07459853872940)) + add(Point(-2.649299725185938, 56.07268236586862)) + add(Point(-2.653076267983328, 56.07182005699860)) + add(Point(-2.655479522490758, 56.07086191340429)) + add(Point(-2.658741082179413, 56.07047864929729)) + add(Point(-2.663375930158029, 56.07028701581465)) + add(Point(-2.666637489846684, 56.07009538137926)) + add(Point(-2.670070710571584, 56.06990374599109)) + add(Point(-2.674190575441464, 56.06913719491074)) + add(Point(-2.678310440311345, 56.06808316228391)) + add(Point(-2.682086983108735, 56.06789151689155)) + add(Point(-2.686893492123596, 56.06760404701653)) + add(Point(-2.691185018029721, 56.06722075051504)) + add(Point(-2.695133221863356, 56.06702910083509)) + add(Point(-2.698223120515766, 56.06683745020233)) + add(Point(-2.701656341240667, 56.06645414607839)) + add(Point(-2.706119528183037, 56.06607083814320)) + add(Point(-2.710067732016672, 56.06559169786458)) + add(Point(-2.713329291705327, 56.06520838135397)) + add(Point(-2.716762512430227, 56.06453756828941)) + add(Point(-2.718307461756433, 56.06348340989081)) + add(Point(-2.719165766937657, 56.06281256681154)) + add(Point(-2.719852411082638, 56.06204587471371)) + add(Point(-2.719165766937657, 56.06166252294756)) + add(Point(-2.718307461756433, 56.06147084563517)) + } + + // create the polyline from the point collection + return Polyline(boatPositions) } - // create a polygon from the point collection - return Polygon(points) - } + /** + * Create a polygon from a point collection. + * + * @return a new polygon + */ + private fun getNestingGroundGeometry(): Polygon { + // a new point collection to make up the polygon + val points = PointCollection(wgs84).apply { + // add points to the point collection + add(Point(-2.643077012566659, 56.07712534604447)) + add(Point(-2.642819521015944, 56.07717324600376)) + add(Point(-2.642540571836003, 56.07774804087097)) + add(Point(-2.642712232869812, 56.07792766250863)) + add(Point(-2.642454741319098, 56.07829887790651)) + add(Point(-2.641853927700763, 56.07852639525372)) + add(Point(-2.640974164902487, 56.07880180919243)) + add(Point(-2.639987113958079, 56.07881378366685)) + add(Point(-2.639407757968971, 56.07908919555142)) + add(Point(-2.638764029092183, 56.07917301616904)) + add(Point(-2.638485079912242, 56.07896945149566)) + add(Point(-2.638570910429147, 56.07820308072684)) + add(Point(-2.638785486721410, 56.07756841839600)) + add(Point(-2.639193181676709, 56.07719719596109)) + add(Point(-2.639944198699627, 56.07675411934114)) + add(Point(-2.640652300464093, 56.07673016910844)) + add(Point(-2.640673758093319, 56.07632301287509)) + add(Point(-2.640180232621116, 56.07599967986049)) + add(Point(-2.640244605508794, 56.07584400003405)) + add(Point(-2.640416266542604, 56.07578412301025)) + add(Point(-2.640888334385582, 56.07580807383093)) + add(Point(-2.641768097183858, 56.07623918605773)) + add(Point(-2.642197249768383, 56.07625116132851)) + add(Point(-2.642840978645171, 56.07661041772168)) + add(Point(-2.643077012566659, 56.07712534604447)) + } + + // create a polygon from the point collection + return Polygon(points) + } - override fun onResume() { - super.onResume() - mapView.resume() - } + override fun onResume() { + super.onResume() + mapView.resume() + } - override fun onPause() { - mapView.pause() - super.onPause() - } + override fun onPause() { + mapView.pause() + super.onPause() + } - override fun onDestroy() { - mapView.dispose() - super.onDestroy() - } + override fun onDestroy() { + mapView.dispose() + super.onDestroy() + } } diff --git a/kotlin/analyze-hotspots/src/main/java/com/esri/arcgisruntime/sample/analyzehotspots/MainActivity.kt b/kotlin/analyze-hotspots/src/main/java/com/esri/arcgisruntime/sample/analyzehotspots/MainActivity.kt index 8d4479b8fc..83680219a1 100644 --- a/kotlin/analyze-hotspots/src/main/java/com/esri/arcgisruntime/sample/analyzehotspots/MainActivity.kt +++ b/kotlin/analyze-hotspots/src/main/java/com/esri/arcgisruntime/sample/analyzehotspots/MainActivity.kt @@ -42,228 +42,229 @@ import java.util.* // enum to flag whether the date picker calendar shown should be for the 'from' or 'to' date enum class InputCalendar { - From, To + From, To } class MainActivity : AppCompatActivity() { - private val activityMainBinding by lazy { - ActivityMainBinding.inflate(layoutInflater) - } + private val activityMainBinding by lazy { + ActivityMainBinding.inflate(layoutInflater) + } - private val mapView: MapView by lazy { - activityMainBinding.mapView - } + private val mapView: MapView by lazy { + activityMainBinding.mapView + } - private val calendarButton: FloatingActionButton by lazy { - activityMainBinding.calendarButton - } + private val calendarButton: FloatingActionButton by lazy { + activityMainBinding.calendarButton + } - private val TAG = this::class.java.simpleName + private val TAG = this::class.java.simpleName - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(activityMainBinding.root) + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(activityMainBinding.root) - // authentication with an API key or named user is required to access basemaps and other - // location services - ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY) + // authentication with an API key or named user is required to access basemaps and other + // location services + ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY) - // create a map with the BasemapType topographic - val map = ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC) - // set the map to the map view - mapView.map = map - mapView.setViewpoint( - Viewpoint( - Point(-13671170.0, 5693633.0, SpatialReference.create(3857)), - 57779.0 - ) - ) - - calendarButton.setOnClickListener { - showDateRangeDialog() - } + // create a map with the BasemapStyle topographic + val map = ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC) - showDateRangeDialog() - } - - /** - * Creates the date range dialog. Includes listeners to handle click events, - * which call showCalendar(...) or analyzeHotspots(...). - */ - private fun showDateRangeDialog() { - val geoprocessingTask = GeoprocessingTask(getString(R.string.hotspot_911_calls)) - - val dateRangeDialogBinding = DateRangeDialogBinding.inflate(layoutInflater) - // create custom dialog - Dialog(this).apply { - setContentView(dateRangeDialogBinding.root) - setCancelable(true) - - dateRangeDialogBinding.fromDateText.setOnClickListener { - showCalendar(dateRangeDialogBinding, InputCalendar.From) - } - - dateRangeDialogBinding.toDateText.setOnClickListener { - showCalendar(dateRangeDialogBinding, InputCalendar.To) - } - - dateRangeDialogBinding.analyzeButton.setOnClickListener { - analyzeHotspots( - geoprocessingTask, - dateRangeDialogBinding.fromDateText.text.toString(), - dateRangeDialogBinding.toDateText.text.toString() + // set the map to the map view + mapView.map = map + mapView.setViewpoint( + Viewpoint( + Point(-13671170.0, 5693633.0, SpatialReference.create(3857)), + 57779.0 + ) ) - dismiss() - } - }.show() - } - - /** - * Shows a date picker dialog and writes the date chosen to the correct editable text. - * - * @param inputCalendar enum which specifies which editable text the chosen date should be written to - */ - private fun showCalendar( - dateRangeDialogBinding: DateRangeDialogBinding, - inputCalendar: InputCalendar - ) { - - // define the date picker dialog - val calendar = Calendar.getInstance() - val year = calendar.get(Calendar.YEAR) - val month = calendar.get(Calendar.MONTH) - val day = calendar.get(Calendar.DAY_OF_MONTH) - - DatePickerDialog(this, { _, year, monthOfYear, dayOfMonth -> - - val dateString = StringBuilder() - .append(year) - .append("-") - .append(monthOfYear + 1) - .append("-") - .append(dayOfMonth) - - when (inputCalendar) { - InputCalendar.From -> { - dateRangeDialogBinding.fromDateText.setText(dateString) - } - InputCalendar.To -> { - dateRangeDialogBinding.toDateText.setText(dateString) - } - } - }, year, month, day).apply { - datePicker.minDate = parseDate(getString(R.string.min_date))!!.time - datePicker.maxDate = parseDate(getString(R.string.max_date))!!.time - if (inputCalendar == InputCalendar.From) { - updateDate(1998, 0, 1) - } - }.show() - } - - /** - * Runs the geoprocessing job, updating progress while loading. On job done, loads the resulting - * ArcGISMapImageLayer to the map and resets the Viewpoint of the MapView. - * - * @param geoprocessingTask Geoprocessing task to generate hotspots - * @param from string which holds a date - * @param to string which holds a date - */ - private fun analyzeHotspots(geoprocessingTask: GeoprocessingTask, from: String, to: String) { - geoprocessingTask.loadAsync() - - // a map image layer is generated as a result, clear previous results - mapView.map.operationalLayers.clear() - - // create parameters for geoprocessing job - val paramsFuture = geoprocessingTask.createDefaultParametersAsync() - paramsFuture.addDoneListener { - try { - val geoprocessingParameters = paramsFuture.get() - geoprocessingParameters.processSpatialReference = mapView.spatialReference - geoprocessingParameters.outputSpatialReference = mapView.spatialReference - - val queryString = StringBuilder("(\"DATE\" > date '") - .append(from) - .append(" 00:00:00' AND \"DATE\" < date '") - .append(to) - .append(" 00:00:00')") - - val geoprocessingString = GeoprocessingString(queryString.toString()) - geoprocessingParameters.inputs["Query"] = geoprocessingString - // create and start geoprocessing job - val geoprocessingJob = geoprocessingTask.createJob(geoprocessingParameters) - geoprocessingJob.start() - - // show progress - val progressDialog = ProgressDialog(this).apply { - setTitle(getString(R.string.app_name)) - setMessage(getString(R.string.dialog_text)) - setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) - show() - } - // update progress - geoprocessingJob.addProgressChangedListener { - val progress = geoprocessingJob.progress - progressDialog.progress = progress + calendarButton.setOnClickListener { + showDateRangeDialog() } - // when the job finishes - geoprocessingJob.addJobDoneListener { - // dismiss the dialog - progressDialog.dismiss() - - when (geoprocessingJob.status) { - Job.Status.SUCCEEDED -> { - // get results - val geoprocessingResult = geoprocessingJob.result - val hotspotMapImageLayer = geoprocessingResult.mapImageLayer - hotspotMapImageLayer.opacity = 0.5f - - // add new layer to map - mapView.map.operationalLayers.add(hotspotMapImageLayer) - - // zoom to the layer extent - hotspotMapImageLayer.addDoneLoadingListener { - mapView.setViewpointGeometryAsync(hotspotMapImageLayer.fullExtent) - } + showDateRangeDialog() + } + + /** + * Creates the date range dialog. Includes listeners to handle click events, + * which call showCalendar(...) or analyzeHotspots(...). + */ + private fun showDateRangeDialog() { + val geoprocessingTask = GeoprocessingTask(getString(R.string.hotspot_911_calls)) + + val dateRangeDialogBinding = DateRangeDialogBinding.inflate(layoutInflater) + // create custom dialog + Dialog(this).apply { + setContentView(dateRangeDialogBinding.root) + setCancelable(true) + + dateRangeDialogBinding.fromDateText.setOnClickListener { + showCalendar(dateRangeDialogBinding, InputCalendar.From) + } + + dateRangeDialogBinding.toDateText.setOnClickListener { + showCalendar(dateRangeDialogBinding, InputCalendar.To) + } + + dateRangeDialogBinding.analyzeButton.setOnClickListener { + analyzeHotspots( + geoprocessingTask, + dateRangeDialogBinding.fromDateText.text.toString(), + dateRangeDialogBinding.toDateText.text.toString() + ) + dismiss() + } + }.show() + } + + /** + * Shows a date picker dialog and writes the date chosen to the correct editable text. + * + * @param inputCalendar enum which specifies which editable text the chosen date should be written to + */ + private fun showCalendar( + dateRangeDialogBinding: DateRangeDialogBinding, + inputCalendar: InputCalendar + ) { + + // define the date picker dialog + val calendar = Calendar.getInstance() + val year = calendar.get(Calendar.YEAR) + val month = calendar.get(Calendar.MONTH) + val day = calendar.get(Calendar.DAY_OF_MONTH) + + DatePickerDialog(this, { _, year, monthOfYear, dayOfMonth -> + + val dateString = StringBuilder() + .append(year) + .append("-") + .append(monthOfYear + 1) + .append("-") + .append(dayOfMonth) + + when (inputCalendar) { + InputCalendar.From -> { + dateRangeDialogBinding.fromDateText.setText(dateString) + } + InputCalendar.To -> { + dateRangeDialogBinding.toDateText.setText(dateString) + } + } + }, year, month, day).apply { + datePicker.minDate = parseDate(getString(R.string.min_date))!!.time + datePicker.maxDate = parseDate(getString(R.string.max_date))!!.time + if (inputCalendar == InputCalendar.From) { + updateDate(1998, 0, 1) + } + }.show() + } + + /** + * Runs the geoprocessing job, updating progress while loading. On job done, loads the resulting + * ArcGISMapImageLayer to the map and resets the Viewpoint of the MapView. + * + * @param geoprocessingTask Geoprocessing task to generate hotspots + * @param from string which holds a date + * @param to string which holds a date + */ + private fun analyzeHotspots(geoprocessingTask: GeoprocessingTask, from: String, to: String) { + geoprocessingTask.loadAsync() + + // a map image layer is generated as a result, clear previous results + mapView.map.operationalLayers.clear() + + // create parameters for geoprocessing job + val paramsFuture = geoprocessingTask.createDefaultParametersAsync() + paramsFuture.addDoneListener { + try { + val geoprocessingParameters = paramsFuture.get() + geoprocessingParameters.processSpatialReference = mapView.spatialReference + geoprocessingParameters.outputSpatialReference = mapView.spatialReference + + val queryString = StringBuilder("(\"DATE\" > date '") + .append(from) + .append(" 00:00:00' AND \"DATE\" < date '") + .append(to) + .append(" 00:00:00')") + + val geoprocessingString = GeoprocessingString(queryString.toString()) + geoprocessingParameters.inputs["Query"] = geoprocessingString + // create and start geoprocessing job + val geoprocessingJob = geoprocessingTask.createJob(geoprocessingParameters) + geoprocessingJob.start() + + // show progress + val progressDialog = ProgressDialog(this).apply { + setTitle(getString(R.string.app_name)) + setMessage(getString(R.string.dialog_text)) + setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) + show() + } + + // update progress + geoprocessingJob.addProgressChangedListener { + val progress = geoprocessingJob.progress + progressDialog.progress = progress + } + + // when the job finishes + geoprocessingJob.addJobDoneListener { + // dismiss the dialog + progressDialog.dismiss() + + when (geoprocessingJob.status) { + Job.Status.SUCCEEDED -> { + // get results + val geoprocessingResult = geoprocessingJob.result + val hotspotMapImageLayer = geoprocessingResult.mapImageLayer + hotspotMapImageLayer.opacity = 0.5f + + // add new layer to map + mapView.map.operationalLayers.add(hotspotMapImageLayer) + + // zoom to the layer extent + hotspotMapImageLayer.addDoneLoadingListener { + mapView.setViewpointGeometryAsync(hotspotMapImageLayer.fullExtent) + } + } + else -> Toast.makeText( + this, + getString(R.string.job_failed), + Toast.LENGTH_LONG + ).show() + } + } + } catch (e: Exception) { + val error = "Error generating geoprocessing parameters: " + e.message + Toast.makeText(this, error, Toast.LENGTH_LONG).show() + Log.e(TAG, error) } - else -> Toast.makeText( - this, - getString(R.string.job_failed), - Toast.LENGTH_LONG - ).show() - } } - } catch (e: Exception) { - val error = "Error generating geoprocessing parameters: " + e.message - Toast.makeText(this, error, Toast.LENGTH_LONG).show() - Log.e(TAG, error) - } } - } - - /** - * Parse the date using a simple date format. - */ - private fun parseDate(date: String): Date? { - return SimpleDateFormat(getString(R.string.date_format), Locale.US).parse(date) - } - - override fun onPause() { - mapView.pause() - super.onPause() - } - - override fun onResume() { - super.onResume() - mapView.resume() - } - - override fun onDestroy() { - mapView.dispose() - super.onDestroy() - } + + /** + * Parse the date using a simple date format. + */ + private fun parseDate(date: String): Date? { + return SimpleDateFormat(getString(R.string.date_format), Locale.US).parse(date) + } + + override fun onPause() { + mapView.pause() + super.onPause() + } + + override fun onResume() { + super.onResume() + mapView.resume() + } + + override fun onDestroy() { + mapView.dispose() + super.onDestroy() + } } diff --git a/kotlin/animate-images-with-image-overlay/src/main/java/com/esri/arcgisruntime/sample/animateimageswithimageoverlay/MainActivity.kt b/kotlin/animate-images-with-image-overlay/src/main/java/com/esri/arcgisruntime/sample/animateimageswithimageoverlay/MainActivity.kt index ac7b1e8fcb..3cb7101917 100644 --- a/kotlin/animate-images-with-image-overlay/src/main/java/com/esri/arcgisruntime/sample/animateimageswithimageoverlay/MainActivity.kt +++ b/kotlin/animate-images-with-image-overlay/src/main/java/com/esri/arcgisruntime/sample/animateimageswithimageoverlay/MainActivity.kt @@ -122,16 +122,16 @@ class MainActivity : AppCompatActivity() { imageOverlays.add(ImageOverlay()) } - // get the image files from local storage as an unordered list - (File(getExternalFilesDir(null).toString() + "/PacificSouthWest").listFiles())?.let { imageFiles -> - // sort the list of image files - Arrays.sort(imageFiles) - imageFiles.forEach { file -> - // create an image with the given path and use it to create an image frame - val imageFrame = ImageFrame(file.path, pacificSouthwestEnvelope) - imageFrames.add(imageFrame) - } - } + // get the image files from local storage as an unordered list + (File(getExternalFilesDir(null).toString() + "/PacificSouthWest").listFiles())?.let { imageFiles -> + // sort the list of image files + Arrays.sort(imageFiles) + imageFiles.forEach { file -> + // create an image with the given path and use it to create an image frame + val imageFrame = ImageFrame(file.path, pacificSouthwestEnvelope) + imageFrames.add(imageFrame) + } + } // setup touch and ui element behaviours setupUI() @@ -192,13 +192,13 @@ class MainActivity : AppCompatActivity() { sceneView.apply { // create a touch listener setOnTouchListener(object : DefaultSceneViewOnTouchListener(sceneView) { - // close the options sheet when the map is tapped - override fun onTouch(view: View?, motionEvent: MotionEvent?): Boolean { - if (fab.isExpanded) { - fab.isExpanded = false + // close the options sheet when the map is tapped + override fun onTouch(view: View?, motionEvent: MotionEvent?): Boolean { + if (fab.isExpanded) { + fab.isExpanded = false + } + return super.onTouch(view, motionEvent) } - return super.onTouch(view, motionEvent) - } }) // ensure the floating action button moves to be above the attribution view addAttributionViewLayoutChangeListener { _, _, _, _, bottom, _, _, _, oldBottom -> @@ -214,38 +214,38 @@ class MainActivity : AppCompatActivity() { // seek bar controls image overlay opacity opacitySeekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { - override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { - // convert the seekbar progress (0 - 100) to a float 0.0 - 1.0 - val opacity: Float = progress.toFloat() / 100 - sceneView.imageOverlays[0].opacity = opacity - currOpacityTextView.text = opacity.toString() - } - - override fun onStartTrackingTouch(seekBar: SeekBar?) {} - override fun onStopTrackingTouch(seekBar: SeekBar?) {} + override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { + // convert the seekbar progress (0 - 100) to a float 0.0 - 1.0 + val opacity: Float = progress.toFloat() / 100 + sceneView.imageOverlays[0].opacity = opacity + currOpacityTextView.text = opacity.toString() + } + + override fun onStartTrackingTouch(seekBar: SeekBar?) {} + override fun onStopTrackingTouch(seekBar: SeekBar?) {} }) // spinner controls how many image overlays to display per second fpsSpinner.apply { // create an adapter with fps options adapter = ArrayAdapter( - this@MainActivity, - android.R.layout.simple_spinner_dropdown_item, - arrayOf("60 fps", "30 fps", "15 fps") + this@MainActivity, + android.R.layout.simple_spinner_dropdown_item, + arrayOf("60 fps", "30 fps", "15 fps") ) // set period based on the fps option selected onItemSelectedListener = object : AdapterView.OnItemSelectedListener { override fun onItemSelected( - parent: AdapterView<*>?, - view: View?, - position: Int, - id: Long + parent: AdapterView<*>?, + view: View?, + position: Int, + id: Long ) { // get the period for the chosen fps period = when (position) { - 0 -> 17 // 1000ms/17 = 60 fps - 1 -> 33 // 1000ms/33 = 30 fps - 2 -> 67 // 1000ms/67 = 15 fps + 0 -> 17 // 1000ms/17 = 60 fps + 1 -> 33 // 1000ms/33 = 30 fps + 2 -> 67 // 1000ms/67 = 15 fps else -> 0 } // create a new timer for this period diff --git a/kotlin/apply-mosaic-rule-to-rasters/src/main/java/com/esri/arcgisruntime/sample/applymosaicruletorasters/MainActivity.kt b/kotlin/apply-mosaic-rule-to-rasters/src/main/java/com/esri/arcgisruntime/sample/applymosaicruletorasters/MainActivity.kt index 464ed1b9fb..3351979b17 100644 --- a/kotlin/apply-mosaic-rule-to-rasters/src/main/java/com/esri/arcgisruntime/sample/applymosaicruletorasters/MainActivity.kt +++ b/kotlin/apply-mosaic-rule-to-rasters/src/main/java/com/esri/arcgisruntime/sample/applymosaicruletorasters/MainActivity.kt @@ -39,124 +39,129 @@ import com.esri.arcgisruntime.sample.applymosaicruletorasters.databinding.Activi class MainActivity : AppCompatActivity() { - private val TAG = MainActivity::class.java.simpleName + private val TAG = MainActivity::class.java.simpleName - private val activityMainBinding by lazy { - ActivityMainBinding.inflate(layoutInflater) - } - - private val mapView: MapView by lazy { - activityMainBinding.mapView - } - - private val spinner: Spinner by lazy { - activityMainBinding.spinner - } - - // create an image service raster from a url for an image service - private val imageServiceRaster: ImageServiceRaster by lazy { - ImageServiceRaster("https://sampleserver7.arcgisonline.com/server/rest/services/amberg_germany/ImageServer").apply { - // set its mosaic rule - if (mosaicRule == null) mosaicRule = MosaicRule() + private val activityMainBinding by lazy { + ActivityMainBinding.inflate(layoutInflater) } - } - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(activityMainBinding.root) - - // authentication with an API key or named user is required to access basemaps and other - // location services - ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY) + private val mapView: MapView by lazy { + activityMainBinding.mapView + } - // create a raster layer from the image service - val rasterLayer = RasterLayer(imageServiceRaster) - // add the raster layer to a new map on the map view - mapView.map = ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC).apply { - operationalLayers.add(rasterLayer) + private val spinner: Spinner by lazy { + activityMainBinding.spinner } - // listen for the raster layer to finish loading - rasterLayer.addDoneLoadingListener { - // if the raster layer didn't load - if (rasterLayer.loadStatus != LoadStatus.LOADED) { - rasterLayer.loadError?.let { error -> - Log.e(TAG, "Raster layer failed to load: ${error.cause}") + // create an image service raster from a url for an image service + private val imageServiceRaster: ImageServiceRaster by lazy { + ImageServiceRaster("https://sampleserver7.arcgisonline.com/server/rest/services/amberg_germany/ImageServer").apply { + // set its mosaic rule + if (mosaicRule == null) mosaicRule = MosaicRule() } - return@addDoneLoadingListener - } - // set the map's viewpoint to the raster extent - mapView.setViewpointAsync(Viewpoint(rasterLayer.fullExtent.center, 25000.0)) } - // set up the spinner with some predefined mosaic rules - ArrayAdapter.createFromResource( - this, - R.array.mosaic_rules, - android.R.layout.simple_spinner_item - ).also { adapter -> - adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) - spinner.adapter = adapter - } + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(activityMainBinding.root) - spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { - override fun onNothingSelected(parent: AdapterView<*>?) { - setMosaicRule("Default") - } + // authentication with an API key or named user is required to access basemaps and other + // location services + ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY) - override fun onItemSelected(parent: AdapterView<*>, view: View?, position: Int, id: Long) { - setMosaicRule(parent.getItemAtPosition(position) as String) - } - } - } - - /** - * Applies one of the predefined mosaic rules to the image service raster. - * - * @param ruleName one of "Default", "Northwest", "Center", "By attribute", and "Lock raster" - */ - private fun setMosaicRule(ruleName: String) { - imageServiceRaster.mosaicRule = MosaicRule().apply { - when (ruleName) { - "Default" -> { - mosaicMethod = MosaicMethod.NONE - } - "Northwest" -> { - mosaicMethod = MosaicMethod.NORTHWEST - mosaicOperation = MosaicOperation.FIRST + // create a raster layer from the image service + val rasterLayer = RasterLayer(imageServiceRaster) + // add the raster layer to a new map on the map view + mapView.map = ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC).apply { + operationalLayers.add(rasterLayer) } - "Center" -> { - mosaicMethod = MosaicMethod.CENTER - mosaicOperation = MosaicOperation.BLEND + + // listen for the raster layer to finish loading + rasterLayer.addDoneLoadingListener { + // if the raster layer didn't load + if (rasterLayer.loadStatus != LoadStatus.LOADED) { + rasterLayer.loadError?.let { error -> + Log.e(TAG, "Raster layer failed to load: ${error.cause}") + } + return@addDoneLoadingListener + } + // set the map's viewpoint to the raster extent + mapView.setViewpointAsync(Viewpoint(rasterLayer.fullExtent.center, 25000.0)) } - "By attribute" -> { - mosaicMethod = MosaicMethod.ATTRIBUTE - sortField = "OBJECTID" + + // set up the spinner with some predefined mosaic rules + ArrayAdapter.createFromResource( + this, + R.array.mosaic_rules, + android.R.layout.simple_spinner_item + ).also { adapter -> + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) + spinner.adapter = adapter } - "Lock raster" -> { - mosaicMethod = MosaicMethod.LOCK_RASTER - lockRasterIds.clear() - lockRasterIds.addAll(listOf(1, 7, 12)) + + spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onNothingSelected(parent: AdapterView<*>?) { + setMosaicRule("Default") + } + + override fun onItemSelected( + parent: AdapterView<*>, + view: View?, + position: Int, + id: Long + ) { + setMosaicRule(parent.getItemAtPosition(position) as String) + } } - else -> { - mosaicMethod = MosaicMethod.NONE + } + + /** + * Applies one of the predefined mosaic rules to the image service raster. + * + * @param ruleName one of "Default", "Northwest", "Center", "By attribute", and "Lock raster" + */ + private fun setMosaicRule(ruleName: String) { + imageServiceRaster.mosaicRule = MosaicRule().apply { + when (ruleName) { + "Default" -> { + mosaicMethod = MosaicMethod.NONE + } + "Northwest" -> { + mosaicMethod = MosaicMethod.NORTHWEST + mosaicOperation = MosaicOperation.FIRST + } + "Center" -> { + mosaicMethod = MosaicMethod.CENTER + mosaicOperation = MosaicOperation.BLEND + } + "By attribute" -> { + mosaicMethod = MosaicMethod.ATTRIBUTE + sortField = "OBJECTID" + } + "Lock raster" -> { + mosaicMethod = MosaicMethod.LOCK_RASTER + lockRasterIds.clear() + lockRasterIds.addAll(listOf(1, 7, 12)) + } + else -> { + mosaicMethod = MosaicMethod.NONE + } + } } - } } - } - - override fun onResume() { - super.onResume() - mapView.resume() - } - - override fun onPause() { - mapView.pause() - super.onPause() - } - - override fun onDestroy() { - mapView.dispose() - super.onDestroy() - } + + override fun onResume() { + super.onResume() + mapView.resume() + } + + override fun onPause() { + mapView.pause() + super.onPause() + } + + override fun onDestroy() { + mapView.dispose() + super.onDestroy() + } } diff --git a/kotlin/apply-mosaic-rule-to-rasters/src/main/res/drawable/ic_expand_more_black_24dp.xml b/kotlin/apply-mosaic-rule-to-rasters/src/main/res/drawable/ic_expand_more_black_24dp.xml index 8d57dbc10f..c1f391b617 100644 --- a/kotlin/apply-mosaic-rule-to-rasters/src/main/res/drawable/ic_expand_more_black_24dp.xml +++ b/kotlin/apply-mosaic-rule-to-rasters/src/main/res/drawable/ic_expand_more_black_24dp.xml @@ -1,9 +1,9 @@ + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + android:pathData="M16.59,8.59L12,13.17 7.41,8.59 6,10l6,6 6,-6z" /> diff --git a/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/custom1_color.xml b/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/custom1_color.xml index ad0842c95f..2d02c88743 100644 --- a/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/custom1_color.xml +++ b/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/custom1_color.xml @@ -1,17 +1,17 @@ - - - + + + - + + android:bottomRightRadius="7dp" /> \ No newline at end of file diff --git a/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/custom2_color.xml b/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/custom2_color.xml index 90c4186b50..97c9f18462 100644 --- a/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/custom2_color.xml +++ b/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/custom2_color.xml @@ -1,17 +1,17 @@ - - - - - - - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/default_color.xml b/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/default_color.xml index 0aa8c9c8d3..6c531f5ae2 100644 --- a/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/default_color.xml +++ b/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/default_color.xml @@ -1,17 +1,17 @@ - - - - - - - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/style1_color.xml b/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/style1_color.xml index ed2dac7980..2f527823a6 100644 --- a/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/style1_color.xml +++ b/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/style1_color.xml @@ -1,17 +1,17 @@ - - - - - - - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/style2_color.xml b/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/style2_color.xml index 39182e5fff..8aff43b719 100644 --- a/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/style2_color.xml +++ b/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/style2_color.xml @@ -1,17 +1,17 @@ - - - - - - - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/style3_color.xml b/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/style3_color.xml index b3b3b2817e..f1a0955a63 100644 --- a/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/style3_color.xml +++ b/kotlin/arcgis-vector-tiled-layer-custom-style/src/main/res/drawable/style3_color.xml @@ -1,17 +1,17 @@ - - - - - - - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/kotlin/attribution-view-change/src/main/java/com/esri/arcgisruntime/sample/attributionviewchange/MainActivity.kt b/kotlin/attribution-view-change/src/main/java/com/esri/arcgisruntime/sample/attributionviewchange/MainActivity.kt index 3184ae6098..49243d241a 100644 --- a/kotlin/attribution-view-change/src/main/java/com/esri/arcgisruntime/sample/attributionviewchange/MainActivity.kt +++ b/kotlin/attribution-view-change/src/main/java/com/esri/arcgisruntime/sample/attributionviewchange/MainActivity.kt @@ -29,62 +29,66 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton class MainActivity : AppCompatActivity() { - private val activityMainBinding by lazy { - ActivityMainBinding.inflate(layoutInflater) - } + private val activityMainBinding by lazy { + ActivityMainBinding.inflate(layoutInflater) + } - private val mapView: MapView by lazy { - activityMainBinding.mapView - } + private val mapView: MapView by lazy { + activityMainBinding.mapView + } - private val fab: FloatingActionButton by lazy { - activityMainBinding.fab - } + private val fab: FloatingActionButton by lazy { + activityMainBinding.fab + } - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(activityMainBinding.root) + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(activityMainBinding.root) - // authentication with an API key or named user is required to access basemaps and other - // location services - ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY) + // authentication with an API key or named user is required to access basemaps and other + // location services + ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY) - // create a map with the topographic basemap - val map = ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC) + // create a map with the topographic basemap + val map = ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC) - // set the map to be displayed in this view - mapView.map = map - mapView.setViewpoint(Viewpoint(47.495052, -121.786863, 100000.0)) + // set the map to be displayed in this view + mapView.map = map + mapView.setViewpoint(Viewpoint(47.495052, -121.786863, 100000.0)) - // create a FAB to respond to attribution bar - fab.setOnClickListener { - Toast.makeText(this@MainActivity, "Tap the attribution bar to expand it.", Toast.LENGTH_LONG).show() - } + // create a FAB to respond to attribution bar + fab.setOnClickListener { + Toast.makeText( + this@MainActivity, + "Tap the attribution bar to expand it.", + Toast.LENGTH_LONG + ).show() + } - // set attribution bar listener - mapView.addAttributionViewLayoutChangeListener { _, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom -> - val heightDelta = oldBottom - bottom - fab.y += heightDelta - Toast.makeText( - this@MainActivity, - "new bounds [$left,$top,$right,$bottom] old bounds [$oldLeft,$oldTop,$oldRight,$oldBottom]", - Toast.LENGTH_SHORT - ).show() + // set attribution bar listener + mapView.addAttributionViewLayoutChangeListener { _, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom -> + val heightDelta = oldBottom - bottom + fab.y += heightDelta + Toast.makeText( + this@MainActivity, + "new bounds [$left,$top,$right,$bottom] old bounds [$oldLeft,$oldTop,$oldRight,$oldBottom]", + Toast.LENGTH_SHORT + ).show() + } } - } - override fun onPause() { - super.onPause() - mapView.pause() - } + override fun onPause() { + super.onPause() + mapView.pause() + } - override fun onResume() { - super.onResume() - mapView.resume() - } + override fun onResume() { + super.onResume() + mapView.resume() + } - override fun onDestroy() { - super.onDestroy() - mapView.dispose() - } + override fun onDestroy() { + super.onDestroy() + mapView.dispose() + } } diff --git a/kotlin/attribution-view-change/src/main/res/layout/activity_main.xml b/kotlin/attribution-view-change/src/main/res/layout/activity_main.xml index 75c7e6689c..c4c619713a 100644 --- a/kotlin/attribution-view-change/src/main/res/layout/activity_main.xml +++ b/kotlin/attribution-view-change/src/main/res/layout/activity_main.xml @@ -9,7 +9,7 @@ + android:layout_height="match_parent" /> Redirect URIs - val oAuthConfiguration = OAuthConfiguration( - getString(R.string.portal_url), - getString(R.string.oauth_client_id), - getString(R.string.oauth_redirect_uri) + "://" + getString(R.string.oauth_redirect_host) - ) - - // setup AuthenticationManager to handle auth challenges - val defaultAuthenticationChallengeHandler = DefaultAuthenticationChallengeHandler(this) - - // use the DefaultChallengeHandler to handle authentication challenges - AuthenticationManager.setAuthenticationChallengeHandler( - defaultAuthenticationChallengeHandler - ) - - // add an OAuth configuration - // NOTE: you must add the DefaultOAuthIntentReceiver Activity to the app's manifest to handle starting a browser - AuthenticationManager.addOAuthConfiguration(oAuthConfiguration) - - // load the portal and add the portal item as a map to the map view - val portal = Portal(getString(R.string.portal_url)) - val portalItem = PortalItem(portal, getString(R.string.webmap_world_traffic_id)) - mapView.apply { - map = ArcGISMap(portalItem) - } - } catch (e: MalformedURLException) { - logError("Error in OAuthConfiguration URL: " + e.message) + private val activityMainBinding by lazy { + ActivityMainBinding.inflate(layoutInflater) } - } - - override fun onResume() { - super.onResume() - mapView.resume() - } - - override fun onPause() { - // normally, you won't want to clear credentials once a device has been verified. These calls are made to keep this - // sample from interfering with other authentication samples - AuthenticationManager.CredentialCache.clear() - AuthenticationManager.clearOAuthConfigurations() - - mapView.pause() - super.onPause() - } - - override fun onDestroy() { - mapView.dispose() - super.onDestroy() - } - - /** - * Log an error to logcat and to the screen via Toast. - * @param message the text to log. - */ - private fun logError(message: String?) { - message?.let { - Log.e(TAG, message) - Toast.makeText(this, message, Toast.LENGTH_LONG).show() + + private val mapView: MapView by lazy { + activityMainBinding.mapView + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(activityMainBinding.root) + + try { + // set up an oauth config with url to portal, a client id and a re-direct url + // a custom client id for your app can be set on the ArcGIS for Developers dashboard under + // Authentication --> Redirect URIs + val oAuthConfiguration = OAuthConfiguration( + getString(R.string.portal_url), + getString(R.string.oauth_client_id), + getString(R.string.oauth_redirect_uri) + "://" + getString(R.string.oauth_redirect_host) + ) + + // setup AuthenticationManager to handle auth challenges + val defaultAuthenticationChallengeHandler = DefaultAuthenticationChallengeHandler(this) + + // use the DefaultChallengeHandler to handle authentication challenges + AuthenticationManager.setAuthenticationChallengeHandler( + defaultAuthenticationChallengeHandler + ) + + // add an OAuth configuration + // NOTE: you must add the DefaultOAuthIntentReceiver Activity to the app's manifest to handle starting a browser + AuthenticationManager.addOAuthConfiguration(oAuthConfiguration) + + // load the portal and add the portal item as a map to the map view + val portal = Portal(getString(R.string.portal_url)) + val portalItem = PortalItem(portal, getString(R.string.webmap_world_traffic_id)) + mapView.apply { + map = ArcGISMap(portalItem) + } + } catch (e: MalformedURLException) { + logError("Error in OAuthConfiguration URL: " + e.message) + } + } + + override fun onResume() { + super.onResume() + mapView.resume() + } + + override fun onPause() { + // normally, you won't want to clear credentials once a device has been verified. These calls are made to keep this + // sample from interfering with other authentication samples + AuthenticationManager.CredentialCache.clear() + AuthenticationManager.clearOAuthConfigurations() + + mapView.pause() + super.onPause() + } + + override fun onDestroy() { + mapView.dispose() + super.onDestroy() + } + + /** + * Log an error to logcat and to the screen via Toast. + * @param message the text to log. + */ + private fun logError(message: String?) { + message?.let { + Log.e(TAG, message) + Toast.makeText(this, message, Toast.LENGTH_LONG).show() + } + } + + companion object { + private val TAG: String = MainActivity::class.java.simpleName } - } } diff --git a/kotlin/browse-ogc-api-feature-service/src/main/res/drawable-v24/ic_launcher_foreground.xml b/kotlin/browse-ogc-api-feature-service/src/main/res/drawable-v24/ic_launcher_foreground.xml index 32f45a04d7..7706ab9e6d 100644 --- a/kotlin/browse-ogc-api-feature-service/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ b/kotlin/browse-ogc-api-feature-service/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -1,30 +1,30 @@ + xmlns:aapt="http://schemas.android.com/aapt" + android:width="108dp" + android:height="108dp" + android:viewportWidth="108" + android:viewportHeight="108"> + android:endX="85.84757" + android:endY="92.4963" + android:startX="42.9492" + android:startY="49.59793" + android:type="linear"> + android:color="#44000000" + android:offset="0.0" /> + android:color="#00000000" + android:offset="1.0" /> + android:fillColor="#FFFFFF" + android:fillType="nonZero" + android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z" + android:strokeWidth="1" + android:strokeColor="#00000000" /> diff --git a/kotlin/browse-ogc-api-feature-service/src/main/res/drawable/ic_launcher_background.xml b/kotlin/browse-ogc-api-feature-service/src/main/res/drawable/ic_launcher_background.xml index 6ae213eb0e..07d5da9cbf 100644 --- a/kotlin/browse-ogc-api-feature-service/src/main/res/drawable/ic_launcher_background.xml +++ b/kotlin/browse-ogc-api-feature-service/src/main/res/drawable/ic_launcher_background.xml @@ -1,170 +1,170 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + android:width="108dp" + android:height="108dp" + android:viewportWidth="108" + android:viewportHeight="108"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kotlin/browse-ogc-api-feature-service/src/main/res/layout/activity_main.xml b/kotlin/browse-ogc-api-feature-service/src/main/res/layout/activity_main.xml index a244bb4b6d..2aa080853b 100644 --- a/kotlin/browse-ogc-api-feature-service/src/main/res/layout/activity_main.xml +++ b/kotlin/browse-ogc-api-feature-service/src/main/res/layout/activity_main.xml @@ -1,101 +1,101 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="match_parent"> + android:id="@+id/mapView" + android:layout_width="match_parent" + android:layout_height="match_parent" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintLeft_toLeftOf="parent" + app:layout_constraintRight_toRightOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + android:id="@+id/serviceDetailsLayout" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@android:color/background_light" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> + android:id="@+id/instructionsTextView" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="8dp" + android:text="@string/instructions_text" + android:textSize="12sp" + app:layout_constraintEnd_toEndOf="@+id/serviceEditText" + app:layout_constraintStart_toStartOf="@+id/serviceEditText" + app:layout_constraintTop_toTopOf="parent" /> + android:id="@+id/serviceEditText" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="8dp" + android:autofillHints="@string/daraa_url" + android:hint="@string/url_hint" + android:inputType="textUri" + android:textSize="12sp" + app:layout_constraintEnd_toStartOf="@+id/loadServiceButton" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/instructionsTextView" /> + android:id="@+id/loadServiceButton" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:layout_marginEnd="8dp" + android:layout_marginBottom="8dp" + android:text="@string/load_service" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + android:id="@+id/layerFAB" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="bottom|end" + android:layout_margin="16dp" + android:clickable="true" + android:contentDescription="@string/layers_floating_action_button" + android:focusable="true" + android:src="@android:drawable/ic_dialog_map" + app:elevation="16dp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toStartOf="@+id/mapView" /> + android:layout_width="match_parent" + android:layout_height="180dp" + android:layout_gravity="bottom|end" + android:layout_margin="32dp" + android:background="@android:color/white" + android:visibility="visible" + app:layout_behavior="com.google.android.material.transformation.FabTransformationSheetBehavior" + app:layout_constraintBottom_toTopOf="@+id/mapView" + app:layout_constraintEnd_toStartOf="@+id/mapView"> + android:id="@+id/featureCollectionTitleListView" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@android:color/background_light" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/layers" /> diff --git a/kotlin/browse-ogc-api-feature-service/src/main/res/layout/feature_collection_title_list_item.xml b/kotlin/browse-ogc-api-feature-service/src/main/res/layout/feature_collection_title_list_item.xml index 6eebc5c982..f88e5eb030 100644 --- a/kotlin/browse-ogc-api-feature-service/src/main/res/layout/feature_collection_title_list_item.xml +++ b/kotlin/browse-ogc-api-feature-service/src/main/res/layout/feature_collection_title_list_item.xml @@ -1,12 +1,12 @@ + android:id="@+id/featureCollectionTitleText" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:ellipsize="end" + android:gravity="center_vertical" + android:maxLines="1" + android:paddingStart="4dp" + android:paddingTop="4dp" + android:paddingEnd="4dp" + android:paddingBottom="4dp" + android:textSize="15sp" /> diff --git a/kotlin/buffer/src/main/java/com/esri/arcgisruntime/sample/buffer/MainActivity.kt b/kotlin/buffer/src/main/java/com/esri/arcgisruntime/sample/buffer/MainActivity.kt index 04d574e701..00cb208050 100644 --- a/kotlin/buffer/src/main/java/com/esri/arcgisruntime/sample/buffer/MainActivity.kt +++ b/kotlin/buffer/src/main/java/com/esri/arcgisruntime/sample/buffer/MainActivity.kt @@ -44,145 +44,145 @@ import kotlin.math.roundToInt class MainActivity : AppCompatActivity() { - private val activityMainBinding by lazy { - ActivityMainBinding.inflate(layoutInflater) - } - - private val mapView: MapView by lazy { - activityMainBinding.mapView - } - - private val bufferInput: EditText by lazy { - activityMainBinding.bufferInput - } - - private val clearButton: Button by lazy { - activityMainBinding.clearButton - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(activityMainBinding.root) - - // authentication with an API key or named user is required to access basemaps and other - // location services - ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY) - - // create a map with a topographic basemap - mapView.map = ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC) - - // create a fill symbol for geodesic buffer polygons - val geodesicOutlineSymbol = SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.BLACK, 2F) - val geodesicBufferFillSymbol = SimpleFillSymbol( - SimpleFillSymbol.Style.SOLID, Color.GREEN, - geodesicOutlineSymbol - ) - - // create a graphics overlay to display geodesic polygons and set its renderer - val geodesicGraphicsOverlay = GraphicsOverlay().apply { - renderer = SimpleRenderer(geodesicBufferFillSymbol) - opacity = 0.5f + private val activityMainBinding by lazy { + ActivityMainBinding.inflate(layoutInflater) } - // create a fill symbol for planar buffer polygons - val planarOutlineSymbol = SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.BLACK, 2F) - val planarBufferFillSymbol = SimpleFillSymbol( - SimpleFillSymbol.Style.SOLID, Color.RED, - planarOutlineSymbol - ) - - // create a graphics overlay to display planar polygons and set its renderer - val planarGraphicsOverlay = GraphicsOverlay().apply { - renderer = SimpleRenderer(planarBufferFillSymbol) - opacity = 0.5f + private val mapView: MapView by lazy { + activityMainBinding.mapView } - // create a marker symbol for tap locations - val tapSymbol = SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CROSS, Color.WHITE, 14F) + private val bufferInput: EditText by lazy { + activityMainBinding.bufferInput + } - // create a graphics overlay to display tap locations for buffers and set its renderer - val tapLocationsOverlay = GraphicsOverlay().apply { - renderer = SimpleRenderer(tapSymbol) + private val clearButton: Button by lazy { + activityMainBinding.clearButton } - // add overlays to the mapView - mapView.graphicsOverlays.addAll( - listOf( - geodesicGraphicsOverlay, - planarGraphicsOverlay, - tapLocationsOverlay - ) - ) - - // create a buffer around the clicked location - mapView.onTouchListener = - object : DefaultMapViewOnTouchListener(applicationContext, mapView) { - override fun onSingleTapConfirmed(motionEvent: MotionEvent): Boolean { - - // get the point that was clicked and convert it to a point in the map - val screenPoint = android.graphics.Point( - motionEvent.x.roundToInt(), - motionEvent.y.roundToInt() - ) - val mapPoint = mapView.screenToLocation(screenPoint) - - // only draw a buffer if a value was entered - if (bufferInput.text.toString().isNotEmpty()) { - // get the buffer distance (miles) entered in the text box - val bufferInMiles = bufferInput.text.toString().toDouble() - - // convert the input distance to meters, 1609.34 meters in one mile - val bufferInMeters = bufferInMiles * 1609.34 - - // create a planar buffer graphic around the input location at the specified distance - val bufferGeometryPlanar = GeometryEngine.buffer(mapPoint, bufferInMeters) - val planarBufferGraphic = Graphic(bufferGeometryPlanar) - - // create a geodesic buffer graphic using the same location and distance - val bufferGeometryGeodesic = GeometryEngine.bufferGeodetic( - mapPoint, bufferInMeters, - LinearUnit(LinearUnitId.METERS), Double.NaN, GeodeticCurveType.GEODESIC + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(activityMainBinding.root) + + // authentication with an API key or named user is required to access basemaps and other + // location services + ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY) + + // create a map with a topographic basemap + mapView.map = ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC) + + // create a fill symbol for geodesic buffer polygons + val geodesicOutlineSymbol = SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.BLACK, 2F) + val geodesicBufferFillSymbol = SimpleFillSymbol( + SimpleFillSymbol.Style.SOLID, Color.GREEN, + geodesicOutlineSymbol + ) + + // create a graphics overlay to display geodesic polygons and set its renderer + val geodesicGraphicsOverlay = GraphicsOverlay().apply { + renderer = SimpleRenderer(geodesicBufferFillSymbol) + opacity = 0.5f + } + + // create a fill symbol for planar buffer polygons + val planarOutlineSymbol = SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.BLACK, 2F) + val planarBufferFillSymbol = SimpleFillSymbol( + SimpleFillSymbol.Style.SOLID, Color.RED, + planarOutlineSymbol + ) + + // create a graphics overlay to display planar polygons and set its renderer + val planarGraphicsOverlay = GraphicsOverlay().apply { + renderer = SimpleRenderer(planarBufferFillSymbol) + opacity = 0.5f + } + + // create a marker symbol for tap locations + val tapSymbol = SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CROSS, Color.WHITE, 14F) + + // create a graphics overlay to display tap locations for buffers and set its renderer + val tapLocationsOverlay = GraphicsOverlay().apply { + renderer = SimpleRenderer(tapSymbol) + } + + // add overlays to the mapView + mapView.graphicsOverlays.addAll( + listOf( + geodesicGraphicsOverlay, + planarGraphicsOverlay, + tapLocationsOverlay ) - val geodesicBufferGraphic = Graphic(bufferGeometryGeodesic) - - // create a graphic for the user tap location - val locationGraphic = Graphic(mapPoint) - - // add the buffer polygons and tap location graphics to the appropriate graphic overlays - planarGraphicsOverlay.graphics.add(planarBufferGraphic) - geodesicGraphicsOverlay.graphics.add(geodesicBufferGraphic) - tapLocationsOverlay.graphics.add(locationGraphic) - } else { - Toast.makeText( - this@MainActivity, - "Please enter a buffer distance first.", - Toast.LENGTH_LONG - ).show() - } - return true + ) + + // create a buffer around the clicked location + mapView.onTouchListener = + object : DefaultMapViewOnTouchListener(applicationContext, mapView) { + override fun onSingleTapConfirmed(motionEvent: MotionEvent): Boolean { + + // get the point that was clicked and convert it to a point in the map + val screenPoint = android.graphics.Point( + motionEvent.x.roundToInt(), + motionEvent.y.roundToInt() + ) + val mapPoint = mapView.screenToLocation(screenPoint) + + // only draw a buffer if a value was entered + if (bufferInput.text.toString().isNotEmpty()) { + // get the buffer distance (miles) entered in the text box + val bufferInMiles = bufferInput.text.toString().toDouble() + + // convert the input distance to meters, 1609.34 meters in one mile + val bufferInMeters = bufferInMiles * 1609.34 + + // create a planar buffer graphic around the input location at the specified distance + val bufferGeometryPlanar = GeometryEngine.buffer(mapPoint, bufferInMeters) + val planarBufferGraphic = Graphic(bufferGeometryPlanar) + + // create a geodesic buffer graphic using the same location and distance + val bufferGeometryGeodesic = GeometryEngine.bufferGeodetic( + mapPoint, bufferInMeters, + LinearUnit(LinearUnitId.METERS), Double.NaN, GeodeticCurveType.GEODESIC + ) + val geodesicBufferGraphic = Graphic(bufferGeometryGeodesic) + + // create a graphic for the user tap location + val locationGraphic = Graphic(mapPoint) + + // add the buffer polygons and tap location graphics to the appropriate graphic overlays + planarGraphicsOverlay.graphics.add(planarBufferGraphic) + geodesicGraphicsOverlay.graphics.add(geodesicBufferGraphic) + tapLocationsOverlay.graphics.add(locationGraphic) + } else { + Toast.makeText( + this@MainActivity, + "Please enter a buffer distance first.", + Toast.LENGTH_LONG + ).show() + } + return true + } + } + + // clear the graphics from the graphics overlays + clearButton.setOnClickListener { + planarGraphicsOverlay.graphics.clear() + geodesicGraphicsOverlay.graphics.clear() + tapLocationsOverlay.graphics.clear() } - } + } + + override fun onResume() { + super.onResume() + mapView.resume() + } + + override fun onPause() { + mapView.pause() + super.onPause() + } - // clear the graphics from the graphics overlays - clearButton.setOnClickListener { - planarGraphicsOverlay.graphics.clear() - geodesicGraphicsOverlay.graphics.clear() - tapLocationsOverlay.graphics.clear() + override fun onDestroy() { + mapView.dispose() + super.onDestroy() } - } - - override fun onResume() { - super.onResume() - mapView.resume() - } - - override fun onPause() { - mapView.pause() - super.onPause() - } - - override fun onDestroy() { - mapView.dispose() - super.onDestroy() - } } diff --git a/kotlin/change-atmosphere-effect/src/main/java/com/esri/arcgisruntime/sample/changeatmosphereeffect/MainActivity.kt b/kotlin/change-atmosphere-effect/src/main/java/com/esri/arcgisruntime/sample/changeatmosphereeffect/MainActivity.kt index 280638f35e..13a45c0808 100644 --- a/kotlin/change-atmosphere-effect/src/main/java/com/esri/arcgisruntime/sample/changeatmosphereeffect/MainActivity.kt +++ b/kotlin/change-atmosphere-effect/src/main/java/com/esri/arcgisruntime/sample/changeatmosphereeffect/MainActivity.kt @@ -29,66 +29,66 @@ import com.esri.arcgisruntime.sample.changeatmosphereeffect.databinding.Activity class MainActivity : AppCompatActivity() { - private val activityMainBinding by lazy { - ActivityMainBinding.inflate(layoutInflater) - } + private val activityMainBinding by lazy { + ActivityMainBinding.inflate(layoutInflater) + } + + private val sceneView: SceneView by lazy { + activityMainBinding.sceneView + } - private val sceneView: SceneView by lazy { - activityMainBinding.sceneView - } + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(activityMainBinding.root) - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(activityMainBinding.root) + // authentication with an API key or named user is required to access basemaps and other + // location services + ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY) - // authentication with an API key or named user is required to access basemaps and other - // location services - ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY) + // create a scene and add a base map to it + val scene = ArcGISScene(BasemapStyle.ARCGIS_IMAGERY) + sceneView.scene = scene - // create a scene and add a base map to it - val scene = ArcGISScene(BasemapStyle.ARCGIS_IMAGERY) - sceneView.scene = scene + // add base surface for elevation data + sceneView.scene.baseSurface = Surface().apply { + elevationSources.add( + ArcGISTiledElevationSource(getString(R.string.elevation_image_service)) + ) + } - // add base surface for elevation data - sceneView.scene.baseSurface = Surface().apply { - elevationSources.add( - ArcGISTiledElevationSource(getString(R.string.elevation_image_service)) - ) + // create a camera and set it as the viewpoint for when the scene loads + val camera = Camera(64.416919, -14.483728, 100.0, 318.0, 105.0, 0.0) + sceneView.setViewpointCamera(camera) } - // create a camera and set it as the viewpoint for when the scene loads - val camera = Camera(64.416919, -14.483728, 100.0, 318.0, 105.0, 0.0) - sceneView.setViewpointCamera(camera) - } - - override fun onCreateOptionsMenu(menu: Menu?): Boolean { - menuInflater.inflate(R.menu.change_atmosphere_effect_menu, menu) - return super.onCreateOptionsMenu(menu) - } + override fun onCreateOptionsMenu(menu: Menu?): Boolean { + menuInflater.inflate(R.menu.change_atmosphere_effect_menu, menu) + return super.onCreateOptionsMenu(menu) + } - override fun onOptionsItemSelected(item: MenuItem): Boolean { - // set different atmosphere effects on the scene view - sceneView.atmosphereEffect = when (item.itemId) { - R.id.action_no_atmosphere_effect -> AtmosphereEffect.NONE - R.id.action_realistic_atmosphere_effect -> AtmosphereEffect.REALISTIC - R.id.action_horizon_atmosphere_effect -> AtmosphereEffect.HORIZON_ONLY - else -> return super.onOptionsItemSelected(item) + override fun onOptionsItemSelected(item: MenuItem): Boolean { + // set different atmosphere effects on the scene view + sceneView.atmosphereEffect = when (item.itemId) { + R.id.action_no_atmosphere_effect -> AtmosphereEffect.NONE + R.id.action_realistic_atmosphere_effect -> AtmosphereEffect.REALISTIC + R.id.action_horizon_atmosphere_effect -> AtmosphereEffect.HORIZON_ONLY + else -> return super.onOptionsItemSelected(item) + } + return true } - return true - } - override fun onResume() { - super.onResume() - sceneView.resume() - } + override fun onResume() { + super.onResume() + sceneView.resume() + } - override fun onPause() { - sceneView.pause() - super.onPause() - } + override fun onPause() { + sceneView.pause() + super.onPause() + } - override fun onDestroy() { - sceneView.dispose() - super.onDestroy() - } + override fun onDestroy() { + sceneView.dispose() + super.onDestroy() + } } diff --git a/kotlin/change-basemaps/src/main/res/layout/activity_main.xml b/kotlin/change-basemaps/src/main/res/layout/activity_main.xml index 8f641de9ee..d478c4b9a1 100644 --- a/kotlin/change-basemaps/src/main/res/layout/activity_main.xml +++ b/kotlin/change-basemaps/src/main/res/layout/activity_main.xml @@ -5,13 +5,13 @@ + android:layout_height="match_parent" /> diff --git a/kotlin/change-viewpoint/src/main/java/com/esri/arcgisruntime/sample/changeviewpoint/MainActivity.kt b/kotlin/change-viewpoint/src/main/java/com/esri/arcgisruntime/sample/changeviewpoint/MainActivity.kt index fb151ef800..f635117cca 100644 --- a/kotlin/change-viewpoint/src/main/java/com/esri/arcgisruntime/sample/changeviewpoint/MainActivity.kt +++ b/kotlin/change-viewpoint/src/main/java/com/esri/arcgisruntime/sample/changeviewpoint/MainActivity.kt @@ -33,75 +33,75 @@ import com.esri.arcgisruntime.sample.changeviewpoint.databinding.ActivityMainBin class MainActivity : AppCompatActivity() { - private val activityMainBinding by lazy { - ActivityMainBinding.inflate(layoutInflater) - } - - private val mapView: MapView by lazy { - activityMainBinding.mapView - } - - private val scale = 5000.0 - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(activityMainBinding.root) - - // authentication with an API key or named user is required to access basemaps and other - // location services - ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY) - - // create a map with an imagery basemap and set it to the map view - mapView.map = ArcGISMap(BasemapStyle.ARCGIS_IMAGERY) - - // create point for starting location - val startPoint = Point(-14093.0, 6711377.0, SpatialReferences.getWebMercator()) - - // set viewpoint of map view to starting point and scale - mapView.setViewpointCenterAsync(startPoint, scale) - } - - fun onAnimateClicked(view: View) { - // create the London location point - val londonPoint = Point(-14093.0, 6711377.0, SpatialReferences.getWebMercator()) - // create the viewpoint with the London point and scale - val viewpoint = Viewpoint(londonPoint, scale) - // set the map view's viewpoint to London with a seven second animation duration - mapView.setViewpointAsync(viewpoint, 7f) - } - - fun onCenterClicked(view: View) { - // create the Waterloo location point - val waterlooPoint = Point(-12153.0, 6710527.0, SpatialReferences.getWebMercator()) - // set the map view's viewpoint centered on Waterloo and scaled - mapView.setViewpointCenterAsync(waterlooPoint, scale) - } - - fun onGeometryClicked(view: View) { - // create a collection of points around Westminster - val westminsterPoints = PointCollection(SpatialReferences.getWebMercator()) - westminsterPoints.add(Point(-13823.0, 6710390.0)) - westminsterPoints.add(Point(-13823.0, 6710150.0)) - westminsterPoints.add(Point(-14680.0, 6710390.0)) - westminsterPoints.add(Point(-14680.0, 6710150.0)) - val geometry = Polyline(westminsterPoints) - - // set the map view's viewpoint to Westminster - mapView.setViewpointGeometryAsync(geometry) - } - - override fun onPause() { - mapView.pause() - super.onPause() - } - - override fun onResume() { - super.onResume() - mapView.resume() - } - - override fun onDestroy() { - mapView.dispose() - super.onDestroy() - } + private val activityMainBinding by lazy { + ActivityMainBinding.inflate(layoutInflater) + } + + private val mapView: MapView by lazy { + activityMainBinding.mapView + } + + private val scale = 5000.0 + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(activityMainBinding.root) + + // authentication with an API key or named user is required to access basemaps and other + // location services + ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY) + + // create a map with an imagery basemap and set it to the map view + mapView.map = ArcGISMap(BasemapStyle.ARCGIS_IMAGERY) + + // create point for starting location + val startPoint = Point(-14093.0, 6711377.0, SpatialReferences.getWebMercator()) + + // set viewpoint of map view to starting point and scale + mapView.setViewpointCenterAsync(startPoint, scale) + } + + fun onAnimateClicked(view: View) { + // create the London location point + val londonPoint = Point(-14093.0, 6711377.0, SpatialReferences.getWebMercator()) + // create the viewpoint with the London point and scale + val viewpoint = Viewpoint(londonPoint, scale) + // set the map view's viewpoint to London with a seven second animation duration + mapView.setViewpointAsync(viewpoint, 7f) + } + + fun onCenterClicked(view: View) { + // create the Waterloo location point + val waterlooPoint = Point(-12153.0, 6710527.0, SpatialReferences.getWebMercator()) + // set the map view's viewpoint centered on Waterloo and scaled + mapView.setViewpointCenterAsync(waterlooPoint, scale) + } + + fun onGeometryClicked(view: View) { + // create a collection of points around Westminster + val westminsterPoints = PointCollection(SpatialReferences.getWebMercator()) + westminsterPoints.add(Point(-13823.0, 6710390.0)) + westminsterPoints.add(Point(-13823.0, 6710150.0)) + westminsterPoints.add(Point(-14680.0, 6710390.0)) + westminsterPoints.add(Point(-14680.0, 6710150.0)) + val geometry = Polyline(westminsterPoints) + + // set the map view's viewpoint to Westminster + mapView.setViewpointGeometryAsync(geometry) + } + + override fun onPause() { + mapView.pause() + super.onPause() + } + + override fun onResume() { + super.onResume() + mapView.resume() + } + + override fun onDestroy() { + mapView.dispose() + super.onDestroy() + } } diff --git a/kotlin/choose-camera-controller/src/main/java/com/esri/arcgisruntime/sample/choosecameracontroller/MainActivity.kt b/kotlin/choose-camera-controller/src/main/java/com/esri/arcgisruntime/sample/choosecameracontroller/MainActivity.kt index c568a54d49..6aebea146b 100644 --- a/kotlin/choose-camera-controller/src/main/java/com/esri/arcgisruntime/sample/choosecameracontroller/MainActivity.kt +++ b/kotlin/choose-camera-controller/src/main/java/com/esri/arcgisruntime/sample/choosecameracontroller/MainActivity.kt @@ -44,163 +44,174 @@ import java.io.FileOutputStream class MainActivity : AppCompatActivity() { - private val activityMainBinding by lazy { - ActivityMainBinding.inflate(layoutInflater) - } - - private val sceneView: SceneView by lazy { - activityMainBinding.sceneView - } - - private val toolbar: androidx.appcompat.widget.Toolbar by lazy { - activityMainBinding.toolbar - } - - private lateinit var sceneOverlay: GraphicsOverlay - private lateinit var plane3d: Graphic - private lateinit var orbitLocationCameraController: OrbitLocationCameraController - private lateinit var orbitPlaneCameraController: OrbitGeoElementCameraController - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(activityMainBinding.root) - - // authentication with an API key or named user is required to access basemaps and other - // location services - ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY) - - // load plane model and texture from assets into cache directory - copyFilesFromAssetsToCache(resources.getStringArray(R.array.required_files_array)) - - // setup Toolbar - setSupportActionBar(toolbar) - toolbar.overflowIcon = ContextCompat.getDrawable(this, R.drawable.ic_photo_camera) - - // create a scene and add it to the scene view - sceneView.scene = ArcGISScene(BasemapStyle.ARCGIS_IMAGERY) - - // add base surface for elevation data - with(Surface()) { - this.elevationSources.add( - ArcGISTiledElevationSource( - getString(R.string.world_elevation_service_url) - ) - ) - sceneView.scene.baseSurface = this + private val activityMainBinding by lazy { + ActivityMainBinding.inflate(layoutInflater) } - // create a graphics overlay for the scene - sceneOverlay = GraphicsOverlay() - sceneOverlay.sceneProperties.surfacePlacement = LayerSceneProperties.SurfacePlacement.ABSOLUTE - sceneView.graphicsOverlays.add(sceneOverlay) - - // create a camera and set it as the viewpoint for when the scene loads - val camera = Camera(38.459291, -109.937576, 5500.0, 150.0, 20.0, 0.0) - sceneView.setViewpointCamera(camera) - - // instantiate a new camera controller which orbits a target location - with(Point(-109.929589, 38.437304, 1700.0, SpatialReferences.getWgs84())) { - orbitLocationCameraController = OrbitLocationCameraController(this, 5000.0).apply { - this.cameraPitchOffset = 3.0 - this.cameraHeadingOffset = 150.0 - } + private val sceneView: SceneView by lazy { + activityMainBinding.sceneView } - loadModel().addDoneLoadingListener { - // instantiate a new camera controller which orbits the plane at a set distance - orbitPlaneCameraController = OrbitGeoElementCameraController(plane3d, 100.0).apply { - this.cameraPitchOffset = 30.0 - this.cameraHeadingOffset = 150.0 - } + private val toolbar: androidx.appcompat.widget.Toolbar by lazy { + activityMainBinding.toolbar } - } - - override fun onCreateOptionsMenu(menu: Menu): Boolean { - menuInflater.inflate(R.menu.camera_controller_menu, menu) - return super.onCreateOptionsMenu(menu) - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - sceneView.cameraController = when (item.itemId) { - R.id.action_camera_controller_plane -> orbitPlaneCameraController - R.id.action_camera_controller_crater -> orbitLocationCameraController - R.id.action_camera_controller_globe -> GlobeCameraController() - else -> return super.onOptionsItemSelected(item) + + private lateinit var sceneOverlay: GraphicsOverlay + private lateinit var plane3d: Graphic + private lateinit var orbitLocationCameraController: OrbitLocationCameraController + private lateinit var orbitPlaneCameraController: OrbitGeoElementCameraController + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(activityMainBinding.root) + + // authentication with an API key or named user is required to access basemaps and other + // location services + ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY) + + // load plane model and texture from assets into cache directory + copyFilesFromAssetsToCache(resources.getStringArray(R.array.required_files_array)) + + // setup Toolbar + setSupportActionBar(toolbar) + toolbar.overflowIcon = ContextCompat.getDrawable(this, R.drawable.ic_photo_camera) + + // create a scene and add it to the scene view + sceneView.scene = ArcGISScene(BasemapStyle.ARCGIS_IMAGERY) + + // add base surface for elevation data + with(Surface()) { + this.elevationSources.add( + ArcGISTiledElevationSource( + getString(R.string.world_elevation_service_url) + ) + ) + sceneView.scene.baseSurface = this + } + + // create a graphics overlay for the scene + sceneOverlay = GraphicsOverlay() + sceneOverlay.sceneProperties.surfacePlacement = + LayerSceneProperties.SurfacePlacement.ABSOLUTE + sceneView.graphicsOverlays.add(sceneOverlay) + + // create a camera and set it as the viewpoint for when the scene loads + val camera = Camera(38.459291, -109.937576, 5500.0, 150.0, 20.0, 0.0) + sceneView.setViewpointCamera(camera) + + // instantiate a new camera controller which orbits a target location + with(Point(-109.929589, 38.437304, 1700.0, SpatialReferences.getWgs84())) { + orbitLocationCameraController = OrbitLocationCameraController(this, 5000.0).apply { + this.cameraPitchOffset = 3.0 + this.cameraHeadingOffset = 150.0 + } + } + + loadModel().addDoneLoadingListener { + // instantiate a new camera controller which orbits the plane at a set distance + orbitPlaneCameraController = OrbitGeoElementCameraController(plane3d, 100.0).apply { + this.cameraPitchOffset = 30.0 + this.cameraHeadingOffset = 150.0 + } + } + } + + override fun onCreateOptionsMenu(menu: Menu): Boolean { + menuInflater.inflate(R.menu.camera_controller_menu, menu) + return super.onCreateOptionsMenu(menu) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + sceneView.cameraController = when (item.itemId) { + R.id.action_camera_controller_plane -> orbitPlaneCameraController + R.id.action_camera_controller_crater -> orbitLocationCameraController + R.id.action_camera_controller_globe -> GlobeCameraController() + else -> return super.onOptionsItemSelected(item) + } + return true } - return true - } - - /** - * Load the plane model from the cache, use to construct a Model Scene Symbol and add it to the scene's graphic overlay. - */ - private fun loadModel(): ModelSceneSymbol { - // create a graphic with a ModelSceneSymbol of a plane to add to the scene - val pathToModel = cacheDir.toString() + File.separator + getString(R.string.file_bristol_model) - val plane3DSymbol = ModelSceneSymbol(pathToModel, 1.0) - plane3DSymbol.heading = 45.0 - plane3d = - Graphic(Point(-109.937516, 38.456714, 5000.0, SpatialReferences.getWgs84()), plane3DSymbol) - sceneOverlay.graphics.add(plane3d) - return plane3DSymbol - } - - /** - * Copy the given file from the app's assets folder to the app's cache directory. - * - * @param files as String - */ - private fun copyFilesFromAssetsToCache(files: Array) { - applicationContext.assets?.let { assetManager -> - files.forEach { filename -> - with(File(cacheDir.toString() + File.separator + filename)) { - if (!this.exists()) { - try { - val bis = BufferedInputStream(assetManager.open(filename)) - val bos = BufferedOutputStream( - FileOutputStream(cacheDir.toString() + File.separator + filename) - ) - val buffer = ByteArray(bis.available()) - var read = bis.read(buffer) - while (read != -1) { - bos.write(buffer, 0, read) - read = bis.read(buffer) - } - bos.close() - bis.close() - Log.i(logTag, "$filename copied to cache.") - } catch (e: Exception) { - logToUser(getString(R.string.error_writing_to_cache, filename, e.message)) + + /** + * Load the plane model from the cache, use to construct a Model Scene Symbol and add it to the scene's graphic overlay. + */ + private fun loadModel(): ModelSceneSymbol { + // create a graphic with a ModelSceneSymbol of a plane to add to the scene + val pathToModel = + cacheDir.toString() + File.separator + getString(R.string.file_bristol_model) + val plane3DSymbol = ModelSceneSymbol(pathToModel, 1.0) + plane3DSymbol.heading = 45.0 + plane3d = + Graphic( + Point(-109.937516, 38.456714, 5000.0, SpatialReferences.getWgs84()), + plane3DSymbol + ) + sceneOverlay.graphics.add(plane3d) + return plane3DSymbol + } + + /** + * Copy the given file from the app's assets folder to the app's cache directory. + * + * @param files as String + */ + private fun copyFilesFromAssetsToCache(files: Array) { + applicationContext.assets?.let { assetManager -> + files.forEach { filename -> + with(File(cacheDir.toString() + File.separator + filename)) { + if (!this.exists()) { + try { + val bis = BufferedInputStream(assetManager.open(filename)) + val bos = BufferedOutputStream( + FileOutputStream(cacheDir.toString() + File.separator + filename) + ) + val buffer = ByteArray(bis.available()) + var read = bis.read(buffer) + while (read != -1) { + bos.write(buffer, 0, read) + read = bis.read(buffer) + } + bos.close() + bis.close() + Log.i(logTag, "$filename copied to cache.") + } catch (e: Exception) { + logToUser( + getString( + R.string.error_writing_to_cache, + filename, + e.message + ) + ) + } + } else { + Log.i(logTag, "$files already in cache.") + } + } } - } else { - Log.i(logTag, "$files already in cache.") - } } - } } - } - - override fun onResume() { - super.onResume() - sceneView.resume() - } - - override fun onPause() { - sceneView.pause() - super.onPause() - } - - override fun onDestroy() { - sceneView.dispose() - super.onDestroy() - } - - /** - * AppCompatActivityExtensions - */ - private val AppCompatActivity.logTag: String get() = this::class.java.simpleName - - private fun AppCompatActivity.logToUser(message: String) { - Toast.makeText(this, message, Toast.LENGTH_LONG).show() - Log.d(logTag, message) - } + + override fun onResume() { + super.onResume() + sceneView.resume() + } + + override fun onPause() { + sceneView.pause() + super.onPause() + } + + override fun onDestroy() { + sceneView.dispose() + super.onDestroy() + } + + /** + * AppCompatActivityExtensions + */ + private val AppCompatActivity.logTag: String get() = this::class.java.simpleName + + private fun AppCompatActivity.logToUser(message: String) { + Toast.makeText(this, message, Toast.LENGTH_LONG).show() + Log.d(logTag, message) + } } diff --git a/kotlin/configure-subnetwork-trace/src/main/java/com/esri/arcgisruntime/sample/configuresubnetworktrace/MainActivity.kt b/kotlin/configure-subnetwork-trace/src/main/java/com/esri/arcgisruntime/sample/configuresubnetworktrace/MainActivity.kt index 8c7f91a068..65ed85518e 100644 --- a/kotlin/configure-subnetwork-trace/src/main/java/com/esri/arcgisruntime/sample/configuresubnetworktrace/MainActivity.kt +++ b/kotlin/configure-subnetwork-trace/src/main/java/com/esri/arcgisruntime/sample/configuresubnetworktrace/MainActivity.kt @@ -39,384 +39,398 @@ import com.esri.arcgisruntime.utilitynetworks.UtilityTraversabilityScope class MainActivity : AppCompatActivity() { - private val TAG: String = MainActivity::class.java.simpleName + private val TAG: String = MainActivity::class.java.simpleName - private val activityMainBinding by lazy { - ActivityMainBinding.inflate(layoutInflater) - } + private val activityMainBinding by lazy { + ActivityMainBinding.inflate(layoutInflater) + } - private val exampleTextView: TextView by lazy { - activityMainBinding.exampleTextView - } + private val exampleTextView: TextView by lazy { + activityMainBinding.exampleTextView + } - private val sourceSpinner: Spinner by lazy { - activityMainBinding.sourceSpinner - } + private val sourceSpinner: Spinner by lazy { + activityMainBinding.sourceSpinner + } - private val operatorSpinner: Spinner by lazy { - activityMainBinding.operatorSpinner - } + private val operatorSpinner: Spinner by lazy { + activityMainBinding.operatorSpinner + } - private val expressionTextView: TextView by lazy { - activityMainBinding.expressionTextView - } + private val expressionTextView: TextView by lazy { + activityMainBinding.expressionTextView + } - private val valuesSpinner: Spinner by lazy { - activityMainBinding.valuesSpinner - } + private val valuesSpinner: Spinner by lazy { + activityMainBinding.valuesSpinner + } - private val valuesBackgroundView: RelativeLayout by lazy { - activityMainBinding.valuesBackgroundView - } + private val valuesBackgroundView: RelativeLayout by lazy { + activityMainBinding.valuesBackgroundView + } - private val valueBooleanButton: ToggleButton by lazy { - activityMainBinding.valueBooleanButton - } + private val valueBooleanButton: ToggleButton by lazy { + activityMainBinding.valueBooleanButton + } - private val valuesEditText: EditText by lazy { - activityMainBinding.valuesEditText - } + private val valuesEditText: EditText by lazy { + activityMainBinding.valuesEditText + } - private val utilityNetwork by lazy { - UtilityNetwork("https://sampleserver7.arcgisonline.com/server/rest/services/UtilityNetwork/NapervilleElectric/FeatureServer").apply { - // set user credentials to authenticate with the service - // NOTE: a licensed user is required to perform utility network operations - credential = UserCredential("viewer01", "I68VGU^nMurF") + private val utilityNetwork by lazy { + UtilityNetwork("https://sampleserver7.arcgisonline.com/server/rest/services/UtilityNetwork/NapervilleElectric/FeatureServer").apply { + // set user credentials to authenticate with the service + // NOTE: a licensed user is required to perform utility network operations + credential = UserCredential("viewer01", "I68VGU^nMurF") + } } - } - - private var initialExpression: UtilityTraceConditionalExpression? = null - private var sourceTier: UtilityTier? = null - private var sources: List? = null - private var operators: Array? = null - private var startingLocation: UtilityElement? = null - private var values: List? = null - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(activityMainBinding.root) - - exampleTextView.movementMethod = ScrollingMovementMethod() - - // create a utility network and wait for it to finish to load - utilityNetwork.loadAsync() - utilityNetwork.addDoneLoadingListener { - if (utilityNetwork.loadStatus == LoadStatus.LOADED) { - // create a list of utility network attributes whose system is not defined - sources = utilityNetwork.definition.networkAttributes.filter { !it.isSystemDefined } - .also { sources -> - - sourceSpinner.apply { - // assign an adapter to the spinner with source names - adapter = ArrayAdapter( - applicationContext, - android.R.layout.simple_list_item_1, - sources.map { it.name }) - - // add an on item selected listener which calls on comparison source changed - onItemSelectedListener = object : AdapterView.OnItemSelectedListener { - override fun onItemSelected( - parent: AdapterView<*>?, - view: View?, - position: Int, - id: Long - ) { - (sources[sourceSpinner.selectedItemPosition]) - onComparisonSourceChanged(sources[sourceSpinner.selectedItemPosition]) + + private var initialExpression: UtilityTraceConditionalExpression? = null + private var sourceTier: UtilityTier? = null + private var sources: List? = null + private var operators: Array? = null + private var startingLocation: UtilityElement? = null + private var values: List? = null + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(activityMainBinding.root) + + exampleTextView.movementMethod = ScrollingMovementMethod() + + // create a utility network and wait for it to finish to load + utilityNetwork.loadAsync() + utilityNetwork.addDoneLoadingListener { + if (utilityNetwork.loadStatus == LoadStatus.LOADED) { + // create a list of utility network attributes whose system is not defined + sources = utilityNetwork.definition.networkAttributes.filter { !it.isSystemDefined } + .also { sources -> + + sourceSpinner.apply { + // assign an adapter to the spinner with source names + adapter = ArrayAdapter( + applicationContext, + android.R.layout.simple_list_item_1, + sources.map { it.name }) + + // add an on item selected listener which calls on comparison source changed + onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, + view: View?, + position: Int, + id: Long + ) { + (sources[sourceSpinner.selectedItemPosition]) + onComparisonSourceChanged(sources[sourceSpinner.selectedItemPosition]) + } + + override fun onNothingSelected(parent: AdapterView<*>?) {} + } + } + } + + // create a list of utility attribute comparison operators + operators = UtilityAttributeComparisonOperator.values().also { operators -> + // assign operator spinner an adapter of operator names + operatorSpinner.adapter = ArrayAdapter( + applicationContext, + android.R.layout.simple_list_item_1, + operators.map { it.name }) } - override fun onNothingSelected(parent: AdapterView<*>?) {} - } - } - } - - // create a list of utility attribute comparison operators - operators = UtilityAttributeComparisonOperator.values().also { operators -> - // assign operator spinner an adapter of operator names - operatorSpinner.adapter = ArrayAdapter( - applicationContext, - android.R.layout.simple_list_item_1, - operators.map { it.name }) - } + // create a default starting location + val networkSource = + utilityNetwork.definition.getNetworkSource("Electric Distribution Device") + val assetGroup = networkSource.getAssetGroup("Circuit Breaker") + val assetType = assetGroup.getAssetType("Three Phase") + val globalId = java.util.UUID.fromString("1CAF7740-0BF4-4113-8DB2-654E18800028") - // create a default starting location - val networkSource = - utilityNetwork.definition.getNetworkSource("Electric Distribution Device") - val assetGroup = networkSource.getAssetGroup("Circuit Breaker") - val assetType = assetGroup.getAssetType("Three Phase") - val globalId = java.util.UUID.fromString("1CAF7740-0BF4-4113-8DB2-654E18800028") + // utility element to start the trace from + startingLocation = utilityNetwork.createElement(assetType, globalId).apply { + terminal = assetType.terminalConfiguration.terminals.first { it.name == "Load" } + } - // utility element to start the trace from - startingLocation = utilityNetwork.createElement(assetType, globalId).apply { - terminal = assetType.terminalConfiguration.terminals.first { it.name == "Load" } + // get a default trace configuration from a tier to update the UI + val domainNetwork = + utilityNetwork.definition.getDomainNetwork("ElectricDistribution") + sourceTier = domainNetwork.getTier("Medium Voltage Radial")?.apply { + (traceConfiguration.traversability.barriers as? UtilityTraceConditionalExpression)?.let { + expressionTextView.text = expressionToString(it) + initialExpression = it + } + // set the traversability scope + traceConfiguration.traversability.scope = UtilityTraversabilityScope.JUNCTIONS + } + } else { + ("Utility network failed to load!").also { + Toast.makeText(this, it, Toast.LENGTH_LONG).show() + Log.e(TAG, it) + } + } } + } - // get a default trace configuration from a tier to update the UI - val domainNetwork = utilityNetwork.definition.getDomainNetwork("ElectricDistribution") - sourceTier = domainNetwork.getTier("Medium Voltage Radial")?.apply { - (traceConfiguration.traversability.barriers as? UtilityTraceConditionalExpression)?.let { - expressionTextView.text = expressionToString(it) - initialExpression = it - } - // set the traversability scope - traceConfiguration.traversability.scope = UtilityTraversabilityScope.JUNCTIONS - } - } else { - ("Utility network failed to load!").also { - Toast.makeText(this, it, Toast.LENGTH_LONG).show() - Log.e(TAG, it) + /** + * When a comparison source attribute is chosen check if it's a coded value domain and, if it is, + * present a spinner of coded value domains. If not, show the correct UI view for the utility + * network attribute data type. + * + * @param attribute being compared + */ + private fun onComparisonSourceChanged(attribute: UtilityNetworkAttribute) { + // if the domain is a coded value domain + (attribute.domain as? CodedValueDomain)?.let { codedValueDomain -> + // update the list of coded values + values = codedValueDomain.codedValues + // show the values spinner + setVisible(valuesBackgroundView.id) + // update the values spinner adapter + valuesSpinner.adapter = ArrayAdapter( + applicationContext, + android.R.layout.simple_list_item_1, + // add the coded values from the coded value domain to the values spinner + codedValueDomain.codedValues.map { it.name } + ) + // if the domain is not a coded value domain + } ?: when (attribute.dataType) { + UtilityNetworkAttribute.DataType.BOOLEAN -> { + setVisible(valueBooleanButton.id) + } + UtilityNetworkAttribute.DataType.DOUBLE, UtilityNetworkAttribute.DataType.FLOAT -> { + // show the edit text and only allow numbers (decimals allowed) + valuesEditText.inputType = + InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL + setVisible(valuesEditText.id) + } + UtilityNetworkAttribute.DataType.INTEGER -> { + // show the edit text only allowing for integer input + valuesEditText.inputType = InputType.TYPE_CLASS_NUMBER + setVisible(valuesEditText.id) + } + else -> { + ("Unexpected utility network attribute data type.").also { + Toast.makeText(this, it, Toast.LENGTH_LONG).show() + Log.e(TAG, it) + } + } } - } } - } - - /** - * When a comparison source attribute is chosen check if it's a coded value domain and, if it is, - * present a spinner of coded value domains. If not, show the correct UI view for the utility - * network attribute data type. - * - * @param attribute being compared - */ - private fun onComparisonSourceChanged(attribute: UtilityNetworkAttribute) { - // if the domain is a coded value domain - (attribute.domain as? CodedValueDomain)?.let { codedValueDomain -> - // update the list of coded values - values = codedValueDomain.codedValues - // show the values spinner - setVisible(valuesBackgroundView.id) - // update the values spinner adapter - valuesSpinner.adapter = ArrayAdapter( - applicationContext, - android.R.layout.simple_list_item_1, - // add the coded values from the coded value domain to the values spinner - codedValueDomain.codedValues.map { it.name } - ) - // if the domain is not a coded value domain - } ?: when (attribute.dataType) { - UtilityNetworkAttribute.DataType.BOOLEAN -> { - setVisible(valueBooleanButton.id) - } - UtilityNetworkAttribute.DataType.DOUBLE, UtilityNetworkAttribute.DataType.FLOAT -> { - // show the edit text and only allow numbers (decimals allowed) - valuesEditText.inputType = - InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL - setVisible(valuesEditText.id) - } - UtilityNetworkAttribute.DataType.INTEGER -> { - // show the edit text only allowing for integer input - valuesEditText.inputType = InputType.TYPE_CLASS_NUMBER - setVisible(valuesEditText.id) - } - else -> { - ("Unexpected utility network attribute data type.").also { - Toast.makeText(this, it, Toast.LENGTH_LONG).show() - Log.e(TAG, it) + + /** + * Show the given UI view and hide the others which share the same space. + * + * @param id of the view to make visible + */ + private fun setVisible(id: Int) { + when (id) { + valuesBackgroundView.id -> { + valuesBackgroundView.visibility = View.VISIBLE + valueBooleanButton.visibility = View.GONE + valuesEditText.visibility = View.GONE + } + valuesEditText.id -> { + valuesEditText.visibility = View.VISIBLE + valueBooleanButton.visibility = View.GONE + valuesBackgroundView.visibility = View.GONE + } + valueBooleanButton.id -> { + valueBooleanButton.visibility = View.VISIBLE + valuesBackgroundView.visibility = View.GONE + valuesEditText.visibility = View.GONE + } } - } - } - } - - /** - * Show the given UI view and hide the others which share the same space. - * - * @param id of the view to make visible - */ - private fun setVisible(id: Int) { - when (id) { - valuesBackgroundView.id -> { - valuesBackgroundView.visibility = View.VISIBLE - valueBooleanButton.visibility = View.GONE - valuesEditText.visibility = View.GONE - } - valuesEditText.id -> { - valuesEditText.visibility = View.VISIBLE - valueBooleanButton.visibility = View.GONE - valuesBackgroundView.visibility = View.GONE - } - valueBooleanButton.id -> { - valueBooleanButton.visibility = View.VISIBLE - valuesBackgroundView.visibility = View.GONE - valuesEditText.visibility = View.GONE - } - } - } - - /** - * Add a new barrier condition to the trace options. - * - * @param view of the add button - */ - fun addCondition(view: View) { - // if source tier doesn't contain a trace configuration, create one - val traceConfiguration = sourceTier?.traceConfiguration ?: UtilityTraceConfiguration().apply { - // if the trace configuration doesn't contain traversability, create one - traversability ?: UtilityTraversability() } - // get the currently selected attribute - val attribute = sources?.get(sourceSpinner.selectedItemPosition) - attribute?.let { - // get the currently selected attribute operator - val attributeOperator = operators?.get(operatorSpinner.selectedItemPosition) - attributeOperator?.let { - // if the other value is a coded value domain - val otherValue = if (attribute.domain is CodedValueDomain) { - values?.get(valuesSpinner.selectedItemPosition)?.code?.let { - convertToDataType(it, attribute.dataType) - } - } else { - convertToDataType(valuesEditText.text, attribute.dataType) - } - try { - // NOTE: You may also create a UtilityNetworkAttributeComparison with another - // NetworkAttribute - var expression: UtilityTraceConditionalExpression = UtilityNetworkAttributeComparison( - attribute, - attributeOperator, - otherValue - ) - (traceConfiguration.traversability.barriers as? UtilityTraceConditionalExpression)?.let { otherExpression -> - // NOTE: You may also combine expressions with UtilityTraceAndCondition - expression = UtilityTraceOrCondition(otherExpression, expression) - } - traceConfiguration.traversability.barriers = expression - expressionTextView.text = expressionToString(expression) - } catch (e: Exception) { - val error = - "Error creating UtilityNetworkAttributeComparison! Did you forget to input a numeric value? ${e.message}" - Log.e(TAG, error) - Toast.makeText(this@MainActivity, error, Toast.LENGTH_LONG).show() - return + /** + * Add a new barrier condition to the trace options. + * + * @param view of the add button + */ + fun addCondition(view: View) { + // if source tier doesn't contain a trace configuration, create one + val traceConfiguration = + sourceTier?.traceConfiguration ?: UtilityTraceConfiguration().apply { + // if the trace configuration doesn't contain traversability, create one + traversability ?: UtilityTraversability() + } + + // get the currently selected attribute + val attribute = sources?.get(sourceSpinner.selectedItemPosition) + attribute?.let { + // get the currently selected attribute operator + val attributeOperator = operators?.get(operatorSpinner.selectedItemPosition) + attributeOperator?.let { + // if the other value is a coded value domain + val otherValue = if (attribute.domain is CodedValueDomain) { + values?.get(valuesSpinner.selectedItemPosition)?.code?.let { + convertToDataType(it, attribute.dataType) + } + } else { + convertToDataType(valuesEditText.text, attribute.dataType) + } + try { + // NOTE: You may also create a UtilityNetworkAttributeComparison with another + // NetworkAttribute + var expression: UtilityTraceConditionalExpression = + UtilityNetworkAttributeComparison( + attribute, + attributeOperator, + otherValue + ) + (traceConfiguration.traversability.barriers as? UtilityTraceConditionalExpression)?.let { otherExpression -> + // NOTE: You may also combine expressions with UtilityTraceAndCondition + expression = UtilityTraceOrCondition(otherExpression, expression) + } + traceConfiguration.traversability.barriers = expression + expressionTextView.text = expressionToString(expression) + } catch (e: Exception) { + val error = + "Error creating UtilityNetworkAttributeComparison! Did you forget to input a numeric value? ${e.message}" + Log.e(TAG, error) + Toast.makeText(this@MainActivity, error, Toast.LENGTH_LONG).show() + return + } + } } - } - } - } - - /** - * Run the network trace with the parameters and display the result in an alert dialog. - * - * @param view of the trace button - */ - fun trace(view: View) { - // don't attempt a trace on an unloaded utility network - if (utilityNetwork.loadStatus != LoadStatus.LOADED) { - return } - try { - val parameters = - UtilityTraceParameters(UtilityTraceType.SUBNETWORK, listOf(startingLocation)).apply { - sourceTier?.traceConfiguration?.let { - traceConfiguration = it - } + + /** + * Run the network trace with the parameters and display the result in an alert dialog. + * + * @param view of the trace button + */ + fun trace(view: View) { + // don't attempt a trace on an unloaded utility network + if (utilityNetwork.loadStatus != LoadStatus.LOADED) { + return } - val traceFuture = utilityNetwork.traceAsync(parameters) - traceFuture.addDoneListener { try { - val results = traceFuture.get() - (results.firstOrNull() as? UtilityElementTraceResult)?.let { elementResult -> - // create an alert dialog - AlertDialog.Builder(this).apply { - // set the alert dialog title - setTitle("Trace result") - // show the element result count - setMessage(elementResult.elements.count().toString() + " elements found.") - }.show() - } + val parameters = + UtilityTraceParameters( + UtilityTraceType.SUBNETWORK, + listOf(startingLocation) + ).apply { + sourceTier?.traceConfiguration?.let { + traceConfiguration = it + } + } + val traceFuture = utilityNetwork.traceAsync(parameters) + traceFuture.addDoneListener { + try { + val results = traceFuture.get() + (results.firstOrNull() as? UtilityElementTraceResult)?.let { elementResult -> + // create an alert dialog + AlertDialog.Builder(this).apply { + // set the alert dialog title + setTitle("Trace result") + // show the element result count + setMessage( + elementResult.elements.count().toString() + " elements found." + ) + }.show() + } + } catch (e: Exception) { + (e.cause?.message + "\nFor a working barrier condition, try \"Transformer Load\" Equal \"15\".").also { + Toast.makeText(this, it, Toast.LENGTH_LONG).show() + Log.e(TAG, it) + } + } + } } catch (e: Exception) { - (e.cause?.message + "\nFor a working barrier condition, try \"Transformer Load\" Equal \"15\".").also { - Toast.makeText(this, it, Toast.LENGTH_LONG).show() - Log.e(TAG, it) - } + ("Error during trace operation: " + e.message).also { + Toast.makeText(this, it, Toast.LENGTH_LONG).show() + Log.e(TAG, it) + } } - } - } catch (e: Exception) { - ("Error during trace operation: " + e.message).also { - Toast.makeText(this, it, Toast.LENGTH_LONG).show() - Log.e(TAG, it) - } } - } - - /** - * Convert the given UtilityTraceConditionalExpression into a string. - * - * @param expression to convert to a string - */ - private fun expressionToString(expression: UtilityTraceConditionalExpression): String? { - when (expression) { - // when the expression is a category comparison expression - is UtilityCategoryComparison -> { - return expression.category.name + " " + expression.comparisonOperator - } - // when the expression is an attribute comparison expression - is UtilityNetworkAttributeComparison -> { - // the name and comparison operator of the expression - val networkAttributeNameAndOperator = - expression.networkAttribute.name + " " + expression.comparisonOperator + " " - // check whether the network attribute has a coded value domain - (expression.networkAttribute.domain as? CodedValueDomain)?.let { codedValueDomain -> - // if there's a coded value domain name - val codedValueDomainName = codedValueDomain.codedValues.first { - convertToDataType(it.code, expression.networkAttribute.dataType) == - convertToDataType(expression.value, expression.networkAttribute.dataType) - }.name - return networkAttributeNameAndOperator + codedValueDomainName + + /** + * Convert the given UtilityTraceConditionalExpression into a string. + * + * @param expression to convert to a string + */ + private fun expressionToString(expression: UtilityTraceConditionalExpression): String? { + when (expression) { + // when the expression is a category comparison expression + is UtilityCategoryComparison -> { + return expression.category.name + " " + expression.comparisonOperator + } + // when the expression is an attribute comparison expression + is UtilityNetworkAttributeComparison -> { + // the name and comparison operator of the expression + val networkAttributeNameAndOperator = + expression.networkAttribute.name + " " + expression.comparisonOperator + " " + // check whether the network attribute has a coded value domain + (expression.networkAttribute.domain as? CodedValueDomain)?.let { codedValueDomain -> + // if there's a coded value domain name + val codedValueDomainName = codedValueDomain.codedValues.first { + convertToDataType(it.code, expression.networkAttribute.dataType) == + convertToDataType( + expression.value, + expression.networkAttribute.dataType + ) + }.name + return networkAttributeNameAndOperator + codedValueDomainName + } + // if there's no coded value domain name + ?: return networkAttributeNameAndOperator + (expression.otherNetworkAttribute?.name + ?: expression.value) + } + // when the expression is an utility trace AND condition + is UtilityTraceAndCondition -> { + return expressionToString(expression.leftExpression) + " AND\n" + expressionToString( + expression.rightExpression + ) + } + // when the expression is an utility trace OR condition + is UtilityTraceOrCondition -> { + return expressionToString(expression.leftExpression) + " OR\n" + expressionToString( + expression.rightExpression + ) + } + else -> { + return null + } } - // if there's no coded value domain name - ?: return networkAttributeNameAndOperator + (expression.otherNetworkAttribute?.name - ?: expression.value) - } - // when the expression is an utility trace AND condition - is UtilityTraceAndCondition -> { - return expressionToString(expression.leftExpression) + " AND\n" + expressionToString( - expression.rightExpression - ) - } - // when the expression is an utility trace OR condition - is UtilityTraceOrCondition -> { - return expressionToString(expression.leftExpression) + " OR\n" + expressionToString( - expression.rightExpression - ) - } - else -> { - return null - } } - } - - /** - * Reset the current barrier condition to the initial expression - * "Operational Device Status EQUAL Open". - * - * @param view of the rest button - */ - fun reset(view: View) { - initialExpression?.let { - val traceConfiguration = sourceTier?.traceConfiguration - traceConfiguration?.traversability?.barriers = it - expressionTextView.text = expressionToString(it) + + /** + * Reset the current barrier condition to the initial expression + * "Operational Device Status EQUAL Open". + * + * @param view of the rest button + */ + fun reset(view: View) { + initialExpression?.let { + val traceConfiguration = sourceTier?.traceConfiguration + traceConfiguration?.traversability?.barriers = it + expressionTextView.text = expressionToString(it) + } } - } - - /** - * Convert the given value into the correct Kotlin data type by using the attribute's data type. - * - * @param otherValue which will be converted - * @param dataType to be converted to - */ - private fun convertToDataType(otherValue: Any, dataType: UtilityNetworkAttribute.DataType): Any { - return try { - when (dataType) { - UtilityNetworkAttribute.DataType.BOOLEAN -> otherValue.toString().toBoolean() - UtilityNetworkAttribute.DataType.DOUBLE -> otherValue.toString().toDouble() - UtilityNetworkAttribute.DataType.FLOAT -> otherValue.toString().toFloat() - UtilityNetworkAttribute.DataType.INTEGER -> otherValue.toString().toInt() - } - } catch (e: Exception) { - ("Error converting data type: " + e.message).also { - Toast.makeText(this, it, Toast.LENGTH_LONG).show() - Log.e(TAG, it) - } + + /** + * Convert the given value into the correct Kotlin data type by using the attribute's data type. + * + * @param otherValue which will be converted + * @param dataType to be converted to + */ + private fun convertToDataType( + otherValue: Any, + dataType: UtilityNetworkAttribute.DataType + ): Any { + return try { + when (dataType) { + UtilityNetworkAttribute.DataType.BOOLEAN -> otherValue.toString().toBoolean() + UtilityNetworkAttribute.DataType.DOUBLE -> otherValue.toString().toDouble() + UtilityNetworkAttribute.DataType.FLOAT -> otherValue.toString().toFloat() + UtilityNetworkAttribute.DataType.INTEGER -> otherValue.toString().toInt() + } + } catch (e: Exception) { + ("Error converting data type: " + e.message).also { + Toast.makeText(this, it, Toast.LENGTH_LONG).show() + Log.e(TAG, it) + } + } } - } } diff --git a/kotlin/convex-hull/src/main/java/com/esri/arcgisruntime/sample/convexhull/MainActivity.kt b/kotlin/convex-hull/src/main/java/com/esri/arcgisruntime/sample/convexhull/MainActivity.kt index c39a94b9a9..683f4bb86a 100644 --- a/kotlin/convex-hull/src/main/java/com/esri/arcgisruntime/sample/convexhull/MainActivity.kt +++ b/kotlin/convex-hull/src/main/java/com/esri/arcgisruntime/sample/convexhull/MainActivity.kt @@ -41,114 +41,115 @@ import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol class MainActivity : AppCompatActivity() { - private val activityMainBinding by lazy { - ActivityMainBinding.inflate(layoutInflater) - } - - private val mapView: MapView by lazy { - activityMainBinding.mapView - } - - private val createButton: Button by lazy { - activityMainBinding.createButton - } - - private val resetButton: Button by lazy { - activityMainBinding.resetButton - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(activityMainBinding.root) - - // authentication with an API key or named user is required to access basemaps and other - // location services - ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY) - - // create an array list to store points - val inputPoints = arrayListOf() - - // create a symbol and graphic to represent single points - val pointSymbol = SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, Color.RED, 10F) - val pointGraphic = Graphic().apply { symbol = pointSymbol } - - // create a graphic for the convex hull consisting of a line and empty interior - val lineSymbol = SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.BLUE, 3F) - val fillSymbol = SimpleFillSymbol(SimpleFillSymbol.Style.NULL, Color.TRANSPARENT, lineSymbol) - val convexHullGraphic = Graphic() - - // create a graphics overlay and add the graphics to it - val graphicsOverlay = GraphicsOverlay() - graphicsOverlay.graphics.addAll(listOf(pointGraphic, convexHullGraphic)) - - mapView.apply { - // set the map to a topographic basemap - map = ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC) - // add the graphics overlay to the map - graphicsOverlays.add(graphicsOverlay) - - onTouchListener = object : DefaultMapViewOnTouchListener(this@MainActivity, mapView) { - override fun onSingleTapConfirmed(e: MotionEvent): Boolean { - // get the tapped point and convert it to a screen point - val point = android.graphics.Point(e.x.toInt(), e.y.toInt()) - val convertedPoint = mapView.screenToLocation(point) - - // add the new point to the list and recreate the graphic representing the input points - inputPoints.add(convertedPoint) - val multiPoint = Multipoint(PointCollection(inputPoints)) - pointGraphic.geometry = multiPoint - - if (inputPoints.isNotEmpty()) { - createButton.isEnabled = true - resetButton.isEnabled = true - } - - return super.onSingleTapConfirmed(e) + private val activityMainBinding by lazy { + ActivityMainBinding.inflate(layoutInflater) + } + + private val mapView: MapView by lazy { + activityMainBinding.mapView + } + + private val createButton: Button by lazy { + activityMainBinding.createButton + } + + private val resetButton: Button by lazy { + activityMainBinding.resetButton + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(activityMainBinding.root) + + // authentication with an API key or named user is required to access basemaps and other + // location services + ArcGISRuntimeEnvironment.setApiKey(BuildConfig.API_KEY) + + // create an array list to store points + val inputPoints = arrayListOf() + + // create a symbol and graphic to represent single points + val pointSymbol = SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, Color.RED, 10F) + val pointGraphic = Graphic().apply { symbol = pointSymbol } + + // create a graphic for the convex hull consisting of a line and empty interior + val lineSymbol = SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.BLUE, 3F) + val fillSymbol = + SimpleFillSymbol(SimpleFillSymbol.Style.NULL, Color.TRANSPARENT, lineSymbol) + val convexHullGraphic = Graphic() + + // create a graphics overlay and add the graphics to it + val graphicsOverlay = GraphicsOverlay() + graphicsOverlay.graphics.addAll(listOf(pointGraphic, convexHullGraphic)) + + mapView.apply { + // set the map to a topographic basemap + map = ArcGISMap(BasemapStyle.ARCGIS_TOPOGRAPHIC) + // add the graphics overlay to the map + graphicsOverlays.add(graphicsOverlay) + + onTouchListener = object : DefaultMapViewOnTouchListener(this@MainActivity, mapView) { + override fun onSingleTapConfirmed(e: MotionEvent): Boolean { + // get the tapped point and convert it to a screen point + val point = android.graphics.Point(e.x.toInt(), e.y.toInt()) + val convertedPoint = mapView.screenToLocation(point) + + // add the new point to the list and recreate the graphic representing the input points + inputPoints.add(convertedPoint) + val multiPoint = Multipoint(PointCollection(inputPoints)) + pointGraphic.geometry = multiPoint + + if (inputPoints.isNotEmpty()) { + createButton.isEnabled = true + resetButton.isEnabled = true + } + + return super.onSingleTapConfirmed(e) + } + } + } + + // create the convex hull when the button is pressed + createButton.setOnClickListener { + // normalize the points for panning beyond the meridian + val normalizedPoints = GeometryEngine.normalizeCentralMeridian(pointGraphic.geometry) + // create a convex hull from the points + val convexHull = GeometryEngine.convexHull(normalizedPoints) + // the convex hull's geometry may be a point or polyline if the number of points is less than 3 + convexHullGraphic.symbol = when (convexHull.geometryType) { + GeometryType.POINT -> pointSymbol + GeometryType.POLYLINE -> lineSymbol + GeometryType.POLYGON -> fillSymbol + else -> null + } + // set the convex hull graphic to display the new geometry + convexHullGraphic.geometry = convexHull + // disable the button + createButton.isEnabled = false } - } + + // clear the points and graphics and disable the buttons when reset is tapped + resetButton.setOnClickListener { + inputPoints.clear() + pointGraphic.geometry = null + convexHullGraphic.geometry = null + resetButton.isEnabled = false + createButton.isEnabled = false + } + } + + override fun onResume() { + super.onResume() + mapView.resume() } - // create the convex hull when the button is pressed - createButton.setOnClickListener { - // normalize the points for panning beyond the meridian - val normalizedPoints = GeometryEngine.normalizeCentralMeridian(pointGraphic.geometry) - // create a convex hull from the points - val convexHull = GeometryEngine.convexHull(normalizedPoints) - // the convex hull's geometry may be a point or polyline if the number of points is less than 3 - convexHullGraphic.symbol = when (convexHull.geometryType) { - GeometryType.POINT -> pointSymbol - GeometryType.POLYLINE -> lineSymbol - GeometryType.POLYGON -> fillSymbol - else -> null - } - // set the convex hull graphic to display the new geometry - convexHullGraphic.geometry = convexHull - // disable the button - createButton.isEnabled = false + override fun onPause() { + mapView.pause() + super.onPause() } - // clear the points and graphics and disable the buttons when reset is tapped - resetButton.setOnClickListener { - inputPoints.clear() - pointGraphic.geometry = null - convexHullGraphic.geometry = null - resetButton.isEnabled = false - createButton.isEnabled = false + override fun onDestroy() { + mapView.dispose() + super.onDestroy() } - } - - override fun onResume() { - super.onResume() - mapView.resume() - } - - override fun onPause() { - mapView.pause() - super.onPause() - } - - override fun onDestroy() { - mapView.dispose() - super.onDestroy() - } } diff --git a/kotlin/convex-hull/src/main/res/layout/activity_main.xml b/kotlin/convex-hull/src/main/res/layout/activity_main.xml index 9f2def00ac..740bccfaae 100644 --- a/kotlin/convex-hull/src/main/res/layout/activity_main.xml +++ b/kotlin/convex-hull/src/main/res/layout/activity_main.xml @@ -9,8 +9,7 @@ + android:layout_height="match_parent" />