Andrea Aime ha scritto:
So I've followed that lead and hacked a very crude
proof of concept patch that would skip the rendering
architecture fully and just encode out the result
of the raster symbolizer, appropriately rescaled.
Using it works fine as long as the coverage is not
rotated and the image requested is fully within
the coverage definition area (both conditions are
satisfied in the OSGEO benchmarks).
Ah, the patch contained an error, the final affine transform
was not applied for good. I'm rerunning the benchmarks
and it does not seem to make much of a difference anyways,
so the good speedups hold.
But if you want to try it on your machine better use
the one attached to this mail
Cheers
Andrea
--
Andrea Aime
OpenGeo - http://opengeo.org
Expert service straight from the developers.
Index: src/main/java/org/vfny/geoserver/wms/responses/DefaultRasterMapProducer.java
===================================================================
--- src/main/java/org/vfny/geoserver/wms/responses/DefaultRasterMapProducer.java (revisione 13825)
+++ src/main/java/org/vfny/geoserver/wms/responses/DefaultRasterMapProducer.java (copia locale)
@@ -5,15 +5,32 @@
package org.vfny.geoserver.wms.responses;
import java.awt.Color;
+import java.awt.Composite;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.Image;
+import java.awt.Paint;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.RenderingHints.Key;
+import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphVector;
+import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
+import java.awt.image.BufferedImageOp;
+import java.awt.image.ImageObserver;
import java.awt.image.IndexColorModel;
import java.awt.image.RenderedImage;
+import java.awt.image.renderable.RenderableImage;
import java.io.File;
import java.io.OutputStream;
+import java.text.AttributedCharacterIterator;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -28,6 +45,7 @@
import javax.media.jai.InterpolationNearest;
import javax.media.jai.JAI;
import javax.media.jai.LookupTableJAI;
+import javax.media.jai.operator.AffineDescriptor;
import javax.media.jai.operator.LookupDescriptor;
import org.geoserver.platform.ServiceException;
@@ -40,13 +58,25 @@
import org.geoserver.wms.responses.MapDecorationLayout;
import org.geoserver.wms.responses.MetatiledMapDecorationLayout;
import org.geoserver.wms.responses.decoration.WatermarkDecoration;
+import org.geotools.coverage.grid.GridCoverage2D;
+import org.geotools.coverage.grid.GridEnvelope2D;
+import org.geotools.coverage.grid.GridGeometry2D;
+import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
+import org.geotools.coverage.grid.io.AbstractGridFormat;
import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.map.DefaultMapContext;
import org.geotools.map.MapLayer;
+import org.geotools.parameter.Parameter;
+import org.geotools.renderer.lite.RendererUtilities;
import org.geotools.renderer.lite.StreamingRenderer;
+import org.geotools.renderer.lite.gridcoverage2d.GridCoverageRenderer;
import org.geotools.renderer.shape.ShapefileRenderer;
import org.geotools.styling.PointSymbolizer;
import org.geotools.styling.Style;
import org.geotools.styling.visitor.DuplicatingStyleVisitor;
+import org.opengis.feature.Feature;
+import org.opengis.parameter.GeneralParameterValue;
+import org.opengis.style.RasterSymbolizer;
import org.vfny.geoserver.global.GeoserverDataDirectory;
import org.vfny.geoserver.wms.RasterMapProducer;
import org.vfny.geoserver.wms.WMSMapContext;
@@ -192,6 +222,11 @@
} catch (Exception e) {
throw new WmsException(e);
}
+
+ if(true) {
+ directRasterRender(mapContext);
+ return;
+ }
Rectangle paintArea = new Rectangle(
0, 0,
@@ -601,5 +636,521 @@
RenderingHints hints = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout);
return LookupDescriptor.create(source, IDENTITY_TABLE, hints);
}
+
+ private void directRasterRender(WMSMapContext mapContext) {
+ try {
+ Feature feature = mapContext.getLayer(0).getFeatureSource().getFeatures().features().next();
+ AbstractGridCoverage2DReader reader = (AbstractGridCoverage2DReader) feature.getProperty("grid").getValue();
+ org.geotools.styling.RasterSymbolizer symbolizer = (org.geotools.styling.RasterSymbolizer)
+ mapContext.getLayer(0).getStyle().featureTypeStyles().get(0).rules().get(0).symbolizers().get(0);
+ GridCoverage2D coverage;
+
+ Rectangle paintArea = new Rectangle(0, 0, mapContext.getMapWidth(), mapContext.getMapHeight());
+ AffineTransform worldToScreen = RendererUtilities.worldToScreenTransform(mapContext.getAreaOfInterest(), paintArea);
+ final GridCoverageRenderer gcr = new GridCoverageRenderer(mapContext.getCoordinateReferenceSystem() , mapContext.getAreaOfInterest(),
+ paintArea, worldToScreen, null);
+
+ // //
+ // It is an AbstractGridCoverage2DReader, let's use parameters
+ // if we have any supplied by a user.
+ // //
+ // first I created the correct ReadGeometry
+ final Parameter<GridGeometry2D> readGG = new Parameter<GridGeometry2D>(AbstractGridFormat.READ_GRIDGEOMETRY2D);
+ readGG.setValue(new GridGeometry2D(new GridEnvelope2D(paintArea),
+ mapContext.getAreaOfInterest()));
+ // then I try to get read parameters associated with this
+ // coverage if there are any.
+ final Object params = feature.getProperty("params").getValue();
+ if (params != null) {
+ // //
+ //
+ // Getting parameters to control how to read this coverage.
+ // Remember to check to actually have them before forwarding
+ // them to the reader.
+ //
+ // //
+ GeneralParameterValue[] readParams = (GeneralParameterValue[]) params;
+ final int length = readParams.length;
+ if (length > 0) {
+ // we have a valid number of parameters, let's check if
+ // also have a READ_GRIDGEOMETRY2D. In such case we just
+ // override it with the one we just build for this
+ // request.
+ final String name = AbstractGridFormat.READ_GRIDGEOMETRY2D
+ .getName().toString();
+ int i = 0;
+ for (; i < length; i++)
+ if (readParams[i].getDescriptor().getName()
+ .toString().equalsIgnoreCase(name))
+ break;
+ // did we find anything?
+ if (i < length) {
+ //we found another READ_GRIDGEOMETRY2D, let's override it.
+ ((Parameter) readParams[i]).setValue(readGG);
+ coverage = (GridCoverage2D) reader.read(readParams);
+ } else {
+ // add the correct read geometry to the supplied
+ // params since we did not find anything
+ GeneralParameterValue[] readParams2 = new GeneralParameterValue[length + 1];
+ System.arraycopy(readParams, 0, readParams2, 0,length);
+ readParams2[length] = readGG;
+ coverage = (GridCoverage2D) reader.read(readParams2);
+ }
+ } else
+ // we have no parameters hence we just use the read grid
+ // geometry to get a coverage
+ coverage = (GridCoverage2D) reader.read(new GeneralParameterValue[] { readGG });
+ } else {
+ coverage = (GridCoverage2D) reader.read(new GeneralParameterValue[] { readGG });
+ }
+ try{
+ if(coverage!=null) {
+ FakeGraphics2D g2d = new FakeGraphics2D();
+ gcr.paint(g2d, coverage, symbolizer);
+ this.image = g2d.img;
+ }
+ } finally {
+ //we need to try and dispose this coverage since it was created on purpose for rendering
+ if(coverage!=null)
+ coverage.dispose(true);
+ }
+
+ } catch(Exception e) {
+ throw new WmsException(e);
+ }
+
+
+ }
+
+
+ class FakeGraphics2D extends Graphics2D {
+
+ private RenderedImage img;
+
+ @Override
+ public void addRenderingHints(Map<?, ?> hints) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void clip(Shape s) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void draw(Shape s) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void drawGlyphVector(GlyphVector g, float x, float y) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void drawRenderableImage(RenderableImage img, AffineTransform xform) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void drawRenderedImage(RenderedImage img, AffineTransform xform) {
+ this.img = AffineDescriptor.create(img, xform, new InterpolationNearest(), null, null);
+ }
+
+ @Override
+ public void drawString(String str, int x, int y) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void drawString(String s, float x, float y) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void drawString(AttributedCharacterIterator iterator, int x, int y) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void drawString(AttributedCharacterIterator iterator, float x, float y) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void fill(Shape s) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public Color getBackground() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Composite getComposite() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public GraphicsConfiguration getDeviceConfiguration() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public FontRenderContext getFontRenderContext() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Paint getPaint() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Object getRenderingHint(Key hintKey) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public RenderingHints getRenderingHints() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Stroke getStroke() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public AffineTransform getTransform() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public boolean hit(Rectangle rect, Shape s, boolean onStroke) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public void rotate(double theta) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void rotate(double theta, double x, double y) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void scale(double sx, double sy) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void setBackground(Color color) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void setComposite(Composite comp) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void setPaint(Paint paint) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void setRenderingHint(Key hintKey, Object hintValue) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void setRenderingHints(Map<?, ?> hints) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void setStroke(Stroke s) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void setTransform(AffineTransform Tx) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void shear(double shx, double shy) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void transform(AffineTransform Tx) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void translate(int x, int y) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void translate(double tx, double ty) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void clearRect(int x, int y, int width, int height) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void clipRect(int x, int y, int width, int height) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void copyArea(int x, int y, int width, int height, int dx, int dy) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public Graphics create() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void dispose() {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public boolean drawImage(Image img, int x, int y, ImageObserver observer) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean drawImage(Image img, int x, int y, Color bgcolor, ImageObserver observer) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean drawImage(Image img, int x, int y, int width, int height,
+ ImageObserver observer) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean drawImage(Image img, int x, int y, int width, int height, Color bgcolor,
+ ImageObserver observer) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1,
+ int sx2, int sy2, ImageObserver observer) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1,
+ int sx2, int sy2, Color bgcolor, ImageObserver observer) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public void drawLine(int x1, int y1, int x2, int y2) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void drawOval(int x, int y, int width, int height) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void fillOval(int x, int y, int width, int height) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void fillRect(int x, int y, int width, int height) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public Shape getClip() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Rectangle getClipBounds() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Color getColor() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Font getFont() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public FontMetrics getFontMetrics(Font f) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void setClip(Shape clip) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void setClip(int x, int y, int width, int height) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void setColor(Color c) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void setFont(Font font) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void setPaintMode() {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void setXORMode(Color c1) {
+ // TODO Auto-generated method stub
+
+ }
+
+ }
+
}
------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev
_______________________________________________
Geoserver-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geoserver-devel