private int calculateScale(ReferencedEnvelope extent, Rectangle screenArea) { int scale = 0; try { scale = (int) Math.round( RendererUtilities.calculateScale( extent, screenArea.width, screenArea.height, this.resolution)); } catch (FactoryException | TransformException ex) { throw new RuntimeException("Failed to calculate scale", ex); } return scale; }
/** * Renders features based on the map layers and their styles as specified in the map context * using <code>setContext</code>. * * <p>This version of the method assumes that the area of the visible part of the map and the * size of the output area are known. The transform between the two is calculated internally. * * @param graphics The graphics object to draw to. * @param paintArea The size of the output area in output units (eg: pixels). * @param mapArea the map's visible area (viewport) in map coordinates. */ public void paint(Graphics2D graphics, Rectangle paintArea, ReferencedEnvelope mapArea) { if (mapArea == null || paintArea == null) { LOGGER.info("renderer passed null arguments"); return; } // Other arguments get checked later paint( graphics, paintArea, mapArea, RendererUtilities.worldToScreenTransform(mapArea, paintArea)); }
private double computeScale( ReferencedEnvelope envelope, Rectangle paintArea, AffineTransform worldToScreen, Map hints) { if (getScaleComputationMethod().equals(SCALE_ACCURATE)) { try { return RendererUtilities.calculateScale( envelope, paintArea.width, paintArea.height, hints); } catch (Exception e) // probably either (1) no CRS (2) error xforming { LOGGER.log(Level.WARNING, e.getLocalizedMessage(), e); } } if (XAffineTransform.getRotation(worldToScreen) != 0.0) { return RendererUtilities.calculateOGCScaleAffine( envelope.getCoordinateReferenceSystem(), worldToScreen, hints); } return RendererUtilities.calculateOGCScale(envelope, paintArea.width, hints); }
/** * First searches the hints for the scale denominator hint otherwise calls {@link * #calculateScale(Envelope, CoordinateReferenceSystem, int, int, double)}. If the hints * contains a DPI then that DPI is used otherwise 90 is used (the OGS default). */ public static double calculateScale( ReferencedEnvelope envelope, int imageWidth, int imageHeight, Map hints) throws TransformException, FactoryException { if (hints != null && hints.containsKey("declaredScaleDenominator")) { Double scale = (Double) hints.get("declaredScaleDenominator"); if (scale.doubleValue() <= 0) throw new IllegalArgumentException( "the declaredScaleDenominator must be greater than 0, was: " + scale.doubleValue()); return scale.doubleValue(); } return calculateScale(envelope, imageWidth, imageHeight, getDpi(hints)); }
/** * This method performs the computation using the methods suggested by the OGC SLD * specification, page 26. * * <p>In GeoTools 12 this method started to take into account units of measure, if this is not * desirable in your application you can set the system variable * "org.geotoools.render.lite.scale.unitCompensation" to false. * * @param envelope * @param imageWidth * @return */ public static double calculateOGCScale(ReferencedEnvelope envelope, int imageWidth, Map hints) { // if it's geodetic, we're dealing with lat/lon unit measures CoordinateReferenceSystem crs = envelope.getCoordinateReferenceSystem(); double width = envelope.getWidth(); double widthMeters = toMeters(width, crs); return widthMeters / (imageWidth / getDpi(hints) * 0.0254); }
private double computeScale(ReferencedEnvelope envelope, CoordinateReferenceSystem crs, Rectangle paintArea, Map hints) { if(getScaleComputationMethod().equals(SCALE_ACCURATE)) { try { return RendererUtilities.calculateScale(envelope, paintArea.width, paintArea.height, hints); } catch (Exception e) // probably either (1) no CRS (2) error xforming { LOGGER.log(Level.WARNING, e.getLocalizedMessage(), e); } } return RendererUtilities.calculateOGCScale(envelope, paintArea.width, hints); }
double computeScaleDenominator(MapLayer layer, WMSMapContext mapContext) { Rectangle paintArea = new Rectangle(mapContext.getMapWidth(), mapContext.getMapHeight()); AffineTransform worldToScreen = RendererUtilities.worldToScreenTransform(mapContext .getAreaOfInterest(), paintArea); try { //90 = OGC standard DPI (see SLD spec page 37) return RendererUtilities.calculateScale(mapContext.getAreaOfInterest(), mapContext.getCoordinateReferenceSystem(), paintArea.width, paintArea.height, 90); } catch (Exception e) { //probably either (1) no CRS (2) error xforming, revert to // old method - the best we can do (DJB) return 1 / worldToScreen.getScaleX(); } }
/** * Applies Unit Of Measure rescaling against all symbolizers, the result will be symbolizers * that operate purely in pixels * * @param lfts */ void applyUnitRescale(final ArrayList<LiteFeatureTypeStyle> lfts) { // apply dpi rescale double dpi = RendererUtilities.getDpi(getRendererHints()); double standardDpi = RendererUtilities.getDpi(Collections.emptyMap()); if (dpi != standardDpi) { double scaleFactor = dpi / standardDpi; DpiRescaleStyleVisitor dpiVisitor = new GraphicsAwareDpiRescaleStyleVisitor(scaleFactor); for (LiteFeatureTypeStyle fts : lfts) { rescaleFeatureTypeStyle(fts, dpiVisitor); } } // apply UOM rescaling double pixelsPerMeters = RendererUtilities.calculatePixelsPerMeterRatio(scaleDenominator, rendererHints); UomRescaleStyleVisitor rescaleVisitor = new UomRescaleStyleVisitor(pixelsPerMeters); for (LiteFeatureTypeStyle fts : lfts) { rescaleFeatureTypeStyle(fts, rescaleVisitor); } }
/** * Calculates the pixels per meter ratio based on a scale denominator. * * @param scaleDenominator The scale denominator value. * @param hints The hints used in calculation. if "dpi" key is present, it uses it's Integer * value as the dpi of the current device. if not it uses 90 that is the OGC default value. * @return The pixels per meter ratio for the given scale denominator. */ public static double calculatePixelsPerMeterRatio(double scaleDenominator, Map hints) { if (scaleDenominator <= 0.0) throw new IllegalArgumentException("The scale denominator must be positive."); double scale = 1.0 / scaleDenominator; return scale * (getDpi(hints) / 0.0254); }
mapArea = RendererUtilities.createMapEnvelope(paintArea, worldToScreen); paint(graphics, paintArea, mapArea, worldToScreen); } catch (NoninvertibleTransformException e) {
public void testOGCScaleFeet() throws Exception { try { ReferencedEnvelope re = new ReferencedEnvelope( new Envelope(0, 10, 0, 10), CRS.decode("EPSG:2927", true)); int tenMetersPixels = (int) Math.round(10 / 0.00028); RendererUtilities.SCALE_UNIT_COMPENSATION = false; double scale = RendererUtilities.calculateOGCScale(re, tenMetersPixels, new HashMap()); assertEquals(1, scale, 0.0001); RendererUtilities.SCALE_UNIT_COMPENSATION = true; scale = RendererUtilities.calculateOGCScale(re, tenMetersPixels, new HashMap()); assertEquals(0.304803, scale, 0.0001); } finally { RendererUtilities.SCALE_UNIT_COMPENSATION = true; } }
return getTransformedShape(RendererUtilities.getCentroid(tx), sa); } else { return getTransformedShape(RendererUtilities.getCentroid(g), null); return getTransformedShape(RendererUtilities.getCentroid(g), sa);
Geometry g; if(symbolizers[m] instanceof PointSymbolizer) { g = RendererUtilities.getCentroid((Geometry) geom); } else { g = (Geometry) geom; double size = RendererUtilities.getStyle2DSize(style) + 10; Envelope env = new Envelope(screenSize.getMinX(), screenSize.getMaxX(), screenSize.getMinY(), screenSize.getMaxY()); env.expandBy(size); }else{ if(symbolizers[m] instanceof PointSymbolizer) { shape = new LiteShape2(RendererUtilities.getCentroid((Geometry) feature.getDefaultGeometry()), null, null, false, false); } else { shape = getShape((SimpleGeometry) geom);
public void testOGCScaleAffineProjected() throws Exception { // 1 pixel == 500 m => 0.00028 m [ screen] == 500 m [world] // => scaleDenominator = 500/0.00028 final AffineTransform screenToWord = AffineTransform.getScaleInstance(500, 500); final AffineTransform worldToScreen = screenToWord.createInverse(); final CoordinateReferenceSystem crs = DefaultEngineeringCRS.CARTESIAN_2D; double scale; scale = RendererUtilities.calculateOGCScaleAffine(crs, worldToScreen, new HashMap()); assertEquals(500 / 0.00028, scale, 0.0001); worldToScreen.rotate(1.0); scale = RendererUtilities.calculateOGCScaleAffine(crs, worldToScreen, new HashMap()); assertEquals(500 / 0.00028, scale, 0.0001); worldToScreen.translate(100.0, 100.0); scale = RendererUtilities.calculateOGCScaleAffine(crs, worldToScreen, new HashMap()); assertEquals(500 / 0.00028, scale, 0.0001); }
/** * Tests that symbols relative sizes are proportional also if using uoms in some Symbolizer and * not using them in others. */ @org.junit.Test public void testProportionalSymbolSizePartialUOM() throws Exception { GetLegendGraphicRequest req = new GetLegendGraphicRequest(); req.setScale(RendererUtilities.calculatePixelsPerMeterRatio(10, Collections.EMPTY_MAP)); FeatureTypeInfo ftInfo = getCatalog() .getFeatureTypeByName( MockData.MPOINTS.getNamespaceURI(), MockData.MPOINTS.getLocalPart()); req.setLayer(ftInfo.getFeatureType()); req.setStyle(readSLD("ProportionalSymbolsPartialUOM.sld")); BufferedImage image = this.legendProducer.buildLegendGraphic(req); assertNotBlank("testProportionalSymbolSize", image, LegendUtils.DEFAULT_BG_COLOR); // UOM symbol assertPixel(image, 1, 1, new Color(255, 255, 255)); assertPixel(image, 5, 5, new Color(255, 0, 0)); assertPixel(image, 10, 10, new Color(255, 0, 0)); // non UOM symbol assertPixel(image, 1, 1, new Color(255, 255, 255)); assertPixel(image, 5, 5, new Color(255, 0, 0)); assertPixel(image, 10, 10, new Color(255, 0, 0)); }
private double computeScale(ReferencedEnvelope envelope, Rectangle paintArea, Map hints) { if(getScaleComputationMethod().equals(SCALE_ACCURATE)) { try { return RendererUtilities.calculateScale(envelope, paintArea.width, paintArea.height, hints); } catch (Exception e) // probably either (1) no CRS (2) error xforming { LOGGER.log(Level.WARNING, e.getLocalizedMessage(), e); } } return RendererUtilities.calculateOGCScale(envelope, paintArea.width, hints); }
/** * First searches the hints for the scale denominator hint otherwise calls * {@link #calculateScale(Envelope, CoordinateReferenceSystem, int, int, double)}. If * the hints contains a DPI then that DPI is used otherwise 90 is used (the OGS default). */ public static double calculateScale(ReferencedEnvelope envelope, int imageWidth,int imageHeight, Map hints ) throws TransformException, FactoryException { if( hints!=null && hints.containsKey("declaredScaleDenominator")){ Double scale=(Double) hints.get("declaredScaleDenominator"); if( scale.doubleValue()<=0 ) throw new IllegalArgumentException("the declaredScaleDenominator must be greater than 0, was: "+scale.doubleValue()); return scale.doubleValue(); } return calculateScale(envelope, imageWidth, imageHeight, getDpi(hints)); }
/** * Applies Unit Of Measure rescaling against all symbolizers, the result will be symbolizers * that operate purely in pixels * @param lfts */ void applyUnitRescale(final ArrayList<LiteFeatureTypeStyle> lfts) { // apply dpi rescale double dpi = RendererUtilities.getDpi(getRendererHints()); double standardDpi = RendererUtilities.getDpi(Collections.emptyMap()); if(dpi != standardDpi) { double scaleFactor = dpi / standardDpi; DpiRescaleStyleVisitor dpiVisitor = new DpiRescaleStyleVisitor(scaleFactor); for(LiteFeatureTypeStyle fts : lfts) { rescaleFeatureTypeStyle(fts, dpiVisitor); } } // apply UOM rescaling double pixelsPerMeters = RendererUtilities.calculatePixelsPerMeterRatio(scaleDenominator, rendererHints); UomRescaleStyleVisitor rescaleVisitor = new UomRescaleStyleVisitor(pixelsPerMeters); for(LiteFeatureTypeStyle fts : lfts) { rescaleFeatureTypeStyle(fts, rescaleVisitor); } }
/** * This method performs the computation using the methods suggested by the OGC SLD * specification, page 26. * * @param CRS the coordinate reference system. Used to check if we are operating in degrees or * meters. * @param worldToScreen the transformation mapping world coordinates to screen coordinates. * Might specify a rotation in addition to translation and scaling. * @return */ public static double calculateOGCScaleAffine( CoordinateReferenceSystem crs, AffineTransform worldToScreen, Map hints) { double scale = XAffineTransform.getScale(worldToScreen); // if it's geodetic, we're dealing with lat/lon unit measures if (crs instanceof GeographicCRS) { return (OGC_DEGREE_TO_METERS * getDpi(hints)) / (scale * 0.0254); } else { return (getDpi(hints)) / (scale * 0.0254); } }
worldToScreen.translate(-offset, -offset); AffineTransform at = new AffineTransform(worldToScreen); Envelope env = RendererUtilities.createMapEnvelope(paintArea, at); assertEnvelopeEquals( new Envelope(offset, offset + 1600, offset, offset + 1200), env, 0.001); env = RendererUtilities.createMapEnvelope(paintArea, at); assertEnvelopeEquals( new Envelope(-offset, -offset + 1600, -offset, -offset + 1200), env, 0.001); env = RendererUtilities.createMapEnvelope(paintArea, at); assertEnvelopeEquals( new Envelope(offset, offset + 1200, offset - 1600, offset), env, 0.0001); at = new AffineTransform(worldToScreen); at.rotate(Math.PI / 4.0, offset, offset); env = RendererUtilities.createMapEnvelope(paintArea, at); assertEnvelopeEquals( new Envelope(