diff --git a/DataExtractionOSM/.gitignore b/DataExtractionOSM/.gitignore index e660fd93d3..c21696e5be 100644 --- a/DataExtractionOSM/.gitignore +++ b/DataExtractionOSM/.gitignore @@ -1 +1,3 @@ bin/ +build/ +build.zip diff --git a/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexWriter.java b/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexWriter.java index 984e1285e6..fbba1361e3 100644 --- a/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexWriter.java +++ b/DataExtractionOSM/src/net/osmand/binary/BinaryMapIndexWriter.java @@ -23,10 +23,10 @@ import net.osmand.binary.OsmandOdb.TransportRoute; import net.osmand.binary.OsmandOdb.TransportRouteStop; import net.osmand.data.Building; import net.osmand.data.City; +import net.osmand.data.IndexConstants; import net.osmand.data.MapObject; import net.osmand.data.Street; import net.osmand.data.TransportStop; -import net.osmand.data.index.IndexConstants; import net.osmand.osm.LatLon; import net.osmand.osm.MapUtils; import net.osmand.osm.Node; diff --git a/DataExtractionOSM/src/net/osmand/data/index/IndexConstants.java b/DataExtractionOSM/src/net/osmand/data/IndexConstants.java similarity index 95% rename from DataExtractionOSM/src/net/osmand/data/index/IndexConstants.java rename to DataExtractionOSM/src/net/osmand/data/IndexConstants.java index 490294b8b2..b9d765f9db 100644 --- a/DataExtractionOSM/src/net/osmand/data/index/IndexConstants.java +++ b/DataExtractionOSM/src/net/osmand/data/IndexConstants.java @@ -1,27 +1,27 @@ -package net.osmand.data.index; - - -public class IndexConstants { - - // Important : Every time you change schema of db upgrade version!!! - // If you want that new application support old index : put upgrade code in android app ResourceManager - public final static int POI_TABLE_VERSION = 1; - public final static int BINARY_MAP_VERSION = 1; // starts with 1 - public final static int VOICE_VERSION = 0; - - public static final String POI_INDEX_DIR = "POI/"; //$NON-NLS-1$ - public static final String VOICE_INDEX_DIR = "voice/"; //$NON-NLS-1$ - public static final String RENDERERS_DIR = "rendering/"; //$NON-NLS-1$ - - public static final String POI_INDEX_EXT = ".poi.odb"; //$NON-NLS-1$ - public static final String BINARY_MAP_INDEX_EXT = ".obf"; //$NON-NLS-1$ - - public static final String POI_INDEX_EXT_ZIP = ".poi.zip"; //$NON-NLS-1$ - public static final String VOICE_INDEX_EXT_ZIP = ".voice.zip"; //$NON-NLS-1$ - public static final String BINARY_MAP_INDEX_EXT_ZIP = ".obf.zip"; //$NON-NLS-1$ - - public static final String RENDERER_INDEX_EXT = ".render.xml"; //$NON-NLS-1$ - - public final static String POI_TABLE = "poi"; //$NON-NLS-1$ - -} +package net.osmand.data; + + +public class IndexConstants { + + // Important : Every time you change schema of db upgrade version!!! + // If you want that new application support old index : put upgrade code in android app ResourceManager + public final static int POI_TABLE_VERSION = 1; + public final static int BINARY_MAP_VERSION = 1; // starts with 1 + public final static int VOICE_VERSION = 0; + + public static final String POI_INDEX_DIR = "POI/"; //$NON-NLS-1$ + public static final String VOICE_INDEX_DIR = "voice/"; //$NON-NLS-1$ + public static final String RENDERERS_DIR = "rendering/"; //$NON-NLS-1$ + + public static final String POI_INDEX_EXT = ".poi.odb"; //$NON-NLS-1$ + public static final String BINARY_MAP_INDEX_EXT = ".obf"; //$NON-NLS-1$ + + public static final String POI_INDEX_EXT_ZIP = ".poi.zip"; //$NON-NLS-1$ + public static final String VOICE_INDEX_EXT_ZIP = ".voice.zip"; //$NON-NLS-1$ + public static final String BINARY_MAP_INDEX_EXT_ZIP = ".obf.zip"; //$NON-NLS-1$ + + public static final String RENDERER_INDEX_EXT = ".render.xml"; //$NON-NLS-1$ + + public final static String POI_TABLE = "poi"; //$NON-NLS-1$ + +} diff --git a/DataExtractionOSM/src/net/osmand/data/preparation/MapTileDownloader.java b/DataExtractionOSM/src/net/osmand/data/MapTileDownloader.java similarity index 96% rename from DataExtractionOSM/src/net/osmand/data/preparation/MapTileDownloader.java rename to DataExtractionOSM/src/net/osmand/data/MapTileDownloader.java index bb12955da6..d30b51ec78 100644 --- a/DataExtractionOSM/src/net/osmand/data/preparation/MapTileDownloader.java +++ b/DataExtractionOSM/src/net/osmand/data/MapTileDownloader.java @@ -1,4 +1,4 @@ -package net.osmand.data.preparation; +package net.osmand.data; import java.io.BufferedInputStream; import java.io.File; diff --git a/DataExtractionOSM/src/net/osmand/data/index/DownloaderIndexFromGoogleCode.java b/DataExtractionOSM/src/net/osmand/data/index/DownloaderIndexFromGoogleCode.java index f197a34f18..c0f44b7ba5 100644 --- a/DataExtractionOSM/src/net/osmand/data/index/DownloaderIndexFromGoogleCode.java +++ b/DataExtractionOSM/src/net/osmand/data/index/DownloaderIndexFromGoogleCode.java @@ -1,10 +1,10 @@ package net.osmand.data.index; -import static net.osmand.data.index.IndexConstants.BINARY_MAP_INDEX_EXT; -import static net.osmand.data.index.IndexConstants.BINARY_MAP_INDEX_EXT_ZIP; -import static net.osmand.data.index.IndexConstants.BINARY_MAP_VERSION; -import static net.osmand.data.index.IndexConstants.VOICE_INDEX_EXT_ZIP; -import static net.osmand.data.index.IndexConstants.VOICE_VERSION; +import static net.osmand.data.IndexConstants.BINARY_MAP_INDEX_EXT; +import static net.osmand.data.IndexConstants.BINARY_MAP_INDEX_EXT_ZIP; +import static net.osmand.data.IndexConstants.BINARY_MAP_VERSION; +import static net.osmand.data.IndexConstants.VOICE_INDEX_EXT_ZIP; +import static net.osmand.data.IndexConstants.VOICE_VERSION; import java.io.BufferedReader; import java.io.BufferedWriter; diff --git a/DataExtractionOSM/src/net/osmand/data/index/IndexBatchCreator.java b/DataExtractionOSM/src/net/osmand/data/index/IndexBatchCreator.java index 3ce05db291..fdfe73de54 100644 --- a/DataExtractionOSM/src/net/osmand/data/index/IndexBatchCreator.java +++ b/DataExtractionOSM/src/net/osmand/data/index/IndexBatchCreator.java @@ -18,42 +18,43 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Set; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; - -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; - -import net.osmand.Algoritms; -import net.osmand.LogUtil; -import net.osmand.binary.BinaryMapIndexReader; -import net.osmand.data.preparation.IndexCreator; -import net.osmand.data.preparation.MapZooms; -import net.osmand.impl.ConsoleProgressImplementation; -import net.osmand.osm.MapRenderingTypes; - -import org.apache.commons.logging.Log; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NodeList; -import org.xml.sax.SAXException; - -import rtree.RTree; - - - -public class IndexBatchCreator { - - - protected static final Log log = LogUtil.getLog(IndexBatchCreator.class); +import java.util.Comparator; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import net.osmand.Algoritms; +import net.osmand.LogUtil; +import net.osmand.binary.BinaryMapIndexReader; +import net.osmand.data.IndexConstants; +import net.osmand.data.preparation.IndexCreator; +import net.osmand.data.preparation.MapZooms; +import net.osmand.impl.ConsoleProgressImplementation; +import net.osmand.osm.MapRenderingTypes; + +import org.apache.commons.logging.Log; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import rtree.RTree; + + + +public class IndexBatchCreator { + + + protected static final Log log = LogUtil.getLog(IndexBatchCreator.class); private final static double MIN_SIZE_TO_UPLOAD = 0.015d; private final static double MIN_SIZE_TO_NOT_ZIP = 2d; private final static double MAX_SIZE_TO_NOT_SPLIT = 190d; diff --git a/DataExtractionOSM/src/net/osmand/data/preparation/IndexCreator.java b/DataExtractionOSM/src/net/osmand/data/preparation/IndexCreator.java index 4f77f1b749..111d846e04 100644 --- a/DataExtractionOSM/src/net/osmand/data/preparation/IndexCreator.java +++ b/DataExtractionOSM/src/net/osmand/data/preparation/IndexCreator.java @@ -1,621 +1,621 @@ -package net.osmand.data.preparation; - -import java.io.BufferedInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.RandomAccessFile; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; - -import net.osmand.Algoritms; -import net.osmand.IProgress; -import net.osmand.binary.BinaryMapIndexWriter; -import net.osmand.data.index.IndexConstants; -import net.osmand.data.preparation.OsmDbAccessor.OsmDbVisitor; -import net.osmand.impl.ConsoleProgressImplementation; -import net.osmand.osm.Entity; -import net.osmand.osm.MapRenderingTypes; -import net.osmand.osm.Relation; -import net.osmand.osm.Entity.EntityId; -import net.osmand.osm.Entity.EntityType; -import net.osmand.osm.io.IOsmStorageFilter; -import net.osmand.osm.io.OsmBaseStorage; -import net.osmand.swing.DataExtractionSettings; -import net.osmand.swing.Messages; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.tools.bzip2.CBZip2InputStream; -import org.xml.sax.SAXException; - -import rtree.RTreeException; - -/** - * http://wiki.openstreetmap.org/wiki/OSM_tags_for_routing#Is_inside.2Foutside - * http://wiki.openstreetmap.org/wiki/Relations/Proposed/Postal_Addresses - * http://wiki.openstreetmap.org/wiki/Proposed_features/House_numbers/Karlsruhe_Schema#Tags (node, way) - * - * That data extraction has aim, save runtime memory and generate indexes on the fly. It will be longer than load in memory (needed part) - * and save into index. - */ -public class IndexCreator { - private static final Log log = LogFactory.getLog(IndexCreator.class); - - // ONLY derby.jar needed for derby dialect - private final DBDialect dialect = DBDialect.SQLITE; - - public static final int BATCH_SIZE = 5000; - public static final int BATCH_SIZE_OSM = 10000; - public static final String TEMP_NODES_DB = "nodes.tmp.odb"; - - public static final int STEP_MAIN = 4; - - private File workingDir = null; - - private boolean indexMap; - private boolean indexPOI; - private boolean indexTransport; - private boolean indexAddress; - - private boolean normalizeStreets = true; // true by default - private boolean saveAddressWays = true; // true by default - - private String regionName; - private String poiFileName = null; - private String mapFileName = null; - private Long lastModifiedDate = null; - - - private IndexTransportCreator indexTransportCreator; - private IndexPoiCreator indexPoiCreator; - private IndexAddressCreator indexAddressCreator; - private IndexVectorMapCreator indexMapCreator; - private OsmDbAccessor accessor; - // constants to start process from the middle and save temporary results - private boolean recreateOnlyBinaryFile = false; // false; - private boolean deleteOsmDB = false; - private boolean deleteDatabaseIndexes = true; - - private Connection dbConn; - private File dbFile; - - private File mapFile; - private RandomAccessFile mapRAFile; - private Connection mapConnection; - private String cityAdminLevel = "8"; - - - public IndexCreator(File workingDir) { - this.workingDir = workingDir; - } - - public void setIndexAddress(boolean indexAddress) { - this.indexAddress = indexAddress; - } - - public void setIndexMap(boolean indexMap) { - this.indexMap = indexMap; - } - - public void setIndexPOI(boolean indexPOI) { - this.indexPOI = indexPOI; - } - - public void setIndexTransport(boolean indexTransport) { - this.indexTransport = indexTransport; - } - - public void setSaveAddressWays(boolean saveAddressWays) { - this.saveAddressWays = saveAddressWays; - } - - public void setNormalizeStreets(boolean normalizeStreets) { - this.normalizeStreets = normalizeStreets; - } - - public String getRegionName() { - if (regionName == null) { - return "Region"; //$NON-NLS-1$ - } - return regionName; - } - - public void setRegionName(String regionName) { - this.regionName = regionName; - } - - private Connection getDatabaseConnection(String fileName) throws SQLException { - return dialect.getDatabaseConnection(fileName, log); - } - - public void setPoiFileName(String poiFileName) { - this.poiFileName = poiFileName; - } - - public void setNodesDBFile(File file) { - dbFile = file; - } - - public void setMapFileName(String mapFileName) { - this.mapFileName = mapFileName; - } - - public String getMapFileName() { - if (mapFileName == null) { - return getRegionName() + IndexConstants.BINARY_MAP_INDEX_EXT; - } - return mapFileName; - } - - public String getTempMapDBFileName() { - return getMapFileName() + ".tmp"; //$NON-NLS-1$ - } - - public Long getLastModifiedDate() { - return lastModifiedDate; - } - - public void setLastModifiedDate(Long lastModifiedDate) { - this.lastModifiedDate = lastModifiedDate; - } - - public String getPoiFileName() { - if (poiFileName == null) { - return IndexConstants.POI_INDEX_DIR + getRegionName() + IndexConstants.POI_INDEX_EXT; - } - return poiFileName; - } - - public String getCityAdminLevel() { - return cityAdminLevel; - } - - public void setCityAdminLevel(String cityAdminLevel) { - this.cityAdminLevel = cityAdminLevel; - } - - public String getRTreeMapIndexNonPackFileName() { - return mapFile.getAbsolutePath() + ".rtree"; //$NON-NLS-1$ - } - - public String getRTreeTransportStopsFileName() { - return mapFile.getAbsolutePath() + ".trans"; //$NON-NLS-1$ - } - - public String getRTreeTransportStopsPackFileName() { - return mapFile.getAbsolutePath() + ".ptrans"; //$NON-NLS-1$ - } - - public String getRTreeMapIndexPackFileName() { - return mapFile.getAbsolutePath() + ".prtree"; //$NON-NLS-1$ - } - - /* ***** END OF GETTERS/SETTERS ***** */ - public void generateIndexes(File readFile, IProgress progress, IOsmStorageFilter addFilter) throws IOException, SAXException, SQLException{ - generateIndexes(readFile, progress, addFilter, null, null); - } - - private void iterateMainEntity(Entity e, OsmDbAccessorContext ctx) throws SQLException { - if (indexPOI) { - indexPoiCreator.iterateEntity(e, ctx); - } - if (indexTransport) { - indexTransportCreator.visitEntityMainStep(e, ctx); - } - if (indexMap) { - indexMapCreator.iterateMainEntity(e, ctx); - } - if (indexAddress) { - indexAddressCreator.iterateMainEntity(e, ctx); - } - } - - private OsmDbCreator extractOsmToNodesDB(File readFile, IProgress progress, IOsmStorageFilter addFilter) throws FileNotFoundException, - IOException, SQLException, SAXException { - boolean pbfFile = false; - InputStream stream = new BufferedInputStream(new FileInputStream(readFile), 8192 * 4); - InputStream streamFile = stream; - long st = System.currentTimeMillis(); - if (readFile.getName().endsWith(".bz2")) { //$NON-NLS-1$ - if (stream.read() != 'B' || stream.read() != 'Z') { - throw new RuntimeException("The source stream must start with the characters BZ if it is to be read as a BZip2 stream."); //$NON-NLS-1$ - } else { - stream = new CBZip2InputStream(stream); - } - } else if (readFile.getName().endsWith(".pbf")) { //$NON-NLS-1$ - pbfFile = true; - } - - OsmBaseStorage storage = new OsmBaseStorage(); - storage.setSupressWarnings(DataExtractionSettings.getSettings().isSupressWarningsForDuplicatedId()); - if (addFilter != null) { - storage.getFilters().add(addFilter); - } - - storage.getFilters().add(new IOsmStorageFilter() { - - @Override - public boolean acceptEntityToLoad(OsmBaseStorage storage, EntityId entityId, Entity entity) { - indexAddressCreator.registerCityIfNeeded(entity); - // accept to allow db creator parse it - return true; - } - }); - - // 1. Loading osm file - OsmDbCreator dbCreator = new OsmDbCreator(this); - try { - progress.setGeneralProgress("[35 / 100]"); //$NON-NLS-1$ - progress.startTask(Messages.getString("IndexCreator.LOADING_FILE") + readFile.getAbsolutePath(), -1); //$NON-NLS-1$ - // 1 init database to store temporary data - dbCreator.initDatabase(dialect, dbConn); - storage.getFilters().add(dbCreator); - if (pbfFile) { - storage.parseOSMPbf(stream, progress, false); - } else { - storage.parseOSM(stream, progress, streamFile, false); - } - dbCreator.finishLoading(); - dbConn.commit(); - - if (log.isInfoEnabled()) { - log.info("File parsed : " + (System.currentTimeMillis() - st)); //$NON-NLS-1$ - } - progress.finishTask(); - return dbCreator; - } finally { - if (log.isInfoEnabled()) { - log.info("File indexed : " + (System.currentTimeMillis() - st)); //$NON-NLS-1$ - } - } - } - - private boolean createPlainOsmDb(IProgress progress, File readFile, IOsmStorageFilter addFilter) throws SQLException, FileNotFoundException, IOException, SAXException{ - // initialize db file - boolean loadFromExistingFile = dbFile != null && dialect.databaseFileExists(dbFile); - if (dbFile == null) { - dbFile = new File(workingDir, TEMP_NODES_DB); - // to save space - if (dialect.databaseFileExists(dbFile)) { - dialect.removeDatabase(dbFile); - } - } - dbConn = getDatabaseConnection(dbFile.getAbsolutePath()); - int allRelations = 100000; - int allWays = 1000000; - int allNodes = 10000000; - if (!loadFromExistingFile) { - OsmDbCreator dbCreator = extractOsmToNodesDB(readFile, progress, addFilter); - if (dbCreator != null) { - allNodes = dbCreator.getAllNodes(); - allWays = dbCreator.getAllWays(); - allRelations = dbCreator.getAllRelations(); - } - } - accessor.initDatabase(dbConn, allNodes, allWays, allRelations); - return loadFromExistingFile; - } - - private void createDatabaseIndexesStructure() throws SQLException, IOException { - // 2.1 create temporary sqlite database to put temporary results to it - if (indexMap || indexAddress || indexTransport) { - mapFile = new File(workingDir, getMapFileName()); - // to save space - mapFile.getParentFile().mkdirs(); - File tempDBMapFile = new File(workingDir, getTempMapDBFileName()); - dialect.removeDatabase(tempDBMapFile); - mapConnection = getDatabaseConnection(tempDBMapFile.getAbsolutePath()); - mapConnection.setAutoCommit(false); - } - - // 2.2 create rtree map - if (indexMap) { - indexMapCreator.createDatabaseStructure(mapConnection, dialect, getRTreeMapIndexNonPackFileName()); - } - if (indexAddress) { - indexAddressCreator.createDatabaseStructure(mapConnection, dialect); - } - if (indexPOI) { - indexPoiCreator.createDatabaseStructure(new File(workingDir, getPoiFileName())); - } - if (indexTransport) { - indexTransportCreator.createDatabaseStructure(mapConnection, dialect, getRTreeTransportStopsFileName()); - } - } - - - public void generateIndexes(File readFile, IProgress progress, IOsmStorageFilter addFilter, MapZooms mapZooms, - MapRenderingTypes renderingTypes) throws IOException, SAXException, SQLException { - if (renderingTypes == null) { - renderingTypes = MapRenderingTypes.getDefault(); - } - if (mapZooms == null) { - mapZooms = MapZooms.getDefault(); - } - - // clear previous results and setting variables - if (readFile != null && regionName == null) { - int i = readFile.getName().indexOf('.'); - if (i > -1) { - regionName = Algoritms.capitalizeFirstLetterAndLowercase(readFile.getName().substring(0, i)); - } - } - this.indexTransportCreator = new IndexTransportCreator(); - this.indexPoiCreator = new IndexPoiCreator(); - this.indexAddressCreator = new IndexAddressCreator(); - this.indexMapCreator = new IndexVectorMapCreator(); - this.accessor = new OsmDbAccessor(); - - - indexMapCreator.initSettings(mapZooms, renderingTypes); - - // init address - String[] normalizeDefaultSuffixes = null; - String[] normalizeSuffixes = null; - if (normalizeStreets) { - normalizeDefaultSuffixes = DataExtractionSettings.getSettings().getDefaultSuffixesToNormalizeStreets(); - normalizeSuffixes = DataExtractionSettings.getSettings().getSuffixesToNormalizeStreets(); - } - indexAddressCreator.initSettings(normalizeStreets, normalizeDefaultSuffixes, normalizeSuffixes, saveAddressWays, cityAdminLevel); - - // Main generation method - try { - // //////////////////////////////////////////////////////////////////////// - // 1. creating nodes db to fast access for all nodes and simply import all relations, ways, nodes to it - boolean loadFromExistingFile = createPlainOsmDb(progress, readFile, addFilter); - - // do not create temp map file and rtree files - if (recreateOnlyBinaryFile) { - mapFile = new File(workingDir, getMapFileName()); - File tempDBMapFile = new File(workingDir, getTempMapDBFileName()); - mapConnection = getDatabaseConnection(tempDBMapFile.getAbsolutePath()); - mapConnection.setAutoCommit(false); - try { - if (indexMap) { - indexMapCreator.createRTreeFiles(getRTreeMapIndexPackFileName()); - } - if (indexTransport) { - indexTransportCreator.createRTreeFile(getRTreeTransportStopsPackFileName()); - } - } catch (RTreeException e) { - log.error("Error flushing", e); //$NON-NLS-1$ - throw new IOException(e); - } - } else { - - // 2. Create index connections and index structure - createDatabaseIndexesStructure(); - - // 3. Processing all entries - - // 3.1 write all cities - if (indexAddress) { - progress.setGeneralProgress("[40 / 100]"); //$NON-NLS-1$ - progress.startTask(Messages.getString("IndexCreator.INDEX_CITIES"), accessor.getAllNodes()); //$NON-NLS-1$ - if (loadFromExistingFile) { - // load cities names - accessor.iterateOverEntities(progress, EntityType.NODE, new OsmDbVisitor() { - @Override - public void iterateEntity(Entity e, OsmDbAccessorContext ctx) { - indexAddressCreator.registerCityIfNeeded(e); - } - }); - } - indexAddressCreator.writeCitiesIntoDb(); - } - - // 3.2 index address relations - if (indexAddress || indexMap) { - progress.setGeneralProgress("[30 / 100]"); //$NON-NLS-1$ - progress.startTask(Messages.getString("IndexCreator.PREINDEX_ADRESS_MAP"), accessor.getAllRelations()); //$NON-NLS-1$ - accessor.iterateOverEntities(progress, EntityType.RELATION, new OsmDbVisitor() { - @Override - public void iterateEntity(Entity e, OsmDbAccessorContext ctx) throws SQLException { - if (indexAddress) { - indexAddressCreator.indexAddressRelation((Relation) e, ctx); - indexAddressCreator.indexBoundariesRelation((Relation) e, ctx); - } - if (indexMap) { - indexMapCreator.indexMapRelationsAndMultiPolygons(e, ctx); - } - } - }); - if (indexAddress) { - progress.setGeneralProgress("[40 / 100]"); //$NON-NLS-1$ - progress.startTask(Messages.getString("IndexCreator.PREINDEX_ADRESS_MAP"), accessor.getAllWays()); //$NON-NLS-1$ - accessor.iterateOverEntities(progress, EntityType.WAY, new OsmDbVisitor() { - @Override - public void iterateEntity(Entity e, OsmDbAccessorContext ctx) throws SQLException { - indexAddressCreator.indexBoundariesRelation(e, ctx); - } - }); - - indexAddressCreator.commitToPutAllCities(); - } - - } - - // 3.3 MAIN iterate over all entities - if (indexPOI || indexAddress || indexMap) { - progress.setGeneralProgress("[50 / 100]"); - progress.startTask(Messages.getString("IndexCreator.PROCESS_OSM_NODES"), accessor.getAllNodes()); - accessor.iterateOverEntities(progress, EntityType.NODE, new OsmDbVisitor() { - @Override - public void iterateEntity(Entity e, OsmDbAccessorContext ctx) throws SQLException { - iterateMainEntity(e, ctx); - } - }); - progress.setGeneralProgress("[70 / 100]"); - progress.startTask(Messages.getString("IndexCreator.PROCESS_OSM_WAYS"), accessor.getAllWays()); - accessor.iterateOverEntities(progress, EntityType.WAY, new OsmDbVisitor() { - @Override - public void iterateEntity(Entity e, OsmDbAccessorContext ctx) throws SQLException { - iterateMainEntity(e, ctx); - } - }); - } - progress.setGeneralProgress("[85 / 100]"); - progress.startTask(Messages.getString("IndexCreator.PROCESS_OSM_REL"), accessor.getAllRelations()); - accessor.iterateOverEntities(progress, EntityType.RELATION, new OsmDbVisitor() { - @Override - public void iterateEntity(Entity e, OsmDbAccessorContext ctx) throws SQLException { - iterateMainEntity(e, ctx); - } - }); - - // 3.4 combine all low level ways and simplify them - if (indexMap) { - progress.setGeneralProgress("[90 / 100]"); - progress.startTask(Messages.getString("IndexCreator.INDEX_LO_LEVEL_WAYS"), indexMapCreator.getLowLevelWays()); - indexMapCreator.processingLowLevelWays(progress); - } - - // 3.5 update all postal codes from relations - if (indexAddress) { - progress.setGeneralProgress("[90 / 100]"); - progress.startTask(Messages.getString("IndexCreator.REGISTER_PCODES"), -1); - indexAddressCreator.processingPostcodes(); - } - - // 4. packing map rtree indexes - if (indexMap) { - progress.setGeneralProgress("[90 / 100]"); //$NON-NLS-1$ - progress.startTask(Messages.getString("IndexCreator.PACK_RTREE_MAP"), -1); //$NON-NLS-1$ - indexMapCreator.packRtreeFiles(getRTreeMapIndexNonPackFileName(), getRTreeMapIndexPackFileName()); - } - - if (indexTransport) { - progress.setGeneralProgress("[90 / 100]"); //$NON-NLS-1$ - progress.startTask(Messages.getString("IndexCreator.PACK_RTREE_TRANSP"), -1); //$NON-NLS-1$ - indexTransportCreator.packRTree(getRTreeTransportStopsFileName(), getRTreeTransportStopsPackFileName()); - } - } - - // 5. Writing binary file - if (indexMap || indexAddress || indexTransport) { - if (mapFile.exists()) { - mapFile.delete(); - } - mapRAFile = new RandomAccessFile(mapFile, "rw"); - BinaryMapIndexWriter writer = new BinaryMapIndexWriter(mapRAFile); - if (indexMap) { - progress.setGeneralProgress("[95 of 100]"); - progress.startTask("Writing map index to binary file...", -1); - indexMapCreator.writeBinaryMapIndex(writer, regionName); - } - - if (indexAddress) { - progress.setGeneralProgress("[95 of 100]"); - progress.startTask("Writing address index to binary file...", -1); - indexAddressCreator.writeBinaryAddressIndex(writer, regionName, progress); - } - - if (indexTransport) { - progress.setGeneralProgress("[95 of 100]"); - progress.startTask("Writing transport index to binary file...", -1); - indexTransportCreator.writeBinaryTransportIndex(writer, regionName, mapConnection); - } - progress.finishTask(); - writer.close(); - mapRAFile.close(); - log.info("Finish writing binary file"); //$NON-NLS-1$ - } - } catch (RuntimeException e) { - log.error("Log exception", e); //$NON-NLS-1$ - throw e; - } catch (SQLException e) { - log.error("Log exception", e); //$NON-NLS-1$ - throw e; - } catch (IOException e) { - log.error("Log exception", e); //$NON-NLS-1$ - throw e; - } catch (SAXException e) { - log.error("Log exception", e); //$NON-NLS-1$ - throw e; - } finally { - try { - accessor.closeReadingConnection(); - - indexPoiCreator.commitAndClosePoiFile(lastModifiedDate); - indexAddressCreator.closeAllPreparedStatements(); - indexTransportCreator.commitAndCloseFiles(getRTreeTransportStopsFileName(), getRTreeTransportStopsPackFileName(), - deleteDatabaseIndexes); - indexMapCreator.commitAndCloseFiles(getRTreeMapIndexNonPackFileName(), getRTreeMapIndexPackFileName(), - deleteDatabaseIndexes); - - if (mapConnection != null) { - mapConnection.commit(); - mapConnection.close(); - mapConnection = null; - File tempDBFile = new File(workingDir, getTempMapDBFileName()); - if (dialect.databaseFileExists(tempDBFile) && deleteDatabaseIndexes) { - // do not delete it for now - dialect.removeDatabase(tempDBFile); - } - } - - // do not delete first db connection - if (dbConn != null) { - if (DBDialect.H2 == dialect) { - dbConn.createStatement().execute("SHUTDOWN COMPACT"); //$NON-NLS-1$ - } - dbConn.close(); - } - if (deleteOsmDB) { - if (DBDialect.DERBY == dialect) { - try { - DriverManager.getConnection("jdbc:derby:;shutdown=true"); //$NON-NLS-1$ - } catch (SQLException e) { - // ignore exception - } - } - dialect.removeDatabase(dbFile); - } - } catch (SQLException e) { - e.printStackTrace(); - } - } - } - - - public static void main(String[] args) throws IOException, SAXException, SQLException { - - long time = System.currentTimeMillis(); - IndexCreator creator = new IndexCreator(new File("/home/victor/projects/OsmAnd/data/osm-gen/")); //$NON-NLS-1$ - creator.setIndexMap(true); - creator.setIndexAddress(true); - creator.setIndexPOI(true); - creator.setIndexTransport(true); - // for NL -// creator.setCityAdminLevel("10"); - - creator.recreateOnlyBinaryFile = false; - creator.deleteDatabaseIndexes = true; - - creator.generateIndexes(new File("/home/victor/projects/OsmAnd/download/406/map.osm"), - new ConsoleProgressImplementation(1), null, MapZooms.getDefault(), null); -// creator.generateIndexes(new File("/home/victor/projects/OsmAnd/data/osm-maps/minsk_around.osm"), -// new ConsoleProgressImplementation(1), null, MapZooms.getDefault(), null); - - - -// creator.setNodesDBFile(new File("e:/Information/OSM maps/osmand/minsk.tmp.odb")); -// creator.generateIndexes(new File("e:/Information/OSM maps/belarus osm/minsk.osm"), new ConsoleProgressImplementation(3), null, MapZooms.getDefault(), null); - - - - System.out.println("WHOLE GENERATION TIME : " + (System.currentTimeMillis() - time)); //$NON-NLS-1$ - System.out.println("COORDINATES_SIZE " + BinaryMapIndexWriter.COORDINATES_SIZE + " count " + BinaryMapIndexWriter.COORDINATES_COUNT); //$NON-NLS-1$ //$NON-NLS-2$ - System.out.println("TYPES_SIZE " + BinaryMapIndexWriter.TYPES_SIZE); //$NON-NLS-1$ - System.out.println("ID_SIZE " + BinaryMapIndexWriter.ID_SIZE); //$NON-NLS-1$ - System.out.println("- COORD_TYPES_ID SIZE " + (BinaryMapIndexWriter.COORDINATES_SIZE + BinaryMapIndexWriter.TYPES_SIZE + BinaryMapIndexWriter.ID_SIZE)); //$NON-NLS-1$ - System.out.println("- MAP_DATA_SIZE " + BinaryMapIndexWriter.MAP_DATA_SIZE); //$NON-NLS-1$ - System.out.println("- STRING_TABLE_SIZE " + BinaryMapIndexWriter.STRING_TABLE_SIZE); //$NON-NLS-1$ - System.out.println("-- MAP_DATA_AND_STRINGS SIZE " + (BinaryMapIndexWriter.MAP_DATA_SIZE + BinaryMapIndexWriter.STRING_TABLE_SIZE)); //$NON-NLS-1$ - - } +package net.osmand.data.preparation; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.RandomAccessFile; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +import net.osmand.Algoritms; +import net.osmand.IProgress; +import net.osmand.binary.BinaryMapIndexWriter; +import net.osmand.data.IndexConstants; +import net.osmand.data.preparation.OsmDbAccessor.OsmDbVisitor; +import net.osmand.impl.ConsoleProgressImplementation; +import net.osmand.osm.Entity; +import net.osmand.osm.MapRenderingTypes; +import net.osmand.osm.Relation; +import net.osmand.osm.Entity.EntityId; +import net.osmand.osm.Entity.EntityType; +import net.osmand.osm.io.IOsmStorageFilter; +import net.osmand.osm.io.OsmBaseStorage; +import net.osmand.swing.DataExtractionSettings; +import net.osmand.swing.Messages; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.tools.bzip2.CBZip2InputStream; +import org.xml.sax.SAXException; + +import rtree.RTreeException; + +/** + * http://wiki.openstreetmap.org/wiki/OSM_tags_for_routing#Is_inside.2Foutside + * http://wiki.openstreetmap.org/wiki/Relations/Proposed/Postal_Addresses + * http://wiki.openstreetmap.org/wiki/Proposed_features/House_numbers/Karlsruhe_Schema#Tags (node, way) + * + * That data extraction has aim, save runtime memory and generate indexes on the fly. It will be longer than load in memory (needed part) + * and save into index. + */ +public class IndexCreator { + private static final Log log = LogFactory.getLog(IndexCreator.class); + + // ONLY derby.jar needed for derby dialect + private final DBDialect dialect = DBDialect.SQLITE; + + public static final int BATCH_SIZE = 5000; + public static final int BATCH_SIZE_OSM = 10000; + public static final String TEMP_NODES_DB = "nodes.tmp.odb"; + + public static final int STEP_MAIN = 4; + + private File workingDir = null; + + private boolean indexMap; + private boolean indexPOI; + private boolean indexTransport; + private boolean indexAddress; + + private boolean normalizeStreets = true; // true by default + private boolean saveAddressWays = true; // true by default + + private String regionName; + private String poiFileName = null; + private String mapFileName = null; + private Long lastModifiedDate = null; + + + private IndexTransportCreator indexTransportCreator; + private IndexPoiCreator indexPoiCreator; + private IndexAddressCreator indexAddressCreator; + private IndexVectorMapCreator indexMapCreator; + private OsmDbAccessor accessor; + // constants to start process from the middle and save temporary results + private boolean recreateOnlyBinaryFile = false; // false; + private boolean deleteOsmDB = false; + private boolean deleteDatabaseIndexes = true; + + private Connection dbConn; + private File dbFile; + + private File mapFile; + private RandomAccessFile mapRAFile; + private Connection mapConnection; + private String cityAdminLevel = "8"; + + + public IndexCreator(File workingDir) { + this.workingDir = workingDir; + } + + public void setIndexAddress(boolean indexAddress) { + this.indexAddress = indexAddress; + } + + public void setIndexMap(boolean indexMap) { + this.indexMap = indexMap; + } + + public void setIndexPOI(boolean indexPOI) { + this.indexPOI = indexPOI; + } + + public void setIndexTransport(boolean indexTransport) { + this.indexTransport = indexTransport; + } + + public void setSaveAddressWays(boolean saveAddressWays) { + this.saveAddressWays = saveAddressWays; + } + + public void setNormalizeStreets(boolean normalizeStreets) { + this.normalizeStreets = normalizeStreets; + } + + public String getRegionName() { + if (regionName == null) { + return "Region"; //$NON-NLS-1$ + } + return regionName; + } + + public void setRegionName(String regionName) { + this.regionName = regionName; + } + + private Connection getDatabaseConnection(String fileName) throws SQLException { + return dialect.getDatabaseConnection(fileName, log); + } + + public void setPoiFileName(String poiFileName) { + this.poiFileName = poiFileName; + } + + public void setNodesDBFile(File file) { + dbFile = file; + } + + public void setMapFileName(String mapFileName) { + this.mapFileName = mapFileName; + } + + public String getMapFileName() { + if (mapFileName == null) { + return getRegionName() + IndexConstants.BINARY_MAP_INDEX_EXT; + } + return mapFileName; + } + + public String getTempMapDBFileName() { + return getMapFileName() + ".tmp"; //$NON-NLS-1$ + } + + public Long getLastModifiedDate() { + return lastModifiedDate; + } + + public void setLastModifiedDate(Long lastModifiedDate) { + this.lastModifiedDate = lastModifiedDate; + } + + public String getPoiFileName() { + if (poiFileName == null) { + return IndexConstants.POI_INDEX_DIR + getRegionName() + IndexConstants.POI_INDEX_EXT; + } + return poiFileName; + } + + public String getCityAdminLevel() { + return cityAdminLevel; + } + + public void setCityAdminLevel(String cityAdminLevel) { + this.cityAdminLevel = cityAdminLevel; + } + + public String getRTreeMapIndexNonPackFileName() { + return mapFile.getAbsolutePath() + ".rtree"; //$NON-NLS-1$ + } + + public String getRTreeTransportStopsFileName() { + return mapFile.getAbsolutePath() + ".trans"; //$NON-NLS-1$ + } + + public String getRTreeTransportStopsPackFileName() { + return mapFile.getAbsolutePath() + ".ptrans"; //$NON-NLS-1$ + } + + public String getRTreeMapIndexPackFileName() { + return mapFile.getAbsolutePath() + ".prtree"; //$NON-NLS-1$ + } + + /* ***** END OF GETTERS/SETTERS ***** */ + public void generateIndexes(File readFile, IProgress progress, IOsmStorageFilter addFilter) throws IOException, SAXException, SQLException{ + generateIndexes(readFile, progress, addFilter, null, null); + } + + private void iterateMainEntity(Entity e, OsmDbAccessorContext ctx) throws SQLException { + if (indexPOI) { + indexPoiCreator.iterateEntity(e, ctx); + } + if (indexTransport) { + indexTransportCreator.visitEntityMainStep(e, ctx); + } + if (indexMap) { + indexMapCreator.iterateMainEntity(e, ctx); + } + if (indexAddress) { + indexAddressCreator.iterateMainEntity(e, ctx); + } + } + + private OsmDbCreator extractOsmToNodesDB(File readFile, IProgress progress, IOsmStorageFilter addFilter) throws FileNotFoundException, + IOException, SQLException, SAXException { + boolean pbfFile = false; + InputStream stream = new BufferedInputStream(new FileInputStream(readFile), 8192 * 4); + InputStream streamFile = stream; + long st = System.currentTimeMillis(); + if (readFile.getName().endsWith(".bz2")) { //$NON-NLS-1$ + if (stream.read() != 'B' || stream.read() != 'Z') { + throw new RuntimeException("The source stream must start with the characters BZ if it is to be read as a BZip2 stream."); //$NON-NLS-1$ + } else { + stream = new CBZip2InputStream(stream); + } + } else if (readFile.getName().endsWith(".pbf")) { //$NON-NLS-1$ + pbfFile = true; + } + + OsmBaseStorage storage = new OsmBaseStorage(); + storage.setSupressWarnings(DataExtractionSettings.getSettings().isSupressWarningsForDuplicatedId()); + if (addFilter != null) { + storage.getFilters().add(addFilter); + } + + storage.getFilters().add(new IOsmStorageFilter() { + + @Override + public boolean acceptEntityToLoad(OsmBaseStorage storage, EntityId entityId, Entity entity) { + indexAddressCreator.registerCityIfNeeded(entity); + // accept to allow db creator parse it + return true; + } + }); + + // 1. Loading osm file + OsmDbCreator dbCreator = new OsmDbCreator(this); + try { + progress.setGeneralProgress("[35 / 100]"); //$NON-NLS-1$ + progress.startTask(Messages.getString("IndexCreator.LOADING_FILE") + readFile.getAbsolutePath(), -1); //$NON-NLS-1$ + // 1 init database to store temporary data + dbCreator.initDatabase(dialect, dbConn); + storage.getFilters().add(dbCreator); + if (pbfFile) { + storage.parseOSMPbf(stream, progress, false); + } else { + storage.parseOSM(stream, progress, streamFile, false); + } + dbCreator.finishLoading(); + dbConn.commit(); + + if (log.isInfoEnabled()) { + log.info("File parsed : " + (System.currentTimeMillis() - st)); //$NON-NLS-1$ + } + progress.finishTask(); + return dbCreator; + } finally { + if (log.isInfoEnabled()) { + log.info("File indexed : " + (System.currentTimeMillis() - st)); //$NON-NLS-1$ + } + } + } + + private boolean createPlainOsmDb(IProgress progress, File readFile, IOsmStorageFilter addFilter) throws SQLException, FileNotFoundException, IOException, SAXException{ + // initialize db file + boolean loadFromExistingFile = dbFile != null && dialect.databaseFileExists(dbFile); + if (dbFile == null) { + dbFile = new File(workingDir, TEMP_NODES_DB); + // to save space + if (dialect.databaseFileExists(dbFile)) { + dialect.removeDatabase(dbFile); + } + } + dbConn = getDatabaseConnection(dbFile.getAbsolutePath()); + int allRelations = 100000; + int allWays = 1000000; + int allNodes = 10000000; + if (!loadFromExistingFile) { + OsmDbCreator dbCreator = extractOsmToNodesDB(readFile, progress, addFilter); + if (dbCreator != null) { + allNodes = dbCreator.getAllNodes(); + allWays = dbCreator.getAllWays(); + allRelations = dbCreator.getAllRelations(); + } + } + accessor.initDatabase(dbConn, allNodes, allWays, allRelations); + return loadFromExistingFile; + } + + private void createDatabaseIndexesStructure() throws SQLException, IOException { + // 2.1 create temporary sqlite database to put temporary results to it + if (indexMap || indexAddress || indexTransport) { + mapFile = new File(workingDir, getMapFileName()); + // to save space + mapFile.getParentFile().mkdirs(); + File tempDBMapFile = new File(workingDir, getTempMapDBFileName()); + dialect.removeDatabase(tempDBMapFile); + mapConnection = getDatabaseConnection(tempDBMapFile.getAbsolutePath()); + mapConnection.setAutoCommit(false); + } + + // 2.2 create rtree map + if (indexMap) { + indexMapCreator.createDatabaseStructure(mapConnection, dialect, getRTreeMapIndexNonPackFileName()); + } + if (indexAddress) { + indexAddressCreator.createDatabaseStructure(mapConnection, dialect); + } + if (indexPOI) { + indexPoiCreator.createDatabaseStructure(new File(workingDir, getPoiFileName())); + } + if (indexTransport) { + indexTransportCreator.createDatabaseStructure(mapConnection, dialect, getRTreeTransportStopsFileName()); + } + } + + + public void generateIndexes(File readFile, IProgress progress, IOsmStorageFilter addFilter, MapZooms mapZooms, + MapRenderingTypes renderingTypes) throws IOException, SAXException, SQLException { + if (renderingTypes == null) { + renderingTypes = MapRenderingTypes.getDefault(); + } + if (mapZooms == null) { + mapZooms = MapZooms.getDefault(); + } + + // clear previous results and setting variables + if (readFile != null && regionName == null) { + int i = readFile.getName().indexOf('.'); + if (i > -1) { + regionName = Algoritms.capitalizeFirstLetterAndLowercase(readFile.getName().substring(0, i)); + } + } + this.indexTransportCreator = new IndexTransportCreator(); + this.indexPoiCreator = new IndexPoiCreator(); + this.indexAddressCreator = new IndexAddressCreator(); + this.indexMapCreator = new IndexVectorMapCreator(); + this.accessor = new OsmDbAccessor(); + + + indexMapCreator.initSettings(mapZooms, renderingTypes); + + // init address + String[] normalizeDefaultSuffixes = null; + String[] normalizeSuffixes = null; + if (normalizeStreets) { + normalizeDefaultSuffixes = DataExtractionSettings.getSettings().getDefaultSuffixesToNormalizeStreets(); + normalizeSuffixes = DataExtractionSettings.getSettings().getSuffixesToNormalizeStreets(); + } + indexAddressCreator.initSettings(normalizeStreets, normalizeDefaultSuffixes, normalizeSuffixes, saveAddressWays, cityAdminLevel); + + // Main generation method + try { + // //////////////////////////////////////////////////////////////////////// + // 1. creating nodes db to fast access for all nodes and simply import all relations, ways, nodes to it + boolean loadFromExistingFile = createPlainOsmDb(progress, readFile, addFilter); + + // do not create temp map file and rtree files + if (recreateOnlyBinaryFile) { + mapFile = new File(workingDir, getMapFileName()); + File tempDBMapFile = new File(workingDir, getTempMapDBFileName()); + mapConnection = getDatabaseConnection(tempDBMapFile.getAbsolutePath()); + mapConnection.setAutoCommit(false); + try { + if (indexMap) { + indexMapCreator.createRTreeFiles(getRTreeMapIndexPackFileName()); + } + if (indexTransport) { + indexTransportCreator.createRTreeFile(getRTreeTransportStopsPackFileName()); + } + } catch (RTreeException e) { + log.error("Error flushing", e); //$NON-NLS-1$ + throw new IOException(e); + } + } else { + + // 2. Create index connections and index structure + createDatabaseIndexesStructure(); + + // 3. Processing all entries + + // 3.1 write all cities + if (indexAddress) { + progress.setGeneralProgress("[40 / 100]"); //$NON-NLS-1$ + progress.startTask(Messages.getString("IndexCreator.INDEX_CITIES"), accessor.getAllNodes()); //$NON-NLS-1$ + if (loadFromExistingFile) { + // load cities names + accessor.iterateOverEntities(progress, EntityType.NODE, new OsmDbVisitor() { + @Override + public void iterateEntity(Entity e, OsmDbAccessorContext ctx) { + indexAddressCreator.registerCityIfNeeded(e); + } + }); + } + indexAddressCreator.writeCitiesIntoDb(); + } + + // 3.2 index address relations + if (indexAddress || indexMap) { + progress.setGeneralProgress("[30 / 100]"); //$NON-NLS-1$ + progress.startTask(Messages.getString("IndexCreator.PREINDEX_ADRESS_MAP"), accessor.getAllRelations()); //$NON-NLS-1$ + accessor.iterateOverEntities(progress, EntityType.RELATION, new OsmDbVisitor() { + @Override + public void iterateEntity(Entity e, OsmDbAccessorContext ctx) throws SQLException { + if (indexAddress) { + indexAddressCreator.indexAddressRelation((Relation) e, ctx); + indexAddressCreator.indexBoundariesRelation((Relation) e, ctx); + } + if (indexMap) { + indexMapCreator.indexMapRelationsAndMultiPolygons(e, ctx); + } + } + }); + if (indexAddress) { + progress.setGeneralProgress("[40 / 100]"); //$NON-NLS-1$ + progress.startTask(Messages.getString("IndexCreator.PREINDEX_ADRESS_MAP"), accessor.getAllWays()); //$NON-NLS-1$ + accessor.iterateOverEntities(progress, EntityType.WAY, new OsmDbVisitor() { + @Override + public void iterateEntity(Entity e, OsmDbAccessorContext ctx) throws SQLException { + indexAddressCreator.indexBoundariesRelation(e, ctx); + } + }); + + indexAddressCreator.commitToPutAllCities(); + } + + } + + // 3.3 MAIN iterate over all entities + if (indexPOI || indexAddress || indexMap) { + progress.setGeneralProgress("[50 / 100]"); + progress.startTask(Messages.getString("IndexCreator.PROCESS_OSM_NODES"), accessor.getAllNodes()); + accessor.iterateOverEntities(progress, EntityType.NODE, new OsmDbVisitor() { + @Override + public void iterateEntity(Entity e, OsmDbAccessorContext ctx) throws SQLException { + iterateMainEntity(e, ctx); + } + }); + progress.setGeneralProgress("[70 / 100]"); + progress.startTask(Messages.getString("IndexCreator.PROCESS_OSM_WAYS"), accessor.getAllWays()); + accessor.iterateOverEntities(progress, EntityType.WAY, new OsmDbVisitor() { + @Override + public void iterateEntity(Entity e, OsmDbAccessorContext ctx) throws SQLException { + iterateMainEntity(e, ctx); + } + }); + } + progress.setGeneralProgress("[85 / 100]"); + progress.startTask(Messages.getString("IndexCreator.PROCESS_OSM_REL"), accessor.getAllRelations()); + accessor.iterateOverEntities(progress, EntityType.RELATION, new OsmDbVisitor() { + @Override + public void iterateEntity(Entity e, OsmDbAccessorContext ctx) throws SQLException { + iterateMainEntity(e, ctx); + } + }); + + // 3.4 combine all low level ways and simplify them + if (indexMap) { + progress.setGeneralProgress("[90 / 100]"); + progress.startTask(Messages.getString("IndexCreator.INDEX_LO_LEVEL_WAYS"), indexMapCreator.getLowLevelWays()); + indexMapCreator.processingLowLevelWays(progress); + } + + // 3.5 update all postal codes from relations + if (indexAddress) { + progress.setGeneralProgress("[90 / 100]"); + progress.startTask(Messages.getString("IndexCreator.REGISTER_PCODES"), -1); + indexAddressCreator.processingPostcodes(); + } + + // 4. packing map rtree indexes + if (indexMap) { + progress.setGeneralProgress("[90 / 100]"); //$NON-NLS-1$ + progress.startTask(Messages.getString("IndexCreator.PACK_RTREE_MAP"), -1); //$NON-NLS-1$ + indexMapCreator.packRtreeFiles(getRTreeMapIndexNonPackFileName(), getRTreeMapIndexPackFileName()); + } + + if (indexTransport) { + progress.setGeneralProgress("[90 / 100]"); //$NON-NLS-1$ + progress.startTask(Messages.getString("IndexCreator.PACK_RTREE_TRANSP"), -1); //$NON-NLS-1$ + indexTransportCreator.packRTree(getRTreeTransportStopsFileName(), getRTreeTransportStopsPackFileName()); + } + } + + // 5. Writing binary file + if (indexMap || indexAddress || indexTransport) { + if (mapFile.exists()) { + mapFile.delete(); + } + mapRAFile = new RandomAccessFile(mapFile, "rw"); + BinaryMapIndexWriter writer = new BinaryMapIndexWriter(mapRAFile); + if (indexMap) { + progress.setGeneralProgress("[95 of 100]"); + progress.startTask("Writing map index to binary file...", -1); + indexMapCreator.writeBinaryMapIndex(writer, regionName); + } + + if (indexAddress) { + progress.setGeneralProgress("[95 of 100]"); + progress.startTask("Writing address index to binary file...", -1); + indexAddressCreator.writeBinaryAddressIndex(writer, regionName, progress); + } + + if (indexTransport) { + progress.setGeneralProgress("[95 of 100]"); + progress.startTask("Writing transport index to binary file...", -1); + indexTransportCreator.writeBinaryTransportIndex(writer, regionName, mapConnection); + } + progress.finishTask(); + writer.close(); + mapRAFile.close(); + log.info("Finish writing binary file"); //$NON-NLS-1$ + } + } catch (RuntimeException e) { + log.error("Log exception", e); //$NON-NLS-1$ + throw e; + } catch (SQLException e) { + log.error("Log exception", e); //$NON-NLS-1$ + throw e; + } catch (IOException e) { + log.error("Log exception", e); //$NON-NLS-1$ + throw e; + } catch (SAXException e) { + log.error("Log exception", e); //$NON-NLS-1$ + throw e; + } finally { + try { + accessor.closeReadingConnection(); + + indexPoiCreator.commitAndClosePoiFile(lastModifiedDate); + indexAddressCreator.closeAllPreparedStatements(); + indexTransportCreator.commitAndCloseFiles(getRTreeTransportStopsFileName(), getRTreeTransportStopsPackFileName(), + deleteDatabaseIndexes); + indexMapCreator.commitAndCloseFiles(getRTreeMapIndexNonPackFileName(), getRTreeMapIndexPackFileName(), + deleteDatabaseIndexes); + + if (mapConnection != null) { + mapConnection.commit(); + mapConnection.close(); + mapConnection = null; + File tempDBFile = new File(workingDir, getTempMapDBFileName()); + if (dialect.databaseFileExists(tempDBFile) && deleteDatabaseIndexes) { + // do not delete it for now + dialect.removeDatabase(tempDBFile); + } + } + + // do not delete first db connection + if (dbConn != null) { + if (DBDialect.H2 == dialect) { + dbConn.createStatement().execute("SHUTDOWN COMPACT"); //$NON-NLS-1$ + } + dbConn.close(); + } + if (deleteOsmDB) { + if (DBDialect.DERBY == dialect) { + try { + DriverManager.getConnection("jdbc:derby:;shutdown=true"); //$NON-NLS-1$ + } catch (SQLException e) { + // ignore exception + } + } + dialect.removeDatabase(dbFile); + } + } catch (SQLException e) { + e.printStackTrace(); + } + } + } + + + public static void main(String[] args) throws IOException, SAXException, SQLException { + + long time = System.currentTimeMillis(); + IndexCreator creator = new IndexCreator(new File("/home/victor/projects/OsmAnd/data/osm-gen/")); //$NON-NLS-1$ + creator.setIndexMap(true); + creator.setIndexAddress(true); + creator.setIndexPOI(true); + creator.setIndexTransport(true); + // for NL +// creator.setCityAdminLevel("10"); + + creator.recreateOnlyBinaryFile = false; + creator.deleteDatabaseIndexes = true; + + creator.generateIndexes(new File("/home/victor/projects/OsmAnd/download/406/map.osm"), + new ConsoleProgressImplementation(1), null, MapZooms.getDefault(), null); +// creator.generateIndexes(new File("/home/victor/projects/OsmAnd/data/osm-maps/minsk_around.osm"), +// new ConsoleProgressImplementation(1), null, MapZooms.getDefault(), null); + + + +// creator.setNodesDBFile(new File("e:/Information/OSM maps/osmand/minsk.tmp.odb")); +// creator.generateIndexes(new File("e:/Information/OSM maps/belarus osm/minsk.osm"), new ConsoleProgressImplementation(3), null, MapZooms.getDefault(), null); + + + + System.out.println("WHOLE GENERATION TIME : " + (System.currentTimeMillis() - time)); //$NON-NLS-1$ + System.out.println("COORDINATES_SIZE " + BinaryMapIndexWriter.COORDINATES_SIZE + " count " + BinaryMapIndexWriter.COORDINATES_COUNT); //$NON-NLS-1$ //$NON-NLS-2$ + System.out.println("TYPES_SIZE " + BinaryMapIndexWriter.TYPES_SIZE); //$NON-NLS-1$ + System.out.println("ID_SIZE " + BinaryMapIndexWriter.ID_SIZE); //$NON-NLS-1$ + System.out.println("- COORD_TYPES_ID SIZE " + (BinaryMapIndexWriter.COORDINATES_SIZE + BinaryMapIndexWriter.TYPES_SIZE + BinaryMapIndexWriter.ID_SIZE)); //$NON-NLS-1$ + System.out.println("- MAP_DATA_SIZE " + BinaryMapIndexWriter.MAP_DATA_SIZE); //$NON-NLS-1$ + System.out.println("- STRING_TABLE_SIZE " + BinaryMapIndexWriter.STRING_TABLE_SIZE); //$NON-NLS-1$ + System.out.println("-- MAP_DATA_AND_STRINGS SIZE " + (BinaryMapIndexWriter.MAP_DATA_SIZE + BinaryMapIndexWriter.STRING_TABLE_SIZE)); //$NON-NLS-1$ + + } } \ No newline at end of file diff --git a/DataExtractionOSM/src/net/osmand/data/preparation/IndexPoiCreator.java b/DataExtractionOSM/src/net/osmand/data/preparation/IndexPoiCreator.java index 3478cd431c..49011eaf20 100644 --- a/DataExtractionOSM/src/net/osmand/data/preparation/IndexPoiCreator.java +++ b/DataExtractionOSM/src/net/osmand/data/preparation/IndexPoiCreator.java @@ -13,7 +13,7 @@ import java.util.List; import net.osmand.Algoritms; import net.osmand.data.Amenity; import net.osmand.data.AmenityType; -import net.osmand.data.index.IndexConstants; +import net.osmand.data.IndexConstants; import net.osmand.osm.Entity; import net.osmand.osm.MapUtils; import net.osmand.osm.OSMSettings.OSMTagKey; diff --git a/DataExtractionOSM/src/net/osmand/ExceptionHandler.java b/DataExtractionOSM/src/net/osmand/swing/ExceptionHandler.java similarity index 89% rename from DataExtractionOSM/src/net/osmand/ExceptionHandler.java rename to DataExtractionOSM/src/net/osmand/swing/ExceptionHandler.java index 7450b85f99..60eb2546ec 100644 --- a/DataExtractionOSM/src/net/osmand/ExceptionHandler.java +++ b/DataExtractionOSM/src/net/osmand/swing/ExceptionHandler.java @@ -1,8 +1,8 @@ -package net.osmand; +package net.osmand.swing; import javax.swing.JOptionPane; -import net.osmand.swing.OsmExtractionUI; +import net.osmand.LogUtil; import org.apache.commons.logging.Log; diff --git a/DataExtractionOSM/src/net/osmand/swing/MapPanel.java b/DataExtractionOSM/src/net/osmand/swing/MapPanel.java index c1f2715790..ea65488d2f 100644 --- a/DataExtractionOSM/src/net/osmand/swing/MapPanel.java +++ b/DataExtractionOSM/src/net/osmand/swing/MapPanel.java @@ -40,9 +40,9 @@ import javax.swing.UIManager; import net.osmand.Algoritms; import net.osmand.LogUtil; import net.osmand.data.DataTileManager; -import net.osmand.data.preparation.MapTileDownloader; -import net.osmand.data.preparation.MapTileDownloader.DownloadRequest; -import net.osmand.data.preparation.MapTileDownloader.IMapDownloaderCallback; +import net.osmand.data.MapTileDownloader; +import net.osmand.data.MapTileDownloader.DownloadRequest; +import net.osmand.data.MapTileDownloader.IMapDownloaderCallback; import net.osmand.map.IMapLocationListener; import net.osmand.map.ITileSource; import net.osmand.map.TileSourceManager; diff --git a/DataExtractionOSM/src/net/osmand/swing/MapRouterLayer.java b/DataExtractionOSM/src/net/osmand/swing/MapRouterLayer.java index bf905d62eb..695e4a64c6 100644 --- a/DataExtractionOSM/src/net/osmand/swing/MapRouterLayer.java +++ b/DataExtractionOSM/src/net/osmand/swing/MapRouterLayer.java @@ -23,7 +23,6 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; -import net.osmand.ExceptionHandler; import net.osmand.binary.BinaryMapDataObject; import net.osmand.binary.BinaryMapIndexReader; import net.osmand.binary.BinaryRouteDataReader; diff --git a/DataExtractionOSM/src/net/osmand/swing/OsmExtractionUI.java b/DataExtractionOSM/src/net/osmand/swing/OsmExtractionUI.java index 3592c5ec0a..6409747726 100644 --- a/DataExtractionOSM/src/net/osmand/swing/OsmExtractionUI.java +++ b/DataExtractionOSM/src/net/osmand/swing/OsmExtractionUI.java @@ -1,889 +1,886 @@ -package net.osmand.swing; - -import java.awt.BorderLayout; -import java.awt.Container; -import java.awt.FlowLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.lang.Thread.UncaughtExceptionHandler; -import java.lang.reflect.InvocationTargetException; -import java.sql.SQLException; -import java.text.MessageFormat; - -import javax.swing.AbstractAction; -import javax.swing.JCheckBox; -import javax.swing.JDialog; -import javax.swing.JFileChooser; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JMenuItem; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JSplitPane; -import javax.swing.JTree; -import javax.swing.UIManager; -import javax.swing.filechooser.FileFilter; -import javax.swing.tree.DefaultMutableTreeNode; -import javax.swing.tree.DefaultTreeModel; -import javax.xml.stream.XMLStreamException; - -import net.osmand.ExceptionHandler; -import net.osmand.Version; -import net.osmand.data.preparation.IndexCreator; -import net.osmand.map.IMapLocationListener; -import net.osmand.map.ITileSource; -import net.osmand.osm.MapRenderingTypes; -import net.osmand.osm.io.IOsmStorageFilter; -import net.osmand.osm.io.OsmBaseStorage; -import net.osmand.osm.io.OsmBoundsFilter; -import net.osmand.osm.io.OsmStorageWriter; -import net.osmand.swing.MapPanel.MapSelectionArea; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.tools.bzip2.CBZip2OutputStream; -import org.xml.sax.SAXException; - -import rtree.RTree; - - -public class OsmExtractionUI implements IMapLocationListener { - - private static final Log log = LogFactory.getLog(OsmExtractionUI.class); - public static final String LOG_PATH = getUserLogDirectoryPath() + "/Osmand/osmand.log"; //$NON-NLS-1$ //$NON-NLS-2$ - public static OsmExtractionUI MAIN_APP; - - public static String getUserLogDirectoryPath() { - String path = null; - if (System.getProperty("os.name").startsWith("Windows")) { - path = System.getenv("APPDATA").replaceAll("\\\\", "/"); - } else if (System.getProperty("os.name").startsWith("Mac")) { - path = System.getProperty("user.home") + "/Library/Logs"; - } else if (System.getenv("XDG_CACHE_HOME") != null) { - path = System.getenv("XDG_CACHE_HOME"); - } else { - path = System.getProperty("user.home") + "/.cache"; - } - return path; - } - - public static void main(String[] args) { - // first of all config log - new File(LOG_PATH).getParentFile().mkdirs(); - final UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler(); - Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler(){ - @Override - public void uncaughtException(Thread t, Throwable e) { - if(!(e instanceof ThreadDeath)){ - ExceptionHandler.handle("Error in thread " + t.getName(), e); //$NON-NLS-1$ - } - defaultHandler.uncaughtException(t, e); - } - }); - - MAIN_APP = new OsmExtractionUI(); - MAIN_APP.frame.setBounds(DataExtractionSettings.getSettings().getWindowBounds()); - MAIN_APP.frame.setVisible(true); - } - - - - - private JTree treePlaces; -// private DataExtractionTreeNode amenitiesTree; -// private TreeModelListener treeModelListener; - - - private MapPanel mapPanel; - private JFrame frame; - private JLabel statusBarLabel; - - - private JCheckBox buildPoiIndex; - private JCheckBox buildAddressIndex; - private JCheckBox buildMapIndex; - private JCheckBox buildTransportIndex; - private JCheckBox normalizingStreets; - - private String regionName; - - - - public OsmExtractionUI(){ - createUI(); - } - - - - - - public void createUI(){ - frame = new JFrame(Messages.getString("OsmExtractionUI.OSMAND_MAP_CREATOR")); //$NON-NLS-1$ - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (Exception e) { - log.error("Can't set look and feel", e); //$NON-NLS-1$ - } - - - frame.addWindowListener(new ExitListener()); - Container content = frame.getContentPane(); - frame.setFocusable(true); - - mapPanel = new MapPanel(DataExtractionSettings.getSettings().getTilesDirectory()); - mapPanel.setFocusable(true); - mapPanel.addMapLocationListener(this); - - statusBarLabel = new JLabel(); - content.add(statusBarLabel, BorderLayout.SOUTH); - File workingDir = DataExtractionSettings.getSettings().getDefaultWorkingDir(); - statusBarLabel.setText(workingDir == null ? Messages.getString("OsmExtractionUI.WORKING_DIR_UNSPECIFIED") : Messages.getString("OsmExtractionUI.WORKING_DIRECTORY") + workingDir.getAbsolutePath()); //$NON-NLS-1$ //$NON-NLS-2$ - - - treePlaces = new JTree(); - treePlaces.setModel(new DefaultTreeModel(new DefaultMutableTreeNode(Messages.getString("OsmExtractionUI.REGION")), false)); //$NON-NLS-1$ - JSplitPane panelForTreeAndMap = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JScrollPane(treePlaces), mapPanel); - panelForTreeAndMap.setResizeWeight(0.2); - content.add(panelForTreeAndMap, BorderLayout.CENTER); - - createButtonsBar(content); - - JMenuBar bar = new JMenuBar(); - fillMenuWithActions(bar); - - frame.setJMenuBar(bar); - } - - - - - public void createButtonsBar(Container content){ - JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT)); - content.add(panel, BorderLayout.NORTH); - - buildMapIndex = new JCheckBox(); - buildMapIndex.setText(Messages.getString("OsmExtractionUI.BUILD_MAP")); //$NON-NLS-1$ - panel.add(buildMapIndex); - buildMapIndex.setSelected(true); - - buildPoiIndex = new JCheckBox(); - buildPoiIndex.setText(Messages.getString("OsmExtractionUI.BUILD_POI")); //$NON-NLS-1$ - panel.add(buildPoiIndex); - buildPoiIndex.setSelected(true); - - buildAddressIndex = new JCheckBox(); - buildAddressIndex.setText(Messages.getString("OsmExtractionUI.BUILD_ADDRESS")); //$NON-NLS-1$ - panel.add(buildAddressIndex); - buildAddressIndex.setSelected(true); - - normalizingStreets = new JCheckBox(); - normalizingStreets.setText(Messages.getString("OsmExtractionUI.NORMALIZE_STREETS")); //$NON-NLS-1$ - panel.add(normalizingStreets); - normalizingStreets.setSelected(true); - - buildTransportIndex = new JCheckBox(); - buildTransportIndex.setText(Messages.getString("OsmExtractionUI.BUILD_TRANSPORT")); //$NON-NLS-1$ - panel.add(buildTransportIndex); - buildTransportIndex.setSelected(true); - - - - } - - public void fillMenuWithActions(final JMenuBar bar){ - JMenu menu = new JMenu(Messages.getString("OsmExtractionUI.MENU_FILE")); //$NON-NLS-1$ - bar.add(menu); - JMenuItem loadFile = new JMenuItem(Messages.getString("OsmExtractionUI.MENU_SELECT_FILE")); //$NON-NLS-1$ - menu.add(loadFile); - JMenuItem loadSpecifiedAreaFile = new JMenuItem(Messages.getString("OsmExtractionUI.MENU_SELECT_OSM_FILE_AREA")); //$NON-NLS-1$ - menu.add(loadSpecifiedAreaFile); - JMenuItem specifyWorkingDir = new JMenuItem(Messages.getString("OsmExtractionUI.SPECIFY_WORKING_DIR")); //$NON-NLS-1$ - menu.add(specifyWorkingDir); - menu.addSeparator(); - JMenuItem exitMenu= new JMenuItem(Messages.getString("OsmExtractionUI.MENU_EXIT")); //$NON-NLS-1$ - menu.add(exitMenu); - - JMenu tileSource = MapPanel.getMenuToChooseSource(mapPanel); - final JMenuItem sqliteDB = new JMenuItem(Messages.getString("OsmExtractionUI.MENU_CREATE_SQLITE")); //$NON-NLS-1$ - tileSource.addSeparator(); - tileSource.add(sqliteDB); - bar.add(tileSource); - - menu = new JMenu(Messages.getString("OsmExtractionUI.MENU_WINDOW")); //$NON-NLS-1$ - bar.add(menu); - JMenuItem settings = new JMenuItem(Messages.getString("OsmExtractionUI.MENU_SETTINGS")); //$NON-NLS-1$ - menu.add(settings); - menu.addSeparator(); - JMenuItem openLogFile = new JMenuItem(Messages.getString("OsmExtractionUI.MENU_OPEN_LOG")); //$NON-NLS-1$ - menu.add(openLogFile); - - menu = new JMenu(Messages.getString("OsmExtractionUI.MENU_ABOUT")); //$NON-NLS-1$ - bar.add(menu); - JMenuItem aboutApplication = new JMenuItem(Messages.getString("OsmExtractionUI.MENU_ABOUT_2")); //$NON-NLS-1$ - menu.add(aboutApplication); - - - aboutApplication.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - JOptionPane.showMessageDialog(frame, Version.APP_MAP_CREATOR_FULL_NAME); - } - }); - - openLogFile.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - File file = new File(OsmExtractionUI.LOG_PATH); - if (file != null && file.exists()) { - if (System.getProperty("os.name").startsWith("Windows")) { //$NON-NLS-1$ //$NON-NLS-2$ - try { - Runtime.getRuntime().exec(new String[] { "notepad.exe", file.getAbsolutePath() }); //$NON-NLS-1$ - } catch (IOException es) { - ExceptionHandler.handle(Messages.getString("OsmExtractionUI.UNABLE_OPEN_FILE"), es); //$NON-NLS-1$ - } - } else { - JOptionPane.showMessageDialog(frame, Messages.getString("OsmExtractionUI.OPEN_LOG_FILE_MANUALLY") + LOG_PATH); //$NON-NLS-1$ - } - - } else { - ExceptionHandler.handle(Messages.getString("OsmExtractionUI.LOG_FILE_NOT_FOUND")); //$NON-NLS-1$ - } - } - }); - - sqliteDB.addActionListener(new ActionListener(){ - @Override - public void actionPerformed(ActionEvent e) { - final String regionName = OsmExtractionUI.this.regionName == null ? Messages.getString("OsmExtractionUI.REGION") : OsmExtractionUI.this.regionName; //$NON-NLS-1$ - final ITileSource map = mapPanel.getMap(); - if(map != null){ - try { - final ProgressDialog dlg = new ProgressDialog(frame, Messages.getString("OsmExtractionUI.CREATING_INDEX")); //$NON-NLS-1$ - dlg.setRunnable(new Runnable(){ - - @Override - public void run() { - try { - SQLiteBigPlanetIndex.createSQLiteDatabase(DataExtractionSettings.getSettings().getTilesDirectory(), regionName, map); - } catch (SQLException e1) { - throw new IllegalArgumentException(e1); - } catch (IOException e1) { - throw new IllegalArgumentException(e1); - } - } - }); - dlg.run(); - } catch (InterruptedException e1) { - log.error("Interrupted", e1); //$NON-NLS-1$ - } catch (InvocationTargetException e1) { - ExceptionHandler.handle("Can't create big planet sqlite index", (Exception) e1.getCause()); //$NON-NLS-1$ - } - - - } - } - }); - - - exitMenu.addActionListener(new ActionListener(){ - @Override - public void actionPerformed(ActionEvent e) { - frame.setVisible(false); - exit(); - } - }); - settings.addActionListener(new ActionListener(){ - @Override - public void actionPerformed(ActionEvent e) { - OsmExtractionPreferencesDialog dlg = new OsmExtractionPreferencesDialog(frame); - dlg.showDialog(); - } - - }); - specifyWorkingDir.addActionListener(new ActionListener(){ - - @Override - public void actionPerformed(ActionEvent e) { - JFileChooser fc = new JFileChooser(); - fc.setDialogTitle(Messages.getString("OsmExtractionUI.CHOOSE_WORKING_DIR")); //$NON-NLS-1$ - fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); - File workingDir = DataExtractionSettings.getSettings().getDefaultWorkingDir(); - if(workingDir != null){ - fc.setCurrentDirectory(workingDir); - } - if(fc.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION && fc.getSelectedFile() != null && - fc.getSelectedFile().isDirectory()){ - DataExtractionSettings.getSettings().saveDefaultWorkingDir(fc.getSelectedFile()); - mapPanel.setTilesLocation(DataExtractionSettings.getSettings().getTilesDirectory()); - statusBarLabel.setText(Messages.getString("OsmExtractionUI.WORKING_DIR") + fc.getSelectedFile().getAbsolutePath()); //$NON-NLS-1$ - JMenu tileSource = MapPanel.getMenuToChooseSource(mapPanel); - tileSource.add(sqliteDB); - bar.remove(1); - bar.add(tileSource, 1); - } - } - - }); - loadSpecifiedAreaFile.addActionListener(new ActionListener(){ - @Override - public void actionPerformed(ActionEvent e) { - JFileChooser fc = getOsmFileChooser(); - int answer = fc.showOpenDialog(frame) ; - if (answer == JFileChooser.APPROVE_OPTION && fc.getSelectedFile() != null){ - final JDialog dlg = new JDialog(frame, true); - dlg.setTitle(Messages.getString("OsmExtractionUI.SELECT_AREA_TO_FILTER")); //$NON-NLS-1$ - MapPanel panel = new MapPanel(DataExtractionSettings.getSettings().getTilesDirectory()); - panel.setLatLon(mapPanel.getLatitude(), mapPanel.getLongitude()); - panel.setZoom(mapPanel.getZoom()); - final StringBuilder res = new StringBuilder(); - panel.getLayer(MapInformationLayer.class).setAreaActionHandler(new AbstractAction(Messages.getString("OsmExtractionUI.SELECT_AREA")){ //$NON-NLS-1$ - private static final long serialVersionUID = -3452957517341961969L; - @Override - public void actionPerformed(ActionEvent e) { - res.append(true); - dlg.setVisible(false); - } - - }); - dlg.add(panel); - - - JMenuBar bar = new JMenuBar(); - bar.add(MapPanel.getMenuToChooseSource(panel)); - dlg.setJMenuBar(bar); - dlg.setSize(512, 512); - double x = frame.getBounds().getCenterX(); - double y = frame.getBounds().getCenterY(); - dlg.setLocation((int) x - dlg.getWidth() / 2, (int) y - dlg.getHeight() / 2); - - dlg.setVisible(true); - if(res.length() > 0 && panel.getSelectionArea().isVisible()){ - MapSelectionArea area = panel.getSelectionArea(); - IOsmStorageFilter filter = new OsmBoundsFilter(area.getLat1(), area.getLon1(), area.getLat2(), area.getLon2()); - loadCountry(fc.getSelectedFile(), filter); - } - } - } - - }); - loadFile.addActionListener(new ActionListener(){ - - @Override - public void actionPerformed(ActionEvent e) { - JFileChooser fc = getOsmFileChooser(); - int answer = fc.showOpenDialog(frame) ; - if (answer == JFileChooser.APPROVE_OPTION && fc.getSelectedFile() != null){ - loadCountry(fc.getSelectedFile(), null); - } - } - - }); - - } - - public JFileChooser getOsmFileChooser(){ - JFileChooser fc = new JFileChooser(); - fc.setDialogTitle(Messages.getString("OsmExtractionUI.CHOOSE_OSM_FILE")); //$NON-NLS-1$ - fc.setFileSelectionMode(JFileChooser.FILES_ONLY); - fc.setAcceptAllFileFilterUsed(true); - fc.setCurrentDirectory(DataExtractionSettings.getSettings().getDefaultWorkingDir().getParentFile()); - fc.setFileFilter(new FileFilter(){ - - @Override - public boolean accept(File f) { - return f.isDirectory() || f.getName().endsWith(".bz2") || f.getName().endsWith(".osm") || f.getName().endsWith(".pbf"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - - @Override - public String getDescription() { - return Messages.getString("OsmExtractionUI.OSM_FILES"); //$NON-NLS-1$ - } - }); - return fc; - } - - public JFrame getFrame() { - return frame; - } - - public void loadCountry(final File f, final IOsmStorageFilter filter){ - try { - final ProgressDialog dlg = new ProgressDialog(frame, Messages.getString("OsmExtractionUI.LOADING_OSM_FILE")); //$NON-NLS-1$ - dlg.setRunnable(new Runnable(){ - - @Override - public void run() { - File dir = DataExtractionSettings.getSettings().getDefaultWorkingDir(); - IndexCreator creator = new IndexCreator(dir); - try { - creator.setIndexAddress(buildAddressIndex.isSelected()); - creator.setIndexPOI(buildPoiIndex.isSelected()); - creator.setNormalizeStreets(normalizingStreets.isSelected()); - creator.setIndexTransport(buildTransportIndex.isSelected()); - creator.setIndexMap(buildMapIndex.isSelected()); - creator.setCityAdminLevel(DataExtractionSettings.getSettings().getCityAdminLevel()); - String fn = DataExtractionSettings.getSettings().getMapRenderingTypesFile(); - MapRenderingTypes types; - if(fn == null || fn.length() == 0){ - types = MapRenderingTypes.getDefault(); - } else { - types = new MapRenderingTypes(fn); - } - RTree.clearCache(); - creator.generateIndexes(f, dlg, filter, DataExtractionSettings.getSettings().getMapZooms(), types); - } catch (IOException e) { - throw new IllegalArgumentException(e); - } catch (SAXException e) { - throw new IllegalStateException(e); - } catch (SQLException e) { - throw new IllegalStateException(e); - } - regionName = creator.getRegionName(); - StringBuilder msg = new StringBuilder(); - msg.append(Messages.getString("OsmExtractionUI.INDEXES_FOR")).append(regionName).append(" : "); //$NON-NLS-1$ //$NON-NLS-2$ - boolean comma = false; - if (buildMapIndex.isSelected()) { - if(comma) msg.append(", "); //$NON-NLS-1$ - comma = true; - msg.append(Messages.getString("OsmExtractionUI.MAP")); //$NON-NLS-1$ - } - if (buildPoiIndex.isSelected()) { - if(comma) msg.append(", "); //$NON-NLS-1$ - comma = true; - msg.append(Messages.getString("OsmExtractionUI.POI")); //$NON-NLS-1$ - } - if (buildAddressIndex.isSelected()) { - if(comma) msg.append(", "); //$NON-NLS-1$ - comma = true; - msg.append(Messages.getString("OsmExtractionUI.ADDRESS")); //$NON-NLS-1$ - } - if (buildTransportIndex.isSelected()) { - if(comma) msg.append(", "); //$NON-NLS-1$ - comma = true; - msg.append(Messages.getString("OsmExtractionUI.TRANSPORT")); //$NON-NLS-1$ - } - msg.append(MessageFormat.format(Messages.getString("OsmExtractionUI.WERE_SUCCESFULLY_CREATED"), dir.getAbsolutePath())); //$NON-NLS-1$ - JOptionPane pane = new JOptionPane(msg); - JDialog dialog = pane.createDialog(frame, Messages.getString("OsmExtractionUI.GENERATION_DATA")); //$NON-NLS-1$ - dialog.setVisible(true); - } - }); - - dlg.run(); - frame.setTitle(Messages.getString("OsmExtractionUI.OSMAND_MAP_CREATOR_FILE") + f.getName()); //$NON-NLS-1$ - } catch (InterruptedException e1) { - log.error("Interrupted", e1); //$NON-NLS-1$ - } catch (InvocationTargetException e1) { - ExceptionHandler.handle("Exception during operation", e1.getCause()); //$NON-NLS-1$ - } - } - - public void saveCountry(final File f, final OsmBaseStorage storage){ - final OsmStorageWriter writer = new OsmStorageWriter(); - try { - final ProgressDialog dlg = new ProgressDialog(frame, Messages.getString("OsmExtractionUI.SAVING_OSM_FILE")); //$NON-NLS-1$ - dlg.setRunnable(new Runnable() { - @Override - public void run() { - try { - OutputStream output = new FileOutputStream(f); - try { - if (f.getName().endsWith(".bz2")) { //$NON-NLS-1$ - output.write('B'); - output.write('Z'); - output = new CBZip2OutputStream(output); - } - writer.saveStorage(output, storage, null, false); - } finally { - output.close(); - } - } catch (IOException e) { - throw new IllegalArgumentException(e); - } catch (XMLStreamException e) { - throw new IllegalArgumentException(e); - } - } - }); - dlg.run(); - } catch (InterruptedException e1) { - log.error("Interrupted", e1); //$NON-NLS-1$ - } catch (InvocationTargetException e1) { - ExceptionHandler.handle("Log file is not found", e1.getCause()); //$NON-NLS-1$ - } - } - - @Override - public void locationChanged(final double newLatitude, final double newLongitude, Object source){ -// recalculateAmenities(newLatitude, newLongitude); - } - - - - - public class ExitListener extends WindowAdapter { - public void windowClosing(WindowEvent event) { - exit(); - } - } - - public void exit(){ - // save preferences - DataExtractionSettings settings = DataExtractionSettings.getSettings(); - settings.saveDefaultLocation(mapPanel.getLatitude(), mapPanel.getLongitude()); - settings.saveDefaultZoom(mapPanel.getZoom()); - settings.saveWindowBounds(frame.getBounds()); - System.exit(0); - } - - - - - - // OLD CODE -/* - - public JTree createTree(Container content) { - treePlaces.setEditable(true); - treePlaces.setCellEditor(new RegionCellEditor(treePlaces, (DefaultTreeCellRenderer) treePlaces.getCellRenderer())); - treePlaces.addTreeSelectionListener(new TreeSelectionListener() { - @Override - public void valueChanged(TreeSelectionEvent e) { - if (e.getPath() != null) { - if (e.getPath().getLastPathComponent() instanceof DataExtractionTreeNode) { - Object o = ((DataExtractionTreeNode) e.getPath().getLastPathComponent()).getModelObject(); - - if (o instanceof MapObject) { - MapObject c = (MapObject) o; - LatLon location = c.getLocation(); - if (location != null) { - if (o instanceof Street) { - DataTileManager ways = new DataTileManager(); - for (Way w : ((Street) o).getWayNodes()) { - LatLon l = w.getLatLon(); - ways.registerObject(l.getLatitude(), l.getLongitude(), w); - } - mapPanel.setPoints(ways); - mapPanel.requestFocus(); - } - mapPanel.setLatLon(location.getLatitude(), location.getLongitude()); - mapPanel.requestFocus(); - } - if (o instanceof TransportRoute) { - DataTileManager ways = new DataTileManager(); - for (Way w : ((TransportRoute) o).getWays()) { - LatLon l = w.getLatLon(); - ways.registerObject(l.getLatitude(), l.getLongitude(), w); - } - for (TransportStop w : ((TransportRoute) o).getBackwardStops()) { - LatLon l = w.getLocation(); - ways.registerObject(l.getLatitude(), l.getLongitude(), new Node(l.getLatitude(), l.getLongitude(), w - .getId())); - } - for (TransportStop w : ((TransportRoute) o).getForwardStops()) { - LatLon l = w.getLocation(); - ways.registerObject(l.getLatitude(), l.getLongitude(), new Node(l.getLatitude(), l.getLongitude(), w - .getId())); - } - mapPanel.setPoints(ways); - mapPanel.requestFocus(); - } - - } else if (o instanceof Entity) { - Entity c = (Entity) o; - LatLon latLon = c.getLatLon(); - if (latLon != null) { - mapPanel.setLatLon(latLon.getLatitude(), latLon.getLongitude()); - mapPanel.requestFocus(); - } - } - } - } - - } - }); - - treeModelListener = new TreeModelListener() { - public void treeNodesChanged(TreeModelEvent e) { - Object node = e.getTreePath().getLastPathComponent(); - if (e.getChildren() != null && e.getChildren().length > 0) { - node = e.getChildren()[0]; - } - if (node instanceof DataExtractionTreeNode) { - DataExtractionTreeNode n = ((DataExtractionTreeNode) node); - if (n.getModelObject() instanceof MapObject) { - MapObject r = (MapObject) n.getModelObject(); - String newName = n.getUserObject().toString(); - if (!r.getName().equals(newName)) { - r.setName(n.getUserObject().toString()); - } - if (r instanceof Street && !((Street) r).isRegisteredInCity()) { - DefaultMutableTreeNode parent = ((DefaultMutableTreeNode) n.getParent()); - parent.remove(n); - ((DefaultTreeModel) treePlaces.getModel()).nodeStructureChanged(parent); - } - } - } - } - - public void treeNodesInserted(TreeModelEvent e) { - } - - public void treeNodesRemoved(TreeModelEvent e) { - } - - public void treeStructureChanged(TreeModelEvent e) { - } - }; - treePlaces.getModel().addTreeModelListener(treeModelListener); - return treePlaces; - } - - public void fillPopupMenuWithActions(JPopupMenu menu) { - Action delete = new AbstractAction("Delete") { - private static final long serialVersionUID = 7476603434847164396L; - - public void actionPerformed(ActionEvent e) { - TreePath[] p = treePlaces.getSelectionPaths(); - if(p != null && - JOptionPane.OK_OPTION == - JOptionPane.showConfirmDialog(frame, "Are you sure about deleting " +p.length + " resources ? ")){ - for(TreePath path : treePlaces.getSelectionPaths()){ - Object node = path.getLastPathComponent(); - if (node instanceof DataExtractionTreeNode) { - DataExtractionTreeNode n = ((DataExtractionTreeNode) node); - if(n.getParent() instanceof DataExtractionTreeNode){ - DataExtractionTreeNode parent = ((DataExtractionTreeNode) n.getParent()); - boolean remove = false; - if (n.getModelObject() instanceof Street) { - ((City)parent.getModelObject()).unregisterStreet(((Street)n.getModelObject()).getName()); - remove = true; - } else if (n.getModelObject() instanceof Building) { - ((Street)parent.getModelObject()).getBuildings().remove(n.getModelObject()); - remove = true; - } else if (n.getModelObject() instanceof City) { - Region r = (Region) ((DataExtractionTreeNode)parent.getParent()).getModelObject(); - r.unregisterCity((City) n.getModelObject()); - remove = true; - } else if (n.getModelObject() instanceof Amenity) { - Region r = (Region) ((DataExtractionTreeNode)parent.getParent().getParent()).getModelObject(); - Amenity am = (Amenity) n.getModelObject(); - r.getAmenityManager().unregisterObject(am.getLocation().getLatitude(), am.getLocation().getLongitude(), am); - remove = true; - } - if(remove){ - parent.remove(n); - ((DefaultTreeModel) treePlaces.getModel()).nodeStructureChanged(parent); - } - } - } - } - - } - } - }; - menu.add(delete); - Action rename= new AbstractAction("Rename") { - private static final long serialVersionUID = -8257594433235073767L; - - public void actionPerformed(ActionEvent e) { - TreePath path = treePlaces.getSelectionPath(); - if(path != null){ - treePlaces.startEditingAtPath(path); - } - } - }; - menu.add(rename); - } - - - public void setRegion(Region region, String name){ - if (this.region == region) { - return; - } - this.region = region; - DefaultMutableTreeNode root = new DataExtractionTreeNode(name, region); - if (region != null) { - amenitiesTree = new DataExtractionTreeNode("Amenities", region); - amenitiesTree.add(new DataExtractionTreeNode("First 15", region)); - for (AmenityType type : AmenityType.values()) { - amenitiesTree.add(new DataExtractionTreeNode(Algoritms.capitalizeFirstLetterAndLowercase(type.toString()), type)); - } - root.add(amenitiesTree); - - DataExtractionTreeNode transport = new DataExtractionTreeNode("Transport", region); - root.add(transport); - for(String s : region.getTransportRoutes().keySet()){ - DataExtractionTreeNode trRoute = new DataExtractionTreeNode(s, s); - transport.add(trRoute); - List list = region.getTransportRoutes().get(s); - for(TransportRoute r : list){ - DataExtractionTreeNode route = new DataExtractionTreeNode(r.getRef(), r); - trRoute.add(route); - } - - } - - for (CityType t : CityType.values()) { - DefaultMutableTreeNode cityTree = new DataExtractionTreeNode(Algoritms.capitalizeFirstLetterAndLowercase(t.toString()), t); - root.add(cityTree); - for (City ct : region.getCitiesByType(t)) { - DefaultMutableTreeNode cityNodeTree = new DataExtractionTreeNode(ct.getName(), ct); - cityTree.add(cityNodeTree); - - for (Street str : ct.getStreets()) { - DefaultMutableTreeNode strTree = new DataExtractionTreeNode(str.getName(), str); - cityNodeTree.add(strTree); - for (Building b : str.getBuildings()) { - DefaultMutableTreeNode building = new DataExtractionTreeNode(b.getName(), b); - strTree.add(building); - } - } - } - } - } - - if (searchList != null) { - updateListCities(region, searchTextField.getText(), searchList); - } - mapPanel.repaint(); - DefaultTreeModel newModel = new DefaultTreeModel(root, false); - newModel.addTreeModelListener(treeModelListener); - treePlaces.setModel(newModel); - - updateButtonsBar(); - locationChanged(mapPanel.getLatitude(), mapPanel.getLongitude(), this); - } - - public static class DataExtractionTreeNode extends DefaultMutableTreeNode { - private static final long serialVersionUID = 1L; - private final Object modelObject; - - public DataExtractionTreeNode(String name, Object modelObject){ - super(name); - this.modelObject = modelObject; - } - - public Object getModelObject(){ - return modelObject; - } - - } - - private void recalculateAmenities(final double newLatitude, final double newLongitude) { - if (amenitiesTree != null) { - Region reg = (Region) amenitiesTree.getModelObject(); - List closestAmenities = reg.getAmenityManager().getClosestObjects(newLatitude, newLongitude, 0, 5); - MapUtils.sortListOfMapObject(closestAmenities, newLatitude, newLongitude); - - - Map> filter = new HashMap>(); - for (Amenity n : closestAmenities) { - AmenityType type = n.getType(); - if (!filter.containsKey(type)) { - filter.put(type, new ArrayList()); - } - filter.get(type).add(n); - } - - - for (int i = 1; i < amenitiesTree.getChildCount(); i++) { - AmenityType type = (AmenityType) ((DataExtractionTreeNode) amenitiesTree.getChildAt(i)).getModelObject(); - ((DefaultMutableTreeNode) amenitiesTree.getChildAt(i)).removeAllChildren(); - if (filter.get(type) != null) { - for (Amenity n : filter.get(type)) { - int dist = (int) (MapUtils.getDistance(n.getLocation(), newLatitude, newLongitude)); - String str = n.getStringWithoutType(false) + " [" + dist + " m ]"; - DataExtractionTreeNode node = new DataExtractionTreeNode(str, n); - ((DefaultMutableTreeNode) amenitiesTree.getChildAt(i)).add(node); - } - } - ((DefaultTreeModel)treePlaces.getModel()).nodeStructureChanged(amenitiesTree.getChildAt(i)); - } - ((DefaultMutableTreeNode) amenitiesTree.getChildAt(0)).removeAllChildren(); - - for (int i = 0; i < 15 && i < closestAmenities.size(); i++) { - Amenity n = closestAmenities.get(i); - int dist = (int) (MapUtils.getDistance(n.getLocation(), newLatitude, newLongitude)); - String str = n.getSimpleFormat(false) + " [" + dist + " m ]"; - ((DefaultMutableTreeNode) amenitiesTree.getChildAt(0)).add(new DataExtractionTreeNode(str, n)); - ((DefaultTreeModel)treePlaces.getModel()).nodeStructureChanged(amenitiesTree.getChildAt(0)); - } - } - } - - public void updateListCities(Region r, String text, JList jList) { - Collection city; - if (r == null) { - city = Collections.emptyList(); - } else { - city = r.getSuggestedCities(text, 100); - } - City[] names = new City[city.size()]; - int i = 0; - for (City c : city) { - names[i++] = c; - } - jList.setListData(names); - } - - public static class RegionCellEditor extends DefaultTreeCellEditor { - - public RegionCellEditor(JTree tree, DefaultTreeCellRenderer renderer) { - super(tree, renderer); - } - - public RegionCellEditor(JTree tree, DefaultTreeCellRenderer renderer, TreeCellEditor editor) { - super(tree, renderer, editor); - } - - public boolean isCellEditable(EventObject event) { - boolean returnValue = super.isCellEditable(event); - if (returnValue) { - Object node = tree.getLastSelectedPathComponent(); - if (node instanceof DataExtractionTreeNode) { - DataExtractionTreeNode treeNode = (DataExtractionTreeNode) node; - if (treeNode.getModelObject() instanceof Region || treeNode.getModelObject() instanceof MapObject) { - return true; - } - } - } - return returnValue; - } - - } - private class PopupTrigger extends MouseAdapter { - - private final JPopupMenu popupMenu; - - public PopupTrigger(JPopupMenu popupMenu) { - this.popupMenu = popupMenu; - } - public void mouseReleased(MouseEvent e) - { - if (e.isPopupTrigger()) - { - int x = e.getX(); - int y = e.getY(); - TreePath path = treePlaces.getPathForLocation(x, y); - if (path != null) { - if(!treePlaces.getSelectionModel().isPathSelected(path)){ - treePlaces.setSelectionPath(path); - } - popupMenu.show(treePlaces, x, y); - } - } - } - } -*/ - - -} +package net.osmand.swing; + +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.lang.Thread.UncaughtExceptionHandler; +import java.lang.reflect.InvocationTargetException; +import java.sql.SQLException; +import java.text.MessageFormat; + +import javax.swing.AbstractAction; +import javax.swing.JCheckBox; +import javax.swing.JDialog; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.JTree; +import javax.swing.UIManager; +import javax.swing.filechooser.FileFilter; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.xml.stream.XMLStreamException; + +import net.osmand.Version; +import net.osmand.data.preparation.IndexCreator; +import net.osmand.map.IMapLocationListener; +import net.osmand.map.ITileSource; +import net.osmand.osm.MapRenderingTypes; +import net.osmand.osm.io.IOsmStorageFilter; +import net.osmand.osm.io.OsmBaseStorage; +import net.osmand.osm.io.OsmBoundsFilter; +import net.osmand.osm.io.OsmStorageWriter; +import net.osmand.swing.MapPanel.MapSelectionArea; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.tools.bzip2.CBZip2OutputStream; +import org.xml.sax.SAXException; + +import rtree.RTree; + + +public class OsmExtractionUI implements IMapLocationListener { + + private static final Log log = LogFactory.getLog(OsmExtractionUI.class); + public static final String LOG_PATH = getUserLogDirectoryPath() + "/Osmand/osmand.log"; //$NON-NLS-1$ //$NON-NLS-2$ + public static OsmExtractionUI MAIN_APP; + + public static String getUserLogDirectoryPath() { + String path = null; + if (System.getProperty("os.name").startsWith("Windows")) { + path = System.getenv("APPDATA").replaceAll("\\\\", "/"); + } else if (System.getProperty("os.name").startsWith("Mac")) { + path = System.getProperty("user.home") + "/Library/Logs"; + } else if (System.getenv("XDG_CACHE_HOME") != null) { + path = System.getenv("XDG_CACHE_HOME"); + } else { + path = System.getProperty("user.home") + "/.cache"; + } + return path; + } + + public static void main(String[] args) { + // first of all config log + new File(LOG_PATH).getParentFile().mkdirs(); + final UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler(); + Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler(){ + @Override + public void uncaughtException(Thread t, Throwable e) { + if(!(e instanceof ThreadDeath)){ + ExceptionHandler.handle("Error in thread " + t.getName(), e); //$NON-NLS-1$ + } + defaultHandler.uncaughtException(t, e); + } + }); + + MAIN_APP = new OsmExtractionUI(); + MAIN_APP.frame.setBounds(DataExtractionSettings.getSettings().getWindowBounds()); + MAIN_APP.frame.setVisible(true); + } + + + + + private JTree treePlaces; +// private DataExtractionTreeNode amenitiesTree; +// private TreeModelListener treeModelListener; + + + private MapPanel mapPanel; + private JFrame frame; + private JLabel statusBarLabel; + + + private JCheckBox buildPoiIndex; + private JCheckBox buildAddressIndex; + private JCheckBox buildMapIndex; + private JCheckBox buildTransportIndex; + private JCheckBox normalizingStreets; + + private String regionName; + + + + public OsmExtractionUI(){ + createUI(); + } + + + + + + public void createUI(){ + frame = new JFrame(Messages.getString("OsmExtractionUI.OSMAND_MAP_CREATOR")); //$NON-NLS-1$ + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Exception e) { + log.error("Can't set look and feel", e); //$NON-NLS-1$ + } + + + frame.addWindowListener(new ExitListener()); + Container content = frame.getContentPane(); + frame.setFocusable(true); + + mapPanel = new MapPanel(DataExtractionSettings.getSettings().getTilesDirectory()); + mapPanel.setFocusable(true); + mapPanel.addMapLocationListener(this); + + statusBarLabel = new JLabel(); + content.add(statusBarLabel, BorderLayout.SOUTH); + File workingDir = DataExtractionSettings.getSettings().getDefaultWorkingDir(); + statusBarLabel.setText(workingDir == null ? Messages.getString("OsmExtractionUI.WORKING_DIR_UNSPECIFIED") : Messages.getString("OsmExtractionUI.WORKING_DIRECTORY") + workingDir.getAbsolutePath()); //$NON-NLS-1$ //$NON-NLS-2$ + + + treePlaces = new JTree(); + treePlaces.setModel(new DefaultTreeModel(new DefaultMutableTreeNode(Messages.getString("OsmExtractionUI.REGION")), false)); //$NON-NLS-1$ + JSplitPane panelForTreeAndMap = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JScrollPane(treePlaces), mapPanel); + panelForTreeAndMap.setResizeWeight(0.2); + content.add(panelForTreeAndMap, BorderLayout.CENTER); + + createButtonsBar(content); + + JMenuBar bar = new JMenuBar(); + fillMenuWithActions(bar); + + frame.setJMenuBar(bar); + } + + + + + public void createButtonsBar(Container content){ + JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT)); + content.add(panel, BorderLayout.NORTH); + + buildMapIndex = new JCheckBox(); + buildMapIndex.setText(Messages.getString("OsmExtractionUI.BUILD_MAP")); //$NON-NLS-1$ + panel.add(buildMapIndex); + buildMapIndex.setSelected(true); + + buildPoiIndex = new JCheckBox(); + buildPoiIndex.setText(Messages.getString("OsmExtractionUI.BUILD_POI")); //$NON-NLS-1$ + panel.add(buildPoiIndex); + buildPoiIndex.setSelected(true); + + buildAddressIndex = new JCheckBox(); + buildAddressIndex.setText(Messages.getString("OsmExtractionUI.BUILD_ADDRESS")); //$NON-NLS-1$ + panel.add(buildAddressIndex); + buildAddressIndex.setSelected(true); + + normalizingStreets = new JCheckBox(); + normalizingStreets.setText(Messages.getString("OsmExtractionUI.NORMALIZE_STREETS")); //$NON-NLS-1$ + panel.add(normalizingStreets); + normalizingStreets.setSelected(true); + + buildTransportIndex = new JCheckBox(); + buildTransportIndex.setText(Messages.getString("OsmExtractionUI.BUILD_TRANSPORT")); //$NON-NLS-1$ + panel.add(buildTransportIndex); + buildTransportIndex.setSelected(true); + + + + } + + public void fillMenuWithActions(final JMenuBar bar){ + JMenu menu = new JMenu(Messages.getString("OsmExtractionUI.MENU_FILE")); //$NON-NLS-1$ + bar.add(menu); + JMenuItem loadFile = new JMenuItem(Messages.getString("OsmExtractionUI.MENU_SELECT_FILE")); //$NON-NLS-1$ + menu.add(loadFile); + JMenuItem loadSpecifiedAreaFile = new JMenuItem(Messages.getString("OsmExtractionUI.MENU_SELECT_OSM_FILE_AREA")); //$NON-NLS-1$ + menu.add(loadSpecifiedAreaFile); + JMenuItem specifyWorkingDir = new JMenuItem(Messages.getString("OsmExtractionUI.SPECIFY_WORKING_DIR")); //$NON-NLS-1$ + menu.add(specifyWorkingDir); + menu.addSeparator(); + JMenuItem exitMenu= new JMenuItem(Messages.getString("OsmExtractionUI.MENU_EXIT")); //$NON-NLS-1$ + menu.add(exitMenu); + + JMenu tileSource = MapPanel.getMenuToChooseSource(mapPanel); + final JMenuItem sqliteDB = new JMenuItem(Messages.getString("OsmExtractionUI.MENU_CREATE_SQLITE")); //$NON-NLS-1$ + tileSource.addSeparator(); + tileSource.add(sqliteDB); + bar.add(tileSource); + + menu = new JMenu(Messages.getString("OsmExtractionUI.MENU_WINDOW")); //$NON-NLS-1$ + bar.add(menu); + JMenuItem settings = new JMenuItem(Messages.getString("OsmExtractionUI.MENU_SETTINGS")); //$NON-NLS-1$ + menu.add(settings); + menu.addSeparator(); + JMenuItem openLogFile = new JMenuItem(Messages.getString("OsmExtractionUI.MENU_OPEN_LOG")); //$NON-NLS-1$ + menu.add(openLogFile); + + menu = new JMenu(Messages.getString("OsmExtractionUI.MENU_ABOUT")); //$NON-NLS-1$ + bar.add(menu); + JMenuItem aboutApplication = new JMenuItem(Messages.getString("OsmExtractionUI.MENU_ABOUT_2")); //$NON-NLS-1$ + menu.add(aboutApplication); + + + aboutApplication.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JOptionPane.showMessageDialog(frame, Version.APP_MAP_CREATOR_FULL_NAME); + } + }); + + openLogFile.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + File file = new File(OsmExtractionUI.LOG_PATH); + if (file != null && file.exists()) { + if (System.getProperty("os.name").startsWith("Windows")) { //$NON-NLS-1$ //$NON-NLS-2$ + try { + Runtime.getRuntime().exec(new String[] { "notepad.exe", file.getAbsolutePath() }); //$NON-NLS-1$ + } catch (IOException es) { + ExceptionHandler.handle(Messages.getString("OsmExtractionUI.UNABLE_OPEN_FILE"), es); //$NON-NLS-1$ + } + } else { + JOptionPane.showMessageDialog(frame, Messages.getString("OsmExtractionUI.OPEN_LOG_FILE_MANUALLY") + LOG_PATH); //$NON-NLS-1$ + } + + } else { + ExceptionHandler.handle(Messages.getString("OsmExtractionUI.LOG_FILE_NOT_FOUND")); //$NON-NLS-1$ + } + } + }); + + sqliteDB.addActionListener(new ActionListener(){ + @Override + public void actionPerformed(ActionEvent e) { + final String regionName = OsmExtractionUI.this.regionName == null ? Messages.getString("OsmExtractionUI.REGION") : OsmExtractionUI.this.regionName; //$NON-NLS-1$ + final ITileSource map = mapPanel.getMap(); + if(map != null){ + try { + final ProgressDialog dlg = new ProgressDialog(frame, Messages.getString("OsmExtractionUI.CREATING_INDEX")); //$NON-NLS-1$ + dlg.setRunnable(new Runnable(){ + + @Override + public void run() { + try { + SQLiteBigPlanetIndex.createSQLiteDatabase(DataExtractionSettings.getSettings().getTilesDirectory(), regionName, map); + } catch (SQLException e1) { + throw new IllegalArgumentException(e1); + } catch (IOException e1) { + throw new IllegalArgumentException(e1); + } + } + }); + dlg.run(); + } catch (InterruptedException e1) { + log.error("Interrupted", e1); //$NON-NLS-1$ + } catch (InvocationTargetException e1) { + ExceptionHandler.handle("Can't create big planet sqlite index", (Exception) e1.getCause()); //$NON-NLS-1$ + } + + + } + } + }); + + + exitMenu.addActionListener(new ActionListener(){ + @Override + public void actionPerformed(ActionEvent e) { + frame.setVisible(false); + exit(); + } + }); + settings.addActionListener(new ActionListener(){ + @Override + public void actionPerformed(ActionEvent e) { + OsmExtractionPreferencesDialog dlg = new OsmExtractionPreferencesDialog(frame); + dlg.showDialog(); + } + + }); + specifyWorkingDir.addActionListener(new ActionListener(){ + + @Override + public void actionPerformed(ActionEvent e) { + JFileChooser fc = new JFileChooser(); + fc.setDialogTitle(Messages.getString("OsmExtractionUI.CHOOSE_WORKING_DIR")); //$NON-NLS-1$ + fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + File workingDir = DataExtractionSettings.getSettings().getDefaultWorkingDir(); + if(workingDir != null){ + fc.setCurrentDirectory(workingDir); + } + if(fc.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION && fc.getSelectedFile() != null && + fc.getSelectedFile().isDirectory()){ + DataExtractionSettings.getSettings().saveDefaultWorkingDir(fc.getSelectedFile()); + mapPanel.setTilesLocation(DataExtractionSettings.getSettings().getTilesDirectory()); + statusBarLabel.setText(Messages.getString("OsmExtractionUI.WORKING_DIR") + fc.getSelectedFile().getAbsolutePath()); //$NON-NLS-1$ + JMenu tileSource = MapPanel.getMenuToChooseSource(mapPanel); + tileSource.add(sqliteDB); + bar.remove(1); + bar.add(tileSource, 1); + } + } + + }); + loadSpecifiedAreaFile.addActionListener(new ActionListener(){ + @Override + public void actionPerformed(ActionEvent e) { + JFileChooser fc = getOsmFileChooser(); + int answer = fc.showOpenDialog(frame) ; + if (answer == JFileChooser.APPROVE_OPTION && fc.getSelectedFile() != null){ + final JDialog dlg = new JDialog(frame, true); + dlg.setTitle(Messages.getString("OsmExtractionUI.SELECT_AREA_TO_FILTER")); //$NON-NLS-1$ + MapPanel panel = new MapPanel(DataExtractionSettings.getSettings().getTilesDirectory()); + panel.setLatLon(mapPanel.getLatitude(), mapPanel.getLongitude()); + panel.setZoom(mapPanel.getZoom()); + final StringBuilder res = new StringBuilder(); + panel.getLayer(MapInformationLayer.class).setAreaActionHandler(new AbstractAction(Messages.getString("OsmExtractionUI.SELECT_AREA")){ //$NON-NLS-1$ + private static final long serialVersionUID = -3452957517341961969L; + @Override + public void actionPerformed(ActionEvent e) { + res.append(true); + dlg.setVisible(false); + } + + }); + dlg.add(panel); + + + JMenuBar bar = new JMenuBar(); + bar.add(MapPanel.getMenuToChooseSource(panel)); + dlg.setJMenuBar(bar); + dlg.setSize(512, 512); + double x = frame.getBounds().getCenterX(); + double y = frame.getBounds().getCenterY(); + dlg.setLocation((int) x - dlg.getWidth() / 2, (int) y - dlg.getHeight() / 2); + + dlg.setVisible(true); + if(res.length() > 0 && panel.getSelectionArea().isVisible()){ + MapSelectionArea area = panel.getSelectionArea(); + IOsmStorageFilter filter = new OsmBoundsFilter(area.getLat1(), area.getLon1(), area.getLat2(), area.getLon2()); + loadCountry(fc.getSelectedFile(), filter); + } + } + } + + }); + loadFile.addActionListener(new ActionListener(){ + + @Override + public void actionPerformed(ActionEvent e) { + JFileChooser fc = getOsmFileChooser(); + int answer = fc.showOpenDialog(frame) ; + if (answer == JFileChooser.APPROVE_OPTION && fc.getSelectedFile() != null){ + loadCountry(fc.getSelectedFile(), null); + } + } + + }); + + } + + public JFileChooser getOsmFileChooser(){ + JFileChooser fc = new JFileChooser(); + fc.setDialogTitle(Messages.getString("OsmExtractionUI.CHOOSE_OSM_FILE")); //$NON-NLS-1$ + fc.setFileSelectionMode(JFileChooser.FILES_ONLY); + fc.setAcceptAllFileFilterUsed(true); + fc.setCurrentDirectory(DataExtractionSettings.getSettings().getDefaultWorkingDir().getParentFile()); + fc.setFileFilter(new FileFilter(){ + + @Override + public boolean accept(File f) { + return f.isDirectory() || f.getName().endsWith(".bz2") || f.getName().endsWith(".osm") || f.getName().endsWith(".pbf"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + @Override + public String getDescription() { + return Messages.getString("OsmExtractionUI.OSM_FILES"); //$NON-NLS-1$ + } + }); + return fc; + } + + public JFrame getFrame() { + return frame; + } + + public void loadCountry(final File f, final IOsmStorageFilter filter){ + try { + final ProgressDialog dlg = new ProgressDialog(frame, Messages.getString("OsmExtractionUI.LOADING_OSM_FILE")); //$NON-NLS-1$ + dlg.setRunnable(new Runnable(){ + + @Override + public void run() { + File dir = DataExtractionSettings.getSettings().getDefaultWorkingDir(); + IndexCreator creator = new IndexCreator(dir); + try { + creator.setIndexAddress(buildAddressIndex.isSelected()); + creator.setIndexPOI(buildPoiIndex.isSelected()); + creator.setNormalizeStreets(normalizingStreets.isSelected()); + creator.setIndexTransport(buildTransportIndex.isSelected()); + creator.setIndexMap(buildMapIndex.isSelected()); + String fn = DataExtractionSettings.getSettings().getMapRenderingTypesFile(); + MapRenderingTypes types; + if(fn == null || fn.length() == 0){ + types = MapRenderingTypes.getDefault(); + } else { + types = new MapRenderingTypes(fn); + } + RTree.clearCache(); + creator.generateIndexes(f, dlg, filter, DataExtractionSettings.getSettings().getMapZooms(), types); + } catch (IOException e) { + throw new IllegalArgumentException(e); + } catch (SAXException e) { + throw new IllegalStateException(e); + } catch (SQLException e) { + throw new IllegalStateException(e); + } + regionName = creator.getRegionName(); + StringBuilder msg = new StringBuilder(); + msg.append(Messages.getString("OsmExtractionUI.INDEXES_FOR")).append(regionName).append(" : "); //$NON-NLS-1$ //$NON-NLS-2$ + boolean comma = false; + if (buildMapIndex.isSelected()) { + if(comma) msg.append(", "); //$NON-NLS-1$ + comma = true; + msg.append(Messages.getString("OsmExtractionUI.MAP")); //$NON-NLS-1$ + } + if (buildPoiIndex.isSelected()) { + if(comma) msg.append(", "); //$NON-NLS-1$ + comma = true; + msg.append(Messages.getString("OsmExtractionUI.POI")); //$NON-NLS-1$ + } + if (buildAddressIndex.isSelected()) { + if(comma) msg.append(", "); //$NON-NLS-1$ + comma = true; + msg.append(Messages.getString("OsmExtractionUI.ADDRESS")); //$NON-NLS-1$ + } + if (buildTransportIndex.isSelected()) { + if(comma) msg.append(", "); //$NON-NLS-1$ + comma = true; + msg.append(Messages.getString("OsmExtractionUI.TRANSPORT")); //$NON-NLS-1$ + } + msg.append(MessageFormat.format(Messages.getString("OsmExtractionUI.WERE_SUCCESFULLY_CREATED"), dir.getAbsolutePath())); //$NON-NLS-1$ + JOptionPane pane = new JOptionPane(msg); + JDialog dialog = pane.createDialog(frame, Messages.getString("OsmExtractionUI.GENERATION_DATA")); //$NON-NLS-1$ + dialog.setVisible(true); + } + }); + + dlg.run(); + frame.setTitle(Messages.getString("OsmExtractionUI.OSMAND_MAP_CREATOR_FILE") + f.getName()); //$NON-NLS-1$ + } catch (InterruptedException e1) { + log.error("Interrupted", e1); //$NON-NLS-1$ + } catch (InvocationTargetException e1) { + ExceptionHandler.handle("Exception during operation", e1.getCause()); //$NON-NLS-1$ + } + } + + public void saveCountry(final File f, final OsmBaseStorage storage){ + final OsmStorageWriter writer = new OsmStorageWriter(); + try { + final ProgressDialog dlg = new ProgressDialog(frame, Messages.getString("OsmExtractionUI.SAVING_OSM_FILE")); //$NON-NLS-1$ + dlg.setRunnable(new Runnable() { + @Override + public void run() { + try { + OutputStream output = new FileOutputStream(f); + try { + if (f.getName().endsWith(".bz2")) { //$NON-NLS-1$ + output.write('B'); + output.write('Z'); + output = new CBZip2OutputStream(output); + } + writer.saveStorage(output, storage, null, false); + } finally { + output.close(); + } + } catch (IOException e) { + throw new IllegalArgumentException(e); + } catch (XMLStreamException e) { + throw new IllegalArgumentException(e); + } + } + }); + dlg.run(); + } catch (InterruptedException e1) { + log.error("Interrupted", e1); //$NON-NLS-1$ + } catch (InvocationTargetException e1) { + ExceptionHandler.handle("Log file is not found", e1.getCause()); //$NON-NLS-1$ + } + } + + @Override + public void locationChanged(final double newLatitude, final double newLongitude, Object source){ +// recalculateAmenities(newLatitude, newLongitude); + } + + + + + public class ExitListener extends WindowAdapter { + public void windowClosing(WindowEvent event) { + exit(); + } + } + + public void exit(){ + // save preferences + DataExtractionSettings settings = DataExtractionSettings.getSettings(); + settings.saveDefaultLocation(mapPanel.getLatitude(), mapPanel.getLongitude()); + settings.saveDefaultZoom(mapPanel.getZoom()); + settings.saveWindowBounds(frame.getBounds()); + System.exit(0); + } + + + + + + // OLD CODE +/* + + public JTree createTree(Container content) { + treePlaces.setEditable(true); + treePlaces.setCellEditor(new RegionCellEditor(treePlaces, (DefaultTreeCellRenderer) treePlaces.getCellRenderer())); + treePlaces.addTreeSelectionListener(new TreeSelectionListener() { + @Override + public void valueChanged(TreeSelectionEvent e) { + if (e.getPath() != null) { + if (e.getPath().getLastPathComponent() instanceof DataExtractionTreeNode) { + Object o = ((DataExtractionTreeNode) e.getPath().getLastPathComponent()).getModelObject(); + + if (o instanceof MapObject) { + MapObject c = (MapObject) o; + LatLon location = c.getLocation(); + if (location != null) { + if (o instanceof Street) { + DataTileManager ways = new DataTileManager(); + for (Way w : ((Street) o).getWayNodes()) { + LatLon l = w.getLatLon(); + ways.registerObject(l.getLatitude(), l.getLongitude(), w); + } + mapPanel.setPoints(ways); + mapPanel.requestFocus(); + } + mapPanel.setLatLon(location.getLatitude(), location.getLongitude()); + mapPanel.requestFocus(); + } + if (o instanceof TransportRoute) { + DataTileManager ways = new DataTileManager(); + for (Way w : ((TransportRoute) o).getWays()) { + LatLon l = w.getLatLon(); + ways.registerObject(l.getLatitude(), l.getLongitude(), w); + } + for (TransportStop w : ((TransportRoute) o).getBackwardStops()) { + LatLon l = w.getLocation(); + ways.registerObject(l.getLatitude(), l.getLongitude(), new Node(l.getLatitude(), l.getLongitude(), w + .getId())); + } + for (TransportStop w : ((TransportRoute) o).getForwardStops()) { + LatLon l = w.getLocation(); + ways.registerObject(l.getLatitude(), l.getLongitude(), new Node(l.getLatitude(), l.getLongitude(), w + .getId())); + } + mapPanel.setPoints(ways); + mapPanel.requestFocus(); + } + + } else if (o instanceof Entity) { + Entity c = (Entity) o; + LatLon latLon = c.getLatLon(); + if (latLon != null) { + mapPanel.setLatLon(latLon.getLatitude(), latLon.getLongitude()); + mapPanel.requestFocus(); + } + } + } + } + + } + }); + + treeModelListener = new TreeModelListener() { + public void treeNodesChanged(TreeModelEvent e) { + Object node = e.getTreePath().getLastPathComponent(); + if (e.getChildren() != null && e.getChildren().length > 0) { + node = e.getChildren()[0]; + } + if (node instanceof DataExtractionTreeNode) { + DataExtractionTreeNode n = ((DataExtractionTreeNode) node); + if (n.getModelObject() instanceof MapObject) { + MapObject r = (MapObject) n.getModelObject(); + String newName = n.getUserObject().toString(); + if (!r.getName().equals(newName)) { + r.setName(n.getUserObject().toString()); + } + if (r instanceof Street && !((Street) r).isRegisteredInCity()) { + DefaultMutableTreeNode parent = ((DefaultMutableTreeNode) n.getParent()); + parent.remove(n); + ((DefaultTreeModel) treePlaces.getModel()).nodeStructureChanged(parent); + } + } + } + } + + public void treeNodesInserted(TreeModelEvent e) { + } + + public void treeNodesRemoved(TreeModelEvent e) { + } + + public void treeStructureChanged(TreeModelEvent e) { + } + }; + treePlaces.getModel().addTreeModelListener(treeModelListener); + return treePlaces; + } + + public void fillPopupMenuWithActions(JPopupMenu menu) { + Action delete = new AbstractAction("Delete") { + private static final long serialVersionUID = 7476603434847164396L; + + public void actionPerformed(ActionEvent e) { + TreePath[] p = treePlaces.getSelectionPaths(); + if(p != null && + JOptionPane.OK_OPTION == + JOptionPane.showConfirmDialog(frame, "Are you sure about deleting " +p.length + " resources ? ")){ + for(TreePath path : treePlaces.getSelectionPaths()){ + Object node = path.getLastPathComponent(); + if (node instanceof DataExtractionTreeNode) { + DataExtractionTreeNode n = ((DataExtractionTreeNode) node); + if(n.getParent() instanceof DataExtractionTreeNode){ + DataExtractionTreeNode parent = ((DataExtractionTreeNode) n.getParent()); + boolean remove = false; + if (n.getModelObject() instanceof Street) { + ((City)parent.getModelObject()).unregisterStreet(((Street)n.getModelObject()).getName()); + remove = true; + } else if (n.getModelObject() instanceof Building) { + ((Street)parent.getModelObject()).getBuildings().remove(n.getModelObject()); + remove = true; + } else if (n.getModelObject() instanceof City) { + Region r = (Region) ((DataExtractionTreeNode)parent.getParent()).getModelObject(); + r.unregisterCity((City) n.getModelObject()); + remove = true; + } else if (n.getModelObject() instanceof Amenity) { + Region r = (Region) ((DataExtractionTreeNode)parent.getParent().getParent()).getModelObject(); + Amenity am = (Amenity) n.getModelObject(); + r.getAmenityManager().unregisterObject(am.getLocation().getLatitude(), am.getLocation().getLongitude(), am); + remove = true; + } + if(remove){ + parent.remove(n); + ((DefaultTreeModel) treePlaces.getModel()).nodeStructureChanged(parent); + } + } + } + } + + } + } + }; + menu.add(delete); + Action rename= new AbstractAction("Rename") { + private static final long serialVersionUID = -8257594433235073767L; + + public void actionPerformed(ActionEvent e) { + TreePath path = treePlaces.getSelectionPath(); + if(path != null){ + treePlaces.startEditingAtPath(path); + } + } + }; + menu.add(rename); + } + + + public void setRegion(Region region, String name){ + if (this.region == region) { + return; + } + this.region = region; + DefaultMutableTreeNode root = new DataExtractionTreeNode(name, region); + if (region != null) { + amenitiesTree = new DataExtractionTreeNode("Amenities", region); + amenitiesTree.add(new DataExtractionTreeNode("First 15", region)); + for (AmenityType type : AmenityType.values()) { + amenitiesTree.add(new DataExtractionTreeNode(Algoritms.capitalizeFirstLetterAndLowercase(type.toString()), type)); + } + root.add(amenitiesTree); + + DataExtractionTreeNode transport = new DataExtractionTreeNode("Transport", region); + root.add(transport); + for(String s : region.getTransportRoutes().keySet()){ + DataExtractionTreeNode trRoute = new DataExtractionTreeNode(s, s); + transport.add(trRoute); + List list = region.getTransportRoutes().get(s); + for(TransportRoute r : list){ + DataExtractionTreeNode route = new DataExtractionTreeNode(r.getRef(), r); + trRoute.add(route); + } + + } + + for (CityType t : CityType.values()) { + DefaultMutableTreeNode cityTree = new DataExtractionTreeNode(Algoritms.capitalizeFirstLetterAndLowercase(t.toString()), t); + root.add(cityTree); + for (City ct : region.getCitiesByType(t)) { + DefaultMutableTreeNode cityNodeTree = new DataExtractionTreeNode(ct.getName(), ct); + cityTree.add(cityNodeTree); + + for (Street str : ct.getStreets()) { + DefaultMutableTreeNode strTree = new DataExtractionTreeNode(str.getName(), str); + cityNodeTree.add(strTree); + for (Building b : str.getBuildings()) { + DefaultMutableTreeNode building = new DataExtractionTreeNode(b.getName(), b); + strTree.add(building); + } + } + } + } + } + + if (searchList != null) { + updateListCities(region, searchTextField.getText(), searchList); + } + mapPanel.repaint(); + DefaultTreeModel newModel = new DefaultTreeModel(root, false); + newModel.addTreeModelListener(treeModelListener); + treePlaces.setModel(newModel); + + updateButtonsBar(); + locationChanged(mapPanel.getLatitude(), mapPanel.getLongitude(), this); + } + + public static class DataExtractionTreeNode extends DefaultMutableTreeNode { + private static final long serialVersionUID = 1L; + private final Object modelObject; + + public DataExtractionTreeNode(String name, Object modelObject){ + super(name); + this.modelObject = modelObject; + } + + public Object getModelObject(){ + return modelObject; + } + + } + + private void recalculateAmenities(final double newLatitude, final double newLongitude) { + if (amenitiesTree != null) { + Region reg = (Region) amenitiesTree.getModelObject(); + List closestAmenities = reg.getAmenityManager().getClosestObjects(newLatitude, newLongitude, 0, 5); + MapUtils.sortListOfMapObject(closestAmenities, newLatitude, newLongitude); + + + Map> filter = new HashMap>(); + for (Amenity n : closestAmenities) { + AmenityType type = n.getType(); + if (!filter.containsKey(type)) { + filter.put(type, new ArrayList()); + } + filter.get(type).add(n); + } + + + for (int i = 1; i < amenitiesTree.getChildCount(); i++) { + AmenityType type = (AmenityType) ((DataExtractionTreeNode) amenitiesTree.getChildAt(i)).getModelObject(); + ((DefaultMutableTreeNode) amenitiesTree.getChildAt(i)).removeAllChildren(); + if (filter.get(type) != null) { + for (Amenity n : filter.get(type)) { + int dist = (int) (MapUtils.getDistance(n.getLocation(), newLatitude, newLongitude)); + String str = n.getStringWithoutType(false) + " [" + dist + " m ]"; + DataExtractionTreeNode node = new DataExtractionTreeNode(str, n); + ((DefaultMutableTreeNode) amenitiesTree.getChildAt(i)).add(node); + } + } + ((DefaultTreeModel)treePlaces.getModel()).nodeStructureChanged(amenitiesTree.getChildAt(i)); + } + ((DefaultMutableTreeNode) amenitiesTree.getChildAt(0)).removeAllChildren(); + + for (int i = 0; i < 15 && i < closestAmenities.size(); i++) { + Amenity n = closestAmenities.get(i); + int dist = (int) (MapUtils.getDistance(n.getLocation(), newLatitude, newLongitude)); + String str = n.getSimpleFormat(false) + " [" + dist + " m ]"; + ((DefaultMutableTreeNode) amenitiesTree.getChildAt(0)).add(new DataExtractionTreeNode(str, n)); + ((DefaultTreeModel)treePlaces.getModel()).nodeStructureChanged(amenitiesTree.getChildAt(0)); + } + } + } + + public void updateListCities(Region r, String text, JList jList) { + Collection city; + if (r == null) { + city = Collections.emptyList(); + } else { + city = r.getSuggestedCities(text, 100); + } + City[] names = new City[city.size()]; + int i = 0; + for (City c : city) { + names[i++] = c; + } + jList.setListData(names); + } + + public static class RegionCellEditor extends DefaultTreeCellEditor { + + public RegionCellEditor(JTree tree, DefaultTreeCellRenderer renderer) { + super(tree, renderer); + } + + public RegionCellEditor(JTree tree, DefaultTreeCellRenderer renderer, TreeCellEditor editor) { + super(tree, renderer, editor); + } + + public boolean isCellEditable(EventObject event) { + boolean returnValue = super.isCellEditable(event); + if (returnValue) { + Object node = tree.getLastSelectedPathComponent(); + if (node instanceof DataExtractionTreeNode) { + DataExtractionTreeNode treeNode = (DataExtractionTreeNode) node; + if (treeNode.getModelObject() instanceof Region || treeNode.getModelObject() instanceof MapObject) { + return true; + } + } + } + return returnValue; + } + + } + private class PopupTrigger extends MouseAdapter { + + private final JPopupMenu popupMenu; + + public PopupTrigger(JPopupMenu popupMenu) { + this.popupMenu = popupMenu; + } + public void mouseReleased(MouseEvent e) + { + if (e.isPopupTrigger()) + { + int x = e.getX(); + int y = e.getY(); + TreePath path = treePlaces.getPathForLocation(x, y); + if (path != null) { + if(!treePlaces.getSelectionModel().isPathSelected(path)){ + treePlaces.setSelectionPath(path); + } + popupMenu.show(treePlaces, x, y); + } + } + } + } +*/ + +} \ No newline at end of file diff --git a/DataExtractionOSM/src/net/osmand/swing/TileBundleDownloadDialog.java b/DataExtractionOSM/src/net/osmand/swing/TileBundleDownloadDialog.java index e2f9b51b1b..762f8e6342 100644 --- a/DataExtractionOSM/src/net/osmand/swing/TileBundleDownloadDialog.java +++ b/DataExtractionOSM/src/net/osmand/swing/TileBundleDownloadDialog.java @@ -24,10 +24,9 @@ import javax.swing.SpinnerNumberModel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; -import net.osmand.ExceptionHandler; -import net.osmand.data.preparation.MapTileDownloader; -import net.osmand.data.preparation.MapTileDownloader.DownloadRequest; -import net.osmand.data.preparation.MapTileDownloader.IMapDownloaderCallback; +import net.osmand.data.MapTileDownloader; +import net.osmand.data.MapTileDownloader.DownloadRequest; +import net.osmand.data.MapTileDownloader.IMapDownloaderCallback; import net.osmand.map.ITileSource; import net.osmand.osm.MapUtils; import net.osmand.swing.MapPanel.MapSelectionArea; diff --git a/OsmAnd/.classpath b/OsmAnd/.classpath index 79924d7430..ad4b0086fd 100644 --- a/OsmAnd/.classpath +++ b/OsmAnd/.classpath @@ -1,7 +1,7 @@ - + diff --git a/OsmAnd/.gitignore b/OsmAnd/.gitignore index ece13020a6..0663f62a55 100644 --- a/OsmAnd/.gitignore +++ b/OsmAnd/.gitignore @@ -2,3 +2,4 @@ bin/ gen/ assets/ local.properties +raw/ diff --git a/OsmAnd/build.xml b/OsmAnd/build.xml index da352314cc..7b3b6cab4e 100644 --- a/OsmAnd/build.xml +++ b/OsmAnd/build.xml @@ -129,16 +129,14 @@ - - - - - + + + diff --git a/OsmAnd/src/net/osmand/GPXUtilities.java b/OsmAnd/src/net/osmand/GPXUtilities.java index c728735aa0..3b3866199d 100644 --- a/OsmAnd/src/net/osmand/GPXUtilities.java +++ b/OsmAnd/src/net/osmand/GPXUtilities.java @@ -1,215 +1,216 @@ -package net.osmand; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.text.NumberFormat; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Locale; -import java.util.TimeZone; - -import net.osmand.plus.R; - -import org.apache.commons.logging.Log; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlSerializer; - -import android.content.Context; -import android.location.Location; -import android.util.Xml; - -public class GPXUtilities { - public final static Log log = LogUtil.getLog(GPXUtilities.class); - - - private final static String GPX_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'"; //$NON-NLS-1$ - - private final static NumberFormat latLonFormat = new DecimalFormat("0.00#####", new DecimalFormatSymbols(Locale.US)); - - public static class TrkPt { - public double lat; - public double lon; - public double ele; - public double speed; - public long time; - } - - public static class WptPt { - public double lat; - public double lon; - public String name; - // by default - public long time = 0; - } - - public static class TrkSegment { - public List points = new ArrayList(); - } - - public static class Track { - public List segments = new ArrayList(); - } - - public static class GPXFile { - public List tracks = new ArrayList(); - public List points = new ArrayList(); - } - - - public static String writeGpxFile(File fout, GPXFile file, Context ctx) { - try { - SimpleDateFormat format = new SimpleDateFormat(GPX_TIME_FORMAT); - format.setTimeZone(TimeZone.getTimeZone("UTC")); - FileOutputStream output = new FileOutputStream(fout); - XmlSerializer serializer = Xml.newSerializer(); - serializer.setOutput(output, "UTF-8"); //$NON-NLS-1$ - serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); //$NON-NLS-1$ - serializer.startDocument("UTF-8", true); //$NON-NLS-1$ - serializer.startTag(null, "gpx"); //$NON-NLS-1$ - serializer.attribute(null, "version", "1.1"); //$NON-NLS-1$ //$NON-NLS-2$ - serializer.attribute(null, "creator", Version.APP_NAME_VERSION); //$NON-NLS-1$ - serializer.attribute(null, "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); - serializer.attribute(null, "xsi:schemaLocation", "http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"); - - - for (Track track : file.tracks) { - serializer.startTag(null, "trk"); //$NON-NLS-1$ - for (TrkSegment segment : track.segments) { - serializer.startTag(null, "trkseg"); //$NON-NLS-1$ - for (TrkPt p : segment.points) { - serializer.startTag(null, "trkpt"); //$NON-NLS-1$ - serializer.attribute(null, "lat", latLonFormat.format(p.lat)); //$NON-NLS-1$ //$NON-NLS-2$ - serializer.attribute(null, "lon", latLonFormat.format(p.lon)); //$NON-NLS-1$ //$NON-NLS-2$ - serializer.startTag(null, "ele"); //$NON-NLS-1$ - serializer.text(p.ele + ""); //$NON-NLS-1$ - serializer.endTag(null, "ele"); //$NON-NLS-1$ - serializer.startTag(null, "time"); //$NON-NLS-1$ - serializer.text(format.format(new Date(p.time))); - serializer.endTag(null, "time"); //$NON-NLS-1$ - if (p.speed > 0) { - serializer.startTag(null, "extensions"); - serializer.startTag(null, "speed"); //$NON-NLS-1$ - serializer.text(p.speed + ""); //$NON-NLS-1$ - serializer.endTag(null, "speed"); //$NON-NLS-1$ - serializer.endTag(null, "extensions"); - } - - serializer.endTag(null, "trkpt"); //$NON-NLS-1$ - } - serializer.endTag(null, "trkseg"); //$NON-NLS-1$ - } - serializer.endTag(null, "trk"); //$NON-NLS-1$ - } - - for (WptPt l : file.points) { - serializer.startTag(null, "wpt"); //$NON-NLS-1$ - serializer.attribute(null, "lat", latLonFormat.format(l.lat)); //$NON-NLS-1$ - serializer.attribute(null, "lon", latLonFormat.format(l.lon)); //$NON-NLS-1$ //$NON-NLS-2$ - if (l.time != 0) { - serializer.startTag(null, "time"); //$NON-NLS-1$ - serializer.text(format.format(new Date(l.time))); - serializer.endTag(null, "time"); //$NON-NLS-1$ - } - serializer.startTag(null, "name"); //$NON-NLS-1$ - serializer.text(l.name); - serializer.endTag(null, "name"); //$NON-NLS-1$ - serializer.endTag(null, "wpt"); //$NON-NLS-1$ - } - - serializer.endTag(null, "gpx"); //$NON-NLS-1$ - serializer.flush(); - serializer.endDocument(); - } catch (RuntimeException e) { - log.error("Error saving gpx", e); //$NON-NLS-1$ - return ctx.getString(R.string.error_occurred_saving_gpx); - } catch (IOException e) { - log.error("Error saving gpx", e); //$NON-NLS-1$ - return ctx.getString(R.string.error_occurred_saving_gpx); - } - return null; - } - - - public static class GPXFileResult { - public ArrayList> locations = new ArrayList>(); - public ArrayList wayPoints = new ArrayList(); - // special case for cloudmate gpx : they discourage common schema - // by using waypoint as track points and rtept are not very close to real way - // such as wpt. However they provide additional information into gpx. - public boolean cloudMadeFile; - public String error; - } - - public static GPXFileResult loadGPXFile(Context ctx, File f){ - GPXFileResult res = new GPXFileResult(); - try { - boolean cloudMade = false; - XmlPullParser parser = Xml.newPullParser(); - parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$ - - int tok; - Location current = null; - String currentName = ""; //$NON-NLS-1$ - while ((tok = parser.next()) != XmlPullParser.END_DOCUMENT) { - if (tok == XmlPullParser.START_TAG) { - if (parser.getName().equals("copyright")) { //$NON-NLS-1$ - cloudMade |= "cloudmade".equalsIgnoreCase(parser.getAttributeValue("", "author")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - - } else if (parser.getName().equals("trkseg")) { //$NON-NLS-1$ - res.locations.add(new ArrayList()); - } else if (parser.getName().equals("wpt") || parser.getName().equals("trkpt") || //$NON-NLS-1$//$NON-NLS-2$ - (!cloudMade && parser.getName().equals("rtept"))) { //$NON-NLS-1$ - // currently not distinguish different point represents all as a line - try { - currentName = ""; //$NON-NLS-1$ - current = new Location("gpx_file"); //$NON-NLS-1$ - current.setLatitude(Double.parseDouble(parser.getAttributeValue("", "lat"))); //$NON-NLS-1$ //$NON-NLS-2$ - current.setLongitude(Double.parseDouble(parser.getAttributeValue("", "lon"))); //$NON-NLS-1$ //$NON-NLS-2$ - } catch (NumberFormatException e) { - current = null; - - } - } else if (current != null && parser.getName().equals("name")) { //$NON-NLS-1$ - if (parser.next() == XmlPullParser.TEXT) { - currentName = parser.getText(); - } - } - } else if (tok == XmlPullParser.END_TAG) { - if (parser.getName().equals("wpt") || //$NON-NLS-1$ - parser.getName().equals("trkpt") || (!cloudMade && parser.getName().equals("rtept"))) { //$NON-NLS-1$ //$NON-NLS-2$ - if (current != null) { - if (parser.getName().equals("wpt") && !cloudMade) { //$NON-NLS-1$ - WptPt pt = new WptPt(); - pt.lat = current.getLatitude(); - pt.lon = current.getLongitude(); - pt.name = currentName; - res.wayPoints.add(pt); - } else { - if (res.locations.isEmpty()) { - res.locations.add(new ArrayList()); - } - res.locations.get(res.locations.size() - 1).add(current); - } - } - } - } - } - } catch (XmlPullParserException e) { - log.error("Error reading gpx", e); //$NON-NLS-1$ - res.error = ctx.getString(R.string.error_reading_gpx); - } catch (IOException e) { - log.error("Error reading gpx", e); //$NON-NLS-1$ - res.error = ctx.getString(R.string.error_reading_gpx); - } - - return res; - } - -} +package net.osmand; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.text.NumberFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.TimeZone; + +import net.osmand.plus.R; + +import org.apache.commons.logging.Log; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlSerializer; + +import android.content.Context; +import android.location.Location; +import android.util.Xml; + +public class GPXUtilities { + public final static Log log = LogUtil.getLog(GPXUtilities.class); + + + private final static String GPX_TIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'"; //$NON-NLS-1$ + + private final static NumberFormat latLonFormat = new DecimalFormat("0.00#####", new DecimalFormatSymbols(Locale.US)); + + public static class TrkPt { + public double lat; + public double lon; + public double ele; + public double speed; + public long time; + } + + public static class WptPt { + public double lat; + public double lon; + public String name; + // by default + public long time = 0; + } + + public static class TrkSegment { + public List points = new ArrayList(); + } + + public static class Track { + public List segments = new ArrayList(); + } + + public static class GPXFile { + public List tracks = new ArrayList(); + public List points = new ArrayList(); + } + + + public static String writeGpxFile(File fout, GPXFile file, Context ctx) { + try { + SimpleDateFormat format = new SimpleDateFormat(GPX_TIME_FORMAT); + format.setTimeZone(TimeZone.getTimeZone("UTC")); + FileOutputStream output = new FileOutputStream(fout); + XmlSerializer serializer = Xml.newSerializer(); + serializer.setOutput(output, "UTF-8"); //$NON-NLS-1$ + serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); //$NON-NLS-1$ + serializer.startDocument("UTF-8", true); //$NON-NLS-1$ + serializer.startTag(null, "gpx"); //$NON-NLS-1$ + serializer.attribute(null, "version", "1.1"); //$NON-NLS-1$ //$NON-NLS-2$ + serializer.attribute(null, "creator", Version.APP_NAME_VERSION); //$NON-NLS-1$ + serializer.attribute(null, "xmlns", "http://www.topografix.com/GPX/1/1"); //$NON-NLS-1$ //$NON-NLS-2$ + serializer.attribute(null, "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); + serializer.attribute(null, "xsi:schemaLocation", "http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd"); + + + for (Track track : file.tracks) { + serializer.startTag(null, "trk"); //$NON-NLS-1$ + for (TrkSegment segment : track.segments) { + serializer.startTag(null, "trkseg"); //$NON-NLS-1$ + for (TrkPt p : segment.points) { + serializer.startTag(null, "trkpt"); //$NON-NLS-1$ + serializer.attribute(null, "lat", latLonFormat.format(p.lat)); //$NON-NLS-1$ //$NON-NLS-2$ + serializer.attribute(null, "lon", latLonFormat.format(p.lon)); //$NON-NLS-1$ //$NON-NLS-2$ + serializer.startTag(null, "ele"); //$NON-NLS-1$ + serializer.text(p.ele + ""); //$NON-NLS-1$ + serializer.endTag(null, "ele"); //$NON-NLS-1$ + serializer.startTag(null, "time"); //$NON-NLS-1$ + serializer.text(format.format(new Date(p.time))); + serializer.endTag(null, "time"); //$NON-NLS-1$ + if (p.speed > 0) { + serializer.startTag(null, "extensions"); + serializer.startTag(null, "speed"); //$NON-NLS-1$ + serializer.text(p.speed + ""); //$NON-NLS-1$ + serializer.endTag(null, "speed"); //$NON-NLS-1$ + serializer.endTag(null, "extensions"); + } + + serializer.endTag(null, "trkpt"); //$NON-NLS-1$ + } + serializer.endTag(null, "trkseg"); //$NON-NLS-1$ + } + serializer.endTag(null, "trk"); //$NON-NLS-1$ + } + + for (WptPt l : file.points) { + serializer.startTag(null, "wpt"); //$NON-NLS-1$ + serializer.attribute(null, "lat", latLonFormat.format(l.lat)); //$NON-NLS-1$ + serializer.attribute(null, "lon", latLonFormat.format(l.lon)); //$NON-NLS-1$ //$NON-NLS-2$ + if (l.time != 0) { + serializer.startTag(null, "time"); //$NON-NLS-1$ + serializer.text(format.format(new Date(l.time))); + serializer.endTag(null, "time"); //$NON-NLS-1$ + } + serializer.startTag(null, "name"); //$NON-NLS-1$ + serializer.text(l.name); + serializer.endTag(null, "name"); //$NON-NLS-1$ + serializer.endTag(null, "wpt"); //$NON-NLS-1$ + } + + serializer.endTag(null, "gpx"); //$NON-NLS-1$ + serializer.flush(); + serializer.endDocument(); + } catch (RuntimeException e) { + log.error("Error saving gpx", e); //$NON-NLS-1$ + return ctx.getString(R.string.error_occurred_saving_gpx); + } catch (IOException e) { + log.error("Error saving gpx", e); //$NON-NLS-1$ + return ctx.getString(R.string.error_occurred_saving_gpx); + } + return null; + } + + + public static class GPXFileResult { + public ArrayList> locations = new ArrayList>(); + public ArrayList wayPoints = new ArrayList(); + // special case for cloudmate gpx : they discourage common schema + // by using waypoint as track points and rtept are not very close to real way + // such as wpt. However they provide additional information into gpx. + public boolean cloudMadeFile; + public String error; + } + + public static GPXFileResult loadGPXFile(Context ctx, File f){ + GPXFileResult res = new GPXFileResult(); + try { + boolean cloudMade = false; + XmlPullParser parser = Xml.newPullParser(); + parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$ + + int tok; + Location current = null; + String currentName = ""; //$NON-NLS-1$ + while ((tok = parser.next()) != XmlPullParser.END_DOCUMENT) { + if (tok == XmlPullParser.START_TAG) { + if (parser.getName().equals("copyright")) { //$NON-NLS-1$ + cloudMade |= "cloudmade".equalsIgnoreCase(parser.getAttributeValue("", "author")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + + } else if (parser.getName().equals("trkseg")) { //$NON-NLS-1$ + res.locations.add(new ArrayList()); + } else if (parser.getName().equals("wpt") || parser.getName().equals("trkpt") || //$NON-NLS-1$//$NON-NLS-2$ + (!cloudMade && parser.getName().equals("rtept"))) { //$NON-NLS-1$ + // currently not distinguish different point represents all as a line + try { + currentName = ""; //$NON-NLS-1$ + current = new Location("gpx_file"); //$NON-NLS-1$ + current.setLatitude(Double.parseDouble(parser.getAttributeValue("", "lat"))); //$NON-NLS-1$ //$NON-NLS-2$ + current.setLongitude(Double.parseDouble(parser.getAttributeValue("", "lon"))); //$NON-NLS-1$ //$NON-NLS-2$ + } catch (NumberFormatException e) { + current = null; + + } + } else if (current != null && parser.getName().equals("name")) { //$NON-NLS-1$ + if (parser.next() == XmlPullParser.TEXT) { + currentName = parser.getText(); + } + } + } else if (tok == XmlPullParser.END_TAG) { + if (parser.getName().equals("wpt") || //$NON-NLS-1$ + parser.getName().equals("trkpt") || (!cloudMade && parser.getName().equals("rtept"))) { //$NON-NLS-1$ //$NON-NLS-2$ + if (current != null) { + if (parser.getName().equals("wpt") && !cloudMade) { //$NON-NLS-1$ + WptPt pt = new WptPt(); + pt.lat = current.getLatitude(); + pt.lon = current.getLongitude(); + pt.name = currentName; + res.wayPoints.add(pt); + } else { + if (res.locations.isEmpty()) { + res.locations.add(new ArrayList()); + } + res.locations.get(res.locations.size() - 1).add(current); + } + } + } + } + } + } catch (XmlPullParserException e) { + log.error("Error reading gpx", e); //$NON-NLS-1$ + res.error = ctx.getString(R.string.error_reading_gpx); + } catch (IOException e) { + log.error("Error reading gpx", e); //$NON-NLS-1$ + res.error = ctx.getString(R.string.error_reading_gpx); + } + + return res; + } + +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/OsmAndFormatter.java b/OsmAnd/src/net/osmand/OsmAndFormatter.java index 07c90f39fa..4e091b9af5 100644 --- a/OsmAnd/src/net/osmand/OsmAndFormatter.java +++ b/OsmAnd/src/net/osmand/OsmAndFormatter.java @@ -7,7 +7,6 @@ import net.osmand.data.AmenityType; import net.osmand.plus.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.OsmandSettings.MetricsConstants; - import android.content.Context; public class OsmAndFormatter { diff --git a/OsmAnd/src/net/osmand/plus/AmenityIndexRepositoryOdb.java b/OsmAnd/src/net/osmand/plus/AmenityIndexRepositoryOdb.java index c908205673..6acc1b20d5 100644 --- a/OsmAnd/src/net/osmand/plus/AmenityIndexRepositoryOdb.java +++ b/OsmAnd/src/net/osmand/plus/AmenityIndexRepositoryOdb.java @@ -16,7 +16,7 @@ import net.osmand.IProgress; import net.osmand.LogUtil; import net.osmand.data.Amenity; import net.osmand.data.AmenityType; -import net.osmand.data.index.IndexConstants; +import net.osmand.data.IndexConstants; import net.osmand.osm.Entity; import net.osmand.osm.LatLon; import net.osmand.osm.MapUtils; diff --git a/OsmAnd/src/net/osmand/plus/DownloadOsmandIndexesHelper.java b/OsmAnd/src/net/osmand/plus/DownloadOsmandIndexesHelper.java index c9f0bd023a..08ed791cdb 100644 --- a/OsmAnd/src/net/osmand/plus/DownloadOsmandIndexesHelper.java +++ b/OsmAnd/src/net/osmand/plus/DownloadOsmandIndexesHelper.java @@ -7,7 +7,7 @@ import java.util.Map; import java.util.TreeMap; import net.osmand.LogUtil; -import net.osmand.data.index.IndexConstants; +import net.osmand.data.IndexConstants; import org.apache.commons.logging.Log; import org.xmlpull.v1.XmlPullParser; diff --git a/OsmAnd/src/net/osmand/plus/PoiFilter.java b/OsmAnd/src/net/osmand/plus/PoiFilter.java index 0b9607d84b..6958ceaa04 100644 --- a/OsmAnd/src/net/osmand/plus/PoiFilter.java +++ b/OsmAnd/src/net/osmand/plus/PoiFilter.java @@ -10,7 +10,7 @@ import java.util.Set; import net.osmand.OsmAndFormatter; import net.osmand.data.Amenity; import net.osmand.data.AmenityType; -import net.osmand.data.index.IndexConstants; +import net.osmand.data.IndexConstants; import net.osmand.osm.MapUtils; import net.osmand.plus.activities.OsmandApplication; diff --git a/OsmAnd/src/net/osmand/plus/ResourceManager.java b/OsmAnd/src/net/osmand/plus/ResourceManager.java index 049d38052b..07030b6ddd 100644 --- a/OsmAnd/src/net/osmand/plus/ResourceManager.java +++ b/OsmAnd/src/net/osmand/plus/ResourceManager.java @@ -1,837 +1,838 @@ -package net.osmand.plus; - -import java.io.File; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.text.Collator; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Stack; -import java.util.TreeMap; - -import net.osmand.IProgress; -import net.osmand.LogUtil; -import net.osmand.binary.BinaryMapIndexReader; -import net.osmand.data.Amenity; -import net.osmand.data.TransportStop; -import net.osmand.data.index.IndexConstants; -import net.osmand.data.preparation.MapTileDownloader; -import net.osmand.data.preparation.MapTileDownloader.DownloadRequest; -import net.osmand.data.preparation.MapTileDownloader.IMapDownloaderCallback; -import net.osmand.map.ITileSource; -import net.osmand.osm.LatLon; -import net.osmand.osm.MapUtils; -import net.osmand.plus.activities.OsmandApplication; -import net.osmand.plus.render.BaseOsmandRender; -import net.osmand.plus.render.MapRenderRepositories; -import net.osmand.plus.render.RendererRegistry; -import net.osmand.plus.views.POIMapLayer; - -import org.apache.commons.logging.Log; - -import android.database.sqlite.SQLiteException; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; - -/** - * Resource manager is responsible to work with all resources - * that could consume memory (especially with file resources). - * Such as indexes, tiles. - * Also it is responsible to create cache for that resources if they - * can't be loaded fully into memory & clear them on request. - *SQLITE - */ -public class ResourceManager { - - public static final String APP_DIR = "osmand/"; //$NON-NLS-1$ - public static final String POI_PATH = APP_DIR + IndexConstants.POI_INDEX_DIR; - public static final String VOICE_PATH = APP_DIR + IndexConstants.VOICE_INDEX_DIR; - public static final String MAPS_PATH = APP_DIR; - public static final String TILES_PATH = APP_DIR+"tiles/"; //$NON-NLS-1$ - public static final String TEMP_SOURCE_TO_LOAD = "temp"; //$NON-NLS-1$ - public static final String VECTOR_MAP = "#vector_map"; //$NON-NLS-1$ - - public static final int LIMIT_TRANSPORT = 200; - - private static final Log log = LogUtil.getLog(ResourceManager.class); - - protected static ResourceManager manager = null; - - // it is not good investigated but no more than 64 (satellite images) - // Only 8 MB (from 16 Mb whole mem) available for images : image 64K * 128 = 8 MB (8 bit), 64 - 16 bit, 32 - 32 bit - protected int maxImgCacheSize = 32; - - protected Map cacheOfImages = new LinkedHashMap(); - protected Map imagesOnFS = new LinkedHashMap() ; - - protected File dirWithTiles ; - - private final OsmandApplication context; - - private BusyIndicator busyIndicator; - - private final MapTileDownloader downloader = MapTileDownloader.getInstance(); - // Indexes - private final Map addressMap = new TreeMap(Collator.getInstance()); - - protected final List amenityRepositories = new ArrayList(); - - protected final List transportRepositories = new ArrayList(); - - protected final Map indexFileNames = new LinkedHashMap(); - - protected final MapRenderRepositories renderer; - - public final AsyncLoadingThread asyncLoadingTiles = new AsyncLoadingThread(); - - protected boolean internetIsNotAccessible = false; - - - public ResourceManager(OsmandApplication context) { - this.context = context; - this.renderer = new MapRenderRepositories(context); - asyncLoadingTiles.start(); - resetStoreDirectory(); - } - - public void resetStoreDirectory() { - dirWithTiles = OsmandSettings.extendOsmandPath(context, TILES_PATH); - dirWithTiles.mkdirs(); - } - - public OsmandApplication getContext() { - return context; - } - - ////////////////////////////////////////////// Working with tiles //////////////////////////////////////////////// - - public void indexingImageTiles(IProgress progress){ - progress.startTask(context.getString(R.string.reading_cached_tiles), -1); //$NON-NLS-1$ - imagesOnFS.clear(); - for(File c : dirWithTiles.listFiles()){ - indexImageTilesFS("", c); //$NON-NLS-1$ - } - } - - private void indexImageTilesFS(String prefix, File f){ - if(f.isDirectory()){ - for(File c : f.listFiles()){ - indexImageTilesFS(prefix +f.getName() +"/" , c); //$NON-NLS-1$ - } - } else if(f.getName().endsWith(".tile")){ //$NON-NLS-1$ - imagesOnFS.put(prefix + f.getName(), Boolean.TRUE); - } else if(f.getName().endsWith(".sqlitedb")){ //$NON-NLS-1$ - // nothing to do here - } - } - - - public Bitmap getTileImageForMapAsync(String file, ITileSource map, int x, int y, int zoom, boolean loadFromInternetIfNeeded) { - return getTileImageForMap(file, map, x, y, zoom, loadFromInternetIfNeeded, false, true); - } - - - public Bitmap getTileImageFromCache(String file){ - return cacheOfImages.get(file); - } - - - public Bitmap getTileImageForMapSync(String file, ITileSource map, int x, int y, int zoom, boolean loadFromInternetIfNeeded) { - return getTileImageForMap(file, map, x, y, zoom, loadFromInternetIfNeeded, true, true); - } - - public void tileDownloaded(DownloadRequest request){ - if(request instanceof TileLoadDownloadRequest){ - TileLoadDownloadRequest req = ((TileLoadDownloadRequest) request); - imagesOnFS.put(req.tileId, Boolean.TRUE); - if(req.fileToSave != null && req.tileSource instanceof SQLiteTileSource){ - try { - ((SQLiteTileSource) req.tileSource).insertImage(req.xTile, req.yTile, req.zoom, req.fileToSave); - } catch (IOException e) { - log.warn("File "+req.fileToSave.getName() + " couldn't be read", e); //$NON-NLS-1$//$NON-NLS-2$ - } - req.fileToSave.delete(); - String[] l = req.fileToSave.getParentFile().list(); - if(l == null || l.length == 0){ - req.fileToSave.getParentFile().delete(); - l = req.fileToSave.getParentFile().getParentFile().list(); - if(l == null || l.length == 0){ - req.fileToSave.getParentFile().getParentFile().delete(); - } - } - } - } - - } - - public synchronized boolean tileExistOnFileSystem(String file, ITileSource map, int x, int y, int zoom){ - if(!imagesOnFS.containsKey(file)){ - boolean ex = false; - if(map instanceof SQLiteTileSource){ - ex = ((SQLiteTileSource) map).exists(x, y, zoom); - } else { - if(file == null){ - file = calculateTileId(map, x, y, zoom); - } - ex = new File(dirWithTiles, file).exists(); - } - if (ex) { - imagesOnFS.put(file, Boolean.TRUE); - } else { - imagesOnFS.put(file, null); - } - } - return imagesOnFS.get(file) != null; - } - - public void clearTileImageForMap(String file, ITileSource map, int x, int y, int zoom){ - getTileImageForMap(file, map, x, y, zoom, true, false, true, true); - } - - /** - * @param file - null could be passed if you do not call very often with that param - */ - protected Bitmap getTileImageForMap(String file, ITileSource map, int x, int y, int zoom, - boolean loadFromInternetIfNeeded, boolean sync, boolean loadFromFs) { - return getTileImageForMap(file, map, x, y, zoom, loadFromInternetIfNeeded, sync, loadFromFs, false); - } - - // introduce cache in order save memory - private int insertString(char[] ar, int offset, String s) { - for (int j = 0; j < s.length(); j++) { - ar[offset++] = s.charAt(j); - } - return offset; - } - protected StringBuilder builder = new StringBuilder(40); - protected char[] tileId = new char[120]; - public synchronized String calculateTileId(ITileSource map, int x, int y, int zoom){ - if(false){ - // performance improve ? - int ind = 0; - String mapName = map == null ? TEMP_SOURCE_TO_LOAD : map.getName(); - ind = insertString(tileId, ind, mapName); - if (map instanceof SQLiteTileSource) { - tileId[ind++] = '@'; - } else { - tileId[ind++] = '/'; - } - ind = insertString(tileId, ind, Integer.toString(zoom)); - tileId[ind++] = '/'; - ind = insertString(tileId, ind, Integer.toString(x)); - tileId[ind++] = '/'; - ind = insertString(tileId, ind, Integer.toString(y)); - ind = insertString(tileId, ind, map == null ? ".jpg" : map.getTileFormat()); //$NON-NLS-1$ - ind = insertString(tileId, ind, ".tile"); //$NON-NLS-1$ - return new String(tileId, 0, ind); - } else { - - builder.setLength(0); - if (map == null) { - builder.append(TEMP_SOURCE_TO_LOAD); - } else { - builder.append(map.getName()); - } - - if (map instanceof SQLiteTileSource) { - builder.append('@'); - } else { - builder.append('/'); - } - builder.append(zoom).append('/').append(x).append('/').append(y) - .append(map == null ? ".jpg" : map.getTileFormat()).append(".tile"); //$NON-NLS-1$ //$NON-NLS-2$ - return builder.toString(); - } - } - - - protected synchronized Bitmap getTileImageForMap(String tileId, ITileSource map, int x, int y, int zoom, - boolean loadFromInternetIfNeeded, boolean sync, boolean loadFromFs, boolean deleteBefore) { - if (tileId == null) { - tileId = calculateTileId(map, x, y, zoom); - if(tileId == null){ - return null; - } - } - - if(deleteBefore){ - cacheOfImages.remove(tileId); - if (map instanceof SQLiteTileSource) { - ((SQLiteTileSource) map).deleteImage(x, y, zoom); - } else { - File f = new File(dirWithTiles, tileId); - if (f.exists()) { - f.delete(); - } - } - imagesOnFS.put(tileId, null); - } - - if (loadFromFs && cacheOfImages.get(tileId) == null && map != null) { - if(!loadFromInternetIfNeeded && !tileExistOnFileSystem(tileId, map, x, y, zoom)){ - return null; - } - String url = loadFromInternetIfNeeded ? map.getUrlToLoad(x, y, zoom) : null; - File toSave = null; - if (url != null) { - if (map instanceof SQLiteTileSource) { - toSave = new File(dirWithTiles, calculateTileId(((SQLiteTileSource) map).getBase(), x, y, zoom)); - } else { - toSave = new File(dirWithTiles, tileId); - } - } - TileLoadDownloadRequest req = new TileLoadDownloadRequest(dirWithTiles, url, toSave, - tileId, map, x, y, zoom); - if(sync){ - return getRequestedImageTile(req); - } else { - asyncLoadingTiles.requestToLoadImage(req); - } - } - return cacheOfImages.get(tileId); - } - - - - private Bitmap getRequestedImageTile(TileLoadDownloadRequest req){ - if(req.tileId == null || req.dirWithTiles == null){ - return null; - } - if (cacheOfImages.size() > maxImgCacheSize) { - clearTiles(); - } - if (req.dirWithTiles.canRead() && !downloader.isFileCurrentlyDownloaded(req.fileToSave)) { - long time = System.currentTimeMillis(); - Bitmap bmp = null; - if (req.tileSource instanceof SQLiteTileSource) { - bmp = ((SQLiteTileSource) req.tileSource).getImage(req.xTile, req.yTile, req.zoom); - } else { - File en = new File(req.dirWithTiles, req.tileId); - if (en.exists()) { - try { - bmp = BitmapFactory.decodeFile(en.getAbsolutePath()); - } catch (OutOfMemoryError e) { - log.error("Out of memory error", e); //$NON-NLS-1$ - clearTiles(); - } - } - } - - if (bmp != null) { - cacheOfImages.put(req.tileId, bmp); - if (log.isDebugEnabled()) { - log.debug("Loaded file : " + req.tileId + " " + -(time - System.currentTimeMillis()) + " ms " + cacheOfImages.size()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - } - - if (cacheOfImages.get(req.tileId) == null && req.url != null) { - downloader.requestToDownload(req); - } - - } - return cacheOfImages.get(req.tileId); - } - - ////////////////////////////////////////////// Working with indexes //////////////////////////////////////////////// - - public List reloadIndexes(IProgress progress){ - close(); - initRenderers(progress); - // do it lazy - // indexingImageTiles(progress); - List warnings = new ArrayList(); - warnings.addAll(indexingPoi(progress)); - warnings.addAll(indexingMaps(progress)); - return warnings; - } - - private void initRenderers(IProgress progress) { - File file = OsmandSettings.extendOsmandPath(context, APP_DIR + IndexConstants.RENDERERS_DIR); - file.mkdirs(); - Map externalRenderers = new LinkedHashMap(); - if (file.exists() && file.canRead()) { - for (File f : file.listFiles()) { - if (f.getName().endsWith(IndexConstants.RENDERER_INDEX_EXT)) { - String name = f.getName().substring(0, f.getName().length() - IndexConstants.RENDERER_INDEX_EXT.length()); - externalRenderers.put(name, f); - } - } - } - RendererRegistry.getRegistry().setExternalRenderers(externalRenderers); - String r = OsmandSettings.getVectorRenderer(OsmandSettings.getPrefs(context)); - if(r != null){ - BaseOsmandRender obj = RendererRegistry.getRegistry().getRenderer(r); - if(obj != null){ - RendererRegistry.getRegistry().setCurrentSelectedRender(obj); - } - } - } - - public List indexingMaps(final IProgress progress) { - File file = OsmandSettings.extendOsmandPath(context, MAPS_PATH); - file.mkdirs(); - List warnings = new ArrayList(); - renderer.clearAllResources(); - if (file.exists() && file.canRead()) { - for (File f : file.listFiles()) { - if (f.getName().endsWith(IndexConstants.BINARY_MAP_INDEX_EXT)) { - progress.startTask(context.getString(R.string.indexing_map) + " " + f.getName(), -1); //$NON-NLS-1$ - try { - BinaryMapIndexReader index = renderer.initializeNewResource(progress, f); - if (index == null) { - warnings.add(MessageFormat.format(context.getString(R.string.version_index_is_not_supported), f.getName())); //$NON-NLS-1$ - } else { - indexFileNames.put(f.getName(), MessageFormat.format("{0,date,dd.MM.yyyy}", new Date(f.lastModified()))); //$NON-NLS-1$ - for(String rName : index.getRegionNames()) { - // skip duplicate names (don't make collision between getName() and name in the map) - RegionAddressRepositoryBinary rarb = new RegionAddressRepositoryBinary(index, rName); - addressMap.put(rName, rarb); - } - if (index.hasTransportData()) { - try { - RandomAccessFile raf = new RandomAccessFile(f, "r"); //$NON-NLS-1$ - transportRepositories.add(new TransportIndexRepositoryBinary(new BinaryMapIndexReader(raf))); - } catch (IOException e) { - log.error("Exception reading " + f.getAbsolutePath(), e); //$NON-NLS-1$ - warnings.add(MessageFormat.format(context.getString(R.string.version_index_is_not_supported), f.getName())); //$NON-NLS-1$ - } - } - if(index.containsMapData()){ - // that's not fully acceptable - // TODO -// try { -// RandomAccessFile raf = new RandomAccessFile(f, "r"); //$NON-NLS-1$ -// amenityRepositories.add(new AmenityIndexRepositoryBinary(new BinaryMapIndexReader(raf))); -// } catch (IOException e) { -// log.error("Exception reading " + f.getAbsolutePath(), e); //$NON-NLS-1$ -// warnings.add(MessageFormat.format(Messages.getMessage("version_index_is_not_supported"), f.getName())); //$NON-NLS-1$ -// } - } - } - } catch (SQLiteException e) { - log.error("Exception reading " + f.getAbsolutePath(), e); //$NON-NLS-1$ - warnings.add(MessageFormat.format(context.getString(R.string.version_index_is_not_supported), f.getName())); //$NON-NLS-1$ - } catch (OutOfMemoryError oome) { - log.error("Exception reading " + f.getAbsolutePath(), oome); //$NON-NLS-1$ - warnings.add(MessageFormat.format(context.getString(R.string.version_index_is_big_for_memory), f.getName())); - } - } else if(f.getName().endsWith(".map.odb")){ //$NON-NLS-1$ - warnings.add(MessageFormat.format(context.getString(R.string.old_map_index_is_not_supported), f.getName())); //$NON-NLS-1$ - } - } - } - return warnings; - } - - // POI INDEX // - public List indexingPoi(final IProgress progress) { - File file = OsmandSettings.extendOsmandPath(context, POI_PATH); - file.mkdirs(); - List warnings = new ArrayList(); - closeAmenities(); - if (file.exists() && file.canRead()) { - for (File f : file.listFiles()) { - indexingPoi(progress, warnings, f); - } - } - return warnings; - } - - public void indexingPoi(final IProgress progress, List warnings, File f) { - if (f.getName().endsWith(IndexConstants.POI_INDEX_EXT)) { - AmenityIndexRepositoryOdb repository = new AmenityIndexRepositoryOdb(); - - progress.startTask(context.getString(R.string.indexing_poi) + " " + f.getName(), -1); //$NON-NLS-1$ - try { - boolean initialized = repository.initialize(progress, f); - if (initialized) { - amenityRepositories.add(repository); - indexFileNames.put(f.getName(), MessageFormat.format("{0,date,dd.MM.yyyy}", new Date(f.lastModified()))); //$NON-NLS-1$ - } else { - warnings.add(MessageFormat.format(context.getString(R.string.version_index_is_not_supported), f.getName())); //$NON-NLS-1$ - } - } catch (SQLiteException e) { - log.error("Exception reading " + f.getAbsolutePath(), e); //$NON-NLS-1$ - warnings.add(MessageFormat.format(context.getString(R.string.version_index_is_not_supported), f.getName())); //$NON-NLS-1$ - } - } - } - - public void updateIndexLastDateModified(File f){ - if(f != null && f.exists()){ - indexFileNames.put(f.getName(), MessageFormat.format("{0,date,dd.MM.yyyy}", new Date(f.lastModified()))); //$NON-NLS-1$ - } - } - - - ////////////////////////////////////////////// Working with amenities //////////////////////////////////////////////// - public List searchAmenityRepositories(double latitude, double longitude) { - List repos = new ArrayList(); - for (AmenityIndexRepository index : amenityRepositories) { - if (index.checkContains(latitude,longitude)) { - repos.add(index); - } - } - return repos; - } - - public List searchAmenities(PoiFilter filter, double latitude, double longitude, int zoom, int limit) { - double tileNumberX = MapUtils.getTileNumberX(zoom, longitude); - double tileNumberY = MapUtils.getTileNumberY(zoom, latitude); - double topLatitude = MapUtils.getLatitudeFromTile(zoom, tileNumberY - 0.5); - double bottomLatitude = MapUtils.getLatitudeFromTile(zoom, tileNumberY + 0.5); - double leftLongitude = MapUtils.getLongitudeFromTile(zoom, tileNumberX - 0.5); - double rightLongitude = MapUtils.getLongitudeFromTile(zoom, tileNumberX + 0.5); - List amenities = new ArrayList(); - for (AmenityIndexRepository index : amenityRepositories) { - if (index.checkContains(topLatitude, leftLongitude, bottomLatitude, rightLongitude)) { - if (!index.checkCachedAmenities(topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom, filter.getFilterId(), - amenities, false)) { - index.searchAmenities(topLatitude, leftLongitude, bottomLatitude, rightLongitude, limit, filter, amenities); - } - } - } - - return amenities; - } - - public void searchAmenitiesAsync(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, PoiFilter filter, List toFill){ - if(filter instanceof NameFinderPoiFilter){ - List amenities = ((NameFinderPoiFilter) filter).getSearchedAmenities(); - for(Amenity a : amenities){ - LatLon l = a.getLocation(); - if(l != null && l.getLatitude() <= topLatitude && l.getLatitude() >= bottomLatitude && l.getLongitude() >= leftLongitude && l.getLongitude() <= rightLongitude){ - toFill.add(a); - } - } - - } else { - String filterId = filter == null ? null : filter.getFilterId(); - for (AmenityIndexRepository index : amenityRepositories) { - if (index.checkContains(topLatitude, leftLongitude, bottomLatitude, rightLongitude)) { - if (!index.checkCachedAmenities(topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom, filterId, toFill, - true)) { - asyncLoadingTiles.requestToLoadAmenities(new AmenityLoadRequest(index, topLatitude, leftLongitude, bottomLatitude, - rightLongitude, zoom, filter)); - } - } - } - } - } - - ////////////////////////////////////////////// Working with address /////////////////////////////////////////// - - public RegionAddressRepository getRegionRepository(String name){ - return addressMap.get(name); - } - - public Collection getAddressRepositories(){ - return addressMap.values(); - } - - ////////////////////////////////////////////// Working with transport //////////////////////////////////////////////// - public List searchTransportRepositories(double latitude, double longitude) { - List repos = new ArrayList(); - for (TransportIndexRepository index : transportRepositories) { - if (index.checkContains(latitude,longitude)) { - repos.add(index); - } - } - return repos; - } - - - public void searchTransportAsync(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, List toFill){ - for(TransportIndexRepository index : transportRepositories){ - if(index.checkContains(topLatitude, leftLongitude, bottomLatitude, rightLongitude)){ - if(!index.checkCachedObjects(topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom, toFill, true)){ - asyncLoadingTiles.requestToLoadTransport( - new TransportLoadRequest(index, topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom)); - } - } - } - } - - ////////////////////////////////////////////// Working with map //////////////////////////////////////////////// - public boolean updateRenderedMapNeeded(RotatedTileBox rotatedTileBox){ - return renderer.updateMapIsNeeded(rotatedTileBox); - } - - public void updateRendererMap(RotatedTileBox rotatedTileBox){ - renderer.interruptLoadingMap(); - asyncLoadingTiles.requestToLoadMap( - new MapLoadRequest(new RotatedTileBox(rotatedTileBox))); - } - - public void interruptRendering(){ - renderer.interruptLoadingMap(); - } - - public MapRenderRepositories getRenderer() { - return renderer; - } - - ////////////////////////////////////////////// Closing methods //////////////////////////////////////////////// - - public void closeAmenities(){ - for(AmenityIndexRepository r : amenityRepositories){ - r.close(); - } - amenityRepositories.clear(); - } - - public void closeAddresses(){ - for(RegionAddressRepository r : addressMap.values()){ - r.close(); - } - addressMap.clear(); - } - - public void closeTransport(){ - for(TransportIndexRepository r : transportRepositories){ - r.close(); - } - transportRepositories.clear(); - } - - public BusyIndicator getBusyIndicator() { - return busyIndicator; - } - - public synchronized void setBusyIndicator(BusyIndicator busyIndicator) { - this.busyIndicator = busyIndicator; - } - - public synchronized void close(){ - imagesOnFS.clear(); - indexFileNames.clear(); - renderer.clearAllResources(); - closeAmenities(); - closeAddresses(); - closeTransport(); - } - - public Map getIndexFileNames() { - return indexFileNames; - } - - public synchronized void reloadTilesFromFS(){ - imagesOnFS.clear(); - } - - /// On low memory method /// - public void onLowMemory() { - log.info("On low memory : cleaning tiles - size = " + cacheOfImages.size()); //$NON-NLS-1$ - clearTiles(); - for(AmenityIndexRepository r : amenityRepositories){ - r.clearCache(); - } - for(RegionAddressRepository r : addressMap.values()){ - r.clearCache(); - } - renderer.clearCache(); - - System.gc(); - } - - - public synchronized void updateMapSource(boolean useVectorMap, ITileSource source){ - log.info("Clear cache with new source " + cacheOfImages.size()); //$NON-NLS-1$ - cacheOfImages.clear(); - renderer.clearCache(); - if(source == null || source.getBitDensity() == 0){ - maxImgCacheSize = 32; - } else { - maxImgCacheSize = Math.max(384 / source.getBitDensity() , 32); - } - - } - - - protected synchronized void clearTiles(){ - log.info("Cleaning tiles - size = " + cacheOfImages.size()); //$NON-NLS-1$ - ArrayList list = new ArrayList(cacheOfImages.keySet()); - // remove first images (as we think they are older) - for (int i = 0; i < list.size() /2; i ++) { - cacheOfImages.remove(list.get(i)); - } - } - - - private static class TileLoadDownloadRequest extends DownloadRequest { - - public final String tileId; - public final File dirWithTiles; - public final ITileSource tileSource; - - public TileLoadDownloadRequest(File dirWithTiles, String url, File fileToSave, - String tileId, ITileSource source, int tileX, int tileY, int zoom) { - super(url, fileToSave, tileX, tileY, zoom); - this.dirWithTiles = dirWithTiles; - this.tileSource = source; - this.tileId = tileId; - } - } - - private static class AmenityLoadRequest { - public final AmenityIndexRepository repository; - public final double topLatitude; - public final double bottomLatitude; - public final double leftLongitude; - public final double rightLongitude; - public final PoiFilter filter; - public final int zoom; - - public AmenityLoadRequest(AmenityIndexRepository repository, double topLatitude, double leftLongitude, - double bottomLatitude, double rightLongitude, int zoom, PoiFilter filter) { - super(); - this.bottomLatitude = bottomLatitude; - this.leftLongitude = leftLongitude; - this.repository = repository; - this.rightLongitude = rightLongitude; - this.topLatitude = topLatitude; - this.zoom = zoom; - this.filter = filter; - } - } - - - - private static class TransportLoadRequest { - public final TransportIndexRepository repository; - public final double topLatitude; - public final double bottomLatitude; - public final double leftLongitude; - public final double rightLongitude; - public final int zoom; - - public TransportLoadRequest(TransportIndexRepository repository, double topLatitude, double leftLongitude, - double bottomLatitude, double rightLongitude, int zoom) { - super(); - this.bottomLatitude = bottomLatitude; - this.leftLongitude = leftLongitude; - this.repository = repository; - this.rightLongitude = rightLongitude; - this.topLatitude = topLatitude; - this.zoom = zoom; - } - } - - private static class MapLoadRequest { - public final RotatedTileBox tileBox; - - public MapLoadRequest(RotatedTileBox tileBox) { - super(); - this.tileBox = tileBox; - } - } - - public class AsyncLoadingThread extends Thread { - Stack requests = new Stack(); - - public AsyncLoadingThread(){ - super("Loader map objects (tiles, poi)"); //$NON-NLS-1$ - } - - @Override - public void run() { - while(true){ - try { - boolean update = false; - boolean amenityLoaded = false; - boolean transportLoaded = false; - boolean mapLoaded = false; - int progress = 0; - if(downloader.isSomethingBeingDownloaded()){ - progress = BusyIndicator.STATUS_GREEN; - } - synchronized(ResourceManager.this){ - if(busyIndicator != null){ - if(context.getRoutingHelper().isRouteBeingCalculated()){ - progress = BusyIndicator.STATUS_BLUE; - } else if(!requests.isEmpty()){ - progress = BusyIndicator.STATUS_BLACK;; - } - busyIndicator.updateStatus(progress); - } - } - while(!requests.isEmpty()){ - Object req = requests.pop(); - if (req instanceof TileLoadDownloadRequest) { - TileLoadDownloadRequest r = (TileLoadDownloadRequest) req; - if (cacheOfImages.get(r.tileId) == null) { - update |= getRequestedImageTile(r) != null; - } - } else if(req instanceof AmenityLoadRequest){ - if(!amenityLoaded){ - AmenityLoadRequest r = (AmenityLoadRequest) req; - r.repository.evaluateCachedAmenities(r.topLatitude, r.leftLongitude, - r.bottomLatitude, r.rightLongitude, r.zoom, POIMapLayer.LIMIT_POI, r.filter, null); - amenityLoaded = true; - } - } else if(req instanceof TransportLoadRequest){ - if(!transportLoaded){ - TransportLoadRequest r = (TransportLoadRequest) req; - r.repository.evaluateCachedTransportStops(r.topLatitude, r.leftLongitude, - r.bottomLatitude, r.rightLongitude, r.zoom, LIMIT_TRANSPORT, null); - transportLoaded = true; - } - } else if(req instanceof MapLoadRequest){ - if(!mapLoaded){ - MapLoadRequest r = (MapLoadRequest) req; - renderer.loadMap(r.tileBox, downloader.getDownloaderCallbacks()); - mapLoaded = true; - } - } - } - if(update || amenityLoaded || transportLoaded || mapLoaded){ - // use downloader callback - for(IMapDownloaderCallback c : downloader.getDownloaderCallbacks()){ - c.tileDownloaded(null); - } - } - boolean routeBeingCalculated = context.getRoutingHelper().isRouteBeingCalculated(); - if (progress != 0 || routeBeingCalculated || downloader.isSomethingBeingDownloaded()) { - synchronized (ResourceManager.this) { - if (busyIndicator != null) { - if(routeBeingCalculated){ - progress = BusyIndicator.STATUS_BLUE; - } else if(downloader.isSomethingBeingDownloaded()){ - progress = BusyIndicator.STATUS_GREEN; - } else { - progress = 0; - } - busyIndicator.updateStatus(progress); - } - } - } - sleep(750); - } catch (InterruptedException e) { - log.error(e, e); - } catch (RuntimeException e){ - log.error(e, e); - } - } - } - - public void requestToLoadImage(TileLoadDownloadRequest req){ - requests.push(req); - } - public void requestToLoadAmenities(AmenityLoadRequest req){ - requests.push(req); - } - - public void requestToLoadMap(MapLoadRequest req){ - requests.push(req); - } - - public void requestToLoadTransport(TransportLoadRequest req){ - requests.push(req); - } - }; -} +package net.osmand.plus; + + +import java.io.File; +import java.io.IOException; +import java.io.RandomAccessFile; +import java.text.Collator; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Stack; +import java.util.TreeMap; + +import net.osmand.IProgress; +import net.osmand.LogUtil; +import net.osmand.binary.BinaryMapIndexReader; +import net.osmand.data.Amenity; +import net.osmand.data.IndexConstants; +import net.osmand.data.MapTileDownloader; +import net.osmand.data.TransportStop; +import net.osmand.data.MapTileDownloader.DownloadRequest; +import net.osmand.data.MapTileDownloader.IMapDownloaderCallback; +import net.osmand.map.ITileSource; +import net.osmand.osm.LatLon; +import net.osmand.osm.MapUtils; +import net.osmand.plus.activities.OsmandApplication; +import net.osmand.plus.render.BaseOsmandRender; +import net.osmand.plus.render.MapRenderRepositories; +import net.osmand.plus.render.RendererRegistry; +import net.osmand.plus.views.POIMapLayer; + +import org.apache.commons.logging.Log; + +import android.database.sqlite.SQLiteException; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; + +/** + * Resource manager is responsible to work with all resources + * that could consume memory (especially with file resources). + * Such as indexes, tiles. + * Also it is responsible to create cache for that resources if they + * can't be loaded fully into memory & clear them on request. + *SQLITE + */ +public class ResourceManager { + + public static final String APP_DIR = "osmand/"; //$NON-NLS-1$ + public static final String POI_PATH = APP_DIR + IndexConstants.POI_INDEX_DIR; + public static final String VOICE_PATH = APP_DIR + IndexConstants.VOICE_INDEX_DIR; + public static final String MAPS_PATH = APP_DIR; + public static final String TILES_PATH = APP_DIR+"tiles/"; //$NON-NLS-1$ + public static final String TEMP_SOURCE_TO_LOAD = "temp"; //$NON-NLS-1$ + public static final String VECTOR_MAP = "#vector_map"; //$NON-NLS-1$ + + public static final int LIMIT_TRANSPORT = 200; + + private static final Log log = LogUtil.getLog(ResourceManager.class); + + protected static ResourceManager manager = null; + + // it is not good investigated but no more than 64 (satellite images) + // Only 8 MB (from 16 Mb whole mem) available for images : image 64K * 128 = 8 MB (8 bit), 64 - 16 bit, 32 - 32 bit + protected int maxImgCacheSize = 32; + + protected Map cacheOfImages = new LinkedHashMap(); + protected Map imagesOnFS = new LinkedHashMap() ; + + protected File dirWithTiles ; + + private final OsmandApplication context; + + private BusyIndicator busyIndicator; + + private final MapTileDownloader downloader = MapTileDownloader.getInstance(); + // Indexes + private final Map addressMap = new TreeMap(Collator.getInstance()); + + protected final List amenityRepositories = new ArrayList(); + + protected final List transportRepositories = new ArrayList(); + + protected final Map indexFileNames = new LinkedHashMap(); + + protected final MapRenderRepositories renderer; + + public final AsyncLoadingThread asyncLoadingTiles = new AsyncLoadingThread(); + + protected boolean internetIsNotAccessible = false; + + + public ResourceManager(OsmandApplication context) { + this.context = context; + this.renderer = new MapRenderRepositories(context); + asyncLoadingTiles.start(); + resetStoreDirectory(); + } + + public void resetStoreDirectory() { + dirWithTiles = OsmandSettings.extendOsmandPath(context, TILES_PATH); + dirWithTiles.mkdirs(); + } + + public OsmandApplication getContext() { + return context; + } + + ////////////////////////////////////////////// Working with tiles //////////////////////////////////////////////// + + public void indexingImageTiles(IProgress progress){ + progress.startTask(context.getString(R.string.reading_cached_tiles), -1); //$NON-NLS-1$ + imagesOnFS.clear(); + for(File c : dirWithTiles.listFiles()){ + indexImageTilesFS("", c); //$NON-NLS-1$ + } + } + + private void indexImageTilesFS(String prefix, File f){ + if(f.isDirectory()){ + for(File c : f.listFiles()){ + indexImageTilesFS(prefix +f.getName() +"/" , c); //$NON-NLS-1$ + } + } else if(f.getName().endsWith(".tile")){ //$NON-NLS-1$ + imagesOnFS.put(prefix + f.getName(), Boolean.TRUE); + } else if(f.getName().endsWith(".sqlitedb")){ //$NON-NLS-1$ + // nothing to do here + } + } + + + public Bitmap getTileImageForMapAsync(String file, ITileSource map, int x, int y, int zoom, boolean loadFromInternetIfNeeded) { + return getTileImageForMap(file, map, x, y, zoom, loadFromInternetIfNeeded, false, true); + } + + + public Bitmap getTileImageFromCache(String file){ + return cacheOfImages.get(file); + } + + + public Bitmap getTileImageForMapSync(String file, ITileSource map, int x, int y, int zoom, boolean loadFromInternetIfNeeded) { + return getTileImageForMap(file, map, x, y, zoom, loadFromInternetIfNeeded, true, true); + } + + public void tileDownloaded(DownloadRequest request){ + if(request instanceof TileLoadDownloadRequest){ + TileLoadDownloadRequest req = ((TileLoadDownloadRequest) request); + imagesOnFS.put(req.tileId, Boolean.TRUE); + if(req.fileToSave != null && req.tileSource instanceof SQLiteTileSource){ + try { + ((SQLiteTileSource) req.tileSource).insertImage(req.xTile, req.yTile, req.zoom, req.fileToSave); + } catch (IOException e) { + log.warn("File "+req.fileToSave.getName() + " couldn't be read", e); //$NON-NLS-1$//$NON-NLS-2$ + } + req.fileToSave.delete(); + String[] l = req.fileToSave.getParentFile().list(); + if(l == null || l.length == 0){ + req.fileToSave.getParentFile().delete(); + l = req.fileToSave.getParentFile().getParentFile().list(); + if(l == null || l.length == 0){ + req.fileToSave.getParentFile().getParentFile().delete(); + } + } + } + } + + } + + public synchronized boolean tileExistOnFileSystem(String file, ITileSource map, int x, int y, int zoom){ + if(!imagesOnFS.containsKey(file)){ + boolean ex = false; + if(map instanceof SQLiteTileSource){ + ex = ((SQLiteTileSource) map).exists(x, y, zoom); + } else { + if(file == null){ + file = calculateTileId(map, x, y, zoom); + } + ex = new File(dirWithTiles, file).exists(); + } + if (ex) { + imagesOnFS.put(file, Boolean.TRUE); + } else { + imagesOnFS.put(file, null); + } + } + return imagesOnFS.get(file) != null; + } + + public void clearTileImageForMap(String file, ITileSource map, int x, int y, int zoom){ + getTileImageForMap(file, map, x, y, zoom, true, false, true, true); + } + + /** + * @param file - null could be passed if you do not call very often with that param + */ + protected Bitmap getTileImageForMap(String file, ITileSource map, int x, int y, int zoom, + boolean loadFromInternetIfNeeded, boolean sync, boolean loadFromFs) { + return getTileImageForMap(file, map, x, y, zoom, loadFromInternetIfNeeded, sync, loadFromFs, false); + } + + // introduce cache in order save memory + private int insertString(char[] ar, int offset, String s) { + for (int j = 0; j < s.length(); j++) { + ar[offset++] = s.charAt(j); + } + return offset; + } + protected StringBuilder builder = new StringBuilder(40); + protected char[] tileId = new char[120]; + public synchronized String calculateTileId(ITileSource map, int x, int y, int zoom){ + if(false){ + // performance improve ? + int ind = 0; + String mapName = map == null ? TEMP_SOURCE_TO_LOAD : map.getName(); + ind = insertString(tileId, ind, mapName); + if (map instanceof SQLiteTileSource) { + tileId[ind++] = '@'; + } else { + tileId[ind++] = '/'; + } + ind = insertString(tileId, ind, Integer.toString(zoom)); + tileId[ind++] = '/'; + ind = insertString(tileId, ind, Integer.toString(x)); + tileId[ind++] = '/'; + ind = insertString(tileId, ind, Integer.toString(y)); + ind = insertString(tileId, ind, map == null ? ".jpg" : map.getTileFormat()); //$NON-NLS-1$ + ind = insertString(tileId, ind, ".tile"); //$NON-NLS-1$ + return new String(tileId, 0, ind); + } else { + + builder.setLength(0); + if (map == null) { + builder.append(TEMP_SOURCE_TO_LOAD); + } else { + builder.append(map.getName()); + } + + if (map instanceof SQLiteTileSource) { + builder.append('@'); + } else { + builder.append('/'); + } + builder.append(zoom).append('/').append(x).append('/').append(y) + .append(map == null ? ".jpg" : map.getTileFormat()).append(".tile"); //$NON-NLS-1$ //$NON-NLS-2$ + return builder.toString(); + } + } + + + protected synchronized Bitmap getTileImageForMap(String tileId, ITileSource map, int x, int y, int zoom, + boolean loadFromInternetIfNeeded, boolean sync, boolean loadFromFs, boolean deleteBefore) { + if (tileId == null) { + tileId = calculateTileId(map, x, y, zoom); + if(tileId == null){ + return null; + } + } + + if(deleteBefore){ + cacheOfImages.remove(tileId); + if (map instanceof SQLiteTileSource) { + ((SQLiteTileSource) map).deleteImage(x, y, zoom); + } else { + File f = new File(dirWithTiles, tileId); + if (f.exists()) { + f.delete(); + } + } + imagesOnFS.put(tileId, null); + } + + if (loadFromFs && cacheOfImages.get(tileId) == null && map != null) { + if(!loadFromInternetIfNeeded && !tileExistOnFileSystem(tileId, map, x, y, zoom)){ + return null; + } + String url = loadFromInternetIfNeeded ? map.getUrlToLoad(x, y, zoom) : null; + File toSave = null; + if (url != null) { + if (map instanceof SQLiteTileSource) { + toSave = new File(dirWithTiles, calculateTileId(((SQLiteTileSource) map).getBase(), x, y, zoom)); + } else { + toSave = new File(dirWithTiles, tileId); + } + } + TileLoadDownloadRequest req = new TileLoadDownloadRequest(dirWithTiles, url, toSave, + tileId, map, x, y, zoom); + if(sync){ + return getRequestedImageTile(req); + } else { + asyncLoadingTiles.requestToLoadImage(req); + } + } + return cacheOfImages.get(tileId); + } + + + + private Bitmap getRequestedImageTile(TileLoadDownloadRequest req){ + if(req.tileId == null || req.dirWithTiles == null){ + return null; + } + if (cacheOfImages.size() > maxImgCacheSize) { + clearTiles(); + } + if (req.dirWithTiles.canRead() && !downloader.isFileCurrentlyDownloaded(req.fileToSave)) { + long time = System.currentTimeMillis(); + Bitmap bmp = null; + if (req.tileSource instanceof SQLiteTileSource) { + bmp = ((SQLiteTileSource) req.tileSource).getImage(req.xTile, req.yTile, req.zoom); + } else { + File en = new File(req.dirWithTiles, req.tileId); + if (en.exists()) { + try { + bmp = BitmapFactory.decodeFile(en.getAbsolutePath()); + } catch (OutOfMemoryError e) { + log.error("Out of memory error", e); //$NON-NLS-1$ + clearTiles(); + } + } + } + + if (bmp != null) { + cacheOfImages.put(req.tileId, bmp); + if (log.isDebugEnabled()) { + log.debug("Loaded file : " + req.tileId + " " + -(time - System.currentTimeMillis()) + " ms " + cacheOfImages.size()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + } + + if (cacheOfImages.get(req.tileId) == null && req.url != null) { + downloader.requestToDownload(req); + } + + } + return cacheOfImages.get(req.tileId); + } + + ////////////////////////////////////////////// Working with indexes //////////////////////////////////////////////// + + public List reloadIndexes(IProgress progress){ + close(); + initRenderers(progress); + // do it lazy + // indexingImageTiles(progress); + List warnings = new ArrayList(); + warnings.addAll(indexingPoi(progress)); + warnings.addAll(indexingMaps(progress)); + return warnings; + } + + private void initRenderers(IProgress progress) { + File file = OsmandSettings.extendOsmandPath(context, APP_DIR + IndexConstants.RENDERERS_DIR); + file.mkdirs(); + Map externalRenderers = new LinkedHashMap(); + if (file.exists() && file.canRead()) { + for (File f : file.listFiles()) { + if (f.getName().endsWith(IndexConstants.RENDERER_INDEX_EXT)) { + String name = f.getName().substring(0, f.getName().length() - IndexConstants.RENDERER_INDEX_EXT.length()); + externalRenderers.put(name, f); + } + } + } + RendererRegistry.getRegistry().setExternalRenderers(externalRenderers); + String r = OsmandSettings.getVectorRenderer(OsmandSettings.getPrefs(context)); + if(r != null){ + BaseOsmandRender obj = RendererRegistry.getRegistry().getRenderer(r); + if(obj != null){ + RendererRegistry.getRegistry().setCurrentSelectedRender(obj); + } + } + } + + public List indexingMaps(final IProgress progress) { + File file = OsmandSettings.extendOsmandPath(context, MAPS_PATH); + file.mkdirs(); + List warnings = new ArrayList(); + renderer.clearAllResources(); + if (file.exists() && file.canRead()) { + for (File f : file.listFiles()) { + if (f.getName().endsWith(IndexConstants.BINARY_MAP_INDEX_EXT)) { + progress.startTask(context.getString(R.string.indexing_map) + " " + f.getName(), -1); //$NON-NLS-1$ + try { + BinaryMapIndexReader index = renderer.initializeNewResource(progress, f); + if (index == null) { + warnings.add(MessageFormat.format(context.getString(R.string.version_index_is_not_supported), f.getName())); //$NON-NLS-1$ + } else { + indexFileNames.put(f.getName(), MessageFormat.format("{0,date,dd.MM.yyyy}", new Date(f.lastModified()))); //$NON-NLS-1$ + for(String rName : index.getRegionNames()) { + // skip duplicate names (don't make collision between getName() and name in the map) + RegionAddressRepositoryBinary rarb = new RegionAddressRepositoryBinary(index, rName); + addressMap.put(rName, rarb); + } + if (index.hasTransportData()) { + try { + RandomAccessFile raf = new RandomAccessFile(f, "r"); //$NON-NLS-1$ + transportRepositories.add(new TransportIndexRepositoryBinary(new BinaryMapIndexReader(raf))); + } catch (IOException e) { + log.error("Exception reading " + f.getAbsolutePath(), e); //$NON-NLS-1$ + warnings.add(MessageFormat.format(context.getString(R.string.version_index_is_not_supported), f.getName())); //$NON-NLS-1$ + } + } + if(index.containsMapData()){ + // that's not fully acceptable + // TODO +// try { +// RandomAccessFile raf = new RandomAccessFile(f, "r"); //$NON-NLS-1$ +// amenityRepositories.add(new AmenityIndexRepositoryBinary(new BinaryMapIndexReader(raf))); +// } catch (IOException e) { +// log.error("Exception reading " + f.getAbsolutePath(), e); //$NON-NLS-1$ +// warnings.add(MessageFormat.format(Messages.getMessage("version_index_is_not_supported"), f.getName())); //$NON-NLS-1$ +// } + } + } + } catch (SQLiteException e) { + log.error("Exception reading " + f.getAbsolutePath(), e); //$NON-NLS-1$ + warnings.add(MessageFormat.format(context.getString(R.string.version_index_is_not_supported), f.getName())); //$NON-NLS-1$ + } catch (OutOfMemoryError oome) { + log.error("Exception reading " + f.getAbsolutePath(), oome); //$NON-NLS-1$ + warnings.add(MessageFormat.format(context.getString(R.string.version_index_is_big_for_memory), f.getName())); + } + } else if(f.getName().endsWith(".map.odb")){ //$NON-NLS-1$ + warnings.add(MessageFormat.format(context.getString(R.string.old_map_index_is_not_supported), f.getName())); //$NON-NLS-1$ + } + } + } + return warnings; + } + + // POI INDEX // + public List indexingPoi(final IProgress progress) { + File file = OsmandSettings.extendOsmandPath(context, POI_PATH); + file.mkdirs(); + List warnings = new ArrayList(); + closeAmenities(); + if (file.exists() && file.canRead()) { + for (File f : file.listFiles()) { + indexingPoi(progress, warnings, f); + } + } + return warnings; + } + + public void indexingPoi(final IProgress progress, List warnings, File f) { + if (f.getName().endsWith(IndexConstants.POI_INDEX_EXT)) { + AmenityIndexRepositoryOdb repository = new AmenityIndexRepositoryOdb(); + + progress.startTask(context.getString(R.string.indexing_poi) + " " + f.getName(), -1); //$NON-NLS-1$ + try { + boolean initialized = repository.initialize(progress, f); + if (initialized) { + amenityRepositories.add(repository); + indexFileNames.put(f.getName(), MessageFormat.format("{0,date,dd.MM.yyyy}", new Date(f.lastModified()))); //$NON-NLS-1$ + } else { + warnings.add(MessageFormat.format(context.getString(R.string.version_index_is_not_supported), f.getName())); //$NON-NLS-1$ + } + } catch (SQLiteException e) { + log.error("Exception reading " + f.getAbsolutePath(), e); //$NON-NLS-1$ + warnings.add(MessageFormat.format(context.getString(R.string.version_index_is_not_supported), f.getName())); //$NON-NLS-1$ + } + } + } + + public void updateIndexLastDateModified(File f){ + if(f != null && f.exists()){ + indexFileNames.put(f.getName(), MessageFormat.format("{0,date,dd.MM.yyyy}", new Date(f.lastModified()))); //$NON-NLS-1$ + } + } + + + ////////////////////////////////////////////// Working with amenities //////////////////////////////////////////////// + public List searchAmenityRepositories(double latitude, double longitude) { + List repos = new ArrayList(); + for (AmenityIndexRepository index : amenityRepositories) { + if (index.checkContains(latitude,longitude)) { + repos.add(index); + } + } + return repos; + } + + public List searchAmenities(PoiFilter filter, double latitude, double longitude, int zoom, int limit) { + double tileNumberX = MapUtils.getTileNumberX(zoom, longitude); + double tileNumberY = MapUtils.getTileNumberY(zoom, latitude); + double topLatitude = MapUtils.getLatitudeFromTile(zoom, tileNumberY - 0.5); + double bottomLatitude = MapUtils.getLatitudeFromTile(zoom, tileNumberY + 0.5); + double leftLongitude = MapUtils.getLongitudeFromTile(zoom, tileNumberX - 0.5); + double rightLongitude = MapUtils.getLongitudeFromTile(zoom, tileNumberX + 0.5); + List amenities = new ArrayList(); + for (AmenityIndexRepository index : amenityRepositories) { + if (index.checkContains(topLatitude, leftLongitude, bottomLatitude, rightLongitude)) { + if (!index.checkCachedAmenities(topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom, filter.getFilterId(), + amenities, false)) { + index.searchAmenities(topLatitude, leftLongitude, bottomLatitude, rightLongitude, limit, filter, amenities); + } + } + } + + return amenities; + } + + public void searchAmenitiesAsync(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, PoiFilter filter, List toFill){ + if(filter instanceof NameFinderPoiFilter){ + List amenities = ((NameFinderPoiFilter) filter).getSearchedAmenities(); + for(Amenity a : amenities){ + LatLon l = a.getLocation(); + if(l != null && l.getLatitude() <= topLatitude && l.getLatitude() >= bottomLatitude && l.getLongitude() >= leftLongitude && l.getLongitude() <= rightLongitude){ + toFill.add(a); + } + } + + } else { + String filterId = filter == null ? null : filter.getFilterId(); + for (AmenityIndexRepository index : amenityRepositories) { + if (index.checkContains(topLatitude, leftLongitude, bottomLatitude, rightLongitude)) { + if (!index.checkCachedAmenities(topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom, filterId, toFill, + true)) { + asyncLoadingTiles.requestToLoadAmenities(new AmenityLoadRequest(index, topLatitude, leftLongitude, bottomLatitude, + rightLongitude, zoom, filter)); + } + } + } + } + } + + ////////////////////////////////////////////// Working with address /////////////////////////////////////////// + + public RegionAddressRepository getRegionRepository(String name){ + return addressMap.get(name); + } + + public Collection getAddressRepositories(){ + return addressMap.values(); + } + + ////////////////////////////////////////////// Working with transport //////////////////////////////////////////////// + public List searchTransportRepositories(double latitude, double longitude) { + List repos = new ArrayList(); + for (TransportIndexRepository index : transportRepositories) { + if (index.checkContains(latitude,longitude)) { + repos.add(index); + } + } + return repos; + } + + + public void searchTransportAsync(double topLatitude, double leftLongitude, double bottomLatitude, double rightLongitude, int zoom, List toFill){ + for(TransportIndexRepository index : transportRepositories){ + if(index.checkContains(topLatitude, leftLongitude, bottomLatitude, rightLongitude)){ + if(!index.checkCachedObjects(topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom, toFill, true)){ + asyncLoadingTiles.requestToLoadTransport( + new TransportLoadRequest(index, topLatitude, leftLongitude, bottomLatitude, rightLongitude, zoom)); + } + } + } + } + + ////////////////////////////////////////////// Working with map //////////////////////////////////////////////// + public boolean updateRenderedMapNeeded(RotatedTileBox rotatedTileBox){ + return renderer.updateMapIsNeeded(rotatedTileBox); + } + + public void updateRendererMap(RotatedTileBox rotatedTileBox){ + renderer.interruptLoadingMap(); + asyncLoadingTiles.requestToLoadMap( + new MapLoadRequest(new RotatedTileBox(rotatedTileBox))); + } + + public void interruptRendering(){ + renderer.interruptLoadingMap(); + } + + public MapRenderRepositories getRenderer() { + return renderer; + } + + ////////////////////////////////////////////// Closing methods //////////////////////////////////////////////// + + public void closeAmenities(){ + for(AmenityIndexRepository r : amenityRepositories){ + r.close(); + } + amenityRepositories.clear(); + } + + public void closeAddresses(){ + for(RegionAddressRepository r : addressMap.values()){ + r.close(); + } + addressMap.clear(); + } + + public void closeTransport(){ + for(TransportIndexRepository r : transportRepositories){ + r.close(); + } + transportRepositories.clear(); + } + + public BusyIndicator getBusyIndicator() { + return busyIndicator; + } + + public synchronized void setBusyIndicator(BusyIndicator busyIndicator) { + this.busyIndicator = busyIndicator; + } + + public synchronized void close(){ + imagesOnFS.clear(); + indexFileNames.clear(); + renderer.clearAllResources(); + closeAmenities(); + closeAddresses(); + closeTransport(); + } + + public Map getIndexFileNames() { + return indexFileNames; + } + + public synchronized void reloadTilesFromFS(){ + imagesOnFS.clear(); + } + + /// On low memory method /// + public void onLowMemory() { + log.info("On low memory : cleaning tiles - size = " + cacheOfImages.size()); //$NON-NLS-1$ + clearTiles(); + for(AmenityIndexRepository r : amenityRepositories){ + r.clearCache(); + } + for(RegionAddressRepository r : addressMap.values()){ + r.clearCache(); + } + renderer.clearCache(); + + System.gc(); + } + + + public synchronized void updateMapSource(boolean useVectorMap, ITileSource source){ + log.info("Clear cache with new source " + cacheOfImages.size()); //$NON-NLS-1$ + cacheOfImages.clear(); + renderer.clearCache(); + if(source == null || source.getBitDensity() == 0){ + maxImgCacheSize = 32; + } else { + maxImgCacheSize = Math.max(384 / source.getBitDensity() , 32); + } + + } + + + protected synchronized void clearTiles(){ + log.info("Cleaning tiles - size = " + cacheOfImages.size()); //$NON-NLS-1$ + ArrayList list = new ArrayList(cacheOfImages.keySet()); + // remove first images (as we think they are older) + for (int i = 0; i < list.size() /2; i ++) { + cacheOfImages.remove(list.get(i)); + } + } + + + private static class TileLoadDownloadRequest extends DownloadRequest { + + public final String tileId; + public final File dirWithTiles; + public final ITileSource tileSource; + + public TileLoadDownloadRequest(File dirWithTiles, String url, File fileToSave, + String tileId, ITileSource source, int tileX, int tileY, int zoom) { + super(url, fileToSave, tileX, tileY, zoom); + this.dirWithTiles = dirWithTiles; + this.tileSource = source; + this.tileId = tileId; + } + } + + private static class AmenityLoadRequest { + public final AmenityIndexRepository repository; + public final double topLatitude; + public final double bottomLatitude; + public final double leftLongitude; + public final double rightLongitude; + public final PoiFilter filter; + public final int zoom; + + public AmenityLoadRequest(AmenityIndexRepository repository, double topLatitude, double leftLongitude, + double bottomLatitude, double rightLongitude, int zoom, PoiFilter filter) { + super(); + this.bottomLatitude = bottomLatitude; + this.leftLongitude = leftLongitude; + this.repository = repository; + this.rightLongitude = rightLongitude; + this.topLatitude = topLatitude; + this.zoom = zoom; + this.filter = filter; + } + } + + + + private static class TransportLoadRequest { + public final TransportIndexRepository repository; + public final double topLatitude; + public final double bottomLatitude; + public final double leftLongitude; + public final double rightLongitude; + public final int zoom; + + public TransportLoadRequest(TransportIndexRepository repository, double topLatitude, double leftLongitude, + double bottomLatitude, double rightLongitude, int zoom) { + super(); + this.bottomLatitude = bottomLatitude; + this.leftLongitude = leftLongitude; + this.repository = repository; + this.rightLongitude = rightLongitude; + this.topLatitude = topLatitude; + this.zoom = zoom; + } + } + + private static class MapLoadRequest { + public final RotatedTileBox tileBox; + + public MapLoadRequest(RotatedTileBox tileBox) { + super(); + this.tileBox = tileBox; + } + } + + public class AsyncLoadingThread extends Thread { + Stack requests = new Stack(); + + public AsyncLoadingThread(){ + super("Loader map objects (tiles, poi)"); //$NON-NLS-1$ + } + + @Override + public void run() { + while(true){ + try { + boolean update = false; + boolean amenityLoaded = false; + boolean transportLoaded = false; + boolean mapLoaded = false; + int progress = 0; + if(downloader.isSomethingBeingDownloaded()){ + progress = BusyIndicator.STATUS_GREEN; + } + synchronized(ResourceManager.this){ + if(busyIndicator != null){ + if(context.getRoutingHelper().isRouteBeingCalculated()){ + progress = BusyIndicator.STATUS_BLUE; + } else if(!requests.isEmpty()){ + progress = BusyIndicator.STATUS_BLACK;; + } + busyIndicator.updateStatus(progress); + } + } + while(!requests.isEmpty()){ + Object req = requests.pop(); + if (req instanceof TileLoadDownloadRequest) { + TileLoadDownloadRequest r = (TileLoadDownloadRequest) req; + if (cacheOfImages.get(r.tileId) == null) { + update |= getRequestedImageTile(r) != null; + } + } else if(req instanceof AmenityLoadRequest){ + if(!amenityLoaded){ + AmenityLoadRequest r = (AmenityLoadRequest) req; + r.repository.evaluateCachedAmenities(r.topLatitude, r.leftLongitude, + r.bottomLatitude, r.rightLongitude, r.zoom, POIMapLayer.LIMIT_POI, r.filter, null); + amenityLoaded = true; + } + } else if(req instanceof TransportLoadRequest){ + if(!transportLoaded){ + TransportLoadRequest r = (TransportLoadRequest) req; + r.repository.evaluateCachedTransportStops(r.topLatitude, r.leftLongitude, + r.bottomLatitude, r.rightLongitude, r.zoom, LIMIT_TRANSPORT, null); + transportLoaded = true; + } + } else if(req instanceof MapLoadRequest){ + if(!mapLoaded){ + MapLoadRequest r = (MapLoadRequest) req; + renderer.loadMap(r.tileBox, downloader.getDownloaderCallbacks()); + mapLoaded = true; + } + } + } + if(update || amenityLoaded || transportLoaded || mapLoaded){ + // use downloader callback + for(IMapDownloaderCallback c : downloader.getDownloaderCallbacks()){ + c.tileDownloaded(null); + } + } + boolean routeBeingCalculated = context.getRoutingHelper().isRouteBeingCalculated(); + if (progress != 0 || routeBeingCalculated || downloader.isSomethingBeingDownloaded()) { + synchronized (ResourceManager.this) { + if (busyIndicator != null) { + if(routeBeingCalculated){ + progress = BusyIndicator.STATUS_BLUE; + } else if(downloader.isSomethingBeingDownloaded()){ + progress = BusyIndicator.STATUS_GREEN; + } else { + progress = 0; + } + busyIndicator.updateStatus(progress); + } + } + } + sleep(750); + } catch (InterruptedException e) { + log.error(e, e); + } catch (RuntimeException e){ + log.error(e, e); + } + } + } + + public void requestToLoadImage(TileLoadDownloadRequest req){ + requests.push(req); + } + public void requestToLoadAmenities(AmenityLoadRequest req){ + requests.push(req); + } + + public void requestToLoadMap(MapLoadRequest req){ + requests.push(req); + } + + public void requestToLoadTransport(TransportLoadRequest req){ + requests.push(req); + } + }; +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/activities/DownloadIndexActivity.java b/OsmAnd/src/net/osmand/plus/activities/DownloadIndexActivity.java index f38b645e2a..89d0d1d843 100644 --- a/OsmAnd/src/net/osmand/plus/activities/DownloadIndexActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/DownloadIndexActivity.java @@ -1,174 +1,174 @@ -package net.osmand.plus.activities; - -import static net.osmand.data.index.IndexConstants.BINARY_MAP_INDEX_EXT; -import static net.osmand.data.index.IndexConstants.BINARY_MAP_INDEX_EXT_ZIP; -import static net.osmand.data.index.IndexConstants.BINARY_MAP_VERSION; -import static net.osmand.data.index.IndexConstants.POI_INDEX_EXT; -import static net.osmand.data.index.IndexConstants.POI_INDEX_EXT_ZIP; -import static net.osmand.data.index.IndexConstants.POI_TABLE_VERSION; -import static net.osmand.data.index.IndexConstants.VOICE_INDEX_EXT_ZIP; -import static net.osmand.data.index.IndexConstants.VOICE_VERSION; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.FilenameFilter; -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.text.MessageFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Map.Entry; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -import net.osmand.IProgress; -import net.osmand.LogUtil; -import net.osmand.data.index.IndexConstants; -import net.osmand.plus.DownloadOsmandIndexesHelper; -import net.osmand.plus.OsmandSettings; -import net.osmand.plus.ProgressDialogImplementation; -import net.osmand.plus.R; -import net.osmand.plus.ResourceManager; -import net.osmand.plus.DownloadOsmandIndexesHelper.IndexItem; - -import org.apache.commons.logging.Log; - -import android.app.AlertDialog; -import android.app.ListActivity; -import android.app.ProgressDialog; -import android.app.AlertDialog.Builder; -import android.content.DialogInterface; -import android.graphics.Color; -import android.os.Bundle; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ArrayAdapter; -import android.widget.CheckBox; -import android.widget.EditText; -import android.widget.Filter; -import android.widget.Filterable; -import android.widget.ListView; -import android.widget.TextView; -import android.widget.Toast; - -public class DownloadIndexActivity extends ListActivity { - - private final static Log log = LogUtil.getLog(DownloadIndexActivity.class); - private static final int RELOAD_ID = 0; - private static final int SELECT_ALL_ID = 1; - private static final int DESELECT_ALL_ID = 2; - private static final int FILTER_EXISTING_REGIONS = 3; - - private static DownloadIndexListThread downloadListIndexThread = new DownloadIndexListThread(); - - private ProgressDialog progressFileDlg = null; - private ProgressDialog progressListDlg = null; - private Map indexFileNames = null; - private LinkedHashMap entriesToDownload = new LinkedHashMap(); - private TextWatcher textWatcher = new TextWatcher() { - - public void afterTextChanged(Editable s) { - } - - public void beforeTextChanged(CharSequence s, int start, int count, - int after) { - } - - public void onTextChanged(CharSequence s, int start, int before, - int count) { - DownloadIndexAdapter adapter = ((DownloadIndexAdapter)getListAdapter()); - if(adapter != null){ - adapter.getFilter().filter(s); - } - } - - }; - - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - // recreation upon rotation is prevented in manifest file - setContentView(R.layout.download_index); - findViewById(R.id.DownloadButton).setOnClickListener(new View.OnClickListener(){ - - @Override - public void onClick(View v) { - downloadFiles(); - } - - }); - - indexFileNames = ((OsmandApplication)getApplication()).getResourceManager().getIndexFileNames(); - - EditText filterText = (EditText) findViewById(R.id.search_box); - filterText.addTextChangedListener(textWatcher); - - if(downloadListIndexThread.getCachedIndexFiles() != null){ - setListAdapter(new DownloadIndexAdapter(downloadListIndexThread.getCachedIndexFiles())); - } else { - downloadIndexList(); - } - } - - private void downloadIndexList() { - progressListDlg = ProgressDialog.show(this, getString(R.string.downloading), getString(R.string.downloading_list_indexes)); - progressListDlg.setCancelable(true); - downloadListIndexThread.setUiActivity(this); - if(downloadListIndexThread.getState() == Thread.State.NEW){ - downloadListIndexThread.start(); - } else if(downloadListIndexThread.getState() == Thread.State.TERMINATED){ - // possibly exception occurred we don't have cache of files - downloadListIndexThread = new DownloadIndexListThread(); - downloadListIndexThread.setUiActivity(this); - downloadListIndexThread.start(); - } - } - - @Override - - public boolean onPrepareOptionsMenu(Menu menu) { - super.onPrepareOptionsMenu(menu); - menu.clear(); - menu.add(0, RELOAD_ID, 0, R.string.reload); - if (getListAdapter() != null) { - // item.setIcon(R.drawable.ic_menu_refresh); - menu.add(0, SELECT_ALL_ID, 0, R.string.select_all); - menu.add(0, DESELECT_ALL_ID, 0, R.string.deselect_all); - menu.add(0, FILTER_EXISTING_REGIONS, 0, R.string.filter_existing_indexes); - } - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if(item.getItemId() == RELOAD_ID){ - //re-create the thread - downloadListIndexThread = new DownloadIndexListThread(); - downloadIndexList(); - } else { - final DownloadIndexAdapter listAdapter = (DownloadIndexAdapter)getListAdapter(); - if(item.getItemId() == SELECT_ALL_ID){ - int selected = 0; - for (int i = 0; i < listAdapter.getCount(); i++) { - IndexItem es = listAdapter.getItem(i); - if(!entriesToDownload.containsKey(es.getFileName())){ - selected++; +package net.osmand.plus.activities; + +import static net.osmand.data.IndexConstants.BINARY_MAP_INDEX_EXT; +import static net.osmand.data.IndexConstants.BINARY_MAP_INDEX_EXT_ZIP; +import static net.osmand.data.IndexConstants.BINARY_MAP_VERSION; +import static net.osmand.data.IndexConstants.POI_INDEX_EXT; +import static net.osmand.data.IndexConstants.POI_INDEX_EXT_ZIP; +import static net.osmand.data.IndexConstants.POI_TABLE_VERSION; +import static net.osmand.data.IndexConstants.VOICE_INDEX_EXT_ZIP; +import static net.osmand.data.IndexConstants.VOICE_VERSION; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.text.MessageFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Map.Entry; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import net.osmand.IProgress; +import net.osmand.LogUtil; +import net.osmand.data.IndexConstants; +import net.osmand.plus.DownloadOsmandIndexesHelper; +import net.osmand.plus.OsmandSettings; +import net.osmand.plus.ProgressDialogImplementation; +import net.osmand.plus.R; +import net.osmand.plus.ResourceManager; +import net.osmand.plus.DownloadOsmandIndexesHelper.IndexItem; + +import org.apache.commons.logging.Log; + +import android.app.AlertDialog; +import android.app.ListActivity; +import android.app.ProgressDialog; +import android.app.AlertDialog.Builder; +import android.content.DialogInterface; +import android.graphics.Color; +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Filter; +import android.widget.Filterable; +import android.widget.ListView; +import android.widget.TextView; +import android.widget.Toast; + +public class DownloadIndexActivity extends ListActivity { + + private final static Log log = LogUtil.getLog(DownloadIndexActivity.class); + private static final int RELOAD_ID = 0; + private static final int SELECT_ALL_ID = 1; + private static final int DESELECT_ALL_ID = 2; + private static final int FILTER_EXISTING_REGIONS = 3; + + private static DownloadIndexListThread downloadListIndexThread = new DownloadIndexListThread(); + + private ProgressDialog progressFileDlg = null; + private ProgressDialog progressListDlg = null; + private Map indexFileNames = null; + private LinkedHashMap entriesToDownload = new LinkedHashMap(); + private TextWatcher textWatcher = new TextWatcher() { + + public void afterTextChanged(Editable s) { + } + + public void beforeTextChanged(CharSequence s, int start, int count, + int after) { + } + + public void onTextChanged(CharSequence s, int start, int before, + int count) { + DownloadIndexAdapter adapter = ((DownloadIndexAdapter)getListAdapter()); + if(adapter != null){ + adapter.getFilter().filter(s); + } + } + + }; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + // recreation upon rotation is prevented in manifest file + setContentView(R.layout.download_index); + findViewById(R.id.DownloadButton).setOnClickListener(new View.OnClickListener(){ + + @Override + public void onClick(View v) { + downloadFiles(); + } + + }); + + indexFileNames = ((OsmandApplication)getApplication()).getResourceManager().getIndexFileNames(); + + EditText filterText = (EditText) findViewById(R.id.search_box); + filterText.addTextChangedListener(textWatcher); + + if(downloadListIndexThread.getCachedIndexFiles() != null){ + setListAdapter(new DownloadIndexAdapter(downloadListIndexThread.getCachedIndexFiles())); + } else { + downloadIndexList(); + } + } + + private void downloadIndexList() { + progressListDlg = ProgressDialog.show(this, getString(R.string.downloading), getString(R.string.downloading_list_indexes)); + progressListDlg.setCancelable(true); + downloadListIndexThread.setUiActivity(this); + if(downloadListIndexThread.getState() == Thread.State.NEW){ + downloadListIndexThread.start(); + } else if(downloadListIndexThread.getState() == Thread.State.TERMINATED){ + // possibly exception occurred we don't have cache of files + downloadListIndexThread = new DownloadIndexListThread(); + downloadListIndexThread.setUiActivity(this); + downloadListIndexThread.start(); + } + } + + @Override + + public boolean onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + menu.clear(); + menu.add(0, RELOAD_ID, 0, R.string.reload); + if (getListAdapter() != null) { + // item.setIcon(R.drawable.ic_menu_refresh); + menu.add(0, SELECT_ALL_ID, 0, R.string.select_all); + menu.add(0, DESELECT_ALL_ID, 0, R.string.deselect_all); + menu.add(0, FILTER_EXISTING_REGIONS, 0, R.string.filter_existing_indexes); + } + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if(item.getItemId() == RELOAD_ID){ + //re-create the thread + downloadListIndexThread = new DownloadIndexListThread(); + downloadIndexList(); + } else { + final DownloadIndexAdapter listAdapter = (DownloadIndexAdapter)getListAdapter(); + if(item.getItemId() == SELECT_ALL_ID){ + int selected = 0; + for (int i = 0; i < listAdapter.getCount(); i++) { + IndexItem es = listAdapter.getItem(i); + if(!entriesToDownload.containsKey(es.getFileName())){ + selected++; entriesToDownload.put(es.getFileName(), createDownloadEntry(es)); } } diff --git a/OsmAnd/src/net/osmand/plus/activities/DownloadTilesDialog.java b/OsmAnd/src/net/osmand/plus/activities/DownloadTilesDialog.java index d949f52eb5..b5d28a375a 100644 --- a/OsmAnd/src/net/osmand/plus/activities/DownloadTilesDialog.java +++ b/OsmAnd/src/net/osmand/plus/activities/DownloadTilesDialog.java @@ -4,9 +4,9 @@ import java.text.MessageFormat; import java.util.ArrayList; import net.osmand.LogUtil; -import net.osmand.data.preparation.MapTileDownloader; -import net.osmand.data.preparation.MapTileDownloader.DownloadRequest; -import net.osmand.data.preparation.MapTileDownloader.IMapDownloaderCallback; +import net.osmand.data.MapTileDownloader; +import net.osmand.data.MapTileDownloader.DownloadRequest; +import net.osmand.data.MapTileDownloader.IMapDownloaderCallback; import net.osmand.map.ITileSource; import net.osmand.osm.MapUtils; import net.osmand.plus.R; diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java index 20a9fe40e3..668014c789 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivity.java @@ -1,294 +1,280 @@ -package net.osmand.plus.activities; - -import java.io.File; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import net.osmand.Algoritms; -import net.osmand.FavouritePoint; -import net.osmand.GPXUtilities; -import net.osmand.LogUtil; -import net.osmand.OsmAndFormatter; -import net.osmand.Version; -import net.osmand.GPXUtilities.GPXFileResult; -import net.osmand.GPXUtilities.WptPt; -import net.osmand.data.Amenity; -import net.osmand.data.AmenityType; -import net.osmand.data.preparation.MapTileDownloader; -import net.osmand.data.preparation.MapTileDownloader.DownloadRequest; -import net.osmand.data.preparation.MapTileDownloader.IMapDownloaderCallback; -import net.osmand.map.IMapLocationListener; -import net.osmand.map.ITileSource; -import net.osmand.osm.LatLon; -import net.osmand.osm.MapUtils; -import net.osmand.plus.AmenityIndexRepository; -import net.osmand.plus.AmenityIndexRepositoryOdb; -import net.osmand.plus.BusyIndicator; -import net.osmand.plus.FavouritesDbHelper; -import net.osmand.plus.OsmandSettings; -import net.osmand.plus.PoiFilter; -import net.osmand.plus.PoiFiltersHelper; -import net.osmand.plus.R; -import net.osmand.plus.ResourceManager; -import net.osmand.plus.SQLiteTileSource; -import net.osmand.plus.OsmandSettings.ApplicationMode; -import net.osmand.plus.activities.search.SearchActivity; -import net.osmand.plus.activities.search.SearchPoiFilterActivity; -import net.osmand.plus.activities.search.SearchTransportActivity; -import net.osmand.plus.render.MapRenderRepositories; -import net.osmand.plus.render.RendererLayer; -import net.osmand.plus.views.AnimateDraggingMapThread; -import net.osmand.plus.views.ContextMenuLayer; -import net.osmand.plus.views.FavoritesLayer; -import net.osmand.plus.views.GPXLayer; -import net.osmand.plus.views.MapInfoLayer; -import net.osmand.plus.views.OsmBugsLayer; -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.YandexTrafficLayer; -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.ProgressDialog; -import android.app.AlertDialog.Builder; -import android.content.ActivityNotFoundException; -import android.content.ComponentName; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.SharedPreferences.Editor; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.res.Resources; -import android.graphics.Rect; -import android.graphics.RectF; -import android.hardware.Sensor; -import android.hardware.SensorEvent; -import android.hardware.SensorEventListener; -import android.hardware.SensorManager; -import android.location.Location; -import android.location.LocationListener; -import android.location.LocationManager; -import android.location.LocationProvider; -import android.media.AudioManager; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.os.Environment; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.os.PowerManager; -import android.os.PowerManager.WakeLock; -import android.text.ClipboardManager; -import android.text.Html; -import android.util.FloatMath; -import android.util.Log; -import android.view.KeyEvent; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.MotionEvent; -import android.view.View; -import android.view.Window; -import android.view.View.OnClickListener; -import android.widget.CompoundButton; -import android.widget.EditText; -import android.widget.ImageButton; -import android.widget.LinearLayout; -import android.widget.Toast; -import android.widget.ToggleButton; -import android.widget.ZoomControls; - -public class MapActivity extends Activity implements IMapLocationListener, SensorEventListener { - - private static final String GPS_STATUS_ACTIVITY = "com.eclipsim.gpsstatus2.GPSStatus"; //$NON-NLS-1$ - private static final String GPS_STATUS_COMPONENT = "com.eclipsim.gpsstatus2"; //$NON-NLS-1$ - - // stupid error but anyway hero 2.1 : always lost gps signal (temporarily unavailable) for timeout = 2000 - private static final int GPS_TIMEOUT_REQUEST = 1000; - private static final int GPS_DIST_REQUEST = 5; - // use only gps (not network) for 12 seconds - private static final int USE_ONLY_GPS_INTERVAL = 12000; - - private boolean providerSupportsBearing = false; - @SuppressWarnings("unused") - private boolean providerSupportsSpeed = false; - private String currentLocationProvider = null; - private long lastTimeAutoZooming = 0; - private long lastTimeGPXLocationFixed = 0; - - /** Called when the activity is first created. */ - private OsmandMapTileView mapView; - private MapActivityActions mapActions = new MapActivityActions(this); - - private ImageButton backToLocation; - private ImageButton backToMenu; - - // the order of layer should be preserved ! when you are inserting new layer - private RendererLayer rendererLayer; - private GPXLayer gpxLayer; - private RouteLayer routeLayer; - private YandexTrafficLayer trafficLayer; - private OsmBugsLayer osmBugsLayer; - private POIMapLayer poiMapLayer; - private FavoritesLayer favoritesLayer; - private TransportStopsLayer transportStopsLayer; - private TransportInfoLayer transportInfoLayer; - private PointLocationLayer locationLayer; - private PointNavigationLayer navigationLayer; - private MapInfoLayer mapInfoLayer; - private ContextMenuLayer contextMenuLayer; - private RouteInfoLayer routeInfoLayer; - - private SavingTrackHelper savingTrackHelper; - private RoutingHelper routingHelper; - - - private WakeLock wakeLock; - private boolean sensorRegistered = false; - - private NotificationManager mNotificationManager; - private Handler mapPositionHandler = null; - private int APP_NOTIFICATION_ID; - private int currentScreenOrientation; - private int currentMapRotation; - private boolean currentShowingAngle; - - private Dialog progressDlg = null; - private SharedPreferences settings; - - private boolean isMapLinkedToLocation(){ - return OsmandSettings.isMapSyncToGpsLocation(settings); - } - - private Notification getNotification(){ - Intent notificationIndent = new Intent(this, MapActivity.class); - notificationIndent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); - Notification notification = new Notification(R.drawable.icon, "", //$NON-NLS-1$ - System.currentTimeMillis()); - notification.setLatestEventInfo(this, Version.APP_NAME, - getString(R.string.go_back_to_osmand), PendingIntent.getActivity( - this, 0, notificationIndent, - PendingIntent.FLAG_UPDATE_CURRENT)); - return notification; - } - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - settings = OsmandSettings.getPrefs(this); - // for voice navigation - setVolumeControlStream(AudioManager.STREAM_MUSIC); - requestWindowFeature(Window.FEATURE_NO_TITLE); - // Full screen is not used here -// getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); - setContentView(R.layout.main); - ProgressDialog dlg = ((OsmandApplication)getApplication()).checkApplicationIsBeingInitialized(this); - if(dlg != null){ - // Do some action on close - dlg.setOnDismissListener(new DialogInterface.OnDismissListener(){ - @Override - public void onDismiss(DialogInterface dialog) { - OsmandApplication app = ((OsmandApplication)getApplication()); - if(OsmandSettings.isUsingMapVectorData(settings) && app.getResourceManager().getRenderer().isEmpty()){ - Toast.makeText(MapActivity.this, getString(R.string.no_vector_map_loaded), Toast.LENGTH_LONG).show(); - } - } - }); - } - parseLaunchIntentLocation(); - - mapView = (OsmandMapTileView) findViewById(R.id.MapView); - mapView.setTrackBallDelegate(new OsmandMapTileView.OnTrackBallListener(){ - @Override - public boolean onTrackBallEvent(MotionEvent e) { - showAndHideMapPosition(); - return MapActivity.this.onTrackballEvent(e); - } - - }); - MapTileDownloader.getInstance().addDownloaderCallback(new IMapDownloaderCallback(){ - @Override - public void tileDownloaded(DownloadRequest request) { - if(request != null && !request.error && request.fileToSave != null){ - ResourceManager mgr = ((OsmandApplication)getApplication()).getResourceManager(); - mgr.tileDownloaded(request); - } - mapView.tileDownloaded(request); - - } - }); - - mapView.setMapLocationListener(this); - routingHelper = ((OsmandApplication) getApplication()).getRoutingHelper(); - - // 0.5 layer - rendererLayer = new RendererLayer(); - mapView.addLayer(rendererLayer, 0.5f); - - // 0.6 gpx layer - gpxLayer = new GPXLayer(); - mapView.addLayer(gpxLayer, 0.6f); - - // 1. route layer - routeLayer = new RouteLayer(routingHelper); - mapView.addLayer(routeLayer, 1); - - // 1.5. traffic layer - trafficLayer = new YandexTrafficLayer(); - mapView.addLayer(trafficLayer, 1.5f); - - - // 2. osm bugs layer - osmBugsLayer = new OsmBugsLayer(this); - // 3. poi layer - poiMapLayer = new POIMapLayer(); - // 4. favorites layer - favoritesLayer = new FavoritesLayer(); - // 5. transport layer - transportStopsLayer = new TransportStopsLayer(); - // 5.5 transport info layer - transportInfoLayer = new TransportInfoLayer(TransportRouteHelper.getInstance()); - mapView.addLayer(transportInfoLayer, 5.5f); - // 6. point navigation layer - navigationLayer = new PointNavigationLayer(); - mapView.addLayer(navigationLayer, 6); - // 7. point location layer - locationLayer = new PointLocationLayer(); - mapView.addLayer(locationLayer, 7); - // 8. map info layer - mapInfoLayer = new MapInfoLayer(this, routeLayer); - mapView.addLayer(mapInfoLayer, 8); - // 9. context menu layer - contextMenuLayer = new ContextMenuLayer(this); - mapView.addLayer(contextMenuLayer, 9); - // 10. route info layer - routeInfoLayer = new RouteInfoLayer(routingHelper, (LinearLayout) findViewById(R.id.RouteLayout)); - mapView.addLayer(routeInfoLayer, 10); - - - - savingTrackHelper = new SavingTrackHelper(this); - - LatLon pointToNavigate = OsmandSettings.getPointToNavigate(settings); - +package net.osmand.plus.activities; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; + +import net.osmand.Algoritms; +import net.osmand.FavouritePoint; +import net.osmand.GPXUtilities; +import net.osmand.LogUtil; +import net.osmand.OsmAndFormatter; +import net.osmand.Version; +import net.osmand.GPXUtilities.GPXFileResult; +import net.osmand.GPXUtilities.WptPt; +import net.osmand.data.AmenityType; +import net.osmand.data.MapTileDownloader; +import net.osmand.data.MapTileDownloader.DownloadRequest; +import net.osmand.data.MapTileDownloader.IMapDownloaderCallback; +import net.osmand.map.IMapLocationListener; +import net.osmand.map.ITileSource; +import net.osmand.osm.LatLon; +import net.osmand.plus.BusyIndicator; +import net.osmand.plus.FavouritesDbHelper; +import net.osmand.plus.OsmandSettings; +import net.osmand.plus.PoiFilter; +import net.osmand.plus.PoiFiltersHelper; +import net.osmand.plus.R; +import net.osmand.plus.ResourceManager; +import net.osmand.plus.SQLiteTileSource; +import net.osmand.plus.OsmandSettings.ApplicationMode; +import net.osmand.plus.activities.search.SearchActivity; +import net.osmand.plus.activities.search.SearchPoiFilterActivity; +import net.osmand.plus.activities.search.SearchTransportActivity; +import net.osmand.plus.render.MapRenderRepositories; +import net.osmand.plus.render.RendererLayer; +import net.osmand.plus.views.AnimateDraggingMapThread; +import net.osmand.plus.views.ContextMenuLayer; +import net.osmand.plus.views.FavoritesLayer; +import net.osmand.plus.views.GPXLayer; +import net.osmand.plus.views.MapInfoLayer; +import net.osmand.plus.views.OsmBugsLayer; +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.YandexTrafficLayer; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.ProgressDialog; +import android.app.AlertDialog.Builder; +import android.content.ActivityNotFoundException; +import android.content.ComponentName; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.location.LocationProvider; +import android.media.AudioManager; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Environment; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.os.PowerManager; +import android.os.PowerManager.WakeLock; +import android.util.Log; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.MotionEvent; +import android.view.View; +import android.view.Window; +import android.view.View.OnClickListener; +import android.widget.CompoundButton; +import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.Toast; +import android.widget.ToggleButton; +import android.widget.ZoomControls; + +public class MapActivity extends Activity implements IMapLocationListener, SensorEventListener { + + private static final String GPS_STATUS_ACTIVITY = "com.eclipsim.gpsstatus2.GPSStatus"; //$NON-NLS-1$ + private static final String GPS_STATUS_COMPONENT = "com.eclipsim.gpsstatus2"; //$NON-NLS-1$ + + // stupid error but anyway hero 2.1 : always lost gps signal (temporarily unavailable) for timeout = 2000 + private static final int GPS_TIMEOUT_REQUEST = 1000; + private static final int GPS_DIST_REQUEST = 5; + // use only gps (not network) for 12 seconds + private static final int USE_ONLY_GPS_INTERVAL = 12000; + + private boolean providerSupportsBearing = false; + @SuppressWarnings("unused") + private boolean providerSupportsSpeed = false; + private String currentLocationProvider = null; + private long lastTimeAutoZooming = 0; + private long lastTimeGPXLocationFixed = 0; + + /** Called when the activity is first created. */ + private OsmandMapTileView mapView; + private MapActivityActions mapActions = new MapActivityActions(this); + + private ImageButton backToLocation; + private ImageButton backToMenu; + + // the order of layer should be preserved ! when you are inserting new layer + private RendererLayer rendererLayer; + private GPXLayer gpxLayer; + private RouteLayer routeLayer; + private YandexTrafficLayer trafficLayer; + private OsmBugsLayer osmBugsLayer; + private POIMapLayer poiMapLayer; + private FavoritesLayer favoritesLayer; + private TransportStopsLayer transportStopsLayer; + private TransportInfoLayer transportInfoLayer; + private PointLocationLayer locationLayer; + private PointNavigationLayer navigationLayer; + private MapInfoLayer mapInfoLayer; + private ContextMenuLayer contextMenuLayer; + private RouteInfoLayer routeInfoLayer; + + private SavingTrackHelper savingTrackHelper; + private RoutingHelper routingHelper; + + + private WakeLock wakeLock; + private boolean sensorRegistered = false; + + private NotificationManager mNotificationManager; + private Handler mapPositionHandler = null; + private int APP_NOTIFICATION_ID; + private int currentScreenOrientation; + private int currentMapRotation; + private boolean currentShowingAngle; + + private Dialog progressDlg = null; + private SharedPreferences settings; + + private boolean isMapLinkedToLocation(){ + return OsmandSettings.isMapSyncToGpsLocation(settings); + } + + private Notification getNotification(){ + Intent notificationIndent = new Intent(this, MapActivity.class); + notificationIndent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); + Notification notification = new Notification(R.drawable.icon, "", //$NON-NLS-1$ + System.currentTimeMillis()); + notification.setLatestEventInfo(this, Version.APP_NAME, + getString(R.string.go_back_to_osmand), PendingIntent.getActivity( + this, 0, notificationIndent, + PendingIntent.FLAG_UPDATE_CURRENT)); + return notification; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + settings = OsmandSettings.getPrefs(this); + // for voice navigation + setVolumeControlStream(AudioManager.STREAM_MUSIC); + requestWindowFeature(Window.FEATURE_NO_TITLE); + // Full screen is not used here +// getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); + setContentView(R.layout.main); + ProgressDialog dlg = ((OsmandApplication)getApplication()).checkApplicationIsBeingInitialized(this); + if(dlg != null){ + // Do some action on close + dlg.setOnDismissListener(new DialogInterface.OnDismissListener(){ + @Override + public void onDismiss(DialogInterface dialog) { + OsmandApplication app = ((OsmandApplication)getApplication()); + if(OsmandSettings.isUsingMapVectorData(settings) && app.getResourceManager().getRenderer().isEmpty()){ + Toast.makeText(MapActivity.this, getString(R.string.no_vector_map_loaded), Toast.LENGTH_LONG).show(); + } + } + }); + } + parseLaunchIntentLocation(); + + mapView = (OsmandMapTileView) findViewById(R.id.MapView); + mapView.setTrackBallDelegate(new OsmandMapTileView.OnTrackBallListener(){ + @Override + public boolean onTrackBallEvent(MotionEvent e) { + showAndHideMapPosition(); + return MapActivity.this.onTrackballEvent(e); + } + + }); + MapTileDownloader.getInstance().addDownloaderCallback(new IMapDownloaderCallback(){ + @Override + public void tileDownloaded(DownloadRequest request) { + if(request != null && !request.error && request.fileToSave != null){ + ResourceManager mgr = ((OsmandApplication)getApplication()).getResourceManager(); + mgr.tileDownloaded(request); + } + mapView.tileDownloaded(request); + + } + }); + + mapView.setMapLocationListener(this); + routingHelper = ((OsmandApplication) getApplication()).getRoutingHelper(); + + // 0.5 layer + rendererLayer = new RendererLayer(); + mapView.addLayer(rendererLayer, 0.5f); + + // 0.6 gpx layer + gpxLayer = new GPXLayer(); + mapView.addLayer(gpxLayer, 0.6f); + + // 1. route layer + routeLayer = new RouteLayer(routingHelper); + mapView.addLayer(routeLayer, 1); + + // 1.5. traffic layer + trafficLayer = new YandexTrafficLayer(); + mapView.addLayer(trafficLayer, 1.5f); + + + // 2. osm bugs layer + osmBugsLayer = new OsmBugsLayer(this); + // 3. poi layer + poiMapLayer = new POIMapLayer(); + // 4. favorites layer + favoritesLayer = new FavoritesLayer(); + // 5. transport layer + transportStopsLayer = new TransportStopsLayer(); + // 5.5 transport info layer + transportInfoLayer = new TransportInfoLayer(TransportRouteHelper.getInstance()); + mapView.addLayer(transportInfoLayer, 5.5f); + // 6. point navigation layer + navigationLayer = new PointNavigationLayer(); + mapView.addLayer(navigationLayer, 6); + // 7. point location layer + locationLayer = new PointLocationLayer(); + mapView.addLayer(locationLayer, 7); + // 8. map info layer + mapInfoLayer = new MapInfoLayer(this, routeLayer); + mapView.addLayer(mapInfoLayer, 8); + // 9. context menu layer + contextMenuLayer = new ContextMenuLayer(this); + mapView.addLayer(contextMenuLayer, 9); + // 10. route info layer + routeInfoLayer = new RouteInfoLayer(routingHelper, (LinearLayout) findViewById(R.id.RouteLayout)); + mapView.addLayer(routeInfoLayer, 10); + + + + savingTrackHelper = new SavingTrackHelper(this); + + LatLon pointToNavigate = OsmandSettings.getPointToNavigate(settings); + // This situtation could be when navigation suddenly crashed and after restarting // it tries to continue the last route if(!Algoritms.objectEquals(routingHelper.getFinalLocation(), pointToNavigate)){ diff --git a/OsmAnd/src/net/osmand/plus/activities/ShowRouteInfoActivity.java b/OsmAnd/src/net/osmand/plus/activities/ShowRouteInfoActivity.java index b8e65431df..a1458029ed 100644 --- a/OsmAnd/src/net/osmand/plus/activities/ShowRouteInfoActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/ShowRouteInfoActivity.java @@ -7,7 +7,6 @@ import java.text.MessageFormat; import java.util.List; import net.osmand.OsmAndFormatter; -import net.osmand.osm.MapUtils; import net.osmand.plus.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.activities.RoutingHelper.RouteDirectionInfo; diff --git a/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java b/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java index 09d6a4fb1c..9a4bf7c841 100644 --- a/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java +++ b/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java @@ -24,8 +24,8 @@ import net.osmand.binary.BinaryMapDataObject; import net.osmand.binary.BinaryMapIndexReader; import net.osmand.binary.BinaryMapIndexReader.SearchRequest; import net.osmand.binary.BinaryMapIndexReader.TagValuePair; -import net.osmand.data.index.IndexConstants; -import net.osmand.data.preparation.MapTileDownloader.IMapDownloaderCallback; +import net.osmand.data.IndexConstants; +import net.osmand.data.MapTileDownloader.IMapDownloaderCallback; import net.osmand.osm.MapRenderingTypes; import net.osmand.osm.MapUtils; import net.osmand.osm.MultyPolygon; diff --git a/OsmAnd/src/net/osmand/plus/render/OsmandRenderer.java b/OsmAnd/src/net/osmand/plus/render/OsmandRenderer.java index 41381cafe6..27e70f0732 100644 --- a/OsmAnd/src/net/osmand/plus/render/OsmandRenderer.java +++ b/OsmAnd/src/net/osmand/plus/render/OsmandRenderer.java @@ -14,7 +14,7 @@ import java.util.Map; import net.osmand.LogUtil; import net.osmand.binary.BinaryMapDataObject; import net.osmand.binary.BinaryMapIndexReader.TagValuePair; -import net.osmand.data.preparation.MapTileDownloader.IMapDownloaderCallback; +import net.osmand.data.MapTileDownloader.IMapDownloaderCallback; import net.osmand.osm.MapRenderingTypes; import net.osmand.osm.MultyPolygon; import net.sf.junidecode.Junidecode; diff --git a/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java b/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java index aefac8f8d1..d9520af0b0 100644 --- a/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java +++ b/OsmAnd/src/net/osmand/plus/views/OsmandMapTileView.java @@ -7,9 +7,9 @@ import java.util.List; import java.util.Map; import net.osmand.LogUtil; -import net.osmand.data.preparation.MapTileDownloader; -import net.osmand.data.preparation.MapTileDownloader.DownloadRequest; -import net.osmand.data.preparation.MapTileDownloader.IMapDownloaderCallback; +import net.osmand.data.MapTileDownloader; +import net.osmand.data.MapTileDownloader.DownloadRequest; +import net.osmand.data.MapTileDownloader.IMapDownloaderCallback; import net.osmand.map.IMapLocationListener; import net.osmand.map.ITileSource; import net.osmand.osm.LatLon; diff --git a/OsmAnd/src/net/osmand/plus/voice/CommandPlayer.java b/OsmAnd/src/net/osmand/plus/voice/CommandPlayer.java index 0755784010..5d7cacbab5 100644 --- a/OsmAnd/src/net/osmand/plus/voice/CommandPlayer.java +++ b/OsmAnd/src/net/osmand/plus/voice/CommandPlayer.java @@ -12,7 +12,7 @@ import java.util.Iterator; import java.util.List; import net.osmand.LogUtil; -import net.osmand.data.index.IndexConstants; +import net.osmand.data.IndexConstants; import net.osmand.plus.OsmandSettings; import net.osmand.plus.R; import net.osmand.plus.ResourceManager;