[Schmitzm-commits] r1203 - in trunk: src/schmitzm/geotools/gui src/skrueger/geotools src_junit/schmitzm/jfree/feature/style src_junit/schmitzm/swing

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Tue Nov 2 23:53:55 CET 2010


Author: alfonx
Date: 2010-11-02 23:53:55 +0100 (Tue, 02 Nov 2010)
New Revision: 1203

Removed:
   trunk/src/skrueger/geotools/StyledRasterPyramidInterface.java
Modified:
   trunk/src/schmitzm/geotools/gui/SelectableXMapPane.java
   trunk/src/skrueger/geotools/StyledFS.java
   trunk/src/skrueger/geotools/StyledFeatureCollection.java
   trunk/src/skrueger/geotools/StyledGridCoverage.java
   trunk/src/skrueger/geotools/StyledGridCoverageReader.java
   trunk/src/skrueger/geotools/StyledLayerInterface.java
   trunk/src/skrueger/geotools/StyledLayerUtil.java
   trunk/src_junit/schmitzm/jfree/feature/style/FeatureChartStyleTest.java
   trunk/src_junit/schmitzm/swing/TestingUtil.java
Log:
When adding a layer to a map, the AtlasMapView stops if it's outside of the allowed max map extend.

Modified: trunk/src/schmitzm/geotools/gui/SelectableXMapPane.java
===================================================================
--- trunk/src/schmitzm/geotools/gui/SelectableXMapPane.java	2010-11-02 22:21:30 UTC (rev 1202)
+++ trunk/src/schmitzm/geotools/gui/SelectableXMapPane.java	2010-11-02 22:53:55 UTC (rev 1203)
@@ -129,31 +129,59 @@
  */
 public class SelectableXMapPane extends XMapPane {
 
+	/** Logger for debug messages. */
+	protected static final Logger LOGGER = Logger
+			.getLogger(SelectableXMapPane.class);
 	/**
+	 * Flag fuer Modus "Nichts machen".
+	 * 
+	 * @see #setState(int)
+	 * @see #setState(int)
+	 */
+	public static final int NONE = 100;
+	/**
 	 * "SimpleFeature-Auswahl auf allen (sichtbaren) Layern".
 	 */
 	public static final int SELECT_ALL = 103;
+
 	/**
 	 * "Auswahl nur eines Features, das erste sichtbare von Oben".
 	 */
 	public static final int SELECT_ONE_FROM_TOP = 104;
+
 	/**
 	 * "SimpleFeature-Auswahl auf dem obersten (sichtbaren) Layer".
 	 */
 	public static final int SELECT_TOP = 4;
 
-	/** Logger for debug messages. */
-	protected static final Logger LOGGER = Logger
-			.getLogger(SelectableXMapPane.class);
-
 	/**
-	 * Flag fuer Modus "Nichts machen".
+	 * Prueft, ob es sich bei einem Layer um ein Raster-Layer handelt. VOn SK an
+	 * eine GT Methode abgegeben.
 	 * 
-	 * @see #setState(int)
-	 * @see #setState(int)
+	 * @param layer
+	 *            zu ueberpruefendes Layer
 	 */
-	public static final int NONE = 100;
+	public static boolean isGridCoverageLayer(MapLayer layer) {
+		String GRID_PACKAGE = "org.geotools.coverage.grid";
+		String GRID_PACKAGE2 = "org.opengis.coverage.grid";
 
+		// TODO when my patch is accepted, replace the whole method with
+		// MapLayerUtil.isGridLayer again .. where is my pathc? what patch?!
+
+		Collection<PropertyDescriptor> descriptors = layer.getFeatureSource()
+				.getSchema().getDescriptors();
+		for (PropertyDescriptor desc : descriptors) {
+			String className = desc.getType().getBinding().getName();
+
+			if (className.contains(GRID_PACKAGE)
+					|| className.contains(GRID_PACKAGE2)) {
+				return true;
+			}
+		}
+
+		return false;
+	}
+
 	/**
 	 * Erzeugt ein neues MapPane.
 	 * 
@@ -171,8 +199,8 @@
 	 *            Verwaltung der einzelnen Layer (z.B. {@link DefaultMapContext}
 	 *            ).
 	 */
-	public SelectableXMapPane(MapContext context) {
-		super(context, null);
+	public SelectableXMapPane() {
+		super(null, null);
 	}
 
 	/**
@@ -192,174 +220,11 @@
 	 *            Verwaltung der einzelnen Layer (z.B. {@link DefaultMapContext}
 	 *            ).
 	 */
-	public SelectableXMapPane() {
-		super(null, null);
+	public SelectableXMapPane(MapContext context) {
+		super(context, null);
 	}
 
 	/**
-	 * Liefert die Anzahl der Einheiten, die ein Bildschirm-Pixel darstellt. Die
-	 * Einheit ist die Grundeinheit des CRS
-	 */
-	public double getScale() {
-
-		if (!isWellDefined())
-			return 0.0;
-
-		// double scale = getMapArea().getWidth() / getWidth();
-		// LOGGER.debug("Scale in XMapPane = "+scale);
-
-		AffineTransform worldToScreenTransform = getWorldToScreenTransform();
-		if (worldToScreenTransform == null)
-			return 0.0;
-
-		double scale2 = 1. / worldToScreenTransform.getScaleX();
-		// LOGGER.debug("Alternativ = " + scale2);
-
-		return scale2;
-	}
-
-	/**
-	 * Liefert oberste Layer (sichtbar oder unsichtbar).
-	 */
-	public MapLayer getTopLayer() {
-		int count = getMapContext().getLayerCount();
-		return count > 0 ? getMapContext().getLayer(count - 1) : null;
-	}
-
-	/**
-	 * Liefert oberste sichtbare Layer.
-	 */
-	public MapLayer getTopVisibleLayer() {
-		for (int i = getMapContext().getLayerCount() - 1; i >= 0; i--) {
-			MapLayer layer = getMapContext().getLayer(i);
-			if (layer.isVisible())
-				return layer;
-		}
-		return null;
-	}
-
-	/**
-	 * Liefert oberste sichtbare Raster-Layer.
-	 */
-	public MapLayer getTopVisibleGridCoverageLayer() {
-		for (int i = getMapContext().getLayerCount() - 1; i >= 0; i--) {
-			MapLayer layer = getMapContext().getLayer(i);
-			if (layer.isVisible() && isGridCoverageLayer(layer))
-				return layer;
-		}
-		return null;
-	}
-
-	/**
-	 * Liefert oberste sichtbare Nicht-Raster-Layer.
-	 */
-	public MapLayer getTopVisibleNonGridCoverageLayer() {
-		for (int i = getMapContext().getLayerCount() - 1; i >= 0; i--) {
-			MapLayer layer = getMapContext().getLayer(i);
-			if (layer.isVisible() && !isGridCoverageLayer(layer))
-				return layer;
-		}
-		return null;
-	}
-
-	/**
-	 * Liefert unterste Layer (sichtbar oder unsichtbar).
-	 */
-	public MapLayer getBottomLayer() {
-		return getMapContext().getLayerCount() > 0 ? getMapContext()
-				.getLayer(0) : null;
-	}
-
-	/**
-	 * Ermittelt die Raster-Werte, die an einem Punkt liegen und erzeugt
-	 * entsprechende {@link GridCoverageValueSelectedEvent
-	 * GridCoverageValueSelectedEvents}. Beim Modus {@link #SELECT_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-Referenz
-	 * @param mode
-	 *            Suchmodus
-	 * @return eine leere {@link Hashtable} falls der Punkt {@code null} ist
-	 * 
-	 * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
-	 *         (University of Bonn/Germany)
-	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
-	 */
-	public boolean findGridCoverageValuesAndFireEvents(Point2D point, int mode) {
-		Hashtable<MapLayer, double[]> result = findGridCoverageValues(point,
-				mode);
-
-		// Events ausloesen fuer jedes Layer
-		for (Enumeration<MapLayer> e = result.keys(); e.hasMoreElements();) {
-			MapLayer layer = e.nextElement();
-
-			double[] values = result.get(layer);
-			fireMapPaneEvent(new GridCoverageValueSelectedEvent(this, layer,
-					point, values));
-		}
-		return !result.isEmpty();
-	}
-
-	/**
-	 * Setzt die sichtbare Karte. Danach wird die {@linkplain AffineTransform
-	 * Transformation} zwischen Fenster-Koordinaten und Karten-Koordinaten neu
-	 * berechnet.<br>
-	 * Loest ein {@link ScaleChangedEvent aus}
-	 * 
-	 * {@link #setMapArea(Envelope)} return <code>false</code>, falls durch die
-	 * neue MapArea ein nicht gueltiger Massstab entstehen wuerde UND die
-	 * bisherige maparea != null ist
-	 * 
-	 * @param newMapArea
-	 *            neuer Kartenausschnitt im CRS des {@link MapContext}
-	 * @see #resetTransforms()
-	 * @see #getScreenToWorld()
-	 * 
-	 * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
-	 *         (University of Bonn/Germany)
-	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
-	 */
-	@Override
-	public boolean setMapArea(ReferencedEnvelope newMapArea) {
-		double oldScale = getScale();
-
-		boolean b = super.setMapArea(newMapArea);
-
-		if (b) {
-			if (getScale() > 0) {
-				// If the JPane has not been set yet, there is
-				// no scale
-				// if (oldScale != getScale())
-				fireMapPaneEvent(new ScaleChangedEvent(this, oldScale,
-						getScale()));
-			}
-			fireMapPaneEvent(new MapAreaChangedEvent(this, oldMapArea,
-					getMapArea()));
-		}
-		return b;
-	}
-
-	/**
-	 * Sets the mapArea to smartly present the given features. Note: The method
-	 * does not call {@link #repaint()} on the {@link SelectableXMapPane}.
-	 * 
-	 * @return <code>true</code> if the {@link #mapArea} has changed and
-	 *         rendering has been triggered.
-	 */
-	public boolean zoomTo(SimpleFeature feature) {
-		final MemoryFeatureCollection mfc = new MemoryFeatureCollection(
-				feature.getFeatureType());
-		mfc.add(feature);
-		return zoomTo(mfc);
-	}
-
-	/**
 	 * Testet (anhand der Features), ob das Objekt eines Layers eine
 	 * Bounding-Box schneidet.
 	 * 
@@ -463,6 +328,131 @@
 	}
 
 	/**
+	 * Ermittelt alle Features, die in einem Bereich liegen und erzeugt
+	 * entsprechende {@link FeatureSelectedEvent FeatureSelectedEvents}. Beim
+	 * Modus {@link #SELECT_TOP} wird nur das oberste sichtbare Layer
+	 * durchsucht. Beim Modus {@link #SELECT_ALL} werden alle sichtbaren Layer
+	 * durchsucht.
+	 * 
+	 * @param filterGenerator
+	 *            adapts a filter to a concrete {@link FeatureSource}
+	 * @param selectionMode
+	 *            Suchmodus
+	 * @param env
+	 *            Bereich der durchsucht wird (fuer das Filtern irrelevant; wird
+	 *            nur fuer Events benoetigt!)
+	 */
+	public boolean findFeaturesAndFireEvents(
+			GeomFilterGenerator filterGenerator, int selectionMode, Envelope env) {
+		Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>> result = findVisibleFeatures(
+				filterGenerator, selectionMode, env);
+
+		// Events ausloesen fuer jedes Layer
+		for (final Enumeration<MapLayer> e = result.keys(); e.hasMoreElements();) {
+
+			final MapLayer layer = e.nextElement();
+
+			// System.out.println("checking in " + layer.getTitle());
+
+			final FeatureCollection<SimpleFeatureType, SimpleFeature> fc = result
+					.get(layer);
+			if (fc != null && !fc.isEmpty())
+				fireMapPaneEvent(new FeatureSelectedEvent(this, layer, env, fc));
+		}
+		return !result.isEmpty();
+	}
+
+	/**
+	 * Ermittelt alle Teil-Raster, die in einem Bereich liegen.
+	 * BefindFeaturesAndFireEventsim Modus {@link #SELECT_TOP} wird nur das
+	 * oberste sichtbare Layer durchsucht. Beim Modus {@link #SELECT_ALL} werden
+	 * alle sichtbaren Layer durchsucht.
+	 * 
+	 * @param env
+	 *            Bounding-Box
+	 * @param selectionMode
+	 *            Suchmodus
+	 * @return eine leere {@link Hashtable} falls die Bounding-Box {@code null}
+	 *         ist
+	 */
+	protected Hashtable<MapLayer, GridCoverage2D> findGridCoverageSubsets(
+			Envelope env, int selectionMode) {
+		Hashtable<MapLayer, GridCoverage2D> result = new Hashtable<MapLayer, GridCoverage2D>();
+		if (env == null)
+			return result;
+
+		MapContext context = getMapContext();
+		// Je nach Modus: Alle oder nur das oberste Layer
+		MapLayer[] layerList = context.getLayers();
+		for (int i = layerList.length - 1; i >= 0; i--) {
+			MapLayer layer = layerList[i];
+			Object layerObj = FeatureUtil
+					.getWrappedGeoObject((FeatureSource<SimpleFeatureType, SimpleFeature>) layer
+							.getFeatureSource());
+			if (!layer.isVisible())
+				continue;
+
+			// Bei einem Nicht-Raster-Layer, das die BB schneidet, abbrechen,
+			// wenn nur im obersten (sichtbaren) Layer gesucht wird.
+			// Ansonsten Nicht-Raster-Layer einfach uebergehen.
+			if (!(layerObj instanceof GridCoverage2D)) {
+				if ((selectionMode == SELECT_TOP || selectionMode == SELECT_ONE_FROM_TOP)
+						&& featureLayerIntersectsEnvelope(layer, env))
+					break;
+				continue;
+			}
+
+			GridCoverage2D sourceGrid = (GridCoverage2D) layerObj;
+			com.vividsolutions.jts.geom.Envelope jtsEnv = env;
+			org.geotools.geometry.Envelope2D gtEnv2D = JTS.getEnvelope2D(
+					jtsEnv, sourceGrid.getCoordinateReferenceSystem());
+			org.opengis.geometry.Envelope gtGenEnv = new GeneralEnvelope(
+					(org.opengis.geometry.Envelope) gtEnv2D); // gt2-2.4.2
+
+			// GridCoverage2D subsetGrid =
+			// (GridCoverage2D)Operations.DEFAULT.crop(sourceGrid,gtGenEnv);
+			GridCoverage2D subsetGrid = GridUtil.createGridCoverage(sourceGrid,
+					gtGenEnv);
+			if (subsetGrid != null)
+				result.put(layer, subsetGrid);
+			// Beim Modus "oberstes Layer selektieren" die Schleife beenden
+			if (selectionMode == SELECT_TOP
+					|| selectionMode == SELECT_ONE_FROM_TOP)
+				break;
+		}
+		return result;
+	}
+
+	/**
+	 * Ermittelt alle Teil-Raster, die in einem Bereich liegen und erzeugt
+	 * entsprechende {@link GridCoverageSelectedEvent
+	 * GridCoverageSelectedEvents}. Beim Modus {@link #SELECT_TOP} wird nur das
+	 * oberste sichtbare Layer durchsucht. Beim Modus {@link #SELECT_ALL} werden
+	 * alle sichtbaren Layer durchsucht.
+	 * 
+	 * @param env
+	 *            Bounding-Box
+	 * @param mode
+	 *            Suchmodus
+	 * @return eine leere {@link Hashtable} falls die Bounding-Box {@code null}
+	 *         ist
+	 */
+	public boolean findGridCoverageSubsetsAndFireEvents(final Envelope env,
+			final int mode) {
+		final Hashtable<MapLayer, GridCoverage2D> result = findGridCoverageSubsets(
+				env, mode);
+		// Events ausloesen fuer jedes Layer
+		for (final Enumeration<MapLayer> e = result.keys(); e.hasMoreElements();) {
+			final MapLayer layer = e.nextElement();
+			final GridCoverage2D subset = result.get(layer);
+			if (subset != null)
+				fireMapPaneEvent(new GridCoverageSelectedEvent(this, layer,
+						env, subset));
+		}
+		return !result.isEmpty();
+	}
+
+	/**
 	 * Ermittelt alle Raster-Werte, die an einer bestimmten Geo-Position liegen.
 	 * Beim Modus {@link #SELECT_TOP} oder {@link #SELECT_ONE_FROM_TOP} wird nur
 	 * das oberste sichtbare Layer durchsucht. Beim Modus {@link #SELECT_ALL}
@@ -500,8 +490,8 @@
 				continue;
 
 			if (!isMapLayerSelectable(layer)) {
-//				LOGGER.debug("Ignoring layer " + layer.getTitle()
-//						+ " because it is not declared as selectable!");
+				// LOGGER.debug("Ignoring layer " + layer.getTitle()
+				// + " because it is not declared as selectable!");
 				continue;
 			}
 
@@ -590,177 +580,42 @@
 	}
 
 	/**
-	 * Verarbeitet die Selektion eines Karten-Ausschnitts. Erzeugt immer ein
-	 * {@link GeneralSelectionEvent} fuer den ausgewaehlten Bereich. Wurden
-	 * Features oder Raster selektiert, werden zudem
-	 * {@link FeatureSelectedEvent FeatureSelectedEvents} (bzw.
-	 * GridCoverageSelectedEvents GridCoverageSelectedEvents) ausgeloest.
+	 * Ermittelt die Raster-Werte, die an einem Punkt liegen und erzeugt
+	 * entsprechende {@link GridCoverageValueSelectedEvent
+	 * GridCoverageValueSelectedEvents}. Beim Modus {@link #SELECT_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 ox
-	 *            X-Koordinate der VON-Position
-	 * @param oy
-	 *            Y-Koordinate der VON-Position
-	 * @param px
-	 *            X-Koordinate der BIS-Position
-	 * @param py
-	 *            Y-Koordinate der BIS-Position
+	 * @param point
+	 *            Geo-Referenz
+	 * @param mode
+	 *            Suchmodus
+	 * @return eine leere {@link Hashtable} falls der Punkt {@code null} ist
 	 * 
-	 * @param selectionMode
-	 *            on of SELECT_TOP, SELECT_ONE_FROM_TOP, SELECT_ALL
+	 * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+	 *         (University of Bonn/Germany)
+	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
 	 */
-	public void performSelectionEvent(int ox, int oy, int px, int py,
-			int selectionMode) {
+	public boolean findGridCoverageValuesAndFireEvents(Point2D point, int mode) {
+		Hashtable<MapLayer, double[]> result = findGridCoverageValues(point,
+				mode);
 
-		if (getMapContext().getLayerCount() == 0)
-			return;
-
-		// Fenster-Koordinaten in Map-Koordinaten umwandeln
-		Envelope env = tranformWindowToGeo(ox, oy, px, py);
-
-		// Generelles Event ausloesen
-		fireMapPaneEvent(new GeneralSelectionEvent(this, env));
-
-		switch (selectionMode) {
-		case SELECT_TOP:
-		case SELECT_ONE_FROM_TOP:
-		case SELECT_ALL: // Features selektieren
-
-			boolean featuresFound = findFeaturesAndFireEvents(
-					new BoundingBoxFilterGenerator(env, getMapContext()
-							.getCoordinateReferenceSystem()), selectionMode,
-					env);
-			if (selectionMode == SELECT_ALL || !featuresFound)
-				findGridCoverageSubsetsAndFireEvents(env, selectionMode);
-			break;
-		}
-	}
-
-	/**
-	 * Ermittelt alle Features, die in einem Bereich liegen und erzeugt
-	 * entsprechende {@link FeatureSelectedEvent FeatureSelectedEvents}. Beim
-	 * Modus {@link #SELECT_TOP} wird nur das oberste sichtbare Layer
-	 * durchsucht. Beim Modus {@link #SELECT_ALL} werden alle sichtbaren Layer
-	 * durchsucht.
-	 * 
-	 * @param filterGenerator
-	 *            adapts a filter to a concrete {@link FeatureSource}
-	 * @param selectionMode
-	 *            Suchmodus
-	 * @param env
-	 *            Bereich der durchsucht wird (fuer das Filtern irrelevant; wird
-	 *            nur fuer Events benoetigt!)
-	 */
-	public boolean findFeaturesAndFireEvents(
-			GeomFilterGenerator filterGenerator, int selectionMode, Envelope env) {
-		Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>> result = findVisibleFeatures(
-				filterGenerator, selectionMode, env);
-
 		// Events ausloesen fuer jedes Layer
-		for (final Enumeration<MapLayer> e = result.keys(); e.hasMoreElements();) {
+		for (Enumeration<MapLayer> e = result.keys(); e.hasMoreElements();) {
+			MapLayer layer = e.nextElement();
 
-			final MapLayer layer = e.nextElement();
-
-			// System.out.println("checking in " + layer.getTitle());
-
-			final FeatureCollection<SimpleFeatureType, SimpleFeature> fc = result
-					.get(layer);
-			if (fc != null && !fc.isEmpty())
-				fireMapPaneEvent(new FeatureSelectedEvent(this, layer, env, fc));
+			double[] values = result.get(layer);
+			fireMapPaneEvent(new GridCoverageValueSelectedEvent(this, layer,
+					point, values));
 		}
 		return !result.isEmpty();
 	}
 
 	/**
-	 * Ermittelt alle Teil-Raster, die in einem Bereich liegen.
-	 * BefindFeaturesAndFireEventsim Modus {@link #SELECT_TOP} wird nur das
-	 * oberste sichtbare Layer durchsucht. Beim Modus {@link #SELECT_ALL} werden
-	 * alle sichtbaren Layer durchsucht.
-	 * 
-	 * @param env
-	 *            Bounding-Box
-	 * @param selectionMode
-	 *            Suchmodus
-	 * @return eine leere {@link Hashtable} falls die Bounding-Box {@code null}
-	 *         ist
-	 */
-	protected Hashtable<MapLayer, GridCoverage2D> findGridCoverageSubsets(
-			Envelope env, int selectionMode) {
-		Hashtable<MapLayer, GridCoverage2D> result = new Hashtable<MapLayer, GridCoverage2D>();
-		if (env == null)
-			return result;
-
-		MapContext context = getMapContext();
-		// Je nach Modus: Alle oder nur das oberste Layer
-		MapLayer[] layerList = context.getLayers();
-		for (int i = layerList.length - 1; i >= 0; i--) {
-			MapLayer layer = layerList[i];
-			Object layerObj = FeatureUtil
-					.getWrappedGeoObject((FeatureSource<SimpleFeatureType, SimpleFeature>) layer
-							.getFeatureSource());
-			if (!layer.isVisible())
-				continue;
-
-			// Bei einem Nicht-Raster-Layer, das die BB schneidet, abbrechen,
-			// wenn nur im obersten (sichtbaren) Layer gesucht wird.
-			// Ansonsten Nicht-Raster-Layer einfach uebergehen.
-			if (!(layerObj instanceof GridCoverage2D)) {
-				if ((selectionMode == SELECT_TOP || selectionMode == SELECT_ONE_FROM_TOP)
-						&& featureLayerIntersectsEnvelope(layer, env))
-					break;
-				continue;
-			}
-
-			GridCoverage2D sourceGrid = (GridCoverage2D) layerObj;
-			com.vividsolutions.jts.geom.Envelope jtsEnv = env;
-			org.geotools.geometry.Envelope2D gtEnv2D = JTS.getEnvelope2D(
-					jtsEnv, sourceGrid.getCoordinateReferenceSystem());
-			org.opengis.geometry.Envelope gtGenEnv = new GeneralEnvelope(
-					(org.opengis.geometry.Envelope) gtEnv2D); // gt2-2.4.2
-
-			// GridCoverage2D subsetGrid =
-			// (GridCoverage2D)Operations.DEFAULT.crop(sourceGrid,gtGenEnv);
-			GridCoverage2D subsetGrid = GridUtil.createGridCoverage(sourceGrid,
-					gtGenEnv);
-			if (subsetGrid != null)
-				result.put(layer, subsetGrid);
-			// Beim Modus "oberstes Layer selektieren" die Schleife beenden
-			if (selectionMode == SELECT_TOP
-					|| selectionMode == SELECT_ONE_FROM_TOP)
-				break;
-		}
-		return result;
-	}
-
-	/**
-	 * Ermittelt alle Teil-Raster, die in einem Bereich liegen und erzeugt
-	 * entsprechende {@link GridCoverageSelectedEvent
-	 * GridCoverageSelectedEvents}. Beim Modus {@link #SELECT_TOP} wird nur das
-	 * oberste sichtbare Layer durchsucht. Beim Modus {@link #SELECT_ALL} werden
-	 * alle sichtbaren Layer durchsucht.
-	 * 
-	 * @param env
-	 *            Bounding-Box
-	 * @param mode
-	 *            Suchmodus
-	 * @return eine leere {@link Hashtable} falls die Bounding-Box {@code null}
-	 *         ist
-	 */
-	public boolean findGridCoverageSubsetsAndFireEvents(final Envelope env,
-			final int mode) {
-		final Hashtable<MapLayer, GridCoverage2D> result = findGridCoverageSubsets(
-				env, mode);
-		// Events ausloesen fuer jedes Layer
-		for (final Enumeration<MapLayer> e = result.keys(); e.hasMoreElements();) {
-			final MapLayer layer = e.nextElement();
-			final GridCoverage2D subset = result.get(layer);
-			if (subset != null)
-				fireMapPaneEvent(new GridCoverageSelectedEvent(this, layer,
-						env, subset));
-		}
-		return !result.isEmpty();
-	}
-
-	/**
 	 * 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
@@ -795,8 +650,8 @@
 			}
 
 			if (!isMapLayerSelectable(layer)) {
-//				LOGGER.debug("Ignoring layer " + layer.getTitle()
-//						+ " because it is not declared as selectable!");
+				// LOGGER.debug("Ignoring layer " + layer.getTitle()
+				// + " because it is not declared as selectable!");
 				continue;
 			}
 
@@ -865,38 +720,80 @@
 	}
 
 	/**
-	 * Testet (anhand der Bounding-Box), ob das Objekt eines Layers eine andere
-	 * Bounding-Box schneidet. Die Bounding-Box des Layer-Objekts wird zunaechst
-	 * in das CRS des MapPanes umgerechnets.<br>
-	 * If the layer's bbox is <code>null</code>, returns <code>false</code>. *
-	 * 
-	 * @param layer
-	 *            ein Layer
-	 * @param env
-	 *            Bounding-Box in CRS des MapPane
-	 * 
-	 *            TODO movve to some utility class
+	 * Liefert unterste Layer (sichtbar oder unsichtbar).
 	 */
-	public boolean layerIntersectsEnvelope(MapLayer layer, Envelope env) {
-		try {
-			// BB des Layers umrechnen von Layer-CRS in Map-CRS
-			Envelope bounds_MapCRS = JTSUtil.transformEnvelope(layer
-					.getFeatureSource().getBounds(), layer.getFeatureSource()
-					.getSchema().getGeometryDescriptor()
-					.getCoordinateReferenceSystem(), getMapContext()
-					.getCoordinateReferenceSystem());
+	public MapLayer getBottomLayer() {
+		return getMapContext().getLayerCount() > 0 ? getMapContext()
+				.getLayer(0) : null;
+	}
 
-			// TODO warum kann bounds_MapCRS == null sein ?? ?SK fragt martin???
-			if (bounds_MapCRS == null)
-				return false;
+	/**
+	 * Liefert die Anzahl der Einheiten, die ein Bildschirm-Pixel darstellt. Die
+	 * Einheit ist die Grundeinheit des CRS
+	 */
+	public double getScale() {
 
-			return bounds_MapCRS.intersects(env);
-		} catch (Exception err) {
-			return false;
+		if (!isWellDefined())
+			return 0.0;
+
+		// double scale = getMapArea().getWidth() / getWidth();
+		// LOGGER.debug("Scale in XMapPane = "+scale);
+
+		AffineTransform worldToScreenTransform = getWorldToScreenTransform();
+		if (worldToScreenTransform == null)
+			return 0.0;
+
+		double scale2 = 1. / worldToScreenTransform.getScaleX();
+		// LOGGER.debug("Alternativ = " + scale2);
+
+		return scale2;
+	}
+
+	/**
+	 * Liefert oberste Layer (sichtbar oder unsichtbar).
+	 */
+	public MapLayer getTopLayer() {
+		int count = getMapContext().getLayerCount();
+		return count > 0 ? getMapContext().getLayer(count - 1) : null;
+	}
+
+	/**
+	 * Liefert oberste sichtbare Raster-Layer.
+	 */
+	public MapLayer getTopVisibleGridCoverageLayer() {
+		for (int i = getMapContext().getLayerCount() - 1; i >= 0; i--) {
+			MapLayer layer = getMapContext().getLayer(i);
+			if (layer.isVisible() && isGridCoverageLayer(layer))
+				return layer;
 		}
+		return null;
 	}
 
 	/**
+	 * Liefert oberste sichtbare Layer.
+	 */
+	public MapLayer getTopVisibleLayer() {
+		for (int i = getMapContext().getLayerCount() - 1; i >= 0; i--) {
+			MapLayer layer = getMapContext().getLayer(i);
+			if (layer.isVisible())
+				return layer;
+		}
+		return null;
+	}
+
+	/**
+	 * Liefert oberste sichtbare Nicht-Raster-Layer.
+	 */
+	public MapLayer getTopVisibleNonGridCoverageLayer() {
+		for (int i = getMapContext().getLayerCount() - 1; i >= 0; i--) {
+			MapLayer layer = getMapContext().getLayer(i);
+			if (layer.isVisible() && !isGridCoverageLayer(layer))
+				return layer;
+		}
+		return null;
+	}
+
+	/**
 	 * Testet (anhand der Bounding-Box), ob das Objekt eines Layers eine
 	 * Coordinate schneidet. Die Bounding-Box des Layer-Objekts wird zunaechst
 	 * in das CRS des MapPanes umgerechnets.<br/>
@@ -934,31 +831,134 @@
 	}
 
 	/**
-	 * Prueft, ob es sich bei einem Layer um ein Raster-Layer handelt. VOn SK an
-	 * eine GT Methode abgegeben.
+	 * Testet (anhand der Bounding-Box), ob das Objekt eines Layers eine andere
+	 * Bounding-Box schneidet. Die Bounding-Box des Layer-Objekts wird zunaechst
+	 * in das CRS des MapPanes umgerechnets.<br>
+	 * If the layer's bbox is <code>null</code>, returns <code>false</code>. *
 	 * 
 	 * @param layer
-	 *            zu ueberpruefendes Layer
+	 *            ein Layer
+	 * @param env
+	 *            Bounding-Box in CRS des MapPane
+	 * 
+	 *            TODO movve to some utility class
 	 */
-	public static boolean isGridCoverageLayer(MapLayer layer) {
-		String GRID_PACKAGE = "org.geotools.coverage.grid";
-		String GRID_PACKAGE2 = "org.opengis.coverage.grid";
+	public boolean layerIntersectsEnvelope(MapLayer layer, Envelope env) {
+		try {
+			// BB des Layers umrechnen von Layer-CRS in Map-CRS
+			Envelope bounds_MapCRS = JTSUtil.transformEnvelope(layer
+					.getFeatureSource().getBounds(), layer.getFeatureSource()
+					.getSchema().getGeometryDescriptor()
+					.getCoordinateReferenceSystem(), getMapContext()
+					.getCoordinateReferenceSystem());
 
-		// TODO when my patch is accepted, replace the whole method with
-		// MapLayerUtil.isGridLayer again
+			// TODO warum kann bounds_MapCRS == null sein ?? ?SK fragt martin???
+			if (bounds_MapCRS == null)
+				return false;
 
-		Collection<PropertyDescriptor> descriptors = layer.getFeatureSource()
-				.getSchema().getDescriptors();
-		for (PropertyDescriptor desc : descriptors) {
-			String className = desc.getType().getBinding().getName();
+			return bounds_MapCRS.intersects(env);
+		} catch (Exception err) {
+			return false;
+		}
+	}
 
-			if (className.contains(GRID_PACKAGE)
-					|| className.contains(GRID_PACKAGE2)) {
-				return true;
+	/**
+	 * Verarbeitet die Selektion eines Karten-Ausschnitts. Erzeugt immer ein
+	 * {@link GeneralSelectionEvent} fuer den ausgewaehlten Bereich. Wurden
+	 * Features oder Raster selektiert, werden zudem
+	 * {@link FeatureSelectedEvent FeatureSelectedEvents} (bzw.
+	 * GridCoverageSelectedEvents GridCoverageSelectedEvents) ausgeloest.
+	 * 
+	 * @param ox
+	 *            X-Koordinate der VON-Position
+	 * @param oy
+	 *            Y-Koordinate der VON-Position
+	 * @param px
+	 *            X-Koordinate der BIS-Position
+	 * @param py
+	 *            Y-Koordinate der BIS-Position
+	 * 
+	 * @param selectionMode
+	 *            on of SELECT_TOP, SELECT_ONE_FROM_TOP, SELECT_ALL
+	 */
+	public void performSelectionEvent(int ox, int oy, int px, int py,
+			int selectionMode) {
+
+		if (getMapContext().getLayerCount() == 0)
+			return;
+
+		// Fenster-Koordinaten in Map-Koordinaten umwandeln
+		Envelope env = tranformWindowToGeo(ox, oy, px, py);
+
+		// Generelles Event ausloesen
+		fireMapPaneEvent(new GeneralSelectionEvent(this, env));
+
+		switch (selectionMode) {
+		case SELECT_TOP:
+		case SELECT_ONE_FROM_TOP:
+		case SELECT_ALL: // Features selektieren
+
+			boolean featuresFound = findFeaturesAndFireEvents(
+					new BoundingBoxFilterGenerator(env, getMapContext()
+							.getCoordinateReferenceSystem()), selectionMode,
+					env);
+			if (selectionMode == SELECT_ALL || !featuresFound)
+				findGridCoverageSubsetsAndFireEvents(env, selectionMode);
+			break;
+		}
+	}
+
+	/**
+	 * Setzt die sichtbare Karte. Danach wird die {@linkplain AffineTransform
+	 * Transformation} zwischen Fenster-Koordinaten und Karten-Koordinaten neu
+	 * berechnet.<br>
+	 * Loest ein {@link ScaleChangedEvent aus}
+	 * 
+	 * {@link #setMapArea(Envelope)} return <code>false</code>, falls durch die
+	 * neue MapArea ein nicht gueltiger Massstab entstehen wuerde UND die
+	 * bisherige maparea != null ist
+	 * 
+	 * @param newMapArea
+	 *            neuer Kartenausschnitt im CRS des {@link MapContext}
+	 * @see #resetTransforms()
+	 * @see #getScreenToWorld()
+	 * 
+	 * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+	 *         (University of Bonn/Germany)
+	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
+	 */
+	@Override
+	public boolean setMapArea(ReferencedEnvelope newMapArea) {
+		double oldScale = getScale();
+
+		boolean b = super.setMapArea(newMapArea);
+
+		if (b) {
+			if (getScale() > 0) {
+				// If the JPane has not been set yet, there is
+				// no scale
+				// if (oldScale != getScale())
+				fireMapPaneEvent(new ScaleChangedEvent(this, oldScale,
+						getScale()));
 			}
+			fireMapPaneEvent(new MapAreaChangedEvent(this, oldMapArea,
+					getMapArea()));
 		}
+		return b;
+	}
 
-		return false;
+	/**
+	 * Sets the mapArea to smartly present the given features. Note: The method
+	 * does not call {@link #repaint()} on the {@link SelectableXMapPane}.
+	 * 
+	 * @return <code>true</code> if the {@link #mapArea} has changed and
+	 *         rendering has been triggered.
+	 */
+	public boolean zoomTo(SimpleFeature feature) {
+		final MemoryFeatureCollection mfc = new MemoryFeatureCollection(
+				feature.getFeatureType());
+		mfc.add(feature);
+		return zoomTo(mfc);
 	}
 
 }

Modified: trunk/src/skrueger/geotools/StyledFS.java
===================================================================
--- trunk/src/skrueger/geotools/StyledFS.java	2010-11-02 22:21:30 UTC (rev 1202)
+++ trunk/src/skrueger/geotools/StyledFS.java	2010-11-02 22:53:55 UTC (rev 1203)
@@ -42,6 +42,7 @@
 import org.geotools.data.FeatureSource;
 import org.geotools.feature.FeatureCollection;
 import org.geotools.feature.NameImpl;
+import org.geotools.geometry.jts.ReferencedEnvelope;
 import org.geotools.styling.Style;
 import org.opengis.feature.simple.SimpleFeature;
 import org.opengis.feature.simple.SimpleFeatureType;
@@ -422,4 +423,9 @@
 		crs = crs2;
 	}
 
+	@Override
+	public ReferencedEnvelope getReferencedEnvelope() {
+		return new ReferencedEnvelope(getEnvelope(), getCrs());
+	}
+
 }

Modified: trunk/src/skrueger/geotools/StyledFeatureCollection.java
===================================================================
--- trunk/src/skrueger/geotools/StyledFeatureCollection.java	2010-11-02 22:21:30 UTC (rev 1202)
+++ trunk/src/skrueger/geotools/StyledFeatureCollection.java	2010-11-02 22:53:55 UTC (rev 1203)
@@ -40,6 +40,7 @@
 import org.geotools.feature.FeatureCollection;
 import org.geotools.feature.NameImpl;
 import org.geotools.feature.collection.SubFeatureCollection;
+import org.geotools.geometry.jts.ReferencedEnvelope;
 import org.geotools.styling.Style;
 import org.opengis.feature.simple.SimpleFeature;
 import org.opengis.feature.simple.SimpleFeatureType;
@@ -439,4 +440,9 @@
 	}
 
 
+	@Override
+	public ReferencedEnvelope getReferencedEnvelope() {
+		return new ReferencedEnvelope(getEnvelope(), getCrs());
+	}
+
 }

Modified: trunk/src/skrueger/geotools/StyledGridCoverage.java
===================================================================
--- trunk/src/skrueger/geotools/StyledGridCoverage.java	2010-11-02 22:21:30 UTC (rev 1202)
+++ trunk/src/skrueger/geotools/StyledGridCoverage.java	2010-11-02 22:53:55 UTC (rev 1203)
@@ -34,6 +34,7 @@
 import javax.swing.ImageIcon;
 
 import org.geotools.coverage.grid.GridCoverage2D;
+import org.geotools.geometry.jts.ReferencedEnvelope;
 import org.geotools.styling.Style;
 
 import schmitzm.geotools.JTSUtil;
@@ -46,198 +47,267 @@
  * for {@link GridCoverage2D}. The uncache functionality is not supported,
  * because this class bases on an existing {@link GridCoverage2D} object in
  * memory.
- * @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.0
  */
-public class StyledGridCoverage extends AbstractStyledLayer<GridCoverage2D> implements StyledGridCoverageInterface {
+public class StyledGridCoverage extends AbstractStyledLayer<GridCoverage2D>
+		implements StyledGridCoverageInterface {
 
-  /** Holds the meta data for displaying a legend. */
-  protected RasterLegendData legendData = null;
+	/** Holds the meta data for displaying a legend. */
+	protected RasterLegendData legendData = null;
 
-  /**
-   * Creates a styled grid with language-specific informations.
-   * @param gc the grid
-   * @param id a unique ID for the object
-   * @param title a (language-specific) short description
-   * @param desc a (language-specific) long description
-   * @param keywords (language-specific) keywords for the geo objects
-   * @param style a display style (if {@code null}, a default style is created)
-   * @param legendData meta data for displaying a legend
-   * @param icon an icon for the object (can be {@code null})
-   * @exception IllegalArgumentException if {@code null} is given as ID or geo object
-   */
-  public StyledGridCoverage(GridCoverage2D gc, String id, Translation title, Translation desc, Translation keywords, Style style, RasterLegendData legendData, ImageIcon icon) {
-    super(gc, JTSUtil.createEnvelope(gc.getEnvelope()), gc.getCoordinateReferenceSystem(), id, title, desc, keywords, style, icon);
-    setLegendMetaData(legendData);
-  }
+	/**
+	 * Creates a styled grid with language-specific informations.
+	 * 
+	 * @param gc
+	 *            the grid
+	 * @param id
+	 *            a unique ID for the object
+	 * @param title
+	 *            a (language-specific) short description
+	 * @param desc
+	 *            a (language-specific) long description
+	 * @param keywords
+	 *            (language-specific) keywords for the geo objects
+	 * @param style
+	 *            a display style (if {@code null}, a default style is created)
+	 * @param legendData
+	 *            meta data for displaying a legend
+	 * @param icon
+	 *            an icon for the object (can be {@code null})
+	 * @exception IllegalArgumentException
+	 *                if {@code null} is given as ID or geo object
+	 */
+	public StyledGridCoverage(GridCoverage2D gc, String id, Translation title,
+			Translation desc, Translation keywords, Style style,
+			RasterLegendData legendData, ImageIcon icon) {
+		super(gc, JTSUtil.createEnvelope(gc.getEnvelope()), gc
+				.getCoordinateReferenceSystem(), id, title, desc, keywords,
+				style, icon);
+		setLegendMetaData(legendData);
+	}
 
-  /**
-   * Creates a styled grid with language-specific informations.
-   * @param gc the grid
-   * @param id a unique ID for the object
-   * @param title a (language-specific) short description
-   * @param desc a (language-specific) long description
-   * @param keywords (language-specific) keywords for the geo objects
-   * @param style a display style with legend information
-   * @param icon an icon for the object (can be {@code null})
-   * @exception IllegalArgumentException if {@code null} is given as ID or geo object
-   */
-  public StyledGridCoverage(GridCoverage2D gc, String id, Translation title, Translation desc, Translation keywords, StyledLayerStyle<RasterLegendData> style, ImageIcon icon) {
-    super(gc, JTSUtil.createEnvelope(gc.getEnvelope()), gc.getCoordinateReferenceSystem(), id, title, desc, keywords, style != null ? style.getGeoObjectStyle() : null, icon);
-    setLegendMetaData( style != null ? style.getMetaData() : null );
-  }
+	/**
+	 * Creates a styled grid with language-specific informations.
+	 * 
+	 * @param gc
+	 *            the grid
+	 * @param id
+	 *            a unique ID for the object
+	 * @param title
+	 *            a (language-specific) short description
+	 * @param desc
+	 *            a (language-specific) long description
+	 * @param keywords
+	 *            (language-specific) keywords for the geo objects
+	 * @param style
+	 *            a display style with legend information
+	 * @param icon
+	 *            an icon for the object (can be {@code null})
+	 * @exception IllegalArgumentException
+	 *                if {@code null} is given as ID or geo object
+	 */
+	public StyledGridCoverage(GridCoverage2D gc, String id, Translation title,
+			Translation desc, Translation keywords,
+			StyledLayerStyle<RasterLegendData> style, ImageIcon icon) {
+		super(gc, JTSUtil.createEnvelope(gc.getEnvelope()), gc
+				.getCoordinateReferenceSystem(), id, title, desc, keywords,
+				style != null ? style.getGeoObjectStyle() : null, icon);
+		setLegendMetaData(style != null ? style.getMetaData() : null);
+	}
 
-  /**
-   * Creates a styled grid with a language-specific title, no long description, no
-   * keywords and no icon.
-   * @param gc the grid
-   * @param id a unique ID for the object
-   * @param title a short description
-   * @param style a display style (if {@code null}, a default style is created)
-   * @param legendData meta data for displaying a legend
-   * @exception IllegalArgumentException if {@code null} is given as ID or geo object
-   */
-  public StyledGridCoverage(GridCoverage2D gc, String id, Translation title, Style style, RasterLegendData legendData) {
-    this(gc, id, title, null, null, style, legendData, null);
-  }
+	/**
+	 * Creates a styled grid with a language-specific title, no long
+	 * description, no keywords and no icon.
+	 * 
+	 * @param gc
+	 *            the grid
+	 * @param id
+	 *            a unique ID for the object
+	 * @param title
+	 *            a short description
+	 * @param style
+	 *            a display style (if {@code null}, a default style is created)
+	 * @param legendData
+	 *            meta data for displaying a legend
+	 * @exception IllegalArgumentException
+	 *                if {@code null} is given as ID or geo object
+	 */
+	public StyledGridCoverage(GridCoverage2D gc, String id, Translation title,
+			Style style, RasterLegendData legendData) {
+		this(gc, id, title, null, null, style, legendData, null);
+	}
 
-  /**
-   * Creates a styled grid with non-translated informations.
-   * @param gc the grid
-   * @param id a unique ID for the object
-   * @param title a short description
-   * @param desc a long description
-   * @param keywords keywords for the geo objects
-   * @param style a display style (if {@code null}, a default style is created)
-   * @param legendData meta data for displaying a legend
-   * @param icon an icon for the object (can be {@code null})
-   * @exception IllegalArgumentException if {@code null} is given as ID or geo object
-   */
-  public StyledGridCoverage(GridCoverage2D gc, String id, String title, String desc, String keywords, Style style, RasterLegendData legendData, ImageIcon icon) {
-    this(gc, id, (Translation)null, null, null, style, legendData, icon);
-    setTitle(title);
-    setDesc(desc);
-    setKeywords(keywords);
-  }
+	/**
+	 * Creates a styled grid with non-translated informations.
+	 * 
+	 * @param gc
+	 *            the grid
+	 * @param id
+	 *            a unique ID for the object
+	 * @param title
+	 *            a short description
+	 * @param desc
+	 *            a long description
+	 * @param keywords
+	 *            keywords for the geo objects
+	 * @param style
+	 *            a display style (if {@code null}, a default style is created)
+	 * @param legendData
+	 *            meta data for displaying a legend
+	 * @param icon
+	 *            an icon for the object (can be {@code null})
+	 * @exception IllegalArgumentException
+	 *                if {@code null} is given as ID or geo object
+	 */
+	public StyledGridCoverage(GridCoverage2D gc, String id, String title,
+			String desc, String keywords, Style style,
+			RasterLegendData legendData, ImageIcon icon) {
+		this(gc, id, (Translation) null, null, null, style, legendData, icon);
+		setTitle(title);
+		setDesc(desc);
+		setKeywords(keywords);
+	}
 
-  /**
-   * Creates a styled grid with non-translated informations.
-   * @param gc the grid
-   * @param id a unique ID for the object
-   * @param title a short description
-   * @param desc a long description
-   * @param keywords keywords for the geo objects
-   * @param style a display style with legend information
-   * @param icon an icon for the object (can be {@code null})
-   * @exception IllegalArgumentException if {@code null} is given as ID or geo object
-   */
-  public StyledGridCoverage(GridCoverage2D gc, String id, String title, String desc, String keywords, StyledLayerStyle<RasterLegendData> style, ImageIcon icon) {
-    this(gc,
-         id,
-         title,
-         desc,
-         keywords,
-         style != null ? style.getGeoObjectStyle() : null,
-         style != null ? style.getMetaData() : null,
-         icon
-    );
-  }
+	/**
+	 * Creates a styled grid with non-translated informations.
+	 * 
+	 * @param gc
+	 *            the grid
+	 * @param id
+	 *            a unique ID for the object
+	 * @param title
+	 *            a short description
+	 * @param desc
+	 *            a long description
+	 * @param keywords
+	 *            keywords for the geo objects
+	 * @param style
+	 *            a display style with legend information
+	 * @param icon
+	 *            an icon for the object (can be {@code null})
+	 * @exception IllegalArgumentException
+	 *                if {@code null} is given as ID or geo object
+	 */
+	public StyledGridCoverage(GridCoverage2D gc, String id, String title,
+			String desc, String keywords,
+			StyledLayerStyle<RasterLegendData> style, ImageIcon icon) {
+		this(gc, id, title, desc, keywords, style != null ? style
+				.getGeoObjectStyle() : null, style != null ? style
+				.getMetaData() : null, icon);
+	}
 
-  /**
-   * Creates a styled grid with a non-translated title, no long description, no
-   * keywords and no icon.
-   * @param gc the grid
-   * @param id a unique ID for the object
-   * @param title a short description
-   * @param style a display style (if {@code null}, a default style is created)
-   * @exception IllegalArgumentException if {@code null} is given as ID or geo object
-   */
-  public StyledGridCoverage(GridCoverage2D gc, String id, String title, Style style, RasterLegendData legendData) {
-    this(gc, id, title, null, null, style, legendData, null);
-  }
+	/**
+	 * Creates a styled grid with a non-translated title, no long description,
+	 * no keywords and no icon.
+	 * 
+	 * @param gc
+	 *            the grid
+	 * @param id
+	 *            a unique ID for the object
+	 * @param title
+	 *            a short description
+	 * @param style
+	 *            a display style (if {@code null}, a default style is created)
+	 * @exception IllegalArgumentException
+	 *                if {@code null} is given as ID or geo object
+	 */
+	public StyledGridCoverage(GridCoverage2D gc, String id, String title,
+			Style style, RasterLegendData legendData) {
+		this(gc, id, title, null, null, style, legendData, null);
+	}
 
-  /**
-   * Creates a styled grid with a non-translated title, no long description, no
-   * keywords and no icon.
-   * @param gc the grid
-   * @param id a unique ID for the object
-   * @param title a short description
-   * @param style a display style with legend information
-   * @exception IllegalArgumentException if {@code null} is given as ID or geo object
-   */
-  public StyledGridCoverage(GridCoverage2D gc, String id, String title, StyledLayerStyle<RasterLegendData> style) {
-    this(gc,
-         id,
-         title,
-         null,
-         null,
-         style != null ? style.getGeoObjectStyle() : null,
-         style != null ? style.getMetaData() : null,
-         null
-    );
-  }
+	/**
+	 * Creates a styled grid with a non-translated title, no long description,
+	 * no keywords and no icon.
+	 * 
+	 * @param gc
+	 *            the grid
+	 * @param id
+	 *            a unique ID for the object
+	 * @param title
+	 *            a short description
+	 * @param style
+	 *            a display style with legend information
+	 * @exception IllegalArgumentException
+	 *                if {@code null} is given as ID or geo object
+	 */
+	public StyledGridCoverage(GridCoverage2D gc, String id, String title,
+			StyledLayerStyle<RasterLegendData> style) {
+		this(gc, id, title, null, null, style != null ? style
+				.getGeoObjectStyle() : null, style != null ? style
+				.getMetaData() : null, null);
+	}
 
-  /**
-   * Creates a default style for a {@link GridCoverage2D}.
-   * @see GridUtil#createDefaultStyle()
-   */
-  protected Style createDefaultStyle() {
-    return GridUtil.createDefaultStyle();
-  }
+	/**
+	 * Creates a default style for a {@link GridCoverage2D}.
+	 * 
+	 * @see GridUtil#createDefaultStyle()
+	 */
+	protected Style createDefaultStyle() {
+		return GridUtil.createDefaultStyle();
+	}
 
-  /**
-   * Returns the meta data needed for displaying a legend.
-   */
-  public RasterLegendData getLegendMetaData() {
-    return legendData;
-  }
+	/**
+	 * Returns the meta data needed for displaying a legend.
+	 */
+	public RasterLegendData getLegendMetaData() {
+		return legendData;
+	}
 
-  /**
-   * Sets the meta data needed for displaying a legend.
-   * If {@code legendData} is {@code null} an empty {@link RasterLegendData}
-   * (without gaps) is set, so {@link #getLegendMetaData()} never returns {@code null}.
-   * @param legendData legend meta data
-   */
-  public void setLegendMetaData(RasterLegendData legendData) {
-    this.legendData = (legendData != null) ? legendData : new RasterLegendData(false);
-  }
+	/**
+	 * Sets the meta data needed for displaying a legend. If {@code legendData}
+	 * is {@code null} an empty {@link RasterLegendData} (without gaps) is set,
+	 * so {@link #getLegendMetaData()} never returns {@code null}.
+	 * 
+	 * @param legendData
+	 *            legend meta data
+	 */
+	public void setLegendMetaData(RasterLegendData legendData) {
+		this.legendData = (legendData != null) ? legendData
+				: new RasterLegendData(false);
+	}
 
-  /**
-   * Simply sets the {@link #geoObject}, {@link #crs}, {@link #envelope} and
-   * {@link #legendData} to {@code null}.
-   */
-  public void dispose() {
-    this.geoObject  = null;
-    this.envelope   = null;
-    this.crs        = null;
-    this.legendData = null;
-  }
+	/**
+	 * Simply sets the {@link #geoObject}, {@link #crs}, {@link #envelope} and
+	 * {@link #legendData} to {@code null}.
+	 */
+	public void dispose() {
+		this.geoObject = null;
+		this.envelope = null;
+		this.crs = null;
+		this.legendData = null;
+	}
 
-  /**
-   * Tests whether the geo object is disposed.
-   * @return boolean
-   */
-  public boolean isDisposed() {
-    return geoObject == null;
-  }
+	/**
+	 * Tests whether the geo object is disposed.
+	 * 
+	 * @return boolean
+	 */
+	public boolean isDisposed() {
+		return geoObject == null;
+	}
 
-  /**
-   * Does nothing, because the {@link AbstractStyledLayer} bases on existing
-   * objects (in memory) which can not be uncached and reloaded.
-   */
-  public void uncache() {
-    LOGGER.warn("Uncache functionality is not supported. Object remains in memory.");
-  }
+	/**
+	 * Does nothing, because the {@link AbstractStyledLayer} bases on existing
+	 * objects (in memory) which can not be uncached and reloaded.
+	 */
+	public void uncache() {
+		LOGGER.warn("Uncache functionality is not supported. Object remains in memory.");
+	}
 
-  /*
-   * (non-Javadoc)
-   * @see skrueger.geotools.StyledLayerInterface#getInfoURL()
-   */
-  public URL getInfoURL() {
-	return null;
-  }
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see skrueger.geotools.StyledLayerInterface#getInfoURL()
+	 */
+	public URL getInfoURL() {
+		return null;
+	}
 
-  /**
+	/**
 	 * If true, this layer will not be shown in the legend. Default = false
 	 */
 	/**
@@ -249,9 +319,11 @@
 	 * nicht in der Legende auftauchen sollen. Meines Wissens hat keiner bisher
 	 * die Funktion genutzt.
 	 * 
-  public boolean isHideInLegend() {
-	return false;
-   }
+	 * public boolean isHideInLegend() { return false; }
 	 */
-  
+	@Override
+	public ReferencedEnvelope getReferencedEnvelope() {
+		return new ReferencedEnvelope(getEnvelope(), getCrs());
+	}
+
 }

Modified: trunk/src/skrueger/geotools/StyledGridCoverageReader.java
===================================================================
--- trunk/src/skrueger/geotools/StyledGridCoverageReader.java	2010-11-02 22:21:30 UTC (rev 1202)
+++ trunk/src/skrueger/geotools/StyledGridCoverageReader.java	2010-11-02 22:53:55 UTC (rev 1203)
@@ -35,6 +35,7 @@
 
 import org.geotools.coverage.grid.GridCoverage2D;
 import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
+import org.geotools.geometry.jts.ReferencedEnvelope;
 import org.geotools.styling.Style;
 
 import schmitzm.geotools.JTSUtil;
@@ -51,6 +52,10 @@
  * @version 1.0
  */
 public class StyledGridCoverageReader extends AbstractStyledLayer<AbstractGridCoverage2DReader> implements StyledGridCoverageReaderInterface {
+	@Override
+	public ReferencedEnvelope getReferencedEnvelope() {
+		return new ReferencedEnvelope(getEnvelope(), getCrs());
+	}
 
   /** Holds the meta data for displaying a legend. */
   protected RasterLegendData legendData = null;
@@ -238,6 +243,7 @@
     return null;
   }
 
+
   /**
 	 * If true, this layer will not be shown in the legend. Default = false
 	 */

Modified: trunk/src/skrueger/geotools/StyledLayerInterface.java
===================================================================
--- trunk/src/skrueger/geotools/StyledLayerInterface.java	2010-11-02 22:21:30 UTC (rev 1202)
+++ trunk/src/skrueger/geotools/StyledLayerInterface.java	2010-11-02 22:53:55 UTC (rev 1203)
@@ -34,6 +34,7 @@
 import javax.swing.ImageIcon;
 
 import org.geotools.feature.FeatureCollection;
+import org.geotools.geometry.jts.ReferencedEnvelope;
 import org.geotools.styling.Style;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 
@@ -116,6 +117,12 @@
 	public Envelope getEnvelope();
 
 	/**
+	 * @return <code>null</code> is no CRS is available
+	 */
+	public ReferencedEnvelope getReferencedEnvelope();
+
+
+	/**
 	 * @return return an ImageIcon - <code>null</code> is valid and no icon or a
 	 *         default icon will then be shown
 	 */
@@ -156,6 +163,5 @@
 	 * reread on next call of getGeoObject()
 	 */
 	public void uncache();
-
 //	public String getLegendHtml();
 }

Modified: trunk/src/skrueger/geotools/StyledLayerUtil.java
===================================================================
--- trunk/src/skrueger/geotools/StyledLayerUtil.java	2010-11-02 22:21:30 UTC (rev 1202)
+++ trunk/src/skrueger/geotools/StyledLayerUtil.java	2010-11-02 22:53:55 UTC (rev 1203)
@@ -1151,7 +1151,7 @@
 			if (geoObject instanceof GridCoverage2D) {
 				final GridCoverage2D cov = (GridCoverage2D) geoObject;
 				colorModel = cov.getRenderedImage().getColorModel();
-			} else if (styledGrid instanceof StyledRasterPyramidInterface) {
+			} else if (styledGrid instanceof StyledGridCoverageReaderInterface) {
 
 				final Parameter readGG = new Parameter(
 						AbstractGridFormat.READ_GRIDGEOMETRY2D);

Deleted: trunk/src/skrueger/geotools/StyledRasterPyramidInterface.java
===================================================================
--- trunk/src/skrueger/geotools/StyledRasterPyramidInterface.java	2010-11-02 22:21:30 UTC (rev 1202)
+++ trunk/src/skrueger/geotools/StyledRasterPyramidInterface.java	2010-11-02 22:53:55 UTC (rev 1203)
@@ -1,37 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009 Stefan A. Tzeggai.
- * 
- * This file is part of the AtlasViewer application - A GIS viewer application targeting at end-users with no GIS-experience. Its main purpose is to present the atlases created with the Geopublisher application.
- * http://www.geopublishing.org
- * 
- * AtlasViewer is part of the Geopublishing Framework hosted at:
- * http://wald.intevation.org/projects/atlas-framework/
- * 
- * This program 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; either version 3
- * of the License, or (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public License (license.txt)
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- * or try this link: http://www.gnu.org/licenses/lgpl.html
- * 
- * Contributors:
- *     Stefan A. Tzeggai - initial API and implementation
- ******************************************************************************/
-package skrueger.geotools;
-
-import org.geotools.feature.FeatureCollection;
-import org.opengis.feature.simple.SimpleFeature;
-import org.opengis.feature.simple.SimpleFeatureType;
-
-
-public interface StyledRasterPyramidInterface extends
-		StyledRasterInterface<FeatureCollection<SimpleFeatureType, SimpleFeature>> {
-};

Modified: trunk/src_junit/schmitzm/jfree/feature/style/FeatureChartStyleTest.java
===================================================================
--- trunk/src_junit/schmitzm/jfree/feature/style/FeatureChartStyleTest.java	2010-11-02 22:21:30 UTC (rev 1202)
+++ trunk/src_junit/schmitzm/jfree/feature/style/FeatureChartStyleTest.java	2010-11-02 22:53:55 UTC (rev 1203)
@@ -29,7 +29,6 @@
 import org.jfree.chart.plot.XYPlot;
 import org.jfree.data.category.CategoryDataset;
 import org.jfree.data.category.DefaultCategoryDataset;
-import org.jfree.data.xy.XYDataset;
 import org.jfree.data.xy.XYSeriesCollection;
 import org.jfree.ui.RectangleEdge;
 import org.jfree.ui.TextAnchor;
@@ -51,7 +50,6 @@
 import schmitzm.jfree.chart.style.ChartStyleXMLFactory;
 import schmitzm.jfree.chart.style.ChartType;
 import schmitzm.jfree.data.RegressionDataset;
-import schmitzm.jfree.data.RegressionDatasetImpl;
 import schmitzm.jfree.table.AggregationFunction;
 import schmitzm.swing.SwingUtil;
 import schmitzm.swing.TestingUtil;

Modified: trunk/src_junit/schmitzm/swing/TestingUtil.java
===================================================================
--- trunk/src_junit/schmitzm/swing/TestingUtil.java	2010-11-02 22:21:30 UTC (rev 1202)
+++ trunk/src_junit/schmitzm/swing/TestingUtil.java	2010-11-02 22:53:55 UTC (rev 1203)
@@ -45,7 +45,6 @@
 
 import schmitzm.geotools.io.GeoImportUtil;
 import schmitzm.io.IOUtil;
-import schmitzm.jfree.chart.SelectableChartPanel;
 import schmitzm.lang.LangUtil;
 /**
  * Helpers to test Swing applications in general. <br/>



More information about the Schmitzm-commits mailing list