use of net.osmand.data.MultipolygonBuilder in project OsmAnd-tools by osmandapp.
the class IndexVectorMapCreator method createMultipolygonBuilder.
private MultipolygonBuilder createMultipolygonBuilder(Entity e, OsmDbAccessorContext ctx) throws SQLException {
ctx.loadEntityRelation((Relation) e);
// create a multipolygon object for this
MultipolygonBuilder original = new MultipolygonBuilder();
original.setId(e.getId());
// fill the multipolygon with all ways from the Relation
for (RelationMember es : ((Relation) e).getMembers()) {
if (es.getEntity() instanceof Way) {
// $NON-NLS-1$
boolean inner = "inner".equals(es.getRole());
if (inner) {
original.addInnerWay((Way) es.getEntity());
} else if ("outer".equals(es.getRole())) {
original.addOuterWay((Way) es.getEntity());
}
}
}
return original;
}
use of net.osmand.data.MultipolygonBuilder 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.MultipolygonBuilder in project OsmAnd-tools by osmandapp.
the class CombineSRTMIntoFile method process.
private static void process(BinaryMapDataObject country, List<BinaryMapDataObject> boundaries, String downloadName, File directoryWithSRTMFiles, File directoryWithTargetFiles, boolean dryRun, int limit, boolean feet) throws IOException, SQLException, InterruptedException, IllegalArgumentException, XmlPullParserException {
final String suffix = "_" + IndexConstants.BINARY_MAP_VERSION + (feet ? IndexConstants.BINARY_SRTM_FEET_MAP_INDEX_EXT : IndexConstants.BINARY_SRTM_MAP_INDEX_EXT);
String name = country.getName();
String dwName = Algorithms.capitalizeFirstLetterAndLowercase(downloadName + suffix);
final File targetFile = new File(directoryWithTargetFiles, dwName);
if (targetFile.exists()) {
System.out.println("Already processed " + name);
return;
}
Set<String> srtmFileNames = new TreeSet<String>();
QuadRect qr = new QuadRect(180, -90, -180, 90);
MultipolygonBuilder bld = new MultipolygonBuilder();
if (boundaries != null) {
for (BinaryMapDataObject o : boundaries) {
bld.addOuterWay(convertToWay(o));
updateBbox(o, qr);
}
} else {
bld.addOuterWay(convertToWay(country));
updateBbox(country, qr);
}
Multipolygon polygon = bld.build();
int rightLon = (int) Math.floor(qr.right);
int leftLon = (int) Math.floor(qr.left);
int bottomLat = (int) Math.floor(qr.bottom);
int topLat = (int) Math.floor(qr.top);
boolean onetile = leftLon == rightLon && bottomLat == topLat;
for (int lon = leftLon; lon <= rightLon; lon++) {
for (int lat = bottomLat; lat <= topLat; lat++) {
boolean isOut = !polygon.containsPoint(lat + 0.5, lon + 0.5) && !onetile;
if (isOut) {
LatLon bl = new LatLon(lat, lon);
LatLon br = new LatLon(lat, lon + 1);
LatLon tr = new LatLon(lat + 1, lon + 1);
LatLon tl = new LatLon(lat + 1, lon);
for (Ring r : polygon.getOuterRings()) {
List<Node> border = r.getBorder();
Node prev = border.get(border.size() - 1);
for (int i = 0; i < border.size() && isOut; i++) {
Node n = border.get(i);
if (MapAlgorithms.linesIntersect(prev.getLatLon(), n.getLatLon(), tr, tl)) {
isOut = false;
} else if (MapAlgorithms.linesIntersect(prev.getLatLon(), n.getLatLon(), tr, br)) {
isOut = false;
} else if (MapAlgorithms.linesIntersect(prev.getLatLon(), n.getLatLon(), bl, tl)) {
isOut = false;
} else if (MapAlgorithms.linesIntersect(prev.getLatLon(), n.getLatLon(), br, bl)) {
isOut = false;
}
prev = n;
}
if (!isOut) {
break;
}
}
}
if (!isOut) {
final String filename = getFileName(lon, lat);
srtmFileNames.add(filename);
}
}
}
System.out.println();
System.out.println("-----------------------------");
System.out.println("PROCESSING " + name + " lon [" + leftLon + " - " + rightLon + "] lat [" + bottomLat + " - " + topLat + "] TOTAL " + srtmFileNames.size() + " files " + srtmFileNames);
if (dryRun) {
return;
}
if (srtmFileNames.size() > limit) {
System.out.println("\n\n!!!!!!!! WARNING BECAUSE LIMIT OF FILES EXCEEDED !!!!!!!!!\n\n");
return;
}
File procFile = new File(directoryWithTargetFiles, dwName + ".proc");
boolean locked = !procFile.createNewFile();
if (locked) {
System.out.println("\n\n!!!!!!!! WARNING FILE IS BEING PROCESSED !!!!!!!!!\n\n");
return;
}
// final File work = new File(directoryWithTargetFiles, "work");
// Map<File, String> mp = new HashMap<File, String>();
long length = 0;
List<File> files = new ArrayList<File>();
for (String file : srtmFileNames) {
final File fl = new File(directoryWithSRTMFiles, file + ".osm.bz2");
if (!fl.exists()) {
System.err.println("!! Missing " + name + " because " + file + " doesn't exist");
} else {
length += fl.length();
files.add(fl);
// File ttf = new File(fl.getParentFile(), Algorithms.capitalizeFirstLetterAndLowercase(file) + "_"+ name + ".obf");
// mp.put(ttf, null);
}
}
if (files.isEmpty()) {
System.err.println("!!! WARNING " + name + " because no files are present to index !!!");
} else {
IndexCreatorSettings settings = new IndexCreatorSettings();
settings.indexMap = true;
settings.zoomWaySmoothness = 2;
settings.boundary = polygon;
IndexCreator ic = new IndexCreator(targetFile.getParentFile(), settings);
// if (srtmFileNames.size() > NUMBER_OF_FILES_TO_PROCESS_ON_DISK || length > SIZE_GB_TO_COMBINE_INRAM) {
// ic.setDialects(DBDialect.SQLITE, DBDialect.SQLITE);
// System.out.println("SQLITE on disk is used.");
// } else {
ic.setDialects(DBDialect.SQLITE, DBDialect.SQLITE_IN_MEMORY);
// System.out.println("SQLITE in memory used: be aware whole database is stored in memory.");
// }
ic.setRegionName(name + " contour lines");
ic.setMapFileName(targetFile.getName());
File nodesDB = new File(targetFile.getParentFile(), dwName + "." + IndexCreator.TEMP_NODES_DB);
ic.setNodesDBFile(nodesDB);
ic.generateIndexes(files.toArray(new File[files.size()]), new ConsoleProgressImplementation(1), null, MapZooms.parseZooms("11-12;13-"), new MapRenderingTypesEncoder(targetFile.getName()), log, true, false);
nodesDB.delete();
RTree.clearCache();
}
procFile.delete();
// if(length > Integer.MAX_VALUE) {
// System.err.println("!! Can't process " + name + " because too big");
// } else {
// BinaryInspector.combineParts(targetFile, mp);
// }
// for(String file : srtmFileNames) {
// final File fl = new File(work, file);
// fl.delete();
// }
}
use of net.osmand.data.MultipolygonBuilder 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 = getBoundaryCenter(city.getId(), e);
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 = getBoundaryCenter(es.getEntity().getId(), es.getEntity());
} else if (es.getEntity() instanceof Node && ("label".equals(es.getRole()) && centerId == 0)) {
centerId = getBoundaryCenter(es.getEntity().getId(), es.getEntity());
}
}
} 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.MultipolygonBuilder in project OsmAnd-tools by osmandapp.
the class IndexVectorMapCreator method indexMultiPolygon.
/**
* index a multipolygon into the database
* only multipolygons without admin_level and with type=multipolygon are indexed
* broken multipolygons are also indexed, inner ways are sometimes left out, broken rings are split and closed
* broken multipolygons will normally be logged
* @param e the entity to index
* @param ctx the database context
* @throws SQLException
*/
private void indexMultiPolygon(Relation e, OsmDbAccessorContext ctx) throws SQLException {
// Don't handle things that aren't multipolygon, and nothing administrative
if ((!"multipolygon".equals(e.getTag(OSMTagKey.TYPE)) && !"protected_area".equals(e.getTag("boundary"))) || e.getTag(OSMTagKey.ADMIN_LEVEL) != null)
return;
MultipolygonBuilder original = createMultipolygonBuilder(e, ctx);
try {
renderingTypes.encodeEntityWithType(false, e.getModifiableTags(), mapZooms.getLevel(0).getMaxZoom(), typeUse, addtypeUse, namesUse, tempNameUse);
} catch (RuntimeException es) {
es.printStackTrace();
return;
}
List<Map<String, String>> splitEntities = renderingTypes.splitTags(e.getModifiableTags(), EntityType.valueOf(e));
// Don't add multipolygons with an unknown type
if (typeUse.size() == 0)
return;
excludeFromMainIteration(original.getOuterWays());
excludeFromMainIteration(original.getInnerWays());
// Rings with different types (inner or outer) in one ring will be logged in the previous case
// The Rings are only composed by type, so if one way gets in a different Ring, the rings will be incomplete
List<Multipolygon> multipolygons = original.splitPerOuterRing(logMapDataWarn);
for (Multipolygon m : multipolygons) {
assert m.getOuterRings().size() == 1;
// Log the fact that Rings aren't complete, but continue with the relation, try to close it as well as possible
if (!m.areRingsComplete()) {
logMapDataWarn.warn("In multipolygon " + e.getId() + " there are incompleted ways");
}
Ring out = m.getOuterRings().get(0);
if (out.getBorder().size() == 0) {
logMapDataWarn.warn("Multipolygon has an outer ring that can't be formed: " + e.getId());
// don't index this
continue;
}
// innerWays are new closed ways
List<List<Node>> innerWays = new ArrayList<List<Node>>();
for (Ring r : m.getInnerRings()) {
innerWays.add(r.getBorder());
}
// don't use the relation ids. Create new onesgetInnerRings
Map<String, String> stags = splitEntities == null ? e.getModifiableTags() : splitEntities.get(0);
long assignId = assignIdForMultipolygon((Relation) e);
createMultipolygonObject(stags, out, innerWays, assignId);
if (splitEntities != null) {
for (int i = 1; i < splitEntities.size(); i++) {
Map<String, String> tags = splitEntities.get(i);
while (generatedIds.contains(assignId)) {
assignId += 2;
}
generatedIds.add(assignId);
createMultipolygonObject(tags, out, innerWays, assignId);
}
}
}
}
Aggregations