use of net.osmand.data.Boundary in project OsmAnd-tools by osmandapp.
the class IndexAddressCreator method getStreetInCity.
public Set<Long> getStreetInCity(Set<String> isInNames, String name, Map<String, String> names, final LatLon location) throws SQLException {
if (location == null) {
return Collections.emptySet();
}
name = normalizeStreetName(name);
Set<City> result = new LinkedHashSet<City>();
List<City> nearestObjects = new ArrayList<City>();
nearestObjects.addAll(cityManager.getClosestObjects(location.getLatitude(), location.getLongitude()));
nearestObjects.addAll(cityVillageManager.getClosestObjects(location.getLatitude(), location.getLongitude()));
// either we found a city boundary the street is in
for (City c : nearestObjects) {
Boundary boundary = cityBoundaries.get(c);
if (isInNames.contains(c.getName()) || (boundary != null && boundary.containsPoint(location))) {
result.add(c);
}
}
// or we need to find closest city
Collections.sort(nearestObjects, new Comparator<City>() {
@Override
public int compare(City c1, City c2) {
double r1 = relativeDistance(location, c1);
double r2 = relativeDistance(location, c2);
return Double.compare(r1, r2);
}
});
for (City c : nearestObjects) {
if (relativeDistance(location, c) > 0.2) {
if (result.isEmpty()) {
result.add(c);
}
break;
} else if (!result.contains(c)) {
// city doesn't have boundary or there is a mistake in boundaries and we found nothing before
if (!cityBoundaries.containsKey(c) || result.isEmpty()) {
result.add(c);
}
}
}
return registerStreetInCities(name, names, location, result);
}
use of net.osmand.data.Boundary in project OsmAnd-tools by osmandapp.
the class IndexAddressCreator method putCityBoundary.
private Boundary putCityBoundary(Boundary boundary, City cityFound) {
final Boundary oldBoundary = cityBoundaries.get(cityFound);
if (oldBoundary == null) {
cityBoundaries.put(cityFound, boundary);
logBoundaryChanged(boundary, cityFound, getCityBoundaryImportance(boundary, cityFound), 100);
return oldBoundary;
} else if (oldBoundary.getAdminLevel() == boundary.getAdminLevel() && oldBoundary != boundary && boundary.getName().equalsIgnoreCase(oldBoundary.getName())) {
oldBoundary.mergeWith(boundary);
return oldBoundary;
} else {
int old = getCityBoundaryImportance(oldBoundary, cityFound);
int n = getCityBoundaryImportance(boundary, cityFound);
if (n < old) {
cityBoundaries.put(cityFound, boundary);
logBoundaryChanged(boundary, cityFound, n, old);
}
return oldBoundary;
}
}
use of net.osmand.data.Boundary in project OsmAnd-tools by osmandapp.
the class IndexAddressCreator method findCityPart.
private String findCityPart(LatLon location, City city) {
String cityPart = city.getName();
boolean found = false;
Boundary cityBoundary = cityBoundaries.get(city);
if (cityBoundary != null) {
List<City> subcities = boundaryToContainingCities.get(cityBoundary);
if (subcities != null) {
for (City subpart : subcities) {
if (subpart != city) {
Boundary subBoundary = cityBoundaries.get(subpart);
if (cityBoundary != null && subBoundary != null && subBoundary.getAdminLevel() > cityBoundary.getAdminLevel()) {
// old code
// subpart.getName();
cityPart = findNearestCityOrSuburb(subBoundary, location);
// ?FIXME
if (subBoundary.containsPoint(location)) {
cityPart = subpart.getName();
found = true;
break;
}
}
}
}
}
}
if (!found) {
Boundary b = cityBoundaries.get(city);
cityPart = findNearestCityOrSuburb(b, location);
}
return cityPart;
}
use of net.osmand.data.Boundary in project OsmAnd-tools by osmandapp.
the class IndexAddressCreator method extractBoundary.
private Boundary extractBoundary(Entity e, OsmDbAccessorContext ctx) throws SQLException {
if (e instanceof Node) {
return null;
}
long centerId = 0;
CityType ct = CityType.valueFromString(e.getTag(OSMTagKey.PLACE));
// if a place that has addr_place is a neighbourhood mark it as a suburb (made for the suburbs of Venice)
boolean isNeighbourhood = e.getTag(OSMTagKey.ADDR_PLACE) != null && "neighbourhood".equals(e.getTag(OSMTagKey.PLACE));
if ((ct == null && "townland".equals(e.getTag(OSMTagKey.LOCALITY))) || isNeighbourhood) {
if (e instanceof Relation) {
ctx.loadEntityRelation((Relation) e);
}
final City city = createMissingCity(e, CityType.SUBURB);
if (city != null) {
centerId = city.getId();
ct = CityType.SUBURB;
}
}
boolean administrative = "administrative".equals(e.getTag(OSMTagKey.BOUNDARY));
boolean postalCode = "postal_code".equals(e.getTag(OSMTagKey.BOUNDARY));
if (administrative || postalCode || ct != null) {
if (e instanceof Way && visitedBoundaryWays.contains(e.getId())) {
return null;
}
String bname = e.getTag(OSMTagKey.NAME);
MultipolygonBuilder m = new MultipolygonBuilder();
if (e instanceof Relation) {
Relation aRelation = (Relation) e;
ctx.loadEntityRelation(aRelation);
for (RelationMember es : aRelation.getMembers()) {
if (es.getEntity() instanceof Way) {
// $NON-NLS-1$
boolean inner = "inner".equals(es.getRole());
if (inner) {
m.addInnerWay((Way) es.getEntity());
} else {
String wName = es.getEntity().getTag(OSMTagKey.NAME);
// if name are not equal keep the way for further check (it could be different suburb)
if (Algorithms.objectEquals(wName, bname) || wName == null) {
visitedBoundaryWays.add(es.getEntity().getId());
}
m.addOuterWay((Way) es.getEntity());
}
} else if (es.getEntity() instanceof Node && ("admin_centre".equals(es.getRole()) || "admin_center".equals(es.getRole()))) {
centerId = es.getEntity().getId();
} else if (es.getEntity() instanceof Node && ("label".equals(es.getRole()) && centerId == 0)) {
centerId = es.getEntity().getId();
}
}
} else if (e instanceof Way) {
m.addOuterWay((Way) e);
}
Boundary boundary = new Boundary(m);
boundary.setName(bname);
// Goteborg
boundary.setAltName(e.getTag("short_name"));
boundary.setAdminLevel(extractBoundaryAdminLevel(e));
boundary.setBoundaryId(e.getId());
boundary.setCityType(ct);
if (centerId != 0) {
boundary.setAdminCenterId(centerId);
}
return boundary;
} else {
return null;
}
}
use of net.osmand.data.Boundary in project OsmAnd-tools by osmandapp.
the class IndexAddressCreator method tryToAssignBoundaryToFreeCities.
public void tryToAssignBoundaryToFreeCities(IProgress progress) {
progress.startWork(cities.size());
// Why to do this? This is completely incorrect to do with suburbs because it assigns boundary that is much bigger
// than suburb and after that findCityPart works incorrectly
// for cities without boundaries, try to find the right one
// start at level 8 for now...
int smallestAdminLevel = 7;
for (City c : cities.values()) {
progress.progress(1);
Boundary cityB = cityBoundaries.get(c);
if (cityB == null && (c.getType() == CityType.CITY || c.getType() == CityType.TOWN)) {
LatLon location = c.getLocation();
Boundary smallestBoundary = null;
// try to found boundary
for (Boundary b : notAssignedBoundaries) {
if (b.getAdminLevel() >= smallestAdminLevel) {
if (b.containsPoint(location.getLatitude(), location.getLongitude())) {
// the bigger the admin level, the smaller the boundary :-)
smallestAdminLevel = b.getAdminLevel();
smallestBoundary = b;
}
}
}
if (smallestBoundary != null) {
putCityBoundary(smallestBoundary, c);
notAssignedBoundaries.remove(smallestBoundary);
}
}
}
}
Aggregations