use of net.osmand.data.Street in project OsmAnd-tools by osmandapp.
the class IndexAddressCreator method writeBinaryAddressIndex.
public void writeBinaryAddressIndex(BinaryMapIndexWriter writer, String regionName, IProgress progress) throws IOException, SQLException {
processPostcodes();
cleanCityPart();
streetDAO.close();
closePreparedStatements(addressCityStat);
mapConnection.commit();
createDatabaseIndexes(mapConnection);
mapConnection.commit();
Map<String, City> postcodes = new TreeMap<String, City>();
updatePostcodeBoundaries(progress, postcodes);
mapConnection.commit();
List<String> additionalTags = new ArrayList<String>();
Map<String, Integer> tagRules = new HashMap<String, Integer>();
int ind = 0;
for (String lng : langAttributes) {
additionalTags.add("name:" + lng);
tagRules.put("name:" + lng, ind);
ind++;
}
writer.startWriteAddressIndex(regionName, additionalTags);
Map<CityType, List<City>> cities = readCities(mapConnection);
PreparedStatement streetstat = //
mapConnection.prepareStatement(// $NON-NLS-1$
"SELECT A.id, A.name, A.name_en, A.latitude, A.longitude, " + // $NON-NLS-1$
"B.id, B.name, B.name_en, B.latitude, B.longitude, B.postcode, A.cityPart, " + " B.name2, B.name_en2, B.lat2, B.lon2, B.interval, B.interpolateType, A.cityPart == C.name as MainTown " + // $NON-NLS-1$
"FROM street A LEFT JOIN building B ON B.street = A.id JOIN city C ON A.city = C.id " + // $NON-NLS-1$
"WHERE A.city = ? ORDER BY MainTown DESC, A.name ASC");
PreparedStatement waynodesStat = // $NON-NLS-1$
mapConnection.prepareStatement("SELECT A.id, A.latitude, A.longitude FROM street_node A WHERE A.street = ? ");
// collect suburbs with is in value
List<City> suburbs = new ArrayList<City>();
List<City> cityTowns = new ArrayList<City>();
List<City> villages = new ArrayList<City>();
for (CityType t : cities.keySet()) {
if (t == CityType.CITY || t == CityType.TOWN) {
cityTowns.addAll(cities.get(t));
} else {
villages.addAll(cities.get(t));
}
if (t == CityType.SUBURB) {
for (City c : cities.get(t)) {
if (c.getIsInValue() != null) {
suburbs.add(c);
}
}
}
}
Map<String, List<MapObject>> namesIndex = new TreeMap<String, List<MapObject>>(Collator.getInstance());
// $NON-NLS-1$
progress.startTask(Messages.getString("IndexCreator.SERIALIZING_ADDRESS"), cityTowns.size() + villages.size() / 100 + 1);
writeCityBlockIndex(writer, CITIES_TYPE, streetstat, waynodesStat, suburbs, cityTowns, postcodes, namesIndex, tagRules, progress);
writeCityBlockIndex(writer, VILLAGES_TYPE, streetstat, waynodesStat, null, villages, postcodes, namesIndex, tagRules, progress);
// write postcodes
List<BinaryFileReference> refs = new ArrayList<BinaryFileReference>();
writer.startCityBlockIndex(POSTCODES_TYPE);
ArrayList<City> posts = new ArrayList<City>(postcodes.values());
for (City s : posts) {
refs.add(writer.writeCityHeader(s, -1, tagRules));
}
for (int i = 0; i < posts.size(); i++) {
City postCode = posts.get(i);
BinaryFileReference ref = refs.get(i);
putNamedMapObject(namesIndex, postCode, ref.getStartPointer());
ArrayList<Street> streets = new ArrayList<Street>(postCode.getStreets());
Collections.sort(streets, new Comparator<Street>() {
final net.osmand.Collator clt = OsmAndCollator.primaryCollator();
@Override
public int compare(Street o1, Street o2) {
return clt.compare(o1.getName(), o2.getName());
}
});
writer.writeCityIndex(postCode, streets, null, ref, tagRules);
}
writer.endCityBlockIndex();
progress.finishTask();
writer.writeAddressNameIndex(namesIndex);
writer.endWriteAddressIndex();
writer.flush();
streetstat.close();
if (waynodesStat != null) {
waynodesStat.close();
}
}
use of net.osmand.data.Street in project OsmAnd-tools by osmandapp.
the class BinaryComparator method compareAddress.
private void compareAddress(BinaryMapIndexReader i0, BinaryMapIndexReader i1) throws IOException {
for (int cityType : BinaryMapAddressReaderAdapter.CITY_TYPES) {
List<City> ct0 = i0.getCities(null, cityType);
List<City> ct1 = i1.getCities(null, cityType);
Comparator<City> c = comparator();
Collections.sort(ct0, c);
Collections.sort(ct1, c);
int i = 0;
int j = 0;
printComment("CITY TYPE: " + cityType);
while (i < ct0.size() || j < ct1.size()) {
City c0 = get(ct0, i);
City c1 = get(ct1, j);
int cmp = c.compare(c0, c1);
if (cmp < 0) {
while (c.compare(c0, c1) < 0) {
if (COMPARE_SET.contains(CITY_COMPARE) && COMPARE_SET.contains(COMPARE_UNIQUE_1)) {
City ps = searchSimilarCities(c0, ct1, j);
if (ps != null) {
int distance = (int) MapUtils.getDistance(c0.getLocation(), ps.getLocation());
printMapObject(CITY_COMPARE, c0, "(1). Extra city in 1st file: " + c0 + "( " + distance + " m ) possible duplicate " + ps);
} else {
printMapObject(CITY_COMPARE, c0, "(1)! Extra city in 1st file: " + c0);
}
}
i++;
c0 = get(ct0, i);
}
} else if (cmp > 0) {
while (c.compare(c0, c1) > 0) {
if (COMPARE_SET.contains(CITY_COMPARE) && COMPARE_SET.contains(COMPARE_UNIQUE_2)) {
City ps = searchSimilarCities(c1, ct0, i);
if (ps != null) {
int distance = (int) MapUtils.getDistance(c1.getLocation(), ps.getLocation());
printMapObject(CITY_COMPARE, c1, "(1). Extra city in 2nd file: " + c1 + "( " + distance + " m ) possible duplicate " + ps);
} else {
printMapObject(CITY_COMPARE, c1, "(1)! Extra city in 2nd file: " + c0);
}
}
j++;
c1 = get(ct1, j);
}
} else {
// if(cityType == BinaryMapAddressReaderAdapter.CITY_TOWN_TYPE) {
// System.out.println("Same city " + c1.getName() + " == " + c0.getName());
// }
i++;
j++;
i0.preloadStreets(c0, null);
i1.preloadStreets(c1, null);
if (COMPARE_SET.contains(CITY_NAME_COMPARE) && !c0.getNamesMap(true).equals(c1.getNamesMap(true))) {
printComment("(1). City all names are not same : " + c1 + " " + (new JSONObject(c0.getNamesMap(true)) + " != " + (new JSONObject(c1.getNamesMap(true)))));
}
if (c0.getStreets().size() != c1.getStreets().size()) {
if (COMPARE_SET.contains(STREET_COMPARE)) {
if (!isOsmOutput()) {
printComment("(2). City streets " + c1 + ": " + c0.getStreets().size() + " <> " + c1.getStreets().size());
}
List<String> s0 = new ArrayList<String>();
List<String> s1 = new ArrayList<String>();
for (Street s : c0.getStreets()) {
if (c1.getStreetByName(s.getName()) == null) {
s0.add(s.getName());
if (isOsmOutput()) {
printMapObject(STREET_COMPARE, s, "(2) Street " + s + "is not present in 2nd file");
}
}
}
for (Street s : c1.getStreets()) {
if (c0.getStreetByName(s.getName()) == null) {
if (isOsmOutput()) {
printMapObject(STREET_COMPARE, s, "(2) Street " + s + " is not present in 1st file");
}
s1.add(s.getName());
}
}
if (s0.isEmpty() && s1.isEmpty()) {
// locations of streets are not equal
printMapObject(STREET_COMPARE, c0, "(2) Number of streets with same name is not equal" + c0.getStreets());
} else {
printComment("(2).. " + s0 + "<>" + s1);
}
}
} else {
// compare streets
for (int ij = 0; ij < c1.getStreets().size(); ij++) {
Street s0 = c0.getStreets().get(ij);
Street s1 = c1.getStreets().get(ij);
if (!s0.getNamesMap(true).equals(s1.getNamesMap(true)) && COMPARE_SET.contains(STREET_NAME_COMPARE)) {
printMapObject(STREET_NAME_COMPARE, s0, "(2)- Street all names are not same : " + c1 + " " + s0.getNamesMap(true) + " <> " + s1.getNamesMap(true));
}
if (s0.getName().equals(s1.getName())) {
i0.preloadBuildings(s0, null);
i1.preloadBuildings(s1, null);
if (COMPARE_SET.contains(BUILDINGS_COMPARE)) {
if (s0.getBuildings().size() != s1.getBuildings().size()) {
printMapObject(BUILDINGS_COMPARE, s0, "(3). Buildings size: " + s0.getBuildings().size() + "<>" + s1.getBuildings().size() + " " + c0 + ", " + s0);
} else {
for (int it = 0; it < s0.getBuildings().size(); it++) {
Building b0 = s0.getBuildings().get(it);
Building b1 = s1.getBuildings().get(it);
if (!b0.getName().equals(b1.getName())) {
printMapObject(BUILDINGS_COMPARE, b0, "(4). Buildings name: " + b0.getName() + "<>" + b1.getName() + " " + c0 + ", " + s0);
}
if (!Algorithms.objectEquals(b0.getPostcode(), b1.getPostcode())) {
printMapObject(BUILDINGS_COMPARE, b0, "(4). Buildings postcode: " + b0.getPostcode() + "<>" + b1.getPostcode() + " " + c0 + ", " + s0);
}
}
}
}
if (COMPARE_SET.contains(INTERSECTIONS_COMPARE)) {
if (s0.getIntersectedStreets().size() != s1.getIntersectedStreets().size()) {
printMapObject(INTERSECTIONS_COMPARE, s0, "(5). Intersections size: " + s0.getIntersectedStreets().size() + "<>" + s1.getIntersectedStreets().size() + " " + c0 + ", " + s0);
} else {
Collections.sort(s0.getIntersectedStreets(), MapObject.BY_NAME_COMPARATOR);
Collections.sort(s1.getIntersectedStreets(), MapObject.BY_NAME_COMPARATOR);
for (int it = 0; it < s0.getIntersectedStreets().size(); it++) {
Street st0 = s0.getIntersectedStreets().get(it);
Street st1 = s1.getIntersectedStreets().get(it);
if (!st0.getName().equals(st1.getName())) // || !st0.getNamesMap(true).equals(st1.getNamesMap(true))
{
printMapObject(INTERSECTIONS_COMPARE, st0, "(5). Intersections names <> : " + st0 + "<>" + st1 + " " + c0 + ", " + s0 + " ");
}
if (MapUtils.getDistance(st0.getLocation(), st1.getLocation()) > 1500) {
printMapObject(INTERSECTIONS_COMPARE, st0, "(5). Intersections location <> : " + st0 + "<>" + st1 + " " + c0 + ", " + s0 + " ");
}
}
}
}
} else {
if (COMPARE_SET.contains(STREET_NAME_COMPARE)) {
printMapObject(STREET_NAME_COMPARE, s0, "(3)? Street name order: " + s0 + "!=" + s1 + " " + c0);
}
}
}
}
}
}
}
}
use of net.osmand.data.Street in project OsmAnd-tools by osmandapp.
the class BinaryMerger method combineAddressIndex.
private void combineAddressIndex(String name, BinaryMapIndexWriter writer, AddressRegion[] addressRegions, BinaryMapIndexReader[] indexes) throws IOException {
Set<String> attributeTagsTableSet = new TreeSet<String>();
for (int i = 0; i != addressRegions.length; i++) {
AddressRegion region = addressRegions[i];
attributeTagsTableSet.addAll(region.getAttributeTagsTable());
}
writer.startWriteAddressIndex(name, attributeTagsTableSet);
List<String> attributeTagsTable = new ArrayList<String>();
attributeTagsTable.addAll(attributeTagsTableSet);
Map<String, Integer> tagRules = new HashMap<String, Integer>();
Map<String, List<MapObject>> namesIndex = new TreeMap<String, List<MapObject>>(Collator.getInstance());
ListIterator<String> it = attributeTagsTable.listIterator();
while (it.hasNext()) {
tagRules.put(it.next(), it.previousIndex());
}
for (int type : BinaryMapAddressReaderAdapter.CITY_TYPES) {
Map<City, BinaryMapIndexReader> cityMap = new HashMap<City, BinaryMapIndexReader>();
for (int i = 0; i < addressRegions.length; i++) {
AddressRegion region = addressRegions[i];
final BinaryMapIndexReader index = indexes[i];
for (City city : index.getCities(region, null, type)) {
normalizePostcode(city, extractCountryName(index));
if (cityMap.containsKey(city)) {
cityMap.remove(city);
}
cityMap.put(city, index);
}
}
List<City> cities = new ArrayList<City>(cityMap.keySet());
Map<City, List<City>> mergeCityGroup = new HashMap<City, List<City>>();
Collections.sort(cities, MapObject.BY_NAME_COMPARATOR);
mergeCitiesByNameDistance(cities, mergeCityGroup, cityMap, type == BinaryMapAddressReaderAdapter.CITY_TOWN_TYPE);
List<BinaryFileReference> refs = new ArrayList<BinaryFileReference>();
// 1. write cities
writer.startCityBlockIndex(type);
Map<City, Map<Street, List<Node>>> namesakesStreetNodes = new HashMap<City, Map<Street, List<Node>>>();
for (int i = 0; i < cities.size(); i++) {
City city = cities.get(i);
BinaryMapIndexReader rindex = cityMap.get(city);
preloadStreetsAndBuildings(rindex, city, namesakesStreetNodes);
List<City> namesakes = mergeCityGroup.get(city);
if (namesakes != null) {
for (City namesake : namesakes) {
preloadStreetsAndBuildings(cityMap.get(namesake), namesake, namesakesStreetNodes);
city = mergeCities(city, namesake, namesakesStreetNodes);
}
}
int cityType = city.isPostcode() ? -1 : city.getType().ordinal();
BinaryFileReference ref = writer.writeCityHeader(city, cityType, tagRules);
refs.add(ref);
writer.writeCityIndex(city, city.getStreets(), namesakesStreetNodes.get(city), ref, tagRules);
IndexAddressCreator.putNamedMapObject(namesIndex, city, ref.getStartPointer());
if (!city.isPostcode()) {
for (Street s : city.getStreets()) {
IndexAddressCreator.putNamedMapObject(namesIndex, s, s.getFileOffset());
}
}
city.getStreets().clear();
namesakesStreetNodes.clear();
}
writer.endCityBlockIndex();
}
writer.writeAddressNameIndex(namesIndex);
writer.endWriteAddressIndex();
}
use of net.osmand.data.Street in project Osmand by osmandapp.
the class BinaryMapAddressReaderAdapter method searchAddressDataByName.
public void searchAddressDataByName(AddressRegion reg, SearchRequest<MapObject> req, List<Integer> typeFilter) throws IOException {
TIntArrayList loffsets = new TIntArrayList();
CollatorStringMatcher stringMatcher = new CollatorStringMatcher(req.nameQuery, req.matcherMode);
String postcode = Postcode.normalize(req.nameQuery, map.getCountryName());
final CityMatcher postcodeMatcher = new DefaultCityMatcher(new CollatorStringMatcher(postcode, req.matcherMode));
final CityMatcher cityMatcher = new DefaultCityMatcher(stringMatcher);
final CityMatcher cityPostcodeMatcher = new CityMatcher() {
@Override
public boolean matches(City city) {
return city.isPostcode() ? postcodeMatcher.matches(city) : cityMatcher.matches(city);
}
};
long time = System.currentTimeMillis();
int indexOffset = 0;
while (true) {
if (req.isCancelled()) {
return;
}
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch(tag) {
case 0:
return;
case OsmAndAddressNameIndexData.TABLE_FIELD_NUMBER:
int length = readInt();
indexOffset = codedIS.getTotalBytesRead();
int oldLimit = codedIS.pushLimit(length);
// here offsets are sorted by distance
map.readIndexedStringTable(stringMatcher.getCollator(), req.nameQuery, "", loffsets, 0);
codedIS.popLimit(oldLimit);
break;
case OsmAndAddressNameIndexData.ATOM_FIELD_NUMBER:
// also offsets can be randomly skipped by limit
loffsets.sort();
TIntArrayList[] refs = new TIntArrayList[5];
TIntArrayList[] refsContainer = new TIntArrayList[5];
for (int i = 0; i < refs.length; i++) {
refs[i] = new TIntArrayList();
refsContainer[i] = new TIntArrayList();
}
LOG.info("Searched address structure in " + (System.currentTimeMillis() - time) + "ms. Found " + loffsets.size() + " subtress");
for (int j = 0; j < loffsets.size(); j++) {
int fp = indexOffset + loffsets.get(j);
codedIS.seek(fp);
int len = codedIS.readRawVarint32();
int oldLim = codedIS.pushLimit(len);
int stag = 0;
do {
int st = codedIS.readTag();
stag = WireFormat.getTagFieldNumber(st);
if (stag == AddressNameIndexData.ATOM_FIELD_NUMBER) {
int slen = codedIS.readRawVarint32();
int soldLim = codedIS.pushLimit(slen);
readAddressNameData(req, refs, refsContainer, fp);
codedIS.popLimit(soldLim);
} else if (stag != 0) {
skipUnknownField(st);
}
} while (stag != 0);
codedIS.popLimit(oldLim);
if (req.isCancelled()) {
return;
}
}
if (typeFilter == null) {
typeFilter = TYPES;
}
for (int i = 0; i < typeFilter.size() && !req.isCancelled(); i++) {
TIntArrayList list = refs[typeFilter.get(i)];
TIntArrayList listContainer = refsContainer[typeFilter.get(i)];
if (typeFilter.get(i) == STREET_TYPE) {
TIntLongHashMap mp = new TIntLongHashMap();
for (int j = 0; j < list.size(); j++) {
mp.put(list.get(j), listContainer.get(j));
}
list.sort();
for (int j = 0; j < list.size() && !req.isCancelled(); j++) {
int offset = list.get(j);
if (j > 0 && offset == list.get(j - 1)) {
continue;
}
City obj;
{
int contOffset = (int) mp.get(offset);
codedIS.seek(contOffset);
int len = codedIS.readRawVarint32();
int old = codedIS.pushLimit(len);
obj = readCityHeader(null, contOffset, reg.attributeTagsTable);
codedIS.popLimit(old);
}
if (obj != null) {
codedIS.seek(offset);
int len = codedIS.readRawVarint32();
int old = codedIS.pushLimit(len);
LatLon l = obj.getLocation();
Street s = new Street(obj);
s.setFileOffset(offset);
readStreet(s, null, false, MapUtils.get31TileNumberX(l.getLongitude()) >> 7, MapUtils.get31TileNumberY(l.getLatitude()) >> 7, obj.isPostcode() ? obj.getName() : null, reg.attributeTagsTable);
boolean matches = stringMatcher.matches(s.getName());
if (!matches) {
for (String n : s.getAllNames()) {
matches = stringMatcher.matches(n);
if (matches) {
break;
}
}
}
if (matches) {
req.publish(s);
}
codedIS.popLimit(old);
}
}
} else {
list.sort();
TIntSet published = new TIntHashSet();
for (int j = 0; j < list.size() && !req.isCancelled(); j++) {
int offset = list.get(j);
if (j > 0 && offset == list.get(j - 1)) {
continue;
}
codedIS.seek(offset);
int len = codedIS.readRawVarint32();
int old = codedIS.pushLimit(len);
City obj = readCityHeader(cityPostcodeMatcher, list.get(j), reg.attributeTagsTable);
if (obj != null && !published.contains(offset)) {
req.publish(obj);
published.add(offset);
}
codedIS.popLimit(old);
}
}
}
LOG.info("Whole address search by name is done in " + (System.currentTimeMillis() - time) + "ms. Found " + req.getSearchResults().size());
return;
default:
skipUnknownField(t);
break;
}
}
}
use of net.osmand.data.Street in project Osmand by osmandapp.
the class BinaryMapAddressReaderAdapter method readStreet.
protected Street readStreet(Street s, SearchRequest<Building> buildingsMatcher, boolean loadBuildingsAndIntersected, int city24X, int city24Y, String postcodeFilter, List<String> additionalTagsTable) throws IOException {
int x = 0;
int y = 0;
LinkedList<String> additionalTags = null;
boolean loadLocation = city24X != 0 || city24Y != 0;
while (true) {
int t = codedIS.readTag();
int tag = WireFormat.getTagFieldNumber(t);
switch(tag) {
case 0:
if (loadLocation) {
s.setLocation(MapUtils.getLatitudeFromTile(24, y), MapUtils.getLongitudeFromTile(24, x));
}
return s;
case OsmandOdb.StreetIndex.ID_FIELD_NUMBER:
s.setId(codedIS.readUInt64());
break;
case OsmandOdb.StreetIndex.ATTRIBUTETAGIDS_FIELD_NUMBER:
int tgid = codedIS.readUInt32();
if (additionalTags == null) {
additionalTags = new LinkedList<String>();
}
if (additionalTagsTable != null && tgid < additionalTagsTable.size()) {
additionalTags.add(additionalTagsTable.get(tgid));
}
break;
case OsmandOdb.StreetIndex.ATTRIBUTEVALUES_FIELD_NUMBER:
String nm = codedIS.readString();
if (additionalTags != null && additionalTags.size() > 0) {
String tg = additionalTags.pollFirst();
if (tg.startsWith("name:")) {
s.setName(tg.substring("name:".length()), nm);
}
}
break;
case OsmandOdb.StreetIndex.NAME_EN_FIELD_NUMBER:
s.setEnName(codedIS.readString());
break;
case OsmandOdb.StreetIndex.NAME_FIELD_NUMBER:
s.setName(codedIS.readString());
break;
case OsmandOdb.StreetIndex.X_FIELD_NUMBER:
int sx = codedIS.readSInt32();
if (loadLocation) {
x = sx + city24X;
} else {
x = (int) MapUtils.getTileNumberX(24, s.getLocation().getLongitude());
}
break;
case OsmandOdb.StreetIndex.Y_FIELD_NUMBER:
int sy = codedIS.readSInt32();
if (loadLocation) {
y = sy + city24Y;
} else {
y = (int) MapUtils.getTileNumberY(24, s.getLocation().getLatitude());
}
break;
case OsmandOdb.StreetIndex.INTERSECTIONS_FIELD_NUMBER:
int length = codedIS.readRawVarint32();
if (loadBuildingsAndIntersected) {
int oldLimit = codedIS.pushLimit(length);
Street si = readIntersectedStreet(s.getCity(), x, y, additionalTagsTable);
s.addIntersectedStreet(si);
codedIS.popLimit(oldLimit);
} else {
codedIS.skipRawBytes(length);
}
break;
case OsmandOdb.StreetIndex.BUILDINGS_FIELD_NUMBER:
int offset = codedIS.getTotalBytesRead();
length = codedIS.readRawVarint32();
if (loadBuildingsAndIntersected) {
int oldLimit = codedIS.pushLimit(length);
Building b = readBuilding(offset, x, y, additionalTagsTable);
if (postcodeFilter == null || postcodeFilter.equalsIgnoreCase(b.getPostcode())) {
if (buildingsMatcher == null || buildingsMatcher.publish(b)) {
s.addBuilding(b);
}
}
codedIS.popLimit(oldLimit);
} else {
codedIS.skipRawBytes(length);
}
break;
default:
skipUnknownField(t);
break;
}
}
}
Aggregations