Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
689ec5e9c0
3 changed files with 262 additions and 8 deletions
|
@ -1182,6 +1182,137 @@ public class GPXUtilities {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static GPXFile loadWptPt(Context ctx, File f) {
|
||||||
|
FileInputStream fis = null;
|
||||||
|
try {
|
||||||
|
fis = new FileInputStream(f);
|
||||||
|
GPXFile file = loadWptPt(ctx, fis);
|
||||||
|
file.path = f.getAbsolutePath();
|
||||||
|
try {
|
||||||
|
fis.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
GPXFile res = new GPXFile();
|
||||||
|
res.path = f.getAbsolutePath();
|
||||||
|
log.error("Error reading gpx", e); //$NON-NLS-1$
|
||||||
|
res.warning = ctx.getString(R.string.error_reading_gpx);
|
||||||
|
return res;
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (fis != null)
|
||||||
|
fis.close();
|
||||||
|
} catch (IOException ignore) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GPXFile loadWptPt(Context ctx, InputStream f) {
|
||||||
|
GPXFile res = new GPXFile();
|
||||||
|
SimpleDateFormat format = new SimpleDateFormat(GPX_TIME_FORMAT, Locale.US);
|
||||||
|
format.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||||
|
try {
|
||||||
|
XmlPullParser parser = PlatformUtil.newXMLPullParser();
|
||||||
|
parser.setInput(getUTF8Reader(f)); //$NON-NLS-1$
|
||||||
|
Stack<GPXExtensions> parserState = new Stack<GPXExtensions>();
|
||||||
|
boolean extensionReadMode = false;
|
||||||
|
parserState.push(res);
|
||||||
|
int tok;
|
||||||
|
while ((tok = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
||||||
|
if (tok == XmlPullParser.START_TAG) {
|
||||||
|
Object parse = parserState.peek();
|
||||||
|
String tag = parser.getName();
|
||||||
|
if (extensionReadMode && parse instanceof GPXExtensions) {
|
||||||
|
String value = readText(parser, tag);
|
||||||
|
if (value != null) {
|
||||||
|
((GPXExtensions) parse).getExtensionsToWrite().put(tag, value);
|
||||||
|
if (tag.equals("speed") && parse instanceof WptPt) {
|
||||||
|
try {
|
||||||
|
((WptPt) parse).speed = Float.parseFloat(value);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (parse instanceof GPXExtensions && tag.equals("extensions")) {
|
||||||
|
extensionReadMode = true;
|
||||||
|
} else {
|
||||||
|
if (parse instanceof GPXFile) {
|
||||||
|
if (parser.getName().equals("wpt")) {
|
||||||
|
WptPt wptPt = parseWptAttributes(parser);
|
||||||
|
((GPXFile) parse).points.add(wptPt);
|
||||||
|
parserState.push(wptPt);
|
||||||
|
}
|
||||||
|
} else if (parse instanceof WptPt) {
|
||||||
|
if (parser.getName().equals("name")) {
|
||||||
|
((WptPt) parse).name = readText(parser, "name");
|
||||||
|
} else if (parser.getName().equals("desc")) {
|
||||||
|
((WptPt) parse).desc = readText(parser, "desc");
|
||||||
|
} else if (parser.getName().equals("link")) {
|
||||||
|
((WptPt) parse).link = parser.getAttributeValue("", "href");
|
||||||
|
} else if (tag.equals("category")) {
|
||||||
|
((WptPt) parse).category = readText(parser, "category");
|
||||||
|
} else if (tag.equals("type")) {
|
||||||
|
if (((WptPt) parse).category == null) {
|
||||||
|
((WptPt) parse).category = readText(parser, "type");
|
||||||
|
}
|
||||||
|
} else if (parser.getName().equals("ele")) {
|
||||||
|
String text = readText(parser, "ele");
|
||||||
|
if (text != null) {
|
||||||
|
try {
|
||||||
|
((WptPt) parse).ele = Float.parseFloat(text);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (parser.getName().equals("hdop")) {
|
||||||
|
String text = readText(parser, "hdop");
|
||||||
|
if (text != null) {
|
||||||
|
try {
|
||||||
|
((WptPt) parse).hdop = Float.parseFloat(text);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (parser.getName().equals("time")) {
|
||||||
|
String text = readText(parser, "time");
|
||||||
|
if (text != null) {
|
||||||
|
try {
|
||||||
|
((WptPt) parse).time = format.parse(text).getTime();
|
||||||
|
} catch (ParseException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (tok == XmlPullParser.END_TAG) {
|
||||||
|
Object parse = parserState.peek();
|
||||||
|
String tag = parser.getName();
|
||||||
|
if (parse instanceof GPXExtensions && tag.equals("extensions")) {
|
||||||
|
extensionReadMode = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tag.equals("wpt")) {
|
||||||
|
Object pop = parserState.pop();
|
||||||
|
assert pop instanceof WptPt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
log.error("Error reading gpx", e); //$NON-NLS-1$
|
||||||
|
res.warning = ctx.getString(R.string.error_reading_gpx) + " " + e.getMessage();
|
||||||
|
} catch (XmlPullParserException e) {
|
||||||
|
log.error("Error reading gpx", e); //$NON-NLS-1$
|
||||||
|
res.warning = ctx.getString(R.string.error_reading_gpx) + " " + e.getMessage();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("Error reading gpx", e); //$NON-NLS-1$
|
||||||
|
res.warning = ctx.getString(R.string.error_reading_gpx) + " " + e.getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
private static Reader getUTF8Reader(InputStream f) throws IOException {
|
private static Reader getUTF8Reader(InputStream f) throws IOException {
|
||||||
BufferedInputStream bis = new BufferedInputStream(f);
|
BufferedInputStream bis = new BufferedInputStream(f);
|
||||||
assert bis.markSupported();
|
assert bis.markSupported();
|
||||||
|
|
|
@ -29,6 +29,7 @@ import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import net.osmand.AndroidUtils;
|
import net.osmand.AndroidUtils;
|
||||||
|
import net.osmand.IndexConstants;
|
||||||
import net.osmand.Location;
|
import net.osmand.Location;
|
||||||
import net.osmand.ResultMatcher;
|
import net.osmand.ResultMatcher;
|
||||||
import net.osmand.binary.BinaryMapIndexReader;
|
import net.osmand.binary.BinaryMapIndexReader;
|
||||||
|
@ -36,6 +37,7 @@ import net.osmand.data.FavouritePoint;
|
||||||
import net.osmand.data.LatLon;
|
import net.osmand.data.LatLon;
|
||||||
import net.osmand.plus.GPXUtilities;
|
import net.osmand.plus.GPXUtilities;
|
||||||
import net.osmand.plus.GPXUtilities.GPXFile;
|
import net.osmand.plus.GPXUtilities.GPXFile;
|
||||||
|
import net.osmand.plus.GPXUtilities.WptPt;
|
||||||
import net.osmand.plus.LockableViewPager;
|
import net.osmand.plus.LockableViewPager;
|
||||||
import net.osmand.plus.OsmAndLocationProvider.OsmAndCompassListener;
|
import net.osmand.plus.OsmAndLocationProvider.OsmAndCompassListener;
|
||||||
import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener;
|
import net.osmand.plus.OsmAndLocationProvider.OsmAndLocationListener;
|
||||||
|
@ -45,6 +47,7 @@ import net.osmand.plus.R;
|
||||||
import net.osmand.plus.activities.MapActivity;
|
import net.osmand.plus.activities.MapActivity;
|
||||||
import net.osmand.plus.helpers.SearchHistoryHelper;
|
import net.osmand.plus.helpers.SearchHistoryHelper;
|
||||||
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
|
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
|
||||||
|
import net.osmand.plus.myplaces.AvailableGPXFragment.GpxInfo;
|
||||||
import net.osmand.plus.resources.RegionAddressRepository;
|
import net.osmand.plus.resources.RegionAddressRepository;
|
||||||
import net.osmand.search.SearchUICore;
|
import net.osmand.search.SearchUICore;
|
||||||
import net.osmand.search.SearchUICore.SearchResultCollection;
|
import net.osmand.search.SearchUICore.SearchResultCollection;
|
||||||
|
@ -62,6 +65,7 @@ import net.osmand.util.MapUtils;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
@ -97,6 +101,8 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
||||||
|
|
||||||
public static final int SEARCH_FAVORITE_API_PRIORITY = 2;
|
public static final int SEARCH_FAVORITE_API_PRIORITY = 2;
|
||||||
public static final int SEARCH_FAVORITE_OBJECT_PRIORITY = 10;
|
public static final int SEARCH_FAVORITE_OBJECT_PRIORITY = 10;
|
||||||
|
public static final int SEARCH_WPT_API_PRIORITY = 2;
|
||||||
|
public static final int SEARCH_WPT_OBJECT_PRIORITY = 10;
|
||||||
public static final int SEARCH_HISTORY_API_PRIORITY = 3;
|
public static final int SEARCH_HISTORY_API_PRIORITY = 3;
|
||||||
public static final int SEARCH_HISTORY_OBJECT_PRIORITY = 10;
|
public static final int SEARCH_HISTORY_OBJECT_PRIORITY = 10;
|
||||||
|
|
||||||
|
@ -299,7 +305,7 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Setup favorites search api
|
// Register favorites search api
|
||||||
searchUICore.registerAPI(new SearchBaseAPI() {
|
searchUICore.registerAPI(new SearchBaseAPI() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -330,6 +336,9 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
||||||
return SEARCH_FAVORITE_API_PRIORITY;
|
return SEARCH_FAVORITE_API_PRIORITY;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Register WptPt search api
|
||||||
|
searchUICore.registerAPI(new SearchWptAPI(app));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -774,7 +783,7 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
||||||
protected GPXFile doInBackground(Void... params) {
|
protected GPXFile doInBackground(Void... params) {
|
||||||
GPXFile gpx = new GPXFile();
|
GPXFile gpx = new GPXFile();
|
||||||
for (HistoryEntry h : historyEntries) {
|
for (HistoryEntry h : historyEntries) {
|
||||||
GPXUtilities.WptPt pt = new GPXUtilities.WptPt();
|
WptPt pt = new WptPt();
|
||||||
pt.lat = h.getLat();
|
pt.lat = h.getLat();
|
||||||
pt.lon = h.getLon();
|
pt.lon = h.getLon();
|
||||||
pt.name = h.getName().getName();
|
pt.name = h.getName().getName();
|
||||||
|
@ -959,4 +968,104 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
||||||
return SEARCH_HISTORY_API_PRIORITY;
|
return SEARCH_HISTORY_API_PRIORITY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class SearchWptAPI extends SearchBaseAPI {
|
||||||
|
|
||||||
|
private OsmandApplication app;
|
||||||
|
private LoadGpxTask asyncLoader = new LoadGpxTask();
|
||||||
|
|
||||||
|
public SearchWptAPI(OsmandApplication app) {
|
||||||
|
this.app = app;
|
||||||
|
asyncLoader.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean search(SearchPhrase phrase, SearchResultMatcher resultMatcher) {
|
||||||
|
if (asyncLoader.getResult() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<GpxInfo> infos = asyncLoader.getResult();
|
||||||
|
for (GpxInfo info : infos) {
|
||||||
|
for (WptPt point : info.gpx.points) {
|
||||||
|
SearchResult sr = new SearchResult(phrase);
|
||||||
|
sr.localeName = point.getPointDescription(app).getName();
|
||||||
|
sr.object = point;
|
||||||
|
sr.priority = SEARCH_WPT_OBJECT_PRIORITY;
|
||||||
|
sr.objectType = ObjectType.WPT;
|
||||||
|
sr.location = new LatLon(point.getLatitude(), point.getLongitude());
|
||||||
|
sr.localeRelatedObjectName = info.getFileName();
|
||||||
|
sr.preferredZoom = 17;
|
||||||
|
if (phrase.getLastWord().length() <= 1 && phrase.isNoSelectedType()) {
|
||||||
|
resultMatcher.publish(sr);
|
||||||
|
} else if (phrase.getNameStringMatcher().matches(sr.localeName)) {
|
||||||
|
resultMatcher.publish(sr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSearchPriority(SearchPhrase p) {
|
||||||
|
if(!p.isNoSelectedType()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return SEARCH_WPT_API_PRIORITY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class LoadGpxTask extends AsyncTask<Void, Void, List<GpxInfo>> {
|
||||||
|
|
||||||
|
private List<GpxInfo> result;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<GpxInfo> doInBackground(Void... params) {
|
||||||
|
List<GpxInfo> result = new ArrayList<>();
|
||||||
|
loadGPXData(app.getAppPath(IndexConstants.GPX_INDEX_DIR), result, this);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(List<GpxInfo> result) {
|
||||||
|
this.result = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private File[] listFilesSorted(File dir) {
|
||||||
|
File[] listFiles = dir.listFiles();
|
||||||
|
if (listFiles == null) {
|
||||||
|
return new File[0];
|
||||||
|
}
|
||||||
|
Arrays.sort(listFiles);
|
||||||
|
return listFiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadGPXData(File mapPath, List<GpxInfo> result, LoadGpxTask loadTask) {
|
||||||
|
if (mapPath.canRead()) {
|
||||||
|
loadGPXFolder(mapPath, result, loadTask, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadGPXFolder(File mapPath, List<GpxInfo> result, LoadGpxTask loadTask,
|
||||||
|
String gpxSubfolder) {
|
||||||
|
for (File gpxFile : listFilesSorted(mapPath)) {
|
||||||
|
if (gpxFile.isDirectory()) {
|
||||||
|
String sub = gpxSubfolder.length() == 0 ? gpxFile.getName() : gpxSubfolder + "/"
|
||||||
|
+ gpxFile.getName();
|
||||||
|
loadGPXFolder(gpxFile, result, loadTask, sub);
|
||||||
|
} else if (gpxFile.isFile() && gpxFile.getName().toLowerCase().endsWith(".gpx")) {
|
||||||
|
GpxInfo info = new GpxInfo();
|
||||||
|
info.subfolder = gpxSubfolder;
|
||||||
|
info.file = gpxFile;
|
||||||
|
info.gpx = GPXUtilities.loadWptPt(app, gpxFile);
|
||||||
|
result.add(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<GpxInfo> getResult() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@ import net.osmand.osm.AbstractPoiType;
|
||||||
import net.osmand.osm.PoiCategory;
|
import net.osmand.osm.PoiCategory;
|
||||||
import net.osmand.osm.PoiFilter;
|
import net.osmand.osm.PoiFilter;
|
||||||
import net.osmand.osm.PoiType;
|
import net.osmand.osm.PoiType;
|
||||||
|
import net.osmand.plus.GPXUtilities;
|
||||||
|
import net.osmand.plus.GPXUtilities.WptPt;
|
||||||
import net.osmand.plus.OsmAndFormatter;
|
import net.osmand.plus.OsmAndFormatter;
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
|
@ -182,9 +184,9 @@ public class QuickSearchListItem {
|
||||||
return typeStr;
|
return typeStr;
|
||||||
case LOCATION:
|
case LOCATION:
|
||||||
LatLon latLon = (LatLon) searchResult.object;
|
LatLon latLon = (LatLon) searchResult.object;
|
||||||
String country = app.getRegions().getCountryName(latLon);
|
String locationCountry = app.getRegions().getCountryName(latLon);
|
||||||
if (!Algorithms.isEmpty(country)) {
|
if (!Algorithms.isEmpty(locationCountry)) {
|
||||||
return country;
|
return locationCountry;
|
||||||
} else {
|
} else {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -205,7 +207,19 @@ public class QuickSearchListItem {
|
||||||
return app.getString(R.string.shared_string_history);
|
return app.getString(R.string.shared_string_history);
|
||||||
}
|
}
|
||||||
case WPT:
|
case WPT:
|
||||||
break;
|
StringBuilder sb = new StringBuilder();
|
||||||
|
WptPt wpt = (WptPt) searchResult.object;
|
||||||
|
String wptCountry = app.getRegions().getCountryName(new LatLon(wpt.getLatitude(), wpt.getLongitude()));
|
||||||
|
if (!Algorithms.isEmpty(wptCountry)) {
|
||||||
|
sb.append(wptCountry);
|
||||||
|
}
|
||||||
|
if (!Algorithms.isEmpty(searchResult.localeRelatedObjectName)) {
|
||||||
|
if (sb.length() > 0) {
|
||||||
|
sb.append(", ");
|
||||||
|
}
|
||||||
|
sb.append(searchResult.localeRelatedObjectName);
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
case UNKNOWN_NAME_FILTER:
|
case UNKNOWN_NAME_FILTER:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -295,8 +309,8 @@ public class QuickSearchListItem {
|
||||||
return app.getIconsCache().getIcon(SearchHistoryFragment.getItemIcon(entry.getName()),
|
return app.getIconsCache().getIcon(SearchHistoryFragment.getItemIcon(entry.getName()),
|
||||||
app.getSettings().isLightContent() ? R.color.osmand_orange : R.color.osmand_orange_dark);
|
app.getSettings().isLightContent() ? R.color.osmand_orange : R.color.osmand_orange_dark);
|
||||||
case WPT:
|
case WPT:
|
||||||
return app.getIconsCache().getIcon(R.drawable.map_action_flag_dark,
|
WptPt wpt = (WptPt) searchResult.object;
|
||||||
app.getSettings().isLightContent() ? R.color.osmand_orange : R.color.osmand_orange_dark);
|
return FavoriteImageDrawable.getOrCreate(app, wpt.getColor(), false);
|
||||||
case UNKNOWN_NAME_FILTER:
|
case UNKNOWN_NAME_FILTER:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue