From 9b6212b5ed17dae0cdb7afcccf1a0175a6ace5f5 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Wed, 16 Jun 2010 15:05:06 +0000 Subject: [PATCH] implementing editing osm data git-svn-id: https://osmand.googlecode.com/svn/trunk@167 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8 --- .../src/com/osmand/ToDoConstants.java | 9 +- .../src/com/osmand/data/Amenity.java | 25 +- .../src/com/osmand/data/AmenityType.java | 135 ++--- .../com/osmand/data/index/IndexConstants.java | 4 +- .../src/com/osmand/osm/Entity.java | 4 + OsmAnd/res/layout/editing_poi.xml | 31 + OsmAnd/res/layout/list_textview.xml | 6 + OsmAnd/res/values/strings.xml | 2 + OsmAnd/res/xml/settings_pref.xml | 1 + .../com/osmand/AmenityIndexRepository.java | 35 ++ OsmAnd/src/com/osmand/OsmandSettings.java | 17 +- OsmAnd/src/com/osmand/PoiFiltersHelper.java | 1 + .../com/osmand/RegionAddressRepository.java | 34 +- OsmAnd/src/com/osmand/ResourceManager.java | 9 + .../osmand/activities/EditingPOIActivity.java | 534 ++++++++++++++++++ .../com/osmand/activities/MapActivity.java | 8 +- .../osmand/activities/SettingsActivity.java | 7 + .../activities/search/SearchPOIActivity.java | 14 +- OsmAnd/src/com/osmand/util/Base64.java | 93 +++ OsmAnd/src/com/osmand/views/POIMapLayer.java | 52 +- 20 files changed, 901 insertions(+), 120 deletions(-) create mode 100644 OsmAnd/res/layout/editing_poi.xml create mode 100644 OsmAnd/res/layout/list_textview.xml create mode 100644 OsmAnd/src/com/osmand/activities/EditingPOIActivity.java create mode 100644 OsmAnd/src/com/osmand/util/Base64.java diff --git a/DataExtractionOSM/src/com/osmand/ToDoConstants.java b/DataExtractionOSM/src/com/osmand/ToDoConstants.java index 542d4dcfb1..a117fae75b 100644 --- a/DataExtractionOSM/src/com/osmand/ToDoConstants.java +++ b/DataExtractionOSM/src/com/osmand/ToDoConstants.java @@ -31,17 +31,11 @@ public class ToDoConstants { // DONE : back end (POI filter object, save, delete, read) // TODO : activity to create/edit new index, activity to read both user defined/osm standard, add actions to remove/create -// 8. Enable change POI directly on map (requires OSM login) -// GOT : Victor -// DONE : Victor investigation -// TODO: - // 33. Build transport locations. Create transport index (transport-stops) (investigate) // GOT : Victor // DONE: Load transport routes in swing. // TODO: Create transport index, create transport activity -// 36. Postcode search // 37. Get rid of exit button (!). Think about when notification should go & how clear resources if it is necessary // DONE : @@ -51,7 +45,6 @@ public class ToDoConstants { // IDEA : Victor have ideas - // FUTURE RELEASES // 43. Enable poi filter by name (?) // 40. Support simple vector road rendering (require new index file) (?) @@ -70,6 +63,8 @@ public class ToDoConstants { // BUGS Swing // DONE ANDROID : + // 36. Postcode search + // 8. Enable change POI directly on map (requires OSM login) // 45. Autozoom feature (for car navigation) // 44. Introduce settings presets (car/bicycle/pedestrian/default) - show different icons for car (bigger), possibly change fonts, position // 20. Implement save track/route to gpx diff --git a/DataExtractionOSM/src/com/osmand/data/Amenity.java b/DataExtractionOSM/src/com/osmand/data/Amenity.java index 0281e5df91..897550fd40 100644 --- a/DataExtractionOSM/src/com/osmand/data/Amenity.java +++ b/DataExtractionOSM/src/com/osmand/data/Amenity.java @@ -20,6 +20,23 @@ public class Amenity extends MapObject { public Amenity(){ } + public String convertToAmenityTag(){ + switch (getType()) { + case SHOP: + return OSMTagKey.SHOP.getValue(); + case LEISURE: + return OSMTagKey.LEISURE.getValue(); + case HISTORIC: + return OSMTagKey.HISTORIC.getValue(); + case TOURISM: + return OSMTagKey.TOURISM.getValue(); + case SPORT: + return OSMTagKey.SPORT.getValue(); + default: + return OSMTagKey.AMENITY.getValue(); + } + } + protected String getSubType(Entity node) { if (node.getTag(OSMTagKey.SHOP) != null) { return node.getTag(OSMTagKey.SHOP); @@ -44,8 +61,10 @@ public class Amenity extends MapObject { return AmenityType.SHOP; } else if(node.getTag(OSMTagKey.TOURISM) != null){ return AmenityType.TOURISM; - } else if(node.getTag(OSMTagKey.LEISURE) != null || node.getTag(OSMTagKey.SPORT) != null){ - return AmenityType.LEISURE_AND_SPORT; + } else if(node.getTag(OSMTagKey.LEISURE) != null){ + return AmenityType.LEISURE; + } else if(node.getTag(OSMTagKey.SPORT) != null){ + return AmenityType.SPORT; } else if(node.getTag(OSMTagKey.HISTORIC) != null){ return AmenityType.HISTORIC; } else if(AmenityType.amenityMap.containsKey(node.getTag(OSMTagKey.AMENITY))){ @@ -77,6 +96,8 @@ public class Amenity extends MapObject { return true; } else if(n.getTag(OSMTagKey.LEISURE) != null){ return true; + } else if(n.getTag(OSMTagKey.SPORT) != null){ + return true; } else if(n.getTag(OSMTagKey.TOURISM) != null){ return true; } else if(n.getTag(OSMTagKey.HISTORIC) != null){ diff --git a/DataExtractionOSM/src/com/osmand/data/AmenityType.java b/DataExtractionOSM/src/com/osmand/data/AmenityType.java index e0fd10fd41..aa30421871 100644 --- a/DataExtractionOSM/src/com/osmand/data/AmenityType.java +++ b/DataExtractionOSM/src/com/osmand/data/AmenityType.java @@ -20,7 +20,8 @@ public enum AmenityType { TOURISM, // [TAG] hotel, sights, museum .. HISTORIC, // [TAG] historic places, monuments (should we unify tourism/historic) SHOP, // [TAG] convenience (product), clothes... - LEISURE_AND_SPORT, // [TAG] sport + LEISURE, // [TAG] leisure + SPORT, // [TAG] sport OTHER, // grave-yard, police, post-office [+Internet_access] ; @@ -151,76 +152,76 @@ public enum AmenityType { amenityMap.put("video", AmenityType.SHOP); - amenityMap.put("dog_park", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("sports_centre", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("golf_course", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("stadium", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("track", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("pitch", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("water_park", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("marina", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("slipway", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("fishing", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("nature_reserve", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("park", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("playground", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("garden", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("common", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("ice_rink", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("miniature_golf", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("dance", AmenityType.LEISURE_AND_SPORT); + amenityMap.put("dog_park", AmenityType.LEISURE); + amenityMap.put("sports_centre", AmenityType.LEISURE); + amenityMap.put("golf_course", AmenityType.LEISURE); + amenityMap.put("stadium", AmenityType.LEISURE); + amenityMap.put("track", AmenityType.LEISURE); + amenityMap.put("pitch", AmenityType.LEISURE); + amenityMap.put("water_park", AmenityType.LEISURE); + amenityMap.put("marina", AmenityType.LEISURE); + amenityMap.put("slipway", AmenityType.LEISURE); + amenityMap.put("fishing", AmenityType.LEISURE); + amenityMap.put("nature_reserve", AmenityType.LEISURE); + amenityMap.put("park", AmenityType.LEISURE); + amenityMap.put("playground", AmenityType.LEISURE); + amenityMap.put("garden", AmenityType.LEISURE); + amenityMap.put("common", AmenityType.LEISURE); + amenityMap.put("ice_rink", AmenityType.LEISURE); + amenityMap.put("miniature_golf", AmenityType.LEISURE); + amenityMap.put("dance", AmenityType.LEISURE); - amenityMap.put("9pin", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("10pin", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("archery", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("athletics", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("australian_football", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("baseball", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("basketball", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("beachvolleyball", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("boules", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("bowls", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("canoe", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("chess", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("climbing", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("cricket", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("cricket_nets", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("croquet", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("cycling", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("diving", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("dog_racing", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("equestrian", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("football", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("golf", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("gymnastics", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("hockey", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("horse_racing", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("ice_stock", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("korfball", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("motor", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("multi", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("orienteering", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("paddle_tennis", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("paragliding", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("pelota", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("racquet", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("rowing", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("rugby", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("shooting", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("skating", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("skateboard", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("skiing", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("soccer", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("swimming", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("table_tennis", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("team_handball", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("tennis", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("toboggan", AmenityType.LEISURE_AND_SPORT); - amenityMap.put("volleyball", AmenityType.LEISURE_AND_SPORT); + amenityMap.put("9pin", AmenityType.SPORT); + amenityMap.put("10pin", AmenityType.SPORT); + amenityMap.put("archery", AmenityType.SPORT); + amenityMap.put("athletics", AmenityType.SPORT); + amenityMap.put("australian_football", AmenityType.SPORT); + amenityMap.put("baseball", AmenityType.SPORT); + amenityMap.put("basketball", AmenityType.SPORT); + amenityMap.put("beachvolleyball", AmenityType.SPORT); + amenityMap.put("boules", AmenityType.SPORT); + amenityMap.put("bowls", AmenityType.SPORT); + amenityMap.put("canoe", AmenityType.SPORT); + amenityMap.put("chess", AmenityType.SPORT); + amenityMap.put("climbing", AmenityType.SPORT); + amenityMap.put("cricket", AmenityType.SPORT); + amenityMap.put("cricket_nets", AmenityType.SPORT); + amenityMap.put("croquet", AmenityType.SPORT); + amenityMap.put("cycling", AmenityType.SPORT); + amenityMap.put("diving", AmenityType.SPORT); + amenityMap.put("dog_racing", AmenityType.SPORT); + amenityMap.put("equestrian", AmenityType.SPORT); + amenityMap.put("football", AmenityType.SPORT); + amenityMap.put("golf", AmenityType.SPORT); + amenityMap.put("gymnastics", AmenityType.SPORT); + amenityMap.put("hockey", AmenityType.SPORT); + amenityMap.put("horse_racing", AmenityType.SPORT); + amenityMap.put("ice_stock", AmenityType.SPORT); + amenityMap.put("korfball", AmenityType.SPORT); + amenityMap.put("motor", AmenityType.SPORT); + amenityMap.put("multi", AmenityType.SPORT); + amenityMap.put("orienteering", AmenityType.SPORT); + amenityMap.put("paddle_tennis", AmenityType.SPORT); + amenityMap.put("paragliding", AmenityType.SPORT); + amenityMap.put("pelota", AmenityType.SPORT); + amenityMap.put("racquet", AmenityType.SPORT); + amenityMap.put("rowing", AmenityType.SPORT); + amenityMap.put("rugby", AmenityType.SPORT); + amenityMap.put("shooting", AmenityType.SPORT); + amenityMap.put("skating", AmenityType.SPORT); + amenityMap.put("skateboard", AmenityType.SPORT); + amenityMap.put("skiing", AmenityType.SPORT); + amenityMap.put("soccer", AmenityType.SPORT); + amenityMap.put("swimming", AmenityType.SPORT); + amenityMap.put("table_tennis", AmenityType.SPORT); + amenityMap.put("team_handball", AmenityType.SPORT); + amenityMap.put("tennis", AmenityType.SPORT); + amenityMap.put("toboggan", AmenityType.SPORT); + amenityMap.put("volleyball", AmenityType.SPORT); // amenity sub type - amenityMap.put("place_of_worship", AmenityType.HISTORIC); + amenityMap.put("place_of_worship", AmenityType.OTHER); amenityMap.put("restaurant", AmenityType.SUSTENANCE); amenityMap.put("food_court", AmenityType.SUSTENANCE); diff --git a/DataExtractionOSM/src/com/osmand/data/index/IndexConstants.java b/DataExtractionOSM/src/com/osmand/data/index/IndexConstants.java index 2d7d97a120..00182612d7 100644 --- a/DataExtractionOSM/src/com/osmand/data/index/IndexConstants.java +++ b/DataExtractionOSM/src/com/osmand/data/index/IndexConstants.java @@ -2,8 +2,10 @@ package com.osmand.data.index; public class IndexConstants { + // Important : Every time you change schema of db upgrade version!!! + // If you want that new application support old index : put upgrade code in android app ResourceManager public final static int POI_TABLE_VERSION = 0; - public final static int ADDRESS_TABLE_VERSION = 0; + public final static int ADDRESS_TABLE_VERSION = 1; public static final String POI_INDEX_DIR = "POI/"; public static final String ADDRESS_INDEX_DIR = "Address/"; diff --git a/DataExtractionOSM/src/com/osmand/osm/Entity.java b/DataExtractionOSM/src/com/osmand/osm/Entity.java index 1197fd38b5..394c53fbd3 100644 --- a/DataExtractionOSM/src/com/osmand/osm/Entity.java +++ b/DataExtractionOSM/src/com/osmand/osm/Entity.java @@ -20,6 +20,10 @@ public abstract class Entity { return id; } + public String removeTag(String key){ + return tags.remove(key); + } + public String putTag(String key, String value){ if(tags == null){ tags = new LinkedHashMap(); diff --git a/OsmAnd/res/layout/editing_poi.xml b/OsmAnd/res/layout/editing_poi.xml new file mode 100644 index 0000000000..d95dad3376 --- /dev/null +++ b/OsmAnd/res/layout/editing_poi.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + diff --git a/OsmAnd/res/layout/list_textview.xml b/OsmAnd/res/layout/list_textview.xml new file mode 100644 index 0000000000..8c41dbaf3d --- /dev/null +++ b/OsmAnd/res/layout/list_textview.xml @@ -0,0 +1,6 @@ + + + diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 5b3a6a2ae1..d7ba33bec3 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -1,5 +1,7 @@ + Input osm password + User password Specify osm settings: show bugs, osm login Specify monitor settings : save track Specify search settings diff --git a/OsmAnd/res/xml/settings_pref.xml b/OsmAnd/res/xml/settings_pref.xml index 83d8b6e121..16932d00d1 100644 --- a/OsmAnd/res/xml/settings_pref.xml +++ b/OsmAnd/res/xml/settings_pref.xml @@ -28,6 +28,7 @@ + diff --git a/OsmAnd/src/com/osmand/AmenityIndexRepository.java b/OsmAnd/src/com/osmand/AmenityIndexRepository.java index 14bf791fe7..6b91f26aed 100644 --- a/OsmAnd/src/com/osmand/AmenityIndexRepository.java +++ b/OsmAnd/src/com/osmand/AmenityIndexRepository.java @@ -79,6 +79,35 @@ public class AmenityIndexRepository { return amenities; } + public boolean addAmenity(long id, double latitude, double longitude, String name, String nameEn, AmenityType t, String subType, String openingHours){ + assert IndexPoiTable.values().length == 8; + db.execSQL("INSERT INTO " + IndexPoiTable.getTable() + " VALUES (?, ?, ?, ?, ?, ?, ?, ?)", + new Object[]{id, latitude, longitude, openingHours, name, nameEn,AmenityType.valueToString(t), subType}); + return true; + } + + public boolean updateAmenity(long id, double latitude, double longitude, String name, String nameEn, AmenityType t, String subType, String openingHours){ + StringBuilder b = new StringBuilder(); + b.append("UPDATE " + IndexPoiTable.getTable() + " SET "); + b.append(IndexPoiTable.LATITUDE.name()).append(" = ?").append(", "). + append(IndexPoiTable.LONGITUDE.name()).append(" = ?").append(", "). + append(IndexPoiTable.OPENING_HOURS.name()).append(" = ?").append(", "). + append(IndexPoiTable.NAME.name()).append(" = ?").append(", "). + append(IndexPoiTable.NAME_EN.name()).append(" = ?").append(", "). + append(IndexPoiTable.TYPE.name()).append(" = ?").append(", "). + append(IndexPoiTable.SUBTYPE.name()).append(" = ?").append(" "). + append(" WHERE ").append(IndexPoiTable.ID.name()).append(" = ?"); + + db.execSQL(b.toString(), + new Object[]{latitude, longitude, openingHours, name, nameEn,AmenityType.valueToString(t), subType, id}); + return true; + } + + public boolean deleteAmenity(long id){ + db.execSQL("DELETE FROM " + IndexPoiTable.getTable()+ " WHERE id="+id); + return true; + } + public synchronized void clearCache(){ cachedAmenities.clear(); @@ -168,6 +197,12 @@ public class AmenityIndexRepository { return name; } + public boolean checkContains(double latitude, double longitude){ + if(latitude < dataTopLatitude && latitude > dataBottomLatitude && longitude > dataLeftLongitude && longitude < dataRightLongitude){ + return true; + } + return false; + } public boolean checkContains(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude){ if(rightLongitude < dataLeftLongitude || leftLongitude > dataRightLongitude){ diff --git a/OsmAnd/src/com/osmand/OsmandSettings.java b/OsmAnd/src/com/osmand/OsmandSettings.java index 030785b7eb..5c61be4aea 100644 --- a/OsmAnd/src/com/osmand/OsmandSettings.java +++ b/OsmAnd/src/com/osmand/OsmandSettings.java @@ -24,7 +24,7 @@ public class OsmandSettings { PEDESTRIAN(R.string.app_mode_pedestrian); private final int key; - + ApplicationMode(int key) { this.key = key; } @@ -68,7 +68,18 @@ public class OsmandSettings { SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE); return prefs.edit().putString(USER_NAME, name).commit(); } - + + public static final String USER_PASSWORD = "user_password"; + public static String getUserPassword(Context ctx){ + SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE); + return prefs.getString(USER_PASSWORD, ""); + } + + public static boolean setUserPassword(Context ctx, String name){ + SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE); + return prefs.edit().putString(USER_PASSWORD, name).commit(); + } + // this value string is synchronized with settings_pref.xml preference name public static final String APPLICATION_MODE = "application_mode"; @@ -299,7 +310,7 @@ public class OsmandSettings { SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE); Editor edit = prefs.edit().putLong(LAST_SEARCHED_CITY, cityId).putString(LAST_SEARCHED_STREET, "").putString( LAST_SEARCHED_BUILDING, ""); - if (prefs.contains(LAST_SEARCHED_INTERSECTED_STREET)) { + if(prefs.contains(LAST_SEARCHED_INTERSECTED_STREET)){ edit.putString(LAST_SEARCHED_INTERSECTED_STREET, ""); } return edit.commit(); diff --git a/OsmAnd/src/com/osmand/PoiFiltersHelper.java b/OsmAnd/src/com/osmand/PoiFiltersHelper.java index a58d656ddd..724b053d3a 100644 --- a/OsmAnd/src/com/osmand/PoiFiltersHelper.java +++ b/OsmAnd/src/com/osmand/PoiFiltersHelper.java @@ -56,6 +56,7 @@ public class PoiFiltersHelper { types.put(AmenityType.HISTORIC, null); types.put(AmenityType.TOURISM, null); list = new ArrayList(); + list.add("place_of_worship"); list.add("internet_access"); list.add("bench"); list.add("embassy"); diff --git a/OsmAnd/src/com/osmand/RegionAddressRepository.java b/OsmAnd/src/com/osmand/RegionAddressRepository.java index 8aee18c525..6b655750d4 100644 --- a/OsmAnd/src/com/osmand/RegionAddressRepository.java +++ b/OsmAnd/src/com/osmand/RegionAddressRepository.java @@ -1,7 +1,6 @@ package com.osmand; import java.io.File; -import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -311,24 +310,21 @@ public class RegionAddressRepository { public void preloadPostcodes(City city) { if (city.getPostcodes().isEmpty()) { - // check if it possible to load postcodes - try { - Cursor query = db.query(true, IndexBuildingTable.getTable(), new String[]{IndexBuildingTable.POSTCODE.toString()},null,null,null,null,null,null); - log.debug("Start loading postcodes for " + city.getName()); - if (query.moveToFirst()) { - do { - String postcode = query.getString(0); - if (postcode != null) { - city.getPostcodes().add(postcode); - } - } while (query.moveToNext()); - } - query.close(); - log.debug("Loaded " + city.getPostcodes().size() + " buildings"); - } catch (Throwable t) { - log.warn("Can't load postcodes information. It might be that you are using old version of index.", t); - } - } + // check if it possible to load postcodes + Cursor query = db.query(true, IndexBuildingTable.getTable(), new String[] { IndexBuildingTable.POSTCODE.toString() }, null, + null, null, null, null, null); + log.debug("Start loading postcodes for " + city.getName()); + if (query.moveToFirst()) { + do { + String postcode = query.getString(0); + if (postcode != null) { + city.getPostcodes().add(postcode); + } + } while (query.moveToNext()); + } + query.close(); + log.debug("Loaded " + city.getPostcodes().size() + " postcodes "); + } } public void preloadBuildings(Street street){ diff --git a/OsmAnd/src/com/osmand/ResourceManager.java b/OsmAnd/src/com/osmand/ResourceManager.java index 2533a66bc6..8f30e19155 100644 --- a/OsmAnd/src/com/osmand/ResourceManager.java +++ b/OsmAnd/src/com/osmand/ResourceManager.java @@ -218,6 +218,15 @@ public class ResourceManager { } // //////////////////////////////////////////// Working with amenities //////////////////////////////////////////////// + public List searchRepositories(double latitude, double longitude) { + List repos = new ArrayList(); + for (AmenityIndexRepository index : amenityRepositories) { + if (index.checkContains(latitude,longitude)) { + repos.add(index); + } + } + return repos; + } public List searchAmenities(PoiFilter filter, double latitude, double longitude, int zoom, int limit) { double tileNumberX = MapUtils.getTileNumberX(zoom, longitude); double tileNumberY = MapUtils.getTileNumberY(zoom, latitude); diff --git a/OsmAnd/src/com/osmand/activities/EditingPOIActivity.java b/OsmAnd/src/com/osmand/activities/EditingPOIActivity.java new file mode 100644 index 0000000000..08c0dddc0c --- /dev/null +++ b/OsmAnd/src/com/osmand/activities/EditingPOIActivity.java @@ -0,0 +1,534 @@ +package com.osmand.activities; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.StringWriter; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.http.HttpResponse; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.params.BasicHttpParams; +import org.apache.http.params.HttpConnectionParams; +import org.apache.http.params.HttpParams; +import org.xml.sax.SAXException; +import org.xmlpull.v1.XmlSerializer; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.AlertDialog.Builder; +import android.content.Context; +import android.content.DialogInterface; +import android.util.Xml; +import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Toast; + +import com.osmand.AmenityIndexRepository; +import com.osmand.LogUtil; +import com.osmand.OsmandSettings; +import com.osmand.R; +import com.osmand.ResourceManager; +import com.osmand.Version; +import com.osmand.data.Amenity; +import com.osmand.data.AmenityType; +import com.osmand.osm.Entity; +import com.osmand.osm.EntityInfo; +import com.osmand.osm.Node; +import com.osmand.osm.OSMSettings.OSMTagKey; +import com.osmand.osm.io.OsmBaseStorage; +import com.osmand.util.Base64; +import com.osmand.views.OsmandMapTileView; + +public class EditingPOIActivity { + +// private final static String SITE_API = "http://api06.dev.openstreetmap.org/"; + private final static String SITE_API = "http://api.openstreetmap.org/"; + + private static final String DELETE_ACTION = "delete"; // NON-NLS + private static final String MODIFY_ACTION = "modify"; // NON-NLS + private static final String CREATE_ACTION = "create"; // NON-NLS + + private Dialog dlg; + private final Context ctx; + private final OsmandMapTileView view; + private AutoCompleteTextView typeText; + private EditText nameText; + private Button typeButton; + private EditText openingHours; + private EntityInfo entityInfo; + private EditText commentText; + private final static Log log = LogUtil.getLog(EditingPOIActivity.class); + + public EditingPOIActivity(final Context ctx){ + this.ctx = ctx; + this.view = null; + } + + + public EditingPOIActivity(final Context ctx, OsmandMapTileView view){ + this.ctx = ctx; + this.view = view; + } + + public void showEditDialog(long id){ + Node n = loadNode(id); + if(n != null){ + dlg = new Dialog(ctx); + dlg.setTitle("Edit POI"); + showDialog(n); + } + } + + public void showCreateDialog(double latitude, double longitude){ + dlg = new Dialog(ctx); + Node n = new Node(latitude, longitude, -1); + n.putTag(OSMTagKey.AMENITY.getValue(), ""); + n.putTag(OSMTagKey.OPENING_HOURS.getValue(), "Mo-Su 08:00-20:00"); + dlg.setTitle("Create POI"); + showDialog(n); + } + + public void showDeleteDialog(long id){ + final Node n = loadNode(id); + if(n == null){ + Toast.makeText(ctx, "POI doesn't found", Toast.LENGTH_LONG).show(); + return; + } + + Builder builder = new AlertDialog.Builder(ctx); + builder.setTitle("Are you sure to delete " + n.getTag(OSMTagKey.NAME)+" (enter comment) ?"); + final EditText comment = new EditText(ctx); + comment.setText("Delete POI"); + builder.setView(comment); + builder.setNegativeButton("Cancel", null); + builder.setPositiveButton("Delete", new DialogInterface.OnClickListener(){ + @Override + public void onClick(DialogInterface dialog, int which) { + String c = comment.getText().toString(); + if(commitNode(DELETE_ACTION, n, entityInfo, c)){ // NON-NLS + Toast.makeText(ctx, "POI was successfully deleted", Toast.LENGTH_LONG).show(); + if(view != null){ + view.refreshMap(); + } + } + } + }); + builder.show(); + } + + private void showDialog(final Node n){ + final Amenity a = new Amenity(n); + dlg.setContentView(R.layout.editing_poi); + nameText =((EditText)dlg.findViewById(R.id.Name)); + nameText.setText(a.getName()); + typeText = ((AutoCompleteTextView)dlg.findViewById(R.id.Type)); + typeButton = ((Button)dlg.findViewById(R.id.TypeButton)); + openingHours = ((EditText)dlg.findViewById(R.id.OpeningHours)); + openingHours.setText(a.getOpeningHours()); + typeText = ((AutoCompleteTextView)dlg.findViewById(R.id.Type)); + typeText.setThreshold(1); + commentText = ((EditText)dlg.findViewById(R.id.Comment)); + updateType(a); + + + typeButton.setOnClickListener(new View.OnClickListener(){ + @Override + public void onClick(View v) { + Builder builder = new AlertDialog.Builder(ctx); + String[] vals = new String[AmenityType.values().length]; + for(int i=0; i subCategories = AmenityType.getSubCategories(a.getType()); + ArrayAdapter adapter = new ArrayAdapter(ctx, R.layout.list_textview, subCategories.toArray()); + typeText.setAdapter(adapter); + } + + + + + protected String sendRequsetThroughHttpClient(String url, String requestMethod, String requestBody, String userOperation, boolean doAuthenticate) { + StringBuilder responseBody = new StringBuilder(); + try { + + HttpParams params = new BasicHttpParams(); + HttpConnectionParams.setConnectionTimeout(params, 15000); + DefaultHttpClient httpclient = new DefaultHttpClient(params); + + if (doAuthenticate) { + UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(OsmandSettings.getUserName(ctx) + ":" + + OsmandSettings.getUserPassword(ctx)); + httpclient.getCredentialsProvider().setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), credentials); + } + HttpRequestBase method = null; + if (requestMethod.equals("GET")) { + method = new HttpGet(url); + } else if (requestMethod.equals("POST")) { + method = new HttpPost(url); + } else if (requestMethod.equals("PUT")) { + method = new HttpPut(url); + } else if (requestMethod.equals("DELETE")) { + method = new HttpDelete(url); + + } else { + throw new IllegalArgumentException(requestMethod + " is invalid method"); + } + if (requestMethod.equals("PUT") || requestMethod.equals("POST") || requestMethod.equals("DELETE")) { + // TODO +// connection.setDoOutput(true); +// connection.setRequestProperty("Content-type", "text/xml"); +// OutputStream out = connection.getOutputStream(); +// if (requestBody != null) { +// BufferedWriter bwr = new BufferedWriter(new OutputStreamWriter(out, "UTF-8")); +// bwr.write(requestBody); +// bwr.flush(); +// } +// out.close(); + } + + HttpResponse response = httpclient.execute(method); + if(response.getStatusLine() == null || + response.getStatusLine().getStatusCode() != 200){ + + String msg; + if(response.getStatusLine() != null){ + msg = userOperation + " failed" ; + } else { + msg = userOperation + " failed " + response.getStatusLine().getStatusCode() +" : "+ + response.getStatusLine().getReasonPhrase(); + } + log.error(msg); + Toast.makeText(ctx, msg, Toast.LENGTH_LONG).show(); + } else { + InputStream is = response.getEntity().getContent(); + if (is != null) { + BufferedReader in = new BufferedReader(new InputStreamReader(is, "UTF-8")); + String s; + while ((s = in.readLine()) != null) { + responseBody.append(s); + responseBody.append("\n"); + } + is.close(); + } + httpclient.getConnectionManager().shutdown(); + return responseBody.toString(); + } + } catch (MalformedURLException e) { + log.error(userOperation + " failed", e); + Toast.makeText(ctx, "Unexpected exception while " + userOperation + " ocurred", Toast.LENGTH_LONG).show(); + } catch (IOException e) { + log.error(userOperation + " failed", e); + Toast.makeText(ctx, "Input/output exception while " + userOperation + " ocurred", Toast.LENGTH_LONG).show(); + } + return null; + + } + private String sendRequest(String url, String requestMethod, String requestBody, String userOperation, boolean doAuthenticate) { + log.info("Sending request " + url); +// if(true){ +// return sendRequsetThroughHttpClient(url, requestMethod, requestBody, userOperation, doAuthenticate); +// } + + try { + HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); + + connection.setConnectTimeout(15000); + connection.setRequestMethod(requestMethod); + StringBuilder responseBody = new StringBuilder(); + if (doAuthenticate) { + String token = OsmandSettings.getUserName(ctx) + ":" + OsmandSettings.getUserPassword(ctx); + connection.addRequestProperty("Authorization", "Basic " + Base64.encode(token.getBytes("UTF-8"))); + } + connection.setDoInput(true); + if (requestMethod.equals("PUT") || requestMethod.equals("POST") || requestMethod.equals("DELETE")) { + connection.setDoOutput(true); + connection.setRequestProperty("Content-type", "text/xml"); + OutputStream out = connection.getOutputStream(); + if (requestBody != null) { + BufferedWriter bwr = new BufferedWriter(new OutputStreamWriter(out, "UTF-8"), 1024); + bwr.write(requestBody); + bwr.flush(); + } + out.close(); + } + connection.connect(); + if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { + String msg = userOperation + " failed : " + connection.getResponseMessage(); + log.error(msg); + Toast.makeText(ctx, msg, Toast.LENGTH_LONG).show(); + } else { + log.info("Response : " + connection.getResponseMessage()); + // populate return fields. + responseBody.setLength(0); + InputStream i = connection.getInputStream(); + if (i != null) { + BufferedReader in = new BufferedReader(new InputStreamReader(i, "UTF-8"), 256); + String s; + boolean f = true; + while ((s = in.readLine()) != null) { + if(!f){ + responseBody.append("\n"); + } else { + f = false; + } + responseBody.append(s); + } + } + return responseBody.toString(); + } + } catch (NullPointerException e) { + // that's tricky case why NPE is thrown to fix that problem httpClient could be used + String msg = "Authorization failed"; + log.error(msg , e); + Toast.makeText(ctx, msg, Toast.LENGTH_LONG).show(); + } catch (MalformedURLException e) { + log.error(userOperation + " failed" , e); + Toast.makeText(ctx, "Unexpected exception while "+ userOperation+" ocurred", Toast.LENGTH_LONG).show(); + } catch (IOException e) { + log.error(userOperation + " failed" , e); + Toast.makeText(ctx, "Input/output exception while "+ userOperation+" ocurred", Toast.LENGTH_LONG).show(); + } + + return null; + } + + public long openChangeSet(String comment,double lat, double lon) { + long id = -1; + StringWriter writer = new StringWriter(256); + XmlSerializer ser = Xml.newSerializer(); + try { + ser.setOutput(writer); + ser.startDocument("UTF-8", true); + ser.startTag(null, "osm"); + ser.startTag(null, "changeset"); + + ser.startTag(null, "tag"); + ser.attribute(null, "k", "comment"); + ser.attribute(null, "v", comment); + ser.endTag(null, "tag"); + + ser.startTag(null, "tag"); + ser.attribute(null, "k", "created_by"); + ser.attribute(null, "v", Version.APP_NAME_VERSION); + ser.endTag(null, "tag"); + ser.endTag(null, "changeset"); + ser.endTag(null, "osm"); + ser.endDocument(); + writer.close(); + } catch (IOException e) { + log.error("Unhandled exception", e); + } + String response = sendRequest(SITE_API + "api/0.6/changeset/create/", "PUT", writer.getBuffer().toString(), "Opening changeset", true); + if (response != null && response.length() > 0) { + id = Long.parseLong(response); + } + + return id; + } + + public void closeChangeSet(long id){ + String response = sendRequest(SITE_API+"api/0.6/changeset/"+id+"/close", "PUT", "", "Closing changeset", true); + log.info("Response : " + response); + } + + private void writeNode(Node n, EntityInfo i, XmlSerializer ser, long changeSetId, String user) throws IllegalArgumentException, IllegalStateException, IOException{ + ser.startTag(null, "node"); + ser.attribute(null, "id", n.getId()+""); + ser.attribute(null, "lat", n.getLatitude()+""); + ser.attribute(null, "lon", n.getLongitude()+""); + if (i != null) { + // ser.attribute(null, "timestamp", i.getETimestamp()); + // ser.attribute(null, "uid", i.getUid()); + // ser.attribute(null, "user", i.getUser()); + ser.attribute(null, "visible", i.getVisible()); + ser.attribute(null, "version", i.getVersion()); + } + ser.attribute(null, "changeset", changeSetId+""); + + for(String k : n.getTagKeySet()){ + String val = n.getTag(k); + ser.startTag(null, "tag"); + ser.attribute(null, "k", k); + ser.attribute(null, "v", val); + ser.endTag(null, "tag"); + } + ser.endTag(null, "node"); + } + + private void updateNodeInIndexes(String action, Node n){ + List repos = ResourceManager.getResourceManager().searchRepositories(n.getLatitude(), n.getLongitude()); + if(DELETE_ACTION.equals(action)){ + for(AmenityIndexRepository r: repos){ + r.deleteAmenity(n.getId()); + r.clearCache(); + } + } else { + boolean changed = MODIFY_ACTION.equals(action); + Amenity a = new Amenity(n); + for(AmenityIndexRepository r: repos){ + if(changed){ + r.updateAmenity(a.getId(), n.getLatitude(), n.getLongitude(), a.getName(), a.getEnName(), a.getType(), a.getSubType(), a.getOpeningHours()); + } else { + r.addAmenity(a.getId(), n.getLatitude(), n.getLongitude(), a.getName(), a.getEnName(), a.getType(), a.getSubType(), a.getOpeningHours()); + } + r.clearCache(); + } + } + + } + + public boolean commitNode(String action, Node n, EntityInfo info, String comment){ + if(info == null && !CREATE_ACTION.equals(action)){ + Toast.makeText(ctx, "Info about node was not loaded", Toast.LENGTH_LONG).show(); + return false; + } + + long changeSetId = openChangeSet(comment, n.getLatitude(), n.getLongitude()); + if(changeSetId < 0){ + return false; + } + try { + StringWriter writer = new StringWriter(256); + XmlSerializer ser = Xml.newSerializer(); + try { + ser.setOutput(writer); + ser.startDocument("UTF-8", true); + ser.startTag(null, "osmChange"); + ser.attribute(null, "version", "0.6"); + ser.attribute(null, "generator", Version.APP_NAME); + ser.startTag(null, action); + ser.attribute(null, "version", "0.6"); + ser.attribute(null, "generator", Version.APP_NAME); + writeNode(n, info, ser, changeSetId, OsmandSettings.getUserName(ctx)); + ser.endTag(null, action); + ser.endTag(null, "osmChange"); + ser.endDocument(); + } catch (IOException e) { + log.error("Unhandled exception", e); + } + String res = sendRequest(SITE_API+"api/0.6/changeset/"+changeSetId + "/upload", "POST", + writer.getBuffer().toString(), "Commiting node", true); + log.debug(res+""); + if (res != null) { + if (CREATE_ACTION.equals(action)) { + long newId = n.getId(); + int i = res.indexOf("new_id=\""); + if (i > 0) { + i = i + "new_id=\"".length(); + int end = res.indexOf("\"", i); + if (end > 0) { + newId = Long.parseLong(res.substring(i, end)); + Node newN = new Node(n.getLatitude(), n.getLongitude(), newId); + for (String t : n.getTagKeySet()) { + newN.putTag(t, n.getTag(t)); + } + n = newN; + } + } + } + updateNodeInIndexes(action, n); + return true; + } + return false; + } finally { + closeChangeSet(changeSetId); + } + } + + public Node loadNode(long id) { + try { + String res = sendRequest(SITE_API+"api/0.6/node/"+id, "GET", null, "Loading poi " + id, false); + if(res != null){ + OsmBaseStorage st = new OsmBaseStorage(); + st.parseOSM(new ByteArrayInputStream(res.getBytes("UTF-8")), null, null, true); + Entity entity = st.getRegisteredEntities().get(id); + entityInfo = st.getRegisteredEntityInfo().get(id); + if(entity instanceof Node){ + return (Node) entity; + } + } + + } catch (IOException e) { + log.error("Loading node failed" + id, e); + Toast.makeText(ctx, "Input/output exception ocurred", Toast.LENGTH_LONG).show(); + } catch (SAXException e) { + log.error("Loading node failed" + id, e); + Toast.makeText(ctx, "Input/output exception ocurred", Toast.LENGTH_LONG).show(); + } + return null; + } + + +} + diff --git a/OsmAnd/src/com/osmand/activities/MapActivity.java b/OsmAnd/src/com/osmand/activities/MapActivity.java index fc6ce1fd63..aa05edec23 100644 --- a/OsmAnd/src/com/osmand/activities/MapActivity.java +++ b/OsmAnd/src/com/osmand/activities/MapActivity.java @@ -355,6 +355,7 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat if(!OsmandSettings.isShowingViewAngle(this)){ locationLayer.setHeading(null); } + poiMapLayer.setFilter(OsmandSettings.getPoiFilterForMap(this)); mapView.setMapPosition(OsmandSettings.getPositionOnMap(this)); SharedPreferences prefs = getSharedPreferences(OsmandSettings.SHARED_PREFERENCES_NAME, MODE_WORLD_READABLE); if(prefs != null && prefs.contains(OsmandSettings.LAST_KNOWN_MAP_LAT)){ @@ -363,7 +364,7 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat mapView.setZoom(OsmandSettings.getLastKnownMapZoom(this)); } backToLocation.setVisibility(View.INVISIBLE); - poiMapLayer.setFilter(OsmandSettings.getPoiFilterForMap(this)); + if(mapView.getLayers().contains(poiMapLayer) != OsmandSettings.isShowingPoiOverMap(this)){ @@ -491,7 +492,7 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat protected void contextMenuPoint(final double latitude, final double longitude){ Builder builder = new AlertDialog.Builder(this); - builder.setItems(new String[]{"Navigate to point", "Add to favourites", "Update map", "Open osm bug"}, new DialogInterface.OnClickListener(){ + builder.setItems(new String[]{"Navigate to point", "Add to favourites", "Update map", "Open osm bug", "Create POI"}, new DialogInterface.OnClickListener(){ @Override public void onClick(DialogInterface dialog, int which) { @@ -503,6 +504,9 @@ public class MapActivity extends Activity implements LocationListener, IMapLocat reloadTile(mapView.getZoom(), latitude, longitude); } else if(which == 3){ osmBugsLayer.openBug(MapActivity.this, getLayoutInflater(), mapView, latitude, longitude); + } else if(which == 4){ + EditingPOIActivity activity = new EditingPOIActivity(MapActivity.this, mapView); + activity.showCreateDialog(latitude, longitude); } } }); diff --git a/OsmAnd/src/com/osmand/activities/SettingsActivity.java b/OsmAnd/src/com/osmand/activities/SettingsActivity.java index 4ae755a4de..e8360ec532 100644 --- a/OsmAnd/src/com/osmand/activities/SettingsActivity.java +++ b/OsmAnd/src/com/osmand/activities/SettingsActivity.java @@ -37,6 +37,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference private Preference saveCurrentTrack; private ListPreference applicationMode; private CheckBoxPreference autoZoom; + private EditTextPreference userPassword; @Override public void onCreate(Bundle savedInstanceState) { @@ -64,6 +65,8 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference useEnglishNames.setOnPreferenceChangeListener(this); userName = (EditTextPreference) screen.findPreference(OsmandSettings.USER_NAME); userName.setOnPreferenceChangeListener(this); + userPassword = (EditTextPreference) screen.findPreference(OsmandSettings.USER_PASSWORD); + userPassword.setOnPreferenceChangeListener(this); saveTrackToGpx =(CheckBoxPreference) screen.findPreference(OsmandSettings.SAVE_TRACK_TO_GPX); saveTrackToGpx.setOnPreferenceChangeListener(this); @@ -101,6 +104,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference positionOnMap.setEntries(e); positionOnMap.setValueIndex(OsmandSettings.getPositionOnMap(this)); userName.setText(OsmandSettings.getUserName(this)); + userPassword.setText(OsmandSettings.getUserPassword(this)); saveTrackInterval.setEntries(new String[]{"1 second", "2 seconds", "5 seconds", "15 seconds", "30 seconds", "1 minute", "5 minute"}); saveTrackInterval.setEntryValues(new String[]{"1", "2", "5", "15", "30", "60", "300"}); @@ -170,6 +174,9 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference } else if(preference == saveTrackInterval){ edit.putInt(OsmandSettings.SAVE_TRACK_INTERVAL, Integer.parseInt(newValue.toString())); edit.commit(); + } else if(preference == userPassword){ + edit.putString(OsmandSettings.USER_PASSWORD, (String) newValue); + edit.commit(); } else if(preference == userName){ edit.putString(OsmandSettings.USER_NAME, (String) newValue); edit.commit(); diff --git a/OsmAnd/src/com/osmand/activities/search/SearchPOIActivity.java b/OsmAnd/src/com/osmand/activities/search/SearchPOIActivity.java index 17653d7fff..d3c5fcb2fd 100644 --- a/OsmAnd/src/com/osmand/activities/search/SearchPOIActivity.java +++ b/OsmAnd/src/com/osmand/activities/search/SearchPOIActivity.java @@ -8,7 +8,6 @@ import java.util.List; import android.app.ListActivity; import android.content.Intent; -import android.content.SharedPreferences; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; @@ -102,16 +101,11 @@ public class SearchPOIActivity extends ListActivity { } } - - public void onListItemClick(ListView parent, View v, int position, long id) { - SharedPreferences prefs = getSharedPreferences(OsmandSettings.SHARED_PREFERENCES_NAME, MODE_WORLD_READABLE); - if (prefs != null) { - Amenity amenity = ((AmenityAdapter)getListAdapter()).getItem(position); - OsmandSettings.setMapLocationToShow(this, amenity.getLocation().getLatitude(), amenity.getLocation().getLongitude()); - Intent newIntent = new Intent(SearchPOIActivity.this, MapActivity.class); - startActivity(newIntent); - } + Amenity amenity = ((AmenityAdapter) getListAdapter()).getItem(position); + OsmandSettings.setMapLocationToShow(this, amenity.getLocation().getLatitude(), amenity.getLocation().getLongitude()); + Intent newIntent = new Intent(SearchPOIActivity.this, MapActivity.class); + startActivity(newIntent); } class AmenityAdapter extends ArrayAdapter { diff --git a/OsmAnd/src/com/osmand/util/Base64.java b/OsmAnd/src/com/osmand/util/Base64.java new file mode 100644 index 0000000000..df1f1cc890 --- /dev/null +++ b/OsmAnd/src/com/osmand/util/Base64.java @@ -0,0 +1,93 @@ +package com.osmand.util; + +/** + * @source http://www.javaworld.com/javaworld/javatips/jw-javatip47.html -- 24.11.2008, (mb) + */ +public class Base64 { + /******************************************************************************************************************* + * BASE 64 encoding of a String or an array of bytes. See also RFC 1421. + * + * @author Unknown + * @author David W. Croft + * @version 1998-06-08 + ******************************************************************************************************************/ + + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + public static final char[] alphabet = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0 to 7 + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 8 to 15 + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 16 to 23 + 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', // 24 to 31 + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 32 to 39 + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 40 to 47 + 'w', 'x', 'y', 'z', '0', '1', '2', '3', // 48 to 55 + '4', '5', '6', '7', '8', '9', '+', '/' }; // 56 to 63 + + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + + public static String encode(final String s) + ////////////////////////////////////////////////////////////////////// + { + return encode(s.getBytes()); + } + + public static String encode(final byte[] octetString) + ////////////////////////////////////////////////////////////////////// + { + int bits24; + int bits6; + + final char[] out = new char[((octetString.length - 1) / 3 + 1) * 4]; + + int outIndex = 0; + int i = 0; + + while ((i + 3) <= octetString.length) { + // store the octets + bits24 = (octetString[i++] & 0xFF) << 16; + bits24 |= (octetString[i++] & 0xFF) << 8; + bits24 |= (octetString[i++] & 0xFF) << 0; + + bits6 = (bits24 & 0x00FC0000) >> 18; + out[outIndex++] = alphabet[bits6]; + bits6 = (bits24 & 0x0003F000) >> 12; + out[outIndex++] = alphabet[bits6]; + bits6 = (bits24 & 0x00000FC0) >> 6; + out[outIndex++] = alphabet[bits6]; + bits6 = (bits24 & 0x0000003F); + out[outIndex++] = alphabet[bits6]; + } + + if (octetString.length - i == 2) { + // store the octets + bits24 = (octetString[i] & 0xFF) << 16; + bits24 |= (octetString[i + 1] & 0xFF) << 8; + + bits6 = (bits24 & 0x00FC0000) >> 18; + out[outIndex++] = alphabet[bits6]; + bits6 = (bits24 & 0x0003F000) >> 12; + out[outIndex++] = alphabet[bits6]; + bits6 = (bits24 & 0x00000FC0) >> 6; + out[outIndex++] = alphabet[bits6]; + + // padding + out[outIndex++] = '='; + } else if (octetString.length - i == 1) { + // store the octets + bits24 = (octetString[i] & 0xFF) << 16; + + bits6 = (bits24 & 0x00FC0000) >> 18; + out[outIndex++] = alphabet[bits6]; + bits6 = (bits24 & 0x0003F000) >> 12; + out[outIndex++] = alphabet[bits6]; + + // padding + out[outIndex++] = '='; + out[outIndex++] = '='; + } + + return new String(out); + } + +} \ No newline at end of file diff --git a/OsmAnd/src/com/osmand/views/POIMapLayer.java b/OsmAnd/src/com/osmand/views/POIMapLayer.java index 5d3d83af6f..5d0c22a615 100644 --- a/OsmAnd/src/com/osmand/views/POIMapLayer.java +++ b/OsmAnd/src/com/osmand/views/POIMapLayer.java @@ -3,6 +3,10 @@ package com.osmand.views; import java.util.ArrayList; import java.util.List; +import android.app.AlertDialog; +import android.app.AlertDialog.Builder; +import android.content.Context; +import android.content.DialogInterface; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; @@ -14,6 +18,7 @@ import android.widget.Toast; import com.osmand.OsmandSettings; import com.osmand.PoiFilter; import com.osmand.ResourceManager; +import com.osmand.activities.EditingPOIActivity; import com.osmand.data.Amenity; import com.osmand.osm.MapUtils; @@ -32,6 +37,27 @@ public class POIMapLayer implements OsmandMapLayer { @Override public boolean onLongPressEvent(PointF point) { + final Amenity n = getAmenityFromPoint(point); + if(n != null){ + Context ctx = view.getContext(); + Builder builder = new AlertDialog.Builder(ctx); + final EditingPOIActivity edit = new EditingPOIActivity(ctx, view); + builder.setItems(new String[]{"Modify", "Delete"}, new DialogInterface.OnClickListener(){ + + @Override + public void onClick(DialogInterface dialog, int which) { + if(which == 0){ + edit.showEditDialog(n.getId()); + } else { + edit.showDeleteDialog(n.getId()); + } + + } + + }); + builder.show(); + return true; + } return false; } @@ -43,9 +69,7 @@ public class POIMapLayer implements OsmandMapLayer { this.filter = filter; } - - @Override - public boolean onTouchEvent(PointF point) { + public Amenity getAmenityFromPoint(PointF point){ if (objects != null) { int ex = (int) point.x; int ey = (int) point.y; @@ -56,18 +80,28 @@ public class POIMapLayer implements OsmandMapLayer { int x = view.getRotatedMapXForPoint(n.getLocation().getLatitude(), n.getLocation().getLongitude()); int y = view.getRotatedMapYForPoint(n.getLocation().getLatitude(), n.getLocation().getLongitude()); if (Math.abs(x - ex) <= radius && Math.abs(y - ey) <= radius) { - String format = n.getSimpleFormat(OsmandSettings.usingEnglishNames(view.getContext())); - if(n.getOpeningHours() != null){ - format += "\n Opening hours : " + n.getOpeningHours(); - } - Toast.makeText(view.getContext(), format, Toast.LENGTH_SHORT).show(); - return true; + return n; } } } catch (IndexOutOfBoundsException e) { // that's really rare case, but is much efficient than introduce synchronized block } } + return null; + } + + + @Override + public boolean onTouchEvent(PointF point) { + Amenity n = getAmenityFromPoint(point); + if(n != null){ + String format = n.getSimpleFormat(OsmandSettings.usingEnglishNames(view.getContext())); + if(n.getOpeningHours() != null){ + format += "\nOpening hours : " + n.getOpeningHours(); + } + Toast.makeText(view.getContext(), format, Toast.LENGTH_SHORT).show(); + return true; + } return false; }