Add download button when the map is missing
This commit is contained in:
parent
bc88a329b4
commit
19ce935266
12 changed files with 451 additions and 76 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,6 +2,7 @@
|
|||
routing*.xml
|
||||
rendering_types.xml
|
||||
countries.reginfo
|
||||
regions.ocbf
|
||||
h_*.png
|
||||
g_*.png
|
||||
mm_*.png
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
<copy todir="${src.absolute.dir}/net/osmand/map/">
|
||||
<fileset dir="../../resources/countries-info/">
|
||||
<include name="countries.reginfo" />
|
||||
<include name="regions.ocbf" />
|
||||
</fileset>
|
||||
</copy>
|
||||
</target>
|
||||
|
@ -92,6 +93,17 @@
|
|||
<include name="**/*.java" />
|
||||
</fileset>
|
||||
</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" />
|
||||
</target>
|
||||
|
|
|
@ -52,7 +52,7 @@ public class BinaryInspector {
|
|||
in.inspector(args);
|
||||
// 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"});
|
||||
// test case extract parts
|
||||
// test case
|
||||
|
@ -67,16 +67,16 @@ public class BinaryInspector {
|
|||
}
|
||||
|
||||
private void println(String s) {
|
||||
if(vInfo != null && vInfo.osm) {
|
||||
if(vInfo != null && vInfo.osm && vInfo.osmOut == null) {
|
||||
// ignore
|
||||
} else {
|
||||
System.out.println(s);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void print(String s) {
|
||||
if(vInfo != null && vInfo.osm) {
|
||||
if(vInfo != null && vInfo.osm && vInfo.osmOut == null) {
|
||||
// ignore
|
||||
} else {
|
||||
System.out.print(s);
|
||||
|
@ -696,6 +696,7 @@ public class BinaryInspector {
|
|||
}
|
||||
String name = names.get(keys[j]);
|
||||
name = name.replace("'", "'");
|
||||
name = name.replace("&", "&");
|
||||
tags.append("\t<tag k='").append(pair.tag).append("' v='").append(name).append("' />\n");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,28 +15,44 @@ import java.util.*;
|
|||
|
||||
public class OsmandRegions {
|
||||
|
||||
private BinaryMapIndexReader reader;
|
||||
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),
|
||||
8, 0.55f);
|
||||
QuadTree<String> quadTree = null ;
|
||||
|
||||
|
||||
Integer downloadNameType = null;
|
||||
Integer prefixType = null;
|
||||
Integer suffixType = null;
|
||||
static String FILE_NAME = "/home/victor/projects/osmand/osm-gen/Osmand_regions.obf";
|
||||
private Integer suffixType;
|
||||
private String fname;
|
||||
|
||||
public OsmandRegions() {
|
||||
|
||||
public void prepareFile(String fileName) throws IOException {
|
||||
reader = new BinaryMapIndexReader(new RandomAccessFile(fileName, "r"));
|
||||
}
|
||||
|
||||
|
||||
Integer getDownloadNameType(){
|
||||
return downloadNameType;
|
||||
public String getDownloadName(BinaryMapDataObject o) {
|
||||
if(downloadNameType == null) {
|
||||
return null;
|
||||
}
|
||||
return o.getNameByType(downloadNameType);
|
||||
}
|
||||
|
||||
Integer getPrefixType() {
|
||||
return prefixType;
|
||||
public String getPrefix(BinaryMapDataObject o) {
|
||||
if(prefixType == null) {
|
||||
return null;
|
||||
}
|
||||
return o.getNameByType(prefixType);
|
||||
}
|
||||
|
||||
Integer getSuffixType() {
|
||||
return suffixType;
|
||||
public String getSuffix(BinaryMapDataObject o) {
|
||||
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;
|
||||
}
|
||||
|
||||
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),
|
||||
new ArrayList<String>()));
|
||||
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>();
|
||||
BinaryMapIndexReader reader = new BinaryMapIndexReader(new RandomAccessFile(fileName, "r"));
|
||||
BinaryMapIndexReader.SearchRequest<BinaryMapDataObject> sr = BinaryMapIndexReader.buildSearchRequest(tile31x, tile31x, tile31y, tile31y,
|
||||
5, new BinaryMapIndexReader.SearchFilter() {
|
||||
@Override
|
||||
|
@ -97,6 +119,7 @@ public class OsmandRegions {
|
|||
if (object.getPointsLength() < 1) {
|
||||
return false;
|
||||
}
|
||||
initTypes(object);
|
||||
if (contain(object, tile31x, tile31y)) {
|
||||
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,
|
||||
5, new BinaryMapIndexReader.SearchFilter() {
|
||||
@Override
|
||||
|
@ -132,14 +185,7 @@ public class OsmandRegions {
|
|||
if (object.getPointsLength() < 1) {
|
||||
return false;
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
initTypes(object);
|
||||
String nm = object.getNameByType(downloadNameType);
|
||||
if (!countries.containsKey(nm)) {
|
||||
LinkedList<BinaryMapDataObject> ls = new LinkedList<BinaryMapDataObject>();
|
||||
|
@ -180,45 +226,50 @@ public class OsmandRegions {
|
|||
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 {
|
||||
//List<BinaryMapDataObject> cs = or.getCountries(MapUtils.get31TileNumberX(lon), MapUtils.get31TileNumberY(lat));
|
||||
List<BinaryMapDataObject> cs = or.queryNoInit(FILE_NAME, MapUtils.get31TileNumberX(lon), MapUtils.get31TileNumberY(lat));
|
||||
if(cs.size() != test.length) {
|
||||
StringBuilder found = new StringBuilder();
|
||||
long t = System.currentTimeMillis();
|
||||
List<BinaryMapDataObject> cs = or.query(MapUtils.get31TileNumberX(lon), MapUtils.get31TileNumberY(lat));
|
||||
Set<String> expected = new TreeSet<String>(Arrays.asList(test));
|
||||
Set<String> found = new TreeSet<String>();
|
||||
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++) {
|
||||
String nm = cs.get(i).getName();
|
||||
if (!test[i].equals(nm)) {
|
||||
throw new IllegalStateException(" Expected " + test[i] + " but was " + nm);
|
||||
}
|
||||
if(!found.equals(expected)) {
|
||||
throw new IllegalStateException(" Expected " + expected + " but was " + found);
|
||||
}
|
||||
System.out.println("Found " + expected + " in " + (System.currentTimeMillis() - t) + " ms");
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
OsmandRegions or = new OsmandRegions();
|
||||
long t = System.currentTimeMillis();
|
||||
// or.init(FILE_NAME);
|
||||
System.out.println(System.currentTimeMillis() - t);
|
||||
or.prepareFile("/home/victor/projects/osmand/osm-gen/Osmand_regions.obf");
|
||||
|
||||
// long t = System.currentTimeMillis();
|
||||
// or.cacheAllCountries();
|
||||
// System.out.println("Init " + (System.currentTimeMillis() - t));
|
||||
|
||||
//testCountry(or, 15.8, 23.09, "chad");
|
||||
testCountry(or, 52.10, 4.92, "netherlands");
|
||||
testCountry(or, 52.15, 7.50, "nordrhein-westfalen");
|
||||
testCountry(or, 40.0760, 9.2807, "italy");
|
||||
System.out.println(System.currentTimeMillis() - t);
|
||||
testCountry(or, 28.8056, 29.9858, "africa", "egypt" );
|
||||
System.out.println(System.currentTimeMillis() - t);
|
||||
testCountry(or, 35.7521, 139.7887, "japan");
|
||||
System.out.println(System.currentTimeMillis() - t);
|
||||
testCountry(or, 46.5145, 102.2580, "mongolia");
|
||||
|
||||
System.out.println(System.currentTimeMillis() - t);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
<copy todir="${src.absolute.dir}/net/osmand/map/">
|
||||
<fileset dir="../../resources/countries-info/" >
|
||||
<include name="countries.reginfo"/>
|
||||
<include name="regions.ocbf"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
</target>
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
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
|
||||
-->
|
||||
<string name="base_world_map">base world map</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:
|
||||
\n\nOther than the balanced \'default\' map style, you may in \'Menu\' → \'Configure screen\' → \'Map Style\' select for example
|
||||
|
|
|
@ -37,20 +37,7 @@ import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin;
|
|||
import net.osmand.plus.render.MapVectorLayer;
|
||||
import net.osmand.plus.render.RenderingIcons;
|
||||
import net.osmand.plus.routing.RoutingHelper;
|
||||
import net.osmand.plus.views.ContextMenuLayer;
|
||||
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 net.osmand.plus.views.*;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.AlertDialog.Builder;
|
||||
import android.app.ProgressDialog;
|
||||
|
@ -94,6 +81,7 @@ public class MapActivityLayers {
|
|||
private ContextMenuLayer contextMenuLayer;
|
||||
private RouteInfoLayer routeInfoLayer;
|
||||
private MapControlsLayer mapControlsLayer;
|
||||
private DownloadedRegionsLayer downloadedRegionsLayer;
|
||||
|
||||
public MapActivityLayers(MapActivity activity) {
|
||||
this.activity = activity;
|
||||
|
@ -117,7 +105,10 @@ public class MapActivityLayers {
|
|||
// 0.5 layer
|
||||
mapVectorLayer = new MapVectorLayer(mapTileLayer);
|
||||
mapView.addLayer(mapVectorLayer, 0.5f);
|
||||
|
||||
|
||||
downloadedRegionsLayer = new DownloadedRegionsLayer();
|
||||
mapView.addLayer(downloadedRegionsLayer, 0.5f);
|
||||
|
||||
// 0.9 gpx layer
|
||||
gpxLayer = new GPXLayer();
|
||||
mapView.addLayer(gpxLayer, 0.9f);
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.util.Set;
|
|||
import net.osmand.IProgress;
|
||||
import net.osmand.NativeLibrary.NativeSearchResult;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.ResultMatcher;
|
||||
import net.osmand.access.AccessibleToast;
|
||||
import net.osmand.binary.BinaryMapDataObject;
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
|
@ -249,7 +250,7 @@ public class MapRenderRepositories {
|
|||
}
|
||||
|
||||
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()) {
|
||||
resultHandler.deleteNativeResult();
|
||||
return false;
|
||||
|
@ -399,12 +400,6 @@ public class MapRenderRepositories {
|
|||
mapIndex.initMapEncodingRule(0, 1, "natural", "coastline");
|
||||
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) {
|
||||
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) {
|
||||
interrupted = false;
|
||||
if (currentRenderingContext != null) {
|
||||
|
|
|
@ -50,7 +50,7 @@ public class NativeOsmandLibrary extends NativeLibrary {
|
|||
log.debug("Creating NativeOsmandLibrary instance..."); //$NON-NLS-1$
|
||||
library = new NativeOsmandLibrary(true);
|
||||
isNativeSupported = true;
|
||||
} catch(Throwable e) {
|
||||
} catch(Error e) {
|
||||
log.error("Failed to load new native library", e); //$NON-NLS-1$
|
||||
}
|
||||
if(!isNativeSupported) {
|
||||
|
|
|
@ -18,6 +18,7 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import android.os.AsyncTask;
|
||||
import net.osmand.AndroidUtils;
|
||||
import net.osmand.GeoidAltitudeCorrection;
|
||||
import net.osmand.IProgress;
|
||||
|
@ -67,6 +68,7 @@ import android.graphics.Bitmap;
|
|||
import android.graphics.BitmapFactory;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.WindowManager;
|
||||
import net.osmand.map.OsmandRegions;
|
||||
|
||||
/**
|
||||
* Resource manager is responsible to work with all resources
|
||||
|
@ -123,6 +125,8 @@ public class ResourceManager {
|
|||
protected final Map<String, BinaryMapIndexReader> routingMapFiles = Collections.synchronizedMap(new LinkedHashMap<String, BinaryMapIndexReader>());
|
||||
|
||||
protected final MapRenderRepositories renderer;
|
||||
|
||||
protected final OsmandRegions regions;
|
||||
|
||||
protected final MapTileDownloader tileDownloader;
|
||||
|
||||
|
@ -134,7 +138,7 @@ public class ResourceManager {
|
|||
this.context = context;
|
||||
this.renderer = new MapRenderRepositories(context);
|
||||
asyncLoadingThread.start();
|
||||
|
||||
|
||||
tileDownloader = MapTileDownloader.getInstance(Version.getFullVersion(context));
|
||||
|
||||
resetStoreDirectory();
|
||||
|
@ -145,7 +149,8 @@ public class ResourceManager {
|
|||
// at least 3*9?
|
||||
float tiles = (dm.widthPixels / 256 + 2) * (dm.heightPixels / 256 + 2) * 3;
|
||||
log.info("Tiles to load in memory : " + tiles);
|
||||
maxImgCacheSize = (int) (tiles) ;
|
||||
maxImgCacheSize = (int) (tiles) ;
|
||||
regions = new OsmandRegions();
|
||||
}
|
||||
|
||||
public MapTileDownloader getMapTileDownloader() {
|
||||
|
@ -405,6 +410,7 @@ public class ResourceManager {
|
|||
warnings.addAll(checkAssets(progress));
|
||||
initRenderers(progress);
|
||||
geoidAltitudeCorrection = new GeoidAltitudeCorrection(context.getAppPath(null));
|
||||
indexRegionsBoundaries(progress, false);
|
||||
// do it lazy
|
||||
// indexingImageTiles(progress);
|
||||
warnings.addAll(indexingMaps(progress));
|
||||
|
@ -413,7 +419,23 @@ public class ResourceManager {
|
|||
|
||||
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){
|
||||
File file = context.getAppPath(IndexConstants.VOICE_INDEX_DIR);
|
||||
file.mkdirs();
|
||||
|
@ -445,7 +467,8 @@ public class ResourceManager {
|
|||
applicationDataDir.mkdirs();
|
||||
if(applicationDataDir.canWrite()){
|
||||
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();
|
||||
boolean isFirstInstall = context.getSettings().PREVIOUS_INSTALLED_VERSION.get().equals("");
|
||||
unpackBundledAssets(assetManager, applicationDataDir, progress, isFirstInstall);
|
||||
|
@ -938,6 +961,10 @@ public class ResourceManager {
|
|||
public GeoidAltitudeCorrection getGeoidAltitudeCorrection() {
|
||||
return geoidAltitudeCorrection;
|
||||
}
|
||||
|
||||
public OsmandRegions getOsmandRegions() {
|
||||
return regions;
|
||||
}
|
||||
|
||||
|
||||
protected synchronized void clearTiles() {
|
||||
|
|
265
OsmAnd/src/net/osmand/plus/views/DownloadedRegionsLayer.java
Normal file
265
OsmAnd/src/net/osmand/plus/views/DownloadedRegionsLayer.java
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -413,7 +413,7 @@ public class OsmandMapTileView extends SurfaceView implements IMapDownloaderCall
|
|||
|
||||
public int getCenterPointY() {
|
||||
if (mapPosition == OsmandSettings.BOTTOM_CONSTANT) {
|
||||
return 3 * getHeight() / 4;
|
||||
return 4 * getHeight() / 5;
|
||||
}
|
||||
return getHeight() / 2;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue