[Schmitzm-commits] r340 - in branches/1.0-gt2-2.6/src: org/geotools/renderer/shape schmitzm/geotools schmitzm/geotools/gui
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Fri Aug 28 13:13:52 CEST 2009
Author: alfonx
Date: 2009-08-28 13:13:50 +0200 (Fri, 28 Aug 2009)
New Revision: 340
Modified:
branches/1.0-gt2-2.6/src/org/geotools/renderer/shape/TransitionShapefileRenderer.java
branches/1.0-gt2-2.6/src/schmitzm/geotools/FilterUtil.java
branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/JMapPane.java
Log:
* Replaced the TransitionShapefileRenderer with the latest 2.6 version (without the hack ATM)
Modified: branches/1.0-gt2-2.6/src/org/geotools/renderer/shape/TransitionShapefileRenderer.java
===================================================================
--- branches/1.0-gt2-2.6/src/org/geotools/renderer/shape/TransitionShapefileRenderer.java 2009-08-28 10:45:01 UTC (rev 339)
+++ branches/1.0-gt2-2.6/src/org/geotools/renderer/shape/TransitionShapefileRenderer.java 2009-08-28 11:13:50 UTC (rev 340)
@@ -1,8 +1,9 @@
/*
- * Geotools2 - OpenSource mapping toolkit
+ * GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
- * (C) 2002, Geotools Project Managment Committee (PMC)
*
+ * (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
@@ -12,10 +13,13 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
*/
package org.geotools.renderer.shape;
+import static org.geotools.data.shapefile.ShpFileType.GRX;
+import static org.geotools.data.shapefile.ShpFileType.QIX;
+import static org.geotools.data.shapefile.ShpFileType.SHX;
+
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
@@ -24,19 +28,21 @@
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.io.IOException;
-import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.NoSuchElementException;
import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
-import javax.media.jai.util.Range;
+import javax.xml.parsers.FactoryConfigurationError;
import org.geotools.data.DataStore;
import org.geotools.data.DefaultQuery;
@@ -48,15 +54,18 @@
import org.geotools.data.TransactionStateDiff;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.shapefile.ShapefileRendererUtil;
+import org.geotools.data.shapefile.ShpFiles;
import org.geotools.data.shapefile.dbf.DbaseFileHeader;
import org.geotools.data.shapefile.dbf.DbaseFileReader;
import org.geotools.data.shapefile.dbf.IndexedDbaseFileReader;
+import org.geotools.data.shapefile.indexed.IndexType;
import org.geotools.data.shapefile.shp.ShapeType;
import org.geotools.data.shapefile.shp.ShapefileReader;
import org.geotools.data.shapefile.shp.ShapefileReader.Record;
-import org.geotools.feature.FeatureTypeBuilder;
-import org.geotools.feature.GeometryAttributeType;
+import org.geotools.feature.FeatureTypes;
import org.geotools.feature.SchemaException;
+import org.geotools.feature.simple.SimpleFeatureBuilder;
+import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.filter.FilterAttributeExtractor;
import org.geotools.geometry.jts.Decimator;
import org.geotools.geometry.jts.LiteCoordinateSequenceFactory;
@@ -70,11 +79,12 @@
import org.geotools.referencing.ReferencingFactoryFinder;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.referencing.operation.matrix.GeneralMatrix;
+import org.geotools.referencing.operation.matrix.XAffineTransform;
import org.geotools.renderer.GTRenderer;
import org.geotools.renderer.RenderListener;
+import org.geotools.renderer.label.LabelCacheImpl;
import org.geotools.renderer.lite.LabelCache;
import org.geotools.renderer.lite.LabelCacheDefault;
-import org.geotools.renderer.lite.ListenerList;
import org.geotools.renderer.lite.RendererUtilities;
import org.geotools.renderer.lite.StreamingRenderer;
import org.geotools.renderer.style.SLDStyleFactory;
@@ -93,6 +103,7 @@
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
+import org.opengis.feature.type.GeometryDescriptor;
import org.opengis.filter.Filter;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
@@ -100,9 +111,6 @@
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
-import schmitzm.geotools.feature.FeatureOperationTreeFilter;
-import schmitzm.io.IOUtil;
-
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
@@ -121,122 +129,112 @@
* @author jeichar
* @since 2.1.x
* @source $URL:
- * http://svn.geotools.org/geotools/branches/2.2.x/ext/shaperenderer
- * /src/org/geotools/renderer/shape/ShapefileRenderer.java $
+ * http://svn.geotools.org/geotools/branches/2.2.x/ext/shaperenderer/src/org/geotools/renderer/shape/ShapefileRenderer.java $
*/
public class TransitionShapefileRenderer implements GTRenderer {
- public static final Logger logGt = org.geotools.util.logging.Logging
- .getLogger("org.geotools.renderer.shape");
+ public static final Logger LOGGER = org.geotools.util.logging.Logging.getLogger("org.geotools.renderer.shape");
- org.apache.log4j.Logger LOGGER = org.apache.log4j.Logger
- .getLogger(TransitionShapefileRenderer.class);
+ /** Tolerance used to compare doubles for equality */
+ private static final double TOLERANCE = 1e-6;
+ private static final GeometryFactory geomFactory = new GeometryFactory(
+ new LiteCoordinateSequenceFactory());
+ private static final Coordinate[] COORDS;
+ private static final MultiPolygon MULTI_POLYGON_GEOM;
+ private static final Polygon POLYGON_GEOM;
+ private static final LinearRing LINE_GEOM;
+ private static final MultiLineString MULTI_LINE_GEOM;
+ private static final Point POINT_GEOM;
+ private static final MultiPoint MULTI_POINT_GEOM;
+
+ /**
+ * Computes the scale as the ratio between map distances and real world distances,
+ * assuming 90dpi and taking into consideration projection deformations and actual
+ * earth shape. <br>
+ * Use this method only when in need of accurate computation. Will break if the
+ * data extent is outside of the currenct projection definition area.
+ */
+ public static final String SCALE_ACCURATE = "ACCURATE";
+
+ /**
+ * Very simple and lenient scale computation method that conforms to the OGC SLD
+ * specification 1.0, page 26. <br>This method is quite approximative, but should
+ * never break and ensure constant scale even on lat/lon unprojected maps (because
+ * in that case scale is computed as if the area was along the equator no matter
+ * what the real position is).
+ */
+ public static final String SCALE_OGC = "OGC";
+
+ private String scaleComputationMethodDEFAULT = SCALE_ACCURATE;
+ static {
+ COORDS = new Coordinate[5];
+ COORDS[0] = new Coordinate(0.0, 0.0);
+ COORDS[1] = new Coordinate(5.0, 0.0);
+ COORDS[2] = new Coordinate(5.0, 5.0);
+ COORDS[3] = new Coordinate(0.0, 5.0);
+ COORDS[4] = new Coordinate(0.0, 0.0);
+ LINE_GEOM = geomFactory.createLinearRing(COORDS);
+ MULTI_LINE_GEOM = geomFactory.createMultiLineString(new LineString[]{LINE_GEOM});
+ POLYGON_GEOM = geomFactory.createPolygon(LINE_GEOM, new LinearRing[0]);
+ MULTI_POLYGON_GEOM = geomFactory.createMultiPolygon(new Polygon[]{POLYGON_GEOM});
+ POINT_GEOM = geomFactory.createPoint(COORDS[2]);
+ MULTI_POINT_GEOM = geomFactory.createMultiPoint(COORDS);
+ }
- /** Tolerance used to compare doubles for equality */
- private static final double TOLERANCE = 1e-6;
- private static final GeometryFactory geomFactory = new GeometryFactory(
- new LiteCoordinateSequenceFactory());
- private static final Coordinate[] COORDS;
- private static final MultiPolygon MULTI_POLYGON_GEOM;
- private static final Polygon POLYGON_GEOM;
- private static final LinearRing LINE_GEOM;
- private static final MultiLineString MULTI_LINE_GEOM;
- private static final Point POINT_GEOM;
- private static final MultiPoint MULTI_POINT_GEOM;
+ /**
+ * This listener is added to the list of listeners automatically. It should be removed if the
+ * default logging is not needed.
+ */
+ public static final DefaultRenderListener DEFAULT_LISTENER = new DefaultRenderListener();
- /**
- * Computes the scale as the ratio between map distances and real world
- * distances, assuming 90dpi and taking into consideration projection
- * deformations and actual earth shape. <br>
- * Use this method only when in need of accurate computation. Will break if
- * the data extent is outside of the currenct projection definition area.
- */
- public static final String SCALE_ACCURATE = "ACCURATE";
+ private static final IndexInfo STREAMING_RENDERER_INFO = new IndexInfo(IndexType.NONE,null);
+ static int NUM_SAMPLES = 200;
+ private RenderingHints hints;
- /**
- * Very simple and lenient scale computation method that conforms to the OGC
- * SLD specification 1.0, page 26. <br>
- * This method is quite approximative, but should never break and ensure
- * constant scale even on lat/lon unprojected maps (because in that case
- * scale is computed as if the area was along the equator no matter what the
- * real position is).
- */
- public static final String SCALE_OGC = "OGC";
+ /** Factory that will resolve symbolizers into rendered styles */
+ private SLDStyleFactory styleFactory = new SLDStyleFactory();
+ private boolean renderingStopRequested;
+ private boolean concatTransforms;
+ private MapContext context;
+ LabelCache labelCache = new LabelCacheImpl();
+ private List<RenderListener> renderListeners = new CopyOnWriteArrayList<RenderListener>();
+ /** If we are caching styles; by default this is false */
+ boolean caching = false;
+ private double scaleDenominator;
+ DbaseFileHeader dbfheader;
+ private Object defaultGeom;
+ IndexInfo[] layerIndexInfo;
+ StreamingRenderer delegate;
- private final String scaleComputationMethodDEFAULT = SCALE_ACCURATE;
- static {
- COORDS = new Coordinate[5];
- COORDS[0] = new Coordinate(0.0, 0.0);
- COORDS[1] = new Coordinate(5.0, 0.0);
- COORDS[2] = new Coordinate(5.0, 5.0);
- COORDS[3] = new Coordinate(0.0, 5.0);
- COORDS[4] = new Coordinate(0.0, 0.0);
- LINE_GEOM = geomFactory.createLinearRing(COORDS);
- MULTI_LINE_GEOM = geomFactory
- .createMultiLineString(new LineString[] { LINE_GEOM });
- POLYGON_GEOM = geomFactory.createPolygon(LINE_GEOM, new LinearRing[0]);
- MULTI_POLYGON_GEOM = geomFactory
- .createMultiPolygon(new Polygon[] { POLYGON_GEOM });
- POINT_GEOM = geomFactory.createPoint(COORDS[2]);
- MULTI_POINT_GEOM = geomFactory.createMultiPoint(COORDS);
- }
+ /**
+ * Maps between the AttributeType index of the new generated FeatureType and the real
+ * attributeType
+ */
+ int[] attributeIndexing;
- /**
- * This listener is added to the list of listeners automatically. It should
- * be removed if the default logging is not needed.
- */
- public static final DefaultRenderListener DEFAULT_LISTENER = new DefaultRenderListener();
-
- private static final IndexInfo STREAMING_RENDERER_INFO = new IndexInfo(
- (byte) 0, null, null);
- static int NUM_SAMPLES = 200;
- private RenderingHints hints;
-
- /** Factory that will resolve symbolizers into rendered styles */
- private final SLDStyleFactory styleFactory = new SLDStyleFactory();
- private boolean renderingStopRequested;
- private boolean concatTransforms;
- private MapContext context;
- LabelCache labelCache = new LabelCacheDefault();
- private final ListenerList renderListeners = new ListenerList();
- boolean caching = false;
- private double scaleDenominator;
- DbaseFileHeader dbfheader;
- private Object defaultGeom;
- IndexInfo[] layerIndexInfo;
-
- /**
- * Maps between the AttributeDescriptor index of the new generated SimpleFeatureType and
- * the real attributeType
- */
- int[] attributeIndexing;
-
- /** The painter class we use to depict shapes onto the screen */
- private StyledShapePainter painter = new StyledShapePainter(labelCache);
- private final Map decimators = new HashMap();
-
- /**
- * Text will be rendered using the usual calls
- * gc.drawString/drawGlyphVector. This is a little faster, and more
- * consistent with how the platform renders the text in other applications.
- * The downside is that on most platform the label and its eventual halo are
- * not properly centered.
- */
- public static final String TEXT_RENDERING_STRING = "STRING";
-
- /**
- * Text will be rendered using the associated {@link GlyphVector} outline,
- * that is, a {@link Shape}. This ensures perfect centering between the text
- * and the halo, but introduces more text aliasing.
- */
- public static final String TEXT_RENDERING_OUTLINE = "OUTLINE";
-
- /**
- * The text rendering method, either TEXT_RENDERING_OUTLINE or
- * TEXT_RENDERING_STRING
- */
- public static final String TEXT_RENDERING_KEY = "textRenderingMethod";
- private final String textRenderingModeDEFAULT = TEXT_RENDERING_STRING;
-
+ /** The painter class we use to depict shapes onto the screen */
+ private StyledShapePainter painter = new StyledShapePainter(labelCache);
+ private Map decimators = new HashMap();
+
+ /**
+ * Text will be rendered using the usual calls gc.drawString/drawGlyphVector.
+ * This is a little faster, and more consistent with how the platform renders
+ * the text in other applications. The downside is that on most platform the label
+ * and its eventual halo are not properly centered.
+ */
+ public static final String TEXT_RENDERING_STRING = "STRING";
+
+ /**
+ * Text will be rendered using the associated {@link GlyphVector} outline, that is, a {@link Shape}.
+ * This ensures perfect centering between the text and the halo, but introduces more text aliasing.
+ */
+ public static final String TEXT_RENDERING_OUTLINE = "OUTLINE";
+
+ /**
+ * The text rendering method, either TEXT_RENDERING_OUTLINE or TEXT_RENDERING_STRING
+ */
+ public static final String TEXT_RENDERING_KEY = "textRenderingMethod";
+ private String textRenderingModeDEFAULT = TEXT_RENDERING_STRING;
+
public static final String LABEL_CACHE_KEY = "labelCache";
public static final String FORCE_CRS_KEY = "forceCRS";
public static final String DPI_KEY = "dpi";
@@ -244,1404 +242,1311 @@
public static final String MEMORY_PRE_LOADING_KEY = "memoryPreloadingEnabled";
public static final String OPTIMIZED_DATA_LOADING_KEY = "optimizedDataLoadingEnabled";
public static final String SCALE_COMPUTATION_METHOD_KEY = "scaleComputationMethod";
+
+ /**
+ * "optimizedDataLoadingEnabled" - Boolean yes/no (see default optimizedDataLoadingEnabledDEFAULT)
+ * "memoryPreloadingEnabled" - Boolean yes/no (see default memoryPreloadingEnabledDEFAULT)
+ * "declaredScaleDenominator" - Double the value of the scale denominator to use by the renderer.
+ * by default the value is calculated based on the screen size
+ * and the displayed area of the map.
+ * "dpi" - Integer number of dots per inch of the display 90 DPI is the default (as declared by OGC)
+ * "forceCRS" - CoordinateReferenceSystem declares to the renderer that all layers are of the CRS declared in this hint
+ * "labelCache" - Declares the label cache that will be used by the renderer.
+ */
+ private Map rendererHints = null;
- /**
- * "optimizedDataLoadingEnabled" - Boolean yes/no (see default
- * optimizedDataLoadingEnabledDEFAULT) "memoryPreloadingEnabled" - Boolean
- * yes/no (see default memoryPreloadingEnabledDEFAULT)
- * "declaredScaleDenominator" - Double the value of the scale denominator to
- * use by the renderer. by default the value is calculated based on the
- * screen size and the displayed area of the map. "dpi" - Integer number of
- * dots per inch of the display 90 DPI is the default (as declared by OGC)
- * "forceCRS" - CoordinateReferenceSystem declares to the renderer that all
- * layers are of the CRS declared in this hint "labelCache" - Declares the
- * label cache that will be used by the renderer.
- */
- private Map rendererHints = null;
+ public TransitionShapefileRenderer( MapContext context ) {
+ setContext(context);
+ }
- public TransitionShapefileRenderer(final MapContext context) {
-// LOGGER.debug("new tr instanciated with context");
- setContext(context);
- }
+ public TransitionShapefileRenderer() {
+ }
- public TransitionShapefileRenderer() {
-// LOGGER.debug("new tr instanciated without context");
- }
+ 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));
+ }
- public void paint(final Graphics2D graphics, final Rectangle paintArea,
- final ReferencedEnvelope mapArea) {
- if (mapArea == null || paintArea == null) {
- logGt.info("renderer passed null arguments");
- return;
- } // Other arguments get checked later
- paint(graphics, paintArea, mapArea, RendererUtilities
- .worldToScreenTransform(mapArea, paintArea));
- }
+ private DbaseFileHeader getDBFHeader( ShapefileDataStore ds ) {
+ DbaseFileReader reader = null;
- private DbaseFileHeader getDBFHeader(final ShapefileDataStore ds) {
- DbaseFileReader reader = null;
+ try {
+ reader = ShapefileRendererUtil.getDBFReader(ds);
- try {
- reader = ShapefileRendererUtil.getDBFReader(ds);
+ return reader.getHeader();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
- return reader.getHeader();
- } catch (final IOException e) {
- e.printStackTrace();
- } finally {
- if (reader != null) {
- try {
- reader.close();
- } catch (final IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
+ return null;
+ }
- return null;
- }
+ private void processStylers( Graphics2D graphics, ShapefileDataStore datastore,
+ Query query, Envelope bbox, Rectangle screenSize, MathTransform mt, Style style, IndexInfo info,
+ Transaction transaction, String layerId) throws IOException {
+ if (LOGGER.isLoggable(Level.FINE)) {
+ LOGGER.fine("processing " + style.getFeatureTypeStyles().length + " stylers");
+ }
- private void processStylers(final Graphics2D graphics,
- final ShapefileDataStore datastore, final Query query, final Envelope bbox,
- final Rectangle screenSize, final MathTransform mt, final Style style,
- final IndexInfo info, final Transaction transaction, final String layerId)
- throws IOException {
- if (logGt.isLoggable(Level.FINE)) {
- logGt.fine("processing " + style.getFeatureTypeStyles().length
- + " stylers");
- }
+ FeatureTypeStyle[] featureStylers = style.getFeatureTypeStyles();
+ SimpleFeatureType type;
- final FeatureTypeStyle[] featureStylers = style.getFeatureTypeStyles();
- SimpleFeatureType type;
+ try {
+ type = createFeatureType(query, style, datastore);
+ } catch (Exception e) {
+ fireErrorEvent(e);
+ LOGGER.logp(Level.WARNING, "org.geotools.renderer.shape.ShapefileRenderer", "processStylers", "Could not prep style for rendering", e);
+ return;
+ }
- try {
- type = createFeatureType(query, style, datastore);
- } catch (final Exception e) {
- fireErrorEvent(e);
+ for( int i = 0; i < featureStylers.length; i++ ) {
+ if (LOGGER.isLoggable(Level.FINE)) {
+ LOGGER.fine("processing style " + i);
+ }
- return;
- }
+ FeatureTypeStyle fts = featureStylers[i];
+ String typeName = datastore.getSchema().getTypeName();
- for (int i = 0; i < featureStylers.length; i++) {
- if (logGt.isLoggable(Level.FINE)) {
- logGt.fine("processing style " + i);
- }
+ if ((typeName != null) &&
+ ( FeatureTypes.isDecendedFrom(datastore.getSchema(), null, fts.getFeatureTypeName())
+ || typeName .equalsIgnoreCase(fts.getFeatureTypeName()))) {
+ // get applicable rules at the current scale
+ Rule[] rules = fts.getRules();
+ List ruleList = new ArrayList();
+ List elseRuleList = new ArrayList();
+
+ // TODO process filter for geometry expressions and restrict bbox further based on
+ // the result
+
+ for( int j = 0; j < rules.length; j++ ) {
+ if (LOGGER.isLoggable(Level.FINE)) {
+ LOGGER.fine("processing rule " + j);
+ }
- final FeatureTypeStyle fts = featureStylers[i];
- final String typeName = datastore.getSchema().getTypeName();
+ Rule r = rules[j];
+ Filter f = r.getFilter();
+ if(f != null) {
+ GeometryFilterChecker checker = new GeometryFilterChecker();
+ f.accept(checker, null);
+ // geometry filters are quite unlikely in SLD, but if we have any,
+ // we need to reproject it to screen space since geometries are
+ // read directly in screen space
+ if(checker.isGeometryFilterPresent()) {
+ // make copy so we don't modify the style
+ DuplicatingStyleVisitor duplicator = new DuplicatingStyleVisitor();
+ r.accept(duplicator);
+ r=(Rule) duplicator.getCopy();
+
+ FilterTransformer transformer= new FilterTransformer(mt);
+ r.setFilter((Filter) r.getFilter().accept(transformer, null));
+ }
+ }
+ if (isWithInScale(r)) {
+ if (r.hasElseFilter()) {
+ elseRuleList.add(r);
+ } else {
+ ruleList.add(r);
+ }
+ }
+ }
- if ((typeName != null)
- && (datastore.getSchema().isDescendedFrom(null,
- fts.getFeatureTypeName()) || typeName
- .equalsIgnoreCase(fts.getFeatureTypeName()))) {
- // get applicable rules at the current scale
- final Rule[] rules = fts.getRules();
- final List ruleList = new ArrayList();
- final List elseRuleList = new ArrayList();
+ // process the features according to the rules
+ // TODO: find a better way to declare the scale ranges so that
+ // we
+ // get style caching also between multiple rendering runs
+ NumberRange scaleRange = new NumberRange(scaleDenominator, scaleDenominator);
- // TODO process filter for geometry expressions and restrict
- // bbox further based on
- // the result
+ Set modifiedFIDs = processTransaction(graphics, bbox, mt, datastore, transaction,
+ typeName, query, ruleList, elseRuleList, scaleRange, layerId);
- for (int j = 0; j < rules.length; j++) {
- if (logGt.isLoggable(Level.FINE)) {
- logGt.fine("processing rule " + j);
- }
+ // don't try to read the shapefile if there is nothing to draw
+ if(ruleList.size() > 0 || elseRuleList.size() > 0)
+ processShapefile(graphics, datastore, bbox,screenSize, mt, info, type, query, ruleList,
+ elseRuleList, modifiedFIDs, scaleRange, layerId);
+ }
+ }
+ }
- Rule r = rules[j];
+ private Set processTransaction( Graphics2D graphics, Envelope bbox, MathTransform transform,
+ DataStore ds, Transaction transaction, String typename, Query query, List ruleList,
+ List elseRuleList, NumberRange scaleRange, String layerId ) {
+ if (transaction == Transaction.AUTO_COMMIT) {
+ return Collections.EMPTY_SET;
+ }
- // make copy so I don't accidentally modify style
- final DuplicatingStyleVisitor duplicator = new DuplicatingStyleVisitor();
- r.accept(duplicator);
- r = (Rule) duplicator.getCopy();
- if (r.getFilter() != null) {
- // now reproject the geometries in filter because geoms
- // are retrieved projected to screen space
- final FilterTransformer transformer = new FilterTransformer(
- mt);
- r.setFilter((Filter) r.getFilter().accept(transformer,
- null));
- }
- if (isWithInScale(r)) {
- if (r.hasElseFilter()) {
- elseRuleList.add(r);
- } else {
- ruleList.add(r);
- }
- }
- }
+ TransactionStateDiff state = (TransactionStateDiff) transaction.getState(ds);
- // process the features according to the rules
- // TODO: find a better way to declare the scale ranges so that
- // we
- // get style caching also between multiple rendering runs
- final NumberRange scaleRange = new NumberRange(scaleDenominator,
- scaleDenominator);
+ if (state == null) {
+ return Collections.EMPTY_SET;
+ }
+ // set of fids that has been modified (ie updated or deleted)
+ Set fids = new HashSet();
+ Map modified = null;
+ Map added = null;
+ Diff diff=null;
- final Set modifiedFIDs = processTransaction(graphics, bbox, mt,
- datastore, transaction, typeName, query, ruleList,
- elseRuleList, scaleRange, layerId);
+ try {
+ diff = state.diff(typename);
+ modified = diff.modified2;
+ added = diff.added;
+ fids = new HashSet();
+ } catch (IOException e) {
+ fids = Collections.EMPTY_SET;
+ return fids;
+ }
- // don't try to read the shapefile if there is nothing to draw
- if (ruleList.size() > 0 || elseRuleList.size() > 0)
- processShapefile(graphics, datastore, bbox, screenSize, mt,
- info, type, query, ruleList, elseRuleList,
- modifiedFIDs, scaleRange, layerId);
- }
- }
- }
+ if (!diff.isEmpty()) {
+ SimpleFeature feature;
- private Set processTransaction(final Graphics2D graphics, final Envelope bbox,
- final MathTransform transform, final DataStore ds, final Transaction transaction,
- final String typename, final Query query, final List ruleList, final List elseRuleList,
- final NumberRange scaleRange, final String layerId) {
- if (transaction == Transaction.AUTO_COMMIT) {
- return Collections.EMPTY_SET;
- }
+ for( Iterator modifiedIter = modified.keySet().iterator(),
+ addedIter=added.values().iterator();
+ modifiedIter.hasNext() || addedIter.hasNext(); ) {
+ try {
+ if (renderingStopRequested) {
+ break;
+ }
+ boolean doElse = true;
+ if( modifiedIter.hasNext() ){
+ String fid= (String) modifiedIter.next();
+ feature = (SimpleFeature) modified.get(fid);
+ fids.add(fid);
+ } else {
+ feature = (SimpleFeature) addedIter.next();
+ }
+ if( feature == TransactionStateDiff.NULL){
+ continue; // skip this feature as it is removed
+ }
+ if (!query.getFilter().evaluate(feature)){
+ // currently this is failing for TransactionStateDiff.NULL
+ continue;
+ }
+
+ // applicable rules
+ for( Iterator it = ruleList.iterator(); it.hasNext(); ) {
+ Rule r = (Rule) it.next();
- final TransactionStateDiff state = (TransactionStateDiff) transaction
- .getState(ds);
+ if (LOGGER.isLoggable(Level.FINER)) {
+ LOGGER.finer("applying rule: " + r.toString());
+ }
- if (state == null) {
- return Collections.EMPTY_SET;
- }
+ if (LOGGER.isLoggable(Level.FINER)) {
+ LOGGER.finer("this rule applies ...");
+ }
- Set fids = new HashSet();
- Map modified = null;
- Map added = null;
- Diff diff = null;
+ Filter filter = r.getFilter();
- try {
- diff = state.diff(typename);
- modified = diff.modified2;
- added = diff.added;
- fids = new HashSet();
- } catch (final IOException e) {
- fids = Collections.EMPTY_SET;
- return fids;
- }
+ if ((filter == null) || filter.evaluate(feature)) {
+ doElse = false;
- if (!diff.isEmpty()) {
- SimpleFeature feature;
+ if (LOGGER.isLoggable(Level.FINER)) {
+ LOGGER.finer("processing Symobolizer ...");
+ }
- for (Iterator modifiedIter = modified.keySet().iterator(), addedIter = added
- .values().iterator(); modifiedIter.hasNext()
- || addedIter.hasNext();) {
- if (renderingStopRequested) {
- break;
- }
+ Symbolizer[] symbolizers = r.getSymbolizers();
- boolean doElse = true;
- if (modifiedIter.hasNext()) {
- final String fid = (String) modifiedIter.next();
- feature = (SimpleFeature) modified.get(fid);
- fids.add(fid);
- } else {
- feature = (SimpleFeature) addedIter.next();
- }
+ try {
+ processSymbolizers(graphics, feature, symbolizers, scaleRange,
+ transform, layerId);
+ } catch (Exception e) {
+ fireErrorEvent(e);
- if (!query.getFilter().evaluate(feature))
- continue;
+ continue;
+ }
- if (feature != TransactionStateDiff.NULL) {
- // applicable rules
- for (final Iterator it = ruleList.iterator(); it.hasNext();) {
- final Rule r = (Rule) it.next();
+ if (LOGGER.isLoggable(Level.FINER)) {
+ LOGGER.finer("... done!");
+ }
+ }
+ }
- if (logGt.isLoggable(Level.FINER)) {
- logGt.finer("applying rule: " + r.toString());
- }
+ if (doElse) {
+ // rules with an else filter
+ if (LOGGER.isLoggable(Level.FINER)) {
+ LOGGER.finer("rules with an else filter");
+ }
- if (logGt.isLoggable(Level.FINER)) {
- logGt.finer("this rule applies ...");
- }
+ for( Iterator it = elseRuleList.iterator(); it.hasNext(); ) {
+ Rule r = (Rule) it.next();
+ Symbolizer[] symbolizers = r.getSymbolizers();
- final Filter filter = r.getFilter();
+ if (LOGGER.isLoggable(Level.FINER)) {
+ LOGGER.finer("processing Symobolizer ...");
+ }
- if ((filter == null) || filter.evaluate(feature)) {
- doElse = false;
+ try {
+ processSymbolizers(graphics, feature, symbolizers, scaleRange,
+ transform, layerId);
+ } catch (Exception e) {
+ fireErrorEvent(e);
- if (logGt.isLoggable(Level.FINER)) {
- logGt.finer("processing Symobolizer ...");
- }
+ continue;
+ }
- final Symbolizer[] symbolizers = r.getSymbolizers();
+ if (LOGGER.isLoggable(Level.FINER)) {
+ LOGGER.finer("... done!");
+ }
+ }
+ }
- try {
- processSymbolizers(graphics, feature,
- symbolizers, scaleRange, transform,
- layerId);
- } catch (final Exception e) {
- fireErrorEvent(e);
+ if (LOGGER.isLoggable(Level.FINER)) {
+ LOGGER.finer("feature rendered event ...");
+ }
+ }
+ catch (RuntimeException e) {
+ fireErrorEvent(e);
+ }
+ }
+ }
+ return fids;
+ }
- continue;
- }
+ private void processShapefile( Graphics2D graphics, ShapefileDataStore datastore,
+ Envelope bbox, Rectangle screenSize, MathTransform mt, IndexInfo info, SimpleFeatureType type, Query query,
+ List ruleList, List elseRuleList, Set modifiedFIDs, NumberRange scaleRange, String layerId )
+ throws IOException {
+ IndexedDbaseFileReader dbfreader = null;
- if (logGt.isLoggable(Level.FINER)) {
- logGt.finer("... done!");
- }
- }
- }
+ // don't waste time processing the dbf file if the only attribute loades is the geometry
+ if(type.getAttributeCount() > 1) {
+ try {
+ dbfreader = ShapefileRendererUtil.getDBFReader(datastore);
+ } catch (Exception e) {
+ fireErrorEvent(e);
+ }
+ }
- if (doElse) {
- // rules with an else filter
- if (logGt.isLoggable(Level.FINER)) {
- logGt.finer("rules with an else filter");
- }
+ OpacityFinder opacityFinder = new OpacityFinder(getAcceptableSymbolizers(type
+ .getGeometryDescriptor()));
- for (final Iterator it = elseRuleList.iterator(); it
- .hasNext();) {
- final Rule r = (Rule) it.next();
- final Symbolizer[] symbolizers = r.getSymbolizers();
+ for( Iterator iter = ruleList.iterator(); iter.hasNext(); ) {
+ Rule rule = (Rule) iter.next();
+ rule.accept(opacityFinder);
+ }
- if (logGt.isLoggable(Level.FINER)) {
- logGt.finer("processing Symobolizer ...");
- }
+ IndexInfo.Reader shpreader = null;
+ boolean useJTS=true;
+
+ try {
+ shpreader = new IndexInfo.Reader(info, ShapefileRendererUtil.getShpReader(datastore,
+ bbox, screenSize, mt, opacityFinder.hasOpacity, useJTS), bbox);
+ } catch (Exception e) {
+ fireErrorEvent(e);
+ return;
+ }
- try {
- processSymbolizers(graphics, feature,
- symbolizers, scaleRange, transform,
- layerId);
- } catch (final Exception e) {
- fireErrorEvent(e);
+ FIDReader fidReader = null;
+ try {
+ fidReader = ShapefileRendererUtil.getFidReader(datastore,shpreader);
+ } catch (Exception e) {
+ fireErrorEvent(e);
+ return;
+ }
+
+ SimpleFeatureBuilder fbuilder = new SimpleFeatureBuilder(type);
+
+ try {
+ while( true ) {
+ try {
+ if (renderingStopRequested) {
+ break;
+ }
- continue;
- }
+ if (!shpreader.hasNext()) {
+ break;
+ }
- if (logGt.isLoggable(Level.FINER)) {
- logGt.finer("... done!");
- }
- }
- }
+ boolean doElse = true;
- if (logGt.isLoggable(Level.FINER)) {
- logGt.finer("feature rendered event ...");
- }
- }
- }
- }
+ String nextFid = null;
+ if( fidReader.hasNext() ){
+ try {
+ nextFid = fidReader.next();
+ }
+ catch( NoSuchElementException invalidIndex){
+ fireErrorEvent(new IllegalStateException("Skipping invalid FID; Please regenerate your index.", invalidIndex));
+ // TODO: mark index as needing regeneration
+ }
+ }
+ else {
+ fireErrorEvent(new IllegalStateException("Skipping invalid FID; shape and index are out of sync please regenerate index."));
+ // TODO: mark index as needing regeneration
+ }
+ if(LOGGER.isLoggable(Level.FINER))
+ LOGGER.finer("trying to read geometry ...");
+ if (nextFid == null || modifiedFIDs.contains(nextFid)) {
+ // this one is modified we will get it when we processTransaction
+ shpreader.next();
+ if( dbfreader != null && !dbfreader.IsRandomAccessEnabled() ){
+ dbfreader.skip();
+ }
+ continue;
+ }
+
+ if( dbfreader != null && dbfreader.IsRandomAccessEnabled() ){
+ dbfreader.goTo(shpreader.getRecordNumber());
+ }
+ ShapefileReader.Record record = shpreader.next();
- return fids;
- }
+ Object geom = record.shape();
+ if (geom == null) {
+ if(LOGGER.isLoggable(Level.FINEST))
+ LOGGER.finest("skipping geometry");
+ if( dbfreader != null && !dbfreader.IsRandomAccessEnabled() )
+ dbfreader.skip();
+ continue;
+ }
- private void processShapefile(final Graphics2D graphics,
- final ShapefileDataStore datastore, final Envelope bbox, final Rectangle screenSize,
- final MathTransform mt, final IndexInfo info, final SimpleFeatureType type, final Query query,
- final List ruleList, final List elseRuleList, final Set modifiedFIDs,
- final NumberRange scaleRange, final String layerId) throws IOException {
- IndexedDbaseFileReader dbfreader = null;
+ SimpleFeature feature = createFeature(fbuilder, record, dbfreader, nextFid);
+ if (!query.getFilter().evaluate(feature))
+ continue;
- // don't waste time processing the dbf file if the only attribute loades
- // is the geometry
- if (type.getAttributeCount() > 1) {
- try {
- dbfreader = ShapefileRendererUtil.getDBFReader(datastore);
- } catch (final Exception e) {
- fireErrorEvent(e);
- }
- }
+ if (renderingStopRequested) {
+ break;
+ }
- final OpacityFinder opacityFinder = new OpacityFinder(
- getAcceptableSymbolizers(type.getDefaultGeometry()));
+ if (LOGGER.isLoggable(Level.FINEST)) {
+ LOGGER.finest("... done: " + geom.toString());
+ }
- for (final Iterator iter = ruleList.iterator(); iter.hasNext();) {
- final Rule rule = (Rule) iter.next();
- rule.accept(opacityFinder);
- }
+ if (LOGGER.isLoggable(Level.FINER)) {
+ LOGGER.fine("... done: " + type.getTypeName());
+ }
- IndexInfo.Reader shpreader = null;
- final boolean useJTS = true;
+ // applicable rules
+ for( Iterator it = ruleList.iterator(); it.hasNext(); ) {
+ Rule r = (Rule) it.next();
- try {
- shpreader = new IndexInfo.Reader(info, ShapefileRendererUtil
- .getShpReader(datastore, bbox, screenSize, mt,
- opacityFinder.hasOpacity, useJTS), bbox);
- } catch (final Exception e) {
- fireErrorEvent(e);
- return;
- }
+ if (LOGGER.isLoggable(Level.FINER)) {
+ LOGGER.finer("applying rule: " + r.toString());
+ }
- FIDReader fidReader = null;
- try {
- fidReader = ShapefileRendererUtil
- .getFidReader(datastore, shpreader);
- } catch (final Exception e) {
- fireErrorEvent(e);
- return;
- }
+ if (LOGGER.isLoggable(Level.FINER)) {
+ LOGGER.finer("this rule applies ...");
+ }
- try {
- while (true) {
- try {
- if (renderingStopRequested) {
- break;
- }
+ Filter filter = r.getFilter();
- if (!shpreader.hasNext()) {
- break;
- }
+ if ((filter == null) || filter.evaluate(feature)) {
+ doElse = false;
- boolean doElse = true;
+ if (LOGGER.isLoggable(Level.FINER)) {
+ LOGGER.finer("processing Symobolizer ...");
+ }
- if (logGt.isLoggable(Level.FINER)) {
- logGt.fine("trying to read geometry ...");
- }
+ Symbolizer[] symbolizers = r.getSymbolizers();
- final String nextFid = fidReader.next();
- if (modifiedFIDs.contains(nextFid)) {
- shpreader.next();
- if (dbfreader != null
- && !dbfreader.IsRandomAccessEnabled())
- dbfreader.skip();
- continue;
- }
- if (dbfreader != null && dbfreader.IsRandomAccessEnabled())
- dbfreader.goTo(shpreader.getRecordNumber());
- final ShapefileReader.Record record = shpreader.next();
+ processSymbolizers(graphics, feature, geom, symbolizers, scaleRange, useJTS, layerId);
- final Object geom = record.shape();
+ if (LOGGER.isLoggable(Level.FINER)) {
+ LOGGER.finer("... done!");
+ }
+ }
+ }
- if (geom == null) {
- logGt.finest("skipping geometry");
- if (dbfreader != null
- && !dbfreader.IsRandomAccessEnabled())
- dbfreader.skip();
- continue;
- }
+ if (doElse) {
+ // rules with an else filter
+ if (LOGGER.isLoggable(Level.FINER)) {
+ LOGGER.finer("rules with an else filter");
+ }
- final SimpleFeature feature = createFeature(type, record, dbfreader,
- nextFid);
- if (!query.getFilter().evaluate(feature))
- continue;
+ for( Iterator it = elseRuleList.iterator(); it.hasNext(); ) {
+ Rule r = (Rule) it.next();
+ Symbolizer[] symbolizers = r.getSymbolizers();
- if (renderingStopRequested) {
- break;
- }
+ if (LOGGER.isLoggable(Level.FINER)) {
+ LOGGER.finer("processing Symobolizer ...");
+ }
- if (logGt.isLoggable(Level.FINEST)) {
- logGt.finest("... done: " + geom.toString());
- }
+ processSymbolizers(graphics, feature, geom, symbolizers, scaleRange, useJTS, layerId);
- if (logGt.isLoggable(Level.FINER)) {
- logGt.fine("... done: " + type.getTypeName());
- }
+ if (LOGGER.isLoggable(Level.FINER)) {
+ LOGGER.finer("... done!");
+ }
+ }
+ }
- // applicable rules
- for (final Iterator it = ruleList.iterator(); it.hasNext();) {
- final Rule r = (Rule) it.next();
+ if (LOGGER.isLoggable(Level.FINER)) {
+ LOGGER.finer("feature rendered event ...");
+ }
+ } catch (Exception e) {
+ fireErrorEvent(e);
+ }
+ }
+ } finally {
+ try {
+ if (dbfreader != null) {
+ dbfreader.close();
+ }
+ } finally {
+ try {
+ if (shpreader != null) {
+ shpreader.close();
+ }
+ } finally {
+ if (fidReader != null)
+ fidReader.close();
+ }
+ }
+ }
+ }
- if (logGt.isLoggable(Level.FINER)) {
- logGt.finer("applying rule: " + r.toString());
- }
+ private Class[] getAcceptableSymbolizers( GeometryDescriptor defaultGeometry ) {
+ Class binding = defaultGeometry.getType().getBinding();
+ if (Polygon.class.isAssignableFrom(binding)
+ || MultiPolygon.class.isAssignableFrom(binding)) {
+ return new Class[]{PointSymbolizer.class, LineSymbolizer.class, PolygonSymbolizer.class};
+ }
- if (logGt.isLoggable(Level.FINER)) {
- logGt.finer("this rule applies ...");
- }
+ return new Class[]{PointSymbolizer.class, LineSymbolizer.class};
+ }
- final Filter filter = r.getFilter();
+ SimpleFeature createFeature(SimpleFeatureBuilder builder, Record record, DbaseFileReader dbfreader, String id )
+ throws Exception {
+ SimpleFeatureType type = builder.getFeatureType();
+ if (type.getAttributeCount() == 1) {
+ builder.add(getGeom(record.shape(), type.getGeometryDescriptor()));
+ return builder.buildFeature(id);
+ } else {
+ dbfreader.read();
+ for( int i = 0; i < (type.getAttributeCount() - 1); i++ ) {
+ builder.add(dbfreader.readField(attributeIndexing[i]));
+ }
+ builder.add(getGeom(record.shape(), type.getGeometryDescriptor()));
+ return builder.buildFeature(id);
+ }
+ }
- if ((filter == null) || filter.evaluate(feature)) {
- doElse = false;
+ /**
+ * Return provided geom; or use a default value if null.
+ *
+ * @param geom Provided Geometry as read from record.shape()
+ * @param defaultGeometry GeometryDescriptor used to determine default value
+ * @return provided geom or default value if null
+ */
+ private Object getGeom( Object geom, GeometryDescriptor defaultGeometry ) {
+ if( geom instanceof Geometry){
+ return geom;
+ }
+ return getGeom( defaultGeometry );
+ }
- if (logGt.isLoggable(Level.FINER)) {
- logGt.finer("processing Symobolizer ...");
- }
+ /**
+ * This class keeps a couple of default geometries on hand to use
+ * when making a feature with default values.
+ *
+ * @param defaultGeometry
+ * @return placeholder to use as a default while waiting for a real geometry.
+ */
+ private Object getGeom(GeometryDescriptor defaultGeometry) {
+ Class binding = defaultGeometry.getType().getBinding();
+ if (MultiPolygon.class.isAssignableFrom(binding)) {
+ return MULTI_POLYGON_GEOM;
+ }
+ else if (MultiLineString.class.isAssignableFrom(binding)) {
+ return MULTI_LINE_GEOM;
+ }
+ else if (Point.class.isAssignableFrom(binding)) {
+ return POINT_GEOM;
+ }
+ else if (MultiPoint.class.isAssignableFrom(binding)) {
+ return MULTI_POINT_GEOM;
+ }
+ return null; // we don't have a good default value - null will need to do
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param query
+ * @param style
+ * @param schema DOCUMENT ME!
+ * @return
+ * @throws FactoryConfigurationError
+ * @throws SchemaException
+ */
+ SimpleFeatureType createFeatureType( Query query, Style style, ShapefileDataStore ds)
+ throws SchemaException, IOException {
+ SimpleFeatureType schema = ds.getSchema();
+ String[] attributes = findStyleAttributes((query == null) ? Query.ALL : query, style,
+ schema);
+ AttributeDescriptor[] types = new AttributeDescriptor[attributes.length];
+ attributeIndexing = new int[attributes.length];
+
+ if(attributes.length == 1 && attributes[0].equals(schema.getGeometryDescriptor().getLocalName())) {
+ types[0] = schema.getDescriptor(attributes[0]);
+ } else {
+ dbfheader = getDBFHeader(ds);
+ for( int i = 0; i < types.length; i++ ) {
+ types[i] = schema.getDescriptor(attributes[i]);
+
+ for( int j = 0; j < dbfheader.getNumFields(); j++ ) {
+ if (dbfheader.getFieldName(j).equals(attributes[i])) {
+ attributeIndexing[i] = j;
+
+ break;
+ }
+ }
+ }
+ }
- final Symbolizer[] symbolizers = r.getSymbolizers();
+ SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder();
+ tb.setName( schema.getName() );
+ tb.addAll( types );
+ tb.setDefaultGeometry( schema.getGeometryDescriptor().getLocalName() );
+
+ return tb.buildFeatureType();
+ }
- processSymbolizers(graphics, feature, geom,
- symbolizers, scaleRange, useJTS, layerId);
+ /**
+ * Inspects the <code>MapLayer</code>'s style and retrieves it's needed attribute names,
+ * returning at least the default geometry attribute name.
+ *
+ * @param query DOCUMENT ME!
+ * @param style the <code>Style</code> to determine the needed attributes from
+ * @param schema the FeatureSource<SimpleFeatureType, SimpleFeature> schema
+ * @return the minimun set of attribute names needed to render <code>layer</code>
+ */
+ private String[] findStyleAttributes( final Query query, Style style, SimpleFeatureType schema ) {
+ StyleAttributeExtractor sae = new StyleAttributeExtractor();
+ sae.visit(style);
- if (logGt.isLoggable(Level.FINER)) {
- logGt.finer("... done!");
- }
- }
- }
-
- if (doElse) {
- // rules with an else filter
- if (logGt.isLoggable(Level.FINER)) {
- logGt.finer("rules with an else filter");
- }
-
- for (final Iterator it = elseRuleList.iterator(); it
- .hasNext();) {
- final Rule r = (Rule) it.next();
- final Symbolizer[] symbolizers = r.getSymbolizers();
-
- if (logGt.isLoggable(Level.FINER)) {
- logGt.finer("processing Symobolizer ...");
- }
-
- processSymbolizers(graphics, feature, geom,
- symbolizers, scaleRange, useJTS, layerId);
-
- if (logGt.isLoggable(Level.FINER)) {
- logGt.finer("... done!");
- }
- }
- }
-
- if (logGt.isLoggable(Level.FINER)) {
- logGt.finer("feature rendered event ...");
- }
- } catch (final Exception e) {
- fireErrorEvent(e);
- }
- }
- } finally {
- try {
- if (dbfreader != null) {
- dbfreader.close();
- }
- } finally {
- try {
- if (shpreader != null) {
- shpreader.close();
- }
- } finally {
- // if (fidReader != null)
- // fidReader.close();
- }
- }
- }
- }
-
- private Class[] getAcceptableSymbolizers(
- final GeometryAttributeType defaultGeometry) {
- if (Polygon.class.isAssignableFrom(defaultGeometry.getType())
- || MultiPolygon.class.isAssignableFrom(defaultGeometry
- .getType())) {
- return new Class[] { PointSymbolizer.class, LineSymbolizer.class,
- PolygonSymbolizer.class };
- }
-
- return new Class[] { PointSymbolizer.class, LineSymbolizer.class };
- }
-
- SimpleFeature createFeature(final SimpleFeatureType type, final Record record,
- final DbaseFileReader dbfreader, final String id) throws Exception {
- if (type.getAttributeCount() == 1) {
- return type.create(new Object[] { getGeom(record.shape(), type
- .getDefaultGeometry()) }, id);
+
+ FilterAttributeExtractor qae = new FilterAttributeExtractor();
+ query.getFilter().accept(qae,null);
+ Set ftsAttributes = new LinkedHashSet(sae.getAttributeNameSet());
+ ftsAttributes.addAll(qae.getAttributeNameSet());
+ if (sae.getDefaultGeometryUsed()
+ && (!ftsAttributes.contains(schema.getGeometryDescriptor().getLocalName()))) {
+ ftsAttributes.add(schema.getGeometryDescriptor().getLocalName());
} else {
- final DbaseFileHeader header = dbfreader.getHeader();
-
- final Object[] all = dbfreader.readEntry();
- final Object[] values = new Object[type.getAttributeCount()];
-
- for (int i = 0; i < (values.length - 1); i++) {
- values[i] = all[attributeIndexing[i]];
-
- if (header.getFieldName(attributeIndexing[i]).equals(
- type.getAttributeType(i))) {
- System.out.println("ok");
- }
- }
-
- values[values.length - 1] = getGeom(record.shape(), type
- .getDefaultGeometry());
-
- return type.create(values, id);
+ // the code following assumes the geometry column is the last one
+ // make sure it's the last for good
+ ftsAttributes.remove(schema.getGeometryDescriptor().getLocalName());
+ ftsAttributes.add(schema.getGeometryDescriptor().getLocalName());
}
- }
+ return (String[]) ftsAttributes.toArray(new String[0]);
+ }
- /**
- * Return provided geom; or use a default value if null.
- *
- * @param geom
- * Provided Geometry as read from record.shape()
- * @param defaultGeometry
- * GeometryAttributeType used to determine default value
- * @return provided geom or default value if null
- */
- private Object getGeom(final Object geom, final GeometryAttributeType defaultGeometry) {
- if (geom instanceof Geometry) {
- return geom;
- }
- return getGeom(defaultGeometry);
- }
+ /**
+ * DOCUMENT ME!
+ *
+ * @param graphics
+ * @param feature DOCUMENT ME!
+ * @param geom
+ * @param symbolizers
+ * @param scaleRange
+ * @param layerId
+ */
+ private void processSymbolizers( Graphics2D graphics, SimpleFeature feature, Object geom,
+ Symbolizer[] symbolizers, NumberRange scaleRange, boolean isJTS, String layerId ) {
+ for( int m = 0; m < symbolizers.length; m++ ) {
+ if (LOGGER.isLoggable(Level.FINER)) {
+ LOGGER.finer("applying symbolizer " + symbolizers[m]);
+ }
- /**
- * This class keeps a couple of default geometries on hand to use when
- * making a feature with default values.
- *
- * @param defaultGeometry
- * @return placeholder to use as a default while waiting for a real
- * geometry.
- */
- private Object getGeom(final GeometryAttributeType defaultGeometry) {
- if (MultiPolygon.class.isAssignableFrom(defaultGeometry.getType())) {
- return MULTI_POLYGON_GEOM;
- } else if (MultiLineString.class.isAssignableFrom(defaultGeometry
- .getType())) {
- return MULTI_LINE_GEOM;
- } else if (Point.class.isAssignableFrom(defaultGeometry.getType())) {
- return POINT_GEOM;
- } else if (MultiPoint.class.isAssignableFrom(defaultGeometry.getType())) {
- return MULTI_POINT_GEOM;
- }
- return null; // we don't have a good default value - null will need to
- // do
- }
+ if (renderingStopRequested) {
+ break;
+ }
- /**
- * DOCUMENT ME!
- *
- * @param query
- * @param style
- * @param schema
- * DOCUMENT ME!
- * @return
- * @throws FactoryConfigurationError
- * @throws SchemaException
- */
- SimpleFeatureType createFeatureType(final Query query, final Style style,
- final ShapefileDataStore ds) throws SchemaException, IOException {
- final SimpleFeatureType schema = ds.getSchema();
- final String[] attributes = findStyleAttributes((query == null) ? Query.ALL
- : query, style, schema);
- final AttributeDescriptor[] types = new AttributeDescriptor[attributes.length];
- attributeIndexing = new int[attributes.length];
+ if (symbolizers[m] instanceof TextSymbolizer) {
+ try {
+ labelCache.put(layerId,(TextSymbolizer) symbolizers[m],
+ feature,
+ new LiteShape2((Geometry)feature.getDefaultGeometry(), null, null, false, false),
+ scaleRange);
+ } catch (Exception e) {
+ fireErrorEvent(e);
+ }
+ } else {
+ Shape shape;
+ try {
+ Style2D style = styleFactory.createStyle(feature, symbolizers[m], scaleRange);
+ if( isJTS ){
+ Geometry g;
+ if(symbolizers[m] instanceof PointSymbolizer) {
+ g = RendererUtilities.getCentroid((Geometry) geom);
+ } else {
+ g = (Geometry) geom;
+ }
+ shape = new LiteShape2(g, null, null, false, false);
+ painter.paint(graphics, shape, style, scaleDenominator);
+ }else{
+ if(symbolizers[m] instanceof PointSymbolizer) {
+ shape = new LiteShape2(RendererUtilities.getCentroid((Geometry) feature.getDefaultGeometry()), null, null, false, false);
+ } else {
+ shape = getShape((SimpleGeometry) geom);
+ }
+
+ painter.paint(graphics, shape, style, scaleDenominator);
+ }
+ } catch (Exception e) {
+ fireErrorEvent(e);
+ }
+ }
- if (attributes.length == 1
- && attributes[0].equals(schema.getDefaultGeometry()
- .getLocalName())) {
- types[0] = schema.getAttributeType(attributes[0]);
- } else {
- dbfheader = getDBFHeader(ds);
- for (int i = 0; i < types.length; i++) {
- types[i] = schema.getAttributeType(attributes[i]);
+ }
+ fireFeatureRenderedEvent(feature);
+ }
- for (int j = 0; j < dbfheader.getNumFields(); j++) {
- if (dbfheader.getFieldName(j).equals(attributes[i])) {
- attributeIndexing[i] = j;
+ /**
+ * Applies each of a set of symbolizers in turn to a given feature.
+ * <p>
+ * This is an internal method and should only be called by processStylers.
+ * </p>
+ *
+ * @param graphics
+ * @param feature The feature to be rendered
+ * @param symbolizers An array of symbolizers which actually perform the rendering.
+ * @param scaleRange The scale range we are working on... provided in order to make the style
+ * factory happy
+ * @param transform DOCUMENT ME!
+ * @param layerId
+ * @throws TransformException
+ * @throws FactoryException
+ */
+ private void processSymbolizers( final Graphics2D graphics, final SimpleFeature feature,
+ final Symbolizer[] symbolizers, NumberRange scaleRange, MathTransform transform, String layerId )
+ throws TransformException, FactoryException {
+ LiteShape2 shape;
- break;
- }
- }
- }
- }
+ for( int m = 0; m < symbolizers.length; m++ ) {
+ if (LOGGER.isLoggable(Level.FINER)) {
+ LOGGER.finer("applying symbolizer " + symbolizers[m]);
+ }
- final SimpleFeatureType type = FeatureTypeBuilder.newFeatureType(types, schema
- .getTypeName(), schema.getNamespace(), false, null, schema
- .getDefaultGeometry());
+ Geometry g = (Geometry) feature.getDefaultGeometry();
+ if(symbolizers[m] instanceof PointSymbolizer)
+ g = RendererUtilities.getCentroid(g);
+ shape = new LiteShape2(g, transform, getDecimator(transform), false);
- return type;
- }
+ if (symbolizers[m] instanceof TextSymbolizer) {
+ labelCache.put(layerId, (TextSymbolizer) symbolizers[m], feature, shape, scaleRange);
+ } else {
+ Style2D style = styleFactory.createStyle(feature, symbolizers[m], scaleRange);
+ painter.paint(graphics, shape, style, scaleDenominator);
+ }
+ }
- /**
- * Inspects the <code>MapLayer</code>'s style and retrieves it's needed
- * attribute names, returning at least the default geometry attribute name.
- *
- * @param query
- * DOCUMENT ME!
- * @param style
- * the <code>Style</code> to determine the needed attributes from
- * @param schema
- * the featuresource schema
- * @return the minimun set of attribute names needed to render
- * <code>layer</code>
- */
- private String[] findStyleAttributes(final Query query, final Style style,
- final SimpleFeatureType schema) {
- final StyleAttributeExtractor sae = new StyleAttributeExtractor() {
- public void visit(final Rule rule) {
+ fireFeatureRenderedEvent(feature);
+ }
- final DuplicatingStyleVisitor dupeStyleVisitor = new DuplicatingStyleVisitor();
- dupeStyleVisitor.visit(rule);
- final Rule clone = (Rule) dupeStyleVisitor.getCopy();
+ /**
+ * DOCUMENT ME!
+ *
+ * @param mathTransform DOCUMENT ME!
+ * @return
+ * @throws org.opengis.referencing.operation.NoninvertibleTransformException
+ */
+ private Decimator getDecimator( MathTransform mathTransform )
+ throws org.opengis.referencing.operation.NoninvertibleTransformException {
+ Decimator decimator=null;
+
+ if( mathTransform!=null )
+ decimator = (Decimator) decimators.get(mathTransform);
- super.visit(clone);
- }
- };
+ if (decimator == null) {
+ decimator = new Decimator(mathTransform.inverse());
- sae.visit(style);
+ decimators.put(mathTransform, decimator);
+ }
- final FilterAttributeExtractor qae = new FilterAttributeExtractor();
- query.getFilter().accept(qae, null);
- final Set ftsAttributes = new HashSet(sae.getAttributeNameSet());
- ftsAttributes.addAll(qae.getAttributeNameSet());
- // the code following assumes we won't extract the default geometry, and
- // that's
- // most of the time true, but fails if the filter or the style uses it.
- ftsAttributes.remove(schema.getDefaultGeometry().getLocalName());
- return (String[]) ftsAttributes.toArray(new String[0]);
- }
+ return decimator;
+ }
+//
+// /**
+// * Creates a JTS shape that is an approximation of the SImpleGeometry. This is ONLY use for
+// * labelling and is only created if a text symbolizer is part of the current style.
+// *
+// * @param geom the geometry to wrap
+// * @return
+// * @throws TransformException
+// * @throws FactoryException
+// * @throws RuntimeException DOCUMENT ME!
+// */
+// LiteShape2 getLiteShape2( SimpleGeometry geom ) throws TransformException, FactoryException {
+// Geometry jtsGeom;
+// if ((geom.type == ShapeType.POLYGON) || (geom.type == ShapeType.POLYGONM)
+// || (geom.type == ShapeType.POLYGONZ)) {
+// double[] points = getPointSample(geom, true);
+// CoordinateSequence seq = new LiteCoordinateSequence(points);
+// Polygon poly;
+//
+// try {
+// poly = geomFactory.createPolygon(geomFactory.createLinearRing(seq),
+// new LinearRing[]{});
+// } catch (Exception e) {
+// throw new RuntimeException(e);
+// }
+//
+// jtsGeom = geomFactory.createMultiPolygon(new Polygon[]{poly});
+// } else if ((geom.type == ShapeType.ARC) || (geom.type == ShapeType.ARCM)
+// || (geom.type == ShapeType.ARCZ)) {
+// double[] points = getPointSample(geom, false);
+// CoordinateSequence seq = new LiteCoordinateSequence(points);
+// jtsGeom = geomFactory.createMultiLineString(new LineString[]{geomFactory
+// .createLineString(seq)});
+// } else if ((geom.type == ShapeType.MULTIPOINT) || (geom.type == ShapeType.MULTIPOINTM)
+// || (geom.type == ShapeType.MULTIPOINTZ)) {
+// double[] points = getPointSample(geom, false);
+// CoordinateSequence seq = new LiteCoordinateSequence(points);
+// jtsGeom = geomFactory.createMultiPoint(seq);
+// } else {
+// jtsGeom = geomFactory.createPoint(new Coordinate(geom.coords[0][0], geom.coords[0][1]));
+// }
+//
+// LiteShape2 shape = new LiteShape2(jtsGeom, null, null, false);
+//
+// return shape;
+// }
- /**
- * DOCUMENT ME!
- *
- * @param graphics
- * @param feature
- * DOCUMENT ME!
- * @param geom
- * @param symbolizers
- * @param scaleRange
- * @param layerId
- */
- private void processSymbolizers(final Graphics2D graphics, final SimpleFeature feature,
- final Object geom, final Symbolizer[] symbolizers, final NumberRange scaleRange,
- final boolean isJTS, final String layerId) {
- for (int m = 0; m < symbolizers.length; m++) {
- if (logGt.isLoggable(Level.FINER)) {
- logGt.finer("applying symbolizer " + symbolizers[m]);
- }
+// /**
+// * takes a random sampling from the geometry. Only uses the larges part of the geometry.
+// *
+// * @param geom
+// * @param isPolygon DOCUMENT ME!
+// * @return
+// */
+// private double[] getPointSample( SimpleGeometry geom, boolean isPolygon ) {
+// int largestPart = 0;
+//
+// for( int i = 0; i < geom.coords.length; i++ ) {
+// if (geom.coords[i].length > geom.coords[largestPart].length) {
+// largestPart = i;
+// }
+// }
+//
+// return geom.coords[largestPart];
+// }
- if (renderingStopRequested) {
- break;
- }
+ /**
+ * DOCUMENT ME!
+ *
+ * @param geom
+ * @return
+ */
+ private Shape getShape( SimpleGeometry geom ) {
+ if ((geom.type == ShapeType.ARC) || (geom.type == ShapeType.ARCM)
+ || (geom.type == ShapeType.ARCZ)) {
+ return new MultiLineShape(geom);
+ }
- if (symbolizers[m] instanceof TextSymbolizer) {
- try {
- labelCache.put(layerId, (TextSymbolizer) symbolizers[m],
- feature, new LiteShape2(feature
- .getDefaultGeometry(), null, null, false,
- false), scaleRange);
- } catch (final Exception e) {
- fireErrorEvent(e);
- }
- } else {
- Shape shape;
- try {
- final Style2D style = styleFactory.createStyle(feature,
- symbolizers[m], scaleRange);
- if (isJTS) {
- Geometry g;
- if (symbolizers[m] instanceof PointSymbolizer) {
- g = RendererUtilities.getCentroid((Geometry) geom);
- } else {
- g = (Geometry) geom;
- }
- shape = new LiteShape2(g, null, null, false, false);
- painter.paint(graphics, shape, style, scaleDenominator);
- } else {
- if (symbolizers[m] instanceof PointSymbolizer) {
- shape = new LiteShape2(RendererUtilities
- .getCentroid(feature.getDefaultGeometry()),
- null, null, false, false);
- } else {
- shape = getShape((SimpleGeometry) geom);
- }
+ if ((geom.type == ShapeType.POLYGON) || (geom.type == ShapeType.POLYGONM)
+ || (geom.type == ShapeType.POLYGONZ)) {
+ return new PolygonShape(geom);
+ }
- painter.paint(graphics, shape, style, scaleDenominator);
- }
- } catch (final Exception e) {
- fireErrorEvent(e);
- }
- }
+ if ((geom.type == ShapeType.POINT) || (geom.type == ShapeType.POINTM)
+ || (geom.type == ShapeType.POINTZ) || (geom.type == ShapeType.MULTIPOINT)
+ || (geom.type == ShapeType.MULTIPOINTM) || (geom.type == ShapeType.MULTIPOINTZ)) {
+ return new MultiPointShape(geom);
+ }
+
+
- }
- fireFeatureRenderedEvent(feature);
- }
+ return null;
+ }
- /**
- * Applies each of a set of symbolizers in turn to a given feature.
- * <p>
- * This is an internal method and should only be called by processStylers.
- * </p>
- *
- * @param graphics
- * @param feature
- * The feature to be rendered
- * @param symbolizers
- * An array of symbolizers which actually perform the rendering.
- * @param scaleRange
- * The scale range we are working on... provided in order to make
- * the style factory happy
- * @param transform
- * DOCUMENT ME!
- * @param layerId
- * @throws TransformException
- * @throws FactoryException
- */
- private void processSymbolizers(final Graphics2D graphics,
- final SimpleFeature feature, final Symbolizer[] symbolizers,
- final Range scaleRange, final MathTransform transform, final String layerId)
- throws TransformException, FactoryException {
- LiteShape2 shape;
+ /**
+ * Checks if a rule can be triggered at the current scale level
+ *
+ * @param r The rule
+ * @return true if the scale is compatible with the rule settings
+ */
+ private boolean isWithInScale( Rule r ) {
+ return ((r.getMinScaleDenominator() - TOLERANCE) <= scaleDenominator)
+ && ((r.getMaxScaleDenominator() + TOLERANCE) > scaleDenominator);
+ }
- for (int m = 0; m < symbolizers.length; m++) {
- if (logGt.isLoggable(Level.FINER)) {
- logGt.finer("applying symbolizer " + symbolizers[m]);
- }
+ /**
+ * adds a listener that responds to error events of feature rendered events.
+ *
+ * @param listener the listener to add.
+ * @see RenderListener
+ */
+ public void addRenderListener( RenderListener listener ) {
+ renderListeners.add(listener);
+ }
- Geometry g = feature.getDefaultGeometry();
- if (symbolizers[m] instanceof PointSymbolizer)
- g = RendererUtilities.getCentroid(g);
- shape = new LiteShape2(g, transform, getDecimator(transform), false);
+ /**
+ * Removes a render listener.
+ *
+ * @param listener the listener to remove.
+ * @see RenderListener
+ */
+ public void removeRenderListener( RenderListener listener ) {
+ renderListeners.remove(listener);
+ }
- if (symbolizers[m] instanceof TextSymbolizer) {
- labelCache.put(layerId, (TextSymbolizer) symbolizers[m],
- feature, shape, scaleRange);
- } else {
- final Style2D style = styleFactory.createStyle(feature,
- symbolizers[m], scaleRange);
- painter.paint(graphics, shape, style, scaleDenominator);
- }
- }
+ private void fireFeatureRenderedEvent( SimpleFeature feature ) {
+ if (renderListeners.size() > 0) {
+ RenderListener listener;
+ for (int i = 0; i < renderListeners.size(); i++) {
+ listener = renderListeners.get(i);
+ listener.featureRenderer((SimpleFeature) feature);
+ }
+ }
+ }
- fireFeatureRenderedEvent(feature);
- }
+ private void fireErrorEvent(Exception e) {
+ if (renderListeners.size() > 0) {
+ RenderListener listener;
+ for (int i = 0; i < renderListeners.size(); i++) {
+ try {
+ listener = renderListeners.get(i);
+ listener.errorOccurred(e);
+ } catch (RuntimeException ignore) {
+ LOGGER.fine("Provided RenderListener could not handle error message:" + ignore);
+ LOGGER.throwing(getClass().getName(), "fireErrorEvent", ignore);
+ }
+ }
+ }
+ }
- /**
- * DOCUMENT ME!
- *
- * @param mathTransform
- * DOCUMENT ME!
- * @return
- * @throws org.opengis.referencing.operation.NoninvertibleTransformException
- */
- private Decimator getDecimator(final MathTransform mathTransform)
- throws org.opengis.referencing.operation.NoninvertibleTransformException {
- Decimator decimator = null;
+ /**
+ * Setter for property scaleDenominator.
+ *
+ * @param scaleDenominator New value of property scaleDenominator.
+ */
+ protected void setScaleDenominator( double scaleDenominator ) {
+ this.scaleDenominator = scaleDenominator;
+ }
- if (mathTransform != null)
- decimator = (Decimator) decimators.get(mathTransform);
+ /**
+ * If you call this method from another thread than the one that called <code>paint</code> or
+ * <code>render</code> the rendering will be forcefully stopped before termination
+ */
+ public void stopRendering() {
+ try {
+ if(delegate != null)
+ delegate.stopRendering();
+ } catch(NullPointerException e) {
+ // Since stopRendering is called by another thread the null check may
+ // pass, and the method call can NPE nevertheless. It's ok, in that
+ // case rendering is done anyways
+ }
+ renderingStopRequested = true;
+ labelCache.stop();
+ }
- if (decimator == null) {
- decimator = new Decimator(mathTransform.inverse());
+ /**
+ * True if we are caching styles.
+ *
+ * @return <code>ture </code>if caching
+ */
+ public boolean isCaching() {
+ return caching;
+ }
- decimators.put(mathTransform, decimator);
- }
+ /**
+ * Set to true to cache styles.
+ *
+ * @param caching The caching to set.
+ */
+ public void setCaching( boolean caching ) {
+ this.caching = caching;
+ }
- return decimator;
- }
+ public MapContext getContext() {
+ return context;
+ }
- //
- // /**
- // * Creates a JTS shape that is an approximation of the SImpleGeometry.
- // This is ONLY use for
- // * labelling and is only created if a text symbolizer is part of the
- // current style.
- // *
- // * @param geom the geometry to wrap
- // * @return
- // * @throws TransformException
- // * @throws FactoryException
- // * @throws RuntimeException DOCUMENT ME!
- // */
- // LiteShape2 getLiteShape2( SimpleGeometry geom ) throws
- // TransformException, FactoryException {
- // Geometry jtsGeom;
- // if ((geom.type == ShapeType.POLYGON) || (geom.type == ShapeType.POLYGONM)
- // || (geom.type == ShapeType.POLYGONZ)) {
- // double[] points = getPointSample(geom, true);
- // CoordinateSequence seq = new LiteCoordinateSequence(points);
- // Polygon poly;
- //
- // try {
- // poly = geomFactory.createPolygon(geomFactory.createLinearRing(seq),
- // new LinearRing[]{});
- // } catch (Exception e) {
- // throw new RuntimeException(e);
- // }
- //
- // jtsGeom = geomFactory.createMultiPolygon(new Polygon[]{poly});
- // } else if ((geom.type == ShapeType.ARC) || (geom.type == ShapeType.ARCM)
- // || (geom.type == ShapeType.ARCZ)) {
- // double[] points = getPointSample(geom, false);
- // CoordinateSequence seq = new LiteCoordinateSequence(points);
- // jtsGeom = geomFactory.createMultiLineString(new LineString[]{geomFactory
- // .createLineString(seq)});
- // } else if ((geom.type == ShapeType.MULTIPOINT) || (geom.type ==
- // ShapeType.MULTIPOINTM)
- // || (geom.type == ShapeType.MULTIPOINTZ)) {
- // double[] points = getPointSample(geom, false);
- // CoordinateSequence seq = new LiteCoordinateSequence(points);
- // jtsGeom = geomFactory.createMultiPoint(seq);
- // } else {
- // jtsGeom = geomFactory.createPoint(new Coordinate(geom.coords[0][0],
- // geom.coords[0][1]));
- // }
- //
- // LiteShape2 shape = new LiteShape2(jtsGeom, null, null, false);
- //
- // return shape;
- // }
+ public boolean isConcatTransforms() {
+ return concatTransforms;
+ }
- // /**
- // * takes a random sampling from the geometry. Only uses the larges part of
- // the geometry.
- // *
- // * @param geom
- // * @param isPolygon DOCUMENT ME!
- // * @return
- // */
- // private double[] getPointSample( SimpleGeometry geom, boolean isPolygon )
- // {
- // int largestPart = 0;
- //
- // for( int i = 0; i < geom.coords.length; i++ ) {
- // if (geom.coords[i].length > geom.coords[largestPart].length) {
- // largestPart = i;
- // }
- // }
- //
- // return geom.coords[largestPart];
- // }
+ public void setConcatTransforms( boolean concatTransforms ) {
+ this.concatTransforms = concatTransforms;
+ }
- /**
- * DOCUMENT ME!
- *
- * @param geom
- * @return
- */
- private Shape getShape(final SimpleGeometry geom) {
- if ((geom.type == ShapeType.ARC) || (geom.type == ShapeType.ARCM)
- || (geom.type == ShapeType.ARCZ)) {
- return new MultiLineShape(geom);
- }
+ public IndexInfo useIndex( ShapefileDataStore ds ) throws IOException, StoreException {
+ IndexInfo info;
- if ((geom.type == ShapeType.POLYGON)
- || (geom.type == ShapeType.POLYGONM)
- || (geom.type == ShapeType.POLYGONZ)) {
- return new PolygonShape(geom);
- }
+ ShpFiles shpFiles = ShapefileRendererUtil.getShpFiles(ds);
+ if (ds.isLocal()) {
- if ((geom.type == ShapeType.POINT) || (geom.type == ShapeType.POINTM)
- || (geom.type == ShapeType.POINTZ)
- || (geom.type == ShapeType.MULTIPOINT)
- || (geom.type == ShapeType.MULTIPOINTM)
- || (geom.type == ShapeType.MULTIPOINTZ)) {
- return new MultiPointShape(geom);
- }
+ if (!shpFiles.exists(SHX)) {
+ info = new IndexInfo(IndexType.NONE, shpFiles);
+ LOGGER.fine("No indexing");
+ } else if (shpFiles.exists(QIX)) {
+ info = new IndexInfo(IndexType.QIX, shpFiles);
+ LOGGER.fine("Using quad tree");
+ } else {
+ info = new IndexInfo(IndexType.NONE, shpFiles);
+ LOGGER.fine("No indexing");
+ }
+ } else {
+ info = new IndexInfo(IndexType.NONE, shpFiles);
+ LOGGER.fine("No indexing");
+ }
- return null;
- }
+ return info;
+ }
- /**
- * Checks if a rule can be triggered at the current scale level
- *
- * @param r
- * The rule
- * @return true if the scale is compatible with the rule settings
- */
- private boolean isWithInScale(final Rule r) {
- return ((r.getMinScaleDenominator() - TOLERANCE) <= scaleDenominator)
- && ((r.getMaxScaleDenominator() + TOLERANCE) > scaleDenominator);
- }
+ /**
+ * By default ignores all feature renderered events and logs all exceptions as severe.
+ */
+ private static class DefaultRenderListener implements RenderListener {
+ /**
+ * @see org.geotools.renderer.lite.RenderListener#featureRenderer(org.geotools.feature.Feature)
+ */
+ public void featureRenderer( SimpleFeature feature ) {
+ // do nothing.
+ }
- /**
- * adds a listener that responds to error events of feature rendered events.
- *
- * @param listener
- * the listener to add.
- * @see RenderListener
- */
- public void addRenderListener(final RenderListener listener) {
- renderListeners.add(listener);
- }
+ /**
+ * @see org.geotools.renderer.lite.RenderListener#errorOccurred(java.lang.Exception)
+ */
+ public void errorOccurred( Exception e ) {
+ LOGGER.log(Level.SEVERE, e.getMessage(), e);
+ }
+ }
- /**
- * Removes a render listener.
- *
- * @param listener
- * the listener to remove.
- * @see RenderListener
- */
- public void removeRenderListener(final RenderListener listener) {
- renderListeners.remove(listener);
- }
+ public void setJava2DHints( RenderingHints hints ) {
+ this.hints = hints;
+ }
- private void fireFeatureRenderedEvent(final SimpleFeature feature) {
- final Object[] objects = renderListeners.getListeners();
+ public RenderingHints getJava2DHints() {
+ return hints;
+ }
- for (int i = 0; i < objects.length; i++) {
- final RenderListener listener = (RenderListener) objects[i];
- listener.featureRenderer(feature);
- }
- }
+ public void setRendererHints(Map hints) {
+ if( hints!=null && hints.containsKey(LABEL_CACHE_KEY) ){
+ LabelCache cache=(LabelCache) hints.get(LABEL_CACHE_KEY);
+ if( cache==null )
+ throw new NullPointerException("Label_Cache_Hint has a null value for the labelcache");
+
+ this.labelCache=cache;
+ this.painter=new StyledShapePainter(cache);
+ }
+ if(hints != null && hints.containsKey(StreamingRenderer.LINE_WIDTH_OPTIMIZATION_KEY)) {
+ styleFactory.setLineOptimizationEnabled(Boolean.TRUE.equals(hints.get(StreamingRenderer.LINE_WIDTH_OPTIMIZATION_KEY)));
+ }
+ rendererHints = hints;
+ }
+
+ public Map getRendererHints() {
+ return rendererHints;
+ }
- private void fireErrorEvent(final Exception e) {
- final Object[] objects = renderListeners.getListeners();
+ public void setContext( MapContext context ) {
+ if (context == null) {
+ context = new DefaultMapContext(DefaultGeographicCRS.WGS84);
+ }
- for (int i = 0; i < objects.length; i++) {
- final RenderListener listener = (RenderListener) objects[i];
- listener.errorOccurred(e);
- }
- }
+ // TODO Hack missing!
+
+ this.context = context;
- /**
- * Setter for property scaleDenominator.
- *
- * @param scaleDenominator
- * New value of property scaleDenominator.
- */
- protected void setScaleDenominator(final double scaleDenominator) {
- this.scaleDenominator = scaleDenominator;
- }
+ MapLayer[] layers = context.getLayers();
+ layerIndexInfo = new IndexInfo[layers.length];
- /**
- * If you call this method from another thread than the one that called
- * <code>paint</code> or <code>render</code> the rendering will be
- * forcefully stopped before termination
- */
- public void stopRendering() {
- renderingStopRequested = true;
- labelCache.stop();
- }
+ int i=0;
+ for(MapLayer layer:layers ) {
+ DataStore ds = (DataStore) layer.getFeatureSource().getDataStore();
+ if( ds instanceof ShapefileDataStore ){
+ ShapefileDataStore sds = (ShapefileDataStore) ds;
+ try {
+ layerIndexInfo[i] = useIndex(sds);
+ } catch (Exception e) {
+ layerIndexInfo[i] = new IndexInfo(IndexType.NONE, ShapefileRendererUtil.getShpFiles(sds));
+ if(LOGGER.isLoggable(Level.FINE))
+ LOGGER.fine("Exception while trying to use index" + e.getLocalizedMessage());
+ }
+ }else{
+ layerIndexInfo[i]=STREAMING_RENDERER_INFO;
+ }
+ i++;
+ }
+ }
- /**
- * DOCUMENT ME!
- *
- * @return Returns the caching.
- */
- public boolean isCaching() {
- return caching;
- }
+ public void paint( Graphics2D graphics, Rectangle paintArea, AffineTransform worldToScreen ) {
+ if (worldToScreen == null || paintArea == null) {
+ LOGGER.info("renderer passed null arguments");
+ return;
+ } // Other arguments get checked later
+ // First, create the bbox in real world coordinates
+ ReferencedEnvelope mapArea;
+ try {
+ mapArea = RendererUtilities.createMapEnvelope(paintArea, worldToScreen, getContext().getCoordinateReferenceSystem());
+ paint(graphics, paintArea, mapArea, worldToScreen);
+ } catch (NoninvertibleTransformException e) {
+ fireErrorEvent(new Exception("Can't create pixel to world transform", e));
+ }
+ }
- /**
- * DOCUMENT ME!
- *
- * @param caching
- * The caching to set.
- */
- public void setCaching(final boolean caching) {
- this.caching = caching;
- }
+ public void paint( Graphics2D graphics, Rectangle paintArea, ReferencedEnvelope envelope,
+ AffineTransform transform ) {
- public MapContext getContext() {
- return context;
- }
+ if (hints != null) {
+ graphics.setRenderingHints(hints);
+ }
- public boolean isConcatTransforms() {
- return concatTransforms;
- }
+ if ((graphics == null) || (paintArea == null)) {
+ LOGGER.info("renderer passed null arguments");
- public void setConcatTransforms(final boolean concatTransforms) {
- this.concatTransforms = concatTransforms;
- }
+ return;
+ }
- public IndexInfo useIndex(final ShapefileDataStore ds) throws IOException,
- StoreException {
- IndexInfo info;
- String filename = null;
- final URL url = ShapefileRendererUtil.getshpURL(ds);
+ // reset the abort flag
+ renderingStopRequested = false;
- if (url == null) {
- throw new NullPointerException("Null URL for ShapefileDataSource");
- }
+ if (LOGGER.isLoggable(Level.FINE)) {
+ LOGGER.fine("Affine Transform is " + transform);
+ }
- try {
- filename = java.net.URLDecoder.decode(url.toString(), "US-ASCII");
- } catch (final java.io.UnsupportedEncodingException use) {
- throw new java.net.MalformedURLException("Unable to decode " + url
- + " cause " + use.getMessage());
- }
+ /*
+ * If we are rendering to a component which has already set up some form of transformation
+ * then we can concatenate our transformation to it. An example of this is the ZoomPane
+ * component of the swinggui module.
+ */
+ if (concatTransforms) {
+ AffineTransform atg = graphics.getTransform();
- filename = filename.substring(0, filename.length() - 4);
+ // graphics.setTransform(new AffineTransform());
+ atg.concatenate(transform);
+ transform = atg;
+ }
- final String grxext = ".grx";
- final String qixext = ".qix";
+ try {
+ setScaleDenominator(
+ computeScale(
+ envelope,
+ context.getCoordinateReferenceSystem(),
+ paintArea,
+ transform,
+ this.rendererHints));
+ } catch (Exception e) // probably either (1) no CRS (2) error xforming
+ {
+ LOGGER.throwing("RendererUtilities", "calculateScale(envelope, coordinateReferenceSystem, imageWidth, imageHeight, hints)", e);
+ setScaleDenominator(1 / transform.getScaleX()); // DJB old method - the best we can do
+ }
- final boolean local = ds.isLocal();
- LOGGER.debug("TransitionShapefileRendere is local = " + local
- + ".. anyway ignoring it.");
- // if (local) {
- final URL shx = IOUtil.changeUrlExt(url, "shx");
- final URL qixTree = IOUtil.changeUrlExt(url, "qix");
- final URL grxTree = IOUtil.changeUrlExt(url, "grx");
+ MapLayer[] layers = context.getLayers();
- if (!IOUtil.urlExists(shx)) {
- LOGGER.debug(shx + " doesn exist => no index");
- info = new IndexInfo(IndexInfo.TREE_NONE, null, null);
- } else if (IOUtil.urlExists(qixTree)) {
- info = new IndexInfo(IndexInfo.QUAD_TREE, qixTree, shx);
- LOGGER.debug("Using quad tree");
- } else {
- LOGGER.debug(qixTree + " doesn exist ");
- if (IOUtil.urlExists(grxTree)) {
- info = new IndexInfo(IndexInfo.R_TREE, grxTree, shx);
- LOGGER.debug("Using r-tree");
- } else {
- LOGGER.debug(grxTree + " doesn exist ");
- info = new IndexInfo(IndexInfo.TREE_NONE, null, null);
- LOGGER.debug("No indexing");
- }
- }
- // } else {
- // info = new IndexInfo(IndexInfo.TREE_NONE, null, null);
- // }
+ // get detstination CRS
+ CoordinateReferenceSystem destinationCrs = context.getCoordinateReferenceSystem();
+ labelCache.start();
+ labelCache.clear();
+ if(labelCache instanceof LabelCacheDefault) {
+ boolean outlineEnabled = TEXT_RENDERING_OUTLINE.equals(getTextRenderingMethod());
+ ((LabelCacheDefault) labelCache).setOutlineRenderingEnabled(outlineEnabled);
+ }
+ for( int i = 0; i < layers.length; i++ ) {
+ MapLayer currLayer = layers[i];
- return info;
- }
+ if (!currLayer.isVisible()) {
+ // Only render layer when layer is visible
+ continue;
+ }
- /**
- * By default ignores all feature renderered events and logs all exceptions
- * as severe.
- */
- private static class DefaultRenderListener implements RenderListener {
- /**
- * @see org.geotools.renderer.lite.RenderListener#featureRenderer(org.geotools.feature.SimpleFeature)
- */
- public void featureRenderer(final SimpleFeature feature) {
- // do nothing.
- }
+ if (renderingStopRequested) {
+ return;
+ }
+
+ if( layerIndexInfo[i]==STREAMING_RENDERER_INFO ){
+ renderWithStreamingRenderer(currLayer, graphics, paintArea, envelope, transform);
+ continue;
+ }
+ labelCache.startLayer(""+i);
- /**
- * @see org.geotools.renderer.lite.RenderListener#errorOccurred(java.lang.Exception)
- */
- public void errorOccurred(final Exception e) {
- logGt.log(Level.SEVERE, e.getMessage(), e);
- }
- }
+ ReferencedEnvelope bbox = envelope;
- public void setJava2DHints(final RenderingHints hints) {
- this.hints = hints;
- }
+ try {
+ GeometryDescriptor geom = currLayer.getFeatureSource().getSchema().getGeometryDescriptor();
+
+ CoordinateReferenceSystem dataCRS;
+ if( getForceCRSHint()==null )
+ dataCRS = geom.getCoordinateReferenceSystem();
+ else
+ dataCRS=getForceCRSHint();
+
+ MathTransform mt;
+ CoordinateOperation op;
- public RenderingHints getJava2DHints() {
- return hints;
- }
+ try {
+ op = CRS.getCoordinateOperationFactory(true).createOperation(dataCRS, destinationCrs);
+ mt = op.getMathTransform();
+ bbox = bbox.transform(dataCRS, true, 10);
+ } catch (Exception e) {
+ fireErrorEvent(e);
+ LOGGER.log(Level.WARNING, "Could not reproject the bounding boxes, proceeding in non reprojecting mode", e);
+ op = null;
+ mt = null;
+ }
- public void setRendererHints(final Map hints) {
- if (hints != null && hints.containsKey(LABEL_CACHE_KEY)) {
- final LabelCache cache = (LabelCache) hints.get(LABEL_CACHE_KEY);
- if (cache == null)
- throw new NullPointerException(
- "Label_Cache_Hint has a null value for the labelcache");
+ MathTransform at = ReferencingFactoryFinder.getMathTransformFactory(null)
+ .createAffineTransform(new GeneralMatrix(transform));
- this.labelCache = cache;
- this.painter = new StyledShapePainter(cache);
- }
- rendererHints = hints;
- }
+ if (mt == null) {
+ mt = at;
+ } else {
+ mt = ReferencingFactoryFinder.getMathTransformFactory(null).createConcatenatedTransform(
+ mt, at);
+ }
- public Map getRendererHints() {
- return rendererHints;
- }
+ // dbfheader must be set so that the attributes required for theming can be read in.
+ ShapefileDataStore ds = (ShapefileDataStore) currLayer.getFeatureSource().getDataStore();
- public void setContext(MapContext context) {
- if (context == null) {
- context = new DefaultMapContext(DefaultGeographicCRS.WGS84);
- }
+ // graphics.setTransform(transform);
+ // extract the feature type stylers from the style object
+ // and process them
- this.context = context;
+ Transaction transaction = Transaction.AUTO_COMMIT;
- final MapLayer[] layers = context.getLayers();
- layerIndexInfo = new IndexInfo[layers.length];
+ if (currLayer.getFeatureSource() instanceof FeatureStore) {
+ transaction = ((FeatureStore<SimpleFeatureType, SimpleFeature>) currLayer.getFeatureSource()).getTransaction();
+ }
- for (int i = 0; i < layers.length; i++) {
- final DataStore ds = layers[i].getFeatureSource().getDataStore();
+ DefaultQuery query = new DefaultQuery(currLayer.getQuery());
+ if( query.getFilter() !=null ){
+ // now reproject the geometries in filter because geoms are retrieved projected to screen space
+ FilterTransformer transformer= new FilterTransformer(mt);
+ Filter transformedFilter = (Filter) query.getFilter().accept(transformer, null);
+ query.setFilter(transformedFilter);
+ }
+
+ // by processing the filter we can further restrict the maximum bounds that are
+ // required. For example if a filter
+ //BoundsExtractor extractor=new BoundsExtractor(bbox);
+ //if( query.getFilter()!=null )
+ // query.getFilter().accept(extractor);
+ //
+ //processStylers(graphics, ds, query, extractor.getIntersection(), paintArea,
+ // mt, currLayer.getStyle(), layerIndexInfo[i], transaction);
+ processStylers(graphics, ds, query, bbox, paintArea,
+ mt, currLayer.getStyle(), layerIndexInfo[i], transaction, ""+i);
+ } catch (Exception exception) {
+ fireErrorEvent(new Exception("Exception rendering layer " + currLayer, exception));
+ }
- if (ds instanceof ShapefileDataStore) {
- /**
- * Here is the HACK:
- */
- if (layers[i].getQuery() != null
- && layers[i].getQuery().getFilter() instanceof FeatureOperationTreeFilter) {
- layerIndexInfo[i] = STREAMING_RENDERER_INFO;
- logGt
- .info("Fallback to StreamingRenderer because Filter is instanceof FeatureOperationTreeFilter!");
- } else {
+ labelCache.endLayer(""+i, graphics, paintArea);
+ }
- final ShapefileDataStore sds = (ShapefileDataStore) ds;
-
- try {
- layerIndexInfo[i] = useIndex(sds);
- } catch (final Exception e) {
- layerIndexInfo[i] = new IndexInfo(IndexInfo.TREE_NONE,
- null, null);
- logGt.fine("Exception while trying to use index"
- + e.getLocalizedMessage());
- }
- }
- } else {
- layerIndexInfo[i] = STREAMING_RENDERER_INFO;
- }
- }
- }
-
- public void paint(final Graphics2D graphics, final Rectangle paintArea,
- final AffineTransform worldToScreen) {
- if (worldToScreen == null || paintArea == null) {
- logGt.info("renderer passed null arguments");
- return;
- } // Other arguments get checked later
- // First, create the bbox in real world coordinates
- ReferencedEnvelope mapArea;
- try {
- mapArea = RendererUtilities.createMapEnvelope(paintArea,
- worldToScreen, getContext().getCoordinateReferenceSystem());
- paint(graphics, paintArea, mapArea, worldToScreen);
- } catch (final NoninvertibleTransformException e) {
- fireErrorEvent(new Exception(
- "Can't create pixel to world transform", e));
- }
- }
-
- public void paint(final Graphics2D graphics, final Rectangle paintArea,
- final ReferencedEnvelope envelope, AffineTransform transform) {
-
- if (hints != null) {
- graphics.setRenderingHints(hints);
- }
-
- if ((graphics == null) || (paintArea == null)) {
- logGt.info("renderer passed null arguments");
-
- return;
- }
-
- // reset the abort flag
- renderingStopRequested = false;
-
- if (logGt.isLoggable(Level.FINE)) {
- logGt.fine("Affine Transform is " + transform);
- }
-
- /*
- * If we are rendering to a component which has already set up some form
- * of transformation then we can concatenate our transformation to it.
- * An example of this is the ZoomPane component of the swinggui module.
- */
- if (concatTransforms) {
- final AffineTransform atg = graphics.getTransform();
-
- // graphics.setTransform(new AffineTransform());
- atg.concatenate(transform);
- transform = atg;
- }
-
- try {
- setScaleDenominator(computeScale(envelope, context
- .getCoordinateReferenceSystem(), paintArea,
- this.rendererHints));
- } catch (final Exception e) // probably either (1) no CRS (2) error xforming
- {
- logGt
- .throwing(
- "RendererUtilities",
- "calculateScale(envelope, coordinateReferenceSystem, imageWidth, imageHeight, hints)",
- e);
- setScaleDenominator(1 / transform.getScaleX()); // DJB old method -
- // the best we can
- // do
- }
-
- final MapLayer[] layers = context.getLayers();
-
- // get detstination CRS
- final CoordinateReferenceSystem destinationCrs = context
- .getCoordinateReferenceSystem();
- labelCache.start();
- labelCache.clear();
- if (labelCache instanceof LabelCacheDefault) {
- final boolean outlineEnabled = TEXT_RENDERING_OUTLINE
- .equals(getTextRenderingMethod());
- ((LabelCacheDefault) labelCache)
- .setOutlineRenderingEnabled(outlineEnabled);
- }
- for (int i = 0; i < layers.length; i++) {
- final MapLayer currLayer = layers[i];
-
- if (!currLayer.isVisible()) {
- // Only render layer when layer is visible
- continue;
- }
-
- if (renderingStopRequested) {
- return;
- }
-
- if (layerIndexInfo[i] == STREAMING_RENDERER_INFO) {
- renderWithStreamingRenderer(currLayer, graphics, paintArea,
- envelope, transform);
- continue;
- }
- labelCache.startLayer("" + i);
-
- ReferencedEnvelope bbox = envelope;
-
- try {
- final GeometryAttributeType geom = currLayer.getFeatureSource()
- .getSchema().getDefaultGeometry();
-
- CoordinateReferenceSystem dataCRS;
- if (getForceCRSHint() == null)
- dataCRS = geom.getCoordinateSystem();
- else
- dataCRS = getForceCRSHint();
-
- MathTransform mt;
- CoordinateOperation op;
-
- try {
- op = CRS.getCoordinateOperationFactory(true)
- .createOperation(dataCRS, destinationCrs);
- mt = op.getMathTransform();
- bbox = bbox.transform(dataCRS, true, 10);
- } catch (final Exception e) {
- fireErrorEvent(e);
- logGt
- .log(
- Level.WARNING,
- "Could not reproject the bounding boxes, proceeding in non reprojecting mode",
- e);
- op = null;
- mt = null;
- }
-
- final MathTransform at = ReferencingFactoryFinder
- .getMathTransformFactory(null).createAffineTransform(
- new GeneralMatrix(transform));
-
- if (mt == null) {
- mt = at;
- } else {
- mt = ReferencingFactoryFinder.getMathTransformFactory(null)
- .createConcatenatedTransform(mt, at);
- }
-
- // dbfheader must be set so that the attributes required for
- // theming can be read in.
- final ShapefileDataStore ds = (ShapefileDataStore) currLayer
- .getFeatureSource().getDataStore();
-
- // graphics.setTransform(transform);
- // extract the feature type stylers from the style object
- // and process them
-
- Transaction transaction = Transaction.AUTO_COMMIT;
-
- if (currLayer.getFeatureSource() instanceof FeatureStore) {
- transaction = ((FeatureStore) currLayer.getFeatureSource())
- .getTransaction();
- }
-
- final DefaultQuery query = new DefaultQuery(currLayer.getQuery());
- if (query.getFilter() != null) {
- // now reproject the geometries in filter because geoms are
- // retrieved projected to screen space
- final FilterTransformer transformer = new FilterTransformer(
- dataCRS, destinationCrs, mt);
- query.setFilter((Filter) query.getFilter().accept(
- transformer, null));
- }
-
- // by processing the filter we can further restrict the maximum
- // bounds that are
- // required. For example if a filter
- // BoundsExtractor extractor=new BoundsExtractor(bbox);
- // if( query.getFilter()!=null )
- // query.getFilter().accept(extractor);
- //
- // processStylers(graphics, ds, query,
- // extractor.getIntersection(), paintArea,
- // mt, currLayer.getStyle(), layerIndexInfo[i], transaction);
- processStylers(graphics, ds, query, bbox, paintArea, mt,
- currLayer.getStyle(), layerIndexInfo[i], transaction,
- "" + i);
- } catch (final Exception exception) {
- fireErrorEvent(new Exception("Exception rendering layer "
- + currLayer, exception));
- }
-
- labelCache.endLayer("" + i, graphics, paintArea);
- }
-
- labelCache.end(graphics, paintArea);
- logGt.fine("Style cache hit ratio: " + styleFactory.getHitRatio()
- + " , hits " + styleFactory.getHits() + ", requests "
- + styleFactory.getRequests());
- }
-
- /**
- * Returns the text rendering method
- */
- private String getTextRenderingMethod() {
- if (rendererHints == null)
- return textRenderingModeDEFAULT;
- final String result = (String) rendererHints.get(TEXT_RENDERING_KEY);
- if (result == null)
- return textRenderingModeDEFAULT;
- return result;
- }
-
- /**
- * <p>
- * Returns scale computation algorithm to be used.
- * </p>
- */
- private String getScaleComputationMethod() {
- if (rendererHints == null)
- return scaleComputationMethodDEFAULT;
- final String result = (String) rendererHints
- .get(SCALE_COMPUTATION_METHOD_KEY);
- if (result == null)
- return scaleComputationMethodDEFAULT;
- return result;
- }
-
- private double computeScale(final ReferencedEnvelope envelope,
- final CoordinateReferenceSystem crs, final Rectangle paintArea, final Map hints) {
- if (getScaleComputationMethod().equals(SCALE_ACCURATE)) {
- try {
- return RendererUtilities.calculateScale(envelope,
- paintArea.width, paintArea.height, hints);
- } catch (final Exception e) // probably either (1) no CRS (2) error
- // xforming
- {
- logGt.log(Level.WARNING, e.getLocalizedMessage(), e);
- }
- }
- return RendererUtilities.calculateOGCScale(envelope, paintArea.width,
- hints);
- }
-
- private void renderWithStreamingRenderer(final MapLayer layer,
- final Graphics2D graphics, final Rectangle paintArea,
- final ReferencedEnvelope envelope, final AffineTransform transform) {
+ labelCache.end(graphics, paintArea);
+ if(LOGGER.isLoggable(Level.FINE))
+ LOGGER.fine("Style cache hit ratio: " + styleFactory.getHitRatio() + " , hits "
+ + styleFactory.getHits() + ", requests " + styleFactory.getRequests());
+ }
+
+ /**
+ * Returns the text rendering method
+ */
+ private String getTextRenderingMethod() {
+ if (rendererHints == null)
+ return textRenderingModeDEFAULT;
+ String result = (String) rendererHints.get(TEXT_RENDERING_KEY);
+ if (result == null)
+ return textRenderingModeDEFAULT;
+ return result;
+ }
+
+ /**
+ * <p>
+ * Returns scale computation algorithm to be used.
+ * </p>
+ */
+ private String getScaleComputationMethod() {
+ if (rendererHints == null)
+ return scaleComputationMethodDEFAULT;
+ String result = (String) rendererHints.get(SCALE_COMPUTATION_METHOD_KEY);
+ if (result == null)
+ return scaleComputationMethodDEFAULT;
+ return result;
+ }
+
+ private double computeScale(ReferencedEnvelope envelope, CoordinateReferenceSystem crs, 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);
+ }
+
+ private void renderWithStreamingRenderer(MapLayer layer, Graphics2D graphics, Rectangle paintArea, ReferencedEnvelope envelope, AffineTransform transform) {
MapContext context = null;
+ RenderListener listener = null;;
try {
- context = new DefaultMapContext(new MapLayer[] { layer }, envelope
- .getCoordinateReferenceSystem());
- final StreamingRenderer renderer = new StreamingRenderer();
- renderer.setContext(context);
- renderer.setJava2DHints(getJava2DHints());
- final Map rendererHints2 = new HashMap(
- getRendererHints() != null ? getRendererHints()
- : Collections.EMPTY_MAP);
- rendererHints2.put(LABEL_CACHE_KEY, new IntegratingLabelCache(
- labelCache));
- renderer.setRendererHints(rendererHints2);
- renderer.paint(graphics, paintArea, envelope, transform);
+ context = new DefaultMapContext(new MapLayer[]{layer}, envelope.getCoordinateReferenceSystem());
+ delegate = new StreamingRenderer();
+ delegate.setContext(context);
+ delegate.setJava2DHints(getJava2DHints());
+ Map rendererHints2 = new HashMap(getRendererHints() != null ? getRendererHints() : Collections.EMPTY_MAP);
+ rendererHints2.put(LABEL_CACHE_KEY, new IntegratingLabelCache(labelCache));
+ delegate.setRendererHints(rendererHints2);
+
+ // cascade events, provided there is anyone listening
+ listener = new RenderListener() {
+
+ public void featureRenderer(SimpleFeature feature) {
+ fireFeatureRenderedEvent(feature);
+ }
+
+ public void errorOccurred(Exception e) {
+ fireErrorEvent(e);
+ }
+ };
+ delegate.addRenderListener(listener);
+
+ delegate.paint(graphics, paintArea, envelope, transform);
} finally {
- if (context != null)
- context.clearLayerList();
+ // cleanups to avoid circular references
+ if(context != null)
+ context.clearLayerList();
+ if(listener != null && delegate != null)
+ delegate.removeRenderListener(listener);
+
+
+ delegate = null;
}
}
/**
- * If the forceCRS hint is set then return the value.
- *
- * @return the value of the forceCRS hint or null
- */
- private CoordinateReferenceSystem getForceCRSHint() {
- if (rendererHints == null)
- return null;
- final Object crs = this.rendererHints.get("forceCRS");
- if (crs instanceof CoordinateReferenceSystem)
- return (CoordinateReferenceSystem) crs;
-
- return null;
+ * If the forceCRS hint is set then return the value.
+ * @return the value of the forceCRS hint or null
+ */
+ private CoordinateReferenceSystem getForceCRSHint() {
+ if ( rendererHints==null )
+ return null;
+ Object crs=this.rendererHints.get("forceCRS");
+ if( crs instanceof CoordinateReferenceSystem )
+ return (CoordinateReferenceSystem) crs;
+
+ return null;
}
- /**
- * @deprecated
- */
- public void paint(final Graphics2D graphics, final Rectangle paintArea, final Envelope mapArea) {
- paint(graphics, paintArea, new ReferencedEnvelope(mapArea, context
- .getCoordinateReferenceSystem()));
- }
+ /**
+ * @deprecated
+ */
+ public void paint(Graphics2D graphics, Rectangle paintArea, Envelope mapArea) {
+ paint(graphics, paintArea, new ReferencedEnvelope(mapArea, context.getCoordinateReferenceSystem()));
+ }
- /**
- * @deprecated
- */
- public void paint(final Graphics2D graphics, final Rectangle paintArea,
- final Envelope mapArea, final AffineTransform worldToScreen) {
- paint(graphics, paintArea, new ReferencedEnvelope(mapArea, context
- .getCoordinateReferenceSystem()), worldToScreen);
- }
+ /**
+ * @deprecated
+ */
+ public void paint(Graphics2D graphics, Rectangle paintArea, Envelope mapArea, AffineTransform worldToScreen) {
+ paint(graphics, paintArea, new ReferencedEnvelope(mapArea, context.getCoordinateReferenceSystem()), worldToScreen);
+ }
}
Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/FilterUtil.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/FilterUtil.java 2009-08-28 10:45:01 UTC (rev 339)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/FilterUtil.java 2009-08-28 11:13:50 UTC (rev 340)
@@ -38,30 +38,39 @@
import com.vividsolutions.jts.geom.GeometryFactory;
-
/**
* Diese Klasse enthaelt statische Helper-Methoden fuer die Arbeit mit
* {@link Filter}.
- * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
*
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ * (University of Bonn/Germany)
+ *
* @version 1.01
*
*/
public class FilterUtil {
- /** Instanz von {@link FilterFactory}. */
- public static final FilterFactory FILTER_FAC = CommonFactoryFinder.getFilterFactory(null);
- /** Globale Instanz von {@link FilterFactory2} **/
- public static final FilterFactory2 FILTER_FAC2 = CommonFactoryFinder.getFilterFactory2(null);
- /** Instanz von {@link GeometryFactory}. */
- public static final GeometryFactory GEOMETRY_FAC = new GeometryFactory();
-
- /**
- * Erzeugt eine Kopie eines Filters
- * @param filter ein Filter
- */
- public static Filter cloneFilter(Filter filter) {
- DuplicatingFilterVisitor dfv = new DuplicatingFilterVisitor(FILTER_FAC2);
- Filter newFilter = (Filter) dfv.visit( filter , (Object)null );
- return newFilter;
- }
+ /** Instanz von {@link FilterFactory}. */
+ public static final FilterFactoryImpl FILTER_FAC = (FilterFactoryImpl) CommonFactoryFinder
+ .getFilterFactory(null);
+ /** Globale Instanz von {@link FilterFactory2} **/
+ public static final FilterFactory2 FILTER_FAC2 = CommonFactoryFinder
+ .getFilterFactory2(null);
+ /** Instanz von {@link GeometryFactory}. */
+ public static final GeometryFactory GEOMETRY_FAC = new GeometryFactory();
+//
+// /**
+// * Erzeugt eine Kopie eines Filters
+// *
+// * @param filter
+// * ein Filter
+// *
+// * TODO GT 26 Das wird in Atlas und Schmitzm nichtbenötig. Wir
+// * können die Methode als theoretisch einfach mal entfernen..
+// * Ansonsten habe ich auch eine Mail auf die gt-user geschickt.
+// */
+// public static Filter cloneFilter(Filter filter) {
+// DuplicatingFilterVisitor dfv = new DuplicatingFilterVisitor(FILTER_FAC2);
+// Filter newFilter = (Filter) dfv.visit(filter, (Object) null);
+// return newFilter;
+// }
}
Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/JMapPane.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/JMapPane.java 2009-08-28 10:45:01 UTC (rev 339)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/JMapPane.java 2009-08-28 11:13:50 UTC (rev 340)
@@ -91,6 +91,7 @@
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.GeometryDescriptor;
import org.opengis.filter.Filter;
+import org.opengis.filter.FilterFactory;
import org.opengis.filter.expression.Expression;
import org.opengis.filter.spatial.BinarySpatialOperator;
import org.opengis.parameter.GeneralParameterValue;
@@ -408,7 +409,7 @@
}
};
- private static final FilterFactoryImpl ff = FilterUtil.FILTER_FAC;
+ private static final FilterFactory ff = FilterUtil.FILTER_FAC;
private static final GeometryFactory gf = FilterUtil.GEOMETRY_FAC;
/**
@@ -2598,7 +2599,7 @@
filter = prepareFilter(fsCRS);
filterCache.put(fsCRS, filter);
}
- Expression geometry = ff.createAttributeExpression(geomDescr
+ Expression geometry = ff.property(geomDescr
.getLocalName());
filter.setExpression1(geometry);
return filter;
@@ -2739,11 +2740,13 @@
}
// Filter fuer Point zusammenstellen
final Geometry geometry = FilterUtil.GEOMETRY_FAC.createPoint(nearPoint);
+
final DWithinImpl dwithinFilter = (DWithinImpl) FilterUtil.FILTER_FAC
.createGeometryDistanceFilter(DWithinImpl.GEOMETRY_DWITHIN);
dwithinFilter.setDistance(nearDist);
dwithinFilter.setExpression2(FilterUtil.FILTER_FAC
.createLiteralExpression(geometry));
+
return dwithinFilter;
}
More information about the Schmitzm-commits
mailing list