From d52d761a5c1612aa113b54bf2449bb7033c628b7 Mon Sep 17 00:00:00 2001 From: Hannes Janetzek Date: Tue, 28 Jan 2014 17:45:08 +0100 Subject: [PATCH] add mapsforge activity to example --- vtm-android-example/AndroidManifest.xml | 9 +- .../res/drawable-mdpi/file_picker_back.png | Bin 0 -> 1951 bytes .../res/drawable-mdpi/file_picker_file.png | Bin 0 -> 1024 bytes .../res/drawable-mdpi/file_picker_folder.png | Bin 0 -> 1460 bytes .../res/layout/activity_file_picker.xml | 4 + vtm-android-example/res/values/strings.xml | 4 + .../oscim/android/filepicker/FilePicker.java | 250 ++++++++++++++++++ .../filepicker/FilePickerIconAdapter.java | 116 ++++++++ .../filepicker/FilterByFileExtension.java | 48 ++++ .../android/filepicker/ValidFileFilter.java | 29 ++ .../android/filepicker/ValidMapFile.java | 42 +++ .../android/filepicker/ValidRenderTheme.java | 71 +++++ .../android/test/MapsforgeMapActivity.java | 127 +++++++++ .../src/org/oscim/android/test/Samples.java | 6 + 14 files changed, 705 insertions(+), 1 deletion(-) create mode 100644 vtm-android-example/res/drawable-mdpi/file_picker_back.png create mode 100644 vtm-android-example/res/drawable-mdpi/file_picker_file.png create mode 100644 vtm-android-example/res/drawable-mdpi/file_picker_folder.png create mode 100644 vtm-android-example/res/layout/activity_file_picker.xml create mode 100755 vtm-android-example/src/org/oscim/android/filepicker/FilePicker.java create mode 100755 vtm-android-example/src/org/oscim/android/filepicker/FilePickerIconAdapter.java create mode 100644 vtm-android-example/src/org/oscim/android/filepicker/FilterByFileExtension.java create mode 100644 vtm-android-example/src/org/oscim/android/filepicker/ValidFileFilter.java create mode 100644 vtm-android-example/src/org/oscim/android/filepicker/ValidMapFile.java create mode 100644 vtm-android-example/src/org/oscim/android/filepicker/ValidRenderTheme.java create mode 100644 vtm-android-example/src/org/oscim/android/test/MapsforgeMapActivity.java diff --git a/vtm-android-example/AndroidManifest.xml b/vtm-android-example/AndroidManifest.xml index 75d2bdd6..c237b828 100644 --- a/vtm-android-example/AndroidManifest.xml +++ b/vtm-android-example/AndroidManifest.xml @@ -27,6 +27,7 @@ + - + + + \ No newline at end of file diff --git a/vtm-android-example/res/drawable-mdpi/file_picker_back.png b/vtm-android-example/res/drawable-mdpi/file_picker_back.png new file mode 100644 index 0000000000000000000000000000000000000000..671901539449fd2f4f4993acfdd4b85de89cf0bb GIT binary patch literal 1951 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 literal 0 HcmV?d00001 diff --git a/vtm-android-example/res/drawable-mdpi/file_picker_file.png b/vtm-android-example/res/drawable-mdpi/file_picker_file.png new file mode 100644 index 0000000000000000000000000000000000000000..d0411244893b084e7ffe4aae7c28e679f3d75603 GIT binary patch literal 1024 zcmV+b1poVqP)Px&x=BPqRA}DqS-WoAFcdu$ZOefa#i=bIaDrsYFLddazv$kzpO7iPkfCe-pj+qu zMW&2_10w-aBrxA3Bh8tdo9HSgi!;m6(G-S;}!26ZN7S@!Mf>grP% zh9DvU0OuS+2r$M#MDRRseNQ+2nwsk}B0>~JxVgFc3SfT(q?8~cyu7?XN(lh)eIHqt zt$``8sG~Wyo!f{8K~P&6wF#()Gse~{tw7trSCMdPd5d>idq4-H2q;^vRuDooUUg+* z7?u{IQv&Add!Dx;qix{z>-zJWc&rftwYn~OyuH04Ns>z7E?`82FbthZU~e&?%f|G= zY&I+1cg28<1n0aI15JoD@_;EJW$*9r$g<2SAv0!73C(7+?qk3PT*ZJ80(qW0Gto8) znK9If2lR*PFC`*Or&DJtZAwH>8ha-|M0k9B#M#+d3DEQN^E!yDvWW})>FMdmWuZ8Z zF&GR=Y1H?9aL#wG#AboqyM&ZWIp^S-08AzmYc{Fd8!7p9O2E}{DL_)njg_|nsR~j> zzEcUA{SN@VzP=(&(+znM5sr_KF`Z6prBHS3B#l;iU_PIhq+=44QkFDsYv!6tr
=2dB$P5vnR|datEEQ#&CbrNm;fz_vi8M`XdB9f4R2|r*Bi*T)GXruo z8g2bXu4=XQ80lO>wylyN2%LqiN?PW}(T8LqTMl0?msqV<8`3dBo2`Yi%gf7BHE!aK z)&x{wM^WUIkX{$UFvP*ZK`C(aJa>}oL_)T1Rn4*OQs{L-pSx@3X-pu`bM7iGj4?z} zWGz@G8CRF;Xek(gt?af{4+bDg)6}oCbEm$Y^^ISBrPY1cSbH7=Fa5l+TW`Jn=k^ydg}8-Qpwv|W0000Px)Zb?KzRA}Dqn7@x4SrNxS)vtfdjQ4yxu|_LFLI64m5kW$Hk|W1R2u>tiWSp}J znG+mf$pMx)>5w>yf54FmAaDi_5F8h*4s5h{_WA7d?0BcU-_IhLA3NTio!yY8aUcGvGFc^?hnyRW!*F&ls8yoWA!Gm^hZ}08fw{JgQHGq84rm8k6 zrOUg!yHlfMjHoIx#@E1%@0UE!+1lDFo2wV6?Nu9pVgy16P20BAbxn+M>h;4qn??X_+tTTDes%r&^>-F&79}8mkOpFcFD_5@cHa9nau(h>CQ51*>B0`pB({-XE!qcZu zxqtuuXTZ-d6hK|q^!t6BbJH_$iYN#`zu#wPXJ=F`#sDV98)Fa=j4@01;AR{`v6LXXNqR5#*Op5i9s>sC0w6GE_ zj6jUB@!n6s(CK!uKAs|}mrtFfP}?}FKt)Cf@e6>z{N~5YMZh^nZVXW>dfkfF$CVg9 zDMYo6)9b1*cppDsx)Z0An!2v3>zaP8Y+fp9T)Nl*jLBe#iN>WVIm|LJ8CV~mor_AS zDwi(xNJF95DJ~=evkW&WI3IB#O(_RJo@J;)W5eA3A|z!VWzUV!xOhGQF-GgXr&H!Q>0*rF7DQk~=0;wf9LPycp8y-}r)g(Cpb{Jb z@a0~EYFZA!wQJXCn#OtWwOi%Vrh-f|d`z!9}_Vh%k}3*VUd_DJbAM>1p~w|CL3M{&#=+yQNdehY;v? zyVz6_6>1l!JZR$O(-@@3aiU{31lZeelL*7}9O7WD)xpq;3fQ28Fni$S5YyC!OHaSZfRK zz1jeIZm{FBcR1#HoQvn0#;H(Puhg~E=Ec7hFhD#DfDG7Znx+#%z{ZTSET~-~Mm;fA zj?O7(xOXg#Pgv`bKVf4Kd@IQQGJO=lWc3q;;PwF1g + \ No newline at end of file diff --git a/vtm-android-example/res/values/strings.xml b/vtm-android-example/res/values/strings.xml index 8e666a04..5e2d46c5 100644 --- a/vtm-android-example/res/values/strings.xml +++ b/vtm-android-example/res/values/strings.xml @@ -7,5 +7,9 @@ Default Tubes Osmarender + OK + Cancel + Error + The selected file is invalid. \ No newline at end of file diff --git a/vtm-android-example/src/org/oscim/android/filepicker/FilePicker.java b/vtm-android-example/src/org/oscim/android/filepicker/FilePicker.java new file mode 100755 index 00000000..40553e4f --- /dev/null +++ b/vtm-android-example/src/org/oscim/android/filepicker/FilePicker.java @@ -0,0 +1,250 @@ +/* + * Copyright 2010, 2011, 2012 mapsforge.org + * + * This program is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * this program. If not, see . + */ +package org.oscim.android.filepicker; + +import java.io.File; +import java.io.FileFilter; +import java.util.Arrays; +import java.util.Comparator; + +import org.oscim.android.test.R; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import android.os.Bundle; +import android.view.View; +import android.widget.AdapterView; +import android.widget.GridView; + +/** + * A FilePicker displays the contents of directories. The user can navigate + * within the file system and select a single + * file whose path is then returned to the calling activity. The ordering of + * directory contents can be specified via + * {@link #setFileComparator(Comparator)}. By default subfolders and files are + * grouped and each group is ordered + * alphabetically. + *

+ * A {@link FileFilter} can be activated via + * {@link #setFileDisplayFilter(FileFilter)} to restrict the displayed files and + * folders. By default all files and folders are visible. + *

+ * Another FileFilter can be applied via + * {@link #setFileSelectFilter(ValidFileFilter)} to check if a selected file is + * valid before its path is returned. By default all files are considered as + * valid and can be selected. + */ +public class FilePicker extends Activity implements AdapterView.OnItemClickListener { + /** + * The name of the extra data in the result {@link Intent}. + */ + public static final String SELECTED_FILE = "selectedFile"; + + private static final String PREFERENCES_FILE = "FilePicker"; + private static final String CURRENT_DIRECTORY = "currentDirectory"; + private static final String DEFAULT_DIRECTORY = "/"; + private static final int DIALOG_FILE_INVALID = 0; + + // private static final int DIALOG_FILE_SELECT = 1; + protected Comparator mFileComparator = getDefaultFileComparator(); + protected FileFilter mFileDisplayFilter; + protected ValidFileFilter mFileSelectFilter; + + /** + * Sets the file comparator which is used to order the contents of all + * directories before displaying them. If set to + * null, subfolders and files will not be ordered. + * + * @param fileComparator + * the file comparator (may be null). + */ + public void setFileComparator(Comparator fileComparator) { + mFileComparator = fileComparator; + } + + /** + * Sets the file display filter. This filter is used to determine which + * files and subfolders of directories will be + * displayed. If set to null, all files and subfolders are shown. + * + * @param fileDisplayFilter + * the file display filter (may be null). + */ + public void setFileDisplayFilter(FileFilter fileDisplayFilter) { + mFileDisplayFilter = fileDisplayFilter; + } + + /** + * Sets the file select filter. This filter is used when the user selects a + * file to determine if it is valid. If set + * to null, all files are considered as valid. + * + * @param fileSelectFilter + * the file selection filter (may be null). + */ + public void setFileSelectFilter(ValidFileFilter fileSelectFilter) { + mFileSelectFilter = fileSelectFilter; + } + + /** + * Creates the default file comparator. + * + * @return the default file comparator. + */ + private static Comparator getDefaultFileComparator() { + // order all files by type and alphabetically by name + return new Comparator() { + @Override + public int compare(File file1, File file2) { + if (file1.isDirectory() && !file2.isDirectory()) { + return -1; + } else if (!file1.isDirectory() && file2.isDirectory()) { + return 1; + } else { + return file1.getName().compareToIgnoreCase(file2.getName()); + } + } + }; + } + + private File mDirectory; + private FilePickerIconAdapter mFilePickerIconAdapter; + private File[] mFiles; + private File[] mFilesWithParentFolder; + + @SuppressWarnings("deprecation") + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + File selectedFile = mFiles[(int) id]; + if (selectedFile.isDirectory()) { + mDirectory = selectedFile; + browseToCurrentDirectory(); + } else if (mFileSelectFilter == null || mFileSelectFilter.accept(selectedFile)) { + setResult(RESULT_OK, + new Intent().putExtra(SELECTED_FILE, selectedFile.getAbsolutePath())); + finish(); + } else { + showDialog(DIALOG_FILE_INVALID); + } + } + + /** + * Browses to the current directory. + */ + private void browseToCurrentDirectory() { + setTitle(mDirectory.getAbsolutePath()); + + // read the subfolders and files from the current directory + if (mFileDisplayFilter == null) { + mFiles = mDirectory.listFiles(); + } else { + mFiles = mDirectory.listFiles(mFileDisplayFilter); + } + + if (mFiles == null) { + mFiles = new File[0]; + } else { + // order the subfolders and files + Arrays.sort(mFiles, mFileComparator); + } + + // if a parent directory exists, add it at the first position + if (mDirectory.getParentFile() != null) { + mFilesWithParentFolder = new File[mFiles.length + 1]; + mFilesWithParentFolder[0] = mDirectory.getParentFile(); + System.arraycopy(mFiles, 0, mFilesWithParentFolder, 1, + mFiles.length); + mFiles = mFilesWithParentFolder; + mFilePickerIconAdapter.setFiles(mFiles, true); + } else { + mFilePickerIconAdapter.setFiles(mFiles, false); + } + mFilePickerIconAdapter.notifyDataSetChanged(); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_file_picker); + + mFilePickerIconAdapter = new FilePickerIconAdapter(this); + GridView gridView = (GridView) findViewById(R.id.filePickerView); + gridView.setOnItemClickListener(this); + gridView.setAdapter(mFilePickerIconAdapter); + + // if (savedInstanceState == null) { + // // first start of this instance + // showDialog(DIALOG_FILE_SELECT); + // } + } + + @Override + protected Dialog onCreateDialog(int id) { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + switch (id) { + case DIALOG_FILE_INVALID: + builder.setIcon(android.R.drawable.ic_menu_info_details); + builder.setTitle(R.string.error); + + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(getString(R.string.file_invalid)); + stringBuilder.append("\n\n"); + stringBuilder.append(mFileSelectFilter.getFileOpenResult() + .getErrorMessage()); + + builder.setMessage(stringBuilder.toString()); + builder.setPositiveButton(R.string.ok, null); + return builder.create(); + // case DIALOG_FILE_SELECT: + // builder.setMessage(R.string.file_select); + // builder.setPositiveButton(R.string.ok, null); + // return builder.create(); + default: + // do dialog will be created + return null; + } + } + + @Override + protected void onPause() { + super.onPause(); + // save the current directory + Editor editor = getSharedPreferences(PREFERENCES_FILE, MODE_PRIVATE).edit(); + editor.clear(); + if (mDirectory != null) { + editor.putString(CURRENT_DIRECTORY, mDirectory.getAbsolutePath()); + } + editor.commit(); + } + + @Override + protected void onResume() { + super.onResume(); + + // restore the current directory + SharedPreferences preferences = getSharedPreferences(PREFERENCES_FILE, + MODE_PRIVATE); + mDirectory = new File(preferences.getString(CURRENT_DIRECTORY, + DEFAULT_DIRECTORY)); + if (!mDirectory.exists() || !mDirectory.canRead()) { + mDirectory = new File(DEFAULT_DIRECTORY); + } + browseToCurrentDirectory(); + } +} diff --git a/vtm-android-example/src/org/oscim/android/filepicker/FilePickerIconAdapter.java b/vtm-android-example/src/org/oscim/android/filepicker/FilePickerIconAdapter.java new file mode 100755 index 00000000..8943cfe9 --- /dev/null +++ b/vtm-android-example/src/org/oscim/android/filepicker/FilePickerIconAdapter.java @@ -0,0 +1,116 @@ +/* + * Copyright 2010, 2011, 2012 mapsforge.org + * + * This program is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * this program. If not, see . + */ +package org.oscim.android.filepicker; + +import java.io.File; + +import org.oscim.android.test.R; + +import android.content.Context; +import android.view.Gravity; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.TextView; + +/** + * An adapter for the FilePicker GridView. + */ +class FilePickerIconAdapter extends BaseAdapter { + private final Context mContext; + private File mCurrentFile; + private File[] mFiles; + private boolean mHasParentFolder; + private TextView mTextView; + + /** + * Creates a new FilePickerIconAdapter with the given context. + * + * @param context + * the context of this adapter, through which new Views are + * created. + */ + FilePickerIconAdapter(Context context) { + super(); + mContext = context; + } + + @Override + public int getCount() { + if (mFiles == null) { + return 0; + } + return mFiles.length; + } + + @Override + public Object getItem(int index) { + return mFiles[index]; + } + + @Override + public long getItemId(int index) { + return index; + } + + @Override + public View getView(int index, View convertView, ViewGroup parent) { + if (convertView instanceof TextView) { + // recycle the old view + mTextView = (TextView) convertView; + } else { + // create a new view object + mTextView = new TextView(mContext); + mTextView.setLines(2); + mTextView.setGravity(Gravity.CENTER_HORIZONTAL); + mTextView.setPadding(5, 10, 5, 10); + } + + if (index == 0 && mHasParentFolder) { + // the parent directory of the current folder + mTextView.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.file_picker_back, 0, 0); + mTextView.setText(".."); + } else { + mCurrentFile = mFiles[index]; + if (mCurrentFile.isDirectory()) { + mTextView.setCompoundDrawablesWithIntrinsicBounds(0, + R.drawable.file_picker_folder, + 0, + 0); + } else { + mTextView.setCompoundDrawablesWithIntrinsicBounds(0, + R.drawable.file_picker_file, + 0, + 0); + } + mTextView.setText(mCurrentFile.getName()); + } + return mTextView; + } + + /** + * Sets the data of this adapter. + * + * @param files + * the new files for this adapter. + * @param newHasParentFolder + * true if the file array has a parent folder at index 0, false + * otherwise. + */ + void setFiles(File[] files, boolean newHasParentFolder) { + mFiles = files.clone(); + mHasParentFolder = newHasParentFolder; + } +} diff --git a/vtm-android-example/src/org/oscim/android/filepicker/FilterByFileExtension.java b/vtm-android-example/src/org/oscim/android/filepicker/FilterByFileExtension.java new file mode 100644 index 00000000..32e1c9df --- /dev/null +++ b/vtm-android-example/src/org/oscim/android/filepicker/FilterByFileExtension.java @@ -0,0 +1,48 @@ +/* + * Copyright 2010, 2011, 2012 mapsforge.org + * + * This program is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * this program. If not, see . + */ +package org.oscim.android.filepicker; + +import java.io.File; +import java.io.FileFilter; + +/** + * Accepts all readable directories and all readable files with a given + * extension. + */ +public class FilterByFileExtension implements FileFilter { + private final String mExtension; + + /** + * @param extension + * the allowed file name extension. + */ + public FilterByFileExtension(String extension) { + mExtension = extension; + } + + @Override + public boolean accept(File file) { + // accept only readable files + if (file.canRead()) { + if (file.isDirectory()) { + // accept all directories + return true; + } else if (file.isFile() && file.getName().endsWith(mExtension)) { + return true; + } + } + return false; + } +} diff --git a/vtm-android-example/src/org/oscim/android/filepicker/ValidFileFilter.java b/vtm-android-example/src/org/oscim/android/filepicker/ValidFileFilter.java new file mode 100644 index 00000000..45f80ded --- /dev/null +++ b/vtm-android-example/src/org/oscim/android/filepicker/ValidFileFilter.java @@ -0,0 +1,29 @@ +/* + * Copyright 2010, 2011, 2012 mapsforge.org + * + * This program is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * this program. If not, see . + */ +package org.oscim.android.filepicker; + +import java.io.FileFilter; + +import org.oscim.tiling.source.TileSource.OpenResult; + +/** + * An extension of the {@link FileFilter} interface. + */ +public interface ValidFileFilter extends FileFilter { + /** + * @return the result of the last {@link #accept} call (might be null). + */ + OpenResult getFileOpenResult(); +} diff --git a/vtm-android-example/src/org/oscim/android/filepicker/ValidMapFile.java b/vtm-android-example/src/org/oscim/android/filepicker/ValidMapFile.java new file mode 100644 index 00000000..2f668077 --- /dev/null +++ b/vtm-android-example/src/org/oscim/android/filepicker/ValidMapFile.java @@ -0,0 +1,42 @@ +/* + * Copyright 2010, 2011, 2012 mapsforge.org + * + * This program is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * this program. If not, see . + */ +package org.oscim.android.filepicker; + +import java.io.File; + +import org.oscim.tiling.source.TileSource.OpenResult; +import org.oscim.tiling.source.mapfile.MapFileTileSource; + +/** + * Accepts all valid map files. + */ +public final class ValidMapFile implements ValidFileFilter { + private OpenResult mOpenResult; + + @Override + public boolean accept(File file) { + MapFileTileSource mapFileSource = new MapFileTileSource(); + mapFileSource.setMapFile(file.getAbsolutePath()); + + this.mOpenResult = mapFileSource.open(); + mapFileSource.close(); + return mOpenResult.isSuccess(); + } + + @Override + public OpenResult getFileOpenResult() { + return mOpenResult; + } +} diff --git a/vtm-android-example/src/org/oscim/android/filepicker/ValidRenderTheme.java b/vtm-android-example/src/org/oscim/android/filepicker/ValidRenderTheme.java new file mode 100644 index 00000000..ff8f799e --- /dev/null +++ b/vtm-android-example/src/org/oscim/android/filepicker/ValidRenderTheme.java @@ -0,0 +1,71 @@ +/* + * Copyright 2010, 2011, 2012 mapsforge.org + * + * This program is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * this program. If not, see . + */ +package org.oscim.android.filepicker; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; + +import org.oscim.theme.RenderThemeHandler; +import org.oscim.tiling.source.TileSource.OpenResult; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; + +/** + * Accepts all valid render theme XML files. + */ +public final class ValidRenderTheme implements ValidFileFilter { + private OpenResult mOpenResult; + + @Override + public boolean accept(File file) { + InputStream inputStream = null; + + try { + inputStream = new FileInputStream(file); + RenderThemeHandler renderThemeHandler = new RenderThemeHandler(); + XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); + xmlReader.setContentHandler(renderThemeHandler); + xmlReader.parse(new InputSource(inputStream)); + mOpenResult = OpenResult.SUCCESS; + } catch (ParserConfigurationException e) { + mOpenResult = new OpenResult(e.getMessage()); + } catch (SAXException e) { + mOpenResult = new OpenResult(e.getMessage()); + } catch (IOException e) { + mOpenResult = new OpenResult(e.getMessage()); + } finally { + try { + if (inputStream != null) { + inputStream.close(); + } + } catch (IOException e) { + mOpenResult = new OpenResult(e.getMessage()); + } + } + + return mOpenResult.isSuccess(); + } + + @Override + public OpenResult getFileOpenResult() { + return mOpenResult; + } +} diff --git a/vtm-android-example/src/org/oscim/android/test/MapsforgeMapActivity.java b/vtm-android-example/src/org/oscim/android/test/MapsforgeMapActivity.java new file mode 100644 index 00000000..dec90852 --- /dev/null +++ b/vtm-android-example/src/org/oscim/android/test/MapsforgeMapActivity.java @@ -0,0 +1,127 @@ +/* + * Copyright 2014 Hannes Janetzek + * + * This program is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * this program. If not, see . + */ +package org.oscim.android.test; + +import org.oscim.android.MapActivity; +import org.oscim.android.MapView; +import org.oscim.android.filepicker.FilePicker; +import org.oscim.android.filepicker.FilterByFileExtension; +import org.oscim.android.filepicker.ValidMapFile; +import org.oscim.core.MapPosition; +import org.oscim.core.Tile; +import org.oscim.layers.tile.vector.VectorTileLayer; +import org.oscim.layers.tile.vector.labeling.LabelLayer; +import org.oscim.theme.InternalRenderTheme; +import org.oscim.tiling.source.mapfile.MapFileTileSource; +import org.oscim.tiling.source.mapfile.MapInfo; + +import android.content.Intent; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; + +public class MapsforgeMapActivity extends MapActivity { + private static final int SELECT_MAP_FILE = 0; + + MapView mMapView; + MapFileTileSource mTileSource; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_map); + + mMapView = (MapView) findViewById(R.id.mapView); + registerMapView(mMapView); + + startActivityForResult(new Intent(this, MapFilePicker.class), + SELECT_MAP_FILE); + } + + public static class MapFilePicker extends FilePicker { + public MapFilePicker() { + setFileDisplayFilter(new FilterByFileExtension(".map")); + setFileSelectFilter(new ValidMapFile()); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.theme_menu, menu); + return true; + } + + @Override + public boolean onMenuItemSelected(int featureId, MenuItem item) { + + switch (item.getItemId()) { + case R.id.theme_default: + mMap.setTheme(InternalRenderTheme.DEFAULT); + item.setChecked(true); + return true; + + case R.id.theme_tubes: + mMap.setTheme(InternalRenderTheme.TRONRENDER); + item.setChecked(true); + return true; + + case R.id.theme_osmarender: + mMap.setTheme(InternalRenderTheme.OSMARENDER); + item.setChecked(true); + return true; + } + + return false; + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent intent) { + + if (requestCode == SELECT_MAP_FILE) { + if (resultCode != RESULT_OK || intent == null) + return; + if (intent.getStringExtra(FilePicker.SELECTED_FILE) == null) + return; + + mTileSource = new MapFileTileSource(); + String file = intent.getStringExtra(FilePicker.SELECTED_FILE); + if (mTileSource.setMapFile(file)) { + + VectorTileLayer l = mMap.setBaseMap(mTileSource); + mMap.setTheme(InternalRenderTheme.DEFAULT); + mMap.getLayers().add(new LabelLayer(mMap, l.getTileRenderer())); + + MapInfo info = mTileSource.getMapInfo(); + if (info.boundingBox != null) { + MapPosition pos = new MapPosition(); + pos.setByBoundingBox(info.boundingBox, + Tile.SIZE * 4, + Tile.SIZE * 4); + mMap.setMapPosition(pos); + Samples.log.debug("set position {}",pos); + } else if (info.mapCenter != null) { + + double scale = 1 << 8; + if (info.startZoomLevel != null) + scale = 1 << info.startZoomLevel.intValue(); + + mMap.setMapPosition(info.mapCenter.getLatitude(), + info.mapCenter.getLongitude(), + scale); + } + } + } + } +} diff --git a/vtm-android-example/src/org/oscim/android/test/Samples.java b/vtm-android-example/src/org/oscim/android/test/Samples.java index c217df8d..6a4b511f 100644 --- a/vtm-android-example/src/org/oscim/android/test/Samples.java +++ b/vtm-android-example/src/org/oscim/android/test/Samples.java @@ -17,6 +17,9 @@ */ package org.oscim.android.test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import android.app.Activity; import android.content.Intent; import android.os.Bundle; @@ -29,6 +32,8 @@ import android.widget.LinearLayout; * A simple start screen for the sample activities. */ public class Samples extends Activity { + public static Logger log = LoggerFactory.getLogger(Samples.class); + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -37,6 +42,7 @@ public class Samples extends Activity { LinearLayout linearLayout = (LinearLayout) findViewById(R.id.samples); linearLayout.addView(createButton(SimpleMapActivity.class)); linearLayout.addView(createButton(BitmapTileMapActivity.class)); + linearLayout.addView(createButton(MapsforgeMapActivity.class)); linearLayout.addView(createButton(PathOverlayActivity.class)); linearLayout.addView(createButton(MarkerOverlayActivity.class)); }