/** * Compute the facade index for given osm tags, polygon and height. * * @param tags * @param polygon * @param height * @return Integer the facade index. */ public Integer computeFacadeIndex(OsmPolygon polygon) { Integer result = null; // first, do we are on a residential object? // yes if there is residential or house tag // or if surface of the polygon is under the max surface for a // residential house // and height is under max residential height if ((OsmUtils.isValueinTags("residential", polygon.getTags()) || OsmUtils.isValueinTags("house", polygon.getTags()) || polygon.getArea() * 10000000 < ASSERTION_RESIDENTIAL_MAX_AREA) && polygon.getHeight() < XplaneOptionsHelper.getOptions().getResidentialMax()) { result = computeResidentialFacadeIndex(polygon); } // do we are on a building object? // yes if there is industrial or Commercial tag // or if surface of the polygon is above the max surface for a // residential house // and height is above max residential height else { if (OsmUtils.isValueinTags("industrial", polygon.getTags()) || OsmUtils.isValueinTags("Commercial", polygon.getTags()) || polygon.getArea() * 10000000 > ASSERTION_RESIDENTIAL_MAX_AREA || polygon.getHeight() > XplaneOptionsHelper.getOptions().getResidentialMax()) { result = computeBuildingFacadeIndex(polygon); } } return result; }
@Override public void complete() { // if smart exclusions enabled and tile is not empty, send them to // writer if (!StatsHelper.isTileEmpty(stats) && XplaneOptionsHelper.getOptions().isSmartExclusions()) { String exclusions = exclusionsHelper.exportExclusions(); writer.complete(exclusions); } else { writer.complete(null); } if (!StatsHelper.isTileEmpty(stats)) { Osm2xpLogger.info( "Tile " + (int) currentTile.x + "/" + (int) currentTile.y + " stats : " + stats.getBuildingsNumber() + " buildings, " + stats.getForestsNumber() + " forests, " + stats.getStreetlightsNumber() + " street lights, " + stats.getObjectsNumber() + " objects. (generation took " + MiscUtils.getTimeDiff(startTime, new Date()) + ")"); // stats try { if (XplaneOptionsHelper.getOptions().isGenerateXmlStats() || XplaneOptionsHelper.getOptions().isGeneratePdfStats()) { StatsHelper.getStatsList().add(stats); } if (XplaneOptionsHelper.getOptions().isGenerateXmlStats()) { StatsHelper.saveStats(folderPath, currentTile, stats); } if (XplaneOptionsHelper.getOptions().isGeneratePdfStats()) { StatsHelper.generatePdfReport(folderPath, stats); } } catch (Osm2xpBusinessException e) { Osm2xpLogger.error("Error saving stats file for tile " + currentTile, e); } } else if (!GuiOptionsHelper.getOptions().isSinglePass()) { Osm2xpLogger.info( "Tile " + (int) currentTile.x + "/" + (int) currentTile.y + " is empty, no dsf generated"); } }
/** * send a streetLight in the dsf file. * * @param osmPolygon osm polygon * @return true if a streetlight has been written in the dsf file. */ private boolean processStreetLights(OsmPolygon osmPolygon) { Boolean result = false; if (XplaneOptionsHelper.getOptions().isGenerateStreetLights() && OsmUtils.isTagInTagsList("highway", "residential", osmPolygon.getTags())) { writeStreetLightToDsf(osmPolygon); result = true; } return result; }
@Override public void init() { // writer initialization writer.init(currentTile); // exclusionHelper if (XplaneOptionsHelper.getOptions().isSmartExclusions()) { exclusionsHelper.run(); } }
/** * @param way * @param polygon * @return */ private boolean processForest(OsmPolygon osmPolygon) { Boolean result = false; if (XplaneOptionsHelper.getOptions().isGenerateFor()) { Integer[] forestIndexAndDensity = dsfObjectsProvider.getRandomForestIndexAndDensity(osmPolygon.getTags()); if (forestIndexAndDensity != null) { writeForestToDsf(osmPolygon, forestIndexAndDensity); result = true; } } return result; }
private void processLightObject(OsmPolygon poly) { if (XplaneOptionsHelper.getOptions().isGenerateLights()) { XplaneDsfObject object = dsfObjectsProvider.getRandomDsfLightObject(poly); if (object != null) { object.setPolygon(poly); try { writeObjectToDsf(object); } catch (Osm2xpBusinessException e) { } } } }
/** * Write streetlight objects in dsf file. * * @param osmPolygon osm road polygon */ public void writeStreetLightToDsf(OsmPolygon osmPolygon) { // init d'un entier pour modulo densité street lights Integer densityIndex = 0; if (XplaneOptionsHelper.getOptions().getLightsDensity() == 0) { densityIndex = 10; } else { if (XplaneOptionsHelper.getOptions().getLightsDensity() == 1) { densityIndex = 5; } else { if (XplaneOptionsHelper.getOptions().getLightsDensity() == 2) densityIndex = 3; } } StringBuffer sb = new StringBuffer(); for (int i = 0; i < osmPolygon.getPolygon().getVertices().size(); i++) { if ((i % densityIndex) == 0) { Point2D lightLoc = osmPolygon.getPolygon().getVertex(i); lightLoc.x = lightLoc.x + 0.0001; lightLoc.y = lightLoc.y + 0.0001; if (GeomUtils.compareCoordinates(lightLoc, currentTile)) { Random randomGenerator = new Random(); int orientation = randomGenerator.nextInt(360); sb.append( "OBJECT " + dsfObjectsProvider.getRandomStreetLightObject() + " " + (lightLoc.y) + " " + (lightLoc.x) + " " + orientation); sb.append(System.getProperty("line.separator")); // stats StatsHelper.addStreetLight(stats); } } } writer.write(sb.toString()); }
/** * Construct and write a facade building in the dsf file. * * @param osmPolygon osm polygon * @return true if a building has been gennerated in the dsf file. */ private boolean processBuilding(OsmPolygon osmPolygon) { Boolean result = false; if (XplaneOptionsHelper.getOptions().isGenerateBuildings() && OsmUtils.isBuilding(osmPolygon.getTags()) && !OsmUtils.isExcluded(osmPolygon.getTags(), osmPolygon.getId()) && osmPolygon.getPolygon().getVertexNumber() > BUILDING_MIN_VECTORS && osmPolygon.getPolygon().getVertexNumber() < BUILDING_MAX_VECTORS) { // check that the largest vector of the building // and that the area of the osmPolygon.getPolygon() are over the // minimum values set by the user Double maxVector = osmPolygon.getMaxVectorSize(); if (maxVector > XplaneOptionsHelper.getOptions().getMinHouseSegment() && maxVector < XplaneOptionsHelper.getOptions().getMaxHouseSegment() && ((osmPolygon.getPolygon().getArea() * 100000) * 100000) > XplaneOptionsHelper.getOptions().getMinHouseArea()) { // simplify shape if checked and if necessary if (GuiOptionsHelper.getOptions().isSimplifyShapes() && !osmPolygon.isSimplePolygon()) { osmPolygon.simplifyPolygon(); } // compute height and facade dsf index osmPolygon.setHeight(computeBuildingHeight(osmPolygon)); Integer facade = computeFacadeIndex(osmPolygon); // write building in dsf file writeBuildingToDsf(osmPolygon, facade); // Smart exclusions if (XplaneOptionsHelper.getOptions().isSmartExclusions()) { exclusionsHelper.addTodoPolygon(osmPolygon); exclusionsHelper.run(); } result = true; } } return result; }
/** * Compute the height for this polygon and osm tags. * * @return Integer the height. */ private Integer computeBuildingHeight(OsmPolygon polygon) { Integer result = null; Integer osmHeight = polygon.getHeight(); if (osmHeight != null) { result = osmHeight; } else { if (polygon.getArea() * 10000000 < 0.2) { result = XplaneOptionsHelper.getOptions().getResidentialMin(); } else { if (polygon.getArea() * 10000000 > ASSERTION_RESIDENTIAL_MAX_AREA) result = MiscUtils.getRandomSize( XplaneOptionsHelper.getOptions().getBuildingMin(), XplaneOptionsHelper.getOptions().getBuildingMax()); else if (polygon.getArea() * 10000000 < ASSERTION_RESIDENTIAL_MAX_AREA) result = MiscUtils.getRandomSize( XplaneOptionsHelper.getOptions().getResidentialMin(), XplaneOptionsHelper.getOptions().getResidentialMax()); } } return result; }
/** * choose and write a 3D object in the dsf file. * * @param polygon osm polygon. * @return true if a 3D object has been written in the dsf file. */ private boolean process3dObject(OsmPolygon osmPolygon) { Boolean result = false; if (XplaneOptionsHelper.getOptions().isGenerateObj()) { // simplify shape if checked and if necessary if (GuiOptionsHelper.getOptions().isSimplifyShapes() && !osmPolygon.isSimplePolygon()) { osmPolygon.simplifyPolygon(); } XplaneDsfObject object = dsfObjectsProvider.getRandomDsfObject(osmPolygon); if (object != null) { object.setPolygon(osmPolygon); try { writeObjectToDsf(object); result = true; } catch (Osm2xpBusinessException e) { result = false; } } } return result; }
/** * compute the dsf index of the residential facade object used for a given polygon * * @param polygon * @param height * @return Integer the facade index */ private Integer computeResidentialFacadeIndex(OsmPolygon osmPolygon) { Integer result = null; // we check if we can use a sloped roof if the user wants them if (XplaneOptionsHelper.getOptions().isGenerateSlopedRoofs() && osmPolygon.isSimplePolygon()) { result = dsfObjectsProvider.computeFacadeDsfIndex(true, true, true, osmPolygon); } // no sloped roof, so we'll use a standard house facade else { // if the polygon is a simple rectangle, we'll use a facade made for // simple shaped buildings if (osmPolygon.getPolygon().getEdges().size() == 4) { result = dsfObjectsProvider.computeFacadeDsfIndex(true, true, false, osmPolygon); } // the building has a complex footprint, so we'll use a facade made // for this case else { result = dsfObjectsProvider.computeFacadeDsfIndex(false, true, false, osmPolygon); } } return result; }
@Override public void processNode(Node node) throws Osm2xpBusinessException { // process the node if we're on a single pass mode. // if not on single pass, only process if the node is on the current // lat/long tile if (XplaneOptionsHelper.getOptions().isGenerateObj()) { if ((!GuiOptionsHelper.getOptions().isSinglePass() && GeomUtils.compareCoordinates(currentTile, node)) || GuiOptionsHelper.getOptions().isSinglePass()) { // write a 3D object in the dsf file if this node is in an // object // rule XplaneDsf3DObject object = dsfObjectsProvider.getRandomDsfObjectIndexAndAngle(node.getTag(), node.getId()); if (object != null) { List<Node> nodes = new ArrayList<Node>(); nodes.add(node); object.setPolygon(new OsmPolygon(node.getId(), node.getTag(), nodes)); writeObjectToDsf(object); } } } }