"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "modules/library/render/src/main/java/org/geotools/renderer/lite/StreamingRenderer.java" between
geotools-21.1-project.zip and geotools-21.2-project.zip

About: GeoTools (The Open Source Java GIS Toolkit) is a Java code library which provides standards compliant methods for the manipulation of geospatial data.

StreamingRenderer.java  (geotools-21.1-project):StreamingRenderer.java  (geotools-21.2-project)
skipping to change at line 22 skipping to change at line 22
* This library is distributed in the hope that it will be useful, * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. * Lesser General Public License for more details.
*/ */
package org.geotools.renderer.lite; package org.geotools.renderer.lite;
import static java.lang.Math.abs; import static java.lang.Math.abs;
import com.conversantmedia.util.concurrent.PushPullBlockingQueue; import com.conversantmedia.util.concurrent.PushPullBlockingQueue;
import com.conversantmedia.util.concurrent.SpinPolicy;
import java.awt.AlphaComposite; import java.awt.AlphaComposite;
import java.awt.Composite; import java.awt.Composite;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.RenderingHints; import java.awt.RenderingHints;
import java.awt.RenderingHints.Key; import java.awt.RenderingHints.Key;
import java.awt.Shape; import java.awt.Shape;
import java.awt.font.GlyphVector; import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage; import java.awt.image.RenderedImage;
import java.io.IOException; import java.io.IOException;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.IdentityHashMap; import java.util.IdentityHashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.Spliterator; import java.util.Spliterator;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
skipping to change at line 106 skipping to change at line 109
import org.geotools.map.MapContent; import org.geotools.map.MapContent;
import org.geotools.map.MapContext; import org.geotools.map.MapContext;
import org.geotools.map.MapLayer; import org.geotools.map.MapLayer;
import org.geotools.map.StyleLayer; import org.geotools.map.StyleLayer;
import org.geotools.referencing.CRS; import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS; import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.referencing.operation.matrix.XAffineTransform; import org.geotools.referencing.operation.matrix.XAffineTransform;
import org.geotools.referencing.operation.transform.AffineTransform2D; import org.geotools.referencing.operation.transform.AffineTransform2D;
import org.geotools.referencing.operation.transform.ConcatenatedTransform; import org.geotools.referencing.operation.transform.ConcatenatedTransform;
import org.geotools.referencing.operation.transform.ProjectiveTransform; import org.geotools.referencing.operation.transform.ProjectiveTransform;
import org.geotools.referencing.operation.transform.WarpBuilder;
import org.geotools.renderer.GTRenderer; import org.geotools.renderer.GTRenderer;
import org.geotools.renderer.RenderListener; import org.geotools.renderer.RenderListener;
import org.geotools.renderer.crs.ProjectionHandler; import org.geotools.renderer.crs.ProjectionHandler;
import org.geotools.renderer.crs.ProjectionHandlerFinder; import org.geotools.renderer.crs.ProjectionHandlerFinder;
import org.geotools.renderer.crs.WrappingProjectionHandler;
import org.geotools.renderer.label.LabelCacheImpl; import org.geotools.renderer.label.LabelCacheImpl;
import org.geotools.renderer.label.LabelCacheImpl.LabelRenderingMode; import org.geotools.renderer.label.LabelCacheImpl.LabelRenderingMode;
import org.geotools.renderer.lite.gridcoverage2d.GridCoverageReaderHelper; import org.geotools.renderer.lite.gridcoverage2d.GridCoverageReaderHelper;
import org.geotools.renderer.lite.gridcoverage2d.GridCoverageRenderer; import org.geotools.renderer.lite.gridcoverage2d.GridCoverageRenderer;
import org.geotools.renderer.style.LineStyle2D; import org.geotools.renderer.style.LineStyle2D;
import org.geotools.renderer.style.SLDStyleFactory; import org.geotools.renderer.style.SLDStyleFactory;
import org.geotools.renderer.style.Style2D; import org.geotools.renderer.style.Style2D;
import org.geotools.renderer.style.StyleAttributeExtractor; import org.geotools.renderer.style.StyleAttributeExtractor;
import org.geotools.styling.FeatureTypeStyle; import org.geotools.styling.FeatureTypeStyle;
import org.geotools.styling.PointSymbolizer; import org.geotools.styling.PointSymbolizer;
skipping to change at line 368 skipping to change at line 373
public static final String CONTINUOUS_MAP_WRAPPING = "continuousMapWrapping" ; public static final String CONTINUOUS_MAP_WRAPPING = "continuousMapWrapping" ;
/** /**
* Boolean flag indicating whether vector rendering should be preferred when painting graphic * Boolean flag indicating whether vector rendering should be preferred when painting graphic
* fills. See {@link SLDStyleFactory#isVectorRenderingEnabled()} for more de tails. * fills. See {@link SLDStyleFactory#isVectorRenderingEnabled()} for more de tails.
*/ */
public static final String VECTOR_RENDERING_KEY = "vectorRenderingEnabled"; public static final String VECTOR_RENDERING_KEY = "vectorRenderingEnabled";
private static boolean VECTOR_RENDERING_ENABLED_DEFAULT = false; private static boolean VECTOR_RENDERING_ENABLED_DEFAULT = false;
/**
* Boolean flag indicating whether advanced projection densification should
be used when needed.
*/
public static final String ADVANCED_PROJECTION_DENSIFICATION_KEY =
"advancedProjectionDensificationEnabled";
private static boolean ADVANCED_PROJECTION_DENSIFICATION_DEFAULT = false;
/** Densification Tolerance, to be used when densification is enabled. */
public static final String ADVANCED_PROJECTION_DENSIFICATION_TOLERANCE_KEY =
"advancedProjectionDensificationTolerance";
private static double ADVANCED_PROJECTION_DENSIFICATION_TOLERANCE_DEFAULT =
0.8;
/**
* Boolean flag indicating whether advanced projection wrapping heuristic sh
ould be used or nto.
*/
public static final String DATELINE_WRAPPING_HEURISTIC_KEY = "datelineWrappi
ngCheckEnabled";
private static boolean DATELINE_WRAPPING_HEURISTIC_DEFAULT = true;
public static final String LABEL_CACHE_KEY = "labelCache"; public static final String LABEL_CACHE_KEY = "labelCache";
public static final String FORCE_EPSG_AXIS_ORDER_KEY = "ForceEPSGAxisOrder"; public static final String FORCE_EPSG_AXIS_ORDER_KEY = "ForceEPSGAxisOrder";
public static final String DPI_KEY = "dpi"; public static final String DPI_KEY = "dpi";
public static final String DECLARED_SCALE_DENOM_KEY = "declaredScaleDenomina tor"; public static final String DECLARED_SCALE_DENOM_KEY = "declaredScaleDenomina tor";
public static final String SCALE_COMPUTATION_METHOD_KEY = "scaleComputationM ethod"; public static final String SCALE_COMPUTATION_METHOD_KEY = "scaleComputationM ethod";
public static final String BYLAYER_INTERPOLATION = "byLayerInterpolation"; public static final String BYLAYER_INTERPOLATION = "byLayerInterpolation";
/** /**
* "vectorRenderingEnabled" - Boolean yes/no (see default vectorRenderingEna bledDEFAULT) * "vectorRenderingEnabled" - Boolean yes/no (see default vectorRenderingEna bledDEFAULT)
* "declaredScaleDenominator" - Double the value of the scale denominator to use by the * "declaredScaleDenominator" - Double the value of the scale denominator to use by the
skipping to change at line 406 skipping to change at line 432
* layer we will set this flag depending on whether the datastore can do ful l generalization for * layer we will set this flag depending on whether the datastore can do ful l generalization for
* us, or not * us, or not
*/ */
// private boolean inMemoryGeneralization = true; // private boolean inMemoryGeneralization = true;
/** The thread pool used to submit the painter workers. */ /** The thread pool used to submit the painter workers. */
private ExecutorService threadPool; private ExecutorService threadPool;
private PainterThread painterThread; private PainterThread painterThread;
private static int MAX_PIXELS_DENSIFY =
Integer.valueOf(System.getProperty("ADVANCED_PROJECTION_DENSIFY_MAX_
PIXELS", "5"));
/** /**
* Creates a new instance of LiteRenderer without a context. Use it only to gain access to * Creates a new instance of LiteRenderer without a context. Use it only to gain access to
* utility methods of this class or if you want to render random feature col lections instead of * utility methods of this class or if you want to render random feature col lections instead of
* using the map context interface * using the map context interface
*/ */
public StreamingRenderer() {} public StreamingRenderer() {}
/** /**
* Sets a thread pool to be used in parallel rendering * Sets a thread pool to be used in parallel rendering
* *
skipping to change at line 1070 skipping to change at line 1099
// see what attributes we really need by exploring the styles // see what attributes we really need by exploring the styles
// for testing purposes we have a null case --> // for testing purposes we have a null case -->
try { try {
// Then create the geometry filters. We have to create one for // Then create the geometry filters. We have to create one for
// each geometric attribute used during the rendering as the // each geometric attribute used during the rendering as the
// feature may have more than one and the styles could use non // feature may have more than one and the styles could use non
// default geometric ones // default geometric ones
List<ReferencedEnvelope> envelopes = null; List<ReferencedEnvelope> envelopes = null;
// enable advanced projection handling with the updated map extent // enable advanced projection handling with the updated map extent
if (isAdvancedProjectionHandlingEnabled()) { if (isAdvancedProjectionHandlingEnabled()) {
Map projectionHints = new HashMap();
if (isAdvancedProjectionDensificationEnabled()
&& !CRS.equalsIgnoreMetadata(featCrs, mapCRS)) {
double tolerance = getAdvancedProjectionDensificationToleran
ce();
if (tolerance > 0.0) {
ReferencedEnvelope targetEnvelope = envelope;
ReferencedEnvelope sourceEnvelope =
transformEnvelope(targetEnvelope, featCrs);
AffineTransform at = worldToScreenTransform;
AffineTransform screenToWorldTransform = new AffineTrans
form(at);
screenToWorldTransform.invert();
MathTransform2D crsTransform =
(MathTransform2D)
CRS.findMathTransform(
CRS.getHorizontalCRS(featCrs),
CRS.getHorizontalCRS(mapCRS));
MathTransform2D screenTransform = new AffineTransform2D(
at);
MathTransform2D fullTranform =
(MathTransform2D)
ConcatenatedTransform.create(crsTransfor
m, screenTransform);
Rectangle2D.Double sourceDomain =
new Rectangle2D.Double(
sourceEnvelope.getMinX(),
sourceEnvelope.getMinY(),
sourceEnvelope.getWidth(),
sourceEnvelope.getHeight());
WarpBuilder wb = new WarpBuilder(tolerance);
double densifyDistance = 0.0;
int[] actualSplit =
wb.isValidDomain(sourceDomain)
? wb.getRowColsSplit(fullTranform, sourc
eDomain)
: null;
double minDistance =
Math.min(
MAX_PIXELS_DENSIFY
* sourceEnvelope.getWidth()
/ screenSize.getWidth(),
MAX_PIXELS_DENSIFY
* sourceEnvelope.getHeight()
/ screenSize.getHeight());
if (actualSplit == null) {
// alghoritm gave up, we decide to use a fixed dista
nce value
densifyDistance = minDistance;
} else if (actualSplit[0] != 1 || actualSplit[1] != 1) {
densifyDistance =
Math.max(
Math.min(
sourceEnvelope.getWidth() /
actualSplit[0],
sourceEnvelope.getHeight() /
actualSplit[1]),
minDistance);
}
if (densifyDistance > 0.0) {
projectionHints.put(
ProjectionHandler.ADVANCED_PROJECTION_DENSIF
Y, densifyDistance);
}
}
}
if (!isWrappingHeuristicEnabled()) {
projectionHints.put(
WrappingProjectionHandler.DATELINE_WRAPPING_CHECK_EN
ABLED, false);
}
// get the projection handler and set a tentative envelope // get the projection handler and set a tentative envelope
ProjectionHandler projectionHandler = ProjectionHandler projectionHandler =
ProjectionHandlerFinder.getHandler( ProjectionHandlerFinder.getHandler(
envelope, featCrs, isMapWrappingEnabled()); envelope, featCrs, isMapWrappingEnabled(), proje ctionHints);
if (projectionHandler != null) { if (projectionHandler != null) {
setProjectionHandler(styleList, projectionHandler); setProjectionHandler(styleList, projectionHandler);
envelopes = projectionHandler.getQueryEnvelopes(); envelopes = projectionHandler.getQueryEnvelopes();
} }
} }
if (envelopes == null) { if (envelopes == null) {
if (mapCRS != null if (mapCRS != null
&& featCrs != null && featCrs != null
&& !CRS.equalsIgnoreMetadata(featCrs, mapCRS)) { && !CRS.equalsIgnoreMetadata(featCrs, mapCRS)) {
envelopes = Collections.singletonList(envelope.transform(fea tCrs, true, 10)); envelopes = Collections.singletonList(envelope.transform(fea tCrs, true, 10));
skipping to change at line 1217 skipping to change at line 1308
// simplify the filter // simplify the filter
SimplifyingFilterVisitor simplifier = new SimplifyingFilterVisitor(); SimplifyingFilterVisitor simplifier = new SimplifyingFilterVisitor();
simplifier.setFeatureType(source.getSchema()); simplifier.setFeatureType(source.getSchema());
Filter simplifiedFilter = (Filter) query.getFilter().accept(simplifier, null); Filter simplifiedFilter = (Filter) query.getFilter().accept(simplifier, null);
query.setFilter(simplifiedFilter); query.setFilter(simplifiedFilter);
return query; return query;
} }
private ReferencedEnvelope transformEnvelope(
ReferencedEnvelope envelope, CoordinateReferenceSystem crs)
throws TransformException, FactoryException {
try {
ProjectionHandler projectionHandler =
ProjectionHandlerFinder.getHandler(envelope, crs, isMapWrapp
ingEnabled());
return projectionHandler.getProjectedEnvelope(envelope, crs);
} catch (FactoryException e) {
return envelope.transform(crs, true);
}
}
private void setMetaBuffer(List<LiteFeatureTypeStyle> styleList, int metaBuf fer) { private void setMetaBuffer(List<LiteFeatureTypeStyle> styleList, int metaBuf fer) {
for (LiteFeatureTypeStyle fts : styleList) { for (LiteFeatureTypeStyle fts : styleList) {
fts.metaBuffer = metaBuffer; fts.metaBuffer = metaBuffer;
} }
} }
private void setProjectionHandler( private void setProjectionHandler(
List<LiteFeatureTypeStyle> styleList, ProjectionHandler projectionHa ndler) { List<LiteFeatureTypeStyle> styleList, ProjectionHandler projectionHa ndler) {
for (LiteFeatureTypeStyle fts : styleList) { for (LiteFeatureTypeStyle fts : styleList) {
fts.projectionHandler = projectionHandler; fts.projectionHandler = projectionHandler;
skipping to change at line 1553 skipping to change at line 1656
* Checks if vector rendering is enabled or not. See {@link * Checks if vector rendering is enabled or not. See {@link
* SLDStyleFactory#isVectorRenderingEnabled()} for a full explanation. * SLDStyleFactory#isVectorRenderingEnabled()} for a full explanation.
*/ */
private boolean isVectorRenderingEnabled() { private boolean isVectorRenderingEnabled() {
if (rendererHints == null) return true; if (rendererHints == null) return true;
Object result = rendererHints.get(VECTOR_RENDERING_KEY); Object result = rendererHints.get(VECTOR_RENDERING_KEY);
if (result == null) return VECTOR_RENDERING_ENABLED_DEFAULT; if (result == null) return VECTOR_RENDERING_ENABLED_DEFAULT;
return ((Boolean) result).booleanValue(); return ((Boolean) result).booleanValue();
} }
/** Checks if advanced projection densification is enabled or not. */
private boolean isAdvancedProjectionDensificationEnabled() {
if (rendererHints == null) return false;
Object result = rendererHints.get(ADVANCED_PROJECTION_DENSIFICATION_KEY)
;
if (result == null) return ADVANCED_PROJECTION_DENSIFICATION_DEFAULT;
return ((Boolean) result).booleanValue();
}
private double getAdvancedProjectionDensificationTolerance() {
if (rendererHints == null) return ADVANCED_PROJECTION_DENSIFICATION_TOLE
RANCE_DEFAULT;
Object result = rendererHints.get(ADVANCED_PROJECTION_DENSIFICATION_TOLE
RANCE_KEY);
if (result == null) return ADVANCED_PROJECTION_DENSIFICATION_TOLERANCE_D
EFAULT;
return ((Double) result).doubleValue();
}
/** Checks if advanced projection wrapping heuristic should be enabled. */
private boolean isWrappingHeuristicEnabled() {
if (rendererHints == null) return true;
Object result = rendererHints.get(DATELINE_WRAPPING_HEURISTIC_KEY);
if (result == null) return DATELINE_WRAPPING_HEURISTIC_DEFAULT;
return ((Boolean) result).booleanValue();
}
/** /**
* Returns an estimate of the rendering buffer needed to properly display th is layer taking into * Returns an estimate of the rendering buffer needed to properly display th is layer taking into
* consideration the constant stroke sizes in the feature type styles. * consideration the constant stroke sizes in the feature type styles.
* *
* @param styles the feature type styles to be applied to the layer * @param styles the feature type styles to be applied to the layer
* @return an estimate of the buffer that should be used to properly display a layer rendered * @return an estimate of the buffer that should be used to properly display a layer rendered
* with the specified styles * with the specified styles
*/ */
private int findRenderingBuffer(List<LiteFeatureTypeStyle> styles) { private int findRenderingBuffer(List<LiteFeatureTypeStyle> styles) {
final MetaBufferEstimator rbe = new MetaBufferEstimator(); final MetaBufferEstimator rbe = new MetaBufferEstimator();
skipping to change at line 3492 skipping to change at line 3618
void execute() { void execute() {
if (graphics instanceof DelayedBackbufferGraphic) { if (graphics instanceof DelayedBackbufferGraphic) {
((DelayedBackbufferGraphic) graphics).init(); ((DelayedBackbufferGraphic) graphics).init();
} }
for (LiteFeatureTypeStyle currentLayer : lfts) { for (LiteFeatureTypeStyle currentLayer : lfts) {
// first fts won't have an image, it's using the user provided g raphics // first fts won't have an image, it's using the user provided g raphics
// straight, so we don't need to compose it back in. // straight, so we don't need to compose it back in.
final Graphics2D ftsGraphics = currentLayer.graphics; final Graphics2D ftsGraphics = currentLayer.graphics;
if (ftsGraphics instanceof DelayedBackbufferGraphic && !(ftsGrap hics == graphics)) { if (ftsGraphics instanceof DelayedBackbufferGraphic && !(ftsGrap hics == graphics)) {
final BufferedImage image = ((DelayedBackbufferGraphic) ftsG BufferedImage image = ((DelayedBackbufferGraphic) ftsGraphic
raphics).image; s).image;
// we may have not found anything to paint, in that case the if (currentLayer.composite == null) {
delegate graphics.setComposite(AlphaComposite.SrcOver);
// has not been initialized } else {
if (image != null) { // we may have not found anything to paint, in that case
if (currentLayer.composite == null) { the delegate
graphics.setComposite(AlphaComposite.SrcOver); // has not been initialized
} else { if (image == null) {
graphics.setComposite(currentLayer.composite); Rectangle size = ((DelayedBackbufferGraphic) ftsGrap
hics).screenSize;
image =
new BufferedImage(
size.width, size.height, BufferedIma
ge.TYPE_4BYTE_ABGR);
} }
graphics.setComposite(currentLayer.composite);
}
if (image != null) {
graphics.drawImage(image, 0, 0, null); graphics.drawImage(image, 0, 0, null);
ftsGraphics.dispose(); ftsGraphics.dispose();
} }
} }
} }
} }
} }
protected class MargeCompositingGroupRequest extends RenderingRequest { protected class MargeCompositingGroupRequest extends RenderingRequest {
Graphics2D graphics; Graphics2D graphics;
skipping to change at line 3811 skipping to change at line 3943
* has been requested: puts are getting ignored, and take always returns an EndRequest * has been requested: puts are getting ignored, and take always returns an EndRequest
* *
* @author Andrea Aime - GeoSolutions * @author Andrea Aime - GeoSolutions
*/ */
public class RenderingBlockingQueue implements BlockingQueue<RenderingReques t> { public class RenderingBlockingQueue implements BlockingQueue<RenderingReques t> {
private static final long serialVersionUID = 4908029658595573833L; private static final long serialVersionUID = 4908029658595573833L;
PushPullBlockingQueue<RenderingRequest> delegate; PushPullBlockingQueue<RenderingRequest> delegate;
public RenderingBlockingQueue(int capacity) { public RenderingBlockingQueue(int capacity) {
this.delegate = new PushPullBlockingQueue<>(capacity); this.delegate = new PushPullBlockingQueue<>(capacity, SpinPolicy.BLO CKING);
} }
@Override @Override
public boolean add(RenderingRequest renderingRequest) { public boolean add(RenderingRequest renderingRequest) {
return delegate.add(renderingRequest); return delegate.add(renderingRequest);
} }
@Override @Override
public boolean offer(RenderingRequest renderingRequest) { public boolean offer(RenderingRequest renderingRequest) {
return delegate.offer(renderingRequest); return delegate.offer(renderingRequest);
 End of changes. 14 change blocks. 
12 lines changed or deleted 166 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)