/**
   * @param outputObject
   * @param id
   * @param lunghezza
   * @param pterr
   * @param inputFeature
   * @throws IOException
   */
  private void addAggregateDissestoFeature(
      OutputObject outputObject,
      int id,
      int lunghezza,
      Set<Integer> pterr,
      SimpleFeature inputFeature)
      throws IOException {
    SimpleFeatureBuilder dissestoFeatureBuilder = outputObject.getBuilder();

    for (int dissesto : pterr) {
      // compiles the attributes from target and read feature data, using mappings
      // to match input attributes with output ones
      for (AttributeDescriptor attr : outputObject.getSchema().getAttributeDescriptors()) {
        if (attr.getLocalName().equals(geoId)) {
          dissestoFeatureBuilder.add(id);
        } else if (attr.getLocalName().equals("id_dissesto")) {
          dissestoFeatureBuilder.add(dissesto);
        } else if (attr.getLocalName().equals("fk_partner")) {
          dissestoFeatureBuilder.add(partner + "");
        } else {
          dissestoFeatureBuilder.add(null);
        }
      }
      String featureid = dissesto + "." + id;
      SimpleFeature feature = dissestoFeatureBuilder.buildFeature(featureid);
      feature.getUserData().put(Hints.USE_PROVIDED_FID, true);

      outputObject.getWriter().addFeatures(DataUtilities.collection(feature));
    }
  }
  private void addAggregateCFFFeature(
      OutputObject cffObject, int id, int lunghezza, double cff[], SimpleFeature inputFeature)
      throws IOException {

    SimpleFeatureBuilder featureBuilder = cffObject.getBuilder();
    for (int count = 0; count < cff.length; count++) {
      try {
        double cffElement = cff[count];
        featureBuilder.reset();
        // compiles the attributes from target and read feature data, using mappings
        // to match input attributes with output ones
        for (AttributeDescriptor attr : cffObject.getSchema().getAttributeDescriptors()) {
          if (attr.getLocalName().equals("cff")) {
            // compute the aritmetic average
            featureBuilder.add(cffElement / lunghezza);
          } else if (attr.getLocalName().equals("fk_partner")) {
            featureBuilder.add(partner + "");
          } else {
            featureBuilder.add(null);
          }
        }
        String idBersaglio = bersaglio.getProperty(Integer.toString(count + 1));
        String featureid = id + "." + idBersaglio;
        SimpleFeature feature = featureBuilder.buildFeature(featureid);
        feature.getUserData().put(Hints.USE_PROVIDED_FID, true);

        cffObject.getWriter().addFeatures(DataUtilities.collection(feature));
      } catch (NumberFormatException e) {

      }
    }
  }
  private void addAggregatePADRFeature(
      OutputObject padrObject, int id, int lunghezza, double padr[], SimpleFeature inputFeature)
      throws IOException {

    SimpleFeatureBuilder featureBuilder = padrObject.getBuilder();
    for (int count = 0; count < padr.length; count++) {
      try {
        double padrElement = padr[count];
        featureBuilder.reset();
        // compiles the attributes from target and read feature data,
        // using mappings
        // to match input attributes with output ones
        for (AttributeDescriptor attr : padrObject.getSchema().getAttributeDescriptors()) {
          if (attr.getLocalName().equals("padr")) {
            // compute the aritmetic average
            featureBuilder.add(padrElement / lunghezza);
          } else if (attr.getLocalName().equals("fk_partner")) {
            featureBuilder.add(partner + "");
          } else {
            featureBuilder.add(null);
          }
        }

        String idSostanza = (count + 1) + "";
        String featureid = id + "." + idSostanza;
        SimpleFeature feature = featureBuilder.buildFeature(featureid);
        feature.getUserData().put(Hints.USE_PROVIDED_FID, true);

        padrObject.getWriter().addFeatures(DataUtilities.collection(feature));
      } catch (NumberFormatException e) {

      }
    }
  }
 /**
  * @param outputObject
  * @param id
  * @param geo
  * @param lunghezza
  * @param corsie
  * @param inputFeature
  * @throws IOException
  */
 private void addAggregateGeoFeature(
     OutputObject outputObject,
     int id,
     int idTematico,
     Geometry geo,
     int lunghezza,
     int corsie,
     int incidenti,
     SimpleFeature inputFeature,
     int idOrigin,
     String flgCorsie,
     String flgIncidenti)
     throws IOException {
   SimpleFeatureBuilder geoFeatureBuilder = outputObject.getBuilder();
   for (AttributeDescriptor attr : outputObject.getSchema().getAttributeDescriptors()) {
     if (attr.getLocalName().equals(geoId)) {
       geoFeatureBuilder.add(id);
     } else if (attr.getLocalName().equals("fk_partner")) {
       geoFeatureBuilder.add(partner + "");
     } else if (attr.getLocalName().equals("id_tematico_shape")) {
       geoFeatureBuilder.add(idTematico + "");
     } else if (attr.getLocalName().equals("geometria")) {
       geoFeatureBuilder.add(geo);
     } else if (attr.getLocalName().equals("lunghezza")) {
       geoFeatureBuilder.add(lunghezza);
     } else if (attr.getLocalName().equals("nr_incidenti")) {
       geoFeatureBuilder.add(incidenti);
     } else if (attr.getLocalName().equals("nr_incidenti_elab")) {
       geoFeatureBuilder.add(incidenti);
     } else if (attr.getLocalName().equals("flg_nr_corsie")) {
       geoFeatureBuilder.add(flgCorsie);
     } else if (attr.getLocalName().equals("flg_nr_incidenti")) {
       geoFeatureBuilder.add(flgIncidenti);
     } else if (attr.getLocalName().equals("id_origine")) {
       geoFeatureBuilder.add(idOrigin);
     } else if (attr.getLocalName().equals("nr_corsie")) {
       if (lunghezza == 0) {
         geoFeatureBuilder.add(0);
       } else {
         geoFeatureBuilder.add(corsie / lunghezza);
       }
     } else {
       geoFeatureBuilder.add(null);
     }
   }
   SimpleFeature geoFeature = geoFeatureBuilder.buildFeature("" + id);
   geoFeature.getUserData().put(Hints.USE_PROVIDED_FID, true);
   outputObject.getWriter().addFeatures(DataUtilities.collection(geoFeature));
 }
  /**
   * @param outputObject
   * @param id
   * @param idTematico
   * @param tgm
   * @param velocita
   * @param inputFeature
   * @throws IOException
   */
  private void addAggregateVehicleFeature(
      OutputObject outputObject,
      int id,
      int lunghezza,
      int[] tgm,
      int[] velocita,
      String flgTgm,
      String flgVeloc,
      SimpleFeature inputFeature)
      throws IOException {
    SimpleFeatureBuilder byvehicleFeatureBuilder = outputObject.getBuilder();

    for (int type = 0; type <= 1; type++) {
      for (AttributeDescriptor attr : outputObject.getSchema().getAttributeDescriptors()) {
        if (attr.getLocalName().equals(geoId)) {
          byvehicleFeatureBuilder.add(id);
        } else if (attr.getLocalName().equals("densita_veicolare")) {
          if (lunghezza == 0) {
            byvehicleFeatureBuilder.add(0);
          } else {
            byvehicleFeatureBuilder.add(tgm[type] / lunghezza);
          }
        } else if (attr.getLocalName().equals("id_tipo_veicolo")) {
          byvehicleFeatureBuilder.add(type + 1);
        } else if (attr.getLocalName().equals("flg_velocita")) {
          byvehicleFeatureBuilder.add(flgVeloc);
        } else if (attr.getLocalName().equals("flg_densita_veicolare")) {
          byvehicleFeatureBuilder.add(flgTgm);
        } else if (attr.getLocalName().equals("velocita_media")) {
          if (lunghezza == 0) {
            byvehicleFeatureBuilder.add(0);
          } else {
            byvehicleFeatureBuilder.add(velocita[type] / lunghezza);
          }
        } else if (attr.getLocalName().equals("fk_partner")) {
          byvehicleFeatureBuilder.add(partner + "");
        } else {
          byvehicleFeatureBuilder.add(null);
        }
      }
      String featureid = (type + 1) + "." + id;
      SimpleFeature feature = byvehicleFeatureBuilder.buildFeature(featureid);
      feature.getUserData().put(Hints.USE_PROVIDED_FID, true);

      outputObject.getWriter().addFeatures(DataUtilities.collection(feature));
    }
  }
  private void addCFFFeature(OutputObject cffObject, int id, SimpleFeature inputFeature)
      throws IOException {

    SimpleFeatureBuilder featureBuilder = cffObject.getBuilder();
    Object cffAttribute = inputFeature.getAttribute("CFF");
    String[] cffAttributeSplitted =
        cffAttribute == null ? new String[] {} : cffAttribute.toString().split("\\|");

    for (int count = 0; count < cffAttributeSplitted.length; count++) {
      try {
        String el = cffAttributeSplitted[count].replace(",", ".");
        double cffElement = Double.parseDouble(el);
        featureBuilder.reset();

        String idBersaglio = bersaglio.getProperty(Integer.toString(count + 1));

        // compiles the attributes from target and read feature data, using mappings
        // to match input attributes with output ones
        for (AttributeDescriptor attr : cffObject.getSchema().getAttributeDescriptors()) {
          if (attr.getLocalName().equals(geoId)) {
            featureBuilder.add(id);
          } else if (attr.getLocalName().equals("cff")) {
            featureBuilder.add(cffElement);
          } else if (attr.getLocalName().equals("id_bersaglio")) {
            featureBuilder.add(idBersaglio);
          } else if (attr.getLocalName().equals("fk_partner")) {
            featureBuilder.add(partner + "");
          } else {
            featureBuilder.add(null);
          }
        }
        //                            String fid2 = el.replaceAll("\\,", "");
        //                            fid2 = el.replaceAll("\\.", "");
        String featureid = id + "." + idBersaglio;
        SimpleFeature feature = featureBuilder.buildFeature(featureid);
        feature.getUserData().put(Hints.USE_PROVIDED_FID, true);

        cffObject.getWriter().addFeatures(DataUtilities.collection(feature));
      } catch (NumberFormatException e) {

      }
    }
  }
  private void addSostanzaFeature(
      OutputObject sostanzaObject, int id, SimpleFeature inputFeature, DataStore datastore)
      throws IOException {

    SimpleFeatureBuilder featureBuilder = sostanzaObject.getBuilder();
    Object padrAttribute = inputFeature.getAttribute("PADR");
    String[] padrAttributeSplitted =
        padrAttribute == null ? new String[] {} : padrAttribute.toString().split("\\|");

    for (int count = 0; count < padrAttributeSplitted.length; count++) {
      try {
        String el = padrAttributeSplitted[count].replace(",", ".");
        double padrElement = Double.parseDouble(el);
        featureBuilder.reset();
        String id_sostanza = (count + 1) + "";
        // for (String id_sostanza : sostanze) {
        for (AttributeDescriptor attr : sostanzaObject.getSchema().getAttributeDescriptors()) {
          if (attr.getLocalName().equals(geoId)) {
            featureBuilder.add(id);
          } else if (attr.getLocalName().equals("id_sostanza")) {
            featureBuilder.add(id_sostanza);
          } else if (attr.getLocalName().equals("padr")) {
            featureBuilder.add(padrElement);
          } else if (attr.getLocalName().equals("fk_partner")) {
            featureBuilder.add(partner + "");
          } else {
            featureBuilder.add(null);
          }
        }
        String featureid = id + "." + id_sostanza;
        SimpleFeature feature = featureBuilder.buildFeature(featureid);
        feature.getUserData().put(Hints.USE_PROVIDED_FID, true);

        sostanzaObject.getWriter().addFeatures(DataUtilities.collection(feature));
        // }
      } catch (NumberFormatException e) {

      }
    }
  }
  /**
   * Adds a new geo arc feature.
   *
   * @param geoSchema
   * @param geoFeatureBuilder
   * @param geoFeatureWriter
   * @param inputFeature
   * @param id
   * @throws IOException
   */
  private void addGeoFeature(OutputObject geoObject, int id, SimpleFeature inputFeature)
      throws IOException {
    SimpleFeatureBuilder geoFeatureBuilder = geoObject.getBuilder();
    // compiles the attributes from target and read feature data
    for (AttributeDescriptor attr : geoObject.getSchema().getAttributeDescriptors()) {
      if (attr.getLocalName().equals(geoId)) {
        geoFeatureBuilder.add(id);
      } else if (attr.getLocalName().equals("fk_partner")) {
        geoFeatureBuilder.add(partner + "");
      } else if (attr.getLocalName().equals("geometria")) {
        geoFeatureBuilder.add(inputFeature.getDefaultGeometry());
      } else if (attributeMappings.containsKey(attr.getLocalName())) {
        geoFeatureBuilder.add(getMapping(inputFeature, attributeMappings, attr.getLocalName()));
      } else {
        geoFeatureBuilder.add(null);
      }
    }

    SimpleFeature geoFeature = geoFeatureBuilder.buildFeature("" + id);
    geoFeature.getUserData().put(Hints.USE_PROVIDED_FID, true);
    geoObject.getWriter().addFeatures(DataUtilities.collection(geoFeature));
  }
  /** Adds arc - dissesto data feature. */
  private void addDissestoFeature(OutputObject dissestoObject, int id, SimpleFeature inputFeature)
      throws IOException {

    SimpleFeatureBuilder featureBuilder = dissestoObject.getBuilder();

    String[] pterrs =
        inputFeature.getAttribute("PTERR") == null
            ? null
            : inputFeature.getAttribute("PTERR").toString().split("\\|");

    for (int count = 0; count < pterrs.length; count++) {
      try {
        int dissesto = Integer.parseInt(pterrs[count]);
        featureBuilder.reset();
        // compiles the attributes from target and read feature data, using mappings
        // to match input attributes with output ones
        for (AttributeDescriptor attr : dissestoObject.getSchema().getAttributeDescriptors()) {
          if (attr.getLocalName().equals(geoId)) {
            featureBuilder.add(id);
          } else if (attr.getLocalName().equals("id_dissesto")) {
            featureBuilder.add(dissesto);
          } else if (attr.getLocalName().equals("fk_partner")) {
            featureBuilder.add(partner + "");
          } else {
            featureBuilder.add(null);
          }
        }
        String featureid = id + "." + dissesto;
        SimpleFeature feature = featureBuilder.buildFeature(featureid);
        feature.getUserData().put(Hints.USE_PROVIDED_FID, true);

        dissestoObject.getWriter().addFeatures(DataUtilities.collection(feature));
      } catch (NumberFormatException e) {

      }
    }
  }
  /** Adds arc - vehicletype data feature. */
  private void addVehicleFeature(OutputObject vehicleObject, int id, SimpleFeature inputFeature)
      throws IOException {

    SimpleFeatureBuilder featureBuilder = vehicleObject.getBuilder();

    int[] tgm = extractMultipleValues(inputFeature, "TGM");
    int[] velocita = extractMultipleValues(inputFeature, "VELOCITA");

    for (int type = 0; type <= 1; type++) {
      featureBuilder.reset();
      // compiles the attributes from target and read feature data, using mappings
      // to match input attributes with output ones
      for (AttributeDescriptor attr : vehicleObject.getSchema().getAttributeDescriptors()) {
        if (attr.getLocalName().equals(geoId)) {
          featureBuilder.add(id);
        } else if (attr.getLocalName().equals("densita_veicolare")) {
          featureBuilder.add(tgm[type]);
        } else if (attr.getLocalName().equals("id_tipo_veicolo")) {
          featureBuilder.add(type + 1);
        } else if (attr.getLocalName().equals("velocita_media")) {
          featureBuilder.add(velocita[type]);
        } else if (attr.getLocalName().equals("fk_partner")) {
          featureBuilder.add(partner + "");
        } else if (attributeMappings.containsKey(attr.getLocalName())) {
          featureBuilder.add(getMapping(inputFeature, attributeMappings, attr.getLocalName()));
        } else {
          featureBuilder.add(null);
        }
      }
      String featureid = (type + 1) + "." + id;
      SimpleFeature feature = featureBuilder.buildFeature(featureid);
      feature.getUserData().put(Hints.USE_PROVIDED_FID, true);

      vehicleObject.getWriter().addFeatures(DataUtilities.collection(feature));
    }
  }