Symbolizing Results Sample

This sample demonstrates how to use ClassBreaksRenderer to symbolize the graphics with similar attribute values. It also shows how to customize the callout by modifying the Extensible Markup Language (XML) style file and implementing custom callout behavior.

Sample Design

This sample creates a query task, which queries all of the counties in Kansas. The query result contains the county's name and Square Mile (SQMI) information. A ClassBreaksRenderer is created and set on the GraphicsLayer. When the query result returns, the features are placed into the graphics layer and are rendered with the previously mentioned ClassBreaksRenderer. To show a callout containing the county's SQMI information, the OnSingleTapListener interface is implemented and set on the map. When the single tap occurs, the tapped county graphic is queried through the getGraphics() method on the graphics layer. Information from the graphic's result is set as the callout's content. The callout style is customized using an XML style file, which is set on the callout object.

Sample Code

/* Copyright 2010 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.arcgis.android.samples.symbolizingresults;

import android.app.Activity;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.esri.android.map.Callout;
import com.esri.android.map.GraphicsLayer;
import com.esri.android.map.MapView;
import com.esri.android.map.ags.ArcGISTiledMapServiceLayer;
import com.esri.android.map.event.OnSingleTapListener;
import com.esri.core.geometry.Point;
import com.esri.core.map.Feature;
import com.esri.core.map.FeatureResult;
import com.esri.core.map.Graphic;
import com.esri.core.renderer.ClassBreak;
import com.esri.core.renderer.ClassBreaksRenderer;
import com.esri.core.renderer.Renderer;
import com.esri.core.symbol.SimpleFillSymbol;
import com.esri.core.tasks.query.QueryParameters;
import com.esri.core.tasks.query.QueryTask;

public class SymbolizingResults extends Activity {

	MapView map;
	GraphicsLayer graphicsLayer;
	Callout callout;

	/** Called when the activity is first created. */

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		map = (MapView) findViewById(R.id.map);
		map.addLayer(new ArcGISTiledMapServiceLayer(
				"http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"));

		graphicsLayer = new GraphicsLayer();
		graphicsLayer.setRenderer(createClassBreaksRenderer());
		map.addLayer(graphicsLayer);

		// Sets 'OnSingleTapListener' so that when single tap
		// happens, Callout would show 'SQMI' information associated
		// with tapped 'Graphic'
		map.setOnSingleTapListener(new OnSingleTapListener() {

			private static final long serialVersionUID = 1L;

			public void onSingleTap(float x, float y) {

				if (!map.isLoaded())
					return;
				int[] uids = graphicsLayer.getGraphicIDs(x, y, 2);
				if (uids != null && uids.length > 0) {

					int targetId = uids[0];
					Graphic gr = graphicsLayer.getGraphic(targetId);
					callout = map.getCallout();

					// Sets Callout style
					callout.setStyle(R.xml.countypop);
					String countyName = (String) gr.getAttributeValue("NAME");
					String countyPop = gr.getAttributeValue("POP07_SQMI")
							.toString();
					// Sets custom content view to Callout
					callout.setContent(loadView(countyName, countyPop));
					callout.show(map.toMapPoint(new Point(x, y)));
				} else {
					if (callout != null && callout.isShowing()) {
						callout.hide();
					}
				}

			}
		});

	}

	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.action, menu);

		return super.onCreateOptionsMenu(menu);
	}
	
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {

		case R.id.query:
			// Sets query parameter
			QueryParameters queryParams = new QueryParameters();
			queryParams.setWhere("STATE_NAME='Kansas'");

			queryParams.setReturnGeometry(true);
			String[] outfields = new String[] { "NAME", "STATE_NAME",
					"POP07_SQMI" };
			queryParams.setOutFields(outfields);
			queryParams.setOutSpatialReference(map.getSpatialReference());

			AsyncQueryTask queryTask = new AsyncQueryTask();

			queryTask.execute(queryParams);
			return true;

		}
		return super.onOptionsItemSelected(item);
	}
	
	
	// Creates custom content view with 'Graphic' attributes
	private View loadView(String countyName, String pop07) {
		View view = LayoutInflater.from(SymbolizingResults.this).inflate(
				R.layout.sqmi, null);

		final TextView name = (TextView) view.findViewById(R.id.county_name);
		name.setText(countyName + "'s SQMI");

		final TextView number = (TextView) view.findViewById(R.id.pop_sqmi);
		number.setText(pop07);

		final ImageView photo = (ImageView) view
				.findViewById(R.id.family_photo);
		photo.setImageDrawable(SymbolizingResults.this.getResources()
				.getDrawable(R.drawable.family));

		return view;

	}

	// Creates 'ClassBreaksRenderer' based on 'SQMI'
	private Renderer createClassBreaksRenderer() {
		ClassBreaksRenderer renderer = new ClassBreaksRenderer();
		renderer.setMinValue(0.0);
		renderer.setField("POP07_SQMI");
		ClassBreak cb1 = new ClassBreak();
		cb1.setClassMaxValue(25);
		cb1.setSymbol(new SimpleFillSymbol(Color.argb(128, 56, 168, 0)));
		cb1.setLabel("First class");

		ClassBreak cb2 = new ClassBreak();
		cb2.setClassMaxValue(75);
		cb2.setSymbol(new SimpleFillSymbol(Color.argb(128, 139, 209, 0)));
		cb2.setLabel("Second class");

		ClassBreak cb3 = new ClassBreak();
		cb3.setClassMaxValue(175);
		cb3.setSymbol(new SimpleFillSymbol(Color.argb(128, 255, 255, 0)));
		cb3.setLabel("Third class");

		ClassBreak cb4 = new ClassBreak();
		cb4.setClassMaxValue(400);
		cb4.setSymbol(new SimpleFillSymbol(Color.argb(128, 255, 128, 0)));
		cb4.setLabel("Fourth class");

		ClassBreak cb5 = new ClassBreak();
		cb5.setClassMaxValue(Double.MAX_VALUE);
		cb5.setSymbol(new SimpleFillSymbol(Color.argb(128, 255, 0, 0)));

		renderer.addClassBreak(cb1);
		renderer.addClassBreak(cb2);
		renderer.addClassBreak(cb3);
		renderer.addClassBreak(cb4);
		renderer.addClassBreak(cb5);
		return renderer;
	}

	private class AsyncQueryTask extends AsyncTask<QueryParameters, Void, FeatureResult> {

		protected FeatureResult doInBackground(QueryParameters... params) {

			if (params.length > 0) {
				QueryParameters queryParams = params[0];
				QueryTask queryTask = new QueryTask(
						"http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/3");
				try {
					FeatureResult fs = queryTask.execute(queryParams);
					return fs;
				} catch (Exception e) {
					e.printStackTrace();
					return null;
				}
			}

			return null;
		}

		protected void onPostExecute(FeatureResult results) {
			
            // iterate through results
            for (Object element : results) {
                // if object is feature cast to feature
                if (element instanceof Feature) {
                    Feature feature = (Feature) element;
                    // convert feature to graphic
                    Graphic graphic = new Graphic(feature.getGeometry(), feature.getSymbol(), feature.getAttributes());
                    // add it to the layer
                    graphicsLayer.addGraphic(graphic);
                }
            }
			Toast toast = Toast.makeText(SymbolizingResults.this,
					"Tap on county for SQMI data", Toast.LENGTH_LONG);
			toast.show();
		}

	}

	@Override
	protected void onPause() {
		super.onPause();
		map.pause();
	}

	@Override
	protected void onResume() {
		super.onResume();
		map.unpause();
	}

}
Feedback on this topic?