Query on mobile map package (mmpk)

2070
2
Jump to solution
06-27-2018 01:31 PM
CharlesLoftis
New Contributor III

BACKGROUND

I am using the ArcGIS Runtime SDK for Andorid (100.2.1).

I am being provided with mobile map packages (mmpk) by my GIS department. The mmpks contain several vector layers - one layer has an attribute named "Page". Another layer has an attribute named "Segid". The layers containing "Page" and "Segid" shapes are polygons that I would like to programatically select and zoom to.

So, using ArcGIS Runtime SDK for Andorid (100.2.1)...

QUESTIONS

  • How do I query for a list of "Segid"s and/or "Page"s contained in the mmpk?
  • How do I get a count of the number of "Segid"s and/or "Page"s contained in the mmpk?
  • How do I select a polygon ("Page" or "Segid") feature and zoom to it?
0 Kudos
1 Solution

Accepted Solutions
EricBader
Occasional Contributor III

You can first open the mobile map package to get the map(s) containing your vector (feature) layers that contain the polygons you want to get.

// create a map view
mapView = new MapView();

//load a mobile map package
final String mmpkPath  = new File("./samples-data/mmpk/Yellowstone.mmpk").getAbsolutePath();


MobileMapPackage mobileMapPackage = new MobileMapPackage(mmpkPath);

mobileMapPackage.loadAsync();mobileMapPackage.addDoneLoadingListener(() -> {
     if (mobileMapPackage.getLoadStatus() == LoadStatus.LOADED && mobileMapPackage.getMaps().size() > 0) {
        //add the map from the mobile map package to the map view
        mapView.setMap(mobileMapPackage.getMaps().get(0));
     } else {
       Alert alert = new Alert(Alert.AlertType.ERROR, "Failed to load the mobile map package");
       alert.show();
    }
});

You will now have access to the map's operational layers, and you can find the one you need from that list. Just like any other feature layer from any other data source, you can query for Segids and Pages, using FeatureLayer.selectFeaturesAsync.

The FeatureQueryResult will give you access to the number of selected segids and pages.

You can iterate through each feature in the result, collect the geometry extent for each polygon, merge them using GeometryEngine, then zoom to the merged geometries using MapView.setViewpointGeometryAsync() - MapView| arcgis-android 

I think some good examples to look at are:

Open Mobile Map Package—ArcGIS Runtime SDK for Android | ArcGIS for Developers 

Feature Layer Query—ArcGIS Runtime SDK for Android | ArcGIS for Developers 

View solution in original post

2 Replies
EricBader
Occasional Contributor III

You can first open the mobile map package to get the map(s) containing your vector (feature) layers that contain the polygons you want to get.

// create a map view
mapView = new MapView();

//load a mobile map package
final String mmpkPath  = new File("./samples-data/mmpk/Yellowstone.mmpk").getAbsolutePath();


MobileMapPackage mobileMapPackage = new MobileMapPackage(mmpkPath);

mobileMapPackage.loadAsync();mobileMapPackage.addDoneLoadingListener(() -> {
     if (mobileMapPackage.getLoadStatus() == LoadStatus.LOADED && mobileMapPackage.getMaps().size() > 0) {
        //add the map from the mobile map package to the map view
        mapView.setMap(mobileMapPackage.getMaps().get(0));
     } else {
       Alert alert = new Alert(Alert.AlertType.ERROR, "Failed to load the mobile map package");
       alert.show();
    }
});

You will now have access to the map's operational layers, and you can find the one you need from that list. Just like any other feature layer from any other data source, you can query for Segids and Pages, using FeatureLayer.selectFeaturesAsync.

The FeatureQueryResult will give you access to the number of selected segids and pages.

You can iterate through each feature in the result, collect the geometry extent for each polygon, merge them using GeometryEngine, then zoom to the merged geometries using MapView.setViewpointGeometryAsync() - MapView| arcgis-android 

I think some good examples to look at are:

Open Mobile Map Package—ArcGIS Runtime SDK for Android | ArcGIS for Developers 

Feature Layer Query—ArcGIS Runtime SDK for Android | ArcGIS for Developers 

CharlesLoftis
New Contributor III

Eric,

Thanks for the reply. I reviewed both of the examples you linked and found them helpful. Pasted below is the code that I've come up with - it works, but I'm having to query each layer because I don't know the name of the layer that contains the "Page" numbers. (I'm not creating my own mmpks, just consuming ones that have been previously created by my GIS group.) This works but throws Exceptions (that are being caught and ignored) - not very elegant. If I knew the name of the layer containing the "Page" attributes I could just query the layer of interest. Is there a way to query the map for a specific layer (by name?) or is accessing a specific layer an exercise in iterating through all the operational layers as I've done below?

    LayerList mMapOperationalLayers = arcGISMap.getOperationalLayers(); // get LayerList from Map
    for (final Layer layer : mMapOperationalLayers) {
       Log.d("layer", layer.getName() + ", " + layer.getFullExtent().toJson());
       FeatureLayer featureLayer = (FeatureLayer) layer;
       FeatureTable featureTable = featureLayer.getFeatureTable();
       QueryParameters queryParameters = new QueryParameters();
       queryParameters.setWhereClause(String.format("PAGE=%1$s", page_number));
       final ListenableFuture listenableFuture = featureTable.queryFeaturesAsync(queryParameters);
       listenableFuture.addDoneListener(new Runnable() {
          @Override
          public void run() {
             try {
                Object result = listenableFuture.get();
                FeatureQueryResult featureQueyResult = (FeatureQueryResult) result;
                if (featureQueyResult.iterator().hasNext()) {
                   // get extent of 1st feature in result & zoom to it
                   Feature feature = featureQueyResult.iterator().next();
                   Envelope envelope = feature.getGeometry().getExtent();
                   mMapView.setViewpointGeometryAsync(envelope, 50);
                   //Select the feature
                   //((FeatureLayer) layer).selectFeature(feature);
                } else {
                   //Toast.makeText(MainActivity.this, "No page found with number: " + page_number, Toast.LENGTH_SHORT).show();
                }
             } catch (Exception e) {
                Log.e(TAG, e.getMessage());
             }
           }
       });
0 Kudos