/* * Copyright (C) 2010- Peer internet solutions * * This file is part of mixare. * * 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.mixare; import java.util.ArrayList; import java.util.List; import org.mixare.data.DataHandler; import org.mixare.data.DataSourceList; import org.mixare.lib.marker.Marker; import org.mixare.lib.MixUtils; import android.app.SearchManager; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Point; import android.graphics.drawable.Drawable; import android.location.Location; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.view.ViewGroup.LayoutParams; import android.widget.TextView; import android.widget.Toast; import com.google.android.maps.GeoPoint; import com.google.android.maps.ItemizedOverlay; import com.google.android.maps.MapActivity; import com.google.android.maps.MapController; import com.google.android.maps.MapView; import com.google.android.maps.Overlay; import com.google.android.maps.OverlayItem; import com.google.android.maps.Projection; /** * This class creates the map view and its overlay. It also adds an overlay with * the markers to the map. */ public class MixMap extends MapActivity implements OnTouchListener { private static List<Overlay> mapOverlays; private Drawable drawable; private static List<Marker> markerList; private static DataView dataView; private static GeoPoint startPoint; private static List<GeoPoint> walkingPath = new ArrayList<GeoPoint>(); public static final String PREFS_NAME = "MixMapPrefs"; private MixContext mixContext; private MapView mapView; // static MixMap map; private static Context thisContext; private static TextView searchNotificationTxt; public static List<Marker> originalMarkerList; @Override protected boolean isRouteDisplayed() { return false; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); dataView = MixView.getDataView(); setMixContext(dataView.getContext()); setMarkerList(dataView.getDataHandler().getMarkerList()); // map = this; //savedInstanceState will save the instance for you. setMapContext(this); // setMapView(new MapView(this, // "0bynx7meN9jlSdHQ4-lK_Vzsw-T82UVibnI0nCA")); setMapView(new MapView(this, "0JVbMIwBOBDk1Ei2XXLK4kYTyCLBmC0DHON76kQ")); getMapView().setBuiltInZoomControls(true); getMapView().setClickable(true); getMapView().setSatellite(true); getMapView().setEnabled(true); this.setContentView(getMapView()); setStartPoint(); createOverlay(); createWalkingPath(); if (dataView.isFrozen()) { searchNotificationTxt = new TextView(this); searchNotificationTxt.setWidth(MixView.getdWindow().getWidth()); searchNotificationTxt.setPadding(10, 2, 0, 0); searchNotificationTxt.setText(getString(R.string.search_active_1) + " " + DataSourceList.getDataSourcesStringList() + getString(R.string.search_active_2)); searchNotificationTxt.setBackgroundColor(Color.DKGRAY); searchNotificationTxt.setTextColor(Color.WHITE); searchNotificationTxt.setOnTouchListener(this); addContentView(searchNotificationTxt, new LayoutParams( LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); } } /** * Closes MapView Activity and returns that request to NOT refresh screen by * default. * * @param boolean do refresh? true or false */ private void closeMapViewActivity(boolean doRefreshScreen) { Intent closeMapView = new Intent(); closeMapView.putExtra("RefreshScreen", doRefreshScreen); setResult(RESULT_OK, closeMapView); finish(); } /** * Closes MapView Activity and returns that request to NOT refresh screen. * Default value is false */ private void closeMapViewActivity() { closeMapViewActivity(false); } /* ********* Operators ********** */ public void setStartPoint() { Location location = getMixContext().getLocationFinder() .getCurrentLocation(); MapController controller; double latitude = location.getLatitude() * 1E6; double longitude = location.getLongitude() * 1E6; controller = getMapView().getController(); startPoint = new GeoPoint((int) latitude, (int) longitude); controller.setCenter(startPoint); controller.setZoom(15); } public void createOverlay() { setMapOverlays(getMapView().getOverlays()); OverlayItem item; setDrawable(this.getResources().getDrawable(R.drawable.icon_map)); MixOverlay mixOverlay = new MixOverlay(this, getDrawable()); for (Marker marker : markerList) { if (marker.isActive()) { GeoPoint point = new GeoPoint( (int) (marker.getLatitude() * 1E6), (int) (marker.getLongitude() * 1E6)); item = new OverlayItem(point, "", ""); mixOverlay.addOverlay(item); } } // Solved issue 39: only one overlay with all marker instead of one // overlay for each marker getMapOverlays().add(mixOverlay); MixOverlay myOverlay; setDrawable(this.getResources().getDrawable(R.drawable.loc_icon)); myOverlay = new MixOverlay(this, getDrawable()); item = new OverlayItem(startPoint, "Your Position", ""); myOverlay.addOverlay(item); getMapOverlays().add(myOverlay); } public void createWalkingPath() { if (isPathVisible()) { mapOverlays = mapView.getOverlays(); Overlay item = new MixPath(walkingPath); mapOverlays.add(item); } } public void createListView() { if (dataView.getDataHandler().getMarkerCount() > 0) { Intent intent1 = new Intent(MixMap.this, MixListView.class); startActivityForResult(intent1, 42); } /* if the list is empty */ else { Toast.makeText(this, R.string.empty_list, Toast.LENGTH_LONG).show(); } } private void togglePath() { final String property = "pathVisible"; SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); SharedPreferences.Editor editor = settings.edit(); boolean result = settings.getBoolean(property, true); editor.putBoolean(property, !result); editor.commit(); } /* ********* Operator - Menu ***** */ @Override public boolean onCreateOptionsMenu(Menu menu) { int base = Menu.FIRST; /* define the first */ MenuItem item1 = menu.add(base, base, base, getString(R.string.map_menu_normal_mode)); MenuItem item2 = menu.add(base, base + 1, base + 1, getString(R.string.map_menu_satellite_mode)); MenuItem item3 = menu.add(base, base + 2, base + 2, getString(R.string.map_my_location)); MenuItem item4 = menu.add(base, base + 3, base + 3, getString(R.string.menu_item_2)); MenuItem item5 = menu.add(base, base + 4, base + 4, getString(R.string.map_menu_cam_mode)); MenuItem item6 = null; if (isPathVisible()) { item6 = menu.add(base, base + 5, base + 5, getString(R.string.map_toggle_path_off)); } else { item6 = menu.add(base, base + 5, base + 5, getString(R.string.map_toggle_path_on)); } /* assign icons to the menu items */ item1.setIcon(android.R.drawable.ic_menu_gallery); item2.setIcon(android.R.drawable.ic_menu_mapmode); item3.setIcon(android.R.drawable.ic_menu_mylocation); item4.setIcon(android.R.drawable.ic_menu_view); item5.setIcon(android.R.drawable.ic_menu_camera); item6.setIcon(android.R.drawable.ic_menu_directions); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { /* Satellite View */ case 1: getMapView().setSatellite(false); break; /* street View */ case 2: getMapView().setSatellite(true); break; /* go to users location */ case 3: setStartPoint(); break; /* List View */ case 4: createListView(); // finish(); don't close map if list view created break; /* back to Camera View */ case 5: closeMapViewActivity(); break; case 6: togglePath(); // refresh: startActivity(getIntent()); closeMapViewActivity(); } return true; } public void startPointMsg() { Toast.makeText(getMapContext(), R.string.map_current_location_click, Toast.LENGTH_LONG).show(); } /* ************ Handlers ************ */ private void handleIntent(Intent intent) { if (Intent.ACTION_SEARCH.equals(intent.getAction())) { String query = intent.getStringExtra(SearchManager.QUERY); doMixSearch(query); } } @Override public void onNewIntent(Intent intent) { setIntent(intent); handleIntent(intent); } private void doMixSearch(String query) { DataHandler jLayer = dataView.getDataHandler(); if (!dataView.isFrozen()) { originalMarkerList = jLayer.getMarkerList(); MixListView.originalMarkerList = jLayer.getMarkerList(); } markerList = new ArrayList<Marker>(); for (int i = 0; i < jLayer.getMarkerCount(); i++) { Marker ma = jLayer.getMarker(i); if (ma.getTitle().toLowerCase().indexOf(query.toLowerCase()) != -1) { markerList.add(ma); } } if (markerList.size() == 0) { Toast.makeText(this, getString(R.string.search_failed_notification), Toast.LENGTH_LONG).show(); } else { jLayer.setMarkerList(markerList); dataView.setFrozen(true); finish(); Intent intent1 = new Intent(this, MixMap.class); startActivityForResult(intent1, 42); } } @Override public boolean onTouch(View v, MotionEvent event) { dataView.setFrozen(false); dataView.getDataHandler().setMarkerList(originalMarkerList); searchNotificationTxt.setVisibility(View.INVISIBLE); searchNotificationTxt = null; finish(); Intent intent1 = new Intent(this, MixMap.class); startActivityForResult(intent1, 42); return false; } /* ******* Getter and Setters ********** */ /** * @return the mapOverlays */ private static List<Overlay> getMapOverlays() { return mapOverlays; } /** * @param mapOverlays * the mapOverlays to set */ private static void setMapOverlays(List<Overlay> mapOverlays) { MixMap.mapOverlays = mapOverlays; } /** * @return the drawable */ private Drawable getDrawable() { return drawable; } /** * @param drawable * the drawable to set */ private void setDrawable(Drawable drawable) { this.drawable = drawable; } /** * @return the mixContext */ private MixContext getMixContext() { return mixContext; } /** * @param mixContext * the mixContext to set */ private void setMixContext(MixContext mixContext) { this.mixContext = mixContext; } /** * @return the mapView */ private MapView getMapView() { return mapView; } /** * @param mapView * the mapView to set */ private void setMapView(MapView mapView) { this.mapView = mapView; } public void setMarkerList(List<Marker> maList) { markerList = maList; } public DataView getDataView() { return dataView; } public List<Overlay> getMapOverlayList() { return getMapOverlays(); } public void setMapContext(Context context) { thisContext = context; } public Context getMapContext() { return thisContext; } /** * Adds a position to the walking route.(This route will be drawn on the * map) */ public static void addWalkingPathPosition(GeoPoint geoPoint) { walkingPath.add(geoPoint); } private boolean isPathVisible() { final String property = "pathVisible"; SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); return settings.getBoolean(property, true); } } /** * Draws Items on the map. */ class MixOverlay extends ItemizedOverlay<OverlayItem> { private ArrayList<OverlayItem> overlayItems = new ArrayList<OverlayItem>(); private MixMap mixMap; public MixOverlay(MixMap mixMap, Drawable marker) { super(boundCenterBottom(marker)); // need to call populate here. See // http://code.google.com/p/android/issues/detail?id=2035 populate(); this.mixMap = mixMap; } @Override protected OverlayItem createItem(int i) { return overlayItems.get(i); } @Override public int size() { return overlayItems.size(); } @Override protected boolean onTap(int index) { if (size() == 1) mixMap.startPointMsg(); else if (mixMap.getDataView().getDataHandler().getMarker(index) .getURL() != null) { String url = mixMap.getDataView().getDataHandler().getMarker(index) .getURL(); Log.d("MapView", "opern url: " + url); try { if (url != null && url.startsWith("webpage")) { String newUrl = MixUtils.parseAction(url); mixMap.getDataView().getContext().getWebContentManager() .loadWebPage(newUrl, mixMap.getMapContext()); } } catch (Exception e) { e.printStackTrace(); } } return true; } public void addOverlay(OverlayItem overlay) { overlayItems.add(overlay); populate(); } } /** * Draws a path(line) on the map. */ class MixPath extends Overlay { private List<GeoPoint> geoPoints; public MixPath(List<GeoPoint> geoPoints) { Log.i("MapActivity", geoPoints.toString()); this.geoPoints = geoPoints; } public void draw(Canvas canvas, MapView mapv, boolean shadow) { super.draw(canvas, mapv, shadow); if (geoPoints.size() <= 0) { return; } Projection projection = mapv.getProjection(); Paint mPaint = new Paint(); mPaint.setDither(true); mPaint.setColor(Color.BLUE); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeWidth(3); Path path = new Path(); Point start = new Point(); projection.toPixels(geoPoints.get(0), start); path.moveTo(start.x, start.y); for (GeoPoint gp : geoPoints) { Point p = new Point(); projection.toPixels(gp, p); path.lineTo(p.x, p.y); } canvas.drawPath(path, mPaint); } }