added viget for route steps. Added activity which starts when click on widget.

This commit is contained in:
unknown 2014-06-13 17:56:54 +03:00
parent 8bc95b4aac
commit a8f7c49d3a
9 changed files with 465 additions and 149 deletions

View file

@ -114,6 +114,7 @@
<activity android:name="net.osmand.plus.activities.SettingsNavigationActivity" android:configChanges="keyboardHidden|orientation"></activity>
<activity android:name="net.osmand.plus.monitoring.SettingsMonitoringActivity" android:configChanges="keyboardHidden|orientation"></activity>
<activity android:name="net.osmand.plus.rastermaps.SettingsRasterMapsActivity" android:configChanges="keyboardHidden|orientation"></activity>
<activity android:name=".routesteps.RouteStepsActivity"/>
<activity android:name="net.osmand.plus.osmedit.SettingsOsmEditingActivity" android:configChanges="keyboardHidden|orientation"></activity>
<activity android:name="net.osmand.plus.development.SettingsDevelopmentActivity" android:configChanges="keyboardHidden|orientation"></activity>

View file

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="6dip" >
<TextView android:id="@+id/index"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"/>
<CheckBox
android:id="@+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:focusable="false"
android:focusableInTouchMode="false"/>
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/checkBox1"
android:layout_alignBottom="@+id/checkBox1"
android:layout_toRightOf="@+id/checkBox1"/>
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/checkBox1"
android:layout_alignBottom="@+id/checkBox1"
android:layout_alignParentRight="true"/>
</RelativeLayout>

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content" android:padding="10dp"
android:text="@string/all_route_points" android:textSize="20sp" />
<Button android:id="@+id/done"
android:layout_width="wrap_content"
android:layout_marginRight="6dp"
android:layout_alignParentRight="true"
android:layout_height="wrap_content"
android:text="done"/>
</RelativeLayout>
<ListView android:id="@+id/pointsListView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>

View file

@ -792,14 +792,14 @@
<string name="overlay_transparency">Opacitat de la capa superposada</string>
<string name="layer_underlay">Mapa de base…</string>
<string name="preferred_locale">Llengua de visualització</string>
<string name="tip_search_t">Podeu cercar llocs directament al mapa via \'Usar posició\' → \'Buscar prop d'aquí\', o amb la pantalla dedicada a les cerques via \'Menú\' → \'Cerca\'.
<string name="tip_search_t">Podeu cercar llocs directament al mapa via \'Usar posició\' → \'Buscar prop d\'aquí\', o amb la pantalla dedicada a les cerques via \'Menú\' → \'Cerca\'.
\n\nLa pantalla de cerca admet diferents formats de cerca:
\n\t* per adreça
\n\t* amb coordenades
\n\t* com PDI (per tipus o per nom)
\n\t* dins el teu històric de cerques
\n\t* o entre els teus preferits ja predefinits
\n\n Per qualsevol selecció un menú de context o una barra d'accions ofereix opcions com \'Indicacions\' or \'Mostra al mapa\', etc.
\n\n Per qualsevol selecció un menú de context o una barra d\'accions ofereix opcions com \'Indicacions\' or \'Mostra al mapa\', etc.
</string>
<string name="add_waypoint_dialog_added">La fita «{0}» s\'ha afegit correctament</string>
<string name="add_waypoint_dialog_title">Afegeix una fita a la traça GPX enregistrada</string>

View file

@ -877,6 +877,8 @@ Afghanistan, Albania, Algeria, Andorra, Angola, Anguilla, Antigua and Barbuda, A
<string name="map_widget_right_stack">Right panel:</string>
<string name="map_widget_left_stack">Left panel:</string>
<string name="map_widget_parking">Parking</string>
<string name="map_widget_route_steps">Route steps</string>
<string name="all_route_points">All route points</string>
<string name="map_widget_monitoring">GPX recording</string>
<string name="map_widget_speed">Speed</string>
<string name="map_widget_distance">Destination</string>

View file

@ -85,8 +85,9 @@ public abstract class OsmandPlugin {
installedPlugins.add(parking);
}
final RouteStepsPlugin routeSteps = new RouteStepsPlugin(app);
installPlugin(ROUTE_STEPS_PLUGIN_COMPONENT, RouteStepsPlugin.ID, app, routeSteps);
//final RouteStepsPlugin routeSteps = new RouteStepsPlugin(app);
//installPlugin(ROUTE_STEPS_PLUGIN_COMPONENT, RouteStepsPlugin.ID, app, routeSteps);
installedPlugins.add(new RouteStepsPlugin(app));
installPlugin(OSMODROID_PLUGIN_COMPONENT, OsMoDroidPlugin.ID, app, new OsMoDroidPlugin(app));
installedPlugins.add(new OsmEditingPlugin(app));

View file

@ -0,0 +1,314 @@
package net.osmand.plus.routesteps;
import alice.tuprolog.Int;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.*;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import net.osmand.plus.GPXUtilities;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import java.io.File;
import java.util.*;
/**
* Created by Barsik on 13.06.2014.
*/
public class RouteStepsActivity extends SherlockFragmentActivity {
private static final String VISITED_KEY = "IsVisited";
private static final String POINT_KEY = "Point";
private static final String CURRENT_ROUTE_KEY = "CurrentRoute";
private File file;
private GPXUtilities.GPXFile gpx;
private OsmandApplication app;
private GPXUtilities.Route currentRoute;
private List<GPXUtilities.WptPt> pointsList;
private List<Long> pointsStatus;
//saves indexed of sorted list
private List<Integer> pointsIndex;
//needed to save user selection
private List<Boolean> pointsChangedState;
private List<Boolean> pointsStartState;
private PointItemAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.setContentView(R.layout.route_steps_main);
this.app = (OsmandApplication) getApplication();
this.file = new File("/storage/emulated/0/osmand/tracks/", "504.gpx");
gpx = GPXUtilities.loadGPXFile(app, file);
loadCurrentRoute();
pointsList = currentRoute.points;
sortPoints();
pointsStatus = getAllPointsStatus();
pointsStartState = getPointsState();
pointsChangedState = new ArrayList<Boolean>(pointsStartState);
Button done = (Button) findViewById(R.id.done);
done.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
saveStatus();
}
});
super.onCreate(savedInstanceState);
displayListView();
}
private void displayListView() {
ArrayList<PointItem> pointItemsList = new ArrayList<PointItem>();
for (int i = 0; i < pointsList.size(); i++) {
String pointName = pointsList.get(i).name;
if (pointsStatus.get(i) != 0) {
String dateString= DateFormat.format("MM/dd/yyyy", new Date(pointsStatus.get(i))).toString();
pointItemsList.add(new PointItem(true, pointName, dateString));
} else {
pointItemsList.add(new PointItem(false, pointName, ""));
}
}
adapter = new PointItemAdapter(this,R.layout.route_point_info, pointItemsList);
ListView listView = (ListView) findViewById(R.id.pointsListView);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
}
});
}
private void loadCurrentRoute() {
if (gpx.routes.size() < 1) {
return;
}
Map<String, String> map = gpx.getExtensionsToRead();
if (map.containsKey(CURRENT_ROUTE_KEY)) {
String routeName = map.get(CURRENT_ROUTE_KEY);
int i = 0;
for (GPXUtilities.Route route : gpx.routes) {
if (route.name.equals(routeName)) {
currentRoute = route;
return;
}
i++;
}
}
currentRoute = gpx.routes.get(0);
}
private List<Long> getAllPointsStatus() {
List<Long> pointsStatus = new ArrayList<Long>();
for (int i = 0; i < pointsList.size(); i++) {
pointsStatus.add(getPointStatus(pointsIndex.get(i)));
}
return pointsStatus;
}
private void saveStatus(){
for (int i = 0; i < pointsChangedState.size(); i++) {
boolean newValue = pointsChangedState.get(i);
//if values is the same - there's no need to save data
if (newValue != pointsStartState.get(i)) {
int indexToWrite = pointsIndex.get(i);
setPointStatus(indexToWrite, newValue);
}
}
saveGPXFile();
finish();
}
private void sortPoints(){
List<GPXUtilities.WptPt> listToSort = new ArrayList<GPXUtilities.WptPt>();
List<Integer> indexItemsAtTheEnd = new ArrayList<Integer>();
pointsIndex = new ArrayList<Integer>();
for (int i =0; i< pointsList.size(); i++){
long status = getPointStatus(i);
if (status == 0L){
listToSort.add(pointsList.get(i));
pointsIndex.add(i);
} else{
indexItemsAtTheEnd.add(i);
}
}
for (int i : indexItemsAtTheEnd){
listToSort.add(pointsList.get(i));
pointsIndex.add(i);
}
pointsList = listToSort;
}
private void saveGPXFile() {
GPXUtilities.writeGpxFile(file, gpx, app);
}
private long getPointStatus(int numberOfPoint) {
Map<String, String> map = currentRoute.getExtensionsToRead();
String mapKey = POINT_KEY + numberOfPoint + VISITED_KEY;
if (map.containsKey(mapKey)) {
String value = map.get(mapKey);
return (Long.valueOf(value));
}
return 0L;
}
//saves point status value to gpx extention file
private void setPointStatus(int numberOfPoint, boolean status) {
Map<String, String> map = currentRoute.getExtensionsToWrite();
String mapKey = POINT_KEY + numberOfPoint + VISITED_KEY;
if (status) {
//value is current time
Calendar c = Calendar.getInstance();
long number = c.getTimeInMillis();
map.put(mapKey, String.valueOf(number));
} else if (map.containsKey(mapKey)) {
map.remove(mapKey);
}
}
public List<Boolean> getPointsState() {
List<Boolean> status = new ArrayList<Boolean>();
for (int i = 0; i < pointsStatus.size(); i++) {
if (pointsStatus.get(i) == 0) {
status.add(false);
} else {
status.add(true);
}
}
return status;
}
private boolean[] toPrimitiveArray(final List<Boolean> booleanList) {
final boolean[] primitives = new boolean[booleanList.size()];
int index = 0;
for (Boolean object : booleanList) {
primitives[index++] = object;
}
return primitives;
}
private class PointItemAdapter extends ArrayAdapter<PointItem> {
private RouteStepsActivity ctx;
private ArrayList<PointItem> pointsList;
public PointItemAdapter(Context context, int textViewResourceId, ArrayList<PointItem> pointsList) {
super(context, textViewResourceId, pointsList);
ctx = (RouteStepsActivity) context;
this.pointsList = new ArrayList<PointItem>();
this.pointsList.addAll(pointsList);
}
private class ViewHolder {
TextView index;
TextView name;
TextView date;
CheckBox visited;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
Log.v("ConvertView", String.valueOf(position));
if (convertView == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.route_point_info, null);
holder = new ViewHolder();
holder.index = (TextView) convertView.findViewById(R.id.index);
holder.date = (TextView) convertView.findViewById(R.id.date);
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.visited = (CheckBox) convertView.findViewById(R.id.checkBox1);
convertView.setTag(holder);
holder.visited.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
CheckBox ch = (CheckBox) view;
RelativeLayout parent = (RelativeLayout) ch.getParent();
TextView text = (TextView) parent.getChildAt(0);
pointsChangedState.set(Integer.parseInt(text.getText().toString()), ch.isChecked());
}
});
} else {
holder = (ViewHolder) convertView.getTag();
}
PointItem point = pointsList.get(position);
holder.index.setText(String.valueOf(position));
holder.visited.setChecked(point.isSelected());
String pointName = point.getName();
int pos = pointName.indexOf(":");
holder.name.setText(pointName.substring(0, pos));
if (point.isSelected()){
holder.date.setText(String.valueOf(point.getTime()));
} else{
holder.date.setText("");
}
return convertView;
}
}
private class PointItem {
private boolean visited;
private String name;
private String time;
public PointItem(boolean visited, String name, String time) {
this.visited = visited;
this.name = name;
this.time = time;
}
public String getName() {
return name;
}
public String getTime() {
return time;
}
public boolean isSelected() {
return visited;
}
public void setSelected(boolean selected) {
this.visited = selected;
}
}
}

View file

@ -3,11 +3,21 @@ package net.osmand.plus.routesteps;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Paint;
import android.view.View;
import net.osmand.data.LatLon;
import net.osmand.plus.*;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.views.AnimateDraggingMapThread;
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 java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
@ -18,11 +28,6 @@ public class RouteStepsPlugin extends OsmandPlugin {
public static final String ID = "osmand.route.stepsPlugin";
private static final String VISITED_KEY = "IsVisited";
private static final String POINT_KEY = "Point";
private static final String CURRENT_ROUTE_KEY = "CurrentRoute";
private OsmandApplication app;
private GPXUtilities.GPXFile gpx;
private File file;
@ -31,23 +36,19 @@ public class RouteStepsPlugin extends OsmandPlugin {
private int currentPointPos;
private RouteStepsLayer routeStepsLayer;
private List<GPXUtilities.WptPt> pointsList;
private List<Boolean> pointsStatus;
private TextInfoWidget routeStepsControl;
public RouteStepsPlugin(OsmandApplication app) {
ApplicationMode. regWidget("route_steps", (ApplicationMode[]) null);
this.app = app;
this.file = new File("/storage/emulated/0/osmand/tracks/", "504.gpx");
gpx = GPXUtilities.loadGPXFile(app, file);
loadCurrentRoute();
pointsList = currentRoute.points;
pointsStatus = new ArrayList<Boolean>(pointsList.size());
getAllPointsStatus();
}
public void setGpxFile(GPXUtilities.GPXFile file){ this.gpx = file;}
public void saveGPXFile(){ GPXUtilities.writeGpxFile(file,gpx,app); }
public void setGpxFile(GPXUtilities.GPXFile file) {
this.gpx = file;
}
public void setCurrentPoint(GPXUtilities.WptPt point) {
currentPoint = point;
@ -60,6 +61,10 @@ public class RouteStepsPlugin extends OsmandPlugin {
currentPointPos = number;
}
public List<GPXUtilities.WptPt> getPoints() {
return currentRoute.points;
}
@Override
public String getId() {
return ID;
@ -88,33 +93,16 @@ public class RouteStepsPlugin extends OsmandPlugin {
}
routeStepsLayer = new RouteStepsLayer(activity, this);
activity.getMapView().addLayer(routeStepsLayer, 5.5f);
//registerWidget(activity);
registerWidget(activity);
}
public List<GPXUtilities.WptPt> getPoints() {return currentRoute.points;}
public boolean getPointStatus(int numberOfPoint) {
Map<String, String> map = currentRoute.getExtensionsToRead();
String mapKey = POINT_KEY + numberOfPoint + VISITED_KEY;
if (map.containsKey(mapKey)){
String value = map.get(mapKey);
return (value.equals("true"));
}
return false;
}
//saves point status value to gpx extention file
public void setPointStatus(int numberOfPoint, boolean status) {
Map<String, String> map = currentRoute.getExtensionsToWrite();
String mapKey = POINT_KEY + numberOfPoint + VISITED_KEY;
if (status){
map.put(mapKey, "true");
} else {
map.put(mapKey, "false");
private void registerWidget(MapActivity activity) {
MapInfoLayer mapInfoLayer = activity.getMapLayers().getMapInfoLayer();
if (mapInfoLayer != null) {
routeStepsControl = createRouteStepsInfoControl(activity, mapInfoLayer.getPaintText(), mapInfoLayer.getPaintSubText());
mapInfoLayer.getMapInfoControls().registerSideWidget(routeStepsControl,
R.drawable.widget_parking, R.string.map_widget_route_steps, "route_steps", false, 8);
mapInfoLayer.recreateControls();
}
}
@ -126,100 +114,7 @@ public class RouteStepsPlugin extends OsmandPlugin {
}
}
private void loadCurrentRoute() {
if (gpx.routes.size() < 1){
return;
}
Map<String,String> map = gpx.getExtensionsToRead();
if (map.containsKey(CURRENT_ROUTE_KEY)){
String routeName = map.get(CURRENT_ROUTE_KEY);
int i = 0;
for(GPXUtilities.Route route : gpx.routes){
if (route.name.equals(routeName)){
currentRoute = route;
return;
}
i++;
}
}
currentRoute = gpx.routes.get(0);
}
@Override
public void registerMapContextMenuActions(final MapActivity mapActivity,
final double latitude, final double longitude,
ContextMenuAdapter adapter, Object selectedObj) {
ContextMenuAdapter.OnContextMenuClick addListener = new ContextMenuAdapter.OnContextMenuClick() {
@Override
public void onContextMenuClick(int resId, int pos,
boolean isChecked, DialogInterface dialog) {
if (resId == R.string.context_menu_item_show_route_points) {
showStepsDialog(mapActivity);
}
}
};
adapter.item(R.string.context_menu_item_show_route_points)
.icons( R.drawable.ic_action_parking_dark, R.drawable.ic_action_parking_light).listen(addListener).reg();
}
private void getAllPointsStatus(){
for(int i=0; i< pointsList.size(); i++){
pointsStatus.add(getPointStatus(i));
}
}
private void showStepsDialog(MapActivity mapActivity){
List<String> pointNames = new ArrayList<String>();
//this array need to collect user selection during dialogue
final List<Boolean> pointsIntermediateState = new ArrayList<Boolean>(pointsStatus);
for(GPXUtilities.WptPt point : pointsList){
pointNames.add(point.name);
}
AlertDialog.Builder builder = new AlertDialog.Builder(mapActivity);
builder.setTitle("All available points");
builder.setMultiChoiceItems(pointNames.toArray(new String[pointNames.size()]), toPrimitiveArray(pointsIntermediateState), new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i, boolean isChecked) {
//saving user choice
pointsIntermediateState.set(i,isChecked);
}
});
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
for (int j=0; j< pointsIntermediateState.size(); j++){
boolean newValue = pointsIntermediateState.get(j);
//if values is the same - there's no need to save data
if (newValue != pointsStatus.get(j)){
setPointStatus(j,newValue);
}
}
pointsStatus = new ArrayList<Boolean>(pointsIntermediateState);
saveGPXFile();
}
});
builder.setNegativeButton("Cancel", null);
builder.show();
}
private boolean[] toPrimitiveArray(final List<Boolean> booleanList) {
final boolean[] primitives = new boolean[booleanList.size()];
int index = 0;
for (Boolean object : booleanList) {
primitives[index++] = object;
}
return primitives;
}
private int findPointPosition(GPXUtilities.WptPt point){
public int findPointPosition(GPXUtilities.WptPt point) {
int i = 0;
for (GPXUtilities.WptPt item : pointsList) {
if (item.equals(point)) {
@ -230,4 +125,43 @@ public class RouteStepsPlugin extends OsmandPlugin {
return -1;
}
@Override
public void updateLayers(OsmandMapTileView mapView, MapActivity activity) {
if (routeStepsLayer == null){
registerLayers(activity);
}
if (routeStepsControl == null) {
registerWidget(activity);
}
}
private TextInfoWidget createRouteStepsInfoControl(final MapActivity map, Paint paintText, Paint paintSubText) {
TextInfoWidget routeStepsControl = new TextInfoWidget(map, 0, paintText, paintSubText) {
@Override
public boolean updateInfo(OsmandMapLayer.DrawSettings drawSettings) {
if (gpx != null) {
OsmandMapTileView view = map.getMapView();
setText("test", "test");
}
return true;
}
};
routeStepsControl.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(app, RouteStepsActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
app.startActivity(intent);
}
});
routeStepsControl.setText(null, null);
routeStepsControl.setImageDrawable(map.getResources().getDrawable(R.drawable.widget_parking));
return routeStepsControl;
}
}