title: Android Image map
body: <p>I use the following code to display a very large bitmap which is zoomable by pinch gesture</p>
  
  <pre><code>package com.davemorrissey.labs.subscaleview;
  
  import android.app.Activity;
  import android.graphics.PointF;
  import android.os.Bundle;
  import android.util.Log;
  import com.davemorrissey.labs.subscaleview.R.id;
  
  import java.io.IOException;
  
  public class DemoActivity extends Activity {
  
  private static final String STATE_SCALE = "state-scale";
  private static final String STATE_CENTER_X = "state-center-x";
  private static final String STATE_CENTER_Y = "state-center-y";
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      try {
          SubsamplingScaleImageView imageView = (SubsamplingScaleImageView)findViewById(id.imageView);
          imageView.setImageAsset("DSC00266.jpg");
  
          if (savedInstanceState != null &amp;&amp; 
                  savedInstanceState.containsKey(STATE_SCALE) &amp;&amp;
                  savedInstanceState.containsKey(STATE_CENTER_X) &amp;&amp;
                  savedInstanceState.containsKey(STATE_CENTER_Y)) {
              imageView.setScaleAndCenter(savedInstanceState.getFloat(STATE_SCALE), new PointF(savedInstanceState.getFloat(STATE_CENTER_X), savedInstanceState.getFloat(STATE_CENTER_Y)));
          }
      } catch (IOException e) {
          Log.e(DemoActivity.class.getSimpleName(), "Could not load asset", e);
      }
  }
  
  @Override
  protected void onSaveInstanceState(Bundle outState) {
      super.onSaveInstanceState(outState);
  
      SubsamplingScaleImageView imageView = (SubsamplingScaleImageView)findViewById(id.imageView);
      outState.putFloat(STATE_SCALE, imageView.getScale());
      PointF center = imageView.getCenter();
      if (center != null) {
          outState.putFloat(STATE_CENTER_X, center.x);
          outState.putFloat(STATE_CENTER_Y, center.y);
      }
  }
  }
  </code></pre>
  
  <p>the gesture is handled by a separate class called SubsamplingScaleImageView.java which has the following code to handle the pinch and zoom</p>
  
  <pre><code>public boolean onTouchEvent(MotionEvent event) {
      PointF vCenterEnd;
      float vDistEnd;
      flingMomentum = null;
      flingFrom = null;
      // Detect flings
      if (detector == null || detector.onTouchEvent(event)) {
          return true;
      }
      // Abort if not ready
      if (vTranslate == null) {
          return true;
      }
      int touchCount = event.getPointerCount();
      switch (event.getAction()) {
          case MotionEvent.ACTION_DOWN:
          case MotionEvent.ACTION_POINTER_1_DOWN:
          case MotionEvent.ACTION_POINTER_2_DOWN:
              if (touchCount &gt;= 2) {
                  // Start pinch to zoom. Calculate distance between touch points and center point of the pinch.
                  float distance = distance(event.getX(0), event.getX(1), event.getY(0), event.getY(1));
                  scaleStart = scale;
                  vDistStart = distance;
                  vTranslateStart = new PointF(vTranslate.x, vTranslate.y);
                  vCenterStart = new PointF((event.getX(0) + event.getX(1))/2, (event.getY(0) + event.getY(1))/2);
                  isZooming = true;
              } else {
                  // Start one-finger pan
                  vTranslateStart = new PointF(vTranslate.x, vTranslate.y);
                  vCenterStart = new PointF(event.getX(), event.getY());
              }
          case MotionEvent.ACTION_MOVE:
              if (touchCount &gt;= 2 &amp;&amp; isZooming) {
                  // Calculate new distance between touch points, to scale and pan relative to start values.
                  vDistEnd = distance(event.getX(0), event.getX(1), event.getY(0), event.getY(1));
                  vCenterEnd = new PointF((event.getX(0) + event.getX(1))/2, (event.getY(0) + event.getY(1))/2);
                  scale = Math.min(maxScale, (vDistEnd / vDistStart) * scaleStart);
  
                  // Translate to place the source image coordinate that was at the center of the pinch at the start
                  // at the center of the pinch now, to give simultaneous pan + zoom.
                  float vLeftStart = vCenterStart.x - vTranslateStart.x;
                  float vTopStart = vCenterStart.y - vTranslateStart.y;
                  float vLeftNow = vLeftStart * (scale/scaleStart);
                  float vTopNow = vTopStart * (scale/scaleStart);
                  vTranslate.x = vCenterEnd.x - vLeftNow;
                  vTranslate.y = vCenterEnd.y - vTopNow;
  
                  fitToBounds();
                  refreshRequiredTiles(false);
              } else if (!isZooming) {
                  // One finger pan - translate the image
                  vTranslate.x = vTranslateStart.x + (event.getX() - vCenterStart.x);
                  vTranslate.y = vTranslateStart.y + (event.getY() - vCenterStart.y);
                  fitToBounds();
                  refreshRequiredTiles(false);
              }
              invalidate();
              break;
          case MotionEvent.ACTION_UP:
          case MotionEvent.ACTION_POINTER_UP:
          case MotionEvent.ACTION_POINTER_2_UP:
              if (event.getPointerCount() &lt; 2) {
                  isZooming = false;
              }
              // Trigger load of tiles now required
              refreshRequiredTiles(true);
              break;
      }
      return true;
  }
  </code></pre>
  
  <p>I now want to be able to double tap on an area once I have zoomed in and for the app to tell me the coordinates of the double tap</p>
  
  <p>I know i need to put code into the on touch motion event but I cant work out how to implement it</p>
  
  <p>Has anyone got any ideas how I do it?</p>
  
  <p>Any help appreciated</p>
  
  <p>Mark</p>