add transport index
git-svn-id: https://osmand.googlecode.com/svn/trunk@269 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
parent
508acd5fe3
commit
29703f0d70
9 changed files with 395 additions and 26 deletions
|
@ -21,27 +21,28 @@ public class ToDoConstants {
|
||||||
// 50. Invent opening hours editor in order to edit POI hours better on device
|
// 50. Invent opening hours editor in order to edit POI hours better on device
|
||||||
// GOT by Olga
|
// GOT by Olga
|
||||||
|
|
||||||
// TODO sort hamlets by distance
|
|
||||||
// 60. Audio guidance for routing
|
// 60. Audio guidance for routing
|
||||||
// 61. Provide route information for YOURS (calclate turns/angle/expected time).
|
// 61. Provide route information for YOURS (calclate turns/angle/expected time).
|
||||||
// Fix some missing turns in CloudMade (for secondary roads wo name). Add them (if dist to prev/next turn > 150m) [dacha]
|
// Fix some missing turns in CloudMade (for secondary roads wo name). Add them (if dist to prev/next turn > 150m) [dacha]
|
||||||
// 33. Build transport locations. Create transport index (transport-stops) (investigate)
|
// 33. Build transport locations. Create transport index (transport-stops) (investigate)
|
||||||
// DONE: Load transport routes in swing.
|
// DONE: Load transport routes in swing.
|
||||||
// IDEA TO HAVE :
|
// IDEA TO HAVE :
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 43. Enable poi filter by name
|
// 43. Enable poi filter by name
|
||||||
// 58. Upload/Download zip-index from site & unzip them on phone
|
// 58. Upload/Download zip-index from site & unzip them on phone
|
||||||
// 45. Get clear <Use internet> settings. Move that setting on top settings screen.
|
// 45. Get clear <Use internet> settings. Move that setting on top settings screen.
|
||||||
// That setting should rule all activities that use internet. It should ask whenever internet is used
|
// That setting should rule all activities that use internet. It should ask whenever internet is used
|
||||||
// (would you like to use internet for that operation - if using internet is not checked).
|
// (would you like to use internet for that operation - if using internet is not checked).
|
||||||
// Internet using now for : edit POI osm, show osm bugs layer, download tiles.
|
// Internet using now for : edit POI osm, show osm bugs layer, download tiles.
|
||||||
|
|
||||||
|
// 64. Traffic information (?)
|
||||||
|
// 65. Intermediate points (?)
|
||||||
// 40. Support simple vector road rendering (require new index file) (?)
|
// 40. Support simple vector road rendering (require new index file) (?)
|
||||||
// 63. Support simple offline routing(require new index file) (?)
|
// 63. Support simple offline routing(require new index file) (?)
|
||||||
|
|
||||||
// BUGS Android
|
// BUGS Android
|
||||||
// FIXME !!!! Check agains ID is not unique ! (for relation/node/way - it could be the same)
|
// FIXME !!!! Check agains ID is not unique ! (for relation/node/way - it could be the same) - checked for data extraction & index creator
|
||||||
|
|
||||||
// TODO swing
|
// TODO swing
|
||||||
// 9. Fix issues with big files (such as netherlands) - save memory (!) - very slow due to transport index !
|
// 9. Fix issues with big files (such as netherlands) - save memory (!) - very slow due to transport index !
|
||||||
|
|
|
@ -103,5 +103,10 @@ public abstract class MapObject implements Comparable<MapObject> {
|
||||||
public void doDataPreparation() {
|
public void doDataPreparation() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getClass().getSimpleName() + " " + name +"("+id+")";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.osmand.osm.MapUtils;
|
||||||
import com.osmand.osm.Relation;
|
import com.osmand.osm.Relation;
|
||||||
import com.osmand.osm.Way;
|
import com.osmand.osm.Way;
|
||||||
|
|
||||||
|
@ -12,6 +13,8 @@ public class TransportRoute extends MapObject {
|
||||||
private List<TransportStop> forwardStops = new ArrayList<TransportStop>();
|
private List<TransportStop> forwardStops = new ArrayList<TransportStop>();
|
||||||
private List<TransportStop> backwardStops = new ArrayList<TransportStop>();
|
private List<TransportStop> backwardStops = new ArrayList<TransportStop>();
|
||||||
private String ref;
|
private String ref;
|
||||||
|
private String operator;
|
||||||
|
private String type;
|
||||||
|
|
||||||
public TransportRoute(Relation r, String ref){
|
public TransportRoute(Relation r, String ref){
|
||||||
super(r);
|
super(r);
|
||||||
|
@ -48,5 +51,32 @@ public class TransportRoute extends MapObject {
|
||||||
this.ref = ref;
|
this.ref = ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getOperator() {
|
||||||
|
return operator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOperator(String operator) {
|
||||||
|
this.operator = operator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAvgBothDistance(){
|
||||||
|
int d = 0;
|
||||||
|
for(int i=1; i< backwardStops.size(); i++){
|
||||||
|
d += MapUtils.getDistance(backwardStops.get(i-1).getLocation(), backwardStops.get(i).getLocation());
|
||||||
|
}
|
||||||
|
for(int i=1; i< forwardStops.size(); i++){
|
||||||
|
d += MapUtils.getDistance(forwardStops.get(i-1).getLocation(), forwardStops.get(i).getLocation());
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,10 @@ import java.sql.PreparedStatement;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
|
@ -19,12 +22,17 @@ import com.osmand.data.Building;
|
||||||
import com.osmand.data.City;
|
import com.osmand.data.City;
|
||||||
import com.osmand.data.Region;
|
import com.osmand.data.Region;
|
||||||
import com.osmand.data.Street;
|
import com.osmand.data.Street;
|
||||||
|
import com.osmand.data.TransportRoute;
|
||||||
|
import com.osmand.data.TransportStop;
|
||||||
import com.osmand.data.City.CityType;
|
import com.osmand.data.City.CityType;
|
||||||
import com.osmand.data.index.IndexConstants.IndexBuildingTable;
|
import com.osmand.data.index.IndexConstants.IndexBuildingTable;
|
||||||
import com.osmand.data.index.IndexConstants.IndexCityTable;
|
import com.osmand.data.index.IndexConstants.IndexCityTable;
|
||||||
import com.osmand.data.index.IndexConstants.IndexPoiTable;
|
import com.osmand.data.index.IndexConstants.IndexPoiTable;
|
||||||
import com.osmand.data.index.IndexConstants.IndexStreetNodeTable;
|
import com.osmand.data.index.IndexConstants.IndexStreetNodeTable;
|
||||||
import com.osmand.data.index.IndexConstants.IndexStreetTable;
|
import com.osmand.data.index.IndexConstants.IndexStreetTable;
|
||||||
|
import com.osmand.data.index.IndexConstants.IndexTransportRoute;
|
||||||
|
import com.osmand.data.index.IndexConstants.IndexTransportRouteStop;
|
||||||
|
import com.osmand.data.index.IndexConstants.IndexTransportStop;
|
||||||
import com.osmand.osm.Node;
|
import com.osmand.osm.Node;
|
||||||
import com.osmand.osm.Way;
|
import com.osmand.osm.Way;
|
||||||
|
|
||||||
|
@ -239,6 +247,107 @@ public class DataIndexWriter {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public DataIndexWriter writeTransport() throws IOException, SQLException{
|
||||||
|
return writeTransport(IndexConstants.TRANSPORT_INDEX_DIR+region.getName()+IndexConstants.TRANSPORT_INDEX_EXT, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataIndexWriter writeTransport(String fileName, Long date) throws IOException, SQLException{
|
||||||
|
File file = checkFile(fileName);
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
try {
|
||||||
|
Class.forName("org.sqlite.JDBC"); //$NON-NLS-1$
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
log.error("Illegal configuration", e); //$NON-NLS-1$
|
||||||
|
throw new IllegalStateException(e);
|
||||||
|
}
|
||||||
|
Connection conn = DriverManager.getConnection("jdbc:sqlite:"+file.getAbsolutePath()); //$NON-NLS-1$
|
||||||
|
try {
|
||||||
|
Statement stat = conn.createStatement();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
stat.executeUpdate(IndexConstants.generateCreateSQL(IndexTransportRoute.values()));
|
||||||
|
stat.executeUpdate(IndexConstants.generateCreateIndexSQL(IndexTransportRoute.values()));
|
||||||
|
stat.executeUpdate(IndexConstants.generateCreateSQL(IndexTransportRouteStop.values()));
|
||||||
|
stat.executeUpdate(IndexConstants.generateCreateIndexSQL(IndexTransportRouteStop.values()));
|
||||||
|
stat.executeUpdate(IndexConstants.generateCreateSQL(IndexTransportStop.values()));
|
||||||
|
stat.executeUpdate(IndexConstants.generateCreateIndexSQL(IndexTransportStop.values()));
|
||||||
|
stat.execute("PRAGMA user_version = " + IndexConstants.TRANSPORT_TABLE_VERSION); //$NON-NLS-1$
|
||||||
|
stat.close();
|
||||||
|
|
||||||
|
PreparedStatement prepRoute = conn.prepareStatement(
|
||||||
|
IndexConstants.generatePrepareStatementToInsert(IndexTransportRoute.getTable(), IndexTransportRoute.values().length));
|
||||||
|
PreparedStatement prepRouteStops = conn.prepareStatement(
|
||||||
|
IndexConstants.generatePrepareStatementToInsert(IndexTransportRouteStop.getTable(), IndexTransportRouteStop.values().length));
|
||||||
|
PreparedStatement prepStops = conn.prepareStatement(
|
||||||
|
IndexConstants.generatePrepareStatementToInsert(IndexTransportStop.getTable(), IndexTransportStop.values().length));
|
||||||
|
Map<PreparedStatement, Integer> count = new HashMap<PreparedStatement, Integer>();
|
||||||
|
count.put(prepRouteStops, 0);
|
||||||
|
count.put(prepRoute, 0);
|
||||||
|
count.put(prepStops, 0);
|
||||||
|
conn.setAutoCommit(false);
|
||||||
|
|
||||||
|
|
||||||
|
Set<Long> writtenStops = new LinkedHashSet<Long>();
|
||||||
|
for(String t : region.getTransportRoutes().keySet()){
|
||||||
|
for(TransportRoute r : region.getTransportRoutes().get(t)) {
|
||||||
|
assert IndexTransportRoute.values().length == 7;
|
||||||
|
prepRoute.setLong(IndexTransportRoute.ID.ordinal() + 1, r.getId());
|
||||||
|
prepRoute.setString(IndexTransportRoute.TYPE.ordinal() + 1, r.getType());
|
||||||
|
prepRoute.setString(IndexTransportRoute.OPERATOR.ordinal() + 1, r.getOperator());
|
||||||
|
prepRoute.setString(IndexTransportRoute.REF.ordinal() + 1, r.getRef());
|
||||||
|
prepRoute.setString(IndexTransportRoute.NAME.ordinal() + 1, r.getName());
|
||||||
|
prepRoute.setString(IndexTransportRoute.NAME_EN.ordinal() + 1, r.getEnName());
|
||||||
|
prepRoute.setInt(IndexTransportRoute.DIST.ordinal() + 1, r.getAvgBothDistance());
|
||||||
|
addBatch(count, prepRoute);
|
||||||
|
|
||||||
|
writeRouteStops(prepRouteStops, prepStops, count, writtenStops, r, r.getForwardStops(), true);
|
||||||
|
writeRouteStops(prepRouteStops, prepStops, count, writtenStops, r, r.getBackwardStops(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(PreparedStatement p : count.keySet()){
|
||||||
|
if(count.get(p) > 0){
|
||||||
|
p.executeBatch();
|
||||||
|
}
|
||||||
|
p.close();
|
||||||
|
}
|
||||||
|
conn.setAutoCommit(true);
|
||||||
|
} finally {
|
||||||
|
conn.close();
|
||||||
|
log.info(String.format("Indexing transport done in %s ms.", System.currentTimeMillis() - now)); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if(date != null){
|
||||||
|
file.setLastModified(date);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeRouteStops(PreparedStatement prepRouteStops, PreparedStatement prepStops, Map<PreparedStatement, Integer> count,
|
||||||
|
Set<Long> writtenStops, TransportRoute r, List<TransportStop> stops, boolean direction) throws SQLException {
|
||||||
|
for(TransportStop s : stops){
|
||||||
|
if (!writtenStops.contains(s.getId())) {
|
||||||
|
assert IndexTransportStop.values().length == 5;
|
||||||
|
prepStops.setLong(IndexTransportStop.ID.ordinal() + 1, s.getId());
|
||||||
|
prepStops.setDouble(IndexTransportStop.LATITUDE.ordinal() + 1, s.getLocation().getLatitude());
|
||||||
|
prepStops.setDouble(IndexTransportStop.LONGITUDE.ordinal() + 1, s.getLocation().getLongitude());
|
||||||
|
prepStops.setString(IndexTransportStop.NAME.ordinal() + 1, s.getName());
|
||||||
|
prepStops.setString(IndexTransportStop.NAME_EN.ordinal() + 1, s.getEnName());
|
||||||
|
addBatch(count, prepStops);
|
||||||
|
writtenStops.add(s.getId());
|
||||||
|
}
|
||||||
|
assert IndexTransportRouteStop.values().length == 3;
|
||||||
|
prepRouteStops.setLong(IndexTransportRouteStop.ROUTE.ordinal() + 1, r.getId());
|
||||||
|
prepRouteStops.setLong(IndexTransportRouteStop.STOP.ordinal() + 1, s.getId());
|
||||||
|
prepRouteStops.setBoolean(IndexTransportRouteStop.DIRECTION.ordinal() + 1, direction);
|
||||||
|
addBatch(count, prepRouteStops);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void addBatch(Map<PreparedStatement, Integer> count, PreparedStatement p) throws SQLException{
|
private void addBatch(Map<PreparedStatement, Integer> count, PreparedStatement p) throws SQLException{
|
||||||
p.addBatch();
|
p.addBatch();
|
||||||
if(count.get(p) >= BATCH_SIZE){
|
if(count.get(p) >= BATCH_SIZE){
|
||||||
|
|
|
@ -4,14 +4,17 @@ public class IndexConstants {
|
||||||
|
|
||||||
// Important : Every time you change schema of db upgrade version!!!
|
// 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
|
// If you want that new application support old index : put upgrade code in android app ResourceManager
|
||||||
|
public final static int TRANSPORT_TABLE_VERSION = 0;
|
||||||
public final static int POI_TABLE_VERSION = 0;
|
public final static int POI_TABLE_VERSION = 0;
|
||||||
public final static int ADDRESS_TABLE_VERSION = 1;
|
public final static int ADDRESS_TABLE_VERSION = 1;
|
||||||
|
|
||||||
public static final String POI_INDEX_DIR = "POI/"; //$NON-NLS-1$
|
public static final String POI_INDEX_DIR = "POI/"; //$NON-NLS-1$
|
||||||
public static final String ADDRESS_INDEX_DIR = "Address/"; //$NON-NLS-1$
|
public static final String ADDRESS_INDEX_DIR = "Address/"; //$NON-NLS-1$
|
||||||
|
public static final String TRANSPORT_INDEX_DIR = "Transport/"; //$NON-NLS-1$
|
||||||
|
|
||||||
public static final String POI_INDEX_EXT = ".poi.odb"; //$NON-NLS-1$
|
public static final String POI_INDEX_EXT = ".poi.odb"; //$NON-NLS-1$
|
||||||
public static final String ADDRESS_INDEX_EXT = ".addr.odb"; //$NON-NLS-1$
|
public static final String ADDRESS_INDEX_EXT = ".addr.odb"; //$NON-NLS-1$
|
||||||
|
public static final String TRANSPORT_INDEX_EXT = ".trans.odb"; //$NON-NLS-1$
|
||||||
|
|
||||||
public interface IndexColumn {
|
public interface IndexColumn {
|
||||||
public boolean isIndex();
|
public boolean isIndex();
|
||||||
|
@ -108,6 +111,7 @@ public class IndexConstants {
|
||||||
return b.toString();
|
return b.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// POI index
|
||||||
|
|
||||||
public enum IndexPoiTable implements IndexColumn {
|
public enum IndexPoiTable implements IndexColumn {
|
||||||
ID("long"), LATITUDE("double", true), LONGITUDE("double", true), OPENING_HOURS, NAME, NAME_EN, TYPE, SUBTYPE; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
ID("long"), LATITUDE("double", true), LONGITUDE("double", true), OPENING_HOURS, NAME, NAME_EN, TYPE, SUBTYPE; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||||
|
@ -137,7 +141,8 @@ public class IndexConstants {
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Address index
|
||||||
|
|
||||||
public enum IndexCityTable implements IndexColumn {
|
public enum IndexCityTable implements IndexColumn {
|
||||||
ID("long"), LATITUDE("double", true), LONGITUDE("double", true), NAME, NAME_EN, CITY_TYPE; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
ID("long"), LATITUDE("double", true), LONGITUDE("double", true), NAME, NAME_EN, CITY_TYPE; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||||
|
@ -282,4 +287,115 @@ public class IndexConstants {
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Transport Index
|
||||||
|
public enum IndexTransportStop implements IndexColumn {
|
||||||
|
ID("long"), LATITUDE("double", true), LONGITUDE("double", true), NAME, NAME_EN; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||||
|
boolean index = false;
|
||||||
|
String type = null;
|
||||||
|
|
||||||
|
private IndexTransportStop() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private IndexTransportStop(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IndexTransportStop(String type, boolean index) {
|
||||||
|
this(type);
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getTable() {
|
||||||
|
return "transport_stop"; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTableName() {
|
||||||
|
return getTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public enum IndexTransportRouteStop implements IndexColumn {
|
||||||
|
STOP("long"), ROUTE("long", true), DIRECTION("boolean"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
boolean index = false;
|
||||||
|
String type = null;
|
||||||
|
|
||||||
|
private IndexTransportRouteStop() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private IndexTransportRouteStop(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IndexTransportRouteStop(String type, boolean index) {
|
||||||
|
this(type);
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getTable() {
|
||||||
|
return "transport_route_stop"; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTableName() {
|
||||||
|
return getTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum IndexTransportRoute implements IndexColumn {
|
||||||
|
ID("long", true), TYPE, OPERATOR, REF, NAME, NAME_EN, DIST("int"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
boolean index = false;
|
||||||
|
String type = null;
|
||||||
|
|
||||||
|
private IndexTransportRoute() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private IndexTransportRoute(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IndexTransportRoute(String type, boolean index) {
|
||||||
|
this(type);
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getTable() {
|
||||||
|
return "transport_route"; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTableName() {
|
||||||
|
return getTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,13 @@ import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
@ -323,6 +327,17 @@ public class DataExtraction {
|
||||||
transport.add((Relation) e);
|
transport.add((Relation) e);
|
||||||
processed = true;
|
processed = true;
|
||||||
}
|
}
|
||||||
|
if(e instanceof Node && "bus_stop".equals(e.getTag(OSMTagKey.HIGHWAY))){
|
||||||
|
// load all stops in order to get their names
|
||||||
|
processed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e instanceof Node && e.getTag(OSMTagKey.RAILWAY) != null) {
|
||||||
|
if ("tram_stop".equals(e.getTag(OSMTagKey.RAILWAY)) || "station".equals(e.getTag(OSMTagKey.RAILWAY))) {
|
||||||
|
// load all stops in order to get their names
|
||||||
|
processed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// put all nodes into temporary db to get only required nodes after loading all data
|
// put all nodes into temporary db to get only required nodes after loading all data
|
||||||
try {
|
try {
|
||||||
|
@ -571,6 +586,19 @@ public class DataExtraction {
|
||||||
/// way with name : МЗОР, ул. ...,
|
/// way with name : МЗОР, ул. ...,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Set<String> acceptedRoutes = new HashSet<String>();
|
||||||
|
static {
|
||||||
|
acceptedRoutes.add("bus");
|
||||||
|
acceptedRoutes.add("trolleybus");
|
||||||
|
acceptedRoutes.add("share_taxi");
|
||||||
|
|
||||||
|
acceptedRoutes.add("subway");
|
||||||
|
acceptedRoutes.add("train");
|
||||||
|
|
||||||
|
acceptedRoutes.add("tram");
|
||||||
|
|
||||||
|
acceptedRoutes.add("ferry");
|
||||||
|
}
|
||||||
|
|
||||||
public void readingTransport(final ArrayList<Relation> transport, Region country, IProgress progress){
|
public void readingTransport(final ArrayList<Relation> transport, Region country, IProgress progress){
|
||||||
progress.startTask("Reading transport...", -1);
|
progress.startTask("Reading transport...", -1);
|
||||||
|
@ -579,10 +607,18 @@ public class DataExtraction {
|
||||||
for(Relation rel : transport){
|
for(Relation rel : transport){
|
||||||
String ref = rel.getTag(OSMTagKey.REF);
|
String ref = rel.getTag(OSMTagKey.REF);
|
||||||
String route = rel.getTag(OSMTagKey.ROUTE);
|
String route = rel.getTag(OSMTagKey.ROUTE);
|
||||||
|
String operator = rel.getTag(OSMTagKey.OPERATOR);
|
||||||
if(route == null || ref == null){
|
if(route == null || ref == null){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
String operator = rel.getTag(OSMTagKey.OPERATOR);
|
if(!acceptedRoutes.contains(route)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
TransportRoute r = new TransportRoute(rel, ref);
|
||||||
|
r.setOperator(operator);
|
||||||
|
r.setType(route);
|
||||||
|
|
||||||
|
|
||||||
if(operator != null){
|
if(operator != null){
|
||||||
route = operator + " : " + route;
|
route = operator + " : " + route;
|
||||||
}
|
}
|
||||||
|
@ -590,44 +626,111 @@ public class DataExtraction {
|
||||||
routes.put(route, new ArrayList<TransportRoute>());
|
routes.put(route, new ArrayList<TransportRoute>());
|
||||||
}
|
}
|
||||||
|
|
||||||
TransportRoute r = new TransportRoute(rel, ref);
|
|
||||||
for(Entry<Entity, String> e: rel.getMemberEntities().entrySet()){
|
final Map<TransportStop, Integer> forwardStops = new LinkedHashMap<TransportStop, Integer>();
|
||||||
|
final Map<TransportStop, Integer> backwardStops = new LinkedHashMap<TransportStop, Integer>();
|
||||||
|
int currentStop = 0;
|
||||||
|
int forwardStop = 0;
|
||||||
|
int backwardStop = 0;
|
||||||
|
for (Entry<Entity, String> e : rel.getMemberEntities().entrySet()) {
|
||||||
if(e.getValue().contains("stop")){
|
if(e.getValue().contains("stop")){
|
||||||
if(e.getKey() instanceof Node){
|
if(e.getKey() instanceof Node){
|
||||||
if(!routeStops.containsKey(e.getKey().getId())){
|
if(!routeStops.containsKey(e.getKey().getId())){
|
||||||
routeStops.put(e.getKey().getId(), new TransportStop(e.getKey()));
|
routeStops.put(e.getKey().getId(), new TransportStop(e.getKey()));
|
||||||
}
|
}
|
||||||
TransportStop stop = routeStops.get(e.getKey().getId());
|
TransportStop stop = routeStops.get(e.getKey().getId());
|
||||||
boolean forward = e.getValue().contains("forward") || !e.getValue().contains("backward");
|
boolean forward = e.getValue().contains("forward");
|
||||||
if(forward){
|
boolean backward = e.getValue().contains("backward");
|
||||||
|
currentStop++;
|
||||||
|
if(forward || !backward){
|
||||||
|
forwardStop ++;
|
||||||
|
}
|
||||||
|
if(backward){
|
||||||
|
backwardStop ++;
|
||||||
|
}
|
||||||
|
boolean common = !forward && !backward;
|
||||||
|
int index = -1;
|
||||||
|
int i = e.getValue().length() -1;
|
||||||
|
int accum = 1;
|
||||||
|
while(i >= 0 && Character.isDigit(e.getValue().charAt(i))){
|
||||||
|
if(index < 0){
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
index = accum * Character.getNumericValue(e.getValue().charAt(i)) + index;
|
||||||
|
accum *= 10;
|
||||||
|
i --;
|
||||||
|
}
|
||||||
|
if(index < 0){
|
||||||
|
index = forward ? forwardStop : (backward ? backwardStop : currentStop) ;
|
||||||
|
}
|
||||||
|
if(forward || common){
|
||||||
|
forwardStops.put(stop, index);
|
||||||
r.getForwardStops().add(stop);
|
r.getForwardStops().add(stop);
|
||||||
} else {
|
}
|
||||||
|
if(backward || common){
|
||||||
|
if(common){
|
||||||
|
// put with negative index
|
||||||
|
backwardStops.put(stop, -index);
|
||||||
|
} else {
|
||||||
|
backwardStops.put(stop, index);
|
||||||
|
}
|
||||||
|
|
||||||
r.getBackwardStops().add(stop);
|
r.getBackwardStops().add(stop);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if(e.getKey() instanceof Way){
|
} else if(e.getKey() instanceof Way){
|
||||||
r.addWay((Way) e.getKey());
|
r.addWay((Way) e.getKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(r.getBackwardStops().isEmpty() && !r.getForwardStops().isEmpty()){
|
if(forwardStops.isEmpty() && backwardStops.isEmpty()){
|
||||||
List<TransportStop> stops = r.getBackwardStops();
|
|
||||||
for(TransportStop s : r.getForwardStops()){
|
|
||||||
stops.add(0, s);
|
|
||||||
}
|
|
||||||
} else if(!r.getForwardStops().isEmpty()){
|
|
||||||
if(r.getForwardStops().get(0) != r.getBackwardStops().get(r.getBackwardStops().size() - 1)){
|
|
||||||
r.getBackwardStops().add(r.getForwardStops().get(0));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
Collections.sort(r.getForwardStops(), new Comparator<TransportStop>(){
|
||||||
|
@Override
|
||||||
|
public int compare(TransportStop o1, TransportStop o2) {
|
||||||
|
return forwardStops.get(o1) - forwardStops.get(o2);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// all common stops are with negative index (reeval them)
|
||||||
|
for(TransportStop s : new ArrayList<TransportStop>(backwardStops.keySet())){
|
||||||
|
if(backwardStops.get(s) < 0){
|
||||||
|
backwardStops.put(s, backwardStops.size() + backwardStops.get(s) -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Collections.sort(r.getBackwardStops(), new Comparator<TransportStop>(){
|
||||||
|
@Override
|
||||||
|
public int compare(TransportStop o1, TransportStop o2) {
|
||||||
|
return backwardStops.get(o1) - backwardStops.get(o2);
|
||||||
|
}
|
||||||
|
});
|
||||||
routes.get(route).add(r);
|
routes.get(route).add(r);
|
||||||
|
|
||||||
|
// validate that all is ok
|
||||||
|
// if (validateTransportStops(r.getBackwardStops(), r) && validateTransportStops(r.getForwardStops(), r)) {
|
||||||
|
// System.out.println("Route " + r + " is valid ");
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
progress.finishTask();
|
progress.finishTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean validateTransportStops(List<TransportStop> stops, TransportRoute r){
|
||||||
|
boolean valid = true;
|
||||||
|
for (int i = 2; i < stops.size(); i++) {
|
||||||
|
TransportStop s1 = stops.get(i - 2);
|
||||||
|
TransportStop s2 = stops.get(i - 1);
|
||||||
|
TransportStop s3 = stops.get(i);
|
||||||
|
if (MapUtils.getDistance(s1.getLocation(), s2.getLocation()) > MapUtils.getDistance(s1.getLocation(), s3.getLocation()) * 1.3) {
|
||||||
|
System.out.println("SOMETHING WRONG with " + i + "th of " + r.getRef() +" "+ r );
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
|
}
|
||||||
|
|
||||||
private void readingAmenities(final ArrayList<Entity> amenities, Region country) {
|
private void readingAmenities(final ArrayList<Entity> amenities, Region country) {
|
||||||
for(Entity a: amenities){
|
for(Entity a: amenities){
|
||||||
country.registerAmenity(new Amenity(a));
|
country.registerAmenity(new Amenity(a));
|
||||||
|
@ -733,6 +836,7 @@ public class DataExtraction {
|
||||||
// String path = "E:\\Information\\OSM maps\\minsk_extr.bz2";
|
// String path = "E:\\Information\\OSM maps\\minsk_extr.bz2";
|
||||||
// String path = "E:\\Information\\OSM maps\\netherlands.osm.bz2";
|
// String path = "E:\\Information\\OSM maps\\netherlands.osm.bz2";
|
||||||
String wDir = "E:\\Information\\OSM maps\\osmand\\";
|
String wDir = "E:\\Information\\OSM maps\\osmand\\";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
File f = new File(path);
|
File f = new File(path);
|
||||||
|
|
|
@ -9,6 +9,7 @@ public class OSMSettings {
|
||||||
HIGHWAY("highway"), //$NON-NLS-1$
|
HIGHWAY("highway"), //$NON-NLS-1$
|
||||||
BUILDING("building"), //$NON-NLS-1$
|
BUILDING("building"), //$NON-NLS-1$
|
||||||
POSTAL_CODE("postal_code"), //$NON-NLS-1$
|
POSTAL_CODE("postal_code"), //$NON-NLS-1$
|
||||||
|
RAILWAY("railway"), //$NON-NLS-1$
|
||||||
// transport
|
// transport
|
||||||
ROUTE("route"), //$NON-NLS-1$
|
ROUTE("route"), //$NON-NLS-1$
|
||||||
OPERATOR("operator"), //$NON-NLS-1$
|
OPERATOR("operator"), //$NON-NLS-1$
|
||||||
|
|
|
@ -403,7 +403,7 @@ public class OsmExtractionUI implements IMapLocationListener {
|
||||||
buildTransportIndex = new JCheckBox();
|
buildTransportIndex = new JCheckBox();
|
||||||
buildTransportIndex.setText("Build transport index");
|
buildTransportIndex.setText("Build transport index");
|
||||||
panel.add(buildTransportIndex);
|
panel.add(buildTransportIndex);
|
||||||
buildTransportIndex.setSelected(false);
|
buildTransportIndex.setSelected(true);
|
||||||
|
|
||||||
loadingAllData = new JCheckBox();
|
loadingAllData = new JCheckBox();
|
||||||
loadingAllData.setText("Loading all osm data");
|
loadingAllData.setText("Loading all osm data");
|
||||||
|
@ -433,10 +433,12 @@ public class OsmExtractionUI implements IMapLocationListener {
|
||||||
if(buildAddressIndex.isSelected()){
|
if(buildAddressIndex.isSelected()){
|
||||||
dlg.startTask("Generating address index...", -1);
|
dlg.startTask("Generating address index...", -1);
|
||||||
builder.writeAddress();
|
builder.writeAddress();
|
||||||
msg.append(", Address index ").append("successfully created");
|
msg.append(", address index ").append("successfully created");
|
||||||
}
|
}
|
||||||
if(buildTransportIndex.isSelected()){
|
if(buildTransportIndex.isSelected()){
|
||||||
// TODO
|
dlg.startTask("Generating transport index...", -1);
|
||||||
|
builder.writeTransport();
|
||||||
|
msg.append(", transport index ").append("successfully created");
|
||||||
}
|
}
|
||||||
|
|
||||||
// new DataIndexReader().testIndex(new File(
|
// new DataIndexReader().testIndex(new File(
|
||||||
|
@ -753,6 +755,7 @@ public class OsmExtractionUI implements IMapLocationListener {
|
||||||
}
|
}
|
||||||
} catch (InterruptedException e1) {
|
} catch (InterruptedException e1) {
|
||||||
log.error("Interrupted", e1);
|
log.error("Interrupted", e1);
|
||||||
|
updateButtonsBar();
|
||||||
} catch (InvocationTargetException e1) {
|
} catch (InvocationTargetException e1) {
|
||||||
ExceptionHandler.handle("Exception during operation", e1.getCause());
|
ExceptionHandler.handle("Exception during operation", e1.getCause());
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,7 +158,7 @@ public class OsmandSettings {
|
||||||
|
|
||||||
public static boolean isShowingViewAngle(Context ctx) {
|
public static boolean isShowingViewAngle(Context ctx) {
|
||||||
SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE);
|
SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE);
|
||||||
return prefs.getBoolean(SHOW_VIEW_ANGLE, true);
|
return prefs.getBoolean(SHOW_VIEW_ANGLE, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// this value string is synchronized with settings_pref.xml preference name
|
// this value string is synchronized with settings_pref.xml preference name
|
||||||
|
@ -290,7 +290,7 @@ public class OsmandSettings {
|
||||||
|
|
||||||
public static int getLastKnownMapZoom(Context ctx) {
|
public static int getLastKnownMapZoom(Context ctx) {
|
||||||
SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE);
|
SharedPreferences prefs = ctx.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_WORLD_READABLE);
|
||||||
return prefs.getInt(LAST_KNOWN_MAP_ZOOM, 3);
|
return prefs.getInt(LAST_KNOWN_MAP_ZOOM, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setLastKnownMapZoom(Context ctx, int zoom) {
|
public static void setLastKnownMapZoom(Context ctx, int zoom) {
|
||||||
|
|
Loading…
Reference in a new issue