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 // 60. Audio guidance for routing
// 61. Provide route information for YOURS (calclate turns/angle/expected time). // 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) // Fix some missing turns in CloudMade (for secondary roads wo name). Add them (if dist to prev/next turn > 150m) [dacha]
// 55. Update POI data from internet for selected area [suggest to create new POI index or extend exising of none exist]
// 43. Enable poi filter by name // 43. Enable poi filter by name
@ -41,6 +40,7 @@ public class ToDoConstants {
// 63. Support simple offline routing(require new index file) (?) // 63. Support simple offline routing(require new index file) (?)
// BUGS Android // BUGS Android
// FIXME !!!! Check agains ID is not unique ! (for relation/node/way - it could be the same)
// TODO swing // TODO swing
// 9. Fix issues with big files (such as netherlands) - save memory (!) - very slow due to transport index ! // 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 // BUGS Swing
// DONE ANDROID : // 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) // 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] // 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. // 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(); return OSMTagKey.LEISURE.getValue();
case HISTORIC: case HISTORIC:
return OSMTagKey.HISTORIC.getValue(); return OSMTagKey.HISTORIC.getValue();
case NATURAL:
return OSMTagKey.NATURAL.getValue();
case TOURISM: case TOURISM:
return OSMTagKey.TOURISM.getValue(); return OSMTagKey.TOURISM.getValue();
case SPORT: case SPORT:
@ -40,6 +42,8 @@ public class Amenity extends MapObject {
protected String getSubType(Entity node) { protected String getSubType(Entity node) {
if (node.getTag(OSMTagKey.SHOP) != null) { if (node.getTag(OSMTagKey.SHOP) != null) {
return node.getTag(OSMTagKey.SHOP); return node.getTag(OSMTagKey.SHOP);
} else if (node.getTag(OSMTagKey.NATURAL) != null) {
return node.getTag(OSMTagKey.NATURAL);
} else if (node.getTag(OSMTagKey.TOURISM) != null) { } else if (node.getTag(OSMTagKey.TOURISM) != null) {
return node.getTag(OSMTagKey.TOURISM); return node.getTag(OSMTagKey.TOURISM);
} else if (node.getTag(OSMTagKey.SPORT) != null) { } else if (node.getTag(OSMTagKey.SPORT) != null) {
@ -59,6 +63,8 @@ public class Amenity extends MapObject {
protected AmenityType getType(Entity node){ protected AmenityType getType(Entity node){
if(node.getTag(OSMTagKey.SHOP) != null){ if(node.getTag(OSMTagKey.SHOP) != null){
return AmenityType.SHOP; return AmenityType.SHOP;
} else if(node.getTag(OSMTagKey.NATURAL) != null){
return AmenityType.NATURAL;
} else if(node.getTag(OSMTagKey.TOURISM) != null){ } else if(node.getTag(OSMTagKey.TOURISM) != null){
return AmenityType.TOURISM; return AmenityType.TOURISM;
} else if(node.getTag(OSMTagKey.LEISURE) != null){ } else if(node.getTag(OSMTagKey.LEISURE) != null){
@ -94,6 +100,8 @@ public class Amenity extends MapObject {
return true; return true;
} else if(n.getTag(OSMTagKey.SHOP) != null){ } else if(n.getTag(OSMTagKey.SHOP) != null){
return true; return true;
} else if(n.getTag(OSMTagKey.NATURAL) != null){
return true;
} else if(n.getTag(OSMTagKey.LEISURE) != null){ } else if(n.getTag(OSMTagKey.LEISURE) != null){
return true; return true;
} else if(n.getTag(OSMTagKey.SPORT) != null){ } 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$ ENTERTAINMENT("amenity_type_entertainment"), // cinema, ... (+! sauna, brothel) //$NON-NLS-1$
TOURISM("amenity_type_tourism"), // [TAG] hotel, sights, museum .. //$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$ 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$ SHOP("amenity_type_shop"), // [TAG] convenience (product), clothes... //$NON-NLS-1$
LEISURE("amenity_type_leisure"), // [TAG] leisure //$NON-NLS-1$ LEISURE("amenity_type_leisure"), // [TAG] leisure //$NON-NLS-1$
SPORT("amenity_type_sport"), // [TAG] sport //$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("sauna", AmenityType.ENTERTAINMENT); //$NON-NLS-1$
amenityMap.put("brothel", 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("internet_access", AmenityType.OTHER); //$NON-NLS-1$
amenityMap.put("bench", AmenityType.OTHER); //$NON-NLS-1$ amenityMap.put("bench", AmenityType.OTHER); //$NON-NLS-1$
amenityMap.put("clock", 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_leisure = Leisure
amenity_type_natural = Natural
amenity_type_other = Other amenity_type_other = Other
amenity_type_shop = Shop 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_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_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_other = \u0414\u0440\u0443\u0433\u043E\u0435
amenity_type_shop = \u041C\u0430\u0433\u0430\u0437\u0438\u043D\u044B 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" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="vertical"> 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> <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"/> <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"/>
<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> <!-- 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>
<TableRow> <TableRow>
<Button android:text="&lt;Type&gt;" android:id="@+id/TypeButton" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <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_weight="1"/> <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_weight="1"/> --> <!-- <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>
<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"/> <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_height="wrap_content" android:layout_weight="1"></EditText> <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>
<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"/> <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_marginRight="5dp" android:layout_height="wrap_content" android:layout_weight="1"></EditText> <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> </TableRow>
</TableLayout> </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"/> <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" <LinearLayout android:id="@+id/LinearLayout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal"
android:gravity="bottom|center"> 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,5 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<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_city">Город : {0}</string>
<string name="search_history_street">Улица : {0}, {1}</string> <string name="search_history_street">Улица : {0}, {1}</string>
<string name="search_history_int_streets">Пересечение улиц : {0} x {1} в {2}</string> <string name="search_history_int_streets">Пересечение улиц : {0} x {1} в {2}</string>
@ -196,7 +203,7 @@
<string name="context_menu_item_update_map">Обновить карту</string> <string name="context_menu_item_update_map">Обновить карту</string>
<string name="context_menu_item_open_bug">Создать open street bug</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_create_poi">Добавить poi</string>
<string name="context_menu_item_update_map_confirm">Вы действительно хотите удалить эту часть карты с диска и загрузить ее из Интернет?</string>
<string name="default_buttons_yes">Да</string> <string name="default_buttons_yes">Да</string>
<string name="default_buttons_cancel">Отмена</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> <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="osb_comment_dialog_author">Автор</string>
<string name="poi_edit_title">Редактирование POI</string> <string name="poi_edit_title">Редактирование POI</string>
<string name="poi_create_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_confirm_template">Вы действительно хотите удалить {0}?</string>
<string name="poi_remove_title">Удаление POI</string> <string name="poi_remove_title">Удаление POI</string>
<string name="default_buttons_delete">Удалить</string> <string name="default_buttons_delete">Удалить</string>

View file

@ -1,5 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <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_city">City : {0}</string>
<string name="search_history_street">Street : {0}, {1}</string> <string name="search_history_street">Street : {0}, {1}</string>
<string name="search_history_int_streets">Intersection streets : {0} x {1} in {2}</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_update_map">Update map</string>
<string name="context_menu_item_open_bug">Open osm bug</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_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_yes">Yes</string>
<string name="default_buttons_cancel">Cancel</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> <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="osb_comment_dialog_author">Author name</string>
<string name="poi_edit_title">Edit POI</string> <string name="poi_edit_title">Edit POI</string>
<string name="poi_create_title">Create 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_confirm_template">Are you sure to delete {0} (enter comment) ?</string>
<string name="poi_remove_title">Delete POI</string> <string name="poi_remove_title">Delete POI</string>
<string name="default_buttons_delete">Delete</string> <string name="default_buttons_delete">Delete</string>

View file

@ -1,19 +1,28 @@
package com.osmand; package com.osmand;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.xml.sax.SAXException;
import android.database.Cursor; import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
import com.osmand.data.Amenity; import com.osmand.data.Amenity;
import com.osmand.data.AmenityType; import com.osmand.data.AmenityType;
import com.osmand.data.index.IndexConstants; import com.osmand.data.index.IndexConstants;
import com.osmand.data.index.IndexConstants.IndexPoiTable; import com.osmand.data.index.IndexConstants.IndexPoiTable;
import com.osmand.osm.Entity;
import com.osmand.osm.LatLon; 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 { public class AmenityIndexRepository {
private static final Log log = LogUtil.getLog(AmenityIndexRepository.class); private static final Log log = LogUtil.getLog(AmenityIndexRepository.class);
@ -203,6 +212,37 @@ public class AmenityIndexRepository {
return name; 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){ public boolean checkContains(double latitude, double longitude){
if(latitude < dataTopLatitude && latitude > dataBottomLatitude && longitude > dataLeftLongitude && longitude < dataRightLongitude){ if(latitude < dataTopLatitude && latitude > dataBottomLatitude && longitude > dataLeftLongitude && longitude < dataRightLongitude){
return true; 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; return repos;
} }
public List<Amenity> searchAmenities(PoiFilter filter, double latitude, double longitude, int zoom, int limit) { public List<Amenity> searchAmenities(PoiFilter filter, double latitude, double longitude, int zoom, int limit) {
double tileNumberX = MapUtils.getTileNumberX(zoom, longitude); double tileNumberX = MapUtils.getTileNumberX(zoom, longitude);
double tileNumberY = MapUtils.getTileNumberY(zoom, latitude); 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.data.AmenityType;
import com.osmand.osm.Entity; import com.osmand.osm.Entity;
import com.osmand.osm.EntityInfo; import com.osmand.osm.EntityInfo;
import com.osmand.osm.MapUtils;
import com.osmand.osm.Node; import com.osmand.osm.Node;
import com.osmand.osm.OSMSettings.OSMTagKey; import com.osmand.osm.OSMSettings.OSMTagKey;
import com.osmand.osm.io.OsmBaseStorage; import com.osmand.osm.io.OsmBaseStorage;
@ -88,12 +89,14 @@ public class EditingPOIActivity {
this.view = view; this.view = view;
} }
public void showEditDialog(long id){ public void showEditDialog(Amenity a){
Node n = loadNode(id); Node n = loadNode(a);
if(n != null){ if(n != null){
dlg = new Dialog(ctx); dlg = new Dialog(ctx);
dlg.setTitle(R.string.poi_edit_title); dlg.setTitle(R.string.poi_edit_title);
showDialog(n); 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); showDialog(n);
} }
public void showDeleteDialog(long id){ public void showDeleteDialog(Amenity a){
final Node n = loadNode(id); final Node n = loadNode(a);
if(n == null){ if(n == null){
Toast.makeText(ctx, ctx.getResources().getString(R.string.poi_error_poi_not_found), Toast.LENGTH_LONG).show(); Toast.makeText(ctx, ctx.getResources().getString(R.string.poi_error_poi_not_found), Toast.LENGTH_LONG).show();
return; return;
@ -542,24 +545,27 @@ public class EditingPOIActivity {
} }
} }
public Node loadNode(long id) { public Node loadNode(Amenity n) {
try { 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){ if(res != null){
OsmBaseStorage st = new OsmBaseStorage(); OsmBaseStorage st = new OsmBaseStorage();
st.parseOSM(new ByteArrayInputStream(res.getBytes("UTF-8")), null, null, true); //$NON-NLS-1$ st.parseOSM(new ByteArrayInputStream(res.getBytes("UTF-8")), null, null, true); //$NON-NLS-1$
Entity entity = st.getRegisteredEntities().get(id); Entity entity = st.getRegisteredEntities().get(n.getId());
entityInfo = st.getRegisteredEntityInfo().get(id); entityInfo = st.getRegisteredEntityInfo().get(n.getId());
if(entity instanceof Node){ if(entity instanceof Node){
// 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; return (Node) entity;
} }
} }
}
} catch (IOException e) { } 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(); Toast.makeText(ctx, ctx.getResources().getString(R.string.error_io_error), Toast.LENGTH_LONG).show();
} catch (SAXException e) { } 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(); Toast.makeText(ctx, ctx.getResources().getString(R.string.error_io_error), Toast.LENGTH_LONG).show();
} }
return null; return null;

View file

@ -1,6 +1,7 @@
package com.osmand.activities; package com.osmand.activities;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import android.app.Activity; import android.app.Activity;
@ -8,6 +9,7 @@ import android.app.AlertDialog;
import android.app.Notification; import android.app.Notification;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.app.AlertDialog.Builder; import android.app.AlertDialog.Builder;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.DialogInterface; import android.content.DialogInterface;
@ -17,6 +19,8 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.PointF; import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.hardware.Sensor; import android.hardware.Sensor;
import android.hardware.SensorEvent; import android.hardware.SensorEvent;
import android.hardware.SensorEventListener; import android.hardware.SensorEventListener;
@ -29,6 +33,7 @@ import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.PowerManager; import android.os.PowerManager;
import android.os.PowerManager.WakeLock; import android.os.PowerManager.WakeLock;
import android.util.FloatMath;
import android.util.Log; import android.util.Log;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.Menu; import android.view.Menu;
@ -44,6 +49,7 @@ import android.widget.Toast;
import android.widget.ZoomControls; import android.widget.ZoomControls;
import com.osmand.Algoritms; import com.osmand.Algoritms;
import com.osmand.AmenityIndexRepository;
import com.osmand.LogUtil; import com.osmand.LogUtil;
import com.osmand.OsmandSettings; import com.osmand.OsmandSettings;
import com.osmand.R; import com.osmand.R;
@ -52,6 +58,7 @@ import com.osmand.Version;
import com.osmand.activities.FavouritesActivity.FavouritePoint; import com.osmand.activities.FavouritesActivity.FavouritePoint;
import com.osmand.activities.FavouritesActivity.FavouritesDbHelper; import com.osmand.activities.FavouritesActivity.FavouritesDbHelper;
import com.osmand.activities.search.SearchActivity; import com.osmand.activities.search.SearchActivity;
import com.osmand.data.Amenity;
import com.osmand.data.preparation.MapTileDownloader; import com.osmand.data.preparation.MapTileDownloader;
import com.osmand.data.preparation.MapTileDownloader.DownloadRequest; import com.osmand.data.preparation.MapTileDownloader.DownloadRequest;
import com.osmand.data.preparation.MapTileDownloader.IMapDownloaderCallback; 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 builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.context_menu_item_update_map_confirm); builder.setMessage(R.string.context_menu_item_update_map_confirm);
builder.setNegativeButton(R.string.default_buttons_cancel, null); 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 @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
int x = (int) MapUtils.getTileNumberX(zoom, longitude); Rect pixRect = new Rect(0, 0, mapView.getWidth(), mapView.getHeight());
int y = (int) MapUtils.getTileNumberY(zoom, latitude); RectF tilesRect = new RectF();
ResourceManager.getResourceManager().clearTileImageForMap(null, mapView.getMap(), x, y, zoom); 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(); 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(); 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){ protected void contextMenuPoint(final double latitude, final double longitude, boolean menu){
Builder builder = new AlertDialog.Builder(this); Builder builder = new AlertDialog.Builder(this);
Resources resources = this.getResources(); 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_add_favorite),
resources.getString(R.string.context_menu_item_open_bug), 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_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(){ 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 x1 = calcDiffTileX(pixRect.left - cx, pixRect.top - cy);
float x2 = calcDiffTileX(pixRect.left - cx, pixRect.bottom - cy); float x2 = calcDiffTileX(pixRect.left - cx, pixRect.bottom - cy);
float x3 = calcDiffTileX(pixRect.right - cx, pixRect.top - 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); 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 x1 = calcDiffPixelX(tileRect.left - ctilex, tileRect.top - ctiley);
float x2 = calcDiffPixelX(tileRect.left - ctilex, tileRect.bottom - ctiley); float x2 = calcDiffPixelX(tileRect.left - ctilex, tileRect.bottom - ctiley);
float x3 = calcDiffPixelX(tileRect.right - ctilex, tileRect.top - ctiley); float x3 = calcDiffPixelX(tileRect.right - ctilex, tileRect.top - ctiley);
@ -444,6 +444,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
public boolean mapIsRefreshing(){ public boolean mapIsRefreshing(){
return handler.hasMessages(1); return handler.hasMessages(1);
} }
// this method could be called in non UI thread
public void refreshMap() { public void refreshMap() {
if(!handler.hasMessages(1)){ if(!handler.hasMessages(1)){
Message msg = Message.obtain(handler, new Runnable(){ Message msg = Message.obtain(handler, new Runnable(){

View file

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