package edu.mit.mitmobile2.maps;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import com.esri.android.map.Callout;
import com.esri.android.map.GraphicsLayer;
import com.esri.android.map.Layer;
import com.esri.android.map.LocationService;
import com.esri.android.map.MapView;
import com.esri.android.map.ags.ArcGISTiledMapServiceLayer;
import com.esri.android.map.event.OnSingleTapListener;
import com.esri.android.map.event.OnStatusChangedListener;
import com.esri.core.geometry.GeometryEngine;
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.map.Graphic;
import com.esri.core.symbol.PictureMarkerSymbol;
import com.esri.core.symbol.SimpleLineSymbol;
import edu.mit.mitmobile2.MobileWebApi;
import edu.mit.mitmobile2.R;
import edu.mit.mitmobile2.objs.MapItem;
import edu.mit.mitmobile2.objs.MapPoint;
public class MITMapView extends MapView {
private static final String TAG = "MITMapView";
private MapAbstractionObject mao;
private static SpatialReference mercatorWeb; // spatial reference used by the base map
private static SpatialReference wgs84; // spatial reference used by androids location service
public static String DEFAULT_GRAPHICS_LAYER = "LAYER_GRAPHICS";
public static int DEFAULT_PIN = R.drawable.map_red_pin;
private Polygon selectedExtent; // selected extent for use with fitMapItems
private boolean showCallout = true;
PictureMarkerSymbol pms;
private static int MAP_PADDING = 100;
private static Double WGS84_PADDING = 0.0005; // use to padd wgs84 map points before they are projected to webmercator
private GraphicsLayer gl;
private Context mContext;
protected LocationService ls;
protected boolean baseLayersLoaded = false;
public static final String MAP_ITEMS_KEY = "map_items";
public static final String MAP_ITEM_INDEX_KEY = "map_item_index";
public MITMapView(Context context) {
super(context);
mContext = context;
init(context);
}
public MITMapView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
init(context);
}
public void addMAOBaseLayer(MapBaseLayer mapBaseLayer) {
mao.getBaseLayers().put(mapBaseLayer.getLayerIdentifier(), mapBaseLayer);
}
public void addMAOGraphicsLayer(String layerName) {
MapGraphicsLayer mapGraphicsLayer = new MapGraphicsLayer(layerName);
mao.getGraphicsLayers().put(layerName, mapGraphicsLayer);
}
public void addMapLayer(Layer layer, String layerName) {
this.addLayer(layer);
mao.getLayerIdMap().put(layerName, layer.getID());
}
public Layer getMapLayer(String layerName) {
if (mao.getLayerIdMap() != null) {
Long id = mao.getLayerIdMap().get(layerName);
return this.getLayerByID(id);
}
else {
return null;
}
}
public void updateBaseLayersStatus() {
// loop through base layers
Iterator<Map.Entry<String,MapBaseLayer>> it = mao.getBaseLayers().entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String,MapBaseLayer> glpairs = (Map.Entry<String,MapBaseLayer>)it.next();
String layerName = (String)glpairs.getKey();
Layer layer = this.getMapLayer(layerName);
if (!layer.isInitialized()) {
this.baseLayersLoaded = false;
}
}
this.baseLayersLoaded = true;
MobileWebApi.sendSuccessMessage(mapInitUiHandler);
}
public void addMapItems(ArrayList<? extends MapItem> mapItems) {
addMapItems(mapItems,MITMapView.DEFAULT_GRAPHICS_LAYER,MapGraphicsLayer.MODE_OVERWRITE);
}
public void addMapItems(ArrayList<? extends MapItem> mapItems, int mode) {
addMapItems(mapItems,MITMapView.DEFAULT_GRAPHICS_LAYER,mode);
}
public void addMapItems(ArrayList<? extends MapItem> mapItems, String layerName) {
addMapItems(mapItems,layerName,MapGraphicsLayer.MODE_OVERWRITE);
}
public void addMapItems(ArrayList<? extends MapItem> mapItems, String layerName, int mode) {
Log.d("PAUSE","add map items for layer " + layerName);
if (mapItems != null) {
if (!mao.getGraphicsLayers().containsKey(layerName)) {
addMAOGraphicsLayer(layerName);
}
mao.getGraphicsLayers().get(layerName).synched = false; // display layer not synched with abstract layer as soon as we add a map item
if (mao.getGraphicsLayers().get(layerName).getMapItems() != null && mode == MapGraphicsLayer.MODE_OVERWRITE) {
mao.getGraphicsLayers().get(layerName).getMapItems().clear();
}
for (int i = 0; i < mapItems.size(); i++) {
MapItem mapItem = mapItems.get(i);
mapItem.setGraphicsLayer(layerName);
if (!mao.getGraphicsLayers().containsKey(layerName)) {
addMAOGraphicsLayer(layerName);
}
mapItem.setIndex(mao.getGraphicsLayers().get(layerName).getMapItems().size());
mao.getGraphicsLayers().get(layerName).getMapItems().add(mapItem);
}
}
if (baseLayersLoaded) {
syncGraphicsLayers(layerName);
}
}
public void addMapItem(MapItem mapItem) {
mapItem.setGraphicsLayer(MITMapView.DEFAULT_GRAPHICS_LAYER);
addMapItem(mapItem,MITMapView.DEFAULT_GRAPHICS_LAYER);
}
public void addMapItem(MapItem mapItem, String layerName) {
mapItem.setGraphicsLayer(layerName);
if (!mao.getGraphicsLayers().containsKey(layerName)) {
addMAOGraphicsLayer(layerName);
}
mapItem.setIndex(mao.getGraphicsLayers().get(layerName).getMapItems().size());
mao.getGraphicsLayers().get(layerName).synched = false; // display layer not synched with abstract layer as soon as we add a map item
mao.getGraphicsLayers().get(layerName).getMapItems().add(mapItem);
}
public void clearMapItems() {
// clears all graphics layers
Iterator<Map.Entry<String,MapGraphicsLayer>> it = mao.getGraphicsLayers().entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String,MapGraphicsLayer> glpairs = it.next();
String layerName = glpairs.getKey();
clearMapItems(layerName);
}
}
public void clearMapItems(String layerName) {
// clears specified graphics layer
if (mao.getGraphicsLayers().get(layerName) != null) {
mao.getGraphicsLayers().get(layerName).getMapItems().clear();
mao.getGraphicsLayers().get(layerName).synched = false;
}
}
protected int dislayMapItem(MapItem mapItem) {
int gId = 0;
switch (mapItem.getGeometryType()) {
case MapItem.TYPE_POINT:
gId = displayMapPoint(mapItem);
break;
case MapItem.TYPE_POLYLINE:
gId = displayMapPolyline(mapItem);
break;
case MapItem.TYPE_POLYGON:
gId = displayMapPolygon(mapItem);
break;
default:
gId = 0;
break;
}
return gId;
}
public static Point toWebmercator(double lat, double lon) {
Point point = new Point();
point = (Point)GeometryEngine.project(new Point(lon,lat), wgs84,mercatorWeb);
return point;
}
Point projectMapPoint(MapPoint mapPoint) {
Point point = (Point)GeometryEngine.project(new Point(mapPoint.long_wgs84,mapPoint.lat_wgs84), mao.getSpatialReference(),this.getSpatialReference());
return point;
}
Polygon projectMapPolygon(Polygon mapPolygon) {
Polygon polygon = (Polygon)GeometryEngine.project(mapPolygon, mao.getSpatialReference(),this.getSpatialReference());
return polygon;
}
protected int displayMapPoint(MapItem mapItem) {
if (mapItem.getMapPoints().size() > 0) {
MapPoint mapPoint = mapItem.getMapPoints().get(0);
Point point = projectMapPoint(mapPoint);
Bitmap libImage = BitmapFactory.decodeResource(getResources(), mapItem.symbol);
BitmapDrawable libDrawable = new BitmapDrawable(libImage);
PictureMarkerSymbol pms = new PictureMarkerSymbol(libDrawable);
switch (mapItem.verticalAlign) {
case MapItem.VALIGN_TOP:
mapItem.offsetY = -(libDrawable.getIntrinsicHeight() / 2);
break;
case MapItem.VALIGN_CENTER:
mapItem.offsetY = 0;
break;
case MapItem.VALIGN_BOTTOM:
mapItem.offsetY = libDrawable.getIntrinsicHeight() / 2;
break;
default:
mapItem.offsetY = libDrawable.getIntrinsicHeight() / 2;
break;
}
switch (mapItem.horizontalAlign) {
case MapItem.ALIGN_LEFT:
mapItem.offsetX = -(libDrawable.getIntrinsicWidth() / 2);
break;
case MapItem.ALIGN_CENTER:
mapItem.offsetX = 0;
break;
case MapItem.ALIGN_RIGHT:
mapItem.offsetX = libDrawable.getIntrinsicWidth() / 2;
break;
default:
mapItem.offsetX = 0;
break;
}
pms.setOffsetY(mapItem.offsetY);
pms.setOffsetX(mapItem.offsetX);
Map<String, Object> attributes = new HashMap<String, Object>();
Graphic g = new Graphic(point, pms,attributes, null);
gl = (GraphicsLayer)this.getMapLayer(mapItem.getGraphicsLayer());
int Uid = gl.addGraphic(g);
return Uid;
}
else {
return 0;
}
}
protected int displayMapPolyline(MapItem mapItem) {
Point point;
Point startPoint;
Polyline polyline = new Polyline();
if (mapItem.getMapPoints().size() > 0) {
startPoint = projectMapPoint(mapItem.getMapPoints().get(0));
polyline.startPath(startPoint);
for (int p = 0; p < mapItem.getMapPoints().size(); p++) {
MapPoint mapPoint = mapItem.getMapPoints().get(p);
point = (Point)GeometryEngine.project(new Point(mapPoint.long_wgs84,mapPoint.lat_wgs84), mao.getSpatialReference(),this.getSpatialReference());
polyline.lineTo(point);
}
Graphic g = new Graphic(polyline,new SimpleLineSymbol(mapItem.lineColor,mapItem.lineWidth));
gl = (GraphicsLayer)this.getMapLayer(mapItem.getGraphicsLayer());
int Uid = gl.addGraphic(g);
return Uid;
}
else {
return 0;
}
}
protected int displayMapPolygon(MapItem mapItem) {
Point point;
Point startPoint;
Polygon polygon = new Polygon();
if (mapItem.getMapPoints().size() > 0) {
//startPoint = toWebmercator(mapItem.getMapPoints().get(0).lat_wgs84,mapItem.getMapPoints().get(0).long_wgs84);
startPoint = (Point)GeometryEngine.project(new Point(mapItem.getMapPoints().get(0).long_wgs84,mapItem.getMapPoints().get(0).lat_wgs84), mao.getSpatialReference(),this.getSpatialReference());
polygon.startPath(startPoint);
for (int p = 0; p < mapItem.getMapPoints().size(); p++) {
MapPoint mapPoint = mapItem.getMapPoints().get(p);
//point = toWebmercator(mapPoint.lat_wgs84,mapPoint.long_wgs84);
point = (Point)GeometryEngine.project(new Point(mapPoint.long_wgs84,mapPoint.lat_wgs84), mao.getSpatialReference(),this.getSpatialReference());
polygon.lineTo(point);
}
Graphic g = new Graphic(polygon,new SimpleLineSymbol(mapItem.lineColor,mapItem.lineWidth));
gl = (GraphicsLayer)this.getMapLayer(mapItem.getGraphicsLayer());
int Uid = gl.addGraphic(g);
return Uid;
}
else {
return 0;
}
}
public void displayCallout(Context context, MapItem mapItem) {
View calloutView = mapItem.getCallout(mContext,mao.getGraphicsLayers().get(mapItem.getGraphicsLayer()).getMapItems(),mapItem.getIndex());
FrameLayout frame = new FrameLayout(context);
frame.setBackgroundResource(R.drawable.map_detail_bubble);
frame.addView(calloutView, new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
Callout callout = getCallout();
int displayDensity = getResources().getDisplayMetrics().densityDpi;
int calloutOffset = (mapItem.offsetY * 2) * displayDensity / DisplayMetrics.DENSITY_HIGH + 9;
callout.setOffset(0, calloutOffset);
Point calloutPoint = getCalloutPoint(mapItem);
callout.setContent(frame);
callout.setCoordinates(calloutPoint);
callout.setStyle(R.xml.callout);
callout.setMaxWidth(getWidth());
callout.setMaxHeight(400);
callout.refresh();
callout.show();
}
public Point getCalloutPoint(MapItem mapItem) {
// return a Point object with the coordinates to display a callout at
// For now, method just uses the first point in the MapPoints array
// Ultimately, is should be modified to properly place callouts for lines and polygons
//Point calloutPoint = MITMapView.toWebmercator(mapItem.getMapPoints().get(0).lat_wgs84, mapItem.getMapPoints().get(0).long_wgs84);
Point calloutPoint = (Point)GeometryEngine.project(new Point(mapItem.getMapPoints().get(0).long_wgs84,mapItem.getMapPoints().get(0).lat_wgs84), mao.getSpatialReference(),this.getSpatialReference());
return calloutPoint;
}
public Polygon getGraphicExtent() {
//loops through all points for all map items and returns a polygon for the extent of those items
Double minLong = null;
Double minLat = null;
Double maxLong = null;
Double maxLat = null;
MapPoint mapPoint;
if (mao != null) {
Iterator<Map.Entry<String,MapGraphicsLayer>> it = mao.getGraphicsLayers().entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String,MapGraphicsLayer> glpairs = (Map.Entry<String,MapGraphicsLayer>)it.next();
String layerName = (String)glpairs.getKey();
MapGraphicsLayer mgl = mao.getGraphicsLayers().get(layerName);
ArrayList<MapItem> mapItems = mgl.getMapItems();
if (mapItems.size() > 0) {
for (int i = 0; i < mapItems.size(); i++) {
for (int p = 0; p < mapItems.get(i).getMapPoints().size(); p++) {
mapPoint = mapItems.get(i).getMapPoints().get(p);
if (minLong == null) {
minLong = mapPoint.long_wgs84;
minLat = mapPoint.lat_wgs84;
maxLong = mapPoint.long_wgs84;
maxLat = mapPoint.lat_wgs84;
}
else {
if (mapPoint.lat_wgs84 <= minLat) {
minLat = mapPoint.lat_wgs84;
}
if (mapPoint.lat_wgs84 >= maxLat) {
maxLat = mapPoint.lat_wgs84;
}
if (mapPoint.long_wgs84 <= minLong) {
minLong = mapPoint.long_wgs84;
}
if (mapPoint.long_wgs84 >= maxLong) {
maxLong = mapPoint.long_wgs84;
}
}
}
}
// if there is only 1 map point, add padding to create the polygon
if( mapItems.size() == 1) {
minLat -= WGS84_PADDING;
maxLat += WGS84_PADDING;
minLong -= WGS84_PADDING;
maxLong += WGS84_PADDING;
}
}
}
Point SW = new Point(minLong,minLat);
Point NW = new Point(minLong,maxLat);
Point NE = new Point(maxLong,maxLat);
Point SE = new Point(maxLong,minLat);
Polygon polygon = new Polygon();
polygon.startPath(SW);
polygon.lineTo(SW);
polygon.lineTo(NW);
polygon.lineTo(NE);
polygon.lineTo(SE);
return polygon;
}
else {
return null;
}
}
public SpatialReference getMercatorWeb() {
return mercatorWeb;
}
public SpatialReference getWgs84() {
return wgs84;
}
public void setMercatorWeb(SpatialReference mercatorWeb) {
MITMapView.mercatorWeb = mercatorWeb;
}
public void setWgs84(SpatialReference wgs84) {
MITMapView.wgs84 = wgs84;
}
public void init(final Context mContext) {
//Log.d(TAG,"mapInit");
mao = new MapAbstractionObject();
final MITMapView mapView = this;
// OnStatusChangedListener
this.setOnStatusChangedListener(new OnStatusChangedListener() {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
public void onStatusChanged(Object source, STATUS status) {
//Log.d(TAG,"map status changed: " + source.getClass().getSimpleName() + " status = " + status.getValue());
updateBaseLayersStatus();
}
});
// END OnStatusChangedListener
// OnSingleTapListener
this.setOnSingleTapListener(new OnSingleTapListener() {
private static final long serialVersionUID = 1L;
@Override
public void onSingleTap(float x, float y) {
//Log.d(TAG,"x: " + x + " y:" + y);
Callout callout = mapView.getCallout();
if (!mapView.isLoaded()) {
return;
}
if (mao.getGraphicsLayers() != null) {
Iterator<Map.Entry<String,MapGraphicsLayer>> it = mao.getGraphicsLayers().entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String,MapGraphicsLayer> glpairs = (Map.Entry<String,MapGraphicsLayer>)it.next();
String layerName = (String)glpairs.getKey();
MapGraphicsLayer mapGraphicsLayer = mapView.getMao().getGraphicsLayers().get(layerName);
GraphicsLayer gl = (GraphicsLayer)mapView.getMapLayer(layerName);
if (gl != null) {
int[] graphicId = gl.getGraphicIDs(x, y, 10);
if (graphicId.length > 0) {
for (int i = 0; i < graphicId.length; i++) {
Graphic g = gl.getGraphic(graphicId[i]);
// get the index of the mapItem from the GraphicIdMap
Integer mapItemIndex = mapView.getMao().getGraphicsLayers().get(layerName).getGraphicIdMap().get(Integer.toString(g.getUid()));
// get the mapItem
MapItem mapItem = mapView.getMao().getGraphicsLayers().get(layerName).getMapItems().get(mapItemIndex);
// Display the Callout if it is defined
if (mapItem.getCallout(mapView.getContext(),mapGraphicsLayer.getMapItems(),mapItemIndex.intValue()) != null) {
// center to the selected item
Point centerPt = mapView.projectMapPoint(mapItem.getCenter());
mapView.centerAt(centerPt, false);
mapView.displayCallout(mContext, mapItem);
return; // quit after the first callout is displayed
}
}
}
else {
callout.hide();
}
} // end if gl != null
} // end while
} // end if mao.getGraphicsLayers() != null
}
});
// END OnSingleTapListener
MapModel.fetchMapServerData(mContext, mapUiHandler);
}
public Handler mapUiHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
//mLoadingView.setVisibility(View.GONE);
if (msg.arg1 == MobileWebApi.SUCCESS) {
//Log.d(TAG,"MobileWebApi success");
MapServerData mapServerData = (MapServerData)msg.obj;
// get the layers for the default group
String defaultBasemap = mapServerData.getDefaultBasemap();
// add the base layers to the map
ArrayList<MapBaseLayer> baseMaps = mapServerData.getBaseLayerGroup().get(defaultBasemap);
if (baseMaps != null) {
for (int i = 0; i < baseMaps.size(); i++) {
MapBaseLayer layer = baseMaps.get(i);
addMAOBaseLayer(layer);
}
}
// add all defined base layers to the mapView
syncLayers();
// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
makeUseOfNewLocation(location);
}
private void makeUseOfNewLocation(Location location) {
//Log.d(TAG,"makeUseOfNewLocation");
// TODO Auto-generated method stub
if (location != null) {
//Log.d(TAG,"lat = " + location.getLatitude());
//Log.d(TAG,"lon = " + location.getLongitude());
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
//Log.d(TAG,"map status = " + status);
//Log.d(TAG,"initialized = " + OnStatusChangedListener.STATUS.INITIALIZED);
}
@Override
public void onProviderEnabled(String provider) {}
@Override
public void onProviderDisabled(String provider) {}
};
// Initialize location service
ls = getLocationService();
Log.d(TAG,"new Locationistener");
ls.setLocationListener(locationListener);
ls.setAutoPan(false);
ls.setAllowNetworkLocation(true);
ls.start();
onMapLoaded();
} else if (msg.arg1 == MobileWebApi.ERROR) {
//mLoadingView.showError();
} else if (msg.arg1 == MobileWebApi.CANCELLED) {
//mLoadingView.showError();
}
}
};
public void syncLayers() {
syncBaseLayers();
}
public void syncBaseLayers() {
// loops through all base layers defined in the map abstraction object, mao, and adds them to the mapView if they don't already exists
Iterator<Map.Entry<String,MapBaseLayer>> it = mao.getBaseLayers().entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String,MapBaseLayer> glpairs = (Map.Entry<String,MapBaseLayer>)it.next();
String layerName = (String)glpairs.getKey();
MapBaseLayer layer = mao.getBaseLayers().get(layerName);
Long layerId = mao.getLayerIdMap().get(layerName);
if (layerId == null) {
// create and add the layer
ArcGISTiledMapServiceLayer serviceLayer = new ArcGISTiledMapServiceLayer(layer.getUrl());
serviceLayer.setName(layer.getLayerIdentifier());
addMapLayer(serviceLayer, serviceLayer.getName());
}
}
}
public void syncGraphicsLayers() {
syncGraphicsLayers(null);
}
public void syncGraphicsLayers(String selectedLayerName) {
Log.d(TAG,"syncGraphicsLayers()");
Log.d("PAUSE","syncing graphics for selected layer " + selectedLayerName);
// loops through all graphics layers defined in mao, adding them if they dont exist
// adds mapitem from each graphics layer in mao, overwriting mapitems
Iterator<Map.Entry<String,MapGraphicsLayer>> it = mao.getGraphicsLayers().entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String,MapGraphicsLayer> glpairs = (Map.Entry<String,MapGraphicsLayer>)it.next();
final String layerName = (String)glpairs.getKey();
if (selectedLayerName == null || selectedLayerName.endsWith(layerName)) {
MapGraphicsLayer layer = mao.getGraphicsLayers().get(layerName);
if (!layer.synched) {
Long layerId = mao.getLayerIdMap().get(layerName);
if (layerId == null) {
// create and add the layer
GraphicsLayer graphicsLayer = new GraphicsLayer();
graphicsLayer.setName(layerName);
graphicsLayer.setOnStatusChangedListener(new OnStatusChangedListener() {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
public void onStatusChanged(Object source, STATUS status) {
if (OnStatusChangedListener.STATUS.INITIALIZED == status){
Log.d(TAG,source.getClass().getName() + " " + ((GraphicsLayer)source).getName() + " is initialized");
if (baseLayersLoaded) {
//Log.d(TAG,"all base layers loaded, ready to add graphics");
processMapItems(layerName);
}
else {
//Log.d(TAG,"still waiting for base layers to load");
}
}
}
});
addMapLayer(graphicsLayer, layerName);
}
else {
if (baseLayersLoaded) {
Log.d(TAG,"all base layers loaded, ready to add graphics");
processMapItems(layerName);
}
else {
Log.d(TAG,"still waiting for base layers to load");
}
}
} // end if layer not synched
} // end if (selectedLayerName == null || selectedLayerName.endsWith(layerName))
}
// Display the callout if there is only one map item with a defined callout, and showCallout is true
ArrayList<MapItem> calloutItems = getCalloutItems();
Log.d(TAG,"num calloutItems = " + calloutItems.size());
Log.d(TAG,"showCallout = " + this.showCallout);
if (calloutItems.size() == 1 && this.showCallout) {
displayCallout(mContext, calloutItems.get(0));
}
}
final class MyOnStatusChangedListener implements OnStatusChangedListener {
private static final long serialVersionUID = 1L;
@Override
public void onStatusChanged(Object source, STATUS status) {
//conditional checks if mapView's status has changed to initialized
if (OnStatusChangedListener.STATUS.INITIALIZED == status && source == this) {
Log.d(TAG,"mapView is initiallized");
}
}
}
public Handler mapInitUiHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
Log.d(TAG,"mapInitUiHandler success");
if (msg.arg1 == MobileWebApi.SUCCESS) {
try {
Log.d(TAG,"map is initialized, synching graphics");
syncGraphicsLayers();
if (selectedExtent != null) {
setExtent(projectMapPolygon(selectedExtent),MAP_PADDING);
}
}
catch (Exception e) {
}
}
else if (msg.arg1 == MobileWebApi.ERROR) {
}
else if (msg.arg1 == MobileWebApi.CANCELLED) {
}
}
};
private void onMapLoaded() {
}
public void fitMapItems() {
if (baseLayersLoaded) {
setExtent(projectMapPolygon(getGraphicExtent()),MAP_PADDING);
}
else {
this.selectedExtent = getGraphicExtent();
}
}
private void processMapItems(final String layerName) {
this.getCallout().hide();
//Log.d(TAG,"processing map Items for " + layerName);
int gId = 0; // ID of graphic object created by displayMapItem
// clear the graphics layer
gl = (GraphicsLayer)getMapLayer(layerName);
gl.removeAll();
//Log.d(TAG,"clearing graphics on layer " + layerName);
// get MapGraphicsLayer
MapGraphicsLayer mapGraphicsLayer = mao.getGraphicsLayers().get(layerName);
ArrayList<MapItem> mapItems = mapGraphicsLayer.getMapItems();
// sort map items by weight of x and y coords
Collections.sort(mapItems, new CustomComparator());
for (int i = 0; i < mapItems.size(); i++) {
try {
MapItem mapItem = mapItems.get(i);
mapItem.setIndex(i);
// get the ID of the graphic once it has been added to the graphics layer
gId = dislayMapItem(mapItem);
// store the index (i) of the mapItem in the graphicIdMap with the key of the graphic ID
// this will let ut use the ID of the tapped graphic to get the corresponding mapItem and create the callout
mapGraphicsLayer.getGraphicIdMap().put(Integer.toString(gId),Integer.valueOf(i));
}
catch (Exception e) {
Log.d(TAG, "error processing map items");
Log.d(TAG, ""+e.getStackTrace().toString());
}
}
mapGraphicsLayer.synched = true;
}
public MapAbstractionObject getMao() {
return mao;
}
public void setMao(MapAbstractionObject mao) {
this.mao = mao;
}
public class CustomComparator implements Comparator<MapItem> {
@Override
public int compare(MapItem o1, MapItem o2) {
return o2.getSortWeight().compareTo(o1.getSortWeight());
}
}
public void debugMAO() {
Iterator<Map.Entry<String,MapGraphicsLayer>> it = mao.getGraphicsLayers().entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String,MapGraphicsLayer> glpairs = (Map.Entry<String,MapGraphicsLayer>)it.next();
final String layerName = (String)glpairs.getKey();
MapGraphicsLayer layer = mao.getGraphicsLayers().get(layerName);
Log.d(TAG,"Graphics Layer: " + layerName);
Log.d(TAG,layer.getMapItems().size() + " map Items for layer");
}
}
@Override
public void pause() {
// TODO Auto-generated method stub
super.pause();
Log.d("PAUSE","pause map");
}
@Override
public void unpause() {
// TODO Auto-generated method stub
super.unpause();
Log.d("PAUSE","unpause map");
}
protected ArrayList<Graphic> getCalloutGraphics() {
ArrayList<Graphic> calloutGraphics = new ArrayList<Graphic>();
if (mao.getGraphicsLayers() != null) {
Iterator<Map.Entry<String,MapGraphicsLayer>> it = mao.getGraphicsLayers().entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String,MapGraphicsLayer> glpairs = (Map.Entry<String,MapGraphicsLayer>)it.next();
String layerName = (String)glpairs.getKey();
MapGraphicsLayer mapGraphicsLayer = this.getMao().getGraphicsLayers().get(layerName);
GraphicsLayer gl = (GraphicsLayer)this.getMapLayer(layerName);
if (gl != null) {
int[] graphicId = gl.getGraphicIDs();
if (graphicId.length > 0) {
for (int i = 0; i < graphicId.length; i++) {
Graphic g = gl.getGraphic(graphicId[i]);
// get the index of the mapItem from the GraphicIdMap
Integer mapItemIndex = this.getMao().getGraphicsLayers().get(layerName).getGraphicIdMap().get(Integer.toString(g.getUid()));
// get the mapItem
MapItem mapItem = this.getMao().getGraphicsLayers().get(layerName).getMapItems().get(mapItemIndex);
// If a callout is defined for the mapItem, add its graphic to the graphics array
if (mapItem.getCallout(this.getContext(),mapGraphicsLayer.getMapItems(),mapItemIndex.intValue()) != null) {
calloutGraphics.add(g);
}
}
}
}
}
}
return calloutGraphics;
}
private ArrayList<MapItem> getCalloutItems() {
ArrayList<MapItem> calloutItems = new ArrayList<MapItem>();
if (mao.getGraphicsLayers() != null) {
Iterator<Map.Entry<String,MapGraphicsLayer>> it = mao.getGraphicsLayers().entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String,MapGraphicsLayer> glpairs = (Map.Entry<String,MapGraphicsLayer>)it.next();
String layerName = (String)glpairs.getKey();
MapGraphicsLayer mapGraphicsLayer = this.getMao().getGraphicsLayers().get(layerName);
if (mapGraphicsLayer.getMapItems() != null) {
for (int m = 0; m < mapGraphicsLayer.getMapItems().size(); m++) {
MapItem mapItem = mapGraphicsLayer.getMapItems().get(m);
if (mapItem.getCallout(this.getContext(),mapItem) != null) {
calloutItems.add(mapItem);
}
}
}
}
}
return calloutItems;
}
}