package com.robert.maps.applib.downloader;
import java.io.File;
import java.io.InputStream;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.andnav.osm.util.GeoPoint;
import org.andnav.osm.views.util.Util;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.TypedValue;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.robert.maps.applib.R;
import com.robert.maps.applib.kml.PoiManager;
import com.robert.maps.applib.kml.XMLparser.PredefMapsParser;
import com.robert.maps.applib.tileprovider.TileProviderInet;
import com.robert.maps.applib.tileprovider.TileSource;
import com.robert.maps.applib.tileprovider.TileSourceBase;
import com.robert.maps.applib.utils.RException;
import com.robert.maps.applib.utils.Ut;
import com.robert.maps.applib.view.IMoveListener;
import com.robert.maps.applib.view.MapView;
import com.robert.maps.applib.view.TileViewOverlay;
public class AreaSelectorActivity extends Activity {
private static final String MAPNAME = "MapName";
private static final String MAPNAMEAREASELECTOR = "MapNameAreaSelector";
private MapView mMap;
private AreaSelectorOverlay mAreaSelectorOverlay;
private TileSource mTileSource;
private MoveListener mMoveListener = new MoveListener();
private int[] mZoomArr = new int[0];
// ServiceConnection mConnection;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// mConnection = new ServiceConnection() {
// public void onServiceConnected(ComponentName className, IBinder service) {
// Toast.makeText(AreaSelectorActivity.this, R.string.downloader_notif_text, Toast.LENGTH_LONG).show();
// AreaSelectorActivity.this.finish();
// }
// public void onServiceDisconnected(ComponentName className) {}
// };
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.area_selector);
final SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences uiState = getPreferences(Activity.MODE_PRIVATE);
mMap = (MapView) findViewById(R.id.map);
mMap.setMoveListener(mMoveListener);
mMap.displayZoomControls(Integer.parseInt(pref.getString("pref_zoomctrl", "1")));
mMap.getController().setCenter(new GeoPoint(uiState.getInt("Latitude", 0), uiState.getInt("Longitude", 0)));
mMap.setLongClickable(false);
mAreaSelectorOverlay = new AreaSelectorOverlay();
mMap.getOverlays().add(mAreaSelectorOverlay);
findViewById(R.id.clear).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mAreaSelectorOverlay.clearArea(mMap.getTileView());
}});
registerForContextMenu(findViewById(R.id.maps));
findViewById(R.id.maps).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
v.showContextMenu();
}
});
findViewById(R.id.start_download).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
startDownLoad();
}
});
findViewById(R.id.next).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
doNext();
}
});
findViewById(R.id.back).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
doBack();
}
});
((CheckBox) findViewById(R.id.online_cache)).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
onOnlineCacheBoxChecked();
}
});
Intent intent = getIntent();
if(intent != null) {
SharedPreferences.Editor editor = uiState.edit();
editor.putString(MAPNAMEAREASELECTOR, intent.getStringExtra(MAPNAME));
editor.putInt("ZoomLevelAS", intent.getIntExtra("ZoomLevel", 0));
if(intent.getBooleanExtra("new", false)) {
intent.putExtra("new", false);
editor.putInt("LatitudeAS", intent.getIntExtra("Latitude", 0));
editor.putInt("LongitudeAS", intent.getIntExtra("Longitude", 0));
editor.putInt("LatitudeAS1", 0);
editor.putInt("LongitudeAS1", 0);
editor.putInt("LatitudeAS2", 0);
editor.putInt("LongitudeAS2", 0);
editor.putBoolean("step2", false);
};
editor.commit();
}
}
protected void doBack() {
getZoomArr();
((LinearLayout) findViewById(R.id.LayerArea1)).removeAllViews();
((LinearLayout) findViewById(R.id.LayerArea2)).removeAllViews();
findViewById(R.id.step1).setVisibility(View.VISIBLE);
findViewById(R.id.step2).setVisibility(View.GONE);
}
private int[] getZoomArr() {
LinearLayout ll = (LinearLayout) findViewById(R.id.LayerArea);
CheckBox cb;
final int[] zoomArr = new int[mTileSource.ZOOM_MAXLEVEL - mTileSource.ZOOM_MINLEVEL + 1];
int j = 0;
for(int i = mTileSource.ZOOM_MINLEVEL; i <= mTileSource.ZOOM_MAXLEVEL; i++) {
cb = (CheckBox) ll.findViewWithTag("Layer"+i);
if(cb != null)
if(cb.isChecked()) {
zoomArr[j] = i;
j++;
}
}
mZoomArr = new int[j];
for(;j > 0; j--) {
mZoomArr[j-1] = zoomArr[j-1];
}
return mZoomArr;
}
protected void doNext() {
LinearLayout ll1 = (LinearLayout) findViewById(R.id.LayerArea1);
LinearLayout ll2 = (LinearLayout) findViewById(R.id.LayerArea2);
CheckBox cb;
final double tileLength = ((TileProviderInet) mTileSource.getTileProvider()).getTileLength();
final int[] coordArr = mAreaSelectorOverlay.getCoordArr();
for(int i = mTileSource.ZOOM_MINLEVEL; i <= mTileSource.ZOOM_MAXLEVEL; i++) {
final int c0[] = Util.getMapTileFromCoordinates(coordArr[0], coordArr[1], i, null, mTileSource.PROJECTION);
final int c1[] = Util.getMapTileFromCoordinates(coordArr[2], coordArr[3], i, null, mTileSource.PROJECTION);
final int yMin = Math.min(c0[0], c1[0]);
final int yMax = Math.max(c0[0], c1[0]);
final int xMin = Math.min(c0[1], c1[1]);
final int xMax = Math.max(c0[1], c1[1]);
final int tileCnt = (yMax - yMin + 1) * (xMax - xMin + 1);
cb = new CheckBox(this);
cb.setTag("Layer"+i);
cb.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12);
cb.setText("Zoom "+(i+1)+"\n"+tileCnt+" tiles, ~"+Ut.formatSize(tileCnt * tileLength));
if(i - mTileSource.ZOOM_MINLEVEL + 1 > (int)((mTileSource.ZOOM_MAXLEVEL - mTileSource.ZOOM_MINLEVEL + 1) / 2.0 + 0.5))
ll2.addView(cb);
else
ll1.addView(cb);
}
for(int i = 0; i < mZoomArr.length; i++) {
cb = (CheckBox) ll1.findViewWithTag("Layer"+mZoomArr[i]);
if(cb != null)
cb.setChecked(true);
cb = (CheckBox) ll2.findViewWithTag("Layer"+mZoomArr[i]);
if(cb != null)
cb.setChecked(true);
}
findViewById(R.id.step1).setVisibility(View.GONE);
findViewById(R.id.step2).setVisibility(View.VISIBLE);
}
private void startDownLoad() {
getZoomArr();
if(mZoomArr.length == 0) {
Toast.makeText(this, R.string.select_zoom, Toast.LENGTH_LONG).show();
return;
}
findViewById(R.id.start_download).setVisibility(View.GONE);
final Intent intent = new Intent("com.robert.maps.mapdownloader");
intent.putExtra("ZOOM", mZoomArr);
intent.putExtra("COORD", mAreaSelectorOverlay.getCoordArr());
intent.putExtra("MAPID", mTileSource.ID);
intent.putExtra("ZOOMCUR", mMap.getZoomLevel());
intent.putExtra("overwritefile", ((CheckBox) findViewById(R.id.overwritefile)).isChecked());
intent.putExtra("overwritetiles", ((CheckBox) findViewById(R.id.overwritetiles)).isChecked());
intent.putExtra("online_cache", ((CheckBox) findViewById(R.id.online_cache)).isChecked());
String filename = ((EditText) findViewById(R.id.name)).getText().toString();
if(!((CheckBox) findViewById(R.id.online_cache)).isChecked()) {
if(filename.equalsIgnoreCase("")) {
Toast.makeText(this, "Invalid file name", Toast.LENGTH_LONG).show();
return;
}
final File folder = Ut.getRMapsMapsDir(this);
if(folder != null) {
File[] files = folder.listFiles();
if(files != null) {
for(int i = 0; i < files.length; i++) {
if(files[i].getName().equalsIgnoreCase(filename+".sqlitedb")) {
filename = files[i].getName().substring(0, files[i].getName().length() - 9);
break;
}
}
}
}
}
intent.putExtra("OFFLINEMAPNAME", filename);
startService(intent);
final GeoPoint point = mMap.getMapCenter();
startActivity(new Intent(this, DownloaderActivity.class)
.putExtra("MAPID", mTileSource.ID)
.putExtra("Latitude", point.getLatitudeE6())
.putExtra("Longitude", point.getLongitudeE6())
.putExtra("ZoomLevel", mMap.getZoomLevel())
.putExtra("OFFLINEMAPNAME", filename)
.putExtra("online_cache", ((CheckBox) findViewById(R.id.online_cache)).isChecked())
);
finish();
}
private class MoveListener implements IMoveListener {
public void onMoveDetected() {
}
public void onZoomDetected() {
setTitle();
}
@Override
public void onCenterDetected() {
}
}
private void setTitle(){
try {
final TextView leftText = (TextView) findViewById(R.id.left_text);
if(leftText != null)
leftText.setText(mMap.getTileSource().NAME);
final TextView gpsText = (TextView) findViewById(R.id.gps_text);
if(gpsText != null){
gpsText.setText("");
}
final TextView rightText = (TextView) findViewById(R.id.right_text);
if(rightText != null){
final double zoom = mMap.getZoomLevelScaled();
if(zoom > mMap.getTileSource().ZOOM_MAXLEVEL)
rightText.setText(""+(mMap.getTileSource().ZOOM_MAXLEVEL+1)+"+");
else
rightText.setText(""+(1 + Math.round(zoom)));
}
} catch (Exception e) {
}
}
@Override
protected void onResume() {
// bindService(new Intent(IRemoteService.class.getName()), mConnection, 0);
final SharedPreferences uiState = getPreferences(Activity.MODE_PRIVATE);
if(mTileSource != null)
mTileSource.Free();
try {
mTileSource = new TileSource(this, uiState.getString(MAPNAMEAREASELECTOR, TileSource.MAPNIK));
if(mTileSource.MAP_TYPE != TileSourceBase.PREDEF_ONLINE && mTileSource.MAP_TYPE != TileSourceBase.MIXMAP_CUSTOM) {
mTileSource.Free();
mTileSource = new TileSource(this, TileSource.MAPNIK);
}
} catch (Exception e) {
e.printStackTrace();
}
mMap.setTileSource(mTileSource);
mMap.getController().setZoom(uiState.getInt("ZoomLevelAS", 0));
mMap.getController().setCenter(new GeoPoint(uiState.getInt("LatitudeAS", 0), uiState.getInt("LongitudeAS", 0)));
setTitle();
final GeoPoint[] p = new GeoPoint[2];
p[0] = new GeoPoint(uiState.getInt("LatitudeAS1", 0), uiState.getInt("LongitudeAS1", 0));
p[1] = new GeoPoint(uiState.getInt("LatitudeAS2", 0), uiState.getInt("LongitudeAS2", 0));
mAreaSelectorOverlay.Init(this, mMap.getTileView(), p);
((EditText) findViewById(R.id.name)).setText(uiState.getString("filename", "NewFile"));
((CheckBox) findViewById(R.id.overwritefile)).setChecked(uiState.getBoolean("overwritefile", true));
((CheckBox) findViewById(R.id.overwritetiles)).setChecked(uiState.getBoolean("overwritetiles", false));
((CheckBox) findViewById(R.id.online_cache)).setChecked(uiState.getBoolean("online_cache", false));
onOnlineCacheBoxChecked();
mZoomArr = new int[uiState.getInt("zoomCnt", 0)];
for(int i = 0; i < mZoomArr.length; i++) {
mZoomArr[i] = uiState.getInt("zoom"+i, 0);
}
if(uiState.getBoolean("step2", false)) {
doNext();
} else {
findViewById(R.id.step1).setVisibility(View.VISIBLE);
findViewById(R.id.step2).setVisibility(View.GONE);
}
super.onResume();
}
private void onOnlineCacheBoxChecked() {
final boolean isOnlineCache = ((CheckBox) findViewById(R.id.online_cache)).isChecked();
findViewById(R.id.name).setVisibility(isOnlineCache ? View.GONE : View.VISIBLE);
findViewById(R.id.overwritefile).setVisibility(isOnlineCache ? View.GONE : View.VISIBLE);
findViewById(R.id.fileNameTitle).setVisibility(isOnlineCache ? View.GONE : View.VISIBLE);
}
@Override
protected void onPause() {
// unbindService(mConnection);
SharedPreferences uiState = getPreferences(Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = uiState.edit();
editor.putString(MAPNAMEAREASELECTOR, mTileSource.ID);
final GeoPoint point = mMap.getMapCenter();
editor.putBoolean("new", false);
editor.putInt("LatitudeAS", point.getLatitudeE6());
editor.putInt("LongitudeAS", point.getLongitudeE6());
editor.putInt("ZoomLevelAS", mMap.getZoomLevel());
editor.putString("filename", ((EditText) findViewById(R.id.name)).getText().toString());
editor.putBoolean("overwritefile", ((CheckBox) findViewById(R.id.overwritefile)).isChecked());
editor.putBoolean("overwritetiles", ((CheckBox) findViewById(R.id.overwritetiles)).isChecked());
editor.putBoolean("online_cache", ((CheckBox) findViewById(R.id.online_cache)).isChecked());
mAreaSelectorOverlay.put(editor);
if(findViewById(R.id.step2).getVisibility() == View.VISIBLE) {
editor.putBoolean("step2", true);
getZoomArr();
} else {
editor.putBoolean("step2", false);
}
editor.putInt("zoomCnt", mZoomArr.length);
for(int i = 0; i < mZoomArr.length; i++) {
editor.putInt("zoom"+i, mZoomArr[i]);
}
editor.commit();
super.onPause();
}
@Override
protected void onDestroy() {
if(mMap != null) {
for (TileViewOverlay osmvo : mMap.getOverlays())
osmvo.Free();
mMap.setMoveListener(null);
}
if(mTileSource != null)
mTileSource.Free();
mTileSource = null;
super.onDestroy();
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
if(v.getId() == R.id.maps) {
menu.clear();
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
final PoiManager poiManager = new PoiManager(this);
Cursor c = poiManager.getGeoDatabase().getMixedMaps();
if(c != null) {
if(c.moveToFirst()) {
do {
if (pref.getBoolean("PREF_MIXMAPS_" + c.getInt(0) + "_enabled", true) && c.getInt(2) == 2) { // Only ownsourcemap
MenuItem item = menu.add(c.getString(1));
item.setTitleCondensed("mixmap_" + c.getInt(0));
}
} while(c.moveToNext());
}
c.close();
}
poiManager.FreeDatabases();
final SAXParserFactory fac = SAXParserFactory.newInstance();
SAXParser parser = null;
try {
parser = fac.newSAXParser();
if(parser != null){
final InputStream in = getResources().openRawResource(R.raw.predefmaps);
parser.parse(in, new PredefMapsParser(menu, pref));
in.close();
final InputStream in2 = getResources().openRawResource(R.raw.predefmaps);
parser.parse(in2, new PredefMapsParser(menu, pref, true, mTileSource.PROJECTION));
in2.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
super.onCreateContextMenu(menu, v, menuInfo);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
final String mapid = (String)item.getTitleCondensed();
if(mTileSource != null)
mTileSource.Free();
try {
mTileSource = new TileSource(this, mapid);
} catch (RException e) {
//addMessage(e);
}
mMap.setTileSource(mTileSource);
setTitle();
return true;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK && findViewById(R.id.step2).getVisibility() == View.VISIBLE) {
doBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
}