Android Open Source - advanced-tourist-map Advanced Tourist Map






From Project

Back to project page advanced-tourist-map.

License

The source code is released under:

GNU General Public License

If you think the Android project advanced-tourist-map listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright 2010, 2011 mapsforge.org/*  www .j a va2s  .c o m*/
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.muxe.advancedtouristmap;

import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;

import org.mapsforge.android.maps.ArrayCircleOverlay;
import org.mapsforge.android.maps.ArrayItemizedOverlay;
import org.mapsforge.android.maps.ArrayWayOverlay;
import org.mapsforge.android.maps.CircleOverlay;
import org.mapsforge.android.maps.GeoPoint;
import org.mapsforge.android.maps.ItemizedOverlay;
import org.mapsforge.android.maps.MapActivity;
import org.mapsforge.android.maps.MapController;
import org.mapsforge.android.maps.MapDatabase;
import org.mapsforge.android.maps.MapView;
import org.mapsforge.android.maps.MapView.TextField;
import org.mapsforge.android.maps.MapViewMode;
import org.mapsforge.android.maps.Overlay;
import org.mapsforge.android.maps.OverlayCircle;
import org.mapsforge.android.maps.OverlayItem;
import org.mapsforge.core.GeoCoordinate;
import org.mapsforge.core.Vertex;
import org.mapsforge.poi.PointOfInterest;
import org.muxe.advancedtouristmap.overlay.GenericOverlay;
import org.muxe.advancedtouristmap.overlay.PoiOverlayItem;
import org.muxe.advancedtouristmap.overlay.PositionOverlayItem;
import org.muxe.advancedtouristmap.overlay.WikiOverlayItem;
import org.muxe.advancedtouristmap.poi.PoiBrowserActivity;
import org.muxe.advancedtouristmap.routing.DecisionOverlay;
import org.muxe.advancedtouristmap.routing.Route;
import org.muxe.advancedtouristmap.routing.RouteCalculator;
import org.muxe.advancedtouristmap.routing.RouteList;
import org.muxe.advancedtouristmap.sourcefiles.FileManagerActivity;
import org.muxe.advancedtouristmap.sourcefiles.MapBundle;
import org.muxe.advancedtouristmap.wikipedia.ArticleRetriever;
import org.muxe.advancedtouristmap.wikipedia.ArticleRetrieverFactory;
import org.muxe.advancedtouristmap.wikipedia.WikiArticleInterface;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.util.Log;
import android.util.TimingLogger;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SubMenu;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

/**
 * A map application which uses the features from the mapsforge library. The map
 * can be centered to the current GPS coordinate. A simple file browser for
 * selecting the map file is also included. Some preferences can be adjusted via
 * the EditPreferences activity and screenshots of the map may be taken in
 * different image formats.
 */
public class AdvancedTouristMap extends MapActivity {
  private static final int DIALOG_ENTER_COORDINATES = 0;
  private static final int DIALOG_GPS_DISABLED = 1;
  private static final int DIALOG_INFO_MAP_FILE = 2;
  private static final String SCREENSHOT_DIRECTORY = "Pictures";
  private static final String SCREENSHOT_FILE_NAME = "Map screenshot";
  private static final int SCREENSHOT_QUALITY = 90;
  private static final int SELECT_MAP_FILE = 0;
  private static final int INTENT_SEARCH = 1;
  static final String TAG = AdvancedTouristMap.class.getSimpleName();

  /**
   * The default size of the memory card cache.
   */
  static final short MEMORY_CARD_CACHE_SIZE_DEFAULT = 250;

  /**
   * The maximum size of the memory card cache.
   */
  static final short MEMORY_CARD_CACHE_SIZE_MAX = 500;

  /**
   * The default move speed of the map.
   */
  static final int MOVE_SPEED_DEFAULT = 10;

  /**
   * The maximum move speed of the map.
   */
  static final int MOVE_SPEED_MAX = 30;

  AdvancedTouristMapApplication advancedMapViewerApplication;

  private InfoSetterAsync infoSetter;

  ArrayCircleOverlay positionCircleOverlay;
  private Paint circleOverlayFill;
  private Paint circleOverlayOutline;
  private ArrayWayOverlay routeOverlay;
  private DecisionOverlay decisionPointOverlay;
  private GenericOverlay genericOverlay;
  SelectionOverlay selectionOverlay;
  // Drawable selectionDrawable;
  OverlayItem selectionOverlayItem;
  private boolean displayRoute;
  private PositionOverlayItem positionOverlayItem;
  private ProgressBar progressBar;

  // routing menu
  LinearLayout routeMenu;
  private ImageButton nextDecisionPointButton;
  private ImageButton previousDecisionPointButton;
  private ImageButton showRoutingListButton;

  // private boolean followGpsEnabled;
  boolean centerGpsEnabled;
  GeoPoint lastPosition;
  Location currentBestLocation;
  private LocationListener locationListener;
  private LocationManager locationManager;
  private MapViewMode mapViewMode;
  private PowerManager powerManager;
  SharedPreferences preferences;
  private Toast toast;
  private WakeLock wakeLock;
  ImageView gpsView;
  ImageView centerView;
  MapController mapController;
  MapView mapView;
  OverlayCircle overlayCircle;
  boolean locationPickerMode;

  private GestureDetector mGestureDetector;
  private Paint fillPaint;

  void setInfosAsync(GeoPoint gp) {
    this.infoSetter = new InfoSetterAsync();
    this.infoSetter.execute(gp);
  }

  @Override
  public boolean dispatchTouchEvent(MotionEvent ev) {
    // disable auto following position on scrolling the map
    if (this.advancedMapViewerApplication.positioningEnabled
        && this.centerGpsEnabled) {
      this.mGestureDetector.onTouchEvent(ev);
    }
    return super.dispatchTouchEvent(ev);
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.options_menu, menu);
    return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.menu_info:
      return true;

    case R.id.menu_info_map_file:
      showDialog(DIALOG_INFO_MAP_FILE);
      return true;

    case R.id.menu_info_about:
      startActivity(new Intent(this, InfoView.class));
      return true;

    case R.id.menu_position:
      return true;

    case R.id.menu_position_gps_toggle:
      if (this.advancedMapViewerApplication.positioningEnabled) {
        disableFollowGPS(true);
      } else {
        if (this.locationManager
            .isProviderEnabled(LocationManager.NETWORK_PROVIDER)
            || this.locationManager
                .isProviderEnabled(LocationManager.GPS_PROVIDER)) {
          enableFollowGPS();
        } else {
          showDialog(DIALOG_GPS_DISABLED);
        }
      }
      return true;

    case R.id.menu_position_enter_coordinates:
      showDialog(DIALOG_ENTER_COORDINATES);
      return true;

    case R.id.menu_position_map_center:
      // disable GPS follow mode if it is enabled
      disableFollowGPS(true);
      this.mapController.setCenter(this.mapView.getMapDatabase()
          .getMapCenter());
      return true;

    case R.id.menu_screenshot:
      return true;

    case R.id.menu_screenshot_jpeg:
      captureScreenshotAsync(CompressFormat.JPEG);
      return true;

    case R.id.menu_screenshot_png:
      captureScreenshotAsync(CompressFormat.PNG);
      return true;

    case R.id.menu_preferences:
      startActivity(new Intent(this, EditPreferences.class));
      return true;

      // case R.id.menu_mapfile:
      // startFileBrowser();
      // return true;
    case R.id.menu_mapfile:
      startBundleBrowser();
      return true;
    case R.id.menu_route_clear:
      disableShowRoute();
      return true;
    case R.id.menu_route_new:
      startActivity(new Intent(this, RouteCalculator.class));
      return true;
    case R.id.menu_route_list:
      startActivity(new Intent(this, RouteList.class));
      return true;
    case R.id.menu_poi:
      startActivity(new Intent(this, PoiBrowserActivity.class).putExtra(
          "lat", this.mapView.getMapCenter().getLatitude()).putExtra(
          "lon", this.mapView.getMapCenter().getLongitude()));
      return true;
    case R.id.menu_clear_map:
      this.clearAllOverlays();
      return true;
    case R.id.menu_wiki:
      new WikiSetterAsync().execute(this.mapView.getMapCenter());
      showToast("Loading Wikipedia Articles");
      return true;
    default:
      return false;
    }
  }

  @Override
  public boolean onPrepareOptionsMenu(Menu menu) {
    if (this.mapView.getMapViewMode().requiresInternetConnection()) {
      menu.findItem(R.id.menu_info_map_file).setEnabled(false);
    } else {
      menu.findItem(R.id.menu_info_map_file).setEnabled(true);
    }

    MenuItem toggleGps = menu.findItem(R.id.menu_position_gps_toggle);
    if (this.locationManager == null) {
      toggleGps.setEnabled(false);
    } else if (this.advancedMapViewerApplication.positioningEnabled) {
      toggleGps.setTitle(R.string.menu_position_gps_disable);
    } else {
      toggleGps.setTitle(R.string.menu_position_gps_enable);
    }

    if (this.mapView.getMapViewMode().requiresInternetConnection()) {
      menu.findItem(R.id.menu_position_map_center).setEnabled(false);
    } else {
      menu.findItem(R.id.menu_position_map_center).setEnabled(true);
    }

    if (this.advancedMapViewerApplication.getCurrentMapBundle()
        .isRoutable()) {
      menu.findItem(R.id.menu_route).setEnabled(true);
      menu.findItem(R.id.menu_route).setVisible(true);
    } else {
      menu.findItem(R.id.menu_route).setEnabled(false);
      menu.findItem(R.id.menu_route).setVisible(false);
    }

    if (this.advancedMapViewerApplication.getCurrentMapBundle().isPoiable()) {
      menu.findItem(R.id.menu_poi).setEnabled(true);
      menu.findItem(R.id.menu_poi).setVisible(true);
    } else {
      menu.findItem(R.id.menu_poi).setEnabled(false);
      menu.findItem(R.id.menu_poi).setVisible(false);
    }

    // http://code.google.com/p/android/issues/detail?id=8359
    SubMenu routingSubmenu = menu.findItem(R.id.menu_route).getSubMenu();
    if (!this.displayRoute) {
      Log.d("Application", "set group invisible");
      // routingSubmenu.setGroupVisible(R.id.menu_route_group_visible,
      // false);
      routingSubmenu
          .setGroupEnabled(R.id.menu_route_group_visible, false);
    } else {
      // routingSubmenu.setGroupVisible(R.id.menu_route_group_visible,
      // true);
      routingSubmenu.setGroupEnabled(R.id.menu_route_group_visible, true);
    }

    return true;
  }

  @Override
  public boolean onTrackballEvent(MotionEvent event) {
    // forward the event to the MapView
    return this.mapView.onTrackballEvent(event);
  }

  private void captureScreenshotAsync(final CompressFormat format) {
    new Thread() {
      @Override
      public void run() {
        try {
          File path = new File(
              Environment.getExternalStorageDirectory(),
              SCREENSHOT_DIRECTORY);
          // make sure the Pictures directory exists
          if (!path.exists() && !path.mkdirs()) {
            showToastOnUiThread("Could not create target directory");
            return;
          }

          // assemble the complete name for the screenshot file
          String fileName = path.getAbsolutePath()
              + File.separatorChar + SCREENSHOT_FILE_NAME + "."
              + format.name().toLowerCase();

          if (AdvancedTouristMap.this.mapView.makeScreenshot(format,
              SCREENSHOT_QUALITY, fileName)) {
            // success
            showToastOnUiThread(fileName);
          } else {
            // failure
            showToastOnUiThread("Screenshot could not be saved");
          }
        } catch (IOException e) {
          showToastOnUiThread(e.getLocalizedMessage());
        }
      }

      private void showToastOnUiThread(final String message) {
        AdvancedTouristMap.this.runOnUiThread(new Runnable() {
          @Override
          public void run() {
            showToast(message);
          }
        });
      }
    }.start();
  }

  private void configureMapView() {
    // configure the MapView and activate the zoomLevel buttons
    this.mapView.setClickable(true);
    this.mapView.setBuiltInZoomControls(true);
    this.mapView.setFocusable(true);

    // set the localized text fields
    this.mapView.setText(TextField.KILOMETER,
        getString(R.string.unit_symbol_kilometer));
    this.mapView.setText(TextField.METER,
        getString(R.string.unit_symbol_meter));

    // get the map controller for this MapView
    this.mapController = this.mapView.getController();
  }

  private void enableFollowGPS() {
    this.positionCircleOverlay = new ArrayCircleOverlay(
        this.circleOverlayFill, this.circleOverlayOutline);
    this.overlayCircle = new OverlayCircle();
    this.positionCircleOverlay.addCircle(this.overlayCircle);
    // this.mapView.getOverlays().add(this.positionOverlay);
    this.insertOverlayOrdered(this.positionCircleOverlay);
    this.positionOverlayItem = new PositionOverlayItem();
    this.positionOverlayItem.setMarker(ItemizedOverlay
        .boundCenter(getResources().getDrawable(
            R.drawable.ic_maps_indicator_current_position)));
    refreshGenericOverlay();

    this.advancedMapViewerApplication.positioningEnabled = true;
    this.centerGpsEnabled = true;

    // get cached locations first
    Location currentLocation;
    for (String provider : this.locationManager.getProviders(true)) {
      currentLocation = this.locationManager
          .getLastKnownLocation(provider);
      if (currentLocation != null) {
        if (Utility.isBetterLocation(currentLocation,
            this.currentBestLocation)) {
          this.currentBestLocation = currentLocation;
          setNewPosition(currentLocation);
          Log.d(TAG, "got better cached location from: " + provider
              + " (" + currentLocation.getAccuracy() + ")");
        } else {
          Log.d(TAG, "dismissed location from: " + provider + " ("
              + currentLocation.getAccuracy() + ")");
        }
      }
    }

    this.locationListener = new LocationListener() {
      @Override
      public void onLocationChanged(Location location) {
        if (Utility.isBetterLocation(location,
            AdvancedTouristMap.this.currentBestLocation)) {
          setNewPosition(location);
        }
      }

      @Override
      public void onProviderDisabled(String provider) {
        // we can have multiple location sources
        // disableFollowGPS(false);
        // showDialog(DIALOG_GPS_DISABLED);
      }

      @Override
      public void onProviderEnabled(String provider) {
        // do nothing
      }

      @Override
      public void onStatusChanged(String provider, int status,
          Bundle extras) {
        if (status == LocationProvider.AVAILABLE) {
          AdvancedTouristMap.this.gpsView
              .setImageResource(R.drawable.stat_sys_gps_on);
        } else if (status == LocationProvider.OUT_OF_SERVICE) {
          AdvancedTouristMap.this.gpsView
              .setImageResource(R.drawable.stat_sys_gps_acquiring);
        } else {
          // must be TEMPORARILY_UNAVAILABLE
          AdvancedTouristMap.this.gpsView
              .setImageResource(R.anim.gps_animation);
          ((AnimationDrawable) AdvancedTouristMap.this.gpsView
              .getDrawable()).start();
        }
      }
    };

    this.locationManager.requestLocationUpdates(
        LocationManager.GPS_PROVIDER, 1000, 0, this.locationListener);
    this.locationManager.requestLocationUpdates(
        LocationManager.NETWORK_PROVIDER, 1000, 0,
        this.locationListener);

    // if (this.locationManager
    // .isProviderEnabled(LocationManager.GPS_PROVIDER)) {
    // this.locationManager.requestLocationUpdates(
    // LocationManager.GPS_PROVIDER, 1000, 0,
    // this.locationListener);
    // } else {
    // this.locationManager.requestLocationUpdates(
    // LocationManager.NETWORK_PROVIDER, 1000, 0,
    // this.locationListener);
    // }

    this.gpsView.setImageResource(R.drawable.stat_sys_gps_acquiring);
    this.gpsView.setVisibility(View.VISIBLE);
    this.gpsView.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        disableFollowGPS(true);
      }
    });

    // the icon to center the view to position
    this.centerView.setImageResource(android.R.drawable.ic_secure);
    this.centerView.setVisibility(View.VISIBLE);
    this.centerView.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        AdvancedTouristMap.this.centerGpsEnabled = true;
        AdvancedTouristMap.this.centerView
            .setImageResource(android.R.drawable.ic_secure);
        if (AdvancedTouristMap.this.lastPosition != null) {
          AdvancedTouristMap.this.mapController
              .setCenter(AdvancedTouristMap.this.lastPosition);
        }
      }
    });
  }

  private void setNewPosition(Location location) {
    GeoPoint point = new GeoPoint(location.getLatitude(),
        location.getLongitude());
    this.lastPosition = point;
    this.overlayCircle.setCircleData(point, location.getAccuracy());
    this.positionOverlayItem.setPoint(point);
    if (this.centerGpsEnabled) {
      this.mapController.setCenter(point);
    } else {
      // refresh position "circle"
      this.positionCircleOverlay.requestRedraw();
      // refresh position "point"
      this.genericOverlay.requestRedraw();
    }
  }

  private void startBundleBrowser() {
    startActivity(new Intent(this, FileManagerActivity.class));
  }

  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == SELECT_MAP_FILE) {
      if (resultCode == RESULT_OK) {
        disableFollowGPS(true);
        if (data != null && data.getStringExtra("selectedFile") != null) {
          this.mapView
              .setMapFile(data.getStringExtra("selectedFile"));
        }
      } else if (resultCode == RESULT_CANCELED
          && !this.mapView.getMapViewMode()
              .requiresInternetConnection()
          && !this.mapView.hasValidMapFile()) {
        finish();
      }
    } else if (requestCode == INTENT_SEARCH) {
      if (resultCode == RESULT_OK) {
        if (data != null && data.hasExtra("lon")
            && data.hasExtra("lat")) {
          double lon = data.getDoubleExtra("lon", 0.0);
          double lat = data.getDoubleExtra("lat", 0.0);
          GeoPoint point = new GeoPoint(lat, lon);
          this.mapView.getController().setCenter(point);
          // this.mapView.getController().setZoom(16);
          this.selectionOverlay.setLabel(point);
        }
      }
    }
  }

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // just visible if title bar is visible
    // requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
    // requestWindowFeature(Window.FEATURE_NO_TITLE);

    TimingLogger timings = new TimingLogger("timing", "onCreate");
    Log.d("lifecycle", "amv onCreate");

    this.advancedMapViewerApplication = (AdvancedTouristMapApplication) getApplication();

    // set up the layout views
    this.advancedMapViewerApplication.setViewWithHelp(this,
        R.layout.activity_advanced_map_viewer);
    this.mapView = (MapView) findViewById(R.id.mapView);
    this.gpsView = (ImageView) findViewById(R.id.gpsView);
    this.centerView = (ImageView) findViewById(R.id.centerView);
    this.routeMenu = (LinearLayout) findViewById(R.id.routeMenu);
    this.progressBar = (ProgressBar) findViewById(R.id.mapview_progress_bar);

    configureMapView();

    // get the pointers to different system services
    this.locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    this.powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
    this.wakeLock = this.powerManager.newWakeLock(
        PowerManager.SCREEN_DIM_WAKE_LOCK, "AMV");

    // set up the paint objects for the location overlay
    this.circleOverlayFill = new Paint(Paint.ANTI_ALIAS_FLAG);
    this.circleOverlayFill.setStyle(Paint.Style.FILL);
    this.circleOverlayFill.setColor(Color.BLUE);
    this.circleOverlayFill.setAlpha(64);

    this.circleOverlayOutline = new Paint(Paint.ANTI_ALIAS_FLAG);
    this.circleOverlayOutline.setStyle(Paint.Style.STROKE);
    this.circleOverlayOutline.setColor(Color.BLUE);
    this.circleOverlayOutline.setAlpha(128);
    this.circleOverlayOutline.setStrokeWidth(3);

    // initialize route overlay
    this.fillPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    this.fillPaint.setStyle(Paint.Style.STROKE);
    this.fillPaint.setColor(Color.BLUE);
    this.fillPaint.setAlpha(160);
    this.fillPaint.setStrokeWidth(6);
    this.fillPaint.setStrokeCap(Paint.Cap.ROUND);
    this.fillPaint.setStrokeJoin(Paint.Join.ROUND);

    // selection overlay to display labels with additional information
    this.selectionOverlay = new SelectionOverlay(null, false);
    // this.mapView.getOverlays().add(this.selectionOverlay);
    this.insertOverlayOrdered(this.selectionOverlay);

    if (this.advancedMapViewerApplication.positioningEnabled
        || (savedInstanceState != null && savedInstanceState
            .getBoolean("locationListener"))) {
      enableFollowGPS();
    }

    this.mGestureDetector = new GestureDetector(this, new ScrollListener());

    /*
     * POI STUFF EXPERIMENTAL
     */

    // Log.d("Restaurant", "achtung jetzt:");
    // IPersistenceManager perstManager = PersistenceManagerFactory
    // .getPerstPersistenceManager("/sdcard/perstPoi.dbs");
    // PoiCategory restCat = new CategoryBuilder("Restaurant").build();
    // long id = 1337;
    // PointOfInterest poi = new PoiBuilder(id, 52.455667, 13.298357,
    // "My Test", "",
    // restCat)
    // .build();
    // perstManager.insertPointOfInterest(poi);
    // TODO: isnt permanent
    // LinkedList<PointOfInterest> restaurants = new
    // LinkedList<PointOfInterest>(
    // perstManager.findNearPosition(new GeoCoordinate(52.4561009222,
    // 13.297641277),
    // 1000, "Restaurant", 50));
    // perstManager.close();
    //
    // // create the default paint objects for overlay circles
    // Paint circleDefaultPaintFill = new Paint(Paint.ANTI_ALIAS_FLAG);
    // circleDefaultPaintFill.setStyle(Paint.Style.FILL);
    // circleDefaultPaintFill.setColor(Color.BLUE);
    // circleDefaultPaintFill.setAlpha(64);
    //
    // Paint circleDefaultPaintOutline = new Paint(Paint.ANTI_ALIAS_FLAG);
    // circleDefaultPaintOutline.setStyle(Paint.Style.STROKE);
    // circleDefaultPaintOutline.setColor(Color.BLUE);
    // circleDefaultPaintOutline.setAlpha(128);
    // circleDefaultPaintOutline.setStrokeWidth(3);
    //
    // // create the CircleOverlay and add the circles
    // ArrayCircleOverlay circleOverlay2 = new
    // ArrayCircleOverlay(circleDefaultPaintFill,
    // circleDefaultPaintOutline, this);
    // // OverlayCircle circle1 = new
    // OverlayCircle(restaurants.get(0).getGeoPoint(), 10,
    // // restaurants.get(0).getName());
    // // circleOverlay2.addCircle(circle1);
    //
    // for (int i = 0; i < restaurants.size(); i++) {
    // Log.d("Restaurant", restaurants.get(i).getName());
    // circleOverlay2.addCircle(new
    // OverlayCircle(restaurants.get(i).getGeoPoint(), 50,
    // restaurants.get(i).getName()));
    // }
    //
    // this.mapView.getOverlays().add(circleOverlay2);

    timings.dumpToLog();
  }

  /**
   * This Listener checks if the map gets moved/scrolled a given distance and
   * if so, disables the auto following of the position.
   */
  class ScrollListener extends GestureDetector.SimpleOnGestureListener {
    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2,
        float distanceX, float distanceY) {
      double delta = Math.sqrt(Math.pow((e1.getX() - e2.getX()), 2)
          + Math.pow((e1.getY() - e2.getY()), 2));
      // only disable, if scrolled for a certain distance
      if (delta > 50) {
        AdvancedTouristMap.this.centerGpsEnabled = false;
        AdvancedTouristMap.this.centerView
            .setImageResource(android.R.drawable.ic_lock_idle_lock);
      }
      return true;
    }
  }

  @Override
  protected Dialog onCreateDialog(int id) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    if (id == DIALOG_ENTER_COORDINATES) {
      builder.setIcon(android.R.drawable.ic_menu_mylocation);
      builder.setTitle(R.string.menu_position_enter_coordinates);
      LayoutInflater factory = LayoutInflater.from(this);
      final View view = factory.inflate(
          R.layout.dialog_enter_coordinates, null);
      builder.setView(view);
      builder.setPositiveButton(R.string.go_to_position,
          new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
              // disable GPS follow mode if it is enabled
              disableFollowGPS(true);

              // set the map center and zoom level
              AdvancedTouristMap.this.mapController.setCenter(new GeoPoint(
                  Double.parseDouble(((EditText) view
                      .findViewById(R.id.latitude))
                      .getText().toString()),
                  Double.parseDouble(((EditText) view
                      .findViewById(R.id.longitude))
                      .getText().toString())));
              AdvancedTouristMap.this.mapController
                  .setZoom(((SeekBar) view
                      .findViewById(R.id.zoomlevel))
                      .getProgress());
            }
          });
      builder.setNegativeButton(R.string.cancel, null);
      return builder.create();
    } else if (id == DIALOG_GPS_DISABLED) {
      builder.setIcon(android.R.drawable.ic_menu_info_details);
      builder.setTitle(R.string.error);
      builder.setMessage(R.string.gps_disabled);
      builder.setPositiveButton(R.string.ok, null);
      return builder.create();
    } else if (id == DIALOG_INFO_MAP_FILE) {
      builder.setIcon(android.R.drawable.ic_menu_info_details);
      builder.setTitle(R.string.menu_info_map_file);
      LayoutInflater factory = LayoutInflater.from(this);
      builder.setView(factory
          .inflate(R.layout.dialog_info_map_file, null));
      builder.setPositiveButton(R.string.ok, null);
      return builder.create();
    } else {
      // do dialog will be created
      return null;
    }
  }

  @Override
  protected void onDestroy() {
    super.onDestroy();
    Log.d("lifecycle", "amv onDestroy");

    // remove the toast messageText if visible
    if (this.toast != null) {
      this.toast.cancel();
      this.toast = null;
    }

    // switch off location updates
    if (this.locationManager != null) {
      if (this.locationListener != null) {
        this.locationManager.removeUpdates(this.locationListener);
        this.locationListener = null;
      }
      this.locationManager = null;
    }
  }

  @Override
  protected void onPause() {
    super.onPause();
    Log.d("lifecycle", "amv onPause");
    // release the wake lock if necessary
    if (this.wakeLock.isHeld()) {
      this.wakeLock.release();
    }
    // disable info setter thread
    if (this.infoSetter != null) {
      this.infoSetter.cancel(false);
    }
    // disable (pause) location updates
    if (!this.preferences.getBoolean("keep_location_updates", false)) {
      pauseFollowGps();
    }
  }

  @Override
  protected void onPrepareDialog(int id, final Dialog dialog) {
    if (id == DIALOG_ENTER_COORDINATES) {
      // latitude
      EditText editText = (EditText) dialog.findViewById(R.id.latitude);
      GeoPoint mapCenter = this.mapView.getMapCenter();
      editText.setText(Double.toString(mapCenter.getLatitude()));

      // longitude
      editText = (EditText) dialog.findViewById(R.id.longitude);
      editText.setText(Double.toString(mapCenter.getLongitude()));

      // zoom level
      SeekBar zoomlevel = (SeekBar) dialog.findViewById(R.id.zoomlevel);
      zoomlevel.setMax(this.mapView.getMaxZoomLevel());
      zoomlevel.setProgress(this.mapView.getZoomLevel());

      // zoom level value
      final TextView textView = (TextView) dialog
          .findViewById(R.id.zoomlevelValue);
      textView.setText(String.valueOf(zoomlevel.getProgress()));
      zoomlevel
          .setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar,
                int progress, boolean fromUser) {
              textView.setText(String.valueOf(progress));
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
              // do nothing
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
              // do nothing
            }
          });
    } else if (id == DIALOG_INFO_MAP_FILE) {
      // map file name
      TextView textView = (TextView) dialog
          .findViewById(R.id.infoMapFileViewName);
      textView.setText(this.mapView.getMapFile());

      // map file name
      textView = (TextView) dialog
          .findViewById(R.id.infoMapFileViewDebug);
      MapDatabase mapDatabase = this.mapView.getMapDatabase();
      if (mapDatabase.isDebugFile()) {
        textView.setText(R.string.info_map_file_debug_yes);
      } else {
        textView.setText(R.string.info_map_file_debug_no);
      }

      // map file date
      textView = (TextView) dialog.findViewById(R.id.infoMapFileViewDate);
      Date date = new Date(mapDatabase.getMapDate());
      textView.setText(DateFormat.getDateTimeInstance().format(date));

      // map file area
      textView = (TextView) dialog.findViewById(R.id.infoMapFileViewArea);
      Rect mapArea = mapDatabase.getMapBoundary();
      textView.setText(mapArea.top / 1000000d + ", " + mapArea.left
          / 1000000d + "  \n" + mapArea.bottom / 1000000d + ", "
          + mapArea.right / 1000000d);

      // map file start position
      textView = (TextView) dialog
          .findViewById(R.id.infoMapFileViewStart);
      GeoPoint startPosition = mapDatabase.getStartPosition();
      if (startPosition == null) {
        textView.setText(null);
      } else {
        textView.setText(startPosition.getLatitude() + ", "
            + startPosition.getLongitude());
      }

      // map file comment text
      textView = (TextView) dialog
          .findViewById(R.id.infoMapFileViewComment);
      String commentText = mapDatabase.getCommentText();
      if (commentText == null) {
        textView.setText(null);
      } else {
        textView.setText(mapDatabase.getCommentText());
      }
    } else {
      super.onPrepareDialog(id, dialog);
    }
  }

  @Override
  protected void onResume() {
    super.onResume();
    TimingLogger timings = new TimingLogger("timing", "onResume");
    Log.d("lifecycle", "amv onResume");
    // TODO: still needed?
    // check if mapview was started, just to return a position
    Intent startingIntent = getIntent();
    if (startingIntent.hasExtra("mode")
        && startingIntent.getStringExtra("mode").equals(
            "LOCATION_PICKER")) {
      this.locationPickerMode = true;
    }
    // TODO: use the one from application?
    // Read the default shared preferences
    // this.preferences =
    // PreferenceManager.getDefaultSharedPreferences(this);
    this.preferences = this.advancedMapViewerApplication.prefs;

    // set the map settings
    this.mapView.setScaleBar(this.preferences.getBoolean("showScaleBar",
        false));
    if (this.preferences.contains("mapViewMode")) {
      this.mapViewMode = Enum.valueOf(MapViewMode.class, this.preferences
          .getString("mapViewMode", MapView.getDefaultMapViewMode()
              .name()));
      this.mapView.setMapViewMode(this.mapViewMode);
    }
    try {
      this.mapView.setTextScale(Float.parseFloat(this.preferences
          .getString("textScale", "1")));
    } catch (NumberFormatException e) {
      this.mapView.setTextScale(1);
    }
    timings.addSplit("set map settings");

    // set the general settings
    if (this.preferences.getBoolean("fullscreen", false)) {
      getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
      getWindow().clearFlags(
          WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
    } else {
      getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
      getWindow().addFlags(
          WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
    }
    if (this.preferences.getBoolean("wakeLock", false)) {
      if (!this.wakeLock.isHeld()) {
        this.wakeLock.acquire();
      }
    }
    this.mapView.setMemoryCardCachePersistence(this.preferences.getBoolean(
        "cachePersistence", false));
    this.mapView.setMemoryCardCacheSize(Math.min(this.preferences.getInt(
        "cacheSize", MEMORY_CARD_CACHE_SIZE_DEFAULT),
        MEMORY_CARD_CACHE_SIZE_MAX));
    this.mapView.setMoveSpeed(Math.min(
        this.preferences.getInt("moveSpeed", MOVE_SPEED_DEFAULT),
        MOVE_SPEED_MAX) / 10f);

    // set the debug settings
    this.mapView.setFpsCounter(this.preferences.getBoolean(
        "showFpsCounter", false));
    this.mapView.setTileFrames(this.preferences.getBoolean(
        "showTileFrames", false));
    this.mapView.setTileCoordinates(this.preferences.getBoolean(
        "showTileCoordinates", false));
    this.mapView.setWaterTiles(this.preferences.getBoolean(
        "showWaterTiles", false));

    timings.addSplit("set general settings");
    // check if the file browser needs to be displayed
    // if (!this.mapView.getMapViewMode().requiresInternetConnection()
    // && !this.mapView.hasValidMapFile()) {
    // startFileBrowser();
    // }

    // check for valid map bundle and start bundle browser, if not present
    MapBundle mapBundle = this.advancedMapViewerApplication
        .getCurrentMapBundle();
    if (mapBundle == null) {
      showToast(getString(R.string.select_a_valid_mapfile));
      this.startBundleBrowser();
    } else {

      // String mapBinary = this.preferences.getString("mapBinary", null);
      String mapBinary = this.advancedMapViewerApplication
          .getBaseBundlePath()
          + File.separator
          + mapBundle.getMapFile().getRelativePath();
      Log.d("Application", mapBinary);
      // if offlinemap AND (map isnt set yet OR current set map differs
      // from map to set)
      if (!this.mapView.getMapViewMode().requiresInternetConnection()
          && (this.mapView.getMapFile() == null || !this.mapView
              .getMapFile().equals(mapBinary))) {
        Log.d("Application", "Had to reset mapfile! old: "
            + this.mapView.getMapFile() + ", new: " + mapBinary);
        this.mapView.setMapFile(mapBinary);
      }
    }
    timings.addSplit("set map file");

    // check if positioning is requested but was paused
    if (this.locationListener == null
        && this.advancedMapViewerApplication.positioningEnabled) {
      enableFollowGPS();
    }

    // draw the route, if there is any
    if (this.advancedMapViewerApplication.currentRoute != null) {
      this.displayRouteOverlay(
          this.advancedMapViewerApplication.currentRoute,
          startingIntent);
    } else {
      this.displayRoute = false;
      this.routeMenu.setVisibility(View.GONE);
    }

    if (this.advancedMapViewerApplication.getCurrentPois().size() > 0
        || this.advancedMapViewerApplication.getCurrentWikiArticles()
            .size() > 0) {
      refreshGenericOverlay();
      // only one poi and requested to center
      if (this.advancedMapViewerApplication.getCurrentPois().size() == 1
          && startingIntent.getBooleanExtra("CENTER_POI", false)) {
        this.mapController
            .setCenter(Utility
                .geoCoordinateToGeoPoint(this.advancedMapViewerApplication
                    .getCurrentPois().get(0)
                    .getGeoCoordinate()));
        // this.mapController.setZoom(16);
        startingIntent.removeExtra("CENTER_POI");
      }
    }

    timings.addSplit("set route");
    timings.dumpToLog();
  }

  private void displayRouteOverlay(Route route, Intent startingIntent) {
    if (this.routeOverlay == null) {
      this.routeOverlay = new ArrayWayOverlay(this.fillPaint, null);
      // this.mapView.getOverlays().add(this.routeOverlay);
      this.insertOverlayOrdered(this.routeOverlay);
    } else {
      this.routeOverlay.clear();
    }

    if (this.decisionPointOverlay == null) {
      this.decisionPointOverlay = new DecisionOverlay(this,
          getResources().getDrawable(R.drawable.jog_tab_target_gray));
      // this.mapView.getOverlays().add(this.decisionPointOverlay);
      this.insertOverlayOrdered(this.decisionPointOverlay);
    } else {
      this.decisionPointOverlay.clear();
    }

    this.displayRoute = true;
    this.routeOverlay.addWay(route.getOverlayWay());
    this.decisionPointOverlay.addItems(Arrays.asList(route
        .getOverlayItems()));
    this.setupRoutingMenu(route);
    if (startingIntent.getBooleanExtra("ROUTE_OVERVIEW", false)) {
      // TODO: better centering of the route
      this.mapController.setCenter(route.getGeoPoints()[0]);
      this.mapController.setZoom(16);
      // only center on first onResume
      startingIntent.removeExtra("ROUTE_OVERVIEW");
    }
    if (startingIntent.getBooleanExtra("CENTER_DP", false)) {
      GeoPoint currentGP = route.currentDecisionPoint.getGeoPoint();
      this.mapController.setCenter(currentGP);
      this.selectionOverlay.setLabel(currentGP);
      // this.mapController.setZoom(16);
    }
  }

  private void refreshGenericOverlay() {
    TimingLogger timings = new TimingLogger("timing",
        "refreshGenericOverlay");
    if (this.genericOverlay == null) {
      this.genericOverlay = new GenericOverlay(this, null);
      this.insertOverlayOrdered(this.genericOverlay);
    } else {
      this.genericOverlay.clear();
    }

    if (this.advancedMapViewerApplication.getCurrentPois() != null) {
      Log.d("Overlay", "inserting pois");
      for (PointOfInterest poi : this.advancedMapViewerApplication
          .getCurrentPois()) {
        this.genericOverlay.addItem(new PoiOverlayItem(poi, poi
            .getCategory().getTitle(), poi.getName(),
            ItemizedOverlay.boundCenterBottom(getResources()
                .getDrawable(R.drawable.marker_poi))));
        // TODO BOUNDCENTER USW?
      }
    }

    if (this.advancedMapViewerApplication.getCurrentWikiArticles() != null) {
      for (WikiArticleInterface wikiArticle : this.advancedMapViewerApplication
          .getCurrentWikiArticles()) {
        this.genericOverlay.addItem(new WikiOverlayItem(wikiArticle,
            wikiArticle.getTitle(), null, ItemizedOverlay
                .boundCenter(getResources().getDrawable(
                    R.drawable.wikipedia_30))));
        // TODO BOUNDCENTER USW?
      }
    }

    if (this.positionOverlayItem != null) {
      this.genericOverlay.addItem(this.positionOverlayItem);
    }
    timings.dumpToLog();
  }

  private void clearAllOverlays() {
    // clear route
    this.disableShowRoute();
    // if position is shown, generic overlay is still needed
    if (this.positionOverlayItem != null) {
      // clear pois
      this.disablePoiOverlay();
      // clear wikipedia
      this.disableWikipediaOverlay();
      // and refresh the overlay
      this.refreshGenericOverlay();
    } else {
      // no position, so remove the whole generic overlay
      this.disableGenericOverlay();
    }
    // clear info
    this.selectionOverlay.clear();
  }

  private void disableShowRoute() {
    this.advancedMapViewerApplication.currentRoute = null;
    this.mapView.getOverlays().remove(this.decisionPointOverlay);
    this.mapView.getOverlays().remove(this.routeOverlay);
    this.decisionPointOverlay = null;
    this.routeOverlay = null;
    this.displayRoute = false;
    this.routeMenu.setVisibility(View.GONE);
  }

  private void disableWikipediaOverlay() {
    this.advancedMapViewerApplication.getCurrentWikiArticles().clear();
  }

  private void disablePoiOverlay() {
    this.advancedMapViewerApplication.getCurrentPois().clear();
  }

  private void disableGenericOverlay() {
    this.disableWikipediaOverlay();
    this.disablePoiOverlay();
    if (this.genericOverlay != null) {
      this.mapView.getOverlays().remove(this.genericOverlay);
      this.genericOverlay = null;
    }
  }

  private void insertOverlayOrdered(Overlay overlay) {
    if (overlay instanceof CircleOverlay) {
      // insert position overlay as first, always
      this.mapView.getOverlays().add(0, overlay);
    } else if (overlay instanceof SelectionOverlay) {
      // insert selection overlay as last, always
      this.mapView.getOverlays().add(overlay);
    } else if (overlay instanceof ArrayWayOverlay) {
      int positionIndex = this.mapView.getOverlays().indexOf(
          this.positionCircleOverlay);
      if (positionIndex >= 0) {
        // positionOverlay is in, so insert this one behind
        this.mapView.getOverlays().add(positionIndex + 1, overlay);
      } else {
        // no positionOverlay, so this is first
        this.mapView.getOverlays().add(0, overlay);
      }
    } else if (overlay instanceof DecisionOverlay) {
      int routeIndex = this.mapView.getOverlays().indexOf(
          this.routeOverlay);
      int positionIndex = this.mapView.getOverlays().indexOf(
          this.positionCircleOverlay);
      if (routeIndex >= 0) {
        // insert behind routeOverlay
        this.mapView.getOverlays().add(routeIndex + 1, overlay);
      } else if (positionIndex >= 0) {
        // or insert behind position overlay
        this.mapView.getOverlays().add(positionIndex + 1, overlay);
      }
    } else if (overlay instanceof GenericOverlay) {
      int selectionIndex = this.mapView.getOverlays().indexOf(
          this.selectionOverlay);
      if (selectionIndex >= 0) {
        // insert before selection overlay
        this.mapView.getOverlays().add(selectionIndex, overlay);
      } else {
        // insert as last
        this.mapView.getOverlays().add(overlay);
      }
    } else {
      // not handled, so just insert last
      this.mapView.getOverlays().add(overlay);
    }
  }

  @Override
  protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    Log.d("lifecycle", "amv onSaveInstanceState");
    outState.putBoolean("locationListener", this.locationListener != null);
  }

  /**
   * Disables the "Follow GPS mode" and removes the GPS icon.
   * 
   * @param showToastMessage
   *            if a toast message should be displayed or not.
   */
  void disableFollowGPS(boolean showToastMessage) {
    // remove the position "circle"
    if (this.positionCircleOverlay != null) {
      this.mapView.getOverlays().remove(this.positionCircleOverlay);
      // this.positionOverlay.clear();
      this.positionCircleOverlay = null;
    }
    // remove the position "dot"
    if (this.genericOverlay != null && this.positionOverlayItem != null) {
      this.genericOverlay.removeItem(this.positionOverlayItem);
      this.positionOverlayItem = null;
      this.genericOverlay.requestRedraw();
    }
    if (this.advancedMapViewerApplication.positioningEnabled) {
      if (this.locationListener != null) {
        this.locationManager.removeUpdates(this.locationListener);
        this.locationListener = null;
      }
      this.lastPosition = null;
      this.gpsView.setVisibility(View.GONE);
      this.centerView.setVisibility(View.GONE);
      if (showToastMessage) {
        showToast(getString(R.string.follow_gps_disabled));
      }
      this.advancedMapViewerApplication.positioningEnabled = false;
    }
  }

  /**
   * Removes updates on the locationListener but keeps an info that the app
   * still wants location updates, when it gets resumed
   */
  void pauseFollowGps() {
    if (this.locationListener != null) {
      this.locationManager.removeUpdates(this.locationListener);
      this.locationListener = null;
    }
  }

  @Override
  public boolean onKeyDown(int keyCode, KeyEvent event) {
    super.onKeyDown(keyCode, event);
    if (keyCode == KeyEvent.KEYCODE_SEARCH) {
      startSearch();
      return true;
    }
    return false;
  }

  /**
   * Show the search activity.
   */
  private void startSearch() {
    if (!this.advancedMapViewerApplication.getCurrentMapBundle()
        .isSearchable()) {
      showToast(getString(R.string.addressfile_not_avaiable));
    } else {
      startActivityForResult(new Intent(this, Search.class),
          INTENT_SEARCH);
    }
  }

  /**
   * Displays a text message via the toast notification system. If a previous
   * message is still visible, the previous message is first removed.
   * 
   * @param text
   *            the text message to display
   */
  void showToast(String text) {
    if (this.toast == null) {
      this.toast = Toast.makeText(this, text, Toast.LENGTH_LONG);
    } else {
      this.toast.cancel();
      this.toast.setText(text);
    }
    this.toast.show();
  }

  /**
   * Sets up the Routing menu for a given Route and makes it visible. Has a
   * button to display the decision point list and two buttons to jump to the
   * next/previous decision point in list
   * 
   * @param route
   *            the route to set the menu for
   */
  private void setupRoutingMenu(final Route route) {
    if (this.nextDecisionPointButton == null) {
      this.nextDecisionPointButton = (ImageButton) findViewById(R.id.route_menu_next);
    }
    if (this.previousDecisionPointButton == null) {
      this.previousDecisionPointButton = (ImageButton) findViewById(R.id.route_menu_prev);
    }
    if (this.showRoutingListButton == null) {
      this.showRoutingListButton = (ImageButton) findViewById(R.id.route_menu_list);
    }
    this.nextDecisionPointButton.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        GeoPoint nextGP = route.getNextDP().getGeoPoint();
        AdvancedTouristMap.this.mapController.setCenter(nextGP);
        AdvancedTouristMap.this.selectionOverlay.setLabel(nextGP);
      }
    });
    this.previousDecisionPointButton
        .setOnClickListener(new OnClickListener() {
          @Override
          public void onClick(View v) {
            GeoPoint previousGP = route.getPreviousDP().getGeoPoint();
            AdvancedTouristMap.this.mapController.setCenter(previousGP);
            AdvancedTouristMap.this.selectionOverlay.setLabel(previousGP);
          }
        });
    this.showRoutingListButton.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        startActivity(new Intent(AdvancedTouristMap.this, RouteList.class));
      }
    });
    this.routeMenu.setVisibility(View.VISIBLE);
  }

  private class InfoSetterAsync extends AsyncTask<GeoPoint, String, Void> {

    /**
     * maximum distance in meters of Pois to the location to be displayed in
     * this overlay
     */
    private static final int POI_MAX_DISTANCE = 100;

    public InfoSetterAsync() {
      super();
    }

    @Override
    protected Void doInBackground(GeoPoint... params) {
      Log.d("Application", "doInBackground");
      if (params.length != 1) {
        return null;
      }
      GeoPoint geoPoint = params[0];
      GeoCoordinate geoCoordinate = new GeoCoordinate(
          geoPoint.getLatitude(), geoPoint.getLongitude());

      String streetName = "";
      String poiName = "";

      publishProgress(getString(R.string.loading_message));
      // TODO: maybe animation while loading
      // try {
      // Thread.sleep(1000);
      // } catch (InterruptedException e) {
      // e.printStackTrace();
      // }

      // if map is routable, set street name from router
      if (!this.isCancelled()
          && AdvancedTouristMap.this.advancedMapViewerApplication
              .getCurrentMapBundle().isRoutable()) {
        // TODO: not very nice yet
        if (!AdvancedTouristMap.this.advancedMapViewerApplication
            .getRouter()
            .getBoundingBox()
            .includes(geoPoint.getLatitudeE6(),
                geoPoint.getLongitudeE6())) {
          publishProgress("out of box");
          return null;
        }
        Vertex vertex = AdvancedTouristMap.this.advancedMapViewerApplication
            .getRouter().getNearestVertex(geoCoordinate);
        if (vertex != null) {
          String info = PositionInfo.edgesToStringInfo(vertex
              .getOutboundEdges());
          if (info != null && !info.equals("")) {
            streetName = info;
            publishProgress(info);
          } else {
            // no info found, show default message
            publishProgress(getString(R.string.selection_this_point));
          }
        }
      } else if (!this.isCancelled()) {
        // mapBundle is not routable, so set default message
        publishProgress(getString(R.string.selection_this_point));
      }

      // set info about the closest POI
      if (!this.isCancelled()
          && AdvancedTouristMap.this.advancedMapViewerApplication
              .getCurrentMapBundle().isPoiable()) {
        Iterator<PointOfInterest> iterator = AdvancedTouristMap.this.advancedMapViewerApplication
            .getPerstManager().neighborIterator(geoCoordinate,
                "Root");

        // find the next *named* POI near the current point inside the
        // given distance
        while (iterator.hasNext()) {
          PointOfInterest nearestPoi = iterator.next();
          int distance = (int) nearestPoi.getGeoCoordinate()
              .sphericalDistance(geoCoordinate);
          if (distance > POI_MAX_DISTANCE) {
            break;
          }
          if (nearestPoi.getName() != null) {
            poiName = nearestPoi.getName() + " (" + distance
                + " m)";
            if (!streetName.equals("")) {
              publishProgress(streetName + "\n" + poiName);
            } else {
              publishProgress(poiName);
            }
            break;
          }
        }
      }
      return null;
    }

    @Override
    protected void onProgressUpdate(String... values) {
      // build the bubbleView
      TextView bubbleView = new TextView(AdvancedTouristMap.this);
      bubbleView.setBackgroundDrawable(getResources().getDrawable(
          R.drawable.map_label));
      bubbleView.setGravity(Gravity.CENTER);
      bubbleView.setMaxEms(20);
      // bubbleView
      // .setMaxWidth((int) (AdvancedMapViewer.this.mapView.getWidth() *
      // (4.0 / 5.0)));

      // set text size according to textScale setting
      float textSize = 15;
      try {
        textSize *= Float
            .parseFloat(AdvancedTouristMap.this.preferences
                .getString("textScale", "1"));
      } catch (NumberFormatException e) {
        e.printStackTrace();
      }
      bubbleView.setTextSize(textSize);
      bubbleView.setTextColor(Color.WHITE);
      bubbleView.setCompoundDrawablesWithIntrinsicBounds(0, 0,
          R.drawable.ic_menu_info_details, 0);
      // set the text
      if (values.length == 1 && values[0] != null) {
        Log.d("Application", "set text to: " + values[0]);
        bubbleView.setText(values[0]);
      }
      // build the drawable from the bubbleView
      Drawable drawable = ItemizedOverlay
          .boundCenterBottom(viewToDrawable(bubbleView));
      AdvancedTouristMap.this.selectionOverlayItem.setMarker(drawable);
      AdvancedTouristMap.this.selectionOverlay.requestRedraw();
    }

    @Override
    protected void onPreExecute() {
      // just visible if title bar is visible
      // setProgressBarIndeterminateVisibility(true);
    }
  }

  private class WikiSetterAsync extends
      AsyncTask<GeoPoint, Void, ArrayList<WikiArticleInterface>> {

    public WikiSetterAsync() {
    }

    @Override
    protected ArrayList<WikiArticleInterface> doInBackground(
        GeoPoint... params) {
      if (params.length != 1) {
        return null;
      }
      try {
        GeoPoint geoPoint = params[0];
        ArticleRetriever retriever = ArticleRetrieverFactory
            .getGeonamesReceiver(AdvancedTouristMap.this.advancedMapViewerApplication
                .getWikiLocale());
        ArrayList<WikiArticleInterface> articles = retriever
            .getArticles(geoPoint, 20000, 50, 0);

        AdvancedTouristMap.this.advancedMapViewerApplication
            .getCurrentWikiArticles().clear();
        AdvancedTouristMap.this.advancedMapViewerApplication
            .getCurrentWikiArticles().addAll(articles);
        return articles;
      } catch (IOException e) {
        e.printStackTrace();
        return null;
      }
    }

    @Override
    protected void onPostExecute(ArrayList<WikiArticleInterface> result) {
      // AdvancedTouristMap.this.displayWikiOverlay(result);
      if (result != null) {
        refreshGenericOverlay();
      } else {
        // something went wrong, let the user know
        Toast.makeText(AdvancedTouristMap.this,
            getString(R.string.wikipedia_no_connection),
            Toast.LENGTH_LONG);
      }
      // remove the ProgressBar
      AdvancedTouristMap.this.progressBar.setVisibility(View.GONE);

    }

    @Override
    protected void onPreExecute() {
      AdvancedTouristMap.this.progressBar.setVisibility(View.VISIBLE);
    }

    @Override
    protected void onCancelled() {
      // remove the ProgressBar
      AdvancedTouristMap.this.progressBar.setVisibility(View.GONE);
    }

  }

  Drawable viewToDrawable(View view) {
    view.measure(MeasureSpec.getSize(view.getMeasuredWidth()),
        MeasureSpec.getSize(view.getMeasuredHeight()));
    view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
    view.setDrawingCacheEnabled(true);
    Drawable drawable = new BitmapDrawable(Bitmap.createBitmap(view
        .getDrawingCache()));
    view.setDrawingCacheEnabled(false);
    return drawable;
  }

  private class SelectionOverlay extends ArrayItemizedOverlay {

    public SelectionOverlay(Drawable defaultMarker, boolean alignMarker) {
      super(defaultMarker, alignMarker);
    }

    @Override
    public boolean onLongPress(GeoPoint geoPoint, MapView overlayMapView) {
      setLabel(geoPoint);
      return true;
    }

    public void setLabel(GeoPoint geoPoint) {
      // clear last label
      this.clear();
      if (AdvancedTouristMap.this.selectionOverlayItem == null) {
        AdvancedTouristMap.this.selectionOverlayItem = new OverlayItem(
            geoPoint, null, null,
            ItemizedOverlay.boundCenterBottom(getResources()
                .getDrawable(R.drawable.map_label)));
      } else {
        AdvancedTouristMap.this.selectionOverlayItem.setPoint(geoPoint);
      }
      addItem(AdvancedTouristMap.this.selectionOverlayItem);
      // asynchronously set the text
      AdvancedTouristMap.this.runOnUiThread(new myRunnable(geoPoint));
    }

    private class myRunnable implements Runnable {
      private GeoPoint geoPoint;

      public myRunnable(GeoPoint geoPoint) {
        this.geoPoint = geoPoint;
      }

      @Override
      public void run() {
        // new InfoSetterAsync().execute(this.geoPoint);
        AdvancedTouristMap.this.setInfosAsync(this.geoPoint);
      }
    }

    @Override
    protected boolean onTap(int index) {
      OverlayItem item = createItem(index);
      if (item != null) {
        if (AdvancedTouristMap.this.locationPickerMode) {
          Log.d("RouteCalculator", "location picker mode on");
          AdvancedTouristMap.this.setResult(
              RESULT_OK,
              new Intent().putExtra("LONGITUDE",
                  item.getPoint().getLongitude()).putExtra(
                  "LATITUDE", item.getPoint().getLatitude()));
          AdvancedTouristMap.this.finish();
          return true;
        }
        startActivity(new Intent(AdvancedTouristMap.this,
            PositionInfo.class).putExtra("LATITUDE",
            item.getPoint().getLatitude()).putExtra("LONGITUDE",
            item.getPoint().getLongitude()));
      }
      return true;
    }

    // @Override
    // public boolean onTap(GeoPoint geoPoint, MapView mv) {
    // // TODO: label disappears on pinch zooming
    // if (!super.onTap(geoPoint, mv)) {
    // AdvancedMapViewer.this.selectionOverlay.clear();
    // }
    // return true;
    // }

  }
}




Java Source Code List

org.mapsforge.geocoding.Unchecked.java
org.mapsforge.geocoding.widget.CityCompletionAdapter.java
org.mapsforge.geocoding.widget.PlaceCompletionAdapter.java
org.mapsforge.geocoding.widget.RoadCompletionAdapter.java
org.mapsforge.geocoding.widget.RoadListAdapter.java
org.mapsforge.geocoding.widget.SqliteCompletionAdapter.java
org.mapsforge.geocoding.widget.State.java
org.muxe.advancedtouristmap.AdvancedTouristMapApplication.java
org.muxe.advancedtouristmap.AdvancedTouristMap.java
org.muxe.advancedtouristmap.BaseActivity.java
org.muxe.advancedtouristmap.CacheSizePreference.java
org.muxe.advancedtouristmap.EditPreferences.java
org.muxe.advancedtouristmap.FilePickerIconAdapter.java
org.muxe.advancedtouristmap.FilePicker.java
org.muxe.advancedtouristmap.InfoView.java
org.muxe.advancedtouristmap.LocationPicker.java
org.muxe.advancedtouristmap.MoveSpeedPreference.java
org.muxe.advancedtouristmap.PositionInfo.java
org.muxe.advancedtouristmap.Search.java
org.muxe.advancedtouristmap.SeekBarPreference.java
org.muxe.advancedtouristmap.Utility.java
org.muxe.advancedtouristmap.overlay.GenericOverlayItem.java
org.muxe.advancedtouristmap.overlay.GenericOverlay.java
org.muxe.advancedtouristmap.overlay.PoiOverlayItem.java
org.muxe.advancedtouristmap.overlay.PositionOverlayItem.java
org.muxe.advancedtouristmap.overlay.WikiOverlayItem.java
org.muxe.advancedtouristmap.poi.PoiBrowserActivity.java
org.muxe.advancedtouristmap.poi.PoiOrCategory.java
org.muxe.advancedtouristmap.routing.AngleCalc.java
org.muxe.advancedtouristmap.routing.DecisionOverlay.java
org.muxe.advancedtouristmap.routing.DecisionPoint.java
org.muxe.advancedtouristmap.routing.RouteCalculator.java
org.muxe.advancedtouristmap.routing.RouteList.java
org.muxe.advancedtouristmap.routing.Route.java
org.muxe.advancedtouristmap.sourcefiles.AddressFile.java
org.muxe.advancedtouristmap.sourcefiles.FileManagerActivity.java
org.muxe.advancedtouristmap.sourcefiles.FileManager.java
org.muxe.advancedtouristmap.sourcefiles.MapBundle.java
org.muxe.advancedtouristmap.sourcefiles.MapFile.java
org.muxe.advancedtouristmap.sourcefiles.PoiFile.java
org.muxe.advancedtouristmap.sourcefiles.RoutingFile.java
org.muxe.advancedtouristmap.sourcefiles.SourceFile.java
org.muxe.advancedtouristmap.wikipedia.AbstractWikiArticle.java
org.muxe.advancedtouristmap.wikipedia.ArticleRetrieverFactory.java
org.muxe.advancedtouristmap.wikipedia.ArticleRetriever.java
org.muxe.advancedtouristmap.wikipedia.GeonamesRetriever.java
org.muxe.advancedtouristmap.wikipedia.OnlineWikiArticle.java
org.muxe.advancedtouristmap.wikipedia.WikiArticleInterface.java
org.muxe.advancedtouristmap.wikipedia.WikilocationRetriever.java