[Schmitzm-commits] r542 - in branches/1.0-gt2-2.6/src: schmitzm/geotools/gui schmitzm/geotools/styling skrueger/geotools

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Sat Nov 21 16:01:08 CET 2009


Author: alfonx
Date: 2009-11-21 16:01:05 +0100 (Sat, 21 Nov 2009)
New Revision: 542

Modified:
   branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/SelectableXMapPane.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/styling/StylingUtil.java
   branches/1.0-gt2-2.6/src/skrueger/geotools/GeomFilterGenerator.java
   branches/1.0-gt2-2.6/src/skrueger/geotools/SelectXMapPaneMouseListener.java
Log:
* Improved selecting with INTERSECTS filter instead of BBOX filter.
* Transforming CRS when SELECT_ONE_FROM_TOP on raster layers of different CRS

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/SelectableXMapPane.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/SelectableXMapPane.java	2009-11-20 21:49:00 UTC (rev 541)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/SelectableXMapPane.java	2009-11-21 15:01:05 UTC (rev 542)
@@ -91,6 +91,7 @@
 import skrueger.geotools.XMapPane;
 import skrueger.geotools.GeomFilterGenerator.BoundingBoxFilterGenerator;
 
+import com.vividsolutions.jts.geom.Coordinate;
 import com.vividsolutions.jts.geom.Envelope;
 
 /**
@@ -741,7 +742,7 @@
 			// wird.AbstractGridCoverage2DReader
 			// Ansonsten Raster-Layer einfach uebergehen.
 			if (isGridCoverageLayer(layer)) {
-				if (mode == SELECT_TOP
+				if ((mode == SELECT_TOP || mode == SELECT_ONE_FROM_TOP)
 						&& gridLayerIntersectsEnvelope(layer, env))
 					break;
 				continue;
@@ -791,16 +792,16 @@
 
 	/**
 	 * Ermittelt alle Raster-Werte, die an einer bestimmten Geo-Position liegen.
-	 * Beim Modus {@link #SELECT_TOP} wird nur das oberste sichtbare Layer
-	 * durchsucht. Beim Modus {@link #SELECT_ALL} werden alle sichtbaren Layer
-	 * durchsucht.
+	 * Beim Modus {@link #SELECT_TOP} oder {@link #SELECT_ONE_FROM_TOP} wird nur
+	 * das oberste sichtbare Layer durchsucht. Beim Modus {@link #SELECT_ALL}
+	 * werden alle sichtbaren Layer durchsucht.
 	 * <p>
 	 * SK: 28.09.2007 Da ein Rasterlayer auch mehrere Baender haben kann, ist es
 	 * sinnvoll, nicht <code>Hashtable MapLayer,Double </code> sondern
 	 * <code>Hashtable MapLayer,Double[] </code> zurueckzugeben.
 	 * 
 	 * @param point
-	 *            Geo-Referenzgeop
+	 *            Geo-Referenz
 	 * @param mode
 	 *            Suchmodus
 	 * @return eine leere {@link Hashtable} falls keine Werte ermittelt werden
@@ -837,7 +838,7 @@
 			if (!(layerObj instanceof GridCoverage2D || layerObj instanceof AbstractGridCoverage2DReader)) {
 				final Envelope pointAsEnvelope = new Envelope(point.getX(),
 						point.getX(), point.getY(), point.getY());
-				if (mode == SELECT_TOP
+				if ((mode == SELECT_TOP || mode == SELECT_ONE_FROM_TOP)
 						&& featureLayerIntersectsEnvelope(layer,
 								pointAsEnvelope)) {
 				}
@@ -850,6 +851,7 @@
 				// LOGGER.info("layerObj instanceof AbstractGridCoverage2DReader"
 				// );
 				AbstractGridCoverage2DReader reader = (AbstractGridCoverage2DReader) layerObj;
+
 				Parameter readGG = new Parameter(
 						AbstractGridFormat.READ_GRIDGEOMETRY2D);
 
@@ -879,7 +881,17 @@
 
 			try {
 				// Grid an Geo-Position auswerten
-				sourceGrid.evaluate(point, values);
+				if (!CRS.equalsIgnoreMetadata(getContext()
+						.getCoordinateReferenceSystem(), sourceGrid
+						.getCoordinateReferenceSystem())) {
+					Coordinate pointInLayerCRS = JTSUtil.transformCoordinate(
+							new Coordinate(point.getX(), point.getY()),
+							getContext().getCoordinateReferenceSystem(),
+							sourceGrid.getCoordinateReferenceSystem());
+					sourceGrid.evaluate(new Point.Double(pointInLayerCRS.x,
+							pointInLayerCRS.y), values);
+				} else
+					sourceGrid.evaluate(point, values);
 			} catch (CannotEvaluateException err) {
 				// z.B. Punkt ausserhalb des Rasters --> Layer uebergehen
 				continue;
@@ -890,7 +902,7 @@
 
 			result.put(layer, values);
 			// Beim Modus "oberstes Layer selektieren" die Schleife beenden
-			if (mode == SELECT_TOP)
+			if (mode == SELECT_TOP || mode == SELECT_ONE_FROM_TOP)
 				break;
 		}
 		return result;
@@ -1081,7 +1093,9 @@
 	 * Ermittelt alle sichtbaren Features, die einen Filter erfuellen. Beim
 	 * Modus {@link #SELECT_TOP} wird nur das oberste sichtbare Layer
 	 * durchsucht. Beim Modus {@link #SELECT_ALL} werden alle sichtbaren Layer
-	 * durchsucht.
+	 * durchsucht.<br/>
+	 * In mode SELECT_ONE_FROM_TOP, the method will iterator over all non-raster
+	 * {@link MapLayer}s and the first layer returning
 	 * 
 	 * @see #findFeatures(GeometryFilterImpl, int, Envelope)
 	 * 
@@ -1120,7 +1134,7 @@
 			// im obersten (sichtbaren) Layer gesucht wird.
 			// Ansonsten Raster-Layer einfach uebergehen.
 			if (isGridCoverageLayer(layer)) {
-				if (mode == SELECT_TOP
+				if ((mode == SELECT_TOP || mode == SELECT_ONE_FROM_TOP)
 						&& gridLayerIntersectsEnvelope(layer, env))
 					break;
 				continue;
@@ -1136,32 +1150,27 @@
 			// sind ploetzlich EMPTY!!!!!!!!!!!!!!!!!!!!!!!!!!!
 			final FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = (FeatureSource<SimpleFeatureType, SimpleFeature>) layer
 					.getFeatureSource();
-			final GeometryFilterImpl distancefilter = filterGenerator
+
+			final GeometryFilterImpl generatedFilter = filterGenerator
 					.adaptFilter(featureSource);
 
 			/**
-			 * 8.8.2008: SK Wenn für das Layer auch ein Filter aktiv ist, dann
-			 * soll dieser mit AND an den distanceFilter gebunden werden.
-			 * "Filter filter" ist entweder der distanceFilter oder
-			 * (distanceFilter AND layerFilter)
+			 * If the layer has already set a filter in its query, we have to
+			 * combine them.
 			 */
-			Filter filter = distancefilter;
+			Filter filter = generatedFilter;
 			if (layer.getQuery() != null) {
 				final Filter layerFilter = layer.getQuery().getFilter();
 				if (layerFilter != null && !layerFilter.equals(Filter.INCLUDE)) {
-					filter = distancefilter.and(layerFilter);
+					filter = generatedFilter.and(layerFilter);
 				}
 			}
 
 			try {
-				// Filter auf Layer des Features anwenden
-				// FeatureCollection fc = layer.getFeatureSource().getFeatures(
-				// FilterUtil.cloneFilter(filter) ); // KLAPPT (NOCH) NICHT
-				// FeatureCollection fc = featureSource.getFeatures(
-				// distancefilter );
 				FeatureCollection<SimpleFeatureType, SimpleFeature> fc = featureSource
 						.getFeatures(filter);
 
+				// If not empty, filter it for visbile features only
 				if (!fc.isEmpty()) {
 					fc = StylingUtil.filterSLDVisibleOnly(fc, layer.getStyle(),
 							this);

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/styling/StylingUtil.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/styling/StylingUtil.java	2009-11-20 21:49:00 UTC (rev 541)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/styling/StylingUtil.java	2009-11-21 15:01:05 UTC (rev 542)
@@ -1304,8 +1304,7 @@
 						}
 
 						// 2. Check: Eine Rule ist gülrig, aber trifft der
-						// Filter
-						// für dieses SimpleFeature?
+						// Filter für dieses SimpleFeature?
 						final Filter rFilter = rule.getFilter();
 						if ((rFilter != null) && (!rFilter.evaluate(feature)))
 							continue;
@@ -1338,11 +1337,22 @@
 								}
 							} else if ((geom instanceof MultiPolygon)
 									|| (geom instanceof Polygon)) {
+								
 								if (symb instanceof PolygonSymbolizer) {
 									if (((PolygonSymbolizer) symb).getFill() != null)
 										passt = true;
 									break;
 								}
+
+								if (symb instanceof PointSymbolizer) {
+									// This is a special case and not handles
+									// 100% correct yet. Polygons visualized
+									// with Pointsymbolizers should also have
+									// different Filters when they are selected
+									if (((PointSymbolizer) symb).getGraphic() != null)
+										passt = true;
+									break;
+								}
 							} else {
 								LOGGER
 										.warn("Unbekannter geom Typ! Gehe von sichbar aus!");
@@ -2435,53 +2445,49 @@
 			};
 
 			public void visit(LineSymbolizer sym) {
-				sym
-						.setGeometryPropertyName(FeatureUtil.findBestMatchingAttributeFallBackFirst(
-								schema, sym.getGeometryPropertyName())
-								.getLocalPart());
+				sym.setGeometryPropertyName(FeatureUtil
+						.findBestMatchingAttributeFallBackFirst(schema,
+								sym.getGeometryPropertyName()).getLocalPart());
 				super.visit(sym);
 			}
 
 			public void visit(PolygonSymbolizer sym) {
-				sym
-						.setGeometryPropertyName(FeatureUtil.findBestMatchingAttributeFallBackFirst(
-								schema, sym.getGeometryPropertyName())
-								.getLocalPart());
+				sym.setGeometryPropertyName(FeatureUtil
+						.findBestMatchingAttributeFallBackFirst(schema,
+								sym.getGeometryPropertyName()).getLocalPart());
 				super.visit(sym);
 			}
 
 			public void visit(PointSymbolizer sym) {
-				sym
-						.setGeometryPropertyName(FeatureUtil.findBestMatchingAttributeFallBackFirst(
-								schema, sym.getGeometryPropertyName())
-								.getLocalPart());
+				sym.setGeometryPropertyName(FeatureUtil
+						.findBestMatchingAttributeFallBackFirst(schema,
+								sym.getGeometryPropertyName()).getLocalPart());
 				super.visit(sym);
 			}
+
 			@Override
 			public void visit(TextSymbolizer sym) {
-				sym
-						.setGeometryPropertyName(FeatureUtil.findBestMatchingAttributeFallBackFirst(
-								schema, sym.getGeometryPropertyName())
-								.getLocalPart());
+				sym.setGeometryPropertyName(FeatureUtil
+						.findBestMatchingAttributeFallBackFirst(schema,
+								sym.getGeometryPropertyName()).getLocalPart());
 
 				if (sym.getLabel() instanceof PropertyName) {
 					PropertyName propertyname = (PropertyName) sym.getLabel();
-					sym.setLabel(ff
-							.property(FeatureUtil.findBestMatchingAttributeFallBackFirst(
-									schema, propertyname.getPropertyName())));
+					sym.setLabel(ff.property(FeatureUtil
+							.findBestMatchingAttributeFallBackFirst(schema,
+									propertyname.getPropertyName())));
 				}
 
 				if (sym.getPriority() instanceof PropertyName) {
 					PropertyName propertyname = (PropertyName) sym
 							.getPriority();
-					sym.setPriority(ff
-							.property(FeatureUtil.findBestMatchingAttributeFallBackFirst(
-									schema, propertyname.getPropertyName())));
+					sym.setPriority(ff.property(FeatureUtil
+							.findBestMatchingAttributeFallBackFirst(schema,
+									propertyname.getPropertyName())));
 				}
 
 				super.visit(sym);
 			}
-			
 
 		};
 
@@ -2490,5 +2496,4 @@
 		return (Style) dsv.getCopy();
 	}
 
-
 }

Modified: branches/1.0-gt2-2.6/src/skrueger/geotools/GeomFilterGenerator.java
===================================================================
--- branches/1.0-gt2-2.6/src/skrueger/geotools/GeomFilterGenerator.java	2009-11-20 21:49:00 UTC (rev 541)
+++ branches/1.0-gt2-2.6/src/skrueger/geotools/GeomFilterGenerator.java	2009-11-21 15:01:05 UTC (rev 542)
@@ -7,9 +7,8 @@
 import org.geotools.data.FeatureSource;
 import org.geotools.filter.AbstractFilter;
 import org.geotools.filter.GeometryFilterImpl;
-import org.geotools.filter.spatial.DWithinImpl;
+import org.geotools.geometry.jts.ReferencedEnvelope;
 import org.geotools.referencing.CRS;
-import org.geotools.resources.CRSUtilities;
 import org.opengis.feature.simple.SimpleFeature;
 import org.opengis.feature.simple.SimpleFeatureType;
 import org.opengis.feature.type.GeometryDescriptor;
@@ -22,26 +21,26 @@
 
 import com.vividsolutions.jts.geom.Coordinate;
 import com.vividsolutions.jts.geom.Envelope;
-import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.MultiPolygon;
+import com.vividsolutions.jts.geom.Polygon;
 
 /**
  * The {@link GeomFilterGenerator} prepares a {@link BinarySpatialOperator}
- * filter for multiple use. Only the "right" argument is prepared. The
- * "left" argument (the geometry attribute of the {@link FeatureSource} to
- * filter) is first set on calling {@link #adaptFilter(FeatureSource)} for a
- * specific {@link FeatureSource}. This method also takes care to recreate
- * the filter (or its "right" argument) if the given {@link FeatureSource}
- * has another {@link CoordinateReferenceSystem} than the base constraint.<br>
+ * filter for multiple use. Only the "right" argument is prepared. The "left"
+ * argument (the geometry attribute of the {@link FeatureSource} to filter) is
+ * first set on calling {@link #adaptFilter(FeatureSource)} for a specific
+ * {@link FeatureSource}. This method also takes care to recreate the filter (or
+ * its "right" argument) if the given {@link FeatureSource} has another
+ * {@link CoordinateReferenceSystem} than the base constraint.<br>
  * The type of filter (e.g. distance or bounding box) is specified by the
- * subclass implemenation of
- * {@link #prepareFilter(CoordinateReferenceSystem)} .
+ * subclass implemenation of {@link #prepareFilter(CoordinateReferenceSystem)} .
  * 
  * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
  */
- public abstract class GeomFilterGenerator {
+public abstract class GeomFilterGenerator {
 	/**
-	 * Holds the {@link CoordinateReferenceSystem} the filter constraint
-	 * bases on.
+	 * Holds the {@link CoordinateReferenceSystem} the filter constraint bases
+	 * on.
 	 */
 	protected CoordinateReferenceSystem baseCRS = null;
 	/**
@@ -54,8 +53,8 @@
 	 * Creates a new filter generator
 	 * 
 	 * @param crs
-	 *            {@link CoordinateReferenceSystem} the base constraint
-	 *            ("right" filter argument is relative to)
+	 *            {@link CoordinateReferenceSystem} the base constraint ("right"
+	 *            filter argument is relative to)
 	 */
 	public GeomFilterGenerator(CoordinateReferenceSystem crs) {
 		this.baseCRS = crs;
@@ -66,17 +65,21 @@
 	 * transformed to the given {@link CoordinateReferenceSystem}.
 	 * 
 	 * @param crs
-	 *            the {@link CoordinateReferenceSystem} the base constraint
-	 *            is transformed to
+	 *            the {@link CoordinateReferenceSystem} the base constraint is
+	 *            transformed to
+	 * @param Class
+	 *            the geometry class we are testing against. For point against
+	 *            polygon for example, an intersects is much faster that the
+	 *            bbox filter
 	 */
 	protected abstract GeometryFilterImpl prepareFilter(
-			CoordinateReferenceSystem crs);
+			CoordinateReferenceSystem crs, Class<?> geomClass);
 
 	/**
 	 * Completes the filter with its "left" argument for a concrete
-	 * {@link FeatureSource}. If the {@link FeatureSource FeatureSource's}
-	 * CRS differs from the CRS the base constraint is specified in, first a
-	 * new filter is created by calling
+	 * {@link FeatureSource}. If the {@link FeatureSource FeatureSource's} CRS
+	 * differs from the CRS the base constraint is specified in, first a new
+	 * filter is created by calling
 	 * {@link #prepareFilter(CoordinateReferenceSystem)}.
 	 * 
 	 * @param fs
@@ -85,16 +88,16 @@
 	 */
 	public GeometryFilterImpl adaptFilter(
 			FeatureSource<SimpleFeatureType, SimpleFeature> fs) {
-		GeometryDescriptor geomDescr = fs.getSchema()
-				.getGeometryDescriptor();
+		GeometryDescriptor geomDescr = fs.getSchema().getGeometryDescriptor();
 		CoordinateReferenceSystem fsCRS = geomDescr
 				.getCoordinateReferenceSystem();
 		GeometryFilterImpl filter = filterCache.get(fsCRS);
 		if (filter == null) {
-			filter = prepareFilter(fsCRS);
+			filter = prepareFilter(fsCRS, geomDescr.getType().getBinding());
 			filterCache.put(fsCRS, filter);
 		}
-		Expression geometry = FilterUtil.FILTER_FAC2.property(geomDescr.getLocalName());
+		Expression geometry = FilterUtil.FILTER_FAC2.property(geomDescr
+				.getLocalName());
 		filter.setExpression1(geometry);
 		return filter;
 	}
@@ -131,18 +134,15 @@
 		 * 
 		 * @param crs
 		 *            the {@link CoordinateReferenceSystem} the bounding box is
-		 *            transformed to
+		 *            transformed to * @param Class the geometry class we are
+		 *            testing against. For point against polygon for example, an
+		 *            intersects is much faster that the bbox filter
 		 */
-		protected GeometryFilterImpl prepareFilter(CoordinateReferenceSystem crs) {
+		protected GeometryFilterImpl prepareFilter(
+				CoordinateReferenceSystem crs, Class<?> geomClass) {
 			Envelope bbEnv = baseEnv;
-			
-			System.out.println("base Envv = "+baseEnv);
-			
-			if (!CRS.equalsIgnoreMetadata(baseCRS,crs))
+			if (!CRS.equalsIgnoreMetadata(baseCRS, crs))
 				bbEnv = JTSUtil.transformEnvelope(baseEnv, baseCRS, crs);
-			
-			System.out.println("thetransformed env = "+bbEnv);
-			
 			// Filter fuer Envelope zusammenstellen
 			Expression bbox = FilterUtil.FILTER_FAC.createBBoxExpression(bbEnv);
 			GeometryFilterImpl bboxFilter = (GeometryFilterImpl) FilterUtil.FILTER_FAC
@@ -160,40 +160,33 @@
 	 * 
 	 * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
 	 */
-	public static class NearPointFilterGenerator extends GeomFilterGenerator {
+	public static class PointFilterGenerator extends GeomFilterGenerator {
 		/**
 		 * Holds the base constraint (coordinate) relative to the
 		 * {@linkplain GeomFilterGenerator#baseCRS base CRS}.
 		 */
 		protected Coordinate basePoint = null;
-		/**
-		 * Holds the distance "around" the base point relative to the
-		 * {@linkplain GeomFilterGenerator#baseCRS base CRS}.
-		 */
-		protected double baseDist = 0.0;
-		/**
-		 * Holds a point which is in distance {@link #baseDist} to the
-		 * {@link #basePoint}.
-		 */
-		protected Coordinate basePoint2 = null;
+		private ReferencedEnvelope baseEnv;
 
 		/**
 		 * Creates a new filter generator.
 		 * 
 		 * @param basePoint
-		 *            defNearPointFilterGeneratorines the point for the "near point" constraint
+		 *            defNearPointFilterGeneratorines the point for the
+		 *            "near point" constraint
 		 * @param dist
 		 *            defines the distance around the base point
 		 * @param crs
 		 *            defines the CRS of base point
 		 */
-		public NearPointFilterGenerator(Coordinate basePoint, double dist,
+		public PointFilterGenerator(Coordinate basePoint, double radius,
 				CoordinateReferenceSystem crs) {
 			super(crs);
 			this.basePoint = basePoint;
-			this.baseDist = dist;
-			// Create a point which is in distance "dist" to the base point
-			this.basePoint2 = new Coordinate(basePoint.x + dist, basePoint.y);
+			this.baseEnv = new ReferencedEnvelope(basePoint.x - radius,
+					basePoint.x + radius, basePoint.y - radius, basePoint.y
+							+ radius, crs);
+
 		}
 
 		/**
@@ -206,7 +199,7 @@
 		 * @param crs
 		 *            defines the CRS of base point
 		 */
-		public NearPointFilterGenerator(Point2D basePoint, double dist,
+		public PointFilterGenerator(Point2D basePoint, double dist,
 				CoordinateReferenceSystem crs) {
 			this(new Coordinate(basePoint.getX(), basePoint.getY()), dist, crs);
 		}
@@ -219,35 +212,48 @@
 		 *            the {@link CoordinateReferenceSystem} the point and
 		 *            distance is transformed to
 		 */
-		protected GeometryFilterImpl prepareFilter(CoordinateReferenceSystem crs) {
-			Coordinate nearPoint = basePoint;
-			double nearDist = baseDist;
-			if (!baseCRS.equals(crs)) {
-				nearPoint = JTSUtil
-						.transformCoordinate(basePoint, baseCRS, crs);
-				// Transform the distance (maybe "dirty")
-				// --> transform the point2 and calculate the
-				// distance to the tranformed base point
-				Coordinate nearPoint2 = JTSUtil.transformCoordinate(basePoint2,
-						baseCRS, crs);
+		protected GeometryFilterImpl prepareFilter(
+				CoordinateReferenceSystem crs, Class<?> geomClass) {
+			Coordinate localCrsPoint = basePoint;
 
-				if (nearPoint == null || nearPoint2 == null)
-					throw new RuntimeException("Unable to transform CRS from "
-							+ baseCRS + " to " + crs);
+			boolean isPolygonGeometry = (Polygon.class
+					.isAssignableFrom(geomClass) || MultiPolygon.class
+					.isAssignableFrom(geomClass));
 
-				nearDist = Math.abs(nearPoint.x - nearPoint2.x);
+			GeometryFilterImpl filter = (GeometryFilterImpl) FilterUtil.FILTER_FAC
+			.createGeometryFilter(AbstractFilter.GEOMETRY_INTERSECTS);
+
+			if (isPolygonGeometry) {
+				// we chanck against a polygon with instersects
+
+				if (!CRS.equalsIgnoreMetadata(baseCRS, crs))
+					localCrsPoint = JTSUtil.transformCoordinate(basePoint,
+							baseCRS, crs);
+//
+//				GeometryFilterImpl intersectsFilter = (GeometryFilterImpl) FilterUtil.FILTER_FAC
+//						.createGeometryFilter(AbstractFilter.GEOMETRY_INTERSECTS);
+				filter.setExpression2(FilterUtil.FILTER_FAC2
+						.literal(localCrsPoint));
+//
+//				return intersectsFilter;
+
+			} else {
+				// we check against lines and points with a bbox
+//				GeometryFilterImpl filter = (GeometryFilterImpl) FilterUtil.FILTER_FAC
+//				.createGeometryFilter(AbstractFilter.GEOMETRY_BBOX);
+
+				Envelope bbEnv = baseEnv;
+				if (!CRS.equalsIgnoreMetadata(baseCRS, crs))
+					bbEnv = JTSUtil.transformEnvelope(baseEnv, baseCRS, crs);
+
+				// Filter fuer Envelope zusammenstellen
+				Expression bbox = FilterUtil.FILTER_FAC
+						.createBBoxExpression(bbEnv);
+				filter.setExpression2(bbox);
 			}
-			// Filter fuer Point zusammenstellen
-			final Geometry geometry = FilterUtil.GEOMETRY_FAC
-					.createPoint(nearPoint);
+			
+			return filter;
 
-			final DWithinImpl dwithinFilter = new DWithinImpl(
-					FilterUtil.FILTER_FAC2, null, null);
-			dwithinFilter.setDistance(nearDist);
-			dwithinFilter.setExpression2(FilterUtil.FILTER_FAC2
-					.literal(geometry));
-
-			return dwithinFilter;
 		}
 
 	}

Modified: branches/1.0-gt2-2.6/src/skrueger/geotools/SelectXMapPaneMouseListener.java
===================================================================
--- branches/1.0-gt2-2.6/src/skrueger/geotools/SelectXMapPaneMouseListener.java	2009-11-20 21:49:00 UTC (rev 541)
+++ branches/1.0-gt2-2.6/src/skrueger/geotools/SelectXMapPaneMouseListener.java	2009-11-21 15:01:05 UTC (rev 542)
@@ -4,34 +4,22 @@
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseWheelEvent;
-import java.awt.geom.AffineTransform;
 import java.awt.geom.Point2D;
-import java.lang.reflect.Constructor;
 import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.Iterator;
-import java.util.List;
-import java.util.WeakHashMap;
 
 import org.apache.log4j.Logger;
 import org.geotools.data.memory.MemoryFeatureCollection;
 import org.geotools.feature.FeatureCollection;
-import org.geotools.feature.FeatureIterator;
-import org.geotools.geometry.DirectPosition2D;
 import org.geotools.geometry.jts.ReferencedEnvelope;
 import org.geotools.map.MapLayer;
-import org.geotools.swing.event.MapMouseEvent;
-import org.geotools.swing.tool.InfoToolHelper;
-import org.geotools.swing.tool.VectorLayerHelper;
-import org.geotools.swing.utils.MapLayerUtils;
-import org.opengis.feature.Feature;
 import org.opengis.feature.simple.SimpleFeature;
 import org.opengis.feature.simple.SimpleFeatureType;
-import org.opengis.feature.type.GeometryDescriptor;
 
 import schmitzm.geotools.gui.SelectableXMapPane;
 import schmitzm.geotools.map.event.FeatureSelectedEvent;
-import skrueger.geotools.GeomFilterGenerator.BoundingBoxFilterGenerator;
+import skrueger.geotools.GeomFilterGenerator.PointFilterGenerator;
 
 import com.vividsolutions.jts.geom.Coordinate;
 import com.vividsolutions.jts.geom.Envelope;
@@ -47,154 +35,23 @@
 		if (!xMapPane.isWellDefined())
 			return false;
 		if ((xMapPane.getState() == XMapPane.ZOOM_IN
-				|| xMapPane.getState() == xMapPane.ZOOM_OUT || xMapPane
-				.getState() == xMapPane.PAN))
+				|| xMapPane.getState() == XMapPane.ZOOM_OUT || xMapPane
+				.getState() == XMapPane.PAN))
 			return false;
 		if (xMapPane.getState() == XMapPane.NONE)
 			;
 		return enabled;
 	}
-//
-//	/**
-//	 * Default distance fraction used with line and point features. When the
-//	 * user clicks on the map, this tool searches for features within a
-//	 * rectangle of width w centred on the mouse location, where w is the
-//	 * average map side length multiplied by the value of this constant.
-//	 */
-//	public static final double DEFAULT_DISTANCE_FRACTION = 0.01d;
-//	
-//
-//    private WeakHashMap<MapLayer, InfoToolHelper> helperTable= new WeakHashMap<MapLayer, InfoToolHelper>();
-////
-//	@Override
-//	public void mouseClicked2(MouseEvent event) {
-//		AffineTransform tr = xMapPane.getScreenToWorld();
-//		DirectPosition2D pos = new DirectPosition2D(event.getX(), event
-//				.getY());
-//		tr.transform(pos, pos);
-//		pos.setCoordinateReferenceSystem(xMapPane.getContext()
-//				.getCoordinateReferenceSystem());
-//		FeatureIterator<? extends Feature> iter = null;
-//
-//		for (MapLayer layer : xMapPane.getContext().getLayers()) {
-//			if (layer.isSelected()) {
-//				InfoToolHelper helper = null;
-//
-//				String layerName = layer.getTitle();
-//				if (layerName == null || layerName.length() == 0) {
-//					layerName = layer.getFeatureSource().getName()
-//							.getLocalPart();
-//				}
-//				if (layerName == null || layerName.length() == 0) {
-//					layerName = layer.getFeatureSource().getSchema().getName()
-//							.getLocalPart();
-//				}
-//
-//				helper = helperTable.get(layer);
-//				if (helper == null) {
-//					if (MapLayerUtils.isGridLayer(layer)) {
-//						String gridAttrName = MapLayerUtils
-//								.getGridAttributeName(layer);
-//						try {
-//							iter = layer.getFeatureSource().getFeatures()
-//									.features();
-//							Object rasterSource = iter.next().getProperty(
-//									gridAttrName).getValue();
-//							Class<?> clazz = Class
-//									.forName("org.geotools.swing.tool.GridLayerHelper");
-//							Constructor<?> ctor = clazz
-//									.getConstructor(Object.class);
-//							helper = (InfoToolHelper) ctor
-//									.newInstance(rasterSource);
-//							helperTable.put(layer, helper);
-//
-//						} catch (Exception ex) {
-//							throw new IllegalStateException(
-//									"Failed to create InfoToolHelper for grid layer",
-//									ex);
-//
-//						} finally {
-//							iter.close();
-//						}
-//
-//					} else {
-//						GeometryDescriptor geomDesc = layer.getFeatureSource()
-//								.getSchema().getGeometryDescriptor();
-//						String attrName = geomDesc.getLocalName();
-//						Class<?> geomClass = geomDesc.getType().getBinding();
-//
-//						try {
-//							Class<?> clazz = Class
-//									.forName("org.geotools.swing.tool.VectorLayerHelper");
-//							Constructor<?> ctor = clazz.getConstructor(
-//									MapLayer.class, String.class, Class.class);
-//							helper = (InfoToolHelper) ctor.newInstance(layer,
-//									attrName, geomClass);
-//							helperTable.put(layer, helper);
-//
-//						} catch (Exception ex) {
-//							throw new IllegalStateException(
-//									"Failed to create InfoToolHelper for vector layer",
-//									ex);
-//						}
-//					}
-//				}
-//
-//				Object info = null;
-//
-//				if (helper.getType() == InfoToolHelper.Type.VECTOR_HELPER) {
-//					ReferencedEnvelope mapEnv = xMapPane.getMapArea();
-//					double searchWidth = DEFAULT_DISTANCE_FRACTION
-//							* (mapEnv.getWidth() + mapEnv.getHeight()) / 2;
-//					try {
-//						info = helper.getInfo(pos, Double.valueOf(searchWidth));
-//					} catch (Exception ex) {
-//						throw new IllegalStateException(ex);
-//					}
-//
-//					if (info != null) {
-//						FeatureCollection selectedFeatures = (FeatureCollection) info;
-//						try {
-//							iter = selectedFeatures.features();
-//							while (iter.hasNext()) {
-//								System.out.println(layerName +": "+ iter.next());
-//							}
-//
-//						} catch (Exception ex) {
-//							throw new IllegalStateException(ex);
-//
-//						} finally {
-//							if (iter != null) {
-//								iter.close();
-//							}
-//						}
-//					}
-//
-//				} else {
-//					try {
-//						info = helper.getInfo(pos);
-//					} catch (Exception ex) {
-//						throw new IllegalStateException(ex);
-//					}
-//
-//					if (info != null) {
-//						List<Number> bandValues = (List<Number>) info;
-//						if (!bandValues.isEmpty()) {
-//							System.out.println(layerName +": "+ iter.next());
-//						}
-//					}
-//				}
-//			}
-//		}
-//	}
-	  /**
-     * Default distance fraction used with line and point features.
-     * When the user clicks on the map, this tool searches for features within
-     * a rectangle of width w centred on the mouse location, where w is the
-     * average map side length multiplied by the value of this constant.
-     */
-    public static final double DEFAULT_DISTANCE_FRACTION = 0.01d;
+
 	/**
+	 * Default distance fraction used with line and point features. When the
+	 * user clicks on the map, this tool searches for features within a
+	 * rectangle of width w centred on the mouse location, where w is the
+	 * average map side length multiplied by the value of this constant.
+	 */
+	public static final double DEFAULT_DISTANCE_FRACTION = 0.01d;
+
+	/**
 	 * Reagiert auf Linksklick mit der ueber {@link #setState(int)}eingestellten
 	 * Aktion und auf Rechtsklick mit Zoom-Out (sofern {@link #ZOOM_IN}-State
 	 * fuer Linksklick eingestellt). Alle anderen Klicks werden ignoriert.
@@ -228,57 +85,16 @@
 		Point2D geoCoord = xMapPane.getScreenToWorld().transform(e.getPoint(),
 				null);
 
-		// new VectorLayerHelper(layer, geomAttributeName, geomClass)
-//
-		com.vividsolutions.jts.geom.Point mousePoint = new GeometryFactory()
-				.createPoint(new Coordinate(geoCoord.getX(), geoCoord.getY()));
-//
-//		// Rechnet 10 Pixel in die Einheit der Karte um.
-//		final Point pAtDistance = new Point((int) e.getPoint().getX() + 10,
-//				(int) e.getPoint().getY());
-//		final Point2D geoCoordAtDistance = xMapPane.getScreenToWorld()
-//				.transform(pAtDistance, null);
-//		final Double dist = Math.abs(geoCoordAtDistance.getX()
-//				- geoCoord.getX()) / 2;
-		
+		double radius = DEFAULT_DISTANCE_FRACTION
+				* (xMapPane.getMapArea().getWidth() + xMapPane.getMapArea()
+						.getHeight()) / 2;
 
-
-		// final Envelope envelope = new Envelope(geoCoord.getX(),
-		// geoCoord.getY(), geoCoord.getX(), geoCoord.getY());
-
-		//
-		// This is a tweak. The NearPointFilterGenerator doesn't work
-		// any more in GT2.6... So we use a small BBOX.
-		// Well, it's not the
-		// NearPointFilterGenerator, but GeoTools that fails. I already
-		// invested 3h in this... I guess the bug is in
-		// ExtractBoundsFilterVisitor.visit(ProperyName) retuning null.
-		// It should return the BBOX of value the named property.
-
-		// Hashtable<MapLayer, FeatureCollection<SimpleFeatureType,
-		// SimpleFeature>> result = findVisibleFeatures(
-		// new NearPointFilterGenerator(geoCoord, dist,
-		// getContext().getCoordinateReferenceSystem()),
-		// state, envelope);
-
-		// envelope.expandBy(dist);
-//		//
-//		Envelope envelope = new Envelope(geoCoord.getX() - dist, geoCoord
-//				.getY()
-//				- dist, geoCoord.getX() + dist, geoCoord.getY() + dist);
-		double radius = DEFAULT_DISTANCE_FRACTION * (xMapPane.getMapArea().getWidth() + xMapPane.getMapArea().getHeight()) / 2;
-        ReferencedEnvelope searchBounds = new ReferencedEnvelope(
-        		geoCoord.getX() - radius,
-        		geoCoord.getX() + radius,
-        		geoCoord.getY() - radius,
-        		geoCoord.getY() + radius,
-                xMapPane.getContext().getCoordinateReferenceSystem());
-
 		Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>> result = xMapPane
-				.findVisibleFeatures(new BoundingBoxFilterGenerator(searchBounds,
+				.findVisibleFeatures(new PointFilterGenerator(geoCoord, radius,
 						xMapPane.getContext().getCoordinateReferenceSystem()),
-						state, searchBounds);
-
+						state, new Envelope(geoCoord.getX(), geoCoord.getX(),
+								geoCoord.getY(), geoCoord.getY()));
+		
 		// Ein Event auslösen für das jeweils nächste Feature pro Layer
 		for (Enumeration<MapLayer> element = result.keys(); element
 				.hasMoreElements();) {
@@ -291,43 +107,34 @@
 			if (fc != null && !fc.isEmpty()) {
 
 				if (fc.size() > 1) {
-					// Hier werden alle Features weggeschmissen, bis auf
-					// das raeumlich naechste.
+					// If the result contains more that one feature, we only
+					// return the nearest one.
 
 					SimpleFeature nearestFeature = null;
 					Double nearestDist = 0.0;
 
 					Iterator<SimpleFeature> fcIt = fc.iterator();
 					try {
-						
-						System.out.println("mosue = "+mousePoint);
+						com.vividsolutions.jts.geom.Point mousePoint = new GeometryFactory()
+						.createPoint(new Coordinate(geoCoord.getX(), geoCoord.getY()));
 
 						while (fcIt.hasNext()) {
 							SimpleFeature f = fcIt.next();
-							Object obj = f.getDefaultGeometryProperty().getValue();
+							Geometry obj = (Geometry) f
+									.getDefaultGeometryProperty().getValue();
 
-							if (obj instanceof Geometry) {
+							// TODO Hier muss doch irgendwie noch CRS
+							// umgewrechnet werden...
 
-								// TODO Hier muss doch irgendwie noch CRS umgewrechnet werden... 
-								
-								Geometry featureGeometry = (Geometry) obj;
-								
-								System.out.println(f.getID()+" "+featureGeometry);
-								
-								double distance = featureGeometry
-										.distance(mousePoint);
+							Geometry featureGeometry = (Geometry) obj;
 
-								if ((nearestFeature == null)
-										|| (distance < nearestDist)) {
-									nearestFeature = f;
-									nearestDist = distance;
-									System.out.println("new nearest = "+f.getID()+":"+featureGeometry);
-								}
-							} else {
-								LOGGER
-										.info("!obj instanceof Geometry      obj = "
-												+ obj.getClass()
-														.getSimpleName());
+							double distance = featureGeometry
+									.distance(mousePoint);
+
+							if ((nearestFeature == null)
+									|| (distance < nearestDist)) {
+								nearestFeature = f;
+								nearestDist = distance;
 							}
 
 						}
@@ -342,10 +149,17 @@
 				} else {
 					fcOne = fc;
 				}
+
+				// Fire the event with the one selected feature
 				xMapPane.fireMapPaneEvent(new FeatureSelectedEvent(xMapPane,
-						layer, searchBounds, fcOne));
+						layer, fcOne.getBounds(), fcOne));
 			}
 		}
+		
+		// If no vector features were found, or we are in SELECT_ALL mode, we check the raster layers now
+		if (state == XMapPane.SELECT_ALL || result.isEmpty()) {
+			xMapPane.findGridCoverageValuesAndFireEvents(geoCoord, state);			
+		}
 
 		xMapPane.updateCursor();
 



More information about the Schmitzm-commits mailing list