/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.mobeegal.android.view.maps;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.mobeegal.android.R;
import com.mobeegal.android.model.MapLocation;
import com.mobeegal.android.view.MapLocationViewer;
import java.util.Iterator;
/**
* @author jailani
*/
public class MapLocationOverlay
extends Overlay
{
// Store these as global instances so we don't keep reloading every time
private Bitmap bubbleIcon, shadowIcon;
private MapLocationViewer mapView;
private Paint innerPaint, borderPaint, textPaint;
// The currently selected Map Location...if any is selected. This tracks whether an information
// window should be displayed & where...i.e. whether a user 'clicked' on a known map location
private MapLocation selectedMapLocation;
public MapLocationOverlay(MapLocationViewer mapView)
{
this.mapView = mapView;
bubbleIcon = BitmapFactory
.decodeResource(mapView.getResources(), R.drawable.bubble);
shadowIcon = BitmapFactory
.decodeResource(mapView.getResources(), R.drawable.shadow);
}
@Override
public boolean onTap(GeoPoint p, MapView mapView)
{
// Store whether prior popup was displayed so we can call invalidate() & remove it if necessary.
boolean isRemovePriorPopup = selectedMapLocation != null;
// Next test whether a new popup should be displayed
selectedMapLocation = getHitMapLocation(p);
if (isRemovePriorPopup || selectedMapLocation != null)
{
mapView.invalidate();
}
// Lastly return true if we handled this onTap()
return selectedMapLocation != null;
}
@Override
public void draw(Canvas canvas, MapView mapview, boolean flag)
{
drawMapLocations(canvas, flag);
drawInfoWindow(canvas, flag);
}
/**
* Test whether an information balloon should be displayed or a prior
* balloon hidden.
*/
private MapLocation getHitMapLocation(GeoPoint tapPoint)
{
// Track which MapLocation was hit...if any
MapLocation hitMapLocation = null;
RectF hitTestRecr = new RectF();
int[] screenCoords = new int[2];
Iterator<MapLocation> iterator = mapView.getMapLocations().iterator();
while (iterator.hasNext())
{
MapLocation testLocation = iterator.next();
// Translate the MapLocation's lat/long coordinates to screen coordinates
// calculator.getPointXY(testLocation.getPoint(), screenCoords);
// Create a 'hit' testing Rectangle w/size and coordinates of our icon
// Set the 'hit' testing Rectangle with the size and coordinates of our on screen icon
hitTestRecr.set(-bubbleIcon.getWidth() / 2, -bubbleIcon.getHeight(),
bubbleIcon.getWidth() / 2, 0);
hitTestRecr.offset(screenCoords[0], screenCoords[1]);
// Finally test for a match between our 'hit' Rectangle and the location clicked by the user
// calculator.getPointXY(tapPoint, screenCoords);
if (hitTestRecr.contains(screenCoords[0], screenCoords[1]))
{
hitMapLocation = testLocation;
break;
}
}
// Lastly clear the newMouseSelection as it has now been processed
tapPoint = null;
return hitMapLocation;
}
private void drawMapLocations(Canvas canvas, boolean shadow)
{
Iterator<MapLocation> iterator = mapView.getMapLocations().iterator();
int[] screenCoords = new int[2];
while (iterator.hasNext())
{
MapLocation location = iterator.next();
// calculator.getPointXY(location.getPoint(), screenCoords);
if (shadow)
{
// Only offset the shadow in the y-axis as the shadow is angled so the base is at x=0;
canvas.drawBitmap(shadowIcon, screenCoords[0],
screenCoords[1] - shadowIcon.getHeight(), null);
}
else
{
canvas.drawBitmap(bubbleIcon,
screenCoords[0] - bubbleIcon.getWidth() / 2,
screenCoords[1] - bubbleIcon.getHeight(), null);
}
}
}
private void drawInfoWindow(Canvas canvas, boolean shadow)
{
if (selectedMapLocation != null)
{
if (shadow)
{
// Skip painting a shadow in this tutorial
}
else
{
// First determine the screen coordinates of the selected MapLocation
int[] selDestinationOffset = new int[2];
// calculator.getPointXY(selectedMapLocation.getPoint(), selDestinationOffset);
// Setup the info window with the right size & location
int INFO_WINDOW_WIDTH = 125;
int INFO_WINDOW_HEIGHT = 25;
RectF infoWindowRect =
new RectF(0, 0, INFO_WINDOW_WIDTH, INFO_WINDOW_HEIGHT);
int infoWindowOffsetX =
selDestinationOffset[0] - INFO_WINDOW_WIDTH / 2;
int infoWindowOffsetY = selDestinationOffset[1] -
INFO_WINDOW_HEIGHT - bubbleIcon.getHeight();
infoWindowRect.offset(infoWindowOffsetX, infoWindowOffsetY);
// Draw inner info window
canvas.drawRoundRect(infoWindowRect, 5, 5, getInnerPaint());
// Draw border for info window
canvas.drawRoundRect(infoWindowRect, 5, 5, getBorderPaint());
// Draw the MapLocation's name
int TEXT_OFFSET_X = 10;
int TEXT_OFFSET_Y = 15;
canvas.drawText(selectedMapLocation.getName(),
infoWindowOffsetX + TEXT_OFFSET_X,
infoWindowOffsetY + TEXT_OFFSET_Y, getTextPaint());
}
}
}
public Paint getInnerPaint()
{
if (innerPaint == null)
{
innerPaint = new Paint();
innerPaint.setARGB(225, 75, 75, 75); //gray
innerPaint.setAntiAlias(true);
}
return innerPaint;
}
public Paint getBorderPaint()
{
if (borderPaint == null)
{
borderPaint = new Paint();
borderPaint.setARGB(255, 255, 255, 255);
borderPaint.setAntiAlias(true);
borderPaint.setStyle(Style.STROKE);
borderPaint.setStrokeWidth(2);
}
return borderPaint;
}
public Paint getTextPaint()
{
if (textPaint == null)
{
textPaint = new Paint();
textPaint.setARGB(255, 255, 255, 255);
textPaint.setAntiAlias(true);
}
return textPaint;
}
}