@Test public void getEnvelope2D() { ReferencedEnvelope refEnv = new ReferencedEnvelope(-10, 10, -5, 5, DefaultGeographicCRS.WGS84); Envelope2D env2D = JTS.getEnvelope2D(refEnv, refEnv.getCoordinateReferenceSystem()); CRS.equalsIgnoreMetadata( refEnv.getCoordinateReferenceSystem(), env2D.getCoordinateReferenceSystem()); assertTrue(env2D.boundsEquals(refEnv, 0, 1, TOL)); }
public void removeFeatures(Filter filter) throws IOException { // this we can optimize, it's a matter of mass updating the last // revisions (and before that, we have to compute the modified envelope) Filter versionedFilter = (Filter) store.buildVersionedFilter(schema.getTypeName(), filter, new RevisionInfo()); // deal with the transaction, are we playing with auto commit or long running? Transaction t = getTransaction(); boolean autoCommit = false; if (Transaction.AUTO_COMMIT.equals(t)) { t = new DefaultTransaction(); autoCommit = true; } VersionedJdbcTransactionState state = store.wrapped.getVersionedJdbcTransactionState(t); // we need to mark the modified bounds and store their wgs84 version into the transaction ReferencedEnvelope bounds = locking.getBounds(new DefaultQuery(schema.getTypeName(), versionedFilter)); if (bounds != null) { if (bounds.getCoordinateReferenceSystem() == null) { bounds = new ReferencedEnvelope(bounds, getSchema().getCoordinateReferenceSystem()); } try { ReferencedEnvelope wgsBounds = null; if (bounds.getCoordinateReferenceSystem() != null) wgsBounds = bounds.transform(DefaultGeographicCRS.WGS84, true); else wgsBounds = bounds; state.expandDirtyBounds(wgsBounds); state.setTypeNameDirty(schema.getTypeName()); } catch (Exception e) { throw new DataSourceException( "Problems computing and storing the " + "bounds affected by this feature removal", e); } } // now we can run the update locking.modifyFeatures( locking.getSchema().getDescriptor("expired"), new Long(state.getRevision()), versionedFilter); // if it's auto commit, don't forget to actually commit if (autoCommit) { t.commit(); t.close(); } store.listenerManager.fireFeaturesRemoved(schema.getTypeName(), t, bounds, false); }
private static ReferencedEnvelope toNativeCrs( final GeneralEnvelope requestedEnvelope, final CoordinateReferenceSystem nativeCRS) throws IllegalArgumentException { ReferencedEnvelope reqEnv = toReferencedEnvelope(requestedEnvelope); if (!CRS.equalsIgnoreMetadata(nativeCRS, reqEnv.getCoordinateReferenceSystem())) { // we're being reprojected. We'll need to reproject reqEnv into // our native coordsys try { // ReferencedEnvelope origReqEnv = reqEnv; reqEnv = reqEnv.transform(nativeCRS, true); } catch (FactoryException fe) { // unable to reproject? throw new IllegalArgumentException( "Unable to find a reprojection from requested " + "coordsys to native coordsys for this request", fe); } catch (TransformException te) { throw new IllegalArgumentException( "Unable to perform reprojection from requested " + "coordsys to native coordsys for this request", te); } } return reqEnv; }
/** * Sets up the affine transform. Stolen from liteRenderer code. * * @param mapExtent the map extent * @param width the screen size * @param height * @return a transform that maps from real world coordinates to the screen */ public static AffineTransform worldToScreenTransform( ReferencedEnvelope mapExtent, double width, double height) { // the transformation depends on an x/y ordering, if we have a lat/lon crs swap it CoordinateReferenceSystem crs = mapExtent.getCoordinateReferenceSystem(); boolean swap = crs != null && CRS.getAxisOrder(crs) == AxisOrder.NORTH_EAST; if (swap) { mapExtent = new ReferencedEnvelope( mapExtent.getMinY(), mapExtent.getMaxY(), mapExtent.getMinX(), mapExtent.getMaxX(), null); } double scaleX = width / mapExtent.getWidth(); double scaleY = height / mapExtent.getHeight(); double tx = -mapExtent.getMinX() * scaleX; double ty = (mapExtent.getMinY() * scaleY) + height; AffineTransform at = new AffineTransform(scaleX, 0.0d, 0.0d, -scaleY, tx, ty); // if we swapped concatenate a transform that swaps back if (swap) { at.concatenate(new AffineTransform(0, 1, 1, 0, 0, 0)); } return at; }
public ProjectionHandler getHandler( ReferencedEnvelope renderingEnvelope, CoordinateReferenceSystem sourceCrs, boolean wrap, int maxWraps) throws FactoryException { MapProjection mapProjection = CRS.getMapProjection(renderingEnvelope.getCoordinateReferenceSystem()); if (renderingEnvelope != null && mapProjection instanceof Mercator) { ProjectionHandler handler; double centralMeridian = mapProjection .getParameterValues() .parameter(AbstractProvider.CENTRAL_MERIDIAN.getName().getCode()) .doubleValue(); if (wrap && maxWraps > 0) { handler = new WrappingProjectionHandler( renderingEnvelope, VALID_AREA, sourceCrs, centralMeridian, maxWraps); } else { handler = new ProjectionHandler(sourceCrs, VALID_AREA, renderingEnvelope); handler.setCentralMeridian(centralMeridian); } return handler; } return null; }
@Override public ReferencedEnvelope getBounds() { ReferencedEnvelope bounds = super.getBounds(); if (bounds.getCoordinateReferenceSystem() == null) return new ReferencedEnvelope(bounds, GeoImportUtil.getDefaultCRS()); else return bounds; }
// private static ReferencedEnvelope calculateOldRequestBoundingBox( // final boolean clientSideReprojection, final Envelope viewportBBox, // final CoordinateReferenceSystem viewportCRS, final List<Layer> wmsLayers, // final boolean[] isFullSizeOut ) throws RenderException { // isFullSizeOut[0] = false; // // Envelope viewportBBox2 = viewportBBox; // if (viewportBBox2 == null) { // viewportBBox2 = new Envelope(-180, 180, -90, 90); // } // // Envelope layersBBox = getLayersBoundingBox(viewportCRS, wmsLayers); // if (layersBBox == null) // try { // return new ReferencedEnvelope(viewportBBox, viewportCRS).transform( // DefaultGeographicCRS.WGS84, true); // } catch (TransformException e1) { // throw (RuntimeException) new RuntimeException(Messages.BasicWMSRenderer2_error) // .initCause(e1); // } catch (FactoryException e1) { // throw (RuntimeException) new RuntimeException(Messages.BasicWMSRenderer2_error) // .initCause(e1); // } // // if (!layersBBox.intersects(viewportBBox2)) // return new ReferencedEnvelope(new Envelope(0, 0, 0, 0), viewportCRS); // // double minx, miny, maxx, maxy; // minx = layersBBox.getMinX(); // maxx = layersBBox.getMaxX(); // miny = layersBBox.getMinY(); // maxy = layersBBox.getMaxY(); // boolean noClipping = false; // // int i = 0; // if (viewportBBox2.getMinX() > minx || noClipping) { // minx = viewportBBox2.getMinX(); // i++; // } // if (viewportBBox2.getMinY() > miny || noClipping) { // miny = viewportBBox2.getMinY(); // i++; // } // if (viewportBBox2.getMaxX() < maxx || noClipping) { // maxx = viewportBBox2.getMaxX(); // i++; // } // if (viewportBBox2.getMaxY() < maxy || noClipping) { // maxy = viewportBBox2.getMaxY(); // i++; // } // // if (i == 4) // isFullSizeOut[0] = true; // // ReferencedEnvelope clippedBBox = new ReferencedEnvelope( // new Envelope(minx, maxx, miny, maxy), viewportCRS); // // if (clientSideReprojection) { // // Convert the clipped bounding box to the request CRS. This is the // // BBox to be used in the request. // try { // String code = findRequestCRS(wmsLayers); // if (code == null) // throw new RenderException( // "Error has occurred in the framework! There is no common CRS in layers in renderer"); // //$NON-NLS-1$ // CoordinateReferenceSystem crs = CRS.decode(code); // // clippedBBox = new ReferencedEnvelope(JTS.transform(clippedBBox, null, CRS // .findMathTransform(viewportCRS, crs, true), 4), crs); // } catch (NoSuchAuthorityCodeException e) { // WMSPlugin.log(e.getLocalizedMessage(), e); // return null; // } catch (FactoryException e) { // WMSPlugin.log(e.getLocalizedMessage(), e); // return null; // } catch (MismatchedDimensionException e) { // WMSPlugin.log(e.getLocalizedMessage(), e); // return null; // } catch (TransformException e) { // e.printStackTrace(); // WMSPlugin.log(e.getLocalizedMessage(), e); // return null; // } // } // // return clippedBBox; // } private static ReferencedEnvelope swapAxis(ReferencedEnvelope envelope) { double min0 = envelope.getLowerCorner().getOrdinate(0); double min1 = envelope.getLowerCorner().getOrdinate(1); double max0 = envelope.getUpperCorner().getOrdinate(0); double max1 = envelope.getUpperCorner().getOrdinate(1); ReferencedEnvelope swap = new ReferencedEnvelope(min1, max1, min0, max0, envelope.getCoordinateReferenceSystem()); return swap; }
@Override public ReferencedEnvelope getBounds() { try { ReferencedEnvelope bounds = featureSource.getBounds(); if (bounds != null) { FeatureType schema = featureSource.getSchema(); CoordinateReferenceSystem schemaCrs = schema.getCoordinateReferenceSystem(); CoordinateReferenceSystem boundsCrs = bounds.getCoordinateReferenceSystem(); if (boundsCrs == null && schemaCrs != null) { LOGGER.warning( "Bounds crs not defined; assuming bounds from schema are correct for " + featureSource); bounds = new ReferencedEnvelope( bounds.getMinX(), bounds.getMaxX(), bounds.getMinY(), bounds.getMaxY(), schemaCrs); } if (boundsCrs != null && schemaCrs != null && !CRS.equalsIgnoreMetadata(boundsCrs, schemaCrs)) { LOGGER.warning( "Bounds crs and schema crs are not consistent; forcing the use of the schema crs so they are consistent"); // bounds = bounds.transform(schemaCrs, true ); bounds = new ReferencedEnvelope( bounds.getMinX(), bounds.getMaxX(), bounds.getMinY(), bounds.getMaxY(), schemaCrs); } return bounds; } } catch (IOException e) { // feature bounds unavailable } CoordinateReferenceSystem crs = featureSource.getSchema().getCoordinateReferenceSystem(); if (crs != null) { // returns the envelope based on the CoordinateReferenceSystem Envelope envelope = CRS.getEnvelope(crs); if (envelope != null) { return new ReferencedEnvelope(envelope); // nice! } else { return new ReferencedEnvelope(crs); // empty bounds } } else { return null; // unknown } }
/** @see org.geotools.data.FeatureSource#getInfo() */ @Override public ResourceInfo getInfo() { DefaultResourceInfo info = new DefaultResourceInfo(); ReferencedEnvelope bounds; try { bounds = getBounds(); if (bounds != null) { info.setBounds(bounds); info.setCRS(bounds.getCoordinateReferenceSystem()); } } catch (IOException e) { Throwables.propagate(e); } info.setName(getName().getLocalPart()); info.setDescription("GeoGit backed Feature Source"); return info; }
@DescribeResult(name = "result", description = "The grid") public SimpleFeatureCollection execute( @DescribeParameter(name = "features", description = "The grid bounds") ReferencedEnvelope bounds, @DescribeParameter( name = "width", description = "Cell width (in the same uom as the bounds referencing system)") double width, @DescribeParameter( name = "height", description = "Cell height (optional, used only for rectangular grids, " + "if not provided it is assumed equals to the width)", min = 0) Double height, @DescribeParameter( name = "vertexSpacing", description = "Distance between vertices (used to create densified " + "sides suitable for reprojection)", min = 0) Double vertexSpacing, @DescribeParameter(name = "mode", description = "The type of grid to be generated", min = 0) GridMode mode) throws ProcessException { final GridFeatureBuilder builder = new GridFeatureBuilderImpl(bounds.getCoordinateReferenceSystem()); double h = height != null ? height : width; SimpleFeatureSource source; if (mode == null || mode == GridMode.Rectangular) { source = Oblongs.createGrid(bounds, width, h, builder); } else if (mode == GridMode.HexagonFlat) { source = Hexagons.createGrid(bounds, width, HexagonOrientation.FLAT, builder); } else { source = Hexagons.createGrid(bounds, width, HexagonOrientation.ANGLED, builder); } try { return source.getFeatures(); } catch (IOException e) { throw new ProcessException("Unexpected exception while grabbing features", e); } }
/* This method is default for testing purposes */ Query createQuery(ExtractorLayerRequest request, FeatureType schema) throws IOException, TransformException, FactoryException { switch (request._owsType) { case WFS: // bbox may not be in the same projection as the data so it sometimes necessary to reproject // the request BBOX ReferencedEnvelope bbox = request._bbox; if (schema.getCoordinateReferenceSystem() != null) { bbox = request._bbox.transform(schema.getCoordinateReferenceSystem(), true, 10); } FilterFactory2 filterFactory = CommonFactoryFinder.getFilterFactory2(GeoTools.getDefaultHints()); String propertyName = schema.getGeometryDescriptor().getLocalName(); PropertyName geomProperty = filterFactory.property(propertyName); Geometry bboxGeom = new GeometryFactory().toGeometry(bbox); String epsgCode = "EPSG:" + CRS.lookupEpsgCode(bbox.getCoordinateReferenceSystem(), false); bboxGeom.setUserData(epsgCode); Literal geometry = filterFactory.literal(bboxGeom); Intersects filter = filterFactory.intersects(geomProperty, geometry); List<String> properties = new ArrayList<String>(); for (PropertyDescriptor desc : schema.getDescriptors()) { if (desc instanceof GeometryDescriptor && desc != schema.getGeometryDescriptor()) { // shapefiles can only have one geometry so skip any // geometry descriptor that is not the default continue; } else { properties.add(desc.getName().getLocalPart()); } } String[] propArray = properties.toArray(new String[properties.size()]); Query query = new Query(request.getWFSName(), filter, propArray); query.setCoordinateSystemReproject(request._projection); return query; default: return null; } }
public PlottableGeoResource(MWC.GUI.Layer theLayer) { _layer = theLayer; _id = CorePlugin.createSafeURL(PlottableServiceExtension.ID + "#" + UUID.randomUUID()); ReferencedEnvelope jtsBounds = JtsAdapter.toEnvelope(theLayer.getBounds()); CoordinateReferenceSystem crs = jtsBounds.getCoordinateReferenceSystem(); info = new IGeoResourceInfo( _layer.getName(), _layer.getName(), _layer.getName(), null, jtsBounds, crs, new String[] {_layer.getName()}, null); service = PlottableService.INSTANCE; }
private void checkTransform() throws TransformException { CoordinateReferenceSystem featuresCRS = featureCollection.getSchema().getCoordinateReferenceSystem(); CoordinateReferenceSystem requestCRS = coverageEnvelope.getCoordinateReferenceSystem(); if (featuresCRS != null && requestCRS != null && !CRS.equalsIgnoreMetadata(requestCRS, featuresCRS)) { try { lineSegmentTransform = new JTSTransform(CRS.findMathTransform(featuresCRS, requestCRS, true)); } catch (Exception ex) { throw new TransformException( "Unable to transform features into output coordinate reference system", ex); } } else { lineSegmentTransform = new PassThroughTransform(); } }
private GridCoverage2D convertImageToGridCoverage( ReferencedEnvelope requestBBox, BufferedImage image) throws RenderException { Envelope env = requestBBox; GeneralEnvelope gtEnv = new GeneralEnvelope( new double[] {env.getMinX(), env.getMinY()}, new double[] {env.getMaxX(), env.getMaxY()}); try { gtEnv.setCoordinateReferenceSystem(requestBBox.getCoordinateReferenceSystem()); } catch (Exception e) { throw wrapException(e); } GridCoverageFactory factory = new GridCoverageFactory(); GridCoverage2D gc = (GridCoverage2D) factory.create("GridCoverage", image, gtEnv); // $NON-NLS-1$ return gc; }
private ReferencedEnvelope calcLayersBounds( Collection<ILayer> layers, CoordinateReferenceSystem crs, IProgressMonitor monitor) throws Exception { log.debug("### mapCRS: " + crs); // $NON-NLS-1$ ReferencedEnvelope result = null; // new ReferencedEnvelope( crs ); for (ILayer layer : layers) { try { IGeoResource res = layer.getGeoResource(); if (res == null) { continue; } ReferencedEnvelope bbox = SetLayerBoundsOperation.obtainBoundsFromResources(layer, crs, monitor); if (!bbox.getCoordinateReferenceSystem().equals(crs)) { bbox = bbox.transform(crs, true); } log.debug("layer: " + layer + ", bbox= " + bbox); // $NON-NLS-1$ //$NON-NLS-2$ if (result == null) { result = bbox; } else { result.expandToInclude(bbox); } log.debug("result: bbox= " + result); // $NON-NLS-1$ } catch (Exception e) { // XXX mark layers!? log.debug("", e); // $NON-NLS-1$ log.warn( "skipping layer: " + layer.getLabel() + " (" + e.toString(), e); //$NON-NLS-1$ //$NON-NLS-2$ layer.setLayerStatus( new LayerStatus( Status.WARNING, LayerStatus.UNSPECIFIED, Messages.get("LayerStatus_noCrs"), e)); //$NON-NLS-1$ } } return result != null ? result : ReferencedEnvelope.EVERYTHING.transform(crs, true); }
/** * It zooms in and out as the user uses the mousewheel. The mouse stays pointing in the same map * coordinates * * @param ev */ private void handleMouseWheelEvent(MouseWheelEvent ev) { if (this.IsRendering()) { return; } double zoomFactor = 0.5; int clicks = ev.getWheelRotation(); // -ve means wheel moved up, +ve means down int sign = (clicks > 0 ? -1 : 1); zoomFactor = sign * zoomFactor / 2; Point2D mouseMapPointPos = this.getPointInMap(ev.getPoint()); ReferencedEnvelope env = this.getDisplayArea(); double width = env.getSpan(0); double height = env.getSpan(1); double newWidth = width - (width * zoomFactor); double newHeight = height - (height * zoomFactor); double centerX = env.getMedian(0); double centerY = env.getMedian(1); double distanceMouseCenterAlongX = mouseMapPointPos.getX() - centerX; double distanceMouseCenterAlongY = mouseMapPointPos.getY() - centerY; centerX += distanceMouseCenterAlongX * zoomFactor; centerY += distanceMouseCenterAlongY * zoomFactor; double newMinX = centerX - newWidth / 2; double newMinY = centerY - newHeight / 2; double newMaxX = centerX + newWidth / 2; double newMaxY = centerY + newHeight / 2; env = new ReferencedEnvelope( newMinX, newMaxX, newMinY, newMaxY, env.getCoordinateReferenceSystem()); this.setDisplayArea(env); // this.refresh(); }
/** * Zooms the map pane image. * * @param action zoom action */ private void zoom(Action action) { ReferencedEnvelope env = mapPane.getDisplayArea(); double zoom; if (!env.isEmpty()) { switch (action) { case ZOOM_FULL_EXTENT: mapPane.reset(); return; case ZOOM_IN: zoom = 1.0 / ZOOM_FRACTION; break; case ZOOM_OUT: zoom = ZOOM_FRACTION; break; default: throw new IllegalArgumentException("invalid action argument: " + action); } double centreX = env.getMedian(0); double centreY = env.getMedian(1); double w = env.getWidth() * zoom; double h = env.getHeight() * zoom; ReferencedEnvelope newEnv = new ReferencedEnvelope( centreX - w / 2, centreX + w / 2, centreY - h / 2, centreY + h / 2, env.getCoordinateReferenceSystem()); mapPane.setDisplayArea(newEnv); } }
private SimpleFeatureCollection createPoints(Coordinate[] pts, ReferencedEnvelope bounds) { SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder(); tb.setName("data"); tb.setCRS(bounds.getCoordinateReferenceSystem()); tb.add("shape", MultiPoint.class); tb.add("value", Double.class); SimpleFeatureType type = tb.buildFeatureType(); SimpleFeatureBuilder fb = new SimpleFeatureBuilder(type); DefaultFeatureCollection fc = new DefaultFeatureCollection(); GeometryFactory factory = new GeometryFactory(new PackedCoordinateSequenceFactory()); for (Coordinate p : pts) { Geometry point = factory.createPoint(p); fb.add(point); fb.add(p.z); fc.add(fb.buildFeature(null)); } return fc; }
/** * Set the bbox for this expression * * @param env The envelope to set as the bounds. * @throws IllegalFilterException If the box can not be created. * @task HACK: currently sets the SRID to null, which can cause problems with JTS when it comes to * doing spatial tests */ public final void setBounds(Envelope env) throws IllegalFilterException { Coordinate[] coords = new Coordinate[5]; coords[0] = new Coordinate(env.getMinX(), env.getMinY()); coords[1] = new Coordinate(env.getMinX(), env.getMaxY()); coords[2] = new Coordinate(env.getMaxX(), env.getMaxY()); coords[3] = new Coordinate(env.getMaxX(), env.getMinY()); coords[4] = new Coordinate(env.getMinX(), env.getMinY()); LinearRing ring = null; try { ring = gfac.createLinearRing(coords); } catch (TopologyException tex) { throw new IllegalFilterException(tex.toString()); } Polygon polygon = gfac.createPolygon(ring, null); if (env instanceof ReferencedEnvelope) { ReferencedEnvelope refEnv = (ReferencedEnvelope) env; polygon.setUserData(refEnv.getCoordinateReferenceSystem()); } super.setValue(polygon); }
/** * Tests point stacking when output CRS is different to data CRS. The result data should be * reprojected. * * @throws NoSuchAuthorityCodeException * @throws FactoryException * @throws TransformException * @throws ProcessException */ @Test public void testReprojected() throws NoSuchAuthorityCodeException, FactoryException, ProcessException, TransformException { ReferencedEnvelope inBounds = new ReferencedEnvelope(0, 10, 0, 10, DefaultGeographicCRS.WGS84); // Dataset with some points located in appropriate area // points are close enough to create a single cluster Coordinate[] data = new Coordinate[] {new Coordinate(-121.813201, 48.777343), new Coordinate(-121.813, 48.777)}; SimpleFeatureCollection fc = createPoints(data, inBounds); ProgressListener monitor = null; // Google Mercator BBOX for northern Washington State (roughly) CoordinateReferenceSystem webMerc = CRS.decode("EPSG:3785"); ReferencedEnvelope outBounds = new ReferencedEnvelope( -1.4045034049133E7, -1.2937920131607E7, 5916835.1504419, 6386464.2521607, webMerc); PointStackerProcess psp = new PointStackerProcess(); SimpleFeatureCollection result = psp.execute( fc, 100, // cellSize null, // normalize null, // preserve location outBounds, // outputBBOX 1810, // outputWidth 768, // outputHeight monitor); checkSchemaCorrect(result.getSchema(), false); assertEquals(1, result.size()); assertEquals( inBounds.getCoordinateReferenceSystem(), result.getBounds().getCoordinateReferenceSystem()); checkResultPoint(result, new Coordinate(-121.813201, 48.777343), 2, 2, null, null); }
public void setCrs(CoordinateReferenceSystem crs) { try { // System.out.println(content.layers().size()); ReferencedEnvelope rEnv = getDisplayArea(); // System.out.println(rEnv); CoordinateReferenceSystem sourceCRS = rEnv.getCoordinateReferenceSystem(); CoordinateReferenceSystem targetCRS = crs; MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS); com.vividsolutions.jts.geom.Envelope newJtsEnv = JTS.transform(rEnv, transform); ReferencedEnvelope newEnvelope = new ReferencedEnvelope(newJtsEnv, targetCRS); content.getViewport().setBounds(newEnvelope); fullExtent = null; doSetDisplayArea(newEnvelope); // ReferencedEnvelope displayArea = getDisplayArea(); // System.out.println(displayArea); } catch (Exception e) { e.printStackTrace(); } }
private DefaultFeatureCollection createFeaturesFromNumberOfLines( final MapfishMapContext mapContext, final SimpleFeatureBuilder featureBuilder, final GridParam layerData, final LabelPositionCollector labels) { GeometryFactory geometryFactory = new GeometryFactory(); ReferencedEnvelope bounds = mapContext.toReferencedEnvelope(); MapfishMapContext rootContext = mapContext.getRootContext(); Polygon rotatedBounds = GridUtils.calculateBounds(rootContext); AffineTransform worldToScreenTransform = GridUtils.getWorldToScreenTransform(mapContext); CoordinateReferenceSystem mapCrs = bounds.getCoordinateReferenceSystem(); String unit = layerData.calculateLabelUnit(mapCrs); MathTransform labelTransform = layerData.calculateLabelTransform(mapCrs); double incrementX = bounds.getWidth() / (layerData.numberOfLines[0] + 1); double incrementY = bounds.getHeight() / (layerData.numberOfLines[1] + 1); double x = bounds.getMinX(); DefaultFeatureCollection features = new DefaultFeatureCollection(); for (int i = 0; i < layerData.numberOfLines[0] + 2; i++) { double y = bounds.getMinY(); for (int j = 0; j < layerData.numberOfLines[1] + 2; j++) { String fid = "grid." + i + "." + j; if ((i != 0 || j != 0) && (i != layerData.numberOfLines[0] + 1 || j != layerData.numberOfLines[1] + 1) && (i != 0 || j != layerData.numberOfLines[1] + 1) && (i != layerData.numberOfLines[0] + 1 || j != 0)) { if (i == 0) { GridUtils.leftBorderLabel( labels, geometryFactory, rotatedBounds, unit, y, worldToScreenTransform, labelTransform, layerData.getGridLabelFormat()); } else if (i == layerData.numberOfLines[0] + 1) { GridUtils.rightBorderLabel( labels, geometryFactory, rotatedBounds, unit, y, worldToScreenTransform, labelTransform, layerData.getGridLabelFormat()); } else if (j == 0) { GridUtils.bottomBorderLabel( labels, geometryFactory, rotatedBounds, unit, x, worldToScreenTransform, labelTransform, layerData.getGridLabelFormat()); } else if (j == layerData.numberOfLines[1] + 1) { GridUtils.topBorderLabel( labels, geometryFactory, rotatedBounds, unit, x, worldToScreenTransform, labelTransform, layerData.getGridLabelFormat()); } else { featureBuilder.reset(); Point geom = geometryFactory.createPoint(new Coordinate(x, y)); featureBuilder.set(Grid.ATT_GEOM, geom); features.add(featureBuilder.buildFeature(fid)); } } y += incrementY; } x += incrementX; } return features; }
public ProjectionHandler getHandler( ReferencedEnvelope renderingEnvelope, CoordinateReferenceSystem sourceCrs, boolean wrap, int maxWraps) throws FactoryException { MapProjection mapProjection = CRS.getMapProjection(renderingEnvelope.getCoordinateReferenceSystem()); if (renderingEnvelope != null && mapProjection instanceof PolarStereographic) { boolean north; // variant B uses standard_parallel ParameterValue<?> stdParallel = null; try { stdParallel = mapProjection .getParameterValues() .parameter(AbstractProvider.STANDARD_PARALLEL_1.getName().getCode()); } catch (ParameterNotFoundException e) { // ignore } if (stdParallel != null) { north = stdParallel.doubleValue() > 0; } else { // variant A uses latitude of origin ParameterValue<?> latOrigin = null; try { latOrigin = mapProjection .getParameterValues() .parameter(AbstractProvider.LATITUDE_OF_ORIGIN.getName().getCode()); } catch (ParameterNotFoundException e) { // ignore } if (latOrigin != null) { north = latOrigin.doubleValue() > 0; } else { return null; } } ReferencedEnvelope validArea; if (north) { validArea = new ReferencedEnvelope( -Double.MAX_VALUE, Double.MAX_VALUE, -0, 90, DefaultGeographicCRS.WGS84); } else { validArea = new ReferencedEnvelope( -Double.MAX_VALUE, Double.MAX_VALUE, -90, 0, DefaultGeographicCRS.WGS84); } return new ProjectionHandler(sourceCrs, validArea, renderingEnvelope) { @Override public List<ReferencedEnvelope> getQueryEnvelopes() throws TransformException, FactoryException { // check if we are crossing the antimeridian and are fully below the pole, // in this case we'd end up reading the full globe when we'd have to just // read two portions near the dateline if (renderingEnvelope.getMaxY() < 0 && renderingEnvelope.getMinX() < 0 && renderingEnvelope.getMaxX() > 0) { ReferencedEnvelope e1 = new ReferencedEnvelope( renderingEnvelope.getMinX(), -1e-6, renderingEnvelope.getMinY(), renderingEnvelope.getMaxY(), renderingEnvelope.getCoordinateReferenceSystem()); ReferencedEnvelope e2 = new ReferencedEnvelope( 1e-6, renderingEnvelope.getMaxX(), renderingEnvelope.getMinY(), renderingEnvelope.getMaxY(), renderingEnvelope.getCoordinateReferenceSystem()); List<ReferencedEnvelope> envelopes = new ArrayList<ReferencedEnvelope>(); envelopes.add(e1); envelopes.add(e2); reprojectEnvelopes(sourceCRS, envelopes); return envelopes; } else { return super.getQueryEnvelopes(); } } }; } return null; }
protected void handleLayerGroups(List<LayerGroupInfo> layerGroups) throws FactoryException, TransformException { if (layerGroups == null || layerGroups.size() == 0) { return; } Collections.sort( layerGroups, new Comparator<LayerGroupInfo>() { public int compare(LayerGroupInfo o1, LayerGroupInfo o2) { return o1.getName().compareTo(o2.getName()); } }); for (LayerGroupInfo layerGroup : layerGroups) { String layerName = layerGroup.getName(); AttributesImpl qatts = new AttributesImpl(); boolean queryable = wmsConfig.isQueryable(layerGroup); qatts.addAttribute("", "queryable", "queryable", "", queryable ? "1" : "0"); // qatts.addAttribute("", "opaque", "opaque", "", "1"); // qatts.addAttribute("", "cascaded", "cascaded", "", "1"); start("Layer", qatts); element("Name", layerName); element("Title", layerName); element("Abstract", "Layer-Group type layer: " + layerName); final ReferencedEnvelope layerGroupBounds = layerGroup.getBounds(); final ReferencedEnvelope latLonBounds = layerGroupBounds.transform(DefaultGeographicCRS.WGS84, true); String authority = layerGroupBounds .getCoordinateReferenceSystem() .getIdentifiers() .toArray()[0] .toString(); element("SRS", authority); handleLatLonBBox(latLonBounds); handleBBox(layerGroupBounds, authority); // Aggregated metadata links (see GEOS-4500) List<LayerInfo> layers = layerGroup.getLayers(); Set<MetadataLinkInfo> aggregatedLinks = new HashSet<MetadataLinkInfo>(); for (LayerInfo layer : layers) { List<MetadataLinkInfo> metadataLinks = layer.getResource().getMetadataLinks(); if (metadataLinks != null) { aggregatedLinks.addAll(metadataLinks); } } handleMetadataList(aggregatedLinks); // the layer style is not provided since the group does just have // one possibility, the lack of styles that will make it use // the default ones for each layer end("Layer"); } }
public synchronized void render( Graphics2D destination, ReferencedEnvelope bounds, IProgressMonitor monitor) throws RenderException { int endLayerStatus = ILayer.DONE; try { if (bounds == null || bounds.isNull()) { bounds = getContext().getImageBounds(); } if (monitor.isCanceled()) return; getContext().setStatus(ILayer.WAIT); WebMapServer wms = getWMS(); GetMapRequest request = wms.createGetMapRequest(); // put in default exception format we understand as a client // (if suppoted by the server) WMSCapabilities capabilities = wms.getCapabilities(); if (capabilities .getRequest() .getGetMap() .getFormats() .contains(GetMapRequest.EXCEPTION_XML)) { request.setExceptions(GetMapRequest.EXCEPTION_XML); } setImageFormat(wms, request); if (monitor.isCanceled()) return; double currScale = getContext().getViewportModel().getScaleDenominator(); List<ILayer> layers = getLayers(); for (int i = layers.size() - 1; i >= 0; i--) { ILayer ilayer = layers.get(i); Layer layer; double minScale = 0; double maxScale = Double.MAX_VALUE; layer = ilayer.getResource(org.geotools.data.ows.Layer.class, null); // check if there are min/max scale rules StyleBlackboard sb = (StyleBlackboard) ilayer.getStyleBlackboard(); Style style = (Style) sb.lookup(Style.class); if (style != null) { Rule rule = style.getFeatureTypeStyles()[0].getRules()[0]; minScale = rule.getMinScaleDenominator(); maxScale = rule.getMaxScaleDenominator(); } if (currScale >= minScale && currScale <= maxScale) { // check for a wms style StyleImpl wmsStyle = (StyleImpl) ilayer.getStyleBlackboard().get(WMSStyleContent.WMSSTYLE); if (wmsStyle != null) { request.addLayer(layer, wmsStyle); } else { request.addLayer(layer); } } } if (monitor.isCanceled()) return; List<Layer> wmsLayers = getWMSLayers(); if (wmsLayers == null || wmsLayers.isEmpty()) { endLayerStatus = ILayer.WARNING; return; } // figure out request CRS String requestCRScode = findRequestCRS(wmsLayers, getViewportCRS(), getContext().getMap()); // TODO: make findRequestCRS more efficient (we are running CRS.decode at *least* twice) CoordinateReferenceSystem requestCRS = CRS.decode(requestCRScode); // figure out viewport // ReferencedEnvelope viewport; // Envelope viewportBBox = getViewportBBox(); // CoordinateReferenceSystem viewportCRS = getViewportCRS(); // if (viewportBBox == null) { // // change viewport to world // viewportBBox = new Envelope(-180, 180, -90, 90); // if (!DefaultGeographicCRS.WGS84.equals(viewportCRS)) { // reproject // viewport = new ReferencedEnvelope(viewportBBox, // DefaultGeographicCRS.WGS84); // viewportBBox = viewport.transform(viewportCRS, true); // } // } ReferencedEnvelope requestBBox = null; Envelope backprojectedBBox = null; // request bbox projected to the viewport crs // viewport = new ReferencedEnvelope(viewportBBox, viewportCRS); // requestBBox = calculateRequestBBox(wmsLayers, viewport, requestCRS); requestBBox = calculateRequestBBox(wmsLayers, bounds, requestCRS, capabilities.getVersion()); // check that a request is needed (not out of a bounds, invalid, etc) if (requestBBox == NILL_BOX) { endLayerStatus = ILayer.WARNING; return; } assert requestBBox.getCoordinateReferenceSystem().equals(requestCRS); if (requestBBox.getCoordinateReferenceSystem().equals(getViewportCRS())) { backprojectedBBox = (Envelope) requestBBox; } else { backprojectedBBox = (Envelope) requestBBox.transform(getViewportCRS(), true); } if (WMSPlugin.isDebugging(Trace.RENDER)) { WMSPlugin.trace("Viewport CRS: " + getViewportCRS().getName()); // $NON-NLS-1$ WMSPlugin.trace("Request CRS: " + requestCRS.getName()); // $NON-NLS-1$ WMSPlugin.trace("Context Image bounds: " + getContext().getImageBounds()); // $NON-NLS-1$ WMSPlugin.trace("Request BBox bounds: " + requestBBox); // $NON-NLS-1$ WMSPlugin.trace("Backprojected request bounds: " + backprojectedBBox); // $NON-NLS-1$ } Service wmsService = capabilities.getService(); Dimension maxDimensions = new Dimension(wmsService.getMaxWidth(), wmsService.getMaxHeight()); // Dimension imageDimensions = // calculateImageDimensions(getContext().getMapDisplay() // .getDisplaySize(), maxDimensions, getViewportBBox(), backprojectedBBox); Dimension imageDimensions = calculateImageDimensions( getContext().getImageSize(), maxDimensions, bounds, backprojectedBBox); if (imageDimensions.height < 1 || imageDimensions.width < 1) { endLayerStatus = ILayer.WARNING; return; } request.setDimensions( imageDimensions.width + "", imageDimensions.height + ""); // $NON-NLS-1$ //$NON-NLS-2$ // epsg could be under identifiers or authority. Set<ReferenceIdentifier> identifiers = requestCRS.getIdentifiers(); String srs = identifiers.isEmpty() ? EPSG_4326 : identifiers.iterator().next().toString(); request.setSRS(srs); // EPSG_4326 request.setBBox(requestBBox); // request.setBBox(requestBBox.getMinX() + "," + requestBBox.getMinY()+ "," + // requestBBox.getMaxX()+ "," + requestBBox.getMaxY()); if (monitor.isCanceled()) return; setFilter(wms, request); // request.setProperty("DACS_ACS", null); BufferedImage image = readImage(wms, request, monitor); if (monitor.isCanceled()) return; if (image == null) { Exception e = new RuntimeException(Messages.BasicWMSRenderer2_unable_to_decode_image); throw wrapException(e); } // backprojectedBBox or viewportBBox renderGridCoverage(destination, backprojectedBBox, imageDimensions, requestBBox, image); } catch (Exception e) { if (e instanceof RenderException) throw (RenderException) e; throw new RenderException(e); } finally { getContext().setStatus(endLayerStatus); if (endLayerStatus == ILayer.DONE) { // clear the status message (rendering was successful) getContext().setStatusMessage(null); } } }
/** * Loads the feature collection based on the current styling and the scale denominator. If no * feature is going to be returned a null feature collection will be returned instead * * @param featureSource * @param layer * @param mapContent * @param wms * @param scaleDenominator * @return * @throws Exception */ public static SimpleFeatureCollection loadFeatureCollection( SimpleFeatureSource featureSource, Layer layer, WMSMapContent mapContent, WMS wms, double scaleDenominator) throws Exception { SimpleFeatureType schema = featureSource.getSchema(); Envelope envelope = mapContent.getRenderingArea(); ReferencedEnvelope aoi = new ReferencedEnvelope(envelope, mapContent.getCoordinateReferenceSystem()); CoordinateReferenceSystem sourceCrs = schema.getCoordinateReferenceSystem(); boolean reprojectBBox = (sourceCrs != null) && !CRS.equalsIgnoreMetadata(aoi.getCoordinateReferenceSystem(), sourceCrs); if (reprojectBBox) { aoi = aoi.transform(sourceCrs, true); } Filter filter = createBBoxFilter(schema, aoi); // now build the query using only the attributes and the bounding // box needed Query q = new Query(schema.getTypeName()); q.setFilter(filter); // now, if a definition query has been established for this layer, // be sure to respect it by combining it with the bounding box one. Query definitionQuery = layer.getQuery(); if (definitionQuery != Query.ALL) { if (q == Query.ALL) { q = (Query) definitionQuery; } else { q = (Query) DataUtilities.mixQueries(definitionQuery, q, "KMLEncoder"); } } // handle startIndex requested by client query q.setStartIndex(definitionQuery.getStartIndex()); // check the regionating strategy RegionatingStrategy regionatingStrategy = null; String stratname = (String) mapContent.getRequest().getFormatOptions().get("regionateBy"); if (("auto").equals(stratname)) { Catalog catalog = wms.getGeoServer().getCatalog(); Name name = layer.getFeatureSource().getName(); stratname = catalog .getFeatureTypeByName(name) .getMetadata() .get("kml.regionateStrategy", String.class); if (stratname == null || "".equals(stratname)) { stratname = "best_guess"; LOGGER.log( Level.FINE, "No default regionating strategy has been configured in " + name + "; using automatic best-guess strategy."); } } if (stratname != null) { regionatingStrategy = findStrategyByName(stratname); // if a strategy was specified but we did not find it, let the user // know if (regionatingStrategy == null) throw new ServiceException("Unknown regionating strategy " + stratname); } // try to load less features by leveraging regionating strategy and the // SLD Filter regionatingFilter = Filter.INCLUDE; if (regionatingStrategy != null) regionatingFilter = regionatingStrategy.getFilter(mapContent, layer); Filter ruleFilter = summarizeRuleFilters( getLayerRules(featureSource.getSchema(), layer.getStyle()), scaleDenominator); Filter finalFilter = joinFilters(q.getFilter(), ruleFilter, regionatingFilter); if (finalFilter == Filter.EXCLUDE) { // if we don't have any feature to return return null; } q.setFilter(finalFilter); // make sure we output in 4326 since that's what KML mandates CoordinateReferenceSystem wgs84; try { wgs84 = CRS.decode("EPSG:4326"); } catch (Exception e) { throw new RuntimeException( "Cannot decode EPSG:4326, the CRS subsystem must be badly broken..."); } if (sourceCrs != null && !CRS.equalsIgnoreMetadata(wgs84, sourceCrs)) { return new ReprojectFeatureResults(featureSource.getFeatures(q), wgs84); } return featureSource.getFeatures(q); }
private void createTABFile( ReferencedEnvelope transformedBBox, final int width, final int height, final String baseFile, final String ext) throws IOException { final StringBuffer buff = new StringBuffer(baseFile); buff.append(".tab"); final File tabFile = new File(buff.toString()); final PrintWriter out = new PrintWriter(new FileOutputStream(tabFile)); try { out.println("!table"); out.println("!version 300"); out.println("!charset UTF-8"); out.println(""); out.println("Definition Table"); out.println("File " + tabFile.getName().replace(".tab", ".") + ext); out.println("Type \"RASTER\""); out.println( "(" + transformedBBox.getMinX() + "," + transformedBBox.getMinY() + ") (0,0) Label \"Pt 1\","); out.println( "(" + transformedBBox.getMaxX() + "," + transformedBBox.getMinY() + ") (" + width + ",0) Label \"Pt 2\","); out.println( "(" + transformedBBox.getMaxX() + "," + transformedBBox.getMaxY() + ") (" + width + "," + height + ") Label \"Pt 3\","); out.println( "(" + transformedBBox.getMinX() + "," + transformedBBox.getMaxY() + ") (0," + height + ") Label \"Pt 4\","); InputStream in = WcsCoverageReader.class .getClassLoader() .getResourceAsStream("org/georchestra/extractorapp/proj4MapinfoTab.properties"); Properties properties = new Properties(); properties.load(in); MIFProjReader tabProjReader = new MIFProjReader(); Iterator<ReferenceIdentifier> iter = transformedBBox.getCoordinateReferenceSystem().getIdentifiers().iterator(); String crsCode = iter.next().toString(); int crs = Integer.valueOf(crsCode.replace("EPSG:", "")); out.println("CoordSys Earth Projection " + tabProjReader.toMifCoordSys(crs)); out.print( "units \"" + CRSUtilities.getUnit( transformedBBox.getCoordinateReferenceSystem().getCoordinateSystem()) .toString() + "\""); /** * GeneralDerivedCRS crs = (GeneralDerivedCRS)request.responseCRS; Conversion * conversionFromBase = crs.getConversionFromBase(); * * <p>Unit<?> unit = CRSUtilities.getUnit(crs.getCoordinateSystem()); GeodeticDatum datum = * (GeodeticDatum)crs.getDatum(); * * <p>// Specific MAPINFO TAB format String projType = * conversionFromBase.getMethod().getName().getCode(); String datumCode = * datum.getEllipsoid().getName().getCode(); * * <p>Map <String, Integer> projectionTypes = new HashMap<String, Integer>(); * projectionTypes.put("Lambert Conic Conformal (2SP)", 3); * * <p>Map <String, Integer> datumCodes = new HashMap<String, Integer>(); datumCodes.put("GRS * 1980", 33); * * <p>// get params from CRS Map<String, String> params= new HashMap<String, String>(); for * (final GeneralParameterValue param : conversionFromBase.getParameterValues().values()) { if * (param instanceof ParameterValue) { final double value = ((ParameterValue<?>) * param).doubleValue(); params.put(param.getDescriptor().getName().getCode(), * String.valueOf(value)); } } * * <p>out.print("CoordSys Earth "); out.print("Projection " + projectionTypes.get(projType) + * ", "); out.print(datumCodes.get(datumCode) + ", "); out.print(unit.toString() + ", "); * out.print(params.get("central_meridian") + ", "); * out.print(params.get("latitude_of_origin") + ", "); * out.print(params.get("standard_parallel_2") + ", "); * out.print(params.get("standard_parallel_1") + ", "); out.print(params.get("false_easting") * + ", "); out.print(params.get("false_northing") + ", "); */ out.flush(); } finally { out.close(); } }
private DefaultFeatureCollection createFeaturesFromSpacing( final MapfishMapContext mapContext, final SimpleFeatureBuilder featureBuilder, final GridParam layerData, final LabelPositionCollector labels) { GeometryFactory geometryFactory = new GeometryFactory(); ReferencedEnvelope bounds = mapContext.toReferencedEnvelope(); CoordinateReferenceSystem mapCrs = bounds.getCoordinateReferenceSystem(); String unit = layerData.calculateLabelUnit(mapCrs); MathTransform labelTransform = layerData.calculateLabelTransform(mapCrs); final double incrementX = layerData.spacing[0]; final double incrementY = layerData.spacing[1]; double minX = GridUtils.calculateFirstLine(bounds, layerData, 0); double minY = GridUtils.calculateFirstLine(bounds, layerData, 1); MapfishMapContext rootContext = mapContext.getRootContext(); Polygon rotatedBounds = GridUtils.calculateBounds(rootContext); AffineTransform worldToScreenTransform = GridUtils.getWorldToScreenTransform(mapContext); DefaultFeatureCollection features = new DefaultFeatureCollection(); int i = 0; int j; boolean addBorderFeatures = true; for (double x = minX; x < bounds.getMaxX(); x += incrementX) { i++; j = 0; if (!onRightBorder(bounds, x)) { // don't add the border features twice. GridUtils.bottomBorderLabel( labels, geometryFactory, rotatedBounds, unit, x, worldToScreenTransform, labelTransform, layerData.getGridLabelFormat()); GridUtils.topBorderLabel( labels, geometryFactory, rotatedBounds, unit, x, worldToScreenTransform, labelTransform, layerData.getGridLabelFormat()); } for (double y = minY; y < bounds.getMaxY(); y += incrementY) { j++; if (addBorderFeatures && !onRightBorder(bounds, x) && !onTopBorder(bounds, y)) { GridUtils.leftBorderLabel( labels, geometryFactory, rotatedBounds, unit, y, worldToScreenTransform, labelTransform, layerData.getGridLabelFormat()); GridUtils.rightBorderLabel( labels, geometryFactory, rotatedBounds, unit, y, worldToScreenTransform, labelTransform, layerData.getGridLabelFormat()); } if (!onTopBorder(bounds, y) && !onBottomBorder(bounds, y) && !onLeftBorder(bounds, x) && !onRightBorder(bounds, x)) { // don't add the border features twice. featureBuilder.reset(); Point geom = geometryFactory.createPoint(new Coordinate(x, y)); featureBuilder.set(Grid.ATT_GEOM, geom); features.add(featureBuilder.buildFeature("grid." + i + "." + j)); } } addBorderFeatures = false; } return features; }
/** * Creates a new envelope from an existing envelope. * * @param envelope The envelope to initialize from * @throws MismatchedDimensionException if the CRS dimension is not valid. * @since 2.3 */ public ReferencedEnvelope(final ReferencedEnvelope envelope) throws MismatchedDimensionException { super(envelope); crs = envelope.getCoordinateReferenceSystem(); checkCoordinateReferenceSystemDimension(); }
/** * Load a specified a raster as a portion of the granule describe by this {@link * GranuleDescriptor}. * * @param imageReadParameters the {@link ImageReadParam} to use for reading. * @param index the index to use for the {@link ImageReader}. * @param cropBBox the bbox to use for cropping. * @param mosaicWorldToGrid the cropping grid to world transform. * @param request the incoming request to satisfy. * @param hints {@link Hints} to be used for creating this raster. * @return a specified a raster as a portion of the granule describe by this {@link * GranuleDescriptor}. * @throws IOException in case an error occurs. */ public GranuleLoadingResult loadRaster( final ImageReadParam imageReadParameters, final int index, final ReferencedEnvelope cropBBox, final MathTransform2D mosaicWorldToGrid, final RasterLayerRequest request, final Hints hints) throws IOException { if (LOGGER.isLoggable(java.util.logging.Level.FINER)) { final String name = Thread.currentThread().getName(); LOGGER.finer( "Thread:" + name + " Loading raster data for granuleDescriptor " + this.toString()); } ImageReadParam readParameters = null; int imageIndex; final ReferencedEnvelope bbox = inclusionGeometry != null ? new ReferencedEnvelope( granuleBBOX.intersection(inclusionGeometry.getEnvelopeInternal()), granuleBBOX.getCoordinateReferenceSystem()) : granuleBBOX; boolean doFiltering = false; if (filterMe) { doFiltering = Utils.areaIsDifferent(inclusionGeometry, baseGridToWorld, granuleBBOX); } // intersection of this tile bound with the current crop bbox final ReferencedEnvelope intersection = new ReferencedEnvelope( bbox.intersection(cropBBox), cropBBox.getCoordinateReferenceSystem()); if (intersection.isEmpty()) { if (LOGGER.isLoggable(java.util.logging.Level.FINE)) { LOGGER.fine( new StringBuilder("Got empty intersection for granule ") .append(this.toString()) .append(" with request ") .append(request.toString()) .append(" Resulting in no granule loaded: Empty result") .toString()); } return null; } ImageInputStream inStream = null; ImageReader reader = null; try { // // get info about the raster we have to read // // get a stream assert cachedStreamSPI != null : "no cachedStreamSPI available!"; inStream = cachedStreamSPI.createInputStreamInstance( granuleUrl, ImageIO.getUseCache(), ImageIO.getCacheDirectory()); if (inStream == null) return null; // get a reader and try to cache the relevant SPI if (cachedReaderSPI == null) { reader = ImageIOExt.getImageioReader(inStream); if (reader != null) cachedReaderSPI = reader.getOriginatingProvider(); } else reader = cachedReaderSPI.createReaderInstance(); if (reader == null) { if (LOGGER.isLoggable(java.util.logging.Level.WARNING)) { LOGGER.warning( new StringBuilder("Unable to get s reader for granuleDescriptor ") .append(this.toString()) .append(" with request ") .append(request.toString()) .append(" Resulting in no granule loaded: Empty result") .toString()); } return null; } // set input reader.setInput(inStream); // Checking for heterogeneous granules if (request.isHeterogeneousGranules()) { // create read parameters readParameters = new ImageReadParam(); // override the overviews controller for the base layer imageIndex = ReadParamsController.setReadParams( request.getRequestedResolution(), request.getOverviewPolicy(), request.getDecimationPolicy(), readParameters, request.rasterManager, overviewsController); } else { imageIndex = index; readParameters = imageReadParameters; } // get selected level and base level dimensions final GranuleOverviewLevelDescriptor selectedlevel = getLevel(imageIndex, reader); // now create the crop grid to world which can be used to decide // which source area we need to crop in the selected level taking // into account the scale factors imposed by the selection of this // level together with the base level grid to world transformation AffineTransform2D cropWorldToGrid = new AffineTransform2D(selectedlevel.gridToWorldTransformCorner); cropWorldToGrid = (AffineTransform2D) cropWorldToGrid.inverse(); // computing the crop source area which lives into the // selected level raster space, NOTICE that at the end we need to // take into account the fact that we might also decimate therefore // we cannot just use the crop grid to world but we need to correct // it. final Rectangle sourceArea = CRS.transform(cropWorldToGrid, intersection).toRectangle2D().getBounds(); // gutter if (selectedlevel.baseToLevelTransform.isIdentity()) sourceArea.grow(2, 2); XRectangle2D.intersect( sourceArea, selectedlevel.rasterDimensions, sourceArea); // make sure roundings don't bother us // is it empty?? if (sourceArea.isEmpty()) { if (LOGGER.isLoggable(java.util.logging.Level.FINE)) { LOGGER.fine( "Got empty area for granuleDescriptor " + this.toString() + " with request " + request.toString() + " Resulting in no granule loaded: Empty result"); } return null; } else if (LOGGER.isLoggable(java.util.logging.Level.FINER)) { LOGGER.finer( "Loading level " + imageIndex + " with source region: " + sourceArea + " subsampling: " + readParameters.getSourceXSubsampling() + "," + readParameters.getSourceYSubsampling() + " for granule:" + granuleUrl); } // Setting subsampling int newSubSamplingFactor = 0; final String pluginName = cachedReaderSPI.getPluginClassName(); if (pluginName != null && pluginName.equals(ImageUtilities.DIRECT_KAKADU_PLUGIN)) { final int ssx = readParameters.getSourceXSubsampling(); final int ssy = readParameters.getSourceYSubsampling(); newSubSamplingFactor = ImageIOUtilities.getSubSamplingFactor2(ssx, ssy); if (newSubSamplingFactor != 0) { if (newSubSamplingFactor > maxDecimationFactor && maxDecimationFactor != -1) { newSubSamplingFactor = maxDecimationFactor; } readParameters.setSourceSubsampling(newSubSamplingFactor, newSubSamplingFactor, 0, 0); } } // set the source region readParameters.setSourceRegion(sourceArea); final RenderedImage raster; try { // read raster = request .getReadType() .read( readParameters, imageIndex, granuleUrl, selectedlevel.rasterDimensions, reader, hints, false); } catch (Throwable e) { if (LOGGER.isLoggable(java.util.logging.Level.FINE)) { LOGGER.log( java.util.logging.Level.FINE, "Unable to load raster for granuleDescriptor " + this.toString() + " with request " + request.toString() + " Resulting in no granule loaded: Empty result", e); } return null; } // use fixed source area sourceArea.setRect(readParameters.getSourceRegion()); // // setting new coefficients to define a new affineTransformation // to be applied to the grid to world transformation // ----------------------------------------------------------------------------------- // // With respect to the original envelope, the obtained planarImage // needs to be rescaled. The scaling factors are computed as the // ratio between the cropped source region sizes and the read // image sizes. // // place it in the mosaic using the coords created above; double decimationScaleX = ((1.0 * sourceArea.width) / raster.getWidth()); double decimationScaleY = ((1.0 * sourceArea.height) / raster.getHeight()); final AffineTransform decimationScaleTranform = XAffineTransform.getScaleInstance(decimationScaleX, decimationScaleY); // keep into account translation to work into the selected level raster space final AffineTransform afterDecimationTranslateTranform = XAffineTransform.getTranslateInstance(sourceArea.x, sourceArea.y); // now we need to go back to the base level raster space final AffineTransform backToBaseLevelScaleTransform = selectedlevel.baseToLevelTransform; // now create the overall transform final AffineTransform finalRaster2Model = new AffineTransform(baseGridToWorld); finalRaster2Model.concatenate(CoverageUtilities.CENTER_TO_CORNER); final double x = finalRaster2Model.getTranslateX(); final double y = finalRaster2Model.getTranslateY(); if (!XAffineTransform.isIdentity(backToBaseLevelScaleTransform, Utils.AFFINE_IDENTITY_EPS)) finalRaster2Model.concatenate(backToBaseLevelScaleTransform); if (!XAffineTransform.isIdentity(afterDecimationTranslateTranform, Utils.AFFINE_IDENTITY_EPS)) finalRaster2Model.concatenate(afterDecimationTranslateTranform); if (!XAffineTransform.isIdentity(decimationScaleTranform, Utils.AFFINE_IDENTITY_EPS)) finalRaster2Model.concatenate(decimationScaleTranform); // keep into account translation factors to place this tile finalRaster2Model.preConcatenate((AffineTransform) mosaicWorldToGrid); final Interpolation interpolation = request.getInterpolation(); // paranoiac check to avoid that JAI freaks out when computing its internal layouT on images // that are too small Rectangle2D finalLayout = ImageUtilities.layoutHelper( raster, (float) finalRaster2Model.getScaleX(), (float) finalRaster2Model.getScaleY(), (float) finalRaster2Model.getTranslateX(), (float) finalRaster2Model.getTranslateY(), interpolation); if (finalLayout.isEmpty()) { if (LOGGER.isLoggable(java.util.logging.Level.INFO)) LOGGER.info( "Unable to create a granuleDescriptor " + this.toString() + " due to jai scale bug creating a null source area"); return null; } ROI granuleLoadingShape = null; if (granuleROIShape != null) { final Point2D translate = mosaicWorldToGrid.transform(new DirectPosition2D(x, y), (Point2D) null); AffineTransform tx2 = new AffineTransform(); tx2.preConcatenate( AffineTransform.getScaleInstance( ((AffineTransform) mosaicWorldToGrid).getScaleX(), -((AffineTransform) mosaicWorldToGrid).getScaleY())); tx2.preConcatenate( AffineTransform.getScaleInstance( ((AffineTransform) baseGridToWorld).getScaleX(), -((AffineTransform) baseGridToWorld).getScaleY())); tx2.preConcatenate( AffineTransform.getTranslateInstance(translate.getX(), translate.getY())); granuleLoadingShape = (ROI) granuleROIShape.transform(tx2); } // apply the affine transform conserving indexed color model final RenderingHints localHints = new RenderingHints( JAI.KEY_REPLACE_INDEX_COLOR_MODEL, interpolation instanceof InterpolationNearest ? Boolean.FALSE : Boolean.TRUE); if (XAffineTransform.isIdentity(finalRaster2Model, Utils.AFFINE_IDENTITY_EPS)) { return new GranuleLoadingResult(raster, granuleLoadingShape, granuleUrl, doFiltering); } else { // // In case we are asked to use certain tile dimensions we tile // also at this stage in case the read type is Direct since // buffered images comes up untiled and this can affect the // performances of the subsequent affine operation. // final Dimension tileDimensions = request.getTileDimensions(); if (tileDimensions != null && request.getReadType().equals(ReadType.DIRECT_READ)) { final ImageLayout layout = new ImageLayout(); layout.setTileHeight(tileDimensions.width).setTileWidth(tileDimensions.height); localHints.add(new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout)); } else { if (hints != null && hints.containsKey(JAI.KEY_IMAGE_LAYOUT)) { final Object layout = hints.get(JAI.KEY_IMAGE_LAYOUT); if (layout != null && layout instanceof ImageLayout) { localHints.add( new RenderingHints(JAI.KEY_IMAGE_LAYOUT, ((ImageLayout) layout).clone())); } } } if (hints != null && hints.containsKey(JAI.KEY_TILE_CACHE)) { final Object cache = hints.get(JAI.KEY_TILE_CACHE); if (cache != null && cache instanceof TileCache) localHints.add(new RenderingHints(JAI.KEY_TILE_CACHE, (TileCache) cache)); } if (hints != null && hints.containsKey(JAI.KEY_TILE_SCHEDULER)) { final Object scheduler = hints.get(JAI.KEY_TILE_SCHEDULER); if (scheduler != null && scheduler instanceof TileScheduler) localHints.add(new RenderingHints(JAI.KEY_TILE_SCHEDULER, (TileScheduler) scheduler)); } boolean addBorderExtender = true; if (hints != null && hints.containsKey(JAI.KEY_BORDER_EXTENDER)) { final Object extender = hints.get(JAI.KEY_BORDER_EXTENDER); if (extender != null && extender instanceof BorderExtender) { localHints.add(new RenderingHints(JAI.KEY_BORDER_EXTENDER, (BorderExtender) extender)); addBorderExtender = false; } } // border extender if (addBorderExtender) { localHints.add(ImageUtilities.BORDER_EXTENDER_HINTS); } // boolean hasScaleX=!(Math.abs(finalRaster2Model.getScaleX()-1) < // 1E-2/(raster.getWidth()+1-raster.getMinX())); // boolean hasScaleY=!(Math.abs(finalRaster2Model.getScaleY()-1) < // 1E-2/(raster.getHeight()+1-raster.getMinY())); // boolean hasShearX=!(finalRaster2Model.getShearX() == 0.0); // boolean hasShearY=!(finalRaster2Model.getShearY() == 0.0); // boolean hasTranslateX=!(Math.abs(finalRaster2Model.getTranslateX()) < // 0.01F); // boolean hasTranslateY=!(Math.abs(finalRaster2Model.getTranslateY()) < // 0.01F); // boolean isTranslateXInt=!(Math.abs(finalRaster2Model.getTranslateX() - // (int) finalRaster2Model.getTranslateX()) < 0.01F); // boolean isTranslateYInt=!(Math.abs(finalRaster2Model.getTranslateY() - // (int) finalRaster2Model.getTranslateY()) < 0.01F); // // boolean isIdentity = finalRaster2Model.isIdentity() && // !hasScaleX&&!hasScaleY &&!hasTranslateX&&!hasTranslateY; // // TODO how can we check that the a skew is harmelss???? // if(isIdentity){ // // TODO check if we are missing anything like tiling or such that // comes from hints // return new GranuleLoadingResult(raster, granuleLoadingShape, // granuleUrl, doFiltering); // } // // // TOLERANCE ON PIXELS SIZE // // // Check and see if the affine transform is in fact doing // // a Translate operation. That is a scale by 1 and no rotation. // // In which case call translate. Note that only integer translate // // is applicable. For non-integer translate we'll have to do the // // affine. // // If the hints contain an ImageLayout hint, we can't use // // TranslateIntOpImage since it isn't capable of dealing with that. // // Get ImageLayout from renderHints if any. // ImageLayout layout = RIFUtil.getImageLayoutHint(localHints); // if ( !hasScaleX && // !hasScaleY && // !hasShearX&& // !hasShearY&& // isTranslateXInt&& // isTranslateYInt&& // layout == null) { // // It's a integer translate // return new GranuleLoadingResult(new TranslateIntOpImage(raster, // localHints, // (int) finalRaster2Model.getShearX(), // (int) // finalRaster2Model.getShearY()),granuleLoadingShape, granuleUrl, doFiltering); // } ImageWorker iw = new ImageWorker(raster); iw.setRenderingHints(localHints); iw.affine(finalRaster2Model, interpolation, request.getBackgroundValues()); return new GranuleLoadingResult( iw.getRenderedImage(), granuleLoadingShape, granuleUrl, doFiltering); } } catch (IllegalStateException e) { if (LOGGER.isLoggable(java.util.logging.Level.WARNING)) { LOGGER.log( java.util.logging.Level.WARNING, new StringBuilder("Unable to load raster for granuleDescriptor ") .append(this.toString()) .append(" with request ") .append(request.toString()) .append(" Resulting in no granule loaded: Empty result") .toString(), e); } return null; } catch (org.opengis.referencing.operation.NoninvertibleTransformException e) { if (LOGGER.isLoggable(java.util.logging.Level.WARNING)) { LOGGER.log( java.util.logging.Level.WARNING, new StringBuilder("Unable to load raster for granuleDescriptor ") .append(this.toString()) .append(" with request ") .append(request.toString()) .append(" Resulting in no granule loaded: Empty result") .toString(), e); } return null; } catch (TransformException e) { if (LOGGER.isLoggable(java.util.logging.Level.WARNING)) { LOGGER.log( java.util.logging.Level.WARNING, new StringBuilder("Unable to load raster for granuleDescriptor ") .append(this.toString()) .append(" with request ") .append(request.toString()) .append(" Resulting in no granule loaded: Empty result") .toString(), e); } return null; } finally { try { if (request.getReadType() != ReadType.JAI_IMAGEREAD && inStream != null) { inStream.close(); } } finally { if (request.getReadType() != ReadType.JAI_IMAGEREAD && reader != null) { reader.dispose(); } } } }