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;
|
||||
}
|
||||
|
||||
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 {
|
||||
BufferedInputStream bis = new BufferedInputStream(f);
|
||||
assert bis.markSupported();
|
||||
|
|
|
@ -29,6 +29,7 @@ import android.widget.ProgressBar;
|
|||
import android.widget.TextView;
|
||||
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.Location;
|
||||
import net.osmand.ResultMatcher;
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
|
@ -36,6 +37,7 @@ import net.osmand.data.FavouritePoint;
|
|||
import net.osmand.data.LatLon;
|
||||
import net.osmand.plus.GPXUtilities;
|
||||
import net.osmand.plus.GPXUtilities.GPXFile;
|
||||
import net.osmand.plus.GPXUtilities.WptPt;
|
||||
import net.osmand.plus.LockableViewPager;
|
||||
import net.osmand.plus.OsmAndLocationProvider.OsmAndCompassListener;
|
||||
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.helpers.SearchHistoryHelper;
|
||||
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
|
||||
import net.osmand.plus.myplaces.AvailableGPXFragment.GpxInfo;
|
||||
import net.osmand.plus.resources.RegionAddressRepository;
|
||||
import net.osmand.search.SearchUICore;
|
||||
import net.osmand.search.SearchUICore.SearchResultCollection;
|
||||
|
@ -62,6 +65,7 @@ import net.osmand.util.MapUtils;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
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_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_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() {
|
||||
|
||||
@Override
|
||||
|
@ -330,6 +336,9 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
|||
return SEARCH_FAVORITE_API_PRIORITY;
|
||||
}
|
||||
});
|
||||
|
||||
// Register WptPt search api
|
||||
searchUICore.registerAPI(new SearchWptAPI(app));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -774,7 +783,7 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
|||
protected GPXFile doInBackground(Void... params) {
|
||||
GPXFile gpx = new GPXFile();
|
||||
for (HistoryEntry h : historyEntries) {
|
||||
GPXUtilities.WptPt pt = new GPXUtilities.WptPt();
|
||||
WptPt pt = new WptPt();
|
||||
pt.lat = h.getLat();
|
||||
pt.lon = h.getLon();
|
||||
pt.name = h.getName().getName();
|
||||
|
@ -959,4 +968,104 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
|||
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.PoiFilter;
|
||||
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.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
|
@ -182,9 +184,9 @@ public class QuickSearchListItem {
|
|||
return typeStr;
|
||||
case LOCATION:
|
||||
LatLon latLon = (LatLon) searchResult.object;
|
||||
String country = app.getRegions().getCountryName(latLon);
|
||||
if (!Algorithms.isEmpty(country)) {
|
||||
return country;
|
||||
String locationCountry = app.getRegions().getCountryName(latLon);
|
||||
if (!Algorithms.isEmpty(locationCountry)) {
|
||||
return locationCountry;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
@ -205,7 +207,19 @@ public class QuickSearchListItem {
|
|||
return app.getString(R.string.shared_string_history);
|
||||
}
|
||||
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:
|
||||
break;
|
||||
}
|
||||
|
@ -295,8 +309,8 @@ public class QuickSearchListItem {
|
|||
return app.getIconsCache().getIcon(SearchHistoryFragment.getItemIcon(entry.getName()),
|
||||
app.getSettings().isLightContent() ? R.color.osmand_orange : R.color.osmand_orange_dark);
|
||||
case WPT:
|
||||
return app.getIconsCache().getIcon(R.drawable.map_action_flag_dark,
|
||||
app.getSettings().isLightContent() ? R.color.osmand_orange : R.color.osmand_orange_dark);
|
||||
WptPt wpt = (WptPt) searchResult.object;
|
||||
return FavoriteImageDrawable.getOrCreate(app, wpt.getColor(), false);
|
||||
case UNKNOWN_NAME_FILTER:
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue