/** * Quick method for populating the {@link CUDABean} instance provided. * * @param bean * @param reference * @param coverage * @param geo * @param transform * @throws IOException * @throws MismatchedDimensionException * @throws TransformException */ private void populateBean( CUDABean bean, boolean reference, GridCoverage2D coverage, Geometry geo, MathTransform transform, int buffer) throws IOException, MismatchedDimensionException, TransformException { RenderedImage image = coverage.getRenderedImage(); // 0) Check if a buffer must be applied Geometry originalGeo = (Geometry) geo.clone(); if (buffer > 0) { try { if (!"EPSG:4326" .equals(CRS.lookupIdentifier(coverage.getCoordinateReferenceSystem(), false))) { geo = geo.buffer(buffer); } else { geo = geo.buffer(buffer / 111.128); } } catch (FactoryException e) { geo = geo.buffer(buffer); } } // 1) Crop the two coverages with the selected Geometry GridCoverage2D crop = CROP.execute(coverage, geo, null); transform = ProjectiveTransform.create( (AffineTransform) crop.getGridGeometry().getGridToCRS(PixelInCell.CELL_CORNER)) .inverse(); // 2) Extract the BufferedImage from each image image = crop.getRenderedImage(); Rectangle rectIMG = new Rectangle(image.getMinX(), image.getMinY(), image.getWidth(), image.getHeight()); ImageWorker w = new ImageWorker(image); BufferedImage buf = w.getBufferedImage(); if (image instanceof RenderedOp) { ((RenderedOp) image).dispose(); } // 3) Generate an array of data from each image Raster data = buf.getData(); final DataBufferByte db = (DataBufferByte) data.getDataBuffer(); byte[] byteData = db.getData(); if (reference) { // 4) Transform the Geometry to Raster space Geometry rs = JTS.transform(geo, transform); Geometry rsFilter = JTS.transform(geo.difference(originalGeo), transform); ROI roiGeo = new ROIGeometry(rs); ROI roiFilter = new ROIGeometry(rsFilter); // 5) Extract an array of data from the transformed ROI byte[] roiData = getROIData((buffer > 0 ? roiFilter : roiGeo), rectIMG); bean.setRoi(roiData); bean.setRoiObj(roiGeo); // 6) Setting the Coverage data array bean.setReferenceImage(byteData); // 7) Setting the Image dimensions bean.setHeight(rectIMG.height); bean.setWidth(rectIMG.width); bean.setMinX(rectIMG.x); bean.setMinY(rectIMG.y); } else { // 6) Setting the Coverage data array bean.setCurrentImage(byteData); } // 7) Store the Reference Covergae containing the geospatial info bean.setReferenceCoverage(coverage); }
@DescribeResult( name = "UrbanGridCUDAProcess", description = "Urban Grid indexes calculated using CUDA", type = List.class) public List<StatisticContainer> execute( @DescribeParameter(name = "reference", description = "Name of the reference raster") GridCoverage2D referenceCoverage, @DescribeParameter(name = "now", description = "Name of the new raster") GridCoverage2D nowCoverage, @DescribeParameter(name = "index", min = 1, description = "Index to calculate") int index, @DescribeParameter( name = "subindex", min = 0, description = "String indicating which sub-index must be calculated") String subId, @DescribeParameter(name = "pixelarea", min = 0, description = "Pixel Area") Double pixelArea, @DescribeParameter(name = "rois", min = 1, description = "Administrative Areas") List<Geometry> rois, @DescribeParameter(name = "populations", min = 0, description = "Populations for each Area") List<List<Integer>> populations, @DescribeParameter( name = "coefficient", min = 0, description = "Multiplier coefficient for index 10") Double coeff, @DescribeParameter(name = "rural", min = 0, description = "Rural or Urban index") boolean rural, @DescribeParameter(name = "radius", min = 0, description = "Radius in meters") int radius) throws IOException { // Check on the index 7 boolean nullSubId = subId == null || subId.isEmpty(); boolean subIndexA = !nullSubId && subId.equalsIgnoreCase("a"); boolean subIndexC = !nullSubId && subId.equalsIgnoreCase("c"); boolean subIndexB = !nullSubId && subId.equalsIgnoreCase("b"); if (index == SEVENTH_INDEX && (nullSubId || !(subIndexA || subIndexB || subIndexC))) { throw new IllegalArgumentException("Wrong subindex for index 7"); } // Check if almost one coverage is present if (referenceCoverage == null && nowCoverage == null) { throw new IllegalArgumentException("No input Coverage provided"); } double areaPx; if (pixelArea == null) { areaPx = PIXEL_AREA; } else { areaPx = pixelArea; } // Check if Geometry area or perimeter must be calculated boolean inRasterSpace = true; // Selection of the operation to do for each index switch (index) { case FIFTH_INDEX: case SIXTH_INDEX: case SEVENTH_INDEX: case ELEVENTH_INDEX: case TWELVE_INDEX: if (!subIndexA) { inRasterSpace = false; } break; default: break; } // If the index is 7a-8-9-10 then the input Geometries must be transformed to the Model Space List<Geometry> geoms = new ArrayList<Geometry>(); final AffineTransform gridToWorldCorner = (AffineTransform) ((GridGeometry2D) referenceCoverage.getGridGeometry()) .getGridToCRS2D(PixelOrientation.UPPER_LEFT); if (inRasterSpace) { for (Geometry geo : rois) { try { geoms.add(JTS.transform(geo, ProjectiveTransform.create(gridToWorldCorner))); } catch (MismatchedDimensionException e) { LOGGER.log(Level.SEVERE, e.getMessage(), e); throw new ProcessException(e); } catch (TransformException e) { LOGGER.log(Level.SEVERE, e.getMessage(), e); throw new ProcessException(e); } } } else { geoms.addAll(rois); } // Check if the Geometries must be reprojected /* Object userData = geoms.get(0).getUserData(); if (!inRasterSpace && userData instanceof CoordinateReferenceSystem) { CoordinateReferenceSystem geomCRS = (CoordinateReferenceSystem) userData; CoordinateReferenceSystem refCRS = referenceCoverage.getCoordinateReferenceSystem(); MathTransform tr = null; try { tr = CRS.findMathTransform(geomCRS, refCRS); if (!(tr == null || tr.isIdentity())) { int geosize = geoms.size(); for (int i = 0; i < geosize; i++) { Geometry geo = geoms.get(i); Geometry transform = JTS.transform(geo, tr); transform.setUserData(refCRS); geoms.set(i, transform); } } } catch (Exception e) { LOGGER.log(Level.SEVERE, e.getMessage(), e); throw new ProcessException(e); } // Otherwise only set the correct User_Data parameter } else if (inRasterSpace){ */ int geosize = geoms.size(); final CoordinateReferenceSystem refCrs = referenceCoverage.getCoordinateReferenceSystem(); for (int i = 0; i < geosize; i++) { Geometry geo = geoms.get(i); geo.setUserData(refCrs); if (geo.getSRID() == 0) { try { geo.setSRID(CRS.lookupEpsgCode(refCrs, true)); } catch (FactoryException e) { LOGGER.log(Level.WARNING, e.getMessage(), e); } } } // } // Empty arrays containing the statistics results double[] statsRef = null; double[] statsNow = null; double[][][] statsComplex = null; // Create a new List of CUDA Bean objects List<CUDABean> beans = new ArrayList<CUDABean>(); // Loop around all the Geometries and generate a new CUDA Bean object try { // MathTransform transform = ProjectiveTransform.create(gridToWorldCorner).inverse(); int counter = 0; int buffer = (index == 12 ? radius : 0); for (Geometry geo : geoms) { // Create the CUDABean object CUDABean bean = new CUDABean(); bean.setAreaPix(areaPx); // Populate it with Reference coverage parameters populateBean(bean, true, referenceCoverage, geo, null, buffer); // Set the population values if needed if (populations != null) { Integer popRef = populations.get(0).get(counter); bean.setPopRef(popRef); } // Do the same for the Current Coverage if present if (nowCoverage != null) { populateBean(bean, false, nowCoverage, geo, null, buffer); // Set the population values if needed if (populations != null) { Integer popCur = populations.get(1).get(counter); bean.setPopCur(popCur); } } // Add the bean to the list beans.add(bean); // Update counter counter++; } } catch (Exception e) { LOGGER.log(Level.SEVERE, e.getMessage(), e); throw new ProcessException(e); } // Calculate the index using CUDA // System.out.println( // java.text.DateFormat.getDateTimeInstance().format(Calendar.getInstance().getTime()) ); // long startTime = System.currentTimeMillis(); /** * Generalize: > isUrban = false/true ------------------------| > RADIUS [meters] = scalar * ---------------------------------| */ Object output = null; try { output = calculateCUDAIndex(index, subId, beans, rural, radius); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } // long estimatedTime = System.currentTimeMillis() - startTime; // System.out.println("Elapsed time calculateCUDAIndex()\t--> " + estimatedTime + " [ms]"); Rectangle refRect = PlanarImage.wrapRenderedImage(referenceCoverage.getRenderedImage()).getBounds(); // For index 8 calculate the final Image if (index == 8 || index == 9 || index == 12) { System.out.println("rural=" + rural + " -- radius/buffer=" + radius + " [m]"); List<StatisticContainer> results = new ArrayList<CLCProcess.StatisticContainer>(); StatisticContainer stats = new StatisticContainer(); double[][][] images = (double[][][]) output; int numGeo = beans.size(); // Images to mosaic RenderedImage[] refImgs = new RenderedImage[numGeo]; ROI[] roiObjs = new ROI[numGeo]; // Giuliano tested for 91 municipalities in NAPLES and it FAILED within the following FOR // loop!! for (int i = 0; i < numGeo; i++) { double[][] refData = images[i]; CUDABean bean = beans.get(i); double[] data = refData[0]; if (data != null) { Rectangle rect = new Rectangle(bean.getMinX(), bean.getMinY(), bean.getWidth(), bean.getHeight()); refImgs[i] = createImage(rect, data); roiObjs[i] = bean.getRoiObj(); } } ImageLayout layout = new ImageLayout2(); layout.setMinX(refRect.x); layout.setMinY(refRect.y); layout.setWidth(refRect.width); layout.setHeight(refRect.height); RenderingHints hints = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout); // Mosaic of the images double[] background = (index == 8 || index == 12 ? new double[] {-1.0} : new double[] {0.0}); RenderedImage finalRef = MosaicDescriptor.create( refImgs, MosaicDescriptor.MOSAIC_TYPE_OVERLAY, null, roiObjs, null, background, hints); // RenderedImageBrowser.showChain(finalRef, false, false); // Upgrade of the statistics container stats.setReferenceImage(finalRef); // Check if the same calculations must be done for the Current coverage if (nowCoverage != null && index != 9) { RenderedImage[] currImgs = new RenderedImage[numGeo]; RenderedImage[] diffImgs = new RenderedImage[numGeo]; for (int i = 0; i < numGeo; i++) { CUDABean bean = beans.get(i); double[] data = images[i][1]; double[] diff = images[i][2]; Rectangle rect = new Rectangle(bean.getMinX(), bean.getMinY(), bean.getWidth(), bean.getHeight()); currImgs[i] = createImage(rect, data); diffImgs[i] = createImage(rect, diff); } // Mosaic of the images RenderedImage finalCurr = MosaicDescriptor.create( currImgs, MosaicDescriptor.MOSAIC_TYPE_OVERLAY, null, roiObjs, null, background, hints); // Mosaic of the images RenderedImage finalDiff = MosaicDescriptor.create( diffImgs, MosaicDescriptor.MOSAIC_TYPE_OVERLAY, null, roiObjs, null, background, hints); // Update the statistics container stats.setNowImage(finalCurr); stats.setDiffImage(finalDiff); } results.add(stats); return results; } /*else if (index == 9) {// LAND TAKE double[][][] values = (double[][][]) output; statsRef = values[0][0]; statsNow = values[0].length > 1 ? values[0][1] : null; }*/ else if (index == 11) { // MODEL OF URBAN DEVELOPMENT statsComplex = (double[][][]) output; } else { double[][][] values = (double[][][]) output; statsRef = new double[values.length]; statsNow = (values[0][0].length > 1 ? new double[values.length] : null); for (int v = 0; v < values.length; v++) { statsRef[v] = values[v][0][0]; if (values[v][0].length > 1) { statsNow[v] = values[v][0][1]; } } } // Result accumulation List<StatisticContainer> results = accumulateResults(rois, statsRef, statsNow, statsComplex); return results; }