/** * Extract the coordinate of a FeatureCollection in a HashMap with an ID as a key. * * @param nStaz * @param collection * @throws Exception if a fiel of elevation isn't the same of the collection */ private LinkedHashMap<Integer, Coordinate> getCoordinate( int nStaz, SimpleFeatureCollection collection, String idField) throws Exception { LinkedHashMap<Integer, Coordinate> id2CoordinatesMap = new LinkedHashMap<Integer, Coordinate>(); FeatureIterator<SimpleFeature> iterator = collection.features(); Coordinate coordinate = null; try { while (iterator.hasNext()) { SimpleFeature feature = iterator.next(); int name = ((Number) feature.getAttribute(idField)).intValue(); coordinate = ((Geometry) feature.getDefaultGeometry()).getCentroid().getCoordinate(); double z = 0; if (fPointZ != null) { try { z = ((Number) feature.getAttribute(fPointZ)).doubleValue(); } catch (NullPointerException e) { pm.errorMessage(msg.message("kriging.noPointZ")); throw new Exception(msg.message("kriging.noPointZ")); } } coordinate.z = z; id2CoordinatesMap.put(name, coordinate); } } finally { iterator.close(); } return id2CoordinatesMap; }
@Execute public void process() throws Exception { // verify if the file name is setted otherwise set it to a default value. if (pNetname == null) { if (pMode == 0) { pNetname = Constants.NETWORK_PROJECT_NAME_SHP; } else if (pMode == 1) { pNetname = Constants.NETWORK_CALIBRATION_NAME_SHP; } } checkNull(inFolder, pCode); CoordinateReferenceSystem crs = CRS.decode(pCode); pm.beginTask(msg.message("trentoP.generatefile.project"), -1); pm.worked(1); // if you want to create an empty file if (!doFromold) { ITrentoPType[] values = PipesTrentoP.values(); String file = new File(inFolder, pNetname).getAbsolutePath(); if (pMode == 0) { // project OmsShapefileFeatureWriter.writeEmptyShapefile(file, getProjectFeatureType(crs)); } else if (pMode == 1) { // calibration OmsShapefileFeatureWriter.writeEmptyShapefile(file, getCalibrationFeatureType(crs)); } file = new File(inFolder, pShapeAreeName).getAbsolutePath(); makePolygonShp(values, file, crs, pShapeAreeName); } else if (doFromold) { if (pOldVector == null) { throw new IllegalArgumentException(msg.message("trentoP.generatefile.error.noFeature")); } String file = new File(inFolder, pNetname).getAbsolutePath(); SimpleFeatureCollection calibrationFC = createNewCollection(getCalibrationFeatureType(crs)); OmsShapefileFeatureWriter.writeShapefile(file, calibrationFC); } pm.done(); }
/** Verify the input of the model. */ private void verifyInput() { if (inData == null || inStations == null) { throw new NullPointerException(msg.message("kriging.stationproblem")); } if (pMode < 0 || pMode > 1) { throw new IllegalArgumentException(msg.message("kriging.defaultMode")); } if (defaultVariogramMode != 0 && defaultVariogramMode != 1) { throw new IllegalArgumentException(msg.message("kriging.variogramMode")); } if (defaultVariogramMode == 0) { if (pVariance == 0 || pIntegralscale[0] == 0 || pIntegralscale[1] == 0 || pIntegralscale[2] == 0) { pm.errorMessage(msg.message("kriging.noParam")); pm.errorMessage("varianza " + pVariance); pm.errorMessage("Integral scale x " + pIntegralscale[0]); pm.errorMessage("Integral scale y " + pIntegralscale[1]); pm.errorMessage("Integral scale z " + pIntegralscale[2]); } } if (defaultVariogramMode == 1) { if (pNug == 0 || pS == 0 || pA == 0) { pm.errorMessage(msg.message("kriging.noParam")); pm.errorMessage("Nugget " + pNug); pm.errorMessage("Sill " + pS); pm.errorMessage("Range " + pA); } } if ((pMode == 0) && inInterpolate == null) { throw new ModelsIllegalargumentException(msg.message("kriging.noPoint"), this, pm); } if (pMode == 1 && inInterpolationGrid == null) { throw new ModelsIllegalargumentException( "The gridded interpolation needs a gridgeometry in input.", this, pm); } }
@Description(OMSTRENTOPPROJECTFILESGENERATOR_DESCRIPTION) @Author( name = OMSTRENTOPPROJECTFILESGENERATOR_AUTHORNAMES, contact = OMSTRENTOPPROJECTFILESGENERATOR_AUTHORCONTACTS) @Keywords(OMSTRENTOPPROJECTFILESGENERATOR_KEYWORDS) @Label(OMSTRENTOPPROJECTFILESGENERATOR_LABEL) @Name(OMSTRENTOPPROJECTFILESGENERATOR_NAME) @Status(OMSTRENTOPPROJECTFILESGENERATOR_STATUS) @License(OMSTRENTOPPROJECTFILESGENERATOR_LICENSE) public class OmsTrentoPProjectFilesGenerator extends JGTModel { @Description(OMSTRENTOPPROJECTFILESGENERATOR_inFolder_DESCRIPTION) @In public String inFolder = null; @Description(OMSTRENTOPPROJECTFILESGENERATOR_pMode_DESCRIPTION) @In public int pMode = 0; @Description(OMSTRENTOPPROJECTFILESGENERATOR_doFromold_DESCRIPTION) @In public boolean doFromold = false; @Description(OMSTRENTOPPROJECTFILESGENERATOR_pCode_DESCRIPTION) @UI(JGTConstants.CRS_UI_HINT) @In public String pCode; @Description(OMSTRENTOPPROJECTFILESGENERATOR_pNetname_DESCRIPTION) @In public String pNetname = null; @Description(OMSTRENTOPPROJECTFILESGENERATOR_pOldVector_DESCRIPTION) @In public SimpleFeatureCollection pOldVector = null; @Description(OMSTRENTOPPROJECTFILESGENERATOR_pShapeAreeName_DESCRIPTION) @In public String pShapeAreeName = Constants.AREA_NAME_SHP; /** Message handler. */ private final HortonMessageHandler msg = HortonMessageHandler.getInstance(); @Execute public void process() throws Exception { // verify if the file name is setted otherwise set it to a default value. if (pNetname == null) { if (pMode == 0) { pNetname = Constants.NETWORK_PROJECT_NAME_SHP; } else if (pMode == 1) { pNetname = Constants.NETWORK_CALIBRATION_NAME_SHP; } } checkNull(inFolder, pCode); CoordinateReferenceSystem crs = CRS.decode(pCode); pm.beginTask(msg.message("trentoP.generatefile.project"), -1); pm.worked(1); // if you want to create an empty file if (!doFromold) { ITrentoPType[] values = PipesTrentoP.values(); String file = new File(inFolder, pNetname).getAbsolutePath(); if (pMode == 0) { // project OmsShapefileFeatureWriter.writeEmptyShapefile(file, getProjectFeatureType(crs)); } else if (pMode == 1) { // calibration OmsShapefileFeatureWriter.writeEmptyShapefile(file, getCalibrationFeatureType(crs)); } file = new File(inFolder, pShapeAreeName).getAbsolutePath(); makePolygonShp(values, file, crs, pShapeAreeName); } else if (doFromold) { if (pOldVector == null) { throw new IllegalArgumentException(msg.message("trentoP.generatefile.error.noFeature")); } String file = new File(inFolder, pNetname).getAbsolutePath(); SimpleFeatureCollection calibrationFC = createNewCollection(getCalibrationFeatureType(crs)); OmsShapefileFeatureWriter.writeShapefile(file, calibrationFC); } pm.done(); } private SimpleFeatureCollection createNewCollection(SimpleFeatureType simpleFeatureType) { DefaultFeatureCollection featureCollection = new DefaultFeatureCollection(); SimpleFeatureIterator stationsIter = pOldVector.features(); SimpleFeatureBuilder builder = new SimpleFeatureBuilder(simpleFeatureType); // create the features. try { while (stationsIter.hasNext()) { SimpleFeature networkFeature = stationsIter.next(); try { // add the geometry. builder.add(networkFeature.getDefaultGeometry()); // add the ID. Integer field = ((Integer) networkFeature.getAttribute(TrentoPFeatureType.ID_STR)); if (field == null) { throw new IllegalArgumentException(); } builder.add(field); // add the area. Double value = ((Double) networkFeature.getAttribute(TrentoPFeatureType.DRAIN_AREA_STR)); if (value == null) { throw new IllegalArgumentException(); } builder.add(value); // add the percentage of the area which is dry. value = ((Double) networkFeature.getAttribute(TrentoPFeatureType.PERCENTAGE_OF_DRY_AREA)); builder.add(value); // the pipes elevation is the elevation of the // terrain minus the depth. value = ((Double) networkFeature.getAttribute(TrentoPFeatureType.DEPTH_INITIAL_PIPE_STR)); builder.add(value); // the pipes elevation is the elevation of the // terrain minus the depth. value = ((Double) networkFeature.getAttribute(TrentoPFeatureType.DEPTH_FINAL_PIPE_STR)); builder.add(value); // add the runoff coefficent. value = ((Double) networkFeature.getAttribute(TrentoPFeatureType.RUNOFF_COEFFICIENT_STR)); builder.add(value); // add the average residence time. value = ((Double) networkFeature.getAttribute(TrentoPFeatureType.AVERAGE_RESIDENCE_TIME_STR)); builder.add(value); // add the ks. value = ((Double) networkFeature.getAttribute(TrentoPFeatureType.KS_STR)); builder.add(value); // add the average slope. value = ((Double) networkFeature.getAttribute(TrentoPFeatureType.AVERAGE_SLOPE_STR)); builder.add(value); // add the diameters. value = ((Double) networkFeature.getAttribute(TrentoPFeatureType.DIAMETER_STR)); builder.add(value); // build the feature SimpleFeature feature = builder.buildFeature(null); featureCollection.add(feature); } catch (NullPointerException e) { throw new IllegalArgumentException(); } } } finally { stationsIter.close(); } return featureCollection; } /** * Build the Calibration Type. * * @param crs * @return the type for the calibration shp. */ private SimpleFeatureType getCalibrationFeatureType(CoordinateReferenceSystem crs) { SimpleFeatureTypeBuilder b = new SimpleFeatureTypeBuilder(); ITrentoPType[] values = TrentoPFeatureType.PipesTrentoP.values(); String typeName = values[0].getName(); b.setName(typeName); b.setCRS(crs); b.add("the_geom", LineString.class); // create ID attribute. b.add(values[0].getAttributeName(), values[0].getClazz()); // create drain area attribute. b.add(values[2].getAttributeName(), values[2].getClazz()); // create the percentage area. b.add(values[11].getAttributeName(), values[12].getClazz()); // The upstream elevation of the node. b.add(values[3].getAttributeName(), values[3].getClazz()); // The downstream elevation of the land. b.add(values[4].getAttributeName(), values[4].getClazz()); // runoff coefficent. b.add(values[5].getAttributeName(), values[5].getClazz()); // average residence time. b.add(values[6].getAttributeName(), values[6].getClazz()); // ks b.add(values[7].getAttributeName(), values[7].getClazz()); // average slope b.add(values[10].getAttributeName(), values[10].getClazz()); // diameter to verify b.add(values[19].getAttributeName(), values[11].getClazz()); return b.buildFeatureType(); } /** * Build the Project Type. * * @param crs * @return the type for the calibration shp. */ private SimpleFeatureType getProjectFeatureType(CoordinateReferenceSystem crs) { SimpleFeatureTypeBuilder b = new SimpleFeatureTypeBuilder(); ITrentoPType[] values = TrentoPFeatureType.PipesTrentoP.values(); String typeName = values[0].getName(); b.setName(typeName); b.setCRS(crs); b.add("the_geom", LineString.class); // create ID attribute. b.add(values[0].getAttributeName(), values[0].getClazz()); // create drain area attribute. b.add(values[2].getAttributeName(), values[2].getClazz()); // create the percentage area. b.add(values[11].getAttributeName(), values[12].getClazz()); // The upstream elevation of the land. b.add(values[3].getAttributeName(), values[3].getClazz()); // The downstream elevation of the land. b.add(values[4].getAttributeName(), values[4].getClazz()); // runoff coefficent. b.add(values[5].getAttributeName(), values[5].getClazz()); // average residence time. b.add(values[6].getAttributeName(), values[6].getClazz()); // ks b.add(values[7].getAttributeName(), values[7].getClazz()); // minimum slope. b.add(values[8].getAttributeName(), values[8].getClazz()); // section type b.add(values[9].getAttributeName(), values[9].getClazz()); // average slope of the basin. b.add(values[10].getAttributeName(), values[10].getClazz()); return b.buildFeatureType(); } }
@Description(OMSKRIGING_DESCRIPTION) @Author(name = OMSKRIGING_AUTHORNAMES, contact = OMSKRIGING_AUTHORCONTACTS) @Keywords(OMSKRIGING_KEYWORDS) @Label(OMSKRIGING_LABEL) @Name(OMSKRIGING_NAME) @Status(OMSKRIGING_STATUS) @License(OMSKRIGING_LICENSE) public class OmsKriging extends JGTModel { @Description(OMSKRIGING_inStations_DESCRIPTION) @In public SimpleFeatureCollection inStations = null; @Description(OMSKRIGING_fStationsid_DESCRIPTION) @In public String fStationsid = null; @Description(OMSKRIGING_fStationsZ_DESCRIPTION) @In public String fStationsZ = null; @Description(OMSKRIGING_inData_DESCRIPTION) @In public HashMap<Integer, double[]> inData = null; @Description(OMSKRIGING_inInterpolate_DESCRIPTION) @In public SimpleFeatureCollection inInterpolate = null; @Description(OMSKRIGING_fInterpolateid_DESCRIPTION) @In public String fInterpolateid = null; @Description(OMSKRIGING_fPointZ_DESCRIPTION) @In public String fPointZ = null; /** * Define the calculation mode. It can be 0 or 1. * * <li>When mode == 0, the values to calculate are in a non-regular * grid (the coordinates are stored in a {@link FeatureCollection}, * so parameters inInterpolate and fInterpolateid must be set, and * the calculated values will be in the outData field. * * <li>When mode == 1, the values are in a regular grid (the coordinates * are stored in a {@link GridCoverage2D), so parameter gridToInterpolate * must be set, and the calculated values will be in the outGrid field. */ @Description(OMSKRIGING_pMode_DESCRIPTION) @In public int pMode = 0; /** * The integral scale, used when defaultVariogramMode is 0. Must be a 3-element double array * containing the scaling factor for the x, y and z dimensions in the elements 0, 1 and 2, * respectively. */ @Description(OMSKRIGING_pIntegralscale_DESCRIPTION) @In public double[] pIntegralscale = null; /** Variance of the measure field. Used when defaultVariogramMode is 0. */ @Description(OMSKRIGING_pVariance_DESCRIPTION) @In public double pVariance = 0; /** The logarithm selector, if it's true then the models runs with the log of the data. */ @Description(OMSKRIGING_doLogarithmic_DESCRIPTION) @In public boolean doLogarithmic = false; @Description(OMSKRIGING_inInterpolationGrid_DESCRIPTION) @In public GridGeometry2D inInterpolationGrid = null; public int defaultVariogramMode = 0; @Description(OMSKRIGING_pSemivariogramType_DESCRIPTION) @In public double pSemivariogramType = 0; @Description(OMSKRIGING_doIncludezero_DESCRIPTION) @In public boolean doIncludezero = true; @Description(OMSKRIGING_pA_DESCRIPTION) @In public double pA; @Description(OMSKRIGING_pS_DESCRIPTION) @In public double pS; @Description(OMSKRIGING_pNug_DESCRIPTION) @In public double pNug; @Description(OMSKRIGING_outGrid_DESCRIPTION) @Out public GridCoverage2D outGrid = null; @Description(OMSKRIGING_outData_DESCRIPTION) @Out public HashMap<Integer, double[]> outData = null; /** A tolerance. */ private static final double TOLL = 1.0d * 10E-8; private HortonMessageHandler msg = HortonMessageHandler.getInstance(); private WritableRaster outWR = null; private int cols; private int rows; private double south; private double west; private double xres; private double yres; /** * Executing ordinary kriging. * * <p> * <li>Verify if the parameters are correct. * <li>Calculating the matrix of the covariance (a). * <li>For each point to interpolated, evalutate the know term vector (b) and solve the system (a * x)=b where x is the weight. * * @throws SchemaException */ @Execute public void process() throws Exception { verifyInput(); List<Double> xStationList = new ArrayList<Double>(); List<Double> yStationList = new ArrayList<Double>(); List<Double> zStationList = new ArrayList<Double>(); List<Double> hStationList = new ArrayList<Double>(); /* * counter for the number of station with measured value !=0. */ int n1 = 0; /* * Store the station coordinates and measured data in the array. */ FeatureIterator<SimpleFeature> stationsIter = inStations.features(); try { while (stationsIter.hasNext()) { SimpleFeature feature = stationsIter.next(); Object stationId = feature.getAttribute(fStationsid); int id; if (stationId instanceof Number) { id = ((Number) stationId).intValue(); } else if (stationId instanceof String) { id = (int) Double.parseDouble((String) stationId); } else { throw new ModelsIllegalargumentException( "Unreadable type found for the station id.", this, pm); } double z = 0; if (fStationsZ != null) { try { z = ((Number) feature.getAttribute(fStationsZ)).doubleValue(); } catch (NullPointerException e) { pm.errorMessage(msg.message("kriging.noStationZ")); throw new Exception(msg.message("kriging.noStationZ")); } } Coordinate coordinate = ((Geometry) feature.getDefaultGeometry()).getCentroid().getCoordinate(); double[] h = inData.get(id); if (h == null || isNovalue(h[0])) { /* * skip data for non existing stations, they are allowed. * Also skip novalues. */ continue; } if (defaultVariogramMode == 0) { if (doIncludezero) { if (Math.abs(h[0]) >= 0.0) { // TOLL xStationList.add(coordinate.x); yStationList.add(coordinate.y); zStationList.add(z); hStationList.add(h[0]); n1 = n1 + 1; } } else { if (Math.abs(h[0]) > 0.0) { // TOLL xStationList.add(coordinate.x); yStationList.add(coordinate.y); zStationList.add(z); hStationList.add(h[0]); n1 = n1 + 1; } } } else if (defaultVariogramMode == 1) { if (doIncludezero) { if (Math.abs(h[0]) >= 0.0) { // TOLL xStationList.add(coordinate.x); yStationList.add(coordinate.y); zStationList.add(z); hStationList.add(h[0]); n1 = n1 + 1; } } else { if (Math.abs(h[0]) > 0.0) { // TOLL xStationList.add(coordinate.x); yStationList.add(coordinate.y); zStationList.add(z); hStationList.add(h[0]); n1 = n1 + 1; } } } } } finally { stationsIter.close(); } int nStaz = xStationList.size(); /* * The coordinates of the station points plus in last position a place * for the coordinate of the point to interpolate. */ double[] xStation = new double[nStaz + 1]; double[] yStation = new double[nStaz + 1]; double[] zStation = new double[nStaz + 1]; double[] hStation = new double[nStaz + 1]; boolean areAllEquals = true; if (nStaz != 0) { xStation[0] = xStationList.get(0); yStation[0] = yStationList.get(0); zStation[0] = zStationList.get(0); hStation[0] = hStationList.get(0); double previousValue = hStation[0]; for (int i = 1; i < nStaz; i++) { double xTmp = xStationList.get(i); double yTmp = yStationList.get(i); double zTmp = zStationList.get(i); double hTmp = hStationList.get(i); boolean doubleStation = ModelsEngine.verifyDoubleStation( xStation, yStation, zStation, hStation, xTmp, yTmp, zTmp, hTmp, i, false, pm); if (!doubleStation) { xStation[i] = xTmp; yStation[i] = yTmp; zStation[i] = zTmp; hStation[i] = hTmp; if (areAllEquals && hStation[i] != previousValue) { areAllEquals = false; } previousValue = hStation[i]; } } } LinkedHashMap<Integer, Coordinate> pointsToInterpolateId2Coordinates = null; // vecchio int numPointToInterpolate = getNumPoint(inInterpolate); int numPointToInterpolate = 0; /* * if the isLogarithmic is true then execute the model with log value. */ // vecchio double[] result = new double[numPointToInterpolate]; if (pMode == 0) { pointsToInterpolateId2Coordinates = getCoordinate(numPointToInterpolate, inInterpolate, fInterpolateid); } else if (pMode == 1) { pointsToInterpolateId2Coordinates = getCoordinate(inInterpolationGrid); numPointToInterpolate = pointsToInterpolateId2Coordinates.size(); } else { throw new ModelsIllegalargumentException("The parameter pMode can only be 0 or 1.", this, pm); } Set<Integer> pointsToInterpolateIdSet = pointsToInterpolateId2Coordinates.keySet(); Iterator<Integer> idIterator = pointsToInterpolateIdSet.iterator(); int j = 0; // vecchio int[] idArray = new int[inInterpolate.size()]; int[] idArray = new int[pointsToInterpolateId2Coordinates.size()]; double[] result = new double[pointsToInterpolateId2Coordinates.size()]; if (n1 != 0) { if (doLogarithmic) { for (int i = 0; i < nStaz; i++) { if (hStation[i] > 0.0) { hStation[i] = Math.log(hStation[i]); } } } /* * calculating the covariance matrix. */ double[][] covarianceMatrix = covMatrixCalculating(xStation, yStation, zStation, n1); /* * extract the coordinate of the points where interpolated. */ /* * initialize the solution and its variance vector. */ if (!areAllEquals && n1 > 1) { // pm.beginTask(msg.message("kriging.working"),inInterpolate.size()); while (idIterator.hasNext()) { double sum = 0.; int id = idIterator.next(); idArray[j] = id; Coordinate coordinate = (Coordinate) pointsToInterpolateId2Coordinates.get(id); xStation[n1] = coordinate.x; yStation[n1] = coordinate.y; zStation[n1] = coordinate.z; /* * calculating the right hand side of the kriging linear * system. */ double[] knownTerm = knownTermsCalculation(xStation, yStation, zStation, n1); /* * solve the linear system, where the result is the weight. */ ColumnVector knownTermColumn = new ColumnVector(knownTerm); LinearSystem linearSystem = new LinearSystem(covarianceMatrix); ColumnVector solution = linearSystem.solve(knownTermColumn, true); // Matrix a = new Matrix(covarianceMatrix); // Matrix b = new Matrix(knownTerm, knownTerm.length); // Matrix x = a.solve(b); double[] moltiplicativeFactor = solution.copyValues1D(); double h0 = 0.0; for (int k = 0; k < n1; k++) { h0 = h0 + moltiplicativeFactor[k] * hStation[k]; sum = sum + moltiplicativeFactor[k]; } if (doLogarithmic) { h0 = Math.exp(h0); } result[j] = h0; j++; if (Math.abs(sum - 1) >= TOLL) { throw new ModelsRuntimeException( "Error in the coffeicients calculation", this.getClass().getSimpleName()); } } } else if (n1 == 1 || areAllEquals) { double tmp = hStation[0]; int k = 0; pm.message(msg.message("kriging.setequalsvalue")); while (idIterator.hasNext()) { int id = idIterator.next(); result[k] = tmp; idArray[k] = id; k++; } } if (pMode == 0) { storeResult(result, idArray); } else { storeResult(result, pointsToInterpolateId2Coordinates); } } else { pm.errorMessage("No rain for this time step"); j = 0; double[] value = inData.values().iterator().next(); while (idIterator.hasNext()) { int id = idIterator.next(); idArray[j] = id; result[j] = value[0]; j++; } if (pMode == 0) { storeResult(result, idArray); } else { storeResult(result, pointsToInterpolateId2Coordinates); } } } /** Verify the input of the model. */ private void verifyInput() { if (inData == null || inStations == null) { throw new NullPointerException(msg.message("kriging.stationproblem")); } if (pMode < 0 || pMode > 1) { throw new IllegalArgumentException(msg.message("kriging.defaultMode")); } if (defaultVariogramMode != 0 && defaultVariogramMode != 1) { throw new IllegalArgumentException(msg.message("kriging.variogramMode")); } if (defaultVariogramMode == 0) { if (pVariance == 0 || pIntegralscale[0] == 0 || pIntegralscale[1] == 0 || pIntegralscale[2] == 0) { pm.errorMessage(msg.message("kriging.noParam")); pm.errorMessage("varianza " + pVariance); pm.errorMessage("Integral scale x " + pIntegralscale[0]); pm.errorMessage("Integral scale y " + pIntegralscale[1]); pm.errorMessage("Integral scale z " + pIntegralscale[2]); } } if (defaultVariogramMode == 1) { if (pNug == 0 || pS == 0 || pA == 0) { pm.errorMessage(msg.message("kriging.noParam")); pm.errorMessage("Nugget " + pNug); pm.errorMessage("Sill " + pS); pm.errorMessage("Range " + pA); } } if ((pMode == 0) && inInterpolate == null) { throw new ModelsIllegalargumentException(msg.message("kriging.noPoint"), this, pm); } if (pMode == 1 && inInterpolationGrid == null) { throw new ModelsIllegalargumentException( "The gridded interpolation needs a gridgeometry in input.", this, pm); } } /** * Store the result in a HashMap (if the mode is 0 or 1) * * @param result2 the result of the model * @param id the associated id of the calculating points. * @throws SchemaException * @throws SchemaException */ private void storeResult(double[] result2, int[] id) throws SchemaException { outData = new HashMap<Integer, double[]>(); for (int i = 0; i < result2.length; i++) { outData.put(id[i], new double[] {checkResultValue(result2[i])}); } } private void storeResult( double[] interpolatedValues, HashMap<Integer, Coordinate> interpolatedCoordinatesMap) throws MismatchedDimensionException, Exception { WritableRandomIter outIter = RandomIterFactory.createWritable(outWR, null); Set<Integer> pointsToInterpolateIdSett = interpolatedCoordinatesMap.keySet(); Iterator<Integer> idIterator = pointsToInterpolateIdSett.iterator(); int c = 0; MathTransform transf = inInterpolationGrid.getCRSToGrid2D(); final DirectPosition gridPoint = new DirectPosition2D(); while (idIterator.hasNext()) { int id = idIterator.next(); Coordinate coordinate = (Coordinate) interpolatedCoordinatesMap.get(id); DirectPosition point = new DirectPosition2D( inInterpolationGrid.getCoordinateReferenceSystem(), coordinate.x, coordinate.y); transf.transform(point, gridPoint); double[] gridCoord = gridPoint.getCoordinate(); int x = (int) gridCoord[0]; int y = (int) gridCoord[1]; outIter.setSample(x, y, 0, checkResultValue(interpolatedValues[c])); c++; } RegionMap regionMap = CoverageUtilities.gridGeometry2RegionParamsMap(inInterpolationGrid); outGrid = CoverageUtilities.buildCoverage( "gridded", outWR, regionMap, inInterpolationGrid.getCoordinateReferenceSystem()); } private double checkResultValue(double resultValue) { if (resultValue < 0) { return 0.0; } return resultValue; } private LinkedHashMap<Integer, Coordinate> getCoordinate(GridGeometry2D grid) { LinkedHashMap<Integer, Coordinate> out = new LinkedHashMap<Integer, Coordinate>(); int count = 0; RegionMap regionMap = CoverageUtilities.gridGeometry2RegionParamsMap(grid); cols = regionMap.getCols(); rows = regionMap.getRows(); south = regionMap.getSouth(); west = regionMap.getWest(); xres = regionMap.getXres(); yres = regionMap.getYres(); outWR = CoverageUtilities.createDoubleWritableRaster(cols, rows, null, null, null); double northing = south; double easting = west; for (int i = 0; i < cols; i++) { easting = easting + xres; for (int j = 0; j < rows; j++) { northing = northing + yres; Coordinate coordinate = new Coordinate(); coordinate.x = west + i * xres; coordinate.y = south + j * yres; out.put(count, coordinate); count++; } } return out; } /** * Extract the coordinate of a FeatureCollection in a HashMap with an ID as a key. * * @param nStaz * @param collection * @throws Exception if a fiel of elevation isn't the same of the collection */ private LinkedHashMap<Integer, Coordinate> getCoordinate( int nStaz, SimpleFeatureCollection collection, String idField) throws Exception { LinkedHashMap<Integer, Coordinate> id2CoordinatesMap = new LinkedHashMap<Integer, Coordinate>(); FeatureIterator<SimpleFeature> iterator = collection.features(); Coordinate coordinate = null; try { while (iterator.hasNext()) { SimpleFeature feature = iterator.next(); int name = ((Number) feature.getAttribute(idField)).intValue(); coordinate = ((Geometry) feature.getDefaultGeometry()).getCentroid().getCoordinate(); double z = 0; if (fPointZ != null) { try { z = ((Number) feature.getAttribute(fPointZ)).doubleValue(); } catch (NullPointerException e) { pm.errorMessage(msg.message("kriging.noPointZ")); throw new Exception(msg.message("kriging.noPointZ")); } } coordinate.z = z; id2CoordinatesMap.put(name, coordinate); } } finally { iterator.close(); } return id2CoordinatesMap; } /** * The gaussian variogram * * @param c0 nugget. * @param a range. * @param sill sill. * @param rx x distance. * @param ry y distance. * @param rz z distance. * @return the variogram value */ private double variogram(double c0, double a, double sill, double rx, double ry, double rz) { if (isNovalue(rz)) { rz = 0; } double value = 0; double h2 = Math.sqrt(rx * rx + rz * rz + ry * ry); if (pSemivariogramType == 0) { value = c0 + sill * (1 - Math.exp(-(h2 * h2) / (a * a))); } if (pSemivariogramType == 1) { // primotest semivariogram value = c0 + sill * (1 - Math.exp(-(h2) / (a))); } return value; } /** * @param rx x distance. * @param ry y distance. * @param rz z distance. * @return */ private double variogram(double rx, double ry, double rz) { if (isNovalue(rz)) { rz = 0; } double h2 = (rx / pIntegralscale[0]) * (rx / pIntegralscale[0]) + (ry / pIntegralscale[1]) * (ry / pIntegralscale[1]) + (rz / pIntegralscale[2]) * (rz / pIntegralscale[2]); if (h2 < TOLL) { return pVariance; } else { return pVariance * Math.exp(-Math.sqrt(h2)); } } /** * @param x the x coordinates. * @param y the y coordinates. * @param z the z coordinates. * @param n the number of the stations points. * @return */ private double[][] covMatrixCalculating(double[] x, double[] y, double[] z, int n) { double[][] ap = new double[n + 1][n + 1]; if (defaultVariogramMode == 0) { for (int j = 0; j < n; j++) { for (int i = 0; i <= j; i++) { double rx = x[i] - x[j]; double ry = y[i] - y[j]; double rz = 0; if (pMode == 0) { rz = z[i] - z[j]; } double tmp = variogram(rx, ry, rz); ap[j][i] = tmp; ap[i][j] = tmp; } } } else if (defaultVariogramMode == 1) { for (int j = 0; j < n; j++) { for (int i = 0; i < n; i++) { double rx = x[i] - x[j]; double ry = y[i] - y[j]; double rz = 0; if (pMode == 0) { rz = z[i] - z[j]; } double tmp = variogram(pNug, pA, pS, rx, ry, rz); ap[j][i] = tmp; ap[i][j] = tmp; } } } for (int i = 0; i < n; i++) { ap[i][n] = 1.0; ap[n][i] = 1.0; } ap[n][n] = 0; return ap; } /** * @param x the x coordinates. * @param y the y coordinates. * @param z the z coordinates. * @param n the number of the stations points. * @return */ private double[] knownTermsCalculation(double[] x, double[] y, double[] z, int n) { double[] gamma = new double[n + 1]; if (defaultVariogramMode == 0) { for (int i = 0; i < n; i++) { double rx = x[i] - x[n]; double ry = y[i] - y[n]; double rz = z[i] - z[n]; gamma[i] = variogram(rx, ry, rz); } } else if (defaultVariogramMode == 1) { for (int i = 0; i < n; i++) { double rx = x[i] - x[n]; double ry = y[i] - y[n]; double rz = z[i] - z[n]; gamma[i] = variogram(pNug, pA, pS, rx, ry, rz); } } gamma[n] = 1.0; return gamma; } }
/** * Executing ordinary kriging. * * <p> * <li>Verify if the parameters are correct. * <li>Calculating the matrix of the covariance (a). * <li>For each point to interpolated, evalutate the know term vector (b) and solve the system (a * x)=b where x is the weight. * * @throws SchemaException */ @Execute public void process() throws Exception { verifyInput(); List<Double> xStationList = new ArrayList<Double>(); List<Double> yStationList = new ArrayList<Double>(); List<Double> zStationList = new ArrayList<Double>(); List<Double> hStationList = new ArrayList<Double>(); /* * counter for the number of station with measured value !=0. */ int n1 = 0; /* * Store the station coordinates and measured data in the array. */ FeatureIterator<SimpleFeature> stationsIter = inStations.features(); try { while (stationsIter.hasNext()) { SimpleFeature feature = stationsIter.next(); Object stationId = feature.getAttribute(fStationsid); int id; if (stationId instanceof Number) { id = ((Number) stationId).intValue(); } else if (stationId instanceof String) { id = (int) Double.parseDouble((String) stationId); } else { throw new ModelsIllegalargumentException( "Unreadable type found for the station id.", this, pm); } double z = 0; if (fStationsZ != null) { try { z = ((Number) feature.getAttribute(fStationsZ)).doubleValue(); } catch (NullPointerException e) { pm.errorMessage(msg.message("kriging.noStationZ")); throw new Exception(msg.message("kriging.noStationZ")); } } Coordinate coordinate = ((Geometry) feature.getDefaultGeometry()).getCentroid().getCoordinate(); double[] h = inData.get(id); if (h == null || isNovalue(h[0])) { /* * skip data for non existing stations, they are allowed. * Also skip novalues. */ continue; } if (defaultVariogramMode == 0) { if (doIncludezero) { if (Math.abs(h[0]) >= 0.0) { // TOLL xStationList.add(coordinate.x); yStationList.add(coordinate.y); zStationList.add(z); hStationList.add(h[0]); n1 = n1 + 1; } } else { if (Math.abs(h[0]) > 0.0) { // TOLL xStationList.add(coordinate.x); yStationList.add(coordinate.y); zStationList.add(z); hStationList.add(h[0]); n1 = n1 + 1; } } } else if (defaultVariogramMode == 1) { if (doIncludezero) { if (Math.abs(h[0]) >= 0.0) { // TOLL xStationList.add(coordinate.x); yStationList.add(coordinate.y); zStationList.add(z); hStationList.add(h[0]); n1 = n1 + 1; } } else { if (Math.abs(h[0]) > 0.0) { // TOLL xStationList.add(coordinate.x); yStationList.add(coordinate.y); zStationList.add(z); hStationList.add(h[0]); n1 = n1 + 1; } } } } } finally { stationsIter.close(); } int nStaz = xStationList.size(); /* * The coordinates of the station points plus in last position a place * for the coordinate of the point to interpolate. */ double[] xStation = new double[nStaz + 1]; double[] yStation = new double[nStaz + 1]; double[] zStation = new double[nStaz + 1]; double[] hStation = new double[nStaz + 1]; boolean areAllEquals = true; if (nStaz != 0) { xStation[0] = xStationList.get(0); yStation[0] = yStationList.get(0); zStation[0] = zStationList.get(0); hStation[0] = hStationList.get(0); double previousValue = hStation[0]; for (int i = 1; i < nStaz; i++) { double xTmp = xStationList.get(i); double yTmp = yStationList.get(i); double zTmp = zStationList.get(i); double hTmp = hStationList.get(i); boolean doubleStation = ModelsEngine.verifyDoubleStation( xStation, yStation, zStation, hStation, xTmp, yTmp, zTmp, hTmp, i, false, pm); if (!doubleStation) { xStation[i] = xTmp; yStation[i] = yTmp; zStation[i] = zTmp; hStation[i] = hTmp; if (areAllEquals && hStation[i] != previousValue) { areAllEquals = false; } previousValue = hStation[i]; } } } LinkedHashMap<Integer, Coordinate> pointsToInterpolateId2Coordinates = null; // vecchio int numPointToInterpolate = getNumPoint(inInterpolate); int numPointToInterpolate = 0; /* * if the isLogarithmic is true then execute the model with log value. */ // vecchio double[] result = new double[numPointToInterpolate]; if (pMode == 0) { pointsToInterpolateId2Coordinates = getCoordinate(numPointToInterpolate, inInterpolate, fInterpolateid); } else if (pMode == 1) { pointsToInterpolateId2Coordinates = getCoordinate(inInterpolationGrid); numPointToInterpolate = pointsToInterpolateId2Coordinates.size(); } else { throw new ModelsIllegalargumentException("The parameter pMode can only be 0 or 1.", this, pm); } Set<Integer> pointsToInterpolateIdSet = pointsToInterpolateId2Coordinates.keySet(); Iterator<Integer> idIterator = pointsToInterpolateIdSet.iterator(); int j = 0; // vecchio int[] idArray = new int[inInterpolate.size()]; int[] idArray = new int[pointsToInterpolateId2Coordinates.size()]; double[] result = new double[pointsToInterpolateId2Coordinates.size()]; if (n1 != 0) { if (doLogarithmic) { for (int i = 0; i < nStaz; i++) { if (hStation[i] > 0.0) { hStation[i] = Math.log(hStation[i]); } } } /* * calculating the covariance matrix. */ double[][] covarianceMatrix = covMatrixCalculating(xStation, yStation, zStation, n1); /* * extract the coordinate of the points where interpolated. */ /* * initialize the solution and its variance vector. */ if (!areAllEquals && n1 > 1) { // pm.beginTask(msg.message("kriging.working"),inInterpolate.size()); while (idIterator.hasNext()) { double sum = 0.; int id = idIterator.next(); idArray[j] = id; Coordinate coordinate = (Coordinate) pointsToInterpolateId2Coordinates.get(id); xStation[n1] = coordinate.x; yStation[n1] = coordinate.y; zStation[n1] = coordinate.z; /* * calculating the right hand side of the kriging linear * system. */ double[] knownTerm = knownTermsCalculation(xStation, yStation, zStation, n1); /* * solve the linear system, where the result is the weight. */ ColumnVector knownTermColumn = new ColumnVector(knownTerm); LinearSystem linearSystem = new LinearSystem(covarianceMatrix); ColumnVector solution = linearSystem.solve(knownTermColumn, true); // Matrix a = new Matrix(covarianceMatrix); // Matrix b = new Matrix(knownTerm, knownTerm.length); // Matrix x = a.solve(b); double[] moltiplicativeFactor = solution.copyValues1D(); double h0 = 0.0; for (int k = 0; k < n1; k++) { h0 = h0 + moltiplicativeFactor[k] * hStation[k]; sum = sum + moltiplicativeFactor[k]; } if (doLogarithmic) { h0 = Math.exp(h0); } result[j] = h0; j++; if (Math.abs(sum - 1) >= TOLL) { throw new ModelsRuntimeException( "Error in the coffeicients calculation", this.getClass().getSimpleName()); } } } else if (n1 == 1 || areAllEquals) { double tmp = hStation[0]; int k = 0; pm.message(msg.message("kriging.setequalsvalue")); while (idIterator.hasNext()) { int id = idIterator.next(); result[k] = tmp; idArray[k] = id; k++; } } if (pMode == 0) { storeResult(result, idArray); } else { storeResult(result, pointsToInterpolateId2Coordinates); } } else { pm.errorMessage("No rain for this time step"); j = 0; double[] value = inData.values().iterator().next(); while (idIterator.hasNext()) { int id = idIterator.next(); idArray[j] = id; result[j] = value[0]; j++; } if (pMode == 0) { storeResult(result, idArray); } else { storeResult(result, pointsToInterpolateId2Coordinates); } } }