/**
   * 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;
  }
  /**
   * 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;
  }