Add GPX import.
This commit is contained in:
parent
57d9cdb36e
commit
4e17bc3800
|
|
@ -20,6 +20,8 @@
|
|||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name=".FilePicker"></activity>
|
||||
</application>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,213 @@
|
|||
package fr.chteufleur.mytrackingdog;
|
||||
|
||||
import android.app.ListActivity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import fr.chteufleur.mytrackingdog.R;
|
||||
|
||||
public class FilePicker extends ListActivity {
|
||||
|
||||
public final static String EXTRA_FILE_PATH = "file_path";
|
||||
public final static String EXTRA_SHOW_HIDDEN_FILES = "show_hidden_files";
|
||||
public final static String EXTRA_ACCEPTED_FILE_EXTENSIONS = "accepted_file_extensions";
|
||||
private final static String DEFAULT_INITIAL_DIRECTORY = "/";
|
||||
|
||||
protected File Directory;
|
||||
protected ArrayList<File> Files;
|
||||
protected FilePickerListAdapter Adapter;
|
||||
protected boolean ShowHiddenFiles = false;
|
||||
protected String[] acceptedFileExtensions;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
LayoutInflater inflator = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
||||
View emptyView = inflator.inflate(R.layout.empty_view, null);
|
||||
((ViewGroup) getListView().getParent()).addView(emptyView);
|
||||
getListView().setEmptyView(emptyView);
|
||||
|
||||
// Set initial directory
|
||||
Directory = new File(DEFAULT_INITIAL_DIRECTORY);
|
||||
|
||||
// Initialize the ArrayList
|
||||
Files = new ArrayList<File>();
|
||||
|
||||
// Set the ListAdapter
|
||||
Adapter = new FilePickerListAdapter(this, Files);
|
||||
setListAdapter(Adapter);
|
||||
|
||||
// Initialize the extensions array to allow any file extensions
|
||||
acceptedFileExtensions = new String[] {};
|
||||
|
||||
// Get intent extras
|
||||
if (getIntent().hasExtra(EXTRA_FILE_PATH)) {
|
||||
Directory = new File(getIntent().getStringExtra(EXTRA_FILE_PATH));
|
||||
}
|
||||
|
||||
if (getIntent().hasExtra(EXTRA_SHOW_HIDDEN_FILES)) {
|
||||
ShowHiddenFiles = getIntent().getBooleanExtra(EXTRA_SHOW_HIDDEN_FILES, false);
|
||||
}
|
||||
|
||||
if (getIntent().hasExtra(EXTRA_ACCEPTED_FILE_EXTENSIONS)) {
|
||||
ArrayList<String> collection = getIntent().getStringArrayListExtra(EXTRA_ACCEPTED_FILE_EXTENSIONS);
|
||||
acceptedFileExtensions = collection.toArray(new String[collection.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
refreshFilesList();
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
protected void refreshFilesList() {
|
||||
Files.clear();
|
||||
ExtensionFilenameFilter filter = new ExtensionFilenameFilter(acceptedFileExtensions);
|
||||
|
||||
File[] files = Directory.listFiles(filter);
|
||||
if (files != null && files.length > 0) {
|
||||
for (File f: files) {
|
||||
if (f.isHidden() && !ShowHiddenFiles) {
|
||||
continue;
|
||||
}
|
||||
Files.add(f);
|
||||
}
|
||||
Collections.sort(Files, new FileComparator());
|
||||
}
|
||||
Adapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (Directory.getParentFile() != null) {
|
||||
Directory = Directory.getParentFile();
|
||||
refreshFilesList();
|
||||
return;
|
||||
}
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onListItemClick(ListView l, View v, int position, long id) {
|
||||
File newFile = (File)l.getItemAtPosition(position);
|
||||
if (newFile.isFile()) {
|
||||
Intent extra = new Intent();
|
||||
extra.putExtra(EXTRA_FILE_PATH, newFile.getAbsolutePath());
|
||||
setResult(RESULT_OK, extra);
|
||||
finish();
|
||||
} else {
|
||||
Directory = newFile;
|
||||
refreshFilesList();
|
||||
}
|
||||
super.onListItemClick(l, v, position, id);
|
||||
}
|
||||
|
||||
private class FilePickerListAdapter extends ArrayAdapter<File> {
|
||||
private List<File> mObjects;
|
||||
|
||||
public FilePickerListAdapter(Context context, List<File> objects) {
|
||||
super(context, R.layout.list_item, android.R.id.text1, objects);
|
||||
mObjects = objects;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
View row = null;
|
||||
|
||||
if (convertView == null) {
|
||||
LayoutInflater inflater = (LayoutInflater)
|
||||
getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
row = inflater.inflate(R.layout.list_item, parent, false);
|
||||
} else {
|
||||
row = convertView;
|
||||
}
|
||||
|
||||
File object = mObjects.get(position);
|
||||
|
||||
ImageView imageView = row.findViewById(R.id.file_picker_image);
|
||||
TextView textView = row.findViewById(R.id.file_picker_text);
|
||||
textView.setSingleLine(true);
|
||||
textView.setText(object.getName());
|
||||
|
||||
if (object.isFile()) {
|
||||
imageView.setImageResource(R.drawable.ic_file);
|
||||
} else {
|
||||
imageView.setImageResource(R.drawable.ic_folder);
|
||||
}
|
||||
|
||||
return row;
|
||||
}
|
||||
}
|
||||
|
||||
private class FileComparator implements Comparator<File> {
|
||||
|
||||
public int compare(File f1, File f2) {
|
||||
|
||||
if (f1 == f2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (f1.isDirectory() && f2.isFile()) {
|
||||
// Show directories above files
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (f1.isFile() && f2.isDirectory()) {
|
||||
// Show files below directories
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Sort the directories alphabetically
|
||||
return f1.getName().compareToIgnoreCase(f2.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private class ExtensionFilenameFilter implements FilenameFilter {
|
||||
|
||||
private String[] Extensions;
|
||||
|
||||
public ExtensionFilenameFilter(String[] extensions) {
|
||||
super();
|
||||
Extensions = extensions;
|
||||
}
|
||||
|
||||
public boolean accept(File dir, String filename) {
|
||||
|
||||
if (new File(dir, filename).isDirectory()) {
|
||||
// Accept all directory names
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Extensions != null && Extensions.length > 0) {
|
||||
for (int i = 0; i < Extensions.length; i++) {
|
||||
if (filename.endsWith(Extensions[i])) {
|
||||
// The filename ends with the extension
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// The filename did not match any of the extensions
|
||||
return false;
|
||||
}
|
||||
// No extensions has been set. Accept all file extensions.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,26 +2,26 @@ package fr.chteufleur.mytrackingdog;
|
|||
|
||||
import android.Manifest;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.hardware.GeomagneticField;
|
||||
import android.location.Location;
|
||||
import android.location.LocationManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.util.Log;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.Surface;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.osmdroid.api.IMapController;
|
||||
|
|
@ -31,7 +31,6 @@ import org.osmdroid.util.GeoPoint;
|
|||
import org.osmdroid.views.MapView;
|
||||
import org.osmdroid.views.overlay.Marker;
|
||||
import org.osmdroid.views.overlay.Polyline;
|
||||
import org.osmdroid.views.overlay.compass.CompassOverlay;
|
||||
import org.osmdroid.views.overlay.compass.IOrientationConsumer;
|
||||
import org.osmdroid.views.overlay.compass.IOrientationProvider;
|
||||
import org.osmdroid.views.overlay.compass.InternalCompassOrientationProvider;
|
||||
|
|
@ -39,11 +38,13 @@ import org.osmdroid.views.overlay.infowindow.BasicInfoWindow;
|
|||
import org.osmdroid.views.overlay.mylocation.GpsMyLocationProvider;
|
||||
import org.osmdroid.views.overlay.mylocation.MyLocationNewOverlay;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
|
||||
import fr.chteufleur.mytrackingdog.models.Gpx;
|
||||
import fr.chteufleur.mytrackingdog.models.beans.MyLocation;
|
||||
import fr.chteufleur.mytrackingdog.services.ServiceGps;
|
||||
|
||||
|
|
@ -54,13 +55,11 @@ public class MainActivity extends AppCompatActivity implements IOrientationConsu
|
|||
public static String appName = "";
|
||||
|
||||
private MyLocationNewOverlay mLocationOverlay;
|
||||
private CompassOverlay mCompassOverlay;
|
||||
private IOrientationProvider compass = null;
|
||||
private ServiceGps serviceGps = null;
|
||||
|
||||
private Context ctx = null;
|
||||
private MapView map = null;
|
||||
private ImageButton btFollowMe;
|
||||
|
||||
private int deviceOrientation = 0;
|
||||
private boolean zoomed = false;
|
||||
|
|
@ -99,6 +98,9 @@ public class MainActivity extends AppCompatActivity implements IOrientationConsu
|
|||
// Keep screen ON
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
map = findViewById(R.id.map);
|
||||
map.setTileSource(TileSourceFactory.MAPNIK);
|
||||
|
||||
|
|
@ -112,11 +114,6 @@ public class MainActivity extends AppCompatActivity implements IOrientationConsu
|
|||
GeoPoint startPoint = new GeoPoint(45.0000, 5.0000);
|
||||
mapController.setCenter(startPoint);
|
||||
|
||||
// Compass
|
||||
this.mCompassOverlay = new CompassOverlay(ctx, new InternalCompassOrientationProvider(ctx), map);
|
||||
map.getOverlays().add(this.mCompassOverlay);
|
||||
this.mCompassOverlay.enableCompass();
|
||||
|
||||
// Current position on the map
|
||||
this.mLocationOverlay = new MyLocationNewOverlay(new GpsMyLocationProvider(ctx), map);
|
||||
map.getOverlays().add(this.mLocationOverlay);
|
||||
|
|
@ -124,20 +121,6 @@ public class MainActivity extends AppCompatActivity implements IOrientationConsu
|
|||
mLocationOverlay.enableFollowLocation();
|
||||
mLocationOverlay.setOptionsMenuEnabled(true);
|
||||
|
||||
// Follow me
|
||||
btFollowMe = findViewById(R.id.ic_follow_me);
|
||||
btFollowMe.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (!mLocationOverlay.isFollowLocationEnabled()) {
|
||||
mLocationOverlay.enableFollowLocation();
|
||||
btFollowMe.setImageResource(R.drawable.osm_ic_follow_me_on);
|
||||
} else {
|
||||
mLocationOverlay.disableFollowLocation();
|
||||
btFollowMe.setImageResource(R.drawable.osm_ic_follow_me);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
start_stop_trace = findViewById(R.id.start_stop_trace);
|
||||
start_stop_trace.setOnClickListener(new View.OnClickListener() {
|
||||
|
|
@ -198,6 +181,10 @@ public class MainActivity extends AppCompatActivity implements IOrientationConsu
|
|||
private void addMarker() {
|
||||
MyLocation loc = serviceGps.addPointObject();
|
||||
GeoPoint gp = new GeoPoint(loc.getLatitude(), loc.getLongitude(), loc.getAltitude());
|
||||
addMarker(gp);
|
||||
}
|
||||
|
||||
private void addMarker(GeoPoint gp) {
|
||||
Marker marker = new Marker(map);
|
||||
marker.setPosition(gp);
|
||||
marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
|
||||
|
|
@ -262,9 +249,6 @@ public class MainActivity extends AppCompatActivity implements IOrientationConsu
|
|||
}
|
||||
|
||||
private void pause() {
|
||||
if (mCompassOverlay != null) {
|
||||
mCompassOverlay.disableCompass();
|
||||
}
|
||||
if (compass != null) {
|
||||
compass.stopOrientationProvider();
|
||||
compass.destroy();
|
||||
|
|
@ -308,13 +292,34 @@ public class MainActivity extends AppCompatActivity implements IOrientationConsu
|
|||
int id = item.getItemId();
|
||||
|
||||
//noinspection SimplifiableIfStatement
|
||||
if (id == R.id.action_settings) {
|
||||
if (id == R.id.action_import_gpx) {
|
||||
Intent intent = new Intent(this, FilePicker.class);
|
||||
intent.putExtra(FilePicker.EXTRA_FILE_PATH, Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+appName);
|
||||
startActivityForResult(intent, REQUEST_PICK_FILE);
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
private static final int REQUEST_PICK_FILE = 1;
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (resultCode == RESULT_OK) {
|
||||
switch (requestCode) {
|
||||
case REQUEST_PICK_FILE:
|
||||
if (data.hasExtra(FilePicker.EXTRA_FILE_PATH)) {
|
||||
serviceGps.importGpxTrace(new File(data.getStringExtra(FilePicker.EXTRA_FILE_PATH)));
|
||||
updateDogTrace();
|
||||
updateTrailTrace();
|
||||
for (MyLocation loc: serviceGps.getListGeoPointObjects()) {
|
||||
addMarker(new GeoPoint(loc.getLatitude(), loc.getLongitude(), loc.getAltitude()));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
|
|
@ -376,40 +381,44 @@ public class MainActivity extends AppCompatActivity implements IOrientationConsu
|
|||
}
|
||||
}
|
||||
|
||||
private void updateDogTrace() {
|
||||
Polyline line = new Polyline(map);
|
||||
line.setTitle(Gpx.DOG_TRACE_NAME);
|
||||
line.setColor(Color.BLUE);
|
||||
line.setPoints(convertListLocation(serviceGps.getListGeoPointDog()));
|
||||
line.setWidth(LINE_WIDTH_BIG);
|
||||
line.setGeodesic(true);
|
||||
line.setInfoWindow(new BasicInfoWindow(R.layout.bonuspack_bubble, map));
|
||||
map.getOverlayManager().add(line);
|
||||
map.invalidate();
|
||||
}
|
||||
|
||||
private void updateTrailTrace() {
|
||||
Polyline line = new Polyline(map);
|
||||
line.setTitle(Gpx.TRAIL_TRACE_NAME);
|
||||
line.setColor(Color.RED);
|
||||
line.setPoints(convertListLocation(serviceGps.getListGeoPointTraceur()));
|
||||
line.setWidth(LINE_WIDTH_BIG);
|
||||
line.setGeodesic(true);
|
||||
line.setInfoWindow(new BasicInfoWindow(R.layout.bonuspack_bubble, map));
|
||||
map.getOverlayManager().add(line);
|
||||
map.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Observable observable, Object o) {
|
||||
if (observable == serviceGps) {
|
||||
if (o instanceof String && o.equals(ServiceGps.NOTIF_NEW_LOCATION)) {
|
||||
Location loc = serviceGps.getCurrentLocation();
|
||||
MyLocation loc = serviceGps.getCurrentLocation();
|
||||
if (loc != null) {
|
||||
GeoPoint currentPoint = new GeoPoint(loc.getLatitude(), loc.getLongitude(), loc.getAltitude());
|
||||
Polyline line = null;
|
||||
map.getController().setCenter(currentPoint);
|
||||
if (serviceGps.isTraceurActivated()) {
|
||||
map.getController().setCenter(currentPoint);
|
||||
|
||||
line = new Polyline(map);
|
||||
line.setTitle("Trail");
|
||||
line.setColor(Color.RED);
|
||||
line.setPoints(convertListLocation(serviceGps.getListGeoPointTraceur()));
|
||||
|
||||
updateTrailTrace();
|
||||
} else if (serviceGps.isDogActivated()) {
|
||||
map.getController().setCenter(currentPoint);
|
||||
|
||||
line = new Polyline(map);
|
||||
line.setTitle("Dog");
|
||||
line.setColor(Color.BLUE);
|
||||
line.setPoints(convertListLocation(serviceGps.getListGeoPointDog()));
|
||||
updateDogTrace();
|
||||
}
|
||||
|
||||
if (line != null) {
|
||||
line.setSubDescription(Polyline.class.getCanonicalName());
|
||||
line.setWidth(LINE_WIDTH_BIG);
|
||||
line.setGeodesic(true);
|
||||
line.setInfoWindow(new BasicInfoWindow(R.layout.bonuspack_bubble, map));
|
||||
map.getOverlayManager().add(line);
|
||||
map.invalidate();
|
||||
}
|
||||
float orientation = serviceGps.getOrientation(deviceOrientation);
|
||||
if (orientation >= 0) {
|
||||
map.setMapOrientation(orientation);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ import java.io.File;
|
|||
|
||||
public class Gpx {
|
||||
|
||||
public static final String DOG_TRACE_NAME = "dog";
|
||||
public static final String TRAIL_TRACE_NAME = "trail";
|
||||
|
||||
protected final File filePath;
|
||||
|
||||
public Gpx(File filePath) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,219 @@
|
|||
package fr.chteufleur.mytrackingdog.models;
|
||||
|
||||
import android.util.Log;
|
||||
import android.util.Xml;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import fr.chteufleur.mytrackingdog.models.beans.MyLocation;
|
||||
import fr.chteufleur.mytrackingdog.models.beans.TraceLocation;
|
||||
import fr.chteufleur.mytrackingdog.models.beans.WayPointLocation;
|
||||
|
||||
public class ImportGpx extends Gpx {
|
||||
|
||||
private static final String TAG = Traces.class.getName();
|
||||
|
||||
private String traceName = "";
|
||||
|
||||
|
||||
public ImportGpx(File filePath) {
|
||||
super(filePath);
|
||||
}
|
||||
|
||||
public String getTraceName() {
|
||||
return this.traceName;
|
||||
}
|
||||
|
||||
public List parse() throws XmlPullParserException, IOException {
|
||||
InputStream in = new FileInputStream(filePath);
|
||||
try {
|
||||
|
||||
XmlPullParser parser = Xml.newPullParser();
|
||||
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
|
||||
parser.setInput(in, null);
|
||||
parser.nextTag();
|
||||
return readGpx(parser);
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private List readGpx(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||
List entries = new ArrayList();
|
||||
|
||||
parser.require(XmlPullParser.START_TAG, null, "gpx");
|
||||
while (parser.next() != XmlPullParser.END_TAG) {
|
||||
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||
continue;
|
||||
}
|
||||
String name = parser.getName();
|
||||
if (name.equals("wpt")) {
|
||||
entries.add(readWaypoint(parser));
|
||||
} else if (name.equals("trk")) {
|
||||
entries.addAll(readTrk(parser));
|
||||
} else {
|
||||
skip(parser);
|
||||
}
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
private List readTrk(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||
List entries = new ArrayList();
|
||||
|
||||
parser.require(XmlPullParser.START_TAG, null, "trk");
|
||||
while (parser.next() != XmlPullParser.END_TAG) {
|
||||
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||
continue;
|
||||
}
|
||||
String name = parser.getName();
|
||||
if (name.equals("trkseg")) {
|
||||
entries = readTrkseq(parser);
|
||||
} else {
|
||||
skip(parser);
|
||||
}
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
private List readTrkseq(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||
List entries = new ArrayList();
|
||||
|
||||
parser.require(XmlPullParser.START_TAG, null, "trkseg");
|
||||
while (parser.next() != XmlPullParser.END_TAG) {
|
||||
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||
continue;
|
||||
}
|
||||
String name = parser.getName();
|
||||
if (name.equals("trkpt")) {
|
||||
entries.add(readTrkpt(parser));
|
||||
} else if (name.equals("name")) {
|
||||
traceName = readName(parser);
|
||||
} else {
|
||||
skip(parser);
|
||||
}
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
|
||||
private MyLocation readTrkpt(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||
parser.require(XmlPullParser.START_TAG, null, "trkpt");
|
||||
|
||||
String latStr = parser.getAttributeValue(null, "lat");
|
||||
String lonStr = parser.getAttributeValue(null, "lon");
|
||||
double lat = Double.parseDouble(latStr);
|
||||
double lon = Double.parseDouble(lonStr);
|
||||
long time = -1;
|
||||
|
||||
while (parser.next() != XmlPullParser.END_TAG) {
|
||||
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||
continue;
|
||||
}
|
||||
String name = parser.getName();
|
||||
if (name.equals("time")) {
|
||||
time = readTime(parser);
|
||||
} else {
|
||||
skip(parser);
|
||||
}
|
||||
}
|
||||
return new TraceLocation(lat, lon, time);
|
||||
}
|
||||
|
||||
|
||||
private MyLocation readWaypoint(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||
parser.require(XmlPullParser.START_TAG, null, "wpt");
|
||||
|
||||
String latStr = parser.getAttributeValue(null, "lat");
|
||||
String lonStr = parser.getAttributeValue(null, "lon");
|
||||
double lat = Double.parseDouble(latStr);
|
||||
double lon = Double.parseDouble(lonStr);
|
||||
long time = -1;
|
||||
|
||||
while (parser.next() != XmlPullParser.END_TAG) {
|
||||
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||
continue;
|
||||
}
|
||||
String name = parser.getName();
|
||||
if (name.equals("time")) {
|
||||
time = readTime(parser);
|
||||
} else {
|
||||
skip(parser);
|
||||
}
|
||||
}
|
||||
return new WayPointLocation(lat, lon, time);
|
||||
}
|
||||
|
||||
|
||||
private long readTime(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||
long ret = 0;
|
||||
parser.require(XmlPullParser.START_TAG, null, "time");
|
||||
String timeStr = readText(parser);
|
||||
|
||||
SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
Pattern pattern = Pattern.compile("([0-9]{4}-[0-9]{2}-[0-9]{2})T([0-9]{2}:[0-9]{2}:[0-9]{2})Z");
|
||||
Matcher matcher = pattern.matcher(timeStr);
|
||||
|
||||
while (matcher.find()) {
|
||||
if (matcher.groupCount() == 2) {
|
||||
try {
|
||||
Date date = formater.parse(matcher.group(1) + " " + matcher.group(2));
|
||||
ret = date.getTime();
|
||||
} catch (ParseException ex) {
|
||||
Log.e(TAG, "Failed to parse time", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
parser.require(XmlPullParser.END_TAG, null, "time");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
private String readName(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||
String ret;
|
||||
parser.require(XmlPullParser.START_TAG, null, "name");
|
||||
ret = readText(parser);
|
||||
parser.require(XmlPullParser.END_TAG, null, "name");
|
||||
return ret;
|
||||
}
|
||||
|
||||
private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
|
||||
String result = "";
|
||||
if (parser.next() == XmlPullParser.TEXT) {
|
||||
result = parser.getText();
|
||||
parser.nextTag();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
|
||||
if (parser.getEventType() != XmlPullParser.START_TAG) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
int depth = 1;
|
||||
while (depth != 0) {
|
||||
switch (parser.next()) {
|
||||
case XmlPullParser.END_TAG:
|
||||
depth--;
|
||||
break;
|
||||
case XmlPullParser.START_TAG:
|
||||
depth++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,28 +2,88 @@ package fr.chteufleur.mytrackingdog.models.beans;
|
|||
|
||||
import android.location.Location;
|
||||
|
||||
public class MyLocation extends Location {
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
public class MyLocation {
|
||||
|
||||
private final double longitude;
|
||||
private final double latitude;
|
||||
private final long time;
|
||||
|
||||
private final double altitude;
|
||||
private final float speed;
|
||||
private final float bearing;
|
||||
|
||||
public MyLocation(Location l) {
|
||||
super(l);
|
||||
if (l == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
this.latitude = l.getLatitude();
|
||||
this.longitude = l.getLongitude();
|
||||
this.time = l.getTime();
|
||||
this.altitude = l.getAltitude();
|
||||
this.speed = l.getSpeed();
|
||||
this.bearing = l.getBearing();
|
||||
}
|
||||
|
||||
public MyLocation(double lat, double lon, long time) {
|
||||
this.latitude = lat;
|
||||
this.longitude = lon;
|
||||
this.time = time;
|
||||
this.altitude = 0;
|
||||
this.speed = 0;
|
||||
this.bearing = 0;
|
||||
}
|
||||
|
||||
|
||||
public double getLatitude() {
|
||||
return this.latitude;
|
||||
}
|
||||
|
||||
public double getLongitude() {
|
||||
return this.longitude;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return this.time;
|
||||
}
|
||||
|
||||
public String getDate() {
|
||||
Date date = new Date(this.time);
|
||||
SimpleDateFormat formaterDate = new SimpleDateFormat("yyyy-MM-dd");
|
||||
SimpleDateFormat formaterTime = new SimpleDateFormat("HH:mm:ss");
|
||||
return formaterDate.format(date)+"T"+formaterTime.format(date)+"Z";
|
||||
}
|
||||
|
||||
public double getAltitude() {
|
||||
return this.altitude;
|
||||
}
|
||||
|
||||
public float getSpeed() {
|
||||
return this.speed;
|
||||
}
|
||||
|
||||
public float getBearing() {
|
||||
return this.bearing;
|
||||
}
|
||||
|
||||
|
||||
public String toWayPoint() {
|
||||
String ret = "<wpt lat=\""+getLatitude()+"\" lon=\""+getLongitude()+"\">";
|
||||
ret += "<time>"+getTime()+"</time>";
|
||||
ret += "<time>"+getDate()+"</time>";
|
||||
ret += "</wpt>";
|
||||
return ret;
|
||||
}
|
||||
|
||||
public String toTracePoint() {
|
||||
String ret = "<trkpt lat=\""+getLatitude()+"\" lon=\""+getLongitude()+"\">";
|
||||
ret += "<time>"+getTime()+"</time>";
|
||||
ret += "<time>"+getDate()+"</time>";
|
||||
ret += "</trkpt>";
|
||||
return ret;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("lat=%,4f ; lon=%,4f ; time=%d", getLatitude(), getLongitude(), getTime());
|
||||
return String.format("lat=%,4f ; lon=%,4f ; time=%s", getLatitude(), getLongitude(), getDate());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
package fr.chteufleur.mytrackingdog.models.beans;
|
||||
|
||||
import android.location.Location;
|
||||
|
||||
public class TraceLocation extends MyLocation {
|
||||
public TraceLocation(Location l) {
|
||||
super(l);
|
||||
}
|
||||
|
||||
public TraceLocation(double lat, double lon, long time) {
|
||||
super(lat, lon, time);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package fr.chteufleur.mytrackingdog.models.beans;
|
||||
|
||||
import android.location.Location;
|
||||
|
||||
|
||||
public class WayPointLocation extends MyLocation {
|
||||
public WayPointLocation(Location l) {
|
||||
super(l);
|
||||
}
|
||||
|
||||
public WayPointLocation(double lat, double lon, long time) {
|
||||
super(lat, lon, time);
|
||||
}
|
||||
}
|
||||
|
|
@ -7,15 +7,22 @@ import android.os.Bundle;
|
|||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Observable;
|
||||
|
||||
import fr.chteufleur.mytrackingdog.models.ExportGpx;
|
||||
import fr.chteufleur.mytrackingdog.models.Gpx;
|
||||
import fr.chteufleur.mytrackingdog.models.ImportGpx;
|
||||
import fr.chteufleur.mytrackingdog.models.Traces;
|
||||
import fr.chteufleur.mytrackingdog.models.beans.MyLocation;
|
||||
import fr.chteufleur.mytrackingdog.models.beans.TraceLocation;
|
||||
import fr.chteufleur.mytrackingdog.models.beans.WayPointLocation;
|
||||
|
||||
public class ServiceGps extends Observable implements IServiceGps, LocationListener {
|
||||
|
||||
|
|
@ -142,19 +149,41 @@ public class ServiceGps extends Observable implements IServiceGps, LocationListe
|
|||
}
|
||||
|
||||
public boolean exportDogTraceToGpx() {
|
||||
File file = new File(getFileName("dog"));
|
||||
ExportGpx exportGpx = new ExportGpx(file, "dog");
|
||||
File file = new File(getFileName(Gpx.DOG_TRACE_NAME));
|
||||
ExportGpx exportGpx = new ExportGpx(file, Gpx.DOG_TRACE_NAME);
|
||||
exportGpx.setTrace(traces.getListPointDog());
|
||||
return exportGpx.export();
|
||||
}
|
||||
|
||||
public boolean exportTrailTraceToGpx() {
|
||||
SimpleDateFormat formater = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
|
||||
String date = formater.format(new Date());
|
||||
File file = new File(getFileName("trail"));
|
||||
ExportGpx exportGpx = new ExportGpx(file, "trail");
|
||||
File file = new File(getFileName(Gpx.TRAIL_TRACE_NAME));
|
||||
ExportGpx exportGpx = new ExportGpx(file, Gpx.TRAIL_TRACE_NAME);
|
||||
exportGpx.setObjects(traces.getListPointObjects());
|
||||
exportGpx.setTrace(traces.getListPointTraceur());
|
||||
return exportGpx.export();
|
||||
}
|
||||
|
||||
public void importGpxTrace(File file) {
|
||||
ImportGpx importGpx = new ImportGpx(file);
|
||||
try {
|
||||
List list = importGpx.parse();
|
||||
String traceName = importGpx.getTraceName();
|
||||
for (int i=0; i<list.size(); i++) {
|
||||
Object o = list.get(i);
|
||||
if (o instanceof WayPointLocation) {
|
||||
traces.addPointObject((WayPointLocation) o);
|
||||
} else if (o instanceof TraceLocation) {
|
||||
if (traceName.equals(Gpx.DOG_TRACE_NAME)) {
|
||||
traces.addPointDog((TraceLocation) o);
|
||||
} else if (traceName.equals(Gpx.TRAIL_TRACE_NAME)) {
|
||||
traces.addPointTraceur((TraceLocation) o);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (XmlPullParserException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 5.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.2 KiB |
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:text="No files or directories"
|
||||
android:background="@android:drawable/toast_frame"
|
||||
android:textSize="28sp"
|
||||
android:gravity="center_vertical|center_horizontal" />
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal" >
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/file_picker_image"
|
||||
android:layout_width="40dip"
|
||||
android:layout_height="40dip"
|
||||
android:layout_marginTop="5dip"
|
||||
android:layout_marginBottom="5dip"
|
||||
android:layout_marginLeft="5dip"
|
||||
android:src="@drawable/direction_arrow"
|
||||
android:scaleType="centerCrop" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/file_picker_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_gravity="left|center_vertical"
|
||||
android:textSize="28sp"
|
||||
android:layout_marginLeft="10dip"
|
||||
android:singleLine="true"
|
||||
android:text="Filename" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
|
|
@ -6,21 +7,25 @@
|
|||
android:layout_height="match_parent"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/AppTheme.AppBarOverlay">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay" />
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<org.osmdroid.views.MapView android:id="@+id/map"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/ic_follow_me"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top|end"
|
||||
android:layout_marginTop="11dp"
|
||||
android:background="#00ffffff"
|
||||
android:contentDescription="@string/bt_follow_me_description"
|
||||
android:cropToPadding="true"
|
||||
android:src="@drawable/osm_ic_follow_me_on" />
|
||||
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
android:id="@+id/start_stop_trace"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context="fr.chteufleur.mytrackingdog.MainActivity">
|
||||
<item
|
||||
android:id="@+id/action_settings"
|
||||
android:id="@+id/action_import_gpx"
|
||||
android:orderInCategory="100"
|
||||
android:title="@string/action_settings"
|
||||
android:title="@string/action_import_gpx"
|
||||
app:showAsAction="never" />
|
||||
</menu>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
<resources>
|
||||
<string name="app_name">MyTrackingDog</string>
|
||||
<string name="action_settings">Settings</string>
|
||||
<string name="bt_follow_me_description">Follow me</string>
|
||||
<string name="action_import_gpx">Import GPX</string>
|
||||
</resources>
|
||||
|
|
|
|||
Loading…
Reference in New Issue