implement updating poi map

git-svn-id: https://osmand.googlecode.com/svn/trunk@233 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
Victor Shcherb 2010-06-27 17:15:29 +00:00
parent 45fe3da006
commit 745389634c
15 changed files with 257 additions and 50 deletions

View file

@ -23,8 +23,7 @@ public class ToDoConstants {
// 60. Audio guidance for routing
// 61. Provide route information for YOURS (calclate turns/angle/expected time).
// Fix some missing turns in CloudMade (for secondary roads wo name). Add them (if dist to prev/next turn > 150m)
// 55. Update POI data from internet for selected area [suggest to create new POI index or extend exising of none exist]
// Fix some missing turns in CloudMade (for secondary roads wo name). Add them (if dist to prev/next turn > 150m) [dacha]
// 43. Enable poi filter by name
@ -41,6 +40,7 @@ public class ToDoConstants {
// 63. Support simple offline routing(require new index file) (?)
// BUGS Android
// FIXME !!!! Check agains ID is not unique ! (for relation/node/way - it could be the same)
// TODO swing
// 9. Fix issues with big files (such as netherlands) - save memory (!) - very slow due to transport index !
@ -52,6 +52,7 @@ public class ToDoConstants {
// BUGS Swing
// DONE ANDROID :
// 55. Update POI data from internet for selected area (do not suggest to create or extend POI index)
// 62. History of searched points (once point was selected to go/to show it is saved in history db and could be shown)
// 47. Internet connectivity could be checked before trying to use [merged with 45]
// 26. Show the whole street on map (when it is chosen in search activity). Possibly extend that story to show layer with streets.

View file

@ -28,6 +28,8 @@ public class Amenity extends MapObject {
return OSMTagKey.LEISURE.getValue();
case HISTORIC:
return OSMTagKey.HISTORIC.getValue();
case NATURAL:
return OSMTagKey.NATURAL.getValue();
case TOURISM:
return OSMTagKey.TOURISM.getValue();
case SPORT:
@ -40,6 +42,8 @@ public class Amenity extends MapObject {
protected String getSubType(Entity node) {
if (node.getTag(OSMTagKey.SHOP) != null) {
return node.getTag(OSMTagKey.SHOP);
} else if (node.getTag(OSMTagKey.NATURAL) != null) {
return node.getTag(OSMTagKey.NATURAL);
} else if (node.getTag(OSMTagKey.TOURISM) != null) {
return node.getTag(OSMTagKey.TOURISM);
} else if (node.getTag(OSMTagKey.SPORT) != null) {
@ -59,6 +63,8 @@ public class Amenity extends MapObject {
protected AmenityType getType(Entity node){
if(node.getTag(OSMTagKey.SHOP) != null){
return AmenityType.SHOP;
} else if(node.getTag(OSMTagKey.NATURAL) != null){
return AmenityType.NATURAL;
} else if(node.getTag(OSMTagKey.TOURISM) != null){
return AmenityType.TOURISM;
} else if(node.getTag(OSMTagKey.LEISURE) != null){
@ -94,6 +100,8 @@ public class Amenity extends MapObject {
return true;
} else if(n.getTag(OSMTagKey.SHOP) != null){
return true;
} else if(n.getTag(OSMTagKey.NATURAL) != null){
return true;
} else if(n.getTag(OSMTagKey.LEISURE) != null){
return true;
} else if(n.getTag(OSMTagKey.SPORT) != null){

View file

@ -19,6 +19,7 @@ public enum AmenityType {
ENTERTAINMENT("amenity_type_entertainment"), // cinema, ... (+! sauna, brothel) //$NON-NLS-1$
TOURISM("amenity_type_tourism"), // [TAG] hotel, sights, museum .. //$NON-NLS-1$
HISTORIC("amenity_type_historic"), // [TAG] historic places, monuments (should we unify tourism/historic) //$NON-NLS-1$
NATURAL("amenity_type_natural"), // [TAG] natural places, monuments (should we unify tourism/historic) //$NON-NLS-1$
SHOP("amenity_type_shop"), // [TAG] convenience (product), clothes... //$NON-NLS-1$
LEISURE("amenity_type_leisure"), // [TAG] leisure //$NON-NLS-1$
SPORT("amenity_type_sport"), // [TAG] sport //$NON-NLS-1$
@ -283,6 +284,31 @@ public enum AmenityType {
amenityMap.put("sauna", AmenityType.ENTERTAINMENT); //$NON-NLS-1$
amenityMap.put("brothel", AmenityType.ENTERTAINMENT); //$NON-NLS-1$
amenityMap.put("bay", AmenityType.NATURAL); //$NON-NLS-1$
amenityMap.put("beach", AmenityType.NATURAL); //$NON-NLS-1$
amenityMap.put("cave_entrance", AmenityType.NATURAL); //$NON-NLS-1$
amenityMap.put("cliff", AmenityType.NATURAL); //$NON-NLS-1$
amenityMap.put("coastline", AmenityType.NATURAL); //$NON-NLS-1$
amenityMap.put("fell", AmenityType.NATURAL); //$NON-NLS-1$
amenityMap.put("glacier", AmenityType.NATURAL); //$NON-NLS-1$
amenityMap.put("heath", AmenityType.NATURAL); //$NON-NLS-1$
amenityMap.put("land", AmenityType.NATURAL); //$NON-NLS-1$
amenityMap.put("heath", AmenityType.NATURAL); //$NON-NLS-1$
amenityMap.put("marsh", AmenityType.NATURAL); //$NON-NLS-1$
amenityMap.put("mud", AmenityType.NATURAL); //$NON-NLS-1$
amenityMap.put("peak", AmenityType.NATURAL); //$NON-NLS-1$
amenityMap.put("sand", AmenityType.NATURAL); //$NON-NLS-1$
amenityMap.put("scree", AmenityType.NATURAL); //$NON-NLS-1$
amenityMap.put("scrub", AmenityType.NATURAL); //$NON-NLS-1$
amenityMap.put("spring", AmenityType.NATURAL); //$NON-NLS-1$
amenityMap.put("stone", AmenityType.NATURAL); //$NON-NLS-1$
amenityMap.put("tree", AmenityType.NATURAL); //$NON-NLS-1$
amenityMap.put("volcano", AmenityType.NATURAL); //$NON-NLS-1$
amenityMap.put("water", AmenityType.NATURAL); //$NON-NLS-1$
amenityMap.put("wetland", AmenityType.NATURAL); //$NON-NLS-1$
amenityMap.put("internet_access", AmenityType.OTHER); //$NON-NLS-1$
amenityMap.put("bench", AmenityType.OTHER); //$NON-NLS-1$
amenityMap.put("clock", AmenityType.OTHER); //$NON-NLS-1$

View file

@ -11,6 +11,8 @@ amenity_type_historic = Historic
amenity_type_leisure = Leisure
amenity_type_natural = Natural
amenity_type_other = Other
amenity_type_shop = Shop

View file

@ -7,10 +7,12 @@ amenity_type_finance = \u0424\u0438\u043D\u0430\u043D\u0441\u044B
amenity_type_healthcare = \u0417\u0434\u043E\u0440\u043E\u0432\u044C\u0435
amenity_type_historic = \u0414\u043E\u0441\u0442\u043E\u043F\u0440\u0438\u043C\u0435\u0447\u0430\u0442\u0435\u043B\u044C\u043D\u043E\u0441\u0442\u0438
amenity_type_historic = \u0418\u0441\u0442\u043E\u0440\u0438\u0447\u0435\u0441\u043A\u043E\u0435
amenity_type_leisure = \u0414\u043E\u0441\u0443\u0433
amenity_type_natural = \u041F\u0440\u0438\u0440\u043E\u0434\u0430
amenity_type_other = \u0414\u0440\u0443\u0433\u043E\u0435
amenity_type_shop = \u041C\u0430\u0433\u0430\u0437\u0438\u043D\u044B

View file

@ -3,25 +3,27 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="vertical">
<TableLayout android:layout_width="fill_parent" android:layout_height="wrap_content">
<TableLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:stretchColumns="1">
<TableRow>
<TextView android:text="@string/poi_dialog_name" android:id="@+id/TextView" android:layout_marginLeft="5dp" android:layout_width="fill_parent" android:layout_height="wrap_content"/>
<EditText android:text="" android:id="@+id/Name" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_height="wrap_content" android:layout_weight="1"></EditText>
<TextView android:text="@string/poi_dialog_name" android:id="@+id/TextView" android:layout_marginLeft="5dp" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<!-- bug with width set it to 100 -->
<EditText android:text="" android:id="@+id/Name" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_height="wrap_content" android:layout_width ="100dp"></EditText>
</TableRow>
<TableRow>
<Button android:text="&lt;Type&gt;" android:id="@+id/TypeButton" android:layout_width="fill_parent" android:layout_height="wrap_content"/>
<AutoCompleteTextView android:text="" android:id="@+id/Type" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_height="wrap_content" android:layout_weight="1"/>
<!-- <EditText android:text="" android:id="@+id/Type" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_height="wrap_content" android:layout_weight="1"/> -->
<Button android:text="&lt;Type&gt;" android:id="@+id/TypeButton" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<AutoCompleteTextView android:text="" android:id="@+id/Type" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_height="wrap_content" android:layout_width ="fill_parent"/>
<!-- <EditText android:text="" android:id="@+id/Type" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_height="wrap_content" android:layout_width = "fill_parent" />-->
</TableRow>
<TableRow>
<TextView android:text="@string/poi_dialog_opening_hours" android:id="@+id/TextView" android:layout_marginLeft="5dp" android:layout_width="fill_parent" android:layout_height="wrap_content"/>
<EditText android:text="" android:hint="Mo-Su 08:00-20:00" android:id="@+id/OpeningHours" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_height="wrap_content" android:layout_weight="1"></EditText>
<TextView android:text="@string/poi_dialog_opening_hours" android:id="@+id/TextView" android:layout_marginLeft="5dp" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<EditText android:text="" android:hint="Mo-Su 08:00-20:00" android:id="@+id/OpeningHours" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_width ="fill_parent" android:layout_height="wrap_content"></EditText>
</TableRow>
<TableRow>
<TextView android:text="@string/poi_dialog_comment" android:id="@+id/TextView" android:layout_marginLeft="5dp" android:layout_width="fill_parent" android:layout_height="wrap_content"/>
<EditText android:text="@string/poi_dialog_comment_default" android:id="@+id/Comment" android:layout_marginLeft="5dp" android:layout_marginRight="5dp" android:layout_height="wrap_content" android:layout_weight="1"></EditText>
<TextView android:text="@string/poi_dialog_comment" android:id="@+id/TextView" android:layout_marginLeft="5dp" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
<EditText android:text="@string/poi_dialog_comment_default" android:id="@+id/Comment" android:layout_marginLeft="5dp" android:layout_width ="fill_parent" android:layout_marginRight="5dp" android:layout_height="wrap_content"></EditText>
</TableRow>
</TableLayout>
<TextView android:text="@string/poi_dialog_other_tags_message" android:id="@+id/TextView" android:layout_marginLeft="5dp" android:layout_width="fill_parent" android:layout_height="wrap_content"/>
<LinearLayout android:id="@+id/LinearLayout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal"
android:gravity="bottom|center">

View file

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:orientation="vertical"
android:layout_height="fill_parent" android:background="@color/menu_background">
</LinearLayout>

View file

@ -1,6 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="search_history_city">Город : {0}</string>
<string name="update_poi_success">Данные POI были успешно обновлены ({0} объектов загружено)</string>
<string name="update_poi_error_local">Ошибка сохранения POI в локальный индекс</string>
<string name="update_poi_error_loading">Ошибка загрузки данных с сервера</string>
<string name="update_poi_no_offline_poi_index">Для данной области не имеется ни одного локального индекса POI</string>
<string name="update_poi_is_not_available_for_zoom">Обновление POI не доступно для такой большой области</string>
<string name="context_menu_item_update_poi">Обновить POI</string>
<string name="context_menu_item_update_map_confirm">Вы действительно хотите обновить локальные данные, загрузив их из Интернета?</string>
<string name="search_history_city">Город : {0}</string>
<string name="search_history_street">Улица : {0}, {1}</string>
<string name="search_history_int_streets">Пересечение улиц : {0} x {1} в {2}</string>
<string name="search_history_building">Здание : {0}, {1}, {2}</string>
@ -196,7 +203,7 @@
<string name="context_menu_item_update_map">Обновить карту</string>
<string name="context_menu_item_open_bug">Создать open street bug</string>
<string name="context_menu_item_create_poi">Добавить poi</string>
<string name="context_menu_item_update_map_confirm">Вы действительно хотите удалить эту часть карты с диска и загрузить ее из Интернет?</string>
<string name="default_buttons_yes">Да</string>
<string name="default_buttons_cancel">Отмена</string>
<string name="default_buttons_apply">Применить</string><string name="default_buttons_add">Добавить</string><string name="default_buttons_no">Нет</string><string name="add_favorite_dialog_top_text">Введите имя точки</string>
@ -229,7 +236,7 @@
<string name="osb_comment_dialog_author">Автор</string>
<string name="poi_edit_title">Редактирование POI</string>
<string name="poi_create_title">Добавление POI</string>
<string name="poi_error_poi_not_found">POI не найден</string>
<string name="poi_error_poi_not_found">POI не найден или он не является точкой</string>
<string name="poi_remove_confirm_template">Вы действительно хотите удалить {0}?</string>
<string name="poi_remove_title">Удаление POI</string>
<string name="default_buttons_delete">Удалить</string>

View file

@ -1,5 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="update_poi_success">POI data was updated successfully ({0} were loaded)</string>
<string name="update_poi_error_local">Error updating local indexes</string>
<string name="update_poi_error_loading">Error while loading data from server</string>
<string name="update_poi_no_offline_poi_index">There is no offline poi indexes available for this area</string>
<string name="update_poi_is_not_available_for_zoom">Updating poi is not available for small zoom</string>
<string name="context_menu_item_update_poi">Update poi</string>
<string name="context_menu_item_update_map_confirm">Are you sure about updating local data with internet data?</string>
<string name="search_history_city">City : {0}</string>
<string name="search_history_street">Street : {0}, {1}</string>
<string name="search_history_int_streets">Intersection streets : {0} x {1} in {2}</string>
@ -197,7 +204,7 @@ See osmand.googlecode.com.</string>
<string name="context_menu_item_update_map">Update map</string>
<string name="context_menu_item_open_bug">Open osm bug</string>
<string name="context_menu_item_create_poi">Create POI</string>
<string name="context_menu_item_update_map_confirm">Tile image will be removed from file system. Do you want to reload tile from internet?</string>
<string name="default_buttons_yes">Yes</string>
<string name="default_buttons_cancel">Cancel</string>
<string name="default_buttons_apply">Apply</string><string name="default_buttons_add">Add</string><string name="default_buttons_no">No</string><string name="add_favorite_dialog_top_text">Input name of favourite point</string>
@ -230,7 +237,7 @@ See osmand.googlecode.com.</string>
<string name="osb_comment_dialog_author">Author name</string>
<string name="poi_edit_title">Edit POI</string>
<string name="poi_create_title">Create POI</string>
<string name="poi_error_poi_not_found">POI hasn't found</string>
<string name="poi_error_poi_not_found">Node can not be found or amenity is not a single node</string>
<string name="poi_remove_confirm_template">Are you sure to delete {0} (enter comment) ?</string>
<string name="poi_remove_title">Delete POI</string>
<string name="default_buttons_delete">Delete</string>

View file

@ -1,19 +1,28 @@
package com.osmand;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.xml.sax.SAXException;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
import com.osmand.data.Amenity;
import com.osmand.data.AmenityType;
import com.osmand.data.index.IndexConstants;
import com.osmand.data.index.IndexConstants.IndexPoiTable;
import com.osmand.osm.Entity;
import com.osmand.osm.LatLon;
import com.osmand.osm.Node;
import com.osmand.osm.io.IOsmStorageFilter;
import com.osmand.osm.io.OsmBaseStorage;
public class AmenityIndexRepository {
private static final Log log = LogUtil.getLog(AmenityIndexRepository.class);
@ -203,6 +212,37 @@ public class AmenityIndexRepository {
return name;
}
private void bindString(SQLiteStatement s, int i, String v){
if(v == null){
s.bindNull(i);
} else {
s.bindString(i, v);
}
}
public boolean updateAmenities(List<Amenity> amenities, double leftLon, double topLat, double rightLon, double bottomLat){
String latCol = IndexPoiTable.LATITUDE.name();
String lonCol = IndexPoiTable.LONGITUDE.name();
db.execSQL("DELETE FROM " + IndexPoiTable.getTable() + " WHERE " + //$NON-NLS-1$ //$NON-NLS-2$
lonCol + ">= ? AND ? <=" + lonCol + " AND " + //$NON-NLS-1$//$NON-NLS-2$
latCol + ">= ? AND ? <=" + latCol, new Double[] { leftLon, rightLon, bottomLat, topLat }); //$NON-NLS-1$
SQLiteStatement stat = db.compileStatement(IndexConstants.generatePrepareStatementToInsert(IndexPoiTable.getTable(), 8));
for (Amenity a : amenities) {
stat.bindLong(IndexPoiTable.ID.ordinal() + 1, a.getId());
stat.bindDouble(IndexPoiTable.LATITUDE.ordinal() + 1, a.getLocation().getLatitude());
stat.bindDouble(IndexPoiTable.LONGITUDE.ordinal() + 1, a.getLocation().getLongitude());
bindString(stat, IndexPoiTable.NAME_EN.ordinal() + 1, a.getEnName());
bindString(stat, IndexPoiTable.NAME.ordinal() + 1, a.getName());
bindString(stat, IndexPoiTable.TYPE.ordinal() + 1, AmenityType.valueToString(a.getType()));
bindString(stat, IndexPoiTable.SUBTYPE.ordinal() + 1, a.getSubType());
bindString(stat, IndexPoiTable.OPENING_HOURS.ordinal() + 1 , a.getOpeningHours());
stat.execute();
}
stat.close();
return true;
}
public boolean checkContains(double latitude, double longitude){
if(latitude < dataTopLatitude && latitude > dataBottomLatitude && longitude > dataLeftLongitude && longitude < dataRightLongitude){
return true;
@ -221,5 +261,40 @@ public class AmenityIndexRepository {
}
private final static String SITE_API = "http://api.openstreetmap.org/"; //$NON-NLS-1$
public static boolean loadingPOIs(List<Amenity> amenities, double leftLon, double topLat, double righLon, double bottomLat) {
try {
// bbox=left,bottom,right,top
String u = SITE_API+"api/0.6/map?bbox="+leftLon+","+bottomLat+","+righLon+","+topLat; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
URL url = new URL(u);
log.info("Start loading poi : " + u); //$NON-NLS-1$
InputStream is = url.openStream();
OsmBaseStorage st = new OsmBaseStorage();
final List<Entity> amen = new ArrayList<Entity>();
st.getFilters().add(new IOsmStorageFilter(){
@Override
public boolean acceptEntityToLoad(OsmBaseStorage storage, Entity entity) {
if(Amenity.isAmenity(entity)){
amen.add(entity);
return true;
}
// to
return entity instanceof Node;
}
});
st.parseOSM(is, null, null, false);
for (Entity e : amen) {
amenities.add(new Amenity(e));
}
log.info("Loaded " +amenities.size() + " amenities"); //$NON-NLS-1$//$NON-NLS-2$
} catch (IOException e) {
log.error("Loading nodes failed", e); //$NON-NLS-1$
return false;
} catch (SAXException e) {
log.error("Loading nodes failed", e); //$NON-NLS-1$
return false;
}
return true;
}
}

View file

@ -296,6 +296,7 @@ public class ResourceManager {
}
return repos;
}
public List<Amenity> searchAmenities(PoiFilter filter, double latitude, double longitude, int zoom, int limit) {
double tileNumberX = MapUtils.getTileNumberX(zoom, longitude);
double tileNumberY = MapUtils.getTileNumberY(zoom, latitude);

View file

@ -57,6 +57,7 @@ import com.osmand.data.Amenity;
import com.osmand.data.AmenityType;
import com.osmand.osm.Entity;
import com.osmand.osm.EntityInfo;
import com.osmand.osm.MapUtils;
import com.osmand.osm.Node;
import com.osmand.osm.OSMSettings.OSMTagKey;
import com.osmand.osm.io.OsmBaseStorage;
@ -88,12 +89,14 @@ public class EditingPOIActivity {
this.view = view;
}
public void showEditDialog(long id){
Node n = loadNode(id);
public void showEditDialog(Amenity a){
Node n = loadNode(a);
if(n != null){
dlg = new Dialog(ctx);
dlg.setTitle(R.string.poi_edit_title);
showDialog(n);
} else {
Toast.makeText(ctx, ctx.getString(R.string.poi_error_poi_not_found), Toast.LENGTH_SHORT).show();
}
}
@ -106,8 +109,8 @@ public class EditingPOIActivity {
showDialog(n);
}
public void showDeleteDialog(long id){
final Node n = loadNode(id);
public void showDeleteDialog(Amenity a){
final Node n = loadNode(a);
if(n == null){
Toast.makeText(ctx, ctx.getResources().getString(R.string.poi_error_poi_not_found), Toast.LENGTH_LONG).show();
return;
@ -542,24 +545,27 @@ public class EditingPOIActivity {
}
}
public Node loadNode(long id) {
public Node loadNode(Amenity n) {
try {
String res = sendRequest(SITE_API+"api/0.6/node/"+id, "GET", null, ctx.getString(R.string.loading_poi_obj) + id, false); //$NON-NLS-1$ //$NON-NLS-2$
String res = sendRequest(SITE_API+"api/0.6/node/"+n.getId(), "GET", null, ctx.getString(R.string.loading_poi_obj) + n.getId(), false); //$NON-NLS-1$ //$NON-NLS-2$
if(res != null){
OsmBaseStorage st = new OsmBaseStorage();
st.parseOSM(new ByteArrayInputStream(res.getBytes("UTF-8")), null, null, true); //$NON-NLS-1$
Entity entity = st.getRegisteredEntities().get(id);
entityInfo = st.getRegisteredEntityInfo().get(id);
Entity entity = st.getRegisteredEntities().get(n.getId());
entityInfo = st.getRegisteredEntityInfo().get(n.getId());
if(entity instanceof Node){
return (Node) entity;
// check whether this is node (because id of node could be the same as relation)
if(MapUtils.getDistance(entity.getLatLon(), n.getLocation()) < 50){
return (Node) entity;
}
}
}
} catch (IOException e) {
log.error("Loading node failed" + id, e); //$NON-NLS-1$
log.error("Loading node failed" + n.getId(), e); //$NON-NLS-1$
Toast.makeText(ctx, ctx.getResources().getString(R.string.error_io_error), Toast.LENGTH_LONG).show();
} catch (SAXException e) {
log.error("Loading node failed" + id, e); //$NON-NLS-1$
log.error("Loading node failed" + n.getId(), e); //$NON-NLS-1$
Toast.makeText(ctx, ctx.getResources().getString(R.string.error_io_error), Toast.LENGTH_LONG).show();
}
return null;

View file

@ -1,6 +1,7 @@
package com.osmand.activities;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
@ -8,6 +9,7 @@ import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.app.AlertDialog.Builder;
import android.content.ComponentName;
import android.content.DialogInterface;
@ -17,6 +19,8 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
@ -29,6 +33,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.util.FloatMath;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
@ -44,6 +49,7 @@ import android.widget.Toast;
import android.widget.ZoomControls;
import com.osmand.Algoritms;
import com.osmand.AmenityIndexRepository;
import com.osmand.LogUtil;
import com.osmand.OsmandSettings;
import com.osmand.R;
@ -52,6 +58,7 @@ import com.osmand.Version;
import com.osmand.activities.FavouritesActivity.FavouritePoint;
import com.osmand.activities.FavouritesActivity.FavouritesDbHelper;
import com.osmand.activities.search.SearchActivity;
import com.osmand.data.Amenity;
import com.osmand.data.preparation.MapTileDownloader;
import com.osmand.data.preparation.MapTileDownloader.DownloadRequest;
import com.osmand.data.preparation.MapTileDownloader.IMapDownloaderCallback;
@ -709,18 +716,92 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.context_menu_item_update_map_confirm);
builder.setNegativeButton(R.string.default_buttons_cancel, null);
builder.setPositiveButton(R.string.default_buttons_yes, new DialogInterface.OnClickListener(){
builder.setPositiveButton(R.string.context_menu_item_update_map, new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
int x = (int) MapUtils.getTileNumberX(zoom, longitude);
int y = (int) MapUtils.getTileNumberY(zoom, latitude);
ResourceManager.getResourceManager().clearTileImageForMap(null, mapView.getMap(), x, y, zoom);
Rect pixRect = new Rect(0, 0, mapView.getWidth(), mapView.getHeight());
RectF tilesRect = new RectF();
mapView.calculateTileRectangle(pixRect, mapView.getCenterPointX(), mapView.getCenterPointY(),
mapView.getXTile(), mapView.getYTile(), tilesRect);
int left = (int) FloatMath.floor(tilesRect.left);
int top = (int) FloatMath.floor(tilesRect.top);
int width = (int) (FloatMath.ceil(tilesRect.right) - left);
int height = (int) (FloatMath.ceil(tilesRect.bottom) - top);
for (int i = 0; i <width; i++) {
for (int j = 0; j< height; j++) {
ResourceManager.getResourceManager().clearTileImageForMap(null, mapView.getMap(), i + left, j + top, zoom);
}
}
mapView.refreshMap();
}
});
builder.setNeutralButton(R.string.context_menu_item_update_poi, new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which) {
updatePoiDb(zoom, latitude, longitude);
}
});
builder.create().show();
}
protected void showToast(final String msg){
runOnUiThread(new Runnable(){
@Override
public void run() {
Toast.makeText(MapActivity.this, msg, Toast.LENGTH_LONG).show();
}
});
}
protected void updatePoiDb(int zoom, double latitude, double longitude){
if(zoom < 15){
Toast.makeText(this, getString(R.string.update_poi_is_not_available_for_zoom), Toast.LENGTH_SHORT).show();
return;
}
final List<AmenityIndexRepository> repos = ResourceManager.getResourceManager().searchRepositories(latitude, longitude);
if(repos.isEmpty()){
Toast.makeText(this, getString(R.string.update_poi_no_offline_poi_index), Toast.LENGTH_SHORT).show();
return;
}
Rect pixRect = new Rect(-mapView.getWidth()/2, -mapView.getHeight()/2, 3*mapView.getWidth()/2, 3*mapView.getHeight()/2);
RectF tileRect = new RectF();
mapView.calculateTileRectangle(pixRect, mapView.getCenterPointX(), mapView.getCenterPointY(),
mapView.getXTile(), mapView.getYTile(), tileRect);
final double leftLon = MapUtils.getLongitudeFromTile(zoom, tileRect.left);
final double topLat = MapUtils.getLatitudeFromTile(zoom, tileRect.top);
final double rightLon = MapUtils.getLongitudeFromTile(zoom, tileRect.right);
final double bottomLat = MapUtils.getLatitudeFromTile(zoom, tileRect.bottom);
final ProgressDialog dlg = ProgressDialog.show(this, getString(R.string.loading), getString(R.string.loading_data));
new Thread(new Runnable(){
@Override
public void run() {
try {
List<Amenity> amenities = new ArrayList<Amenity>();
boolean loadingPOIs = AmenityIndexRepository.loadingPOIs(amenities, leftLon, topLat, rightLon, bottomLat);
if(!loadingPOIs){
showToast(getString(R.string.update_poi_error_loading));
} else {
for(AmenityIndexRepository r : repos){
r.updateAmenities(amenities, leftLon, topLat, rightLon, bottomLat);
}
showToast(MessageFormat.format(getString(R.string.update_poi_success), amenities.size()));
mapView.refreshMap();
}
} catch(Exception e) {
Log.e(LogUtil.TAG, "Error updating local data", e); //$NON-NLS-1$
showToast(getString(R.string.update_poi_error_local));
}finally {
dlg.dismiss();
}
}
}, "LoadingPOI").start(); //$NON-NLS-1$
}
protected void contextMenuPoint(final double latitude, final double longitude, boolean menu){
Builder builder = new AlertDialog.Builder(this);
Resources resources = this.getResources();
@ -729,7 +810,7 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat
resources.getString(R.string.context_menu_item_add_favorite),
resources.getString(R.string.context_menu_item_open_bug),
resources.getString(R.string.context_menu_item_create_poi),
resources.getString(R.string.context_menu_item_update_map),
resources.getString(R.string.context_menu_item_update_map)
};
builder.setItems(res, new DialogInterface.OnClickListener(){

View file

@ -315,7 +315,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
}
}
protected void calculateTileRectangle(Rect pixRect, float cx, float cy, float ctilex, float ctiley, RectF tileRect){
public void calculateTileRectangle(Rect pixRect, float cx, float cy, float ctilex, float ctiley, RectF tileRect){
float x1 = calcDiffTileX(pixRect.left - cx, pixRect.top - cy);
float x2 = calcDiffTileX(pixRect.left - cx, pixRect.bottom - cy);
float x3 = calcDiffTileX(pixRect.right - cx, pixRect.top - cy);
@ -331,7 +331,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
tileRect.set(l, t, r, b);
}
protected void calculatePixelRectangle(Rect pixelRect, float cx, float cy, float ctilex, float ctiley, RectF tileRect){
public void calculatePixelRectangle(Rect pixelRect, float cx, float cy, float ctilex, float ctiley, RectF tileRect){
float x1 = calcDiffPixelX(tileRect.left - ctilex, tileRect.top - ctiley);
float x2 = calcDiffPixelX(tileRect.left - ctilex, tileRect.bottom - ctiley);
float x3 = calcDiffPixelX(tileRect.right - ctilex, tileRect.top - ctiley);
@ -444,6 +444,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
public boolean mapIsRefreshing(){
return handler.hasMessages(1);
}
// this method could be called in non UI thread
public void refreshMap() {
if(!handler.hasMessages(1)){
Message msg = Message.obtain(handler, new Runnable(){

View file

@ -51,9 +51,9 @@ public class POIMapLayer implements OsmandMapLayer {
@Override
public void onClick(DialogInterface dialog, int which) {
if(which == 0){
edit.showEditDialog(n.getId());
edit.showEditDialog(n);
} else {
edit.showDeleteDialog(n.getId());
edit.showDeleteDialog(n);
}
}