Geometry Sample

This sample uses the Geometry engine in different ways to show off the capabilities the Geometry engine provides the user. The samples illustrate the use of following operations: Project, Buffer, Union, Difference, Measure and identification of Spatial Relationships. Each fragment lets the user explore these individually. The sample allows the user to draw geometries and modify them using each of the operations.

Features

  • Reproject Points and Polygons
  • Buffer Points, Lines, & Polygons
  • Find the Union and Difference between intersecting Polygons
  • Determine spatial relationships between polygons, e.g. touches, contains, etc.
  • Measure distance or area
  • Andriod Fragments

Sample Design

The sample has an opening Geometry Sample Activity which presents the different geometry tools you can use in the app. Choose a feature tool from the left hand ListFragment to open the feature tool and use it.

Note

This sample exclusively targets the tablets because of its UI design.

Sample Code

/* Copyright 2013 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 
 * http://help.arcgis.com/en/sdk/10.0/usageRestrictions.htm.
 */

package com.arcgis.android.samples.geometrysample;

import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RadioGroup;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.SeekBar.OnSeekBarChangeListener;

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.Envelope;
import com.esri.core.geometry.Geometry;
import com.esri.core.geometry.GeometryEngine;
import com.esri.core.geometry.LinearUnit;
import com.esri.core.geometry.MultiPath;
import com.esri.core.geometry.Point;
import com.esri.core.geometry.Polygon;
import com.esri.core.geometry.Polyline;
import com.esri.core.geometry.SpatialReference;
import com.esri.core.geometry.Unit;
import com.esri.core.geometry.Unit.UnitType;
import com.esri.core.map.Graphic;
import com.esri.core.symbol.SimpleFillSymbol;
import com.esri.core.symbol.SimpleLineSymbol;

public class BufferFragment extends Fragment {
	final static String ARG_POSITION = "position";

	int mCurrentPosition = -1;

	MapView mapView;

	GraphicsLayer firstGeomLayer = null;

	GraphicsLayer resultGeomLayer = null;

	Button resetButton = null;

	Button bufferExecute = null;

	RadioGroup geomType = null;

	SeekBar bufferDistance = null;

	Button btn2ndGeometry = null;

	Button operatorButton = null;

	Geometry firstGeometry = null;

	volatile int countTap = 0;

	int geomNumWorkon = -1;

	GEOMETRY_TYPE firstGeoType = GEOMETRY_TYPE.point;

	boolean isStartPointSet1 = false;

	int selectedGeomID = 0;

	double bufferDist = 3000;

	SpatialReference spatialRef = SpatialReference.create(102100);

	TextView bufferDistTextValue = null;

	enum GEOMETRY_TYPE {
		point, polyline, polygon
	}

	boolean enableSketching = true;

	/**
	 * Create a new instance of BufferFragment, initialized to show the text at
	 * 'index'.
	 */
	public static BufferFragment newInstance(int index) {
		BufferFragment f = new BufferFragment();

		// Supply index input as an argument.
		Bundle args = new Bundle();
		args.putInt("index", index);
		f.setArguments(args);

		return f;
	}

	public int getShownIndex() {
		return getArguments().getInt("index", 0);
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {

		// If activity recreated (such as from screen rotate), restore
		// the previous article selection set by onSaveInstanceState().
		// This is primarily necessary when in the two-pane layout.
		if (savedInstanceState != null) {
			mCurrentPosition = savedInstanceState.getInt(ARG_POSITION);
		}

		// Inflate the layout for this fragment
		return inflater.inflate(R.layout.buffer, container, false);

		// return inflater.inflate(R.layout.article_view, container, false);
	}

	@Override
	public void onStart() {
		super.onStart();

		// During startup, check if there are arguments passed to the fragment.
		// onStart is a good place to do this because the layout has already
		// been
		// applied to the fragment at this point so we can safely call the
		// method
		// below that sets the article text.
		Bundle args = getArguments();
		if (args != null) {
			// Set article based on argument passed in
			updateArticleView(args.getInt(ARG_POSITION));
		} else if (mCurrentPosition != -1) {
			// Set article based on saved instance state defined during
			// onCreateView
			updateArticleView(mCurrentPosition);
		}
	}

	public void updateArticleView(int position) {

		mapView = (MapView) getActivity().findViewById(R.id.map);

		// Add Tile layer to the MapView
		String tileURL = getActivity().getResources().getString(
				R.string.tileServiceURL);
		ArcGISTiledMapServiceLayer tilelayer = new ArcGISTiledMapServiceLayer(
				tileURL);
		mapView.addLayer(tilelayer);

		// Set the envelope for the map
		Envelope env = new Envelope(-8139237.214629, 5016257.541842,
				-8090341.387563, 5077377.325675);
		mapView.setExtent(env);

		// Add the graphics layer for user to draw on the map
		firstGeomLayer = new GraphicsLayer();
		mapView.addLayer(firstGeomLayer);

		// Add the graphics layer to display results on the map
		resultGeomLayer = new GraphicsLayer();
		mapView.addLayer(resultGeomLayer);

		/**
		 * Single tap listener for MapView ***************
		 */
		mapView.setOnSingleTapListener(new OnSingleTapListener() {
			private static final long serialVersionUID = 1L;

			@Override
			public void onSingleTap(float x, float y) {
				// Check if sketching is enabled
				if (enableSketching) {
					try {
						singleTapAct(x, y);
					} catch (Exception ex) {
						ex.printStackTrace();
					}
				}
			}
		});

		// Display instructions to the user
		Toast.makeText(
				getActivity(),
				"Sketch a geometry and tap the buffer button to see the result",
				Toast.LENGTH_LONG).show();

		// set the behavior of all buttons
		setButtons();

		mCurrentPosition = position;
	}

	/**
	 * SET BUTTONS **************************
	 */
	void setButtons() {

		geomType = (RadioGroup) getActivity().findViewById(R.id.geometrytype);

		geomType.setOnCheckedChangeListener(new OnCheckedChangeListener() {

			@Override
			public void onCheckedChanged(RadioGroup group, int checkedId) {
				// Set the geometry type to draw on the map

				switch (checkedId) {
				case R.id.point:
					firstGeoType = GEOMETRY_TYPE.point;
					break;
				case R.id.line:
					firstGeoType = GEOMETRY_TYPE.polyline;
					break;
				case R.id.polygon:
					firstGeoType = GEOMETRY_TYPE.polygon;
					break;
				}

			}
		});

		resetButton = (Button) getActivity().findViewById(R.id.reset);
		resetButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				// Set all the default values

				firstGeometry = null;

				firstGeomLayer.removeAll();

				resultGeomLayer.removeAll();

				enableSketching = true;
			}
		});

		bufferExecute = (Button) getActivity().findViewById(R.id.buffer);
		bufferExecute.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				// execute buffer
				doBuffer();
			}
		});

		bufferDistance = (SeekBar) getActivity().findViewById(R.id.distance);
		// set default progress
		bufferDistance.setMax(5000);
		bufferDistance.setProgress(3000);

		bufferDistTextValue = (TextView) getActivity().findViewById(
				R.id.bufferdistance);

		bufferDistance
				.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

					@Override
					public void onStopTrackingTouch(SeekBar seekBar) {

					}

					@Override
					public void onStartTrackingTouch(SeekBar seekBar) {

					}

					@Override
					public void onProgressChanged(SeekBar seekBar,
							int progress, boolean fromUser) {
						// Use progress as the distance and calculate the buffer
						// geometry again and plot it on the map
						bufferDist = progress;
						bufferDistTextValue.setText((Integer.toString(progress))
								+ "m");
						doBuffer();

					}
				});

	}

	public void doBuffer() {

		Geometry geom[] = { firstGeometry };

		resultGeomLayer.removeAll();

		if (firstGeometry != null) {
			try {

				Unit unit = spatialRef.getUnit();

				double adjustedAccuracy = bufferDist;

				if (unit.getUnitType() == UnitType.ANGULAR) {
					adjustedAccuracy = metersToDegrees(bufferDist);
				} else {
					unit = Unit.create(LinearUnit.Code.METER);
				}
				// get the result polygon from the buffer operation
				Polygon p = GeometryEngine.buffer(geom[0], spatialRef,
						adjustedAccuracy, unit);

				// Render the polygon on the result graphic layer
				SimpleFillSymbol sfs = new SimpleFillSymbol(Color.GREEN);
				sfs.setOutline(new SimpleLineSymbol(Color.RED, 4,
						com.esri.core.symbol.SimpleLineSymbol.STYLE.SOLID));
				sfs.setAlpha(25);
				Graphic g = new Graphic(p, sfs);
				resultGeomLayer.addGraphic(g);

			} catch (Exception ex) {
				Log.d("Test buffer", ex.getMessage());

			}
			enableSketching = false;
		}

	}

	private final double metersToDegrees(double distanceInMeters) {
		return distanceInMeters / 111319.5;
	}

	void displayResultGeometry(Geometry[] geometry) throws Exception {
		if (geometry == null)
			return;
		Geometry[] geometries = new Geometry[1];
		geometries[0] = geometry[0];
		resultGeomLayer.removeAll();

	}

	/**
	 * action to take on single taping.
	 * 
	 * @param x
	 * @param y
	 * @throws Exception
	 */

	void singleTapAct(float x, float y) throws Exception {
		countTap++;
		Point point = mapView.toMapPoint(x, y);
		Log.d("sigle tap on screen:", "[" + x + "," + y + "]");
		Log.d("sigle tap on map:", "[" + point.getX() + "," + point.getY()
				+ "]");

		if (firstGeometry == null) {
			if (firstGeoType == GEOMETRY_TYPE.point) {
				firstGeometry = point;

			} else if (firstGeoType == GEOMETRY_TYPE.polygon) {
				firstGeometry = new Polygon();
				((MultiPath) firstGeometry).startPath(point);
				isStartPointSet1 = true;
				Log.d("geometry step " + countTap,
						GeometryEngine.geometryToJson(
								mapView.getSpatialReference(), firstGeometry));

			} else if (firstGeoType == GEOMETRY_TYPE.polyline) {
				isStartPointSet1 = true;
				firstGeometry = new Polyline();
				((MultiPath) firstGeometry).startPath(point);
			}

		}

		if (firstGeoType == null)
			return;
		int color1 = Color.BLUE;
		drawGeomOnGraphicLyr(firstGeometry, firstGeomLayer, point,
				firstGeoType, color1, isStartPointSet1);
		Log.d("geometry step " + countTap, GeometryEngine.geometryToJson(
				mapView.getSpatialReference(), firstGeometry));

	}

	void drawGeomOnGraphicLyr(Geometry geometryToDraw, GraphicsLayer glayer,
			Point point, GEOMETRY_TYPE geoTypeToDraw, int color,
			boolean startPointSet) {

		if (geoTypeToDraw == GEOMETRY_TYPE.point) {
			geometryToDraw = point;

		} else {

			if (startPointSet) {

				if (geoTypeToDraw == GEOMETRY_TYPE.polygon) {
					((Polygon) geometryToDraw).lineTo(point);
				} else if (geoTypeToDraw == GEOMETRY_TYPE.polyline) {
					((Polyline) geometryToDraw).lineTo(point);
				}

			}
		}

		Geometry[] geoms = new Geometry[1];
		geoms[0] = geometryToDraw;

		try {
			glayer.removeAll();
			GeometryUtil.highlightGeometriesWithColor(geoms, glayer, color);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@Override
	public void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);

		// Save the current article selection in case we need to recreate the
		// fragment
		outState.putInt(ARG_POSITION, mCurrentPosition);
	}
}
/* Copyright 2013 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 
 * http://help.arcgis.com/en/sdk/10.0/usageRestrictions.htm.
 */

package com.arcgis.android.samples.geometrysample;

import java.text.DecimalFormat;

import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.RadioGroup.OnCheckedChangeListener;

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.AreaUnit;
import com.esri.core.geometry.Envelope;
import com.esri.core.geometry.Geometry;
import com.esri.core.geometry.GeometryEngine;
import com.esri.core.geometry.LinearUnit;
import com.esri.core.geometry.MultiPath;
import com.esri.core.geometry.Point;
import com.esri.core.geometry.Polygon;
import com.esri.core.geometry.Polyline;
import com.esri.core.geometry.SpatialReference;
import com.esri.core.geometry.Unit;

public class MeasureFragment extends Fragment {
	final static String ARG_POSITION = "position";

	int mCurrentPosition = -1;

	MapView mapView;

	ArcGISTiledMapServiceLayer tileLayer = null;

	public static final LinearUnit LINEARUNIT_METER = (LinearUnit) Unit
			.create(LinearUnit.Code.METER);

	public static final AreaUnit AREAUNIT_SQUARE_METER = (AreaUnit) Unit
			.create(AreaUnit.Code.SQUARE_METER);

	GraphicsLayer firstGeomLayer = null;

	boolean enableSketching = true;

	Geometry firstGeometry = null;

	TextView resultText = null;

	GEOMETRY_TYPE firstGeoType = GEOMETRY_TYPE.polyline;

	RadioGroup geomTypeRadioGroup = null;

	Button resetButton = null;

	boolean isStartPointSet1 = false;

	volatile int countTap = 0;

	double measure = 0;

	double value = 0;

	DecimalFormat twoDForm;

	int resId = 0;

	int current_distance_unit = LinearUnit.Code.METER;

	int current_area_unit = AreaUnit.Code.SQUARE_METER;

	enum GEOMETRY_TYPE {
		point, polyline, polygon
	}

	protected int[] distance_units = new int[] { LinearUnit.Code.METER,
			LinearUnit.Code.MILE_US, LinearUnit.Code.YARD,
			LinearUnit.Code.FOOT, LinearUnit.Code.KILOMETER };

	protected int[] area_units = new int[] { AreaUnit.Code.SQUARE_METER,
			AreaUnit.Code.ACRE, AreaUnit.Code.SQUARE_MILE_US,
			AreaUnit.Code.SQUARE_YARD, AreaUnit.Code.SQUARE_KILOMETER };

	/**
	 * Create a new instance of MeasureFragment, initialized to show the text at
	 * 'index'.
	 */
	public static MeasureFragment newInstance(int index) {
		MeasureFragment f = new MeasureFragment();

		// Supply index input as an argument.
		Bundle args = new Bundle();
		args.putInt("index", index);
		f.setArguments(args);

		return f;
	}

	public int getShownIndex() {
		return getArguments().getInt("index", 0);
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {

		// If activity recreated (such as from screen rotate), restore
		// the previous article selection set by onSaveInstanceState().
		// This is primarily necessary when in the two-pane layout.
		if (savedInstanceState != null) {
			mCurrentPosition = savedInstanceState.getInt(ARG_POSITION);
		}

		// Inflate the layout for this fragment
		return inflater.inflate(R.layout.measure, container, false);

		// return inflater.inflate(R.layout.article_view, container, false);
	}

	@Override
	public void onStart() {
		super.onStart();

		// During startup, check if there are arguments passed to the fragment.
		// onStart is a good place to do this because the layout has already
		// been
		// applied to the fragment at this point so we can safely call the
		// method
		// below that sets the article text.
		Bundle args = getArguments();
		if (args != null) {
			// Set article based on argument passed in
			updateArticleView(args.getInt(ARG_POSITION));
		} else if (mCurrentPosition != -1) {
			// Set article based on saved instance state defined during
			// onCreateView
			updateArticleView(mCurrentPosition);
		}
	}

	@SuppressWarnings("serial")
	public void updateArticleView(int position) {

		mapView = (MapView) getActivity().findViewById(R.id.map);

		// Add Tile layer to the MapView
		String tileURL = getActivity().getResources().getString(
				R.string.tileServiceURL);
		ArcGISTiledMapServiceLayer tilelayer = new ArcGISTiledMapServiceLayer(
				tileURL);
		mapView.addLayer(tilelayer);

		// Set the extent of the map
		Envelope env = new Envelope(-8139237.214629, 5016257.541842,
				-8090341.387563, 5077377.325675);
		mapView.setExtent(env);

		// Add the graphics layer to the map
		firstGeomLayer = new GraphicsLayer();
		mapView.addLayer(firstGeomLayer);

		twoDForm = new DecimalFormat("#.##");

		/**
		 * Single tap listener for MapView ***************
		 */
		mapView.setOnSingleTapListener(new OnSingleTapListener() {
			@Override
			public void onSingleTap(float x, float y) {
				if (enableSketching) {
					try {
						singleTapAct(x, y);
					} catch (Exception ex) {
						ex.printStackTrace();
					}
				}
			}
		});

		Toast.makeText(getActivity(),
				"Sketch on the map to measure distance or area",
				Toast.LENGTH_LONG).show();

		// set the behavior of all buttons

		setButtons();

		changeSpinnerUnits();

		mCurrentPosition = position;
	}

	/**
	 * SET BUTTONS **************************
	 */
	void setButtons() {

		resultText = (TextView) getActivity().findViewById(R.id.result);

		geomTypeRadioGroup = (RadioGroup) getActivity().findViewById(
				R.id.geometrytype);

		geomTypeRadioGroup
				.setOnCheckedChangeListener(new OnCheckedChangeListener() {

					@Override
					public void onCheckedChanged(RadioGroup group, int checkedId) {

						switch (checkedId) {
						case R.id.line:
							firstGeoType = GEOMETRY_TYPE.polyline;
							changeSpinnerUnits();
							doReset();
							break;
						case R.id.polygon:
							firstGeoType = GEOMETRY_TYPE.polygon;
							changeSpinnerUnits();
							doReset();
							break;
						}

					}
				});

		resetButton = (Button) getActivity().findViewById(R.id.reset);
		resetButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				doReset();
			}
		});

	}

	@SuppressWarnings("boxing")
	void doReset() {

		firstGeometry = null;

		firstGeomLayer.removeAll();

		enableSketching = true;

		measure = 0;

		value = 0;

		resultText.setText(Double.toString(value));

	}

	/**
	 * Changes the unit types for spinner values on selecting distance vs area
	 * 
	 * @param measuretype
	 */
	void changeSpinnerUnits() {

		if (firstGeoType == GEOMETRY_TYPE.polyline) {
			resId = R.array.DistanceUnits;
		} else {
			resId = R.array.AreaUnits;
		}

		// Create a spinner with the drop down values specified in
		// values->queryparameters.xml
		Spinner measureUnits = (Spinner) getActivity().findViewById(
				R.id.spinner1);
		ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
				getActivity(), resId, android.R.layout.simple_spinner_item);
		adapter.setDropDownViewResource(android.R.layout.simple_spinner_item);
		measureUnits.setAdapter(adapter);

		measureUnits.setOnItemSelectedListener(new OnItemSelectedListener() {
			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int pos, long id) {

				switch (pos) {

				// distance - Miles, area - Acres
				case 0:
					if (firstGeoType == GEOMETRY_TYPE.polyline) {
						current_distance_unit = distance_units[0];
						doConvert(current_distance_unit, GEOMETRY_TYPE.polyline);
					} else {
						current_area_unit = area_units[0];
						doConvert(current_area_unit, GEOMETRY_TYPE.polygon);
					}

					break;

				// distance - Yards, area - Square Miles
				case 1:
					if (firstGeoType == GEOMETRY_TYPE.polyline) {
						current_distance_unit = distance_units[1];
						doConvert(current_distance_unit, GEOMETRY_TYPE.polyline);
					} else {
						current_area_unit = area_units[1];
						doConvert(current_area_unit, GEOMETRY_TYPE.polygon);
					}

					break;

				// distance - Feet, area - Square Yards
				case 2:
					if (firstGeoType == GEOMETRY_TYPE.polyline) {
						current_distance_unit = distance_units[2];
						doConvert(current_distance_unit, GEOMETRY_TYPE.polyline);
					} else {
						current_area_unit = area_units[2];
						doConvert(current_area_unit, GEOMETRY_TYPE.polygon);
					}

					break;

				// distance - Kilometers, area - Square Kilometers
				case 3:
					if (firstGeoType == GEOMETRY_TYPE.polyline) {
						current_distance_unit = distance_units[3];
						doConvert(current_distance_unit, GEOMETRY_TYPE.polyline);
					} else {
						current_area_unit = area_units[3];
						doConvert(current_area_unit, GEOMETRY_TYPE.polygon);
					}

					break;

				// distance - Meters, area - Square Meters
				case 4:
					if (firstGeoType == GEOMETRY_TYPE.polyline) {
						current_distance_unit = distance_units[4];
						doConvert(current_distance_unit, GEOMETRY_TYPE.polyline);
					} else {
						current_area_unit = area_units[4];
						doConvert(current_area_unit, GEOMETRY_TYPE.polygon);
					}

					break;

				default:
					break;
				}

			}

			@Override
			public void onNothingSelected(AdapterView<?> parent) {
				// Do nothing

			}
		});

	}

	@SuppressWarnings("boxing")
	void doConvert(int toUnit, GEOMETRY_TYPE GeoType) {

		// All the measurement is done in meters and sq meters. No need to
		// convert units
		if (toUnit == LinearUnit.Code.METER
				|| toUnit == AreaUnit.Code.SQUARE_METER) {
			// only two digits after the decimal
			value = Double.valueOf(twoDForm.format(measure));
			resultText.setText(Double.toString(value));
			return;
		}

		// Calculate the value of measure in other units
		if (GeoType == GEOMETRY_TYPE.polyline) {
			value = Unit.convertUnits(measure, LINEARUNIT_METER,
					Unit.create(toUnit));
			value = Double.valueOf(twoDForm.format(value));
		} else if (GeoType == GEOMETRY_TYPE.polygon) {
			value = Unit.convertUnits(measure, AREAUNIT_SQUARE_METER,
					Unit.create(toUnit));
			value = Double.valueOf(twoDForm.format(value));
		}

		// Display result in textview
		resultText.setText(Double.toString(value));
	}

	/**
	 * action to take on single taping.
	 * 
	 * @param x
	 * @param y
	 * @throws Exception
	 */

	void singleTapAct(float x, float y) throws Exception {
		countTap++;
		Point point = mapView.toMapPoint(x, y);
		Log.d("single tap on screen:", "[" + x + "," + y + "]");
		Log.d("single tap on map:", "[" + point.getX() + "," + point.getY()
				+ "]");

		if (firstGeometry == null) {
			if (firstGeoType == GEOMETRY_TYPE.point) {
				firstGeometry = point;

			} else if (firstGeoType == GEOMETRY_TYPE.polygon) {
				firstGeometry = new Polygon();
				((MultiPath) firstGeometry).startPath(point);
				isStartPointSet1 = true;
				Log.d("geometry step " + countTap,
						GeometryEngine.geometryToJson(
								mapView.getSpatialReference(), firstGeometry));

			} else if (firstGeoType == GEOMETRY_TYPE.polyline) {
				isStartPointSet1 = true;
				firstGeometry = new Polyline();
				((MultiPath) firstGeometry).startPath(point);
			}

		}

		if (firstGeoType == null)
			return;
		int color1 = Color.BLUE;
		drawGeomOnGraphicLyr(firstGeometry, firstGeomLayer, point,
				firstGeoType, color1, isStartPointSet1);
		Log.d("geometry step " + countTap, GeometryEngine.geometryToJson(
				mapView.getSpatialReference(), firstGeometry));

	}

	void drawGeomOnGraphicLyr(Geometry geometryToDraw, GraphicsLayer glayer,
			Point point, GEOMETRY_TYPE geoTypeToDraw, int color,
			boolean startPointSet) {

		if (geoTypeToDraw == GEOMETRY_TYPE.point) {
			geometryToDraw = point;

		} else {

			if (startPointSet) {

				if (geoTypeToDraw == GEOMETRY_TYPE.polygon) {
					((Polygon) geometryToDraw).lineTo(point);
					// Simplify the geometry and project to spatial ref with
					// WKID for World Cylindrical Equal Area 54034
					Geometry geometry = GeometryEngine.simplify(geometryToDraw,
							mapView.getSpatialReference());
					Geometry g2 = GeometryEngine.project(geometry,
							mapView.getSpatialReference(),
							SpatialReference.create(54034));
					// Get the area for the polygon
					measure = Math.abs(g2.calculateArea2D());
					if (measure != 0.0)
						doConvert(current_area_unit, firstGeoType);

				} else if (geoTypeToDraw == GEOMETRY_TYPE.polyline) {
					((Polyline) geometryToDraw).lineTo(point);
					// Get the geodesic length for the polyline
					measure = GeometryEngine.geodesicLength(geometryToDraw,
							mapView.getSpatialReference(), LINEARUNIT_METER);
					if (measure != 0.0)
						doConvert(current_distance_unit, firstGeoType);
				}

			}
		}

		Geometry[] geoms = new Geometry[1];
		geoms[0] = geometryToDraw;

		try {
			glayer.removeAll();
			GeometryUtil.highlightGeometriesWithColor(geoms, glayer, color);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@Override
	public void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);

		// Save the current article selection in case we need to recreate the
		// fragment
		outState.putInt(ARG_POSITION, mCurrentPosition);
	}
}
/* Copyright 2013 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 
 * http://help.arcgis.com/en/sdk/10.0/usageRestrictions.htm.
 */

package com.arcgis.android.samples.geometrysample;

import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.Toast;

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.Geometry;
import com.esri.core.geometry.GeometryEngine;
import com.esri.core.geometry.MultiPath;
import com.esri.core.geometry.MultiPoint;
import com.esri.core.geometry.Point;
import com.esri.core.geometry.Polygon;
import com.esri.core.geometry.Polyline;
import com.esri.core.geometry.SpatialReference;

public class SpatialRelationshipsFragment extends Fragment {
	final static String ARG_POSITION = "position";

	int mCurrentPosition = -1;

	MapView mapView;

	ArcGISTiledMapServiceLayer tileLayer = null;

	GraphicsLayer firstGeomLayer = null;

	GraphicsLayer secondGeomLayer = null;

	GraphicsLayer resultGeomLayer = null;

	Button addsecGeometry;

	Button resetButton;

	RadioGroup operationType = null;

	RadioButton point;

	RadioButton line;

	RadioButton polygon;

	int geomNumWorkon = 1;

	Geometry firstGeometry = null;

	Geometry secondGeometry = null;

	boolean isStartPointSet1 = false;

	boolean isStartPointSet2 = false;

	volatile int countTap = 0;

	private String TAG = SpatialRelationshipsFragment.class.getSimpleName();

	GEOMETRY_TYPE firstGeoType = GEOMETRY_TYPE.point;

	GEOMETRY_TYPE secondGeoType = GEOMETRY_TYPE.point;

	boolean isSketchingEnabled = true;

	int plusButtonCount = 0;

	CheckBox within = null;

	CheckBox touches = null;

	CheckBox equals = null;

	CheckBox crosses = null;

	CheckBox contains = null;

	enum GEOMETRY_TYPE {
		point, multi_points, polyline, polygon
	}

	SpatialReference spatialRef = SpatialReference.create(102100);

	/**
	 * Create a new instance of SpatialRelationshipsFragment, initialized to
	 * show the text at 'index'.
	 */
	public static SpatialRelationshipsFragment newInstance(int index) {
		SpatialRelationshipsFragment f = new SpatialRelationshipsFragment();

		// Supply index input as an argument.
		Bundle args = new Bundle();
		args.putInt("index", index);
		f.setArguments(args);

		return f;
	}

	public int getShownIndex() {
		return getArguments().getInt("index", 0);
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {

		// If activity recreated (such as from screen rotate), restore
		// the previous article selection set by onSaveInstanceState().
		// This is primarily necessary when in the two-pane layout.
		if (savedInstanceState != null) {
			mCurrentPosition = savedInstanceState.getInt(ARG_POSITION);
		}

		// Inflate the layout for this fragment
		return inflater
				.inflate(R.layout.spatialrelationships, container, false);

		// return inflater.inflate(R.layout.article_view, container, false);
	}

	@Override
	public void onStart() {
		super.onStart();

		// During startup, check if there are arguments passed to the fragment.
		// onStart is a good place to do this because the layout has already
		// been
		// applied to the fragment at this point so we can safely call the
		// method
		// below that sets the article text.
		Bundle args = getArguments();
		if (args != null) {
			// Set article based on argument passed in
			updateArticleView(args.getInt(ARG_POSITION));
		} else if (mCurrentPosition != -1) {
			// Set article based on saved instance state defined during
			// onCreateView
			updateArticleView(mCurrentPosition);
		}
	}

	public void updateArticleView(int position) {

		mapView = (MapView) getActivity().findViewById(R.id.map);

		mapView.enableWrapAround(true);

		// Add Tile layer to the MapView
		String tileURL = getActivity().getResources().getString(
				R.string.tileServiceURL);
		ArcGISTiledMapServiceLayer tilelayer = new ArcGISTiledMapServiceLayer(
				tileURL);
		mapView.addLayer(tilelayer);

		firstGeomLayer = new GraphicsLayer();
		mapView.addLayer(firstGeomLayer);

		secondGeomLayer = new GraphicsLayer();
		mapView.addLayer(secondGeomLayer);

		resultGeomLayer = new GraphicsLayer();
		mapView.addLayer(resultGeomLayer);

		/**
		 * Single tap listener for MapView ***************
		 */
		mapView.setOnSingleTapListener(new OnSingleTapListener() {
			private static final long serialVersionUID = 1L;

			public void onSingleTap(float x, float y) {
				if (isSketchingEnabled) {
					try {
						singleTapAct(x, y);
					} catch (Exception ex) {
						String err = ex.getMessage();
						Log.d(TAG, err);
					}
				}
			}
		});

		// Set the message in the toast
		Toast.makeText(getActivity(),
				"Draw two intersecting polygons by tapping on the map",
				Toast.LENGTH_LONG).show();

		// set the behavior of all buttons
		setButtons();

		mCurrentPosition = position;
	}

	/**
	 * SET BUTTONS **************************
	 */
	void setButtons() {

		point = (RadioButton) getActivity().findViewById(R.id.point);

		line = (RadioButton) getActivity().findViewById(R.id.line);

		polygon = (RadioButton) getActivity().findViewById(R.id.polygon);

		within = (CheckBox) getActivity().findViewById(R.id.within);

		touches = (CheckBox) getActivity().findViewById(R.id.touches);

		equals = (CheckBox) getActivity().findViewById(R.id.equals);

		crosses = (CheckBox) getActivity().findViewById(R.id.crosses);

		contains = (CheckBox) getActivity().findViewById(R.id.contains);

		operationType = (RadioGroup) getActivity().findViewById(
				R.id.geometrytype);

		operationType.setOnCheckedChangeListener(new OnCheckedChangeListener() {

			@Override
			public void onCheckedChanged(RadioGroup group, int checkedId) {

				switch (checkedId) {

				case R.id.point:
					if (plusButtonCount == 0) {
						firstGeoType = GEOMETRY_TYPE.point;
						secondGeoType = GEOMETRY_TYPE.point;
					} else if (plusButtonCount == 1) {
						secondGeoType = GEOMETRY_TYPE.point;
					}

					break;

				case R.id.line:
					if (plusButtonCount == 0) {
						firstGeoType = GEOMETRY_TYPE.polyline;
						secondGeoType = GEOMETRY_TYPE.polyline;
					} else if (plusButtonCount == 1) {
						secondGeoType = GEOMETRY_TYPE.polyline;
					}

					break;

				case R.id.polygon:
					if (plusButtonCount == 0) {
						firstGeoType = GEOMETRY_TYPE.polygon;
						secondGeoType = GEOMETRY_TYPE.polygon;
					} else if (plusButtonCount == 1) {
						secondGeoType = GEOMETRY_TYPE.polygon;
					}

					break;

				}

			}
		});

		resetButton = (Button) getActivity().findViewById(R.id.reset);
		resetButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				firstGeometry = null;
				secondGeometry = null;

				firstGeomLayer.removeAll();
				secondGeomLayer.removeAll();

				resultGeomLayer.removeAll();
				addsecGeometry.setEnabled(true);

				point.setChecked(true);
				line.setChecked(false);
				polygon.setChecked(false);
				firstGeoType = GEOMETRY_TYPE.point;
				secondGeoType = GEOMETRY_TYPE.point;

				within.setChecked(false);
				touches.setChecked(false);
				equals.setChecked(false);
				crosses.setChecked(false);
				contains.setChecked(false);

				geomNumWorkon = 1;
				plusButtonCount = 0;
				isSketchingEnabled = true;
			}
		});

		addsecGeometry = (Button) getActivity().findViewById(
				R.id.addsecgeometry);
		addsecGeometry.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				// first geometry is done start second geometry

				plusButtonCount++;

				if (plusButtonCount < 3) {

					geomNumWorkon = 2;
					if (plusButtonCount == 2) {
						doOperation();
					}
				}

			}
		});

	}

	void doOperation() {

		if (plusButtonCount == 2) {
			addsecGeometry.setEnabled(false);
			operationType.setEnabled(false);
			isSketchingEnabled = false;
			plusButtonCount++;
		}

		if (firstGeometry != null && secondGeometry != null) {

			// Set the checkboxes if the relationship is true
			within.setChecked(GeometryEngine.within(firstGeometry,
					secondGeometry, mapView.getSpatialReference()));
			touches.setChecked(GeometryEngine.touches(firstGeometry,
					secondGeometry, mapView.getSpatialReference()));
			equals.setChecked(GeometryEngine.equals(firstGeometry,
					secondGeometry, mapView.getSpatialReference()));
			crosses.setChecked(GeometryEngine.crosses(firstGeometry,
					secondGeometry, mapView.getSpatialReference()));
			contains.setChecked(GeometryEngine.contains(firstGeometry,
					secondGeometry, mapView.getSpatialReference()));

		}

	}

	void displayResultGeometry(Geometry geometry) throws Exception {
		if (geometry == null)
			return;
		Geometry[] geometries = new Geometry[1];
		geometries[0] = geometry;
		int red = Color.RED;
		resultGeomLayer.removeAll();
		GeometryUtil.highlightGeometriesWithColor(geometries, resultGeomLayer,
				red);

	}

	void singleTapAct(float x, float y) throws Exception {
		countTap++;
		Point point = mapView.toMapPoint(x, y);
		Log.d("sigle tap on screen:", "[" + x + "," + y + "]");
		Log.d("sigle tap on map:", "[" + point.getX() + "," + point.getY()
				+ "]");
		if (geomNumWorkon == 1) {
			if (firstGeometry == null) {
				if (firstGeoType == GEOMETRY_TYPE.point) {
					firstGeometry = point;

				} else if (firstGeoType == GEOMETRY_TYPE.multi_points) {
					firstGeometry = new MultiPoint();
					((MultiPoint) firstGeometry).add(point);
				} else if (firstGeoType == GEOMETRY_TYPE.polygon) {
					firstGeometry = new Polygon();
					((MultiPath) firstGeometry).startPath(point);
					isStartPointSet1 = true;
					Log.d("geometry step " + countTap, GeometryEngine
							.geometryToJson(mapView.getSpatialReference(),
									firstGeometry));

				} else if (firstGeoType == GEOMETRY_TYPE.polyline) {
					isStartPointSet1 = true;
					firstGeometry = new Polyline();
					((MultiPath) firstGeometry).startPath(point);
				}

			}

		} else if (geomNumWorkon == 2) {
			if (secondGeometry == null) {
				if (secondGeoType == GEOMETRY_TYPE.point) {
					secondGeometry = point;

				} else if (secondGeoType == GEOMETRY_TYPE.multi_points) {
					secondGeometry = new MultiPoint();
					((MultiPoint) secondGeometry).add(point);
				} else if (secondGeoType == GEOMETRY_TYPE.polygon) {
					secondGeometry = new Polygon();
					((MultiPath) secondGeometry).startPath(point);
					isStartPointSet2 = true;

				} else if (secondGeoType == GEOMETRY_TYPE.polyline) {
					isStartPointSet2 = true;
					secondGeometry = new Polyline();
					((MultiPath) secondGeometry).startPath(point);
				}

			}

		}

		if (geomNumWorkon == 1) {
			if (firstGeoType == null)
				return;
			// int blue = Color.BLUE;
			int color1 = Color.BLUE;
			drawGeomOnGraphicLyr(firstGeometry, firstGeomLayer, point,
					firstGeoType, color1, isStartPointSet1);
			Log.d("geometry step " + countTap, GeometryEngine.geometryToJson(
					mapView.getSpatialReference(), firstGeometry));

		} else if (geomNumWorkon == 2) {
			if (secondGeoType == null)
				return;
			int green = Color.GREEN;
			int color2 = Color.argb(100, Color.red(green), Color.green(green),
					Color.blue(green));
			drawGeomOnGraphicLyr(secondGeometry, secondGeomLayer, point,
					secondGeoType, color2, isStartPointSet2);
		}

	}

	void drawGeomOnGraphicLyr(Geometry geometryToDraw, GraphicsLayer glayer,
			Point point, GEOMETRY_TYPE geoTypeToDraw, int color,
			boolean startPointSet) {

		if (geoTypeToDraw == GEOMETRY_TYPE.point) {
			geometryToDraw = point;

		} else if (geoTypeToDraw == GEOMETRY_TYPE.multi_points) {
			((MultiPoint) geometryToDraw).add(point);
		} else {

			if (startPointSet) {

				if (geoTypeToDraw == GEOMETRY_TYPE.polygon) {
					((Polygon) geometryToDraw).lineTo(point);
				} else if (geoTypeToDraw == GEOMETRY_TYPE.polyline) {
					((Polyline) geometryToDraw).lineTo(point);
				}

			}
		}

		Geometry[] geoms = new Geometry[1];
		geoms[0] = geometryToDraw;

		try {
			glayer.removeAll();
			GeometryUtil.highlightGeometriesWithColor(geoms, glayer, color);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@Override
	public void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);

		// Save the current article selection in case we need to recreate the
		// fragment
		outState.putInt(ARG_POSITION, mCurrentPosition);
	}
}
/* Copyright 2013 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 
 * http://help.arcgis.com/en/sdk/10.0/usageRestrictions.htm.
 */

package com.arcgis.android.samples.geometrysample;

import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RadioGroup.OnCheckedChangeListener;
import android.widget.Toast;

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.Geometry;
import com.esri.core.geometry.GeometryEngine;
import com.esri.core.geometry.MultiPath;
import com.esri.core.geometry.MultiPoint;
import com.esri.core.geometry.Point;
import com.esri.core.geometry.Polygon;
import com.esri.core.geometry.Polyline;
import com.esri.core.geometry.SpatialReference;

public class UnionDifferenceFragment extends Fragment {
	final static String ARG_POSITION = "position";

	int mCurrentPosition = -1;

	MapView mapView;

	ArcGISTiledMapServiceLayer tileLayer;

	GraphicsLayer firstGeomLayer = null;

	GraphicsLayer secondGeomLayer = null;

	GraphicsLayer resultGeomLayer = null;

	Button addsecGeometry;

	Button resetButton;

	RadioGroup operationTypeRadio = null;

	int geomNumWorkon = 1;

	Geometry firstGeometry = null;

	Geometry secondGeometry = null;

	boolean isStartPointSet1 = false;

	boolean isStartPointSet2 = false;

	int plusButtonCount = 0;

	Geometry geometryFromUnion;

	Geometry geometryFromDiff;

	SpatialReference spatialRef = SpatialReference.create(102100);

	RadioButton union;

	RadioButton difference;

	boolean countDoOperationUnion = true;

	boolean countDoOperationDifference = true;

	boolean isSketchingEnabled = true;

	enum OPERATION_TYPE {
		union, difference
	}

	enum GEOMETRY_TYPE {
		point, multi_points, polyline, polygon
	}

	OPERATION_TYPE operationType = OPERATION_TYPE.union;

	GEOMETRY_TYPE firstGeoType = GEOMETRY_TYPE.polygon;

	GEOMETRY_TYPE secondGeoType = GEOMETRY_TYPE.polygon;

	/**
	 * Create a new instance of UnionDifferenceFragment, initialized to show the
	 * text at 'index'.
	 */
	public static UnionDifferenceFragment newInstance(int index) {
		UnionDifferenceFragment f = new UnionDifferenceFragment();

		// Supply index input as an argument.
		Bundle args = new Bundle();
		args.putInt("index", index);
		f.setArguments(args);

		return f;
	}

	public int getShownIndex() {
		return getArguments().getInt("index", 0);
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {

		// If activity recreated (such as from screen rotate), restore
		// the previous article selection set by onSaveInstanceState().
		// This is primarily necessary when in the two-pane layout.
		if (savedInstanceState != null) {
			mCurrentPosition = savedInstanceState.getInt(ARG_POSITION);
		}

		// Inflate the layout for this fragment
		return inflater.inflate(R.layout.uniondifference, container, false);

		// return inflater.inflate(R.layout.article_view, container, false);
	}

	@Override
	public void onStart() {
		super.onStart();

		// During startup, check if there are arguments passed to the fragment.
		// onStart is a good place to do this because the layout has already
		// been
		// applied to the fragment at this point so we can safely call the
		// method
		// below that sets the article text.
		Bundle args = getArguments();
		if (args != null) {
			// Set article based on argument passed in
			updateArticleView(args.getInt(ARG_POSITION));
		} else if (mCurrentPosition != -1) {
			// Set article based on saved instance state defined during
			// onCreateView
			updateArticleView(mCurrentPosition);
		}
	}

	public void updateArticleView(int position) {

		mapView = (MapView) getActivity().findViewById(R.id.map);

		mapView.enableWrapAround(true);

		// Add Tile layer to the MapView
		String tileURL = getActivity().getResources().getString(
				R.string.tileServiceURL);
		ArcGISTiledMapServiceLayer tilelayer = new ArcGISTiledMapServiceLayer(
				tileURL);
		mapView.addLayer(tilelayer);

		firstGeomLayer = new GraphicsLayer();
		mapView.addLayer(firstGeomLayer);

		secondGeomLayer = new GraphicsLayer();
		mapView.addLayer(secondGeomLayer);

		resultGeomLayer = new GraphicsLayer();
		mapView.addLayer(resultGeomLayer);

		/**
		 * Single tap listener for MapView ***************
		 */
		mapView.setOnSingleTapListener(new OnSingleTapListener() {
			private static final long serialVersionUID = 1L;

			public void onSingleTap(float x, float y) {
				if (isSketchingEnabled) {
					try {
						singleTapAct(x, y);
					} catch (Exception ex) {
						Log.d("TAG", ex.getMessage()); 
					}
				}
			}
		});

		// Set the message in the toast
		Toast.makeText(getActivity(),
				"Draw two intersecting polygons by tapping on the map",
				Toast.LENGTH_LONG).show();

		// set the behavior of all buttons
		setButtons();

		mCurrentPosition = position;
	}

	/**
	 * SET BUTTONS **************************
	 */
	void setButtons() {

		operationTypeRadio = (RadioGroup) getActivity().findViewById(
				R.id.operationtype);
		union = (RadioButton) getActivity().findViewById(R.id.union);
		difference = (RadioButton) getActivity().findViewById(R.id.difference);
		operationTypeRadio
				.setOnCheckedChangeListener(new OnCheckedChangeListener() {

					@Override
					public void onCheckedChanged(RadioGroup group, int checkedId) {

						// Set operation type
						switch (checkedId) {

						case R.id.union:
							operationType = OPERATION_TYPE.union;
							break;

						case R.id.difference:
							operationType = OPERATION_TYPE.difference;
							break;

						}

						doOperation();

					}
				});

		resetButton = (Button) getActivity().findViewById(R.id.reset);
		resetButton.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				firstGeometry = null;
				secondGeometry = null;

				firstGeomLayer.removeAll();
				secondGeomLayer.removeAll();

				resultGeomLayer.removeAll();
				addsecGeometry.setEnabled(true);

				union.setChecked(true);
				difference.setChecked(false);
				operationType = OPERATION_TYPE.union;

				countDoOperationDifference = true;
				countDoOperationUnion = true;

				geomNumWorkon = 1;
				plusButtonCount = 0;
				isSketchingEnabled = true;

			}
		});

		addsecGeometry = (Button) getActivity().findViewById(R.id.secgeometry);
		addsecGeometry.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				// first geometry is done start second geometry
				// and after the second button press display result geometry
				plusButtonCount++;

				if (plusButtonCount < 3) {

					geomNumWorkon = 2;
					if (plusButtonCount == 2) {
						doOperation();
					}
				}

			}
		});

	}

	void doOperation() {

		if (plusButtonCount == 2) {
			addsecGeometry.setEnabled(false);
			isSketchingEnabled = false;
			plusButtonCount++;
		}

		if (firstGeometry != null && secondGeometry != null) {

			if (operationType == OPERATION_TYPE.union) {
				try {
					// perform union operation
					Geometry[] geoms = new Geometry[2];
					geoms[0] = firstGeometry;
					geoms[1] = secondGeometry;

					if (countDoOperationUnion == true) {
						geometryFromUnion = GeometryEngine.union(geoms,
								spatialRef);
						countDoOperationUnion = false;
					}
					displayResultGeometry(geometryFromUnion);
				} catch (Exception ex) {
					Log.e("union", "" + ex);
				}
			} else if (operationType == OPERATION_TYPE.difference) {
				// Execute difference operation
				try {

					if (countDoOperationDifference == true) {
						geometryFromDiff = GeometryEngine.difference(
								firstGeometry, secondGeometry, spatialRef);
						countDoOperationDifference = false;
					}
					displayResultGeometry(geometryFromDiff);

				} catch (Exception ex) {
					Log.e("difference", "" + ex);
				}
			}
		}

	}

	void displayResultGeometry(Geometry geometry) throws Exception {
		if (geometry == null)
			return;
		Geometry[] geometries = new Geometry[1];
		geometries[0] = geometry;
		int red = Color.RED;
		resultGeomLayer.removeAll();
		GeometryUtil.highlightGeometriesWithColor(geometries, resultGeomLayer,
				red);

	}

	/**
	 * action to take on single taping.
	 */
	volatile int countTap = 0;

	// private String TAG = UnionDifferenceFragment.class.getSimpleName();

	void singleTapAct(float x, float y) throws Exception {
		countTap++;
		Point point = mapView.toMapPoint(x, y);
		Log.d("sigle tap on screen:", "[" + x + "," + y + "]");
		Log.d("sigle tap on map:", "[" + point.getX() + "," + point.getY()
				+ "]");
		if (geomNumWorkon == 1) {
			if (firstGeometry == null) {
				if (firstGeoType == GEOMETRY_TYPE.point) {
					firstGeometry = point;

				} else if (firstGeoType == GEOMETRY_TYPE.multi_points) {
					firstGeometry = new MultiPoint();
					((MultiPoint) firstGeometry).add(point);
				} else if (firstGeoType == GEOMETRY_TYPE.polygon) {
					firstGeometry = new Polygon();
					((MultiPath) firstGeometry).startPath(point);
					isStartPointSet1 = true;
					Log.d("geometry step " + countTap, GeometryEngine
							.geometryToJson(mapView.getSpatialReference(),
									firstGeometry));

				} else if (firstGeoType == GEOMETRY_TYPE.polyline) {
					isStartPointSet1 = true;
					firstGeometry = new Polyline();
					((MultiPath) firstGeometry).startPath(point);
				}

			}

		} else if (geomNumWorkon == 2) {
			if (secondGeometry == null) {
				if (secondGeoType == GEOMETRY_TYPE.point) {
					secondGeometry = point;

				} else if (secondGeoType == GEOMETRY_TYPE.multi_points) {
					secondGeometry = new MultiPoint();
					((MultiPoint) secondGeometry).add(point);
				} else if (secondGeoType == GEOMETRY_TYPE.polygon) {
					secondGeometry = new Polygon();
					((MultiPath) secondGeometry).startPath(point);
					isStartPointSet2 = true;

				} else if (secondGeoType == GEOMETRY_TYPE.polyline) {
					isStartPointSet2 = true;
					secondGeometry = new Polyline();
					((MultiPath) secondGeometry).startPath(point);
				}

			}

		}

		if (geomNumWorkon == 1) {
			if (firstGeoType == null)
				return;
			int blue = Color.BLUE;
			int color1 = Color.argb(100, Color.red(blue), Color.green(blue),
					Color.blue(blue));
			drawGeomOnGraphicLyr(firstGeometry, firstGeomLayer, point,
					firstGeoType, color1, isStartPointSet1);
			Log.d("geometry step " + countTap, GeometryEngine.geometryToJson(
					mapView.getSpatialReference(), firstGeometry));

		} else if (geomNumWorkon == 2) {
			if (secondGeoType == null)
				return;
			int green = Color.GREEN;
			int color2 = Color.argb(100, Color.red(green), Color.green(green),
					Color.blue(green));
			drawGeomOnGraphicLyr(secondGeometry, secondGeomLayer, point,
					secondGeoType, color2, isStartPointSet2);
		}

	}

	void drawGeomOnGraphicLyr(Geometry geometryToDraw, GraphicsLayer glayer,
			Point point, GEOMETRY_TYPE geoTypeToDraw, int color,
			boolean startPointSet) {

		if (geoTypeToDraw == GEOMETRY_TYPE.point) {
			geometryToDraw = point;

		} else if (geoTypeToDraw == GEOMETRY_TYPE.multi_points) {
			((MultiPoint) geometryToDraw).add(point);
		} else {

			if (startPointSet) {

				if (geoTypeToDraw == GEOMETRY_TYPE.polygon) {
					((Polygon) geometryToDraw).lineTo(point);
				} else if (geoTypeToDraw == GEOMETRY_TYPE.polyline) {
					((Polyline) geometryToDraw).lineTo(point);
				}

			}
		}

		Geometry[] geoms = new Geometry[1];
		geoms[0] = geometryToDraw;

		try {
			glayer.removeAll();
			GeometryUtil.highlightGeometriesWithColor(geoms, glayer, color);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@Override
	public void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);

		// Save the current article selection in case we need to recreate the
		// fragment
		outState.putInt(ARG_POSITION, mCurrentPosition);
	}
}
Feedback on this topic?