Android Open Source - arcgis-runtime-samples-android Layer Query Task






From Project

Back to project page arcgis-runtime-samples-android.

License

The source code is released under:

Apache License

If you think the Android project arcgis-runtime-samples-android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/* Copyright 2014 ESRI
 *//from w  w  w .j a  va2  s  . c  o m
 * 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.arcgis.android.samples.PopupUICustomization;

import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;

import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.view.ViewGroup;

import com.esri.android.map.GroupLayer;
import com.esri.android.map.Layer;
import com.esri.android.map.MapView;
import com.esri.android.map.ags.ArcGISDynamicMapServiceLayer;
import com.esri.android.map.ags.ArcGISFeatureLayer;
import com.esri.android.map.ags.ArcGISLayerInfo;
import com.esri.android.map.ags.ArcGISTiledMapServiceLayer;
import com.esri.android.map.popup.ArcGISAttributeView;
import com.esri.android.map.popup.ArcGISTitleView;
import com.esri.android.map.popup.ArcGISValueFormat;
import com.esri.android.map.popup.Popup;
import com.esri.android.map.popup.PopupLayout;
import com.esri.android.map.popup.PopupLayoutInfo;
import com.esri.core.geometry.Envelope;
import com.esri.core.geometry.Geometry;
import com.esri.core.geometry.Point;
import com.esri.core.geometry.SpatialReference;
import com.esri.core.map.Feature;
import com.esri.core.map.FeatureResult;
import com.esri.core.map.Graphic;
import com.esri.core.map.popup.PopupInfo;
import com.esri.core.tasks.query.QueryParameters;
import com.esri.core.tasks.query.QueryTask;

/*
 * This class will loop through and query each layer in the mapview. The query result will
 * be displayed in pop-ups. The layout and style of the pop-ups will be customized through
 * XML and sub-classes of some built-in classes of the pop-up API. 
 */
public class LayerQueryTask {
  private MapView mMapView;
  private PopupFragment mPopupFragment;
  private AtomicInteger mCount;
  private boolean mShowGeometryInfo;

  public LayerQueryTask(MapView map, PopupFragment popupFragment) {
    this.mMapView = map;
    this.mPopupFragment = popupFragment;
  }

  // Query each layer in the mapview in async tasks then display result in
  // customized pop-ups.
  public void queryLayers(float x, float y, int tolerance,
      boolean showGeometryInfo) {
    if ((mMapView == null) || (!mMapView.isLoaded())
        || (mPopupFragment == null))
      return;

    this.mShowGeometryInfo = showGeometryInfo;

    // Loop through each layer in the mapview
    Envelope env = new Envelope(mMapView.toMapPoint(x, y), tolerance
        * mMapView.getResolution(), tolerance
        * mMapView.getResolution());
    Layer[] layers = mMapView.getLayers();
    mCount = new AtomicInteger();
    for (Layer layer : layers) {
      // If the layer has not been initialized or is invisible, do
      // nothing.
      if ((!layer.isInitialized()) || (!layer.isVisible()))
        continue;

      if (layer instanceof GroupLayer) {
        Layer[] sublayers = ((GroupLayer) layer).getLayers();
        if (sublayers != null) {
          for (Layer flayer : sublayers) {
            ArcGISFeatureLayer featureLayer = (ArcGISFeatureLayer) flayer;
            if (featureLayer.getPopupInfo() != null) {
              // Query feature layer which is associated with a
              // pop-up definition.
              mCount.incrementAndGet();
              new RunQueryFeatureLayerTask(x, y, tolerance)
                  .execute(featureLayer);
            }
          }
        }
      } else if (layer instanceof ArcGISFeatureLayer) {
        // Query feature layer and display pop-ups
        ArcGISFeatureLayer featureLayer = (ArcGISFeatureLayer) layer;
        if (featureLayer.getPopupInfo() != null) {
          // Query feature layer which is associated with a popup
          // definition.
          mCount.incrementAndGet();
          new RunQueryFeatureLayerTask(x, y, tolerance)
              .execute(featureLayer);
        }
      } else if ((layer instanceof ArcGISDynamicMapServiceLayer)
          || (layer instanceof ArcGISTiledMapServiceLayer)) {
        // Query dynamic map service layer and display pop-ups.
        ArcGISLayerInfo[] layerinfos;
        // Retrieve layer info for each sub-layer of the dynamic map
        // service layer.
        if (layer instanceof ArcGISDynamicMapServiceLayer)
          layerinfos = ((ArcGISDynamicMapServiceLayer) layer)
              .getAllLayers();
        else
          layerinfos = ((ArcGISTiledMapServiceLayer) layer)
              .getAllLayers();

        if (layerinfos == null)
          continue;

        // Loop through each sub-layer
        for (ArcGISLayerInfo layerInfo : layerinfos) {
          // Obtain PopupInfo for sub-layer.
          int subLayerId = layerInfo.getId();
          // Check if a sub-layer is visible by checking its
          // visibility and tracing back to its parent.
          // A sub-layer's visibility depends on the visibility of
          // itself and its parent. When a sub-layer
          // is visible but its parent is invisible, its visibility is
          // false. So need to track back to its parent.
          ArcGISLayerInfo info = layerInfo;
          // If a sub-layer is visible then get hold of its parent and
          // check the parent's visibility.
          // Continue till the current sub-layer is invisible or
          // reaches the root.
          while ((info != null) && (info.isVisible()))
            info = info.getParentLayer();
          // If the current sub-layer is invisible skip it.
          if ((info != null) && (!info.isVisible()))
            continue;

          // Check if the sub-layer is within the scale range
          double maxScale = layerInfo.getMaxScale();
          double minScale = layerInfo.getMinScale();

          if (((maxScale == 0) || (mMapView.getScale() > maxScale))
              && ((minScale == 0) || (mMapView.getScale() < minScale))) {
            // Query sub-layer which is associated with a pop-up
            // definition and is visible and in scale range.
            String url = layer.getQueryUrl(subLayerId);
            if ((url == null) || (url.length() < 1))
              url = layer.getUrl() + "/" + subLayerId;
            mCount.incrementAndGet();
            new RunQueryDynamicLayerTask(env, layer,
                layerInfo.getId(), layer.getSpatialReference())
                .execute(url);
          }
        }
      }
    }

  }

  // Create a customized layout for a pop-up.
  private PopupLayoutInfo createPopupLayout(Context context) {

    PopupLayoutInfo layoutInfo = new PopupLayoutInfo();
    // inflate the layout from xml
    ViewGroup xmlLayout = (ViewGroup) ((Activity) context)
        .getLayoutInflater().inflate(R.layout.popup_layout, null);
    // set the xml layout on the pop-up layout
    layoutInfo.setLayout(xmlLayout);

    // Set the place holders for the four basic views in a pop-up.
    layoutInfo.setTitleViewPlaceHolder((ViewGroup) xmlLayout
        .findViewById(R.id.title_view_placeholder));
    layoutInfo.setAttributesViewPlaceHolder((ViewGroup) xmlLayout
        .findViewById(R.id.attribute_view_placeholder));
    layoutInfo.setMediaViewPlaceHolder((ViewGroup) xmlLayout
        .findViewById(R.id.media_view_placeholder));
    layoutInfo.setAttachmentsViewPlaceHolder((ViewGroup) xmlLayout
        .findViewById(R.id.attachment_view_placeholder));

    return layoutInfo;
  }

  // Customize the four basic views of a pop-up via xml and sub-classes.
  private void createViews(Popup popup) {
    if ((popup == null) || (popup.getLayout() == null))
      return;

    PopupLayout popupLayout = popup.getLayout();
    Context context = mMapView.getContext();

    // Create a view for the title
    popupLayout.setTitleView(new MyTitleView(context, popup, mMapView));

    // Create a view for attributes
    popupLayout.setAttributesView(new ArcGISAttributeView(context, popup));
    ArcGISAttributeView attributeView = (ArcGISAttributeView) popupLayout
        .getAttributesView();
    // Create an adapter for the attributes in read-only mode
    attributeView.setReadOnlyAdapter(new MyReadOnlyAttributesAdapter(
        context, popup));
    // Create an adapter for the attributes in edit mode
    attributeView
        .setEditAdapter(new MyEditAttributesAdapter(context, popup));

    // Change the view for the attachments
    if ((popup.getPopupInfo() != null)
        && (popup.getPopupInfo().isShowAttachments())) {
      popupLayout
          .setAttachmentsView(new MyAttachmentsView(context, popup));
    }

    // Change the view for the media
    popupLayout.setMediaView(new MyMediaView(context, popup));
  }

  // Compose geometry info for a feature based on its geometry type.
  private String getGeometryInfo(Graphic graphic,
      ArcGISValueFormat valueFormat) {
    Geometry geometry = graphic.getGeometry();
    String geometryInfo = null;
    if (geometry == null) {
      geometryInfo = "Missing location";
    } else {
      String unit = mMapView.getSpatialReference().getUnit()
          .getDisplayName();
      switch (graphic.getGeometry().getType()) {
      case ENVELOPE:
      case POLYGON:
      case MULTIPOINT:
        geometryInfo = "Area: "
            + valueFormat.formatValue(new Double(geometry
                .calculateArea2D())) + " Square " + unit + "s";
        break;
      case LINE:
      case POLYLINE:
        geometryInfo = "Distance: "
            + valueFormat.formatValue(new Double(geometry
                .calculateLength2D())) + " " + unit + "s";
        break;
      case POINT:
      default:
        geometryInfo = "X: "
            + valueFormat.formatValue(new Double(((Point) geometry)
                .getX()))
            + ", Y:"
            + valueFormat.formatValue(new Double(((Point) geometry)
                .getY()));
      }
    }

    return geometryInfo;
  }

  // Query dynamic map service layer by QueryTask
  private class RunQueryDynamicLayerTask extends
      AsyncTask<String, Void, FeatureResult> {

    private Envelope env;
    private SpatialReference sr;
    private Layer layer;
    private int subLayerId;

    public RunQueryDynamicLayerTask(Envelope env, Layer layer,
        int subLayerId, SpatialReference sr) {
      super();
      this.env = env;
      this.sr = sr;
      this.layer = layer;
      this.subLayerId = subLayerId;
    }

    @Override
    protected FeatureResult doInBackground(String... urls) {

      for (String url : urls) {
        PopupInfo popupInfo = layer.getPopupInfo(subLayerId);
        // Skip sub-layer which is without a pop-up definition.
        if (popupInfo == null)
          continue;

        // Retrieve graphics within the envelope.
        QueryParameters queryParams = new QueryParameters();
        queryParams.setInSpatialReference(sr);
        queryParams.setOutSpatialReference(sr);
        queryParams.setGeometry(env);
        queryParams.setMaxFeatures(10);
        queryParams.setOutFields(new String[] { "*" });

        try {
          QueryTask queryTask;
          queryTask = new QueryTask(url, layer.getCredentials());

          FeatureResult results = queryTask.execute(queryParams);
          return results;
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
      return null;
    }

    @Override
    protected void onPostExecute(final FeatureResult result) {
      // Validate parameter.
      mCount.decrementAndGet();
      if (result == null)
        return;

      // iterate through results
      for (Object element : result) {
        // if object is a feature cast to feature
        if (element instanceof Feature) {
          Feature feature = (Feature) element;
          // convert feature to graphic
          Graphic graphic = new Graphic(feature.getGeometry(), null,
              feature.getAttributes());
          PopupLayoutInfo layout = createPopupLayout(mMapView
              .getContext());
          Popup popup = layer.createPopup(mMapView, subLayerId,
              graphic, layout, false);
          createViews(popup);

          if (mShowGeometryInfo) {
            ArcGISValueFormat valueFormat = new ArcGISValueFormat(
                popup);
            ArcGISTitleView titleView = (ArcGISTitleView) popup
                .getLayout().getTitleView();
            titleView.setGeometryInfo(getGeometryInfo(graphic,
                valueFormat));
          }

          mPopupFragment.addPopup(popup);
          mPopupFragment.show();
        }
      }

    }

  }

  // Query feature layer by hit-test
  private class RunQueryFeatureLayerTask extends
      AsyncTask<ArcGISFeatureLayer, Void, Graphic[]> {

    private int tolerance;
    private float x;
    private float y;
    private ArcGISFeatureLayer featureLayer;

    public RunQueryFeatureLayerTask(float x, float y, int tolerance) {
      super();
      this.x = x;
      this.y = y;
      this.tolerance = tolerance;
    }

    @Override
    protected Graphic[] doInBackground(ArcGISFeatureLayer... params) {
      for (ArcGISFeatureLayer agsFeatureLayer : params) {
        this.featureLayer = agsFeatureLayer;
        // Retrieve graphic ids near the point.
        int[] ids = agsFeatureLayer.getGraphicIDs(x, y, tolerance);
        if ((ids != null) && (ids.length > 0)) {
          ArrayList<Graphic> graphics = new ArrayList<Graphic>();
          for (int id : ids) {
            // Obtain graphic based on the id.
            Graphic g = agsFeatureLayer.getGraphic(id);
            if (g == null)
              continue;
            graphics.add(g);
          }
          // Return an array of graphics near the point.
          return graphics.toArray(new Graphic[0]);
        }
      }

      return null;
    }

    @Override
    protected void onPostExecute(Graphic[] graphics) {
      mCount.decrementAndGet();
      // Validate parameter.
      if (graphics == null || graphics.length == 0)
        return;

      PopupInfo popupInfo = featureLayer.getPopupInfo();
      if (popupInfo == null)
        return;

      for (Graphic gr : graphics) {
        PopupLayoutInfo layout = createPopupLayout(mMapView
            .getContext());
        Popup popup = featureLayer.createPopup(mMapView, 0, gr, layout,
            false);
        createViews(popup);

        if (mShowGeometryInfo) {
          ArcGISValueFormat valueFormat = new ArcGISValueFormat(popup);
          ArcGISTitleView titleView = (ArcGISTitleView) popup
              .getLayout().getTitleView();
          titleView.setGeometryInfo(getGeometryInfo(gr, valueFormat));
        }
        mPopupFragment.addPopup(popup);
        mPopupFragment.show();
      }

    }

  }
}




Java Source Code List

com.arcgis.android.samples.ExportTileCacheTask.ExportTileCacheTaskSampleActivity.java
com.arcgis.android.samples.cloudportal.featureservicetablequery.MainActivity.java
com.arcgis.android.samples.cloudportal.querycloudfeatureservice.MainActivity.java
com.arcgis.android.samples.dynamiclayer.DynamicLayerRendererActivity.java
com.arcgis.android.samples.geometrysample.BufferFragment.java
com.arcgis.android.samples.geometrysample.GeometrySampleActivity.java
com.arcgis.android.samples.geometrysample.GeometryUtil.java
com.arcgis.android.samples.geometrysample.SampleListFragment.java
com.arcgis.android.samples.geometrysample.SpatialRelationshipsFragment.java
com.arcgis.android.samples.geometrysample.UnionDifferenceFragment.java
com.arcgis.android.samples.localdata.localrasterdata.EditTextUtils.java
com.arcgis.android.samples.localdata.localrasterdata.FileBrowserFragment.java
com.arcgis.android.samples.localdata.localrasterdata.HillshadeRendererParametersFragment.java
com.arcgis.android.samples.localdata.localrasterdata.MainActivity.java
com.arcgis.android.samples.localdata.localrasterdata.OnDialogDismissListener.java
com.arcgis.android.samples.localdata.localrasterdata.RendererType.java
com.arcgis.android.samples.localdata.localrasterdata.StretchParametersFragment.java
com.arcgis.android.samples.maps.basemaps.MainActivity.java
com.arcgis.android.samples.maps.fragmentmanagement.BasemapListFragment.java
com.arcgis.android.samples.maps.fragmentmanagement.MainActivity.java
com.arcgis.android.samples.maps.fragmentmanagement.MapFragment.java
com.arcgis.android.samples.maps.helloworld.MainActivity.java
com.arcgis.android.samples.maps.maplegend.LegendDialogFragment.java
com.arcgis.android.samples.maps.maplegend.MainActivity.java
com.arcgis.android.samples.maps.maprotation.Compass.java
com.arcgis.android.samples.maps.maprotation.MainActivity.java
com.arcgis.android.samples.maps.switchmaps.MainActivity.java
com.arcgis.android.samples.maps.switchmaps.MapFragment.java
com.arcgis.android.samples.milsym2525c.MainActivity.java
com.arcgis.android.samples.milsym2525c.Mil2525cMessageParser.java
com.arcgis.android.samples.oauth2sample.MapFragment.java
com.arcgis.android.samples.oauth2sample.OAuth2Sample.java
com.arcgis.android.samples.oauth2sample.UserContentActivity.java
com.arcgis.android.samples.oauth2sample.UserContentArrayAdapter.java
com.arcgis.android.samples.oauth2sample.UserContentFragment.java
com.arcgis.android.samples.oauth2sample.UserWebmaps.java
com.arcgis.android.samples.search.placesearch.MainActivity.java
com.esri.android.sample.closestfacilities.MainActivity.java
com.esri.android.samples.mbtiles.LocalMBTiles.java
com.esri.android.samples.mbtiles.MBTilesLayer.java
com.esri.android.samples.mgrsgrid.LocateMGRSActivity.java
com.esri.arcgis.android.sample.runtimegeodb.CreateRuntimeGeodatabaseActivity.java
com.esri.arcgis.android.sample.simplemap.SimpleMapActivity.java
com.esri.arcgis.android.sample.simplemap.SimpleMapFragment.java
com.esri.arcgis.android.sample.simplemap.SingleFragmentActivity.java
com.esri.arcgis.android.samples.GeoJSONEarthquakeMap.GeoJSONEarthquakeMapActivity.java
com.esri.arcgis.android.samples.PopupUICustomization.LayerQueryTask.java
com.esri.arcgis.android.samples.PopupUICustomization.MyAttachmentsView.java
com.esri.arcgis.android.samples.PopupUICustomization.MyEditAttributesAdapter.java
com.esri.arcgis.android.samples.PopupUICustomization.MyMediaAdapter.java
com.esri.arcgis.android.samples.PopupUICustomization.MyMediaView.java
com.esri.arcgis.android.samples.PopupUICustomization.MyReadOnlyAttributesAdapter.java
com.esri.arcgis.android.samples.PopupUICustomization.MyTitleView.java
com.esri.arcgis.android.samples.PopupUICustomization.PopupFragment.java
com.esri.arcgis.android.samples.PopupUICustomization.PopupUICustomizationActivity.java
com.esri.arcgis.android.samples.addcsv2graphic.AddCSVActivity.java
com.esri.arcgis.android.samples.attributeeditor.AttributeEditorActivity.java
com.esri.arcgis.android.samples.attributeeditor.AttributeItem.java
com.esri.arcgis.android.samples.attributeeditor.AttributeListAdapter.java
com.esri.arcgis.android.samples.attributeeditor.FeatureLayerUtils.java
com.esri.arcgis.android.samples.basiclicense.MainActivity.java
com.esri.arcgis.android.samples.basiclicense.MessageDialogFragment.java
com.esri.arcgis.android.samples.classbreaksrenderer.ClassBreaksRendererActivity.java
com.esri.arcgis.android.samples.featuredusergroup.FeaturedGroupsActivity.java
com.esri.arcgis.android.samples.featuredusergroup.GroupsFragment.java
com.esri.arcgis.android.samples.featuredusergroup.ItemsFragment.java
com.esri.arcgis.android.samples.featuredusergroup.MapActivity.java
com.esri.arcgis.android.samples.geometryeditor.ConfirmDiscardDialogFragment.java
com.esri.arcgis.android.samples.geometryeditor.EditFailedDialogFragment.java
com.esri.arcgis.android.samples.geometryeditor.FeatureTypeData.java
com.esri.arcgis.android.samples.geometryeditor.FeatureTypeDialogFragment.java
com.esri.arcgis.android.samples.geometryeditor.GeometryEditorActivity.java
com.esri.arcgis.android.samples.identifytask.Identify.java
com.esri.arcgis.android.samples.measure.MainActivity.java
com.esri.arcgis.android.samples.nearby.Nearby.java
com.esri.arcgis.android.samples.offlineeditor.GDBUtil.java
com.esri.arcgis.android.samples.offlineeditor.OfflineActions.java
com.esri.arcgis.android.samples.offlineeditor.OfflineEditorActivity.java
com.esri.arcgis.android.samples.offlineeditor.TemplatePicker.java
com.esri.arcgis.android.samples.offlineroutingandgeocoding.RoutingAndGeocoding.java
com.esri.arcgis.android.samples.popupinwebmapforediting.PopupInWebmapForEditing.java
com.esri.arcgis.android.samples.popupinwebmapforviewing.PopupInWebmapForViewing.java
com.esri.arcgis.android.samples.querytask.MainActivity.java
com.esri.arcgis.android.samples.routing.MyAdapter.java
com.esri.arcgis.android.samples.routing.RoutingDialogFragment.java
com.esri.arcgis.android.samples.routing.RoutingListFragment.java
com.esri.arcgis.android.samples.routing.RoutingSample.java
com.esri.arcgis.android.samples.servicearea.EditFragment.java
com.esri.arcgis.android.samples.servicearea.ServiceAreaSample.java
com.esri.arcgis.android.samples.standardlicense.MainActivity.java
com.esri.arcgis.android.samples.standardlicense.MessageDialogFragment.java
com.esri.arcgis.android.samples.standardlicenseoffline.MainActivity.java
com.esri.arcgis.android.samples.standardlicenseoffline.MessageDialogFragment.java
com.esri.arcgis.android.samples.uniquevaluerenderer.UniqueValueRendererSampleActivity.java
com.esri.arcgis.android.samples.viewshed.Viewshed.java
com.esri.arcgis.android.samples.wmslayer.MainActivity.java
com.esri.arcgis.samples.offlineanalysis.MainActivity.java