Update distance plugin (add save/open gpx)
This commit is contained in:
parent
eba592a42f
commit
f933f0fd62
4 changed files with 449 additions and 49 deletions
|
@ -27,7 +27,7 @@
|
|||
|
||||
<!-- Map colors -->
|
||||
<!-- LAYER and SPECIAL PURPOSE consistency colors -->
|
||||
|
||||
<color name="distance_color">#dd6CB336</color>
|
||||
<color name="gpx_track">#B4B319FF</color>
|
||||
<color name="gpx_track_fluorescent">#B400FFFF</color>
|
||||
<!-- magenta is alternate track color for cyan but less contrast in many situations: color name="gpx_track_fluorescent">#B4FF00FF</color -->
|
||||
|
|
|
@ -7,4 +7,10 @@
|
|||
<string name="ga_dispatchPeriod">10</string>
|
||||
<string name="ga_debug">true</string>
|
||||
<string name="versionFeatures">+play_market +gps_status -parking_plugin -blackberry -free_version -amazon</string>
|
||||
<string name="next_tips_and_tricks_not_translate">
|
||||
* New downlad screen
|
||||
* Planning mode
|
||||
* Delete SRTM files
|
||||
* GPX subfolders structure
|
||||
</string>
|
||||
</resources>
|
||||
|
|
|
@ -9,6 +9,26 @@
|
|||
3. All your modified/created strings are in the top of the file (to make easier find what\'s translated).
|
||||
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
|
||||
-->
|
||||
<string name="plugin_distance_point_time">time</string>
|
||||
<string name="plugin_distance_point_hdop">precision</string>
|
||||
<string name="plugin_distance_point_speed">speed</string>
|
||||
<string name="plugin_distance_point_ele">elevation</string>
|
||||
<string name="plugin_distance_point">Point</string>
|
||||
<string name="gpx_file_name">GPX file name</string>
|
||||
<string name="gpx_saved_sucessfully">GPX file succesfully saved to {0}</string>
|
||||
<string name="osmand_distance_planning_plugin_description">Create a path to measure the distance between points, open existing GPX file to edit and save it. Could be used to plan a route by GPX. </string>
|
||||
<string name="osmand_distance_planning_plugin_name">Distance calculator & Planning Tool</string>
|
||||
<string name="use_distance_measurement_help">* Tap to mark a point.\n
|
||||
* Press and hold on the map to delete previous point.\n
|
||||
* Press and hold on point to view and attach description.\n
|
||||
* Click on measurement widget to see more actions.</string>
|
||||
<string name="default_buttons_do_not_show_again">Do not show again</string>
|
||||
<string name="distance_measurement_start_editing">Start editing</string>
|
||||
<string name="distance_measurement_finish_editing">Finish editing</string>
|
||||
<string name="distance_measurement_finish_subtrack">Next subtrack/point</string>
|
||||
<string name="distance_measurement_clear_route">Clear points</string>
|
||||
<string name="distance_measurement_save_gpx">Save As GPX</string>
|
||||
<string name="distance_measurement_load_gpx">Open existing GPX</string>
|
||||
<string name="wait_current_task_finished">Please wait until current task is finished</string>
|
||||
<string name="use_kalman_filter_compass_descr">Use Kalman filter to avoid compass aberrations</string>
|
||||
<string name="use_kalman_filter_compass">Use Kalman filter</string>
|
||||
|
@ -141,10 +161,6 @@
|
|||
<string name="map_widget_av_notes">Audio/video notes</string>
|
||||
<string name="osmand_srtm_short_description_80_chars">OsmAnd plugin for offline contour lines</string>
|
||||
<string name="osmand_srtm_long_description_1000_chars">This plugin provides contour lines which can be displayed in OsmAnd\'s offline maps. The global data (between 70 degrees north and 70 degrees south) is based on measurements by SRTM (Shuttle Radar Topography Mission) and ASTER (Advanced Spaceborne Thermal Emission and Reflection Radiometer), an imaging instrument onboard Terra, the flagship satellite of NASA\'s Earth Observing System. ASTER is a cooperative effort between NASA, Japan\'s Ministry of Economy, Trade and Industry (METI), and Japan Space Systems (J-spacesystems).</string>
|
||||
<string name="osmand_distance_plugin_description">Measure the distance between two or more points. Add points by a short click and remove by a long press.</string>
|
||||
<string name="osmand_distance_plugin_name">Distance calculator</string>
|
||||
<string name="use_clear_distance_measurement">Click one more time to clear measurement points.</string>
|
||||
<string name="use_distance_measurement">Tap to mark a point, press and hold to delete previous points, click on measurement widget to exit.</string>
|
||||
<string name="map_widget_distancemeasurement">Distance measurement</string>
|
||||
<string name="audionotes_location_not_defined">Location to associate with the note is not defined yet. \"Use location...\" to assign a note to the specified location</string>
|
||||
<string name="monitoring_control_stop">stop</string>
|
||||
|
|
|
@ -1,25 +1,49 @@
|
|||
package net.osmand.plus.distancecalculator;
|
||||
|
||||
import gnu.trove.list.array.TIntArrayList;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import net.osmand.CallbackWithObject;
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.access.AccessibleToast;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.plus.ApplicationMode;
|
||||
import net.osmand.plus.GPXUtilities;
|
||||
import net.osmand.plus.GPXUtilities.GPXFile;
|
||||
import net.osmand.plus.GPXUtilities.Route;
|
||||
import net.osmand.plus.GPXUtilities.Track;
|
||||
import net.osmand.plus.GPXUtilities.TrkSegment;
|
||||
import net.osmand.plus.GPXUtilities.WptPt;
|
||||
import net.osmand.plus.OsmAndFormatter;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandPlugin;
|
||||
import net.osmand.plus.OsmandSettings.CommonPreference;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.activities.MapActivity;
|
||||
import net.osmand.plus.views.ContextMenuLayer;
|
||||
import net.osmand.plus.views.MapInfoLayer;
|
||||
import net.osmand.plus.views.OsmandMapLayer;
|
||||
import net.osmand.plus.views.OsmandMapTileView;
|
||||
import net.osmand.plus.views.mapwidgets.TextInfoWidget;
|
||||
import net.osmand.util.MapUtils;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.AlertDialog.Builder;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Paint.Cap;
|
||||
import android.graphics.Paint.Join;
|
||||
|
@ -27,7 +51,15 @@ import android.graphics.Paint.Style;
|
|||
import android.graphics.Path;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.RectF;
|
||||
import android.os.AsyncTask;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class DistanceCalculatorPlugin extends OsmandPlugin {
|
||||
|
@ -35,7 +67,11 @@ public class DistanceCalculatorPlugin extends OsmandPlugin {
|
|||
private OsmandApplication app;
|
||||
private DistanceCalculatorLayer distanceCalculatorLayer;
|
||||
private TextInfoWidget distanceControl;
|
||||
private List<LatLon> measurementPoints = new ArrayList<LatLon>();
|
||||
|
||||
private List<LinkedList<WptPt>> measurementPoints = new ArrayList<LinkedList<WptPt>>();
|
||||
private GPXFile originalGPX;
|
||||
private String distance = null;
|
||||
private DisplayMetrics dm;
|
||||
|
||||
private int distanceMeasurementMode = 0;
|
||||
|
||||
|
@ -50,12 +86,12 @@ public class DistanceCalculatorPlugin extends OsmandPlugin {
|
|||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return app.getString(R.string.osmand_distance_plugin_description);
|
||||
return app.getString(R.string.osmand_distance_planning_plugin_description);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return app.getString(R.string.osmand_distance_plugin_name);
|
||||
return app.getString(R.string.osmand_distance_planning_plugin_name);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -90,14 +126,10 @@ public class DistanceCalculatorPlugin extends OsmandPlugin {
|
|||
|
||||
private void updateText() {
|
||||
if (distanceControl != null) {
|
||||
if (distanceMeasurementMode == 0) {
|
||||
String ds = distance;
|
||||
if (distance == null) {
|
||||
distanceControl.setText(app.getString(R.string.dist_control_start), "");
|
||||
} else {
|
||||
float dist = 0;
|
||||
for (int j = 1; j < measurementPoints.size(); j++) {
|
||||
dist += MapUtils.getDistance(measurementPoints.get(j - 1), measurementPoints.get(j));
|
||||
}
|
||||
String ds = OsmAndFormatter.getFormattedDistance(dist, app);
|
||||
int ls = ds.lastIndexOf(' ');
|
||||
if (ls == -1) {
|
||||
distanceControl.setText(ds, null);
|
||||
|
@ -107,33 +139,258 @@ public class DistanceCalculatorPlugin extends OsmandPlugin {
|
|||
}
|
||||
}
|
||||
}
|
||||
private void showDialog(final MapActivity activity) {
|
||||
Builder bld = new AlertDialog.Builder(activity);
|
||||
final TIntArrayList list = new TIntArrayList();
|
||||
if(distanceMeasurementMode == 0) {
|
||||
list.add(R.string.distance_measurement_start_editing);
|
||||
} else {
|
||||
list.add(R.string.distance_measurement_finish_editing);
|
||||
}
|
||||
if(measurementPoints.size() > 0) {
|
||||
list.add(R.string.distance_measurement_finish_subtrack);
|
||||
list.add(R.string.distance_measurement_clear_route);
|
||||
list.add(R.string.distance_measurement_save_gpx);
|
||||
}
|
||||
list.add(R.string.distance_measurement_load_gpx);
|
||||
String[] items = new String[list.size()];
|
||||
for(int i = 0; i < items.length; i++) {
|
||||
items[i] = activity.getString(list.get(i));
|
||||
}
|
||||
bld.setItems(items, new DialogInterface.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
int id = list.get(which);
|
||||
switch (id) {
|
||||
case R.string.distance_measurement_start_editing :
|
||||
distanceMeasurementMode = 1; startEditingHelp(activity) ; break;
|
||||
case R.string.distance_measurement_finish_editing :
|
||||
distanceMeasurementMode = 0; break;
|
||||
case R.string.distance_measurement_finish_subtrack :
|
||||
measurementPoints.add(new LinkedList<GPXUtilities.WptPt>()); break;
|
||||
case R.string.distance_measurement_clear_route :
|
||||
measurementPoints.clear(); calculateDistance(); break;
|
||||
case R.string.distance_measurement_save_gpx :
|
||||
saveGpx(activity); break;
|
||||
case R.string.distance_measurement_load_gpx :
|
||||
loadGpx(activity); break;
|
||||
}
|
||||
activity.getMapView().refreshMap();
|
||||
updateText();
|
||||
}
|
||||
});
|
||||
bld.show();
|
||||
}
|
||||
|
||||
|
||||
protected void loadGpx(final MapActivity activity) {
|
||||
activity.getMapLayers().selectGPXFileLayer(true, false, false, new CallbackWithObject<GPXUtilities.GPXFile>() {
|
||||
|
||||
@Override
|
||||
public boolean processResult(GPXFile result) {
|
||||
measurementPoints.clear();
|
||||
if (result != null) {
|
||||
originalGPX = result;
|
||||
for (Track t : result.tracks) {
|
||||
for (TrkSegment s : t.segments) {
|
||||
if (s.points.size() > 0) {
|
||||
LinkedList<WptPt> l = new LinkedList<WptPt>(s.points);
|
||||
measurementPoints.add(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Route r : result.routes) {
|
||||
LinkedList<WptPt> l = new LinkedList<WptPt>(r.points);
|
||||
measurementPoints.add(l);
|
||||
}
|
||||
for (WptPt p : result.points) {
|
||||
LinkedList<WptPt> l = new LinkedList<WptPt>();
|
||||
l.add(p);
|
||||
measurementPoints.add(l);
|
||||
}
|
||||
WptPt pt = result.findPointToShow();
|
||||
OsmandMapTileView mapView = activity.getMapView();
|
||||
if(pt != null){
|
||||
mapView.getAnimatedDraggingThread().startMoving(pt.lat, pt.lon,
|
||||
mapView.getFloatZoom(), true);
|
||||
}
|
||||
}
|
||||
calculateDistance();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void saveGpx(final MapActivity activity) {
|
||||
Builder b = new AlertDialog.Builder(activity);
|
||||
final File dir = app.getAppPath(IndexConstants.GPX_INDEX_DIR);
|
||||
LinearLayout ll = new LinearLayout(activity);
|
||||
ll.setOrientation(LinearLayout.VERTICAL);
|
||||
ll.setPadding(5, 5, 5, 5);
|
||||
final TextView tv = new TextView(activity);
|
||||
tv.setText("");
|
||||
tv.setTextColor(Color.RED);
|
||||
ll.addView(tv);
|
||||
final EditText editText = new EditText(activity);
|
||||
editText.setHint(R.string.gpx_file_name);
|
||||
editText.addTextChangedListener(new TextWatcher() {
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
boolean e = false;
|
||||
try {
|
||||
e = new File(dir, s.toString()).exists() || new File(dir, s.toString() +".gpx").exists();
|
||||
} catch (Exception e1) {
|
||||
}
|
||||
if (e) {
|
||||
tv.setText(R.string.file_with_name_already_exists);
|
||||
} else {
|
||||
tv.setText("");
|
||||
}
|
||||
}
|
||||
});
|
||||
ll.addView(editText);
|
||||
b.setView(ll);
|
||||
b.setPositiveButton(R.string.default_buttons_save, new DialogInterface.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
String newName = editText.getText().toString();
|
||||
if(!newName.endsWith(".gpx")){
|
||||
newName += ".gpx";
|
||||
}
|
||||
saveGpx(activity, newName);
|
||||
}
|
||||
});
|
||||
b.setNegativeButton(R.string.default_buttons_cancel, null);
|
||||
b.show();
|
||||
}
|
||||
|
||||
private void saveGpx(final MapActivity activity, final String fileNameSave) {
|
||||
final AsyncTask<Void, Void, String> exportTask = new AsyncTask<Void, Void, String>() {
|
||||
private ProgressDialog dlg;
|
||||
private File toSave;
|
||||
|
||||
@Override
|
||||
protected String doInBackground(Void... params) {
|
||||
toSave = new File(app.getAppPath(IndexConstants.GPX_INDEX_DIR), fileNameSave);
|
||||
GPXFile gpx;
|
||||
boolean saveTrackToRte = false;
|
||||
if(originalGPX != null) {
|
||||
gpx = originalGPX;
|
||||
saveTrackToRte = originalGPX.routes.size() > 0 && originalGPX.tracks.size() == 0;
|
||||
gpx.tracks.clear();
|
||||
gpx.routes.clear();
|
||||
gpx.points.clear();
|
||||
} else {
|
||||
gpx = new GPXFile();
|
||||
}
|
||||
for(int i = 0; i<measurementPoints.size(); i++) {
|
||||
LinkedList<WptPt> lt = measurementPoints.get(i);
|
||||
if(lt.size() == 1) {
|
||||
gpx.points.add(lt.getFirst());
|
||||
} else if(lt.size() > 1) {
|
||||
if(saveTrackToRte) {
|
||||
Route rt = new Route();
|
||||
gpx.routes.add(rt);
|
||||
rt.points.addAll(lt);
|
||||
} else {
|
||||
if(gpx.tracks.size() == 0) {
|
||||
gpx.tracks.add(new Track());
|
||||
}
|
||||
Track ts = gpx.tracks.get(gpx.tracks.size() - 1);
|
||||
TrkSegment sg = new TrkSegment();
|
||||
ts.segments.add(sg);
|
||||
sg.points.addAll(lt);
|
||||
}
|
||||
}
|
||||
}
|
||||
return GPXUtilities.writeGpxFile(toSave, gpx, app);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
dlg = new ProgressDialog(activity);
|
||||
dlg.setMessage(app.getString(R.string.saving_gpx_tracks));
|
||||
dlg.show();
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String warning) {
|
||||
if (warning == null) {
|
||||
AccessibleToast.makeText(activity,
|
||||
MessageFormat.format(app.getString(R.string.gpx_saved_sucessfully), toSave.getAbsolutePath()),
|
||||
Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
AccessibleToast.makeText(activity, warning, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
if(dlg != null && dlg.isShowing()) {
|
||||
dlg.dismiss();
|
||||
}
|
||||
};
|
||||
};
|
||||
exportTask.execute(new Void[0]);
|
||||
|
||||
|
||||
}
|
||||
private void startEditingHelp(MapActivity ctx) {
|
||||
final CommonPreference<Boolean> pref = app.getSettings().registerBooleanPreference("show_measurement_help_first_time", true);
|
||||
pref.makeGlobal();
|
||||
if(pref.get()) {
|
||||
Builder builder = new AlertDialog.Builder(ctx);
|
||||
builder.setMessage(R.string.use_distance_measurement_help);
|
||||
builder.setNegativeButton(R.string.default_buttons_do_not_show_again, new OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
pref.set(false);
|
||||
}
|
||||
});
|
||||
builder.setPositiveButton(R.string.default_buttons_ok, null);
|
||||
|
||||
builder.show();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private TextInfoWidget createDistanceControl(final MapActivity activity, Paint paintText, Paint paintSubText) {
|
||||
final TextInfoWidget distanceControl = new TextInfoWidget(activity, 0, paintText, paintSubText);
|
||||
distanceControl.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if(distanceMeasurementMode == 0) {
|
||||
AccessibleToast.makeText(app, app.getString(R.string.use_distance_measurement), Toast.LENGTH_LONG).show();
|
||||
distanceMeasurementMode++;
|
||||
} else if(distanceMeasurementMode == 1){
|
||||
AccessibleToast.makeText(app, app.getString(R.string.use_clear_distance_measurement), Toast.LENGTH_LONG).show();
|
||||
distanceMeasurementMode++;
|
||||
} else {
|
||||
measurementPoints.clear();
|
||||
distanceMeasurementMode = 0;
|
||||
}
|
||||
activity.getMapView().refreshMap();
|
||||
updateText();
|
||||
showDialog(activity);
|
||||
}
|
||||
});
|
||||
distanceControl.setImageDrawable(app.getResources().getDrawable(R.drawable.widget_distance));
|
||||
return distanceControl;
|
||||
}
|
||||
|
||||
private void calculateDistance() {
|
||||
float dist = 0;
|
||||
if (measurementPoints.size() == 0) {
|
||||
distance = null;
|
||||
} else {
|
||||
for (int j = 0; j < measurementPoints.size(); j++) {
|
||||
List<WptPt> ls = measurementPoints.get(j);
|
||||
for (int i = 1; i < ls.size(); i++) {
|
||||
dist += MapUtils.getDistance(ls.get(i - 1).lat, ls.get(i - 1).lon, ls.get(i).lat, ls.get(i).lon);
|
||||
}
|
||||
}
|
||||
distance = OsmAndFormatter.getFormattedDistance(dist, app);
|
||||
}
|
||||
}
|
||||
|
||||
public class DistanceCalculatorLayer extends OsmandMapLayer {
|
||||
|
||||
public class DistanceCalculatorLayer extends OsmandMapLayer implements ContextMenuLayer.IContextMenuProvider {
|
||||
private OsmandMapTileView view;
|
||||
|
||||
private Bitmap originIcon;
|
||||
|
@ -143,6 +400,7 @@ public class DistanceCalculatorPlugin extends OsmandPlugin {
|
|||
private Path path;
|
||||
|
||||
private Paint paint;
|
||||
private Paint paint2;
|
||||
|
||||
public DistanceCalculatorLayer() {
|
||||
}
|
||||
|
@ -150,6 +408,9 @@ public class DistanceCalculatorPlugin extends OsmandPlugin {
|
|||
@Override
|
||||
public void initLayer(OsmandMapTileView view) {
|
||||
this.view = view;
|
||||
dm = new DisplayMetrics();
|
||||
WindowManager wmgr = (WindowManager) view.getContext().getSystemService(Context.WINDOW_SERVICE);
|
||||
wmgr.getDefaultDisplay().getMetrics(dm);
|
||||
originIcon = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_pin_origin);
|
||||
destinationIcon = BitmapFactory.decodeResource(view.getResources(), R.drawable.map_pin_destination);
|
||||
bitmapPaint = new Paint();
|
||||
|
@ -158,20 +419,33 @@ public class DistanceCalculatorPlugin extends OsmandPlugin {
|
|||
bitmapPaint.setFilterBitmap(true);
|
||||
path = new Path();
|
||||
|
||||
int distanceColor = view.getResources().getColor(R.color.distance_color);
|
||||
paint = new Paint();
|
||||
paint.setStyle(Style.STROKE);
|
||||
paint.setStrokeWidth(10);
|
||||
paint.setStrokeWidth(7 * dm.density);
|
||||
paint.setAntiAlias(true);
|
||||
paint.setStrokeCap(Cap.ROUND);
|
||||
paint.setStrokeJoin(Join.ROUND);
|
||||
paint.setColor(0xdd6CB336);
|
||||
paint.setColor(distanceColor);
|
||||
|
||||
paint2 = new Paint();
|
||||
paint2.setStyle(Style.FILL_AND_STROKE);
|
||||
paint2.setAntiAlias(true);
|
||||
paint2.setColor(distanceColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSingleTap(PointF point) {
|
||||
if(distanceMeasurementMode == 1) {
|
||||
LatLon l = view.getLatLonFromScreenPoint(point.x, point.y);
|
||||
measurementPoints.add(l);
|
||||
if(measurementPoints.size() == 0) {
|
||||
measurementPoints.add(new LinkedList<GPXUtilities.WptPt>());
|
||||
}
|
||||
WptPt pt = new WptPt();
|
||||
pt.lat = l.getLatitude();
|
||||
pt.lon = l.getLongitude();
|
||||
measurementPoints.get(measurementPoints.size() - 1).add(pt);
|
||||
calculateDistance();
|
||||
view.refreshMap();
|
||||
updateText();
|
||||
return true;
|
||||
|
@ -181,8 +455,12 @@ public class DistanceCalculatorPlugin extends OsmandPlugin {
|
|||
|
||||
@Override
|
||||
public boolean onLongPressEvent(PointF point) {
|
||||
if(distanceMeasurementMode == 1 && measurementPoints.size() > 0) {
|
||||
measurementPoints.remove(measurementPoints.size() - 1);
|
||||
if (distanceMeasurementMode == 1 && measurementPoints.size() > 0) {
|
||||
LinkedList<WptPt> lt = measurementPoints.get(measurementPoints.size() - 1);
|
||||
if (lt.size() > 0) {
|
||||
lt.removeLast();
|
||||
}
|
||||
calculateDistance();
|
||||
view.refreshMap();
|
||||
updateText();
|
||||
return true;
|
||||
|
@ -192,29 +470,47 @@ public class DistanceCalculatorPlugin extends OsmandPlugin {
|
|||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas, RectF latlonRect, RectF tilesRect, DrawSettings settings) {
|
||||
if (distanceMeasurementMode != 0) {
|
||||
if (measurementPoints.size() > 0) {
|
||||
path.reset();
|
||||
int marginY = originIcon.getHeight();
|
||||
int marginX = originIcon.getWidth() / 2;
|
||||
for (int i = 0; i < measurementPoints.size(); i++) {
|
||||
LatLon point = measurementPoints.get(i);
|
||||
double lat = point.getLatitude();
|
||||
double lon = point.getLongitude();
|
||||
int locationX = view.getMapXForPoint(lon);
|
||||
int locationY = view.getMapYForPoint(lat);
|
||||
if (view.isPointOnTheRotatedMap(lat, lon)) {
|
||||
canvas.rotate(-view.getRotate(), locationX, locationY);
|
||||
canvas.drawBitmap(distanceMeasurementMode == 1? originIcon : destinationIcon,
|
||||
locationX - marginX, locationY - marginY, bitmapPaint);
|
||||
canvas.rotate(view.getRotate(), locationX, locationY);
|
||||
}
|
||||
if (i == 0) {
|
||||
path.moveTo(locationX, locationY);
|
||||
} else {
|
||||
path.lineTo(locationX, locationY);
|
||||
Iterator<WptPt> it = measurementPoints.get(i).iterator();
|
||||
boolean first = true;
|
||||
while (it.hasNext()) {
|
||||
WptPt point = it.next();
|
||||
int locationX = view.getMapXForPoint(point.lon);
|
||||
int locationY = view.getMapYForPoint(point.lat);
|
||||
if (first) {
|
||||
path.moveTo(locationX, locationY);
|
||||
first = false;
|
||||
} else {
|
||||
path.lineTo(locationX, locationY);
|
||||
}
|
||||
}
|
||||
}
|
||||
canvas.drawPath(path, paint);
|
||||
for (int i = 0; i < measurementPoints.size(); i++) {
|
||||
Iterator<WptPt> it = measurementPoints.get(i).iterator();
|
||||
boolean first = true;
|
||||
while(it.hasNext()) {
|
||||
WptPt pt = it.next();
|
||||
if (view.isPointOnTheRotatedMap(pt.lat, pt.lon)) {
|
||||
int locationX = view.getMapXForPoint(pt.lon);
|
||||
int locationY = view.getMapYForPoint(pt.lat);
|
||||
|
||||
if(first || !it.hasNext() || pt.desc != null) {
|
||||
canvas.rotate(-view.getRotate(), locationX, locationY);
|
||||
canvas.drawBitmap(distanceMeasurementMode == 1? originIcon : destinationIcon,
|
||||
locationX - marginX, locationY - marginY, bitmapPaint);
|
||||
canvas.rotate(view.getRotate(), locationX, locationY);
|
||||
} else {
|
||||
canvas.drawCircle(locationX, locationY, 10 * dm.density, paint2);
|
||||
}
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,5 +523,87 @@ public class DistanceCalculatorPlugin extends OsmandPlugin {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void collectObjectsFromPoint(PointF point, List<Object> o) {
|
||||
getMPointsFromPoint(point, o);
|
||||
}
|
||||
|
||||
public void getMPointsFromPoint(PointF point, List<? super WptPt> res) {
|
||||
int r = (int) (12* dm.density);
|
||||
int rs = (int) (7* dm.density);
|
||||
int ex = (int) point.x;
|
||||
int ey = (int) point.y;
|
||||
for(int i = 0; i < measurementPoints.size(); i++) {
|
||||
Iterator<WptPt> it = measurementPoints.get(i).iterator();
|
||||
boolean first = true;
|
||||
while (it.hasNext()) {
|
||||
WptPt pt = it.next();
|
||||
int x = view.getRotatedMapXForPoint(pt.lat, pt.lon);
|
||||
int y = view.getRotatedMapYForPoint(pt.lat, pt.lon);
|
||||
if (pt.desc != null || !it.hasNext() || first) {
|
||||
if (calculateBelongsBig(ex, ey, x, y, r)) {
|
||||
res.add(pt);
|
||||
}
|
||||
} else {
|
||||
if (calculateBelongsSmall(ex, ey, x, y, rs)) {
|
||||
res.add(pt);
|
||||
}
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean calculateBelongsBig(int ex, int ey, int objx, int objy, int radius) {
|
||||
return Math.abs(objx - ex) <= radius && (ey - objy) <= radius / 2 && (objy - ey) <= 3 * radius ;
|
||||
}
|
||||
|
||||
private boolean calculateBelongsSmall(int ex, int ey, int objx, int objy, int radius) {
|
||||
return Math.abs(objx - ex) <= radius && Math.abs(ey - objy) <= radius ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LatLon getObjectLocation(Object o) {
|
||||
if (o instanceof WptPt) {
|
||||
return new LatLon(((WptPt) o).lat, ((WptPt) o).lon);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getObjectDescription(Object o) {
|
||||
if(o instanceof WptPt) {
|
||||
String desc = getObjectName(o);
|
||||
List<String> l = new ArrayList<String>();
|
||||
if(!Double.isNaN(((WptPt) o).ele)) {
|
||||
l.add(app.getString(R.string.plugin_distance_point_ele) + " "+ OsmAndFormatter.getFormattedDistance((float) ((WptPt) o).ele, app));
|
||||
}
|
||||
if(!Double.isNaN(((WptPt) o).speed)) {
|
||||
l.add(app.getString(R.string.plugin_distance_point_speed) + " "+ OsmAndFormatter.getFormattedSpeed((float) ((WptPt) o).speed, app));
|
||||
}
|
||||
if(!Double.isNaN(((WptPt) o).hdop)) {
|
||||
l.add(app.getString(R.string.plugin_distance_point_hdop) + " "+ OsmAndFormatter.getFormattedDistance((float) ((WptPt) o).hdop, app));
|
||||
}
|
||||
if(((WptPt) o).time != 0) {
|
||||
Date date = new Date(((WptPt) o).time);
|
||||
java.text.DateFormat dateFormat = android.text.format.DateFormat.getTimeFormat(app);
|
||||
l.add(app.getString(R.string.plugin_distance_point_time) + " "+ dateFormat.format(date));
|
||||
}
|
||||
return desc + " " + l;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getObjectName(Object o) {
|
||||
if(o instanceof WptPt) {
|
||||
if(((WptPt) o).desc == null) {
|
||||
return app.getString(R.string.plugin_distance_point);
|
||||
}
|
||||
return ((WptPt) o).desc;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue