implement new binary format
git-svn-id: https://osmand.googlecode.com/svn/trunk@593 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
parent
45b8c23ee8
commit
e1f4daa59c
8 changed files with 553 additions and 396 deletions
|
@ -2,13 +2,15 @@ package net.osmand.binary;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Stack;
|
||||
|
||||
import net.osmand.Algoritms;
|
||||
import net.osmand.data.index.IndexConstants;
|
||||
|
||||
import com.google.protobuf.CodedOutputStream;
|
||||
import com.google.protobuf.WireFormat;
|
||||
import com.google.protobuf.WireFormat.JavaType;
|
||||
|
||||
public class BinaryIndexWriter {
|
||||
|
||||
|
@ -31,6 +33,9 @@ public class BinaryIndexWriter {
|
|||
|
||||
}
|
||||
private Stack<Bounds> stackBounds = new Stack<Bounds>();
|
||||
// needed for map tree
|
||||
private Stack<Long> stackBaseIds = new Stack<Long>();
|
||||
private Stack<Map<String, Integer>> stackStringTable = new Stack<Map<String, Integer>>();
|
||||
|
||||
// internal constants to track state of index writing
|
||||
private Stack<Integer> state = new Stack<Integer>();
|
||||
|
@ -38,7 +43,6 @@ public class BinaryIndexWriter {
|
|||
private final static int MAP_INDEX_INIT = 2;
|
||||
private final static int MAP_ROOT_LEVEL_INIT = 3;
|
||||
private final static int MAP_TREE = 4;
|
||||
private final static int MAP_DATA = 5;
|
||||
|
||||
public BinaryIndexWriter(OutputStream out) throws IOException{
|
||||
this.out = out;
|
||||
|
@ -62,12 +66,13 @@ public class BinaryIndexWriter {
|
|||
// /// Simple messages
|
||||
// message MapData {
|
||||
// required bytes coordinates = 1; // array of delta x,y uin32 could be read by codedinputstream
|
||||
// repeated sint32 types = 2;
|
||||
// required bytes types = 2; // array of fixed int16
|
||||
//
|
||||
// required sint64 id = 3; // delta encoded
|
||||
// optional uint32 stringId = 4;
|
||||
//
|
||||
// repeated sint64 restrictions = 5; // delta encoded 3 bytes for type and other for id
|
||||
// repeated sint64 restrictions = 5; // delta encoded 3 bytes for type and other for id
|
||||
// optional int32 highwayMeta = 6;
|
||||
// }
|
||||
|
||||
public void startWriteMapIndex() throws IOException{
|
||||
|
@ -129,7 +134,8 @@ public class BinaryIndexWriter {
|
|||
codedOutStream.writeSInt32(OsmandOdb.MapTree.TOP_FIELD_NUMBER, topY - bounds.topY);
|
||||
codedOutStream.writeSInt32(OsmandOdb.MapTree.BOTTOM_FIELD_NUMBER, bottomY - bounds.bottomY);
|
||||
stackBounds.push(new Bounds(leftX, rightX, topY, bottomY));
|
||||
|
||||
stackBaseIds.push(0L);
|
||||
stackStringTable.push(null);
|
||||
}
|
||||
|
||||
public void endWriteMapTreeElement() throws IOException{
|
||||
|
@ -137,15 +143,93 @@ public class BinaryIndexWriter {
|
|||
state.pop();
|
||||
|
||||
stackBounds.pop();
|
||||
Long l = stackBaseIds.pop();
|
||||
if(l != 0){
|
||||
codedOutStream.writeTag(OsmandOdb.MapTree.BASEID_FIELD_NUMBER, WireFormat.FieldType.UINT64.getWireType());
|
||||
codedOutStream.writeUInt64NoTag(l);
|
||||
}
|
||||
Map<String, Integer> map = stackStringTable.peek();
|
||||
if(map != null){
|
||||
codedOutStream.writeTag(OsmandOdb.MapTree.STRINGTABLE_FIELD_NUMBER, WireFormat.FieldType.MESSAGE.getWireType());
|
||||
// TODO write size
|
||||
codedOutStream.writeFixed32NoTag(0);
|
||||
|
||||
int i = 0;
|
||||
for(String s : map.keySet()){
|
||||
Integer integer = map.get(s);
|
||||
if(integer != i){
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
i++;
|
||||
codedOutStream.writeTag(OsmandOdb.StringTable.S_FIELD_NUMBER, WireFormat.FieldType.MESSAGE.getWireType());
|
||||
codedOutStream.writeStringNoTag(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void writeMapData(long id) throws IOException{
|
||||
public void writeMapData(long id, byte[] nodes, byte[] types, String name, int highwayAttributes, byte[] restrictions) throws IOException{
|
||||
assert state.peek() == MAP_TREE;
|
||||
// TODO
|
||||
codedOutStream.writeInt64NoTag(id);
|
||||
codedOutStream.writeTag(OsmandOdb.MapTree.LEAFS_FIELD_NUMBER, WireFormat.FieldType.MESSAGE.getWireType());
|
||||
// TODO write size of map data !!! here
|
||||
|
||||
Bounds bounds = stackBounds.peek();
|
||||
codedOutStream.writeTag(OsmandOdb.MapData.COORDINATES_FIELD_NUMBER, WireFormat.FieldType.BYTES.getWireType());
|
||||
int size = 0;
|
||||
for(int i=0; i< nodes.length / 8; i++){
|
||||
int x = Algoritms.parseIntFromBytes(nodes, i*8) - bounds.leftX;
|
||||
int y = Algoritms.parseIntFromBytes(nodes, i*8 + 4) - bounds.topY;
|
||||
size += CodedOutputStream.computeInt32SizeNoTag(x);
|
||||
size += CodedOutputStream.computeInt32SizeNoTag(y);
|
||||
}
|
||||
codedOutStream.writeRawVarint32(size);
|
||||
for(int i=0; i< nodes.length / 8; i++){
|
||||
int x = Algoritms.parseIntFromBytes(nodes, i*8) - bounds.leftX;
|
||||
int y = Algoritms.parseIntFromBytes(nodes, i*8 + 4) - bounds.topY;
|
||||
codedOutStream.writeInt32NoTag(x);
|
||||
codedOutStream.writeInt32NoTag(y);
|
||||
}
|
||||
|
||||
codedOutStream.writeTag(OsmandOdb.MapData.TYPES_FIELD_NUMBER, WireFormat.FieldType.BYTES.getWireType());
|
||||
codedOutStream.writeRawVarint32(types.length);
|
||||
codedOutStream.writeRawBytes(types);
|
||||
|
||||
if(stackBaseIds.peek() == 0){
|
||||
stackBaseIds.pop();
|
||||
stackBaseIds.push(id);
|
||||
}
|
||||
codedOutStream.writeTag(OsmandOdb.MapData.ID_FIELD_NUMBER, WireFormat.FieldType.SINT64.getWireType());
|
||||
codedOutStream.writeSInt64NoTag(id - stackBaseIds.peek());
|
||||
|
||||
if(name != null){
|
||||
if(stackStringTable.peek() == null) {
|
||||
stackStringTable.pop();
|
||||
stackStringTable.push(new LinkedHashMap<String, Integer>());
|
||||
}
|
||||
Map<String, Integer> map = stackStringTable.peek();
|
||||
int s;
|
||||
if(map.containsKey(name)) {
|
||||
s = map.get(name);
|
||||
} else {
|
||||
s = map.size();
|
||||
map.put(name, s);
|
||||
}
|
||||
codedOutStream.writeTag(OsmandOdb.MapData.STRINGID_FIELD_NUMBER, WireFormat.FieldType.UINT32.getWireType());
|
||||
codedOutStream.writeUInt32NoTag(s);
|
||||
}
|
||||
|
||||
if(restrictions.length > 0){
|
||||
// TODO restrictions delta?
|
||||
codedOutStream.writeTag(OsmandOdb.MapData.RESTRICTIONS_FIELD_NUMBER, WireFormat.FieldType.BYTES.getWireType());
|
||||
codedOutStream.writeRawVarint32(restrictions.length);
|
||||
codedOutStream.writeRawBytes(restrictions);
|
||||
}
|
||||
if(highwayAttributes != 0){
|
||||
codedOutStream.writeTag(OsmandOdb.MapData.HIGHWAYMETA_FIELD_NUMBER, WireFormat.FieldType.UINT32.getWireType());
|
||||
codedOutStream.writeRawVarint32(highwayAttributes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public void close() throws IOException{
|
||||
assert state.peek() == OSMAND_STRUCTURE_INIT;
|
||||
|
|
|
@ -2310,17 +2310,12 @@ public final class OsmandOdb {
|
|||
public boolean hasCoordinates() { return hasCoordinates; }
|
||||
public com.google.protobuf.ByteString getCoordinates() { return coordinates_; }
|
||||
|
||||
// repeated sint32 types = 2;
|
||||
// required bytes types = 2;
|
||||
public static final int TYPES_FIELD_NUMBER = 2;
|
||||
private java.util.List<java.lang.Integer> types_ =
|
||||
java.util.Collections.emptyList();
|
||||
public java.util.List<java.lang.Integer> getTypesList() {
|
||||
return types_;
|
||||
}
|
||||
public int getTypesCount() { return types_.size(); }
|
||||
public int getTypes(int index) {
|
||||
return types_.get(index);
|
||||
}
|
||||
private boolean hasTypes;
|
||||
private com.google.protobuf.ByteString types_ = com.google.protobuf.ByteString.EMPTY;
|
||||
public boolean hasTypes() { return hasTypes; }
|
||||
public com.google.protobuf.ByteString getTypes() { return types_; }
|
||||
|
||||
// required sint64 id = 3;
|
||||
public static final int ID_FIELD_NUMBER = 3;
|
||||
|
@ -2348,10 +2343,18 @@ public final class OsmandOdb {
|
|||
return restrictions_.get(index);
|
||||
}
|
||||
|
||||
// optional int32 highwayMeta = 6;
|
||||
public static final int HIGHWAYMETA_FIELD_NUMBER = 6;
|
||||
private boolean hasHighwayMeta;
|
||||
private int highwayMeta_ = 0;
|
||||
public boolean hasHighwayMeta() { return hasHighwayMeta; }
|
||||
public int getHighwayMeta() { return highwayMeta_; }
|
||||
|
||||
private void initFields() {
|
||||
}
|
||||
public final boolean isInitialized() {
|
||||
if (!hasCoordinates) return false;
|
||||
if (!hasTypes) return false;
|
||||
if (!hasId) return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -2362,8 +2365,8 @@ public final class OsmandOdb {
|
|||
if (hasCoordinates()) {
|
||||
output.writeBytes(1, getCoordinates());
|
||||
}
|
||||
for (int element : getTypesList()) {
|
||||
output.writeSInt32(2, element);
|
||||
if (hasTypes()) {
|
||||
output.writeBytes(2, getTypes());
|
||||
}
|
||||
if (hasId()) {
|
||||
output.writeSInt64(3, getId());
|
||||
|
@ -2374,6 +2377,9 @@ public final class OsmandOdb {
|
|||
for (long element : getRestrictionsList()) {
|
||||
output.writeSInt64(5, element);
|
||||
}
|
||||
if (hasHighwayMeta()) {
|
||||
output.writeInt32(6, getHighwayMeta());
|
||||
}
|
||||
getUnknownFields().writeTo(output);
|
||||
}
|
||||
|
||||
|
@ -2387,14 +2393,9 @@ public final class OsmandOdb {
|
|||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(1, getCoordinates());
|
||||
}
|
||||
{
|
||||
int dataSize = 0;
|
||||
for (int element : getTypesList()) {
|
||||
dataSize += com.google.protobuf.CodedOutputStream
|
||||
.computeSInt32SizeNoTag(element);
|
||||
}
|
||||
size += dataSize;
|
||||
size += 1 * getTypesList().size();
|
||||
if (hasTypes()) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeBytesSize(2, getTypes());
|
||||
}
|
||||
if (hasId()) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
|
@ -2413,6 +2414,10 @@ public final class OsmandOdb {
|
|||
size += dataSize;
|
||||
size += 1 * getRestrictionsList().size();
|
||||
}
|
||||
if (hasHighwayMeta()) {
|
||||
size += com.google.protobuf.CodedOutputStream
|
||||
.computeInt32Size(6, getHighwayMeta());
|
||||
}
|
||||
size += getUnknownFields().getSerializedSize();
|
||||
memoizedSerializedSize = size;
|
||||
return size;
|
||||
|
@ -2555,10 +2560,6 @@ public final class OsmandOdb {
|
|||
throw new IllegalStateException(
|
||||
"build() has already been called on this Builder.");
|
||||
}
|
||||
if (result.types_ != java.util.Collections.EMPTY_LIST) {
|
||||
result.types_ =
|
||||
java.util.Collections.unmodifiableList(result.types_);
|
||||
}
|
||||
if (result.restrictions_ != java.util.Collections.EMPTY_LIST) {
|
||||
result.restrictions_ =
|
||||
java.util.Collections.unmodifiableList(result.restrictions_);
|
||||
|
@ -2582,11 +2583,8 @@ public final class OsmandOdb {
|
|||
if (other.hasCoordinates()) {
|
||||
setCoordinates(other.getCoordinates());
|
||||
}
|
||||
if (!other.types_.isEmpty()) {
|
||||
if (result.types_.isEmpty()) {
|
||||
result.types_ = new java.util.ArrayList<java.lang.Integer>();
|
||||
}
|
||||
result.types_.addAll(other.types_);
|
||||
if (other.hasTypes()) {
|
||||
setTypes(other.getTypes());
|
||||
}
|
||||
if (other.hasId()) {
|
||||
setId(other.getId());
|
||||
|
@ -2600,6 +2598,9 @@ public final class OsmandOdb {
|
|||
}
|
||||
result.restrictions_.addAll(other.restrictions_);
|
||||
}
|
||||
if (other.hasHighwayMeta()) {
|
||||
setHighwayMeta(other.getHighwayMeta());
|
||||
}
|
||||
this.mergeUnknownFields(other.getUnknownFields());
|
||||
return this;
|
||||
}
|
||||
|
@ -2629,17 +2630,8 @@ public final class OsmandOdb {
|
|||
setCoordinates(input.readBytes());
|
||||
break;
|
||||
}
|
||||
case 16: {
|
||||
addTypes(input.readSInt32());
|
||||
break;
|
||||
}
|
||||
case 18: {
|
||||
int length = input.readRawVarint32();
|
||||
int limit = input.pushLimit(length);
|
||||
while (input.getBytesUntilLimit() > 0) {
|
||||
addTypes(input.readSInt32());
|
||||
}
|
||||
input.popLimit(limit);
|
||||
setTypes(input.readBytes());
|
||||
break;
|
||||
}
|
||||
case 24: {
|
||||
|
@ -2663,6 +2655,10 @@ public final class OsmandOdb {
|
|||
input.popLimit(limit);
|
||||
break;
|
||||
}
|
||||
case 48: {
|
||||
setHighwayMeta(input.readInt32());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2689,37 +2685,24 @@ public final class OsmandOdb {
|
|||
return this;
|
||||
}
|
||||
|
||||
// repeated sint32 types = 2;
|
||||
public java.util.List<java.lang.Integer> getTypesList() {
|
||||
return java.util.Collections.unmodifiableList(result.types_);
|
||||
// required bytes types = 2;
|
||||
public boolean hasTypes() {
|
||||
return result.hasTypes();
|
||||
}
|
||||
public int getTypesCount() {
|
||||
return result.getTypesCount();
|
||||
public com.google.protobuf.ByteString getTypes() {
|
||||
return result.getTypes();
|
||||
}
|
||||
public int getTypes(int index) {
|
||||
return result.getTypes(index);
|
||||
}
|
||||
public Builder setTypes(int index, int value) {
|
||||
result.types_.set(index, value);
|
||||
return this;
|
||||
}
|
||||
public Builder addTypes(int value) {
|
||||
if (result.types_.isEmpty()) {
|
||||
result.types_ = new java.util.ArrayList<java.lang.Integer>();
|
||||
}
|
||||
result.types_.add(value);
|
||||
return this;
|
||||
}
|
||||
public Builder addAllTypes(
|
||||
java.lang.Iterable<? extends java.lang.Integer> values) {
|
||||
if (result.types_.isEmpty()) {
|
||||
result.types_ = new java.util.ArrayList<java.lang.Integer>();
|
||||
}
|
||||
super.addAll(values, result.types_);
|
||||
public Builder setTypes(com.google.protobuf.ByteString value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
result.hasTypes = true;
|
||||
result.types_ = value;
|
||||
return this;
|
||||
}
|
||||
public Builder clearTypes() {
|
||||
result.types_ = java.util.Collections.emptyList();
|
||||
result.hasTypes = false;
|
||||
result.types_ = getDefaultInstance().getTypes();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -2793,6 +2776,24 @@ public final class OsmandOdb {
|
|||
return this;
|
||||
}
|
||||
|
||||
// optional int32 highwayMeta = 6;
|
||||
public boolean hasHighwayMeta() {
|
||||
return result.hasHighwayMeta();
|
||||
}
|
||||
public int getHighwayMeta() {
|
||||
return result.getHighwayMeta();
|
||||
}
|
||||
public Builder setHighwayMeta(int value) {
|
||||
result.hasHighwayMeta = true;
|
||||
result.highwayMeta_ = value;
|
||||
return this;
|
||||
}
|
||||
public Builder clearHighwayMeta() {
|
||||
result.hasHighwayMeta = false;
|
||||
result.highwayMeta_ = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
// @@protoc_insertion_point(builder_scope:MapData)
|
||||
}
|
||||
|
||||
|
@ -2855,10 +2856,11 @@ public final class OsmandOdb {
|
|||
"top\030\003 \002(\021\022\016\n\006bottom\030\004 \002(\021\022!\n\013stringTable" +
|
||||
"\030\005 \001(\0132\014.StringTable\022\016\n\006baseId\030\006 \001(\004\022\032\n\010",
|
||||
"subtrees\030\007 \003(\0132\010.MapTree\022\027\n\005leafs\030\010 \003(\0132" +
|
||||
"\010.MapData\"\030\n\013StringTable\022\t\n\001s\030\001 \003(\t\"a\n\007M" +
|
||||
"apData\022\023\n\013coordinates\030\001 \002(\014\022\r\n\005types\030\002 \003" +
|
||||
"(\021\022\n\n\002id\030\003 \002(\022\022\020\n\010stringId\030\004 \001(\r\022\024\n\014rest" +
|
||||
"rictions\030\005 \003(\022B\023\n\021net.osmand.binary"
|
||||
"\010.MapData\"\030\n\013StringTable\022\t\n\001s\030\001 \003(\t\"v\n\007M" +
|
||||
"apData\022\023\n\013coordinates\030\001 \002(\014\022\r\n\005types\030\002 \002" +
|
||||
"(\014\022\n\n\002id\030\003 \002(\022\022\020\n\010stringId\030\004 \001(\r\022\024\n\014rest" +
|
||||
"rictions\030\005 \003(\022\022\023\n\013highwayMeta\030\006 \001(\005B\023\n\021n" +
|
||||
"et.osmand.binary"
|
||||
};
|
||||
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||
|
@ -2910,7 +2912,7 @@ public final class OsmandOdb {
|
|||
internal_static_MapData_fieldAccessorTable = new
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||
internal_static_MapData_descriptor,
|
||||
new java.lang.String[] { "Coordinates", "Types", "Id", "StringId", "Restrictions", },
|
||||
new java.lang.String[] { "Coordinates", "Types", "Id", "StringId", "Restrictions", "HighwayMeta", },
|
||||
net.osmand.binary.OsmandOdb.MapData.class,
|
||||
net.osmand.binary.OsmandOdb.MapData.Builder.class);
|
||||
return null;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package net.osmand.data.index;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
@ -190,44 +191,23 @@ public class DataIndexWriter {
|
|||
|
||||
public static void createMapIndexStructure(Connection conn) throws SQLException{
|
||||
Statement stat = conn.createStatement();
|
||||
stat.execute(IndexConstants.generateCreateSQL(IndexMapRenderObject.values()));
|
||||
stat.execute(IndexConstants.generateCreateIndexSQL(IndexMapRenderObject.values()));
|
||||
stat.execute(IndexConstants.generateCreateSQL(IndexBinaryMapRenderObject.values()));
|
||||
stat.execute(IndexConstants.generateCreateIndexSQL(IndexBinaryMapRenderObject.values()));
|
||||
stat.execute("CREATE VIRTUAL TABLE "+IndexConstants.indexMapLocationsTable+" USING rtree (id, minLon, maxLon, minLat, maxLat);"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
stat.execute("CREATE VIRTUAL TABLE "+IndexConstants.indexMapLocationsTable2+" USING rtree (id, minLon, maxLon, minLat, maxLat);"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
stat.execute("CREATE VIRTUAL TABLE "+IndexConstants.indexMapLocationsTable3+" USING rtree (id, minLon, maxLon, minLat, maxLat);"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
stat.execute("PRAGMA user_version = " + IndexConstants.MAP_TABLE_VERSION); //$NON-NLS-1$
|
||||
stat.close();
|
||||
}
|
||||
|
||||
public static PreparedStatement createStatementMapWaysInsert(Connection conn) throws SQLException{
|
||||
assert IndexMapRenderObject.values().length == 4;
|
||||
return conn.prepareStatement(IndexConstants.generatePrepareStatementToInsert(IndexMapRenderObject.getTable(), 4));
|
||||
}
|
||||
|
||||
|
||||
public static PreparedStatement createStatementMapBinaryInsert(Connection conn) throws SQLException{
|
||||
assert IndexBinaryMapRenderObject.values().length == 5;
|
||||
return conn.prepareStatement(IndexConstants.generatePrepareStatementToInsert(IndexBinaryMapRenderObject.getTable(), 5));
|
||||
}
|
||||
public static PreparedStatement createStatementMapWaysLocationsInsert(Connection conn) throws SQLException{
|
||||
return conn.prepareStatement(IndexConstants.generatePrepareStatementToInsert(IndexConstants.indexMapLocationsTable, 5));
|
||||
}
|
||||
public static PreparedStatement createStatementMapWaysLocationsInsertLevel2(Connection conn) throws SQLException{
|
||||
return conn.prepareStatement(IndexConstants.generatePrepareStatementToInsert(IndexConstants.indexMapLocationsTable2, 5));
|
||||
}
|
||||
|
||||
public static PreparedStatement createStatementMapWaysLocationsInsertLevel3(Connection conn) throws SQLException{
|
||||
return conn.prepareStatement(IndexConstants.generatePrepareStatementToInsert(IndexConstants.indexMapLocationsTable3, 5));
|
||||
assert IndexBinaryMapRenderObject.values().length == 6;
|
||||
return conn.prepareStatement(IndexConstants.generatePrepareStatementToInsert(IndexBinaryMapRenderObject.getTable(), 6));
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void insertMapRenderObjectIndex(Map<PreparedStatement, Integer> statements,
|
||||
PreparedStatement mapStat, PreparedStatement mapWayLocationsStat,
|
||||
RTree mapTree, Entity e, String name,
|
||||
long id, int type, List<Integer> typeUse, List<Long> restrictions, boolean writeRestrictions,
|
||||
public static void insertBinaryMapRenderObjectIndex(Map<PreparedStatement, Integer> statements,
|
||||
PreparedStatement mapBinaryStat, RTree mapTree, Entity e, String name,
|
||||
long id, int type, List<Integer> typeUse, int highwayAttributes, List<Long> restrictions,
|
||||
boolean inversePath, boolean writeAsPoint, int batchSize) throws SQLException {
|
||||
assert IndexMapRenderObject.values().length == 4;
|
||||
assert IndexBinaryMapRenderObject.values().length == 6;
|
||||
if(e instanceof Relation){
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
@ -236,10 +216,6 @@ public class DataIndexWriter {
|
|||
int maxX = 0;
|
||||
int minY = Integer.MAX_VALUE;
|
||||
int maxY = 0;
|
||||
double minLat = 180;
|
||||
double maxLat = -180;
|
||||
double minLon = 360;
|
||||
double maxLon = -360;
|
||||
Collection<Node> nodes;
|
||||
if (e instanceof Way) {
|
||||
if (writeAsPoint) {
|
||||
|
@ -256,68 +232,43 @@ public class DataIndexWriter {
|
|||
Collections.reverse((List<?>) nodes);
|
||||
}
|
||||
|
||||
byte[] bytes;
|
||||
int offset = 0;
|
||||
boolean multiType = (type & 1) == 1;
|
||||
int len = nodes.size() * 8;
|
||||
if(multiType){
|
||||
len += typeUse.size() * 2 + 1;
|
||||
}
|
||||
if(writeRestrictions){
|
||||
len += restrictions.size() * 8 + 1;
|
||||
}
|
||||
bytes = new byte[len];
|
||||
if(multiType){
|
||||
bytes[offset++] = (byte) typeUse.size();
|
||||
}
|
||||
if(writeRestrictions){
|
||||
bytes[offset++] = (byte) restrictions.size();
|
||||
}
|
||||
if(multiType){
|
||||
for(Integer i : typeUse){
|
||||
Algoritms.putSmallIntBytes(bytes, offset, i);
|
||||
offset += 2;
|
||||
}
|
||||
}
|
||||
if(writeRestrictions){
|
||||
for(Long i : restrictions){
|
||||
Algoritms.putLongToBytes(bytes, offset, i);
|
||||
offset += 8;
|
||||
}
|
||||
}
|
||||
|
||||
ByteArrayOutputStream bnodes = new ByteArrayOutputStream();
|
||||
ByteArrayOutputStream btypes = new ByteArrayOutputStream();
|
||||
ByteArrayOutputStream brestrictions = new ByteArrayOutputStream();
|
||||
for (Node n : nodes) {
|
||||
if (n != null) {
|
||||
int y = MapUtils.get31TileNumberY(n.getLatitude());
|
||||
int x = MapUtils.get31TileNumberX(n.getLongitude());
|
||||
minLat = Math.min(minLat, n.getLatitude());
|
||||
maxLat = Math.max(maxLat, n.getLatitude());
|
||||
minLon = Math.min(minLon, n.getLongitude());
|
||||
maxLon = Math.max(maxLon, n.getLongitude());
|
||||
minX = Math.min(minX, x);
|
||||
maxX = Math.max(maxX, x);
|
||||
minY = Math.min(minY, y);
|
||||
maxY = Math.max(maxY, y);
|
||||
init = true;
|
||||
Algoritms.putIntToBytes(bytes, offset, y);
|
||||
offset += 4;
|
||||
Algoritms.putIntToBytes(bytes, offset, x);
|
||||
offset += 4;
|
||||
|
||||
|
||||
|
||||
try {
|
||||
Algoritms.writeSmallInt(btypes, type);
|
||||
for (Integer i : typeUse) {
|
||||
Algoritms.writeSmallInt(btypes, i);
|
||||
}
|
||||
for (Long i : restrictions) {
|
||||
Algoritms.writeLongInt(brestrictions, i);
|
||||
}
|
||||
|
||||
for (Node n : nodes) {
|
||||
if (n != null) {
|
||||
int y = MapUtils.get31TileNumberY(n.getLatitude());
|
||||
int x = MapUtils.get31TileNumberX(n.getLongitude());
|
||||
minX = Math.min(minX, x);
|
||||
maxX = Math.max(maxX, x);
|
||||
minY = Math.min(minY, y);
|
||||
maxY = Math.max(maxY, y);
|
||||
init = true;
|
||||
Algoritms.writeInt(bnodes, x);
|
||||
Algoritms.writeInt(bnodes, y);
|
||||
}
|
||||
}
|
||||
} catch (IOException es) {
|
||||
throw new IllegalStateException(es);
|
||||
}
|
||||
if (init) {
|
||||
|
||||
|
||||
mapStat.setLong(IndexMapRenderObject.ID.ordinal() + 1, id);
|
||||
mapStat.setInt(IndexMapRenderObject.TYPE.ordinal() + 1, type);
|
||||
mapStat.setString(IndexMapRenderObject.NAME.ordinal() + 1, name);
|
||||
mapStat.setBytes(IndexMapRenderObject.NODES.ordinal() + 1, bytes);
|
||||
addBatch(statements, mapStat);
|
||||
mapBinaryStat.setLong(IndexBinaryMapRenderObject.ID.ordinal() + 1, id);
|
||||
mapBinaryStat.setBytes(IndexBinaryMapRenderObject.TYPES.ordinal() + 1, btypes.toByteArray());
|
||||
mapBinaryStat.setBytes(IndexBinaryMapRenderObject.RESTRICTIONS.ordinal() + 1, brestrictions.toByteArray());
|
||||
mapBinaryStat.setBytes(IndexBinaryMapRenderObject.NODES.ordinal() + 1, bnodes.toByteArray());
|
||||
mapBinaryStat.setInt(IndexBinaryMapRenderObject.HIGHWAY.ordinal() + 1, highwayAttributes);
|
||||
mapBinaryStat.setString(IndexBinaryMapRenderObject.NAME.ordinal() + 1, name);
|
||||
addBatch(statements, mapBinaryStat);
|
||||
|
||||
|
||||
try {
|
||||
|
@ -327,17 +278,6 @@ public class DataIndexWriter {
|
|||
} catch (IllegalValueException e1) {
|
||||
throw new IllegalArgumentException(e1);
|
||||
}
|
||||
|
||||
mapWayLocationsStat.setLong(1, id);
|
||||
mapWayLocationsStat.setFloat(2, (float) minLon);
|
||||
mapWayLocationsStat.setFloat(3, (float) maxLon);
|
||||
mapWayLocationsStat.setFloat(4, (float) minLat);
|
||||
mapWayLocationsStat.setFloat(5, (float) maxLat);
|
||||
// mapWayLocationsStat.setInt(2, minX);
|
||||
// mapWayLocationsStat.setInt(3, maxX);
|
||||
// mapWayLocationsStat.setInt(4, minY);
|
||||
// mapWayLocationsStat.setInt(5, maxY);
|
||||
addBatch(statements, mapWayLocationsStat);
|
||||
}
|
||||
}
|
||||
private static void addBatch(Map<PreparedStatement, Integer> count, PreparedStatement p) throws SQLException{
|
||||
|
|
|
@ -454,7 +454,7 @@ public class IndexConstants {
|
|||
}
|
||||
|
||||
public enum IndexBinaryMapRenderObject implements IndexColumn {
|
||||
ID("long", true), NAME, TYPES("BLOB"), RESTRICTIONS("BLOB"), NODES("BLOB"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
ID("long", true), NAME, TYPES("BLOB"), RESTRICTIONS("BLOB"), NODES("BLOB"), HIGHWAY("INT"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
boolean index = false;
|
||||
String type = null;
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import java.io.FileInputStream;
|
|||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
|
@ -38,6 +39,7 @@ import net.osmand.data.TransportStop;
|
|||
import net.osmand.data.City.CityType;
|
||||
import net.osmand.data.index.DataIndexWriter;
|
||||
import net.osmand.data.index.IndexConstants;
|
||||
import net.osmand.data.index.IndexConstants.IndexBinaryMapRenderObject;
|
||||
import net.osmand.data.index.IndexConstants.IndexBuildingTable;
|
||||
import net.osmand.data.index.IndexConstants.IndexCityTable;
|
||||
import net.osmand.data.index.IndexConstants.IndexStreetNodeTable;
|
||||
|
@ -147,11 +149,9 @@ public class IndexCreator {
|
|||
|
||||
private File mapFile;
|
||||
private Connection mapConnection;
|
||||
private PreparedStatement mapObjStat;
|
||||
private PreparedStatement mapLocsStatLevel0;
|
||||
private PreparedStatement mapLocsStatLevel1;
|
||||
private PreparedStatement mapLocsStatLevel2;
|
||||
private RTree mapTree;
|
||||
private PreparedStatement mapBinaryStat;
|
||||
private static final int[] MAP_ZOOMS = new int[]{6, 9, 14, 22};
|
||||
private RTree[] mapTree = null;
|
||||
|
||||
private File binaryMapFile;
|
||||
|
||||
|
@ -982,9 +982,10 @@ public class IndexCreator {
|
|||
// manipulate what kind of way to load
|
||||
loadEntityData(e, true);
|
||||
boolean inverse = "-1".equals(e.getTag(OSMTagKey.ONEWAY));
|
||||
writeBinaryEntityToMapDatabase(e, e.getId(), inverse, 0);
|
||||
writeBinaryEntityToMapDatabase(e, e.getId(), false, 1);
|
||||
writeBinaryEntityToMapDatabase(e, e.getId(), false, 2);
|
||||
for (int i = 0; i < MAP_ZOOMS.length - 1; i++) {
|
||||
writeBinaryEntityToMapDatabase(e, e.getId(), i == 0 ? inverse : false, i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (indexAddress) {
|
||||
|
@ -1382,10 +1383,8 @@ public class IndexCreator {
|
|||
return;
|
||||
}
|
||||
|
||||
boolean useRestrictions = false;
|
||||
restrictionsUse.clear();
|
||||
if (MapRenderingTypes.isHighwayType(type >> 1)) {
|
||||
useRestrictions = true;
|
||||
if (MapRenderingTypes.isHighwayType(type)) {
|
||||
// try to find restrictions only for max zoom level
|
||||
if (level == 0 && highwayRestrictions.containsKey(baseId)) {
|
||||
restrictionsUse.addAll(highwayRestrictions.get(baseId));
|
||||
|
@ -1393,22 +1392,12 @@ public class IndexCreator {
|
|||
|
||||
}
|
||||
|
||||
boolean point = ((type >> 1) & 3) == MapRenderingTypes.POINT_TYPE;
|
||||
PreparedStatement mapLocations;
|
||||
boolean point = (type & 3) == MapRenderingTypes.POINT_TYPE;
|
||||
RTree rtree = null;
|
||||
int zoom;
|
||||
long id = baseId << 3;
|
||||
if (level == 1) {
|
||||
id |= 2;
|
||||
mapLocations = mapLocsStatLevel1;
|
||||
zoom = 12;
|
||||
} else if (level == 2) {
|
||||
id |= 4;
|
||||
zoom = 7;
|
||||
mapLocations = mapLocsStatLevel2;
|
||||
} else {
|
||||
zoom = 18;
|
||||
mapLocations = mapLocsStatLevel0;
|
||||
}
|
||||
long id = (baseId << 3) | ((level & 3) << 1);
|
||||
rtree = mapTree[level];
|
||||
zoom = MAP_ZOOMS[MAP_ZOOMS.length - level - 1] - 2;
|
||||
boolean skip = false;
|
||||
if (e instanceof Way) {
|
||||
id |= 1;
|
||||
|
@ -1448,166 +1437,45 @@ public class IndexCreator {
|
|||
}
|
||||
|
||||
if (!skip) {
|
||||
int highwayAttributes = 0;
|
||||
if(MapRenderingTypes.isHighwayType(type)){
|
||||
highwayAttributes = MapRenderingTypes.getHighwayAttributes(e);
|
||||
}
|
||||
String eName = MapRenderingTypes.getEntityName(e, type);
|
||||
if (eName == null) {
|
||||
eName = multiPolygonsNames.get(baseId);
|
||||
}
|
||||
DataIndexWriter.insertMapRenderObjectIndex(pStatements, mapObjStat, mapLocations, mapTree, e, eName, id, type, typeUse,
|
||||
restrictionsUse, useRestrictions, inverse, point, BATCH_SIZE);
|
||||
DataIndexWriter.insertBinaryMapRenderObjectIndex(pStatements, mapBinaryStat, rtree, e, eName, id,
|
||||
type, typeUse, highwayAttributes, restrictionsUse, inverse, point, BATCH_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*private void writeEntityToMapDatabase(Entity e, long baseId, boolean inverse, int level) throws SQLException {
|
||||
int type = MapRenderingTypes.encodeEntityWithType(e, level, false, typeUse);
|
||||
Map<Long, Set<Integer>> multiPolygonsWays;
|
||||
if(level == 0){
|
||||
multiPolygonsWays = multiPolygonsWays0;
|
||||
} else if(level == 1){
|
||||
multiPolygonsWays = multiPolygonsWays1;
|
||||
} else if(level == 2){
|
||||
multiPolygonsWays = multiPolygonsWays2;
|
||||
} else {
|
||||
multiPolygonsWays = Collections.emptyMap();
|
||||
}
|
||||
boolean hasMulti = e instanceof Way && multiPolygonsWays.containsKey(e.getId());
|
||||
if(type == 0){
|
||||
if(hasMulti){
|
||||
Set<Integer> set = multiPolygonsWays.get(e.getId());
|
||||
boolean first = true;
|
||||
for(Integer i : set){
|
||||
if(first){
|
||||
type = i << 1;
|
||||
first = false;
|
||||
} else {
|
||||
typeUse.add(i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else if(hasMulti){
|
||||
Set<Integer> set = multiPolygonsWays.get(e.getId());
|
||||
for(Integer i : set){
|
||||
// do not compare direction
|
||||
int k = i & 0x7fff;
|
||||
int ks = k | MapRenderingTypes.POLYGON_TYPE;
|
||||
// turn of polygon type 3 ^ (suppose polygon = multipolygon)
|
||||
if(ks == ((type >> 1) & 0xffff)){
|
||||
type = ((type >> 16) << 16) | (i << 1);
|
||||
} else if(ks == type >> 16){
|
||||
type = (type & 0xffff) | (i << 16);
|
||||
} else {
|
||||
int ind = typeUse.indexOf(ks);
|
||||
if (ind == -1) {
|
||||
typeUse.add(i);
|
||||
} else {
|
||||
typeUse.set(ind, i);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// be sure about last segments
|
||||
if(!typeUse.isEmpty()){
|
||||
type |= 1;
|
||||
}
|
||||
|
||||
boolean useRestrictions = false;
|
||||
restrictionsUse.clear();
|
||||
if(MapRenderingTypes.isHighwayType(type >> 1)){
|
||||
useRestrictions = true;
|
||||
// try to find restrictions only for max zoom level
|
||||
if(level == 0 && highwayRestrictions.containsKey(baseId)){
|
||||
restrictionsUse.addAll(highwayRestrictions.get(baseId));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
boolean point = ((type >> 1) & 3) == MapRenderingTypes.POINT_TYPE;
|
||||
PreparedStatement mapLocations;
|
||||
int zoom;
|
||||
long id = baseId << 3;
|
||||
if (level == 1) {
|
||||
id |= 2;
|
||||
mapLocations = mapLocsStatLevel1;
|
||||
zoom = 12;
|
||||
} else if (level == 2) {
|
||||
id |= 4;
|
||||
zoom = 7;
|
||||
mapLocations = mapLocsStatLevel2;
|
||||
} else {
|
||||
zoom = 18;
|
||||
mapLocations = mapLocsStatLevel0;
|
||||
}
|
||||
boolean skip = false;
|
||||
if (e instanceof Way) {
|
||||
id |= 1;
|
||||
// simplify route
|
||||
if (level > 0) {
|
||||
List<Node> nodes = ((Way) e).getNodes();
|
||||
Way way = new Way(id);
|
||||
for(String t : e.getTagKeySet()){
|
||||
way.putTag(t, e.getTag(t));
|
||||
}
|
||||
int prevX = 0;
|
||||
int prevY = 0;
|
||||
int len = 0;
|
||||
for (int i = 0; i < nodes.size(); i++) {
|
||||
// do not simplify last node it could be important node for multipolygon
|
||||
if (nodes.get(i) != null) {
|
||||
int r = i < nodes.size() - 1 ? 4 : 0;
|
||||
int x = (int) (MapUtils.getTileNumberX(zoom, nodes.get(i).getLongitude()) * 256d);
|
||||
int y = (int) (MapUtils.getTileNumberY(zoom, nodes.get(i).getLatitude()) * 256d);
|
||||
int dy = Math.abs(y - prevY);
|
||||
int dx = Math.abs(x - prevX);
|
||||
if (dx > r || dy > r) {
|
||||
way.addNode(nodes.get(i));
|
||||
len += (dx + dy);
|
||||
prevX = x;
|
||||
prevY = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
e = way;
|
||||
skip = way.getNodes().size() < 2;
|
||||
if(!hasMulti && len < 8){
|
||||
skip = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (!skip) {
|
||||
String eName = MapRenderingTypes.getEntityName(e, type);
|
||||
if(eName == null ){
|
||||
eName = multiPolygonsNames.get(baseId);
|
||||
}
|
||||
DataIndexWriter.insertMapRenderObjectIndex(pStatements, mapObjStat, mapLocations, mapTree, e,
|
||||
eName, id, type, typeUse, restrictionsUse, useRestrictions,
|
||||
inverse, point, BATCH_SIZE);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
public void writeBinaryData(RTree rtree) throws IOException {
|
||||
public void writeBinaryData() throws IOException, SQLException {
|
||||
|
||||
try {
|
||||
long rootIndex = rtree.getFileHdr().getRootIndex();
|
||||
assert IndexConstants.IndexBinaryMapRenderObject.values().length == 6;
|
||||
PreparedStatement selectData = mapConnection.prepareStatement("SELECT * FROM " + IndexBinaryMapRenderObject.getTable() + " WHERE id = ?");
|
||||
|
||||
binaryMapFile = new File(workingDir, getBinaryMapFileName());
|
||||
FileOutputStream fout = new FileOutputStream(binaryMapFile);
|
||||
BinaryIndexWriter writer = new BinaryIndexWriter(fout);
|
||||
writer.startWriteMapIndex();
|
||||
rtree.Node root = rtree.getReadNode(rootIndex);
|
||||
Rect rootBounds = calcBounds(root);
|
||||
writer.startWriteMapLevelIndex(6, 17, rootBounds.getMinX(), rootBounds.getMaxX(), rootBounds.getMinY(), rootBounds.getMaxY());
|
||||
|
||||
writeBinaryMapTree(root, rtree, writer);
|
||||
for (int i = 0; i < MAP_ZOOMS.length - 1; i++) {
|
||||
RTree rtree = mapTree[i];
|
||||
long rootIndex = rtree.getFileHdr().getRootIndex();
|
||||
rtree.Node root = rtree.getReadNode(rootIndex);
|
||||
Rect rootBounds = calcBounds(root);
|
||||
writer.startWriteMapLevelIndex(MAP_ZOOMS[MAP_ZOOMS.length - i - 2] + 1,
|
||||
MAP_ZOOMS[MAP_ZOOMS.length - i - 1], rootBounds.getMinX(),
|
||||
rootBounds.getMaxX(), rootBounds.getMinY(), rootBounds.getMaxY());
|
||||
writeBinaryMapTree(root, rtree, writer, selectData);
|
||||
|
||||
writer.endWriteMapLevelIndex();
|
||||
}
|
||||
|
||||
|
||||
writer.endWriteMapLevelIndex();
|
||||
writer.endWriteMapIndex();
|
||||
writer.close();
|
||||
} catch (RTreeException e) {
|
||||
|
@ -1615,19 +1483,26 @@ public class IndexCreator {
|
|||
}
|
||||
}
|
||||
|
||||
public void writeBinaryMapTree(rtree.Node parent, RTree r, BinaryIndexWriter writer) throws IOException, RTreeException {
|
||||
public void writeBinaryMapTree(rtree.Node parent, RTree r, BinaryIndexWriter writer, PreparedStatement selectData) throws IOException, RTreeException, SQLException {
|
||||
Element[] e = parent.getAllElements();
|
||||
for (int i = 0; i < parent.getTotalElements(); i++) {
|
||||
Rect re = e[i].getRect();
|
||||
if(e[i].getElementType() == rtree.Node.LEAF_NODE){
|
||||
// TODO
|
||||
long ptr = ((LeafElement) e[i]).getPtr();
|
||||
writer.writeMapData(ptr);
|
||||
long id = ((LeafElement) e[i]).getPtr();
|
||||
selectData.setLong(1, id);
|
||||
ResultSet rs = selectData.executeQuery();
|
||||
if(rs.next()){
|
||||
writer.writeMapData(id, rs.getBytes(IndexBinaryMapRenderObject.NODES.ordinal()+ 1),
|
||||
rs.getBytes(IndexBinaryMapRenderObject.TYPES.ordinal()+ 1), rs.getString(IndexBinaryMapRenderObject.NAME.ordinal()+ 1),
|
||||
rs.getInt(IndexBinaryMapRenderObject.HIGHWAY.ordinal()+ 1), rs.getBytes(IndexBinaryMapRenderObject.RESTRICTIONS.ordinal()+ 1));
|
||||
} else {
|
||||
log.error("Something goes wrong with id = " + id);
|
||||
}
|
||||
} else {
|
||||
long ptr = ((NonLeafElement) e[i]).getPtr();
|
||||
writer.startMapTreeElement(re.getMinX(), re.getMaxX(), re.getMinY(), re.getMaxY());
|
||||
rtree.Node ns = r.getReadNode(ptr);
|
||||
writeBinaryMapTree(ns, r, writer);
|
||||
writeBinaryMapTree(ns, r, writer, selectData);
|
||||
writer.endWriteMapTreeElement();
|
||||
}
|
||||
}
|
||||
|
@ -1776,23 +1651,22 @@ public class IndexCreator {
|
|||
mapConnection = DriverManager.getConnection("jdbc:sqlite:" + mapFile.getAbsolutePath());
|
||||
|
||||
DataIndexWriter.createMapIndexStructure(mapConnection);
|
||||
mapObjStat = DataIndexWriter.createStatementMapWaysInsert(mapConnection);
|
||||
mapLocsStatLevel0 = DataIndexWriter.createStatementMapWaysLocationsInsert(mapConnection);
|
||||
mapLocsStatLevel1 = DataIndexWriter.createStatementMapWaysLocationsInsertLevel2(mapConnection);
|
||||
mapLocsStatLevel2 = DataIndexWriter.createStatementMapWaysLocationsInsertLevel3(mapConnection);
|
||||
mapBinaryStat = DataIndexWriter.createStatementMapBinaryInsert(mapConnection);
|
||||
try {
|
||||
File file = new File(getRTreeMapIndexNonPackFileName());
|
||||
if(file.exists()){
|
||||
file.delete();
|
||||
}
|
||||
mapTree = new RTree(getRTreeMapIndexNonPackFileName());
|
||||
mapTree = new RTree[MAP_ZOOMS.length - 1];
|
||||
for (int i = 0; i < MAP_ZOOMS.length - 1; i++) {
|
||||
File file = new File(getRTreeMapIndexNonPackFileName() + i);
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
mapTree[i] = new RTree(getRTreeMapIndexNonPackFileName() + i);
|
||||
// very slow
|
||||
//mapTree[i].getFileHdr().setBufferPolicy(true);
|
||||
}
|
||||
} catch (RTreeException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
pStatements.put(mapObjStat, 0);
|
||||
pStatements.put(mapLocsStatLevel0, 0);
|
||||
pStatements.put(mapLocsStatLevel1, 0);
|
||||
pStatements.put(mapLocsStatLevel2, 0);
|
||||
pStatements.put(mapBinaryStat, 0);
|
||||
mapConnection.setAutoCommit(false);
|
||||
}
|
||||
|
||||
|
@ -1950,23 +1824,33 @@ public class IndexCreator {
|
|||
progress.setGeneralProgress("[95 of 100]");
|
||||
progress.startTask("Serializing map data...", -1);
|
||||
try {
|
||||
mapTree.flush();
|
||||
for (int i = 0; i < MAP_ZOOMS.length-1; i++) {
|
||||
mapTree[i].flush();
|
||||
File file = new File(getRTreeMapIndexPackFileName() + i);
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
|
||||
new Pack().packTree(mapTree[i], getRTreeMapIndexPackFileName() + i);
|
||||
mapTree[i].getFileHdr().getFile().close();
|
||||
file = new File(getRTreeMapIndexNonPackFileName() + i);
|
||||
file.delete();
|
||||
|
||||
mapTree[i] = new RTree(getRTreeMapIndexPackFileName() + i);
|
||||
}
|
||||
} catch (RTreeException e) {
|
||||
log.error("Error flushing", e);
|
||||
throw new IOException(e);
|
||||
}
|
||||
File file = new File(getRTreeMapIndexPackFileName());
|
||||
if (file.exists()) {
|
||||
file.delete();
|
||||
}
|
||||
new Pack().packTree(mapTree, getRTreeMapIndexPackFileName());
|
||||
mapTree = null;
|
||||
// update map connection
|
||||
mapBinaryStat.executeBatch();
|
||||
pStatements.remove(mapBinaryStat);
|
||||
mapConnection.commit();
|
||||
|
||||
// TODO !!! create binary output stream in order to close it properly (finally)
|
||||
writeBinaryData(new RTree(getRTreeMapIndexPackFileName()));
|
||||
|
||||
writeBinaryData();
|
||||
}
|
||||
|
||||
} catch (RTreeException e) {
|
||||
throw new IOException(e);
|
||||
} finally {
|
||||
try {
|
||||
if (pselectNode != null) {
|
||||
|
@ -2013,14 +1897,7 @@ public class IndexCreator {
|
|||
mapFile.setLastModified(lastModifiedDate);
|
||||
}
|
||||
}
|
||||
if(mapTree != null){
|
||||
try {
|
||||
mapTree.flush();
|
||||
} catch (RTreeException e) {
|
||||
log.error("Error flushing", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (addressConnection != null) {
|
||||
addressConnection.commit();
|
||||
addressConnection.close();
|
||||
|
@ -2029,6 +1906,25 @@ public class IndexCreator {
|
|||
addressIndexFile.setLastModified(lastModifiedDate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < mapTree.length; i++) {
|
||||
if (mapTree[i] != null) {
|
||||
RandomAccessFile file = mapTree[i].getFileHdr().getFile();
|
||||
file.close();
|
||||
}
|
||||
|
||||
}
|
||||
for (int i = 0; i < mapTree.length; i++) {
|
||||
File f = new File(getRTreeMapIndexNonPackFileName() + i);
|
||||
if (f.exists()) {
|
||||
f.delete();
|
||||
}
|
||||
f = new File(getRTreeMapIndexPackFileName() + i);
|
||||
if (f.exists()) {
|
||||
f.delete();
|
||||
}
|
||||
}
|
||||
dbConn.close();
|
||||
} catch (SQLException e) {
|
||||
}
|
||||
|
|
238
DataExtractionOSM/src/net/osmand/osm/BinaryMapRenderObject.java
Normal file
238
DataExtractionOSM/src/net/osmand/osm/BinaryMapRenderObject.java
Normal file
|
@ -0,0 +1,238 @@
|
|||
package net.osmand.osm;
|
||||
|
||||
import net.osmand.Algoritms;
|
||||
|
||||
public class BinaryMapRenderObject {
|
||||
private String name = null;
|
||||
private int type;
|
||||
private byte[] data = null;
|
||||
private long id;
|
||||
private float order = -1;
|
||||
private boolean multitype = false;
|
||||
private boolean highwayType = false;
|
||||
|
||||
public BinaryMapRenderObject(long id){
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setData(byte[] data) {
|
||||
this.data = data;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
this.type = type;
|
||||
multitype = (type & 1) > 0;
|
||||
highwayType = isHighwayType();
|
||||
order = -1;
|
||||
}
|
||||
|
||||
public int getWholeType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public boolean isMultitype() {
|
||||
return multitype;
|
||||
}
|
||||
|
||||
public byte getMultiTypes(){
|
||||
return multitype ? data[0] : 0;
|
||||
}
|
||||
|
||||
public byte getRestrictions(){
|
||||
if(!highwayType){
|
||||
return 0;
|
||||
}
|
||||
if(multitype){
|
||||
return data[1];
|
||||
}
|
||||
return data[0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getAdditionalType(int k){
|
||||
return Algoritms.parseSmallIntFromBytes(data, highwayType ? k * 2 + 2 : k * 2 + 1);
|
||||
}
|
||||
|
||||
// do not cut type to 15 bits (16 bits needed for multipolygon)
|
||||
public int getMainType(){
|
||||
return (type >> 1);
|
||||
}
|
||||
|
||||
private boolean isHighwayType(){
|
||||
int pr = type >> 1;
|
||||
return (pr & 3) == MapRenderingTypes.POLYLINE_TYPE && MapRenderingTypes.getMainObjectType(pr) == MapRenderingTypes.HIGHWAY;
|
||||
}
|
||||
|
||||
public int getSecondType(){
|
||||
if(isHighwayType()){
|
||||
return 0;
|
||||
}
|
||||
return type >> 16;
|
||||
}
|
||||
|
||||
public byte getRestrictionType(int k){
|
||||
int offset = multitype ? data[0] * 2 + 2 : 1;
|
||||
long l = Algoritms.parseLongFromBytes(data, offset);
|
||||
return (byte) (l & 7);
|
||||
}
|
||||
|
||||
public long getRestriction(int k){
|
||||
int offset = multitype ? data[0] * 2 + 2 : 1;
|
||||
long l = Algoritms.parseLongFromBytes(data, offset);
|
||||
return (l & ~7l) | (id & 7l);
|
||||
}
|
||||
|
||||
|
||||
public int getPointsLength() {
|
||||
if (data == null || data.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
return (data.length - getShiftCoordinates()) / 8;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
private int getShiftCoordinates(){
|
||||
int shift = 0;
|
||||
if(multitype){
|
||||
shift = data[0] * 2 + 1;
|
||||
if(highwayType){
|
||||
shift += data[1] * 8 + 1;
|
||||
}
|
||||
} else if(highwayType){
|
||||
shift = data[0] * 8 + 1;
|
||||
}
|
||||
return shift;
|
||||
}
|
||||
|
||||
public int getPoint31YTile(int ind) {
|
||||
return Algoritms.parseIntFromBytes(data, ind * 8 + getShiftCoordinates());
|
||||
}
|
||||
|
||||
public int getPoint31XTile(int ind) {
|
||||
return Algoritms.parseIntFromBytes(data, ind * 8 + 4 + getShiftCoordinates());
|
||||
}
|
||||
|
||||
public float getMapOrder(){
|
||||
if (order == -1) {
|
||||
order = getOrder(getMainType());
|
||||
}
|
||||
return order;
|
||||
}
|
||||
|
||||
public static float getOrder(int wholeType) {
|
||||
float order = 0;
|
||||
int t = wholeType & 3;
|
||||
int oType = MapRenderingTypes.getMainObjectType(wholeType);
|
||||
int sType = MapRenderingTypes.getObjectSubType(wholeType);
|
||||
int layer = MapRenderingTypes.getWayLayer(wholeType);
|
||||
if (t == MapRenderingTypes.MULTY_POLYGON_TYPE || t == MapRenderingTypes.POLYGON_TYPE) {
|
||||
// 1 - 9
|
||||
if (oType == MapRenderingTypes.MAN_MADE && sType == MapRenderingTypes.SUBTYPE_BUILDING) {
|
||||
// draw over lines
|
||||
if(layer != 1){
|
||||
order = 64;
|
||||
} else {
|
||||
order = 2;
|
||||
}
|
||||
} else {
|
||||
if(layer == 1){
|
||||
order = 0.5f;
|
||||
} else if(layer == 2){
|
||||
// over lines
|
||||
order = 64;
|
||||
} else if (oType == MapRenderingTypes.LANDUSE) {
|
||||
switch (sType) {
|
||||
case 5:
|
||||
case 6:
|
||||
case 15:
|
||||
case 18:
|
||||
case 20:
|
||||
case 23:
|
||||
order = 1;
|
||||
break;
|
||||
case 22:
|
||||
order = 5;
|
||||
break;
|
||||
default:
|
||||
order = 1f;
|
||||
break;
|
||||
}
|
||||
} else if (oType == MapRenderingTypes.LEISURE) {
|
||||
switch (sType) {
|
||||
case 3:
|
||||
case 10:
|
||||
case 13:
|
||||
order = 2;
|
||||
break;
|
||||
case 6:
|
||||
order = 4;
|
||||
default:
|
||||
order = 2;
|
||||
break;
|
||||
}
|
||||
} else if (oType == MapRenderingTypes.POWER) {
|
||||
order = 4;
|
||||
} else if (oType == MapRenderingTypes.NATURAL) {
|
||||
if (order == 5) {
|
||||
// coastline
|
||||
order = 0.5f;
|
||||
} else if (order == 21) {
|
||||
// water
|
||||
order = 5;
|
||||
} else {
|
||||
order = 1;
|
||||
}
|
||||
} else if (oType == MapRenderingTypes.WATERWAY) {
|
||||
// water 5
|
||||
order = 5;
|
||||
} else {
|
||||
order = 1;
|
||||
}
|
||||
}
|
||||
} else if (t == MapRenderingTypes.POLYLINE_TYPE) {
|
||||
// 10 - 68
|
||||
if(layer == 1 && oType != MapRenderingTypes.RAILWAY){
|
||||
// not subway especially
|
||||
order = 10;
|
||||
} else if(layer == 2) {
|
||||
order = 67; // over buildings
|
||||
} else if (oType == MapRenderingTypes.HIGHWAY) {
|
||||
order = 32 - sType + 24;
|
||||
if(sType == MapRenderingTypes.PL_HW_MOTORWAY){
|
||||
// TODO ? that was done only to have good overlay
|
||||
// but really it should be motorway_link have -= 10
|
||||
order -= 2;
|
||||
}
|
||||
} else if (oType == MapRenderingTypes.RAILWAY) {
|
||||
order = 58;
|
||||
} else if (oType == MapRenderingTypes.AERIALWAY) {
|
||||
order = 68; // over buildings
|
||||
} else if (oType == MapRenderingTypes.POWER) {
|
||||
order = 68; // over buildings
|
||||
} else if (oType == MapRenderingTypes.ADMINISTRATIVE) {
|
||||
order = 62;
|
||||
} else if (oType == MapRenderingTypes.WATERWAY) {
|
||||
order = 18;
|
||||
} else {
|
||||
order = 10;
|
||||
}
|
||||
} else {
|
||||
order = 128;
|
||||
}
|
||||
return order;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -29,10 +29,6 @@ public class MapRenderObject {
|
|||
order = -1;
|
||||
}
|
||||
|
||||
public int getWholeType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
|
|
@ -382,9 +382,10 @@ public class CachedNodes
|
|||
|
||||
int calKey(String fileName,int idx)
|
||||
{
|
||||
if(fileName != null)
|
||||
return (idx + fileName.toLowerCase().hashCode());
|
||||
else{
|
||||
if(fileName != null) {
|
||||
// System.out.println(idx + " " + fileName + " " + ((idx << 5)+ fileName.toLowerCase().hashCode() % 32));
|
||||
return ((idx << 5)+ fileName.toLowerCase().hashCode() % 32);
|
||||
} else{
|
||||
System.out.println("CachedNodes.calKey: fileName null");
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue