/** * Transform geometry * * @param geometry Geometry to transform * @param targetSRID TargetEPSG code * @param sourceCRS Source CRS * @param targetCRS Target CRS * @return Transformed geometry * @throws OwsExceptionReport */ private Geometry transform( final Geometry geometry, final int targetSRID, final CoordinateReferenceSystem sourceCRS, final CoordinateReferenceSystem targetCRS) throws OwsExceptionReport { if (sourceCRS.equals(targetCRS)) { return geometry; } Geometry switchedCoordiantes = switchCoordinateAxisIfNeeded(geometry, targetSRID); try { MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS); Geometry transformed = JTS.transform(switchedCoordiantes, transform); transformed.setSRID(targetSRID); return transformed; } catch (FactoryException fe) { throw new NoApplicableCodeException() .causedBy(fe) .withMessage("The EPSG code '%s' is not supported!", switchedCoordiantes.getSRID()); } catch (MismatchedDimensionException mde) { throw new NoApplicableCodeException() .causedBy(mde) .withMessage("The EPSG code '%s' is not supported!", switchedCoordiantes.getSRID()); } catch (TransformException te) { throw new NoApplicableCodeException() .causedBy(te) .withMessage("The EPSG code '%s' is not supported!", switchedCoordiantes.getSRID()); } }
/** * Switch Geometry coordinates if necessary * * @param geom Geometry to switch coordinates * @return Geometry with switched coordinates * @throws OwsExceptionReport If an error occurs */ @Deprecated public Geometry switchCoordinateAxisOrderIfNeeded(final Geometry geom) throws OwsExceptionReport { if (geom != null && isNorthingFirstEpsgCode(geom.getSRID() == 0 ? getStorageEPSG() : geom.getSRID())) { return JTSHelper.switchCoordinateAxisOrder(geom); } else { return geom; } }
private Geometry switchCoordinateAxisIfNeeded(Geometry geometry, int targetSRID) throws OwsExceptionReport { if (geometry != null && !geometry.isEmpty()) { if ((isNorthingFirstEpsgCode(geometry.getSRID()) && isNorthingFirstEpsgCode(targetSRID)) || (isEastingFirstEpsgCode(geometry.getSRID()) && isEastingFirstEpsgCode(targetSRID))) { return geometry; } return JTSHelper.switchCoordinateAxisOrder(geometry); } return geometry; }
/** * Transform geometry to this EPSG code * * @param geometry Geometry to transform * @param targetSRID Target EPSG code * @return Transformed geometry * @throws OwsExceptionReport */ public Geometry transform(final Geometry geometry, final int targetSRID) throws OwsExceptionReport { if (geometry != null && !geometry.isEmpty()) { if (geometry.getSRID() == targetSRID) { return geometry; } CoordinateReferenceSystem sourceCRS = getCRS(geometry.getSRID()); CoordinateReferenceSystem targetCRS = getCRS(targetSRID); return transform(geometry, targetSRID, sourceCRS, targetCRS); } return geometry; }
/** * Convert the raw geometry to the target srid coordinate system. * * @param ctx Command context used to lookup proj4 parameters from table. * @param jtsGeomSrc Geometry to transform. * @param srid Target SRID; must exist in SPATIAL_REF_SYS table. * @return * @throws Exception */ static Geometry transform(CommandContext ctx, Geometry jtsGeomSrc, int srid) throws Exception { String srcParam = lookupProj4Text(ctx, jtsGeomSrc.getSRID()); String tgtParam = lookupProj4Text(ctx, srid); Geometry jtsGeomTgt = transform(jtsGeomSrc, srcParam, tgtParam); return jtsGeomTgt; }
/** * Switch the coordinate axis of geometry from or for datasource * * @param geom Geometry to switch coordinate axis * @return Geometry with switched coordinate axis if needed * @throws OwsExceptionReport If coordinate axis switching fails */ public Geometry switchCoordinateAxisFromToDatasourceIfNeeded(final Geometry geom) throws OwsExceptionReport { if (geom != null && !geom.isEmpty()) { if (isDatasourceNorthingFirst()) { if (!isNorthingFirstEpsgCode(geom.getSRID())) { return JTSHelper.switchCoordinateAxisOrder(geom); } return geom; } else { if (isNorthingFirstEpsgCode(geom.getSRID())) { return JTSHelper.switchCoordinateAxisOrder(geom); } return geom; } } return geom; }
/** decimates JTS geometries. */ public final Geometry decimate(Geometry geom) { GeometryFactory gFac = new GeometryFactory(geom.getPrecisionModel(), geom.getSRID()); if (spanx == -1) return geom; if (geom instanceof MultiPoint) { // TODO check geometry and if its bbox is too small turn it into a 1 // point geom return geom; } if (geom instanceof GeometryCollection) { // TODO check geometry and if its bbox is too small turn it into a // 1-2 point geom // takes a bit of work because the geometry will need to be // recreated. GeometryCollection collection = (GeometryCollection) geom; Geometry[] result = new Geometry[collection.getDimension()]; final int numGeometries = collection.getNumGeometries(); for (int i = 0; i < numGeometries; i++) { result[i] = decimate(collection.getGeometryN(i)); } return gFac.createGeometryCollection(result); } else if (geom instanceof LineString) { LineString line = (LineString) geom; CoordinateSequence seq = (CoordinateSequence) line.getCoordinateSequence(); LiteCoordinateSequence lseq = new LiteCoordinateSequence(seq.toCoordinateArray()); if (decimateOnEnvelope(line, lseq)) { if (lseq.size() >= 2) return gFac.createLineString(lseq); } if (lseq.size() >= 2) return gFac.createLineString(decimate(lseq)); return null; } else if (geom instanceof Polygon) { Polygon line = (Polygon) geom; Coordinate[] exterior = decimate(line.getExteriorRing()).getCoordinates(); forceClosed(exterior); if (exterior.length > 3) { LinearRing ring = gFac.createLinearRing(exterior); final int numRings = line.getNumInteriorRing(); List<LinearRing> rings = new ArrayList<LinearRing>(); for (int i = 0; i < numRings; i++) { Coordinate[] interior = decimate(line.getInteriorRingN(i)).getCoordinates(); forceClosed(interior); if (interior.length > 3) rings.add(gFac.createLinearRing(interior)); } return gFac.createPolygon(ring, rings.toArray(new LinearRing[] {})); } return null; } return geom; }
/** * Transforms the geometry to the storage EPSG code * * @param geometry Geometry to transform * @return Transformed geometry * @throws OwsExceptionReport */ public Geometry transformToStorageEpsg(final Geometry geometry) throws OwsExceptionReport { if (geometry != null && !geometry.isEmpty()) { CoordinateReferenceSystem sourceCRS = getCRS(geometry.getSRID()); int targetSRID; if (sourceCRS.getCoordinateSystem().getDimension() == 3) { targetSRID = getStorage3DEPSG(); } else { targetSRID = getStorageEPSG(); } return transform(geometry, targetSRID, sourceCRS, getCRS(targetSRID)); } return geometry; }
// General helpers private String crsToJsonSpatialReference(Geometry geom) throws IOException { // Get CRS from geometry String wkid = ""; int refsys = geom.getSRID(); if (refsys != 0) { Integer i = new Integer(refsys); wkid = i.toString(); } else { throw new IOException( "The GML geometry that is being transformed to a json polyline does not have a spatial reference (srid)"); } wkid = "\"spatialReference\":{\"wkid\":" + wkid + "}"; return wkid; }
/** * Get the geometry from featureOfInterest object. * * @param feature * @return geometry * @throws OwsExceptionReport */ public Geometry createGeometry(final HasCoordinate coodinates) throws OwsExceptionReport { if (coodinates.isSetLongLat()) { int epsg = getStorageEPSG(); if (coodinates.isSetSrid()) { epsg = coodinates.getSrid(); } final String wktString = GeometryHandler.getInstance() .getWktString(coodinates.getLongitude(), coodinates.getLatitude(), epsg); final Geometry geom = JTSHelper.createGeometryFromWKT(wktString, epsg); if (coodinates.isSetAltitude()) { geom.getCoordinate().z = JavaHelper.asDouble(coodinates.getAltitude()); if (geom.getSRID() == getStorage3DEPSG()) { geom.setSRID(getStorage3DEPSG()); } } return geom; } return null; }
@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; }
private boolean checkSrid(Geometry geom) { final int srid = geom.getSRID(); // SRID is default 0 with jts geometries return (srid != -1) && (srid != 0); }
/** Parse a geometry starting at offset. */ protected void writeGeometry(Geometry geom, ValueSetter dest) { final int dimension; if (geom == null) { throw new NullPointerException(); } else if (geom.isEmpty()) { // don't set any flag bits dimension = 0; } else { dimension = getCoordDim(geom); if (dimension < 2 || dimension > 4) { throw new IllegalArgumentException("Unsupported geometry dimensionality: " + dimension); } } // write endian flag dest.setByte(dest.endian); // write typeword final int plaintype = getWKBType(geom); int typeword = plaintype; if (dimension == 3 || dimension == 4) { typeword |= 0x80000000; } if (dimension == 4) { typeword |= 0x40000000; } final boolean haveSrid = checkSrid(geom); if (haveSrid) { typeword |= 0x20000000; } dest.setInt(typeword); if (haveSrid) { dest.setInt(geom.getSRID()); } switch (plaintype) { case org.postgis.Geometry.POINT: writePoint((Point) geom, dest); break; case org.postgis.Geometry.LINESTRING: writeLineString((LineString) geom, dest); break; case org.postgis.Geometry.POLYGON: writePolygon((Polygon) geom, dest); break; case org.postgis.Geometry.MULTIPOINT: writeMultiPoint((MultiPoint) geom, dest); break; case org.postgis.Geometry.MULTILINESTRING: writeMultiLineString((MultiLineString) geom, dest); break; case org.postgis.Geometry.MULTIPOLYGON: writeMultiPolygon((MultiPolygon) geom, dest); break; case org.postgis.Geometry.GEOMETRYCOLLECTION: writeCollection((GeometryCollection) geom, dest); break; default: throw new IllegalArgumentException("Unknown Geometry Type: " + plaintype); } }
// ~ Methods ------------------------------------------------------------ @Override protected Set<CidsBean> doInBackground() throws Exception { final FlurstueckSchluesselCustomBean currentKey = LagisBroker.getInstance().getCurrentFlurstueckSchluessel(); if (currentKey != null) { Geometry flurstueckGeom = LagisBroker.getInstance().getInstance().getCurrentWFSGeometry(); if (flurstueckGeom != null) { log.info( "Crossover: Geometrie zum bestimmen der Kassenzeichen (vor Transformation): " + flurstueckGeom + ",SRS" + flurstueckGeom.getSRID()); flurstueckGeom = CrsTransformer.transformToGivenCrs(flurstueckGeom, "EPSG:31466"); // Hardcoded FTW log.info( "Crossover: Geometrie zum bestimmen der Kassenzeichen: " + flurstueckGeom + ",SRS" + flurstueckGeom.getSRID()); // final KassenzeichenFacadeRemote verdisServer = // LagisBroker.getInstance().getVerdisServer(); final String query = "SELECT 11, k.id\n" + "FROM kassenzeichen k, geom\n" + "WHERE k.geometrie = geom.id\n" + "AND not isEmpty(geom.geo_field)\n" + "AND intersects(geom.geo_field,st_buffer(st_buffer(geometryfromtext('" + flurstueckGeom.toText() + "',31466), " + LagisBroker.getInstance().getKassenzeichenBuffer() + "), 0))"; if (log.isDebugEnabled()) { log.debug(query); } if (isCancelled()) { return null; } final MetaObject[] result = CidsBroker.getInstance().getMetaObject(query, "VERDIS_GRUNDIS"); final HashSet<CidsBean> kassenzeichen = new HashSet<CidsBean>((result == null) ? 0 : result.length); if (result != null) { for (int i = 0; i < result.length; i++) { kassenzeichen.add(result[i].getBean()); } } // kassenzeichen = // verdisServer.getIntersectingKassenzeichen(flurstueckGeom, // LagisBroker.getInstance().getKassenzeichenBuffer()); if ((kassenzeichen != null) && (kassenzeichen.size() > 0)) { if (log.isDebugEnabled()) { log.debug("Crossover: Anzahl Kassenzeichen: " + kassenzeichen.size()); } } else { log.info("Crossover:Keine geschnittenen Kassenzeichen gefunden."); // ToDo Meldung an // benutzer } return kassenzeichen; } else { // ToDo user message ! lblMessage.setText( "<html>Keine Flurstücksgeometrie vorhanden,<br/>bestimmen der Kasssenzeichen nicht möglich.</html>"); log.warn("Crossover: Keine Geometrie vorhanden zum bestimmen der Kassenzeichen"); } } else { // ToDo user message ! lblMessage.setText( "<html>Bitte wählen Sie ein Flurstück aus,<br/>damit Kassenzeichen bestimmt werden können.</html > "); log.warn("Crossover: Kein Flurstück ausgewählt kann Lagis Kassenzeichen nicht bestimmen"); } return null; }