diff options
Diffstat (limited to 'main/src/cgeo/geocaching/export/GpxExport.java')
| -rw-r--r-- | main/src/cgeo/geocaching/export/GpxExport.java | 301 |
1 files changed, 301 insertions, 0 deletions
diff --git a/main/src/cgeo/geocaching/export/GpxExport.java b/main/src/cgeo/geocaching/export/GpxExport.java new file mode 100644 index 0000000..2c833a2 --- /dev/null +++ b/main/src/cgeo/geocaching/export/GpxExport.java @@ -0,0 +1,301 @@ +package cgeo.geocaching.export; + +import cgeo.geocaching.R; +import cgeo.geocaching.cgCache; +import cgeo.geocaching.LogEntry; +import cgeo.geocaching.cgeoapplication; +import cgeo.geocaching.activity.ActivityMixin; +import cgeo.geocaching.activity.Progress; +import cgeo.geocaching.enumerations.CacheAttribute; +import cgeo.geocaching.enumerations.LoadFlags; +import cgeo.geocaching.utils.BaseUtils; +import cgeo.geocaching.utils.Log; + +import org.apache.commons.lang3.StringEscapeUtils; + +import android.app.Activity; +import android.app.ProgressDialog; +import android.os.AsyncTask; +import android.os.Environment; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.List; + +class GpxExport extends AbstractExport { + private static final File exportLocation = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/gpx-export"); + private static final SimpleDateFormat dateFormatZ = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + + protected GpxExport() { + super(getString(R.string.export_gpx)); + } + + @Override + public void export(final List<cgCache> caches, final Activity activity) { + new ExportTask(caches, activity).execute((Void) null); + } + + private class ExportTask extends AsyncTask<Void, Integer, Boolean> { + private final List<cgCache> caches; + private final Activity activity; + private final Progress progress = new Progress(); + private File exportFile; + + /** + * Instantiates and configures the task for exporting field notes. + * + * @param caches + * The {@link List} of {@link cgCache} to be exported + * @param activity + * optional: Show a progress bar and toasts + */ + public ExportTask(final List<cgCache> caches, final Activity activity) { + this.caches = caches; + this.activity = activity; + } + + @Override + protected void onPreExecute() { + if (null != activity) { + progress.show(activity, null, getString(R.string.export) + ": " + getName(), ProgressDialog.STYLE_HORIZONTAL, null); + progress.setMaxProgressAndReset(caches.size()); + } + } + + @Override + protected Boolean doInBackground(Void... params) { + // quick check for being able to write the GPX file + if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + return false; + } + + // FIXME: complete export is created in memory. That should be some file stream instead. + final StringBuilder gpx = new StringBuilder(); + + gpx.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); + gpx.append("<gpx version=\"1.0\" creator=\"c:geo - http://www.cgeo.org\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.topografix.com/GPX/1/0\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd http://www.groundspeak.com/cache/1/0/1 http://www.groundspeak.com/cache/1/0/1/cache.xsd\">"); + + try { + for (int i = 0; i < caches.size(); i++) { + cgCache cache = caches.get(i); + + if (!cache.isDetailed()) { + cache = cgeoapplication.getInstance().loadCache(caches.get(i).getGeocode(), LoadFlags.LOAD_ALL_DB_ONLY); + } + + gpx.append("<wpt "); + gpx.append("lat=\"" + cache.getCoords().getLatitude() + "\" "); + gpx.append("lon=\"" + cache.getCoords().getLongitude() + "\">"); + + gpx.append("<time>"); + gpx.append(StringEscapeUtils.escapeXml(dateFormatZ.format(cache.getHiddenDate()))); + gpx.append("</time>"); + + gpx.append("<name>"); + gpx.append(StringEscapeUtils.escapeXml(cache.getGeocode())); + gpx.append("</name>"); + + gpx.append("<desc>"); + gpx.append(StringEscapeUtils.escapeXml(cache.getName())); + gpx.append("</desc>"); + + gpx.append("<sym>"); + gpx.append(cache.isFound() ? "Geocache Found" : "Geocache"); + gpx.append("</sym>"); + + gpx.append("<type>"); + gpx.append(StringEscapeUtils.escapeXml("Geocache|" + cache.getType().toString())); //TODO: Correct (english) string + gpx.append("</type>"); + + gpx.append("<groundspeak:cache "); + gpx.append("available=\"" + (!cache.isDisabled() ? "True" : "False")); + gpx.append("\" archived=\"" + (cache.isArchived() ? "True" : "False") + "\" "); + gpx.append("xmlns:groundspeak=\"http://www.groundspeak.com/cache/1/0/1\">"); + + gpx.append("<groundspeak:name>"); + gpx.append(StringEscapeUtils.escapeXml(cache.getName())); + gpx.append("</groundspeak:name>"); + + gpx.append("<groundspeak:placed_by>"); + gpx.append(StringEscapeUtils.escapeXml(cache.getOwner())); + gpx.append("</groundspeak:placed_by>"); + + gpx.append("<groundspeak:owner>"); + gpx.append(StringEscapeUtils.escapeXml(cache.getOwnerReal())); + gpx.append("</groundspeak:owner>"); + + gpx.append("<groundspeak:type>"); + gpx.append(StringEscapeUtils.escapeXml(cache.getType().toString())); //TODO: Correct (english) string + gpx.append("</groundspeak:type>"); + + gpx.append("<groundspeak:container>"); + gpx.append(StringEscapeUtils.escapeXml(cache.getSize().toString())); //TODO: Correct (english) string + gpx.append("</groundspeak:container>"); + + if (cache.hasAttributes()) { + //TODO: Attribute conversion required: English verbose name, gpx-id + gpx.append("<groundspeak:attributes>"); + + for (String attribute : cache.getAttributes()) { + final CacheAttribute attr = CacheAttribute.getByGcRawName(CacheAttribute.trimAttributeName(attribute)); + final boolean enabled = attribute.endsWith(CacheAttribute.INTERNAL_YES); + + gpx.append("<groundspeak:attribute id=\""); + gpx.append(attr.id); + gpx.append("\" inc=\""); + if (enabled) { + gpx.append('1'); + } else { + gpx.append('0'); + } + gpx.append("\">"); + gpx.append(StringEscapeUtils.escapeXml(attr.getL10n(enabled))); + gpx.append("</groundspeak:attribute>"); + } + + gpx.append("</groundspeak:attributes>"); + } + + gpx.append("<groundspeak:difficulty>"); + gpx.append(Float.toString(cache.getDifficulty())); + gpx.append("</groundspeak:difficulty>"); + + gpx.append("<groundspeak:terrain>"); + gpx.append(Float.toString(cache.getTerrain())); + gpx.append("</groundspeak:terrain>"); + + gpx.append("<groundspeak:country>"); + gpx.append(StringEscapeUtils.escapeXml(cache.getLocation())); + gpx.append("</groundspeak:country>"); + + gpx.append("<groundspeak:state>"); + gpx.append(StringEscapeUtils.escapeXml(cache.getLocation())); + gpx.append("</groundspeak:state>"); + + gpx.append("<groundspeak:short_description html=\""); + if (BaseUtils.containsHtml(cache.getShortDescription())) { + gpx.append("True"); + } else { + gpx.append("False"); + } + gpx.append("\">"); + gpx.append(StringEscapeUtils.escapeXml(cache.getShortDescription())); + gpx.append("</groundspeak:short_description>"); + + gpx.append("<groundspeak:long_description html=\""); + if (BaseUtils.containsHtml(cache.getDescription())) { + gpx.append("True"); + } else { + gpx.append("False"); + } + gpx.append("\">"); + gpx.append(StringEscapeUtils.escapeXml(cache.getDescription())); + gpx.append("</groundspeak:long_description>"); + + gpx.append("<groundspeak:encoded_hints>"); + gpx.append(StringEscapeUtils.escapeXml(cache.getHint())); + gpx.append("</groundspeak:encoded_hints>"); + + gpx.append("</groundspeak:cache>"); + + //TODO: Waypoints + + if (cache.getLogs().size() > 0) { + gpx.append("<groundspeak:logs>"); + + for (LogEntry log : cache.getLogs()) { + gpx.append("<groundspeak:log id=\""); + gpx.append(log.id); + gpx.append("\">"); + + gpx.append("<groundspeak:date>"); + gpx.append(StringEscapeUtils.escapeXml(dateFormatZ.format(new Date(log.date)))); + gpx.append("</groundspeak:date>"); + + gpx.append("<groundspeak:type>"); + gpx.append(StringEscapeUtils.escapeXml(log.type.type)); + gpx.append("</groundspeak:type>"); + + gpx.append("<groundspeak:finder id=\"\">"); + gpx.append(StringEscapeUtils.escapeXml(log.author)); + gpx.append("</groundspeak:finder>"); + + gpx.append("<groundspeak:text encoded=\"False\">"); + gpx.append(StringEscapeUtils.escapeXml(log.log)); + gpx.append("</groundspeak:text>"); + + gpx.append("</groundspeak:log>"); + } + + gpx.append("</groundspeak:logs>"); + } + + gpx.append("</wpt>"); + + publishProgress(i + 1); + } + } catch (Exception e) { + Log.e("GpxExport.ExportTask generation", e); + return false; + } + + gpx.append("</gpx>"); + + if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + exportLocation.mkdirs(); + + SimpleDateFormat fileNameDateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); + exportFile = new File(exportLocation.toString() + '/' + fileNameDateFormat.format(new Date()) + ".gpx"); + + OutputStream os = null; + Writer fw = null; + try { + os = new FileOutputStream(exportFile); + fw = new OutputStreamWriter(os, "UTF-8"); + fw.write(gpx.toString()); + } catch (IOException e) { + Log.e("GpxExport.ExportTask export", e); + return false; + } finally { + if (fw != null) { + try { + fw.close(); + } catch (IOException e) { + Log.e("GpxExport.ExportTask export", e); + return false; + } + } + } + } else { + return false; + } + + return true; + } + + @Override + protected void onPostExecute(Boolean result) { + if (null != activity) { + progress.dismiss(); + if (result) { + ActivityMixin.showToast(activity, getName() + ' ' + getString(R.string.export_exportedto) + ": " + exportFile.toString()); + } else { + ActivityMixin.showToast(activity, getString(R.string.export_failed)); + } + } + } + + @Override + protected void onProgressUpdate(Integer... status) { + if (null != activity) { + progress.setProgress(status[0]); + } + } + } +} |
