dialogs refactoring

This commit is contained in:
MadWasp79 2019-12-14 21:56:04 +02:00
parent d464ea2182
commit 7839cb2c32
5 changed files with 192 additions and 78 deletions

View file

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="@dimen/list_content_padding"
android:textSize="@dimen/default_list_text_size"
android:textColor="?attr/textColorAlertDialogListItem"
android:text="Select how many Points you want to process from demo JSON or enter valid URL to custom JSON file with point in geoJSON format" />
<RadioGroup
android:id="@+id/point_quantity_selector"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="@dimen/list_content_padding"
android:paddingRight="@dimen/list_content_padding"
android:paddingBottom="@dimen/list_content_padding"
android:orientation="horizontal"
android:gravity="center">
<RadioButton
android:id="@+id/rb_select10"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/list_content_padding"
android:text="10" />
<RadioButton
android:id="@+id/rb_select100"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/list_content_padding"
android:text="100" />
<RadioButton
android:id="@+id/rb_select500"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/list_content_padding"
android:text="500" />
</RadioGroup>
<EditText
android:id="@+id/json_url_et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/list_content_padding"
android:ems="10"
android:hint="URL to GeoJSON file"
android:text="" />
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
/>
</LinearLayout>

View file

@ -0,0 +1,8 @@
package net.osmand.plus.avoidroads;
import net.osmand.plus.base.BaseOsmAndDialogFragment;
public class AvoidRoadsDialog extends BaseOsmAndDialogFragment {
}

View file

@ -4,9 +4,10 @@ import android.annotation.SuppressLint;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.view.Gravity; import android.view.View;
import android.widget.EditText; import android.widget.EditText;
import android.widget.LinearLayout; import android.widget.RadioButton;
import android.widget.RadioGroup;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.annotations.Expose; import com.google.gson.annotations.Expose;
@ -17,7 +18,6 @@ import net.osmand.Location;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.ResultMatcher; import net.osmand.ResultMatcher;
import net.osmand.binary.RouteDataObject; import net.osmand.binary.RouteDataObject;
import net.osmand.data.PointDescription;
import net.osmand.data.QuadRect; import net.osmand.data.QuadRect;
import net.osmand.data.QuadTree; import net.osmand.data.QuadTree;
import net.osmand.osm.io.NetworkUtils; import net.osmand.osm.io.NetworkUtils;
@ -53,27 +53,31 @@ public class AvoidRoadsHelper {
private static final int FROM_URL = 101; private static final int FROM_URL = 101;
private static final int FROM_STORAGE = 100; private static final int FROM_STORAGE = 100;
private static final int SOURCE = FROM_STORAGE; private static final int SOURCE = FROM_STORAGE;
private static boolean saveResultToFile = true;
private final Map<RouteDataObject, Location> roadsToAvoid; private final Map<RouteDataObject, Location> roadsToAvoid;
private final List<Location> parsedPoints; private final List<Location> parsedPoints;
private final OsmandApplication app; private final OsmandApplication app;
private final ApplicationMode appMode; private final ApplicationMode appMode;
private final CompletionCallback completionCallback; private CompletionCallback completionCallback;
private ParsingProgressCallback ppc;
private ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); private ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
private WeakReference<MapActivity> mapActivityWeakReference = null; private WeakReference<MapActivity> mapActivityWeakReference = null;
// String inputFileName = "points_500.json"; private static boolean saveResultToFile = false;
// String inputFileName = "point_100.json";
String inputFileName = "points_10.json"; private long timeStart;
String testurl = "https://gist.githubusercontent.com/MadWasp79/1238d8878792572e343eb2e296c3c7f5/raw/494f872425993797c3a3bc79a4ec82039db6ee46/point_100.json"; private long timeDownload;
// String testurl = "https://gist.githubusercontent.com/MadWasp79/45f362ea48e9e8edd1593113593993c5/raw/6e817fb3bc7eaeaa3eda24847fde4855eb22485d/points_500.json"; private long timeParsePoints;
private long timeFindSegments;
private final int[] pointsToProcess = {-1};
// private String inputFileName = "points_500.json";
// private String inputFileName = "point_100.json";
private String inputFileName = "points_10.json";
// private String testurl = "https://gist.githubusercontent.com/MadWasp79/1238d8878792572e343eb2e296c3c7f5/raw/494f872425993797c3a3bc79a4ec82039db6ee46/point_100.json";
private String testurl = "https://gist.githubusercontent.com/MadWasp79/45f362ea48e9e8edd1593113593993c5/raw/6e817fb3bc7eaeaa3eda24847fde4855eb22485d/points_500.json";
public AvoidRoadsHelper(final OsmandApplication app) { public AvoidRoadsHelper(final OsmandApplication app) {
@ -85,13 +89,12 @@ public class AvoidRoadsHelper {
completionCallback = new CompletionCallback() { completionCallback = new CompletionCallback() {
@Override @Override
public void onRDOSearchComplete() { public void onRDOSearchComplete() {
timeFindSegments = System.currentTimeMillis();
if (saveResultToFile) { if (saveResultToFile) {
File out = new File (app.getAppPath(IndexConstants.AVOID_ROADS_DIR).getAbsolutePath() + "/" File out = new File (app.getAppPath(IndexConstants.AVOID_ROADS_DIR).getAbsolutePath() + "/"
+ "processed_ids.json"); + "processed_ids.json");
saveRoadsToJson(roadsToAvoid, out); saveRoadsToJson(roadsToAvoid, out);
} }
app.getAvoidRoadsHelper().addResultToImpassibleRoads(roadsToAvoid); app.getAvoidRoadsHelper().addResultToImpassibleRoads(roadsToAvoid);
MapActivity mapActivity = mapActivityWeakReference.get(); MapActivity mapActivity = mapActivityWeakReference.get();
@ -120,46 +123,71 @@ public class AvoidRoadsHelper {
app.getRoutingConfig().addMultipleImpassableRoads(result); app.getRoutingConfig().addMultipleImpassableRoads(result);
} }
public void progressDialog(final MapActivity activity) {
AlertDialog.Builder adb = new AlertDialog.Builder(activity);
adb.setMessage("Searching Roads to Avoid...");
ppc = new ParsingProgressCallback() {
@Override
public void onParsingProgress(int percent) {
}
};
}
public void showUrlDialog(final MapActivity activity) { public void showUrlDialog(final MapActivity activity) {
mapActivityWeakReference = new WeakReference<MapActivity>(activity); mapActivityWeakReference = new WeakReference<MapActivity>(activity);
pointsToProcess[0] = -1;
final AlertDialog.Builder db = new AlertDialog.Builder(activity); final AlertDialog.Builder db = new AlertDialog.Builder(activity);
db.setTitle("Process Avoid Points"); final View dialogView = activity.getLayoutInflater().inflate(R.layout.load_avoid_roads_dialog, null);
db.setMessage("Enter url to JSON file. \"Parse\" to continue:"); final RadioGroup rg = (RadioGroup) dialogView.findViewById(R.id.point_quantity_selector);
final EditText urlInputString = new EditText(activity); final EditText urlEt = (EditText) dialogView.findViewById(R.id.json_url_et);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( db.setTitle("Process Avoid Roads");
LinearLayout.LayoutParams.MATCH_PARENT, db.setView(dialogView);
LinearLayout.LayoutParams.MATCH_PARENT);
urlInputString.setLayoutParams(lp);
urlInputString.setText(testurl);
// urlInputString.selectAll();
db.setView(urlInputString);
db.setIcon(R.drawable.map_pin_avoid_road); db.setIcon(R.drawable.map_pin_avoid_road);
db.setPositiveButton("Parse", new DialogInterface.OnClickListener() { db.setPositiveButton("Parse", new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
String url = urlInputString.getText().toString();
boolean isValidJsonUrl = false; boolean isValidJsonUrl = false;
int selectedId = rg.getCheckedRadioButtonId();
RadioButton rb = (RadioButton) dialogView.findViewById(selectedId);
if (rb != null) {
switch (rb.getText().toString()) {
case "10":
pointsToProcess[0] = 10;
break;
case "100":
pointsToProcess[0] = 100;
break;
case "500":
pointsToProcess[0] = 500;
}
}
String urlFromEt = urlEt.getText().toString();
if (Algorithms.isEmpty(urlFromEt)) {
urlFromEt = testurl;
}
try { try {
URL test = new URL(url); URL test = new URL(urlFromEt);
if (url.endsWith(".json")) { if (urlFromEt.endsWith(".json")) {
isValidJsonUrl = true; isValidJsonUrl = true;
} }
} catch (MalformedURLException e){ } catch (MalformedURLException e){
isValidJsonUrl = false; isValidJsonUrl = false;
app.showShortToastMessage("Enter valid JSON url"); app.showShortToastMessage("Enter valid JSON url!");
} }
if (isValidJsonUrl) { if (isValidJsonUrl) {
timeStart = System.currentTimeMillis();
app.showShortToastMessage("Downloading JSON"); app.showShortToastMessage("Downloading JSON");
app.getAvoidRoadsHelper().loadJson(url, FROM_URL); loadJson(urlFromEt, FROM_URL);
// dialog.dismiss();
} }
} }
}); });
db.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { db.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
pointsToProcess[0] = -1;
dialog.dismiss(); dialog.dismiss();
} }
}); });
@ -168,8 +196,15 @@ public class AvoidRoadsHelper {
public void showParsingCompleteDialog(final MapActivity activity) { public void showParsingCompleteDialog(final MapActivity activity) {
final AlertDialog.Builder db = new AlertDialog.Builder(activity); final AlertDialog.Builder db = new AlertDialog.Builder(activity);
db.setTitle("Avoid Points"); db.setTitle("Processing complete!");
db.setMessage("Parsing complete, applying result to routing config!"); db.setMessage(String.format("Found %d unique roads to avoid.\n" +
"Time to download: %.3fs\n" +
"Time to parse JSON: %.3fs\n" +
"Time to find roads: %.3fs\n",
roadsToAvoid.size(),
(timeDownload-timeStart)/1000.0f,
(timeParsePoints-timeDownload)/1000.0f,
(timeFindSegments-timeParsePoints)/1000.0f));
db.setIcon(R.drawable.map_pin_avoid_road); db.setIcon(R.drawable.map_pin_avoid_road);
db.setPositiveButton("OK", new DialogInterface.OnClickListener() { db.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override @Override
@ -237,13 +272,14 @@ public class AvoidRoadsHelper {
} }
List<Location> result = new ArrayList<>(); List<Location> result = new ArrayList<>();
timeDownload = System.currentTimeMillis();
parseJson(is, result); parseJson(is, result);
if (is != null) { if (is != null) {
is.close(); is.close();
} }
return result; return result;
} catch (Exception e) { } catch (Exception e) {
LOG.error("Error reading json !"); LOG.error("Error reading json!");
} finally { } finally {
if (is != null) { if (is != null) {
try { try {
@ -265,6 +301,45 @@ public class AvoidRoadsHelper {
}.executeOnExecutor(singleThreadExecutor); }.executeOnExecutor(singleThreadExecutor);
} }
private void parseJson(InputStream is, List<Location> result) {
Gson gson = new Gson();
GeoJSON geoJSON = gson.fromJson(new BufferedReader(new InputStreamReader(is)), GeoJSON.class);
double minlat = 0 , maxlat = 0, minlon = 0, maxlon= 0;
boolean first = true;
int limit = pointsToProcess[0];
if (limit == -1 || limit > geoJSON.points.size()) {
limit = geoJSON.points.size();
}
for (int i = 0; i < limit; i++) {
Point o = geoJSON.points.get(i);
Location ll = new Location("geoJSON");
double lat = o.geo.coordinates.get(1);
double lon = o.geo.coordinates.get(0);
if(first) {
minlat = maxlat = lat;
minlon = maxlon = lon;
first = false;
} else {
minlat = Math.min(minlat, lat);
minlon = Math.min(minlon, lon);
maxlat = Math.max(maxlat, lat);
maxlon = Math.max(maxlon, lon);
}
ll.setLatitude(lat);
ll.setLongitude(lon);
result.add(ll);
}
QuadRect qr = new QuadRect(minlon, minlat, maxlon, maxlat);
QuadTree<Location> qt = new QuadTree<Location>(qr, 8, 0.55f);
for(Location l : result) {
qt.insert(l, (float)l.getLongitude(), (float) l.getLatitude());
}
qt.queryInBox(qr, result);
timeParsePoints = System.currentTimeMillis();
app.showShortToastMessage(String.format("Loaded and parsed %d points from JSON. Starting segment search.", result.size()));
LOG.debug(String.format("Points parsed: %d", result.size()));
}
@SuppressLint("StaticFieldLeak") @SuppressLint("StaticFieldLeak")
private void saveRoadsToJson(final Map<RouteDataObject, Location> roadsToAvoid, final File out) { private void saveRoadsToJson(final Map<RouteDataObject, Location> roadsToAvoid, final File out) {
new AsyncTask<Void, Void, Void>() { new AsyncTask<Void, Void, Void>() {
@ -296,46 +371,15 @@ public class AvoidRoadsHelper {
}.executeOnExecutor(singleThreadExecutor); }.executeOnExecutor(singleThreadExecutor);
} }
private void parseJson(InputStream is, List<Location> result) {
Gson gson = new Gson();
GeoJSON geoJSON = gson.fromJson(new BufferedReader(new InputStreamReader(is)), GeoJSON.class);
double minlat = 0 , maxlat = 0, minlon = 0, maxlon= 0;
boolean first = true;
for (Point o : geoJSON.points) {
Location ll = new Location("geoJSON");
double lat = o.geo.coordinates.get(1);
double lon = o.geo.coordinates.get(0);
if(first) {
minlat = maxlat = lat;
minlon = maxlon = lon;
first = false;
} else {
minlat = Math.min(minlat, lat);
minlon = Math.min(minlon, lon);
maxlat = Math.max(maxlat, lat);
maxlon = Math.max(maxlon, lon);
}
ll.setLatitude(lat);
ll.setLongitude(lon);
result.add(ll);
}
QuadRect qr = new QuadRect(minlon, minlat, maxlon, maxlat);
QuadTree<Location> qt = new QuadTree<Location>(qr, 8, 0.55f);
for(Location l : result) {
qt.insert(l, (float)l.getLongitude(), (float) l.getLatitude());
}
qt.queryInBox(qr, result);
// app.showShortToastMessage(String.format("Loaded and parsed %d avoid points from JSON. Starting segment search.", result.size()));
LOG.debug(String.format("Points parsed: %d", result.size()));
}
interface CompletionCallback { interface CompletionCallback {
void onRDOSearchComplete(); void onRDOSearchComplete();
void onPointsParsed(List<Location> result); void onPointsParsed(List<Location> result);
} }
interface ParsingProgressCallback {
void onParsingProgress(int percent);
}
class GeoJSON { class GeoJSON {
@SerializedName("type") @SerializedName("type")
@Expose @Expose

View file

@ -1,6 +0,0 @@
package net.osmand.plus.avoidroads;
public class PointListJsonReader {
}

View file

@ -83,6 +83,9 @@ public class ImpassableRoadsLayer extends OsmandMapLayer implements
drawPoint(canvas, tileBox, latitude, longitude, road != null); drawPoint(canvas, tileBox, latitude, longitude, road != null);
} }
} }
}
if (tileBox.getZoom() > START_ZOOM + 1) {
for (Map.Entry<RouteDataObject, Location> entry : avoidRoadsHelper.getRoadsToAvoid().entrySet()) { for (Map.Entry<RouteDataObject, Location> entry : avoidRoadsHelper.getRoadsToAvoid().entrySet()) {
RouteDataObject rdo = entry.getKey(); RouteDataObject rdo = entry.getKey();
if (rdo != null && contextMenuLayer.getMoveableObject() instanceof RouteDataObject) { if (rdo != null && contextMenuLayer.getMoveableObject() instanceof RouteDataObject) {