Online feature table query

Download Sample Viewer

Description

This sample demonstrates retrieval and display of data independent of any mapping. A feature table (GeodatabaseFeatureServiceTable class) object is created from a feature service URL and the desired layer ID. The table's FeatureRequestMode is set to MANUAL_CACHE. With this mode, the table needs to first be populated with the features of interest from the service by calling populateFromService. This is done right after the feature table is successfully initialized. Once the table is populated, the queries - executed when the user clicks the 'Query' button - are performed against the data in the table, using the queryFeatures method. The query results are displayed in the sample UI.

Code snippet


  // create the geodatabase feature service table
  table = new GeodatabaseFeatureServiceTable(FEATURE_SERVICE_URL, LAYER_ID);
  // set the manual cache mode in order to populate the table from a service query
  table.setFeatureRequestMode(FeatureRequestMode.MANUAL_CACHE); 
    
  // initializes the geodatabase feature table
  table.initialize(new CallbackListener() {
      
      @Override
      public void onError(Throwable e) {
	    // handle error
      }
      
      @Override
      public void onCallback(Status status) {
        if (Status.INITIALIZED == status) {
          // creates a query 
          final QueryParameters queryParameters = new QueryParameters();
          
          // specifies the extent to be queried.
          queryParameters.setGeometry(env);
          
          // populates the geodatabase feature table 
          table.populateFromService(queryParameters, true, new CallbackListener() {
            
            @Override
            public void onError(Throwable e) {
              // handle error    
            }
            
            @Override
            public void onCallback(Boolean success) {
              if (success.booleanValue() == false) {
                // query unsuccessful
			  }
            }
          });
        }
      }
    });

Sample Code

package com.esri.client.samples.search;
/* Copyright 2014 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 use restrictions.*/


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
import javax.swing.table.DefaultTableModel;

import com.esri.core.geodatabase.GeodatabaseFeatureServiceTable;
import com.esri.core.geodatabase.GeodatabaseFeatureServiceTable.FeatureRequestMode;
import com.esri.core.geodatabase.GeodatabaseFeatureServiceTable.Status;
import com.esri.core.geometry.Envelope;
import com.esri.core.map.CallbackListener;
import com.esri.core.map.Feature;
import com.esri.core.map.FeatureResult;
import com.esri.core.tasks.query.QueryParameters;

/**
 * This sample demonstrates retrieval and display of data independent of any mapping. 
 * A feature table (GeodatabaseFeatureServiceTable class) object is created from a 
 * feature service URL and the desired layer ID. The table's <code>FeatureRequestMode</code> 
 * is set to MANUAL_CACHE. With this mode, the table needs to first be populated with 
 * the features of interest from the service by calling <code>populateFromService</code>. 
 * This is done right after the feature table is successfully initialized. Once the table 
 * is populated, the queries - executed when the user clicks the 'Query' button - are 
 * performed against the data in the table, using the <code>queryFeatures</code> method. 
 * The query results are displayed in the sample UI.
 */
public class QueryFeatureServiceTableApp {

  // resources
  private static final String FEATURE_SERVICE_URL = "http://sampleserver6.arcgisonline.com/arcgis/rest/services/DamageAssessment/FeatureServer";
  private static final int LAYER_ID = 0;

  // query attributes
  private final String[] ATTR_NAMES  =
      new String[] {"objectid", "firstname", "lastname", "typdamage", "primcause"};
  private final String[] ATTR_HEADER =
      new String[] {"Object ID", "First Name", "Last Name", "Damage type", "Cause"};
  private JButton btnQuery;
  private JPanel contentPane;
  private GeodatabaseFeatureServiceTable table;
  private Envelope env;

  // ------------------------------------------------------------------------
  // Constructor
  // ------------------------------------------------------------------------
  public QueryFeatureServiceTableApp() {
  }

  // ------------------------------------------------------------------------
  // Core functionality
  // ------------------------------------------------------------------------
  /**
   * Creates a GeodatabaseFeatureServiceTable using a feature service URL and 
   * layer ID and sets the feature request mode and populates the table.
   */
  private void createGeodatabaseFeatureServiceTable() {
    table = new GeodatabaseFeatureServiceTable(FEATURE_SERVICE_URL, LAYER_ID);
    table.setFeatureRequestMode(FeatureRequestMode.MANUAL_CACHE); 

    // initializes the geodatabase feature table
    table.initialize(new CallbackListener<GeodatabaseFeatureServiceTable.Status>() {

      @Override
      public void onError(Throwable e) {
        JOptionPane.showMessageDialog(contentPane, 
            wrap("Error: " + e.getLocalizedMessage()));
      }

      @Override
      public void onCallback(Status status) {
        if (Status.INITIALIZED == status) {
          btnQuery.setEnabled(true);

          // creates a query 
          final QueryParameters queryParameters = new QueryParameters();

          // specifies the extent to be queried.
          queryParameters.setGeometry(env);

          // populates the geodatabase feature table 
          table.populateFromService(queryParameters, true, new CallbackListener<Boolean>() {

            @Override
            public void onError(Throwable e) {
              JOptionPane.showMessageDialog(contentPane, wrap("Error: "+e.getLocalizedMessage()), "", JOptionPane.ERROR_MESSAGE);    
            }

            @Override
            public void onCallback(Boolean success) {
              if (success.booleanValue() == false) 
                JOptionPane.showMessageDialog(contentPane, "Error: unsuccessful query", "", JOptionPane.ERROR_MESSAGE);
            }
          });
        }
      }
    });
  }

  /**
   * Executes a query.
   * @param txtQuery Input query.
   * @param tblModelQueryResult Query result will be populated in this.
   */
  private void executeQuery(JTextField txtQuery, final DefaultTableModel tblModelQueryResult) {

    String damageType = txtQuery.getText();
    // return if input is not valid or table null
    if (table == null || damageType == null || damageType.isEmpty()) {
      return;
    }
    // initialize the result - add the column headers if not already present,
    // and clear existing rows.
    if (tblModelQueryResult.getColumnCount() == 0) {
      for (String attrHeader : ATTR_HEADER) {
        tblModelQueryResult.addColumn(attrHeader);
      }
    }
    tblModelQueryResult.setRowCount(0);

    // create a query 
    final QueryParameters query = new QueryParameters();
    // specify the attributes to be fetched.
    query.setOutFields(ATTR_NAMES);
    // specify the query criteria.
    query.setWhere("typdamage LIKE '%" + damageType + "%'");
    query.setReturnGeometry(false);
    query.setGeometry(env);

    // query features
    table.queryFeatures(query, new CallbackListener<FeatureResult>() {

      @Override
      public void onError(Throwable e) {
        JOptionPane.showMessageDialog(contentPane,
            wrap("Error: " + e.getLocalizedMessage()), "",
            JOptionPane.ERROR_MESSAGE);
      }

      @Override
      public void onCallback(FeatureResult objs) {
        for (Object objFeature : objs) {
          Feature feature = (Feature) objFeature;
          // get attributes' value in the same order as the header.
          Object[] rowData = new Object[ATTR_NAMES.length];
          int index = 0;
          for (String attrName : ATTR_NAMES) {
            rowData[index++] = feature.getAttributeValue(attrName);
          }
          // add one row per feature
          tblModelQueryResult.addRow(rowData);
        }
      }
    });

  }

  // ------------------------------------------------------------------------
  // Static methods
  // ------------------------------------------------------------------------
  /**
   * Starting point of this application.
   * @param args arguments to this application.
   */
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      @Override
      public void run() {
        try {
          // instance of this application
          QueryFeatureServiceTableApp QueryFeatureServiceTableApp = new QueryFeatureServiceTableApp();

          // create the UI, including the map, for the application.
          JFrame appWindow = QueryFeatureServiceTableApp.createWindow();
          appWindow.add(QueryFeatureServiceTableApp.createUI());
          appWindow.setVisible(true);
        } catch (Exception e) {
          // on any error, display the stack trace.
          e.printStackTrace();
        }
      }
    });
  }

  // ------------------------------------------------------------------------
  // Public methods
  // ------------------------------------------------------------------------
  /**
   * Creates and displays the UI for this application.
   */
  public JComponent createUI() throws Exception {
    // application content
    contentPane = new JPanel();
    contentPane.setLayout(new BorderLayout());

    // set the extent to query 
    env = new Envelope(-15689653.31, 3752792.56, -10885739.31, 7405567.87);

    // description
    JTextField txtDescription = createDescription();
    txtDescription.setMaximumSize(new Dimension(600, 40));

    // query label
    JTextArea lblQuery = new JTextArea("Damage type contains (query is case-sensitive): ");
    lblQuery.append("(Values: Affected, Destroyed, Inaccessible,  Major, Minor)");
    lblQuery.setEditable(false);
    lblQuery.setForeground(Color.BLACK);
    lblQuery.setBackground(null);
    lblQuery.setMaximumSize(new Dimension(600, 20));

    // query input field
    final JTextField txtQuery = new JTextField();
    txtQuery.setText("Minor");
    txtQuery.setMaximumSize(new Dimension(350, 20));

    // query result - scrollable table
    final DefaultTableModel tblModelQueryResult = new DefaultTableModel();
    JTable tablQueryResult = new JTable(tblModelQueryResult);
    JScrollPane tblQueryResultScrollable = new JScrollPane(tablQueryResult);

    // query button
    btnQuery = new JButton("Query");
    btnQuery.setEnabled(false);
    btnQuery.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        // execute query when button is pressed.
        executeQuery(txtQuery, tblModelQueryResult);
      }
    });
    btnQuery.setMaximumSize(new Dimension(150, 20));
    btnQuery.setAlignmentX(Component.CENTER_ALIGNMENT);

    // group the above UI items into a panel
    final JPanel controlPanel = new JPanel();
    BoxLayout boxLayout = new BoxLayout(controlPanel, BoxLayout.Y_AXIS);
    controlPanel.setLayout(boxLayout);
    controlPanel.setBorder(new LineBorder(new Color(0, 0, 0, 100), 5, false));

    controlPanel.add(txtDescription);
    controlPanel.add(lblQuery);
    controlPanel.add(txtQuery);
    controlPanel.add(btnQuery);
    controlPanel.add(tblQueryResultScrollable);

    // add the panel to the main window
    contentPane.add(controlPanel);

    createGeodatabaseFeatureServiceTable();

    return contentPane;
  }

  // ------------------------------------------------------------------------
  // Private methods
  // ------------------------------------------------------------------------
  /**
   * Creates a description for this application.
   * @return description
   */
  private JTextField createDescription() {
    JTextField description = new JTextField(
        "This sample demonstrates retrieval and display of data independent of any mapping.");
    description.setFont(new Font("Verdana", Font.PLAIN, 11));
    description.setForeground(Color.WHITE);
    description.setBackground(Color.BLACK);
    description.setEditable(false);
    description.setHorizontalAlignment(SwingConstants.CENTER);
    return description;
  }

  /**
   * Creates a window, disposing of the geodatabase on application exit - you must 
   * call dispose to release any native resources.
   * 
   * @return a window.
   */
  private JFrame createWindow() {
    JFrame window = new JFrame("QueryFeatureServiceTableApp");
    window.setBounds(100, 100, 1000, 700);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.getContentPane().setLayout(new BorderLayout(0, 0));
    window.addWindowListener(new WindowAdapter() {
      @Override
      public void windowClosing(WindowEvent windowEvent) {
        super.windowClosing(windowEvent);
        if (table != null) table.dispose();
      }
    });
    return window;
  }

  private static String wrap(String str) {
    // create a HTML string that wraps text when longer
    return "<html><p style='width:200px;'>" + str + "</html>";
  }
}
Feedback on this topic?