use of net.osmand.data.Boundary in project OsmAnd-tools by osmandapp.
the class IndexAddressCreator method indexBoundariesRelation.
public void indexBoundariesRelation(Entity e, OsmDbAccessorContext ctx) throws SQLException {
Boundary boundary = extractBoundary(e, ctx);
// Bucharest has admin level 4
boolean boundaryValid = boundary != null && (!boundary.hasAdminLevel() || boundary.getAdminLevel() >= 4) && boundary.getCenterPoint() != null && !Algorithms.isEmpty(boundary.getName());
if (boundaryValid) {
LatLon boundaryCenter = boundary.getCenterPoint();
List<City> citiesToSearch = new ArrayList<City>();
citiesToSearch.addAll(cityManager.getClosestObjects(boundaryCenter.getLatitude(), boundaryCenter.getLongitude(), 3));
citiesToSearch.addAll(cityVillageManager.getClosestObjects(boundaryCenter.getLatitude(), boundaryCenter.getLongitude(), 3));
City cityFound = null;
String boundaryName = boundary.getName().toLowerCase();
String altBoundaryName = Algorithms.isEmpty(boundary.getAltName()) ? "" : boundary.getAltName().toLowerCase();
if (boundary.hasAdminCenterId()) {
for (City c : citiesToSearch) {
if (c.getId() == boundary.getAdminCenterId()) {
cityFound = c;
break;
}
}
}
if (cityFound == null) {
for (City c : citiesToSearch) {
if ((boundaryName.equalsIgnoreCase(c.getName()) || altBoundaryName.equalsIgnoreCase(c.getName())) && boundary.containsPoint(c.getLocation())) {
cityFound = c;
break;
}
}
}
// False case : London Borough of Richmond upon Thames (bigger) -> Richmond!
if (cityFound == null) {
for (City c : citiesToSearch) {
String lower = c.getName().toLowerCase();
if (nameContains(boundaryName, lower) || nameContains(altBoundaryName, lower)) {
if (boundary.containsPoint(c.getLocation())) {
cityFound = c;
break;
}
}
}
}
// It could be wrong if the boundary doesn't match center point
if (cityFound == null && /*&& !boundary.hasAdminLevel() */
(boundary.getCityType() == CityType.TOWN || // boundary.getCityType() == CityType.CITY ||
boundary.getCityType() == CityType.HAMLET || boundary.getCityType() == CityType.SUBURB || boundary.getCityType() == CityType.VILLAGE)) {
if (e instanceof Relation) {
ctx.loadEntityRelation((Relation) e);
}
cityFound = createMissingCity(e, boundary.getCityType());
boundary.setAdminCenterId(cityFound.getId());
}
if (cityFound != null) {
putCityBoundary(boundary, cityFound);
} else {
logBoundaryChanged(boundary, null, 0, 0);
notAssignedBoundaries.add(boundary);
}
attachAllCitiesToBoundary(boundary);
} else if (boundary != null) {
if (logMapDataWarn != null) {
logMapDataWarn.warn("Not using boundary: " + boundary + " " + boundary.getBoundaryId());
} else {
log.info("Not using boundary: " + boundary + " " + boundary.getBoundaryId());
}
}
}
use of net.osmand.data.Boundary in project OsmAnd-tools by osmandapp.
the class IndexAddressCreator method iterateMainEntity.
public void iterateMainEntity(Entity e, OsmDbAccessorContext ctx) throws SQLException {
Map<String, String> tags = e.getTags();
// index not only buildings but also nodes that belongs to addr:interpolation ways
// currently not supported because nodes are indexed first with buildings
String interpolation = e.getTag(OSMTagKey.ADDR_INTERPOLATION);
if (e instanceof Way && interpolation != null) {
BuildingInterpolation type = null;
int interpolationInterval = 0;
try {
type = BuildingInterpolation.valueOf(interpolation.toUpperCase());
} catch (RuntimeException ex) {
try {
interpolationInterval = Integer.parseInt(interpolation);
} catch (NumberFormatException ex2) {
}
}
if (type != null || interpolationInterval > 0) {
List<Node> nodesWithHno = new ArrayList<Node>();
for (Node n : ((Way) e).getNodes()) {
if (n.getTag(OSMTagKey.ADDR_HOUSE_NUMBER) != null) {
String strt = n.getTag(OSMTagKey.ADDR_STREET);
if (strt == null) {
strt = n.getTag(OSMTagKey.ADDR_PLACE);
}
if (strt != null) {
nodesWithHno.add(n);
}
}
}
if (nodesWithHno.size() > 1) {
for (int i = 1; i < nodesWithHno.size(); i++) {
Node first = nodesWithHno.get(i - 1);
Node second = nodesWithHno.get(i);
boolean exist = streetDAO.findBuilding(first);
if (exist) {
streetDAO.removeBuilding(first);
}
LatLon l = e.getLatLon();
String strt = first.getTag(OSMTagKey.ADDR_STREET);
if (strt == null) {
strt = first.getTag(OSMTagKey.ADDR_PLACE);
}
Set<Long> idsOfStreet = getStreetInCity(first.getIsInNames(), strt, null, l);
if (!idsOfStreet.isEmpty()) {
Building building = EntityParser.parseBuilding(first);
building.setInterpolationInterval(interpolationInterval);
building.setInterpolationType(type);
building.setName(first.getTag(OSMTagKey.ADDR_HOUSE_NUMBER));
building.setName2(second.getTag(OSMTagKey.ADDR_HOUSE_NUMBER));
building.setLatLon2(second.getLatLon());
streetDAO.writeBuilding(idsOfStreet, building);
}
}
}
}
}
String houseName = e.getTag(OSMTagKey.ADDR_HOUSE_NAME);
String houseNumber = e.getTag(OSMTagKey.ADDR_HOUSE_NUMBER);
String street = null;
if (houseNumber != null) {
street = e.getTag(OSMTagKey.ADDR_STREET);
if (street == null) {
street = e.getTag(OSMTagKey.ADDR_PLACE);
}
}
String street2 = e.getTag(OSMTagKey.ADDR_STREET2);
if ((houseName != null || houseNumber != null)) {
if (e instanceof Relation) {
ctx.loadEntityRelation((Relation) e);
Collection<Entity> outs = ((Relation) e).getMemberEntities("outer");
if (!outs.isEmpty()) {
e = outs.iterator().next();
}
}
// skip relations
boolean exist = e instanceof Relation || streetDAO.findBuilding(e);
if (!exist) {
LatLon l = e.getLatLon();
Set<Long> idsOfStreet = getStreetInCity(e.getIsInNames(), street, null, l);
if (!idsOfStreet.isEmpty()) {
Building building = EntityParser.parseBuilding(e);
String hname = null;
String second = null;
if (DataExtractionSettings.getSettings().isHousenumberPrefered()) {
hname = houseNumber;
second = houseName;
} else {
hname = houseName;
second = houseNumber;
}
if (hname == null) {
hname = second;
second = null;
}
String additionalHname = "";
if (DataExtractionSettings.getSettings().isAdditionalInfo() && second != null)
additionalHname = " - [" + second + "]";
int i = hname.indexOf('-');
if (i != -1 && interpolation != null) {
building.setInterpolationInterval(1);
try {
building.setInterpolationType(BuildingInterpolation.valueOf(interpolation.toUpperCase()));
} catch (RuntimeException ex) {
try {
building.setInterpolationInterval(Integer.parseInt(interpolation));
} catch (NumberFormatException ex2) {
}
}
building.setName(hname.substring(0, i));
building.setName2(hname.substring(i + 1));
} else if ((street2 != null) && !street2.isEmpty()) {
int secondNumber = hname.indexOf('/');
if (secondNumber == -1 || !(secondNumber < hname.length() - 1)) {
building.setName(hname + additionalHname);
} else {
building.setName(hname.substring(0, secondNumber) + additionalHname);
Building building2 = EntityParser.parseBuilding(e);
building2.setName(hname.substring(secondNumber + 1) + additionalHname);
Set<Long> ids2OfStreet = getStreetInCity(e.getIsInNames(), street2, null, l);
// remove duplicated entries!
ids2OfStreet.removeAll(idsOfStreet);
if (!ids2OfStreet.isEmpty()) {
streetDAO.writeBuilding(ids2OfStreet, building2);
} else {
building.setName2(building2.getName() + additionalHname);
}
}
} else {
building.setName(hname + additionalHname);
}
streetDAO.writeBuilding(idsOfStreet, building);
}
}
} else if (e instanceof Way && /* && OSMSettings.wayForCar(e.getTag(OSMTagKey.HIGHWAY)) */
e.getTag(OSMTagKey.HIGHWAY) != null && e.getTag(OSMTagKey.NAME) != null && isStreetTag(e.getTag(OSMTagKey.HIGHWAY))) {
// suppose that streets with names are ways for car
// Ignore all ways that have house numbers and highway type
// if we saved address ways we could checked that we registered before
boolean exist = streetDAO.findStreetNode(e);
// check that street way is not registered already
if (!exist) {
LatLon l = e.getLatLon();
Set<Long> idsOfStreet = getStreetInCity(e.getIsInNames(), e.getTag(OSMTagKey.NAME), getOtherNames(e), l);
if (!idsOfStreet.isEmpty()) {
streetDAO.writeStreetWayNodes(idsOfStreet, (Way) e);
}
}
}
if (e.getTag(OSMTagKey.POSTAL_CODE) != null) {
if ("postal_code".equals(e.getTag(OSMTagKey.BOUNDARY))) {
Boundary boundary = extractBoundary(e, ctx);
if (boundary != null) {
postcodeBoundaries.put(e, boundary);
}
} else if (e instanceof Relation) {
ctx.loadEntityRelation((Relation) e);
postalCodeRelations.add((Relation) e);
}
}
}
use of net.osmand.data.Boundary in project OsmAnd-tools by osmandapp.
the class IndexAddressCreator method updatePostcodeBoundaries.
private void updatePostcodeBoundaries(IProgress progress, Map<String, City> postcodes) throws SQLException {
progress.startTask("Process postcode boundaries", postcodeBoundaries.size());
Iterator<Entry<Entity, Boundary>> it = postcodeBoundaries.entrySet().iterator();
PreparedStatement ps = mapConnection.prepareStatement("SELECT postcode, latitude, longitude, id" + " FROM building where latitude <= ? and latitude >= ? and longitude >= ? and longitude <= ? ");
TLongObjectHashMap<String> assignPostcodes = new TLongObjectHashMap<>();
while (it.hasNext()) {
Entry<Entity, Boundary> e = it.next();
String postcode = e.getKey().getTag(OSMTagKey.POSTAL_CODE);
Multipolygon mp = e.getValue().getMultipolygon();
QuadRect bbox = mp.getLatLonBbox();
if (bbox.width() > 0) {
ps.setDouble(1, bbox.top);
ps.setDouble(2, bbox.bottom);
ps.setDouble(3, bbox.left);
ps.setDouble(4, bbox.right);
ResultSet rs = ps.executeQuery();
while (rs.next()) {
String pst = rs.getString(1);
if (Algorithms.isEmpty(pst)) {
if (mp.containsPoint(rs.getDouble(2), rs.getDouble(3))) {
assignPostcodes.put(rs.getLong(4), postcode);
}
}
}
}
progress.progress(1);
}
ps.close();
ps = mapConnection.prepareStatement("UPDATE " + " building set postcode = ? where id = ? ");
TLongObjectIterator<String> its = assignPostcodes.iterator();
int cnt = 0;
while (its.hasNext()) {
its.advance();
ps.setString(1, its.value());
ps.setLong(2, its.key());
ps.addBatch();
if (cnt > BATCH_SIZE) {
ps.executeBatch();
cnt = 0;
}
}
ps.executeBatch();
ps.close();
}
use of net.osmand.data.Boundary in project OsmAnd-tools by osmandapp.
the class IndexAddressCreator method readCities.
public Map<CityType, List<City>> readCities(Connection c) throws SQLException {
Map<CityType, List<City>> cities = new LinkedHashMap<City.CityType, List<City>>();
for (CityType t : CityType.values()) {
cities.put(t, new ArrayList<City>());
}
Statement stat = c.createStatement();
// $NON-NLS-1$
ResultSet set = stat.executeQuery("select id, latitude, longitude , name , name_en , city_type from city");
while (set.next()) {
CityType type = CityType.valueFromString(set.getString(6));
City city = new City(type);
city.copyNames(set.getString(4), null, Algorithms.decodeMap(set.getString(5)));
city.setLocation(set.getDouble(2), set.getDouble(3));
city.setId(set.getLong(1));
cities.get(type).add(city);
if (DEBUG_FULL_NAMES) {
Boundary cityB = cityBoundaries.get(city);
if (cityB != null) {
city.setName(city.getName() + " " + cityB.getAdminLevel() + ":" + cityB.getName());
}
}
}
set.close();
stat.close();
Comparator<City> comparator = new Comparator<City>() {
@Override
public int compare(City o1, City o2) {
return Collator.getInstance().compare(o1.getName(), o2.getName());
}
};
for (List<City> t : cities.values()) {
Collections.sort(t, comparator);
}
return cities;
}
Aggregations