This commit is contained in:
Victor Shcherb 2015-10-25 21:25:08 +01:00
parent aec0b252c3
commit cd6675b64f
10 changed files with 425 additions and 501 deletions

View file

@ -9,6 +9,8 @@ import java.io.IOException;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
@ -19,6 +21,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
import net.osmand.PlatformUtil;
import net.osmand.ResultMatcher; import net.osmand.ResultMatcher;
import net.osmand.binary.BinaryMapDataObject; import net.osmand.binary.BinaryMapDataObject;
import net.osmand.binary.BinaryMapIndexReader; import net.osmand.binary.BinaryMapIndexReader;
@ -47,13 +50,18 @@ public class OsmandRegions {
private BinaryMapIndexReader reader; private BinaryMapIndexReader reader;
private String locale = "en"; private String locale = "en";
private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(OsmandRegions.class);
Map<String, RegionData> fullNamesToRegionData = new HashMap<String, RegionData>();
WorldRegion worldRegion = new WorldRegion(WorldRegion.WORLD, WorldRegion.WORLD);
Map<String, WorldRegion> fullNamesToRegionData = new HashMap<String, WorldRegion>();
Map<String, String> downloadNamesToFullNames = new HashMap<String, String>(); Map<String, String> downloadNamesToFullNames = new HashMap<String, String>();
Map<String, LinkedList<BinaryMapDataObject>> countriesByDownloadName = new HashMap<String, LinkedList<BinaryMapDataObject>>(); Map<String, LinkedList<BinaryMapDataObject>> countriesByDownloadName = new HashMap<String, LinkedList<BinaryMapDataObject>>();
QuadTree<String> quadTree = null ;
MapIndexFields mapIndexFields = new MapIndexFields(); QuadTree<String> quadTree ;
MapIndexFields mapIndexFields ;
RegionTranslation translator;
private class MapIndexFields { private class MapIndexFields {
Integer parentFullName = null; Integer parentFullName = null;
@ -74,12 +82,65 @@ public class OsmandRegions {
return object.getNameByType(tp); return object.getNameByType(tp);
} }
} }
public void setTranslator(RegionTranslation translator) {
this.translator = translator;
}
public void prepareFile(String fileName) throws IOException { public void prepareFile(String fileName) throws IOException {
reader = new BinaryMapIndexReader(new RandomAccessFile(fileName, "r"), new File(fileName)); reader = new BinaryMapIndexReader(new RandomAccessFile(fileName, "r"), new File(fileName));
initRegionData(); // final Collator clt = OsmAndCollator.primaryCollator();
final Map<String, String> parentRelations = new LinkedHashMap<String, String>();
final ResultMatcher<BinaryMapDataObject> resultMatcher = new ResultMatcher<BinaryMapDataObject>() {
@Override
public boolean publish(BinaryMapDataObject object) {
initTypes(object);
int[] types = object.getTypes();
for(int i = 0; i < types.length; i++ ) {
TagValuePair tp = object.getMapIndex().decodeType(types[i]);
if("boundary".equals(tp.value)) {
return false;
}
}
WorldRegion rd = initRegionData(parentRelations, object);
if(rd == null) {
return false;
}
if(rd.regionDownloadName != null) {
downloadNamesToFullNames.put(rd.regionDownloadName, rd.regionFullName);
}
fullNamesToRegionData.put(rd.regionFullName, rd);
return false;
}
@Override
public boolean isCancelled() {
return false;
}
};
iterateOverAllObjects(resultMatcher);
// post process download names
for(Map.Entry<String, String> e : parentRelations.entrySet()) {
String fullName = e.getKey();
String parentFullName = e.getValue();
// String parentParentFulName = parentRelations.get(parentFullName); // could be used for japan/russia
WorldRegion rd = fullNamesToRegionData.get(fullName);
WorldRegion parent = fullNamesToRegionData.get(parentFullName);
if(parent != null && rd != null) {
parent.addSubregion(rd);
}
if(rd != null) {
rd.superregion = parent;
}
if(parent != null) {
parent.subregions.add(rd);
}
}
structureWorldRegions(new ArrayList<WorldRegion>(fullNamesToRegionData.values()));
} }
public boolean containsCountry(String name){ public boolean containsCountry(String name){
@ -97,16 +158,20 @@ public class OsmandRegions {
} }
public String getLocaleNameByFullName(String fullName, boolean includingParent) { public String getLocaleNameByFullName(String fullName, boolean includingParent) {
RegionData rd = fullNamesToRegionData.get(fullName); WorldRegion rd = fullNamesToRegionData.get(fullName);
if(rd == null) { if(rd == null) {
return fullName.replace('_', ' '); return fullName.replace('_', ' ');
} }
if (includingParent && rd.parent != null) { if (includingParent && rd.superregion != null) {
return rd.parent.getLocaleName() + " " + rd.getLocaleName(); return rd.superregion.getLocaleName() + " " + rd.getLocaleName();
} else { } else {
return rd.getLocaleName(); return rd.getLocaleName();
} }
} }
public WorldRegion getWorldRegion() {
return worldRegion;
}
public boolean isInitialized(){ public boolean isInitialized(){
@ -128,7 +193,6 @@ public class OsmandRegions {
} }
public boolean intersect(BinaryMapDataObject bo, int lx, int ty, int rx, int by) { public boolean intersect(BinaryMapDataObject bo, int lx, int ty, int rx, int by) {
int t = 0;
// 1. polygon in object // 1. polygon in object
if(contain(bo, lx, ty)) { if(contain(bo, lx, ty)) {
return true; return true;
@ -272,10 +336,14 @@ public class OsmandRegions {
} }
public RegionData getRegionData(String fullname) { public WorldRegion getRegionData(String fullname) {
return fullNamesToRegionData.get(fullname); return fullNamesToRegionData.get(fullname);
} }
public WorldRegion getRegionDataByDownloadName(String downloadName) {
return getRegionData(downloadNamesToFullNames.get(downloadName.toLowerCase()));
}
public String getDownloadName(BinaryMapDataObject o) { public String getDownloadName(BinaryMapDataObject o) {
return mapIndexFields.get(mapIndexFields.downloadNameType, o); return mapIndexFields.get(mapIndexFields.downloadNameType, o);
} }
@ -284,66 +352,23 @@ public class OsmandRegions {
return mapIndexFields.get(mapIndexFields.fullNameType, o); return mapIndexFields.get(mapIndexFields.fullNameType, o);
} }
public List<RegionData> getAllRegionData() { public List<WorldRegion> getAllRegionData() {
return new ArrayList<OsmandRegions.RegionData>(fullNamesToRegionData.values()); return new ArrayList<WorldRegion>(fullNamesToRegionData.values());
} }
public void initRegionData() throws IOException {
// final Collator clt = OsmAndCollator.primaryCollator();
final Map<String, String> parentRelations = new LinkedHashMap<String, String>();
final ResultMatcher<BinaryMapDataObject> resultMatcher = new ResultMatcher<BinaryMapDataObject>() {
@Override
public boolean publish(BinaryMapDataObject object) {
initTypes(object);
int[] types = object.getTypes();
for(int i = 0; i < types.length; i++ ) {
TagValuePair tp = object.getMapIndex().decodeType(types[i]);
if("boundary".equals(tp.value)) {
return false;
}
}
RegionData rd = initRegionData(parentRelations, object);
if(rd == null) {
return false;
}
downloadNamesToFullNames.put(rd.regionDownloadName, rd.regionFullName);
fullNamesToRegionData.put(rd.regionFullName, rd);
return false;
}
@Override private WorldRegion initRegionData(final Map<String, String> parentRelations, BinaryMapDataObject object) {
public boolean isCancelled() { String regionDownloadName = mapIndexFields.get(mapIndexFields.downloadNameType, object);
return false; String regionFullName = mapIndexFields.get(mapIndexFields.fullNameType, object);
} if(Algorithms.isEmpty(regionFullName)) {
};
iterateOverAllObjects(resultMatcher);
// post process download names
for(Map.Entry<String, String> e : parentRelations.entrySet()) {
String fullName = e.getKey();
String parentFullName = e.getValue();
// String parentParentFulName = parentRelations.get(parentFullName); // could be used for japan/russia
RegionData rd = fullNamesToRegionData.get(fullName);
if(rd != null) {
rd.parent = fullNamesToRegionData.get(parentFullName);
}
}
}
private RegionData initRegionData(final Map<String, String> parentRelations, BinaryMapDataObject object) {
RegionData rd = new RegionData();
rd.regionDownloadName = mapIndexFields.get(mapIndexFields.downloadNameType, object);
rd.regionFullName = mapIndexFields.get(mapIndexFields.fullNameType, object);
if(Algorithms.isEmpty(rd.regionDownloadName) || Algorithms.isEmpty(rd.regionFullName)) {
return null; return null;
} }
WorldRegion rd = new WorldRegion(regionFullName, regionDownloadName);
double cx = 0; double cx = 0;
double cy = 0; double cy = 0;
for(int i = 0; i<object.getPointsLength(); i++) { for (int i = 0; i < object.getPointsLength(); i++) {
cx +=object.getPoint31XTile(i); cx += object.getPoint31XTile(i);
cy +=object.getPoint31YTile(i); cy += object.getPoint31YTile(i);
} }
if(object.getPointsLength() > 0) { if(object.getPointsLength() > 0) {
cx /= object.getPointsLength(); cx /= object.getPointsLength();
@ -509,6 +534,18 @@ public class OsmandRegions {
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
OsmandRegions or = new OsmandRegions(); OsmandRegions or = new OsmandRegions();
or.prepareFile("/Users/victorshcherb/osmand/repos/resources/countries-info/regions.ocbf"); or.prepareFile("/Users/victorshcherb/osmand/repos/resources/countries-info/regions.ocbf");
LinkedList<WorldRegion> lst = new LinkedList<WorldRegion>();
lst.add(or.getWorldRegion());
// int i =0;
while (!lst.isEmpty()) {
WorldRegion wd = lst.pollFirst();
System.out.println((wd.superregion == null ? "" : wd.superregion.getLocaleName()) + " "
+ wd.getLocaleName() + " " + wd.getRegionDownloadName());
// if(i++ <=5)
// lst.addAll(wd.getSubregions());
}
or.cacheAllCountries(); or.cacheAllCountries();
// long t = System.currentTimeMillis(); // long t = System.currentTimeMillis();
// or.cacheAllCountries(); // or.cacheAllCountries();
@ -522,97 +559,83 @@ public class OsmandRegions {
testCountry(or, 35.7521, 139.7887, "japan"); testCountry(or, 35.7521, 139.7887, "japan");
testCountry(or, 46.5145, 102.2580, "mongolia"); testCountry(or, 46.5145, 102.2580, "mongolia");
testCountry(or, 62.54, 43.36, "arkhangelsk oblast", "northwestern federal district"); testCountry(or, 62.54, 43.36, "arkhangelsk oblast", "northwestern federal district");
} }
public static class RegionData { public interface RegionTranslation {
protected RegionData parent = null;
// filled by osmand regions
protected String regionLeftHandDriving;
protected String regionLang;
protected String regionMetric;
protected String regionRoadSigns;
protected String regionFullName;
protected String regionParentFullName;
protected String regionName;
protected String regionNameEn;
protected String regionNameLocale;
protected String regionSearchText;
protected String regionDownloadName;
protected boolean regionMapDownload;
protected LatLon regionCenter;
public String getTranslation(String id);
public boolean isRegionMapDownload() { }
return regionMapDownload;
private void initWorldRegion(WorldRegion world, String id) {
WorldRegion rg = new WorldRegion(id);
rg.regionParentFullName = world.regionFullName;
if(translator != null) {
rg.regionName = translator.getTranslation(id);
} }
world.addSubregion(rg);
public String getLocaleName() {
if(!Algorithms.isEmpty(regionNameLocale)) {
return regionNameLocale;
}
if(!Algorithms.isEmpty(regionNameEn)) {
return regionNameEn;
}
return regionName;
}
public String getRegionDownloadName() {
return regionDownloadName;
}
public String getRegionLeftHandDriving() {
return regionLeftHandDriving;
}
public String getRegionMetric() {
return regionMetric;
}
public String getRegionRoadSigns() {
return regionRoadSigns;
}
public LatLon getRegionCenter() {
return regionCenter;
}
public String getRegionSearchText() {
return regionSearchText;
}
public String getRegionLang() {
return regionLang;
}
///TODO investigate do we need it ???
String regionId;
private String downloadsId;
private String name;
public String getName() {
return name;
}
public String getRegionId() {
return regionId;
}
public String getDownloadsId() {
return downloadsId;
}
} }
public void structureWorldRegions(List<WorldRegion> loadedItems ) {
if (loadedItems.size() == 0) {
return;
}
WorldRegion world = new WorldRegion(WorldRegion.WORLD);
initWorldRegion(world, WorldRegion.AFRICA_REGION_ID);
initWorldRegion(world, WorldRegion.ASIA_REGION_ID);
initWorldRegion(world, WorldRegion.CENTRAL_AMERICA_REGION_ID);
initWorldRegion(world, WorldRegion.EUROPE_REGION_ID);
initWorldRegion(world, WorldRegion.NORTH_AMERICA_REGION_ID);
initWorldRegion(world, WorldRegion.RUSSIA_REGION_ID);
initWorldRegion(world, WorldRegion.SOUTH_AMERICA_REGION_ID);
Iterator<WorldRegion> it = loadedItems.iterator();
while(it.hasNext()) {
WorldRegion region = it.next();
if(region.superregion == null) {
boolean found = false;
for(WorldRegion worldSubregion : world.subregions) {
if(worldSubregion.getRegionId().equalsIgnoreCase(region.regionParentFullName)) {
worldSubregion.subregions.add(region);
found = true;
break;
}
}
if(found) {
it.remove();
}
} else {
it.remove();
}
}
Comparator<WorldRegion> nameComparator = new Comparator<WorldRegion>() {
@Override
public int compare(WorldRegion w1, WorldRegion w2) {
return w1.getLocaleName().compareTo(w2.getLocaleName());
}
};
sortSubregions(world, nameComparator);
this.worldRegion = world;
if (loadedItems.size() > 0) {
LOG.warn("Found orphaned regions: " + loadedItems.size());
for (WorldRegion regionId : loadedItems) {
LOG.warn("FullName = " + regionId.regionFullName +
" parent=" + regionId.regionParentFullName);
}
}
}
private void sortSubregions(WorldRegion region, Comparator<WorldRegion> comparator) {
Collections.sort(region.subregions, comparator);
for (WorldRegion r : region.subregions) {
if (r.subregions.size() > 0) {
sortSubregions(r, comparator);
}
}
}
} }

View file

@ -0,0 +1,152 @@
package net.osmand.map;
import java.util.LinkedList;
import java.util.List;
import net.osmand.data.LatLon;
import net.osmand.util.Algorithms;
public class WorldRegion {
public static final String WORLD_BASEMAP = "world_basemap";
public static final String AFRICA_REGION_ID = "africa";
public static final String ASIA_REGION_ID = "asia";
public static final String AUSTRALIA_AND_OCEANIA_REGION_ID = "australia-oceania";
public static final String CENTRAL_AMERICA_REGION_ID = "centralamerica";
public static final String EUROPE_REGION_ID = "europe";
public static final String NORTH_AMERICA_REGION_ID = "northamerica";
public static final String RUSSIA_REGION_ID = "russia";
public static final String SOUTH_AMERICA_REGION_ID = "southamerica";
protected static final String WORLD = "world";
// Hierarchy
protected WorldRegion superregion;
protected List<WorldRegion> subregions;
// filled by osmand regions
protected String regionLeftHandDriving;
protected String regionLang;
protected String regionMetric;
protected String regionRoadSigns;
protected String regionFullName;
protected String regionParentFullName;
protected String regionName;
protected String regionNameEn;
protected String regionNameLocale;
protected String regionSearchText;
protected String regionDownloadName;
protected boolean regionMapDownload;
protected LatLon regionCenter;
public boolean isRegionMapDownload() {
return regionMapDownload;
}
public String getLocaleName() {
if(!Algorithms.isEmpty(regionNameLocale)) {
return regionNameLocale;
}
if(!Algorithms.isEmpty(regionNameEn)) {
return regionNameEn;
}
if(!Algorithms.isEmpty(regionName)) {
return regionName;
}
return capitalize(regionFullName.replace('_', ' '));
}
public String getRegionDownloadName() {
return regionDownloadName;
}
public String getRegionDownloadNameLC() {
return regionDownloadName == null ? null : regionDownloadName.toLowerCase();
}
public String getRegionLeftHandDriving() {
return regionLeftHandDriving;
}
public String getRegionMetric() {
return regionMetric;
}
public String getRegionRoadSigns() {
return regionRoadSigns;
}
public LatLon getRegionCenter() {
return regionCenter;
}
public String getRegionSearchText() {
return regionSearchText;
}
public String getRegionLang() {
return regionLang;
}
public WorldRegion getSuperregion() {
return superregion;
}
public List<WorldRegion> getSubregions() {
return subregions;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
WorldRegion that = (WorldRegion) o;
return !(regionFullName != null ? !regionFullName.toLowerCase().equals(that.regionFullName.toLowerCase()) : that.regionFullName != null);
}
@Override
public int hashCode() {
return regionFullName != null ? regionFullName.hashCode() : 0;
}
public WorldRegion(String regionFullName, String downloadName) {
this.regionFullName = regionFullName;
this.regionDownloadName = downloadName;
superregion = null;
subregions = new LinkedList<WorldRegion>();
}
public WorldRegion(String id) {
this(id, null);
}
public String getRegionId() {
return regionFullName;
}
private String capitalize(String s) {
String[] words = s.split(" ");
if (words[0].length() > 0) {
StringBuilder sb = new StringBuilder();
sb.append(Algorithms.capitalizeFirstLetterAndLowercase(words[0]));
for (int i = 1; i < words.length; i++) {
sb.append(" ");
sb.append(Algorithms.capitalizeFirstLetterAndLowercase(words[i]));
}
return sb.toString();
} else {
return s;
}
}
public void addSubregion(WorldRegion rd) {
subregions.add(rd);
rd.superregion = this;
}
}

View file

@ -14,6 +14,8 @@ import net.osmand.IndexConstants;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.access.AccessibleAlertBuilder; import net.osmand.access.AccessibleAlertBuilder;
import net.osmand.map.OsmandRegions; import net.osmand.map.OsmandRegions;
import net.osmand.map.OsmandRegions.RegionTranslation;
import net.osmand.map.WorldRegion;
import net.osmand.osm.AbstractPoiType; import net.osmand.osm.AbstractPoiType;
import net.osmand.osm.MapPoiTypes; import net.osmand.osm.MapPoiTypes;
import net.osmand.plus.activities.DayNightHelper; import net.osmand.plus.activities.DayNightHelper;
@ -254,7 +256,7 @@ public class AppInitializer implements IProgress {
new FileOutputStream(file)); new FileOutputStream(file));
} }
app.regions.prepareFile(file.getAbsolutePath()); app.regions.prepareFile(file.getAbsolutePath());
loadWorldRegions();
} }
} catch (Exception e) { } catch (Exception e) {
warnings.add(e.getMessage()); warnings.add(e.getMessage());
@ -262,9 +264,6 @@ public class AppInitializer implements IProgress {
} }
} }
private void loadWorldRegions() {
app.worldRegion.loadWorldRegions(app);
}
private void initPoiTypes() { private void initPoiTypes() {
if(app.getAppPath("poi_types.xml").exists()) { if(app.getAppPath("poi_types.xml").exists()) {
@ -317,16 +316,41 @@ public class AppInitializer implements IProgress {
app.selectedGpxHelper = startupInit(new GpxSelectionHelper(app, app.savingTrackHelper), GpxSelectionHelper.class); app.selectedGpxHelper = startupInit(new GpxSelectionHelper(app, app.savingTrackHelper), GpxSelectionHelper.class);
app.favorites = startupInit(new FavouritesDbHelper(app), FavouritesDbHelper.class); app.favorites = startupInit(new FavouritesDbHelper(app), FavouritesDbHelper.class);
app.waypointHelper = startupInit(new WaypointHelper(app), WaypointHelper.class); app.waypointHelper = startupInit(new WaypointHelper(app), WaypointHelper.class);
app.worldRegion = startupInit(new WorldRegion(), WorldRegion.class);
app.worldRegion.initWorld();
app.regions = startupInit(new OsmandRegions(), OsmandRegions.class); app.regions = startupInit(new OsmandRegions(), OsmandRegions.class);
app.regions.setLocale(app.getLanguage()); updateRegionVars();
app.poiFilters = startupInit(new PoiFiltersHelper(app), PoiFiltersHelper.class); app.poiFilters = startupInit(new PoiFiltersHelper(app), PoiFiltersHelper.class);
app.rendererRegistry = startupInit(new RendererRegistry(app), RendererRegistry.class); app.rendererRegistry = startupInit(new RendererRegistry(app), RendererRegistry.class);
app.targetPointsHelper = startupInit(new TargetPointsHelper(app), TargetPointsHelper.class); app.targetPointsHelper = startupInit(new TargetPointsHelper(app), TargetPointsHelper.class);
} }
private void updateRegionVars() {
app.regions.setTranslator(new RegionTranslation() {
@Override
public String getTranslation(String id) {
if(WorldRegion.AFRICA_REGION_ID.equals(id)){
return app.getString(R.string.index_name_africa);
} else if(WorldRegion.ASIA_REGION_ID.equals(id)){
return app.getString(R.string.index_name_asia);
} else if(WorldRegion.CENTRAL_AMERICA_REGION_ID.equals(id)){
return app.getString(R.string.index_name_central_america);
} else if(WorldRegion.EUROPE_REGION_ID.equals(id)){
return app.getString(R.string.index_name_europe);
} else if(WorldRegion.RUSSIA_REGION_ID.equals(id)){
return app.getString(R.string.index_name_russia);
} else if(WorldRegion.NORTH_AMERICA_REGION_ID.equals(id)){
return app.getString(R.string.index_name_north_america);
} else if(WorldRegion.SOUTH_AMERICA_REGION_ID.equals(id)){
return app.getString(R.string.index_name_south_america);
}
return null;
}
});
app.regions.setLocale(app.getLanguage());
}
private <T> T startupInit(T object, Class<T> class1) { private <T> T startupInit(T object, Class<T> class1) {
long t = System.currentTimeMillis(); long t = System.currentTimeMillis();

View file

@ -98,7 +98,6 @@ public class OsmandApplication extends Application {
AvoidSpecificRoads avoidSpecificRoads; AvoidSpecificRoads avoidSpecificRoads;
BRouterServiceConnection bRouterServiceConnection; BRouterServiceConnection bRouterServiceConnection;
OsmandRegions regions; OsmandRegions regions;
WorldRegion worldRegion;
RoutingConfiguration.Builder defaultRoutingConfig; RoutingConfiguration.Builder defaultRoutingConfig;
@ -659,9 +658,6 @@ public class OsmandApplication extends Application {
public OsmandRegions getRegions() { public OsmandRegions getRegions() {
return regions; return regions;
} }
public WorldRegion getWorldRegion() {
return worldRegion;
}
public boolean accessibilityExtensions() { public boolean accessibilityExtensions() {
return (Build.VERSION.SDK_INT < 14) ? getSettings().ACCESSIBILITY_EXTENSIONS.get() : false; return (Build.VERSION.SDK_INT < 14) ? getSettings().ACCESSIBILITY_EXTENSIONS.get() : false;

View file

@ -1,264 +0,0 @@
package net.osmand.plus;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import net.osmand.PlatformUtil;
import net.osmand.data.LatLon;
import net.osmand.map.OsmandRegions;
import net.osmand.map.OsmandRegions.RegionData;
import net.osmand.util.Algorithms;
import android.content.res.Resources;
public class WorldRegion {
public static final String AFRICA_REGION_ID = "africa";
public static final String ASIA_REGION_ID = "asia";
public static final String AUSTRALIA_AND_OCEANIA_REGION_ID = "australia-oceania";
public static final String CENTRAL_AMERICA_REGION_ID = "centralamerica";
public static final String EUROPE_REGION_ID = "europe";
public static final String NORTH_AMERICA_REGION_ID = "northamerica";
public static final String RUSSIA_REGION_ID = "russia";
public static final String SOUTH_AMERICA_REGION_ID = "southamerica";
public static final String WORLD = "world";
private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(WorldRegion.class);
// Region data
private OsmandRegions.RegionData regionData;
// Hierarchy
private WorldRegion superregion;
private List<WorldRegion> subregions;
private List<WorldRegion> flattenedSubregions;
public OsmandRegions.RegionData getRegionData() {
return regionData;
}
public String getName() {
return regionData.getName();
}
private String getRegionId() {
return regionData.getRegionId();
}
public WorldRegion getSuperregion() {
return superregion;
}
public List<WorldRegion> getSubregions() {
return subregions;
}
public List<WorldRegion> getFlattenedSubregions() {
return flattenedSubregions;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
WorldRegion that = (WorldRegion) o;
return !(getName() != null ? !getName().toLowerCase().equals(that.getName().toLowerCase()) : that.getName() != null);
}
@Override
public int hashCode() {
return getName() != null ? getName().hashCode() : 0;
}
public WorldRegion() {
superregion = null;
subregions = new LinkedList<>();
flattenedSubregions = new LinkedList<>();
}
public void initWorld() {
regionId = "";
downloadsId = WORLD;
name = "";
superregion = null;
}
private WorldRegion init(String regionId, OsmandRegions osmandRegions, String name) {
this.regionId = regionId;
String downloadName = osmandRegions.getDownloadName(regionId);
if (downloadName != null) {
this.searchText = osmandRegions.getDownloadNameIndexLowercase(downloadName);
downloadsId = downloadName.toLowerCase();
} else {
downloadsId = regionId.toLowerCase();
}
if (name != null) {
this.name = name;
} else {
this.name = osmandRegions.getLocaleNameByFullName(regionId, false);
if (this.name == null) {
this.name = capitalize(regionId.replace('_', ' '));
}
}
return this;
}
private void addSubregion(WorldRegion subregion, WorldRegion world) {
subregion.superregion = this;
subregions.add(subregion);
world.flattenedSubregions.add(subregion);
}
public void loadWorldRegions(OsmandApplication app) {
List<RegionData> loadedItems = osmandRegions.getAllRegionData();
if (loadedItems.size() == 0) {
return;
}
HashMap<String, WorldRegion> regionsLookupTable = new HashMap<>(loadedItems.size());
// Create main regions
Resources res = app.getResources();
WorldRegion africaRegion = createRegionAs(AFRICA_REGION_ID,
loadedItems, osmandRegions, res.getString(R.string.index_name_africa));
addSubregion(africaRegion, this);
regionsLookupTable.put(africaRegion.regionId, africaRegion);
WorldRegion asiaRegion = createRegionAs(ASIA_REGION_ID,
loadedItems, osmandRegions, res.getString(R.string.index_name_asia));
addSubregion(asiaRegion, this);
regionsLookupTable.put(asiaRegion.regionId, asiaRegion);
WorldRegion australiaAndOceaniaRegion = createRegionAs(AUSTRALIA_AND_OCEANIA_REGION_ID,
loadedItems, osmandRegions, res.getString(R.string.index_name_oceania));
addSubregion(australiaAndOceaniaRegion, this);
regionsLookupTable.put(australiaAndOceaniaRegion.regionId, australiaAndOceaniaRegion);
WorldRegion centralAmericaRegion = createRegionAs(CENTRAL_AMERICA_REGION_ID,
loadedItems, osmandRegions, res.getString(R.string.index_name_central_america));
addSubregion(centralAmericaRegion, this);
regionsLookupTable.put(centralAmericaRegion.getRegionId(), centralAmericaRegion);
WorldRegion europeRegion = createRegionAs(EUROPE_REGION_ID,
loadedItems, osmandRegions, res.getString(R.string.index_name_europe));
addSubregion(europeRegion, this);
regionsLookupTable.put(europeRegion.getRegionId(), europeRegion);
WorldRegion northAmericaRegion = createRegionAs(NORTH_AMERICA_REGION_ID,
loadedItems, osmandRegions, res.getString(R.string.index_name_north_america));
addSubregion(northAmericaRegion, this);
regionsLookupTable.put(northAmericaRegion.getRegionId(), northAmericaRegion);
WorldRegion russiaRegion = createRegionAs(RUSSIA_REGION_ID,
loadedItems, osmandRegions, res.getString(R.string.index_name_russia));
addSubregion(russiaRegion, this);
regionsLookupTable.put(russiaRegion.getRegionId(), russiaRegion);
WorldRegion southAmericaRegion = createRegionAs(SOUTH_AMERICA_REGION_ID,
loadedItems, osmandRegions, res.getString(R.string.index_name_south_america));
addSubregion(southAmericaRegion, this);
regionsLookupTable.put(southAmericaRegion.getRegionId(), southAmericaRegion);
// Process all regions
for (; ; ) {
int processedRegions = 0;
Iterator<Entry<String, String>> iterator = loadedItems.entrySet().iterator();
while (iterator.hasNext()) {
String regionId = iterator.next().getKey();
String parentRegionId = osmandRegions.getParentFullName(regionId);
if (parentRegionId == null) {
continue;
}
// Try to find parent of this region
WorldRegion parentRegion = regionsLookupTable.get(parentRegionId);
if (parentRegion == null) {
continue;
}
WorldRegion newRegion = new WorldRegion().init(regionId, osmandRegions, null);
parentRegion.addSubregion(newRegion, this);
regionsLookupTable.put(newRegion.getRegionId(), newRegion);
// Remove
processedRegions++;
iterator.remove();
}
// If all remaining are orphans, that's all
if (processedRegions == 0)
break;
}
Comparator<WorldRegion> nameComparator = new Comparator<WorldRegion>() {
@Override
public int compare(WorldRegion w1, WorldRegion w2) {
return w1.getName().compareTo(w2.getName());
}
};
sortSubregions(this, nameComparator);
if (loadedItems.size() > 0) {
LOG.warn("Found orphaned regions: " + loadedItems.size());
for (String regionId : loadedItems.keySet()) {
LOG.warn("FullName = " + regionId + " parent=" + osmandRegions.getParentFullName(regionId));
}
}
}
private void sortSubregions(WorldRegion region, Comparator<WorldRegion> comparator) {
Collections.sort(region.subregions, comparator);
for (WorldRegion r : region.subregions) {
if (r.subregions.size() > 0) {
sortSubregions(r, comparator);
}
}
}
private static WorldRegion createRegionAs(String regionId, Map<String, String> loadedItems,
OsmandRegions osmandRegions, String localizedName) {
WorldRegion worldRegion = new WorldRegion().init(regionId, osmandRegions, localizedName);
loadedItems.remove(regionId);
return worldRegion;
}
private String capitalize(String s) {
String[] words = s.split(" ");
if (words[0].length() > 0) {
StringBuilder sb = new StringBuilder();
sb.append(Algorithms.capitalizeFirstLetterAndLowercase(words[0]));
for (int i = 1; i < words.length; i++) {
sb.append(" ");
sb.append(Algorithms.capitalizeFirstLetterAndLowercase(words[i]));
}
return sb.toString();
} else {
return s;
}
}
public WorldRegion getRegionById(String regionId) {
if (regionId.length() == 0) {
return this;
} else {
for (WorldRegion region : flattenedSubregions) {
if (region != null && region.getRegionId().equals(regionId)) {
return region;
}
}
}
return null;
}
}

View file

@ -1,5 +1,39 @@
package net.osmand.plus.download; package net.osmand.plus.download;
import java.io.File;
import java.lang.ref.WeakReference;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import net.osmand.IProgress;
import net.osmand.PlatformUtil;
import net.osmand.access.AccessibleToast;
import net.osmand.map.WorldRegion;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.OsmandSettings.DrivingRegion;
import net.osmand.plus.OsmandSettings.MetricsConstants;
import net.osmand.plus.R;
import net.osmand.plus.Version;
import net.osmand.plus.activities.ActionBarProgressActivity;
import net.osmand.plus.activities.LocalIndexInfo;
import net.osmand.plus.activities.TabActivity;
import net.osmand.plus.base.BasicProgressAsyncTask;
import net.osmand.plus.download.DownloadIndexesThread.DownloadEvents;
import net.osmand.plus.download.DownloadResourceGroup.DownloadResourceGroupType;
import net.osmand.plus.download.ui.ActiveDownloadsDialogFragment;
import net.osmand.plus.download.ui.DataStoragePlaceDialogFragment;
import net.osmand.plus.download.ui.DownloadResourceGroupFragment;
import net.osmand.plus.download.ui.LocalIndexesFragment;
import net.osmand.plus.download.ui.UpdatesIndexFragment;
import net.osmand.plus.views.controls.PagerSlidingTabStrip;
import org.apache.commons.logging.Log;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
import android.content.Intent; import android.content.Intent;
import android.net.Uri; import android.net.Uri;
@ -17,40 +51,6 @@ import android.view.View;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import net.osmand.IProgress;
import net.osmand.PlatformUtil;
import net.osmand.access.AccessibleToast;
import net.osmand.map.OsmandRegions.RegionData;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.OsmandSettings.DrivingRegion;
import net.osmand.plus.OsmandSettings.MetricsConstants;
import net.osmand.plus.R;
import net.osmand.plus.Version;
import net.osmand.plus.WorldRegion;
import net.osmand.plus.activities.ActionBarProgressActivity;
import net.osmand.plus.activities.LocalIndexInfo;
import net.osmand.plus.activities.TabActivity;
import net.osmand.plus.base.BasicProgressAsyncTask;
import net.osmand.plus.download.DownloadIndexesThread.DownloadEvents;
import net.osmand.plus.download.DownloadResourceGroup.DownloadResourceGroupType;
import net.osmand.plus.download.ui.ActiveDownloadsDialogFragment;
import net.osmand.plus.download.ui.DataStoragePlaceDialogFragment;
import net.osmand.plus.download.ui.DownloadResourceGroupFragment;
import net.osmand.plus.download.ui.LocalIndexesFragment;
import net.osmand.plus.download.ui.UpdatesIndexFragment;
import net.osmand.plus.views.controls.PagerSlidingTabStrip;
import org.apache.commons.logging.Log;
import java.io.File;
import java.lang.ref.WeakReference;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
public class DownloadActivity extends ActionBarProgressActivity implements DownloadEvents { public class DownloadActivity extends ActionBarProgressActivity implements DownloadEvents {
private static final Log LOG = PlatformUtil.getLog(DownloadActivity.class); private static final Log LOG = PlatformUtil.getLog(DownloadActivity.class);
@ -212,7 +212,7 @@ public class DownloadActivity extends ActionBarProgressActivity implements Downl
@UiThread @UiThread
public void downloadHasFinished() { public void downloadHasFinished() {
visibleBanner.updateBannerInProgress(); visibleBanner.updateBannerInProgress();
if(downloadItem != null && !WorldRegion.WORLD.equals(downloadItem.getDownloadsId())) { if(downloadItem != null && !WorldRegion.WORLD_BASEMAP.equals(downloadItem.getRegionDownloadNameLC())) {
boolean firstMap = getMyApplication().getSettings().FIRST_MAP_IS_DOWNLOADED.get(); boolean firstMap = getMyApplication().getSettings().FIRST_MAP_IS_DOWNLOADED.get();
if(firstMap) { if(firstMap) {
initSettingsFirstMap(downloadItem); initSettingsFirstMap(downloadItem);
@ -501,10 +501,9 @@ public class DownloadActivity extends ActionBarProgressActivity implements Downl
// TODO test set correctly (4 tests): when you download first Australia, Japan, Luxembourgh, US // TODO test set correctly (4 tests): when you download first Australia, Japan, Luxembourgh, US
getMyApplication().getSettings().FIRST_MAP_IS_DOWNLOADED.set(false); getMyApplication().getSettings().FIRST_MAP_IS_DOWNLOADED.set(false);
DrivingRegion drg = null; DrivingRegion drg = null;
RegionData rd = reg.getRegionData(); boolean americanSigns = "american".equals(reg.getRegionRoadSigns());
boolean americanSigns = "american".equals(rd.getRegionRoadSigns()); boolean leftHand = "yes".equals(reg.getRegionLeftHandDriving());
boolean leftHand = "yes".equals(rd.getRegionLeftHandDriving()); MetricsConstants mc = "miles".equals(reg.getRegionMetric()) ?
MetricsConstants mc = "miles".equals(rd.getRegionMetric()) ?
MetricsConstants.MILES_AND_FOOTS : MetricsConstants.KILOMETERS_AND_METERS; MetricsConstants.MILES_AND_FOOTS : MetricsConstants.KILOMETERS_AND_METERS;
for (DrivingRegion r : DrivingRegion.values()) { for (DrivingRegion r : DrivingRegion.values()) {
if(r.americanSigns == americanSigns && r.leftHandDriving == leftHand && if(r.americanSigns == americanSigns && r.leftHandDriving == leftHand &&
@ -516,7 +515,7 @@ public class DownloadActivity extends ActionBarProgressActivity implements Downl
if (drg != null) { if (drg != null) {
getMyApplication().getSettings().DRIVING_REGION.set(drg); getMyApplication().getSettings().DRIVING_REGION.set(drg);
} }
String lng = rd.getRegionLang(); String lng = reg.getRegionLang();
if (lng != null) { if (lng != null) {
String setTts = null; String setTts = null;
for (String s : OsmandSettings.TTS_AVAILABLE_VOICES) { for (String s : OsmandSettings.TTS_AVAILABLE_VOICES) {
@ -552,7 +551,7 @@ public class DownloadActivity extends ActionBarProgressActivity implements Downl
List<IndexItem> list = worldMaps.getIndividualResources(); List<IndexItem> list = worldMaps.getIndividualResources();
if(list != null) { if(list != null) {
for(IndexItem ii : list) { for(IndexItem ii : list) {
if(ii.getBasename().equalsIgnoreCase("world_basemap")) { if(ii.getBasename().equalsIgnoreCase(WorldRegion.WORLD_BASEMAP)) {
worldMap = ii; worldMap = ii;
break; break;
} }

View file

@ -1,8 +1,5 @@
package net.osmand.plus.download; package net.osmand.plus.download;
import android.annotation.SuppressLint;
import android.content.Context;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
@ -11,9 +8,11 @@ import java.util.List;
import net.osmand.OsmAndCollator; import net.osmand.OsmAndCollator;
import net.osmand.map.OsmandRegions; import net.osmand.map.OsmandRegions;
import net.osmand.map.WorldRegion;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.WorldRegion; import android.annotation.SuppressLint;
import android.content.Context;
@SuppressLint("DefaultLocale") @SuppressLint("DefaultLocale")
public class DownloadResourceGroup { public class DownloadResourceGroup {
@ -316,7 +315,7 @@ public class DownloadResourceGroup {
public String getName(Context ctx) { public String getName(Context ctx) {
if (region != null) { if (region != null) {
return region.getName(); return region.getLocaleName();
} else if (type != null && type.resId != -1) { } else if (type != null && type.resId != -1) {
return ctx.getString(type.resId); return ctx.getString(type.resId);
} else { } else {

View file

@ -12,8 +12,9 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import net.osmand.IndexConstants; import net.osmand.IndexConstants;
import net.osmand.map.OsmandRegions;
import net.osmand.map.WorldRegion;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.WorldRegion;
import net.osmand.plus.download.DownloadOsmandIndexesHelper.AssetIndexItem; import net.osmand.plus.download.DownloadOsmandIndexesHelper.AssetIndexItem;
public class DownloadResources extends DownloadResourceGroup { public class DownloadResources extends DownloadResourceGroup {
@ -30,7 +31,7 @@ public class DownloadResources extends DownloadResourceGroup {
public DownloadResources(OsmandApplication app) { public DownloadResources(OsmandApplication app) {
super(null, DownloadResourceGroupType.WORLD, ""); super(null, DownloadResourceGroupType.WORLD, "");
this.region = app.getWorldRegion(); this.region = app.getRegions().getWorldRegion();
this.app = app; this.app = app;
} }
@ -209,12 +210,7 @@ public class DownloadResources extends DownloadResourceGroup {
DownloadResourceGroup worldMaps = new DownloadResourceGroup(this, DownloadResourceGroupType.WORLD_MAPS); DownloadResourceGroup worldMaps = new DownloadResourceGroup(this, DownloadResourceGroupType.WORLD_MAPS);
Map<WorldRegion, List<IndexItem> > groupByRegion = new LinkedHashMap<WorldRegion, List<IndexItem>>(); Map<WorldRegion, List<IndexItem> > groupByRegion = new LinkedHashMap<WorldRegion, List<IndexItem>>();
OsmandRegions regs = app.getRegions();
Map<String, WorldRegion> downloadIdForRegion = new LinkedHashMap<String, WorldRegion>();
for(WorldRegion wg : region.getFlattenedSubregions()) {
downloadIdForRegion.put(wg.getDownloadsId(), wg);
}
for (IndexItem ii : resources) { for (IndexItem ii : resources) {
if (ii.getType() == DownloadActivityType.VOICE_FILE) { if (ii.getType() == DownloadActivityType.VOICE_FILE) {
if (ii.getFileName().endsWith(IndexConstants.TTSVOICE_INDEX_EXT_ZIP)) { if (ii.getFileName().endsWith(IndexConstants.TTSVOICE_INDEX_EXT_ZIP)) {
@ -225,7 +221,7 @@ public class DownloadResources extends DownloadResourceGroup {
continue; continue;
} }
String basename = ii.getBasename().toLowerCase(); String basename = ii.getBasename().toLowerCase();
WorldRegion wg = downloadIdForRegion.get(basename); WorldRegion wg = regs.getRegionDataByDownloadName(basename);
if (wg != null) { if (wg != null) {
if (!groupByRegion.containsKey(wg)) { if (!groupByRegion.containsKey(wg)) {
groupByRegion.put(wg, new ArrayList<IndexItem>()); groupByRegion.put(wg, new ArrayList<IndexItem>());

View file

@ -1,5 +1,26 @@
package net.osmand.plus.download.ui; package net.osmand.plus.download.ui;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import net.osmand.Collator;
import net.osmand.OsmAndCollator;
import net.osmand.map.OsmandRegions;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.download.DownloadActivity.BannerAndDownloadFreeVersion;
import net.osmand.plus.download.DownloadActivityType;
import net.osmand.plus.download.DownloadIndexesThread.DownloadEvents;
import net.osmand.plus.download.DownloadResourceGroup;
import net.osmand.plus.download.DownloadResourceGroup.DownloadResourceGroupType;
import net.osmand.plus.download.DownloadResources;
import net.osmand.plus.download.IndexItem;
import net.osmand.util.Algorithms;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.DialogFragment; import android.support.v4.app.DialogFragment;
@ -19,28 +40,6 @@ import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams; import android.widget.RelativeLayout.LayoutParams;
import android.widget.SearchView; import android.widget.SearchView;
import net.osmand.Collator;
import net.osmand.OsmAndCollator;
import net.osmand.map.OsmandRegions;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.download.DownloadActivity;
import net.osmand.plus.download.DownloadActivity.BannerAndDownloadFreeVersion;
import net.osmand.plus.download.DownloadActivityType;
import net.osmand.plus.download.DownloadIndexesThread.DownloadEvents;
import net.osmand.plus.download.DownloadResourceGroup;
import net.osmand.plus.download.DownloadResourceGroup.DownloadResourceGroupType;
import net.osmand.plus.download.DownloadResources;
import net.osmand.plus.download.IndexItem;
import net.osmand.util.Algorithms;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
public class SearchDialogFragment extends DialogFragment implements DownloadEvents, OnItemClickListener { public class SearchDialogFragment extends DialogFragment implements DownloadEvents, OnItemClickListener {
public static final String TAG = "SearchDialogFragment"; public static final String TAG = "SearchDialogFragment";
@ -330,8 +329,8 @@ public class SearchDialogFragment extends DialogFragment implements DownloadEven
private void processGroup(DownloadResourceGroup group, List<Object> filter, List<List<String>> conds) { private void processGroup(DownloadResourceGroup group, List<Object> filter, List<List<String>> conds) {
String name = null; String name = null;
if (group.getRegion() != null && group.getRegion().getRegionData().getRegionSearchText() != null) { if (group.getRegion() != null && group.getRegion().getRegionSearchText() != null) {
name = group.getRegion().getRegionData().getRegionSearchText().toLowerCase(); name = group.getRegion().getRegionSearchText().toLowerCase();
} }
if (name == null) { if (name == null) {
name = group.getName(ctx).toLowerCase(); name = group.getName(ctx).toLowerCase();

View file

@ -12,7 +12,7 @@ import net.osmand.binary.BinaryMapDataObject;
import net.osmand.data.LatLon; import net.osmand.data.LatLon;
import net.osmand.data.RotatedTileBox; import net.osmand.data.RotatedTileBox;
import net.osmand.map.OsmandRegions; import net.osmand.map.OsmandRegions;
import net.osmand.map.OsmandRegions.RegionData; import net.osmand.map.WorldRegion;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.resources.ResourceManager; import net.osmand.plus.resources.ResourceManager;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
@ -249,8 +249,8 @@ public class DownloadedRegionsLayer extends OsmandMapLayer {
continue; continue;
} }
String fullName = osmandRegions.getFullName(o); String fullName = osmandRegions.getFullName(o);
RegionData rd = osmandRegions.getRegionData(fullName); WorldRegion rd = osmandRegions.getRegionData(fullName);
if (rd != null && rd.isRegionMapDownload()) { if (rd != null && rd.isRegionMapDownload() && rd.getRegionDownloadName() != null) {
String name = rd.getLocaleName(); String name = rd.getLocaleName();
if (checkIfObjectDownloaded(rd.getRegionDownloadName())) { if (checkIfObjectDownloaded(rd.getRegionDownloadName())) {
return null; return null;