Fix address information
This commit is contained in:
parent
4b3e1eae02
commit
18cbce2092
11 changed files with 225 additions and 291 deletions
|
@ -76,6 +76,7 @@ public final class CodedInputStreamRAF {
|
|||
|
||||
lastTag = readRawVarint32();
|
||||
if (WireFormat.getTagFieldNumber(lastTag) == 0) {
|
||||
System.out.println(getTotalBytesRead());
|
||||
// If we actually read zero (or any tag number corresponding to field
|
||||
// number zero), that's not a valid tag.
|
||||
throw InvalidProtocolBufferException.invalidTag();
|
||||
|
|
|
@ -46,7 +46,7 @@ public class BinaryInspector {
|
|||
// inspector(new String[]{"-v","C:\\Users\\tpd\\osmand\\Housenumbers.obf"});
|
||||
//inspector(new String[]{"/home/victor/projects/OsmAnd/data/osm-gen/saved/Belarus-newzooms-new-rt.obf"});
|
||||
// inspector(new String[]{"/home/victor/projects/OsmAnd/download/spain/Spain_europe_1_small.obf"});
|
||||
inspector(new String[]{"/home/victor/projects/OsmAnd/data/osm-gen/Luxembourg.obf"});
|
||||
inspector(new String[]{"-vaddress", "/home/victor/projects/OsmAnd/data/osm-gen/Luxembourg.obf"});
|
||||
|
||||
|
||||
// test case extract parts
|
||||
|
@ -470,31 +470,31 @@ public class BinaryInspector {
|
|||
} else if (p instanceof AddressRegion && (verbose != null && verbose.isVaddress())) {
|
||||
for(String region : index.getRegionNames()){
|
||||
println("\tRegion:" + region);
|
||||
for (City c : index.getCities(region, null)) {
|
||||
index.preloadStreets(c, null);
|
||||
println("\t\tCity:" + c.getName() + getId(c));
|
||||
for (Street t : c.getStreets()) {
|
||||
if (verbose.contains(t)) {
|
||||
print("\t\t\t" + t.getName() + getId(t));
|
||||
index.preloadBuildings(t, null);
|
||||
List<Building> buildings = t.getBuildings();
|
||||
if (buildings != null && !buildings.isEmpty()) {
|
||||
print("\t\t\t\t (");
|
||||
for (Building b : buildings) {
|
||||
print(b.getName() + ",");
|
||||
}
|
||||
print(")");
|
||||
}
|
||||
println("");
|
||||
}
|
||||
}
|
||||
}
|
||||
for (City c : index.getVillages(region, null,null,false)) {
|
||||
if (verbose.contains(c)) {
|
||||
int[] cityType = new int[] {BinaryMapAddressReaderAdapter.CITY_TOWN_TYPE,
|
||||
BinaryMapAddressReaderAdapter.POSTCODES_TYPE,
|
||||
BinaryMapAddressReaderAdapter.VILLAGES_TYPE};
|
||||
for (int j = 0; j < cityType.length; j++) {
|
||||
int type = cityType[j];
|
||||
for (City c : index.getCities(region, null, type)) {
|
||||
println("\t\t" + c + getId(c));
|
||||
index.preloadStreets(c, null);
|
||||
println("\t\tVillage:" + c.getName() + getId(c));
|
||||
for (Street t : c.getStreets()) {
|
||||
println("\t\t\t" + t.getName() + getId(t));
|
||||
if (verbose.contains(t)) {
|
||||
print("\t\t\t" + t.getName() + getId(t));
|
||||
// if (type == BinaryMapAddressReaderAdapter.CITY_TOWN_TYPE) {
|
||||
index.preloadBuildings(t, null);
|
||||
List<Building> buildings = t.getBuildings();
|
||||
if (buildings != null && !buildings.isEmpty()) {
|
||||
print("\t\t\t\t (");
|
||||
for (Building b : buildings) {
|
||||
print(b.getName() + ",");
|
||||
}
|
||||
print(")");
|
||||
}
|
||||
// }
|
||||
println("");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -512,6 +512,9 @@ public class BinaryInspector {
|
|||
}
|
||||
|
||||
private static String getId(MapObject o ){
|
||||
if(o.getId() == null) {
|
||||
return " no id " ;
|
||||
}
|
||||
return " " + (o.getId() >> 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
package net.osmand.binary;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.osmand.StringMatcher;
|
||||
import net.osmand.binary.BinaryMapIndexReader.SearchRequest;
|
||||
import net.osmand.binary.OsmandOdb.OsmAndAddressIndex.CitiesIndex;
|
||||
import net.osmand.data.Building;
|
||||
import net.osmand.data.City;
|
||||
import net.osmand.data.City.CityType;
|
||||
import net.osmand.data.MapObject;
|
||||
import net.osmand.data.PostCode;
|
||||
import net.osmand.data.Street;
|
||||
import net.osmand.osm.LatLon;
|
||||
import net.osmand.osm.MapUtils;
|
||||
|
@ -20,16 +21,22 @@ import com.google.protobuf.WireFormat;
|
|||
|
||||
public class BinaryMapAddressReaderAdapter {
|
||||
|
||||
public final static int CITY_TOWN_TYPE = 1;
|
||||
public final static int POSTCODES_TYPE = 2;
|
||||
public final static int VILLAGES_TYPE = 3;
|
||||
public final static int STREET_TYPE = 4;
|
||||
|
||||
public static class AddressRegion extends BinaryIndexPart {
|
||||
String enName;
|
||||
|
||||
int postcodesOffset = -1;
|
||||
int villagesOffset = -1;
|
||||
int citiesOffset = -1;
|
||||
|
||||
int indexNameOffset = -1;
|
||||
List<CitiesBlock> cities = new ArrayList<BinaryMapAddressReaderAdapter.CitiesBlock>();
|
||||
LatLon calculatedCenter = null;
|
||||
}
|
||||
|
||||
public static class CitiesBlock extends BinaryIndexPart {
|
||||
int type;
|
||||
}
|
||||
|
||||
private CodedInputStreamRAF codedIS;
|
||||
private final BinaryMapIndexReader map;
|
||||
|
||||
|
@ -64,19 +71,32 @@ public class BinaryMapAddressReaderAdapter {
|
|||
region.enName = codedIS.readString();
|
||||
break;
|
||||
case OsmandOdb.OsmAndAddressIndex.CITIES_FIELD_NUMBER :
|
||||
region.citiesOffset = codedIS.getTotalBytesRead();
|
||||
CitiesBlock block = new CitiesBlock();
|
||||
region.cities.add(block);
|
||||
block.type = 1;
|
||||
block.length = readInt();
|
||||
block.filePointer = codedIS.getTotalBytesRead();
|
||||
while(true){
|
||||
int tt = codedIS.readTag();
|
||||
int ttag = WireFormat.getTagFieldNumber(tt);
|
||||
if(ttag == 0) {
|
||||
break;
|
||||
} else if(ttag == CitiesIndex.TYPE_FIELD_NUMBER){
|
||||
block.type = codedIS.readUInt32();
|
||||
break;
|
||||
} else {
|
||||
skipUnknownField(tt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
codedIS.seek(block.filePointer + block.length);
|
||||
|
||||
break;
|
||||
case OsmandOdb.OsmAndAddressIndex.NAMEINDEX_FIELD_NUMBER :
|
||||
region.indexNameOffset = codedIS.getTotalBytesRead();
|
||||
int length = readInt();
|
||||
codedIS.seek(region.citiesOffset + length + 4);
|
||||
break;
|
||||
case OsmandOdb.OsmAndAddressIndex.VILLAGES_FIELD_NUMBER :
|
||||
region.villagesOffset = codedIS.getTotalBytesRead();
|
||||
length = readInt();
|
||||
codedIS.seek(region.villagesOffset + length + 4);
|
||||
break;
|
||||
case OsmandOdb.OsmAndAddressIndex.POSTCODES_FIELD_NUMBER :
|
||||
region.postcodesOffset = codedIS.getTotalBytesRead();
|
||||
length = readInt();
|
||||
codedIS.seek(region.postcodesOffset + length + 4);
|
||||
codedIS.seek(region.indexNameOffset + length + 4);
|
||||
break;
|
||||
default:
|
||||
skipUnknownField(t);
|
||||
|
@ -85,19 +105,18 @@ public class BinaryMapAddressReaderAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
protected void readCities(List<City> cities, SearchRequest<MapObject> resultMatcher, StringMatcher matcher, boolean useEn) throws IOException {
|
||||
protected void readCities(List<City> cities, SearchRequest<City> resultMatcher, StringMatcher matcher, boolean useEn) throws IOException {
|
||||
while(true){
|
||||
int t = codedIS.readTag();
|
||||
int tag = WireFormat.getTagFieldNumber(t);
|
||||
switch (tag) {
|
||||
case 0:
|
||||
return;
|
||||
case OsmandOdb.CitiesIndex.CITIES_FIELD_NUMBER :
|
||||
int offset = codedIS.getTotalBytesRead();
|
||||
case CitiesIndex.CITIES_FIELD_NUMBER :
|
||||
int fp = codedIS.getTotalBytesRead();
|
||||
int length = codedIS.readRawVarint32();
|
||||
|
||||
int oldLimit = codedIS.pushLimit(length);
|
||||
City c = readCity(null, offset, false, null, matcher, useEn);
|
||||
City c = readCityHeader(matcher, fp, useEn);
|
||||
if(c != null){
|
||||
if (resultMatcher == null || resultMatcher.publish(c)) {
|
||||
cities.add(c);
|
||||
|
@ -115,56 +134,32 @@ public class BinaryMapAddressReaderAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
protected PostCode readPostcode(PostCode p, int fileOffset, SearchRequest<Street> resultMatcher, boolean loadStreets, String postcodeFilter) throws IOException{
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
|
||||
protected void readCityStreets(SearchRequest<Street> resultMatcher, City city) throws IOException{
|
||||
int x = MapUtils.get31TileNumberX(city.getLocation().getLongitude());
|
||||
int y = MapUtils.get31TileNumberY(city.getLocation().getLatitude());
|
||||
while(true){
|
||||
int t = codedIS.readTag();
|
||||
int tag = WireFormat.getTagFieldNumber(t);
|
||||
switch (tag) {
|
||||
case 0:
|
||||
return p;
|
||||
case OsmandOdb.PostcodeIndex.POSTCODE_FIELD_NUMBER :
|
||||
String name = codedIS.readString();
|
||||
if(postcodeFilter != null && !postcodeFilter.equalsIgnoreCase(name)){
|
||||
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
|
||||
return null;
|
||||
}
|
||||
if(p == null){
|
||||
p = new PostCode(name);
|
||||
p.setFileOffset(fileOffset);
|
||||
}
|
||||
p.setName(name);
|
||||
break;
|
||||
case OsmandOdb.PostcodeIndex.X_FIELD_NUMBER :
|
||||
x = codedIS.readFixed32();
|
||||
break;
|
||||
case OsmandOdb.PostcodeIndex.Y_FIELD_NUMBER :
|
||||
y = codedIS.readFixed32();
|
||||
p.setLocation(MapUtils.get31LatitudeY(y), MapUtils.get31LongitudeX(x));
|
||||
if(!loadStreets){
|
||||
// skip everything
|
||||
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
|
||||
return p;
|
||||
}
|
||||
break;
|
||||
case OsmandOdb.PostcodeIndex.STREETS_FIELD_NUMBER :
|
||||
int offset = codedIS.getTotalBytesRead();
|
||||
return;
|
||||
case OsmandOdb.CityBlockIndex.STREETS_FIELD_NUMBER :
|
||||
Street s = new Street(city);
|
||||
s.setFileOffset(codedIS.getTotalBytesRead());
|
||||
int length = codedIS.readRawVarint32();
|
||||
if(loadStreets){
|
||||
Street s = new Street(null);
|
||||
int oldLimit = codedIS.pushLimit(length);
|
||||
s.setFileOffset(offset);
|
||||
readStreet(s, null, true, x >> 7, y >> 7, p.getName());
|
||||
if (resultMatcher == null || resultMatcher.publish(s)) {
|
||||
p.registerStreet(s, false);
|
||||
}
|
||||
codedIS.popLimit(oldLimit);
|
||||
} else {
|
||||
codedIS.skipRawBytes(length);
|
||||
int oldLimit = codedIS.pushLimit(length);
|
||||
readStreet(s, null, false, x >> 7, y >> 7, city.isPostcode() ? city.getName() : null);
|
||||
if(resultMatcher == null || resultMatcher.publish(s)){
|
||||
city.registerStreet(s);
|
||||
}
|
||||
if(resultMatcher != null && resultMatcher.isCancelled()) {
|
||||
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
|
||||
}
|
||||
codedIS.popLimit(oldLimit);
|
||||
break;
|
||||
case OsmandOdb.CityBlockIndex.BUILDINGS_FIELD_NUMBER :
|
||||
skipUnknownField(t);
|
||||
default:
|
||||
skipUnknownField(t);
|
||||
break;
|
||||
|
@ -172,12 +167,10 @@ public class BinaryMapAddressReaderAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
protected City readCity(City c, int fileOffset, boolean loadStreets, SearchRequest<Street> resultMatcher,
|
||||
StringMatcher nameMatcher, boolean useEn) throws IOException{
|
||||
protected City readCityHeader(StringMatcher nameMatcher, int filePointer, boolean useEn) throws IOException{
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int streetInd = 0;
|
||||
City c = null;
|
||||
boolean englishNameMatched = false;
|
||||
while(true){
|
||||
int t = codedIS.readTag();
|
||||
|
@ -187,10 +180,7 @@ public class BinaryMapAddressReaderAdapter {
|
|||
return c;
|
||||
case OsmandOdb.CityIndex.CITY_TYPE_FIELD_NUMBER :
|
||||
int type = codedIS.readUInt32();
|
||||
if(c == null){
|
||||
c = new City(CityType.values()[type]);
|
||||
c.setFileOffset(fileOffset);
|
||||
}
|
||||
c = new City(CityType.values()[type]);
|
||||
break;
|
||||
case OsmandOdb.CityIndex.ID_FIELD_NUMBER :
|
||||
c.setId(codedIS.readUInt64());
|
||||
|
@ -213,7 +203,6 @@ public class BinaryMapAddressReaderAdapter {
|
|||
break;
|
||||
case OsmandOdb.CityIndex.NAME_FIELD_NUMBER :
|
||||
String name = codedIS.readString();
|
||||
c.setName(name);
|
||||
if(nameMatcher != null){
|
||||
if(!useEn){
|
||||
if(!nameMatcher.matches(name)) {
|
||||
|
@ -226,41 +215,25 @@ public class BinaryMapAddressReaderAdapter {
|
|||
}
|
||||
}
|
||||
}
|
||||
if(c == null) {
|
||||
c = City.createPostcode(name);
|
||||
}
|
||||
c.setName(name);
|
||||
break;
|
||||
case OsmandOdb.CityIndex.X_FIELD_NUMBER :
|
||||
x = codedIS.readFixed32();
|
||||
x = codedIS.readUInt32();
|
||||
break;
|
||||
case OsmandOdb.CityIndex.Y_FIELD_NUMBER :
|
||||
y = codedIS.readFixed32();
|
||||
y = codedIS.readUInt32();
|
||||
c.setLocation(MapUtils.get31LatitudeY(y), MapUtils.get31LongitudeX(x));
|
||||
if(c.getEnName().length() == 0){
|
||||
c.setEnName(Junidecode.unidecode(c.getName()));
|
||||
}
|
||||
if(!loadStreets){
|
||||
// skip everything
|
||||
codedIS.skipRawBytes(codedIS.getBytesUntilLimit());
|
||||
return c;
|
||||
}
|
||||
break;
|
||||
case OsmandOdb.CityIndex.INTERSECTIONS_FIELD_NUMBER :
|
||||
codedIS.skipRawBytes(codedIS.readRawVarint32());
|
||||
break;
|
||||
case OsmandOdb.CityIndex.STREETS_FIELD_NUMBER :
|
||||
int offset = codedIS.getTotalBytesRead();
|
||||
int length = codedIS.readRawVarint32();
|
||||
if(loadStreets){
|
||||
Street s = new Street(c);
|
||||
int oldLimit = codedIS.pushLimit(length);
|
||||
s.setFileOffset(offset);
|
||||
s.setIndexInCity(streetInd++);
|
||||
readStreet(s, null, false, x >> 7, y >> 7, null);
|
||||
if (resultMatcher == null || resultMatcher.publish(s)) {
|
||||
c.registerStreet(s);
|
||||
}
|
||||
codedIS.popLimit(oldLimit);
|
||||
} else {
|
||||
codedIS.skipRawBytes(length);
|
||||
}
|
||||
case OsmandOdb.CityIndex.SHIFTTOCITYBLOCKINDEX_FIELD_NUMBER :
|
||||
int offset = readInt();
|
||||
offset += filePointer;
|
||||
c.setFileOffset(offset);
|
||||
break;
|
||||
default:
|
||||
skipUnknownField(t);
|
||||
|
@ -310,6 +283,10 @@ public class BinaryMapAddressReaderAdapter {
|
|||
y = (int) MapUtils.getTileNumberY(24, s.getLocation().getLatitude());
|
||||
}
|
||||
break;
|
||||
case OsmandOdb.StreetIndex.INTERSECTIONS_FIELD_NUMBER :
|
||||
// TODO
|
||||
skipUnknownField(t);
|
||||
break;
|
||||
case OsmandOdb.StreetIndex.BUILDINGS_FIELD_NUMBER :
|
||||
int offset = codedIS.getTotalBytesRead();
|
||||
int length = codedIS.readRawVarint32();
|
||||
|
|
|
@ -27,6 +27,7 @@ import net.osmand.ResultMatcher;
|
|||
import net.osmand.StringMatcher;
|
||||
import net.osmand.CollatorStringMatcher.StringMatcherMode;
|
||||
import net.osmand.binary.BinaryMapAddressReaderAdapter.AddressRegion;
|
||||
import net.osmand.binary.BinaryMapAddressReaderAdapter.CitiesBlock;
|
||||
import net.osmand.binary.BinaryMapPoiReaderAdapter.PoiRegion;
|
||||
import net.osmand.binary.BinaryMapTransportReaderAdapter.TransportIndex;
|
||||
import net.osmand.binary.OsmandOdb.OsmAndMapIndex.MapDataBox;
|
||||
|
@ -37,7 +38,6 @@ import net.osmand.data.AmenityType;
|
|||
import net.osmand.data.Building;
|
||||
import net.osmand.data.City;
|
||||
import net.osmand.data.MapObject;
|
||||
import net.osmand.data.PostCode;
|
||||
import net.osmand.data.Street;
|
||||
import net.osmand.data.TransportRoute;
|
||||
import net.osmand.data.TransportStop;
|
||||
|
@ -469,67 +469,29 @@ public class BinaryMapIndexReader {
|
|||
throw new IllegalArgumentException(name);
|
||||
}
|
||||
|
||||
public List<PostCode> getPostcodes(String region, SearchRequest<MapObject> resultMatcher, StringMatcher nameMatcher) throws IOException {
|
||||
List<PostCode> postcodes = new ArrayList<PostCode>();
|
||||
AddressRegion r = getRegionByName(region);
|
||||
if(r.postcodesOffset != -1){
|
||||
codedIS.seek(r.postcodesOffset);
|
||||
int len = readInt();
|
||||
int old = codedIS.pushLimit(len);
|
||||
addressAdapter.readPostcodes(postcodes, resultMatcher, nameMatcher);
|
||||
codedIS.popLimit(old);
|
||||
}
|
||||
return postcodes;
|
||||
}
|
||||
|
||||
public PostCode getPostcodeByName(String region, String name) throws IOException {
|
||||
public List<City> getCities(String region, SearchRequest<City> resultMatcher,
|
||||
int cityType) throws IOException {
|
||||
List<City> cities = new ArrayList<City>();
|
||||
AddressRegion r = getRegionByName(region);
|
||||
if (r.postcodesOffset != -1) {
|
||||
codedIS.seek(r.postcodesOffset);
|
||||
int len = readInt();
|
||||
int old = codedIS.pushLimit(len);
|
||||
PostCode p = addressAdapter.findPostcode(name);
|
||||
if (p != null) {
|
||||
return p;
|
||||
for(CitiesBlock block : r.cities) {
|
||||
if(block.type == cityType) {
|
||||
codedIS.seek(block.filePointer);
|
||||
int old = codedIS.pushLimit(block.length);
|
||||
addressAdapter.readCities(cities, resultMatcher, null, false);
|
||||
codedIS.popLimit(old);
|
||||
}
|
||||
codedIS.popLimit(old);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<City> getCities(String region, SearchRequest<MapObject> resultMatcher) throws IOException {
|
||||
List<City> cities = new ArrayList<City>();
|
||||
AddressRegion r = getRegionByName(region);
|
||||
if(r.citiesOffset != -1){
|
||||
codedIS.seek(r.citiesOffset);
|
||||
int len = readInt();
|
||||
int old = codedIS.pushLimit(len);
|
||||
addressAdapter.readCities(cities, resultMatcher, null, false);
|
||||
codedIS.popLimit(old);
|
||||
}
|
||||
return cities;
|
||||
}
|
||||
|
||||
public List<City> getVillages(String region, SearchRequest<MapObject> resultMatcher, StringMatcher nameMatcher, boolean useEn) throws IOException {
|
||||
List<City> cities = new ArrayList<City>();
|
||||
AddressRegion r = getRegionByName(region);
|
||||
if(r.villagesOffset != -1){
|
||||
codedIS.seek(r.villagesOffset);
|
||||
int len = readInt();
|
||||
int old = codedIS.pushLimit(len);
|
||||
addressAdapter.readCities(cities, resultMatcher, nameMatcher, useEn);
|
||||
codedIS.popLimit(old);
|
||||
}
|
||||
return cities;
|
||||
}
|
||||
|
||||
|
||||
public void preloadStreets(City c, SearchRequest<Street> resultMatcher) throws IOException {
|
||||
checkAddressIndex(c.getFileOffset());
|
||||
codedIS.seek(c.getFileOffset());
|
||||
int size = codedIS.readRawVarint32();
|
||||
int old = codedIS.pushLimit(size);
|
||||
addressAdapter.readCity(c, c.getFileOffset(), true, resultMatcher, null, false);
|
||||
addressAdapter.readCityStreets(resultMatcher, c);
|
||||
codedIS.popLimit(old);
|
||||
}
|
||||
|
||||
|
@ -732,7 +694,7 @@ public class BinaryMapIndexReader {
|
|||
tree.top = codedIS.readSInt32() + atop;
|
||||
break;
|
||||
case MapDataBox.SHIFTTOMAPDATA_FIELD_NUMBER :
|
||||
tree.mapDataBlock = codedIS.readFixed32() + tree.filePointer;
|
||||
tree.mapDataBlock = readInt() + tree.filePointer;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -13,7 +13,7 @@ import net.osmand.osm.OSMSettings.OSMTagKey;
|
|||
|
||||
|
||||
public class City extends MapObject {
|
||||
|
||||
|
||||
public enum CityType {
|
||||
// that's tricky way to play with that numbers (to avoid including suburbs in city & vice verse)
|
||||
CITY(10000), TOWN(5000), VILLAGE(1300), HAMLET(1000), SUBURB(400);
|
||||
|
@ -31,7 +31,7 @@ public class City extends MapObject {
|
|||
public static String valueToString(CityType t) {
|
||||
return t.toString().toLowerCase();
|
||||
}
|
||||
|
||||
|
||||
public static CityType valueFromString(String place) {
|
||||
if (place == null) {
|
||||
return null;
|
||||
|
@ -44,65 +44,83 @@ public class City extends MapObject {
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private CityType type = null;
|
||||
// Be attentive ! Working with street names ignoring case
|
||||
private Map<String, Street> streets = new TreeMap<String, Street>(Collator.getInstance());
|
||||
private Map<String, Street> streets = new TreeMap<String, Street>(Collator.getInstance());
|
||||
private String isin = null;
|
||||
private String postcode = null;
|
||||
|
||||
public City(Node el){
|
||||
|
||||
public City(Node el) {
|
||||
super(el);
|
||||
type = CityType.valueFromString(el.getTag(OSMTagKey.PLACE));
|
||||
isin = el.getTag(OSMTagKey.IS_IN);
|
||||
isin = isin != null ? isin.toLowerCase() : null;
|
||||
}
|
||||
|
||||
public City(CityType type){
|
||||
|
||||
public City(CityType type) {
|
||||
if(type == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
private City(String postcode) {
|
||||
this.type = null;
|
||||
this.name = this.enName = postcode;
|
||||
}
|
||||
|
||||
public static City createPostcode(String postcode){
|
||||
return new City(postcode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getIsInValue() {
|
||||
return isin;
|
||||
}
|
||||
|
||||
public boolean isEmptyWithStreets(){
|
||||
public boolean isPostcode(){
|
||||
return type == null;
|
||||
}
|
||||
|
||||
public boolean isEmptyWithStreets() {
|
||||
return streets.isEmpty();
|
||||
}
|
||||
|
||||
public Street registerStreet(String street){
|
||||
if(!streets.containsKey(street.toLowerCase())){
|
||||
|
||||
public Street registerStreet(String street) {
|
||||
if (!streets.containsKey(street.toLowerCase())) {
|
||||
streets.put(street.toLowerCase(), new Street(this, street));
|
||||
}
|
||||
return streets.get(street.toLowerCase());
|
||||
return streets.get(street.toLowerCase());
|
||||
}
|
||||
|
||||
public Street unregisterStreet(String name){
|
||||
return streets.remove(name.toLowerCase());
|
||||
|
||||
public Street unregisterStreet(String name) {
|
||||
return streets.remove(name.toLowerCase());
|
||||
}
|
||||
|
||||
public void removeAllStreets(){
|
||||
|
||||
public void removeAllStreets() {
|
||||
streets.clear();
|
||||
}
|
||||
|
||||
|
||||
public String getPostcode() {
|
||||
return postcode;
|
||||
}
|
||||
|
||||
|
||||
public void setPostcode(String postcode) {
|
||||
this.postcode = postcode;
|
||||
}
|
||||
|
||||
public Street registerStreet(Street street, boolean en){
|
||||
String name = en ? street.getEnName(): street.getName();
|
||||
|
||||
protected Street registerStreet(Street street, boolean en) {
|
||||
String name = en ? street.getEnName() : street.getName();
|
||||
name = name.toLowerCase();
|
||||
if(!Algoritms.isEmpty(name)){
|
||||
if(!streets.containsKey(name)){
|
||||
if (!Algoritms.isEmpty(name)) {
|
||||
if (!streets.containsKey(name)) {
|
||||
return streets.put(name, street);
|
||||
} else {
|
||||
// try to merge streets
|
||||
Street prev = streets.get(name);
|
||||
if(!street.getWayNodes().isEmpty()){
|
||||
if (!street.getWayNodes().isEmpty()) {
|
||||
prev.getWayNodes().addAll(street.getWayNodes());
|
||||
}
|
||||
prev.getBuildings().addAll(street.getBuildings());
|
||||
|
@ -111,40 +129,43 @@ public class City extends MapObject {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Street registerStreet(Street street){
|
||||
|
||||
public Street registerStreet(Street street) {
|
||||
return registerStreet(street, false);
|
||||
}
|
||||
|
||||
public Building registerBuilding(Entity e){
|
||||
|
||||
public Building registerBuilding(Entity e) {
|
||||
String number = e.getTag(OSMTagKey.ADDR_HOUSE_NUMBER);
|
||||
String street = e.getTag(OSMTagKey.ADDR_STREET);
|
||||
if( street != null && number != null){
|
||||
if (street != null && number != null) {
|
||||
return registerStreet(street).registerBuilding(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public CityType getType(){
|
||||
|
||||
public CityType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public Collection<Street> getStreets(){
|
||||
|
||||
public Collection<Street> getStreets() {
|
||||
return streets.values();
|
||||
}
|
||||
|
||||
public Street getStreet(String name){
|
||||
|
||||
public Street getStreet(String name) {
|
||||
return streets.get(name.toLowerCase());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "City [" +type+"] " + getName(); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
if(isPostcode()) {
|
||||
return "Postcode : " + getName(); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
return "City [" + type + "] " + getName(); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void doDataPreparation(){
|
||||
for(Street s : new ArrayList<Street>(getStreets())){
|
||||
public void doDataPreparation() {
|
||||
for (Street s : new ArrayList<Street>(getStreets())) {
|
||||
s.doDataPreparation();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
package net.osmand.data;
|
||||
|
||||
import java.text.Collator;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class PostCode extends MapObject {
|
||||
private Map<String, Street> streets = new TreeMap<String, Street>(Collator.getInstance());
|
||||
|
||||
public PostCode(String name){
|
||||
setName(name);
|
||||
setEnName(name);
|
||||
setId(-1L);
|
||||
}
|
||||
|
||||
public boolean isEmptyWithStreets(){
|
||||
return streets.isEmpty();
|
||||
}
|
||||
|
||||
public Street getStreet(String name){
|
||||
return streets.get(name);
|
||||
}
|
||||
|
||||
public Collection<Street> getStreets() {
|
||||
return streets.values();
|
||||
}
|
||||
|
||||
public void removeAllStreets()
|
||||
{
|
||||
streets.clear();
|
||||
}
|
||||
|
||||
public Street registerStreet(Street street, boolean useEnglishNames){
|
||||
String name = street.getName(useEnglishNames);
|
||||
streets.put(name, street);
|
||||
return street;
|
||||
}
|
||||
|
||||
}
|
|
@ -47,6 +47,10 @@ public class Street extends MapObject {
|
|||
buildings.add(building);
|
||||
}
|
||||
|
||||
public void registerBuildings(List<Building> buildings){
|
||||
this.buildings.addAll(buildings);
|
||||
}
|
||||
|
||||
public List<Building> getBuildings() {
|
||||
return buildings;
|
||||
}
|
||||
|
|
|
@ -53,7 +53,6 @@ import net.osmand.data.City;
|
|||
import net.osmand.data.City.CityType;
|
||||
import net.osmand.data.IndexConstants;
|
||||
import net.osmand.data.MapObject;
|
||||
import net.osmand.data.PostCode;
|
||||
import net.osmand.data.Street;
|
||||
import net.osmand.data.TransportStop;
|
||||
import net.osmand.data.preparation.IndexPoiCreator.PoiTileBox;
|
||||
|
@ -463,12 +462,14 @@ public class BinaryMapIndexWriter {
|
|||
}
|
||||
int type = 1;
|
||||
if (o instanceof City) {
|
||||
CityType ct = ((City) o).getType();
|
||||
if (ct != CityType.CITY && ct != CityType.TOWN) {
|
||||
type = 3;
|
||||
if (((City) o).isPostcode()) {
|
||||
type = 2;
|
||||
} else {
|
||||
CityType ct = ((City) o).getType();
|
||||
if (ct != CityType.CITY && ct != CityType.TOWN) {
|
||||
type = 3;
|
||||
}
|
||||
}
|
||||
} else if(o instanceof PostCode) {
|
||||
type = 2;
|
||||
} else if(o instanceof Street) {
|
||||
type = 4;
|
||||
}
|
||||
|
@ -503,7 +504,9 @@ public class BinaryMapIndexWriter {
|
|||
if(cityType >= 0) {
|
||||
cityInd.setCityType(cityType);
|
||||
}
|
||||
cityInd.setId(city.getId());
|
||||
if(city.getId() != null) {
|
||||
cityInd.setId(city.getId());
|
||||
}
|
||||
|
||||
cityInd.setName(city.getName());
|
||||
if(checkEnNameToWrite(city)){
|
||||
|
@ -515,11 +518,12 @@ public class BinaryMapIndexWriter {
|
|||
cityInd.setY(cy);
|
||||
cityInd.setShiftToCityBlockIndex(0);
|
||||
codedOutStream.writeMessageNoTag(cityInd.build());
|
||||
return new BinaryFileReference(getFilePointer() - 4, startMessage);
|
||||
codedOutStream.flush();
|
||||
return BinaryFileReference.createShiftReference(getFilePointer() - 4, startMessage);
|
||||
|
||||
}
|
||||
|
||||
public void writeCityIndex(MapObject cityOrPostcode, List<Street> streets, Map<Street, List<Node>> wayNodes,
|
||||
public void writeCityIndex(City cityOrPostcode, List<Street> streets, Map<Street, List<Node>> wayNodes,
|
||||
BinaryFileReference ref) throws IOException {
|
||||
checkPeekState(CITY_INDEX_INIT);
|
||||
codedOutStream.writeTag(CitiesIndex.BLOCKS_FIELD_NUMBER, FieldType.MESSAGE.getWireType());
|
||||
|
@ -545,7 +549,7 @@ public class BinaryMapIndexWriter {
|
|||
}
|
||||
}
|
||||
}
|
||||
String postcodeFilter = cityOrPostcode instanceof PostCode ? cityOrPostcode.getName() : null;
|
||||
String postcodeFilter = cityOrPostcode.isPostcode() ? cityOrPostcode.getName() : null;
|
||||
for (Street s : streets) {
|
||||
StreetIndex streetInd = createStreetAndBuildings(s, cx, cy, postcodeFilter, mapNodeToStreet, wayNodes);
|
||||
currentPointer += CodedOutputStream.computeTagSize(CityBlockIndex.STREETS_FIELD_NUMBER);
|
||||
|
|
|
@ -32,7 +32,6 @@ import net.osmand.data.City;
|
|||
import net.osmand.data.City.CityType;
|
||||
import net.osmand.data.DataTileManager;
|
||||
import net.osmand.data.MapObject;
|
||||
import net.osmand.data.PostCode;
|
||||
import net.osmand.data.Street;
|
||||
import net.osmand.data.WayBoundary;
|
||||
import net.osmand.data.preparation.DBStreetDAO.SimpleStreet;
|
||||
|
@ -848,19 +847,19 @@ public class IndexAddressCreator extends AbstractIndexPartCreator{
|
|||
progress.startTask(Messages.getString("IndexCreator.SERIALIZING_ADRESS"), cityTowns.size() + villages.size() / 100 + 1); //$NON-NLS-1$
|
||||
|
||||
Map<String, List<MapObject>> namesIndex = new TreeMap<String, List<MapObject>>(Collator.getInstance());
|
||||
Map<String, PostCode> postcodes = new TreeMap<String, PostCode>();
|
||||
Map<String, City> postcodes = new TreeMap<String, City>();
|
||||
writeCityBlockIndex(writer, CITIES_TYPE, streetstat, waynodesStat, suburbs, cityTowns, postcodes, namesIndex, progress);
|
||||
writeCityBlockIndex(writer, VILLAGES_TYPE, streetstat, waynodesStat, null, villages, postcodes, namesIndex, progress);
|
||||
|
||||
// write postcodes
|
||||
List<BinaryFileReference> refs = new ArrayList<BinaryFileReference>();
|
||||
writer.startCityBlockIndex(POSTCODES_TYPE);
|
||||
ArrayList<PostCode> posts = new ArrayList<PostCode>(postcodes.values());
|
||||
for (PostCode s : posts) {
|
||||
ArrayList<City> posts = new ArrayList<City>(postcodes.values());
|
||||
for (City s : posts) {
|
||||
refs.add(writer.writeCityHeader(s, -1));
|
||||
}
|
||||
for (int i = 0; i < posts.size(); i++) {
|
||||
PostCode postCode = posts.get(i);
|
||||
City postCode = posts.get(i);
|
||||
BinaryFileReference ref = refs.get(i);
|
||||
putNamedMapObject(namesIndex, postCode, ref.getStartPointer());
|
||||
writer.writeCityIndex(postCode, new ArrayList<Street>(postCode.getStreets()), null, ref);
|
||||
|
@ -900,20 +899,20 @@ public class IndexAddressCreator extends AbstractIndexPartCreator{
|
|||
|
||||
|
||||
private void writeCityBlockIndex(BinaryMapIndexWriter writer, int type, PreparedStatement streetstat, PreparedStatement waynodesStat,
|
||||
List<City> suburbs, List<City> cities, Map<String, PostCode> postcodes, Map<String, List<MapObject>> namesIndex, IProgress progress)
|
||||
throws IOException, SQLException {
|
||||
List<BinaryFileReference> refs = new ArrayList<BinaryFileReference>();
|
||||
List<City> suburbs, List<City> cities, Map<String, City> postcodes, Map<String, List<MapObject>> namesIndex, IProgress progress)
|
||||
throws IOException, SQLException {
|
||||
List<BinaryFileReference> refs = new ArrayList<BinaryFileReference>();
|
||||
// 1. write cities
|
||||
writer.startCityBlockIndex(type);
|
||||
for (City c : cities) {
|
||||
refs.add(writer.writeCityHeader(c, c.getType().ordinal()));
|
||||
}
|
||||
for(int i=0; i<cities.size(); i++) {
|
||||
City city = cities.get(i);
|
||||
BinaryFileReference ref = refs.get(i);
|
||||
putNamedMapObject(namesIndex, city, ref.getStartPointer());
|
||||
if(type == CITIES_TYPE) {
|
||||
progress.progress(1);
|
||||
for (int i = 0; i < cities.size(); i++) {
|
||||
City city = cities.get(i);
|
||||
BinaryFileReference ref = refs.get(i);
|
||||
putNamedMapObject(namesIndex, city, ref.getStartPointer());
|
||||
if (type == CITIES_TYPE) {
|
||||
progress.progress(1);
|
||||
} else {
|
||||
if ((cities.size() - i) % 100 == 0) {
|
||||
progress.progress(1);
|
||||
|
@ -941,21 +940,25 @@ public class IndexAddressCreator extends AbstractIndexPartCreator{
|
|||
putNamedMapObject(namesIndex, s, s.getFileOffset());
|
||||
for (Building b : s.getBuildings()) {
|
||||
bCount++;
|
||||
if(city.getPostcode() != null && b.getPostcode() == null) {
|
||||
if (city.getPostcode() != null && b.getPostcode() == null) {
|
||||
b.setPostcode(city.getPostcode());
|
||||
}
|
||||
if (b.getPostcode() != null) {
|
||||
if (!postcodes.containsKey(b.getPostcode())) {
|
||||
PostCode p = new PostCode(b.getPostcode());
|
||||
City p = City.createPostcode(b.getPostcode());
|
||||
p.setLocation(b.getLocation().getLatitude(), b.getLocation().getLongitude());
|
||||
postcodes.put(b.getPostcode(), p);
|
||||
}
|
||||
postcodes.get(b.getPostcode()).registerStreet(s, false);
|
||||
Street newS = new Street(postcodes.get(b.getPostcode()));
|
||||
newS.setEnName(s.getEnName());
|
||||
newS.setName(s.getName());
|
||||
newS.registerBuildings(s.getBuildings());
|
||||
newS.getWayNodes().addAll(s.getWayNodes());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (f > 500) {
|
||||
if(logMapDataWarn != null) {
|
||||
if (logMapDataWarn != null) {
|
||||
logMapDataWarn.info("! " + city.getName() + " ! " + f + " ms " + streets.size() + " streets " + bCount + " buildings");
|
||||
} else {
|
||||
log.info("! " + city.getName() + " ! " + f + " ms " + streets.size() + " streets " + bCount + " buildings");
|
||||
|
|
|
@ -625,14 +625,14 @@ public class IndexCreator {
|
|||
|
||||
long time = System.currentTimeMillis();
|
||||
IndexCreator creator = new IndexCreator(new File("/home/victor/projects/OsmAnd/data/osm-gen/")); //$NON-NLS-1$
|
||||
creator.setIndexMap(true);
|
||||
creator.setIndexAddress(false);
|
||||
creator.setIndexMap(false);
|
||||
creator.setIndexAddress(true);
|
||||
creator.setIndexPOI(false);
|
||||
creator.setIndexTransport(false);
|
||||
|
||||
creator.recreateOnlyBinaryFile = false;
|
||||
creator.deleteDatabaseIndexes = true;
|
||||
// creator.deleteOsmDB = true;
|
||||
creator.deleteDatabaseIndexes = false;
|
||||
// creator.deleteOsmDB = false;
|
||||
|
||||
creator.setZoomWaySmothness(2);
|
||||
MapRenderingTypes rt = MapRenderingTypes.getDefault();// new MapRenderingTypes("/home/victor/projects/OsmAnd/data/testdata/roads_rendering_types.xml");
|
||||
|
|
|
@ -187,7 +187,6 @@ message OsmAndAddressIndex {
|
|||
// the list of the cities and the blocks are synchronized by the order (so even empty block will be written)
|
||||
repeated CityIndex cities = 5;
|
||||
|
||||
// encoded as fixed32 length delimited
|
||||
repeated CityBlockIndex blocks = 7;
|
||||
}
|
||||
|
||||
|
@ -231,8 +230,8 @@ message CityIndex {
|
|||
optional string name_en = 3;
|
||||
optional uint64 id = 4;
|
||||
|
||||
required uint32 x = 5; // x tile of 24 zoom
|
||||
required uint32 y = 6; // y tile of 24 zoom
|
||||
required uint32 x = 5; // x tile of 31 zoom
|
||||
required uint32 y = 6; // y tile of 31 zoom
|
||||
|
||||
// shift from start CityIndex (without length) to cityBlockIndex
|
||||
optional fixed32 shiftToCityBlockIndex = 10;
|
||||
|
|
Loading…
Reference in a new issue