public void testExecuteUnion() throws Exception {
    org.geotools.process.Process union = factory.create(new NameImpl("JTS", "union"));

    // try less than the required params
    Map<String, Object> inputs = new HashMap<String, Object>();
    try {
      union.execute(inputs, null);
      fail("What!!! Should have failed big time!");
    } catch (ProcessException e) {
      // fine
    }

    // try again with less
    Geometry geom1 = new WKTReader().read("POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))");
    Geometry geom2 = new WKTReader().read("POLYGON((0 1, 0 2, 1 2, 1 1, 0 1))");
    List<Geometry> geometries = new ArrayList<Geometry>();
    geometries.add(geom1);
    inputs.put("geom", geometries);
    try {
      union.execute(inputs, null);
      fail("What!!! Should have failed big time!");
    } catch (ProcessException e) {
      // fine
    }

    // now with just enough
    geometries.add(geom2);
    Map<String, Object> result = union.execute(inputs, null);

    assertEquals(1, result.size());
    Geometry united = (Geometry) result.get("result");
    assertNotNull(united);
    assertTrue(united.equals(geom1.union(geom2)));
  }
  /**
   * @return a single geometry product of unioning all the bounding boxes acquired while traversing
   *     the diff
   */
  public Geometry buildGeometry() {
    List<Geometry> geomList = nonPoints;
    nonPoints = null;
    if (!points.isEmpty()) {
      geomList.add(points);
    }
    points = null;

    Geometry buildGeometry = GEOM_FACTORY.buildGeometry(geomList);
    geomList.clear();
    Geometry union = buildGeometry.union();
    return union;
  }
  /**
   * @param toSplit the line to split
   * @param line the line to use for the split
   * @return a sorted list of geometries as a result of splitting toSplit with line
   */
  protected List<LineString> splitLine(Geometry toSplit, Geometry line) {
    List<LineString> output = new ArrayList();
    Geometry lines = toSplit.union(line);

    for (int i = 0; i < lines.getNumGeometries(); i++) {
      LineString l = (LineString) lines.getGeometryN(i);
      // TODO to be tested
      if (toSplit.contains(l.getInteriorPoint())) {
        output.add(l);
      }
    }
    geometrySorter(output);
    return output;
  }
Example #4
0
  /**
   * @param args
   * @throws IOException
   */
  public static void main(String[] args) throws IOException {
    ZoneCollection zones = new ZoneCollection();
    String data =
        new String(
            Files.readAllBytes(Paths.get("/home/johannes/gsv/gis/nuts/de.nuts3.gk3.geojson")));
    zones.addAll(ZoneGeoJsonIO.parseFeatureCollection(data));
    data = null;
    zones.setPrimaryKey("gsvId");

    Map<String, Set<Zone>> aggZones = new HashMap<>();
    for (Zone zone : zones.getZones()) {
      String code = zone.getAttribute("nuts2_code");
      Set<Zone> set = aggZones.get(code);
      if (set == null) {
        set = new HashSet<>();
        aggZones.put(code, set);
      }
      set.add(zone);
    }

    Set<Zone> newZones = new HashSet<>();

    for (Entry<String, Set<Zone>> entry : aggZones.entrySet()) {
      Set<Zone> set = entry.getValue();
      Geometry refGeo = null;
      for (Zone zone : set) {
        if (refGeo != null) {

          Geometry geo2 = zone.getGeometry();

          refGeo = refGeo.union(geo2);
        } else {
          refGeo = zone.getGeometry();
        }
      }

      Zone zone = new Zone(refGeo);
      zone.setAttribute("nuts2_code", entry.getKey());
      newZones.add(zone);
    }

    data = ZoneGeoJsonIO.toJson(newZones);
    Files.write(
        Paths.get("/home/johannes/gsv/gis/nuts/de.nuts2.gk3.geojson"),
        data.getBytes(),
        StandardOpenOption.CREATE);
  }
  private Geometry createBuffer(
      List<Geometry> lineStrings, double bufferSize, boolean excludeTermini) {
    BufferParameters bufferParameters = new BufferParameters();

    if (excludeTermini) {
      bufferParameters.setEndCapStyle(BufferParameters.CAP_FLAT);
    } else {
      bufferParameters.setEndCapStyle(BufferParameters.CAP_ROUND);
    }

    Geometry union = null;

    for (Geometry lineString : lineStrings) {
      Geometry buffer = BufferOp.bufferOp(lineString, bufferSize, bufferParameters);
      if (union == null) {
        union = buffer;
      } else {
        union = union.union(buffer);
      }
    }

    return union;
  }
  /**
   * Traverses the FeatureCollection<SimpleFeatureType, SimpleFeature> <code>selection</code>
   * creating a buffered geometry on each SimpleFeature's default geometry and stores the result in
   * a new SimpleFeature on the <code>target</code> FeatureStore.
   *
   * <p>Note the buffer computation is made with a slightly {@link BufferOp modified version} of the
   * JTS <code>BufferOp</code> in order to allow the operation to be cancelled while inside the
   * buffer computation.
   *
   * @param params buffer parameters
   * @param selection source layer's selected features in its native CRS
   * @throws SOProcessException if {@link #createBufferedFeature(SimpleFeature, SimpleFeatureType,
   *     Geometry)} fails
   * @throws IOException if it is thrown while adding the resulting features to the target
   *     FeatureStore<SimpleFeatureType, SimpleFeature> or while commiting the transaction
   * @throws InterruptedException if the user cancelled the operation
   */
  private void performBuffer(
      IBufferParameters params, FeatureCollection<SimpleFeatureType, SimpleFeature> selection)
      throws SOProcessException, InterruptedException {

    assert selection != null;

    final int featureCount = selection.size();

    final ILayer sourceLayer = this.sourceLayer;

    final CoordinateReferenceSystem sourceCrs = LayerUtil.getCrs(sourceLayer);

    final CoordinateReferenceSystem mapCrs = MapUtil.getCRS(sourceLayer.getMap());

    final CoordinateReferenceSystem targetCrs =
        this.targetStore.getSchema().getDefaultGeometry().getCRS();

    final Unit sourceUnits = GeoToolsUtils.getDefaultCRSUnit(mapCrs);
    final Unit targetUnits = params.getUnitsOfMeasure();
    final int quadSegments = params.getQuadrantSegments().intValue();

    final Double width = params.getWidth().doubleValue();

    SimpleFeature sourceFeature = null;
    // the one to use if params.isMergeGeometry() == true
    Geometry mergedGeometry = null;

    FeatureIterator<SimpleFeature> iterator = null;

    try {
      int processingCount = 0;
      Geometry geometry;

      String subTaskName;

      iterator = selection.features();
      while (iterator.hasNext()) {

        processingCount++;
        subTaskName =
            MessageFormat.format(
                Messages.BufferProcess_subTask_BufferingFeatureN, processingCount, featureCount);

        getMonitor().subTask(subTaskName);

        checkCancelation();

        sourceFeature = iterator.next();

        geometry = (Geometry) sourceFeature.getDefaultGeometry();
        geometry = GeoToolsUtils.reproject(geometry, sourceCrs, mapCrs);
        geometry =
            makeBufferGeometry(
                geometry, width, sourceUnits, targetUnits, quadSegments, getMonitor());
        geometry = GeoToolsUtils.reproject(geometry, mapCrs, targetCrs);

        checkCancelation();

        if (params.isMergeGeometries()) {
          if (mergedGeometry == null) {
            mergedGeometry = geometry;
          } else {
            mergedGeometry = mergedGeometry.union(geometry);
          }
        } else {
          createAndStoreBufferedFeature(sourceFeature, geometry, this.targetStore);
        }
        getMonitor().worked(1);
      }
      checkCancelation();
      if (params.isMergeGeometries()) {
        createAndStoreBufferedFeature(null, mergedGeometry, this.targetStore);
      }

      getMonitor().subTask(Messages.BufferProcess_subtastCommittingTransaction);

    } catch (OperationNotFoundException e) {
      String message =
          MessageFormat.format(
              Messages.BufferProcess_failed_transforming, sourceFeature.getID(), e.getMessage());
      throw new SOProcessException(message, e);
    } catch (TransformException e) {
      String message =
          MessageFormat.format(
              Messages.BufferProcess_failed_transforming_feature_to_crs,
              sourceFeature.getID(),
              e.getMessage());
      throw new SOProcessException(message, e);
    } finally {

      if (iterator != null) iterator.close();

      getMonitor().done();
    }
  }
Example #7
0
  /** Read in data and set up the simulation */
  public void start() {
    super.start();
    try {

      GeomVectorField populationLayer = new GeomVectorField(grid_width, grid_height);

      //////////////////////////////////////////////
      ///////////// READING IN DATA ////////////////
      //////////////////////////////////////////////

      readInVectorLayer(baseLayer, dirName + "haiti/haiti_meters.shp", "area", new Bag());
      readInVectorLayer(
          populationLayer,
          dirName + "population/popCentroids_meters.shp",
          "residential areas",
          new Bag());
      readInVectorLayer(roadLayer, dirName + "roads/roads_meters.shp", "road network", new Bag());
      readInVectorLayer(
          waterwayLayer, dirName + "waterways/rivers_meters.shp", "waterways", new Bag());
      readInVectorLayer(
          medicalLayer,
          dirName + "healthFacilities/health_meters.shp",
          "health facilities",
          new Bag());

      //////////////////////////////////////////////
      ////////////////// CLEANUP ///////////////////
      //////////////////////////////////////////////

      // standardize the MBRs so that the visualization lines up

      MBR = roadLayer.getMBR();
      //			MBR.init(740000, 780000, 2000000, 2040000); // 35 22
      MBR.init(740000, 779000, 2009000, 2034000); // 35 22
      //			MBR.init(750000, 772000, 2009500, 2028500); // 22 18
      //			MBR.init(756000, 766000, 2015500, 2022500);
      roadLayer.setMBR(MBR);
      // baseLayer.setMBR(MBR);

      this.grid_width = roadLayer.fieldWidth;
      this.grid_height = roadLayer.fieldHeight;

      // base layer

      landArea = (Geometry) ((MasonGeometry) baseLayer.getGeometries().get(0)).geometry.clone();
      for (Object o : baseLayer.getGeometries()) {
        MasonGeometry g = (MasonGeometry) o;
        landArea = landArea.union(g.geometry);
      }

      // clean up the road network

      System.out.print("Cleaning the road network...");

      roads =
          NetworkUtilities.multipartNetworkCleanup(roadLayer, roadNodes, resolution, fa, random, 0);
      roadNodes = roads.getAllNodes();
      testNetworkForIssues(roads);

      /*			// set up roads as being "open" and assemble the list of potential terminii
      			roadLayer = new GeomVectorField(grid_width, grid_height);
      			for(Object o: roadNodes){
      				GeoNode n = (GeoNode) o;
      				networkLayer.addGeometry(n);

      				boolean potential_terminus = false;

      				// check all roads out of the nodes
      				for(Object ed: roads.getEdgesOut(n)){

      					// set it as being (initially, at least) "open"
      					ListEdge edge = (ListEdge) ed;
      					((MasonGeometry)edge.info).addStringAttribute("open", "OPEN");
      					networkEdgeLayer.addGeometry( (MasonGeometry) edge.info);
      					roadLayer.addGeometry((MasonGeometry) edge.info);
      					((MasonGeometry)edge.info).addAttribute("ListEdge", edge);

      					String type = ((MasonGeometry)edge.info).getStringAttribute("highway");
      					if(type.equals("motorway") || type.equals("primary") || type.equals("trunk"))
      						potential_terminus = true;
      				}

      				// check to see if it's a terminus
      				if(potential_terminus && !MBR.contains(n.geometry.getCoordinate()) && roads.getEdges(n, null).size() == 1){
      					terminus_points.add(n);
      				}

      			}
      */
      // reset MBRS in case it got messed up during all the manipulation
      roadLayer.setMBR(MBR);
      networkLayer.setMBR(MBR);
      networkEdgeLayer.setMBR(MBR);
      waterwayLayer.setMBR(MBR);
      baseLayer.setMBR(MBR);
      medicalLayer.setMBR(MBR);
      humanLayer.setMBR(MBR);
      homesLayer.setMBR(MBR);
      diseasesLayer.setMBR(MBR);

      System.out.println("done");

      /////////////////////
      ///////// Clean up roads for Agents to use ///////////
      /////////////////////

      /*	Network majorRoads = extractMajorRoads();
      		testNetworkForIssues(majorRoads);

      		// assemble list of secondary versus local roads
      		ArrayList <Edge> myEdges = new ArrayList <Edge> ();
      		GeomVectorField secondaryRoadsLayer = new GeomVectorField(grid_width, grid_height);
      		GeomVectorField localRoadsLayer = new GeomVectorField(grid_width, grid_height);
      		for(Object o: majorRoads.allNodes){

      			majorRoadNodesLayer.addGeometry((GeoNode)o);

      			for(Object e: roads.getEdges(o, null)){
      				Edge ed = (Edge) e;

      				myEdges.add(ed);

      				String type = ((MasonGeometry)ed.getInfo()).getStringAttribute("highway");
      				if(type.equals("secondary"))
      						secondaryRoadsLayer.addGeometry((MasonGeometry) ed.getInfo());
      				else if(type.equals("local"))
      						localRoadsLayer.addGeometry((MasonGeometry) ed.getInfo());
      			}
      		}

      */ System.gc();

      //////////////////////////////////////////////
      ////////////////// AGENTS ///////////////////
      //////////////////////////////////////////////

      // set up the agents in the simulation
      setupAgents(populationLayer);
      humanLayer.setMBR(MBR);
      homesLayer.setMBR(MBR);

      /*			// for each of the Agents, set up relevant, environment-specific information
      			int aindex = 0;
      			for(Human a: humans){

      				if(a.familiarRoadNetwork == null){

      					// the Human knows about major roads
      					Network familiar = majorRoads.cloneGraph();

      					// connect the major network to the Human's location
      					connectToMajorNetwork(a.getNode(), familiar);

      					a.familiarRoadNetwork = familiar;

      					// add local roads into the network
      					for(Object o: humanLayer.getObjectsWithinDistance(a, 50)){
      						Human b = (Human) o;
      						if(b == a || b.familiarRoadNetwork != null || b.getNode() != a.getNode()) continue;
      						b.familiarRoadNetwork = familiar.cloneGraph();
      					}

      				}

      				// connect the Human's work into its personal network
      				if(a.getWork() != null)
      					connectToMajorNetwork(getClosestGeoNode(a.getWork()), a.familiarRoadNetwork);

      				// set up its basic paths (fast and quicker and recomputing each time)
      				a.setupPaths();

      				if(aindex % 100 == 0){ // print report of progress
      					System.out.println("..." + aindex + " of " + humans.size());
      				}
      				aindex++;
      			}
      */
      //			Disease d = new Disease();
      Cholera d = new Cholera();
      HumanTeleporter h = humans.get(random.nextInt(humans.size()));
      h.acquireDisease(d);

      // seed the simulation randomly
      //			seedRandom(System.currentTimeMillis());

      // schedule the reporter to run
      //			setupReporter();

    } catch (Exception e) {
      e.printStackTrace();
    }
  }
Example #8
0
 /**
  * Returns a geometric object that represents the Point set union of two geometries.
  *
  * @param node1 xml element containing gml object(s)
  * @param node2 xml element containing gml object(s)
  * @return union geometry as a gml element
  * @throws QueryException query exception
  */
 @Deterministic
 public ANode union(final ANode node1, final ANode node2) throws QueryException {
   final Geometry geo1 = checkGeo(node1);
   final Geometry geo2 = checkGeo(node2);
   return gmlWriter(geo1.union(geo2));
 }
  protected final Geometry calcBoundary(final Set<Geometry> geoms) {
    Geometry geom = null;

    Geometry bounds = null;
    float minLat = Float.POSITIVE_INFINITY;
    float maxLat = Float.NEGATIVE_INFINITY;
    float minLon = Float.POSITIVE_INFINITY;
    float maxLon = Float.NEGATIVE_INFINITY;
    boolean emptySet = false;

    for (final Geometry g : geoms) {
      if (g != null) {
        // A Geometry with no dimensions has to be handled
        if (g.getBoundary().isEmpty()) {
          final Coordinate[] cs = g.getCoordinates();
          for (final Coordinate c : cs) {
            minLat = Math.min(minLat, (float) c.x);
            maxLat = Math.max(maxLat, (float) c.x);
            minLon = Math.min(minLon, (float) c.y);
            maxLon = Math.max(maxLon, (float) c.y);
            emptySet = true;
          }
        } else {
          if (bounds != null) {
            bounds = g.union(bounds);
          } else {
            bounds = g;
          }
        }
      }
    }

    if (emptySet) {
      if (minLat == Float.POSITIVE_INFINITY
          || maxLat == Float.NEGATIVE_INFINITY
          || minLon == Float.POSITIVE_INFINITY
          || maxLon == Float.NEGATIVE_INFINITY) {
        log.error("Warning: empty bounds to calculate were not valid, ignoring");
      } else {
        try {
          final Geometry empty =
              new WKTReader()
                  .read(
                      "POLYGON (("
                          + minLat
                          + " "
                          + minLon
                          + ", "
                          + minLat
                          + " "
                          + maxLon
                          + ", "
                          + maxLat
                          + " "
                          + maxLon
                          + ", "
                          + maxLat
                          + " "
                          + minLon
                          + ", "
                          + minLat
                          + " "
                          + minLon
                          + "))");
          log.info("empty=" + empty);
          if (bounds != null) {
            bounds = empty.union(bounds);
          } else {
            bounds = empty;
          }
        } catch (final Throwable e) {
          log.error(e.toString());
        }
      }
    }

    if (bounds != null) {
      geom = bounds.getBoundary();
    } else {
      geom = null;
    }

    return geom;
  }
Example #10
0
 /**
  * Forms create edges between two shapes maintaining convexity.
  *
  * <p>Does not currently work if the shapes intersect
  *
  * @param shape1
  * @param shape2
  * @return
  */
 public Geometry connect(final Geometry shape1, final Geometry shape2) {
   if (shape1.intersects(shape2)) return shape1.union(shape2);
   return connect(shape1, shape2, getClosestPoints(shape1, shape2, distanceFnForCoordinate));
 }
  /**
   * Execute an aggregation step. Aggregates all feature from iterator into a single output record.
   *
   * @param trace
   * @param dataStore
   * @param outputObjects output objects descriptors
   * @param total total input objects
   * @param errors current errors count
   * @param startErrors initial error values (errors can sum up in various phases)
   * @param outputName main output table name
   * @param id main output table id value
   * @param idTematico original object id value
   * @param iterator list of objects to aggregate
   * @param aggregateGeo optional alternative aggregate geo (for grid cells)
   * @param computeOnlyGeoFeature write only main output table
   * @return
   * @throws IOException
   */
  private int aggregateStep(
      int trace,
      DataStore dataStore,
      OutputObject[] outputObjects,
      int total,
      int errors,
      int startErrors,
      String outputName,
      int id,
      int idTematico,
      FeatureIterator<SimpleFeature> iterator,
      Geometry aggregateGeo,
      boolean computeOnlyGeoFeature,
      boolean dontComputeVehicle)
      throws IOException {

    SimpleFeature inputFeature;
    Geometry geo = null;
    int lunghezza = 0;
    int incidenti = 0;
    int corsie = 0;
    int[] tgm = new int[] {0, 0};
    int[] velocita = new int[] {0, 0};
    double[] cff = new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    double[] padr = new double[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    ElementsCounter flgTgmCounter = new ElementsCounter();
    ElementsCounter flgVelocCounter = new ElementsCounter();
    ElementsCounter flgCorsieCounter = new ElementsCounter();
    ElementsCounter flgIncidentiCounter = new ElementsCounter();
    Set<Integer> pterr = new HashSet<Integer>();
    int idOrigin = -1;
    while ((inputFeature = readInput(iterator)) != null) {
      try {
        if (aggregateGeo == null) {
          if (geo == null) {
            geo = (Geometry) inputFeature.getDefaultGeometry();
          } else if (inputFeature.getDefaultGeometry() != null) {
            geo = geo.union((Geometry) inputFeature.getDefaultGeometry());
          }
        } else {
          geo = aggregateGeo;
        }
        idOrigin =
            (idOrigin == -1)
                ? ((Number) getMapping(inputFeature, attributeMappings, "id_origine")).intValue()
                : idOrigin;

        Number currentLunghezza = (Number) getMapping(inputFeature, attributeMappings, "lunghezza");
        if (currentLunghezza != null) {
          lunghezza += currentLunghezza.intValue();
        }
        Number currentIncidenti =
            (Number) getMapping(inputFeature, attributeMappings, "nr_incidenti");
        if (currentIncidenti != null) {
          incidenti += Math.max(0, currentIncidenti.intValue());
        }
        Number currentCorsie = (Number) getMapping(inputFeature, attributeMappings, "nr_corsie");
        if (currentCorsie != null && currentLunghezza != null) {
          corsie += currentCorsie.intValue() * currentLunghezza.intValue();
        }

        String currentFlgCorsie =
            (String) getMapping(inputFeature, attributeMappings, "flg_nr_corsie");

        String currentFlgIncidenti =
            (String) getMapping(inputFeature, attributeMappings, "flg_nr_incidenti");
        flgCorsieCounter.addElement(currentFlgCorsie);
        flgIncidentiCounter.addElement(currentFlgIncidenti);
        if (!dontComputeVehicle) {
          // by vehicle
          int[] tgms = extractMultipleValues(inputFeature, "TGM");
          int[] velocitas = extractMultipleValues(inputFeature, "VELOCITA");
          for (int i = 0; i < tgms.length; i++) {
            if (currentLunghezza != null) {
              tgm[i] += tgms[i] * currentLunghezza.intValue();
              velocita[i] += velocitas[i] * currentLunghezza.intValue();
            }
          }
          String currentFlgTGM =
              (String) getMapping(inputFeature, attributeMappings, "flg_densita_veicolare");

          String currentFlgVeloc =
              (String) getMapping(inputFeature, attributeMappings, "flg_velocita");
          flgTgmCounter.addElement(currentFlgTGM);
          flgVelocCounter.addElement(currentFlgVeloc);
        }

        if (!computeOnlyGeoFeature) {
          // dissesto
          String[] pterrs =
              inputFeature.getAttribute("PTERR") == null
                  ? new String[0]
                  : inputFeature.getAttribute("PTERR").toString().split("\\|");
          for (int j = 0; j < pterrs.length; j++) {
            try {
              int dissesto = Integer.parseInt(pterrs[j]);
              pterr.add(dissesto);
            } catch (NumberFormatException e) {

            }
          }

          // cff
          double[] cffs = extractMultipleValuesDouble(inputFeature, "CFF", cff.length);
          for (int i = 0; i < cff.length; i++) {
            cff[i] += cffs[i] * currentLunghezza.intValue();
          }
          // padr
          double[] padrs = extractMultipleValuesDouble(inputFeature, "PADR", padr.length);
          for (int i = 0; i < padrs.length; i++) {
            padr[i] += padrs[i] * currentLunghezza.intValue();
          }
        }

      } catch (Exception e) {
        LOGGER.error(e.getMessage(), e);
        errors++;
        metadataHandler.logError(
            trace, errors, "Error writing output feature", getError(e), idTematico);
      }
    }
    if (lunghezza <= 0 && geo != null) {
      lunghezza = (int) geo.getLength();
    }
    if (geo != null) {
      Transaction rowTransaction = new DefaultTransaction();
      setTransaction(outputObjects, rowTransaction);

      try {
        addAggregateGeoFeature(
            outputObjects[4],
            id,
            idTematico,
            geo,
            lunghezza,
            corsie,
            incidenti,
            inputFeature,
            idOrigin,
            flgCorsieCounter.getMax(),
            flgIncidentiCounter.getMax());
        if (!dontComputeVehicle) {
          addAggregateVehicleFeature(
              outputObjects[0],
              id,
              lunghezza,
              tgm,
              velocita,
              flgTgmCounter.getMax(),
              flgVelocCounter.getMax(),
              inputFeature);
        }

        if (!computeOnlyGeoFeature) {
          addAggregateDissestoFeature(outputObjects[1], id, lunghezza, pterr, inputFeature);
          addAggregateCFFFeature(outputObjects[2], id, lunghezza, cff, inputFeature);
          addAggregatePADRFeature(outputObjects[3], id, lunghezza, padr, inputFeature);
        }
        rowTransaction.commit();

        updateImportProgress(total, errors - startErrors, "Importing data in " + outputName);
      } catch (Exception e) {
        LOGGER.error(e.getMessage(), e);
        errors++;
        rowTransaction.rollback();
        metadataHandler.logError(
            trace, errors, "Error writing output feature", getError(e), idTematico);
      } finally {
        rowTransaction.close();
      }
    }
    return errors;
  }