/* * 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")); 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); } }