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.List;
|
||||
|
||||
import net.osmand.osm.MapUtils;
|
||||
|
||||
import com.google.protobuf.CodedInputStreamRAF;
|
||||
import com.google.protobuf.WireFormat;
|
||||
|
||||
|
@ -36,15 +38,26 @@ public class BinaryMapIndexReader {
|
|||
int top = 0;
|
||||
int bottom = 0;
|
||||
|
||||
long baseId = 0;
|
||||
|
||||
List<String> stringTable = 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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -169,6 +182,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() {
|
||||
return raf;
|
||||
|
@ -203,9 +402,19 @@ public class BinaryMapIndexReader {
|
|||
RandomAccessFile raf = new RandomAccessFile(new File("e:\\Information\\OSM maps\\osmand\\Minsk.map.pbf"), "r");
|
||||
BinaryMapIndexReader reader = new BinaryMapIndexReader(raf);
|
||||
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()) {
|
||||
System.out.println(b.minZoom + " " + b.maxZoom + " " +b.trees.size() + " "
|
||||
+ 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);
|
||||
}
|
||||
// calculate size
|
||||
int allSize = CodedOutputStream.computeTagSize(OsmandOdb.MapData.COORDINATES_FIELD_NUMBER);
|
||||
int sizeCoordinates = 0;
|
||||
int px = bounds.leftX / 2;
|
||||
int py = bounds.topY / 2;
|
||||
int allSize = 0;
|
||||
int px = bounds.leftX;
|
||||
int py = bounds.topY;
|
||||
for(int i=0; i< nodes.length / 8; i++){
|
||||
int x = Algoritms.parseIntFromBytes(nodes, i*8);
|
||||
int y = Algoritms.parseIntFromBytes(nodes, i*8 + 4);
|
||||
|
@ -208,21 +208,25 @@ public class BinaryMapIndexWriter {
|
|||
px = x;
|
||||
py = y;
|
||||
}
|
||||
allSize += sizeCoordinates;
|
||||
allSize += CodedOutputStream.computeRawVarint32Size(sizeCoordinates) +
|
||||
CodedOutputStream.computeTagSize(OsmandOdb.MapData.COORDINATES_FIELD_NUMBER) + sizeCoordinates;
|
||||
// DEBUG
|
||||
COORDINATES_SIZE += sizeCoordinates + CodedOutputStream.computeTagSize(OsmandOdb.MapData.COORDINATES_FIELD_NUMBER);
|
||||
COORDINATES_SIZE += allSize;
|
||||
|
||||
|
||||
allSize += CodedOutputStream.computeTagSize(OsmandOdb.MapData.TYPES_FIELD_NUMBER);
|
||||
allSize += CodedOutputStream.computeRawVarint32Size(types.length);
|
||||
allSize += types.length;
|
||||
// DEBUG
|
||||
TYPES_SIZE += CodedOutputStream.computeTagSize(OsmandOdb.MapData.TYPES_FIELD_NUMBER) +
|
||||
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());
|
||||
// DEBUG
|
||||
ID_SIZE += CodedOutputStream.computeSInt64Size(OsmandOdb.MapData.ID_FIELD_NUMBER, id - stackBaseIds.peek());
|
||||
|
||||
|
||||
int nameId = 0;
|
||||
if(name != null){
|
||||
if(stackStringTable.peek() == null) {
|
||||
|
@ -260,11 +264,12 @@ public class BinaryMapIndexWriter {
|
|||
codedOutStream.writeTag(OsmandOdb.MapTree.LEAFS_FIELD_NUMBER, WireFormat.FieldType.MESSAGE.getWireType());
|
||||
codedOutStream.writeRawVarint32(allSize);
|
||||
|
||||
|
||||
codedOutStream.writeTag(OsmandOdb.MapData.COORDINATES_FIELD_NUMBER, WireFormat.FieldType.BYTES.getWireType());
|
||||
codedOutStream.writeRawVarint32(sizeCoordinates);
|
||||
|
||||
px = bounds.leftX / 2;
|
||||
py = bounds.topY / 2;
|
||||
px = bounds.leftX;
|
||||
py = bounds.topY;
|
||||
for (int i = 0; i < nodes.length / 8; i++) {
|
||||
int x = Algoritms.parseIntFromBytes(nodes, i*8);
|
||||
int y = Algoritms.parseIntFromBytes(nodes, i*8 + 4);
|
||||
|
@ -274,16 +279,17 @@ public class BinaryMapIndexWriter {
|
|||
py = y;
|
||||
}
|
||||
|
||||
|
||||
codedOutStream.writeTag(OsmandOdb.MapData.TYPES_FIELD_NUMBER, WireFormat.FieldType.BYTES.getWireType());
|
||||
codedOutStream.writeRawVarint32(types.length);
|
||||
codedOutStream.writeRawBytes(types);
|
||||
|
||||
|
||||
codedOutStream.writeSInt64(OsmandOdb.MapData.ID_FIELD_NUMBER, id - stackBaseIds.peek());
|
||||
|
||||
|
||||
if(name != null){
|
||||
codedOutStream.writeUInt32(OsmandOdb.MapData.STRINGID_FIELD_NUMBER, nameId);
|
||||
}
|
||||
}
|
||||
|
||||
if(restrictions.length > 0){
|
||||
codedOutStream.writeTag(OsmandOdb.MapData.RESTRICTIONS_FIELD_NUMBER, WireFormat.FieldType.BYTES.getWireType());
|
||||
|
|
|
@ -785,7 +785,7 @@ public final class CodedInputStreamRAF {
|
|||
} else {
|
||||
// Skipping more bytes than are in the buffer. First skip what we have.
|
||||
int pos = bufferSize - bufferPos;
|
||||
totalBytesRetired += pos;
|
||||
totalBytesRetired += bufferSize;
|
||||
bufferPos = 0;
|
||||
bufferSize = 0;
|
||||
|
||||
|
@ -802,8 +802,8 @@ public final class CodedInputStreamRAF {
|
|||
}
|
||||
|
||||
public void seek(long pointer) throws IOException{
|
||||
if(pointer - totalBytesRetired > 0 && pointer - totalBytesRetired < bufferSize){
|
||||
skipRawBytes((int) (pointer - totalBytesRetired));
|
||||
if(pointer - totalBytesRetired >= 0 && pointer - totalBytesRetired < bufferSize){
|
||||
skipRawBytes((int) (pointer - getTotalBytesRead()));
|
||||
} else {
|
||||
totalBytesRetired = (int) pointer;
|
||||
raf.seek(pointer);
|
||||
|
|
Loading…
Reference in a new issue