fix some problems
git-svn-id: https://osmand.googlecode.com/svn/trunk@600 e29c36b1-1cfa-d876-8d93-3434fc2bb7b8
This commit is contained in:
parent
ce158272f3
commit
ed5416f404
3 changed files with 230 additions and 15 deletions
|
@ -6,6 +6,8 @@ import java.io.RandomAccessFile;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.osmand.osm.MapUtils;
|
||||||
|
|
||||||
import com.google.protobuf.CodedInputStreamRAF;
|
import com.google.protobuf.CodedInputStreamRAF;
|
||||||
import com.google.protobuf.WireFormat;
|
import com.google.protobuf.WireFormat;
|
||||||
|
|
||||||
|
@ -36,15 +38,26 @@ public class BinaryMapIndexReader {
|
||||||
int top = 0;
|
int top = 0;
|
||||||
int bottom = 0;
|
int bottom = 0;
|
||||||
|
|
||||||
|
long baseId = 0;
|
||||||
|
|
||||||
List<String> stringTable = null;
|
List<String> stringTable = null;
|
||||||
List<MapTree> subTrees = null;
|
List<MapTree> subTrees = null;
|
||||||
List<MapObject> children = null;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MapObject {
|
public class MapDataObject {
|
||||||
|
|
||||||
|
|
||||||
|
int[] coordinates = null;
|
||||||
|
int[] types = null;
|
||||||
|
|
||||||
|
int stringId = -1;
|
||||||
|
long id = 0;
|
||||||
|
|
||||||
|
long[] restrictions = null;
|
||||||
|
int highwayAttributes = 0;
|
||||||
|
|
||||||
|
String name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -170,6 +183,192 @@ public class BinaryMapIndexReader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<MapDataObject> searchMapIndex(MapRoot index, int sleft, int sright, int stop, int sbottom,
|
||||||
|
List<MapDataObject> searchResults) throws IOException {
|
||||||
|
for(MapTree tree : index.trees){
|
||||||
|
codedIS.seek(tree.filePointer);
|
||||||
|
int oldLimit = codedIS.pushLimit(tree.length);
|
||||||
|
searchMapTreeBounds(tree, index.left, index.right, index.top, index.bottom,
|
||||||
|
sleft, sright, stop, sbottom, searchResults, " ");
|
||||||
|
codedIS.popLimit(oldLimit);
|
||||||
|
}
|
||||||
|
return searchResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void searchMapTreeBounds(MapTree tree, int pleft, int pright, int ptop, int pbottom,
|
||||||
|
int sleft, int sright, int stop, int sbottom,
|
||||||
|
List<MapDataObject> searchResults, String indent) throws IOException {
|
||||||
|
int init = 0;
|
||||||
|
List<MapDataObject> results = null;
|
||||||
|
while(true){
|
||||||
|
int tag = WireFormat.getTagFieldNumber(codedIS.readTag());
|
||||||
|
if(init == 0xf){
|
||||||
|
init = 0;
|
||||||
|
// coordinates are init
|
||||||
|
if(tree.right < sleft || tree.left > sright || tree.top > sbottom || tree.bottom < stop){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (tag) {
|
||||||
|
case 0:
|
||||||
|
return;
|
||||||
|
case OsmandOdb.MapTree.BOTTOM_FIELD_NUMBER :
|
||||||
|
tree.bottom = codedIS.readSInt32() + pbottom;
|
||||||
|
init |= 1;
|
||||||
|
break;
|
||||||
|
case OsmandOdb.MapTree.LEFT_FIELD_NUMBER :
|
||||||
|
tree.left = codedIS.readSInt32() + pleft;
|
||||||
|
init |= 2;
|
||||||
|
break;
|
||||||
|
case OsmandOdb.MapTree.RIGHT_FIELD_NUMBER :
|
||||||
|
tree.right = codedIS.readSInt32() + pright;
|
||||||
|
init |= 4;
|
||||||
|
break;
|
||||||
|
case OsmandOdb.MapTree.TOP_FIELD_NUMBER :
|
||||||
|
tree.top = codedIS.readSInt32() + ptop;
|
||||||
|
init |= 8;
|
||||||
|
break;
|
||||||
|
case OsmandOdb.MapTree.LEAFS_FIELD_NUMBER :
|
||||||
|
int length = codedIS.readRawVarint32();
|
||||||
|
int oldLimit = codedIS.pushLimit(length);
|
||||||
|
MapDataObject mapObject = readMapDataObject(tree.left, tree.right, tree.top, tree.bottom, sleft, sright, stop, sbottom);
|
||||||
|
if(mapObject != null){
|
||||||
|
if(results == null){
|
||||||
|
results = new ArrayList<MapDataObject>();
|
||||||
|
}
|
||||||
|
results.add(mapObject);
|
||||||
|
searchResults.add(mapObject);
|
||||||
|
|
||||||
|
}
|
||||||
|
codedIS.popLimit(oldLimit);
|
||||||
|
break;
|
||||||
|
case OsmandOdb.MapTree.SUBTREES_FIELD_NUMBER :
|
||||||
|
MapTree r = new MapTree();
|
||||||
|
// left, ... already initialized
|
||||||
|
r.length = readInt();
|
||||||
|
r.filePointer = codedIS.getTotalBytesRead();
|
||||||
|
oldLimit = codedIS.pushLimit(r.length);
|
||||||
|
searchMapTreeBounds(r, tree.left, tree.right, tree.top, tree.bottom, sleft, sright, stop, sbottom, searchResults, indent+" ");
|
||||||
|
codedIS.popLimit(oldLimit);
|
||||||
|
codedIS.seek(r.filePointer + r.length);
|
||||||
|
break;
|
||||||
|
case OsmandOdb.MapTree.BASEID_FIELD_NUMBER :
|
||||||
|
tree.baseId = codedIS.readUInt64();
|
||||||
|
if (results != null) {
|
||||||
|
for (MapDataObject rs : results) {
|
||||||
|
rs.id += tree.baseId;
|
||||||
|
if (rs.restrictions != null) {
|
||||||
|
for (int i = 0; i < rs.restrictions.length; i++) {
|
||||||
|
rs.restrictions[i] += tree.baseId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OsmandOdb.MapTree.STRINGTABLE_FIELD_NUMBER :
|
||||||
|
length = codedIS.readRawVarint32();
|
||||||
|
oldLimit = codedIS.pushLimit(length);
|
||||||
|
tree.stringTable = readStringTable();
|
||||||
|
codedIS.popLimit(oldLimit);
|
||||||
|
|
||||||
|
if (results != null) {
|
||||||
|
for (MapDataObject rs : results) {
|
||||||
|
if (rs.stringId != -1) {
|
||||||
|
rs.name = tree.stringTable.get(rs.stringId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// TODO skip unknown fields
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Integer> CACHE = new ArrayList<Integer>();
|
||||||
|
private MapDataObject readMapDataObject(int left, int right, int top, int bottom, int sleft, int sright, int stop, int sbottom) throws IOException {
|
||||||
|
int tag = WireFormat.getTagFieldNumber(codedIS.readTag());
|
||||||
|
if(OsmandOdb.MapData.COORDINATES_FIELD_NUMBER != tag) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
CACHE.clear();
|
||||||
|
int size = codedIS.readRawVarint32();
|
||||||
|
int old = codedIS.pushLimit(size);
|
||||||
|
int px = left;
|
||||||
|
int py = top;
|
||||||
|
boolean contains = false;
|
||||||
|
while(codedIS.getBytesUntilLimit() > 0){
|
||||||
|
int x = codedIS.readSInt32() + px;
|
||||||
|
int y = codedIS.readSInt32() + py;
|
||||||
|
CACHE.add(x);
|
||||||
|
CACHE.add(y);
|
||||||
|
px = x;
|
||||||
|
py = y;
|
||||||
|
if(!contains && sleft <= x && sright >= x && stop <= y && sbottom >= y){
|
||||||
|
contains = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
codedIS.popLimit(old);
|
||||||
|
if(!contains){
|
||||||
|
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
MapDataObject dataObject = new MapDataObject();
|
||||||
|
dataObject.coordinates = new int[CACHE.size()];
|
||||||
|
for(int i=0; i<CACHE.size(); i++){
|
||||||
|
dataObject.coordinates[i] = CACHE.get(i);
|
||||||
|
}
|
||||||
|
while(true){
|
||||||
|
tag = WireFormat.getTagFieldNumber(codedIS.readTag());
|
||||||
|
switch (tag) {
|
||||||
|
case 0:
|
||||||
|
return dataObject;
|
||||||
|
case OsmandOdb.MapData.TYPES_FIELD_NUMBER :
|
||||||
|
int sizeL = codedIS.readRawVarint32();
|
||||||
|
codedIS.skipRawBytes(sizeL);
|
||||||
|
// TODO read types
|
||||||
|
break;
|
||||||
|
case OsmandOdb.MapData.RESTRICTIONS_FIELD_NUMBER :
|
||||||
|
// TODO read restrictions
|
||||||
|
sizeL = codedIS.readRawVarint32();
|
||||||
|
codedIS.skipRawBytes(sizeL);
|
||||||
|
break;
|
||||||
|
case OsmandOdb.MapData.HIGHWAYMETA_FIELD_NUMBER :
|
||||||
|
dataObject.highwayAttributes = codedIS.readInt32();
|
||||||
|
break;
|
||||||
|
case OsmandOdb.MapData.ID_FIELD_NUMBER :
|
||||||
|
dataObject.id = codedIS.readSInt64();
|
||||||
|
break;
|
||||||
|
case OsmandOdb.MapData.STRINGID_FIELD_NUMBER :
|
||||||
|
dataObject.stringId = codedIS.readUInt32();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// TODO skip unknown fields
|
||||||
|
return dataObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> readStringTable() throws IOException{
|
||||||
|
List<String> list = new ArrayList<String>();
|
||||||
|
while(true){
|
||||||
|
int tag = WireFormat.getTagFieldNumber(codedIS.readTag());
|
||||||
|
switch (tag) {
|
||||||
|
case 0:
|
||||||
|
return list;
|
||||||
|
case OsmandOdb.StringTable.S_FIELD_NUMBER :
|
||||||
|
list.add(codedIS.readString());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// TODO skip unknown fields
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public RandomAccessFile getRaf() {
|
public RandomAccessFile getRaf() {
|
||||||
return raf;
|
return raf;
|
||||||
}
|
}
|
||||||
|
@ -203,9 +402,19 @@ public class BinaryMapIndexReader {
|
||||||
RandomAccessFile raf = new RandomAccessFile(new File("e:\\Information\\OSM maps\\osmand\\Minsk.map.pbf"), "r");
|
RandomAccessFile raf = new RandomAccessFile(new File("e:\\Information\\OSM maps\\osmand\\Minsk.map.pbf"), "r");
|
||||||
BinaryMapIndexReader reader = new BinaryMapIndexReader(raf);
|
BinaryMapIndexReader reader = new BinaryMapIndexReader(raf);
|
||||||
System.out.println(reader.getVersion());
|
System.out.println(reader.getVersion());
|
||||||
|
int sleft = MapUtils.get31TileNumberX(27.578);
|
||||||
|
int sright = MapUtils.get31TileNumberX(27.583);
|
||||||
|
int stop = MapUtils.get31TileNumberY(53.916);
|
||||||
|
int sbottom = MapUtils.get31TileNumberY(53.9138);
|
||||||
|
System.out.println("SEARCH " + sleft + " " + sright + " " + stop + " " + sbottom);
|
||||||
for(MapRoot b : reader.getMapIndexes()) {
|
for(MapRoot b : reader.getMapIndexes()) {
|
||||||
System.out.println(b.minZoom + " " + b.maxZoom + " " +b.trees.size() + " "
|
System.out.println(b.minZoom + " " + b.maxZoom + " " +b.trees.size() + " "
|
||||||
+ b.left + " " + b.right + " " + b.top + " " + b.bottom);
|
+ b.left + " " + b.right + " " + b.top + " " + b.bottom);
|
||||||
|
for(MapDataObject obj : reader.searchMapIndex(b, sleft, sright, stop, sbottom, new ArrayList<MapDataObject>())){
|
||||||
|
if(obj.name != null){
|
||||||
|
System.out.println(" " + obj.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -196,10 +196,10 @@ public class BinaryMapIndexWriter {
|
||||||
stackBaseIds.push(id);
|
stackBaseIds.push(id);
|
||||||
}
|
}
|
||||||
// calculate size
|
// calculate size
|
||||||
int allSize = CodedOutputStream.computeTagSize(OsmandOdb.MapData.COORDINATES_FIELD_NUMBER);
|
|
||||||
int sizeCoordinates = 0;
|
int sizeCoordinates = 0;
|
||||||
int px = bounds.leftX / 2;
|
int allSize = 0;
|
||||||
int py = bounds.topY / 2;
|
int px = bounds.leftX;
|
||||||
|
int py = bounds.topY;
|
||||||
for(int i=0; i< nodes.length / 8; i++){
|
for(int i=0; i< nodes.length / 8; i++){
|
||||||
int x = Algoritms.parseIntFromBytes(nodes, i*8);
|
int x = Algoritms.parseIntFromBytes(nodes, i*8);
|
||||||
int y = Algoritms.parseIntFromBytes(nodes, i*8 + 4);
|
int y = Algoritms.parseIntFromBytes(nodes, i*8 + 4);
|
||||||
|
@ -208,9 +208,11 @@ public class BinaryMapIndexWriter {
|
||||||
px = x;
|
px = x;
|
||||||
py = y;
|
py = y;
|
||||||
}
|
}
|
||||||
allSize += sizeCoordinates;
|
allSize += CodedOutputStream.computeRawVarint32Size(sizeCoordinates) +
|
||||||
|
CodedOutputStream.computeTagSize(OsmandOdb.MapData.COORDINATES_FIELD_NUMBER) + sizeCoordinates;
|
||||||
// DEBUG
|
// DEBUG
|
||||||
COORDINATES_SIZE += sizeCoordinates + CodedOutputStream.computeTagSize(OsmandOdb.MapData.COORDINATES_FIELD_NUMBER);
|
COORDINATES_SIZE += allSize;
|
||||||
|
|
||||||
|
|
||||||
allSize += CodedOutputStream.computeTagSize(OsmandOdb.MapData.TYPES_FIELD_NUMBER);
|
allSize += CodedOutputStream.computeTagSize(OsmandOdb.MapData.TYPES_FIELD_NUMBER);
|
||||||
allSize += CodedOutputStream.computeRawVarint32Size(types.length);
|
allSize += CodedOutputStream.computeRawVarint32Size(types.length);
|
||||||
|
@ -218,11 +220,13 @@ public class BinaryMapIndexWriter {
|
||||||
// DEBUG
|
// DEBUG
|
||||||
TYPES_SIZE += CodedOutputStream.computeTagSize(OsmandOdb.MapData.TYPES_FIELD_NUMBER) +
|
TYPES_SIZE += CodedOutputStream.computeTagSize(OsmandOdb.MapData.TYPES_FIELD_NUMBER) +
|
||||||
CodedOutputStream.computeRawVarint32Size(types.length) + types.length;
|
CodedOutputStream.computeRawVarint32Size(types.length) + types.length;
|
||||||
System.out.println(id + " " + CodedOutputStream.computeSInt64Size(OsmandOdb.MapData.ID_FIELD_NUMBER, id - stackBaseIds.peek()));
|
|
||||||
|
|
||||||
allSize += CodedOutputStream.computeSInt64Size(OsmandOdb.MapData.ID_FIELD_NUMBER, id - stackBaseIds.peek());
|
allSize += CodedOutputStream.computeSInt64Size(OsmandOdb.MapData.ID_FIELD_NUMBER, id - stackBaseIds.peek());
|
||||||
// DEBUG
|
// DEBUG
|
||||||
ID_SIZE += CodedOutputStream.computeSInt64Size(OsmandOdb.MapData.ID_FIELD_NUMBER, id - stackBaseIds.peek());
|
ID_SIZE += CodedOutputStream.computeSInt64Size(OsmandOdb.MapData.ID_FIELD_NUMBER, id - stackBaseIds.peek());
|
||||||
|
|
||||||
|
|
||||||
int nameId = 0;
|
int nameId = 0;
|
||||||
if(name != null){
|
if(name != null){
|
||||||
if(stackStringTable.peek() == null) {
|
if(stackStringTable.peek() == null) {
|
||||||
|
@ -260,11 +264,12 @@ public class BinaryMapIndexWriter {
|
||||||
codedOutStream.writeTag(OsmandOdb.MapTree.LEAFS_FIELD_NUMBER, WireFormat.FieldType.MESSAGE.getWireType());
|
codedOutStream.writeTag(OsmandOdb.MapTree.LEAFS_FIELD_NUMBER, WireFormat.FieldType.MESSAGE.getWireType());
|
||||||
codedOutStream.writeRawVarint32(allSize);
|
codedOutStream.writeRawVarint32(allSize);
|
||||||
|
|
||||||
|
|
||||||
codedOutStream.writeTag(OsmandOdb.MapData.COORDINATES_FIELD_NUMBER, WireFormat.FieldType.BYTES.getWireType());
|
codedOutStream.writeTag(OsmandOdb.MapData.COORDINATES_FIELD_NUMBER, WireFormat.FieldType.BYTES.getWireType());
|
||||||
codedOutStream.writeRawVarint32(sizeCoordinates);
|
codedOutStream.writeRawVarint32(sizeCoordinates);
|
||||||
|
|
||||||
px = bounds.leftX / 2;
|
px = bounds.leftX;
|
||||||
py = bounds.topY / 2;
|
py = bounds.topY;
|
||||||
for (int i = 0; i < nodes.length / 8; i++) {
|
for (int i = 0; i < nodes.length / 8; i++) {
|
||||||
int x = Algoritms.parseIntFromBytes(nodes, i*8);
|
int x = Algoritms.parseIntFromBytes(nodes, i*8);
|
||||||
int y = Algoritms.parseIntFromBytes(nodes, i*8 + 4);
|
int y = Algoritms.parseIntFromBytes(nodes, i*8 + 4);
|
||||||
|
@ -274,13 +279,14 @@ public class BinaryMapIndexWriter {
|
||||||
py = y;
|
py = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
codedOutStream.writeTag(OsmandOdb.MapData.TYPES_FIELD_NUMBER, WireFormat.FieldType.BYTES.getWireType());
|
codedOutStream.writeTag(OsmandOdb.MapData.TYPES_FIELD_NUMBER, WireFormat.FieldType.BYTES.getWireType());
|
||||||
codedOutStream.writeRawVarint32(types.length);
|
codedOutStream.writeRawVarint32(types.length);
|
||||||
codedOutStream.writeRawBytes(types);
|
codedOutStream.writeRawBytes(types);
|
||||||
|
|
||||||
|
|
||||||
codedOutStream.writeSInt64(OsmandOdb.MapData.ID_FIELD_NUMBER, id - stackBaseIds.peek());
|
codedOutStream.writeSInt64(OsmandOdb.MapData.ID_FIELD_NUMBER, id - stackBaseIds.peek());
|
||||||
|
|
||||||
|
|
||||||
if(name != null){
|
if(name != null){
|
||||||
codedOutStream.writeUInt32(OsmandOdb.MapData.STRINGID_FIELD_NUMBER, nameId);
|
codedOutStream.writeUInt32(OsmandOdb.MapData.STRINGID_FIELD_NUMBER, nameId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -785,7 +785,7 @@ public final class CodedInputStreamRAF {
|
||||||
} else {
|
} else {
|
||||||
// Skipping more bytes than are in the buffer. First skip what we have.
|
// Skipping more bytes than are in the buffer. First skip what we have.
|
||||||
int pos = bufferSize - bufferPos;
|
int pos = bufferSize - bufferPos;
|
||||||
totalBytesRetired += pos;
|
totalBytesRetired += bufferSize;
|
||||||
bufferPos = 0;
|
bufferPos = 0;
|
||||||
bufferSize = 0;
|
bufferSize = 0;
|
||||||
|
|
||||||
|
@ -802,8 +802,8 @@ public final class CodedInputStreamRAF {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void seek(long pointer) throws IOException{
|
public void seek(long pointer) throws IOException{
|
||||||
if(pointer - totalBytesRetired > 0 && pointer - totalBytesRetired < bufferSize){
|
if(pointer - totalBytesRetired >= 0 && pointer - totalBytesRetired < bufferSize){
|
||||||
skipRawBytes((int) (pointer - totalBytesRetired));
|
skipRawBytes((int) (pointer - getTotalBytesRead()));
|
||||||
} else {
|
} else {
|
||||||
totalBytesRetired = (int) pointer;
|
totalBytesRetired = (int) pointer;
|
||||||
raf.seek(pointer);
|
raf.seek(pointer);
|
||||||
|
|
Loading…
Reference in a new issue