Add download button when the map is missing

This commit is contained in:
vshcherb 2013-09-24 18:53:48 +02:00
parent bc88a329b4
commit 19ce935266
12 changed files with 451 additions and 76 deletions

1
.gitignore vendored
View file

@ -2,6 +2,7 @@
routing*.xml routing*.xml
rendering_types.xml rendering_types.xml
countries.reginfo countries.reginfo
regions.ocbf
h_*.png h_*.png
g_*.png g_*.png
mm_*.png mm_*.png

View file

@ -46,6 +46,7 @@
<copy todir="${src.absolute.dir}/net/osmand/map/"> <copy todir="${src.absolute.dir}/net/osmand/map/">
<fileset dir="../../resources/countries-info/"> <fileset dir="../../resources/countries-info/">
<include name="countries.reginfo" /> <include name="countries.reginfo" />
<include name="regions.ocbf" />
</fileset> </fileset>
</copy> </copy>
</target> </target>
@ -92,6 +93,17 @@
<include name="**/*.java" /> <include name="**/*.java" />
</fileset> </fileset>
</jar> </jar>
<jar destfile="OsmAnd-core-android.jar" manifest="MANIFEST.MF">
<fileset dir="${bin.absolute.dir}">
<include name="**/*.class" />
<exclude name="**/PlatformUtil*"/>
</fileset>
<fileset dir="${src.absolute.dir}">
<include name="**/*.java" />
<exclude name="**/PlatformUtil*"/>
</fileset>
</jar>
<delete file="MANIFEST.MF" /> <delete file="MANIFEST.MF" />
</target> </target>

View file

@ -52,7 +52,7 @@ public class BinaryInspector {
in.inspector(args); in.inspector(args);
// test cases show info // test cases show info
// in.inspector(new String[]{"-vmap", "-vmapobjects", "-zoom=7", "-osm=/home/victor/projects/osmand/temp/zoom_7.osm", "/home/victor/projects/osmand/osm-gen/World_basemap_2.obf"}); in.inspector(new String[]{"/home/victor/projects/osmand/osm-gen/World_basemap_2z.obf"});
// in.inspector(new String[]{"-vmap", "-vmapobjects", /*"-vstreets", "-bbox=14.4,50.1,14.5,50.01", */"/home/victor/projects/osmand/osm-gen/Osmand_regions.obf"}); // in.inspector(new String[]{"-vmap", "-vmapobjects", /*"-vstreets", "-bbox=14.4,50.1,14.5,50.01", */"/home/victor/projects/osmand/osm-gen/Osmand_regions.obf"});
// test case extract parts // test case extract parts
// test case // test case
@ -67,7 +67,7 @@ public class BinaryInspector {
} }
private void println(String s) { private void println(String s) {
if(vInfo != null && vInfo.osm) { if(vInfo != null && vInfo.osm && vInfo.osmOut == null) {
// ignore // ignore
} else { } else {
System.out.println(s); System.out.println(s);
@ -76,7 +76,7 @@ public class BinaryInspector {
} }
private void print(String s) { private void print(String s) {
if(vInfo != null && vInfo.osm) { if(vInfo != null && vInfo.osm && vInfo.osmOut == null) {
// ignore // ignore
} else { } else {
System.out.print(s); System.out.print(s);
@ -696,6 +696,7 @@ public class BinaryInspector {
} }
String name = names.get(keys[j]); String name = names.get(keys[j]);
name = name.replace("'", "&apos;"); name = name.replace("'", "&apos;");
name = name.replace("&", "&amp;");
tags.append("\t<tag k='").append(pair.tag).append("' v='").append(name).append("' />\n"); tags.append("\t<tag k='").append(pair.tag).append("' v='").append(name).append("' />\n");
} }
} }

View file

@ -15,28 +15,44 @@ import java.util.*;
public class OsmandRegions { public class OsmandRegions {
private BinaryMapIndexReader reader;
Map<String, LinkedList<BinaryMapDataObject>> countries = new HashMap<String, LinkedList<BinaryMapDataObject>>(); Map<String, LinkedList<BinaryMapDataObject>> countries = new HashMap<String, LinkedList<BinaryMapDataObject>>();
QuadTree<String> quadTree = new QuadTree<String>(new QuadRect(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE), QuadTree<String> quadTree = null ;
8, 0.55f);
Integer downloadNameType = null; Integer downloadNameType = null;
Integer prefixType = null; Integer prefixType = null;
Integer suffixType = null; private Integer suffixType;
static String FILE_NAME = "/home/victor/projects/osmand/osm-gen/Osmand_regions.obf"; private String fname;
public OsmandRegions() {
public void prepareFile(String fileName) throws IOException {
reader = new BinaryMapIndexReader(new RandomAccessFile(fileName, "r"));
} }
public String getDownloadName(BinaryMapDataObject o) {
Integer getDownloadNameType(){ if(downloadNameType == null) {
return downloadNameType; return null;
}
return o.getNameByType(downloadNameType);
} }
Integer getPrefixType() { public String getPrefix(BinaryMapDataObject o) {
return prefixType; if(prefixType == null) {
return null;
}
return o.getNameByType(prefixType);
} }
Integer getSuffixType() { public String getSuffix(BinaryMapDataObject o) {
return suffixType; if(suffixType == null) {
return null;
}
return o.getNameByType(suffixType);
}
public boolean isInitialized(){
return reader != null;
} }
@ -55,7 +71,7 @@ public class OsmandRegions {
return t % 2 == 1; return t % 2 == 1;
} }
public List<BinaryMapDataObject> getCountries(int tile31x, int tile31y) { private List<BinaryMapDataObject> getCountries(int tile31x, int tile31y) {
HashSet<String> set = new HashSet<String>(quadTree.queryInBox(new QuadRect(tile31x, tile31y, tile31x, tile31y), HashSet<String> set = new HashSet<String>(quadTree.queryInBox(new QuadRect(tile31x, tile31y, tile31x, tile31y),
new ArrayList<String>())); new ArrayList<String>()));
List<BinaryMapDataObject> result = new ArrayList<BinaryMapDataObject>(); List<BinaryMapDataObject> result = new ArrayList<BinaryMapDataObject>();
@ -80,9 +96,15 @@ public class OsmandRegions {
} }
public List<BinaryMapDataObject> queryNoInit(String fileName, final int tile31x, final int tile31y) throws IOException { public List<BinaryMapDataObject> query(final int tile31x, final int tile31y) throws IOException {
if(quadTree != null) {
return getCountries(tile31x, tile31y);
}
return queryNoInit(tile31x, tile31y);
}
private List<BinaryMapDataObject> queryNoInit(final int tile31x, final int tile31y) throws IOException {
final List<BinaryMapDataObject> result = new ArrayList<BinaryMapDataObject>(); final List<BinaryMapDataObject> result = new ArrayList<BinaryMapDataObject>();
BinaryMapIndexReader reader = new BinaryMapIndexReader(new RandomAccessFile(fileName, "r"));
BinaryMapIndexReader.SearchRequest<BinaryMapDataObject> sr = BinaryMapIndexReader.buildSearchRequest(tile31x, tile31x, tile31y, tile31y, BinaryMapIndexReader.SearchRequest<BinaryMapDataObject> sr = BinaryMapIndexReader.buildSearchRequest(tile31x, tile31x, tile31y, tile31y,
5, new BinaryMapIndexReader.SearchFilter() { 5, new BinaryMapIndexReader.SearchFilter() {
@Override @Override
@ -97,6 +119,7 @@ public class OsmandRegions {
if (object.getPointsLength() < 1) { if (object.getPointsLength() < 1) {
return false; return false;
} }
initTypes(object);
if (contain(object, tile31x, tile31y)) { if (contain(object, tile31x, tile31y)) {
result.add(object); result.add(object);
} }
@ -114,10 +137,40 @@ public class OsmandRegions {
} }
public List<BinaryMapDataObject> queryBbox(int lx, int rx, int ty, int by) throws IOException {
final List<BinaryMapDataObject> result = new ArrayList<BinaryMapDataObject>();
BinaryMapIndexReader.SearchRequest<BinaryMapDataObject> sr = BinaryMapIndexReader.buildSearchRequest(lx, rx, ty, by,
5, new BinaryMapIndexReader.SearchFilter() {
@Override
public boolean accept(TIntArrayList types, BinaryMapIndexReader.MapIndex index) {
return true;
}
}, new ResultMatcher<BinaryMapDataObject>() {
private void init(String fileName) throws IOException { @Override
public boolean publish(BinaryMapDataObject object) {
if (object.getPointsLength() < 1) {
return false;
}
initTypes(object);
result.add(object);
return false;
}
BinaryMapIndexReader reader = new BinaryMapIndexReader(new RandomAccessFile(fileName, "r")); @Override
public boolean isCancelled() {
return false;
}
}
);
reader.searchMapIndex(sr);
return result;
}
public void cacheAllCountries() throws IOException {
quadTree = new QuadTree<String>(new QuadRect(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE),
8, 0.55f);
BinaryMapIndexReader.SearchRequest<BinaryMapDataObject> sr = BinaryMapIndexReader.buildSearchRequest(0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, BinaryMapIndexReader.SearchRequest<BinaryMapDataObject> sr = BinaryMapIndexReader.buildSearchRequest(0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE,
5, new BinaryMapIndexReader.SearchFilter() { 5, new BinaryMapIndexReader.SearchFilter() {
@Override @Override
@ -132,14 +185,7 @@ public class OsmandRegions {
if (object.getPointsLength() < 1) { if (object.getPointsLength() < 1) {
return false; return false;
} }
if (downloadNameType == null) { initTypes(object);
downloadNameType = object.getMapIndex().getRule("download_name", null);
prefixType = object.getMapIndex().getRule("region_prefix", null);
suffixType = object.getMapIndex().getRule("region_suffix", null);
if (downloadNameType == null) {
throw new IllegalStateException();
}
}
String nm = object.getNameByType(downloadNameType); String nm = object.getNameByType(downloadNameType);
if (!countries.containsKey(nm)) { if (!countries.containsKey(nm)) {
LinkedList<BinaryMapDataObject> ls = new LinkedList<BinaryMapDataObject>(); LinkedList<BinaryMapDataObject> ls = new LinkedList<BinaryMapDataObject>();
@ -180,45 +226,50 @@ public class OsmandRegions {
reader.searchMapIndex(sr); reader.searchMapIndex(sr);
} }
private void initTypes(BinaryMapDataObject object) {
if (downloadNameType == null) {
downloadNameType = object.getMapIndex().getRule("download_name", null);
prefixType = object.getMapIndex().getRule("region_prefix", null);
suffixType = object.getMapIndex().getRule("region_suffix", null);
if (downloadNameType == null) {
throw new IllegalStateException();
}
}
}
private static void testCountry(OsmandRegions or, double lat, double lon, String... test) throws IOException { private static void testCountry(OsmandRegions or, double lat, double lon, String... test) throws IOException {
//List<BinaryMapDataObject> cs = or.getCountries(MapUtils.get31TileNumberX(lon), MapUtils.get31TileNumberY(lat)); long t = System.currentTimeMillis();
List<BinaryMapDataObject> cs = or.queryNoInit(FILE_NAME, MapUtils.get31TileNumberX(lon), MapUtils.get31TileNumberY(lat)); List<BinaryMapDataObject> cs = or.query(MapUtils.get31TileNumberX(lon), MapUtils.get31TileNumberY(lat));
if(cs.size() != test.length) { Set<String> expected = new TreeSet<String>(Arrays.asList(test));
StringBuilder found = new StringBuilder(); Set<String> found = new TreeSet<String>();
for(BinaryMapDataObject b : cs) { for(BinaryMapDataObject b : cs) {
found.append(b.getName()).append(' '); found.add(b.getName());
} }
throw new IllegalStateException(" Expected " + Arrays.toString(test) + " - Lat " + lat + " lon " + lon + ", but found : " + found);
}
for (int i = 0; i < test.length; i++) { if(!found.equals(expected)) {
String nm = cs.get(i).getName(); throw new IllegalStateException(" Expected " + expected + " but was " + found);
if (!test[i].equals(nm)) {
throw new IllegalStateException(" Expected " + test[i] + " but was " + nm);
}
} }
System.out.println("Found " + expected + " in " + (System.currentTimeMillis() - t) + " ms");
} }
public static void main(String[] args) throws IOException { public static void main(String[] args) throws IOException {
OsmandRegions or = new OsmandRegions(); OsmandRegions or = new OsmandRegions();
long t = System.currentTimeMillis(); or.prepareFile("/home/victor/projects/osmand/osm-gen/Osmand_regions.obf");
// or.init(FILE_NAME);
System.out.println(System.currentTimeMillis() - t); // long t = System.currentTimeMillis();
// or.cacheAllCountries();
// System.out.println("Init " + (System.currentTimeMillis() - t));
//testCountry(or, 15.8, 23.09, "chad"); //testCountry(or, 15.8, 23.09, "chad");
testCountry(or, 52.10, 4.92, "netherlands"); testCountry(or, 52.10, 4.92, "netherlands");
testCountry(or, 52.15, 7.50, "nordrhein-westfalen"); testCountry(or, 52.15, 7.50, "nordrhein-westfalen");
testCountry(or, 40.0760, 9.2807, "italy"); testCountry(or, 40.0760, 9.2807, "italy");
System.out.println(System.currentTimeMillis() - t);
testCountry(or, 28.8056, 29.9858, "africa", "egypt" ); testCountry(or, 28.8056, 29.9858, "africa", "egypt" );
System.out.println(System.currentTimeMillis() - t);
testCountry(or, 35.7521, 139.7887, "japan"); testCountry(or, 35.7521, 139.7887, "japan");
System.out.println(System.currentTimeMillis() - t);
testCountry(or, 46.5145, 102.2580, "mongolia"); testCountry(or, 46.5145, 102.2580, "mongolia");
System.out.println(System.currentTimeMillis() - t);
} }
} }

View file

@ -47,6 +47,7 @@
<copy todir="${src.absolute.dir}/net/osmand/map/"> <copy todir="${src.absolute.dir}/net/osmand/map/">
<fileset dir="../../resources/countries-info/" > <fileset dir="../../resources/countries-info/" >
<include name="countries.reginfo"/> <include name="countries.reginfo"/>
<include name="regions.ocbf"/>
</fileset> </fileset>
</copy> </copy>
</target> </target>

View file

@ -9,6 +9,7 @@
3. All your modified/created strings are in the top of the file (to make easier find what\'s translated). 3. All your modified/created strings are in the top of the file (to make easier find what\'s translated).
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
--> -->
<string name="base_world_map">base world map</string>
<string name="tip_map_styles">Map Styles</string> <string name="tip_map_styles">Map Styles</string>
<string name="tip_map_styles_t">OsmAnd supports displaying the offline vector maps in different map styles to suit your to needs: <string name="tip_map_styles_t">OsmAnd supports displaying the offline vector maps in different map styles to suit your to needs:
\n\nOther than the balanced \'default\' map style, you may in \'Menu\' → \'Configure screen\' → \'Map Style\' select for example \n\nOther than the balanced \'default\' map style, you may in \'Menu\' → \'Configure screen\' → \'Map Style\' select for example

View file

@ -37,20 +37,7 @@ import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin;
import net.osmand.plus.render.MapVectorLayer; import net.osmand.plus.render.MapVectorLayer;
import net.osmand.plus.render.RenderingIcons; import net.osmand.plus.render.RenderingIcons;
import net.osmand.plus.routing.RoutingHelper; import net.osmand.plus.routing.RoutingHelper;
import net.osmand.plus.views.ContextMenuLayer; import net.osmand.plus.views.*;
import net.osmand.plus.views.FavoritesLayer;
import net.osmand.plus.views.GPXLayer;
import net.osmand.plus.views.MapControlsLayer;
import net.osmand.plus.views.MapInfoLayer;
import net.osmand.plus.views.MapTileLayer;
import net.osmand.plus.views.OsmandMapTileView;
import net.osmand.plus.views.POIMapLayer;
import net.osmand.plus.views.PointLocationLayer;
import net.osmand.plus.views.PointNavigationLayer;
import net.osmand.plus.views.RouteInfoLayer;
import net.osmand.plus.views.RouteLayer;
import net.osmand.plus.views.TransportInfoLayer;
import net.osmand.plus.views.TransportStopsLayer;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.AlertDialog.Builder; import android.app.AlertDialog.Builder;
import android.app.ProgressDialog; import android.app.ProgressDialog;
@ -94,6 +81,7 @@ public class MapActivityLayers {
private ContextMenuLayer contextMenuLayer; private ContextMenuLayer contextMenuLayer;
private RouteInfoLayer routeInfoLayer; private RouteInfoLayer routeInfoLayer;
private MapControlsLayer mapControlsLayer; private MapControlsLayer mapControlsLayer;
private DownloadedRegionsLayer downloadedRegionsLayer;
public MapActivityLayers(MapActivity activity) { public MapActivityLayers(MapActivity activity) {
this.activity = activity; this.activity = activity;
@ -118,6 +106,9 @@ public class MapActivityLayers {
mapVectorLayer = new MapVectorLayer(mapTileLayer); mapVectorLayer = new MapVectorLayer(mapTileLayer);
mapView.addLayer(mapVectorLayer, 0.5f); mapView.addLayer(mapVectorLayer, 0.5f);
downloadedRegionsLayer = new DownloadedRegionsLayer();
mapView.addLayer(downloadedRegionsLayer, 0.5f);
// 0.9 gpx layer // 0.9 gpx layer
gpxLayer = new GPXLayer(); gpxLayer = new GPXLayer();
mapView.addLayer(gpxLayer, 0.9f); mapView.addLayer(gpxLayer, 0.9f);

View file

@ -22,6 +22,7 @@ import java.util.Set;
import net.osmand.IProgress; import net.osmand.IProgress;
import net.osmand.NativeLibrary.NativeSearchResult; import net.osmand.NativeLibrary.NativeSearchResult;
import net.osmand.PlatformUtil; import net.osmand.PlatformUtil;
import net.osmand.ResultMatcher;
import net.osmand.access.AccessibleToast; import net.osmand.access.AccessibleToast;
import net.osmand.binary.BinaryMapDataObject; import net.osmand.binary.BinaryMapDataObject;
import net.osmand.binary.BinaryMapIndexReader; import net.osmand.binary.BinaryMapIndexReader;
@ -249,7 +250,7 @@ public class MapRenderRepositories {
} }
NativeSearchResult resultHandler = library.searchObjectsForRendering(leftX, rightX, topY, bottomY, zoom, renderingReq, NativeSearchResult resultHandler = library.searchObjectsForRendering(leftX, rightX, topY, bottomY, zoom, renderingReq,
checkForDuplicateObjectIds, this, context.getString(R.string.switch_to_raster_map_to_see)); checkForDuplicateObjectIds, this, /*context.getString(R.string.switch_to_raster_map_to_see)*/ "");
if (checkWhetherInterrupted()) { if (checkWhetherInterrupted()) {
resultHandler.deleteNativeResult(); resultHandler.deleteNativeResult();
return false; return false;
@ -399,12 +400,6 @@ public class MapRenderRepositories {
mapIndex.initMapEncodingRule(0, 1, "natural", "coastline"); mapIndex.initMapEncodingRule(0, 1, "natural", "coastline");
mapIndex.initMapEncodingRule(0, 2, "name", ""); mapIndex.initMapEncodingRule(0, 2, "name", "");
} }
// avoid overflow int errors
BinaryMapDataObject o = new BinaryMapDataObject(new int[] { leftX + (rightX - leftX) / 2, topY + (bottomY - topY) / 2 },
new int[] { mapIndex.coastlineEncodingType }, null, -1);
o.setMapIndex(mapIndex);
o.putObjectName(mapIndex.nameEncodingType, context.getString(R.string.switch_to_raster_map_to_see));
tempResult.add(o);
} }
if(zoom <= BASEMAP_ZOOM || emptyData) { if(zoom <= BASEMAP_ZOOM || emptyData) {
tempResult.addAll(basemapResult); tempResult.addAll(basemapResult);
@ -443,6 +438,36 @@ public class MapRenderRepositories {
} }
} }
public boolean checkIfMapIsEmpty(int leftX, int rightX, int topY, int bottomY, int zoom){
final boolean[] empty = new boolean[] {true};
SearchRequest<BinaryMapDataObject> searchRequest = BinaryMapIndexReader.buildSearchRequest(leftX, rightX, topY, bottomY, zoom,
null, new ResultMatcher<BinaryMapDataObject>() {
@Override
public boolean publish(BinaryMapDataObject object) {
empty[0] = false;
return false;
}
@Override
public boolean isCancelled() {
return !empty[0];
}
});
for (BinaryMapIndexReader c : files.values()) {
if(!c.isBasemap()) {
try {
c.searchMapIndex(searchRequest);
} catch (IOException e) {
}
if(!empty[0]) {
return false;
}
}
}
return empty[0];
}
public synchronized void loadMap(RotatedTileBox tileRect, List<IMapDownloaderCallback> notifyList) { public synchronized void loadMap(RotatedTileBox tileRect, List<IMapDownloaderCallback> notifyList) {
interrupted = false; interrupted = false;
if (currentRenderingContext != null) { if (currentRenderingContext != null) {

View file

@ -50,7 +50,7 @@ public class NativeOsmandLibrary extends NativeLibrary {
log.debug("Creating NativeOsmandLibrary instance..."); //$NON-NLS-1$ log.debug("Creating NativeOsmandLibrary instance..."); //$NON-NLS-1$
library = new NativeOsmandLibrary(true); library = new NativeOsmandLibrary(true);
isNativeSupported = true; isNativeSupported = true;
} catch(Throwable e) { } catch(Error e) {
log.error("Failed to load new native library", e); //$NON-NLS-1$ log.error("Failed to load new native library", e); //$NON-NLS-1$
} }
if(!isNativeSupported) { if(!isNativeSupported) {

View file

@ -18,6 +18,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import android.os.AsyncTask;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.GeoidAltitudeCorrection; import net.osmand.GeoidAltitudeCorrection;
import net.osmand.IProgress; import net.osmand.IProgress;
@ -67,6 +68,7 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.view.WindowManager; import android.view.WindowManager;
import net.osmand.map.OsmandRegions;
/** /**
* Resource manager is responsible to work with all resources * Resource manager is responsible to work with all resources
@ -124,6 +126,8 @@ public class ResourceManager {
protected final MapRenderRepositories renderer; protected final MapRenderRepositories renderer;
protected final OsmandRegions regions;
protected final MapTileDownloader tileDownloader; protected final MapTileDownloader tileDownloader;
public final AsyncLoadingThread asyncLoadingThread = new AsyncLoadingThread(this); public final AsyncLoadingThread asyncLoadingThread = new AsyncLoadingThread(this);
@ -146,6 +150,7 @@ public class ResourceManager {
float tiles = (dm.widthPixels / 256 + 2) * (dm.heightPixels / 256 + 2) * 3; float tiles = (dm.widthPixels / 256 + 2) * (dm.heightPixels / 256 + 2) * 3;
log.info("Tiles to load in memory : " + tiles); log.info("Tiles to load in memory : " + tiles);
maxImgCacheSize = (int) (tiles) ; maxImgCacheSize = (int) (tiles) ;
regions = new OsmandRegions();
} }
public MapTileDownloader getMapTileDownloader() { public MapTileDownloader getMapTileDownloader() {
@ -405,6 +410,7 @@ public class ResourceManager {
warnings.addAll(checkAssets(progress)); warnings.addAll(checkAssets(progress));
initRenderers(progress); initRenderers(progress);
geoidAltitudeCorrection = new GeoidAltitudeCorrection(context.getAppPath(null)); geoidAltitudeCorrection = new GeoidAltitudeCorrection(context.getAppPath(null));
indexRegionsBoundaries(progress, false);
// do it lazy // do it lazy
// indexingImageTiles(progress); // indexingImageTiles(progress);
warnings.addAll(indexingMaps(progress)); warnings.addAll(indexingMaps(progress));
@ -414,6 +420,22 @@ public class ResourceManager {
return warnings; return warnings;
} }
private void indexRegionsBoundaries(IProgress progress, boolean overwrite) {
try {
File file = context.getAppPath("regions.ocbf");
if (file != null) {
if (!file.exists() || overwrite) {
Algorithms.streamCopy(OsmandRegions.class.getResourceAsStream("regions.ocbf"),
new FileOutputStream(file));
}
}
regions.prepareFile(file.getAbsolutePath());
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
public List<String> indexVoiceFiles(IProgress progress){ public List<String> indexVoiceFiles(IProgress progress){
File file = context.getAppPath(IndexConstants.VOICE_INDEX_DIR); File file = context.getAppPath(IndexConstants.VOICE_INDEX_DIR);
file.mkdirs(); file.mkdirs();
@ -446,6 +468,7 @@ public class ResourceManager {
if(applicationDataDir.canWrite()){ if(applicationDataDir.canWrite()){
try { try {
progress.startTask(context.getString(R.string.installing_new_resources), -1); progress.startTask(context.getString(R.string.installing_new_resources), -1);
indexRegionsBoundaries(progress, true);
AssetManager assetManager = context.getAssets(); AssetManager assetManager = context.getAssets();
boolean isFirstInstall = context.getSettings().PREVIOUS_INSTALLED_VERSION.get().equals(""); boolean isFirstInstall = context.getSettings().PREVIOUS_INSTALLED_VERSION.get().equals("");
unpackBundledAssets(assetManager, applicationDataDir, progress, isFirstInstall); unpackBundledAssets(assetManager, applicationDataDir, progress, isFirstInstall);
@ -939,6 +962,10 @@ public class ResourceManager {
return geoidAltitudeCorrection; return geoidAltitudeCorrection;
} }
public OsmandRegions getOsmandRegions() {
return regions;
}
protected synchronized void clearTiles() { protected synchronized void clearTiles() {
log.info("Cleaning tiles - size = " + cacheOfImages.size()); //$NON-NLS-1$ log.info("Cleaning tiles - size = " + cacheOfImages.size()); //$NON-NLS-1$

View file

@ -0,0 +1,265 @@
package net.osmand.plus.views;
import android.content.Context;
import android.content.Intent;
import android.graphics.*;
import android.graphics.Paint.Cap;
import android.graphics.Paint.Join;
import android.graphics.Paint.Style;
import android.os.AsyncTask;
import android.text.TextPaint;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import net.osmand.IndexConstants;
import net.osmand.binary.BinaryMapDataObject;
import net.osmand.map.OsmandRegions;
import net.osmand.plus.GPXUtilities.GPXFile;
import net.osmand.plus.GPXUtilities.WptPt;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.activities.DownloadIndexActivity;
import net.osmand.plus.activities.OsmandIntents;
import net.osmand.plus.resources.ResourceManager;
import net.osmand.render.RenderingRuleSearchRequest;
import net.osmand.render.RenderingRulesStorage;
import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
import java.io.IOException;
import java.util.*;
public class DownloadedRegionsLayer extends OsmandMapLayer {
private OsmandMapTileView view;
private Paint paint;
private Path path;
private OsmandSettings settings;
private OsmandRegions osmandRegions;
private List<BinaryMapDataObject> objectsToDraw = new ArrayList<BinaryMapDataObject>();
private RectF queriedBBox = new RectF();
private int queriedZoom = 0;
private boolean basemapExists = true;
private boolean noMapsPresent = false;
private TextPaint textPaint;
private AsyncTask<?, ?, ?> currentTask = null;
private AsyncTask<?, ?, ?> pendingTask = null;
private ResourceManager rm;
private Button downloadBtn;
private StringBuilder filter = new StringBuilder();
@Override
public void initLayer(final OsmandMapTileView view) {
this.view = view;
settings = view.getSettings();
rm = view.getApplication().getResourceManager();
osmandRegions = rm.getOsmandRegions();
paint = new Paint();
paint.setStyle(Style.FILL_AND_STROKE);
paint.setStrokeWidth(1);
paint.setColor(Color.argb(100, 50, 200, 50));
paint.setAntiAlias(true);
paint.setStrokeCap(Cap.ROUND);
paint.setStrokeJoin(Join.ROUND);
textPaint = new TextPaint();
final WindowManager wmgr = (WindowManager) view.getApplication().getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics dm = new DisplayMetrics();
wmgr.getDefaultDisplay().getMetrics(dm);
textPaint.setStrokeWidth(21 * dm.scaledDensity);
textPaint.setAntiAlias(true);
textPaint.setTextAlign(Paint.Align.CENTER);
FrameLayout fl = (FrameLayout) view.getParent();
downloadBtn = new Button(view.getContext());
downloadBtn.setVisibility(View.GONE);
downloadBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Intent intent = new Intent(view.getContext(), OsmandIntents.getDownloadIndexActivity());
intent.putExtra(DownloadIndexActivity.FILTER_KEY, filter.toString());
view.getContext().startActivity(intent);
}
});
final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
lp.gravity = Gravity.CENTER;
fl.addView(downloadBtn, lp);
path = new Path();
}
private static int ZOOM_TO_SHOW_BORDERS_ST = 5;
private static int ZOOM_TO_SHOW_BORDERS = 7;
private static int ZOOM_TO_SHOW_MAP_NAMES = 12;
@Override
public void onDraw(Canvas canvas, RectF latLonBox, RectF tilesRect, DrawSettings nightMode) {
final int zoom = view.getZoom();
if(downloadBtn.getVisibility() == View.VISIBLE) {
downloadBtn.setVisibility(View.GONE);
}
if (zoom >= ZOOM_TO_SHOW_BORDERS_ST && (zoom < ZOOM_TO_SHOW_BORDERS || zoom >= ZOOM_TO_SHOW_MAP_NAMES) &&
osmandRegions.isInitialized()) {
if (!queriedBBox.contains(latLonBox) || Math.abs(queriedZoom - zoom) > 2) {
float w = Math.abs(latLonBox.width() / 2);
float h = Math.abs(latLonBox.height() / 2);
final RectF rf = new RectF(latLonBox.left - w, latLonBox.top + h, latLonBox.right + w, latLonBox.bottom - h);
AsyncTask<Object, Object, List<BinaryMapDataObject>> task = new AsyncTask<Object, Object, List<BinaryMapDataObject>>() {
@Override
protected List<BinaryMapDataObject> doInBackground(Object... params) {
if (queriedBBox.contains(rf)) {
return null;
}
if(zoom < ZOOM_TO_SHOW_MAP_NAMES) {
basemapExists = rm.getRenderer().basemapExists();
}
List<BinaryMapDataObject> result = null;
int left = MapUtils.get31TileNumberX(rf.left);
int right = MapUtils.get31TileNumberX(rf.right);
int top = MapUtils.get31TileNumberY(rf.top);
int bottom = MapUtils.get31TileNumberY(rf.bottom);
final boolean empty = rm.getRenderer().checkIfMapIsEmpty(left, right, top, bottom, zoom);
noMapsPresent = empty;
if(!empty && zoom >= ZOOM_TO_SHOW_MAP_NAMES) {
return Collections.emptyList();
}
try {
result = osmandRegions.queryBbox(left, right, top, bottom);
} catch (IOException e) {
return result;
}
Iterator<BinaryMapDataObject> it = result.iterator();
while (it.hasNext()) {
BinaryMapDataObject o = it.next();
if (zoom < ZOOM_TO_SHOW_BORDERS) {
//
} else {
if (!osmandRegions.contain(o, left / 2 + right / 2, top / 2 + bottom / 2)) {
it.remove();
}
}
}
return result;
}
@Override
protected void onPreExecute() {
currentTask = this;
}
@Override
protected void onPostExecute(List<BinaryMapDataObject> result) {
if (result != null) {
queriedBBox = rf;
objectsToDraw = result;
queriedZoom = zoom;
}
currentTask = null;
if (pendingTask != null) {
pendingTask.execute();
pendingTask = null;
}
}
};
if (currentTask == null) {
task.execute();
} else {
pendingTask = task;
}
}
final List<BinaryMapDataObject> currentObjects = objectsToDraw;
if ((currentObjects != null && currentObjects.size() > 0) || noMapsPresent) {
if (zoom >= ZOOM_TO_SHOW_MAP_NAMES) {
StringBuilder s = new StringBuilder(view.getResources().getString(R.string.download_files));
filter.setLength(0);
if ((currentObjects != null && currentObjects.size() > 0)) {
for (int i = 0; i < currentObjects.size(); i++) {
if (i > 0) {
s.append(" & ");
} else {
s.append(" ");
}
final BinaryMapDataObject o = currentObjects.get(i);
String string = Algorithms.capitalizeFirstLetterAndLowercase(o.getName());
filter.append(string + " ");
if (osmandRegions.getPrefix(o) != null) {
string = Algorithms.capitalizeFirstLetterAndLowercase(osmandRegions.getPrefix(o)) + " " + string;
}
s.append(string);
}
}
downloadBtn.setVisibility(View.VISIBLE);
downloadBtn.setText(s.toString());
} else {
if(!basemapExists) {
filter.setLength(0);
filter.append("basemap");
downloadBtn.setVisibility(View.VISIBLE);
downloadBtn.setText(view.getResources().getString(R.string.download_files) + " " +
view.getResources().getString(R.string.base_world_map));
}
for (BinaryMapDataObject o : currentObjects) {
final String key = Algorithms.capitalizeFirstLetterAndLowercase(osmandRegions.getDownloadName(o)) +
IndexConstants.BINARY_MAP_INDEX_EXT;
if (!rm.getIndexFileNames().containsKey(key)) {
continue;
}
path.reset();
double lat = MapUtils.get31LatitudeY(o.getPoint31YTile(0));
double lon = MapUtils.get31LongitudeX(o.getPoint31XTile(0));
path.moveTo(view.getRotatedMapXForPoint(lat, lon), view.getRotatedMapYForPoint(lat, lon));
for(int j = 1 ; j < o.getPointsLength(); j++) {
lat = MapUtils.get31LatitudeY(o.getPoint31YTile(j));
lon = MapUtils.get31LongitudeX(o.getPoint31XTile(j));
path.lineTo(view.getRotatedMapXForPoint(lat, lon),
view.getRotatedMapYForPoint(lat, lon));
}
canvas.drawPath(path, paint);
}
}
}
}
}
@Override
public void destroyLayer() {
((FrameLayout)downloadBtn.getParent()).removeView(downloadBtn);
}
@Override
public boolean drawInScreenPixels() {
return false;
}
@Override
public boolean onLongPressEvent(PointF point) {
return false;
}
@Override
public boolean onSingleTap(PointF point) {
return false;
}
}

View file

@ -413,7 +413,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
public int getCenterPointY() { public int getCenterPointY() {
if (mapPosition == OsmandSettings.BOTTOM_CONSTANT) { if (mapPosition == OsmandSettings.BOTTOM_CONSTANT) {
return 3 * getHeight() / 4; return 4 * getHeight() / 5;
} }
return getHeight() / 2; return getHeight() / 2;
} }