@Override
  public void processPolygon(OsmPolygon osmPolygon) throws Osm2xpBusinessException {

    // polygon is null or empty don't process it
    if (osmPolygon.getNodes() != null && !osmPolygon.getNodes().isEmpty()) {
      // polygon MUST be in clockwise order
      osmPolygon.setPolygon(GeomUtils.forceClockwise(osmPolygon.getPolygon()));
      // if we're on a single pass mode
      // here we must check if the polygon is on more than one tile
      // if that's the case , we must split it into several polys
      List<OsmPolygon> polygons = new ArrayList<OsmPolygon>();
      if (GuiOptionsHelper.getOptions().isSinglePass()) {
        polygons.addAll(osmPolygon.splitPolygonAroundTiles());
      }
      // if not on a single pass mode, add this single polygon to the poly
      // list
      else {
        polygons.add(osmPolygon);
      }
      // try to transform those polygons into dsf objects.
      for (OsmPolygon poly : polygons) {
        // look for light rules
        processLightObject(poly);

        // try to generate a 3D object
        if (!process3dObject(poly)) {
          // nothing generated? try to generate a facade building.
          if (!processBuilding(poly)) {
            // nothing generated? try to generate a forest.
            processForest(poly);
          }
        }
      }
    }
  }
  /**
   * write a building in the dsf file.
   *
   * @param polygon
   * @param facade
   * @param size
   */
  private void writeBuildingToDsf(OsmPolygon osmPolygon, Integer facade) {
    if (facade != null && osmPolygon.getHeight() != null) {
      StringBuffer sb = new StringBuffer();
      osmPolygon.setPolygon(GeomUtils.setClockwise(osmPolygon.getPolygon()));
      if (osmPolygon.getPolygon().getArea() * 100000000 > 0.1
          && osmPolygon.getPolygon().getVertexNumber() > 3) {

        sb.append("BEGIN_POLYGON " + facade + " " + osmPolygon.getHeight() + " 2");
        sb.append(System.getProperty("line.separator"));
        sb.append("BEGIN_WINDING");
        sb.append(System.getProperty("line.separator"));

        // on supprime le dernier point pour ne pas boucler
        osmPolygon.getPolygon().removePoint(osmPolygon.getPolygon().getLastPoint());
        for (Point2D loc : osmPolygon.getPolygon().getVertices()) {
          sb.append("POLYGON_POINT " + loc.y + " " + loc.x);
          sb.append(System.getProperty("line.separator"));
        }
        sb.append("END_WINDING");
        sb.append(System.getProperty("line.separator"));
        sb.append("END_POLYGON");
        sb.append(System.getProperty("line.separator"));

        // stats TODO not working anymore since v2 facades new features.
        if (dsfObjectsProvider.getPolygonsList().get(facade).toLowerCase().contains("building")
            || dsfObjectsProvider.getPolygonsList().get(facade).toLowerCase().contains("shape")) {
          StatsHelper.addBuildingType("Building", stats);
        } else {
          if (dsfObjectsProvider.getPolygonsList().get(facade).toLowerCase().contains("house")
              || dsfObjectsProvider
                  .getPolygonsList()
                  .get(facade)
                  .toLowerCase()
                  .contains("common")) {
            StatsHelper.addBuildingType("Residential", stats);
          } else {
            StatsHelper.addBuildingType("Facade rule", stats);
          }
        }
        writer.write(
            sb.toString(), GeomUtils.cleanCoordinatePoint(osmPolygon.getPolygon().getFirstPoint()));
      }
    }
  }