From 0a96d65468c847c135b585e83394f4e31b1a88e5 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Sat, 1 Oct 2011 10:53:36 +0200 Subject: [PATCH 1/4] Small improvements --- .../res/layout/favourites_list_category.xml | 4 +- .../plus/activities/MapActivityLayers.java | 52 ++++++++++++++++--- .../plus/activities/SettingsActivity.java | 26 +++++++--- 3 files changed, 67 insertions(+), 15 deletions(-) diff --git a/OsmAnd/res/layout/favourites_list_category.xml b/OsmAnd/res/layout/favourites_list_category.xml index 2ea8c20fe1..8d86cf5046 100644 --- a/OsmAnd/res/layout/favourites_list_category.xml +++ b/OsmAnd/res/layout/favourites_list_category.xml @@ -1,12 +1,12 @@ + android:layout_height="wrap_content" android:paddingLeft="40dp" android:paddingTop="3dp"> + android:textSize="24sp"> diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java index 4a4bd19e99..ac0f2f86d6 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityLayers.java @@ -12,10 +12,12 @@ import java.util.Map.Entry; import net.osmand.Algoritms; import net.osmand.CallbackWithObject; import net.osmand.GPXUtilities; +import net.osmand.ResultMatcher; import net.osmand.GPXUtilities.GPXFile; import net.osmand.OsmAndFormatter; import net.osmand.data.AmenityType; import net.osmand.map.ITileSource; +import net.osmand.map.TileSourceManager.TileSourceTemplate; import net.osmand.plus.OsmandSettings; import net.osmand.plus.OsmandSettings.CommonPreference; import net.osmand.plus.PoiFilter; @@ -518,10 +520,29 @@ public class MapActivityLayers { } updateMapSource(mapView, null); } else if (layerKey.equals(layerInstallMore)) { - SettingsActivity.installMapLayers(activity, new DialogInterface.OnClickListener() { + SettingsActivity.installMapLayers(activity, new ResultMatcher() { + TileSourceTemplate template = null; + int count = 0; @Override - public void onClick(DialogInterface dialog, int which) { - openLayerSelectionDialog(mapView); + public boolean publish(TileSourceTemplate object) { + if(object == null){ + if(count == 1){ + settings.MAP_TILE_SOURCES.set(template.getName()); + settings.MAP_VECTOR_DATA.set(false); + updateMapSource(mapView, settings.MAP_TILE_SOURCES); + } else { + selectMapLayer(mapView); + } + } else { + count ++; + template = object; + } + return false; + } + + @Override + public boolean isCancelled() { + return false; } }); } else { @@ -555,10 +576,29 @@ public class MapActivityLayers { @Override public void onClick(DialogInterface dialog, int which) { if (which == items.length - 1){ - SettingsActivity.installMapLayers(activity, new DialogInterface.OnClickListener() { + SettingsActivity.installMapLayers(activity, new ResultMatcher() { + TileSourceTemplate template = null; + int count = 0; @Override - public void onClick(DialogInterface dialog, int which) { - openLayerSelectionDialog(mapView); + public boolean publish(TileSourceTemplate object) { + if(object == null){ + if(count == 1){ + mapPref.set(template.getName()); + mapControlsLayer.showAndHideTransparencyBar(transparencyPref, transparencyToChange); + updateMapSource(mapView, mapPref); + } else { + selectMapOverlayLayer(mapView, mapPref, transparencyPref, transparencyToChange); + } + } else { + count ++; + template = object; + } + return false; + } + + @Override + public boolean isCancelled() { + return false; } }); } else { diff --git a/OsmAnd/src/net/osmand/plus/activities/SettingsActivity.java b/OsmAnd/src/net/osmand/plus/activities/SettingsActivity.java index 165d5e8e8b..946222b48f 100644 --- a/OsmAnd/src/net/osmand/plus/activities/SettingsActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/SettingsActivity.java @@ -10,6 +10,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import net.osmand.ResultMatcher; import net.osmand.map.TileSourceManager; import net.osmand.map.TileSourceManager.TileSourceTemplate; import net.osmand.plus.NavigationService; @@ -529,10 +530,16 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference } else if (preference == tileSourcePreference || preference == overlayPreference || preference == underlayPreference) { if(MORE_VALUE.equals(newValue)){ - SettingsActivity.installMapLayers(this, new DialogInterface.OnClickListener() { + SettingsActivity.installMapLayers(this, new ResultMatcher() { @Override - public void onClick(DialogInterface dialog, int which) { - updateTileSourceSummary(); + public boolean isCancelled() { return false;} + + @Override + public boolean publish(TileSourceTemplate object) { + if(object == null){ + updateTileSourceSummary(); + } + return true; } }); } else if(preference == tileSourcePreference){ @@ -677,7 +684,7 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference return false; } - public static void installMapLayers(final Activity activity, final DialogInterface.OnClickListener onClickListener){ + public static void installMapLayers(final Activity activity, final ResultMatcher result){ final OsmandSettings settings = ((OsmandApplication) activity.getApplication()).getSettings(); final Map entriesMap = settings.getTileSourceEntries(); if(!settings.isInternetConnectionAvailable(true)){ @@ -717,10 +724,15 @@ public class SettingsActivity extends PreferenceActivity implements OnPreference } } for(TileSourceTemplate ts : toInstall){ - settings.installTileSource(ts); + if(settings.installTileSource(ts)){ + if(result != null){ + result.publish(ts); + } + } } - if(onClickListener != null){ - onClickListener.onClick(dialog, which); + // at the end publish null to show end of process + if (!toInstall.isEmpty() && result != null) { + result.publish(null); } } }); From 89f8885aa96d36c412638c208ea7dd9bdb16b8cf Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Sat, 1 Oct 2011 11:23:13 +0200 Subject: [PATCH 2/4] Small changes --- .../osmand/binary/BinaryMapIndexReader.java | 36 +++++ .../osmand/plus/CollatorStringMatcher.java | 132 ------------------ .../plus/RegionAddressRepositoryBinary.java | 6 +- .../search/SearchByNameAbstractActivity.java | 4 +- .../search/SearchStreetByNameActivity.java | 5 +- 5 files changed, 44 insertions(+), 139 deletions(-) delete mode 100644 OsmAnd/src/net/osmand/plus/CollatorStringMatcher.java diff --git a/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java b/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java index 620530ec5d..6e60152412 100644 --- a/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java +++ b/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java @@ -8,6 +8,7 @@ import gnu.trove.map.hash.TIntObjectHashMap; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; +import java.text.Collator; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; @@ -15,9 +16,11 @@ import java.util.Locale; import java.util.Map; import net.osmand.Algoritms; +import net.osmand.CollatorStringMatcher; import net.osmand.LogUtil; import net.osmand.ResultMatcher; import net.osmand.StringMatcher; +import net.osmand.CollatorStringMatcher.StringMatcherMode; import net.osmand.binary.BinaryMapAddressReaderAdapter.AddressRegion; import net.osmand.binary.BinaryMapPoiReaderAdapter.PoiRegion; import net.osmand.binary.BinaryMapTransportReaderAdapter.TransportIndex; @@ -933,6 +936,39 @@ public class BinaryMapIndexReader { return req.getSearchResults(); } + public Map> searchPoiCategoriesByName(SearchRequest req, Map> map) + throws IOException { + if (req.nameQuery == null || req.nameQuery.length() == 0) { + throw new IllegalArgumentException(); + } + Collator collator = Collator.getInstance(); + collator.setStrength(Collator.PRIMARY); + for (PoiRegion poiIndex : poiIndexes) { + for(int i= 0; i< poiIndex.categories.size(); i++){ + String cat = poiIndex.categories.get(i); + AmenityType catType = poiIndex.categoriesType.get(i); + if(CollatorStringMatcher.cmatches(collator, cat, req.nameQuery, StringMatcherMode.CHECK_STARTS_FROM_SPACE)){ + map.put(catType, null); + } else { + List subcats = poiIndex.subcategories.get(i); + for(int j=0; j< subcats.size(); j++){ + if(CollatorStringMatcher.cmatches(collator, subcats.get(j), req.nameQuery, StringMatcherMode.CHECK_STARTS_FROM_SPACE)){ + if(!map.containsKey(catType)){ + map.put(catType, new ArrayList()); + } + List list = map.get(catType); + if(list != null){ + list.add(subcats.get(j)); + } + } + + } + } + } + } + return map; + } + public List searchPoi(SearchRequest req) throws IOException { req.numberOfVisitedObjects = 0; req.numberOfAcceptedObjects = 0; diff --git a/OsmAnd/src/net/osmand/plus/CollatorStringMatcher.java b/OsmAnd/src/net/osmand/plus/CollatorStringMatcher.java deleted file mode 100644 index 5f7ed90e23..0000000000 --- a/OsmAnd/src/net/osmand/plus/CollatorStringMatcher.java +++ /dev/null @@ -1,132 +0,0 @@ -package net.osmand.plus; - - -import java.text.Collator; - -import net.osmand.StringMatcher; - -/** - * Abstract collator matcher that basically supports subclasses with some collator - * matching. - * - * @author pavol.zibrita - */ -public class CollatorStringMatcher implements StringMatcher { - - private final Collator collator; - private final StringMatcherMode mode; - private final String part; - - public enum StringMatcherMode { - CHECK_ONLY_STARTS_WITH, - CHECK_STARTS_FROM_SPACE, - CHECK_STARTS_FROM_SPACE_NOT_BEGINNING, - CHECK_CONTAINS - } - - public CollatorStringMatcher(Collator collator, String part, StringMatcherMode mode) { - this.collator = collator; - this.part = part; - this.mode = mode; - } - - public Collator getCollator() { - return collator; - } - - @Override - public boolean matches(String name) { - return cmatches(collator, name, part, mode); - } - - - public static boolean cmatches(Collator collator, String base, String part, StringMatcherMode mode){ - switch (mode) { - case CHECK_CONTAINS: - return ccontains(collator, base, part); - case CHECK_STARTS_FROM_SPACE: - return cstartsWith(collator, base, part, true, true); - case CHECK_STARTS_FROM_SPACE_NOT_BEGINNING: - return cstartsWith(collator, base, part, false, true); - case CHECK_ONLY_STARTS_WITH: - return cstartsWith(collator, base, part, true, false); - } - return false; - } - - - /** - * Check if part contains in base - * - * @param collator Collator to use - * @param part String to search - * @param base String where to search - * @return true if part is contained in base - */ - public static boolean ccontains(Collator collator, String base, String part) { - int pos = 0; - if (part.length() > 3) { - // improve searching by searching first 3 characters - pos = cindexOf(collator, pos, part.substring(0, 3), base); - if (pos == -1) { - return false; - } - } - pos = cindexOf(collator, pos, part, base); - if (pos == -1) { - return false; - } - return true; - } - - private static int cindexOf(Collator collator, int start, String part, String base) { - for (int pos = start; pos <= base.length() - part.length(); pos++) { - if (collator.equals(base.substring(pos, pos + part.length()), part)) { - return pos; - } - } - return -1; - } - - /** - * Checks if string starts with another string. - * Special check try to find as well in the middle of name - * - * @param collator - * @param searchIn - * @param theStart - * @return true if searchIn starts with token - */ - public static boolean cstartsWith(Collator collator, String searchIn, String theStart, - boolean checkBeginning, boolean checkSpaces) { - int startLength = theStart.length(); - int searchInLength = searchIn.length(); - if (startLength == 0) { - return true; - } - if (startLength > searchInLength) { - return false; - } - // simulate starts with for collator - if (checkBeginning) { - boolean starts = collator.equals(searchIn.substring(0, startLength), theStart); - if (starts) { - return true; - } - } - if (checkSpaces) { - for (int i = 1; i <= searchInLength - startLength; i++) { - if (considerAsSpace(searchIn.charAt(i - 1)) && !considerAsSpace(searchIn.charAt(i))) { - if (collator.equals(searchIn.substring(i, i + startLength), theStart)) { - return true; - } - } - } - } - return false; - } - - private static boolean considerAsSpace(char c){ - return !Character.isLetter(c) && !Character.isDigit(c); - } -} diff --git a/OsmAnd/src/net/osmand/plus/RegionAddressRepositoryBinary.java b/OsmAnd/src/net/osmand/plus/RegionAddressRepositoryBinary.java index 98d45e60a7..3724cdb5a0 100644 --- a/OsmAnd/src/net/osmand/plus/RegionAddressRepositoryBinary.java +++ b/OsmAnd/src/net/osmand/plus/RegionAddressRepositoryBinary.java @@ -1,6 +1,5 @@ package net.osmand.plus; -import static net.osmand.plus.CollatorStringMatcher.cmatches; import java.io.IOException; import java.text.Collator; @@ -12,8 +11,10 @@ import java.util.Map; import java.util.TreeMap; import net.osmand.Algoritms; +import net.osmand.CollatorStringMatcher; import net.osmand.LogUtil; import net.osmand.ResultMatcher; +import net.osmand.CollatorStringMatcher.StringMatcherMode; import net.osmand.binary.BinaryMapIndexReader; import net.osmand.data.Building; import net.osmand.data.City; @@ -21,7 +22,6 @@ import net.osmand.data.MapObject; import net.osmand.data.PostCode; import net.osmand.data.Street; import net.osmand.osm.LatLon; -import net.osmand.plus.CollatorStringMatcher.StringMatcherMode; import org.apache.commons.logging.Log; @@ -174,7 +174,7 @@ public class RegionAddressRepositoryBinary implements RegionAddressRepository { name = name.toLowerCase(); for (City c : cities.values()) { String cName = c.getName(useEnglishNames); // lower case not needed, collator ensures that - if (cmatches(collator, cName, name, StringMatcherMode.CHECK_STARTS_FROM_SPACE)) { + if (CollatorStringMatcher.cmatches(collator, cName, name, StringMatcherMode.CHECK_STARTS_FROM_SPACE)) { if (resultMatcher.publish(c)) { citiesToFill.add(c); } diff --git a/OsmAnd/src/net/osmand/plus/activities/search/SearchByNameAbstractActivity.java b/OsmAnd/src/net/osmand/plus/activities/search/SearchByNameAbstractActivity.java index 4d9fd7b705..bf1b421008 100644 --- a/OsmAnd/src/net/osmand/plus/activities/search/SearchByNameAbstractActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/search/SearchByNameAbstractActivity.java @@ -4,11 +4,11 @@ import java.text.Collator; import java.util.ArrayList; import java.util.List; +import net.osmand.CollatorStringMatcher; +import net.osmand.CollatorStringMatcher.StringMatcherMode; import net.osmand.osm.LatLon; -import net.osmand.plus.CollatorStringMatcher; import net.osmand.plus.OsmandSettings; import net.osmand.plus.R; -import net.osmand.plus.CollatorStringMatcher.StringMatcherMode; import android.app.ListActivity; import android.content.Intent; import android.os.AsyncTask; diff --git a/OsmAnd/src/net/osmand/plus/activities/search/SearchStreetByNameActivity.java b/OsmAnd/src/net/osmand/plus/activities/search/SearchStreetByNameActivity.java index 7e3026356e..fb406973c2 100644 --- a/OsmAnd/src/net/osmand/plus/activities/search/SearchStreetByNameActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/search/SearchStreetByNameActivity.java @@ -1,16 +1,17 @@ package net.osmand.plus.activities.search; + import java.util.ArrayList; import java.util.List; +import net.osmand.CollatorStringMatcher; import net.osmand.ResultMatcher; +import net.osmand.CollatorStringMatcher.StringMatcherMode; import net.osmand.data.City; import net.osmand.data.PostCode; import net.osmand.data.Street; -import net.osmand.plus.CollatorStringMatcher; import net.osmand.plus.R; import net.osmand.plus.RegionAddressRepository; -import net.osmand.plus.CollatorStringMatcher.StringMatcherMode; import net.osmand.plus.activities.OsmandApplication; import android.os.AsyncTask; import android.os.Message; From 403c8e750a6f7a98b7b93a4767dc49584084a429 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Sat, 1 Oct 2011 12:54:46 +0200 Subject: [PATCH 3/4] Implement search by name poi categories/subcategories --- .../osmand/binary/BinaryMapIndexReader.java | 9 +-- .../data/preparation/IndexPoiCreator.java | 1 - OsmAnd/res/values/strings.xml | 1 + .../plus/AmenityIndexRepositoryBinary.java | 6 ++ OsmAnd/src/net/osmand/plus/PoiFilter.java | 19 +++++ .../src/net/osmand/plus/ResourceManager.java | 13 ++++ .../activities/EditPOIFilterActivity.java | 1 - .../activities/search/SearchPOIActivity.java | 77 +++++++++++++++++-- .../search/SearchPoiFilterActivity.java | 1 + 9 files changed, 113 insertions(+), 15 deletions(-) diff --git a/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java b/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java index 6e60152412..7266353882 100644 --- a/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java +++ b/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexReader.java @@ -936,9 +936,8 @@ public class BinaryMapIndexReader { return req.getSearchResults(); } - public Map> searchPoiCategoriesByName(SearchRequest req, Map> map) - throws IOException { - if (req.nameQuery == null || req.nameQuery.length() == 0) { + public Map> searchPoiCategoriesByName(String query, Map> map) { + if (query == null || query.length() == 0) { throw new IllegalArgumentException(); } Collator collator = Collator.getInstance(); @@ -947,12 +946,12 @@ public class BinaryMapIndexReader { for(int i= 0; i< poiIndex.categories.size(); i++){ String cat = poiIndex.categories.get(i); AmenityType catType = poiIndex.categoriesType.get(i); - if(CollatorStringMatcher.cmatches(collator, cat, req.nameQuery, StringMatcherMode.CHECK_STARTS_FROM_SPACE)){ + if(CollatorStringMatcher.cmatches(collator, cat, query, StringMatcherMode.CHECK_STARTS_FROM_SPACE)){ map.put(catType, null); } else { List subcats = poiIndex.subcategories.get(i); for(int j=0; j< subcats.size(); j++){ - if(CollatorStringMatcher.cmatches(collator, subcats.get(j), req.nameQuery, StringMatcherMode.CHECK_STARTS_FROM_SPACE)){ + if(CollatorStringMatcher.cmatches(collator, subcats.get(j), query, StringMatcherMode.CHECK_STARTS_FROM_SPACE)){ if(!map.containsKey(catType)){ map.put(catType, new ArrayList()); } diff --git a/DataExtractionOSM/src/net/osmand/data/preparation/IndexPoiCreator.java b/DataExtractionOSM/src/net/osmand/data/preparation/IndexPoiCreator.java index e2bcd69e52..37715a13ee 100644 --- a/DataExtractionOSM/src/net/osmand/data/preparation/IndexPoiCreator.java +++ b/DataExtractionOSM/src/net/osmand/data/preparation/IndexPoiCreator.java @@ -555,7 +555,6 @@ public class IndexPoiCreator extends AbstractIndexPartCreator { public static void main(String[] args) throws SQLException, FileNotFoundException, IOException { // TODO support cancelling poi search request! Do it in another thread (Check is cancelled()!!!) - // TODO implement UI to show matching by name subcategories long time = System.currentTimeMillis(); IndexPoiCreator poiCreator = new IndexPoiCreator(); // String fileSqlte = "/home/victor/projects/OsmAnd/data/osm-gen/POI/Ru-mow.poi.odb"; diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 1079f1d2b1..2324b62ac9 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -1,5 +1,6 @@ + Some poi categories matching to the query were found : Local data to search POI is not present. Search by name The poi data file \'%1$s\' is deprecated and can be deleted. diff --git a/OsmAnd/src/net/osmand/plus/AmenityIndexRepositoryBinary.java b/OsmAnd/src/net/osmand/plus/AmenityIndexRepositoryBinary.java index 6fe64dd501..6a43d54840 100644 --- a/OsmAnd/src/net/osmand/plus/AmenityIndexRepositoryBinary.java +++ b/OsmAnd/src/net/osmand/plus/AmenityIndexRepositoryBinary.java @@ -5,6 +5,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import net.osmand.Algoritms; import net.osmand.LogUtil; @@ -49,6 +50,11 @@ public class AmenityIndexRepositoryBinary implements AmenityIndexRepository { } + public Map> searchAmenityCategoriesByName(String query, Map> map) { + return index.searchPoiCategoriesByName(query, map); + } + + public List searchAmenitiesByName(int x, int y, String query, ResultMatcher resulMatcher) { long now = System.currentTimeMillis(); List amenities = Collections.emptyList(); diff --git a/OsmAnd/src/net/osmand/plus/PoiFilter.java b/OsmAnd/src/net/osmand/plus/PoiFilter.java index 0e976800c3..2a5ffd9f7a 100644 --- a/OsmAnd/src/net/osmand/plus/PoiFilter.java +++ b/OsmAnd/src/net/osmand/plus/PoiFilter.java @@ -1,11 +1,13 @@ package net.osmand.plus; import java.util.Collections; +import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.Map.Entry; import net.osmand.OsmAndFormatter; import net.osmand.ResultMatcher; @@ -168,6 +170,10 @@ public class PoiFilter { return set.contains(subtype); } + public void clearFilter(){ + acceptedTypes = new LinkedHashMap>(); + } + public boolean areAllTypesAccepted(){ if(AmenityType.values().length == acceptedTypes.size()){ for(AmenityType a : acceptedTypes.keySet()){ @@ -189,6 +195,19 @@ public class PoiFilter { } } + public void setMapToAccept(Map> newMap) { + Iterator>> iterator = newMap.entrySet().iterator(); + acceptedTypes.clear(); + while(iterator.hasNext()){ + Entry> e = iterator.next(); + if(e.getValue() == null){ + acceptedTypes.put(e.getKey(), null); + } else { + acceptedTypes.put(e.getKey(), new LinkedHashSet(e.getValue())); + } + } + } + public String buildSqlWhereFilter(){ if(areAllTypesAccepted()){ return null; diff --git a/OsmAnd/src/net/osmand/plus/ResourceManager.java b/OsmAnd/src/net/osmand/plus/ResourceManager.java index 53b6e19bdf..048d562e8c 100644 --- a/OsmAnd/src/net/osmand/plus/ResourceManager.java +++ b/OsmAnd/src/net/osmand/plus/ResourceManager.java @@ -25,6 +25,7 @@ import net.osmand.ResultMatcher; import net.osmand.Version; import net.osmand.binary.BinaryMapIndexReader; import net.osmand.data.Amenity; +import net.osmand.data.AmenityType; import net.osmand.data.IndexConstants; import net.osmand.data.MapTileDownloader; import net.osmand.data.TransportStop; @@ -645,6 +646,18 @@ public class ResourceManager { return amenities; } + public Map> searchAmenityCategoriesByName(String searchQuery, double lat, double lon) { + Map> map = new LinkedHashMap>(); + for (AmenityIndexRepository index : amenityRepositories) { + if (index instanceof AmenityIndexRepositoryBinary) { + if (index.checkContains(lat, lon)) { + ((AmenityIndexRepositoryBinary) index).searchAmenityCategoriesByName(searchQuery, map); + } + } + } + return map; + } + public void searchAmenitiesAsync(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, PoiFilter filter, List toFill){ if(filter instanceof NameFinderPoiFilter){ List amenities = ((NameFinderPoiFilter) filter).getSearchedAmenities(); diff --git a/OsmAnd/src/net/osmand/plus/activities/EditPOIFilterActivity.java b/OsmAnd/src/net/osmand/plus/activities/EditPOIFilterActivity.java index cbff500866..b3a621a40a 100644 --- a/OsmAnd/src/net/osmand/plus/activities/EditPOIFilterActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/EditPOIFilterActivity.java @@ -40,7 +40,6 @@ import android.widget.TextView; import android.widget.Toast; /** - * @author Frolov * */ public class EditPOIFilterActivity extends ListActivity { diff --git a/OsmAnd/src/net/osmand/plus/activities/search/SearchPOIActivity.java b/OsmAnd/src/net/osmand/plus/activities/search/SearchPOIActivity.java index a7fe2ce70f..769f7306bf 100644 --- a/OsmAnd/src/net/osmand/plus/activities/search/SearchPOIActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/search/SearchPOIActivity.java @@ -3,19 +3,24 @@ */ package net.osmand.plus.activities.search; + import gnu.trove.set.hash.TLongHashSet; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.Collections; +import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import net.osmand.Algoritms; import net.osmand.LogUtil; import net.osmand.OsmAndFormatter; import net.osmand.ResultMatcher; import net.osmand.data.Amenity; +import net.osmand.data.AmenityType; import net.osmand.osm.LatLon; import net.osmand.osm.OpeningHoursParser; import net.osmand.osm.OpeningHoursParser.OpeningHoursRule; @@ -24,11 +29,13 @@ import net.osmand.plus.OsmandSettings; import net.osmand.plus.PoiFilter; import net.osmand.plus.R; import net.osmand.plus.SearchByNameFilter; +import net.osmand.plus.activities.EditPOIFilterActivity; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.activities.OsmandApplication; import android.app.AlertDialog; import android.app.ListActivity; import android.content.DialogInterface; +import android.content.Intent; import android.content.pm.ActivityInfo; import android.graphics.Canvas; import android.graphics.Color; @@ -70,8 +77,7 @@ import android.widget.TextView; import android.widget.Toast; /** - * @author Maxim Frolov - * + * Search poi activity */ public class SearchPOIActivity extends ListActivity implements SensorEventListener { @@ -137,7 +143,9 @@ public class SearchPOIActivity extends ListActivity implements SensorEventListen runNewSearchQuery(SearchAmenityRequest.buildRequest(location, SearchAmenityRequest.NEW_SEARCH_INIT)); } else if(isSearchByNameFilter() && !Algoritms.objectEquals(((SearchByNameFilter) filter).getQuery(), query)){ + showFilter.setVisibility(View.INVISIBLE); filter.clearPreviousZoom(); + showPoiCategoriesByNameFilter(query, location); ((SearchByNameFilter) filter).setQuery(query); runNewSearchQuery(SearchAmenityRequest.buildRequest(location, SearchAmenityRequest.NEW_SEARCH_INIT)); } else { @@ -149,11 +157,21 @@ public class SearchPOIActivity extends ListActivity implements SensorEventListen showFilter.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - if (searchFilterLayout.getVisibility() == View.GONE) { - searchFilterLayout.setVisibility(View.VISIBLE); + if(isSearchByNameFilter()){ + Intent newIntent = new Intent(SearchPOIActivity.this, EditPOIFilterActivity.class); + newIntent.putExtra(EditPOIFilterActivity.AMENITY_FILTER, PoiFilter.CUSTOM_FILTER_ID); + if(location != null) { + newIntent.putExtra(EditPOIFilterActivity.SEARCH_LAT, location.getLatitude()); + newIntent.putExtra(EditPOIFilterActivity.SEARCH_LON, location.getLongitude()); + } + startActivity(newIntent); } else { - searchFilter.setText(""); //$NON-NLS-1$ - searchFilterLayout.setVisibility(View.GONE); + if (searchFilterLayout.getVisibility() == View.GONE) { + searchFilterLayout.setVisibility(View.VISIBLE); + } else { + searchFilter.setText(""); //$NON-NLS-1$ + searchFilterLayout.setVisibility(View.GONE); + } } } }); @@ -233,14 +251,17 @@ public class SearchPOIActivity extends ListActivity implements SensorEventListen clearSearchQuery(); } - if(isNameFinderFilter() || isSearchByNameFilter() ){ + if(isNameFinderFilter()){ showFilter.setVisibility(View.GONE); searchFilterLayout.setVisibility(View.VISIBLE); + } else if(isSearchByNameFilter() ){ + showFilter.setVisibility(View.INVISIBLE); + searchFilterLayout.setVisibility(View.VISIBLE); } else { showFilter.setVisibility(View.VISIBLE); showOnMap.setEnabled(filter != null); } - showOnMap.setVisibility(isSearchByNameFilter() ? View.INVISIBLE : View.VISIBLE); + showOnMap.setVisibility(isSearchByNameFilter() ? View.GONE : View.VISIBLE); if (filter != null) { searchArea.setText(filter.getSearchArea()); @@ -261,7 +282,47 @@ public class SearchPOIActivity extends ListActivity implements SensorEventListen } } + private void showPoiCategoriesByNameFilter(String query, Location loc){ + OsmandApplication app = (OsmandApplication) getApplication(); + if(loc != null){ + Map> map = app.getResourceManager().searchAmenityCategoriesByName(query, loc.getLatitude(), loc.getLongitude()); + if(!map.isEmpty()){ + PoiFilter filter = ((OsmandApplication)getApplication()).getPoiFilters().getFilterById(PoiFilter.CUSTOM_FILTER_ID); + if(filter != null){ + showFilter.setVisibility(View.VISIBLE); + filter.setMapToAccept(map); + } + + String s = typesToString(map); + Toast.makeText(this, getString(R.string.poi_query_by_name_matches_categories) + s, Toast.LENGTH_LONG).show(); + } + } + } + private String typesToString(Map> map) { + StringBuilder b = new StringBuilder(); + int count = 0; + Iterator>> iterator = map.entrySet().iterator(); + while(iterator.hasNext() && count < 4){ + Entry> e = iterator.next(); + b.append("\n").append(OsmAndFormatter.toPublicString(e.getKey(), this)).append(" - "); + if(e.getValue() == null){ + b.append("..."); + } else { + for(int j=0; j 0){ + b.append(", "); + } + b.append(e.getValue().get(j)); + } + } + } + if(iterator.hasNext()){ + b.append("\n..."); + } + return b.toString(); + } + private void updateSearchPoiTextButton(){ if(location == null){ searchPOILevel.setText(R.string.search_poi_location); diff --git a/OsmAnd/src/net/osmand/plus/activities/search/SearchPoiFilterActivity.java b/OsmAnd/src/net/osmand/plus/activities/search/SearchPoiFilterActivity.java index 415b2bb5cd..e05a50999b 100644 --- a/OsmAnd/src/net/osmand/plus/activities/search/SearchPoiFilterActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/search/SearchPoiFilterActivity.java @@ -110,6 +110,7 @@ public class SearchPoiFilterActivity extends ListActivity { public void onListItemClick(ListView parent, View v, int position, long id) { final PoiFilter filter = ((AmenityAdapter) getListAdapter()).getItem(position); if (filter.getFilterId().equals(PoiFilter.CUSTOM_FILTER_ID)) { + filter.clearFilter(); showEditActivity(filter); return; } From d40fa645683c30dcd11d4fb890fd61d401600cfd Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Sun, 2 Oct 2011 21:04:35 +0200 Subject: [PATCH 4/4] Temporary commit --- .../src/net/osmand/ToDoConstants.java | 15 +- .../data/preparation/IndexPoiCreator.java | 1 - .../osmand/plus/AmenityIndexRepository.java | 2 +- .../plus/AmenityIndexRepositoryBinary.java | 12 +- .../plus/AmenityIndexRepositoryOdb.java | 12 +- .../net/osmand/plus/AsyncLoadingThread.java | 310 ++++++++++++++++++ .../src/net/osmand/plus/ResourceManager.java | 220 ++----------- 7 files changed, 358 insertions(+), 214 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/AsyncLoadingThread.java diff --git a/DataExtractionOSM/src/net/osmand/ToDoConstants.java b/DataExtractionOSM/src/net/osmand/ToDoConstants.java index 973ed56580..fb59afb98c 100644 --- a/DataExtractionOSM/src/net/osmand/ToDoConstants.java +++ b/DataExtractionOSM/src/net/osmand/ToDoConstants.java @@ -9,11 +9,15 @@ public class ToDoConstants { // == Osmand application (TODO 127) == + + // TODO support cancelling poi search request! Do it in another thread (Check is cancelled()!!!) TODO transport progress + // TODO redesign Directions using GPX file! (One menu directions <-> switch 'Route') + // TODO test if voice properly inititialized (first command!) + // TODO prepare C++ version of routing algorithm // Map Refactoring // Remove notification from OsmAndMapTileView (?) // Index version - // 1. POI inside obf // 2. Multiple attributes for one point (amenity=circle, type=...) @@ -21,13 +25,9 @@ public class ToDoConstants { // !|| 125 || Introduce service layer rather than singletons and put all related into new package (services). Review architecture. Split some big classes. || // === Common issues === -// || 104 || Add activity to show current loaded indexes and information about them (Issue 366) || -// || 123 || Improve gpx file showing (very slow for big files) (Issue 412) || // || 110 || Use android voice for pronounce command (could be used in future to pronounce street) (Issue 70) || -// || 97 || For voice navigation consider current speed of vehicle. Especially when speed > 50 pronounce more than 200 m (Issue 420) || // || 111 || Investigate showing street name while driving (Issue 286) || // || 86 || Allow to add/edit custom tags to POI objects (Issue 44) || -// || 92 || Support poi index with standard map index and unify POI categories (unify done +, works very slow) (Issue 417) || // || 113 || Calculate speed cameras/bumps on the road (announce about them) (Issue 418) || @@ -43,13 +43,16 @@ public class ToDoConstants { /////////////////////////// DONE ////////////////////////////// // DONE ANDROID : +// || 104 || Add activity to show current loaded indexes and information about them (Issue 366) || // || 112 || Investigate exiting/minimizing app (Issue 214) || // || 122 || Frozen sqlite db images (bug?). When images are loaded into sqlite the whole map is frozen (issue 413) || // || 120 || Show icons over poi circle (issue 414) || // || 119 || Dialog on main screen tips and tricks (Issue 415) || // || 118 || Config switching between maps on different zoom levels <14 (using raster), > 14 vector (Issue 419) || // || 124 || Animated transition using only raster images (?) - skip animations (!) - don not render vectoring for animations (Issue 238) || - +// || 92 || Support poi index with standard map index and unify POI categories (unify done +, works very slow) (Issue 417) || +// || 97 || For voice navigation consider current speed of vehicle. Especially when speed > 50 pronounce more than 200 m (Issue 420) || +// || 123 || Improve gpx file showing (very slow for big files) (Issue 412) || // DONE SWING } diff --git a/DataExtractionOSM/src/net/osmand/data/preparation/IndexPoiCreator.java b/DataExtractionOSM/src/net/osmand/data/preparation/IndexPoiCreator.java index 37715a13ee..a8c6ecc5c5 100644 --- a/DataExtractionOSM/src/net/osmand/data/preparation/IndexPoiCreator.java +++ b/DataExtractionOSM/src/net/osmand/data/preparation/IndexPoiCreator.java @@ -554,7 +554,6 @@ public class IndexPoiCreator extends AbstractIndexPartCreator { } public static void main(String[] args) throws SQLException, FileNotFoundException, IOException { - // TODO support cancelling poi search request! Do it in another thread (Check is cancelled()!!!) long time = System.currentTimeMillis(); IndexPoiCreator poiCreator = new IndexPoiCreator(); // String fileSqlte = "/home/victor/projects/OsmAnd/data/osm-gen/POI/Ru-mow.poi.odb"; diff --git a/OsmAnd/src/net/osmand/plus/AmenityIndexRepository.java b/OsmAnd/src/net/osmand/plus/AmenityIndexRepository.java index 1ab2e9c2aa..9d32e47766 100644 --- a/OsmAnd/src/net/osmand/plus/AmenityIndexRepository.java +++ b/OsmAnd/src/net/osmand/plus/AmenityIndexRepository.java @@ -26,6 +26,6 @@ public interface AmenityIndexRepository { String filterId, List toFill, boolean fillFound); public void evaluateCachedAmenities(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, - PoiFilter filter, List toFill); + PoiFilter filter); } diff --git a/OsmAnd/src/net/osmand/plus/AmenityIndexRepositoryBinary.java b/OsmAnd/src/net/osmand/plus/AmenityIndexRepositoryBinary.java index 6a43d54840..74bebc660a 100644 --- a/OsmAnd/src/net/osmand/plus/AmenityIndexRepositoryBinary.java +++ b/OsmAnd/src/net/osmand/plus/AmenityIndexRepositoryBinary.java @@ -141,11 +141,11 @@ public class AmenityIndexRepositoryBinary implements AmenityIndexRepository { @Override public void evaluateCachedAmenities(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, - PoiFilter filter, List toFill) { - cTopLatitude = topLatitude + (topLatitude - bottomLatitude); - cBottomLatitude = bottomLatitude - (topLatitude - bottomLatitude); - cLeftLongitude = leftLongitude - (rightLongitude - leftLongitude); - cRightLongitude = rightLongitude + (rightLongitude - leftLongitude); + PoiFilter filter) { + cTopLatitude = topLatitude ; + cBottomLatitude = bottomLatitude ; + cLeftLongitude = leftLongitude ; + cRightLongitude = rightLongitude ; cFilterId = filter == null ? null : filter.getFilterId(); cZoom = zoom; // first of all put all entities in temp list in order to not freeze other read threads @@ -160,8 +160,6 @@ public class AmenityIndexRepositoryBinary implements AmenityIndexRepository { cachedObjects.addAll(tempList); } - checkCachedAmenities(topLatitude, leftLongitude, bottomLatitude, rightLongitude, cZoom, filter.getFilterId(), toFill, true); - } diff --git a/OsmAnd/src/net/osmand/plus/AmenityIndexRepositoryOdb.java b/OsmAnd/src/net/osmand/plus/AmenityIndexRepositoryOdb.java index eeeb184ff9..7121fe8d11 100644 --- a/OsmAnd/src/net/osmand/plus/AmenityIndexRepositoryOdb.java +++ b/OsmAnd/src/net/osmand/plus/AmenityIndexRepositoryOdb.java @@ -102,11 +102,11 @@ public class AmenityIndexRepositoryOdb extends BaseLocationIndexRepository toFill){ - cTopLatitude = topLatitude + (topLatitude -bottomLatitude); - cBottomLatitude = bottomLatitude - (topLatitude -bottomLatitude); - cLeftLongitude = leftLongitude - (rightLongitude - leftLongitude); - cRightLongitude = rightLongitude + (rightLongitude - leftLongitude); + public void evaluateCachedAmenities(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, PoiFilter filter){ + cTopLatitude = topLatitude ; + cBottomLatitude = bottomLatitude ; + cLeftLongitude = leftLongitude ; + cRightLongitude = rightLongitude ; cFilterId = filter == null? null :filter.getFilterId(); cZoom = zoom; // first of all put all entities in temp list in order to not freeze other read threads @@ -120,8 +120,6 @@ public class AmenityIndexRepositoryOdb extends BaseLocationIndexRepository toFill, boolean fillFound){ diff --git a/OsmAnd/src/net/osmand/plus/AsyncLoadingThread.java b/OsmAnd/src/net/osmand/plus/AsyncLoadingThread.java new file mode 100644 index 0000000000..8368e0d040 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/AsyncLoadingThread.java @@ -0,0 +1,310 @@ +package net.osmand.plus; + +import java.io.File; +import java.util.List; +import java.util.Stack; + +import android.os.Handler; +import android.os.Looper; + +import net.osmand.Algoritms; +import net.osmand.ResultMatcher; +import net.osmand.data.Amenity; +import net.osmand.data.MapTileDownloader; +import net.osmand.data.TransportStop; +import net.osmand.data.MapTileDownloader.DownloadRequest; +import net.osmand.data.MapTileDownloader.IMapDownloaderCallback; +import net.osmand.map.ITileSource; + +/** + * Thread to load map objects (POI, transport stops )async + */ +public class AsyncLoadingThread extends Thread { + + public static final int LIMIT_TRANSPORT = 200; + + private Handler asyncLoadingPoi; + + private Handler asyncLoadingTransport; + + Stack requests = new Stack(); + AmenityLoadRequest poiLoadRequest = null; + TransportLoadRequest transportLoadRequest = null; + + private final MapTileDownloader downloader = MapTileDownloader.getInstance(); + + private final ResourceManager resourceManger; + + public AsyncLoadingThread(ResourceManager resourceManger) { + super("Loader map objects (synchronizer)"); //$NON-NLS-1$ + this.resourceManger = resourceManger; + } + + private void startPoiLoadingThread() { + if (asyncLoadingPoi == null) { + Thread th = new Thread(new Runnable() { + @Override + public void run() { + Looper.prepare(); + asyncLoadingPoi = new Handler(); + Looper.loop(); + } + }, "Loading poi"); + th.start(); + } + while(asyncLoadingPoi != null){ + // wait + } + } + + private void startTransportLoadingThread() { + new Thread(new Runnable() { + @Override + public void run() { + Looper.prepare(); + asyncLoadingTransport = new Handler(); + Looper.loop(); + } + }, "Loading transport").start(); + while(asyncLoadingTransport != null){ + // wait + } + } + + + @Override + public void run() { + while (true) { + try { + boolean update = false; + boolean amenityLoaded = false; + boolean transportLoaded = false; + boolean mapLoaded = false; + int progress = 0; + if (downloader.isSomethingBeingDownloaded()) { + progress = BusyIndicator.STATUS_GREEN; + } + synchronized (resourceManger) { + if (resourceManger.getBusyIndicator() != null) { + + if (resourceManger.getContext().getRoutingHelper().isRouteBeingCalculated()) { + progress = BusyIndicator.STATUS_BLUE; + } else if (!requests.isEmpty()) { + progress = BusyIndicator.STATUS_BLACK; + } + resourceManger.getBusyIndicator().updateStatus(progress); + } + } + while (!requests.isEmpty()) { + Object req = requests.pop(); + if (req instanceof TileLoadDownloadRequest) { + TileLoadDownloadRequest r = (TileLoadDownloadRequest) req; + if (cacheOfImages.get(r.tileId) == null) { + update |= getRequestedImageTile(r) != null; + } + } else if (req instanceof AmenityLoadRequest) { + if (!amenityLoaded) { + if (poiLoadRequest == null || asyncLoadingPoi == null) { + startPoiLoadingThread(); + poiLoadRequest = (AmenityLoadRequest) req; + asyncLoadingPoi.post(poiLoadRequest.prepareToRun()); + } else if (poiLoadRequest.recalculateRequest((AmenityLoadRequest) req)) { + asyncLoadingPoi.post(poiLoadRequest.prepareToRun()); + } + amenityLoaded = true; + } + } else if (req instanceof TransportLoadRequest) { + if (!transportLoaded) { + if (transportLoadRequest == null || asyncLoadingTransport == null) { + startTransportLoadingThread(); + transportLoadRequest = (TransportLoadRequest) req; + asyncLoadingTransport.post(transportLoadRequest.prepareToRun()); + } else if (transportLoadRequest.recalculateRequest((TransportLoadRequest) req)) { + asyncLoadingTransport.post(transportLoadRequest.prepareToRun()); + } + transportLoaded = true; + } + } else if (req instanceof MapLoadRequest) { + if (!mapLoaded) { + MapLoadRequest r = (MapLoadRequest) req; + renderer.loadMap(r.tileBox, downloader.getDownloaderCallbacks()); + mapLoaded = true; + } + } + } + if (update || amenityLoaded || transportLoaded || mapLoaded) { + // use downloader callback + for (IMapDownloaderCallback c : downloader.getDownloaderCallbacks()) { + c.tileDownloaded(null); + } + } + boolean routeBeingCalculated = resourceManger.getContext().getRoutingHelper().isRouteBeingCalculated(); + if (progress != 0 || routeBeingCalculated || downloader.isSomethingBeingDownloaded()) { + synchronized (resourceManger) { + if (resourceManger.getBusyIndicator() != null) { + if (routeBeingCalculated) { + progress = BusyIndicator.STATUS_BLUE; + } else if (downloader.isSomethingBeingDownloaded()) { + progress = BusyIndicator.STATUS_GREEN; + } else { + progress = 0; + } + resourceManger.getBusyIndicator().updateStatus(progress); + } + } + } + sleep(750); + } catch (InterruptedException e) { + log.error(e, e); + } catch (RuntimeException e) { + log.error(e, e); + } + } + } + + public void requestToLoadImage(TileLoadDownloadRequest req) { + requests.push(req); + } + + public void requestToLoadAmenities(AmenityLoadRequest req) { + requests.push(req); + } + + public void requestToLoadMap(MapLoadRequest req) { + requests.push(req); + } + + public void requestToLoadTransport(TransportLoadRequest req) { + requests.push(req); + } + + protected static class TileLoadDownloadRequest extends DownloadRequest { + + public final String tileId; + public final File dirWithTiles; + public final ITileSource tileSource; + + public TileLoadDownloadRequest(File dirWithTiles, String url, File fileToSave, String tileId, ITileSource source, int tileX, + int tileY, int zoom) { + super(url, fileToSave, tileX, tileY, zoom); + this.dirWithTiles = dirWithTiles; + this.tileSource = source; + this.tileId = tileId; + } + } + + protected static class MapObjectLoadRequest implements ResultMatcher { + protected double topLatitude; + protected double bottomLatitude; + protected double leftLongitude; + protected double rightLongitude; + protected boolean cancelled = false; + + public boolean isContains(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude) { + boolean inside = this.topLatitude >= topLatitude && this.leftLongitude <= leftLongitude + && this.rightLongitude >= rightLongitude && this.bottomLatitude <= bottomLatitude; + return inside; + } + + public void setBoundaries(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude) { + this.topLatitude = topLatitude; + this.bottomLatitude = bottomLatitude; + this.leftLongitude = leftLongitude; + this.rightLongitude = rightLongitude; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public boolean publish(T object) { + return true; + } + + } + + protected static class AmenityLoadRequest extends MapObjectLoadRequest { + private final List res; + private final PoiFilter filter; + private final int zoom; + + public AmenityLoadRequest(List repos, int zoom, PoiFilter filter) { + super(); + this.res = repos; + this.zoom = zoom; + this.filter = filter; + } + + public Runnable prepareToRun() { + final double ntopLatitude = topLatitude + (topLatitude - bottomLatitude); + final double nbottomLatitude = bottomLatitude - (topLatitude - bottomLatitude); + final double nleftLongitude = leftLongitude - (rightLongitude - leftLongitude); + final double nrightLongitude = rightLongitude + (rightLongitude - leftLongitude); + setBoundaries(ntopLatitude, nleftLongitude, nbottomLatitude, nrightLongitude); + return new Runnable() { + @Override + public void run() { + for (AmenityIndexRepository repository : res) { + repository.evaluateCachedAmenities(ntopLatitude, nleftLongitude, nbottomLatitude, nrightLongitude, zoom, filter); + } + } + }; + } + + public boolean recalculateRequest(AmenityLoadRequest req) { + if (this.zoom != req.zoom || !Algoritms.objectEquals(this.filter, req.filter)) { + return true; + } + return !isContains(req.topLatitude, req.leftLongitude, req.bottomLatitude, req.rightLongitude); + } + + } + + protected static class TransportLoadRequest extends MapObjectLoadRequest { + private final List repos; + private int zoom; + + public TransportLoadRequest(List repos, int zoom) { + super(); + this.repos = repos; + this.zoom = zoom; + } + + public Runnable prepareToRun() { + final double ntopLatitude = topLatitude + (topLatitude - bottomLatitude); + final double nbottomLatitude = bottomLatitude - (topLatitude - bottomLatitude); + final double nleftLongitude = leftLongitude - (rightLongitude - leftLongitude); + final double nrightLongitude = rightLongitude + (rightLongitude - leftLongitude); + setBoundaries(ntopLatitude, nleftLongitude, nbottomLatitude, nrightLongitude); + return new Runnable() { + @Override + public void run() { + for (TransportIndexRepository repository : repos) { + repository.evaluateCachedTransportStops(ntopLatitude, nleftLongitude, nbottomLatitude, nrightLongitude, zoom, + LIMIT_TRANSPORT, this); + } + } + }; + } + + public boolean recalculateRequest(AmenityLoadRequest req) { + if (this.zoom != req.zoom) { + return true; + } + return !isContains(req.topLatitude, req.leftLongitude, req.bottomLatitude, req.rightLongitude); + } + + } + + protected static class MapLoadRequest { + public final RotatedTileBox tileBox; + + public MapLoadRequest(RotatedTileBox tileBox) { + super(); + this.tileBox = tileBox; + } + } + +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/ResourceManager.java b/OsmAnd/src/net/osmand/plus/ResourceManager.java index 048d562e8c..77bf791355 100644 --- a/OsmAnd/src/net/osmand/plus/ResourceManager.java +++ b/OsmAnd/src/net/osmand/plus/ResourceManager.java @@ -15,7 +15,6 @@ import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Stack; import java.util.TreeMap; import net.osmand.Algoritms; @@ -30,10 +29,13 @@ import net.osmand.data.IndexConstants; import net.osmand.data.MapTileDownloader; import net.osmand.data.TransportStop; import net.osmand.data.MapTileDownloader.DownloadRequest; -import net.osmand.data.MapTileDownloader.IMapDownloaderCallback; import net.osmand.map.ITileSource; import net.osmand.osm.LatLon; import net.osmand.osm.MapUtils; +import net.osmand.plus.AsyncLoadingThread.AmenityLoadRequest; +import net.osmand.plus.AsyncLoadingThread.MapLoadRequest; +import net.osmand.plus.AsyncLoadingThread.TileLoadDownloadRequest; +import net.osmand.plus.AsyncLoadingThread.TransportLoadRequest; import net.osmand.plus.activities.OsmandApplication; import net.osmand.plus.render.BaseOsmandRender; import net.osmand.plus.render.MapRenderRepositories; @@ -70,7 +72,6 @@ public class ResourceManager { public static final String TEMP_SOURCE_TO_LOAD = "temp"; //$NON-NLS-1$ public static final String VECTOR_MAP = "#vector_map"; //$NON-NLS-1$ - public static final int LIMIT_TRANSPORT = 200; private static final Log log = LogUtil.getLog(ResourceManager.class); private static final String MINE_POI_DB = APP_DIR + "mine"+ IndexConstants.POI_INDEX_EXT; @@ -92,7 +93,7 @@ public class ResourceManager { private BusyIndicator busyIndicator; - private final MapTileDownloader downloader = MapTileDownloader.getInstance(); + // Indexes private final Map addressMap = new TreeMap(Collator.getInstance()); @@ -107,20 +108,18 @@ public class ResourceManager { protected final MapRenderRepositories renderer; - public final AsyncLoadingThread asyncLoadingTiles = new AsyncLoadingThread(); + public final AsyncLoadingThread asyncLoadingTthread = new AsyncLoadingThread(this); protected boolean internetIsNotAccessible = false; protected AmenityIndexRepositoryOdb updatablePoiDb = null; - public ResourceManager(OsmandApplication context) { this.context = context; this.renderer = new MapRenderRepositories(context); - asyncLoadingTiles.start(); + asyncLoadingTthread.start(); resetStoreDirectory(); - WindowManager mgr = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); DisplayMetrics dm = new DisplayMetrics(); mgr.getDefaultDisplay().getMetrics(dm); @@ -131,6 +130,7 @@ public class ResourceManager { maxImgCacheSize = (int) (tiles) ; } + public void resetStoreDirectory() { dirWithTiles = context.getSettings().extendOsmandPath(TILES_PATH); dirWithTiles.mkdirs(); @@ -300,7 +300,7 @@ public class ResourceManager { if(sync){ return getRequestedImageTile(req); } else { - asyncLoadingTiles.requestToLoadImage(req); + asyncLoadingTthread.requestToLoadImage(req); } } return cacheOfImages.get(tileId); @@ -667,18 +667,22 @@ public class ResourceManager { toFill.add(a); } } - } else { String filterId = filter == null ? null : filter.getFilterId(); + List repos = new ArrayList(); for (AmenityIndexRepository index : amenityRepositories) { if (index.checkContains(topLatitude, leftLongitude, bottomLatitude, rightLongitude)) { if (!index.checkCachedAmenities(topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom, filterId, toFill, true)) { - asyncLoadingTiles.requestToLoadAmenities(new AmenityLoadRequest(index, topLatitude, leftLongitude, bottomLatitude, - rightLongitude, zoom, filter)); + repos.add(index); } } } + if(!repos.isEmpty()){ + AmenityLoadRequest req = new AmenityLoadRequest(repos, zoom, filter); + req.setBoundaries(topLatitude, leftLongitude, bottomLatitude, rightLongitude); + asyncLoadingTthread.requestToLoadAmenities(req); + } } } @@ -705,14 +709,19 @@ public class ResourceManager { public void searchTransportAsync(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, List toFill){ - for(TransportIndexRepository index : transportRepositories){ - if(index.checkContains(topLatitude, leftLongitude, bottomLatitude, rightLongitude)){ - if(!index.checkCachedObjects(topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom, toFill, true)){ - asyncLoadingTiles.requestToLoadTransport( - new TransportLoadRequest(index, topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom)); + List repos = new ArrayList(); + for (TransportIndexRepository index : transportRepositories) { + if (index.checkContains(topLatitude, leftLongitude, bottomLatitude, rightLongitude)) { + if (!index.checkCachedObjects(topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom, toFill, true)) { + repos.add(index); } } } + if(!repos.isEmpty()){ + TransportLoadRequest req = new TransportLoadRequest(repos, zoom); + req.setBoundaries(topLatitude, leftLongitude, bottomLatitude, rightLongitude); + asyncLoadingTthread.requestToLoadTransport(req); + } } ////////////////////////////////////////////// Working with map //////////////////////////////////////////////// @@ -722,7 +731,7 @@ public class ResourceManager { public void updateRendererMap(RotatedTileBox rotatedTileBox){ renderer.interruptLoadingMap(); - asyncLoadingTiles.requestToLoadMap( + asyncLoadingTthread.requestToLoadMap( new MapLoadRequest(new RotatedTileBox(rotatedTileBox))); } @@ -828,177 +837,4 @@ public class ResourceManager { cacheOfImages.remove(list.get(i)); } } - - - private static class TileLoadDownloadRequest extends DownloadRequest { - - public final String tileId; - public final File dirWithTiles; - public final ITileSource tileSource; - - public TileLoadDownloadRequest(File dirWithTiles, String url, File fileToSave, - String tileId, ITileSource source, int tileX, int tileY, int zoom) { - super(url, fileToSave, tileX, tileY, zoom); - this.dirWithTiles = dirWithTiles; - this.tileSource = source; - this.tileId = tileId; - } - } - - private static class AmenityLoadRequest { - public final AmenityIndexRepository repository; - public final double topLatitude; - public final double bottomLatitude; - public final double leftLongitude; - public final double rightLongitude; - public final PoiFilter filter; - public final int zoom; - - public AmenityLoadRequest(AmenityIndexRepository repository, double topLatitude, double leftLongitude, - double bottomLatitude, double rightLongitude, int zoom, PoiFilter filter) { - super(); - this.bottomLatitude = bottomLatitude; - this.leftLongitude = leftLongitude; - this.repository = repository; - this.rightLongitude = rightLongitude; - this.topLatitude = topLatitude; - this.zoom = zoom; - this.filter = filter; - } - } - - - - private static class TransportLoadRequest { - public final TransportIndexRepository repository; - public final double topLatitude; - public final double bottomLatitude; - public final double leftLongitude; - public final double rightLongitude; - public final int zoom; - - public TransportLoadRequest(TransportIndexRepository repository, double topLatitude, double leftLongitude, - double bottomLatitude, double rightLongitude, int zoom) { - super(); - this.bottomLatitude = bottomLatitude; - this.leftLongitude = leftLongitude; - this.repository = repository; - this.rightLongitude = rightLongitude; - this.topLatitude = topLatitude; - this.zoom = zoom; - } - } - - private static class MapLoadRequest { - public final RotatedTileBox tileBox; - - public MapLoadRequest(RotatedTileBox tileBox) { - super(); - this.tileBox = tileBox; - } - } - - public class AsyncLoadingThread extends Thread { - Stack requests = new Stack(); - - public AsyncLoadingThread(){ - super("Loader map objects (tiles, poi)"); //$NON-NLS-1$ - } - - @Override - public void run() { - while(true){ - try { - boolean update = false; - boolean amenityLoaded = false; - boolean transportLoaded = false; - boolean mapLoaded = false; - int progress = 0; - if(downloader.isSomethingBeingDownloaded()){ - progress = BusyIndicator.STATUS_GREEN; - } - synchronized(ResourceManager.this){ - if(busyIndicator != null){ - if(context.getRoutingHelper().isRouteBeingCalculated()){ - progress = BusyIndicator.STATUS_BLUE; - } else if(!requests.isEmpty()){ - progress = BusyIndicator.STATUS_BLACK;; - } - busyIndicator.updateStatus(progress); - } - } - while(!requests.isEmpty()){ - Object req = requests.pop(); - if (req instanceof TileLoadDownloadRequest) { - TileLoadDownloadRequest r = (TileLoadDownloadRequest) req; - if (cacheOfImages.get(r.tileId) == null) { - update |= getRequestedImageTile(r) != null; - } - } else if(req instanceof AmenityLoadRequest){ - if(!amenityLoaded){ - AmenityLoadRequest r = (AmenityLoadRequest) req; - r.repository.evaluateCachedAmenities(r.topLatitude, r.leftLongitude, - r.bottomLatitude, r.rightLongitude, r.zoom, r.filter, null); - amenityLoaded = true; - } - } else if(req instanceof TransportLoadRequest){ - if(!transportLoaded){ - TransportLoadRequest r = (TransportLoadRequest) req; - r.repository.evaluateCachedTransportStops(r.topLatitude, r.leftLongitude, - r.bottomLatitude, r.rightLongitude, r.zoom, LIMIT_TRANSPORT, null); - transportLoaded = true; - } - } else if(req instanceof MapLoadRequest){ - if(!mapLoaded){ - MapLoadRequest r = (MapLoadRequest) req; - renderer.loadMap(r.tileBox, downloader.getDownloaderCallbacks()); - mapLoaded = true; - } - } - } - if(update || amenityLoaded || transportLoaded || mapLoaded){ - // use downloader callback - for(IMapDownloaderCallback c : downloader.getDownloaderCallbacks()){ - c.tileDownloaded(null); - } - } - boolean routeBeingCalculated = context.getRoutingHelper().isRouteBeingCalculated(); - if (progress != 0 || routeBeingCalculated || downloader.isSomethingBeingDownloaded()) { - synchronized (ResourceManager.this) { - if (busyIndicator != null) { - if(routeBeingCalculated){ - progress = BusyIndicator.STATUS_BLUE; - } else if(downloader.isSomethingBeingDownloaded()){ - progress = BusyIndicator.STATUS_GREEN; - } else { - progress = 0; - } - busyIndicator.updateStatus(progress); - } - } - } - sleep(750); - } catch (InterruptedException e) { - log.error(e, e); - } catch (RuntimeException e){ - log.error(e, e); - } - } - } - - public void requestToLoadImage(TileLoadDownloadRequest req){ - requests.push(req); - } - public void requestToLoadAmenities(AmenityLoadRequest req){ - requests.push(req); - } - - public void requestToLoadMap(MapLoadRequest req){ - requests.push(req); - } - - public void requestToLoadTransport(TransportLoadRequest req){ - requests.push(req); - } - }; -} \ No newline at end of file + } \ No newline at end of file