implement poi search using binary format
git-svn-id: https://osmand.googlecode.com/svn/trunk@788 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
parent
787a3e4497
commit
54672c3902
14 changed files with 547 additions and 296 deletions
|
@ -1,7 +1,6 @@
|
|||
package net.osmand.binary;
|
||||
|
||||
import net.osmand.binary.BinaryMapIndexReader.MapIndex;
|
||||
import net.osmand.osm.MapRenderingTypes;
|
||||
|
||||
public class BinaryMapDataObject {
|
||||
protected int[] coordinates = null;
|
||||
|
|
|
@ -1612,7 +1612,7 @@ public class BinaryMapIndexReader {
|
|||
|
||||
boolean accept = true;
|
||||
if (req.searchFilter != null) {
|
||||
accept = req.searchFilter.accept(req.cacheTypes);
|
||||
accept = req.searchFilter.accept(req.cacheTypes, root);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1722,6 +1722,7 @@ public class BinaryMapIndexReader {
|
|||
return request;
|
||||
}
|
||||
|
||||
|
||||
public static SearchRequest<TransportStop> buildSearchTransportRequest(int sleft, int sright, int stop, int sbottom, int limit, List<TransportStop> stops){
|
||||
SearchRequest<TransportStop> request = new SearchRequest<TransportStop>();
|
||||
if (stops != null) {
|
||||
|
@ -1747,11 +1748,12 @@ public class BinaryMapIndexReader {
|
|||
|
||||
public static interface SearchFilter {
|
||||
|
||||
public boolean accept(TIntArrayList types);
|
||||
public boolean accept(TIntArrayList types, MapIndex index);
|
||||
|
||||
}
|
||||
|
||||
public static class SearchRequest<T> {
|
||||
// 31 zoom tiles
|
||||
int left = 0;
|
||||
int right = 0;
|
||||
int top = 0;
|
||||
|
@ -1812,6 +1814,15 @@ public class BinaryMapIndexReader {
|
|||
return decodingRules.get(((subtype << 5) | type));
|
||||
}
|
||||
|
||||
public TagValuePair decodeType(int wholeType){
|
||||
if((wholeType & 3) != MapRenderingTypes.POINT_TYPE ){
|
||||
wholeType = (wholeType >> 2) & MapRenderingTypes.MASK_10;
|
||||
} else {
|
||||
wholeType >>= 2;
|
||||
}
|
||||
return decodingRules.get(wholeType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class TagValuePair {
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
<string name="general_settings">Общие</string>
|
||||
<string name="rendering_settings_descr">Выбрать источник карты и внешний вид</string>
|
||||
<string name="rendering_settings">Карта</string>
|
||||
<string name="index_settings_descr">Загрузить и обновить индексы</string>
|
||||
<string name="index_settings">Данные для офлайн использования</string>
|
||||
<string name="index_settings_descr">Загрузить и обновить данные для офлайн использования</string>
|
||||
<string name="index_settings">Данные</string>
|
||||
<string name="osmand_service">Фоновый режим</string>
|
||||
<string name="osmand_service_descr">Запустить OsmAnd в фоновом режиме для записи трека и навигации</string>
|
||||
<string name="fast_route_mode">Наибыстрейший маршрут</string>
|
||||
|
|
|
@ -1,256 +1,29 @@
|
|||
package net.osmand;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.AmenityType;
|
||||
import net.osmand.data.index.IndexConstants;
|
||||
import net.osmand.osm.Entity;
|
||||
import net.osmand.osm.LatLon;
|
||||
import net.osmand.osm.MapUtils;
|
||||
import net.osmand.osm.Node;
|
||||
import net.osmand.osm.io.IOsmStorageFilter;
|
||||
import net.osmand.osm.io.OsmBaseStorage;
|
||||
import net.sf.junidecode.Junidecode;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.xml.sax.SAXException;
|
||||
public interface AmenityIndexRepository {
|
||||
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteStatement;
|
||||
public void close();
|
||||
|
||||
public boolean checkContains(double latitude, double longitude);
|
||||
|
||||
public class AmenityIndexRepository extends BaseLocationIndexRepository<Amenity> {
|
||||
private static final Log log = LogUtil.getLog(AmenityIndexRepository.class);
|
||||
public final static int LIMIT_AMENITIES = 500;
|
||||
public boolean checkContains(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude);
|
||||
|
||||
|
||||
// cache amenities
|
||||
private String cFilterId;
|
||||
|
||||
|
||||
private final String[] columns = new String[]{"id", "x", "y", "name", "name_en", "type", "subtype", "opening_hours", "phone", "site"}; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$//$NON-NLS-5$//$NON-NLS-6$//$NON-NLS-7$//$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
|
||||
public List<Amenity> searchAmenities(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int limit, PoiFilter filter, List<Amenity> amenities){
|
||||
long now = System.currentTimeMillis();
|
||||
String squery = "? < y AND y < ? AND ? < x AND x < ?"; //$NON-NLS-1$
|
||||
|
||||
if(filter != null){
|
||||
String sql = filter.buildSqlWhereFilter();
|
||||
if(sql != null){
|
||||
squery += " AND " + sql; //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
if(limit != -1){
|
||||
squery += " ORDER BY RANDOM() LIMIT " +limit; //$NON-NLS-1$
|
||||
}
|
||||
Cursor query = db.query(IndexConstants.POI_TABLE, columns, squery,
|
||||
new String[]{MapUtils.get31TileNumberY(topLatitude)+"", //$NON-NLS-1$
|
||||
MapUtils.get31TileNumberY(bottomLatitude)+"", MapUtils.get31TileNumberX(leftLongitude)+"", //$NON-NLS-1$ //$NON-NLS-2$
|
||||
MapUtils.get31TileNumberX(rightLongitude)+""}, null, null, null); //$NON-NLS-1$
|
||||
if(query.moveToFirst()){
|
||||
do {
|
||||
Amenity am = new Amenity();
|
||||
am.setId(query.getLong(0));
|
||||
am.setLocation(MapUtils.get31LatitudeY(query.getInt(2)),
|
||||
MapUtils.get31LongitudeX(query.getInt(1)));
|
||||
am.setName(query.getString(3 ));
|
||||
am.setEnName(query.getString(4));
|
||||
if(am.getEnName().length() == 0){
|
||||
am.setEnName(Junidecode.unidecode(am.getName()));
|
||||
}
|
||||
am.setType(AmenityType.fromString(query.getString(5)));
|
||||
am.setSubType(query.getString(6));
|
||||
am.setOpeningHours(query.getString(7));
|
||||
am.setPhone(query.getString(8));
|
||||
am.setSite(query.getString(9));
|
||||
amenities.add(am);
|
||||
if(limit != -1 && amenities.size() >= limit){
|
||||
break;
|
||||
}
|
||||
} while(query.moveToNext());
|
||||
}
|
||||
query.close();
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(String.format("Search for %s done in %s ms found %s.", //$NON-NLS-1$
|
||||
topLatitude + " " + leftLongitude, System.currentTimeMillis() - now, amenities.size())); //$NON-NLS-1$
|
||||
}
|
||||
return amenities;
|
||||
}
|
||||
|
||||
public boolean addAmenity(Amenity a){
|
||||
insertAmenities(Collections.singleton(a));
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean updateAmenity(Amenity a){
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append("UPDATE " + IndexConstants.POI_TABLE + " SET "); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
b.append(" x = ?, "). //$NON-NLS-1$
|
||||
append(" y = ?, "). //$NON-NLS-1$
|
||||
append(" opening_hours = ?, "). //$NON-NLS-1$
|
||||
append(" name = ?, "). //$NON-NLS-1$
|
||||
append(" name_en = ?, ").//$NON-NLS-1$
|
||||
append(" type = ?, "). //$NON-NLS-1$
|
||||
append(" subtype = ? "). //$NON-NLS-1$
|
||||
append(" site = ? "). //$NON-NLS-1$
|
||||
append(" phone = ? "). //$NON-NLS-1$
|
||||
append(" WHERE append( id = ?"); //$NON-NLS-1$
|
||||
|
||||
db.execSQL(b.toString(),
|
||||
new Object[] { MapUtils.get31TileNumberX(a.getLocation().getLongitude()), MapUtils.get31TileNumberY(a.getLocation().getLatitude()),
|
||||
a.getOpeningHours(), a.getName(), a.getEnName(), AmenityType.valueToString(a.getType()), a.getSubType(),
|
||||
a.getSite(), a.getPhone(), a.getId()});
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean deleteAmenities(long id){
|
||||
db.execSQL("DELETE FROM " + IndexConstants.POI_TABLE+ " WHERE id="+id); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public synchronized void clearCache(){
|
||||
super.clearCache();
|
||||
cFilterId = null;
|
||||
}
|
||||
|
||||
public void evaluateCachedAmenities(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, int limit, PoiFilter filter, List<Amenity> toFill){
|
||||
cTopLatitude = topLatitude + (topLatitude -bottomLatitude);
|
||||
cBottomLatitude = bottomLatitude - (topLatitude -bottomLatitude);
|
||||
cLeftLongitude = leftLongitude - (rightLongitude - leftLongitude);
|
||||
cRightLongitude = rightLongitude + (rightLongitude - leftLongitude);
|
||||
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
|
||||
ArrayList<Amenity> tempList = new ArrayList<Amenity>();
|
||||
searchAmenities(cTopLatitude, cLeftLongitude, cBottomLatitude, cRightLongitude, limit, filter, tempList);
|
||||
synchronized (this) {
|
||||
cachedObjects.clear();
|
||||
cachedObjects.addAll(tempList);
|
||||
}
|
||||
|
||||
checkCachedAmenities(topLatitude, leftLongitude, bottomLatitude, rightLongitude, cZoom, filter.getFilterId(), toFill);
|
||||
}
|
||||
/**
|
||||
* Search amenities in the specified box doesn't cache results
|
||||
*/
|
||||
public List<Amenity> searchAmenities(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int limit,
|
||||
PoiFilter filter, List<Amenity> amenities);
|
||||
|
||||
public synchronized boolean checkCachedAmenities(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, String filterId, List<Amenity> toFill, boolean fillFound){
|
||||
if (db == null) {
|
||||
return true;
|
||||
}
|
||||
boolean inside = cTopLatitude >= topLatitude && cLeftLongitude <= leftLongitude && cRightLongitude >= rightLongitude
|
||||
&& cBottomLatitude <= bottomLatitude && zoom == cZoom;
|
||||
boolean noNeedToSearch = inside && Algoritms.objectEquals(filterId, cFilterId);
|
||||
if((inside || fillFound) && toFill != null && Algoritms.objectEquals(filterId, cFilterId)){
|
||||
for(Amenity a : cachedObjects){
|
||||
LatLon location = a.getLocation();
|
||||
if (location.getLatitude() <= topLatitude && location.getLongitude() >= leftLongitude && location.getLongitude() <= rightLongitude
|
||||
&& location.getLatitude() >= bottomLatitude) {
|
||||
toFill.add(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
return noNeedToSearch;
|
||||
}
|
||||
public boolean checkCachedAmenities(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, String filterId, List<Amenity> toFill){
|
||||
return checkCachedAmenities(topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom, filterId, toFill, false);
|
||||
}
|
||||
|
||||
public boolean initialize(final IProgress progress, File file) {
|
||||
return super.initialize(progress, file, IndexConstants.POI_TABLE_VERSION, IndexConstants.POI_TABLE, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean updateAmenities(List<Amenity> amenities, double leftLon, double topLat, double rightLon, double bottomLat){
|
||||
int l = MapUtils.get31TileNumberX(leftLon);
|
||||
int r = MapUtils.get31TileNumberX(rightLon);
|
||||
int t = MapUtils.get31TileNumberY(topLat);
|
||||
int b = MapUtils.get31TileNumberY(bottomLat);
|
||||
db.execSQL("DELETE FROM " + IndexConstants.POI_TABLE + " WHERE " + //$NON-NLS-1$ //$NON-NLS-2$
|
||||
" x >= ? AND ? >= x AND " + //$NON-NLS-1$
|
||||
" y >= ? AND ? >= y ", new Integer[] { l, r, t, b }); //$NON-NLS-1$
|
||||
|
||||
insertAmenities(amenities);
|
||||
return true;
|
||||
}
|
||||
public void clearCache();
|
||||
|
||||
private void insertAmenities(Collection<Amenity> amenities) {
|
||||
SQLiteStatement stat = db.compileStatement("DELETE FROM " + IndexConstants.POI_TABLE + " WHERE id = ?"); //$NON-NLS-1$//$NON-NLS-2$
|
||||
for (Amenity a : amenities) {
|
||||
stat.bindLong(1, a.getId());
|
||||
stat.execute();
|
||||
}
|
||||
stat.close();
|
||||
stat = db.compileStatement("INSERT INTO " + IndexConstants.POI_TABLE + //$NON-NLS-1$
|
||||
"(id, x, y, name_en, name, type, subtype, opening_hours, site, phone) values(?,?,?,?,?,?,?,?,?,?)"); //$NON-NLS-1$
|
||||
for (Amenity a : amenities) {
|
||||
stat.bindLong(1, a.getId());
|
||||
stat.bindDouble(2, MapUtils.get31TileNumberX(a.getLocation().getLongitude()));
|
||||
stat.bindDouble(3, MapUtils.get31TileNumberY(a.getLocation().getLatitude()));
|
||||
bindString(stat, 4, a.getEnName());
|
||||
bindString(stat, 5, a.getName());
|
||||
bindString(stat, 6, AmenityType.valueToString(a.getType()));
|
||||
bindString(stat, 7, a.getSubType());
|
||||
bindString(stat, 8 , a.getOpeningHours());
|
||||
bindString(stat, 9, a.getSite());
|
||||
bindString(stat, 10, a.getPhone());
|
||||
stat.execute();
|
||||
}
|
||||
stat.close();
|
||||
}
|
||||
public boolean checkCachedAmenities(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom,
|
||||
String filterId, List<Amenity> toFill, boolean fillFound);
|
||||
|
||||
private final static String SITE_API = "http://api.openstreetmap.org/"; //$NON-NLS-1$
|
||||
|
||||
public static boolean loadingPOIs(List<Amenity> amenities, double leftLon, double topLat, double righLon, double bottomLat) {
|
||||
try {
|
||||
// bbox=left,bottom,right,top
|
||||
String u = SITE_API+"api/0.6/map?bbox="+leftLon+","+bottomLat+","+righLon+","+topLat; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
|
||||
URL url = new URL(u);
|
||||
log.info("Start loading poi : " + u); //$NON-NLS-1$
|
||||
InputStream is = url.openStream();
|
||||
OsmBaseStorage st = new OsmBaseStorage();
|
||||
final Map<Amenity, Entity> amen = new LinkedHashMap<Amenity, Entity>();
|
||||
final List<Amenity> tempList = new ArrayList<Amenity>();
|
||||
st.getFilters().add(new IOsmStorageFilter(){
|
||||
@Override
|
||||
public boolean acceptEntityToLoad(OsmBaseStorage storage, Entity.EntityId id, Entity entity) {
|
||||
Amenity.parseAmenities(entity, tempList);
|
||||
if(!tempList.isEmpty()){
|
||||
for(Amenity a : tempList){
|
||||
amen.put(a, entity);
|
||||
}
|
||||
tempList.clear();
|
||||
return true;
|
||||
}
|
||||
// to
|
||||
return entity instanceof Node;
|
||||
}
|
||||
});
|
||||
st.parseOSM(is, null, null, false);
|
||||
for (Amenity am : amen.keySet()) {
|
||||
// update location (when all nodes of way are loaded)
|
||||
am.setEntity(amen.get(am));
|
||||
if(am.getEnName().length() == 0){
|
||||
am.setEnName(Junidecode.unidecode(am.getName()));
|
||||
}
|
||||
amenities.add(am);
|
||||
}
|
||||
log.info("Loaded " +amenities.size() + " amenities"); //$NON-NLS-1$//$NON-NLS-2$
|
||||
} catch (IOException e) {
|
||||
log.error("Loading nodes failed", e); //$NON-NLS-1$
|
||||
return false;
|
||||
} catch (SAXException e) {
|
||||
log.error("Loading nodes failed", e); //$NON-NLS-1$
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public void evaluateCachedAmenities(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom,
|
||||
int limitPoi, PoiFilter filter, List<Amenity> toFill);
|
||||
}
|
||||
|
|
188
OsmAnd/src/net/osmand/AmenityIndexRepositoryBinary.java
Normal file
188
OsmAnd/src/net/osmand/AmenityIndexRepositoryBinary.java
Normal file
|
@ -0,0 +1,188 @@
|
|||
package net.osmand;
|
||||
|
||||
import gnu.trove.list.array.TIntArrayList;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import net.osmand.binary.BinaryIndexPart;
|
||||
import net.osmand.binary.BinaryMapDataObject;
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.binary.BinaryMapIndexReader.MapIndex;
|
||||
import net.osmand.binary.BinaryMapIndexReader.MapRoot;
|
||||
import net.osmand.binary.BinaryMapIndexReader.SearchFilter;
|
||||
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
|
||||
import net.osmand.binary.BinaryMapIndexReader.TagValuePair;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.AmenityType;
|
||||
import net.osmand.osm.MapRenderingTypes;
|
||||
import net.osmand.osm.MapUtils;
|
||||
import net.sf.junidecode.Junidecode;
|
||||
|
||||
public class AmenityIndexRepositoryBinary implements AmenityIndexRepository {
|
||||
|
||||
private final static Log log = LogUtil.getLog(AmenityIndexRepositoryBinary.class);
|
||||
private final BinaryMapIndexReader index;
|
||||
|
||||
public AmenityIndexRepositoryBinary(BinaryMapIndexReader index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
index.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean checkContains(double latitude, double longitude) {
|
||||
int x = MapUtils.get31TileNumberX(longitude);
|
||||
int y = MapUtils.get31TileNumberY(latitude);
|
||||
for(BinaryIndexPart i : index.getIndexes()){
|
||||
if(i instanceof MapIndex){
|
||||
List<MapRoot> rs = ((MapIndex) i).getRoots();
|
||||
if(!rs.isEmpty()){
|
||||
MapRoot rt = rs.get(0);
|
||||
if(rt.getLeft() <= x && rt.getRight() >= x &&
|
||||
rt.getTop() <= y && rt.getBottom() >= y){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkContains(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude) {
|
||||
int leftX = MapUtils.get31TileNumberX(leftLongitude);
|
||||
int rightX = MapUtils.get31TileNumberX(rightLongitude);
|
||||
int bottomY = MapUtils.get31TileNumberY(bottomLatitude);
|
||||
int topY = MapUtils.get31TileNumberY(topLatitude);
|
||||
for(BinaryIndexPart i : index.getIndexes()){
|
||||
if(i instanceof MapIndex){
|
||||
List<MapRoot> rs = ((MapIndex) i).getRoots();
|
||||
if(!rs.isEmpty()){
|
||||
MapRoot rt = rs.get(0);
|
||||
if(rightX < rt.getLeft() || leftX > rt.getRight()){
|
||||
continue;
|
||||
}
|
||||
if(topY > rt.getBottom() || bottomY < rt.getTop()){
|
||||
continue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Amenity> searchAmenities(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int limit,
|
||||
final PoiFilter filter, final List<Amenity> amenities) {
|
||||
long now = System.currentTimeMillis();
|
||||
int sleft = MapUtils.get31TileNumberX(leftLongitude);
|
||||
int sright = MapUtils.get31TileNumberX(rightLongitude);
|
||||
int sbottom = MapUtils.get31TileNumberY(bottomLatitude);
|
||||
int stop = MapUtils.get31TileNumberY(topLatitude);
|
||||
|
||||
SearchRequest<BinaryMapDataObject> req = BinaryMapIndexReader.buildSearchRequest(sleft, sright, stop, sbottom, 16);
|
||||
req.setSearchFilter(new SearchFilter(){
|
||||
|
||||
@Override
|
||||
public boolean accept(TIntArrayList types, MapIndex root) {
|
||||
for (int j = 0; j < types.size(); j++) {
|
||||
int wholeType = types.get(j);
|
||||
TagValuePair pair = root.decodeType(wholeType);
|
||||
if (pair != null) {
|
||||
AmenityType type = MapRenderingTypes.getAmenityType(pair.tag, pair.value);
|
||||
if (type != null) {
|
||||
if(filter.acceptTypeSubtype(type, MapRenderingTypes.getAmenitySubtype(pair.tag, pair.value))){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
});
|
||||
try {
|
||||
index.searchMapIndex(req);
|
||||
for(BinaryMapDataObject o : req.getSearchResults()){
|
||||
if(o.getPointsLength() == 0){
|
||||
continue;
|
||||
}
|
||||
|
||||
int xTile = 0;
|
||||
int yTile = 0;
|
||||
for(int i=0; i<o.getPointsLength();i++){
|
||||
xTile += o.getPoint31XTile(i);
|
||||
yTile += o.getPoint31YTile(i);
|
||||
}
|
||||
double lat = MapUtils.get31LatitudeY(yTile/o.getPointsLength());
|
||||
double lon = MapUtils.get31LongitudeX(xTile/o.getPointsLength());
|
||||
|
||||
|
||||
for (int j = 0; j < o.getTypes().length; j++) {
|
||||
TagValuePair pair = o.getMapIndex().decodeType(o.getTypes()[j]);
|
||||
if(pair != null){
|
||||
Amenity am = new Amenity();
|
||||
am.setId(o.getId());
|
||||
am.setLocation(lat, lon);
|
||||
am.setName(o.getName());
|
||||
am.setEnName(Junidecode.unidecode(am.getName()));
|
||||
AmenityType type = MapRenderingTypes.getAmenityType(pair.tag, pair.value);
|
||||
String subtype = MapRenderingTypes.getAmenitySubtype(pair.tag, pair.value);
|
||||
am.setType(type);
|
||||
am.setSubType(subtype);
|
||||
am.setOpeningHours(null);
|
||||
am.setPhone(null);
|
||||
am.setSite(null);
|
||||
amenities.add(am);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("Error searching amenities", e); //$NON-NLS-1$
|
||||
return amenities;
|
||||
}
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(String.format("Search for %s done in %s ms found %s.", //$NON-NLS-1$
|
||||
topLatitude + " " + leftLongitude, System.currentTimeMillis() - now, amenities.size())); //$NON-NLS-1$
|
||||
}
|
||||
return amenities;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean checkCachedAmenities(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom,
|
||||
String filterId, List<Amenity> toFill, boolean fillFound) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearCache() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void evaluateCachedAmenities(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom,
|
||||
int limitPoi, PoiFilter filter, List<Amenity> toFill) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
256
OsmAnd/src/net/osmand/AmenityIndexRepositoryOdb.java
Normal file
256
OsmAnd/src/net/osmand/AmenityIndexRepositoryOdb.java
Normal file
|
@ -0,0 +1,256 @@
|
|||
package net.osmand;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.AmenityType;
|
||||
import net.osmand.data.index.IndexConstants;
|
||||
import net.osmand.osm.Entity;
|
||||
import net.osmand.osm.LatLon;
|
||||
import net.osmand.osm.MapUtils;
|
||||
import net.osmand.osm.Node;
|
||||
import net.osmand.osm.io.IOsmStorageFilter;
|
||||
import net.osmand.osm.io.OsmBaseStorage;
|
||||
import net.sf.junidecode.Junidecode;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteStatement;
|
||||
|
||||
public class AmenityIndexRepositoryOdb extends BaseLocationIndexRepository<Amenity> implements AmenityIndexRepository {
|
||||
private static final Log log = LogUtil.getLog(AmenityIndexRepositoryOdb.class);
|
||||
public final static int LIMIT_AMENITIES = 500;
|
||||
|
||||
|
||||
// cache amenities
|
||||
private String cFilterId;
|
||||
|
||||
|
||||
private final String[] columns = new String[]{"id", "x", "y", "name", "name_en", "type", "subtype", "opening_hours", "phone", "site"}; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$//$NON-NLS-5$//$NON-NLS-6$//$NON-NLS-7$//$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
|
||||
public List<Amenity> searchAmenities(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int limit, PoiFilter filter, List<Amenity> amenities){
|
||||
long now = System.currentTimeMillis();
|
||||
String squery = "? < y AND y < ? AND ? < x AND x < ?"; //$NON-NLS-1$
|
||||
|
||||
if(filter != null){
|
||||
String sql = filter.buildSqlWhereFilter();
|
||||
if(sql != null){
|
||||
squery += " AND " + sql; //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
if(limit != -1){
|
||||
squery += " ORDER BY RANDOM() LIMIT " +limit; //$NON-NLS-1$
|
||||
}
|
||||
Cursor query = db.query(IndexConstants.POI_TABLE, columns, squery,
|
||||
new String[]{MapUtils.get31TileNumberY(topLatitude)+"", //$NON-NLS-1$
|
||||
MapUtils.get31TileNumberY(bottomLatitude)+"", MapUtils.get31TileNumberX(leftLongitude)+"", //$NON-NLS-1$ //$NON-NLS-2$
|
||||
MapUtils.get31TileNumberX(rightLongitude)+""}, null, null, null); //$NON-NLS-1$
|
||||
if(query.moveToFirst()){
|
||||
do {
|
||||
Amenity am = new Amenity();
|
||||
am.setId(query.getLong(0));
|
||||
am.setLocation(MapUtils.get31LatitudeY(query.getInt(2)),
|
||||
MapUtils.get31LongitudeX(query.getInt(1)));
|
||||
am.setName(query.getString(3 ));
|
||||
am.setEnName(query.getString(4));
|
||||
if(am.getEnName().length() == 0){
|
||||
am.setEnName(Junidecode.unidecode(am.getName()));
|
||||
}
|
||||
am.setType(AmenityType.fromString(query.getString(5)));
|
||||
am.setSubType(query.getString(6));
|
||||
am.setOpeningHours(query.getString(7));
|
||||
am.setPhone(query.getString(8));
|
||||
am.setSite(query.getString(9));
|
||||
amenities.add(am);
|
||||
if(limit != -1 && amenities.size() >= limit){
|
||||
break;
|
||||
}
|
||||
} while(query.moveToNext());
|
||||
}
|
||||
query.close();
|
||||
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(String.format("Search for %s done in %s ms found %s.", //$NON-NLS-1$
|
||||
topLatitude + " " + leftLongitude, System.currentTimeMillis() - now, amenities.size())); //$NON-NLS-1$
|
||||
}
|
||||
return amenities;
|
||||
}
|
||||
|
||||
public boolean addAmenity(Amenity a){
|
||||
insertAmenities(Collections.singleton(a));
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean updateAmenity(Amenity a){
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append("UPDATE " + IndexConstants.POI_TABLE + " SET "); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
b.append(" x = ?, "). //$NON-NLS-1$
|
||||
append(" y = ?, "). //$NON-NLS-1$
|
||||
append(" opening_hours = ?, "). //$NON-NLS-1$
|
||||
append(" name = ?, "). //$NON-NLS-1$
|
||||
append(" name_en = ?, ").//$NON-NLS-1$
|
||||
append(" type = ?, "). //$NON-NLS-1$
|
||||
append(" subtype = ? "). //$NON-NLS-1$
|
||||
append(" site = ? "). //$NON-NLS-1$
|
||||
append(" phone = ? "). //$NON-NLS-1$
|
||||
append(" WHERE append( id = ?"); //$NON-NLS-1$
|
||||
|
||||
db.execSQL(b.toString(),
|
||||
new Object[] { MapUtils.get31TileNumberX(a.getLocation().getLongitude()), MapUtils.get31TileNumberY(a.getLocation().getLatitude()),
|
||||
a.getOpeningHours(), a.getName(), a.getEnName(), AmenityType.valueToString(a.getType()), a.getSubType(),
|
||||
a.getSite(), a.getPhone(), a.getId()});
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean deleteAmenities(long id){
|
||||
db.execSQL("DELETE FROM " + IndexConstants.POI_TABLE+ " WHERE id="+id); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public synchronized void clearCache(){
|
||||
super.clearCache();
|
||||
cFilterId = null;
|
||||
}
|
||||
|
||||
public void evaluateCachedAmenities(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, int limit, PoiFilter filter, List<Amenity> toFill){
|
||||
cTopLatitude = topLatitude + (topLatitude -bottomLatitude);
|
||||
cBottomLatitude = bottomLatitude - (topLatitude -bottomLatitude);
|
||||
cLeftLongitude = leftLongitude - (rightLongitude - leftLongitude);
|
||||
cRightLongitude = rightLongitude + (rightLongitude - leftLongitude);
|
||||
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
|
||||
ArrayList<Amenity> tempList = new ArrayList<Amenity>();
|
||||
searchAmenities(cTopLatitude, cLeftLongitude, cBottomLatitude, cRightLongitude, limit, filter, tempList);
|
||||
synchronized (this) {
|
||||
cachedObjects.clear();
|
||||
cachedObjects.addAll(tempList);
|
||||
}
|
||||
|
||||
checkCachedAmenities(topLatitude, leftLongitude, bottomLatitude, rightLongitude, cZoom, filter.getFilterId(), toFill);
|
||||
}
|
||||
|
||||
public synchronized boolean checkCachedAmenities(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, String filterId, List<Amenity> toFill, boolean fillFound){
|
||||
if (db == null) {
|
||||
return true;
|
||||
}
|
||||
boolean inside = cTopLatitude >= topLatitude && cLeftLongitude <= leftLongitude && cRightLongitude >= rightLongitude
|
||||
&& cBottomLatitude <= bottomLatitude && zoom == cZoom;
|
||||
boolean noNeedToSearch = inside && Algoritms.objectEquals(filterId, cFilterId);
|
||||
if((inside || fillFound) && toFill != null && Algoritms.objectEquals(filterId, cFilterId)){
|
||||
for(Amenity a : cachedObjects){
|
||||
LatLon location = a.getLocation();
|
||||
if (location.getLatitude() <= topLatitude && location.getLongitude() >= leftLongitude && location.getLongitude() <= rightLongitude
|
||||
&& location.getLatitude() >= bottomLatitude) {
|
||||
toFill.add(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
return noNeedToSearch;
|
||||
}
|
||||
public boolean checkCachedAmenities(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, String filterId, List<Amenity> toFill){
|
||||
return checkCachedAmenities(topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom, filterId, toFill, false);
|
||||
}
|
||||
|
||||
public boolean initialize(final IProgress progress, File file) {
|
||||
return super.initialize(progress, file, IndexConstants.POI_TABLE_VERSION, IndexConstants.POI_TABLE, true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public boolean updateAmenities(List<Amenity> amenities, double leftLon, double topLat, double rightLon, double bottomLat){
|
||||
int l = MapUtils.get31TileNumberX(leftLon);
|
||||
int r = MapUtils.get31TileNumberX(rightLon);
|
||||
int t = MapUtils.get31TileNumberY(topLat);
|
||||
int b = MapUtils.get31TileNumberY(bottomLat);
|
||||
db.execSQL("DELETE FROM " + IndexConstants.POI_TABLE + " WHERE " + //$NON-NLS-1$ //$NON-NLS-2$
|
||||
" x >= ? AND ? >= x AND " + //$NON-NLS-1$
|
||||
" y >= ? AND ? >= y ", new Integer[] { l, r, t, b }); //$NON-NLS-1$
|
||||
|
||||
insertAmenities(amenities);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void insertAmenities(Collection<Amenity> amenities) {
|
||||
SQLiteStatement stat = db.compileStatement("DELETE FROM " + IndexConstants.POI_TABLE + " WHERE id = ?"); //$NON-NLS-1$//$NON-NLS-2$
|
||||
for (Amenity a : amenities) {
|
||||
stat.bindLong(1, a.getId());
|
||||
stat.execute();
|
||||
}
|
||||
stat.close();
|
||||
stat = db.compileStatement("INSERT INTO " + IndexConstants.POI_TABLE + //$NON-NLS-1$
|
||||
"(id, x, y, name_en, name, type, subtype, opening_hours, site, phone) values(?,?,?,?,?,?,?,?,?,?)"); //$NON-NLS-1$
|
||||
for (Amenity a : amenities) {
|
||||
stat.bindLong(1, a.getId());
|
||||
stat.bindDouble(2, MapUtils.get31TileNumberX(a.getLocation().getLongitude()));
|
||||
stat.bindDouble(3, MapUtils.get31TileNumberY(a.getLocation().getLatitude()));
|
||||
bindString(stat, 4, a.getEnName());
|
||||
bindString(stat, 5, a.getName());
|
||||
bindString(stat, 6, AmenityType.valueToString(a.getType()));
|
||||
bindString(stat, 7, a.getSubType());
|
||||
bindString(stat, 8 , a.getOpeningHours());
|
||||
bindString(stat, 9, a.getSite());
|
||||
bindString(stat, 10, a.getPhone());
|
||||
stat.execute();
|
||||
}
|
||||
stat.close();
|
||||
}
|
||||
|
||||
private final static String SITE_API = "http://api.openstreetmap.org/"; //$NON-NLS-1$
|
||||
|
||||
public static boolean loadingPOIs(List<Amenity> amenities, double leftLon, double topLat, double righLon, double bottomLat) {
|
||||
try {
|
||||
// bbox=left,bottom,right,top
|
||||
String u = SITE_API+"api/0.6/map?bbox="+leftLon+","+bottomLat+","+righLon+","+topLat; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$
|
||||
URL url = new URL(u);
|
||||
log.info("Start loading poi : " + u); //$NON-NLS-1$
|
||||
InputStream is = url.openStream();
|
||||
OsmBaseStorage st = new OsmBaseStorage();
|
||||
final Map<Amenity, Entity> amen = new LinkedHashMap<Amenity, Entity>();
|
||||
final List<Amenity> tempList = new ArrayList<Amenity>();
|
||||
st.getFilters().add(new IOsmStorageFilter(){
|
||||
@Override
|
||||
public boolean acceptEntityToLoad(OsmBaseStorage storage, Entity.EntityId id, Entity entity) {
|
||||
Amenity.parseAmenities(entity, tempList);
|
||||
if(!tempList.isEmpty()){
|
||||
for(Amenity a : tempList){
|
||||
amen.put(a, entity);
|
||||
}
|
||||
tempList.clear();
|
||||
return true;
|
||||
}
|
||||
// to
|
||||
return entity instanceof Node;
|
||||
}
|
||||
});
|
||||
st.parseOSM(is, null, null, false);
|
||||
for (Amenity am : amen.keySet()) {
|
||||
// update location (when all nodes of way are loaded)
|
||||
am.setEntity(amen.get(am));
|
||||
if(am.getEnName().length() == 0){
|
||||
am.setEnName(Junidecode.unidecode(am.getName()));
|
||||
}
|
||||
amenities.add(am);
|
||||
}
|
||||
log.info("Loaded " +amenities.size() + " amenities"); //$NON-NLS-1$//$NON-NLS-2$
|
||||
} catch (IOException e) {
|
||||
log.error("Loading nodes failed", e); //$NON-NLS-1$
|
||||
return false;
|
||||
} catch (SAXException e) {
|
||||
log.error("Loading nodes failed", e); //$NON-NLS-1$
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
package net.osmand;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import net.osmand.activities.OsmandApplication;
|
||||
import net.osmand.data.Amenity;
|
||||
|
@ -18,7 +19,7 @@ public class PoiFilter {
|
|||
public final static String USER_PREFIX = "user_"; //$NON-NLS-1$
|
||||
public final static String CUSTOM_FILTER_ID = USER_PREFIX + "custom_id"; //$NON-NLS-1$
|
||||
|
||||
private Map<AmenityType, List<String>> acceptedTypes = new LinkedHashMap<AmenityType, List<String>>();
|
||||
private Map<AmenityType, LinkedHashSet<String>> acceptedTypes = new LinkedHashMap<AmenityType, LinkedHashSet<String>>();
|
||||
private String filterByName = null;
|
||||
|
||||
protected String filterId;
|
||||
|
@ -46,7 +47,7 @@ public class PoiFilter {
|
|||
}
|
||||
|
||||
// constructor for standard filters
|
||||
public PoiFilter(String name, String filterId, Map<AmenityType, List<String>> acceptedTypes, OsmandApplication app){
|
||||
public PoiFilter(String name, String filterId, Map<AmenityType, LinkedHashSet<String>> acceptedTypes, OsmandApplication app){
|
||||
application = app;
|
||||
isStandardFilter = false;
|
||||
if(filterId == null){
|
||||
|
@ -130,9 +131,9 @@ public class PoiFilter {
|
|||
* @param type
|
||||
* @return null if all subtypes are accepted/ empty list if type is not accepted at all
|
||||
*/
|
||||
public List<String> getAcceptedSubtypes(AmenityType type){
|
||||
public Set<String> getAcceptedSubtypes(AmenityType type){
|
||||
if(!acceptedTypes.containsKey(type)){
|
||||
return Collections.emptyList();
|
||||
return Collections.emptySet();
|
||||
}
|
||||
return acceptedTypes.get(type);
|
||||
}
|
||||
|
@ -141,8 +142,15 @@ public class PoiFilter {
|
|||
return acceptedTypes.containsKey(t);
|
||||
}
|
||||
|
||||
public boolean isWholeTypeAccepted(AmenityType type){
|
||||
return acceptedTypes.get(type) == null;
|
||||
public boolean acceptTypeSubtype(AmenityType t, String subtype){
|
||||
if(!acceptedTypes.containsKey(t)){
|
||||
return false;
|
||||
}
|
||||
LinkedHashSet<String> set = acceptedTypes.get(t);
|
||||
if(set == null){
|
||||
return true;
|
||||
}
|
||||
return set.contains(subtype);
|
||||
}
|
||||
|
||||
public boolean areAllTypesAccepted(){
|
||||
|
@ -160,7 +168,7 @@ public class PoiFilter {
|
|||
|
||||
public void setTypeToAccept(AmenityType type, boolean accept){
|
||||
if(accept){
|
||||
acceptedTypes.put(type, new ArrayList<String>());
|
||||
acceptedTypes.put(type, new LinkedHashSet<String>());
|
||||
} else {
|
||||
acceptedTypes.remove(type);
|
||||
}
|
||||
|
@ -185,7 +193,7 @@ public class PoiFilter {
|
|||
}
|
||||
b.append("(type = '").append(AmenityType.valueToString(a)).append("'"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
if(acceptedTypes.get(a) != null){
|
||||
List<String> list = acceptedTypes.get(a);
|
||||
LinkedHashSet<String> list = acceptedTypes.get(a);
|
||||
b.append(" AND subtype IN ("); //$NON-NLS-1$
|
||||
boolean bfirst = true;
|
||||
for(String s : list){
|
||||
|
@ -204,11 +212,11 @@ public class PoiFilter {
|
|||
return b.toString();
|
||||
}
|
||||
|
||||
public Map<AmenityType, List<String>> getAcceptedTypes(){
|
||||
return new LinkedHashMap<AmenityType, List<String>>(acceptedTypes);
|
||||
public Map<AmenityType, LinkedHashSet<String>> getAcceptedTypes(){
|
||||
return new LinkedHashMap<AmenityType, LinkedHashSet<String>>(acceptedTypes);
|
||||
}
|
||||
|
||||
public void selectSubTypesToAccept(AmenityType t, List<String> accept){
|
||||
public void selectSubTypesToAccept(AmenityType t, LinkedHashSet<String> accept){
|
||||
acceptedTypes.put(t, accept);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package net.osmand;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -59,14 +60,14 @@ public class PoiFiltersHelper {
|
|||
|
||||
private List<PoiFilter> getUserDefinedDefaultFilters(){
|
||||
List<PoiFilter> filters = new ArrayList<PoiFilter>();
|
||||
Map<AmenityType, List<String>> types = new LinkedHashMap<AmenityType, List<String>>();
|
||||
Map<AmenityType, LinkedHashSet<String>> types = new LinkedHashMap<AmenityType, LinkedHashSet<String>>();
|
||||
|
||||
List<String> list = new ArrayList<String>();
|
||||
LinkedHashSet<String> list = new LinkedHashSet<String>();
|
||||
list.add("fuel"); //$NON-NLS-1$
|
||||
list.add("car_wash"); //$NON-NLS-1$
|
||||
list.add("car_repair"); //$NON-NLS-1$
|
||||
types.put(AmenityType.TRANSPORTATION, list);
|
||||
list = new ArrayList<String>();
|
||||
list = new LinkedHashSet<String>();
|
||||
list.add("car"); //$NON-NLS-1$
|
||||
list.add("car_repair"); //$NON-NLS-1$
|
||||
types.put(AmenityType.SHOP, list);
|
||||
|
@ -76,7 +77,7 @@ public class PoiFiltersHelper {
|
|||
|
||||
types.put(AmenityType.HISTORIC, null);
|
||||
types.put(AmenityType.TOURISM, null);
|
||||
list = new ArrayList<String>();
|
||||
list = new LinkedHashSet<String>();
|
||||
list.add("place_of_worship"); //$NON-NLS-1$
|
||||
list.add("internet_access"); //$NON-NLS-1$
|
||||
list.add("bench"); //$NON-NLS-1$
|
||||
|
@ -93,13 +94,13 @@ public class PoiFiltersHelper {
|
|||
filters.add(new PoiFilter(Messages.getMessage("poi_filter_for_tourists"), null, types, application)); //$NON-NLS-1$
|
||||
types.clear();
|
||||
|
||||
list = new ArrayList<String>();
|
||||
list = new LinkedHashSet<String>();
|
||||
list.add("fuel"); //$NON-NLS-1$
|
||||
types.put(AmenityType.TRANSPORTATION, list);
|
||||
filters.add(new PoiFilter(Messages.getMessage("poi_filter_fuel"), null, types, application)); //$NON-NLS-1$
|
||||
types.clear();
|
||||
|
||||
list = new ArrayList<String>();
|
||||
list = new LinkedHashSet<String>();
|
||||
list.add("alcohol"); //$NON-NLS-1$
|
||||
list.add("bakery"); //$NON-NLS-1$
|
||||
list.add("beverages"); //$NON-NLS-1$
|
||||
|
@ -125,7 +126,7 @@ public class PoiFiltersHelper {
|
|||
////ctx.deleteDatabase(PoiFilterDbHelper.DATABASE_NAME);
|
||||
|
||||
cacheUserDefinedFilters = new ArrayList<PoiFilter>();
|
||||
PoiFilter filter = new PoiFilter(Messages.getMessage("poi_filter_custom_filter"), PoiFilter.CUSTOM_FILTER_ID, new LinkedHashMap<AmenityType, List<String>>(), application); //$NON-NLS-1$
|
||||
PoiFilter filter = new PoiFilter(Messages.getMessage("poi_filter_custom_filter"), PoiFilter.CUSTOM_FILTER_ID, new LinkedHashMap<AmenityType, LinkedHashSet<String>>(), application); //$NON-NLS-1$
|
||||
cacheUserDefinedFilters.add(filter);
|
||||
PoiFilterDbHelper helper = openDbHelper();
|
||||
cacheUserDefinedFilters.addAll(helper.getFilters());
|
||||
|
@ -241,7 +242,7 @@ public class PoiFiltersHelper {
|
|||
if(!addOnlyCategories){
|
||||
db.execSQL("INSERT INTO " + FILTER_NAME + " VALUES (?, ?, ?)",new Object[]{p.getName(), p.getFilterId(), p.getFilterByName()}); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
Map<AmenityType, List<String>> types = p.getAcceptedTypes();
|
||||
Map<AmenityType, LinkedHashSet<String>> types = p.getAcceptedTypes();
|
||||
SQLiteStatement insertCategories = db.compileStatement("INSERT INTO " + CATEGORIES_NAME + " VALUES (?, ?, ?)"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
for(AmenityType a : types.keySet()){
|
||||
if(types.get(a) == null){
|
||||
|
@ -270,21 +271,21 @@ public class PoiFiltersHelper {
|
|||
if(db != null){
|
||||
Cursor query = db.rawQuery("SELECT " + CATEGORIES_FILTER_ID +", " + CATEGORIES_COL_CATEGORY +"," + CATEGORIES_COL_SUBCATEGORY +" FROM " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
CATEGORIES_NAME, null);
|
||||
Map<String, Map<AmenityType, List<String>>> map = new LinkedHashMap<String, Map<AmenityType,List<String>>>();
|
||||
Map<String, Map<AmenityType, LinkedHashSet<String>>> map = new LinkedHashMap<String, Map<AmenityType,LinkedHashSet<String>>>();
|
||||
if(query.moveToFirst()){
|
||||
do {
|
||||
String filterId = query.getString(0);
|
||||
if(!map.containsKey(filterId)){
|
||||
map.put(filterId, new LinkedHashMap<AmenityType, List<String>>());
|
||||
map.put(filterId, new LinkedHashMap<AmenityType, LinkedHashSet<String>>());
|
||||
}
|
||||
Map<AmenityType, List<String>> m = map.get(filterId);
|
||||
Map<AmenityType, LinkedHashSet<String>> m = map.get(filterId);
|
||||
AmenityType a = AmenityType.fromString(query.getString(1));
|
||||
String subCategory = query.getString(2);
|
||||
if(subCategory == null){
|
||||
m.put(a, null);
|
||||
} else {
|
||||
if(m.get(a) == null){
|
||||
m.put(a, new ArrayList<String>());
|
||||
m.put(a, new LinkedHashSet<String>());
|
||||
}
|
||||
m.get(a).add(subCategory);
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ public class ResourceManager {
|
|||
// Indexes
|
||||
private final Map<String, RegionAddressRepository> addressMap = new TreeMap<String, RegionAddressRepository>(Collator.getInstance());
|
||||
|
||||
protected final Map<String, AmenityIndexRepository> amenityRepositories = new LinkedHashMap<String, AmenityIndexRepository>();
|
||||
protected final List<AmenityIndexRepository> amenityRepositories = new ArrayList<AmenityIndexRepository>();
|
||||
|
||||
protected final List<TransportIndexRepository> transportRepositories = new ArrayList<TransportIndexRepository>();
|
||||
|
||||
|
@ -404,6 +404,16 @@ public class ResourceManager {
|
|||
warnings.add(MessageFormat.format(Messages.getMessage("version_index_is_not_supported"), f.getName())); //$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
if(index.containsMapData()){
|
||||
// that's not fully acceptable
|
||||
// try {
|
||||
// RandomAccessFile raf = new RandomAccessFile(f, "r"); //$NON-NLS-1$
|
||||
// amenityRepositories.add(new AmenityIndexRepositoryBinary(new BinaryMapIndexReader(raf)));
|
||||
// } catch (IOException e) {
|
||||
// log.error("Exception reading " + f.getAbsolutePath(), e); //$NON-NLS-1$
|
||||
// warnings.add(MessageFormat.format(Messages.getMessage("version_index_is_not_supported"), f.getName())); //$NON-NLS-1$
|
||||
// }
|
||||
}
|
||||
}
|
||||
} catch (SQLiteException e) {
|
||||
log.error("Exception reading " + f.getAbsolutePath(), e); //$NON-NLS-1$
|
||||
|
@ -432,13 +442,13 @@ public class ResourceManager {
|
|||
|
||||
public void indexingPoi(final IProgress progress, List<String> warnings, File f) {
|
||||
if (f.getName().endsWith(IndexConstants.POI_INDEX_EXT)) {
|
||||
AmenityIndexRepository repository = new AmenityIndexRepository();
|
||||
AmenityIndexRepositoryOdb repository = new AmenityIndexRepositoryOdb();
|
||||
|
||||
progress.startTask(Messages.getMessage("indexing_poi") + f.getName(), -1); //$NON-NLS-1$
|
||||
try {
|
||||
boolean initialized = repository.initialize(progress, f);
|
||||
if (initialized) {
|
||||
amenityRepositories.put(repository.getName(), repository);
|
||||
amenityRepositories.add(repository);
|
||||
} else {
|
||||
warnings.add(MessageFormat.format(Messages.getMessage("version_index_is_not_supported"), f.getName())); //$NON-NLS-1$
|
||||
}
|
||||
|
@ -514,7 +524,7 @@ public class ResourceManager {
|
|||
////////////////////////////////////////////// Working with amenities ////////////////////////////////////////////////
|
||||
public List<AmenityIndexRepository> searchAmenityRepositories(double latitude, double longitude) {
|
||||
List<AmenityIndexRepository> repos = new ArrayList<AmenityIndexRepository>();
|
||||
for (AmenityIndexRepository index : amenityRepositories.values()) {
|
||||
for (AmenityIndexRepository index : amenityRepositories) {
|
||||
if (index.checkContains(latitude,longitude)) {
|
||||
repos.add(index);
|
||||
}
|
||||
|
@ -530,9 +540,10 @@ public class ResourceManager {
|
|||
double leftLongitude = MapUtils.getLongitudeFromTile(zoom, tileNumberX - 0.5);
|
||||
double rightLongitude = MapUtils.getLongitudeFromTile(zoom, tileNumberX + 0.5);
|
||||
List<Amenity> amenities = new ArrayList<Amenity>();
|
||||
for (AmenityIndexRepository index : amenityRepositories.values()) {
|
||||
for (AmenityIndexRepository index : amenityRepositories) {
|
||||
if (index.checkContains(topLatitude, leftLongitude, bottomLatitude, rightLongitude)) {
|
||||
if (!index.checkCachedAmenities(topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom, filter.getFilterId(), amenities)) {
|
||||
if (!index.checkCachedAmenities(topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom, filter.getFilterId(),
|
||||
amenities, false)) {
|
||||
index.searchAmenities(topLatitude, leftLongitude, bottomLatitude, rightLongitude, limit, filter, amenities);
|
||||
}
|
||||
}
|
||||
|
@ -553,7 +564,7 @@ public class ResourceManager {
|
|||
|
||||
} else {
|
||||
String filterId = filter == null ? null : filter.getFilterId();
|
||||
for (AmenityIndexRepository index : amenityRepositories.values()) {
|
||||
for (AmenityIndexRepository index : amenityRepositories) {
|
||||
if (index.checkContains(topLatitude, leftLongitude, bottomLatitude, rightLongitude)) {
|
||||
if (!index.checkCachedAmenities(topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom, filterId, toFill,
|
||||
true)) {
|
||||
|
@ -620,7 +631,7 @@ public class ResourceManager {
|
|||
////////////////////////////////////////////// Closing methods ////////////////////////////////////////////////
|
||||
|
||||
public void closeAmenities(){
|
||||
for(AmenityIndexRepository r : amenityRepositories.values()){
|
||||
for(AmenityIndexRepository r : amenityRepositories){
|
||||
r.close();
|
||||
}
|
||||
amenityRepositories.clear();
|
||||
|
@ -664,7 +675,7 @@ public class ResourceManager {
|
|||
public void onLowMemory() {
|
||||
log.info("On low memory : cleaning tiles - size = " + cacheOfImages.size()); //$NON-NLS-1$
|
||||
clearTiles();
|
||||
for(AmenityIndexRepository r : amenityRepositories.values()){
|
||||
for(AmenityIndexRepository r : amenityRepositories){
|
||||
r.clearCache();
|
||||
}
|
||||
for(RegionAddressRepository r : addressMap.values()){
|
||||
|
|
|
@ -4,9 +4,8 @@
|
|||
package net.osmand.activities;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import net.osmand.OsmandSettings;
|
||||
import net.osmand.PoiFilter;
|
||||
|
@ -165,10 +164,8 @@ public class EditPOIFilterActivity extends ListActivity {
|
|||
ListView listView = new ListView(this);
|
||||
|
||||
final LinkedHashSet<String> subCategories = new LinkedHashSet<String>(AmenityType.getSubCategories(amenity, MapRenderingTypes.getDefault()));
|
||||
List<String> subtypes = filter.getAcceptedSubtypes(amenity);
|
||||
boolean allSubTypesAccepted = subtypes == null;
|
||||
LinkedHashSet<String> acceptedCategories = subtypes == null ? null : new LinkedHashSet<String>(subtypes);
|
||||
if (subtypes != null) {
|
||||
Set<String> acceptedCategories = filter.getAcceptedSubtypes(amenity);
|
||||
if (acceptedCategories != null) {
|
||||
for (String s : acceptedCategories) {
|
||||
if (!subCategories.contains(s)) {
|
||||
subCategories.add(s);
|
||||
|
@ -179,7 +176,7 @@ public class EditPOIFilterActivity extends ListActivity {
|
|||
final String[] array = subCategories.toArray(new String[0]);
|
||||
final boolean[] selected = new boolean[array.length];
|
||||
for (int i = 0; i < selected.length; i++) {
|
||||
if (allSubTypesAccepted) {
|
||||
if (acceptedCategories == null) {
|
||||
selected[i] = true;
|
||||
} else {
|
||||
selected[i] = acceptedCategories.contains(array[i]);
|
||||
|
@ -192,7 +189,7 @@ public class EditPOIFilterActivity extends ListActivity {
|
|||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
List<String> accepted = new ArrayList<String>();
|
||||
LinkedHashSet<String> accepted = new LinkedHashSet<String>();
|
||||
for (int i = 0; i < selected.length; i++) {
|
||||
if(selected[i]){
|
||||
accepted.add(array[i]);
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
|
||||
import net.osmand.AmenityIndexRepository;
|
||||
import net.osmand.AmenityIndexRepositoryOdb;
|
||||
import net.osmand.Base64;
|
||||
import net.osmand.LogUtil;
|
||||
import net.osmand.OsmandSettings;
|
||||
|
@ -568,8 +569,10 @@ public class EditingPOIActivity {
|
|||
// delete all amenities with same id
|
||||
if (DELETE_ACTION.equals(action) || MODIFY_ACTION.equals(action)) {
|
||||
for (AmenityIndexRepository r : repos) {
|
||||
r.deleteAmenities(n.getId() << 1);
|
||||
r.clearCache();
|
||||
if (r instanceof AmenityIndexRepositoryOdb) {
|
||||
((AmenityIndexRepositoryOdb) r).deleteAmenities(n.getId() << 1);
|
||||
((AmenityIndexRepositoryOdb) r).clearCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
// add amenities
|
||||
|
@ -577,8 +580,10 @@ public class EditingPOIActivity {
|
|||
List<Amenity> ams = Amenity.parseAmenities(n, new ArrayList<Amenity>());
|
||||
for (Amenity a : ams) {
|
||||
for (AmenityIndexRepository r : repos) {
|
||||
r.addAmenity(a);
|
||||
r.clearCache();
|
||||
if (r instanceof AmenityIndexRepositoryOdb) {
|
||||
((AmenityIndexRepositoryOdb) r).addAmenity(a);
|
||||
((AmenityIndexRepositoryOdb) r).clearCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.util.Map;
|
|||
|
||||
import net.osmand.Algoritms;
|
||||
import net.osmand.AmenityIndexRepository;
|
||||
import net.osmand.AmenityIndexRepositoryOdb;
|
||||
import net.osmand.BusyIndicator;
|
||||
import net.osmand.FavouritePoint;
|
||||
import net.osmand.FavouritesDbHelper;
|
||||
|
@ -1228,12 +1229,14 @@ public class MapActivity extends Activity implements IMapLocationListener, Senso
|
|||
public void run() {
|
||||
try {
|
||||
List<Amenity> amenities = new ArrayList<Amenity>();
|
||||
boolean loadingPOIs = AmenityIndexRepository.loadingPOIs(amenities, leftLon, topLat, rightLon, bottomLat);
|
||||
boolean loadingPOIs = AmenityIndexRepositoryOdb.loadingPOIs(amenities, leftLon, topLat, rightLon, bottomLat);
|
||||
if(!loadingPOIs){
|
||||
showToast(getString(R.string.update_poi_error_loading));
|
||||
} else {
|
||||
for(AmenityIndexRepository r : repos){
|
||||
r.updateAmenities(amenities, leftLon, topLat, rightLon, bottomLat);
|
||||
if(r instanceof AmenityIndexRepositoryOdb){
|
||||
((AmenityIndexRepositoryOdb) r).updateAmenities(amenities, leftLon, topLat, rightLon, bottomLat);
|
||||
}
|
||||
}
|
||||
showToast(MessageFormat.format(getString(R.string.update_poi_success), amenities.size()));
|
||||
mapView.refreshMap();
|
||||
|
|
|
@ -216,7 +216,7 @@ public class MapRenderRepositories {
|
|||
TIntByteMap map = MapRenderingTypes.getDefault().getObjectTypeMinZoom();
|
||||
|
||||
@Override
|
||||
public boolean accept(TIntArrayList types) {
|
||||
public boolean accept(TIntArrayList types, BinaryMapIndexReader.MapIndex root) {
|
||||
for (int j = 0; j < types.size(); j++) {
|
||||
int type = types.get(j);
|
||||
if ((type & 3) == MapRenderingTypes.POINT_TYPE) {
|
||||
|
|
|
@ -36,7 +36,6 @@ import android.graphics.PointF;
|
|||
import android.graphics.RectF;
|
||||
import android.graphics.Shader;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.BitmapFactory.Options;
|
||||
import android.graphics.Paint.Align;
|
||||
import android.graphics.Paint.Cap;
|
||||
import android.graphics.Paint.Style;
|
||||
|
|
Loading…
Reference in a new issue