Introduce multiname feature

This commit is contained in:
Victor Shcherb 2012-02-18 23:42:28 +01:00
parent 8ee3f3f05b
commit 4844bb98d6
5 changed files with 144 additions and 141 deletions

View file

@ -25,15 +25,19 @@ import net.osmand.Algoritms;
import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.binary.OsmandOdb;
import net.osmand.binary.OsmandOdb.CityIndex;
import net.osmand.binary.OsmandOdb.MapDataBlock;
import net.osmand.binary.OsmandOdb.OsmAndMapIndex.MapDataBox;
import net.osmand.binary.OsmandOdb.OsmAndMapIndex.MapEncodingRule;
import net.osmand.binary.OsmandOdb.OsmAndMapIndex.MapRootLevel;
import net.osmand.binary.OsmandOdb.IndexedStringTable;
import net.osmand.binary.OsmandOdb.OsmAndMapIndex;
import net.osmand.binary.OsmandOdb.OsmAndPoiBoxDataAtom;
import net.osmand.binary.OsmandOdb.OsmAndPoiNameIndex;
import net.osmand.binary.OsmandOdb.OsmAndPoiNameIndexDataAtom;
import net.osmand.binary.OsmandOdb.OsmAndTransportIndex;
import net.osmand.binary.OsmandOdb.StreetIndex;
import net.osmand.binary.OsmandOdb.StreetIntersection;
import net.osmand.binary.OsmandOdb.StringTable;
import net.osmand.binary.OsmandOdb.TransportRoute;
import net.osmand.binary.OsmandOdb.TransportRouteStop;
import net.osmand.binary.OsmandOdb.OsmAndCategoryTable.Builder;
@ -78,10 +82,6 @@ public class BinaryMapIndexWriter {
}
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>();
@ -271,35 +271,7 @@ public class BinaryMapIndexWriter {
public void endWriteMapTreeElement() throws IOException{
popState(MAP_TREE);
stackBounds.pop();
// TODO move to box
// Long l = stackBaseIds.pop();
// if(l != -1){
// codedOutStream.writeTag(OsmandOdb.MapTree.BASEID_FIELD_NUMBER, WireFormat.FieldType.UINT64.getWireType());
// codedOutStream.writeUInt64NoTag(l);
// }
// if(map != null){
//
// int i = 0;
// int size = 0;
// for(String s : map.keySet()){
// Integer integer = map.get(s);
// if(integer != i){
// throw new IllegalStateException();
// }
// i++;
// size += CodedOutputStream.computeStringSize(OsmandOdb.StringTable.S_FIELD_NUMBER, s);
// }
// codedOutStream.writeTag(OsmandOdb.MapTree.STRINGTABLE_FIELD_NUMBER, WireFormat.FieldType.MESSAGE.getWireType());
// STRING_TABLE_SIZE += CodedOutputStream.computeTagSize(OsmandOdb.MapTree.STRINGTABLE_FIELD_NUMBER) +
// CodedOutputStream.computeRawVarint32Size(size) + size;
// codedOutStream.writeRawVarint32(size);
// for(String s : map.keySet()){
// codedOutStream.writeString(OsmandOdb.StringTable.S_FIELD_NUMBER, s);
// }
// }
writeInt32Size();
}
@ -319,15 +291,36 @@ public class BinaryMapIndexWriter {
public void writeMapData(long id, byte[] nodes, byte[] types, String name, int highwayAttributes, byte[] restrictions) throws IOException{
assert state.peek() == MAP_TREE;
public MapDataBlock.Builder createWriteMapDataBlock(long baseid) throws IOException{
MapDataBlock.Builder builder = MapDataBlock.newBuilder();
builder.setBaseId(baseid);
return builder;
}
public void writeMapDataBlock(MapDataBlock.Builder builder, Map<String, Integer> stringTable, BinaryFileReference ref) throws IOException{
checkPeekState(MAP_INDEX_INIT);
StringTable.Builder bs = OsmandOdb.StringTable.newBuilder();
for(String s : stringTable.keySet()){
bs.addS(s);
}
StringTable st = bs.build();
builder.setStringTable(st);
int size = st.getSerializedSize();
STRING_TABLE_SIZE += CodedOutputStream.computeTagSize(OsmandOdb.MapDataBlock.STRINGTABLE_FIELD_NUMBER) +
CodedOutputStream.computeRawVarint32Size(size) + size;
ref.writeReference(raf, getFilePointer());
codedOutStream.writeMessage(OsmAndMapIndex.BLOCKS_FIELD_NUMBER, builder.build());
}
public void writeMapData(long diffId, byte[] nodes, byte[] types, Map<String,String> name, Map<String, Integer> stringTable,
MapDataBlock.Builder dataBlock) throws IOException{
Bounds bounds = stackBounds.peek();
if(stackBaseIds.peek() == -1){
stackBaseIds.pop();
stackBaseIds.push(id);
}
// calculate size
int sizeCoordinates = 0;
int allSize = 0;
@ -357,49 +350,32 @@ public class BinaryMapIndexWriter {
CodedOutputStream.computeRawVarint32Size(types.length) + types.length;
allSize += CodedOutputStream.computeSInt64Size(OsmandOdb.MapData.ID_FIELD_NUMBER, id - stackBaseIds.peek());
allSize += CodedOutputStream.computeSInt64Size(OsmandOdb.MapData.ID_FIELD_NUMBER, diffId);
// DEBUG
ID_SIZE += CodedOutputStream.computeSInt64Size(OsmandOdb.MapData.ID_FIELD_NUMBER, id - stackBaseIds.peek());
ID_SIZE += CodedOutputStream.computeSInt64Size(OsmandOdb.MapData.ID_FIELD_NUMBER, diffId);
int nameId = 0;
if(name != null){
if(stackStringTable.peek() == null) {
stackStringTable.pop();
stackStringTable.push(new LinkedHashMap<String, Integer>());
}
Map<String, Integer> map = stackStringTable.peek();
if(map.containsKey(name)) {
nameId = map.get(name);
if(stringTable.containsKey(name)) {
nameId = stringTable.get(name);
} else {
nameId = map.size();
map.put(name, nameId);
nameId = stringTable.size();
stringTable.put(name, nameId);
}
allSize += CodedOutputStream.computeUInt32Size(OsmandOdb.MapData.STRINGID_FIELD_NUMBER, nameId);
allSize += CodedOutputStream.computeUInt32Size(OsmandOdb.MapData.S, nameId);
}
int restrictionsSize = 0;
if(restrictions != null && restrictions.length > 0){
allSize += CodedOutputStream.computeTagSize(OsmandOdb.MapData.RESTRICTIONS_FIELD_NUMBER);
for (int i = 0; i < restrictions.length / 8; i++) {
long l = Algoritms.parseLongFromBytes(restrictions, i * 8) - stackBaseIds.peek();
restrictionsSize += CodedOutputStream.computeSInt64SizeNoTag(l);
}
allSize += CodedOutputStream.computeRawVarint32Size(restrictionsSize);
allSize += restrictionsSize;
}
if(highwayAttributes != 0){
allSize += CodedOutputStream.computeInt32Size(OsmandOdb.MapData.HIGHWAYMETA_FIELD_NUMBER, highwayAttributes);
}
// DEBUG
MAP_DATA_SIZE += allSize;
// writing data
codedOutStream.writeTag(OsmandOdb.MapTree.LEAFS_FIELD_NUMBER, WireFormat.FieldType.MESSAGE.getWireType());
codedOutStream.writeTag(MapDataBlock.DATAOBJECTS_FIELD_NUMBER, WireFormat.FieldType.MESSAGE.getWireType());
codedOutStream.writeRawVarint32(allSize);
/// TODO !!!!
codedOutStream.writeTag(OsmandOdb.MapData.COORDINATES_FIELD_NUMBER, WireFormat.FieldType.BYTES.getWireType());
codedOutStream.writeRawVarint32(sizeCoordinates);
@ -419,24 +395,17 @@ public class BinaryMapIndexWriter {
codedOutStream.writeRawVarint32(types.length);
codedOutStream.writeRawBytes(types);
codedOutStream.writeSInt64(OsmandOdb.MapData.ID_FIELD_NUMBER, id - stackBaseIds.peek());
// TODO !!!
if(name != null){
codedOutStream.writeUInt32(OsmandOdb.MapData.STRINGID_FIELD_NUMBER, nameId);
}
if(restrictions != null && restrictions.length > 0){
codedOutStream.writeTag(OsmandOdb.MapData.RESTRICTIONS_FIELD_NUMBER, WireFormat.FieldType.BYTES.getWireType());
codedOutStream.writeRawVarint32(restrictionsSize);
for (int i = 0; i < restrictions.length / 8; i++) {
long l = Algoritms.parseLongFromBytes(restrictions, i * 8) - stackBaseIds.peek();
codedOutStream.writeSInt64NoTag(l);
}
}
if(highwayAttributes != 0){
codedOutStream.writeInt32(OsmandOdb.MapData.HIGHWAYMETA_FIELD_NUMBER, highwayAttributes);
}
codedOutStream.writeSInt64(OsmandOdb.MapData.ID_FIELD_NUMBER, diffId);
}
public void startWriteAddressIndex(String name) throws IOException {

View file

@ -23,6 +23,8 @@ import java.util.Set;
import net.osmand.Algoritms;
import net.osmand.IProgress;
import net.osmand.binary.OsmandOdb.MapDataBlock;
import net.osmand.binary.OsmandOdb.MapDataBlock.Builder;
import net.osmand.data.Boundary;
import net.osmand.data.MapAlgorithms;
import net.osmand.osm.Entity;
@ -661,23 +663,40 @@ public class IndexVectorMapCreator extends AbstractIndexPartCreator {
public void writeBinaryMapBlock(rtree.Node parent, RTree r, BinaryMapIndexWriter writer, PreparedStatement selectData, TLongObjectHashMap<BinaryFileReference> bounds) throws IOException, RTreeException, SQLException {
Element[] e = parent.getAllElements();
Map<String, Integer> stringTable = null;
MapDataBlock.Builder dataBlock = null;
BinaryFileReference ref = bounds.get(parent.getNodeIndex());
long baseId = 0;
for (int i = 0; i < parent.getTotalElements(); i++) {
Rect re = e[i].getRect();
if (e[i].getElementType() == rtree.Node.LEAF_NODE) {
BinaryFileReference ref = bounds.get(parent.getNodeIndex());
// TODO create block
long id = ((LeafElement) e[i]).getPtr();
selectData.setLong(1, id);
ResultSet rs = selectData.executeQuery();
if (rs.next()) {
long cid = convertGeneratedIdToObfWrite(id);
if(dataBlock == null){
baseId = cid;
dataBlock = writer.createWriteMapDataBlock(baseId);
}
renderingTypes.getEncodingRuleTypes()
// mapConnection.prepareStatement("SELECT nodes, types, name FROM binary_map_objects WHERE id = ?");
writer.writeMapData(convertGeneratedIdToObfWrite(id), rs.getBytes(1),
writer.writeMapData(cid - id, rs.getBytes(1),
rs.getBytes(2), rs.getString(3));
} else {
logMapDataWarn.error("Something goes wrong with id = " + id); //$NON-NLS-1$
}
} else {
}
}
if(dataBlock != null){
writer.writeMapDataBlock(dataBlock, stringTable, ref);
}
for (int i = 0; i < parent.getTotalElements(); i++) {
Rect re = e[i].getRect();
if (e[i].getElementType() != rtree.Node.LEAF_NODE) {
long ptr = ((NonLeafElement) e[i]).getPtr();
rtree.Node ns = r.getReadNode(ptr);
writeBinaryMapBlock(ns, r, writer, selectData, bounds);

View file

@ -61,6 +61,8 @@ public class MapRenderingTypes {
private Map<AmenityType, Map<String, String>> amenityTypeNameToTagVal = null;
private Map<String, AmenityType> amenityNameToType = null;
private MapRulType nameRuleType;
public MapRenderingTypes(String fileName){
this.resourceName = fileName;
@ -79,6 +81,11 @@ public class MapRenderingTypes {
public Map<String, MapRulType> getEncodingRuleTypes(){
if (types == null) {
types = new LinkedHashMap<String, MapRulType>();
nameRuleType = new MapRulType(types.size());
nameRuleType.tag = "name";
nameRuleType.additional = true;
types.put(constructRuleKey("name", null), nameRuleType);
init();
}
return types;
@ -138,29 +145,29 @@ public class MapRenderingTypes {
}
public String getNullName(Entity e) {
Map<String, MapRulType> rules = getEncodingRuleTypes();
for (int i = 0; i < 2; i++) {
for (String tag : e.getTagKeySet()) {
String val = i == 0 ? e.getTag(tag) : null;
MapRulType rt = rules.get(constructRuleKey(tag, val));
if(rt != null && rt.nameNullTag != null && e.getTag(rt.nameNullTag) != null) {
return e.getTag(rt.nameNullTag);
}
}
}
return null;
}
public String getEntityName(Entity e) {
public void getEntityNames(Entity e, Map<MapRulType, String> names) {
String name = e.getTag(OSMTagKey.NAME);
if (name == null) {
name = e.getTag(OSMTagKey.NAME_EN);
if(name == null) {
name = getNullName(e);
}
if (name != null) {
names.put(nameRuleType, name);
}
Map<String, MapRulType> rules = getEncodingRuleTypes();
for (int i = 0; i < 2; i++) {
for (Entry<String, String> tag : e.getTags().entrySet()) {
MapRulType rt = rules.get(constructRuleKey(tag.getKey(), i == 0 ? tag.getValue() : null));
if (rt != null && rt.names != null) {
for (MapRulType rtname : rt.names) {
String tg = e.getTag(rtname.tag);
if (tg != null) {
names.put(rtname, name);
}
}
}
}
}
return name;
}
public Map<AmenityType, Map<String, String>> getAmenityTypeNameToTagVal() {
@ -259,7 +266,21 @@ public class MapRenderingTypes {
rtype.polyline= Boolean.parseBoolean(attributes.getValue("polyline")); //$NON-NLS-1$
rtype.point = Boolean.parseBoolean(attributes.getValue("point")); //$NON-NLS-1$
rtype.additional = Boolean.parseBoolean(attributes.getValue("additional")); //$NON-NLS-1$
rtype.nameNullTag = attributes.getValue("nameNullTag");
String v = attributes.getValue("nameTags");
if(v != null) {
String[] names = v.split(",");
rtype.names = new MapRulType[names.length];
for(int i=0; i<names.length; i++){
MapRulType mt = types.get(constructRuleKey(names[i], null));
if(mt == null){
mt = new MapRulType(types.size());
mt.tag = names[i];
mt.additional = true;
types.put(constructRuleKey(names[i], null), mt);
}
rtype.names[i] = mt;
}
}
String targetTag = attributes.getValue("target:tag");
String targetValue = attributes.getValue("target:value");
if (targetTag != null || targetValue != null) {
@ -378,14 +399,14 @@ public class MapRenderingTypes {
}
public static class MapRulType {
String nameNullTag;
MapRulType[] names;
String tag;
String value;
int minzoom;
boolean additional;
MapRulType targetTagValue;
int id;
final int id;
int freq;
int targetId;
@ -401,10 +422,6 @@ public class MapRenderingTypes {
this.id = id;
}
public String getNameNullTag() {
return nameNullTag;
}
public boolean isMapIndexed(){
return polygon || polyline || polygon;
}

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<osmand_types>
<!-- 3 different types for polygon="true" that object will be rendered as polygon, polyline ="true" as line, point = "true" - as point -->
<!-- currently 3 name tags are indexed name/ref/ele-->
<!-- currently name tags are indexed with name and additional in nameTags separated by comma-->
<!-- additional -->
<type polyline="true" tag="oneway" value="yes" minzoom="5" additional="true"/>
@ -23,38 +23,38 @@
<type polyline="true" polygon="true" tag="tunnel" minzoom="5" additional="true"/>
<category name="highway">
<type polyline="true" tag="highway" value="motorway" minzoom="5" />
<type polyline="true" tag="highway" value="motorway_link" minzoom="10" />
<type polyline="true" tag="highway" value="trunk" minzoom="5" />
<type polyline="true" tag="highway" value="trunk_link" minzoom="10" />
<type polyline="true" tag="highway" value="primary" minzoom="7" />
<type polyline="true" tag="highway" value="primary_link" minzoom="10" />
<type polyline="true" tag="highway" value="secondary" minzoom="9" />
<type polyline="true" tag="highway" value="secondary_link" minzoom="10" />
<type polyline="true" tag="highway" value="tertiary" minzoom="10" />
<type polyline="true" tag="highway" value="tertiary_link" minzoom="11" />
<type polygon="true" polyline="true" tag="highway" value="residential" minzoom="12" />
<type polygon="true" polyline="true" tag="highway" value="service" minzoom="13" />
<type polyline="true" tag="highway" value="motorway" minzoom="5" nameTags="ref"/>
<type polyline="true" tag="highway" value="motorway_link" minzoom="10" nameTags="ref"/>
<type polyline="true" tag="highway" value="trunk" minzoom="5" nameTags="ref"/>
<type polyline="true" tag="highway" value="trunk_link" minzoom="10" nameTags="ref"/>
<type polyline="true" tag="highway" value="primary" minzoom="7" nameTags="ref"/>
<type polyline="true" tag="highway" value="primary_link" minzoom="10" nameTags="ref"/>
<type polyline="true" tag="highway" value="secondary" minzoom="9" nameTags="ref"/>
<type polyline="true" tag="highway" value="secondary_link" minzoom="10" nameTags="ref"/>
<type polyline="true" tag="highway" value="tertiary" minzoom="10" nameTags="ref"/>
<type polyline="true" tag="highway" value="tertiary_link" minzoom="11" nameTags="ref"/>
<type polygon="true" polyline="true" tag="highway" value="residential" minzoom="12" nameTags="ref"/>
<type polygon="true" polyline="true" tag="highway" value="service" minzoom="13" nameTags="ref"/>
<type polyline="true" tag="highway" value="unclassified" minzoom="12" />
<type polyline="true" tag="highway" value="road" minzoom="12" />
<type polyline="true" tag="highway" value="track" minzoom="12" />
<type polyline="true" tag="highway" value="path" minzoom="12" />
<type polyline="true" tag="highway" value="living_street" minzoom="12" />
<type polyline="true" tag="highway" value="unclassified" minzoom="12" nameTags="ref"/>
<type polyline="true" tag="highway" value="road" minzoom="12" nameTags="ref"/>
<type polyline="true" tag="highway" value="track" minzoom="12" nameTags="ref"/>
<type polyline="true" tag="highway" value="path" minzoom="12" nameTags="ref"/>
<type polyline="true" tag="highway" value="living_street" minzoom="12" nameTags="ref"/>
<type polygon="true" polyline="true" tag="highway" value="pedestrian" minzoom="12" />
<type polyline="true" tag="highway" value="cycleway" minzoom="12" />
<type polyline="true" tag="highway" value="byway" minzoom="12" />
<type polyline="true" tag="highway" value="footway" minzoom="12" />
<type polyline="true" tag="highway" value="steps" minzoom="14" />
<type polyline="true" tag="highway" value="bridleway" minzoom="12" />
<type polygon="true" point="true" tag="highway" value="services" minzoom="12" />
<type polygon="true" polyline="true" tag="highway" value="pedestrian" minzoom="12" nameTags="ref"/>
<type polyline="true" tag="highway" value="cycleway" minzoom="12" nameTags="ref"/>
<type polyline="true" tag="highway" value="byway" minzoom="12" nameTags="ref"/>
<type polyline="true" tag="highway" value="footway" minzoom="12" nameTags="ref"/>
<type polyline="true" tag="highway" value="steps" minzoom="14" nameTags="ref"/>
<type polyline="true" tag="highway" value="bridleway" minzoom="12" nameTags="ref"/>
<type polygon="true" point="true" tag="highway" value="services" minzoom="12" nameTags="ref"/>
<!-- <type id="" polyline="true" tag="highway" value="bus_guideway" minzoom="15" /> -->
<type polyline="true" point="true" tag="highway" value="ford" minzoom="14" />
<type polyline="true" tag="highway" value="construction" minzoom="14" />
<type polyline="true" tag="highway" value="proposed" minzoom="14" />
<type polyline="true" tag="highway" value="construction" minzoom="14" nameTags="ref"/>
<type polyline="true" tag="highway" value="proposed" minzoom="14" nameTags="ref"/>
<!-- POINT typeS -->
<type point="true" tag="highway" value="mini_roundabout" minzoom="16" />
@ -176,7 +176,7 @@
<type polyline="true" tag="aeroway" value="taxiway" minzoom="12" poi:prefix="aeroway_"/>
<type polygon="true" tag="aeroway" value="apron" minzoom="12" poi:prefix="aeroway_"/>
<type point="true" polygon="true" tag="aeroway" value="airport" minzoom="11" />
<type point="true" tag="aeroway" value="gate" minzoom="15" nameNullTag="ref" />
<type point="true" tag="aeroway" value="gate" minzoom="15" nameTags="ref" />
<type point="true" tag="aeroway" value="windsock" minzoom="15" />
</category>
@ -206,8 +206,8 @@
<category name="man_made" poi:tag="man_made" poi:category="man_made">
<type polygon="true" tag="building" minzoom="16" poi:category="" nameNullTag="addr:housenumber"/>
<type point="true" tag="addr:housenumber" minzoom="16" nameNullTag="addr:housenumber"/>
<type polygon="true" tag="building" minzoom="16" poi:category="" nameTags="addr:housenumber"/>
<type point="true" tag="addr:housenumber" minzoom="16" nameTags="addr:housenumber"/>
<type point="true" polygon="true" tag="man_made" value="wastewater_plant" minzoom="16" />
<type polygon="true" point="true" tag="man_made" value="water_works" minzoom="16" />
<type point="true" polygon="true" tag="man_made" value="works" minzoom="15" />
@ -449,7 +449,7 @@
<type point="true" polygon="true" tag="natural" value="land" minzoom="10" poi:category="" />
<type point="true" polygon="true" tag="natural" value="marsh" minzoom="11" />
<type point="true" polygon="true" tag="natural" value="mud" minzoom="11" />
<type point="true" tag="natural" value="peak" minzoom="11" nameNullTag="ele" />
<type point="true" tag="natural" value="peak" minzoom="11" nameTags="ele" />
<type point="true" polygon="true" tag="natural" value="sand" minzoom="11" />
<type point="true" polygon="true" tag="natural" value="scree" minzoom="11" />
<type point="true" polygon="true" tag="natural" value="scrub" minzoom="11" />

View file

@ -72,8 +72,6 @@ message OsmAndMapIndex {
required string name = 2;
// encoded as fixed32 length delimited
repeated MapEncodingRule rules = 4;
message MapEncodingRule {
required string tag = 3;
@ -87,6 +85,7 @@ message OsmAndMapIndex {
optional uint32 type = 10;
}
// encoded as fixed32 length delimited
repeated MapRootLevel levels = 5;
message MapRootLevel {
required int32 maxZoom = 1;
@ -111,7 +110,6 @@ message OsmAndMapIndex {
repeated MapDataBox boxes = 7;
}
// encoded as fixed32 length delimited
repeated MapDataBlocks blocks = 7;
message MapDataBlocks {
// based coordinates can be specified