[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