[Schmitzm-commits] r509 - in branches/1.0-gt2-2.6/src: gtmig/org/geotools/swing schmitzm/geotools schmitzm/geotools/feature schmitzm/geotools/gui schmitzm/geotools/io schmitzm/geotools/map/event schmitzm/geotools/styling schmitzm/jfree schmitzm/jfree/chart schmitzm/jfree/chart/renderer schmitzm/swing skrueger/geotools skrueger/geotools/labelsearch skrueger/geotools/selection skrueger/swing

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Thu Nov 5 09:51:39 CET 2009


Author: alfonx
Date: 2009-11-05 09:51:33 +0100 (Thu, 05 Nov 2009)
New Revision: 509

Added:
   branches/1.0-gt2-2.6/src/gtmig/org/geotools/swing/XMapPane.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/SelectableXMapPane.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/MapPaneEvent.java
Removed:
   branches/1.0-gt2-2.6/src/gtmig/org/geotools/swing/JMapPane.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/JMapPane.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/JMapPaneEvent.java
Modified:
   branches/1.0-gt2-2.6/src/schmitzm/geotools/GTUtil.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/JTSUtil.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/feature/FeatureUtil.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/FeatureLayerFilterDialog.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/FeatureTablePane.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/GeoMapPane.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/GeoPositionLabel.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/GridPanel.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/JEditorPane.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/JEditorToolBar.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/LayeredEditorFrame.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/LayeredMapFrame.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/LayeredMapPane.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/MapActionControlPane.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/MapContextControlPane.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/MapPaneStatusBar.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/RasterPositionLabel.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/SelectableFeatureTablePane.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/io/GeoImportUtil.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/FeatureSelectedEvent.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/GeneralSelectionEvent.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/GridCoverageSelectedEvent.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/GridCoverageValueSelectedEvent.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/JEditorPaneEvent.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/JMapPaneListener.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/MapAreaChangedEvent.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/ObjectSelectionEvent.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/ScaleChangedEvent.java
   branches/1.0-gt2-2.6/src/schmitzm/geotools/styling/StylingUtil.java
   branches/1.0-gt2-2.6/src/schmitzm/jfree/JFreeChartUtil.java
   branches/1.0-gt2-2.6/src/schmitzm/jfree/chart/SelectableChartPanel.java
   branches/1.0-gt2-2.6/src/schmitzm/jfree/chart/renderer/PointSelectionCategoryRenderer.java
   branches/1.0-gt2-2.6/src/schmitzm/jfree/chart/renderer/PointSelectionXYRenderer.java
   branches/1.0-gt2-2.6/src/schmitzm/jfree/chart/renderer/SelectionRenderer.java
   branches/1.0-gt2-2.6/src/schmitzm/jfree/chart/renderer/SelectionXYLineAndShapeRenderer.java
   branches/1.0-gt2-2.6/src/schmitzm/swing/SwingUtil.java
   branches/1.0-gt2-2.6/src/skrueger/geotools/MapPaneToolBar.java
   branches/1.0-gt2-2.6/src/skrueger/geotools/MapView.java
   branches/1.0-gt2-2.6/src/skrueger/geotools/labelsearch/LabelSearch.java
   branches/1.0-gt2-2.6/src/skrueger/geotools/labelsearch/SearchMapDialog.java
   branches/1.0-gt2-2.6/src/skrueger/geotools/labelsearch/SearchResultFeature.java
   branches/1.0-gt2-2.6/src/skrueger/geotools/selection/FeatureMapLayerSelectionSynchronizer.java
   branches/1.0-gt2-2.6/src/skrueger/swing/CancellableDialogManager.java
   branches/1.0-gt2-2.6/src/skrueger/swing/CancellableTabbedDialogAdapter.java
Log:
new XMapPane and SelectableMapPane to replace and restructure JMapPanes

Deleted: branches/1.0-gt2-2.6/src/gtmig/org/geotools/swing/JMapPane.java
===================================================================
--- branches/1.0-gt2-2.6/src/gtmig/org/geotools/swing/JMapPane.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/gtmig/org/geotools/swing/JMapPane.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -1,1073 +0,0 @@
-/*
- *    GeoTools - OpenSource mapping toolkit
- *    http://geotools.org
- *    (C) 2002-2006, GeoTools Project Managment Committee (PMC)
- *
- *    This library is free software; you can redistribute it and/or
- *    modify it under the terms of the GNU Lesser General Public
- *    License as published by the Free Software Foundation;
- *    version 2.1 of the License.
- *
- *    This library 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
- *    Lesser General Public License for more details.
- */
-package gtmig.org.geotools.swing;
-
-/**
- * <b>Xulu:<br>
- *    Code taken from gt-2.4.5 to make some changes (marked with {@code xulu}),
- *    which can not be realized in a subclass:</b>
- *    <ul>
- *       <li>{@link #getMapArea()} declared as {@code final}<li>
- *       <li>some variables declared as {@code protected}</li>
- *       <li>minimal/maximal zoom scale</li>
- *       <li>zoom in and zoom out via mouse click realized by setMapArea(..)</li>
- *    </ul>
- * <br><br>
- * A simple map container that is a JPanel with a map in. provides simple
- * pan,zoom, highlight and selection The mappane stores an image of the map
- * (drawn from the context) and an image of the slected feature(s) to speed up
- * rendering of the highlights. Thus the whole map is only redrawn when the bbox
- * changes, selection is only redrawn when the selected feature changes.
- *
- *
- * @author Ian Turton
- *
- */
-
-import java.awt.Color;
-import java.awt.Cursor;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.LayoutManager;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.event.InputEvent;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-import java.awt.event.MouseMotionListener;
-import java.awt.geom.AffineTransform;
-import java.awt.image.BufferedImage;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.io.IOException;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.swing.JPanel;
-
-import org.apache.log4j.Logger;
-import org.geotools.map.MapContext;
-import org.geotools.map.event.MapLayerListEvent;
-import org.geotools.map.event.MapLayerListListener;
-import org.geotools.renderer.GTRenderer;
-import org.geotools.renderer.label.LabelCacheImpl;
-import org.geotools.renderer.lite.LabelCache;
-import org.geotools.renderer.lite.StreamingRenderer;
-import org.opengis.filter.FilterFactory2;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-
-import schmitzm.geotools.JTSUtil;
-import schmitzm.swing.SwingUtil;
-
-import com.vividsolutions.jts.geom.Coordinate;
-import com.vividsolutions.jts.geom.Envelope;
-import com.vividsolutions.jts.geom.GeometryFactory;
-
-public class JMapPane extends JPanel implements MouseListener,
-		MouseMotionListener, PropertyChangeListener, MapLayerListListener {
-	private static Logger LOGGER = Logger.getLogger(JMapPane.class);
-
-	private static final long serialVersionUID = -8647971481359690499L;
-
-	public static final int Reset = 0;
-
-	public static final int ZoomIn = 1;
-
-	public static final int ZoomOut = 2;
-
-	public static final int Pan = 3;
-
-	public static final int Select = 4;
-
-	/**
-	 * what renders the map
-	 */
-	GTRenderer renderer;
-
-	/**
-	 * the map context to render
-	 */
-	MapContext context;
-
-	/**
-	 * the area of the map to draw
-	 */
-	protected Envelope mapArea;
-
-	/**
-	 * the size of the pane last time we drew
-	 */
-	protected Rectangle oldRect = null;
-
-	/** We store the old mapArea for a moment to use it for the
-	"quick scaled preview" in case of ZoomOut **/
-	protected Envelope oldMapArea = null;
-
-	/**
-	 * the base image of the map
-	 */
-	protected BufferedImage baseImage, panningImage;
-
-	/**
-	 * a factory for filters
-	 */
-	FilterFactory2 ff;
-
-	/**
-	 * a factory for geometries
-	 */
-	GeometryFactory gf = new GeometryFactory(); // FactoryFinder.getGeometryFactory(null);
-
-	private int state = ZoomIn;
-
-	/**
-	 * how far to zoom in or out
-	 */
-	private double zoomFactor = 2.0;
-
-	boolean changed = true;
-
-	LabelCache labelCache = new LabelCacheImpl();
-
-	protected boolean reset = false;
-
-	int startX;
-
-	int startY;
-
-	/**
-	 * If not <code>null</code>, the {@link JMapPane} will not allow to zoom/pan
-	 * out of that area
-	 **/
-	private Envelope maxExtend = null;
-
-	// /**
-	// * Is max. 1 or 0 of the 2 axised allowed to extend the maxExtend? If
-	// * <code>true</code> the extends has to be fully inside maxExtend
-	// **/
-	// boolean maxExtendForceMode = true;
-
-	private boolean clickable;
-
-	int lastX;
-
-	int lastY;
-
-	private Double maxZoomScale = Double.MIN_VALUE;
-	private Double minZoomScale = Double.MAX_VALUE;
-
-	/**
-	 * Wenn true, dann wurde PANNING via mouseDraged-Events begonnen. Dieses
-	 * Flag wird benutzt um nur einmal den passenden Cursor nur einmal zu
-	 * setzen.
-	 */
-	private boolean panning_started = false;
-
-	/**
-	 * This color is used as the default background color when painting a map.
-	 */
-	private Color mapBackgroundColor = Color.WHITE;
-
-	public JMapPane() {
-		this(null, true, null, null);
-	}
-
-	/**
-	 * create a basic JMapPane
-	 * 
-	 * @param render
-	 *            - how to draw the map
-	 * @param context
-	 *            - the map context to display
-	 */
-	public JMapPane(final GTRenderer render, final MapContext context) {
-		this(null, true, render, context);
-	}
-
-	/**
-	 * full constructor extending JPanel
-	 * 
-	 * @param layout
-	 *            - layout (probably shouldn't be set)
-	 * @param isDoubleBuffered
-	 *            - a Swing thing I don't really understand
-	 * @param render
-	 *            - what to draw the map with
-	 * @param context
-	 *            - what to draw
-	 */
-	public JMapPane(final LayoutManager layout, final boolean isDoubleBuffered,
-			final GTRenderer render, final MapContext context) {
-		super(layout, isDoubleBuffered);
-
-		ff = (FilterFactory2) org.geotools.factory.CommonFactoryFinder
-				.getFilterFactory(null);
-		setRenderer(render);
-
-		setContext(context);
-
-		this.addMouseListener(this);
-		this.addMouseMotionListener(this);
-		setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
-	}
-
-	/**
-	 * get the renderer
-	 */
-	public GTRenderer getRenderer() {
-		return renderer;
-	}
-
-	public void setRenderer(final GTRenderer renderer) {
-		Map<Object, Object> hints = new HashMap<Object, Object>();
-
-		this.renderer = renderer;
-		// MS: Apply hint also for ShapeFileRenderer
-		// if (renderer instanceof StreamingRenderer) {
-		hints = renderer.getRendererHints();
-		if (hints == null) {
-			hints = new HashMap<Object, Object>();
-		}
-		if (hints.containsKey(StreamingRenderer.LABEL_CACHE_KEY)) {
-			labelCache = (LabelCache) hints
-					.get(StreamingRenderer.LABEL_CACHE_KEY);
-		} else {
-			hints.put(StreamingRenderer.LABEL_CACHE_KEY, labelCache);
-		}
-
-		hints.put("memoryPreloadingEnabled", Boolean.TRUE);
-
-		renderer.setRendererHints(hints);
-		// }
-
-		if (this.context != null) {
-			this.renderer.setContext(this.context);
-		}
-	}
-
-	public MapContext getContext() {
-		return context;
-	}
-
-	public void setContext(final MapContext context) {
-		if (this.context != null) {
-			this.context.removeMapLayerListListener(this);
-		}
-
-		this.context = context;
-
-		if (context != null) {
-			this.context.addMapLayerListListener(this);
-		}
-
-		if (renderer != null) {
-			renderer.setContext(this.context);
-		}
-	}
-
-	public Envelope getMapArea() {
-		return mapArea;
-	}
-
-	public void setMapArea(final Envelope mapArea) {
-		this.mapArea = mapArea;
-	}
-
-	public int getState() {
-		return state;
-	}
-
-	public void setState(final int state) {
-		this.state = state;
-
-		// System.out.println("State: " + state);
-	}
-
-	public double getZoomFactor() {
-		return zoomFactor;
-	}
-
-	public void setZoomFactor(final double zoomFactor) {
-		this.zoomFactor = zoomFactor;
-	}
-
-	protected void paintComponent(final Graphics g) {
-		super.paintComponent(g);
-
-		if ((renderer == null) || (mapArea == null)) {
-			return;
-		}
-
-		final Rectangle r = getBounds();
-		final Rectangle dr = new Rectangle(r.width, r.height);
-
-		if (!r.equals(oldRect) || reset) {
-			if (!r.equals(oldRect) && (mapArea == null)) {
-				try {
-					mapArea = context.getLayerBounds();
-				} catch (final IOException e) {
-					LOGGER.warn("context.getLayerBounds()", e);
-				}
-			}
-
-			if (mapArea != null) {
-				/* either the viewer size has changed or we've done a reset */
-				changed = true; /* note we need to redraw */
-				reset = false; /* forget about the reset */
-				oldRect = r; /* store what the current size is */
-
-				mapArea = JTSUtil.fixAspectRatio(r, mapArea, false);
-			}
-		}
-
-		if (!mapArea.equals(oldMapArea)) { /* did the map extent change? */
-			changed = true;
-			oldMapArea = mapArea;
-			// when we tell the context that the bounds have changed WMSLayers
-			// can refresh them selves
-			context.setAreaOfInterest(mapArea, context
-					.getCoordinateReferenceSystem());
-		}
-
-		if (changed) { /* if the map changed then redraw */
-			changed = false;
-			
-			// The baseImage should not have alpha
-			baseImage = new BufferedImage(dr.width, dr.height,
-					BufferedImage.TYPE_INT_RGB); 
-
-			final Graphics2D ig = baseImage.createGraphics();
-			ig.setBackground(getMapBackgroundColor());
-			ig.fillRect(0, 0, dr.width, dr.height);
-			
-//			/* System.out.println("rendering"); */
-			if (renderer.getContext() != null)
-				renderer.setContext(context);
-
-			// TODO is this clearing still needed? We already replace all that stuff whenever we change the style. Deactivated 31.10.09.. let's see 
-//			labelCache.clear(); // work around anoying labelcache bug
-
-			// draw the map
-			renderer.paint(ig, dr, mapArea);
-
-			panningImage = new BufferedImage(dr.width, dr.height, BufferedImage.TYPE_INT_RGB);
-
-		}
-
-		((Graphics2D) g).drawImage(baseImage, 0, 0, this);
-	}
-
-	public void mouseClicked(final MouseEvent e) {
-		if (mapArea == null)
-			return;
-		// System.out.println("before area "+mapArea+"\nw:"+mapArea.getWidth()+"
-		// h:"+mapArea.getHeight());
-		final Rectangle bounds = this.getBounds();
-		final double x = (double) (e.getX());
-		final double y = (double) (e.getY());
-		final double width = mapArea.getWidth();
-		final double height = mapArea.getHeight();
-		// xulu.sc
-		// double width2 = mapArea.getWidth() / 2.0;
-		// double height2 = mapArea.getHeight() / 2.0;
-		final double width2 = width / 2.0;
-		final double height2 = height / 2.0;
-		// xulu.ec
-		final double mapX = ((x * width) / (double) bounds.width)
-				+ mapArea.getMinX();
-		final double mapY = (((bounds.getHeight() - y) * height) / (double) bounds.height)
-				+ mapArea.getMinY();
-
-		/*
-		 * System.out.println(""+x+"->"+mapX);
-		 * System.out.println(""+y+"->"+mapY);
-		 */
-
-		/*
-		 * Coordinate ll = new Coordinate(mapArea.getMinX(), mapArea.getMinY());
-		 * Coordinate ur = new Coordinate(mapArea.getMaxX(), mapArea.getMaxY());
-		 */
-		double zlevel = 1.0;
-
-		switch (state) {
-		case Pan:
-			zlevel = 1.0;
-			// xulu.sc SK: return here.. a mouselistener is managing the PANNING
-			// break;
-			return;
-			// xulu.ec
-		case ZoomIn:
-			zlevel = zoomFactor;
-
-			break;
-
-		case ZoomOut:
-			zlevel = 1.0 / zoomFactor;
-
-			break;
-		//
-		// case Select:
-		// doSelection(mapX, mapY, selectionLayer);
-		//
-		// return;
-
-		default:
-			return;
-		}
-
-		final Coordinate ll = new Coordinate(mapX - (width2 / zlevel), mapY
-				- (height2 / zlevel));
-		final Coordinate ur = new Coordinate(mapX + (width2 / zlevel), mapY
-				+ (height2 / zlevel));
-		// xulu.sc SK: Check for min/max scale
-		// mapArea = new Envelope(ll, ur);
-		final Envelope newMapArea = new Envelope(ll, ur);
-		setMapArea(bestAllowedMapArea(newMapArea));
-		// xulu.ec
-
-		// sk.ec
-
-		// System.out.println("after area "+mapArea+"\nw:"+mapArea.getWidth()+"
-		// h:"+mapArea.getHeight());
-		repaint();
-	}
-
-	public void mouseEntered(final MouseEvent e) {
-	}
-
-	public void mouseExited(final MouseEvent e) {
-	}
-
-	public void mousePressed(final MouseEvent e) {
-		startX = e.getX();
-		startY = e.getY();
-		lastX = 0;
-		lastY = 0;
-	}
-
-	public void mouseReleased(final MouseEvent e) {
-		final int endX = e.getX();
-		final int endY = e.getY();
-
-		processDrag(startX, startY, endX, endY, e);
-		lastX = 0;
-		lastY = 0;
-
-		/**
-		 * Es wird nicht (mehr) gepannt!
-		 */
-		panning_started = false;
-	}
-
-	public void mouseDragged(final MouseEvent e) {
-		final Graphics graphics = this.getGraphics();
-		final int x = e.getX();
-		final int y = e.getY();
-
-		if ((state == JMapPane.Pan)
-				|| ((e.getModifiersEx() & InputEvent.BUTTON3_DOWN_MASK) != 0)) {
-			/**
-			 * SK: Der Cursor wird auf PANNING gesetzt.
-			 */
-			if (panning_started == false) {
-				panning_started = true;
-				setCursor(SwingUtil.PANNING_CURSOR);
-			}
-
-			// move the image with the mouse
-			if ((lastX > 0) && (lastY > 0)) {
-				final int dx = lastX - startX;
-				final int dy = lastY - startY;
-				// System.out.println("translate "+dx+","+dy);
-				final Graphics2D g2 = panningImage.createGraphics();
-				g2.setBackground(getMapBackgroundColor()); 
-
-				g2.clearRect(0, 0, this.getWidth(), this.getHeight());
-				g2.drawImage(baseImage, dx, dy, this);
-				graphics.drawImage(panningImage, 0, 0, this);
-			}
-
-			lastX = x;
-			lastY = y;
-		} else
-
-		if ((state == JMapPane.ZoomIn) || (state == JMapPane.ZoomOut)) {
-
-			graphics.setXORMode(Color.WHITE);
-
-			if ((lastX > 0) && (lastY > 0)) {
-				drawRectangle(graphics);
-			}
-
-			// draw new box
-			lastX = x;
-			lastY = y;
-			drawRectangle(graphics);
-		}
-		// else if (state == JMapPane.Select && selectionLayer != null) {
-		//
-		// // construct a new bbox filter
-		// final Rectangle bounds = this.getBounds();
-		//
-		// final double mapWidth = mapArea.getWidth();
-		// final double mapHeight = mapArea.getHeight();
-		//
-		// final double x1 = ((this.startX * mapWidth) / (double) bounds.width)
-		// + mapArea.getMinX();
-		// final double y1 = (((bounds.getHeight() - this.startY) * mapHeight) /
-		// (double) bounds.height)
-		// + mapArea.getMinY();
-		// final double x2 = ((x * mapWidth) / (double) bounds.width)
-		// + mapArea.getMinX();
-		// final double y2 = (((bounds.getHeight() - y) * mapHeight) / (double)
-		// bounds.height)
-		// + mapArea.getMinY();
-		// final double left = Math.min(x1, x2);
-		// final double right = Math.max(x1, x2);
-		// final double bottom = Math.min(y1, y2);
-		// final double top = Math.max(y1, y2);
-		//
-		// String name = selectionLayer.getFeatureSource().getSchema()
-		// .getDefaultGeometry().getName();
-		//
-		// if (name == "") {
-		// name = "the_geom";
-		// }
-		// final Filter bb = ff.bbox(ff.property(name), left, bottom, right,
-		// top,
-		// getContext().getCoordinateReferenceSystem().toString());
-		// if (selectionManager != null) {
-		// selectionManager.selectionChanged(this, bb);
-		// }
-		//
-		// graphics.setXORMode(Color.green);
-		//
-		// /*
-		// * if ((lastX > 0) && (lastY > 0)) { drawRectangle(graphics); }
-		// */
-		//
-		// // draw new box
-		// lastX = x;
-		// lastY = y;
-		// drawRectangle(graphics);
-		// }
-
-	}
-
-	// sk.cs
-	// private void processDrag(int x1, int y1, int x2, int y2) {
-	// sk.ce
-	protected void processDrag(final int x1, final int y1, final int x2,
-			final int y2, final MouseEvent e) {
-
-		/****
-		 * If no layers exist, we ignore the drag.
-		 */
-		if (context.getLayerCount() <= 0) {
-			return;
-		}
-
-		// System.out.println("processing drag from " + x1 + "," + y1 + " -> "
-		// + x2 + "," + y2);
-		if ((x1 == x2) && (y1 == y2)) {
-			if (isClickable()) {
-				mouseClicked(new MouseEvent(this, 0, new Date().getTime(), 0,
-						x1, y1, y2, false));
-			}
-
-			return;
-		}
-
-		final Rectangle bounds = this.getBounds();
-
-		final double mapWidth = mapArea.getWidth();
-		final double mapHeight = mapArea.getHeight();
-
-		final double startX = ((x1 * mapWidth) / (double) bounds.width)
-				+ mapArea.getMinX();
-		final double startY = (((bounds.getHeight() - y1) * mapHeight) / (double) bounds.height)
-				+ mapArea.getMinY();
-		final double endX = ((x2 * mapWidth) / (double) bounds.width)
-				+ mapArea.getMinX();
-		final double endY = (((bounds.getHeight() - y2) * mapHeight) / (double) bounds.height)
-				+ mapArea.getMinY();
-
-		if ((state == JMapPane.Pan) || (e.getButton() == MouseEvent.BUTTON3)) {
-			// move the image with the mouse
-			// calculate X offsets from start point to the end Point
-			final double deltaX1 = endX - startX;
-
-			// System.out.println("deltaX " + deltaX1);
-			// new edges
-			final double left = mapArea.getMinX() - deltaX1;
-			final double right = mapArea.getMaxX() - deltaX1;
-			final double deltaY1 = endY - startY;
-
-			// System.out.println("deltaY " + deltaY1);
-			final double bottom = mapArea.getMinY() - deltaY1;
-			final double top = mapArea.getMaxY() - deltaY1;
-			final Coordinate ll = new Coordinate(left, bottom);
-			final Coordinate ur = new Coordinate(right, top);
-			// xulu.sc
-			// mapArea = fixAspectRatio(this.getBounds(), new Envelope(ll, ur));
-
-			setMapArea(bestAllowedMapArea(new Envelope(ll, ur)));
-			// xulu.ec
-		} else if (state == JMapPane.ZoomIn) {
-
-			// Zu kleine Flächen sollen nicht gezoomt werden.
-			// sk.bc
-			if ((Math.abs(x1 - x2) * Math.abs(y2 - y1)) < 150)
-				return;
-			// sk.ec
-
-			drawRectangle(this.getGraphics());
-			// make the dragged rectangle (in map coords) the new BBOX
-			final double left = Math.min(startX, endX);
-			final double right = Math.max(startX, endX);
-			final double bottom = Math.min(startY, endY);
-			final double top = Math.max(startY, endY);
-			final Coordinate ll = new Coordinate(left, bottom);
-			final Coordinate ur = new Coordinate(right, top);
-			// xulu.sc
-
-			// mapArea = fixAspectRatio(this.getBounds(), new Envelope(ll, ur));
-			setMapArea(bestAllowedMapArea(new Envelope(ll, ur)));
-
-		} else if (state == JMapPane.ZoomOut) {
-			drawRectangle(this.getGraphics());
-
-			// make the dragged rectangle in screen coords the new map size?
-			final double left = Math.min(startX, endX);
-			final double right = Math.max(startX, endX);
-			final double bottom = Math.min(startY, endY);
-			final double top = Math.max(startY, endY);
-			final double nWidth = (mapWidth * mapWidth) / (right - left);
-			final double nHeight = (mapHeight * mapHeight) / (top - bottom);
-			final double deltaX1 = left - mapArea.getMinX();
-			final double nDeltaX1 = (deltaX1 * nWidth) / mapWidth;
-			final double deltaY1 = bottom - mapArea.getMinY();
-			final double nDeltaY1 = (deltaY1 * nHeight) / mapHeight;
-			final Coordinate ll = new Coordinate(mapArea.getMinX() - nDeltaX1,
-					mapArea.getMinY() - nDeltaY1);
-			final double deltaX2 = mapArea.getMaxX() - right;
-			final double nDeltaX2 = (deltaX2 * nWidth) / mapWidth;
-			final double deltaY2 = mapArea.getMaxY() - top;
-			final double nDeltaY2 = (deltaY2 * nHeight) / mapHeight;
-			final Coordinate ur = new Coordinate(mapArea.getMaxX() + nDeltaX2,
-					mapArea.getMaxY() + nDeltaY2);
-			// xulu.sc
-			// mapArea = fixAspectRatio(this.getBounds(), new Envelope(ll, ur));
-			setMapArea(bestAllowedMapArea(new Envelope(ll, ur)));
-
-			// xulu.ec
-		}
-		// else if (state == JMapPane.Select && selectionLayer != null) {
-		// final double left = Math.min(startX, endX);
-		// final double right = Math.max(startX, endX);
-		// final double bottom = Math.min(startY, endY);
-		// final double top = Math.max(startY, endY);
-		//
-		// String name = selectionLayer.getFeatureSource().getSchema()
-		// .getDefaultGeometry().getLocalName();
-		//
-		// if (name == "") {
-		// name = "the_geom";
-		// }
-		// final Filter bb = ff.bbox(ff.property(name), left, bottom, right,
-		// top,
-		// getContext().getCoordinateReferenceSystem().toString());
-		// // System.out.println(bb.toString());
-		// if (selectionManager != null) {
-		// selectionManager.selectionChanged(this, bb);
-		// }
-		// /*
-		// * FeatureCollection fc; selection = null; try { fc =
-		// * selectionLayer.getFeatureSource().getFeatures(bb); selection =
-		// * fc; } catch (IOException e) { e.printStackTrace(); }
-		// */
-		// }
-
-		// xulu.so
-		// setMapArea(mapArea);
-		// xulu.eo
-		repaint();
-	}
-
-	private boolean isClickable() {
-		return clickable;
-	}
-
-	public void propertyChange(final PropertyChangeEvent evt) {
-		final String prop = evt.getPropertyName();
-
-		if (prop.equalsIgnoreCase("crs")) {
-			context.setAreaOfInterest(context.getAreaOfInterest(),
-					(CoordinateReferenceSystem) evt.getNewValue());
-		}
-	}
-
-	public boolean isReset() {
-		return reset;
-	}
-
-	public void setReset(final boolean reset) {
-		this.reset = reset;
-	}
-
-	public void layerAdded(final MapLayerListEvent event) {
-		changed = true;
-
-		if (context.getLayers().length == 1) { // the first one
-
-			try {
-				// xulu.sc
-				// mapArea = context.getLayerBounds();
-				mapArea = context.getAreaOfInterest();
-				if (mapArea == null)
-					mapArea = context.getLayerBounds();
-				// xulu.ec
-			} catch (final IOException e) {
-				LOGGER.error(e);
-			}
-
-			reset = true;
-		}
-
-		repaint();
-	}
-
-	public void layerRemoved(final MapLayerListEvent event) {
-		changed = true;
-		repaint();
-	}
-
-	public void layerChanged(final MapLayerListEvent event) {
-		changed = true;
-		// System.out.println("layer changed - repaint");
-		repaint();
-	}
-
-	public void layerMoved(final MapLayerListEvent event) {
-		changed = true;
-		repaint();
-	}
-
-	protected void drawRectangle(final Graphics graphics) {
-		// undraw last box/draw new box
-		final int left = Math.min(startX, lastX);
-		final int right = Math.max(startX, lastX);
-		final int top = Math.max(startY, lastY);
-		final int bottom = Math.min(startY, lastY);
-		final int width = right - left;
-		final int height = top - bottom;
-		// System.out.println("drawing rect("+left+","+bottom+","+ width+","+
-		// height+")");
-		graphics.drawRect(left, bottom, width, height);
-	}
-
-	/**
-	 * if clickable is set to true then a single click on the map pane will zoom
-	 * or pan the map.
-	 * 
-	 * @param clickable
-	 */
-	public void setClickable(final boolean clickable) {
-		this.clickable = clickable;
-	}
-
-	public void mouseMoved(final MouseEvent e) {
-	}
-
-	// xulu.sn
-	/**
-	 * Korrigiert den {@link Envelope} aka {@code mapArea} auf die beste
-	 * erlaubte Flaeche damit die Massstabsbeschaenkungen noch eingehalten
-	 * werden, FALLS der uebergeben Envelope nicht schon gueltig sein sollte.<br/>
-	 * Since 21. April 09: Before thecalculation starts, the aspect ratio is
-	 * corrected. This change implies, that setMapArea() will most of the time
-	 * not allow setting to a wrong aspectRatio.
-	 * 
-	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
-	 *         Kr&uuml;ger</a>
-	 */
-	public Envelope bestAllowedMapArea(Envelope env) {
-		if (getWidth() == 0)
-			return env;
-		if (env == null)
-			return env;
-
-		Envelope newArea = null;
-
-		/**
-		 * Correct the aspect Ratio before we check the rest. Otherwise we might
-		 * easily fail. We allow to grow here, because we don't check against
-		 * the maxExtend
-		 */
-		env = JTSUtil.fixAspectRatio(this.getBounds(), env, true);
-
-		final double scale = env.getWidth() / getWidth();
-		final double centerX = env.getMinX() + env.getWidth() / 2.;
-		final double centerY = env.getMinY() + env.getHeight() / 2.;
-		double newWidth2 = 0;
-		double newHeight2 = 0;
-		if (scale < getMaxZoomScale()) {
-			// ****************************************************************************
-			// Wir zoomen weiter rein als erlaubt => Anpassen des envelope
-			// ****************************************************************************
-			newWidth2 = getMaxZoomScale() * getWidth() / 2.;
-			newHeight2 = getMaxZoomScale() * getHeight() / 2.;
-		} else if (scale > getMinZoomScale()) {
-			// ****************************************************************************
-			// Wir zoomen weiter raus als erlaubt => Anpassen des envelope
-			// ****************************************************************************
-			newWidth2 = getMinZoomScale() * getWidth() / 2.;
-			newHeight2 = getMinZoomScale() * getHeight() / 2.;
-		} else {
-			// ****************************************************************************
-			// Die mapArea / der Envelope ist ist gueltig! Keine Aenderungen
-			// ****************************************************************************
-			newArea = env;
-		}
-
-		if (newArea == null) {
-
-			final Coordinate ll = new Coordinate(centerX - newWidth2, centerY
-					- newHeight2);
-			final Coordinate ur = new Coordinate(centerX + newWidth2, centerY
-					+ newHeight2);
-
-			newArea = new Envelope(ll, ur);
-		}
-
-		Envelope maxAllowedExtend = getMaxExtend();
-		while (maxAllowedExtend != null && !maxAllowedExtend.contains(newArea)
-				&& newArea != null && !newArea.isNull()
-				&& !Double.isNaN(newArea.getMinX())
-				&& !Double.isNaN(newArea.getMaxX())
-				&& !Double.isNaN(newArea.getMinY())
-				&& !Double.isNaN(newArea.getMaxY())) {
-			/*
-			 * If a maxExtend is set, we have to honour that...
-			 */
-
-			// Exceeds top? Move down and maybe cut
-			if (newArea.getMaxY() > maxAllowedExtend.getMaxY()) {
-				double divY = newArea.getMaxY() - maxAllowedExtend.getMaxY();
-				// LOGGER.debug("Moving area down by " + divY);
-
-				newArea = new Envelope(new Coordinate(newArea.getMinX(),
-						newArea.getMinY() - divY), new Coordinate(newArea
-						.getMaxX(), newArea.getMaxY() - divY));
-
-				if (newArea.getMinY() < maxAllowedExtend.getMinY()) {
-					// LOGGER.debug("Now it exeeds the bottom border.. cut!");
-					// And cut the bottom if it moved out of the area
-					newArea = new Envelope(new Coordinate(newArea.getMinX(),
-							maxAllowedExtend.getMinY()), new Coordinate(newArea
-							.getMaxX(), newArea.getMaxY()));
-
-					// LOGGER.debug("and fix aspect ratio");
-
-					newArea = JTSUtil.fixAspectRatio(this.getBounds(), newArea,
-							false);
-				}
-			}
-
-			// Exceeds bottom? Move up and maybe cut
-			if (newArea.getMinY() < maxAllowedExtend.getMinY()) {
-				double divY = newArea.getMinY() - maxAllowedExtend.getMinY();
-				// LOGGER.debug("Moving area up by " + divY);
-
-				newArea = new Envelope(new Coordinate(newArea.getMinX(),
-						newArea.getMinY() - divY), new Coordinate(newArea
-						.getMaxX(), newArea.getMaxY() - divY));
-
-				if (newArea.getMaxY() > maxAllowedExtend.getMaxY()) {
-					// LOGGER.debug("Now it exeeds the top border.. cut!");
-					// And cut the bottom if it moved out of the area
-					newArea = new Envelope(new Coordinate(newArea.getMinX(),
-							newArea.getMinY()), new Coordinate(newArea
-							.getMaxX(), maxAllowedExtend.getMaxY()));
-
-					// LOGGER.debug("and fix aspect ratio");
-
-					newArea = JTSUtil.fixAspectRatio(this.getBounds(), newArea,
-							false);
-				}
-			}
-
-			// Exceeds to the right? move and maybe cut
-			if (newArea.getMaxX() > maxAllowedExtend.getMaxX()) {
-
-				// Move left..
-				double divX = newArea.getMaxX() - maxAllowedExtend.getMaxX();
-				// LOGGER.debug("Moving area left by " + divX);
-
-				newArea = new Envelope(new Coordinate(newArea.getMinX() - divX,
-						newArea.getMinY()), new Coordinate(newArea.getMaxX()
-						- divX, newArea.getMaxY()));
-
-				if (newArea.getMinX() < maxAllowedExtend.getMinX()) {
-					// LOGGER.debug("Now it exeeds the left border.. cut!");
-					// And cut the left if it moved out of the area
-					newArea = new Envelope(new Coordinate(maxAllowedExtend
-							.getMinX(), newArea.getMinY()), new Coordinate(
-							newArea.getMaxX(), newArea.getMaxY()));
-
-					// LOGGER.debug("and fix aspect ratio");
-
-					newArea = JTSUtil.fixAspectRatio(this.getBounds(), newArea,
-							false);
-				}
-			}
-
-			// Exceeds to the left? move and maybe cut
-			if (newArea.getMinX() < maxAllowedExtend.getMinX()) {
-
-				// Move right..
-				double divX = newArea.getMinX() - maxAllowedExtend.getMinX();
-				// LOGGER.debug("Moving area right by " + divX);
-
-				newArea = new Envelope(new Coordinate(newArea.getMinX() - divX,
-						newArea.getMinY()), new Coordinate(newArea.getMaxX()
-						- divX, newArea.getMaxY()));
-
-				if (newArea.getMaxX() > maxAllowedExtend.getMaxX()) {
-					// LOGGER.debug("Now it exeeds the right border.. cut!");
-					// And cut the left if it moved out of the area
-					newArea = new Envelope(new Coordinate(newArea.getMinX(),
-							newArea.getMinY()), new Coordinate(maxAllowedExtend
-							.getMaxX(), newArea.getMaxY()));
-
-					// LOGGER.debug("and fix aspect ratio");
-
-					newArea = JTSUtil.fixAspectRatio(this.getBounds(), newArea,
-							false);
-				}
-			}
-
-		}
-
-		return newArea;
-	}
-
-	/**
-	 * Retuns the minimum allowed zoom scale. This is the bigger number value of
-	 * the two. Defaults to {@link Double}.MAX_VALUE
-	 * 
-	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
-	 *         Kr&uuml;ger</a>
-	 */
-	public Double getMinZoomScale() {
-		return minZoomScale;
-	}
-
-	/**
-	 * Retuns the maximum allowed zoom scale. This is the smaller number value
-	 * of the two. Defaults to {@link Double}.MIN_VALUE
-	 * 
-	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
-	 *         Kr&uuml;ger</a>
-	 */
-	public Double getMaxZoomScale() {
-		return maxZoomScale;
-	}
-
-	/**
-	 * Set the maximum allowed zoom scale. This is the smaller number value of
-	 * the two. If <code>null</code> is passed, Double.MINVALUE are used which
-	 * mean there is no restriction.
-	 * 
-	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
-	 *         Kr&uuml;ger</a>
-	 */
-	public void setMaxZoomScale(final Double maxZoomScale) {
-		this.maxZoomScale = maxZoomScale == null ? Double.MIN_VALUE
-				: maxZoomScale;
-	}
-
-	/**
-	 * Set the minimum (nearest) allowed zoom scale. This is the bigger number
-	 * value of the two. If <code>null</code> is passed, Double.MAXVALUE are
-	 * used which mean there is no restriction.
-	 * 
-	 * 
-	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
-	 *         Kr&uuml;ger</a>
-	 */
-	public void setMinZoomScale(final Double minZoomScale) {
-		this.minZoomScale = minZoomScale == null ? Double.MAX_VALUE
-				: minZoomScale;
-	}
-
-	/**
-	 * Defines an evelope of the viwable area. The JMapPane will never show
-	 * anything outside of this extend.
-	 * 
-	 * @param maxExtend
-	 *            <code>null</code> to not have this restriction.
-	 */
-	public void setMaxExtend(Envelope maxExtend) {
-		this.maxExtend = maxExtend;
-	}
-
-	/**
-	 * Returns the evelope of the viewable area. The JMapPane will never show
-	 * anything outside of this extend. If this has been set to
-	 * <code>null</code> via {@link #setMaxExtend(Envelope)}, it tries to return
-	 * quickly the context's bounds. It it takes to long to determine the
-	 * context bounds, <code>null</code> is returned.
-	 * 
-	 * @param maxExtend
-	 *            <code>null</code> to not have this restriction.
-	 */
-
-	public Envelope getMaxExtend() {
-		if (maxExtend == null) {
-			try {
-				return JTSUtil.fixAspectRatio(this.getBounds(),
-						// Kartenbereich um 10% vergroessern
-						JTSUtil.expandEnvelope(context.getLayerBounds(), 0.1),
-						true);
-			} catch (IOException e) {
-				LOGGER
-						.warn(
-								"maxExtend == null; failed to getLayerBounds of context",
-								e);
-			}
-		}
-		return maxExtend;
-	}
-
-	/**
-	 * Set the background color of the map. 
-	 * @param if <code>null</code>, white is used.
-	 */
-	public void setMapBackgroundColor(Color bgColor) {
-		if (bgColor == null) bgColor = Color.WHITE;
-		this.mapBackgroundColor = bgColor;
-	}
-
-	/**
-	 * Returns the background {@link Color} of the map pane. Default is white.
-	**/
-	public Color getMapBackgroundColor() {
-		return mapBackgroundColor;
-	}
-
-}

Copied: branches/1.0-gt2-2.6/src/gtmig/org/geotools/swing/XMapPane.java (from rev 506, branches/1.0-gt2-2.6/src/gtmig/org/geotools/swing/JMapPane.java)
===================================================================
--- branches/1.0-gt2-2.6/src/gtmig/org/geotools/swing/JMapPane.java	2009-10-31 12:15:37 UTC (rev 506)
+++ branches/1.0-gt2-2.6/src/gtmig/org/geotools/swing/XMapPane.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -0,0 +1,2245 @@
+/*
+ *    GeoTools - OpenSource mapping toolkit
+ *    http://geotools.org
+ *    (C) 2002-2006, GeoTools Project Managment Committee (PMC)
+ *
+ *    This library is free software; you can redistribute it and/or
+ *    modify it under the terms of the GNU Lesser General Public
+ *    License as published by the Free Software Foundation;
+ *    version 2.1 of the License.
+ *
+ *    This library 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
+ *    Lesser General Public License for more details.
+ */
+package gtmig.org.geotools.swing;
+
+/**
+ * This class is 50% copied from GeoTools 2.6.x JMapPane. GeoTools is LGPL, SCHMITZM also.<br/>
+ * In addition to 
+ */
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.Cursor;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.geom.Point2D;
+import java.awt.image.BufferedImage;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.Timer;
+
+import org.apache.log4j.Logger;
+import org.geotools.feature.FeatureCollection;
+import org.geotools.geometry.jts.JTS;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.map.DefaultMapContext;
+import org.geotools.map.MapContext;
+import org.geotools.map.MapLayer;
+import org.geotools.map.event.MapLayerEvent;
+import org.geotools.map.event.MapLayerListEvent;
+import org.geotools.map.event.MapLayerListListener;
+import org.geotools.map.event.MapLayerListener;
+import org.geotools.referencing.CRS;
+import org.geotools.renderer.GTRenderer;
+import org.geotools.renderer.label.LabelCacheImpl;
+import org.geotools.renderer.lite.LabelCache;
+import org.geotools.swing.JMapPane;
+import org.geotools.swing.event.MapMouseEvent;
+import org.geotools.swing.event.MapPaneEvent;
+import org.geotools.swing.event.MapPaneListener;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.TransformException;
+
+import schmitzm.geotools.GTUtil;
+import schmitzm.geotools.JTSUtil;
+import schmitzm.geotools.gui.SelectableXMapPane;
+import schmitzm.geotools.map.event.JMapPaneListener;
+import schmitzm.geotools.map.event.MapLayerAdapter;
+import schmitzm.swing.SwingUtil;
+import skrueger.geotools.RenderingExecutor;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.geom.Geometry;
+
+public class XMapPane extends JPanel implements PropertyChangeListener {
+	private static Logger LOGGER = Logger.getLogger(XMapPane.class);
+
+	/**
+	 * Sets whether a layer is regarded or ignored on {@link #SELECT_TOP},
+	 * {@link #SELECT_ALL} and {@link #SELECT_ONE_FROM_TOP} actions.
+	 * 
+	 * @param layer
+	 *            a layer
+	 * @param selectable
+	 *            if {@code false} the layer is ignored during the upper
+	 *            mentioned actions. If <code>null</code>, the default (true)
+	 *            will be used.
+	 */
+	public void setMapLayerSelectable(MapLayer layer, Boolean selectable) {
+		if (selectable == null)
+			mapLayerSelectable.remove(layer);
+		else
+			mapLayerSelectable.put(layer, selectable);
+	}
+
+	/**
+	 * Holds a flag for each layer, whether it is regarded or ignored on
+	 * {@link #SELECT_TOP}, {@link #SELECT_ALL} and {@link #SELECT_ONE_FROM_TOP}
+	 * actions.
+	 */
+	final protected HashMap<MapLayer, Boolean> mapLayerSelectable = new HashMap<MapLayer, Boolean>();
+
+	/**
+	 * Returns whether a layer is regarded or ignored on {@link #SELECT_TOP},
+	 * {@link #SELECT_ALL} and {@link #SELECT_ONE_FROM_TOP} actions. Returns
+	 * <code>true</code> if the selectability has not been defined.
+	 * 
+	 * @param layer
+	 *            a layer
+	 */
+	public boolean isMapLayerSelectable(MapLayer layer) {
+		Boolean selectable = mapLayerSelectable.get(layer);
+		return selectable == null ? true : selectable;
+	}
+
+	/**
+	 * Flag fuer Modus "Kartenausschnitt bewegen". Nicht fuer Window-Auswahl
+	 * moeglich!
+	 * 
+	 * @see #setState(int)
+	 */
+	public static final int PAN = 1;
+	/**
+	 * Flag fuer Modus "Heran zoomen".
+	 * 
+	 * @see #setState(int)
+	 * @see #setState(int)
+	 */
+	public static final int ZOOM_IN = 2;
+	/**
+	 * Flag fuer Modus "Heraus zoomen". Nicht fuer Window-Auswahl moeglich!
+	 * 
+	 * @see #setState(int)
+	 */
+	public static final int ZOOM_OUT = 3;
+	/**
+	 * Flag fuer Modus
+	 * "SimpleFeature-Auswahl auf dem obersten (sichtbaren) Layer".
+	 * 
+	 * @see #setState(int)
+	 * @see #setState(int)
+	 */
+	public static final int SELECT_TOP = 4;
+	/**
+	 * Flag fuer Modus "SimpleFeature-Auswahl auf allen (sichtbaren) Layern".
+	 * 
+	 * @see #setState(int)
+	 * @see #setState(int)
+	 */
+	public static final int SELECT_ALL = 103;
+	/**
+	 * Flag fuer Modus
+	 * "Auswahl nur eines Features, das erste sichtbare von Oben".
+	 * 
+	 * @see #setState(int)
+	 * @see #setState(int)
+	 */
+	public static final int SELECT_ONE_FROM_TOP = 104;
+
+	public static final long DEFAULT_REPAINTING_DELAY = 200;
+
+	protected skrueger.geotools.RenderingExecutor bgExecuter;
+
+	/**
+	 * the map context to render
+	 */
+	MapContext localContext;
+	/**
+	 * the map context to render
+	 */
+	MapContext bgContext;
+
+	/**
+	 * the area of the map to draw
+	 */
+	protected Envelope mapArea = null;
+	/**
+	 * We store the old mapArea for a moment to use it for the
+	 * "quick scaled preview" in case of ZoomOut
+	 **/
+	protected Envelope oldMapArea = null;
+
+	/**
+	 * the size of the pane last time we drew
+	 */
+	protected Rectangle oldRect = null;
+
+	/**
+	 * The Renderer for the Background uses this Image. When set to null, please
+	 * dispose the {@link Graphics2D}
+	 */
+	protected BufferedImage bgImage;
+
+	/**
+	 * The Renderer for the LocalLayers uses this Image. When set to null,
+	 * please dispose this {@link Graphics2D}
+	 */
+	volatile protected BufferedImage localImage;
+
+	/**
+	 * compass and icon are rendered into this image
+	 */
+//	protected BufferedImage gadgetsImage;
+
+	/**
+	 * The default state is ZOOM_IN, hence by default the
+	 * {@link #zoomMapPaneMouseListener} is also enabled.
+	 **/
+	private int state = ZOOM_IN;
+
+	/**
+	 * Konvertiert die Maus-Koordinaten (relativ zum <code>JMapPane</code>) in
+	 * Karten-Koordinaten.
+	 * 
+	 * @param e
+	 *            Maus-Ereignis
+	 */
+	public static Point2D getMapCoordinatesFromEvent(MouseEvent e) {
+		// aktuelle Geo-Position aus GeoMouseEvent ermitteln
+		if (e != null && e instanceof MapMouseEvent)
+			try {
+				return ((MapMouseEvent) e).getMapPosition().toPoint2D();
+			} catch (Exception err) {
+				LOGGER
+						.error(
+								"return ((GeoMouseEvent) e).getMapCoordinate(null).toPoint2D();",
+								err);
+			}
+
+		// aktuelle Geo-Position ueber Transformation des JMapPane berechnen
+		if (e != null && e.getSource() instanceof XMapPane) {
+			
+			final XMapPane xMapPane = (XMapPane) e.getSource();
+			
+			if (!xMapPane.isWellDefined()) return null;
+			
+			AffineTransform at = xMapPane.getScreenToWorld();
+			if (at != null)
+				return at.transform(e.getPoint(), null);
+			return null;
+		}
+		throw new IllegalArgumentException(
+				"MouseEvent has to be of instance MapMouseEvent or come from an XMapPane");
+	}
+
+	/**
+	 * A flag indicating that the shown image is invalid and needs to be
+	 * re-rendered.
+	 */
+	protected boolean mapImageInvalid = true;
+
+	protected LabelCache labelCache = new LabelCacheImpl();
+
+	/**
+	 * If not <code>null</code>, the {@link XMapPane} will not allow to zoom/pan
+	 * out of that area
+	 **/
+	private Envelope maxExtend = null;
+
+	private Double maxZoomScale = Double.MIN_VALUE;
+	private Double minZoomScale = Double.MAX_VALUE;
+
+	/**
+	 * This color is used as the default background color when painting a map.
+	 */
+	private Color mapBackgroundColor = Color.WHITE;
+
+	/**
+	 * This {@link MouseListener} is managing all zoom related tasks
+	 */
+	public final ZoomXMapPaneMouseListener zoomMapPaneMouseListener = new ZoomXMapPaneMouseListener(
+			this);
+
+	/**
+	 * A flag indicating, that the image size has changed and the buffered
+	 * images are not big enough any more
+	 **/
+	protected boolean paneResized = false;
+
+	/**
+	 * While threads are working, we call {@link XMapPane#updateFinalImage()}
+	 * regularly and repaint(). This {@link Timer} is stoppen when all renderers
+	 * finished.
+	 */
+	final private Timer repainterTimer;
+
+	/**
+	 * The flag {@link #requestStartRendering} can be set to true by events.
+	 * This {@link Timer} checks the flag regularly and starts one renderer
+	 * thread.
+	 */
+	final private Timer startRenderThreadsTimer;
+
+	private Map<Object, Object> rendererHints;
+
+	public Map<Object, Object> getRendererHints() {
+		return rendererHints;
+	}
+
+	/**
+	 * Nuetzlich wenn die Componente gedruckt (z.B. wenn ein Screenshot gemacht
+	 * wird) wird. Dann werden wird der Hintergrund auf WEISS gesetzt.
+	 * 
+	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
+	 *         Kr&uuml;ger</a>
+	 */
+	@Override
+	public void print(Graphics g) {
+		Color orig = getBackground();
+		setBackground(Color.WHITE);
+
+		// wrap in try/finally so that we always restore the state
+		try {
+			super.print(g);
+		} finally {
+			setBackground(orig);
+		}
+	}
+
+	/**
+	 * full constructor extending JPanel
+	 * 
+	 * @param rendererHints
+	 * 
+	 * @param layout
+	 *            - layout (probably shouldn't be set)
+	 * @param isDoubleBuffered
+	 *            - a Swing thing I don't really understand
+	 * @param render
+	 *            - what to draw the map with
+	 * @param localContext
+	 *            - {@link MapContext} of layer to render.
+	 */
+	public XMapPane(final MapContext localContext,
+			Map<Object, Object> rendererHints) {
+		super(true);
+
+		setRendererHints(rendererHints);
+
+		setOpaque(true);
+
+		setLocalContext(localContext);
+
+		/**
+		 * Adding the #zoomMapPaneMouseListener
+		 */
+		this.addMouseListener(zoomMapPaneMouseListener);
+		this.addMouseMotionListener(zoomMapPaneMouseListener);
+		this.addMouseWheelListener(zoomMapPaneMouseListener);
+
+		/*
+		 * We use a Timer object to avoid rendering delays and flickering when
+		 * the user is drag-resizing the parent container of this map pane.
+		 * 
+		 * Using a ComponentListener doesn't work because, unlike a JFrame, the
+		 * pane receives a stream of events during drag-resizing.
+		 */
+		resizingPaintDelay = DEFAULT_RESIZING_PAINT_DELAY;
+		resizeTimer = new Timer(resizingPaintDelay, new ActionListener() {
+
+			public void actionPerformed(ActionEvent e) {
+				paneResized = true;
+
+				if (!isWellDefined())
+					return;
+
+				Rectangle bounds = getVisibleRect();
+
+				Envelope geoMapArea = tranformWindowToGeo(bounds.x, bounds.y,
+						bounds.x + bounds.width, bounds.y + bounds.height);
+
+				setMapArea(bestAllowedMapArea(geoMapArea));
+			}
+		});
+		resizeTimer.setRepeats(false);
+		this.addComponentListener(new ComponentAdapter() {
+
+			@Override
+			public void componentResized(ComponentEvent e) {
+				if (bgExecuter != null)
+					bgExecuter.cancelTask();
+				if (localExecuter != null)
+					localExecuter.cancelTask();
+				resizeTimer.restart();
+			}
+
+		});
+
+		repainterTimer = new Timer((int) DEFAULT_REPAINTING_DELAY,
+				new ActionListener() {
+
+					@Override
+					public void actionPerformed(ActionEvent e) {
+						updateFinalImage();
+						XMapPane.this.repaint(DEFAULT_REPAINTING_DELAY);
+					}
+				});
+		repainterTimer.setInitialDelay(1000);
+		repainterTimer.setRepeats(true);
+
+		startRenderThreadsTimer = new Timer(200, new ActionListener() {
+
+			@Override
+			public void actionPerformed(ActionEvent e) {
+				synchronized (requestStartRendering) {
+					if (requestStartRendering && isValid())
+						startRendering();
+					requestStartRendering = false;
+				}
+			}
+		});
+		startRenderThreadsTimer.start();
+
+	}
+
+	// TODO doku
+	public XMapPane() {
+		this(null, null);
+	}
+
+	/**
+	 * Sets the mapArea to best possibly present the given features. If only one
+	 * single point is given, the window is moved over the point.
+	 * 
+	 * Note: The method does not call {@link #repaint()} on the
+	 * {@link SelectableXMapPane} .
+	 * 
+	 * @param features
+	 *            if <code>null</code> or size==0, the function doesn nothing.
+	 */
+	public void zoomTo(
+			FeatureCollection<SimpleFeatureType, SimpleFeature> features) {
+
+		CoordinateReferenceSystem mapCRS = getContext()
+				.getCoordinateReferenceSystem();
+		CoordinateReferenceSystem fCRS = features.getSchema()
+				.getGeometryDescriptor().getCoordinateReferenceSystem();
+
+		double width = mapArea.getWidth();
+		double height = mapArea.getHeight();
+		double ratio = height / width;
+
+		if (features == null || features.size() == 0) {
+			// feature count == 0 Zoom to the full extend
+			return;
+		} else if (features.size() == 1) {
+
+			// feature count == 1 Just move the window to the point and zoom 'a
+			// bit'
+			SimpleFeature singleFeature = (SimpleFeature) features.iterator()
+					.next();
+
+			if (((Geometry) singleFeature.getDefaultGeometry())
+					.getCoordinates().length > 1) {
+				// System.out.println("Zoomed to only pne poylgon");
+				// Poly
+				// TODO max width vs. height
+				width = features.getBounds().getWidth() * 3;
+				height = ratio * width;
+			} else {
+				// System.out.println("Zoomed in a bit becasue only one point");
+				// width *= .9;
+				// height *= .9;
+			}
+
+			Coordinate centre = features.getBounds().centre();
+			if (!mapCRS.equals(fCRS)) {
+				// only to calculations if the CRS differ
+				try {
+					MathTransform fToMap;
+					fToMap = CRS.findMathTransform(fCRS, mapCRS);
+					// centre is transformed to the mapCRS
+					centre = JTS.transform(centre, null, fToMap);
+				} catch (FactoryException e) {
+					LOGGER.error("Looking for a Math transform", e);
+				} catch (TransformException e) {
+					LOGGER.error("Looking for a Math transform", e);
+				}
+			}
+
+			Coordinate newLeftBottom = new Coordinate(centre.x - width / 2.,
+					centre.y - height / 2.);
+			Coordinate newTopRight = new Coordinate(centre.x + width / 2.,
+					centre.y + height / 2.);
+
+			Envelope newMapArea = new Envelope(newLeftBottom, newTopRight);
+
+			setMapArea(newMapArea);
+
+		} else {
+			ReferencedEnvelope fBounds = features.getBounds();
+
+			Envelope bounds;
+			if (!mapCRS.equals(fCRS)) {
+				bounds = JTSUtil.transformEnvelope(fBounds, fCRS, mapCRS);
+			} else {
+				bounds = fBounds;
+			}
+			// BB umrechnen von Layer-CRS in Map-CRS
+
+			// Expand a bit
+			bounds.expandBy(bounds.getWidth() / 6., bounds.getHeight() / 6.);
+
+			setMapArea(bounds);
+		}
+	}
+
+	private void setRendererHints(Map<Object, Object> rendererHints) {
+		this.rendererHints = rendererHints;
+	}
+
+	/**
+	 * Return <code>true</code> if a CRS and a {@link #mapArea} are set and the
+	 * {@link XMapPane} is visible and has bounds set.
+	 */
+	public boolean isWellDefined() {
+		
+		try {
+			
+		if (getContext() == null)
+			return false;
+		if (getContext().getLayerCount() <= 0)
+			return false;
+		if (getMapArea() == null)
+			return false;
+		if (getBounds().getWidth() == 0)
+			return false;
+		if (getBounds().getHeight() == 0)
+			return false;
+		} catch (Exception e) {
+			return false;
+		}
+		return true;
+	}
+
+	/**
+	 * Default delay (milliseconds) before the map will be redrawn when resizing
+	 * the pane. This is to avoid flickering while drag-resizing.
+	 */
+	public static final int DEFAULT_RESIZING_PAINT_DELAY = 500; // delay in
+	// milliseconds
+
+	private Timer resizeTimer;
+	private int resizingPaintDelay;
+	/**
+	 * We store the old transform for a moment to use it for the
+	 * "quick scaled preview" in case of ZoomIn
+	 **/
+	protected AffineTransform oldScreenToWorld = null;
+
+	/**
+	 * Manuell gesetzter statischer Cursor, unabhaengig von der aktuellen
+	 * MapPane-Funktion
+	 */
+	protected Cursor staticCursor = null;
+
+	/**
+	 * Standardmaessig wird der Cursor automatisch je nach MapPane-Aktion (Zoom,
+	 * Auswahl, ...) gesetzt. Mit dieser Methode kann ein statischer Cursor
+	 * gesetzt werden, der unabhaengig von der aktuellen MapPanes-Aktion
+	 * beibehalten wird. Um diesen statischen Cursor wieder zu entfernen, kann
+	 * {@code null} als Parameter uebergeben werden
+	 * 
+	 * @param cursor
+	 *            Cursor
+	 */
+	public void setStaticCursor(Cursor cursor) {
+		this.staticCursor = cursor;
+		if (cursor != null)
+			super.setCursor(cursor);
+	}
+
+	/**
+	 * Liefert den statisch eingestellten Cursor, der unabhaengig von der
+	 * eingestellten MapPane-Aktion (Zoom, Auswahl, ...) verwendet wird.
+	 * 
+	 * @return {@code null}, wenn kein statischer Cursor verwendet, sondern der
+	 *         Cursor automatisch je nach MapPane-Aktion eingestellt wird.
+	 */
+	public Cursor getStaticCursor() {
+		return this.staticCursor;
+	}
+
+	/**
+	 * Abhaengig von selState wird der Cursor gesetzt
+	 */
+	public void updateCursorAndRepaintTimer() {
+
+		if (bgExecuter != null && bgExecuter.isRunning()
+				|| localExecuter != null && localExecuter.isRunning()) {
+			setCursor(WAIT_CURSOR);
+			return;
+		} else {
+			// Allow one last rendering
+			if (repainterTimer.isRunning()) {
+				repainterTimer.stop();
+				updateFinalImage();
+				repaint();
+			}
+		}
+
+		// wenn manueller Cursor gesetzt ist, dann diesen verwenden (unabhaengig
+		// von der aktuellen Aktion
+		if (this.staticCursor != null) {
+			setCursor(staticCursor);
+			return;
+		}
+		if (getCursor() == SwingUtil.PANNING_CURSOR) {
+			// This cursor will reset itself
+			return;
+		}
+
+		// Je nach Aktion den Cursor umsetzen
+		switch (state) {
+		case SELECT_TOP:
+		case SELECT_ONE_FROM_TOP:
+		case SELECT_ALL:
+			setCursor(SwingUtil.CROSSHAIR_CURSOR);
+			break;
+		case ZOOM_IN:
+			setCursor(SwingUtil.ZOOMIN_CURSOR);
+			break;
+		case ZOOM_OUT:
+			setCursor(SwingUtil.ZOOMOUT_CURSOR);
+			break;
+		case PAN:
+			setCursor(SwingUtil.PAN_CURSOR);
+			break;
+		default:
+			setCursor(normalCursor);
+			break;
+		}
+	}
+
+	//
+	// /**
+	// * Gibt den "normalen" Cursor zurueck. Dieser kann neben dem "pointer"
+	// auch
+	// * ein Sanduhr-Wartecursor sein.
+	// *
+	// * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
+	// * Kr&uuml;ger</a>
+	// */
+	// public Cursor getNormalCursor() {
+	// return normalCursor;
+	// }
+	//
+	// /**
+	// * Setzt den "normalen" Cursor. Dieser kann neben dem default "pointer"
+	// z.B.
+	// * auch ein Sanduhr-Wartecursor sein.
+	// *
+	// * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
+	// * Kr&uuml;ger</a>
+	// */
+	// public void setNormalCursor(Cursor normalCursor) {
+	// this.normalCursor = normalCursor;
+	// }
+
+	/**
+	 * Berechnet die Transformation zwischen Fenster- und Karten-Koordinaten
+	 * neu.
+	 */
+	protected void resetTransforms() {
+		if (getMapArea() == null || getWidth() == 0 || getHeight() == 0)
+			return;
+
+		// We store the last Transform
+		oldScreenToWorld = screenToWorld;
+
+		this.screenToWorld = new AffineTransform(
+		// Genauso wie die Fenster-Koordinaten, werden die Longitude-Koordinaten
+				// nach rechts (Osten) hin groesser
+				// --> positive Verschiebung
+				getMapArea().getWidth() / getWidth(),
+				// keine Verzerrung
+				0.0, 0.0,
+				// Waehrend die Fenster-Koordinaten nach unten hin groesser
+				// werden,
+				// werden Latitude-Koordinaten nach Sueden hin keiner
+				// --> negative Verschiebung
+				-getMapArea().getHeight() / getHeight(),
+				// Die Longitude-Koordinaten werden nach Osten hin groesser
+				// --> obere linke Ecke des Fensters hat also den Minimalwert
+				getMapArea().getMinX(),
+				// Die Latitude-Koordinaten werden nach Norden hin groesser
+				// --> obere linke Ecke des Fensters hat also den Maximalwert
+				getMapArea().getMaxY());
+
+		try {
+			this.worldToScreen = screenToWorld.createInverse();
+		} catch (NoninvertibleTransformException e) {
+			LOGGER.error(e);
+		}
+	}
+
+	/**
+	 * Transformation zwischen Fenster-Koordinaten und Karten-Koordinaten
+	 * (lat/lon)
+	 */
+	protected AffineTransform screenToWorld = null;
+
+	private AffineTransform worldToScreen;
+
+	/**
+	 * Listens to changes of the "local" {@link MapContext} and triggers
+	 * repaints where needed.
+	 */
+	private MapLayerListListener localContextListener = new MapLayerListListener() {
+
+		@Override
+		public void layerAdded(final MapLayerListEvent event) {
+			event.getLayer().addMapLayerListener(localMapLayerListener);
+
+			if (localContext.getLayers().length == 1) { // the first one
+				// if the Area of Interest is unset, the LayerBounds are used
+				if (!setMapArea(localContext.getAreaOfInterest()))
+					repaint();
+
+				return;
+			}
+
+			// We need to redraw, even in case that the mapArea didn't change
+			// mapImageInvalid = true;
+			// repaint();
+			requestStartRendering();
+
+		}
+
+		@Override
+		public void layerRemoved(final MapLayerListEvent event) {
+			if (event.getLayer() != null)
+				event.getLayer().removeMapLayerListener(localMapLayerListener);
+			// mapImageInvalid = true;
+			// repaint();
+			requestStartRendering();
+		}
+
+		@Override
+		public void layerChanged(final MapLayerListEvent event) {
+			// mapImageInvalid = true;
+			// repaint();
+			requestStartRendering();
+		}
+
+		@Override
+		public void layerMoved(final MapLayerListEvent event) {
+			// mapImageInvalid = true;
+			// repaint();
+			requestStartRendering();
+		}
+	};
+
+	/**
+	 * Listens to changes of the "background" {@link MapContext} and triggers
+	 * repaints where needed.
+	 */
+	private MapLayerListListener bgContextListener = new MapLayerListListener() {
+
+		@Override
+		public void layerAdded(final MapLayerListEvent event) {
+			event.getLayer().addMapLayerListener(bgMapLayerListener);
+
+			if (localContext.getLayers().length == 0
+					&& bgContext.getLayers().length == 1) { // the first one and
+				// localContext is
+				// empty
+				if (!setMapArea(localContext.getAreaOfInterest()))
+					requestStartRendering();
+				return;
+			}
+
+			// We need to redraw, even in case that the mapArea didn't change
+			// mapImageInvalid = true;
+			// repaint();
+			requestStartRendering();
+
+		}
+
+		@Override
+		public void layerRemoved(final MapLayerListEvent event) {
+			if (event.getLayer() != null)
+				event.getLayer().removeMapLayerListener(bgMapLayerListener);
+			// mapImageInvalid = true;
+			// repaint();
+			requestStartRendering();
+		}
+
+		@Override
+		public void layerChanged(final MapLayerListEvent event) {
+			// mapImageInvalid = true;
+			// repaint();
+			requestStartRendering();
+		}
+
+		@Override
+		public void layerMoved(final MapLayerListEvent event) {
+			// mapImageInvalid = true;
+			// repaint();
+			requestStartRendering();
+		}
+	};
+
+	/**
+	 * Listens to each layer in the local {@link MapContext} for changes and
+	 * triggers repaints.
+	 */
+	protected MapLayerListener localMapLayerListener = new MapLayerAdapter() {
+
+		@Override
+		public void layerShown(MapLayerEvent event) {
+			// mapImageInvalid = true;
+			// repaint();
+			requestStartRendering();
+		}
+
+		@Override
+		public void layerHidden(MapLayerEvent event) {
+			// mapImageInvalid = true;
+			// repaint();
+			requestStartRendering();
+		}
+
+		@Override
+		public void layerChanged(MapLayerEvent event) {
+			// Change of SLD for example
+			// mapImageInvalid = true;
+			// repaint();
+			requestStartRendering();
+		}
+	};
+
+	/**
+	 * Listens to each layer in the local {@link MapContext} for changes and
+	 * triggers repaints.
+	 */
+	protected MapLayerListener bgMapLayerListener = new MapLayerAdapter() {
+
+		@Override
+		public void layerShown(MapLayerEvent event) {
+			// mapImageInvalid = true;
+			// repaint();
+			requestStartRendering();
+		}
+
+		@Override
+		public void layerHidden(MapLayerEvent event) {
+			// mapImageInvalid = true;
+			// repaint();
+			requestStartRendering();
+		}
+
+		@Override
+		public void layerChanged(MapLayerEvent event) {
+			// Change of SLD for example
+			// mapImageInvalid = true;
+			// repaint();
+			requestStartRendering();
+		}
+	};
+
+	/**
+	 * Liefert eine affine Transformation, um von den Fenster-Koordinaten in die
+	 * Karten-Koordinaten (Lat/Lon) umzurechnen.
+	 * 
+	 * @return eine Kopie der aktuellen Transformation; <code>null</code> wenn
+	 *         noch keine Karte angezeigt wird
+	 */
+	public AffineTransform getScreenToWorld() {
+		if (screenToWorld == null)
+			resetTransforms();
+		// nur Kopie der Transformation zurueckgeben!
+		if (screenToWorld == null)
+			return null;
+		return new AffineTransform(screenToWorld);
+	}
+
+	public AffineTransform getWorldToScreenTransform() {
+		if (worldToScreen == null) {
+			resetTransforms();
+		}
+		// nur Kopie der Transformation zurueckgeben!
+		return new AffineTransform(worldToScreen);
+	}
+
+	public MapContext getContext() {
+		if (localContext == null) {
+			this.localContext = new DefaultMapContext();
+			this.localContext.addMapLayerListListener(localContextListener);
+		}
+		return localContext;
+	}
+
+	public MapContext getBgContext() {
+		return bgContext;
+	}
+
+	/**
+	 * 
+	 * @param context
+	 */
+	public void setLocalContext(final MapContext context) {
+		// Remove the default listener from the old context
+		if (this.localContext != null) {
+			this.localContext.removeMapLayerListListener(localContextListener);
+
+			// adding listener to all layers
+			for (MapLayer mapLayer : localContext.getLayers()) {
+				mapLayer.removeMapLayerListener(localMapLayerListener);
+			}
+		}
+
+		this.localContext = context;
+
+		if (context != null) {
+			setMapArea(localContext.getAreaOfInterest());
+
+			this.localContext.addMapLayerListListener(localContextListener);
+
+			// adding listener to all layers
+			for (MapLayer mapLayer : localContext.getLayers()) {
+				mapLayer.addMapLayerListener(localMapLayerListener);
+			}
+		}
+
+		mapImageInvalid = true;
+		repaint();
+	}
+
+	public void setBgContext(final MapContext context) {
+
+		// Remove the default listener from the old context
+		if (this.bgContext != null) {
+			this.bgContext.removeMapLayerListListener(bgContextListener);
+
+			// adding listener to all layers
+			for (MapLayer mapLayer : bgContext.getLayers()) {
+				mapLayer.removeMapLayerListener(bgMapLayerListener);
+			}
+		}
+
+		this.bgContext = context;
+
+		if (context != null) {
+			setMapArea(bgContext.getAreaOfInterest());
+
+			this.bgContext.addMapLayerListListener(bgContextListener);
+
+			// adding listener to all layers
+			for (MapLayer mapLayer : bgContext.getLayers()) {
+				mapLayer.addMapLayerListener(bgMapLayerListener);
+			}
+		}
+		mapImageInvalid = true;
+		repaint();
+	}
+
+	/**
+	 * Returns a copy of the mapArea
+	 * 
+	 * @return
+	 */
+	public Envelope getMapArea() {
+		if (mapArea == null) {
+			final Rectangle paneBounds = getBounds();
+
+			try {
+				mapArea = localContext.getLayerBounds();
+			} catch (final IOException e) {
+				LOGGER.warn("context.getLayerBounds()", e);
+			}
+
+			if (mapArea != null) {
+				/* either the viewer size has changed or we've done a reset */
+				mapImageInvalid = true; /* note we need to redraw */
+				oldRect = paneBounds; /* store what the current size is */
+				mapArea = bestAllowedMapArea(mapArea);
+			}
+		}
+
+		if (mapArea == null)
+			return null;
+
+		return new Envelope(mapArea);
+	}
+
+	/**
+	 * @param newMapArea
+	 * @return <code>true</code> if the mapArea has been changed and a repaint
+	 *         has been triggered.
+	 */
+	public boolean setMapArea(final Envelope newMapArea) {
+
+		if (newMapArea == null
+				|| bestAllowedMapArea(newMapArea).equals(mapArea)) {
+			// No change.. no need to repaint
+			return false;
+		}
+
+		// Testen, ob der Unterschied nur im minimalen Rundungsfehlerbereich
+		// liegt
+		if (mapArea != null) {
+			Envelope candNew = bestAllowedMapArea(newMapArea);
+			double tolX = mapArea.getWidth() / 1000.;
+			double tolY = mapArea.getHeight() / 1000.;
+			if ((candNew.getMinX() - tolX < mapArea.getMinX())
+					&& (mapArea.getMinX() < candNew.getMinX() + tolX)
+					&& (candNew.getMaxX() - tolX < mapArea.getMaxX())
+					&& (mapArea.getMaxX() < candNew.getMaxX() + tolX)
+
+					&& (candNew.getMinY() - tolY < mapArea.getMinY())
+					&& (mapArea.getMinY() < candNew.getMinY() + tolY)
+					&& (candNew.getMaxY() - tolY < mapArea.getMaxY())
+					&& (mapArea.getMaxY() < candNew.getMaxY() + tolY)
+
+			) {
+				// The two mapAreas only differ my 1/1000th.. ignore
+
+				return false;
+			}
+		}
+
+		oldMapArea = mapArea;
+
+		System.out.println("requested setting to \\t" + newMapArea);
+		this.mapArea = bestAllowedMapArea(newMapArea);
+		System.out.println("set to \\t\\ŧ" + newMapArea);
+
+		if (localContext != null) {
+			localContext.setAreaOfInterest(mapArea, localContext
+					.getCoordinateReferenceSystem());
+		}
+		if (bgContext != null) {
+			bgContext.setAreaOfInterest(mapArea, localContext
+					.getCoordinateReferenceSystem());
+		}
+		resetTransforms();
+		mapImageInvalid = true;
+		mapAreaChanged = true;
+		repaint();
+		return true;
+	}
+
+	public int getState() {
+		return state;
+	}
+
+	/**
+	 * Enables/Disables the ZOOM Mouse Listener. Upates the Cursor and stops the
+	 * repaint Timer if
+	 * 
+	 * @param state
+	 */
+	public void setState(final int state) {
+		this.state = state;
+
+		zoomMapPaneMouseListener.setEnabled((state == ZOOM_IN
+				|| state == ZOOM_OUT || state == PAN));
+
+		// Je nach Aktion den Cursor umsetzen
+		updateCursorAndRepaintTimer();
+	}
+
+	/** Cursor wenn kein Mausbutton gedrueckt wird. default oder SwingUtil.PAN **/
+	protected static Cursor normalCursor = Cursor
+			.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
+
+	public static final Cursor WAIT_CURSOR = Cursor
+			.getPredefinedCursor(Cursor.WAIT_CURSOR);
+
+	public static final int NONE = -123;
+
+	private RenderingExecutor localExecuter;
+
+	private BufferedImage finalImage;
+
+	/**
+	 * A flag set it {@link #setMapArea(Envelope)} to indicated the
+	 * {@link #paintComponent(Graphics)} method, that the image on-screen is
+	 * associated with {@link #oldMapArea} and may hence be scaled for a quick
+	 * preview.<br/>
+	 * The flag is reset
+	 **/
+	private boolean mapAreaChanged = false;
+
+	private JFrame finalImageFrame;
+
+	private volatile Boolean requestStartRendering = false;
+	private BufferedImage preFinalImage;
+
+	protected void paintComponent(final Graphics g) {
+		// Maybe update the cursor
+		updateCursorAndRepaintTimer();
+
+		if (!acceptsRepaintCalls)
+			return;
+
+		boolean paintedSomething = false;
+
+		if (mapImageInvalid) { /* if the map changed then redraw */
+
+			mapImageInvalid = false; // Reset for next round
+
+			// If the new mapArea and the oldMapArea intersect, we can draw some
+			// quick scaled preview to make the user feel that something is
+			// happening.
+			if (mapAreaChanged && oldMapArea != null
+					&& getMapArea().intersects(oldMapArea)
+					& !getMapArea().equals(oldMapArea)) {
+
+				mapAreaChanged = false;
+
+				if (getMapArea().covers(oldMapArea)) {
+					setQuickPreviewHint(ZOOM_OUT);
+					paintedSomething = drawScaledPreviewImage_Zoom((Graphics2D) g);
+				} else if (oldMapArea.covers(getMapArea())) {
+					setQuickPreviewHint(ZOOM_IN);
+					paintedSomething = drawScaledPreviewImage_Zoom((Graphics2D) g);
+				}
+
+			}
+
+			if (paneResized) {
+				paneResized = false;
+				preFinalImage = null;
+				finalImage = null;
+				localImage = null;
+				bgImage = null;
+//				gadgetsImage = null;
+			}
+
+			// Start the Threads and Timers to render the image
+			requestStartRendering();
+
+		}
+
+		if (!paintedSomething) {
+
+			// TODO Should just paint the getFinalImage(). Update should be
+			// called by timer every 300ms, and the repaint() until all threads
+			// are done.
+			g.drawImage(getFinalImage(), 0, 0, this);
+
+			paintedSomething = true;
+		}
+
+	}
+
+	/**
+	 * Cancels all running renderers and sets the flag to start new ones. <br/>
+	 * 
+	 * @see #startRenderThreadsTimer
+	 */
+	private void requestStartRendering() {
+		if (bgExecuter != null)
+			bgExecuter.cancelTask();
+		if (localExecuter != null)
+			localExecuter.cancelTask();
+		requestStartRendering = true;
+	}
+
+	/**
+	 * Transformiert einen Fenster-Koordinaten-Bereich in Geo-Koordinaten.
+	 * 
+	 * @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
+	 */
+	public Envelope tranformWindowToGeo(int ox, int oy, int px, int py) {
+		AffineTransform at = getScreenToWorld();
+		Point2D geoO = at.transform(new Point2D.Double(ox, oy), null);
+		Point2D geoP = at.transform(new Point2D.Double(px, py), null);
+		return new Envelope(geoO.getX(), geoP.getX(), geoO.getY(), geoP.getY());
+	}
+
+	/**
+	 * Transformiert einen Geo-Koordinaten-Bereich in Fenster-Koordinaten.
+	 * 
+	 * @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 winToGeotransform
+	 *            Eine Window to Geo transform. If <code>null</code>,
+	 *            {@link #getScreenToWorld()} is used.
+	 */
+	public Envelope tranformGeoToWindow(double ox, double oy, double px,
+			double py, AffineTransform winToGeotransform) {
+		AffineTransform at = winToGeotransform == null ? getScreenToWorld()
+				: winToGeotransform;
+		Point2D geoO;
+		try {
+			geoO = at.inverseTransform(new Point2D.Double(ox, oy), null);
+			Point2D geoP = at
+					.inverseTransform(new Point2D.Double(px, py), null);
+			return new Envelope(geoO.getX(), geoP.getX(), geoO.getY(), geoP
+					.getY());
+		} catch (NoninvertibleTransformException e) {
+			LOGGER.error(e);
+			return new Envelope(ox, oy, px, py);
+		}
+	}
+
+	/**
+	 * Diretly paints scaled preview into the {@link SelectableXMapPane}. Used
+	 * to give the user something to look at while we are rendering. Method
+	 * should be called after {@link #setMapArea(Envelope)} has been set to the
+	 * new mapArea and transform has been reset.<br/>
+	 * This method does nothing if the {@link #lastRenderingDuration} is smaller
+	 * then a trashhold.
+	 * 
+	 * @param g
+	 *            Graphics2D to paint the preview into
+	 * 
+	 * @param state
+	 *            Max be {@link #ZOOM_IN} or {@link #ZOOM_OUT}
+	 */
+	protected boolean drawScaledPreviewImage_Zoom(Graphics2D graphics) {
+
+		if (quickPreviewHint == 0)
+			return false;
+
+		graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
+				RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
+		graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+				RenderingHints.VALUE_ANTIALIAS_OFF);
+		graphics.setRenderingHint(RenderingHints.KEY_RENDERING,
+				RenderingHints.VALUE_RENDER_SPEED);
+
+		if (oldMapArea == null)
+			return false;
+
+		Rectangle visibleArea = getVisibleRect();
+
+		// Calculate the oldMapArea in the current WindowCoordinates:
+		Envelope oldMapWindow = tranformGeoToWindow(oldMapArea.getMinX(),
+				oldMapArea.getMinY(), oldMapArea.getMaxX(), oldMapArea
+						.getMaxY(), null);
+
+		int xx1 = (int) Math.round(oldMapWindow.getMinX());
+		int yy1 = (int) Math.round(oldMapWindow.getMinY());
+		int xx2 = (int) Math.round(oldMapWindow.getMaxX());
+		int yy2 = (int) Math.round(oldMapWindow.getMaxY());
+
+		graphics.drawImage(getPreFinalImage(), xx1, yy1, xx2, yy2,
+				(int) visibleArea.getMinX(), (int) visibleArea.getMinY(),
+				(int) visibleArea.getMaxX(), (int) visibleArea.getMaxY(),
+				getMapBackgroundColor(), null);
+		
+
+		Rectangle painedArea = new Rectangle(xx1, yy1, xx2 - xx1, yy2 - yy1);
+
+		SwingUtil.clearAround(graphics, painedArea, visibleArea);
+		
+		addGadgets(graphics);
+//		graphics.drawImage(getGadgetsImage(), 0,0, (int) visibleArea.getMaxX(), (int) visibleArea.getMaxY(),null);
+
+		quickPreviewHint = 0;
+
+		graphics.dispose();
+		// Something has been drawn
+		return true;
+	}
+	
+	final static Font waitFont = new Font("Arial", Font.BOLD, 30);
+
+	/**
+	 * Paints some optinal stuff into the given {@link Graphics2D}. Usually called as the last paint on the mapImage.
+	 */
+	private void addGadgets(Graphics2D graphics) {
+
+		if (mapImage != null)
+			graphics.drawImage(mapImage,
+					getBounds().width - mapImage.getWidth() - 10,
+					getBounds().height - mapImage.getHeight() - 10, this);
+
+		// If still rendering, paint a gray shadow or so...
+		if (bgExecuter != null && bgExecuter.isRunning()
+				|| localExecuter != null && localExecuter.isRunning()) {
+			graphics.setColor(Color.BLACK);
+			
+			graphics.setFont(waitFont);
+			graphics.drawString("Wait...", 40, 70);
+		}
+		
+	}
+
+	/**
+	 * Accumulates all three images
+	 * 
+	 * @return
+	 */
+	synchronized protected BufferedImage updateFinalImage() {
+
+		final Graphics2D finalG = (Graphics2D) getFinalImage().getGraphics();
+		finalG.setBackground(getMapBackgroundColor());
+		
+		
+		// Render the two map images first, into the preFinalImage
+		{
+			final Graphics2D preFinalG = (Graphics2D) getPreFinalImage().getGraphics();
+			preFinalG.setBackground(getMapBackgroundColor());
+			
+			preFinalG.drawImage(getBgImage(), 0, 0,
+					getMapBackgroundColor(), null);
+			// // Draw the local layers image
+			preFinalG.drawImage(getLocalImage(), 0, 0, null);
+			preFinalG.dispose();
+		}
+		
+		finalG.drawImage(getPreFinalImage(), imageOrigin.x, imageOrigin.y,
+				getMapBackgroundColor(), null);
+
+		// System.out.println(new Date().getTime() - startTime +
+		// "ms for update");
+		//
+		// if (finalImageFrame == null) {
+		// finalImageFrame = new JFrame();
+		// finalImageFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+		// SwingUtil.setRelativeFramePosition(finalImageFrame, 0, 0);
+		// }
+		// finalImageFrame.setContentPane(new JLabel(new
+		// ImageIcon(finalImage)));
+		// finalImageFrame.pack();
+		// finalImageFrame.setVisible(true);
+
+		final int finalImageHeight = getFinalImage().getHeight(null);
+		final int finalImageWidth = getFinalImage().getWidth(null);
+
+		Rectangle painedArea = new Rectangle(imageOrigin.x, imageOrigin.y,
+				finalImageWidth, finalImageHeight);
+		SwingUtil.clearAround(finalG, painedArea, getVisibleRect());
+
+		addGadgets(finalG);
+//		finalG.drawImage(getGadgetsImage(), 0, 0, null);
+
+		finalG.dispose();
+
+		return finalImage;
+	}
+
+	/*
+	 * Set alpha composite. For example, pass in 1.0f to have 100% opacity pass
+	 * in 0.25f to have 25% opacity.
+	 */
+	private AlphaComposite makeComposite(float alpha) {
+		int type = AlphaComposite.SRC_OVER;
+		return (AlphaComposite.getInstance(type, alpha));
+	}
+
+	private Image getFinalImage() {
+
+		if (finalImage == null) {
+			finalImage = null;
+			Rectangle curPaintArea = getVisibleRect();
+			finalImage = new BufferedImage(curPaintArea.width,
+					curPaintArea.height, BufferedImage.TYPE_INT_RGB);
+
+			requestStartRendering();
+		}
+		return finalImage;
+	}
+	
+	private Image getPreFinalImage() {
+		
+		if (preFinalImage == null) {
+			preFinalImage = null;
+			Rectangle curPaintArea = getVisibleRect();
+
+			preFinalImage = new BufferedImage(curPaintArea.width,
+					curPaintArea.height, BufferedImage.TYPE_INT_RGB);
+			
+			requestStartRendering();
+		}
+		return preFinalImage;
+	}
+
+	/**
+	 * While dragging, the {@link #updateFinalImage()} method is translating the
+	 * cached images while setting it together.
+	 **/
+	Point imageOrigin = new Point(0, 0);
+
+	/**
+	 * Starts rendering on one or two threads
+	 */
+	private void startRendering() {
+
+		if (!isWellDefined())
+			return;
+
+		if (bgExecuter != null)
+			// Stop all renderers
+			bgExecuter.cancelTask();
+
+		if (localExecuter != null)
+			localExecuter.cancelTask();
+		//
+		//
+		// LOGGER.debug("stopping any running renderes:");
+		// int count = 0;
+		// while (bgExecuter.isRunning() || localExecuter.isRunning()) {
+		// LOGGER.debug("waiting for threads to stop");
+		//
+		// bgExecuter.cancelTask();
+		// localExecuter.cancelTask();
+		//
+		// count++;
+		//
+		// try {
+		// Thread.sleep(100);
+		// } catch (InterruptedException e) {
+		// LOGGER.error(e);
+		// }
+		//
+		// if (count > 100) {
+		// throw new RuntimeException(
+		// "Unable to stop rendering thread for 10secs");
+		// }
+		// }
+		// LOGGER.debug(" threads stopped after " + count / 10. + "secs");
+
+		Rectangle curPaintArea = getVisibleRect();
+
+		// allow a single pixel margin at the right and bottom edges
+		curPaintArea.width -= 1;
+		curPaintArea.height -= 1;
+
+		labelCache.clear();
+
+		/**
+		 */
+
+		/**
+		 * We have to set new renderer
+		 */
+
+		if (getBgContext() != null) {
+			bgExecuter = new RenderingExecutor(this);
+			LOGGER.debug("starting bg renderer:");
+			// /* System.out.println("rendering"); */
+			final GTRenderer createGTRenderer = GTUtil.createGTRenderer(
+					localContext, getRendererHints());
+			createGTRenderer.setJava2DHints(getJava2dHints());
+			bgExecuter.submit(getBgContext().getAreaOfInterest(), curPaintArea,
+					(Graphics2D) getBgImage().getGraphics(), createGTRenderer);
+		}
+
+		if (getContext() != null) {
+			localExecuter = new RenderingExecutor(this);
+			LOGGER.debug("starting local renderer:");
+			final GTRenderer createGTRenderer = GTUtil.createGTRenderer(
+					localContext, getRendererHints());
+			createGTRenderer.setJava2DHints(getJava2dHints());
+			localExecuter.submit(getContext().getAreaOfInterest(),
+					curPaintArea, (Graphics2D) getLocalImage().getGraphics(),
+					createGTRenderer);
+		}
+
+		updateCursorAndRepaintTimer();
+
+		// start regular repaints until all renderers are done.
+		repainterTimer.setRepeats(true);
+		repainterTimer.restart();
+
+	}
+
+	/**
+	 * Lazyly initializes a {@link BufferedImage} for the background renderer.
+	 */
+	private BufferedImage getBgImage() {
+
+		if (bgImage == null) {
+			LOGGER.debug("creating a new background image");
+
+			Rectangle curPaintArea = getVisibleRect();
+			// allow a single pixel margin at the right and bottom edges
+			curPaintArea.width -= 1;
+			curPaintArea.height -= 1;
+
+			bgImage = new BufferedImage(curPaintArea.width + 1,
+					curPaintArea.height + 1, BufferedImage.TYPE_INT_ARGB);
+		}
+
+		return bgImage;
+	}
+
+	/** An (transparent) image to paint over the map in the lower right corner **/
+	private BufferedImage mapImage = null;
+
+	private boolean acceptsRepaintCalls = true;
+
+	/**
+	 * Get the BufferedImage to use as a flaoting icon in the lower right
+	 * corner.
+	 * 
+	 * @return <code>null</code> if the feature is deactivated.
+	 */
+	public BufferedImage getMapImage() {
+		return mapImage;
+	}
+
+	/**
+	 * Set the BufferedImage to use as a flaoting icon in the lower right corner
+	 * 
+	 * @param mapImageIcon
+	 *            <code>null</code> is allowed and deactivates this icon.
+	 */
+	public void setMapImage(BufferedImage mapImage) {
+		this.mapImage = mapImage;
+//		gadgetsImage = null;
+	}
+
+	/**
+	 * Lazyly initializes a {@link BufferedImage} for the background renderer.
+	 */
+	private BufferedImage getLocalImage() {
+
+		if (localImage == null) {
+			LOGGER.debug("creating a new local image");
+
+			Rectangle curPaintArea = getVisibleRect();
+			// allow a single pixel margin at the right and bottom edges
+			curPaintArea.width -= 1;
+			curPaintArea.height -= 1;
+
+			localImage = new BufferedImage(curPaintArea.width + 1,
+					curPaintArea.height + 1, BufferedImage.TYPE_INT_ARGB);
+		}
+
+		return localImage;
+	}
+//
+//	/**
+//	 * Lazyly initializes a {@link BufferedImage} for the background renderer.
+//	 */
+//	private BufferedImage getGadgetsImage() {
+//
+//		if (gadgetsImage == null) {
+//			LOGGER.debug("creating a new gadgets image");
+//
+//			Rectangle curPaintArea = getVisibleRect();
+//			// allow a single pixel margin at the right and bottom edges
+//			curPaintArea.width -= 1;
+//			curPaintArea.height -= 1;
+//
+//			gadgetsImage = new BufferedImage(curPaintArea.width + 1,
+//					curPaintArea.height + 1, BufferedImage.TYPE_INT_ARGB);
+//
+//			if (mapImage != null)
+//				gadgetsImage.getGraphics().drawImage(mapImage,
+//						curPaintArea.width - mapImage.getWidth() - 10,
+//						curPaintArea.height - mapImage.getHeight() - 10, this);
+//			
+//		}
+//
+//		return gadgetsImage;
+//	}
+
+	/**
+	 * Called by the {@linkplain XMapPane.RenderingTask} when rendering has been
+	 * completed Publishes a {@linkplain MapPaneEvent} of type {@code
+	 * MapPaneEvent.Type.RENDERING_STOPPED} to listeners.
+	 * 
+	 * @see MapPaneListener#onRenderingStopped(org.geotools.swing.event.MapPaneEvent)
+	 */
+	public void onRenderingCompleted() {
+		System.out.println("onRenderingCompleted");
+
+		updateFinalImage();
+
+		repaint();
+
+	}
+
+	/**
+	 * Called by the {@linkplain XMapPane.RenderingTask} when rendering was
+	 * cancelled. Publishes a {@linkplain MapPaneEvent} of type {@code
+	 * MapPaneEvent.Type.RENDERING_STOPPED} to listeners.
+	 * 
+	 * @see MapPaneListener#onRenderingStopped(org.geotools.swing.event.MapPaneEvent)
+	 */
+	public void onRenderingCancelled() {
+		LOGGER.debug("Rendering cancelled");
+	}
+
+	/**
+	 * Called by the {@linkplain XMapPane.RenderingTask} when rendering failed.
+	 * Publishes a {@linkplain MapPaneEvent} of type {@code
+	 * MapPaneEvent.Type.RENDERING_STOPPED} to listeners.
+	 * 
+	 * @param renderingError
+	 *            The error that occured during rendering
+	 * 
+	 * @see MapPaneListener#onRenderingStopped(org.geotools.swing.event.MapPaneEvent)
+	 */
+	public void onRenderingFailed(Exception renderingError) {
+		// MapPaneEvent ev = new MapPaneEvent(this,
+		// MapPaneEvent.Type.RENDERING_STOPPED);
+		// publishEvent(ev);
+		LOGGER.warn("Rendering failed", renderingError);
+		updateFinalImage();
+		repaint();
+
+	}
+
+	/**
+	 * Called when a rendering request has been rejected. This will be common,
+	 * such as when the user pauses during drag-resizing fo the map pane. The
+	 * base implementation does nothing. It is provided for sub-classes to
+	 * override if required.
+	 */
+	public void onRenderingRejected() {
+		LOGGER.warn("Rendering rejected");
+		repaint();
+	}
+
+	@Override
+	public void propertyChange(final PropertyChangeEvent evt) {
+		final String prop = evt.getPropertyName();
+
+		if (prop.equalsIgnoreCase("crs")) {
+			localContext.setAreaOfInterest(localContext.getAreaOfInterest(),
+					(CoordinateReferenceSystem) evt.getNewValue());
+		}
+	}
+
+	// xulu.sn
+	/**
+	 * Korrigiert den {@link Envelope} aka {@code mapArea} auf die beste
+	 * erlaubte Flaeche damit die Massstabsbeschaenkungen noch eingehalten
+	 * werden, FALLS der uebergeben Envelope nicht schon gueltig sein sollte.<br/>
+	 * Since 21. April 09: Before thecalculation starts, the aspect ratio is
+	 * corrected. This change implies, that setMapArea() will most of the time
+	 * not allow setting to a wrong aspectRatio.
+	 * 
+	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
+	 *         Kr&uuml;ger</a>
+	 */
+	public Envelope bestAllowedMapArea(Envelope env) {
+		if (getWidth() == 0)
+			return env;
+		if (env == null)
+			return null;
+
+		Envelope newArea = null;
+
+		/**
+		 * Correct the aspect Ratio before we check the rest. Otherwise we might
+		 * easily fail. We allow to grow here, because we don't check against
+		 * the maxExtend
+		 */
+		Rectangle curPaintArea = getVisibleRect();
+
+		env = JTSUtil.fixAspectRatio(curPaintArea, env, true);
+
+		final double scale = env.getWidth() / getWidth();
+		final double centerX = env.getMinX() + env.getWidth() / 2.;
+		final double centerY = env.getMinY() + env.getHeight() / 2.;
+		double newWidth2 = 0;
+		double newHeight2 = 0;
+		if (scale < getMaxZoomScale()) {
+			// ****************************************************************************
+			// Wir zoomen weiter rein als erlaubt => Anpassen des envelope
+			// ****************************************************************************
+			newWidth2 = getMaxZoomScale() * getWidth() / 2.;
+			newHeight2 = getMaxZoomScale() * getHeight() / 2.;
+		} else if (scale > getMinZoomScale()) {
+			// ****************************************************************************
+			// Wir zoomen weiter raus als erlaubt => Anpassen des envelope
+			// ****************************************************************************
+			newWidth2 = getMinZoomScale() * getWidth() / 2.;
+			newHeight2 = getMinZoomScale() * getHeight() / 2.;
+		} else {
+			// ****************************************************************************
+			// Die mapArea / der Envelope ist ist gueltig! Keine Aenderungen
+			// ****************************************************************************
+			newArea = env;
+		}
+
+		if (newArea == null) {
+
+			final Coordinate ll = new Coordinate(centerX - newWidth2, centerY
+					- newHeight2);
+			final Coordinate ur = new Coordinate(centerX + newWidth2, centerY
+					+ newHeight2);
+
+			newArea = new Envelope(ll, ur);
+		}
+
+		Envelope maxAllowedExtend = getMaxExtend();
+		while (maxAllowedExtend != null && !maxAllowedExtend.contains(newArea)
+				&& newArea != null && !newArea.isNull()
+				&& !Double.isNaN(newArea.getMinX())
+				&& !Double.isNaN(newArea.getMaxX())
+				&& !Double.isNaN(newArea.getMinY())
+				&& !Double.isNaN(newArea.getMaxY())) {
+			/*
+			 * If a maxExtend is set, we have to honour that...
+			 */
+
+			// Exceeds top? Move down and maybe cut
+			if (newArea.getMaxY() > maxAllowedExtend.getMaxY()) {
+				double divY = newArea.getMaxY() - maxAllowedExtend.getMaxY();
+				// LOGGER.debug("Moving area down by " + divY);
+
+				newArea = new Envelope(new Coordinate(newArea.getMinX(),
+						newArea.getMinY() - divY), new Coordinate(newArea
+						.getMaxX(), newArea.getMaxY() - divY));
+
+				if (newArea.getMinY() < maxAllowedExtend.getMinY()) {
+					// LOGGER.debug("Now it exeeds the bottom border.. cut!");
+					// And cut the bottom if it moved out of the area
+					newArea = new Envelope(new Coordinate(newArea.getMinX(),
+							maxAllowedExtend.getMinY()), new Coordinate(newArea
+							.getMaxX(), newArea.getMaxY()));
+
+					// LOGGER.debug("and fix aspect ratio");
+
+					newArea = JTSUtil.fixAspectRatio(this.getBounds(), newArea,
+							false);
+				}
+			}
+
+			// Exceeds bottom? Move up and maybe cut
+			if (newArea.getMinY() < maxAllowedExtend.getMinY()) {
+				double divY = newArea.getMinY() - maxAllowedExtend.getMinY();
+				// LOGGER.debug("Moving area up by " + divY);
+
+				newArea = new Envelope(new Coordinate(newArea.getMinX(),
+						newArea.getMinY() - divY), new Coordinate(newArea
+						.getMaxX(), newArea.getMaxY() - divY));
+
+				if (newArea.getMaxY() > maxAllowedExtend.getMaxY()) {
+					// LOGGER.debug("Now it exeeds the top border.. cut!");
+					// And cut the bottom if it moved out of the area
+					newArea = new Envelope(new Coordinate(newArea.getMinX(),
+							newArea.getMinY()), new Coordinate(newArea
+							.getMaxX(), maxAllowedExtend.getMaxY()));
+
+					// LOGGER.debug("and fix aspect ratio");
+
+					newArea = JTSUtil.fixAspectRatio(this.getBounds(), newArea,
+							false);
+				}
+			}
+
+			// Exceeds to the right? move and maybe cut
+			if (newArea.getMaxX() > maxAllowedExtend.getMaxX()) {
+
+				// Move left..
+				double divX = newArea.getMaxX() - maxAllowedExtend.getMaxX();
+				// LOGGER.debug("Moving area left by " + divX);
+
+				newArea = new Envelope(new Coordinate(newArea.getMinX() - divX,
+						newArea.getMinY()), new Coordinate(newArea.getMaxX()
+						- divX, newArea.getMaxY()));
+
+				if (newArea.getMinX() < maxAllowedExtend.getMinX()) {
+					// LOGGER.debug("Now it exeeds the left border.. cut!");
+					// And cut the left if it moved out of the area
+					newArea = new Envelope(new Coordinate(maxAllowedExtend
+							.getMinX(), newArea.getMinY()), new Coordinate(
+							newArea.getMaxX(), newArea.getMaxY()));
+
+					// LOGGER.debug("and fix aspect ratio");
+
+					newArea = JTSUtil.fixAspectRatio(this.getBounds(), newArea,
+							false);
+				}
+			}
+
+			// Exceeds to the left? move and maybe cut
+			if (newArea.getMinX() < maxAllowedExtend.getMinX()) {
+
+				// Move right..
+				double divX = newArea.getMinX() - maxAllowedExtend.getMinX();
+				// LOGGER.debug("Moving area right by " + divX);
+
+				newArea = new Envelope(new Coordinate(newArea.getMinX() - divX,
+						newArea.getMinY()), new Coordinate(newArea.getMaxX()
+						- divX, newArea.getMaxY()));
+
+				if (newArea.getMaxX() > maxAllowedExtend.getMaxX()) {
+					// LOGGER.debug("Now it exeeds the right border.. cut!");
+					// And cut the left if it moved out of the area
+					newArea = new Envelope(new Coordinate(newArea.getMinX(),
+							newArea.getMinY()), new Coordinate(maxAllowedExtend
+							.getMaxX(), newArea.getMaxY()));
+
+					// LOGGER.debug("and fix aspect ratio");
+
+					newArea = JTSUtil.fixAspectRatio(this.getBounds(), newArea,
+							false);
+				}
+			}
+
+		}
+
+		return newArea;
+	}
+
+	/**
+	 * Retuns the minimum allowed zoom scale. This is the bigger number value of
+	 * the two. Defaults to {@link Double}.MAX_VALUE
+	 * 
+	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
+	 *         Kr&uuml;ger</a>
+	 */
+	public Double getMinZoomScale() {
+		return minZoomScale;
+	}
+
+	/**
+	 * Retuns the maximum allowed zoom scale. This is the smaller number value
+	 * of the two. Defaults to {@link Double}.MIN_VALUE
+	 * 
+	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
+	 *         Kr&uuml;ger</a>
+	 */
+	public Double getMaxZoomScale() {
+		return maxZoomScale;
+	}
+
+	/**
+	 * Set the maximum allowed zoom scale. This is the smaller number value of
+	 * the two. If <code>null</code> is passed, Double.MINVALUE are used which
+	 * mean there is no restriction.
+	 * 
+	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
+	 *         Kr&uuml;ger</a>
+	 */
+	public void setMaxZoomScale(final Double maxZoomScale) {
+		this.maxZoomScale = maxZoomScale == null ? Double.MIN_VALUE
+				: maxZoomScale;
+	}
+
+	/**
+	 * Set the minimum (nearest) allowed zoom scale. This is the bigger number
+	 * value of the two. If <code>null</code> is passed, Double.MAXVALUE are
+	 * used which mean there is no restriction.
+	 * 
+	 * 
+	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
+	 *         Kr&uuml;ger</a>
+	 */
+	public void setMinZoomScale(final Double minZoomScale) {
+		this.minZoomScale = minZoomScale == null ? Double.MAX_VALUE
+				: minZoomScale;
+	}
+
+	/**
+	 * Defines an evelope of the viwable area. The JMapPane will never show
+	 * anything outside of this extend.
+	 * 
+	 * @param maxExtend
+	 *            <code>null</code> to not have this restriction.
+	 */
+	public void setMaxExtend(Envelope maxExtend) {
+		this.maxExtend = maxExtend;
+	}
+
+	/**
+	 * Returns the evelope of the viewable area. The JMapPane will never show
+	 * anything outside of this extend. If this has been set to
+	 * <code>null</code> via {@link #setMaxExtend(Envelope)}, it tries to return
+	 * quickly the context's bounds. It it takes to long to determine the
+	 * context bounds, <code>null</code> is returned.
+	 * 
+	 * @param maxExtend
+	 *            <code>null</code> to not have this restriction.
+	 */
+
+	public Envelope getMaxExtend() {
+		if (maxExtend == null) {
+			final ReferencedEnvelope layerBounds = GTUtil
+					.getVisibleLayoutBounds(localContext);
+			if (layerBounds == null) {
+				// TODO Last fallback could be the CRS valid area
+				return null;
+			}
+
+			// Kartenbereich um 10% vergroessern
+			return JTSUtil.fixAspectRatio(this.getBounds(), JTSUtil
+					.expandEnvelope(layerBounds, 0.1), true);
+		}
+		return maxExtend;
+	}
+
+	/**
+	 * Set the background color of the map.
+	 * 
+	 * @param if <code>null</code>, white is used.
+	 */
+	public void setMapBackgroundColor(Color bgColor) {
+		if (bgColor == null)
+			bgColor = Color.WHITE;
+		this.mapBackgroundColor = bgColor;
+	}
+
+	/**
+	 * Returns the background {@link Color} of the map pane. Default is white.
+	 **/
+	public Color getMapBackgroundColor() {
+		return mapBackgroundColor;
+	}
+
+	/**
+	 * 
+	 * @param b
+	 */
+	public void setPainting(boolean b) {
+		acceptsRepaintCalls = b;
+	}
+
+	/**
+	 * Fuegt der Map einen Listener hinzu.
+	 * 
+	 * @param l
+	 *            neuer Listener
+	 */
+	public void addMapPaneListener(JMapPaneListener l) {
+		mapPaneListeners.add(l);
+	}
+
+	/**
+	 * Liste der angeschlossenen Listener, die auf Aktionen des MapPanes
+	 * lauschen.
+	 */
+	protected Vector<JMapPaneListener> mapPaneListeners = new Vector<JMapPaneListener>();
+
+	/**
+	 * A flag indicating if dispose() was already called. If true, then further
+	 * use of this {@link SelectableXMapPane} is undefined.
+	 */
+	private boolean disposed = false;
+
+	/**
+	 * Entfernt einen Listener von der Map.
+	 * 
+	 * @param l
+	 *            zu entfernender Listener
+	 */
+	public void removeMapPaneListener(JMapPaneListener l) {
+		mapPaneListeners.remove(l);
+	}
+
+	/** Stored the time used for the last real rendering in ms. **/
+	private long lastRenderingDuration = Long.MAX_VALUE;
+
+	// if null, no quick preview will be shown
+	private int quickPreviewHint = 0;
+
+	/**
+	 * For every rendering thread started,
+	 * {@link GTUtil#createGTRenderer(MapContext)} is called to create a new
+	 * renderer. These Java2D rendering hints are passed to the
+	 * {@link GTRenderer}. The java2dHints are the same for all renderers (bg
+	 * and local).
+	 */
+	private RenderingHints java2dHints;
+
+	/**
+	 * Returns in milli seconds the time the last rending of the
+	 * {@link SelectableXMapPane} took. #Long.MAX_VALUE if the JMapPane has not
+	 * been rendered yet.
+	 */
+	public long getLastRenderingDuration() {
+		return lastRenderingDuration;
+	}
+
+	/**
+	 * Should be called when the {@link JMapPane} is not needed no more to help
+	 * the GarbageCollector
+	 * 
+	 * Removes all {@link JMapPaneListener}s that are registered
+	 * 
+	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
+	 *         Kr&uuml;ger</a>
+	 */
+	public void dispose() {
+		if (isDisposed())
+			return;
+
+		disposed = true;
+
+		if (bgExecuter != null) {
+			bgExecuter.cancelTask();
+		}
+
+		if (localExecuter != null) {
+			localExecuter.cancelTask();
+		}
+
+		startRenderThreadsTimer.stop();
+		repainterTimer.stop();
+
+		if (bgImage != null)
+			bgImage.flush();
+		if (localImage != null)
+			localImage.flush();
+//		if (gadgetsImage != null)
+//			gadgetsImage.flush();
+		if (finalImage != null)
+			finalImage.flush();
+		if (preFinalImage != null)
+			preFinalImage.flush();
+
+		// if (dragWaitCursorListener != null)
+		// this.removeMouseListener(dragWaitCursorListener);
+		// if (mouseWheelZoomListener != null)
+		// this.removeMouseWheelListener(mouseWheelZoomListener);
+
+		// Alle mapPaneListener entfernen
+		mapPaneListeners.clear();
+
+		removeMouseMotionListener(zoomMapPaneMouseListener);
+		removeMouseListener(zoomMapPaneMouseListener);
+
+		if (localContext != null)
+			getContext().clearLayerList();
+		if (bgContext != null)
+			getBgContext().clearLayerList();
+
+		removeAll();
+	}
+
+	/**
+	 * A flag indicating if dispose() has already been called. If true, then
+	 * further use of this {@link SelectableXMapPane} is undefined.
+	 */
+	private boolean isDisposed() {
+		return disposed;
+	}
+
+	public void setQuickPreviewHint(int quickPreviewHint) {
+		this.quickPreviewHint = quickPreviewHint;
+
+	}
+
+	public void setJava2dHints(RenderingHints java2dHints) {
+		this.java2dHints = java2dHints;
+	}
+
+	public RenderingHints getJava2dHints() {
+		return java2dHints;
+	}
+
+	/**
+	 * Zooms towards a point.
+	 * 
+	 * @param center
+	 *            position in window coordinates
+	 * @param zoomFaktor
+	 *            > 1 for zoom in, < 1 for zoom out. Default is 1.33.
+	 */
+	public void zoomTo(Point center, Double zoomFaktor) {
+		if (zoomFaktor == null || zoomFaktor == 0.)
+			zoomFaktor = 2.;
+
+		Point2D gcenter = getScreenToWorld().transform(center, null);
+		center = null;
+		
+		if (
+				Double.isNaN(gcenter.getX()) || Double.isNaN(gcenter.getY())
+				||
+				Double.isInfinite(gcenter.getX()) || Double.isInfinite(gcenter.getY())
+				
+		) {
+			// Not inside valid CRS area! cancel
+			return;
+		}
+
+		final Envelope mapArea = getMapArea();
+		
+		Envelope newMapArea = new Envelope(mapArea);
+		newMapArea
+				.expandBy((mapArea.getWidth() * zoomFaktor - mapArea
+						.getWidth()) / 2., (mapArea.getHeight()
+						* zoomFaktor - mapArea.getHeight()) / 2.);
+
+		// Move the newMapArea above the new center
+		newMapArea.translate(gcenter.getX() - mapArea.centre().x, gcenter.getY()
+				- mapArea.centre().y);
+
+		setMapArea(newMapArea);
+	}
+
+	/**
+	 * Zooms towards a point.
+	 * 
+	 * @param center
+	 *            position in window coordinates
+	 * @param zoomFactor
+	 *            > 1 for zoom in, < 1 for zoom out. Default is 1.33
+	 */
+	public void zoomTo(Point center) {
+		zoomTo(center, null);
+	}
+
+	public void mouseDragged(Point startPos, Point lastPos, MouseEvent event) {
+
+		if ((getState() == XMapPane.PAN)
+				|| ((event.getModifiersEx() & InputEvent.BUTTON3_DOWN_MASK) != 0)) {
+
+			if (getCursor() != SwingUtil.PANNING_CURSOR) {
+				setCursor(SwingUtil.PANNING_CURSOR);
+
+				// While panning, we deactivate the rendering. So the tasts are
+				// ready to start when the panning os done.
+				if (bgExecuter != null)
+					bgExecuter.cancelTask();
+				if (localExecuter != null)
+					localExecuter.cancelTask();
+			}
+
+			if (lastPos.x > 0 && lastPos.y > 0) {
+				final int dx = event.getX() - lastPos.x;
+				final int dy = event.getY() - lastPos.y;
+
+				// TODO Stop dragging when the drag would not be valid...
+				// boolean dragValid = true;
+				// // check if this panning results in a valid mapArea
+				// {
+				// Rectangle winBounds = xMapPane.getBounds();
+				// winBounds.translate(xMapPane.imageOrigin.x,
+				// -xMapPane.imageOrigin.y);
+				// Envelope newMapAreaBefore = xMapPane.tranformWindowToGeo(
+				// winBounds.x, winBounds.y, winBounds.x
+				// + winBounds.width, winBounds.y
+				// + winBounds.height);
+				//					
+				//
+				// winBounds = xMapPane.getBounds();
+				// Point testIng = new Point(xMapPane.imageOrigin);
+				// testIng.translate(dx, dy);
+				// winBounds.translate(testIng.x, -testIng.y);
+				// Envelope newMapAreaAfter = xMapPane.tranformWindowToGeo(
+				// winBounds.x, winBounds.y, winBounds.x
+				// + winBounds.width, winBounds.y
+				// + winBounds.height);
+				//
+				// // If the last drag doesn't change the MapArea anymore cancel
+				// it.
+				// if (xMapPane.bestAllowedMapArea(newMapAreaAfter).equals(
+				// xMapPane.bestAllowedMapArea(newMapAreaBefore))){
+				// dragValid = false;
+				// return;
+				// }
+				// }
+
+				imageOrigin.translate(dx, dy);
+				updateFinalImage();
+				repaint();
+			}
+
+		} else if ((getState() == XMapPane.ZOOM_IN)
+				|| (getState() == XMapPane.ZOOM_OUT)
+				|| (getState() == XMapPane.SELECT_ALL)
+				|| (getState() == XMapPane.SELECT_TOP)
+		// || (getState() == XMapPane.SELECT_ONE_FROM_TOP)
+		) {
+			final Graphics graphics = getGraphics();
+
+			drawRectangle(graphics, startPos, event.getPoint());
+
+			if ((lastPos.x > 0) && (lastPos.y > 0)) {
+				drawRectangle(graphics, startPos, lastPos);
+			}
+
+		}
+
+	}
+
+	/**
+	 * Draws a rectangle in XOR mode from the origin at {@link #startPos} to the
+	 * given point. All in screen coordinates.
+	 */
+	protected void drawRectangle(final Graphics graphics, Point startPos,
+			Point e) {
+		// undraw last box/draw new box
+		final int left = Math.min(startPos.x, e.x);
+		final int right = Math.max(startPos.x, e.x);
+		final int top = Math.max(startPos.y, e.y);
+		final int bottom = Math.min(startPos.y, e.y);
+		final int width = right - left;
+		final int height = top - bottom;
+
+		if (width == 0 && height == 0)
+			return;
+
+		graphics.setXORMode(Color.WHITE);
+		graphics.drawRect(left, bottom, width, height);
+	}
+
+	/**
+	 * Finalizes a PAN action
+	 */
+	public void performPan() {
+		Rectangle winBounds = getBounds();
+		winBounds.translate(-imageOrigin.x, -imageOrigin.y);
+		Envelope newMapArea = tranformWindowToGeo(winBounds.x, winBounds.y,
+				winBounds.x + winBounds.width, winBounds.y + winBounds.height);
+
+		imageOrigin.x = 0;
+		imageOrigin.y = 0;
+
+		if (!setMapArea(newMapArea)){
+			updateFinalImage();
+			repaint();
+		}
+
+		if (getCursor() == SwingUtil.PANNING_CURSOR)
+			setCursor(SwingUtil.PAN_CURSOR);
+	}
+
+}

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/GTUtil.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/GTUtil.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/GTUtil.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -29,248 +29,428 @@
  ******************************************************************************/
 package schmitzm.geotools;
 
-import java.awt.Rectangle;
 import java.awt.geom.Rectangle2D;
 import java.text.DecimalFormat;
 import java.util.HashMap;
+import java.util.Map;
 import java.util.Set;
 import java.util.SortedMap;
 import java.util.TreeMap;
 
 import org.apache.log4j.Logger;
+import org.geotools.data.FeatureSource;
 import org.geotools.geometry.Envelope2D;
 import org.geotools.geometry.jts.JTS;
+import org.geotools.geometry.jts.ReferencedEnvelope;
 import org.geotools.map.MapContext;
+import org.geotools.map.MapLayer;
 import org.geotools.referencing.CRS;
 import org.geotools.renderer.GTRenderer;
+import org.geotools.renderer.label.LabelCacheImpl;
 import org.geotools.renderer.lite.StreamingRenderer;
 import org.geotools.renderer.shape.ShapefileRenderer;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
 import org.opengis.geometry.Envelope;
+import org.opengis.referencing.FactoryException;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.TransformException;
 
-import com.vividsolutions.jts.geom.Coordinate;
-
 /**
  * Diese Klasse enthaelt allgemeine Funktionen fuer die Arbeit mit Geotools.
- * @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 GTUtil {
-  private static Logger LOGGER = Logger.getLogger( GTUtil.class.getName() );
+	private static Logger LOGGER = Logger.getLogger(GTUtil.class.getName());
 
-  /**
-   * Specifies the types of renderer used by {@link GTUtil#createGTRenderer()}.
-   */
-  public static enum GTRendererType {
-    /** {@link GTUtil#createGTRenderer()} uses {@link StreamingRenderer}. */
-    StreamingRenderer,
-    /** {@link GTUtil#createGTRenderer()} uses {@link ShapefileRenderer}. */
-    ShapefileRenderer
-  }
-  /** Holds the renderer type instantiated by
-   *  {@link GTUtil#createGTRenderer()}. */
-  private static GTRendererType rendererType = GTRendererType.ShapefileRenderer;
-  
-  /** Konstante fuer das CRS "WGS84" (erzeugt als "EPSG:4326")*/
-  public static CoordinateReferenceSystem WGS84 = null;
+	/**
+	 * Specifies the types of renderer used by {@link GTUtil#createGTRenderer()}
+	 * .
+	 */
+	public static enum GTRendererType {
+		/** {@link GTUtil#createGTRenderer()} uses {@link StreamingRenderer}. */
+		StreamingRenderer,
+		/** {@link GTUtil#createGTRenderer()} uses {@link ShapefileRenderer}. */
+		ShapefileRenderer
+	}
 
-  private static HashMap<Object, Object> defaultRendererHints;
+	/**
+	 * Holds the renderer type instantiated by {@link GTUtil#createGTRenderer()}
+	 * .
+	 */
+	private static GTRendererType rendererType = GTRendererType.ShapefileRenderer;
 
-  // Initialisierung der CRS-Konstanten
-  static {
-    try {
-      WGS84 = CRS.decode("EPSG:4326",true); // lat/lon (WGS84)
-    } catch (Exception err) {
-    	LOGGER.warn("Exception while creating default WGS84 from code 'EPSG:4326'");
-    }
-  }
+	/** Konstante fuer das CRS "WGS84" (erzeugt als "EPSG:4326") */
+	public static CoordinateReferenceSystem WGS84 = null;
 
-  /**
-   * Erzeugt ein {@link CoordinateReferenceSystem} aus einer String-Definition.
-   * Akzeptiert wird ein EPSG-Code "EPSG:..." oder eine WKT-Definition des CRS
-   * @param crsDef Definition fuer das CRS.
-   * @return {@code null}, falls der String nicht zu einem CRS dekodiert werden
-   *         kann
-   */
-  public static CoordinateReferenceSystem createCRS(String crsDef) {
-    if ( crsDef == null || crsDef.trim().equals("") )
-      return null;
+	private static HashMap<Object, Object> defaultRendererHints;
 
-    CoordinateReferenceSystem crs = null;
-    try {
-        // Akzeptiert wird: EPSG-Code
-        if (crsDef.startsWith("EPSG:"))
-          crs = createCRS_EPSG( crsDef );
-        else 
-          crs = CRS.parseWKT( crsDef );
-    } catch (Exception err) {
-      LOGGER.error("Error while creating CRS",err);
-    }
-    return crs;
-  }
+	// Initialisierung der CRS-Konstanten
+	static {
+		try {
+			WGS84 = CRS.decode("EPSG:4326", true); // lat/lon (WGS84)
+		} catch (Exception err) {
+			LOGGER
+					.warn("Exception while creating default WGS84 from code 'EPSG:4326'");
+		}
+	}
 
-  /**
-   * Erzeugt ein {@link CoordinateReferenceSystem} aus einem (EPSG-)Code.
-   * Entspricht {@link CRS#decode(String,boolean) CRS#decode(String,true)}.
-   * Exceptions werden jedoch abgefangen und stattdessen {@code null} zurueckgegeben.
-   * @param code Code fuer das CRS.
-   */
-  public static CoordinateReferenceSystem createCRS_EPSG(String code) {
-    try {
-      return CRS.decode(code,true);
-    } catch (Exception err) {
-      LOGGER.error("Error while creating CRS",err);
-      return null;
-    }
-  }
+	/**
+	 * Erzeugt ein {@link CoordinateReferenceSystem} aus einer
+	 * String-Definition. Akzeptiert wird ein EPSG-Code "EPSG:..." oder eine
+	 * WKT-Definition des CRS
+	 * 
+	 * @param crsDef
+	 *            Definition fuer das CRS.
+	 * @return {@code null}, falls der String nicht zu einem CRS dekodiert
+	 *         werden kann
+	 */
+	public static CoordinateReferenceSystem createCRS(String crsDef) {
+		if (crsDef == null || crsDef.trim().equals(""))
+			return null;
 
-  /**
-   * Erzeugt ein UTM-CoordinateReferenceSystem.
-   * @param zone UTM-Zone
-   */
-  public static CoordinateReferenceSystem createCRS_UTM(int zone) {
-    DecimalFormat format_99 = new DecimalFormat("00");
-    return createCRS( "EPSG:326"+format_99.format(zone) );
-  }
+		CoordinateReferenceSystem crs = null;
+		try {
+			// Akzeptiert wird: EPSG-Code
+			if (crsDef.startsWith("EPSG:"))
+				crs = createCRS_EPSG(crsDef);
+			else
+				crs = CRS.parseWKT(crsDef);
+		} catch (Exception err) {
+			LOGGER.error("Error while creating CRS", err);
+		}
+		return crs;
+	}
 
-  /**
-   * Erzeugt einen {@link Envelope2D} aus einem {@link Rectangle2D} .
-   * @param env Georeferenz und Ausdehnung
-   * @param crs CoordinateReferenceSystem
-   */
-  public static Envelope2D createEnvelope2D(Rectangle2D env, CoordinateReferenceSystem crs) {
-    return new Envelope2D(crs, env.getX(), env.getY(), env.getWidth(),
-                          env.getHeight());
-  }
+	/**
+	 * Erzeugt ein {@link CoordinateReferenceSystem} aus einem (EPSG-)Code.
+	 * Entspricht {@link CRS#decode(String,boolean) CRS#decode(String,true)}.
+	 * Exceptions werden jedoch abgefangen und stattdessen {@code null}
+	 * zurueckgegeben.
+	 * 
+	 * @param code
+	 *            Code fuer das CRS.
+	 */
+	public static CoordinateReferenceSystem createCRS_EPSG(String code) {
+		try {
+			return CRS.decode(code, true);
+		} catch (Exception err) {
+			LOGGER.error("Error while creating CRS", err);
+			return null;
+		}
+	}
 
-  /**
-   * Liefert alle zur Verfuegung stehenden {@linkplain CoordinateReferenceSystem CRS} fuer eine
-   * Authority.
-   * @param authority      Authority fuer die die CRS geliefert werden (z.B. {@code "EPSG"})
-   * @param longitudeFirst {@code true} erzwingt die Achsenordnung (longitude, latitude). Siehe
-   *                       {@link CRS#decode(String, boolean)} (Bemerkung: {@code false} bedeutet
-   *                       System-Default, <b>nicht</b> (latitude, longitude)!)
-   * @param suppressWarnings wenn {@code true} werden Warnmeldungen unterdrueckt
-   * @return eine nach dem CRS-Namen geordnete Map
-   */
-  public static final SortedMap<String,CoordinateReferenceSystem> getAvailableCRSByName(String authority, boolean longitudeFirst, boolean suppressWarnings) {
-    SortedMap<String,CoordinateReferenceSystem> mapByCode = getAvailableCRSByCode(authority, longitudeFirst, suppressWarnings);
-    TreeMap<String,CoordinateReferenceSystem>   mapByName = new TreeMap<String, CoordinateReferenceSystem>();
-    for (String code : mapByCode.keySet()) {
-      CoordinateReferenceSystem crs = mapByCode.get(code);
-      mapByName.put( crs.getName().toString()+" ["+code+"]", crs );
-    }
-    return mapByName;
-  }
+	/**
+	 * Erzeugt ein UTM-CoordinateReferenceSystem.
+	 * 
+	 * @param zone
+	 *            UTM-Zone
+	 */
+	public static CoordinateReferenceSystem createCRS_UTM(int zone) {
+		DecimalFormat format_99 = new DecimalFormat("00");
+		return createCRS("EPSG:326" + format_99.format(zone));
+	}
 
-  /**
-   * Liefert alle zur Verfuegung stehenden {@linkplain CoordinateReferenceSystem CRS} fuer eine
-   * Authority.
-   * @param authority      Authority fuer die die CRS geliefert werden (z.B. {@code "EPSG"})
-   * @param longitudeFirst {@code true} erzwingt die Achsenordnung (longitude, latitude). Siehe
-   *                       {@link CRS#decode(String, boolean)} (Bemerkung: {@code false} bedeutet
-   *                       System-Default, <b>nicht</b> (latitude, longitude)!)
-   * @param suppressWarnings wenn {@code true} werden Warnmeldungen unterdrueckt
-   * @return eine nach dem CRS-Code geordnete Map
-   */
-  public static final SortedMap<String,CoordinateReferenceSystem> getAvailableCRSByCode(String authority, boolean longitudeFirst, boolean suppressWarnings) {
-    TreeMap<String,CoordinateReferenceSystem> map = new TreeMap<String, CoordinateReferenceSystem>();
-    for (String code : (Set<String>)CRS.getSupportedCodes(authority)) {
-      if ( !code.startsWith(authority) )
-        code = authority + ":" + code;
-      try {
-        CoordinateReferenceSystem crs = CRS.decode(code, longitudeFirst);
-        map.put(code, crs);
-      } catch (Exception err) {
-        if ( !suppressWarnings )
-          LOGGER.warn("CRS could not be decoded: "+code);
-      }
-    }
-    return map;
-  }
-  
+	/**
+	 * Erzeugt einen {@link Envelope2D} aus einem {@link Rectangle2D} .
+	 * 
+	 * @param env
+	 *            Georeferenz und Ausdehnung
+	 * @param crs
+	 *            CoordinateReferenceSystem
+	 */
+	public static Envelope2D createEnvelope2D(Rectangle2D env,
+			CoordinateReferenceSystem crs) {
+		return new Envelope2D(crs, env.getX(), env.getY(), env.getWidth(), env
+				.getHeight());
+	}
 
+	/**
+	 * Liefert alle zur Verfuegung stehenden
+	 * {@linkplain CoordinateReferenceSystem CRS} fuer eine Authority.
+	 * 
+	 * @param authority
+	 *            Authority fuer die die CRS geliefert werden (z.B. {@code
+	 *            "EPSG"})
+	 * @param longitudeFirst
+	 *            {@code true} erzwingt die Achsenordnung (longitude, latitude).
+	 *            Siehe {@link CRS#decode(String, boolean)} (Bemerkung: {@code
+	 *            false} bedeutet System-Default, <b>nicht</b> (latitude,
+	 *            longitude)!)
+	 * @param suppressWarnings
+	 *            wenn {@code true} werden Warnmeldungen unterdrueckt
+	 * @return eine nach dem CRS-Namen geordnete Map
+	 */
+	public static final SortedMap<String, CoordinateReferenceSystem> getAvailableCRSByName(
+			String authority, boolean longitudeFirst, boolean suppressWarnings) {
+		SortedMap<String, CoordinateReferenceSystem> mapByCode = getAvailableCRSByCode(
+				authority, longitudeFirst, suppressWarnings);
+		TreeMap<String, CoordinateReferenceSystem> mapByName = new TreeMap<String, CoordinateReferenceSystem>();
+		for (String code : mapByCode.keySet()) {
+			CoordinateReferenceSystem crs = mapByCode.get(code);
+			mapByName.put(crs.getName().toString() + " [" + code + "]", crs);
+		}
+		return mapByName;
+	}
 
-  /**
-   * Berechnet den Schnitt zweier {@link Envelope Envelopes}.
-   * @param env1 erster Envelope
-   * @param env2 zweiter Envelope
-   * @param crs  {@link CoordinateReferenceSystem} fuer den Schnitt-Envelope
-   */
-  public static Envelope intersectEnvelope(Envelope env1, Envelope env2, CoordinateReferenceSystem crs) {
-    // Envelopes in JTS umwandeln
-    com.vividsolutions.jts.geom.Envelope env1JTS = new com.vividsolutions.jts.geom.Envelope(
-      env1.getMinimum(0),env1.getMaximum(0),env1.getMinimum(1),env1.getMaximum(1));
-    com.vividsolutions.jts.geom.Envelope env2JTS = new com.vividsolutions.jts.geom.Envelope(
-      env2.getMinimum(0),env2.getMaximum(0),env2.getMinimum(1),env2.getMaximum(1));
-    com.vividsolutions.jts.geom.Envelope intersetionEnvJTS = env1JTS.intersection(env2JTS);
-    // Subset nur bzgl. des Bereichs in dem auch das Raster liegt
-    return JTS.getEnvelope2D(intersetionEnvJTS,crs);
-  }
+	/**
+	 * Liefert alle zur Verfuegung stehenden
+	 * {@linkplain CoordinateReferenceSystem CRS} fuer eine Authority.
+	 * 
+	 * @param authority
+	 *            Authority fuer die die CRS geliefert werden (z.B. {@code
+	 *            "EPSG"})
+	 * @param longitudeFirst
+	 *            {@code true} erzwingt die Achsenordnung (longitude, latitude).
+	 *            Siehe {@link CRS#decode(String, boolean)} (Bemerkung: {@code
+	 *            false} bedeutet System-Default, <b>nicht</b> (latitude,
+	 *            longitude)!)
+	 * @param suppressWarnings
+	 *            wenn {@code true} werden Warnmeldungen unterdrueckt
+	 * @return eine nach dem CRS-Code geordnete Map
+	 */
+	public static final SortedMap<String, CoordinateReferenceSystem> getAvailableCRSByCode(
+			String authority, boolean longitudeFirst, boolean suppressWarnings) {
+		TreeMap<String, CoordinateReferenceSystem> map = new TreeMap<String, CoordinateReferenceSystem>();
+		for (String code : (Set<String>) CRS.getSupportedCodes(authority)) {
+			if (!code.startsWith(authority))
+				code = authority + ":" + code;
+			try {
+				CoordinateReferenceSystem crs = CRS
+						.decode(code, longitudeFirst);
+				map.put(code, crs);
+			} catch (Exception err) {
+				if (!suppressWarnings)
+					LOGGER.warn("CRS could not be decoded: " + code);
+			}
+		}
+		return map;
+	}
 
-  /**
-   * Creates a {@link GTRenderer}. This method can be used all over
-   * a project, so the renderer can be switched easily.
-   * @param mapContext a {@link MapContext} (can be {@code null})
-   */
-  public static GTRenderer createGTRenderer(MapContext mapContext) {
-    GTRenderer renderer = createGTRenderer();
-    if ( mapContext != null )
-      renderer.setContext(mapContext);
-    return renderer;
-  }
+	/**
+	 * Berechnet den Schnitt zweier {@link Envelope Envelopes}.
+	 * 
+	 * @param env1
+	 *            erster Envelope
+	 * @param env2
+	 *            zweiter Envelope
+	 * @param crs
+	 *            {@link CoordinateReferenceSystem} fuer den Schnitt-Envelope
+	 */
+	public static Envelope intersectEnvelope(Envelope env1, Envelope env2,
+			CoordinateReferenceSystem crs) {
+		// Envelopes in JTS umwandeln
+		com.vividsolutions.jts.geom.Envelope env1JTS = new com.vividsolutions.jts.geom.Envelope(
+				env1.getMinimum(0), env1.getMaximum(0), env1.getMinimum(1),
+				env1.getMaximum(1));
+		com.vividsolutions.jts.geom.Envelope env2JTS = new com.vividsolutions.jts.geom.Envelope(
+				env2.getMinimum(0), env2.getMaximum(0), env2.getMinimum(1),
+				env2.getMaximum(1));
+		com.vividsolutions.jts.geom.Envelope intersetionEnvJTS = env1JTS
+				.intersection(env2JTS);
+		// Subset nur bzgl. des Bereichs in dem auch das Raster liegt
+		return JTS.getEnvelope2D(intersetionEnvJTS, crs);
+	}
 
-  /**
-   * Creates a {@link GTRenderer}. This method can be used all over
-   * a project, so the renderer can be switched easily.
-   */
-  public static GTRenderer createGTRenderer() {
-    switch ( rendererType ) {
-      case ShapefileRenderer: return new ShapefileRenderer();
-      case StreamingRenderer: return new StreamingRenderer();
-    }
-    throw new UnsupportedOperationException("Renderer type not supported: "+rendererType);
-  }
-  
-  /**
-   * Sets the renderer used by {@link #createGTRenderer()}.
-   * @param rType renderer type
-   * @see GTRendererType
-   */
-  public static void setGTRendererType(GTRendererType rType) {
-    rendererType = rType;
-  }
-  
-  /**
-   * Returns the renderer used by {@link #createGTRenderer()}.
-   * @see GTRendererType
-   */
-  public static GTRendererType getGTRendererType() {
-    return rendererType;
-  }
-  
 	/**
+	 * Creates a {@link GTRenderer}. This method can be used all over a project,
+	 * so the renderer can be switched easily.
+	 * 
+	 * @param mapContext
+	 *            a {@link MapContext} (can be {@code null})
+	 */
+	public static GTRenderer createGTRenderer(MapContext mapContext) {
+		GTRenderer renderer = createGTRenderer();
+		if (mapContext != null)
+			renderer.setContext(mapContext);
+		return renderer;
+	}
+
+	/**
+	 * Creates a {@link GTRenderer}. This method can be used all over a project,
+	 * so the renderer can be switched easily.
+	 * 
+	 * @param mapContext
+	 *            a {@link MapContext} (can be {@code null})
+	 * @param additionalRenderingHints
+	 *            A list of hints that will overload the default hints. May be
+	 *            <code>null</code>
+	 */
+	public static GTRenderer createGTRenderer(MapContext mapContext,
+			Map<Object, Object> additionalRenderingHints) {
+		GTRenderer renderer = createGTRenderer();
+		if (mapContext != null)
+			renderer.setContext(mapContext);
+
+		if (additionalRenderingHints != null)
+			renderer.getRendererHints().putAll(additionalRenderingHints);
+
+		return renderer;
+	}
+
+	/**
+	 * Creates a {@link GTRenderer}. This method can be used all over a project,
+	 * so the renderer can be switched easily. The {@link GTRenderer} is
+	 * initialized with the default renering hints for the kind of renderer.<br/>
+	 * 
+	 * @see #getDefaultGTRendererHints(GTRenderer)
+	 */
+	public static GTRenderer createGTRenderer() {
+		switch (rendererType) {
+		case ShapefileRenderer:
+			final ShapefileRenderer shapefileRenderer = new ShapefileRenderer();
+			shapefileRenderer
+					.setRendererHints(getDefaultGTRendererHints(shapefileRenderer));
+			return shapefileRenderer;
+		case StreamingRenderer:
+			final StreamingRenderer streamingRenderer = new StreamingRenderer();
+			streamingRenderer
+					.setRendererHints(getDefaultGTRendererHints(streamingRenderer));
+			return streamingRenderer;
+		}
+		throw new UnsupportedOperationException("Renderer type not supported: "
+				+ rendererType);
+	}
+
+	/**
+	 * Sets the renderer used by {@link #createGTRenderer()}.
+	 * 
+	 * @param rType
+	 *            renderer type
+	 * @see GTRendererType
+	 */
+	public static void setGTRendererType(GTRendererType rType) {
+		rendererType = rType;
+	}
+
+	/**
+	 * Returns the renderer used by {@link #createGTRenderer()}.
+	 * 
+	 * @see GTRendererType
+	 */
+	public static GTRendererType getGTRendererType() {
+		return rendererType;
+	}
+
+	/**
+	 * Returns the default RendererHints for a given {@link GTRenderer}. By
+	 * 2009/11/01 the {@link StreamingRenderer} needs
+	 * {@link StreamingRenderer.MEMORY_PRE_LOADING_KEY} false, whereas
+	 * {@link ShapefileRenderer} need its set to true.
+	 * 
+	 * @param renderer
+	 *            is <code>null</code>, the default {@link GTRendererType} is
+	 *            used.
+	 */
+	public static HashMap<Object, Object> getDefaultGTRendererHints(
+			GTRenderer renderer) {
+		// if (defaultRendererHints == null){
+		defaultRendererHints = new HashMap<Object, Object>();
+
+		/**
+		 * This hint avoids "Bursa Wolf Parameters missing" exceptions while
+		 * zooming which slow down the rendering process. The exceptions
+		 * appeared for example in maps that consisted only of layers of DHDN2
+		 * CRS.
+		 */
+		defaultRendererHints.put(
+				StreamingRenderer.SCALE_COMPUTATION_METHOD_KEY,
+				StreamingRenderer.SCALE_OGC);
+
+		defaultRendererHints.put(StreamingRenderer.OPTIMIZE_FTS_RENDERING_KEY,
+				Boolean.TRUE);
+
+		if (renderer instanceof ShapefileRenderer) {
+			defaultRendererHints.put(StreamingRenderer.MEMORY_PRE_LOADING_KEY,
+					Boolean.TRUE);
+		} else {
+			defaultRendererHints.put(StreamingRenderer.MEMORY_PRE_LOADING_KEY,
+					Boolean.FALSE);
+		}
+
+		defaultRendererHints.put(StreamingRenderer.OPTIMIZED_DATA_LOADING_KEY,
+				Boolean.TRUE);
+
+		defaultRendererHints.put(StreamingRenderer.LABEL_CACHE_KEY,
+				new LabelCacheImpl());
+
+		// public static final String DPI_KEY = "dpi";
+		// public static final String DECLARED_SCALE_DENOM_KEY =
+		// "declaredScaleDenominator";
+		// public static final String OPTIMIZED_DATA_LOADING_KEY =
+		// "optimizedDataLoadingEnabled";
+		// public static final String SCALE_COMPUTATION_METHOD_KEY =
+		// "scaleComputationMethod";
+
+		// }
+		return (HashMap<Object, Object>) defaultRendererHints.clone();
+	}
+
+	/**
+	 * Very similar to {@link MapContext#getLayerBounds()}, this may return
+	 * <code>null</code>. Different to {@link MapContext#getLayerBounds()}, this
+	 * instance only looks at visible layers.
+	 * 
+	 * @param localContext
 	 * @return
 	 */
-	public static HashMap<Object, Object> getDefaultGTRendererHints() {
-		if (defaultRendererHints == null){
-			defaultRendererHints = new HashMap<Object, Object>();
-			
-			/**
-			 * This hint avoids "Bursa Wolf Parameters missing" exceptions while
-			 * zooming which slow down the rendering process. The exceptions
-			 * appeared for example in maps that consisted only of layers of DHDN2
-			 * CRS. 
+	public static ReferencedEnvelope getVisibleLayoutBounds(MapContext context) {
+		ReferencedEnvelope result = null;
+		CoordinateReferenceSystem crs = context.getAreaOfInterest()
+				.getCoordinateReferenceSystem();
+
+		final int length = context.getLayerCount();
+		MapLayer layer;
+		FeatureSource<SimpleFeatureType, SimpleFeature> fs;
+		ReferencedEnvelope env;
+		CoordinateReferenceSystem sourceCrs;
+
+		for (int i = 0; i < length; i++) {
+			layer = context.getLayer(i);
+
+			if (!layer.isVisible())
+				continue;
+			/*
+			 * fs = layer.getFeatureSource(); sourceCrs =
+			 * fs.getSchema().getDefaultGeometry() .getCoordinateSystem(); env =
+			 * new ReferencedEnvelope(fs.getBounds(), sourceCrs);
 			 */
-			defaultRendererHints.put(
-					StreamingRenderer.SCALE_COMPUTATION_METHOD_KEY,
-					StreamingRenderer.SCALE_OGC);
-			
-			
-			
+
+			env = layer.getBounds();
+			if (env == null) {
+				continue;
+			} else {
+				try {
+					sourceCrs = env.getCoordinateReferenceSystem();
+					if ((sourceCrs != null) && crs != null
+							&& !CRS.equalsIgnoreMetadata(sourceCrs, crs)) {
+						env = env.transform(crs, true);
+					}
+
+				} catch (FactoryException e) {
+					LOGGER
+							.warn(
+									"Data source and map context coordinate system differ, yet it was not possible to get a projected bounds estimate...",
+									e);
+				} catch (TransformException e) {
+					LOGGER
+							.warn(
+									"Data source and map context coordinate system differ, yet it was not possible to get a projected bounds estimate...",
+									e);
+				}
+
+				if (result == null) {
+					result = env;
+				} else {
+					result.expandToInclude(env);
+				}
+			}
 		}
-		return (HashMap<Object, Object>) defaultRendererHints.clone();
+
+		return result;
 	}
 
-
 }

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/JTSUtil.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/JTSUtil.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/JTSUtil.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -67,20 +67,22 @@
     );
   }
 
-  /**
-   * Expands an {@link Envelope} by percentage.
-   * @param env the {@link Envelope}
-   * @param pct percentage (e.g. 0.1 = 10%) to expands the envelope by
-   */
-  public static Envelope expandEnvelope(Envelope env, double pct) {
-    final Envelope expandedEnv = new Envelope(env);
-    expandedEnv.expandBy(
-        env.getWidth() * pct,
-        env.getHeight() * pct
-    );
-    return expandedEnv;
-  }
+	/**
+	 * Expands an {@link Envelope} by percentage.
+	 * 
+	 * @param env
+	 *            the {@link Envelope}
+	 * @param pct
+	 *            percentage (e.g. 0.1 = 10%) to expands the envelope by.
+	 *            Negative values are allowed.
+	 */
+	public static Envelope expandEnvelope(Envelope env, double pct) {
+		final Envelope expandedEnv = new Envelope(env);
+		expandedEnv.expandBy(env.getWidth() * pct, env.getHeight() * pct);
+		return expandedEnv;
+	}
 
+	
   /**
    * Transformiert einen JTS-Envelope von einem CRS in ein anderes. Wenn Bursa-Wolf parameter fehlen, wird lenient gerechnet.
    * @param sourceEnv JTS-Envelope
@@ -129,7 +131,7 @@
   
   /**
    * Returns an {@link Envelope} that has the same aspect ratio as the given rectangle
-   * @param r
+   * @param rect
    *             defines the aspect ratio the map area is fixed with (e.g. a
    *             gui components size)
    * @param mapArea
@@ -138,7 +140,7 @@
    *            If <code>true</code>, than the area will be enlarged to match
    *            the aspect ratio. If <code>false</code>, it will only shrink.
    */
-  public static Envelope fixAspectRatio(final Rectangle r, final Envelope mapArea,
+  public static Envelope fixAspectRatio(final Rectangle rect, final Envelope mapArea,
           boolean grow) {
       // no map area to fix the aspect ratio for
       if (mapArea == null) {
@@ -146,19 +148,19 @@
           return null;
       }
       // no component size to fix the aspect ratio with
-      if ( r == null || r.width == 0 || r.height == 0 ) {
+      if ( rect == null || rect.width == 0 || rect.height == 0 ) {
         LOGGER.warn("Empty rectangle in method fixAspectRatio, returning an unmodified mapArea!");
         return mapArea;
       }
 
       final double mapWidth = mapArea.getWidth(); /* get the extent of the map */
       final double mapHeight = mapArea.getHeight();
-      final double scaleX = r.getWidth() / mapArea.getWidth(); /*
+      final double scaleX = rect.getWidth() / mapArea.getWidth(); /*
                                                                * calculate the
                                                                * new scale
                                                                */
 
-      final double scaleY = r.getHeight() / mapArea.getHeight();
+      final double scaleY = rect.getHeight() / mapArea.getHeight();
       double scale = 1.0; // stupid compiler!
 
       if ((grow && scaleX < scaleY) || (!grow && scaleX > scaleY)) {
@@ -168,8 +170,8 @@
       }
 
       /* calculate the difference in width and height of the new extent */
-      final double deltaX = /* Math.abs */((r.getWidth() / scale) - mapWidth);
-      final double deltaY = /* Math.abs */((r.getHeight() / scale) - mapHeight);
+      final double deltaX = /* Math.abs */((rect.getWidth() / scale) - mapWidth);
+      final double deltaY = /* Math.abs */((rect.getHeight() / scale) - mapHeight);
 
       /*
        * System.out.println("delta x " + deltaX);

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/feature/FeatureUtil.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/feature/FeatureUtil.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/feature/FeatureUtil.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -2024,6 +2024,11 @@
 		return g.getCentroid();
 	}
 
+	public static Object getLayerSourceObject(MapLayer mapLayer) {
+		return 	getWrappedGeoObject((FeatureSource<SimpleFeatureType, SimpleFeature>) mapLayer
+				.getFeatureSource());
+	}
+
 	// /**
 	// * Extrahiert alle Geometrien aus einer FeatureCollection. Fuer jedes
 	// * Geometry-Attribut der FeatureCollection wird eine GeometrieCollection

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/FeatureLayerFilterDialog.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/FeatureLayerFilterDialog.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/FeatureLayerFilterDialog.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -123,7 +123,7 @@
 
 	private String frameTitle = GeotoolsGUIUtil.RESOURCE
 			.getString(DIALOG_TITLE);
-	private JMapPane mapPane = null;
+	private SelectableXMapPane mapPane = null;
 	private MapLayer layer = null;
 
 	/**
@@ -146,7 +146,7 @@
 	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
 	 *         Kr&uuml;ger</a>
 	 */
-	public FeatureLayerFilterDialog(Window parent, JMapPane mapPane,
+	public FeatureLayerFilterDialog(Window parent, SelectableXMapPane mapPane,
 			MapLayer mapLayer) {
 		this(parent, mapPane, mapLayer, true);
 	}
@@ -175,7 +175,7 @@
 	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
 	 *         Kr&uuml;ger</a>
 	 */
-	protected FeatureLayerFilterDialog(Window parent, JMapPane mapPane,
+	protected FeatureLayerFilterDialog(Window parent, SelectableXMapPane mapPane,
 			MapLayer mapLayer, boolean initGUI) {
 		super(parent);
 		setModal(true);
@@ -306,7 +306,7 @@
 	 * Liefert das MapPane, fuer das {@link FeatureSelectedEvent
 	 * FeatureSelectedEvents} ausgeloest werden.
 	 */
-	public JMapPane getMapPane() {
+	public SelectableXMapPane getMapPane() {
 		return mapPane;
 	}
 

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/FeatureTablePane.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/FeatureTablePane.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/FeatureTablePane.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -29,11 +29,11 @@
  ******************************************************************************/
 package schmitzm.geotools.gui;
 
+import gtmig.org.geotools.swing.XMapPane;
+
 import java.awt.BorderLayout;
 import java.awt.Color;
 import java.awt.Dimension;
-import java.util.HashMap;
-import java.util.Map;
 
 import javax.swing.BorderFactory;
 import javax.swing.JScrollPane;
@@ -48,7 +48,6 @@
 import org.apache.log4j.Logger;
 import org.geotools.feature.FeatureCollection;
 import org.geotools.map.DefaultMapLayer;
-import org.geotools.renderer.lite.StreamingRenderer;
 import org.geotools.styling.Style;
 import org.opengis.feature.simple.SimpleFeature;
 import org.opengis.feature.simple.SimpleFeatureType;
@@ -84,7 +83,7 @@
 	/** Tabellen-Modell der SimpleFeature-Tabelle. */
 	protected FeatureCollectionTableModel featuresTableModel = null;
 	/** Preview-Bereich fuer die in der Tabelle selektierten Features. */
-	protected JMapPane mapPane = null;
+	protected XMapPane mapPane = null;
 	/** Style, in dem die Features in der Karte dargestellt werden */
 	protected Style featureStyle = null;
 
@@ -223,19 +222,8 @@
 		setLayout(new BorderLayout());
 		// MapPane fuer Preview der in der Tabelle selektieren Features
 		if (geomPreview) {
-			this.mapPane = new JMapPane();
+			this.mapPane = new XMapPane();
 			
-			/**
-			 * Add the rendering hint to use the not-so-accurate scale calculations. We
-			 * don't want annoying Bursa-Wolf-Pameter-missing exception coming
-			 * from the preview JMapPane
-			 */
-			Map<Object, Object> hints = this.mapPane.getRenderer()
-					.getRendererHints();
-			if (hints == null) 
-				hints = new HashMap<Object, Object>();
-			hints.put(StreamingRenderer.SCALE_COMPUTATION_METHOD_KEY, StreamingRenderer.SCALE_OGC);
-
 			// {
 			// // Bei Links-Klick auf das gesamte Layer zoomen
 			// public void mouseClicked(MouseEvent e) {
@@ -254,8 +242,7 @@
 			// };
 			mapPane.setToolTipText(GeotoolsGUIUtil.R(PREVIEW_MAPPANE_TOOLTIP));
 
-			mapPane.setState(JMapPane.RESET);
-			mapPane.setWindowSelectionState(JMapPane.NONE);
+			mapPane.setState(SelectableXMapPane.NONE);
 			mapPane.setMinimumSize(new Dimension(100, 100));
 			SwingUtil.setPreferredWidth(mapPane, 200);
 			mapPane.setBorder(BorderFactory.createLoweredBevelBorder());
@@ -442,6 +429,6 @@
 		}
 
 		// Vorschaukarte aktualisieren
-		mapPane.refresh();
+		mapPane.repaint();
 	}
 }

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/GeoMapPane.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/GeoMapPane.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/GeoMapPane.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -36,15 +36,13 @@
 import java.awt.Insets;
 import java.util.HashMap;
 
-import javax.swing.BorderFactory;
-
 import org.geotools.map.MapContext;
 import org.geotools.renderer.GTRenderer;
 import org.geotools.renderer.lite.StreamingRenderer;
 import org.geotools.renderer.shape.ShapefileRenderer;
 
 import schmitzm.geotools.GTUtil;
-import schmitzm.geotools.map.event.JMapPaneEvent;
+import schmitzm.geotools.map.event.MapPaneEvent;
 import schmitzm.geotools.map.event.JMapPaneListener;
 import schmitzm.geotools.map.event.MapAreaChangedEvent;
 import schmitzm.geotools.map.event.ScaleChangedEvent;
@@ -52,7 +50,7 @@
 import schmitzm.swing.SwingUtil;
 
 /**
- * Das {@code GeoMapPane} erweitert das {@link JMapPane} um einen
+ * Das {@code GeoMapPane} erweitert das {@link SelectableXMapPane} um einen
  * Massstab-Balken, sowie ein horizontales und vertikales Koordinaten-Raster
  * (Grid), in dem die Geo-Referenz des angezeigten Karten-Bereichs angezeigt wird. 
  * 
@@ -97,7 +95,7 @@
 	protected HashMap<String, GridBagConstraints> layoutConstraints = new HashMap<String, GridBagConstraints>();
 
 	/** Karten-Bereich des {@code GeoMapPane}. */
-	protected JMapPane mapPane = null;
+	protected SelectableXMapPane mapPane = null;
 	/** Massstab-Balken */
 	private ScalePane scalePane = null;
 	/**
@@ -117,14 +115,11 @@
 	 */
 	private boolean disposed = false;
 	
-	
-	private static HashMap<Object, Object> defaultRendererHints;
-
 	/**
 	 * Erzeugt ein neues {@code GeoMapPane}.
 	 */
 	public GeoMapPane() {
-		this(null, null, null, null, null);
+		this(null, null, null, null);
 	}
 
 	/**
@@ -147,9 +142,11 @@
 	 *            which is cool for creating PDF, SVG.. And the much faster
 	 *            {@link ShapefileRenderer}. Defaults to {@link GTUtil#createGTRenderer(MapContext)}
 	 */
-	public GeoMapPane(JMapPane mapPane, GridPanel vGrid, GridPanel hGrid,
-			ScalePane scalePane, GTRenderer renderer) {
+	public GeoMapPane(SelectableXMapPane mapPane, GridPanel vGrid, GridPanel hGrid,
+			ScalePane scalePane) {
 		this.scalePane = scalePane;
+		
+		setOpaque(true);
 
 		if (vGrid != null && !vGrid.isVertical())
 			throw new IllegalArgumentException(
@@ -159,7 +156,7 @@
 					"GridPanel for horizontal grid must be of type GridPanel.HORIZONTAL!!");
 
 		// Karte
-		this.mapPane = (mapPane != null) ? mapPane : new JMapPane(null,null,renderer, null, GTUtil.getDefaultGTRendererHints());
+		this.mapPane = (mapPane != null) ? mapPane : new SelectableXMapPane();
 		// Koordinaten-Leisten
 		this.setVertGrid((vGrid != null) ? vGrid : new GridPanel(
 				GridPanel.VERTICAL, this.mapPane));
@@ -196,12 +193,12 @@
 		this.setLayout(new GridBagLayout());
 
 		// Karten-Darestellung initialisieren
-		this.mapPane.setBorder(BorderFactory.createLoweredBevelBorder());
+//		this.mapPane.setBorder(BorderFactory.createLoweredBevelBorder());
 		SwingUtil.setPreferredWidth(this.mapPane, 200);
 
 		// MapListener that listens to Scale and MapArea changes
 		this.mapPane.addMapPaneListener(new JMapPaneListener() {
-			public void performMapPaneEvent(JMapPaneEvent e) {
+			public void performMapPaneEvent(MapPaneEvent e) {
 				if (e instanceof ScaleChangedEvent) {
 					ScaleChangedEvent sce = (ScaleChangedEvent) e;
 					getScalePane().setScale(sce.getNewScale());
@@ -231,7 +228,7 @@
 	/**
 	 * Aktualisiert die Karten-Darstellung.
 	 * 
-	 * @see JMapPane#refresh()
+	 * @see SelectableXMapPane#refresh()
 	 */
 	public void refreshMap() {
 		mapPane.refresh();
@@ -251,9 +248,9 @@
 	}
 
 	/**
-	 * Liefert das {@link JMapPane}, in dem die Karten dargestellt werden.
+	 * Liefert das {@link SelectableXMapPane}, in dem die Karten dargestellt werden.
 	 */
-	public final JMapPane getMapPane() {
+	public final SelectableXMapPane getMapPane() {
 		return mapPane;
 	}
 

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/GeoPositionLabel.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/GeoPositionLabel.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/GeoPositionLabel.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -45,15 +45,15 @@
  * angezeigt werden. Dabei werden die Koordinaten auf eine bestimmte Anzahl
  * an Nachkommastellen gerundet.<br>
  * Die Klasse fungiert als {@link MouseListener} und {@link MouseMotionListener} und
- * kann so direkt an ein {@link JMapPane} gekoppelt werden. Die Koordinaten-Darstellung
+ * kann so direkt an ein {@link SelectableXMapPane} gekoppelt werden. Die Koordinaten-Darstellung
  * im Label aktualisiert sich somit automatisch, sobald sich die Maus ueber die
  * Karte bewegt. Wird ein Kartenbereich selektiert (gedrueckte linke Maustaste),
  * werden neben der aktuellen Position auch die Koordinaten des Selektionsstart
  * angezeigt.<br>
  * <b>Bemerke:</b><br>
- * Eine Instanz des <code>GeoPositionLabel</code> muss dem {@link JMapPane} sowohl
- * als {@linkplain JMapPane#addMouseListener(MouseListener) MouseListener}, als
- * auch als {@linkplain JMapPane#addMouseMotionListener(MouseMotionListener) MouseMotionListener}
+ * Eine Instanz des <code>GeoPositionLabel</code> muss dem {@link SelectableXMapPane} sowohl
+ * als {@linkplain SelectableXMapPane#addMouseListener(MouseListener) MouseListener}, als
+ * auch als {@linkplain SelectableXMapPane#addMouseMotionListener(MouseMotionListener) MouseMotionListener}
  * hinzugefuegt werden. Ansonsten bekommt es nicht alle notwendigen Informationen
  * mit!
  * @see #setFractionDigits(int)
@@ -99,18 +99,18 @@
 
   /**
    * Stellt die Koordinaten im Label dar, wenn es sich bei dem Event um
-   * ein {@link GeoMouseEvent} handelt  oder das Event von einem {@link JMapPane}
+   * ein {@link GeoMouseEvent} handelt  oder das Event von einem {@link SelectableXMapPane}
    * ausgeloest wurde.<br>
    * Wird von {@link #mousePressed(MouseEvent)}, {@link #mouseMoved(MouseEvent)}
    * und {@link #mouseDragged(MouseEvent)} aufgerufen.
    * @see #createGeoPositionString(Point2D,Point2D)
    */
   protected void displayCoordinates(final MouseEvent e) {
-    if ( e==null || !(e instanceof MapMouseEvent) && !(e.getSource() instanceof JMapPane) )
+    if ( e==null || !(e instanceof MapMouseEvent) && !(e.getSource() instanceof SelectableXMapPane) )
       return;
 
     // aktuelle Geo-Position ermitteln und runden
-    final Point2D actCoord = JMapPane.getMapCoordinatesFromEvent(e);
+    final Point2D actCoord = SelectableXMapPane.getMapCoordinatesFromEvent(e);
     if ( actCoord == null )
       return;
     final double actLat = Math.round(actCoord.getX() * fracFactor) / fracFactor;
@@ -172,11 +172,11 @@
   /**
    * Wird aufgerufen, wenn der Maus-Button gedrueckt wird.
    * Handelt es sich bei dem Event um ein {@link GeoMouseEvent} oder das Event
-   * von einem {@link JMapPane} ausgeloest wurde, werden die
+   * von einem {@link SelectableXMapPane} ausgeloest wurde, werden die
    * aktuellen Koordinaten in {@link #selStartCoord} gespeichert.
    */
   public void mousePressed(final MouseEvent e) {
-    final Point2D p = JMapPane.getMapCoordinatesFromEvent(e);
+    final Point2D p = SelectableXMapPane.getMapCoordinatesFromEvent(e);
     if ( p != null && e.getButton() == MouseEvent.BUTTON1) {
       selStartCoord = p;
       //MS: on simple click the Envelope-Coordinates should not
@@ -202,7 +202,7 @@
   /**
    * Wird aufgerufen, sobald die Maus bewegt wird.
    * Stellt die Koordinaten im Label dar, wenn es sich bei dem Event um ein
-   * {@link GeoMouseEvent} handelt oder das Event von einem {@link JMapPane}
+   * {@link GeoMouseEvent} handelt oder das Event von einem {@link SelectableXMapPane}
    * ausgeloest wurde.
    */
   public void mouseMoved(final MouseEvent e) {
@@ -212,7 +212,7 @@
   /**
    * Wird aufgerufen, sobald die Maus bei gedrueckter Taste bewegt wird.
    * Stellt die Koordinaten im Label dar, wenn es sich bei dem Event um ein
-   * {@link GeoMouseEvent} handelt oder das Event von einem {@link JMapPane}
+   * {@link GeoMouseEvent} handelt oder das Event von einem {@link SelectableXMapPane}
    * ausgeloest wurde.
    */
   public void mouseDragged(final MouseEvent e) {

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/GridPanel.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/GridPanel.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/GridPanel.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -48,7 +48,7 @@
 
 /**
  * Diese Klasse stellt eine horizontale oder vertikale Koordinaten-Leiste (Grid)
- * dar, die an ein {@link JMapPane} gekoppelt ist.
+ * dar, die an ein {@link SelectableXMapPane} gekoppelt ist.
  * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
  * @version 1.0
  */
@@ -71,7 +71,7 @@
   private int orientation = 0;
 
   /** Karte, an der die Koordinaten-Leiste ausgerichtet wird. */
-  protected JMapPane mapPane = null;
+  protected SelectableXMapPane mapPane = null;
 
   /** Transformation von Karten-CRS zu CRS des Koordinaten-Rasters */
   protected MathTransform mapToGrid = null;
@@ -87,24 +87,24 @@
   protected boolean forceXYIndexSwitch = false;
   
   /**
-   * Erzeugt eine WGS84-Koordinaten-Leiste fuer ein {@link JMapPane}.
+   * Erzeugt eine WGS84-Koordinaten-Leiste fuer ein {@link SelectableXMapPane}.
    * @param orientation Orientierung ({@link #HORIZONTAL} oder {@link #VERTICAL})
    * @param mapPane     Karte an der die Koordinaten-Leiste ausgerichtet wird
    * @see GridPanelFormatter_LatLon1
    */
-  public GridPanel(int orientation, JMapPane mapPane) {
+  public GridPanel(int orientation, SelectableXMapPane mapPane) {
     this(orientation,mapPane,null);
   }
 
   /**
-   * Erzeugt eine Koordinaten-Leiste fuer ein {@link JMapPane}.
+   * Erzeugt eine Koordinaten-Leiste fuer ein {@link SelectableXMapPane}.
    * @param orientation Orientierung ({@link #HORIZONTAL} oder {@link #VERTICAL})
    * @param mapPane     Karte an der die Koordinaten-Leiste ausgerichtet wird
    * @param formatter   definiert das CRS und Koordinaten-Format fuer die Koordinaten
    *                    Leiste (wenn {@code null} wird ein {@link GridPanelFormatter_LatLon1}
    *                    verwendet)
    */
-  public GridPanel(int orientation, JMapPane mapPane, GridPanelFormatter formatter) {
+  public GridPanel(int orientation, SelectableXMapPane mapPane, GridPanelFormatter formatter) {
     this.orientation = orientation;
     this.mapPane     = mapPane;
     setGridFormatter(formatter);
@@ -210,7 +210,7 @@
     g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
     
     
-    if ( getParent() == null || mapPane.getMapArea() == null )
+    if ( getParent() == null || !mapPane.isWellDefined())
       return;
 
     CoordinateReferenceSystem mapCRS = null;   // (aktuelles) CRS des MapPane
@@ -322,7 +322,7 @@
    double   firstGrid = Math.ceil(mapMin/gridDist)*gridDist; // 1. Abschnitt in Lat bzw. Lon
    double[] grid_GCRS = mapMin_GCRS.clone(); // Ausgangspunkt
    double[] grid_MCRS = new double[2];
-   AffineTransform mapToWin = mapPane.getTransform();
+   AffineTransform mapToWin = mapPane.getScreenToWorld();
    for (double gridPos=firstGrid; gridPos<=mapMax; gridPos+=gridDist) {
      grid_GCRS[idx] = gridPos;
      // In Map-CRS und dann in Fenster-Koordinaten transformieren

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/JEditorPane.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/JEditorPane.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/JEditorPane.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -29,11 +29,9 @@
  ******************************************************************************/
 package schmitzm.geotools.gui;
 
-import java.awt.BorderLayout;
 import java.awt.Color;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
-import java.awt.LayoutManager;
 import java.awt.Rectangle;
 import java.awt.event.MouseEvent;
 import java.awt.geom.Point2D;
@@ -78,12 +76,12 @@
 
 
 /**
- * The {@code GeoEditorPane} extends the {@link JMapPane} with functionalities
+ * The {@code GeoEditorPane} extends the {@link SelectableXMapPane} with functionalities
  * to create new vector layers by successively click points via mouse.
  * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
  * @version 1.0
  */
-public class JEditorPane extends JMapPane {
+public class JEditorPane extends SelectableXMapPane {
   /** Modes, the editor can be perform.
    *  @see JEditorPane#startEditing(EditorMode, String, Style) */
   public static enum EditorMode {
@@ -181,11 +179,6 @@
    * Creates a new {@code GeoEditorPane}.
    */
   public JEditorPane() {
-    this( new BorderLayout(),
-          true,
-          GTUtil.createGTRenderer(),
-          new DefaultMapContext(DefaultGeographicCRS.WGS84)
-    );
   }
 
   /**
@@ -194,8 +187,8 @@
    * <b>The specified parameter all can be {@code null}! In this case
    * the respective default component is used.</b>
    */
-  public JEditorPane(LayoutManager layout, boolean isDoubleBuffered, GTRenderer renderer, MapContext context) {
-    super(layout,isDoubleBuffered,renderer,context);
+  public JEditorPane(MapContext context) {
+    super(context);
     this.mapContext = getContext();
     // initalize the editor styles
     this.editorStyles = new HashMap<GeometryForm, Style>();
@@ -204,7 +197,7 @@
 
     // no standard action on left mouse button, instead: adding points
     setState( NONE );
-    setWindowSelectionState( ZOOM_IN );
+    setState( ZOOM_IN );
     // special map context for the editor layers, so the
     // editor layers are not shown in "normal" layer list
     this.editorMapContext = new DefaultMapContext( mapContext.getCoordinateReferenceSystem() );
@@ -217,7 +210,7 @@
     attrInputOption = new FeatureInputOption(null,true,(SimpleFeature)null);
   }
 
-  /**
+/**
    * After the actions of the super method, this method paints the
    * special editor layers in {@link #editorMapContext}.
    */
@@ -236,7 +229,7 @@
    * editor mode.
    */
   public void mouseClicked(MouseEvent e) {
-    Point2D geoCoord = getTransform().transform(e.getPoint(), null);
+    Point2D geoCoord = getScreenToWorld().transform(e.getPoint(), null);
     // Zunaechst Modus auf NULL pruefen, da ansonsten
     // NullPointerException in switch-Statement
     if ( editorMode == null )

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/JEditorToolBar.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/JEditorToolBar.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/JEditorToolBar.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -45,7 +45,7 @@
 
 import schmitzm.geotools.gui.JEditorPane.EditorMode;
 import schmitzm.geotools.map.event.JEditorPaneEvent;
-import schmitzm.geotools.map.event.JMapPaneEvent;
+import schmitzm.geotools.map.event.MapPaneEvent;
 import schmitzm.geotools.map.event.JMapPaneListener;
 import schmitzm.geotools.map.event.LayerEditCanceledEvent;
 import schmitzm.geotools.map.event.LayerEditFinishedEvent;
@@ -101,7 +101,7 @@
       this.actionButtons   = new TreeMap<Integer,JButton>();
       // Create a Listener to sniff the zooms on the JMapPane
       this.mapPaneListener = new JMapPaneListener() {
-          public void performMapPaneEvent(JMapPaneEvent e) {
+          public void performMapPaneEvent(MapPaneEvent e) {
               if ( !(e instanceof JEditorPaneEvent) )
                 return;
 

Deleted: branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/JMapPane.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/JMapPane.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/JMapPane.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -1,2940 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009 Martin O. J. Schmitz.
- * 
- * This file is part of the SCHMITZM library - a collection of utility 
- * classes based on Java 1.6, focusing (not only) on Java Swing 
- * and the Geotools library.
- * 
- * The SCHMITZM project is hosted at:
- * http://wald.intevation.org/projects/schmitzm/
- * 
- * 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:
- *     Martin O. J. Schmitz - initial API and implementation
- *     Stefan A. Krüger - additional utility classes
- ******************************************************************************/
-package schmitzm.geotools.gui;
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Cursor;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.LayoutManager;
-import java.awt.Point;
-import java.awt.RenderingHints;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseWheelEvent;
-import java.awt.event.MouseWheelListener;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.NoninvertibleTransformException;
-import java.awt.geom.Point2D;
-import java.awt.image.BufferedImage;
-import java.awt.image.ImageObserver;
-import java.io.IOException;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Vector;
-
-import javax.swing.JList;
-import javax.swing.SwingUtilities;
-import javax.swing.event.MouseInputAdapter;
-
-import org.apache.log4j.Logger;
-import org.geotools.coverage.grid.GeneralGridEnvelope;
-import org.geotools.coverage.grid.GridCoverage2D;
-import org.geotools.coverage.grid.GridGeometry2D;
-import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
-import org.geotools.coverage.grid.io.AbstractGridFormat;
-import org.geotools.data.FeatureSource;
-import org.geotools.data.memory.MemoryFeatureCollection;
-import org.geotools.factory.GeoTools;
-import org.geotools.feature.FeatureCollection;
-import org.geotools.filter.AbstractFilter;
-import org.geotools.filter.GeometryFilterImpl;
-import org.geotools.filter.spatial.DWithinImpl;
-import org.geotools.geometry.GeneralEnvelope;
-import org.geotools.geometry.jts.JTS;
-import org.geotools.geometry.jts.ReferencedEnvelope;
-import org.geotools.map.DefaultMapContext;
-import org.geotools.map.MapContext;
-import org.geotools.map.MapLayer;
-import org.geotools.map.event.MapLayerListEvent;
-import org.geotools.parameter.Parameter;
-import org.geotools.referencing.CRS;
-import org.geotools.renderer.GTRenderer;
-import org.geotools.renderer.lite.RendererUtilities;
-import org.geotools.renderer.lite.StreamingRenderer;
-import org.geotools.resources.coverage.FeatureUtilities;
-import org.geotools.resources.image.ImageUtilities;
-import org.geotools.styling.Style;
-import org.geotools.swing.event.MapMouseEvent;
-import org.opengis.coverage.CannotEvaluateException;
-import org.opengis.feature.simple.SimpleFeature;
-import org.opengis.feature.simple.SimpleFeatureType;
-import org.opengis.feature.type.GeometryDescriptor;
-import org.opengis.filter.Filter;
-import org.opengis.filter.FilterFactory;
-import org.opengis.filter.expression.Expression;
-import org.opengis.filter.spatial.BinarySpatialOperator;
-import org.opengis.parameter.GeneralParameterValue;
-import org.opengis.referencing.FactoryException;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.opengis.referencing.operation.MathTransform;
-import org.opengis.referencing.operation.TransformException;
-
-import schmitzm.geotools.FilterUtil;
-import schmitzm.geotools.GTUtil;
-import schmitzm.geotools.JTSUtil;
-import schmitzm.geotools.feature.FeatureUtil;
-import schmitzm.geotools.grid.GridUtil;
-import schmitzm.geotools.io.GeoImportUtil;
-import schmitzm.geotools.map.event.FeatureSelectedEvent;
-import schmitzm.geotools.map.event.GeneralSelectionEvent;
-import schmitzm.geotools.map.event.GridCoverageSelectedEvent;
-import schmitzm.geotools.map.event.GridCoverageValueSelectedEvent;
-import schmitzm.geotools.map.event.JMapPaneEvent;
-import schmitzm.geotools.map.event.JMapPaneListener;
-import schmitzm.geotools.map.event.MapAreaChangedEvent;
-import schmitzm.geotools.map.event.MapLayerListAdapter;
-import schmitzm.geotools.map.event.ScaleChangedEvent;
-import schmitzm.geotools.styling.StylingUtil;
-import schmitzm.swing.SwingUtil;
-
-import com.vividsolutions.jts.geom.Coordinate;
-import com.vividsolutions.jts.geom.Envelope;
-import com.vividsolutions.jts.geom.Geometry;
-import com.vividsolutions.jts.geom.GeometryFactory;
-
-/**
- * Diese Klasse erweitert die Geotools-Klasse
- * {@link org.geotools.swing.JMapPane} um folgende Features:
- * <ul>
- * <li>zusaetzliche Maus-Steuerungen:
- * <ul>
- * <li><b>Linksklick:</b> ueber {@link #setState(int)} eingestellte Aktion</li>
- * <li><b>Rechtsklick:</b> Zoom-Out um Faktor 2 (nur wenn Linksklick auf Zoom-In
- * eingestellt ist)</li>
- * <li><b>Drag mit linker Maustaste:</b> neuen Karten-Bereich selektieren oder
- * Features selektieren (siehe {@link #setWindowSelectionState(int)})</li>
- * <li><b>Drag mit rechter Maustaste:</b> Karten-Bereich verschieben</li>
- * <li><b>Mausrad:</b> Zoom-In/Out ueber aktueller Position (Faktor 1.2)</li>
- * </ul>
- * </li>
- * <li>Ankoppeln von {@link JMapPaneListener} und Ausloesung diverser
- * Ereignisse:
- * <ul>
- * <li><b>{@link ScaleChangedEvent}:</b> Wird ausgeloest, wenn sich die
- * Aufloesung der angezeigten Karte aendert</li>
- * <li><b>{@link MapAreaChangedEvent}:</b> Wird ausgeloest, wenn sich die
- * Aufloesung angezeigte Karte-Ausschnitt aendert</li>
- * <li><b>{@link GeneralSelectionEvent}:</b> Wird ausgeloest, wenn der Anwender
- * einen Bereich aus der Karte ausgewaehlt hat (egal ob dabei gezoomt wurde,
- * Features/Raster selektiert wurden, oder nicht selektiert wurde)</li>
- * <li><b>{@link FeatureSelectedEvent}:</b> Wird ausgeloest, wenn der Anwender
- * Features aus der Karte ausgewaehlt hat</li>
- * <li><b>{@link GridCoverageSelectedEvent}:</b> Wird ausgeloest, wenn der
- * Anwender Raster-Bereiche aus der Karte ausgewaehlt hat</li>
- * </ul>
- * </li>
- * </ul>
- * Sofern eingeschaltet, erfolgt {@linkplain #setHighlight(boolean)
- * Highlighting} immer auf dem obersten sichtbaren Nicht-Raster-Layer.<br>
- * Darueberhinaus besteht ueber {@link #getTransform()} Zugriff auf eine
- * {@linkplain AffineTransform affine Transformation} mit der die aktuellen
- * Fenster-Koordinaten (z.B. eines <code>MouseEvent</code>) in
- * Karten-Koordinaten (Latitude/Longitude) umgerechnet werden koennen.
- * 
- * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
- *         (University of Bonn/Germany)
- * @version 1.0
- */
-public class JMapPane extends gtmig.org.geotools.swing.JMapPane {
-	
-	/** Stored the time used for the last real rendering in ms. **/
-	private long lastRenderingDuration = Long.MAX_VALUE; 
-
-	/**
-	 * SK: Nach dem Drag, soll die {@link GeoMapPane} erfahren, dass die Area
-	 * veraendert wurde.
-	 */
-	protected void processDrag(int x1, int y1, int x2, int y2, MouseEvent e) {
-		// MS, 26.05.2008: Zoom-Funktion der Oberklasse soll nur erfolgen, wenn
-		// diese auch fuer die WindowSelection-Aktion eingestellt ist!
-		// Wenn z.B. fuer Links-Klick ZOOM_IN eingestellt ist, fuer
-		// Links-Drag aber SELECT_TOP, dann soll kein Zoom beim
-		// Links-Drag erfolgen!!
-		// Ausnahme: Bei Rechts-Drag (Button 3) soll die Methode
-		// trotzdem aufgerufen werden fuer Pan!
-		
-		if (getState() == ZOOM_IN && getWindowSelectionState() != ZOOM_IN
-				&& e.getButton() != 3)
-			return;
-		
-		super.processDrag(x1, y1, x2, y2, e);
-
-		// SK, 19.6.2009:
-		// Ein MapAreaChangedEvent soll nur geworfen werden, wenn auch gezoomt
-		// wurde! Irgendwie wird das auch aufgerufen, wenn man mit InfoClick
-		// tool nur click - also garkeit kein draggin gemacht hat.
-		if ((oldMapArea == null || !oldMapArea.equals(mapArea))
-				&& (getState() == ZOOM_IN || getState() == ZOOM_OUT))
-		{
-			
-			// Draw a quick scaled preview image, so the user is not do bored
-			drawScaledPreviewImage_Zoom(getState());
-			
-			fireMapPaneEvent(new MapAreaChangedEvent(this, oldMapArea, mapArea));
-		}
-		
-			
-	}
-
-	/**
-	 * Diretly paints scaled preview into the {@link JMapPane}. Used to give the
-	 * user something to look at while we are rendering. Method should be called
-	 * after {@link #setMapArea(Envelope)} has been set to the new mapArea and
-	 * transform has been reset.<br/>
-	 * This method does nothing if the {@link #lastRenderingDuration} is smaller
-	 * then a trashhold.
-	 * 
-	 * @param state Max be {@link #ZOOM_IN} or {@link #ZOOM_OUT}
-	 */
-	private void drawScaledPreviewImage_Zoom(int state) {
-		
-		
-		if (state == ZOOM_IN) {
-			
-		
-		if (lastRenderingDuration < 220) 
-			return;
-
-		if (getTransform() != null && getTransform().equals(oldTransform))
-			return;
-
-		Graphics2D graphics = (Graphics2D) JMapPane.this.getGraphics();
-		Envelope gg = tranformGeoToWindow(mapArea.getMinX(), mapArea.getMinY(),
-				mapArea.getMaxX(), mapArea.getMaxY(), oldTransform);
-
-		graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
-				RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
-		graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
-				RenderingHints.VALUE_ANTIALIAS_OFF);
-		graphics.setRenderingHint(RenderingHints.KEY_RENDERING,
-				RenderingHints.VALUE_RENDER_SPEED);
-
-		int xx1 = (int) Math.round( gg.getMinX() );
-		int yy1 = (int) Math.round(gg.getMinY());
-		int xx2 = (int) Math.round(gg.getMaxX());
-		int yy2 = (int) Math.round(gg.getMaxY());
-
-		graphics.setBackground(getMapBackgroundColor());
-		graphics.drawImage(baseImage, 0, 0, JMapPane.this.getWidth(),
-				JMapPane.this.getHeight(), xx1, yy1, xx2, yy2, null);
-		} else if (state == ZOOM_OUT){
-
-			if (lastRenderingDuration < 400) // This number is higher, because the zoom out preview image is uglier (while borders) 
-				return;
-
-			if (mapArea != null && mapArea.equals(oldMapArea)) 
-				return;
-
-			Graphics2D graphics = (Graphics2D) JMapPane.this.getGraphics();
-			Envelope gg = tranformGeoToWindow(oldMapArea.getMinX(), oldMapArea
-					.getMinY(), oldMapArea.getMaxX(), oldMapArea.getMaxY(), null);
-
-			graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
-					RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
-			graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
-					RenderingHints.VALUE_ANTIALIAS_OFF);
-			graphics.setRenderingHint(RenderingHints.KEY_RENDERING,
-					RenderingHints.VALUE_RENDER_SPEED);
-
-			int xx1 = (int) Math.round( gg.getMinX() );
-			int yy1 = (int) Math.round( gg.getMinY() );
-			int xx2 = (int) Math.round( gg.getMaxX() );
-			int yy2 = (int) Math.round( gg.getMaxY() );
-
-			graphics.setBackground(getMapBackgroundColor());
-			graphics.clearRect(0, 0, JMapPane.this.getWidth(), JMapPane.this
-					.getHeight());
-			graphics.drawImage(baseImage, xx1, yy1, xx2, yy2, 0, 0, JMapPane.this
-					.getWidth(), JMapPane.this.getHeight(), null);
-		}
-	}
-
-	private static final Cursor WAIT_CURSOR = Cursor
-			.getPredefinedCursor(Cursor.WAIT_CURSOR);
-
-	/** Logger for debug messages. */
-	protected static final Logger LOGGER = Logger.getLogger(JMapPane.class);
-
-	/** @deprecated ersetzt durch {@link #ZOOM_IN} */
-	public static final int ZoomIn = gtmig.org.geotools.swing.JMapPane.ZoomIn;
-	/** @deprecated ersetzt durch {@link #ZOOM_OUT} */
-	public static final int ZoomOut = gtmig.org.geotools.swing.JMapPane.ZoomOut;
-	/** @deprecated ersetzt durch {@link #PAN} */
-	public static final int Pan = gtmig.org.geotools.swing.JMapPane.Pan;
-	/** @deprecated ersetzt durch {@link #RESET} */
-	public static final int Reset = gtmig.org.geotools.swing.JMapPane.Reset;
-	/** @deprecated ersetzt durch {@link #SELECT_TOP} */
-	public static final int Select = gtmig.org.geotools.swing.JMapPane.Select;
-
-	/**
-	 * Flag fuer Modus "Nichts machen".
-	 * 
-	 * @see #setWindowSelectionState(int)
-	 * @see #setState(int)
-	 */
-	public static final int NONE = 100;
-	/**
-	 * Flag fuer Modus "Zuruecksetzen". Nicht fuer Window-Auswahl moeglich!
-	 * 
-	 * @see #setState(int)
-	 */
-	public static final int RESET = gtmig.org.geotools.swing.JMapPane.Reset;
-	/**
-	 * Flag fuer Modus "Kartenausschnitt bewegen". Nicht fuer Window-Auswahl
-	 * moeglich!
-	 * 
-	 * @see #setState(int)
-	 */
-	public static final int PAN = gtmig.org.geotools.swing.JMapPane.Pan;
-	/**
-	 * Flag fuer Modus "Heran zoomen".
-	 * 
-	 * @see #setWindowSelectionState(int)
-	 * @see #setState(int)
-	 */
-	public static final int ZOOM_IN = gtmig.org.geotools.swing.JMapPane.ZoomIn;
-	/**
-	 * Flag fuer Modus "Heraus zoomen". Nicht fuer Window-Auswahl moeglich!
-	 * 
-	 * @see #setState(int)
-	 */
-	public static final int ZOOM_OUT = gtmig.org.geotools.swing.JMapPane.ZoomOut;
-	/**
-	 * Flag fuer Modus
-	 * "SimpleFeature-Auswahl auf dem obersten (sichtbaren) Layer".
-	 * 
-	 * @see #setWindowSelectionState(int)
-	 * @see #setState(int)
-	 */
-	public static final int SELECT_TOP = gtmig.org.geotools.swing.JMapPane.Select;
-	/**
-	 * Flag fuer Modus "SimpleFeature-Auswahl auf allen (sichtbaren) Layern".
-	 * 
-	 * @see #setWindowSelectionState(int)
-	 * @see #setState(int)
-	 */
-	public static final int SELECT_ALL = 103;
-	/**
-	 * Flag fuer Modus
-	 * "Auswahl nur eines Features, das erste sichtbare von Oben".
-	 * 
-	 * @see #setWindowSelectionState(int)
-	 * @see #setState(int)
-	 */
-	public static final int SELECT_ONE_FROM_TOP = 104;
-
-	/** Modus fuer Window-Selektion (Default: {@link #ZOOM_IN}). */
-	protected int selState = NONE;
-
-	/**
-	 * Transformation zwischen Fenster-Koordinaten und Karten-Koordinaten
-	 * (lat/lon)
-	 */
-	protected AffineTransform transform = null;
-
-	/**
-	 * Liste der angeschlossenen Listener, die auf Aktionen des MapPanes
-	 * lauschen.
-	 */
-	protected Vector<JMapPaneListener> mapPaneListeners = new Vector<JMapPaneListener>();
-
-	final protected gtmig.org.geotools.swing.MouseSelectionTracker selTracker = new gtmig.org.geotools.swing.MouseSelectionTracker() {
-		public void mouseDragged(final MouseEvent event) {
-			// Wenn Fenster-Selektions-Modus auf NICHTS steht (z.B. Info-Tool),
-			// keinen Rahmen beim Draggen zeichnen
-			if (selState == NONE)
-				return;
-			// Wenn Zoom bereits durch Oberklasse aktiviert wird,
-			// malt diese das Rectangle
-			if (getState() == ZOOM_IN || getState() == ZOOM_OUT)
-				return;
-
-			super.mouseDragged(event);
-		}
-
-		protected void selectionPerformed(int ox, int oy, int px, int py) {
-			// MS, 20.05.2008:
-			// In performSelectionEvent(.) wurde das Zoomen wieder
-			// reingenommen, damit bei Fenster-Auswahl auch gezoomt
-			// wird, wenn der Klick-Zoom (setState(.)) deaktiviert
-			// ist.
-			// Wenn dieser jedoch ebenfalls aktiviert ist, darf an
-			// dieser Stelle nicht nochmal gezoomt werden, da sonst
-			// 2x gezoomt wird!!
-			if (getState() != ZOOM_IN)
-				performSelectionEvent(ox, oy, px, py);
-		}
-	};
-
-	private static final FilterFactory ff = FilterUtil.FILTER_FAC2;
-
-	/**
-	 * A flag indicating if dispose() was already called. If true, then further
-	 * use of this {@link JMapPane} is undefined.
-	 */
-	private boolean disposed = false;
-
-	/** Listener, der auf das Mausrad lauscht und mit Zoom reagiert */
-	private final MouseWheelListener mouseWheelZoomListener = new MouseWheelListener() {
-		public void mouseWheelMoved(MouseWheelEvent e) {
-			performMouseWheelEvent(e);
-		}
-	};;
-
-	// /** Wenn true, dann werden RasterLayer waehrend des Panning auf
-	// setVisible(false) gesetzt **/
-	// protected boolean hideRasterLayersDuringPan = false;
-	// /** Remebers the layers that are hidden during a PAN action **/
-	// protected List<MapLayer> hiddenForPanning = new LinkedList<MapLayer>();
-
-	/**
-	 * Wenn true, dann wird der Cursor waehrend des naechsten Repaint auf die
-	 * WAIT gesetzt.
-	 **/
-	private boolean setWaitCursorDuringNextRepaint;
-	/**
-	 * Defines which Component to change the MouseCursor if in WAIT STATE. If
-	 * unset, only THIS component is used
-	 **/
-	private Component mouseWaitCursorComponent;
-
-	/** Cursor wenn kein Mausbutton gedrueckt wird. default oder SwingUtil.PAN **/
-	private Cursor normalCursor = Cursor
-			.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
-
-	/**
-	 * Manuell gesetzter statischer Cursor, unabhaengig von der aktuellen
-	 * MapPane-Funktion
-	 */
-	protected Cursor staticCursor = null;
-
-	private MouseInputAdapter dragWaitCursorListener;
-
-	/** An (transparent) image to paint over the map in the lower right corner **/
-	private BufferedImage mapImage = null;
-
-	/**
-	 * Holds a flag for each layer, whether it is regarded or ignored on
-	 * {@link #SELECT_TOP}, {@link #SELECT_ALL} and {@link #SELECT_ONE_FROM_TOP}
-	 * actions.
-	 */
-	final protected HashMap<MapLayer, Boolean> mapLayerSelectable = new HashMap<MapLayer, Boolean>();
-
-	/** We store the old transform for a moment to use it for the
-	 "quick scaled preview" in case of ZoomIn **/
-	protected AffineTransform oldTransform = null;
-
-	/**
-	 * Erzeugt ein neues MapPane.
-	 * 
-	 * @param layout
-	 *            Layout-Manager fuer die GUI-Komponente (z.B.
-	 *            {@link BorderLayout})
-	 * @param isDoubleBuffered
-	 *            siehe Konstruktor der
-	 *            {@linkplain org.gtmig.org.geotools.swing.JMapPane#JMapPane(LayoutManager,boolean,GTRenderer,MapContext)
-	 *            Oberklasse}
-	 * @param renderer
-	 *            Renderer fuer die graphische Darestellung (z.B.
-	 *            {@link StreamingRenderer})
-	 * @param context
-	 *            Verwaltung der einzelnen Layer (z.B. {@link DefaultMapContext}
-	 *            ).
-	 */
-	public JMapPane() {
-		this(null, true, null, null, null);
-	}
-
-	/**
-	 * Erzeugt ein neues MapPane.
-	 * 
-	 * @param layout
-	 *            Layout-Manager fuer die GUI-Komponente (z.B.
-	 *            {@link BorderLayout})
-	 * @param isDoubleBuffered
-	 *            siehe Konstruktor der
-	 *            {@linkplain org.gtmig.org.geotools.swing.JMapPane#JMapPane(LayoutManager,boolean,GTRenderer,MapContext)
-	 *            Oberklasse}. Bei <code>null</code> wird <code>true</code>
-	 *            andgenommen.
-	 * @param renderer
-	 *            Renderer fuer die graphische Darestellung (z.B.
-	 *            {@link StreamingRenderer})
-	 * @param context
-	 *            Verwaltung der einzelnen Layer (z.B. {@link DefaultMapContext}
-	 *            ).
-	 * @param rendererHints
-	 *            A {@link Map} with hints for the renderer. May be
-	 *            <code>null</code>.
-	 */
-	public JMapPane(LayoutManager layout, Boolean isDoubleBuffered,
-			GTRenderer renderer, MapContext context,
-			Map<Object, Object> rendererHints) {
-		super(layout != null ? layout : new BorderLayout(),
-				isDoubleBuffered != null ? isDoubleBuffered : true,
-				renderer != null ? renderer : GTUtil.createGTRenderer(),
-				// renderer != null ? renderer : new StreamingRenderer(),
-				context != null ? context : new DefaultMapContext(GeoImportUtil
-						.getDefaultCRS()));
-		//
-		// // Having problems with StreamingRendere!
-		// getRenderer().setContext(getContext());
-
-		// Dieser Hint sorgt wohl dafuer, dass die Rasterpixel nicht
-		// interpoliert werden
-		// Ueber die Methode enableAntiAliasing(boolean) kann das
-		// rechenintensive AntiAliasing fuer Text un Vectoren eingeschaltet
-		// werden
-		RenderingHints hintsJava2d = ImageUtilities.NN_INTERPOLATION_HINT;
-		getRenderer().setJava2DHints(hintsJava2d);
-
-		if (rendererHints != null) {
-			getRenderer().getRendererHints().putAll(rendererHints);
-		}
-
-		// hints.add( new RenderingHints(RenderingHints.KEY_ANTIALIASING,
-		// RenderingHints.VALUE_ANTIALIAS_OFF ) );
-		// hints.add( new RenderingHints(RenderingHints.KEY_INTERPOLATION,
-		// RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR ) );
-		// hints.add( new RenderingHints(RenderingHints.KEY_INTERPOLATION,
-		// RenderingHints.VALUE_INTERPOLATION_BICUBIC ) );
-		// hints.add( new RenderingHints(RenderingHints.KEY_INTERPOLATION,
-		// RenderingHints.VALUE_INTERPOLATION_BILINEAR ) );
-		// hints.add( new RenderingHints(RenderingHints.KEY_ALPHA_INTERPOLATION,
-		// RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED ) );
-		// hints.add( new RenderingHints(RenderingHints.KEY_ALPHA_INTERPOLATION,
-		// RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY ) );
-		// Map rendererParams = new HashMap();
-		// rendererParams.put("optimizedDataLoadingEnabled",new Boolean(true) );
-		// renderer.setRendererHints( rendererParams );
-
-		setWindowSelectionState(ZOOM_IN);
-		setState(ZOOM_IN);
-
-		this.addMouseWheelListener(mouseWheelZoomListener);
-
-		/**
-		 * Dieser Listener setzt nach dem Panning (aka Drag) den Maus-Cursor auf
-		 * Wait. Der Rest des Panning wird in der Uberklasse abgewickelt
-		 */
-		dragWaitCursorListener = new MouseInputAdapter() {
-			public void mouseReleased(MouseEvent e) {
-				setWaitCursorDuringNextRepaint = true;
-			};
-		};
-		this.addMouseListener(dragWaitCursorListener);
-		//
-		// // Hightlight immer auf dem obersten sichtbaren Nicht-Raster-Layer
-		// // MS-01.sc: Der GT-Highlight-Manager arbeitet zu langsam und ohnehin
-		// // nur fuer unprojizierte Layer korrekt
-		// // this.setHighlight(true);
-		// this.setHighlight(false);
-		// // MS-01.ec
-
-		getContext().addMapLayerListListener(
-				new schmitzm.geotools.map.event.MapLayerListAdapter() {
-					private void resetHighlightLayer() {
-						// if (isHighlight())
-						// setHighlightLayer(getTopVisibleNonGridCoverageLayer());
-					}
-
-					public void layerAdded(
-							org.geotools.map.event.MapLayerListEvent e) {
-						resetHighlightLayer();
-					}
-
-					public void layerChanged(
-							org.geotools.map.event.MapLayerListEvent e) {
-						resetHighlightLayer();
-					}
-
-					public void layerMoved(
-							org.geotools.map.event.MapLayerListEvent e) {
-						resetHighlightLayer();
-					}
-
-					public void layerRemoved(
-							org.geotools.map.event.MapLayerListEvent e) {
-						resetHighlightLayer();
-					}
-				});
-
-		// CRS wird immer vom ersten in die Karte eingefuegten Layer uebernommen
-		// Wenn noch keine MapArea gesetzt wurde, wird diese vom Layer
-		// uebernommen
-		getContext().addMapLayerListListener(new MapLayerListAdapter() {
-			public void layerAdded(MapLayerListEvent e) {
-				if (getContext().getLayerCount() == 1) {
-					CoordinateReferenceSystem crs = null;
-					// CRS aus Layer ermitteln
-					try {
-						crs = e.getLayer().getFeatureSource().getSchema()
-								.getGeometryDescriptor()
-								.getCoordinateReferenceSystem();
-						// wenn noch keine MapArea gesetzt wurde, den
-						// Ausdehnungsbereich des ersten Layers
-						// verwenden, so dass die erste
-						// Karte komplett angezeigt wird
-						if (getMapArea() == null) {
-							// Envelope newMapArea = new Envelope(e.getLayer()
-							// .getFeatureSource().getBounds());
-							Envelope newMapArea = getMaxExtend();
-							setMapArea(newMapArea);
-							// in layerAdded(.) der Oberklasse wird
-							// mapArea nochmal neu gesetzt, wenn das
-							// erste Layer
-							// eingefuegt wird
-							// >> hier nur die AreaOfInterest setzen
-							getContext().setAreaOfInterest(newMapArea, crs);
-						}
-					} catch (Exception err) {
-						LOGGER
-								.warn("CRS could not be determined from map layer. "
-										+ GeoImportUtil.getDefaultCRS()
-												.getName() + "  used.");
-						// err.printStackTrace();
-						crs = GeoImportUtil.getDefaultCRS();
-					}
-					// CRS dem MapContext zuweisen
-					try {
-						getContext().setCoordinateReferenceSystem(crs);
-						// LOGGER.debug("MapContext-CRS set to: "+crs);
-					} catch (Exception err) {
-						LOGGER.error(
-								"CRS could not be assigned to map context.",
-								err);
-					}
-				}
-			}
-		});
-
-		// Solved without just with the access methods
-		// // The default is to regard a layer on selection
-		// // actions
-		// getContext().addMapLayerListListener(
-		// new MapLayerListAdapter() {
-		// @Override
-		// public void layerAdded(MapLayerListEvent e) {
-		// setMapLayerSelectable(e.getLayer(),true);
-		// }
-		// @Override
-		// public void layerRemoved(MapLayerListEvent e) {
-		// // remove reference to layer
-		// mapLayerSelectable.remove(e.getLayer());
-		// }
-		// });
-	}
-
-	public JMapPane(LayoutManager layout, boolean isDoubleBuffered,
-			GTRenderer renderer, MapContext context) {
-		this(layout, isDoubleBuffered, renderer, context, null);
-	}
-
-	/**
-	 * Get the BufferedImage to use as a flaoting icon in the lower right
-	 * corner.
-	 * 
-	 * @return <code>null</code> if the feature is deactivated.
-	 */
-	public BufferedImage getMapImage() {
-		return mapImage;
-	}
-
-	/**
-	 * Set the BufferedImage to use as a flaoting icon in the lower right corner
-	 * 
-	 * @param mapImageIcon
-	 *            <code>null</code> is allowed and deactivates this icon.
-	 */
-	public void setMapImage(BufferedImage mapImage) {
-		this.mapImage = mapImage;
-	}
-
-	/**
-	 * Gibt die optional gesetzte {@link Component} zurueck, deren Cursor auch
-	 * auf WAIT gesetzt werden soll
-	 * 
-	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
-	 *         Kr&uuml;ger</a>
-	 * 
-	 * @return null oder {@link Component}
-	 */
-	public Component getWaitCursorComponent() {
-		return mouseWaitCursorComponent;
-	}
-
-	/**
-	 * Setzt eine Componente, deren Cursor zusaetzlich zu THIS noch auf WAIT
-	 * gesetzt wird falls durch dies ueberhaupt durch
-	 * setSetWaitCursorDuringNextRepaint(true) veranlasst wurde
-	 * 
-	 * @param parentComponent
-	 *            z.b. der Frame, der diese {@link JMapPane} enhaelt
-	 * 
-	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
-	 *         Kr&uuml;ger</a>
-	 */
-	public void setWaitCursorComponent(Component parentComponent) {
-		this.mouseWaitCursorComponent = parentComponent;
-	}
-
-	/**
-	 * Aktualisiert die Karten-Anzeige vollstaendig. Ruft
-	 * {@link JMapPane#setReset(boolean) JMapPane#setReset(true)} auf und
-	 * anschliessend {@link #repaint()}.
-	 * 
-	 * <br>
-	 * SK: Der Mauszeiger wird waehrend des repaints auf WAIT gesetzt mittels
-	 * {@link #setWaitCursorDuringNextRepaint(boolean)}
-	 * 
-	 * @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
-	 *         Kr&uuml;ger</a>
-	 */
-	public void refresh() {
-
-		// SK: Added by SK, 27.09.2007
-		// Durch den reset ist das repaint immer etwas aufwaendiger. Der Cursor
-		// wechselt dann auf WAIT
-		setWaitCursorDuringNextRepaint(true);
-
-		setReset(true);
-		repaint();
-	}
-
-	/**
-	 * Aktiviert oder deaktiviert das AntiAliasing for diese {@link JMapPane}.
-	 * AntiALiasing ist besonders fuer Textbeschriftung sehr schoen, verbraucht
-	 * aber auch mehr Performance.
-	 * 
-	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
-	 *         Kr&uuml;ger</a>
-	 */
-	public void setAntiAliasing(final boolean aa) {
-		// LOGGER.info("Setting AntiAliasing for this JMapPane to " + aa);
-		RenderingHints java2DHints = getRenderer().getJava2DHints();
-		if (java2DHints == null)
-			java2DHints = GeoTools.getDefaultHints();
-		java2DHints.put(RenderingHints.KEY_ANTIALIASING,
-				aa ? RenderingHints.VALUE_ANTIALIAS_ON
-						: RenderingHints.VALUE_ANTIALIAS_OFF);
-		java2DHints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
-				aa ? RenderingHints.VALUE_TEXT_ANTIALIAS_ON
-						: RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
-		java2DHints.put(RenderingHints.KEY_RENDERING,
-				aa ? RenderingHints.VALUE_RENDER_QUALITY
-						: RenderingHints.VALUE_RENDER_SPEED);
-		getRenderer().setJava2DHints(java2DHints);
-	}
-
-	/**
-	 * Setzt den Kartenausschnitt auf die Ausdehnung eines bestimmten Layers.
-	 * Macht nichts, wenn {@code null} uebergeben wird.
-	 * 
-	 * <br>
-	 * A refresh of the map is NOT called.
-	 * 
-	 * @param layer
-	 *            ein Layer
-	 */
-	public void zoomToLayer(MapLayer layer) {
-		if (layer == null)
-			return;
-		// This action ususally takes some time..
-		setWaitCursorDuringNextRepaint = true;
-		try {
-
-			// BB umrechnen von Layer-CRS in Map-CRS
-			final CoordinateReferenceSystem targetCRS = getContext()
-					.getCoordinateReferenceSystem();
-			final CoordinateReferenceSystem sourceCRS = layer
-					.getFeatureSource().getSchema()
-					.getCoordinateReferenceSystem();
-
-			Envelope mapAreaNew;
-			if (targetCRS != null && sourceCRS != null
-					&& !CRS.equalsIgnoreMetadata(sourceCRS, targetCRS)) {
-				mapAreaNew = JTSUtil.transformEnvelope(layer.getFeatureSource()
-						.getBounds(), sourceCRS, targetCRS);
-			} else {
-				try {
-					mapAreaNew = layer.getFeatureSource().getBounds();
-				} catch (java.lang.IllegalArgumentException e) {
-					LOGGER.error("Can't calc layers bounds...", e);
-					mapAreaNew = null;
-
-					/**
-					 * 
-					 23.10.2009 11:20:50
-					 * org.geotools.data.shapefile.shp.PolygonHandler read
-					 * WARNUNG: only one hole in this polygon record ERROR
-					 * JMapPane zoomToLayer Zoom to layer did not terminate
-					 * correctly java.lang.IllegalArgumentException: Points of
-					 * LinearRing do not form a closed linestring at
-					 * com.vividsolutions
-					 * .jts.geom.LinearRing.validateConstruction
-					 * (LinearRing.java:105) at
-					 * com.vividsolutions.jts.geom.LinearRing
-					 * .<init>(LinearRing.java:100) at
-					 * com.vividsolutions.jts.geom
-					 * .GeometryFactory.createLinearRing
-					 * (GeometryFactory.java:339) at
-					 * org.geotools.data.shapefile.
-					 * shp.PolygonHandler.read(PolygonHandler.java:188) at
-					 * org.geotools
-					 * .data.shapefile.shp.ShapefileReader$Record.shape
-					 * (ShapefileReader.java:106) at
-					 * org.geotools.data.shapefile.
-					 * ShapefileAttributeReader.next(
-					 * ShapefileAttributeReader.java:157) at
-					 * org.geotools.data.shapefile
-					 * .indexed.IndexedShapefileAttributeReader
-					 * .next(IndexedShapefileAttributeReader.java:122) at
-					 * org.geotools
-					 * .data.FIDFeatureReader.next(FIDFeatureReader.java:96) at
-					 * org.geotools.data.FIDFeatureReader.next(FIDFeatureReader.
-					 * java:55) at org.geotools.data.MaxFeatureReader.next(
-					 * MaxFeatureReader.java:61) at
-					 * org.geotools.data.MaxFeatureReader
-					 * .next(MaxFeatureReader.java:61)
-					 **/
-				}
-			}
-
-			// Kartenbereich um 10% vergroessern, damit z.B. auch ein
-			// Punkt-Layer,
-			// welches nur aus 2 Punnkten besteht, sichtbar ist (Punkte liegen
-			// sonst
-			// genau auf dem Rand der angezeigten Flaeche)
-
-			if (mapAreaNew != null) {
-				mapAreaNew.expandBy(mapAreaNew.getWidth() * 0.1, mapAreaNew
-						.getHeight() * 0.1);
-				setMapArea(mapAreaNew);
-			} else {
-				LOGGER
-						.warn("Couldn't transformEnvelope when zooming to the layer");
-			}
-		} catch (Exception err) {
-			LOGGER.error("Zoom to layer did not terminate correctly", err);
-		}
-	}
-
-	/**
-	 * Zooms the {@link JMapPane} to the {@link Envelope} of a layer.
-	 * 
-	 * <br>
-	 * A refresh of the map is not done automatically
-	 * 
-	 * @param index
-	 *            Index of the {@link MapLayer} in the {@link MapContext} (from
-	 *            back to top)
-	 * 
-	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
-	 *         Kr&uuml;ger</a>
-	 */
-	public void zoomToLayer(int index) {
-		final MapContext context = getContext();
-		if (context != null)
-			zoomToLayer(context.getLayer(index));
-	}
-
-	/**
-	 * Zooms the {@link JMapPane} to the {@link Envelope} of the selected layer.
-	 * The layer is selected by the idx, counting from front to back, like
-	 * humans would expect in a {@link JList}
-	 * 
-	 * <br>
-	 * A refresh of the map is not done automatically
-	 * 
-	 * 
-	 * 
-	 * @param index
-	 *            Reverse index of the {@link MapLayer} in the
-	 *            {@link MapContext}
-	 * 
-	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
-	 *         Kr&uuml;ger</a>
-	 */
-	public void zoomToLayerIdxReverse(int index) {
-		zoomToLayer(getContext().getLayerCount() - 1 - index);
-	}
-
-	/**
-	 * Liefert die Anzahl der Einheiten, die ein Bildschirm-Pixel darstellt. Die
-	 * Einheit ist die Grundeinheit des CRS
-	 */
-	public double getScale() {
-		if (getWidth() == 0 || getMapArea() == null)
-			return 0.0;
-		return getMapArea().getWidth() / getWidth();
-	}
-
-	/**
-	 * Liefert oberste Layer (sichtbar oder unsichtbar).
-	 */
-	public MapLayer getTopLayer() {
-		int count = getContext().getLayerCount();
-		return count > 0 ? getContext().getLayer(count - 1) : null;
-	}
-
-	/**
-	 * Liefert oberste sichtbare Layer.
-	 */
-	public MapLayer getTopVisibleLayer() {
-		for (int i = getContext().getLayerCount() - 1; i >= 0; i--) {
-			MapLayer layer = getContext().getLayer(i);
-			if (layer.isVisible())
-				return layer;
-		}
-		return null;
-	}
-
-	/**
-	 * Liefert oberste sichtbare Raster-Layer.
-	 */
-	public MapLayer getTopVisibleGridCoverageLayer() {
-		for (int i = getContext().getLayerCount() - 1; i >= 0; i--) {
-			MapLayer layer = getContext().getLayer(i);
-			if (layer.isVisible() && isGridCoverageLayer(layer))
-				return layer;
-		}
-		return null;
-	}
-
-	/**
-	 * Liefert oberste sichtbare Nicht-Raster-Layer.
-	 */
-	public MapLayer getTopVisibleNonGridCoverageLayer() {
-		for (int i = getContext().getLayerCount() - 1; i >= 0; i--) {
-			MapLayer layer = getContext().getLayer(i);
-			if (layer.isVisible() && !isGridCoverageLayer(layer))
-				return layer;
-		}
-		return null;
-	}
-
-	/**
-	 * Liefert unterste Layer (sichtbar oder unsichtbar).
-	 */
-	public MapLayer getBottomLayer() {
-		return getContext().getLayerCount() > 0 ? getContext().getLayer(0)
-				: null;
-	}
-
-	/**
-	 * Setzt den Modus fuer Window-Selektion. Default ist {@link #ZOOM_IN}.
-	 * 
-	 * 
-	 * <ul>
-	 * <li>{@link #ZOOM_IN}: Zoom auf selektierten Bereich</li>
-	 * <li>{@link #SELECT_TOP}: Auswahl der Features im selektierten Bereich des
-	 * <b>obersten</b> (sichtbaren) Layers</li>
-	 * <li>{@link #SELECT_ALL} Auswahl der Features im selektierten ueber alle
-	 * Layer</li>
-	 * <li>{@link #NONE} Nichts machen</li>
-	 * </ul>
-	 * 
-	 * @param newSelState
-	 *            Modus fuer Window-Selektion
-	 */
-	public void setWindowSelectionState(final int newSelState) {
-		if (newSelState != NONE && newSelState != ZOOM_IN
-				&& newSelState != SELECT_TOP && newSelState != SELECT_ALL
-				&& newSelState != SELECT_ONE_FROM_TOP)
-			throw new IllegalArgumentException(
-					"Unknown selection state for window selection!");
-
-		// Den selTracker bei Wechsel zu NONE deaktivieren (SK), damit
-		// Selektionsfenster beim Draggen nicht mehr gezeichnet wird
-		if ((newSelState == NONE) && (selState != NONE)) {
-			this.removeMouseListener(selTracker);
-		} else
-		// Den selTracker bei Wechsel von NONE aktivieren (SK)
-		if ((newSelState != NONE) && (selState == NONE)) {
-			this.addMouseListener(selTracker);
-		}
-
-		this.selState = newSelState;
-
-		// Je nach Aktion den Cursor umsetzen
-		updateCursor();
-	}
-
-	/**
-	 * Standardmaessig wird der Cursor automatisch je nach MapPane-Aktion (Zoom,
-	 * Auswahl, ...) gesetzt. Mit dieser Methode kann ein statischer Cursor
-	 * gesetzt werden, der unabhaengig von der aktuellen MapPanes-Aktion
-	 * beibehalten wird. Um diesen statischen Cursor wieder zu entfernen, kann
-	 * {@code null} als Parameter uebergeben werden
-	 * 
-	 * @param cursor
-	 *            Cursor
-	 */
-	public void setStaticCursor(Cursor cursor) {
-		this.staticCursor = cursor;
-		if (cursor != null)
-			super.setCursor(cursor);
-	}
-
-	/**
-	 * Liefert den statisch eingestellten Cursor, der unabhaengig von der
-	 * eingestellten MapPane-Aktion (Zoom, Auswahl, ...) verwendet wird.
-	 * 
-	 * @return {@code null}, wenn kein statischer Cursor verwendet, sondern der
-	 *         Cursor automatisch je nach MapPane-Aktion eingestellt wird.
-	 */
-	public Cursor getStaticCursor() {
-		return this.staticCursor;
-	}
-
-	/**
-	 * Abhaengig von selState wird der Cursor gesetzt
-	 */
-	public void updateCursor() {
-		// wenn manueller Cursor gesetzt ist, dann diesen verwenden (unabhaengig
-		// von der aktuellen Aktion
-		if (this.staticCursor != null) {
-			setCursor(staticCursor);
-			return;
-		}
-		// Je nach Aktion den Cursor umsetzen
-		switch (this.selState) {
-		case SELECT_TOP:
-		case SELECT_ONE_FROM_TOP:
-		case SELECT_ALL:
-			setCursor(SwingUtil.CROSSHAIR_CURSOR);
-			break;
-		case ZOOM_IN:
-			setCursor(SwingUtil.ZOOMIN_CURSOR);
-			break;
-		case ZOOM_OUT:
-			setCursor(SwingUtil.ZOOMOUT_CURSOR);
-			break;
-		default:
-			setCursor(getNormalCursor());
-			break;
-		}
-	}
-
-	/**
-	 * Liefert den Modus fuer Window-Selektion.
-	 * 
-	 * @see #setWindowSelectionState(int)
-	 */
-	public int getWindowSelectionState() {
-		return this.selState;
-	}
-
-	/**
-	 * Fuegt der Map einen Listener hinzu.
-	 * 
-	 * @param l
-	 *            neuer Listener
-	 */
-	public void addMapPaneListener(JMapPaneListener l) {
-		mapPaneListeners.add(l);
-	}
-
-	/**
-	 * Entfernt einen Listener von der Map.
-	 * 
-	 * @param l
-	 *            zu entfernender Listener
-	 */
-	public void removeMapPaneListener(JMapPaneListener l) {
-		mapPaneListeners.remove(l);
-	}
-
-	/**
-	 * Propagiert ein Ereignis an alle angeschlossenen Listener.
-	 * 
-	 * @param e
-	 *            Ereignis
-	 */
-	protected void fireMapPaneEvent(JMapPaneEvent e) {
-		for (JMapPaneListener l : mapPaneListeners)
-			l.performMapPaneEvent(e);
-	}
-
-	/**
-	 * Konvertiert die Maus-Koordinaten (relativ zum <code>JMapPane</code>) in
-	 * Karten-Koordinaten.
-	 * 
-	 * @param e
-	 *            Maus-Ereignis
-	 */
-	public static Point2D getMapCoordinatesFromEvent(MouseEvent e) {
-		// aktuelle Geo-Position aus GeoMouseEvent ermitteln
-		if (e != null && e instanceof MapMouseEvent)
-			try {
-				return ((MapMouseEvent) e).getMapPosition().toPoint2D();
-			} catch (Exception err) {
-				LOGGER
-						.error(
-								"return ((GeoMouseEvent) e).getMapCoordinate(null).toPoint2D();",
-								err);
-			}
-
-		// aktuelle Geo-Position ueber Transformation des JMapPane berechnen
-		if (e != null && e.getSource() instanceof JMapPane) {
-			AffineTransform at = ((JMapPane) e.getSource()).getTransform();
-			if (at != null)
-				return at.transform(e.getPoint(), null);
-		}
-
-		return null;
-	}
-
-	/**
-	 * 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
-	 */
-	protected void performSelectionEvent(int ox, int oy, int px, int py) {
-		if (getContext().getLayerCount() == 0)
-			return;
-
-		// keine wirkliche Selektion, sondern nur ein Klick
-		if (ox == px || oy == py) {
-			// TODO perform dist withing filter 
-			return;
-		}
-
-		// Fenster-Koordinaten in Map-Koordinaten umwandeln
-		Envelope env = tranformWindowToGeo(ox, oy, px, py);
-
-		// Generelles Event ausloesen
-		fireMapPaneEvent(new GeneralSelectionEvent(this, env));
-
-		int selectState = getWindowSelectionState();
-		switch (selectState) {
-		case ZOOM_IN: // Karte neu setzen
-			this.setMapArea(env);
-			refresh(); // WICHTIG!! Damit die veraenderte Form beruecksichtigt
-			// wird!?
-			break;
-		case SELECT_TOP:
-		case SELECT_ONE_FROM_TOP:
-		case SELECT_ALL: // Features selektieren
-			boolean featuresFound = findFeaturesAndFireEvents(
-					new BoundingBoxFilterGenerator(env, getContext()
-							.getCoordinateReferenceSystem()), selectState, env);
-			if (selectState == SELECT_ALL || !featuresFound)
-				findGridCoverageSubsetsAndFireEvents(env, selectState);
-			break;
-		}
-	}
-
-	/**
-	 * Verarbeitet die Mausrad-Aktion, indem gezoomed wird.
-	 * 
-	 * @param wheelEvt
-	 *            Mausrad-Event
-	 */
-	protected void performMouseWheelEvent(MouseWheelEvent wheelEvt) {
-		if (getContext().getLayerCount() == 0)
-			return;
-
-		int units = wheelEvt.getUnitsToScroll();
-		// Positiver Wert --> Zoom in --> Faktor < 1
-		// Negativer Wert --> Zoom out --> Faktir > 1
-
-		// SK: 9.9.2007 zoom jetzt wie bei GoogleEarth
-		double zFactor = units > 0 ? 1.3 : 1 / 1.3;
-		// vorher double zFactor = units > 0 ? 1/1.2 : 1.2;
-
-		// Fenster-Koordinaten zu Karten-Koordinaten transformieren
-		final AffineTransform transform2 = getTransform();
-		if (transform2 == null) {
-			LOGGER
-					.warn("No transform can be created! Skipping MouseWheel performAction.");
-			return;
-		}
-		Point2D mapCoord = transform2.transform(wheelEvt.getPoint(), null);
-		// Relative Position des Mauszeigers zum Kartenausschnitt
-		// -> Nach Zoom soll dieselbe Kartenposition unterhalb des Mauszeigers
-		// erscheinen, wie vor dem Zoom
-		double relX = (mapCoord.getX() - getMapArea().getMinX())
-				/ getMapArea().getWidth();
-		double relY = (mapCoord.getY() - getMapArea().getMinY())
-				/ getMapArea().getHeight();
-
-		// Neuen Karten-Ausschnitt berechnen
-		Coordinate ll = new Coordinate(mapCoord.getX()
-				- getMapArea().getWidth() * relX * zFactor, mapCoord.getY()
-				- getMapArea().getHeight() * relY * zFactor);
-		Coordinate ur = new Coordinate(mapCoord.getX()
-				+ getMapArea().getWidth() * (1 - relX) * zFactor, mapCoord
-				.getY()
-				+ getMapArea().getHeight() * (1 - relY) * zFactor);
-		setMapArea(new Envelope(ll, ur));
-
-		setWaitCursorDuringNextRepaint(true);
-		repaint();
-		
-		if (units > 0) {
-			drawScaledPreviewImage_Zoom(ZOOM_IN);
-		} else {
-			drawScaledPreviewImage_Zoom(ZOOM_OUT);
-		}
-	}
-
-	/**
-	 * Transformiert einen Fenster-Koordinaten-Bereich in Geo-Koordinaten.
-	 * 
-	 * @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
-	 */
-	public Envelope tranformWindowToGeo(int ox, int oy, int px, int py) {
-		AffineTransform at = getTransform();
-		Point2D geoO = at.transform(new Point2D.Double(ox, oy), null);
-		Point2D geoP = at.transform(new Point2D.Double(px, py), null);
-		return new Envelope(geoO.getX(), geoP.getX(), geoO.getY(), geoP.getY());
-	}
-	
-	/**
-	 * Transformiert einen Geo-Koordinaten-Bereich in Fenster-Koordinaten.
-	 * 
-	 * @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 winToGeotransform Eine Window to Geo transform. If <code>null</code>, {@link #getTransform()} is used.
-	 */
-	public Envelope tranformGeoToWindow(double ox, double oy, double px, double py, AffineTransform winToGeotransform) {
-		AffineTransform at = winToGeotransform == null ? getTransform() : winToGeotransform;
-		Point2D geoO;
-		try {
-			geoO = at.inverseTransform(new Point2D.Double(ox, oy), null);
-			Point2D geoP = at.inverseTransform(new Point2D.Double(px, py), null);
-			return new Envelope(geoO.getX(), geoP.getX(), geoO.getY(), geoP.getY());
-		} catch (NoninvertibleTransformException e) {
-			LOGGER.error(e);
-			return new Envelope(ox,oy,px,py);
-		}
-	}
-
-	/**
-	 * Transformiert eine Fenster-Koordinate in eine Geo-Koordinate.
-	 * 
-	 * @param x
-	 *            X-Koordinate
-	 * @param y
-	 *            Y-Koordinate
-	 */
-	public Point2D tranformWindowToGeo(int x, int y) {
-		AffineTransform at = getTransform();
-		return at.transform(new Point2D.Double(x, y), null);
-	}
-
-	/**
-	 * Berechnet die Transformation zwischen Fenster- und Karten-Koordinaten
-	 * neu.
-	 */
-	protected void resetTransform() {
-		if (getMapArea() == null || getWidth() == 0 || getHeight() == 0)
-			return;
-		
-
-		// We store the last Transform
-		oldTransform = transform;
-		
-		this.transform = new AffineTransform(
-		// Genauso wie die Fenster-Koordinaten, werden die Longitude-Koordinaten
-				// nach rechts (Osten) hin groesser
-				// --> positive Verschiebung
-				getMapArea().getWidth() / getWidth(),
-				// keine Verzerrung
-				0.0, 0.0,
-				// Waehrend die Fenster-Koordinaten nach unten hin groesser
-				// werden,
-				// werden Latitude-Koordinaten nach Sueden hin keiner
-				// --> negative Verschiebung
-				-getMapArea().getHeight() / getHeight(),
-				// Die Longitude-Koordinaten werden nach Osten hin groesser
-				// --> obere linke Ecke des Fensters hat also den Minimalwert
-				getMapArea().getMinX(),
-				// Die Latitude-Koordinaten werden nach Norden hin groesser
-				// --> obere linke Ecke des Fensters hat also den Maximalwert
-				getMapArea().getMaxY());
-	}
-
-	/**
-	 * Liefert eine affine Transformation, um von den Fenster-Koordinaten in die
-	 * Karten-Koordinaten (Lat/Lon) umzurechnen.
-	 * 
-	 * @return eine Kopie der aktuellen Transformation; <code>null</code> wenn
-	 *         noch keine Karte angezeigt wird
-	 */
-	public AffineTransform getTransform() {
-		// Workaround: Obwohl eine Karte gesetzt ist, kann es sein, dass die
-		// Transformation noch nicht gesetzt ist (da noch kein
-		// setMapArea(.)-Aufruf stattgefunden hat!)
-		if (transform == null)
-			resetTransform();
-		// nur Kopie der Transformation zurueckgeben!
-		if (transform != null)
-			return new AffineTransform(transform);
-
-		return null;
-	}
-
-	/**
-	 * 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)} wird ignoriert, falls durch die neue
-	 * MapArea ein nicht gueltiger Massstab entstehen wuerde UND die bisherige
-	 * maparea != null ist
-	 * 
-	 * @param env
-	 *            neuer Kartenausschnitt
-	 * @see #resetTransform()
-	 * @see #getTransform()
-	 * 
-	 * @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
-	 *         Kr&uuml;ger</a>
-	 */
-	@Override
-	public void setMapArea(Envelope env) {
-		
-		if (env != null && env.equals(mapArea)) {
-			// Just return if nothing chnaged 
-			return;
-		}
-		
-		
-		// **********************************************************************
-		// Ueber die Funktionen setMaxZoomScale und setMinZoomScale kann der
-		// geotools JMapPane ein gueltiger Massstabsbereich gesetzt werden.
-		// Dieser
-		// wird hier ueberprueft. (SK)
-		// **********************************************************************
-		if (super.getMapArea() != null) {
-			env = bestAllowedMapArea(env);
-		}
-
-		double oldScale = getScale();
-		Envelope oldEnv = getMapArea();
-
-		super.setMapArea(env);
-
-		resetTransform();
-		double newScale = getScale();
-		Envelope newEnv = getMapArea();
-
-		if (oldScale != newScale)
-			fireMapPaneEvent(new ScaleChangedEvent(this, oldScale, newScale));
-		if (oldEnv == null && newEnv != null || oldEnv != null
-				&& !oldEnv.equals(newEnv))
-			fireMapPaneEvent(new MapAreaChangedEvent(this, oldEnv, newEnv));
-	}
-
-	/**
-	 * 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.
-	 * 
-	 * @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
-	 *         Kr&uuml;ger</a>
-	 */
-	public void mouseClicked(MouseEvent e) {
-		// wenn noch kein Layer dargestellt wird, nichts machen
-		if (getContext().getLayerCount() == 0)
-			return;
-
-		switch (e.getButton()) {
-		// Linksklick --> Eingestellte Funktion
-		case MouseEvent.BUTTON1: // SimpleFeature-Auswahl nicht ueber die
-			// super-Funktion
-			int state = getState();
-
-			if (state == SELECT_TOP || state == SELECT_ONE_FROM_TOP
-					|| state == SELECT_ALL) {
-
-				/**
-				 * BEGIN StefanChange Dieser Block findet sichtbare Features im
-				 * Umkreis des Mausklicks und kümmert sich selbst um das
-				 * verschicken der Events. Dabei wird z.Zt. immer eine
-				 * FeaterCollection mit nur einem SimpleFeature verschickt. Und
-				 * zwar jenes SimpleFeature, welches am nächsten liegt.
-				 */
-
-				// Fenster-Koordinate in Geo-Koordinate umwandelt
-				Point2D geoCoord = getTransform().transform(e.getPoint(), null);
-				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 = getTransform().transform(
-						pAtDistance, null);
-				final Double dist = Math.abs(geoCoordAtDistance.getX()
-						- geoCoord.getX()) / 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);
-
-				final Envelope smallBox = new Envelope(geoCoord.getX() - dist,
-						geoCoord.getX() - dist, geoCoord.getY() + dist,
-						geoCoord.getY() + dist);
-
-				Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>> result = findVisibleFeatures(
-						new BoundingBoxFilterGenerator(smallBox, getContext()
-								.getCoordinateReferenceSystem()), state,
-						envelope);
-
-				boolean featuresFound = false;
-				// Events ausloesen fuer jedes Layer
-				for (Enumeration<MapLayer> element = result.keys(); element
-						.hasMoreElements();) {
-
-					MapLayer layer = element.nextElement();
-					FeatureCollection<SimpleFeatureType, SimpleFeature> fc = result
-							.get(layer);
-					FeatureCollection<SimpleFeatureType, SimpleFeature> fcOne;
-
-					if (fc != null && !fc.isEmpty()) {
-
-						if (fc.size() > 1) {
-							// Hier werden alle Features weggeschmissen, bis auf
-							// das raeumlich naechste.
-
-							SimpleFeature nearestFeature = null;
-							Double nearestDist = 0.0;
-
-							Iterator<SimpleFeature> fcIt = fc.iterator();
-							try {
-
-								while (fcIt.hasNext()) {
-									SimpleFeature f = fcIt.next();
-									Object obj = f.getAttribute(0);
-
-									if (obj instanceof Geometry) {
-										// Bei Punkten ja noch ganz einfach:
-										Geometry featureGeometry = (Geometry) obj;
-										double distance = featureGeometry
-												.distance(mousePoint);
-
-										if ((nearestFeature == null)
-												|| (distance < nearestDist)) {
-											nearestFeature = f;
-											nearestDist = distance;
-										}
-									} else {
-										LOGGER
-												.info("!obj instanceof Geometry      obj = "
-														+ obj
-																.getClass()
-																.getSimpleName());
-									}
-
-								}
-
-							} finally {
-								fc.close(fcIt);
-							}
-
-							fcOne = new MemoryFeatureCollection(fc.getSchema());
-							fc.clear();
-							fcOne.add(nearestFeature);
-						} else {
-							fcOne = fc;
-						}
-						fireMapPaneEvent(new FeatureSelectedEvent(
-								JMapPane.this, layer, envelope, fcOne));
-						featuresFound = true;
-					}
-				}
-
-				// TODO TODO TODO SK: DIese trennung: erst SimpleFeature layers,
-				// dann
-				// grid layers check ist doof!
-				// if (state == SELECT_ALL || !result.isEmpty())
-
-				// LOGGER.info("state= "+state+"     featuresFound = "+
-				// featuresFound);
-				if (state == SELECT_ALL || !featuresFound) {
-					// LOGGER.info("   findGridCoverageValuesAndFireEvents");
-					findGridCoverageValuesAndFireEvents(geoCoord, state);
-				}
-
-				break;
-			}
-			super.mouseClicked(e);
-
-			break;
-
-		// Rechtsklick --> Zoom-Out
-		case MouseEvent.BUTTON3:
-			int oldState = getState();
-			// MS: ist doch eleganter, wenn IMMER mit Rechtsklick raus-gezoomt
-			// werden kann!
-			// // ZOOM_OUT nur wenn LinkmapAreas-Klick auf ZOOM_IN eingestellt ist)
-			// if ( oldState != ZOOM_IN )
-			// return;
-			setState(ZOOM_OUT);
-			super.mouseClicked(e);
-			setState(oldState);
-			break;
-
-		// Sonst nix
-		default:
-			return;
-		}
-
-		setMapArea(mapArea);
-
-		if (getState() == ZOOM_IN && e.getButton() == MouseEvent.BUTTON1)
-			drawScaledPreviewImage_Zoom(ZOOM_IN);
-		else if (getState() == ZOOM_IN && e.getButton() == MouseEvent.BUTTON3)
-			drawScaledPreviewImage_Zoom(ZOOM_OUT);
-		else if (getState() == ZOOM_OUT&& e.getButton() == MouseEvent.BUTTON3)
-			drawScaledPreviewImage_Zoom(ZOOM_OUT);
-
-	}
-
-	/**
-	 * In <code>super.paintComponent(.)</code> wird unter gewissen Umstaenden
-	 * die MapArea neu gesetzt, aber leider ohne {@link #setMapArea(Envelope)}
-	 * aufzurufen, sondern indem einfach die Variable <code>mapArea</code> neu
-	 * belegt wird. Damit auch die Transformation an den neuen Kartenbereich
-	 * angepasst wird, muss diese Methode ueberschrieben werden.
-	 * <p>
-	 * Neu von SK: Ich habe in der Geotools
-	 * {@link org.gtmig.org.geotools.swing.JMapPane} die noetigen variablen
-	 * protected gemacht, um hier schon festzustellen, ob der aufruf von
-	 * super.paintComponent das eigentliche aussehen der Karte veraendern wird.
-	 * Die Methode paintComponent wird naemlich bei jeder Bewegung der Maus
-	 * aufgerufen, und meistens wird super.paintComponent nur ein gebufferted
-	 * Image auf den Ausschnitt zeichnen. Falls die "seriouseChange" zu erwarten
-	 * ist, wird evt. der Mauscursor auf WAIT gesetzt, und auf jeden Fall die
-	 * Methode {@link #resetTransform()} aufgerufen.<br>
-	 * Sinn des Ganzen? Ich habe versucht etwas Performance zu gewinnen, da
-	 * sonst bei jeder Mausbewegung die die {@link AffineTransform} durch
-	 * {@link #resetTransform()} neu berechnet wurde.
-	 * 
-	 * @param g
-	 *            Graphics
-	 * @see #resetTransform()
-	 * 
-	 * @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
-	 *         Kr&uuml;ger</a>
-	 */
-	protected void paintComponent(Graphics g) {
-
-		Cursor oldCursor = null;
-		boolean seriouseChange = false;
-
-		if (!getBounds().equals(oldRect) || reset)
-			seriouseChange = true;
-		else if (!mapArea.equals(oldMapArea))
-			seriouseChange = true;
-
-		if (seriouseChange) {
-			if (setWaitCursorDuringNextRepaint) {
-
-				if (getWaitCursorComponent() != null) {
-					// Der Cursor soll auch in einer anderen Component geaendert
-					// werden..
-					oldCursor = getWaitCursorComponent().getCursor();
-					getWaitCursorComponent().setCursor(WAIT_CURSOR);
-				}
-
-				// Den Cursor extra nochmal in dieser COmponente aendern
-				setCursor(WAIT_CURSOR);
-			}
-		}
-
-		try {
-			
-			
-			// Measuring the time needed to render the mappane.
-			long startTime = new Date().getTime(); 
-			
-			super.paintComponent(g);
-			
-			// Only are we interested in the time it takes to do a *real* rendering of the image
-			if (seriouseChange)
-				lastRenderingDuration = new Date().getTime() - startTime; 
-			
-			
-		} catch (Exception e) {
-			/**
-			 * I only need to catch UnknownHostException.. well...
-			 */
-			LOGGER
-					.info(
-							"Error during JMapPane printComponent. Probably we are offline and reference some online SVGs?",
-							e);
-		}
-		if (seriouseChange) {
-			resetTransform();
-			if (setWaitCursorDuringNextRepaint) {
-				setWaitCursorDuringNextRepaint = false;
-				if (oldCursor != null)
-					getWaitCursorComponent().setCursor(oldCursor);
-				updateCursor(); // Den Cursor in dieser Componente immer wieder
-				// herstellen
-			}
-
-			/**
-			 * Paint an icon in the lower right corner. FeatureRequest: [#717]
-			 * MapIcon has long been disabled and should come back
-			 */
-			if (mapImage != null && baseImage != null) {
-				final Graphics baseG2 = (Graphics2D)baseImage.getGraphics();
-				baseG2
-						.drawImage(
-								mapImage,
-								baseImage.getWidth() - mapImage.getWidth() - 10,
-								baseImage.getHeight() - mapImage.getHeight()
-										- 10, this);
-				
-
-//				// If in debug mode, write the rending time into the display
-//				baseG2.setColor(Color.white);
-//				baseG2.drawString(lastRenderingDuration+"ms rendring", 50, 50);
-//				baseG2.setColor(Color.black);
-//				baseG2.drawString(lastRenderingDuration+"ms rendring", 51, 51);
-				
-				// Repaint with the cached image (fast) which now contains the
-				// logo
-				super.paintComponent(g);
-				
-			}
-		}
-
-	}
-
-	/**
-	 * 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.
-	 * 
-	 * @param layer
-	 *            ein Layer
-	 * @param env
-	 *            Bounding-Box in CRS des MapPane
-	 */
-	private boolean gridLayerIntersectsEnvelope(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(), getContext()
-					.getCoordinateReferenceSystem());
-
-			// TODO warum kann bounds_MapCRS == null sein ?? ?SK fragt martin???
-			if (bounds_MapCRS == null)
-				return false;
-
-			return bounds_MapCRS.intersects(env);
-		} catch (Exception err) {
-			return false;
-		}
-	}
-
-	/**
-	 * Testet (anhand der Features), ob das Objekt eines Layers eine
-	 * Bounding-Box schneidet.
-	 * 
-	 * @param layer
-	 *            ein Layer
-	 * @param env
-	 *            Bounding-Box in CRS des MapPane
-	 */
-	private boolean featureLayerIntersectsEnvelope(MapLayer layer, Envelope env) {
-		try {
-			// // BB umrechnen von Map-CRS in Layer-CRS
-			// Envelope env_LayerCRS = JTSUtil.transformEnvelope(env,
-			// getContext()
-			// .getCoordinateReferenceSystem(), layer.getFeatureSource()
-			// .getSchema().getDefaultGeometry().getCoordinateSystem());
-			// GeometryFilterImpl filter =
-			// createBoundingBoxFilter(env_LayerCRS);
-			// Expression geometry = ff.createAttributeExpression(layer
-			// .getFeatureSource().getSchema().getDefaultGeometry()
-			// .getLocalName());
-			// filter.setExpression1(geometry);
-			FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = (FeatureSource<SimpleFeatureType, SimpleFeature>) layer
-					.getFeatureSource();
-			GeometryFilterImpl filter = new BoundingBoxFilterGenerator(env,
-					getContext().getCoordinateReferenceSystem())
-					.adaptFilter(featureSource);
-			return !layer.getFeatureSource().getFeatures(filter).isEmpty();
-		} catch (Exception err) {
-			return false;
-		}
-	}
-
-	/**
-	 * 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.
-	 * 
-	 * @see #findFeatures(GeometryFilterImpl, int, Envelope)
-	 * 
-	 * @param filterGenerator
-	 *            adapts the filter to a concrete FeatureSource
-	 * @param mode
-	 *            Suchmodus
-	 * @return eine leere {@link Hashtable} falls der Filter {@code null} ist
-	 */
-	protected Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>> findVisibleFeatures(
-			GeomFilterGenerator filterGenerator, int mode, Envelope env) {
-		Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>> result = new Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>>();
-		if (filterGenerator == null)
-			return result;
-
-		// Je nach Modus: Alle oder nur das oberste Layer
-		MapContext context = getContext();
-		MapLayer[] layerList = context.getLayers();
-		for (int i = layerList.length - 1; i >= 0; i--) {
-			MapLayer layer = layerList[i];
-			if (!layer.isVisible())
-				continue;
-
-			// This should never happen, because the check should be performed
-			// earlier already
-			if (!isMapLayerSelectable(layer)) {
-				LOGGER.debug("Ignoring layer " + layer.getTitle()
-						+ " because it is not declared as selectable!");
-				continue;
-			}
-
-			// LOGGER.debug("mode = " + mode);
-
-			// Bei einem Raster-Layer, das die BB schneidet, abbrechen, wenn nur
-			// im obersten (sichtbaren) Layer gesucht wird.
-			// Ansonsten Raster-Layer einfach uebergehen.
-			if (isGridCoverageLayer(layer)) {
-				if (mode == SELECT_TOP
-						&& gridLayerIntersectsEnvelope(layer, env))
-					break;
-				continue;
-			}
-
-			// Filter an Layer koppeln
-			// WICHTIG: Dies darf erst geschehen, NACHDEM das
-			// Schleifen-Abbruch-Kriterium
-			// fuer die Raster-Layer geprueft wurde!!
-			// Werden folgende Zeilen naemlich auf das FeatureSource des
-			// Raster-Layers angewandt, dann "bricht" der Filter "irgendwie"
-			// zusammen und auch die ZUVOR gefilterten FeatureCollections,
-			// sind ploetzlich EMPTY!!!!!!!!!!!!!!!!!!!!!!!!!!!
-			final FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = (FeatureSource<SimpleFeatureType, SimpleFeature>) layer
-					.getFeatureSource();
-			final GeometryFilterImpl distancefilter = 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)
-			 */
-			Filter filter = distancefilter;
-			if (layer.getQuery() != null) {
-				final Filter layerFilter = layer.getQuery().getFilter();
-				if (layerFilter != null && !layerFilter.equals(Filter.INCLUDE)) {
-					filter = distancefilter.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 (!fc.isEmpty()) {
-					fc = filterSLDVisibleOnly(fc, layer.getStyle());
-
-					if (!fc.isEmpty()) {
-						result.put(layer, fc);
-						// Beim Modus "oberstes Layer selektieren" die Schleife
-						// beenden
-						if (mode == SELECT_TOP || mode == SELECT_ONE_FROM_TOP)
-							break;
-					}
-
-				}
-			} catch (IOException err) {
-				LOGGER.error("applying the distanceWithin filter", err);
-			}
-
-			// for ( FeatureCollection fc1 : result.values() )
-			// LOGGER.debug("A  "+fc1+"    "+fc1.isEmpty());
-		}
-		// for ( FeatureCollection fc1 : result.values() )
-		// LOGGER.debug("B   "+fc1+"    "+fc1.isEmpty());
-
-		return result;
-	}
-
-	/**
-	 * Ermittelt alle 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.
-	 * 
-	 * 17.4.08, Stefan
-	 * 
-	 * @param iterator
-	 *            Filter
-	 * @param mode
-	 *            Suchmodus
-	 * @return eine leere {@link Hashtable} falls der Filter {@code null} ist
-	 */
-	protected Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>> findFeatures(
-			GeomFilterGenerator filterGenerator, int mode, Envelope env) {
-		Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>> result = new Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>>();
-		if (filterGenerator == null)
-			return result;
-
-		// Je nach Modus: Alle oder nur das oberste Layer
-		MapContext context = getContext();
-		MapLayer[] layerList = context.getLayers();
-		for (int i = layerList.length - 1; i >= 0; i--) {
-			MapLayer layer = layerList[i];
-			if (!layer.isVisible())
-				continue;
-
-			// Bei einem Raster-Layer, das die BB schneidet, abbrechen, wenn nur
-			// im
-			// obersten (sichtbaren) Layer gesucht
-			// wird.AbstractGridCoverage2DReader
-			// Ansonsten Raster-Layer einfach uebergehen.
-			if (isGridCoverageLayer(layer)) {
-				if (mode == SELECT_TOP
-						&& gridLayerIntersectsEnvelope(layer, env))
-					break;
-				continue;
-			}
-
-			// Filter an Layer koppeln
-			// WICHTIG: Dies darf erst geschehen, NACHDEM das
-			// Schleifen-Abbruch-Kriterium
-			// fuer die Raster-Layer geprueft wurde!!
-			// Werden folgende Zeilen naemlich auf das FeatureSource des
-			// Raster-Layers angewandt, dann "bricht" der Filter "irgendwie"
-			// zusammen und auch die ZUVOR gefilterten FeatureCollections,
-			// sind ploetzlich EMPTY!!!!!!!!!!!!!!!!!!!!!!!!!!!
-			final FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = (FeatureSource<SimpleFeatureType, SimpleFeature>) layer
-					.getFeatureSource();
-			final GeometryFilterImpl filter = filterGenerator
-					.adaptFilter(featureSource);
-
-			try {
-				// Filter auf Layer des Features anwenden
-				// FeatureCollection fc = layer.getFeatureSource().getFeatures(
-				// FilterUtil.cloneFilter(filter) ); // KLAPPT (NOCH) NICHT
-				FeatureCollection<SimpleFeatureType, SimpleFeature> fc = featureSource
-						.getFeatures(filter);
-
-				// Liefert eine FeatureCollection zurück, in welcher nur
-				// Features enthalten sind, welche bei der aktuellen
-				// Anzeigeskala aufgrund des Styles gerendert werden.
-				fc = filterSLDVisibleOnly(fc, layer.getStyle());
-
-				if (!fc.isEmpty()) {
-					result.put(layer, fc);
-					// Beim Modus "oberstes Layer selektieren" die Schleife
-					// jetzt beenden, da wir sichtbare Features gefunden haben.
-					if (mode == SELECT_TOP || mode == SELECT_ONE_FROM_TOP)
-						break;
-				}
-			} catch (Exception err) {
-				LOGGER.error("Looking for features:", err);
-			}
-
-			// for ( FeatureCollection fc1 : result.values() )
-			// LOGGER.debug("A  "+fc1+"    "+fc1.isEmpty());
-		}
-		// for ( FeatureCollection fc1 : result.values() )
-		// LOGGER.debug("B   "+fc1+"    "+fc1.isEmpty());
-
-		return result;
-	}
-
-	/**
-	 * SLD Rules können die Paramter MinScaleDenominator und MaxScaleDenominator
-	 * enthalten. Dadurch können Elemente für manche Zoom-Stufen deaktiviert
-	 * werden.
-	 * 
-	 * @param fc
-	 *            Die zu filternde FeatureCollection. Diese wird nicht
-	 *            verändert.
-	 * @param style
-	 *            Der Style, mit dem die Features gerendert werden (z.b.
-	 *            layer.getStyle() )
-	 * 
-	 * @return Eine FeatureCollection in welcher nur die Features enthalten
-	 *         sind, welche bei aktuellen Scale mit dem übergebenen Style
-	 *         gerendert werden.
-	 * 
-	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
-	 *         Kr&uuml;ger</a>
-	 */
-	private MemoryFeatureCollection filterSLDVisibleOnly(
-			final FeatureCollection<SimpleFeatureType, SimpleFeature> fc,
-			final Style style) {
-
-		// Der "scaleDenominator" der aktuellen JMapPane
-		Double scaleDenominator = RendererUtilities
-				.calculateOGCScale(new ReferencedEnvelope(getMapArea(),
-						getContext().getCoordinateReferenceSystem()),
-						getSize().width, null);
-
-		return StylingUtil.filterSLDVisibleOnly(fc, style, scaleDenominator);
-	}
-
-	/**
-	 * 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 mode
-	 *            Suchmodus
-	 * @param env
-	 *            Bereich der durchsucht wird (fuer das Filtern irrelevant; wird
-	 *            nur fuer Events benoetigt!)
-	 */
-	protected boolean findFeaturesAndFireEvents(
-			GeomFilterGenerator filterGenerator, int mode, Envelope env) {
-		Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>> result = findVisibleFeatures(
-				filterGenerator, mode, env);
-
-		// Events ausloesen fuer jedes Layer
-		for (final Enumeration<MapLayer> e = result.keys(); e.hasMoreElements();) {
-
-			final MapLayer layer = e.nextElement();
-
-			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 mode
-	 *            Suchmodus
-	 * @return eine leere {@link Hashtable} falls die Bounding-Box {@code null}
-	 *         ist
-	 */
-	protected Hashtable<MapLayer, GridCoverage2D> findGridCoverageSubsets(
-			Envelope env, int mode) {
-		Hashtable<MapLayer, GridCoverage2D> result = new Hashtable<MapLayer, GridCoverage2D>();
-		if (env == null)
-			return result;
-
-		MapContext context = getContext();
-		// 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 = getLayerSourceObject(layer);
-			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 ((mode == SELECT_TOP || mode == 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.spatialschema.geometry.Envelope gtGenEnv = new
-			// GeneralEnvelope
-			// ((org.opengis.spatialschema.geometry.Envelope)gtEnv2D); //
-			// gt2-2.3.4
-			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 (mode == SELECT_TOP || mode == 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
-	 */
-	protected 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} 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
-	 * @param mode
-	 *            Suchmodus
-	 * @return eine leere {@link Hashtable} falls keine Werte ermittelt werden
-	 *         konnten
-	 * 
-	 * @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
-	 *         Kr&uuml;ger</a>
-	 */
-	protected Hashtable<MapLayer, double[]> findGridCoverageValues(
-			Point2D point, int mode) {
-		Hashtable<MapLayer, double[]> result = new Hashtable<MapLayer, double[]>();
-
-		if (point == null)
-			return result;
-
-		MapContext context = getContext();
-		// 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];
-			if (!layer.isVisible())
-				continue;
-			Object layerObj = getLayerSourceObject(layer);
-
-			// LOGGER.info("layerObj = "+layerObj.getClass().getSimpleName());
-
-			// SK 29.9.2007 Vorher:
-			// // Bei einem Nicht-Raster-Layer, das den Punkt beinhaltet,
-			// abbrechen, wenn nur im
-			// // obersten (sichtbaren) Layer gesucht wird.
-			// // Ansonsten Nicht-Raster-Layer einfach uebergehen.
-			// if ( !(layerObj instanceof GridCoverage2D) ) {
-			// if ( mode == SELECT_TOP &&
-			// featureLayerIntersectsEnvelope(layer,new
-			// Envelope(point.getX(),point.getX(),point.getY(),point.getY())) )
-			// break;
-			// continue;
-			// }
-
-			// Bei einem Nicht-Raster-Layer, das den Punkt beinhaltet,
-			// abbrechen, wenn nur im
-			// obersten (sichtbaren) Layer gesucht wird.
-			// Ansonsten Nicht-Raster-Layer einfach uebergehen.
-			// SK 29.9.07: Ein AbstractGridCoverage2DReader ist auch ein Raster
-			if (!(layerObj instanceof GridCoverage2D || layerObj instanceof AbstractGridCoverage2DReader)) {
-				final Envelope pointAsEnvelope = new Envelope(point.getX(),
-						point.getX(), point.getY(), point.getY());
-				if (mode == SELECT_TOP
-						&& featureLayerIntersectsEnvelope(layer,
-								pointAsEnvelope)) {
-				}
-				continue;
-			}
-
-			GridCoverage2D sourceGrid;
-
-			if (layerObj instanceof AbstractGridCoverage2DReader) {
-				// LOGGER.info("layerObj instanceof AbstractGridCoverage2DReader"
-				// );
-				AbstractGridCoverage2DReader reader = (AbstractGridCoverage2DReader) layerObj;
-				Parameter readGG = new Parameter(
-						AbstractGridFormat.READ_GRIDGEOMETRY2D);
-
-				ReferencedEnvelope mapExtend = new org.geotools.geometry.jts.ReferencedEnvelope(
-						mapArea, context.getCoordinateReferenceSystem());
-
-				readGG.setValue(new GridGeometry2D(new GeneralGridEnvelope(
-						getBounds()), mapExtend));
-
-				try {
-					sourceGrid = (GridCoverage2D) reader
-							.read(new GeneralParameterValue[] { readGG });
-				} catch (Exception e) {
-					LOGGER.error(
-							"read(new GeneralParameterValue[] { readGG })", e);
-					continue;
-				}
-			} else {
-				// Ein instanceof ist nicht noetig, da sonst schon break oder
-				// continue aufgerufen worden waere
-				sourceGrid = (GridCoverage2D) layerObj;
-			}
-
-			// vorher: double[] value = new double[2];
-
-			// getNumSampleDimensions gibt die Anzahl der Baender des Rasters
-			// zurueck.
-			double[] values = new double[sourceGrid.getNumSampleDimensions()];
-
-			try {
-				// Grid an Geo-Position auswerten
-				sourceGrid.evaluate(point, values);
-			} catch (CannotEvaluateException err) {
-				// z.B. Punkt ausserhalb des Rasters --> Layer uebergehen
-				continue;
-			} catch (Exception e) {
-				LOGGER.error("sourceGrid.evaluate(point, values);", e);
-				continue;
-			}
-
-			// SK: voher wurde nur der erste Wert zurueckgegeben
-			// result.put(layer,value[0]);
-			// jetzt werden alle werte zueuckgegeben
-
-			result.put(layer, values);
-			// Beim Modus "oberstes Layer selektieren" die Schleife beenden
-			if (mode == SELECT_TOP)
-				break;
-		}
-		return result;
-	}
-
-	/**
-	 * 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
-	 *         Kr&uuml;ger</a>
-	 */
-	protected 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();
-	}
-
-	// /**
-	// * Bereitet einen BoundingBox-Filter vor. Das "linke" Attribut der
-	// * Expression (das SimpleFeature-Attribut, auf das der Filter angewendet
-	// wird),
-	// * wird dabei noch nicht belegt. Dies geschieht erst bei der Auswertung
-	// * entsprechend des jeweiligen Layers
-	// *
-	// * @param env
-	// * Bounding-Box
-	// */
-	// private static GeometryFilterImpl createBoundingBoxFilter(Envelope env) {
-	// // Filter fuer Envelope zusammenstellen
-	// Expression bbox = ff.createBBoxExpression(env);
-	// GeometryFilterImpl bboxFilter = (GeometryFilterImpl) ff
-	// .createGeometryFilter(AbstractFilter.GEOMETRY_BBOX);
-	// // GeometryFilterImpl bboxFilter =
-	// // (GeometryFilterImpl)ff.createGeometryFilter
-	// // (AbstractFilter.GEOMETRY_WITHIN);
-	// bboxFilter.setExpression2(bbox);
-	// return bboxFilter;
-	// }
-	//
-	// /**
-	// * Bereitet einen Punkt-Filter vor. Das "linke" Attribut der Expression
-	// (das
-	// * SimpleFeature-Attribut, auf das der Filter angewendet wird), wird dabei
-	// noch
-	// * nicht belegt. Dies geschieht erst bei der Auswertung entsprechend des
-	// * jeweiligen Layers
-	// *
-	// * @param point
-	// * Geo-Koordinate
-	// */
-	// private static GeometryFilterImpl createPointFilter(Point2D point) {
-	// // Filter fuer Envelope zusammenstellen
-	// Geometry geometry = gf.createPoint(new Coordinate(point.getX(), point
-	// .getY()));
-	// GeometryFilterImpl pointFilter = (GeometryFilterImpl) ff
-	// .createGeometryFilter(GeometryFilterImpl.GEOMETRY_CONTAINS);
-	// pointFilter.setExpression2(ff.createLiteralExpression(geometry));
-	// return pointFilter;
-	// }
-	//
-	// /**
-	// * Bereitet einen "InDerNaehe von" Distance-Filter vor. Das "linke"
-	// Attribut
-	// * der Expression (das SimpleFeature-Attribut, auf das der Filter
-	// angewendet
-	// * wird), wird dabei noch nicht belegt. Dies geschieht erst bei der
-	// * Auswertung entsprechend des jeweiligen Layers
-	// *
-	// * Wird benoetigt, um mit der Maus einen Punkt zu treffen.
-	// *
-	// * @param point
-	// * Geo-Koordinate
-	// * @param dist
-	// * Distanz zum Punkt in Einheiten des Layers
-	// *
-	// * TODO SK Auf FilterFactory2 ändern... Beispiel von
-	// * http://docs.codehaus.org/display/GEOTDOC/Filter+Examples
-	// * funktioniert erst ab 2.5 ?? Vor dem Distcheck einen BBOX check
-	// * sollte die geschwindigkeit erhöhen.
-	// *
-	// * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
-	// * Kr&uuml;ger</a>
-	// */
-	// private static GeometryFilterImpl createNearPointFilter(
-	// final Point2D point, final Double dist) {
-	// // Filter fuer Envelope zusammenstellen
-	// final Geometry geometry = gf.createPoint(new Coordinate(point.getX(),
-	// point.getY()));
-	//
-	// final DWithinImpl dwithinFilter = (DWithinImpl) ff
-	// .createGeometryDistanceFilter(DWithinImpl.GEOMETRY_DWITHIN);
-	//
-	// dwithinFilter.setDistance(dist);
-	//
-	// dwithinFilter.setExpression2(ff.createLiteralExpression(geometry));
-	//
-	// return dwithinFilter;
-	// }
-
-	/**
-	 * Prueft, ob es sich bei einem Layer um ein Raster-Layer handelt.
-	 * Raster-Layer zeichnen sich dadurch aus, dass die zugrunde liegende
-	 * {@link FeatureCollection} nur ein SimpleFeature enthaelt, das genau ein
-	 * Attribut mit dem Namen "GridCoverage" hat.
-	 * 
-	 * SK: Pyramidenlayer aka AbstractGridCoverage2DReader geben auch true
-	 * zurück.
-	 * 
-	 * @param layer
-	 *            zu ueberpruefendes Layer
-	 */
-	public static boolean isGridCoverageLayer(MapLayer layer) {
-		final Object layerSourceObject = getLayerSourceObject(layer);
-		boolean b = (layerSourceObject instanceof GridCoverage2D)
-				|| (layerSourceObject instanceof AbstractGridCoverage2DReader);
-		// if (!b && layerSourceObject instanceof DefaultFeatureResults){
-		// DefaultFeatureResults dfr = (DefaultFeatureResults)
-		// layerSourceObject;
-		// }
-		// LOGGER.debug(b+"= "+layerSourceObject.getClass().getSimpleName()+" "+
-		// layer.getTitle());
-		return b;
-		// try {
-		// FeatureCollection fc = layer.getFeatureSource().getFeatures();
-		// // Layer muss genau ein SimpleFeature beinhalten
-		// if ( fc == null || fc.size() != 1 )
-		// return false;
-		// // SimpleFeature muss genau 1 Attribut mit dem Namen "GridCoverage"
-		// haben
-		// SimpleFeatureType ftype = fc.getFeatureType();
-		// if ( ftype == null || ftype.getAttributeCount() != 1 ||
-		// !"GridCoverage".equalsIgnoreCase(ftype.getAttributeType(0).getName())
-		// )
-		// return false;
-		// } catch (Exception err) {
-		// }
-		// return true;
-	}
-
-	/**
-	 * Liefert das Objekt ({@link GridCoverage2D} oder {@link FeatureCollection}
-	 * oder {@link AbstractGridCoverageReader} auf dem ein Layer basiert. Ein
-	 * Raster-Layer zeichnen sich dadurch aus, dass die zugrunde liegende
-	 * {@link FeatureCollection} nur ein SimpleFeature enthaelt, das genau ein
-	 * Attribut mit Namen "GridCoverage" und Typ {@code GridCoverage2D} oder
-	 * {@link AbstractGridCoverageReader} hat. Sind diese Bedingungen erfuellt,
-	 * wird das 2. Attribut zurueckgegeben, ansonsten die
-	 * {@link FeatureCollection}.
-	 * 
-	 * @see {@link FeatureUtilities#wrapGridCoverage(GridCoverage2D)} and
-	 *      {@link FeatureUtilities#wrapGridCoverageReader(AbstractGridCoverage2DReader, GeneralParameterValue[])}
-	 * 
-	 * @param layer
-	 *            ein Layer
-	 * @return {@code null}, falls das Objekt nicht ermittelt werden kann (da
-	 *         ein Fehler aufgetreten ist).
-	 */
-	public static Object getLayerSourceObject(MapLayer layer) {
-		return FeatureUtil
-				.getWrappedGeoObject((FeatureSource<SimpleFeatureType, SimpleFeature>) layer
-						.getFeatureSource());
-
-	}
-
-	/**
-	 * Should be called when the {@link JMapPane} is not needed no more to help
-	 * the GarbageCollector
-	 * 
-	 * Removes all {@link JMapPaneListener}s that are registered
-	 * 
-	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
-	 *         Kr&uuml;ger</a>
-	 */
-
-	public void dispose() {
-		if (isDisposed())
-			return;
-
-		if (dragWaitCursorListener != null)
-			this.removeMouseListener(dragWaitCursorListener);
-		if (mouseWheelZoomListener != null)
-			this.removeMouseWheelListener(mouseWheelZoomListener);
-
-		// Alle mapPaneListener entfernen
-		mapPaneListeners.clear();
-
-		getContext().clearLayerList();
-
-		removeAll();
-		disposed = true;
-	}
-
-	/**
-	 * A flag indicating if dispose() has already been called. If true, then
-	 * further use of this {@link JMapPane} is undefined.
-	 */
-	private boolean isDisposed() {
-		return disposed;
-	}
-
-	//
-	// /**
-	// * Werden Rasterlayer waehrend einer PAN Aktion versteckt?
-	// * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
-	// Kr&uuml;ger</a>
-	// */
-	// public boolean isHideRasterLayersDuringPan() {
-	// return hideRasterLayersDuringPan;
-	// }
-	//
-	// /**
-	// * Bestimmt, ob Rasterlayer waehrend einer PAN Aktion versteckt werden
-	// soll. Default ist false.
-	// * @param hideRasterLayersDuringPan
-	// * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
-	// Kr&uuml;ger</a>
-	// */
-	// public void setHideRasterLayersDuringPan(boolean
-	// hideRasterLayersDuringPan) {
-	// this.hideRasterLayersDuringPan = hideRasterLayersDuringPan;
-	// }
-
-	public boolean isSetWaitCursorDuringNextRepaint() {
-		return setWaitCursorDuringNextRepaint;
-	}
-
-	/**
-	 * When setting this to true, the next repaint of this component will be
-	 * accompanied by a WAIT Cursor
-	 * 
-	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
-	 *         Kr&uuml;ger</a>
-	 */
-	public void setWaitCursorDuringNextRepaint(
-			boolean waitCursorDuringNextRepaint) {
-		this.setWaitCursorDuringNextRepaint = waitCursorDuringNextRepaint;
-	}
-
-	/**
-	 * Gibt den "normalen" Cursor zurueck. Dieser kann neben dem "pointer" auch
-	 * ein Sanduhr-Wartecursor sein.
-	 * 
-	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
-	 *         Kr&uuml;ger</a>
-	 */
-	public Cursor getNormalCursor() {
-		return normalCursor;
-	}
-
-	/**
-	 * Setzt den "normalen" Cursor. Dieser kann neben dem default "pointer" z.B.
-	 * auch ein Sanduhr-Wartecursor sein.
-	 * 
-	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
-	 *         Kr&uuml;ger</a>
-	 */
-	public void setNormalCursor(Cursor normalCursor) {
-		this.normalCursor = normalCursor;
-	}
-
-	// /**
-	// * Prueft, ob es sich bei einem Layer um ein Raster-Layer handelt.
-	// * Raster-Layer zeichnen sich dadurch aus, dass die zugrunde liegende
-	// * {@link FeatureCollection} nur ein SimpleFeature enthaelt, das genau ein
-	// Attribut
-	// * vom Type {@link org.geotools.feature.type.FeatureAttributeType} hat,
-	// welches
-	// * wiederum genau zwei Attribute hat:<br>
-	// * Eines vom Typ {@link
-	// org.opengis.spatialschema.geometry.geometry.Polygon}
-	// * und eines vom Typ {@link org.opengis.coverage.grid.GridCoverage}.
-	// * @param layer zu ueberpruefendes Layer
-	// */
-	// public static boolean isGridCoverageLayer(MapLayer layer) {
-	// try {
-	// FeatureCollection fc = layer.getFeatureSource().getFeatures();
-	// // Layer muss genau ein SimpleFeature beinhalten
-	// if ( fc == null || fc.size() != 1 )
-	// return false;
-	// // SimpleFeature muss genau 1 Attribut vom Typ FeatureAttributeType haben
-	// SimpleFeatureType ftype = fc.getFeatureType();
-	// if ( ftype == null || ftype.getAttributeCount() != 1 ||
-	// !(ftype.getAttributeType(0) instanceof
-	// org.geotools.feature.type.FeatureAttributeType) )
-	// return false;
-	// // FeatureAttribute muss genau 2 Atrribute haben
-	// org.geotools.feature.type.FeatureAttributeType atype =
-	// (org.geotools.feature
-	// .type.FeatureAttributeType)ftype.getAttributeType(0);
-	// if ( atype == null || atype.getAttributeCount() != 2 )
-	// return false;
-	// // Typ des ersten Attributs muss Polygon sein
-	// if ( !com.vividsolutions.jts.geom.Polygon.class.isAssignableFrom(
-	// atype.getAttributeType(0).getType() ) )
-	// return false;
-	// // Typ des zweiten Attributs muss GridCoverage sein
-	// if ( !org.opengis.coverage.grid.GridCoverage.class.isAssignableFrom(
-	// atype.getAttributeType(1).getType() ) )
-	// return false;
-	//
-	// } catch (Exception err) {
-	// }
-	// return true;
-	// }
-
-	/**
-	 * Nuetzlich wenn die Componente gedruckt (z.B. wenn ein Screenshot gemacht
-	 * wird) wird. Dann werden wird der Hintergrund auf WEISS gesetzt.
-	 * 
-	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
-	 *         Kr&uuml;ger</a>
-	 */
-	@Override
-	public void print(Graphics g) {
-		Color orig = getBackground();
-		setBackground(Color.WHITE);
-
-		// wrap in try/finally so that we always restore the state
-		try {
-			super.print(g);
-		} finally {
-			setBackground(orig);
-		}
-	}
-
-	/**
-	 * Sets the mapArea to smartly present the given features. Note: The method
-	 * does not call {@link #repaint()} on the {@link JMapPane}.
-	 */
-	public void zoomTo(SimpleFeature feature) {
-		final MemoryFeatureCollection mfc = new MemoryFeatureCollection(feature
-				.getFeatureType());
-		mfc.add(feature);
-		zoomTo(mfc);
-	}
-
-	/**
-	 * Sets the mapArea to best possibly present the given features. If only one
-	 * single point is given, the window is moved over the point.
-	 * 
-	 * Note: The method does not call {@link #repaint()} on the {@link JMapPane}
-	 * .
-	 * 
-	 * @param features
-	 *            if <code>null</code> or size==0, the function doesn nothing.
-	 */
-	public void zoomTo(
-			FeatureCollection<SimpleFeatureType, SimpleFeature> features) {
-
-		CoordinateReferenceSystem mapCRS = getContext()
-				.getCoordinateReferenceSystem();
-		CoordinateReferenceSystem fCRS = features.getSchema()
-				.getGeometryDescriptor().getCoordinateReferenceSystem();
-		// if (! mapCRS.equals(fCRS)) {
-		// throw new
-		// RuntimeException(
-		// "Projecting the features to show to the map CRS is not yet implemented."
-		// );
-		// }
-
-		double width = mapArea.getWidth();
-		double height = mapArea.getHeight();
-		double ratio = height / width;
-
-		if (features == null || features.size() == 0) {
-			// feature count == 0 Zoom to the full extend
-			return;
-		} else if (features.size() == 1) {
-
-			// feature count == 1 Just move the window to the point and zoom 'a
-			// bit'
-			SimpleFeature singleFeature = (SimpleFeature) features.iterator()
-					.next();
-
-			if (((Geometry) singleFeature.getDefaultGeometry())
-					.getCoordinates().length > 1) {
-				// System.out.println("Zoomed to only pne poylgon");
-				// Poly
-				// TODO max width vs. height
-				width = features.getBounds().getWidth() * 3;
-				height = ratio * width;
-			} else {
-				// System.out.println("Zoomed in a bit becasue only one point");
-				// width *= .9;
-				// height *= .9;
-			}
-
-			Coordinate centre = features.getBounds().centre();
-			if (!mapCRS.equals(fCRS)) {
-				// only to calculations if the CRS differ
-				try {
-					MathTransform fToMap;
-					fToMap = CRS.findMathTransform(fCRS, mapCRS);
-					// centre is transformed to the mapCRS
-					centre = JTS.transform(centre, null, fToMap);
-				} catch (FactoryException e) {
-					LOGGER.error("Looking for a Math transform", e);
-				} catch (TransformException e) {
-					LOGGER.error("Looking for a Math transform", e);
-				}
-			}
-
-			Coordinate newLeftBottom = new Coordinate(centre.x - width / 2.,
-					centre.y - height / 2.);
-			Coordinate newTopRight = new Coordinate(centre.x + width / 2.,
-					centre.y + height / 2.);
-
-			Envelope newMapArea = new Envelope(newLeftBottom, newTopRight);
-
-			setMapArea(newMapArea);
-
-		} else {
-			ReferencedEnvelope fBounds = features.getBounds();
-
-			Envelope bounds;
-			if (!mapCRS.equals(fCRS)) {
-				bounds = JTSUtil.transformEnvelope(fBounds, fCRS, mapCRS);
-			} else {
-				bounds = fBounds;
-			}
-			// BB umrechnen von Layer-CRS in Map-CRS
-
-			// Expand a bit
-			bounds.expandBy(bounds.getWidth() / 6., bounds.getHeight() / 6.);
-
-			setMapArea(bounds);
-		}
-	}
-
-	/**
-	 * 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>
-	 * The type of filter (e.g. distance or bounding box) is specified by the
-	 * subclass implemenation of
-	 * {@link #prepareFilter(CoordinateReferenceSystem)} .
-	 * 
-	 * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
-	 */
-	private static abstract class GeomFilterGenerator {
-		/**
-		 * Holds the {@link CoordinateReferenceSystem} the filter constraint
-		 * bases on.
-		 */
-		protected CoordinateReferenceSystem baseCRS = null;
-		/**
-		 * Caches the base filter constraint for several
-		 * {@link CoordinateReferenceSystem CoordinateReferenceSystems}.
-		 */
-		protected Map<CoordinateReferenceSystem, GeometryFilterImpl> filterCache = new HashMap<CoordinateReferenceSystem, GeometryFilterImpl>();
-
-		/**
-		 * Creates a new filter generator
-		 * 
-		 * @param crs
-		 *            {@link CoordinateReferenceSystem} the base constraint
-		 *            ("right" filter argument is relative to)
-		 */
-		public GeomFilterGenerator(CoordinateReferenceSystem crs) {
-			this.baseCRS = crs;
-		}
-
-		/**
-		 * Creates a filter containing the base constraint ("right" argument)
-		 * transformed to the given {@link CoordinateReferenceSystem}.
-		 * 
-		 * @param crs
-		 *            the {@link CoordinateReferenceSystem} the base constraint
-		 *            is transformed to
-		 */
-		protected abstract GeometryFilterImpl prepareFilter(
-				CoordinateReferenceSystem crs);
-
-		/**
-		 * 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 #prepareFilter(CoordinateReferenceSystem)}.
-		 * 
-		 * @param fs
-		 *            {@link FeatureSource} the filter is adaped to
-		 * @return
-		 */
-		public GeometryFilterImpl adaptFilter(
-				FeatureSource<SimpleFeatureType, SimpleFeature> fs) {
-			GeometryDescriptor geomDescr = fs.getSchema()
-					.getGeometryDescriptor();
-			CoordinateReferenceSystem fsCRS = geomDescr
-					.getCoordinateReferenceSystem();
-			GeometryFilterImpl filter = filterCache.get(fsCRS);
-			if (filter == null) {
-				filter = prepareFilter(fsCRS);
-				filterCache.put(fsCRS, filter);
-			}
-			Expression geometry = ff.property(geomDescr.getLocalName());
-			filter.setExpression1(geometry);
-			return filter;
-		}
-
-	}
-
-	/**
-	 * {@link GeomFilterGenerator} for a bounding box constraint.
-	 * 
-	 * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
-	 */
-	private static class BoundingBoxFilterGenerator extends GeomFilterGenerator {
-		/**
-		 * Holds the base constraint (bounding box {@link Envelope}) relative to
-		 * the {@linkplain GeomFilterGenerator#baseCRS base CRS}.
-		 */
-		protected Envelope baseEnv = null;
-
-		/**
-		 * Creates a new filter generator.
-		 * 
-		 * @param baseEnv
-		 *            defines the bounding box
-		 * @param crs
-		 *            defines the CRS of the bounding box
-		 */
-		public BoundingBoxFilterGenerator(Envelope baseEnv,
-				CoordinateReferenceSystem crs) {
-			super(crs);
-			this.baseEnv = baseEnv;
-		}
-
-		/**
-		 * Prepares a filter with the bounding box transformed to the given
-		 * {@link CoordinateReferenceSystem} as the "right" argument.
-		 * 
-		 * @param crs
-		 *            the {@link CoordinateReferenceSystem} the bounding box is
-		 *            transformed to
-		 */
-		protected GeometryFilterImpl prepareFilter(CoordinateReferenceSystem crs) {
-			Envelope bbEnv = baseEnv;
-			if (!baseCRS.equals(crs))
-				bbEnv = JTSUtil.transformEnvelope(baseEnv, baseCRS, crs);
-			// Filter fuer Envelope zusammenstellen
-			Expression bbox = FilterUtil.FILTER_FAC.createBBoxExpression(bbEnv);
-			GeometryFilterImpl bboxFilter = (GeometryFilterImpl) FilterUtil.FILTER_FAC
-					.createGeometryFilter(AbstractFilter.GEOMETRY_BBOX);
-			// GeometryFilterImpl bboxFilter =
-			// (GeometryFilterImpl)ff.createGeometryFilter(AbstractFilter.
-			// GEOMETRY_WITHIN);
-			bboxFilter.setExpression2(bbox);
-			return bboxFilter;
-		}
-	}
-
-	/**
-	 * {@link GeomFilterGenerator} for a "near distance" constraint.
-	 * 
-	 * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
-	 */
-	private static class NearPointFilterGenerator 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;
-
-		/**
-		 * Creates a new filter generator.
-		 * 
-		 * @param basePoint
-		 *            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,
-				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);
-		}
-
-		/**
-		 * Creates a new filter generator.
-		 * 
-		 * @param basePoint
-		 *            defines 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(Point2D basePoint, double dist,
-				CoordinateReferenceSystem crs) {
-			this(new Coordinate(basePoint.getX(), basePoint.getY()), dist, crs);
-		}
-
-		/**
-		 * Prepares a filter with the base point and distance transformed to the
-		 * given {@link CoordinateReferenceSystem} as the "right" argument.
-		 * 
-		 * @param crs
-		 *            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);
-
-				if (nearPoint == null || nearPoint2 == null)
-					throw new RuntimeException("Unable to transform CRS from "
-							+ baseCRS + " to " + crs);
-
-				nearDist = Math.abs(nearPoint.x - nearPoint2.x);
-			}
-			// Filter fuer Point zusammenstellen
-			final Geometry geometry = FilterUtil.GEOMETRY_FAC
-					.createPoint(nearPoint);
-
-			final DWithinImpl dwithinFilter = new DWithinImpl(
-					FilterUtil.FILTER_FAC2, null, null);
-			dwithinFilter.setDistance(nearDist);
-			dwithinFilter.setExpression2(FilterUtil.FILTER_FAC2
-					.literal(geometry));
-
-			return dwithinFilter;
-		}
-
-	}
-
-	/**
-	 * Sets whether a layer is regarded or ignored on {@link #SELECT_TOP},
-	 * {@link #SELECT_ALL} and {@link #SELECT_ONE_FROM_TOP} actions.
-	 * 
-	 * @param layer
-	 *            a layer
-	 * @param selectable
-	 *            if {@code false} the layer is ignored during the upper
-	 *            mentioned actions. If <code>null</code>, the default (true)
-	 *            will be used.
-	 */
-	public void setMapLayerSelectable(MapLayer layer, Boolean selectable) {
-		if (selectable == null)
-			mapLayerSelectable.remove(layer);
-		else
-			mapLayerSelectable.put(layer, selectable);
-	}
-
-	/**
-	 * Returns whether a layer is regarded or ignored on {@link #SELECT_TOP},
-	 * {@link #SELECT_ALL} and {@link #SELECT_ONE_FROM_TOP} actions. Returns
-	 * <code>true</code> if the selectability has not been defined.
-	 * 
-	 * @param layer
-	 *            a layer
-	 */
-	public boolean isMapLayerSelectable(MapLayer layer) {
-		Boolean selectable = mapLayerSelectable.get(layer);
-		return selectable == null ? true : selectable;
-	}
-
-	/**
-	 * Returns in milli seconds the time the last rending of the
-	 * {@link JMapPane} took. #Long.MAX_VALUE if the JMapPane has not been
-	 * rendered yet.
-	 */
-	public long getLastRenderingDuration() {
-		return lastRenderingDuration;
-	}
-}

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/LayeredEditorFrame.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/LayeredEditorFrame.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/LayeredEditorFrame.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -80,7 +80,7 @@
    *            {@code null} wird eine neue {@link LayeredMapPane}-Instanz erzeugt)
    */
   public LayeredEditorFrame(LayeredMapPane lmp, String title) {
-    super( lmp != null ? lmp : new LayeredMapPane(new GeoMapPane(new JEditorPane(),null,null,null, null)),title);
+    super( lmp != null ? lmp : new LayeredMapPane(new GeoMapPane(new JEditorPane(),null,null, null)),title);
     if ( !(layeredMapPane.geoMapPane.mapPane instanceof JEditorPane) )
       throw new IllegalArgumentException("LayeredMapPane must contain a JEditorPane to use in LayeredEditorFrame.");
     this.toolBar  = new JEditorToolBar( (JEditorPane)layeredMapPane.geoMapPane.mapPane );

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/LayeredMapFrame.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/LayeredMapFrame.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/LayeredMapFrame.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -48,7 +48,7 @@
 
 import schmitzm.geotools.map.event.FeatureSelectedEvent;
 import schmitzm.geotools.map.event.GridCoverageSelectedEvent;
-import schmitzm.geotools.map.event.JMapPaneEvent;
+import schmitzm.geotools.map.event.MapPaneEvent;
 import schmitzm.geotools.map.event.JMapPaneListener;
 import schmitzm.swing.SelectionInputOption;
 import schmitzm.swing.SwingUtil;
@@ -61,7 +61,7 @@
  * {@link LayeredMapPane#isVisualisable(Object)}-Methode zu entnehmen.<br>
  * Das Fenster besteht aus 3 Komponenten:
  * <ol>
- * <li>Eine Map ({@link JMapPane}) zu grafischen Darstellung der Layer</li>
+ * <li>Eine Map ({@link SelectableXMapPane}) zu grafischen Darstellung der Layer</li>
  * <li>Eine Liste mit Steuerungskomponenten, ueber die die einzelnen Layer
  *     angesprochen werden koennen (ein/ausblenden, zoomen, ...).</li>
  * <li>Eine Status-Zeile, in der die Koordinaten der aktuellen Mausposition
@@ -86,7 +86,7 @@
   private   JPanel                     contentPane      = null;
   /** Karten- und Layer-Kontroll-Bereich. */
   protected LayeredMapPane             layeredMapPane   = null;
-  private   JMapPane                   mapPane          = null;
+  private   SelectableXMapPane                   mapPane          = null;
   private   MapContext                 mapContext       = null;
   /** Status-Balken. */
   protected MapPaneStatusBar           statusBar        = null;
@@ -160,7 +160,7 @@
     // Spezielles RasterPositionLabel in dem die Koordinaten des in der
     // ComboBox ausgewaehlten Rasters angezeigt werden
     RasterPositionLabel rpLabel = new RasterPositionLabel(1) {
-      protected MapLayer determineRasterLayer(final JMapPane mapPane) {
+      protected MapLayer determineRasterLayer(final SelectableXMapPane mapPane) {
         return rasterComboBox.getValue();
       }
     };
@@ -191,7 +191,7 @@
     featuresFrame.setSize( new Dimension(400,200) );
     // Ausgewaehlte Features werden im Detail-Frame angezeigt
     mapPane.addMapPaneListener( new JMapPaneListener() {
-      public void performMapPaneEvent(JMapPaneEvent e) {
+      public void performMapPaneEvent(MapPaneEvent e) {
         // Wenn Features ueber die Maus aus der Karte ausgewaehlt werden,
         // oeffnet sich ein Detail-Fenster
         if ( e instanceof FeatureSelectedEvent && e.getSourceObject() == mapPane ) {

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/LayeredMapPane.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/LayeredMapPane.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/LayeredMapPane.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -62,7 +62,7 @@
  * Das Fenster besteht aus 2 durch einen Divider voneinander getrennten
  * Komponenten:
  * <ol>
- * <li>Eine Map ({@link JMapPane}) zu grafischen Darstellung der Layer</li>
+ * <li>Eine Map ({@link SelectableXMapPane}) zu grafischen Darstellung der Layer</li>
  * <li>Eine Liste mit Steuerungskomponenten, ueber die die einzelnen Layer
  *     angesprochen werden koennen (ein/ausblenden, zoomen, ...).</li>
  * </ol>
@@ -89,7 +89,7 @@
    *  dargestellt werden */
   protected GeoMapPane geoMapPane = null;
   private   MapContext mapContext = null;
-  private   JMapPane   mapPane = null;
+  private   SelectableXMapPane   mapPane = null;
   private   Hashtable<MapLayer,Object> layerObjects = new Hashtable<MapLayer,Object>();
   /** Komponente, in der die Layer-Kontrolle dargestellt ist. */
   protected MapContextControlPane layerControlList = null;
@@ -148,7 +148,7 @@
   /**
    * Liefert den Karten-Bereich der Komponente.
    */
-  public JMapPane getMapPane() {
+  public SelectableXMapPane getMapPane() {
     return mapPane;
   }
 
@@ -263,7 +263,6 @@
     }
 
     // Anzeige aktualisieren
-    mapPane.setReset(true);
     mapPane.repaint();
 
     // Wenn Rendering geklappt hat, zum Layer gehoerendes Objekt merken
@@ -291,7 +290,6 @@
       mapPane.setMapArea(fc.getBounds());
 
     // Anzeige aktualisieren
-    mapPane.setReset(true);
     mapPane.repaint();
 
     // Wenn Rendering geklappt hat, zum Layer gehoerendes Objekt merken

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/MapActionControlPane.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/MapActionControlPane.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/MapActionControlPane.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -46,7 +46,7 @@
 
 /**
  * Diese Klasse stellt einen {@link JToolBar} dar, mit dem zwischen den
- * verschiedenen "Klick"- und "Drag"-Aktionen des {@link JMapPane} gewechselt werden
+ * verschiedenen "Klick"- und "Drag"-Aktionen des {@link SelectableXMapPane} gewechselt werden
  * kann:
  * <ul>
  *   <li><b>Info:</b>
@@ -112,8 +112,8 @@
   public static final String SELECT_TOP = MapActionControlPane.class.getName()+".SELECT_TOP";
 
 
-  /** {@link JMapPane} das gesteuert wird. */
-  protected JMapPane mapPane = null;
+  /** {@link SelectableXMapPane} das gesteuert wird. */
+  protected SelectableXMapPane mapPane = null;
   /** Button fuer Info-Aktion. */
   protected JToggleButton infoState = null;
   /** Button fuer Zoom-Aktion. */
@@ -126,7 +126,7 @@
   protected int actionMask = 0;
 
   /**
-   * Erzeugt eine horizontale Steuer-Komponente, die (noch) keinem {@link JMapPane}
+   * Erzeugt eine horizontale Steuer-Komponente, die (noch) keinem {@link SelectableXMapPane}
    * zugeordnet ist.
    */
   public MapActionControlPane() {
@@ -135,20 +135,20 @@
 
   /**
    * Erzeugt eine horizontale Steuer-Komponente.
-   * @param mapPane {@link JMapPane} das gesteuert wird
+   * @param mapPane {@link SelectableXMapPane} das gesteuert wird
    */
-  public MapActionControlPane(JMapPane mapPane) {
+  public MapActionControlPane(SelectableXMapPane mapPane) {
     this( mapPane, HORIZONTAL );
   }
 
   /**
    * Erzeugt eine Steuer-Komponente.
-   * @param mapPane {@link JMapPane} das gesteuert wird
+   * @param mapPane {@link SelectableXMapPane} das gesteuert wird
    * @param orientation Orientierung der Komponente ({@link #HORIZONTAL}/{@link #VERTICAL})
    * @param actionMask definiert, welche Aktionen (in Form von Buttons) angezeigt werden
    *                   (OR-Verknuepfung der {@code ACTION}-Konstanten
    */
-  public MapActionControlPane(JMapPane mapPane, int orientation, int actionMask) {
+  public MapActionControlPane(SelectableXMapPane mapPane, int orientation, int actionMask) {
     super(orientation);
     this.actionMask = actionMask;
     // Button erzeugen und in Gruppe einfuegen, damit immer nur
@@ -177,17 +177,17 @@
 
   /**
    * Erzeugt eine Steuer-Komponente. Alle Aktionen sind sichtbar.
-   * @param mapPane {@link JMapPane} das gesteuert wird
+   * @param mapPane {@link SelectableXMapPane} das gesteuert wird
    * @param orientation Orientierung der Komponente ({@link #HORIZONTAL}/{@link #VERTICAL})
    */
-  public MapActionControlPane(JMapPane mapPane, int orientation) {
+  public MapActionControlPane(SelectableXMapPane mapPane, int orientation) {
     this(mapPane,orientation,ACTION_ALL);
   }
 
   /**
    * Setzt die Aktivierung der Aktionen entsprechend den Einstellungen
    * des {@code JMapPane}.
-   * @see JMapPane#getWindowSelectionState()
+   * @see SelectableXMapPane#getWindowSelectionState()
    */
   public void resetActions() {
     for (int i=0; i<getComponentCount(); i++) {
@@ -199,17 +199,17 @@
     // Buttons entsprechend dem MapPane-Status einstellen
     infoState.doClick();
     if ( mapPane != null ) {
-      switch( mapPane.getWindowSelectionState() ) {
-        case JMapPane.ZOOM_IN:     if ( isActionVisible(ACTION_ZOOM_IN) )
+      switch( mapPane.getState() ) {
+        case SelectableXMapPane.ZOOM_IN:     if ( isActionVisible(ACTION_ZOOM_IN) )
                                      zoomState.doClick();
                                    break;
-        case JMapPane.SELECT_TOP:  if ( isActionVisible(ACTION_SELECT_TOP) )
+        case SelectableXMapPane.SELECT_TOP:  if ( isActionVisible(ACTION_SELECT_TOP) )
                                      selectTopState.doClick();
                                    break;
-        case JMapPane.SELECT_ALL:  if ( isActionVisible(ACTION_SELECT_ALL) )
+        case SelectableXMapPane.SELECT_ALL:  if ( isActionVisible(ACTION_SELECT_ALL) )
                                      selectAllState.doClick();
                                    break;
-        case JMapPane.NONE:        if ( isActionVisible(ACTION_INFO) )
+        case SelectableXMapPane.NONE:        if ( isActionVisible(ACTION_INFO) )
                                      infoState.doClick();
                                    break;
       }
@@ -225,17 +225,17 @@
   }
 
   /**
-   * Setzt das {@link JMapPane}, das durch diese Komponente gesteuert wird.
+   * Setzt das {@link SelectableXMapPane}, das durch diese Komponente gesteuert wird.
    */
-  public void setMapPane(JMapPane mapPane) {
+  public void setMapPane(SelectableXMapPane mapPane) {
     this.mapPane = mapPane;
     resetActions();
   }
 
   /**
-   * Liefert das {@link JMapPane}, das durch diese Komponente gesteuert wird.
+   * Liefert das {@link SelectableXMapPane}, das durch diese Komponente gesteuert wird.
    */
-  public JMapPane getMapPane() {
+  public SelectableXMapPane getMapPane() {
     return this.mapPane;
   }
 
@@ -292,12 +292,12 @@
      *   <li>{@code JMapPane.setState( JMapPane.Select )}</li>
      *   <li>{@code JMapPane.setHighlight( true )}</li>
      * </ol>
-     * @see JMapPane
+     * @see SelectableXMapPane
      * @param e das ActionEvent
      */
     public void actionPerformed(ActionEvent e) {
-      getMapPane().setWindowSelectionState( JMapPane.NONE );
-      getMapPane().setState(JMapPane.NONE);
+      getMapPane().setState( SelectableXMapPane.NONE );
+      getMapPane().setState(SelectableXMapPane.NONE);
     }
   }
 
@@ -326,12 +326,12 @@
      *   <li>{@code JMapPane.setState( JMapPane.ZoomIn )}</li>
      *   <li>{@code JMapPane.setHighlight( false )}</li>
      * </ol>
-     * @see JMapPane
+     * @see SelectableXMapPane
      * @param e das ActionEvent
      */
     public void actionPerformed(ActionEvent e) {
-      getMapPane().setWindowSelectionState( JMapPane.ZOOM_IN );
-      getMapPane().setState(JMapPane.ZOOM_IN);
+      getMapPane().setState( SelectableXMapPane.ZOOM_IN );
+      getMapPane().setState(SelectableXMapPane.ZOOM_IN);
     }
   }
 
@@ -361,12 +361,12 @@
      *   <li>{@code JMapPane.setState( JMapPane.Select )}</li>
      *   <li>{@code JMapPane.setHighlight( true )}</li>
      * </ol>
-     * @see JMapPane
+     * @see SelectableXMapPane
      * @param e das ActionEvent
      */
     public void actionPerformed(ActionEvent e) {
-      getMapPane().setWindowSelectionState( JMapPane.SELECT_TOP );
-      getMapPane().setState(JMapPane.SELECT_TOP);
+      getMapPane().setState( SelectableXMapPane.SELECT_TOP );
+      getMapPane().setState(SelectableXMapPane.SELECT_TOP);
     }
   }
 
@@ -395,12 +395,12 @@
      *   <li>{@code JMapPane.setState( JMapPane.Select )}</li>
      *   <li>{@code JMapPane.setHighlight( true )}</li>
      * </ol>
-     * @see JMapPane
+     * @see SelectableXMapPane
      * @param e das ActionEvent
      */
     public void actionPerformed(ActionEvent e) {
-      getMapPane().setWindowSelectionState( JMapPane.SELECT_ALL );
-      getMapPane().setState(JMapPane.SELECT_ALL);
+      getMapPane().setState( SelectableXMapPane.SELECT_ALL );
+      getMapPane().setState(SelectableXMapPane.SELECT_ALL);
     }
   }
 

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/MapContextControlPane.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/MapContextControlPane.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/MapContextControlPane.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -69,7 +69,7 @@
 import schmitzm.swing.menu.ConnectedPopupMenu;
 
 /**
- * Diese Komponente ist an ein {@link JMapPane} gekoppelt und stellt die
+ * Diese Komponente ist an ein {@link SelectableXMapPane} gekoppelt und stellt die
  * dargestellten Layer in Form eine Liste dar.
  * 
  * @author Martin Schmitz
@@ -259,7 +259,7 @@
 	public static final String FF_DIALOG_APPLY = FeatureLayerFilterDialog.APPLY_BUTTON;
 
 	/** Karte, deren Layer kontrolliert werden. */
-	protected JMapPane mapPane = null;
+	protected SelectableXMapPane mapPane = null;
 	/** Farbpaletten, die durch die Kontrolle zugewiesen werden koennen. */
 	private ColorMapManager colorMaps = null;
 
@@ -272,7 +272,7 @@
 	 *            Raster-Farbpaletten, die durch die Kontrolle zugewiesen werden
 	 *            koennen
 	 */
-	public MapContextControlPane(JMapPane mapPane, ColorMapManager colorMaps) {
+	public MapContextControlPane(SelectableXMapPane mapPane, ColorMapManager colorMaps) {
 		super();
 		// this.parentFrame = SwingUtil.getParentWindow(this);
 		this.mapPane = mapPane;
@@ -422,7 +422,7 @@
 			hideAllLayers.addActionListener(this);
 			invertAllLayers.addActionListener(this);
 			filterLayer.addActionListener(this);
-			filterLayer.setEnabled(!JMapPane.isGridCoverageLayer(layer));
+			filterLayer.setEnabled(!SelectableXMapPane.isGridCoverageLayer(layer));
 			if (filterLayer.isEnabled())
 				try {
 					filterDialog = new FeatureLayerFilterDialog(null, mapPane,
@@ -622,7 +622,6 @@
 				if (colMap != null) {
 					layer.setStyle(GridUtil.createStyle(colMap, 1.0));
 					customiseDialogPanel.setColorMap(colMap);
-					mapPane.setReset(true);
 					mapPane.repaint();
 					((JCheckBoxMenuItem) e.getSource()).setSelected(true);
 				}
@@ -694,7 +693,7 @@
 			// FeatureTypeStyle[] fts = layer.getStyle().getFeatureTypeStyles();
 			// if ( !(fts[0].getRules()[0].getSymbolizers()[0] instanceof
 			// RasterSymbolizer) ) {
-			if (!JMapPane.isGridCoverageLayer(layer)) {
+			if (!SelectableXMapPane.isGridCoverageLayer(layer)) {
 				this.setEnabled(false);
 				return;
 			}
@@ -812,7 +811,6 @@
 						layer.setStyle(GridUtil.createStyle(StylingUtil
 								.cloneColorMap(customiseDialogPanel
 										.getColorMap()), 1.0));
-						mapPane.setReset(true);
 						mapPane.repaint();
 						menuItemGroup.setUnselected();
 						// }

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/MapPaneStatusBar.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/MapPaneStatusBar.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/MapPaneStatusBar.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -40,7 +40,7 @@
 /**
  * Stellt ein {@link BorderLayout}-Panel dar, in dem links ein
  * {@link RasterPositionLabel} und rechts ein {@link GeoPositionLabel}
- * dargestellt ist. Beide werden automatisch mit einem {@link JMapPane}
+ * dargestellt ist. Beide werden automatisch mit einem {@link SelectableXMapPane}
  * gekoppelt, so dass automatisch die Anzeige der Labels aktualisiert wird,
  * sobald sich der Cursor ueber die Karte bewegt.
  * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
@@ -57,7 +57,7 @@
    * Erzeugt einen neuen Status-Balken.
    * @param mapPane Karte mit der die Labels gekoppelt werden
    */
-  public MapPaneStatusBar(JMapPane mapPane) {
+  public MapPaneStatusBar(SelectableXMapPane mapPane) {
     this(mapPane,null,null);
   }
 
@@ -69,7 +69,7 @@
    * @param geoPosLabel Label, in dem die Geo-Koordinaten angezeigt
    *        werden (wenn {@code null}, wird ein neues {@link GeoPositionLabel} erzeugt).
    */
-  public MapPaneStatusBar(JMapPane mapPane, RasterPositionLabel rasterPosLabel, GeoPositionLabel geoPosLabel) {
+  public MapPaneStatusBar(SelectableXMapPane mapPane, RasterPositionLabel rasterPosLabel, GeoPositionLabel geoPosLabel) {
     super();
     setLayout( new BorderLayout() );
     // rechts: Anzeige der aktuellen Welt-Koordinaten

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/RasterPositionLabel.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/RasterPositionLabel.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/RasterPositionLabel.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -46,6 +46,7 @@
 import org.opengis.referencing.operation.MathTransform;
 
 import schmitzm.data.WritableGrid;
+import schmitzm.geotools.feature.FeatureUtil;
 import schmitzm.geotools.grid.GridUtil;
 import schmitzm.swing.CaptionsChangeable;
 
@@ -54,7 +55,7 @@
  * Raster-Koordinaten und der Rasterwert an der entsprechenden Stelle angezeigt
  * werden.<br>
  * Die Klasse fungiert als {@link MouseMotionListener} und kann so direkt an ein
- * {@link JMapPane} gekoppelt werden. Die Koordinaten-Darstellung im Label
+ * {@link SelectableXMapPane} gekoppelt werden. Die Koordinaten-Darstellung im Label
  * aktualisiert sich somit automatisch, sobald sich die Maus ueber die Karte
  * bewegt.
  *
@@ -117,15 +118,15 @@
 
 	/**
 	 * Stellt die Koordinaten und den Wert des obersten (sichtbaren) Rasters im
-	 * Label dar, wenn das Event von einem {@link JMapPane} ausgeloest wurde.<br>
+	 * Label dar, wenn das Event von einem {@link SelectableXMapPane} ausgeloest wurde.<br>
 	 * Wird {@link #mouseMoved(MouseEvent)} und
 	 * {@link #mouseDragged(MouseEvent)} aufgerufen.
 	 */
 	protected void displayCoordinates(final MouseEvent e) {
-		if (e == null || !(e.getSource() instanceof JMapPane))
+		if (e == null || !(e.getSource() instanceof SelectableXMapPane))
 			return;
 
-		final JMapPane mapPane = (JMapPane) e.getSource();
+		final SelectableXMapPane mapPane = (SelectableXMapPane) e.getSource();
 		// oberstes dargestelltes Raster suchen
 		final MapLayer layer = determineRasterLayer(mapPane);
 		if (layer == null) {
@@ -133,7 +134,7 @@
 			return;
 		}
 		// Objekt aus Layer herausholen
-		final Object layerObj = JMapPane.getLayerSourceObject(layer);
+		final Object layerObj = FeatureUtil.getLayerSourceObject(layer);
 		if ((layerObj == null)
 				|| (!(layerObj instanceof GridCoverage2D) && !(layerObj instanceof org.geotools.coverage.grid.io.AbstractGridCoverage2DReader)))
 			return;
@@ -146,7 +147,7 @@
 					2);
 			try {
 				// Welt-Koordinaten der Mausposition ermitteln (in CRS der Map)
-				final Point2D actPos_MapCRS = JMapPane
+				final Point2D actPos_MapCRS = SelectableXMapPane
 						.getMapCoordinatesFromEvent(e);
 				if (actPos_MapCRS == null)
 					return;
@@ -203,7 +204,7 @@
 					2);
 			try {
 				// Welt-Koordinaten der Mausposition ermitteln (in CRS der Map)
-				final Point2D actPos_MapCRS = JMapPane
+				final Point2D actPos_MapCRS = SelectableXMapPane
 						.getMapCoordinatesFromEvent(e);
 				if (actPos_MapCRS == null)
 					return;
@@ -217,7 +218,7 @@
 				// Wert im Raster ermitteln
 				Hashtable<MapLayer, double[]> foundGridCoverageValues = mapPane
 						.findGridCoverageValues(actPos_GridCRS.toPoint2D(),
-								JMapPane.SELECT_ALL);
+								SelectableXMapPane.SELECT_ALL);
 				if (foundGridCoverageValues != null
 						&& foundGridCoverageValues.size() > 0) {
 					double[] gcValue = foundGridCoverageValues.values()
@@ -249,7 +250,7 @@
 	 * @param mapPane
 	 *            MapPane der angezeigten Layer.
 	 */
-	protected MapLayer determineRasterLayer(final JMapPane mapPane) {
+	protected MapLayer determineRasterLayer(final SelectableXMapPane mapPane) {
 		return mapPane.getTopVisibleGridCoverageLayer();
 	}
 
@@ -309,7 +310,7 @@
 
 	/**
 	 * Wird aufgerufen, sobald die Maus bewegt wird. Stellt die Koordinaten und
-	 * den Rasterwert im Label dar, wenn das Event von einem {@link JMapPane}
+	 * den Rasterwert im Label dar, wenn das Event von einem {@link SelectableXMapPane}
 	 * ausgeloest wurde.
 	 *
 	 * @see #displayCoordinates(MouseEvent)
@@ -321,7 +322,7 @@
 	/**
 	 * Wird aufgerufen, sobald die Maus bei gedrueckter Taste bewegt wird.
 	 * Stellt die Koordinaten und den Rasterwert im Label dar, wenn das Event
-	 * von einem {@link JMapPane} ausgeloest wurde.
+	 * von einem {@link SelectableXMapPane} ausgeloest wurde.
 	 *
 	 * @see #displayCoordinates(MouseEvent)
 	 */

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/SelectableFeatureTablePane.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/SelectableFeatureTablePane.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/SelectableFeatureTablePane.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -59,8 +59,8 @@
 
 /**
  * Extends the {@link FeatureTablePane} with buttons and functionality to select
- * lines. Can be configured to set the regions on an external a {@link JMapPane}
- * . Can be configured to show a simple preview {@link JMapPane} to the left of
+ * lines. Can be configured to set the regions on an external a {@link SelectableXMapPane}
+ * . Can be configured to show a simple preview {@link SelectableXMapPane} to the left of
  * the table.
  * 
  * @author Stefan A. Krüger
@@ -85,7 +85,7 @@
 					.getResource("resource/icons/mActionZoomToSelected.png"));
 	
 	
-	private final JMapPane externalMapPane;
+	private final SelectableXMapPane externalMapPane;
 	
 	private JLabel statusLabel;
 
@@ -93,16 +93,16 @@
      * @param fc
      *            {@link FeatureCollection} that holds the data.
      * @param geomPreview
-     *            If <code>true</code>, a preview {@link JMapPane} is attached
+     *            If <code>true</code>, a preview {@link SelectableXMapPane} is attached
      *            to the left of the table.
      * @param externalMapPane
      *            <code>null</code> if this component is NOT linked to an
      *            external JMapPane. If mapPane == <code>null</code>, the
      *            "ZoomToSelection" Button is automatically disabled. If a
-     *            {@link JMapPane} is passed, the "ZoomToSelectedFeature"
+     *            {@link SelectableXMapPane} is passed, the "ZoomToSelectedFeature"
      *            function will be enabled.
      */
-    public SelectableFeatureTablePane(FeatureCollection fc, boolean geomPreview, JMapPane externalMapPane) {
+    public SelectableFeatureTablePane(FeatureCollection fc, boolean geomPreview, SelectableXMapPane externalMapPane) {
       this(new FeatureCollectionTableModel(fc), geomPreview, externalMapPane);
     }
 
@@ -110,17 +110,17 @@
 	 * @param model
 	 *            {@link FeatureCollectionTableModel} that holds the data.
 	 * @param geomPreview
-	 *            If <code>true</code>, a preview {@link JMapPane} is attached
+	 *            If <code>true</code>, a preview {@link SelectableXMapPane} is attached
 	 *            to the left of the table.
 	 * @param externalMapPane
 	 *            <code>null</code> if this component is NOT linked to an
 	 *            external JMapPane. If mapPane == <code>null</code>, the
 	 *            "ZoomToSelection" Button is automatically disabled. If a
-	 *            {@link JMapPane} is passed, the "ZoomToSelectedFeature"
+	 *            {@link SelectableXMapPane} is passed, the "ZoomToSelectedFeature"
 	 *            function will be enabled.
 	 */
 	public SelectableFeatureTablePane(FeatureCollectionTableModel model,
-			boolean geomPreview, JMapPane externalMapPane) {
+			boolean geomPreview, SelectableXMapPane externalMapPane) {
 		super(model, null, geomPreview);
 
 		this.externalMapPane = externalMapPane;

Copied: branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/SelectableXMapPane.java (from rev 506, branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/JMapPane.java)
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/JMapPane.java	2009-10-31 12:15:37 UTC (rev 506)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/gui/SelectableXMapPane.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -0,0 +1,1262 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Martin O. J. Schmitz.
+ * 
+ * This file is part of the SCHMITZM library - a collection of utility 
+ * classes based on Java 1.6, focusing (not only) on Java Swing 
+ * and the Geotools library.
+ * 
+ * The SCHMITZM project is hosted at:
+ * http://wald.intevation.org/projects/schmitzm/
+ * 
+ * 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:
+ *     Martin O. J. Schmitz - initial API and implementation
+ *     Stefan A. Krüger - additional utility classes
+ ******************************************************************************/
+package schmitzm.geotools.gui;
+
+import gtmig.org.geotools.swing.GeomFilterGenerator;
+import gtmig.org.geotools.swing.SelectXMapPaneMouseListener;
+import gtmig.org.geotools.swing.XMapPane;
+import gtmig.org.geotools.swing.GeomFilterGenerator.BoundingBoxFilterGenerator;
+
+import java.awt.BorderLayout;
+import java.awt.LayoutManager;
+import java.awt.Point;
+import java.awt.RenderingHints;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Map;
+
+import javax.swing.JList;
+
+import org.apache.log4j.Logger;
+import org.geotools.coverage.grid.GeneralGridEnvelope;
+import org.geotools.coverage.grid.GridCoverage2D;
+import org.geotools.coverage.grid.GridGeometry2D;
+import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
+import org.geotools.coverage.grid.io.AbstractGridFormat;
+import org.geotools.data.FeatureSource;
+import org.geotools.data.memory.MemoryFeatureCollection;
+import org.geotools.factory.GeoTools;
+import org.geotools.feature.FeatureCollection;
+import org.geotools.filter.GeometryFilterImpl;
+import org.geotools.geometry.GeneralEnvelope;
+import org.geotools.geometry.jts.JTS;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.map.DefaultMapContext;
+import org.geotools.map.MapContext;
+import org.geotools.map.MapLayer;
+import org.geotools.parameter.Parameter;
+import org.geotools.referencing.CRS;
+import org.geotools.renderer.GTRenderer;
+import org.geotools.renderer.lite.StreamingRenderer;
+import org.geotools.resources.image.ImageUtilities;
+import org.geotools.swing.utils.MapLayerUtils;
+import org.opengis.coverage.CannotEvaluateException;
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+import org.opengis.filter.Filter;
+import org.opengis.parameter.GeneralParameterValue;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+import schmitzm.geotools.JTSUtil;
+import schmitzm.geotools.feature.FeatureUtil;
+import schmitzm.geotools.grid.GridUtil;
+import schmitzm.geotools.map.event.FeatureSelectedEvent;
+import schmitzm.geotools.map.event.GeneralSelectionEvent;
+import schmitzm.geotools.map.event.GridCoverageSelectedEvent;
+import schmitzm.geotools.map.event.GridCoverageValueSelectedEvent;
+import schmitzm.geotools.map.event.JMapPaneListener;
+import schmitzm.geotools.map.event.MapAreaChangedEvent;
+import schmitzm.geotools.map.event.MapPaneEvent;
+import schmitzm.geotools.map.event.ScaleChangedEvent;
+import schmitzm.geotools.styling.StylingUtil;
+
+import com.vividsolutions.jts.geom.Envelope;
+
+/**
+ * Diese Klasse erweitert die Geotools-Klasse
+ * {@link org.geotools.swing.JMapPane} um folgende Features:
+ * <ul>
+ * <li>zusaetzliche Maus-Steuerungen:
+ * <ul>
+ * <li><b>Linksklick:</b> ueber {@link #setState(int)} eingestellte Aktion</li>
+ * <li><b>Rechtsklick:</b> Zoom-Out um Faktor 2 (nur wenn Linksklick auf Zoom-In
+ * eingestellt ist)</li>
+ * <li><b>Drag mit linker Maustaste:</b> neuen Karten-Bereich selektieren oder
+ * Features selektieren (siehe {@link #setState(int)})</li>
+ * <li><b>Drag mit rechter Maustaste:</b> Karten-Bereich verschieben</li>
+ * <li><b>Mausrad:</b> Zoom-In/Out ueber aktueller Position (Faktor 1.2)</li>
+ * </ul>
+ * </li>
+ * <li>Ankoppeln von {@link JMapPaneListener} und Ausloesung diverser
+ * Ereignisse:
+ * <ul>
+ * <li><b>{@link ScaleChangedEvent}:</b> Wird ausgeloest, wenn sich die
+ * Aufloesung der angezeigten Karte aendert</li>
+ * <li><b>{@link MapAreaChangedEvent}:</b> Wird ausgeloest, wenn sich die
+ * Aufloesung angezeigte Karte-Ausschnitt aendert</li>
+ * <li><b>{@link GeneralSelectionEvent}:</b> Wird ausgeloest, wenn der Anwender
+ * einen Bereich aus der Karte ausgewaehlt hat (egal ob dabei gezoomt wurde,
+ * Features/Raster selektiert wurden, oder nicht selektiert wurde)</li>
+ * <li><b>{@link FeatureSelectedEvent}:</b> Wird ausgeloest, wenn der Anwender
+ * Features aus der Karte ausgewaehlt hat</li>
+ * <li><b>{@link GridCoverageSelectedEvent}:</b> Wird ausgeloest, wenn der
+ * Anwender Raster-Bereiche aus der Karte ausgewaehlt hat</li>
+ * </ul>
+ * </li>
+ * </ul>
+ * Sofern eingeschaltet, erfolgt {@linkplain #setHighlight(boolean)
+ * Highlighting} immer auf dem obersten sichtbaren Nicht-Raster-Layer.<br>
+ * Darueberhinaus besteht ueber {@link #getScreenToWorld()} Zugriff auf eine
+ * {@linkplain AffineTransform affine Transformation} mit der die aktuellen
+ * Fenster-Koordinaten (z.B. eines <code>MouseEvent</code>) in
+ * Karten-Koordinaten (Latitude/Longitude) umgerechnet werden koennen.
+ * 
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
+ *         (University of Bonn/Germany)
+ * @version 1.0
+ */
+public class SelectableXMapPane extends gtmig.org.geotools.swing.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;
+
+	// /** Wenn true, dann werden RasterLayer waehrend des Panning auf
+	// setVisible(false) gesetzt **/
+	// protected boolean hideRasterLayersDuringPan = false;
+	// /** Remebers the layers that are hidden during a PAN action **/
+	// protected List<MapLayer> hiddenForPanning = new LinkedList<MapLayer>();
+
+	// private MouseInputAdapter dragWaitCursorListener;
+
+	/**
+	 * Erzeugt ein neues MapPane.
+	 * 
+	 * @param layout
+	 *            Layout-Manager fuer die GUI-Komponente (z.B.
+	 *            {@link BorderLayout})
+	 * @param isDoubleBuffered
+	 *            siehe Konstruktor der
+	 *            {@linkplain org.SelectableXMapPane.org.geotools.swing.JMapPane#JMapPane(LayoutManager,boolean,GTRenderer,MapContext)
+	 *            Oberklasse}
+	 * @param renderer
+	 *            Renderer fuer die graphische Darestellung (z.B.
+	 *            {@link StreamingRenderer})
+	 * @param localContext
+	 *            Verwaltung der einzelnen Layer (z.B. {@link DefaultMapContext}
+	 *            ).
+	 */
+	public SelectableXMapPane(MapContext context) {
+		this(context, null);
+	}
+	
+	/**
+	 * Erzeugt ein neues MapPane.
+	 * 
+	 * @param layout
+	 *            Layout-Manager fuer die GUI-Komponente (z.B.
+	 *            {@link BorderLayout})
+	 * @param isDoubleBuffered
+	 *            siehe Konstruktor der
+	 *            {@linkplain org.SelectableXMapPane.org.geotools.swing.JMapPane#JMapPane(LayoutManager,boolean,GTRenderer,MapContext)
+	 *            Oberklasse}
+	 * @param renderer
+	 *            Renderer fuer die graphische Darestellung (z.B.
+	 *            {@link StreamingRenderer})
+	 * @param localContext
+	 *            Verwaltung der einzelnen Layer (z.B. {@link DefaultMapContext}
+	 *            ).
+	 */
+	public SelectableXMapPane() {
+		this(null, null);
+	}
+	
+	/**
+	 * This {@link MouseListener} is managing all selection related tasks
+	 */
+	protected final SelectXMapPaneMouseListener selectMapPaneMouseListener = new SelectXMapPaneMouseListener(this);
+
+	/**
+	 * Erzeugt ein neues MapPane.
+	 * 
+	 * @param renderer
+	 *            Renderer fuer die graphische Darestellung (z.B.
+	 *            {@link StreamingRenderer})
+	 * @param context
+	 *            Verwaltung der einzelnen Layer (z.B. {@link DefaultMapContext}
+	 *            ).
+	 * @param rendererHints
+	 *            A {@link Map} with hints for the renderer. May be
+	 *            <code>null</code>.
+	 */
+	public SelectableXMapPane(MapContext context,
+			Map<Object, Object> rendererHints) {
+		super(null, rendererHints);
+
+		//
+		// // Having problems with StreamingRendere!
+		// getRenderer().setContext(getContext());
+
+		// Dieser Hint sorgt wohl dafuer, dass die Rasterpixel nicht
+		// interpoliert werden
+		// Ueber die Methode enableAntiAliasing(boolean) kann das
+		// rechenintensive AntiAliasing fuer Text un Vectoren eingeschaltet
+		// werden
+		RenderingHints hintsJava2d = ImageUtilities.NN_INTERPOLATION_HINT;
+		setJava2dHints(hintsJava2d);
+		
+		/**
+		 * Adding the #selectionMapPaneMouseListener  
+		 */
+		this.addMouseListener(selectMapPaneMouseListener);
+		this.addMouseMotionListener(selectMapPaneMouseListener);
+		this.addMouseWheelListener(selectMapPaneMouseListener);
+
+		setState(ZOOM_IN);
+
+		//
+		// // CRS wird immer vom ersten in die Karte eingefuegten Layer
+		// uebernommen
+		// // Wenn noch keine MapArea gesetzt wurde, wird diese vom Layer
+		// // uebernommen
+		// getLocalContext().addMapLayerListListener(new MapLayerListAdapter() {
+		// public void layerAdded(MapLayerListEvent e) {
+		// if (getLocalContext().getLayerCount() == 1) {
+		// CoordinateReferenceSystem crs = null;
+		// // CRS aus Layer ermitteln
+		// try {
+		// crs = e.getLayer().getFeatureSource().getSchema()
+		// .getGeometryDescriptor()
+		// .getCoordinateReferenceSystem();
+		// // wenn noch keine MapArea gesetzt wurde, den
+		// // Ausdehnungsbereich des ersten Layers
+		// // verwenden, so dass die erste
+		// // Karte komplett angezeigt wird
+		// if (getMapArea() == null) {
+		// // Envelope newMapArea = new Envelope(e.getLayer()
+		// // .getFeatureSource().getBounds());
+		// Envelope newMapArea = getMaxExtend();
+		// setMapArea(newMapArea);
+		// // in layerAdded(.) der Oberklasse wird
+		// // mapArea nochmal neu gesetzt, wenn das
+		// // erste Layer
+		// // eingefuegt wird
+		// // >> hier nur die AreaOfInterest setzen
+		// getLocalContext().setAreaOfInterest(newMapArea, crs);
+		// }
+		// } catch (Exception err) {
+		// LOGGER
+		// .warn("CRS could not be determined from map layer. "
+		// + GeoImportUtil.getDefaultCRS()
+		// .getName() + "  used.");
+		// // err.printStackTrace();
+		// crs = GeoImportUtil.getDefaultCRS();
+		// }
+		// // CRS dem MapContext zuweisen
+		// try {
+		// getLocalContext().setCoordinateReferenceSystem(crs);
+		// // LOGGER.debug("MapContext-CRS set to: "+crs);
+		// } catch (Exception err) {
+		// LOGGER.error(
+		// "CRS could not be assigned to map context.",
+		// err);
+		// }
+		// }
+		// }
+		// });
+
+		// Solved without just with the access methods
+		// // The default is to regard a layer on selection
+		// // actions
+		// getContext().addMapLayerListListener(
+		// new MapLayerListAdapter() {
+		// @Override
+		// public void layerAdded(MapLayerListEvent e) {
+		// setMapLayerSelectable(e.getLayer(),true);
+		// }
+		// @Override
+		// public void layerRemoved(MapLayerListEvent e) {
+		// // remove reference to layer
+		// mapLayerSelectable.remove(e.getLayer());
+		// }
+		// });
+	}
+
+	/**
+	 * Triggers to repaint (fast) and re-render (slow) the JMapPane
+	 */
+	public void refresh() {
+		mapImageInvalid = true;
+		repaint();
+	}
+
+	/**
+	 * Aktiviert oder deaktiviert das AntiAliasing for diese
+	 * {@link SelectableXMapPane}. AntiALiasing ist besonders fuer
+	 * Textbeschriftung sehr schoen, verbraucht aber auch mehr Performance.
+	 * 
+	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
+	 *         Kr&uuml;ger</a>
+	 */
+	public void setAntiAliasing(final boolean aa) {
+		// LOGGER.info("Setting AntiAliasing for this JMapPane to " + aa);
+		RenderingHints java2DHints = super.getJava2dHints();
+		if (java2DHints == null)
+			java2DHints = GeoTools.getDefaultHints();
+		java2DHints.put(RenderingHints.KEY_ANTIALIASING,
+				aa ? RenderingHints.VALUE_ANTIALIAS_ON
+						: RenderingHints.VALUE_ANTIALIAS_OFF);
+		java2DHints.put(RenderingHints.KEY_TEXT_ANTIALIASING,
+				aa ? RenderingHints.VALUE_TEXT_ANTIALIAS_ON
+						: RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
+		java2DHints.put(RenderingHints.KEY_RENDERING,
+				aa ? RenderingHints.VALUE_RENDER_QUALITY
+						: RenderingHints.VALUE_RENDER_SPEED);
+		super.setJava2dHints(java2DHints);
+	}
+
+	/**
+	 * Setzt den Kartenausschnitt auf die Ausdehnung eines bestimmten Layers.
+	 * Macht nichts, wenn {@code null} uebergeben wird.
+	 * 
+	 * <br>
+	 * A refresh of the map is NOT called.
+	 * 
+	 * @param layer
+	 *            ein Layer
+	 */
+	public void zoomToLayer(MapLayer layer) {
+		if (layer == null)
+			return;
+		// This action ususally takes some time..
+		try {
+
+			// BB umrechnen von Layer-CRS in Map-CRS
+			final CoordinateReferenceSystem targetCRS = getContext()
+					.getCoordinateReferenceSystem();
+			final CoordinateReferenceSystem sourceCRS = layer
+					.getFeatureSource().getSchema()
+					.getCoordinateReferenceSystem();
+
+			Envelope mapAreaNew;
+			if (!CRS.equalsIgnoreMetadata(sourceCRS, targetCRS)) {
+				mapAreaNew = JTSUtil.transformEnvelope(layer.getFeatureSource()
+						.getBounds(), sourceCRS, targetCRS);
+			} else {
+				try {
+					mapAreaNew = layer.getFeatureSource().getBounds();
+				} catch (java.lang.IllegalArgumentException e) {
+					LOGGER.error("Can't calc layers bounds...", e);
+					mapAreaNew = null;
+
+					/**
+					 * 
+					 23.10.2009 11:20:50
+					 * org.geotools.data.shapefile.shp.PolygonHandler read
+					 * WARNUNG: only one hole in this polygon record ERROR
+					 * JMapPane zoomToLayer Zoom to layer did not terminate
+					 * correctly java.lang.IllegalArgumentException: Points of
+					 * LinearRing do not form a closed linestring at
+					 * com.vividsolutions
+					 * .jts.geom.LinearRing.validateConstruction
+					 * (LinearRing.java:105) at
+					 * com.vividsolutions.jts.geom.LinearRing
+					 * .<init>(LinearRing.java:100) at
+					 * com.vividsolutions.jts.geom
+					 * .GeometryFactory.createLinearRing
+					 * (GeometryFactory.java:339) at
+					 * org.geotools.data.shapefile.
+					 * shp.PolygonHandler.read(PolygonHandler.java:188) at
+					 * org.geotools
+					 * .data.shapefile.shp.ShapefileReader$Record.shape
+					 * (ShapefileReader.java:106) at
+					 * org.geotools.data.shapefile.
+					 * ShapefileAttributeReader.next(
+					 * ShapefileAttributeReader.java:157) at
+					 * org.geotools.data.shapefile
+					 * .indexed.IndexedShapefileAttributeReader
+					 * .next(IndexedShapefileAttributeReader.java:122) at
+					 * org.geotools
+					 * .data.FIDFeatureReader.next(FIDFeatureReader.java:96) at
+					 * org.geotools.data.FIDFeatureReader.next(FIDFeatureReader.
+					 * java:55) at org.geotools.data.MaxFeatureReader.next(
+					 * MaxFeatureReader.java:61) at
+					 * org.geotools.data.MaxFeatureReader
+					 * .next(MaxFeatureReader.java:61)
+					 **/
+				}
+			}
+
+			// Kartenbereich um 10% vergroessern, damit z.B. auch ein
+			// Punkt-Layer,
+			// welches nur aus 2 Punnkten besteht, sichtbar ist (Punkte liegen
+			// sonst
+			// genau auf dem Rand der angezeigten Flaeche)
+
+			if (mapAreaNew != null) {
+				mapAreaNew.expandBy(mapAreaNew.getWidth() * 0.1, mapAreaNew
+						.getHeight() * 0.1);
+				setMapArea(mapAreaNew);
+			} else {
+				LOGGER
+						.warn("Couldn't transformEnvelope when zooming to the layer");
+			}
+		} catch (Exception err) {
+			LOGGER.error("Zoom to layer did not terminate correctly", err);
+		}
+	}
+
+	/**
+	 * Zooms the {@link SelectableXMapPane} to the {@link Envelope} of a layer.
+	 * 
+	 * <br>
+	 * A refresh of the map is not done automatically
+	 * 
+	 * @param index
+	 *            Index of the {@link MapLayer} in the {@link MapContext} (from
+	 *            back to top)
+	 * 
+	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
+	 *         Kr&uuml;ger</a>
+	 */
+	public void zoomToLayer(int index) {
+		final MapContext context = getContext();
+		if (context != null)
+			zoomToLayer(context.getLayer(index));
+	}
+
+	/**
+	 * Zooms the {@link SelectableXMapPane} to the {@link Envelope} of the
+	 * selected layer. The layer is selected by the idx, counting from front to
+	 * back, like humans would expect in a {@link JList}
+	 * 
+	 * <br>
+	 * A refresh of the map is not done automatically
+	 * 
+	 * 
+	 * 
+	 * @param index
+	 *            Reverse index of the {@link MapLayer} in the
+	 *            {@link MapContext}
+	 * 
+	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
+	 *         Kr&uuml;ger</a>
+	 */
+	public void zoomToLayerIdxReverse(int index) {
+		zoomToLayer(getContext().getLayerCount() - 1 - index);
+	}
+
+	/**
+	 * 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;
+
+		return getMapArea().getWidth() / getWidth();
+	}
+
+	/**
+	 * Liefert oberste Layer (sichtbar oder unsichtbar).
+	 */
+	public MapLayer getTopLayer() {
+		int count = getContext().getLayerCount();
+		return count > 0 ? getContext().getLayer(count - 1) : null;
+	}
+
+	/**
+	 * Liefert oberste sichtbare Layer.
+	 */
+	public MapLayer getTopVisibleLayer() {
+		for (int i = getContext().getLayerCount() - 1; i >= 0; i--) {
+			MapLayer layer = getContext().getLayer(i);
+			if (layer.isVisible())
+				return layer;
+		}
+		return null;
+	}
+
+	/**
+	 * Liefert oberste sichtbare Raster-Layer.
+	 */
+	public MapLayer getTopVisibleGridCoverageLayer() {
+		for (int i = getContext().getLayerCount() - 1; i >= 0; i--) {
+			MapLayer layer = getContext().getLayer(i);
+			if (layer.isVisible() && isGridCoverageLayer(layer))
+				return layer;
+		}
+		return null;
+	}
+
+	/**
+	 * Liefert oberste sichtbare Nicht-Raster-Layer.
+	 */
+	public MapLayer getTopVisibleNonGridCoverageLayer() {
+		for (int i = getContext().getLayerCount() - 1; i >= 0; i--) {
+			MapLayer layer = getContext().getLayer(i);
+			if (layer.isVisible() && !isGridCoverageLayer(layer))
+				return layer;
+		}
+		return null;
+	}
+
+	/**
+	 * Liefert unterste Layer (sichtbar oder unsichtbar).
+	 */
+	public MapLayer getBottomLayer() {
+		return getContext().getLayerCount() > 0 ? getContext().getLayer(0)
+				: null;
+	}
+
+	/**
+	 * Setzt den Modus fuer Window-Selektion. Default ist {@link #ZOOM_IN}.
+	 * 
+	 * 
+	 * <ul>
+	 * <li>{@link #ZOOM_IN}: Zoom auf selektierten Bereich</li>
+	 * <li>{@link #SELECT_TOP}: Auswahl der Features im selektierten Bereich des
+	 * <b>obersten</b> (sichtbaren) Layers</li>
+	 * <li>{@link #SELECT_ALL} Auswahl der Features im selektierten ueber alle
+	 * Layer</li>
+	 * <li>{@link #NONE} Nichts machen</li>
+	 * </ul>
+	 * 
+	 * @param state
+	 *            Modus fuer Window-Selektion
+	 */
+	public void setState(final int state) {
+
+		// if (newSelState != NONE && newSelState != ZOOM_IN
+		// && newSelState != SELECT_TOP && newSelState != SELECT_ALL
+		// && newSelState != SELECT_ONE_FROM_TOP)
+		// throw new IllegalArgumentException(
+		// "Unknown selection state for window selection: "+newSelState);
+
+		// // Den selTracker bei Wechsel zu NONE deaktivieren (SK), damit
+		// // Selektionsfenster beim Draggen nicht mehr gezeichnet wird
+		// if ((state == NONE) && (getState() != NONE)) {
+		// this.removeMouseListener(selTracker);
+		// } else
+		// // Den selTracker bei Wechsel von NONE aktivieren (SK)
+		// if ((state != NONE) && (getState() == NONE)) {
+		// this.addMouseListener(selTracker);
+		// }
+		//		
+		selectMapPaneMouseListener.setEnabled((state == SELECT_ALL || state == SELECT_ONE_FROM_TOP || state == SELECT_TOP));
+
+		super.setState(state);
+	}
+
+	/**
+	 * 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
+	 *         Kr&uuml;ger</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
+	 *         Kr&uuml;ger</a>
+	 */
+	@Override
+	public boolean setMapArea(Envelope 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
+				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}.
+	 */
+	public void zoomTo(SimpleFeature feature) {
+		final MemoryFeatureCollection mfc = new MemoryFeatureCollection(feature
+				.getFeatureType());
+		mfc.add(feature);
+		zoomTo(mfc);
+	}
+
+	/**
+	 * Testet (anhand der Features), ob das Objekt eines Layers eine
+	 * Bounding-Box schneidet.
+	 * 
+	 * @param layer
+	 *            ein Layer
+	 * @param env
+	 *            Bounding-Box in CRS des MapPane
+	 */
+	public boolean featureLayerIntersectsEnvelope(MapLayer layer, Envelope env) {
+		try {
+			// // BB umrechnen von Map-CRS in Layer-CRS
+			// Envelope env_LayerCRS = JTSUtil.transformEnvelope(env,
+			// getContext()
+			// .getCoordinateReferenceSystem(), layer.getFeatureSource()
+			// .getSchema().getDefaultGeometry().getCoordinateSystem());
+			// GeometryFilterImpl filter =
+			// createBoundingBoxFilter(env_LayerCRS);
+			// Expression geometry = ff.createAttributeExpression(layer
+			// .getFeatureSource().getSchema().getDefaultGeometry()
+			// .getLocalName());
+			// filter.setExpression1(geometry);
+			FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = (FeatureSource<SimpleFeatureType, SimpleFeature>) layer
+					.getFeatureSource();
+			GeometryFilterImpl filter = new BoundingBoxFilterGenerator(env,
+					getContext().getCoordinateReferenceSystem())
+					.adaptFilter(featureSource);
+			return !layer.getFeatureSource().getFeatures(filter).isEmpty();
+		} catch (Exception err) {
+			return false;
+		}
+	}
+
+	/**
+	 * Ermittelt alle 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.
+	 * 
+	 * 17.4.08, Stefan
+	 * 
+	 * @param iterator
+	 *            Filter
+	 * @param mode
+	 *            Suchmodus
+	 * @return eine leere {@link Hashtable} falls der Filter {@code null} ist
+	 */
+	protected Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>> findFeatures(
+			GeomFilterGenerator filterGenerator, int mode, Envelope env) {
+		Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>> result = new Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>>();
+		if (filterGenerator == null)
+			return result;
+
+		// Je nach Modus: Alle oder nur das oberste Layer
+		MapContext context = getContext();
+		MapLayer[] layerList = context.getLayers();
+		for (int i = layerList.length - 1; i >= 0; i--) {
+			MapLayer layer = layerList[i];
+			if (!layer.isVisible())
+				continue;
+
+			// Bei einem Raster-Layer, das die BB schneidet, abbrechen, wenn nur
+			// im
+			// obersten (sichtbaren) Layer gesucht
+			// wird.AbstractGridCoverage2DReader
+			// Ansonsten Raster-Layer einfach uebergehen.
+			if (isGridCoverageLayer(layer)) {
+				if (mode == SELECT_TOP
+						&& gridLayerIntersectsEnvelope(layer, env))
+					break;
+				continue;
+			}
+
+			// Filter an Layer koppeln
+			// WICHTIG: Dies darf erst geschehen, NACHDEM das
+			// Schleifen-Abbruch-Kriterium
+			// fuer die Raster-Layer geprueft wurde!!
+			// Werden folgende Zeilen naemlich auf das FeatureSource des
+			// Raster-Layers angewandt, dann "bricht" der Filter "irgendwie"
+			// zusammen und auch die ZUVOR gefilterten FeatureCollections,
+			// sind ploetzlich EMPTY!!!!!!!!!!!!!!!!!!!!!!!!!!!
+			final FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = (FeatureSource<SimpleFeatureType, SimpleFeature>) layer
+					.getFeatureSource();
+			final GeometryFilterImpl filter = filterGenerator
+					.adaptFilter(featureSource);
+
+			try {
+				// Filter auf Layer des Features anwenden
+				// FeatureCollection fc = layer.getFeatureSource().getFeatures(
+				// FilterUtil.cloneFilter(filter) ); // KLAPPT (NOCH) NICHT
+				FeatureCollection<SimpleFeatureType, SimpleFeature> fc = featureSource
+						.getFeatures(filter);
+
+				// Liefert eine FeatureCollection zurück, in welcher nur
+				// Features enthalten sind, welche bei der aktuellen
+				// Anzeigeskala aufgrund des Styles gerendert werden.
+				fc = StylingUtil.filterSLDVisibleOnly(fc, layer.getStyle(),
+						this);
+
+				if (!fc.isEmpty()) {
+					result.put(layer, fc);
+					// Beim Modus "oberstes Layer selektieren" die Schleife
+					// jetzt beenden, da wir sichtbare Features gefunden haben.
+					if (mode == SELECT_TOP || mode == SELECT_ONE_FROM_TOP)
+						break;
+				}
+			} catch (Exception err) {
+				LOGGER.error("Looking for features:", err);
+			}
+
+			// for ( FeatureCollection fc1 : result.values() )
+			// LOGGER.debug("A  "+fc1+"    "+fc1.isEmpty());
+		}
+		// for ( FeatureCollection fc1 : result.values() )
+		// LOGGER.debug("B   "+fc1+"    "+fc1.isEmpty());
+
+		return result;
+	}
+
+	/**
+	 * 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.
+	 * <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
+	 * @param mode
+	 *            Suchmodus
+	 * @return eine leere {@link Hashtable} falls keine Werte ermittelt werden
+	 *         konnten
+	 * 
+	 * @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
+	 *         Kr&uuml;ger</a>
+	 */
+	protected Hashtable<MapLayer, double[]> findGridCoverageValues(
+			Point2D point, int mode) {
+		Hashtable<MapLayer, double[]> result = new Hashtable<MapLayer, double[]>();
+
+		if (point == null)
+			return result;
+
+		MapContext context = getContext();
+		// 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];
+			if (!layer.isVisible())
+				continue;
+			Object layerObj = FeatureUtil
+					.getWrappedGeoObject((FeatureSource<SimpleFeatureType, SimpleFeature>) layer
+							.getFeatureSource());
+
+			// LOGGER.info("layerObj = "+layerObj.getClass().getSimpleName());
+
+			// SK 29.9.2007 Vorher:
+			// // Bei einem Nicht-Raster-Layer, das den Punkt beinhaltet,
+			// abbrechen, wenn nur im
+			// // obersten (sichtbaren) Layer gesucht wird.
+			// // Ansonsten Nicht-Raster-Layer einfach uebergehen.
+			// if ( !(layerObj instanceof GridCoverage2D) ) {
+			// if ( mode == SELECT_TOP &&
+			// featureLayerIntersectsEnvelope(layer,new
+			// Envelope(point.getX(),point.getX(),point.getY(),point.getY())) )
+			// break;
+			// continue;
+			// }
+
+			// Bei einem Nicht-Raster-Layer, das den Punkt beinhaltet,
+			// abbrechen, wenn nur im
+			// obersten (sichtbaren) Layer gesucht wird.
+			// Ansonsten Nicht-Raster-Layer einfach uebergehen.
+			// SK 29.9.07: Ein AbstractGridCoverage2DReader ist auch ein Raster
+			if (!(layerObj instanceof GridCoverage2D || layerObj instanceof AbstractGridCoverage2DReader)) {
+				final Envelope pointAsEnvelope = new Envelope(point.getX(),
+						point.getX(), point.getY(), point.getY());
+				if (mode == SELECT_TOP
+						&& featureLayerIntersectsEnvelope(layer,
+								pointAsEnvelope)) {
+				}
+				continue;
+			}
+
+			GridCoverage2D sourceGrid;
+
+			if (layerObj instanceof AbstractGridCoverage2DReader) {
+				// LOGGER.info("layerObj instanceof AbstractGridCoverage2DReader"
+				// );
+				AbstractGridCoverage2DReader reader = (AbstractGridCoverage2DReader) layerObj;
+				Parameter readGG = new Parameter(
+						AbstractGridFormat.READ_GRIDGEOMETRY2D);
+
+				ReferencedEnvelope mapExtend = new org.geotools.geometry.jts.ReferencedEnvelope(
+						mapArea, context.getCoordinateReferenceSystem());
+
+				readGG.setValue(new GridGeometry2D(new GeneralGridEnvelope(
+						getBounds()), mapExtend));
+
+				try {
+					sourceGrid = (GridCoverage2D) reader
+							.read(new GeneralParameterValue[] { readGG });
+				} catch (Exception e) {
+					LOGGER.error(
+							"read(new GeneralParameterValue[] { readGG })", e);
+					continue;
+				}
+			} else {
+				// Ein instanceof ist nicht noetig, da sonst schon break oder
+				// continue aufgerufen worden waere
+				sourceGrid = (GridCoverage2D) layerObj;
+			}
+
+			// vorher: double[] value = new double[2];
+
+			// getNumSampleDimensions gibt die Anzahl der Baender des Rasters
+			// zurueck.
+			double[] values = new double[sourceGrid.getNumSampleDimensions()];
+
+			try {
+				// Grid an Geo-Position auswerten
+				sourceGrid.evaluate(point, values);
+			} catch (CannotEvaluateException err) {
+				// z.B. Punkt ausserhalb des Rasters --> Layer uebergehen
+				continue;
+			} catch (Exception e) {
+				LOGGER.error("sourceGrid.evaluate(point, values);", e);
+				continue;
+			}
+
+			// SK: voher wurde nur der erste Wert zurueckgegeben
+			// result.put(layer,value[0]);
+			// jetzt werden alle werte zueuckgegeben
+
+			result.put(layer, values);
+			// Beim Modus "oberstes Layer selektieren" die Schleife beenden
+			if (mode == SELECT_TOP)
+				break;
+		}
+		return result;
+	}
+
+	/**
+	 * Propagiert ein Ereignis an alle angeschlossenen Listener.
+	 * 
+	 * @param e
+	 *            Ereignis
+	 */
+	public void fireMapPaneEvent(MapPaneEvent e) {
+		for (JMapPaneListener l : mapPaneListeners)
+			l.performMapPaneEvent(e);
+	}
+
+	/**
+	 * 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
+	 */
+	public void performSelectionEvent(int ox, int oy, int px, int py) {
+		
+		if (getContext().getLayerCount() == 0)
+			return;
+
+
+		// Fenster-Koordinaten in Map-Koordinaten umwandeln
+		Envelope env = tranformWindowToGeo(ox, oy, px, py);
+
+		// Generelles Event ausloesen
+		fireMapPaneEvent(new GeneralSelectionEvent(this, env));
+
+		int selectState = getState();
+		switch (selectState) {
+		case ZOOM_IN: // Karte neu setzen
+			this.setMapArea(env);
+			refresh(); // WICHTIG!! Damit die veraenderte Form beruecksichtigt
+			// wird!?
+			break;
+		case SELECT_TOP:
+		case SELECT_ONE_FROM_TOP:
+		case SELECT_ALL: // Features selektieren
+			boolean featuresFound = findFeaturesAndFireEvents(
+					new BoundingBoxFilterGenerator(env, getContext()
+							.getCoordinateReferenceSystem()), selectState, env);
+			if (selectState == SELECT_ALL || !featuresFound)
+				findGridCoverageSubsetsAndFireEvents(env, selectState);
+			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 mode
+	 *            Suchmodus
+	 * @param env
+	 *            Bereich der durchsucht wird (fuer das Filtern irrelevant; wird
+	 *            nur fuer Events benoetigt!)
+	 */
+	public boolean findFeaturesAndFireEvents(
+			GeomFilterGenerator filterGenerator, int mode, Envelope env) {
+		Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>> result = findVisibleFeatures(
+				filterGenerator, mode, env);
+
+		// Events ausloesen fuer jedes Layer
+		for (final Enumeration<MapLayer> e = result.keys(); e.hasMoreElements();) {
+
+			final MapLayer layer = e.nextElement();
+
+			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 state
+	 *            Suchmodus
+	 * @return eine leere {@link Hashtable} falls die Bounding-Box {@code null}
+	 *         ist
+	 */
+	protected Hashtable<MapLayer, GridCoverage2D> findGridCoverageSubsets(
+			Envelope env, int state) {
+		Hashtable<MapLayer, GridCoverage2D> result = new Hashtable<MapLayer, GridCoverage2D>();
+		if (env == null)
+			return result;
+
+		MapContext context = getContext();
+		// 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 ((state == XMapPane.SELECT_TOP || state == XMapPane.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.spatialschema.geometry.Envelope gtGenEnv = new
+			// GeneralEnvelope
+			// ((org.opengis.spatialschema.geometry.Envelope)gtEnv2D); //
+			// gt2-2.3.4
+			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 (state == SELECT_TOP || state == 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
+	 * durchsucht.
+	 * 
+	 * @see #findFeatures(GeometryFilterImpl, int, Envelope)
+	 * 
+	 * @param filterGenerator
+	 *            adapts the filter to a concrete FeatureSource
+	 * @param mode
+	 *            Suchmodus
+	 * @return eine leere {@link Hashtable} falls der Filter {@code null} ist
+	 */
+	public Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>> findVisibleFeatures(
+			GeomFilterGenerator filterGenerator, int mode, Envelope env) {
+		Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>> result = new Hashtable<MapLayer, FeatureCollection<SimpleFeatureType, SimpleFeature>>();
+		if (filterGenerator == null)
+			throw new IllegalArgumentException("filterGenerator may not be null");
+//			return result;
+
+		// Je nach Modus: Alle oder nur das oberste Layer
+		MapContext context = getContext();
+		MapLayer[] layerList = context.getLayers();
+		for (int i = layerList.length - 1; i >= 0; i--) {
+			MapLayer layer = layerList[i];
+			if (!layer.isVisible())
+				continue;
+
+			// This should never happen, because the check should be performed
+			// earlier already
+			if (!isMapLayerSelectable(layer)) {
+				LOGGER.debug("Ignoring layer " + layer.getTitle()
+						+ " because it is not declared as selectable!");
+				continue;
+			}
+
+			// LOGGER.debug("mode = " + mode);
+
+			// Bei einem Raster-Layer, das die BB schneidet, abbrechen, wenn nur
+			// im obersten (sichtbaren) Layer gesucht wird.
+			// Ansonsten Raster-Layer einfach uebergehen.
+			if (isGridCoverageLayer(layer)) {
+				if (mode == SELECT_TOP
+						&& gridLayerIntersectsEnvelope(layer, env))
+					break;
+				continue;
+			}
+//			ReferencedEnvelope re;
+//			re.inter
+
+			// Filter an Layer koppeln
+			// WICHTIG: Dies darf erst geschehen, NACHDEM das
+			// Schleifen-Abbruch-Kriterium
+			// fuer die Raster-Layer geprueft wurde!!
+			// Werden folgende Zeilen naemlich auf das FeatureSource des
+			// Raster-Layers angewandt, dann "bricht" der Filter "irgendwie"
+			// zusammen und auch die ZUVOR gefilterten FeatureCollections,
+			// sind ploetzlich EMPTY!!!!!!!!!!!!!!!!!!!!!!!!!!!
+			final FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = (FeatureSource<SimpleFeatureType, SimpleFeature>) layer
+					.getFeatureSource();
+			final GeometryFilterImpl distancefilter = 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)
+			 */
+			Filter filter = distancefilter;
+			if (layer.getQuery() != null) {
+				final Filter layerFilter = layer.getQuery().getFilter();
+				if (layerFilter != null && !layerFilter.equals(Filter.INCLUDE)) {
+					filter = distancefilter.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 (!fc.isEmpty()) {
+					fc = StylingUtil.filterSLDVisibleOnly(fc, layer.getStyle(),
+							this);
+
+					if (!fc.isEmpty()) {
+						result.put(layer, fc);
+						// Beim Modus "oberstes Layer selektieren" die Schleife
+						// beenden
+						if (mode == SELECT_TOP || mode == SELECT_ONE_FROM_TOP)
+							break;
+					}
+
+				}
+			} catch (IOException err) {
+				LOGGER.error("applying the distanceWithin filter", err);
+			}
+
+			// for ( FeatureCollection fc1 : result.values() )
+			// LOGGER.debug("A  "+fc1+"    "+fc1.isEmpty());
+		}
+		// for ( FeatureCollection fc1 : result.values() )
+		// LOGGER.debug("B   "+fc1+"    "+fc1.isEmpty());
+
+		return result;
+	}
+	
+	@Override
+	public void mouseDragged(Point startPos, Point lastPos, MouseEvent event) {
+		
+		super.mouseDragged(startPos, lastPos, event);
+		
+	}
+
+	/**
+	 * 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.
+	 * 
+	 * @param layer
+	 *            ein Layer
+	 * @param env
+	 *            Bounding-Box in CRS des MapPane
+	 */
+	private boolean gridLayerIntersectsEnvelope(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(), getContext()
+					.getCoordinateReferenceSystem());
+
+			// TODO warum kann bounds_MapCRS == null sein ?? ?SK fragt martin???
+			if (bounds_MapCRS == null)
+				return false;
+
+			return bounds_MapCRS.intersects(env);
+		} catch (Exception err) {
+			return false;
+		}
+	}
+
+	/**
+	 * Prueft, ob es sich bei einem Layer um ein Raster-Layer handelt.
+	 * Raster-Layer zeichnen sich dadurch aus, dass die zugrunde liegende
+	 * {@link FeatureCollection} nur ein SimpleFeature enthaelt, das genau ein
+	 * Attribut mit dem Namen "GridCoverage" hat.
+	 * 
+	 * SK: Pyramidenlayer aka AbstractGridCoverage2DReader geben auch true
+	 * zurück.
+	 * 
+	 * @param layer
+	 *            zu ueberpruefendes Layer
+	 */
+	public static boolean isGridCoverageLayer(MapLayer layer) {
+		return (MapLayerUtils.isGridLayer(layer).get(MapLayerUtils.IS_GRID_KEY) == Boolean.TRUE);
+	}
+
+}

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/io/GeoImportUtil.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/io/GeoImportUtil.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/io/GeoImportUtil.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -91,7 +91,8 @@
  * @version 1.0
  */
 public class GeoImportUtil {
-	private static final Logger LOGGER = Logger.getLogger(GeoImportUtil.class.getName());
+	private static final Logger LOGGER = Logger.getLogger(GeoImportUtil.class
+			.getName());
 
 	/**
 	 * These postfixes are associated with Arc/Info ASCII Grid files TODO .0
@@ -127,54 +128,67 @@
 		wld, jgw, pgw, tfw
 	};
 
-    ///////////////////////////////////////////////////////////////////////////
-    //              ASCII IMPORT STYLE
-    ///////////////////////////////////////////////////////////////////////////
+	// /////////////////////////////////////////////////////////////////////////
+	// ASCII IMPORT STYLE
+	// /////////////////////////////////////////////////////////////////////////
 
 	/**
-     * This type specifies how this class can proceed the import of ASCII rasters.
-     * @see GeoImportUtil#readGridFromArcInfoASCII(Object, CoordinateReferenceSystem)
-     * @see GeoImportUtil#readGridRasterFromGeoTiff(File, CoordinateReferenceSystem)
-     */
-    public static enum ARCASCII_IMPORT_TYPE {
-      /** Use the old {@link ArcGridRaster}. This works fine (colorization and
-       *  no data transparency), but {@link ArcGridRaster} is deprecated
-       *  and no longer supported since gt2-2.3.0-M0. */
-      USE_ARCGRIDRASTER,
-      /** Use the {@link ArcGridReader} from "standard" GT.<br>
-       *  <b>Note:</b>There may be problems with colorization and 
-       *  no data transparency using this import type! */
-      USE_ARCGRIDREADER
-    }
-    
-    /**
-     * Specifies how this class proceeds the import of ASCII rasters. The default is
-     * {@link ARCASCII_IMPORT_TYPE#USE_ARCGRIDREADER} because this works fine!
-     * @see GeoImportUtil#readGridFromArcInfoASCII(Object, CoordinateReferenceSystem)
-     * @see GeoImportUtil#readGridRasterFromGeoTiff(File, CoordinateReferenceSystem)
-     */
-    private static ARCASCII_IMPORT_TYPE ARCASCII_IMPORT_MODE = ARCASCII_IMPORT_TYPE.USE_ARCGRIDRASTER;
+	 * This type specifies how this class can proceed the import of ASCII
+	 * rasters.
+	 * 
+	 * @see GeoImportUtil#readGridFromArcInfoASCII(Object,
+	 *      CoordinateReferenceSystem)
+	 * @see GeoImportUtil#readGridRasterFromGeoTiff(File,
+	 *      CoordinateReferenceSystem)
+	 */
+	public static enum ARCASCII_IMPORT_TYPE {
+		/**
+		 * Use the old {@link ArcGridRaster}. This works fine (colorization and
+		 * no data transparency), but {@link ArcGridRaster} is deprecated and no
+		 * longer supported since gt2-2.3.0-M0.
+		 */
+		USE_ARCGRIDRASTER,
+		/**
+		 * Use the {@link ArcGridReader} from "standard" GT.<br>
+		 * <b>Note:</b>There may be problems with colorization and no data
+		 * transparency using this import type!
+		 */
+		USE_ARCGRIDREADER
+	}
 
-    /**
-     * Sets how this class proceeds the import of ASCII rasters. 
-     * @param mode the mode how to proceed the import
-     */
-    public static void setAsciiRasterImportMode(ARCASCII_IMPORT_TYPE mode) {
-      ARCASCII_IMPORT_MODE = mode;
-    }
+	/**
+	 * Specifies how this class proceeds the import of ASCII rasters. The
+	 * default is {@link ARCASCII_IMPORT_TYPE#USE_ARCGRIDREADER} because this
+	 * works fine!
+	 * 
+	 * @see GeoImportUtil#readGridFromArcInfoASCII(Object,
+	 *      CoordinateReferenceSystem)
+	 * @see GeoImportUtil#readGridRasterFromGeoTiff(File,
+	 *      CoordinateReferenceSystem)
+	 */
+	private static ARCASCII_IMPORT_TYPE ARCASCII_IMPORT_MODE = ARCASCII_IMPORT_TYPE.USE_ARCGRIDRASTER;
 
-    /**
-     * Returns the default CRS used if no CRS can be found during import.
-     */
-    public static ARCASCII_IMPORT_TYPE getAsciiRasterImportMode() {
-      return ARCASCII_IMPORT_MODE;
-    }
+	/**
+	 * Sets how this class proceeds the import of ASCII rasters.
+	 * 
+	 * @param mode
+	 *            the mode how to proceed the import
+	 */
+	public static void setAsciiRasterImportMode(ARCASCII_IMPORT_TYPE mode) {
+		ARCASCII_IMPORT_MODE = mode;
+	}
 
-    
-    ///////////////////////////////////////////////////////////////////////////
-    //              DEFAULT COORDINATE REFERENCE SYSTEM
-    ///////////////////////////////////////////////////////////////////////////
+	/**
+	 * Returns the default CRS used if no CRS can be found during import.
+	 */
+	public static ARCASCII_IMPORT_TYPE getAsciiRasterImportMode() {
+		return ARCASCII_IMPORT_MODE;
+	}
 
+	// /////////////////////////////////////////////////////////////////////////
+	// DEFAULT COORDINATE REFERENCE SYSTEM
+	// /////////////////////////////////////////////////////////////////////////
+
 	/**
 	 * Standard-CRS, welches verwendet wird, wenn beim Import kein CRS ermittelt
 	 * werden kann (Default: {@link DefaultGeographicCRS#WGS84}).<br>
@@ -186,22 +200,24 @@
 
 	/**
 	 * Sets the default CRS used if no CRS can be found during import.
-	 * @param crs the new default CRS
+	 * 
+	 * @param crs
+	 *            the new default CRS
 	 */
 	public static void setDefaultCRS(CoordinateReferenceSystem crs) {
-	  DEFAULT_CRS = crs;
+		DEFAULT_CRS = crs;
 	}
 
-    /**
-     * Returns the default CRS used if no CRS can be found during import.
-     */
+	/**
+	 * Returns the default CRS used if no CRS can be found during import.
+	 */
 	public static CoordinateReferenceSystem getDefaultCRS() {
-	  return DEFAULT_CRS;
+		return DEFAULT_CRS;
 	}
 
-	///////////////////////////////////////////////////////////////////////////
-    //              FEATURE IMPORT
-	///////////////////////////////////////////////////////////////////////////
+	// /////////////////////////////////////////////////////////////////////////
+	// FEATURE IMPORT
+	// /////////////////////////////////////////////////////////////////////////
 	/**
 	 * Diese Methode extrahiert saemtliche Features aus einem ShapeFile-Projekt
 	 * (<code><i>name</i>.shp <i>name</i>.prj <i>name</i>.dbf ...</code>) und
@@ -221,8 +237,8 @@
 	 * 
 	 * @throws IOException
 	 */
-	public static FeatureCollection<SimpleFeatureType, SimpleFeature> readFeaturesFromShapeURL(URL url, URL prjUrl)
-			throws IOException {
+	public static FeatureCollection<SimpleFeatureType, SimpleFeature> readFeaturesFromShapeURL(
+			URL url, URL prjUrl) throws IOException {
 		ShapefileDataStore store = new ShapefileDataStore(url);
 		try {
 			// Testen, ob Projektion ermittelt werden kann, um vorab das
@@ -238,7 +254,8 @@
 			// store.forceSchemaCRS(DEFAULT_CRS);
 		}
 		String[] typeNames = store.getTypeNames();
-		FeatureCollection<SimpleFeatureType, SimpleFeature> fc = store.getFeatureSource(typeNames[0]).getFeatures();
+		FeatureCollection<SimpleFeatureType, SimpleFeature> fc = store
+				.getFeatureSource(typeNames[0]).getFeatures();
 
 		// Create a new DefaultFeatureCollection to allow modifying
 		// operations on the collection ("fc" is a DataFeatureCollection, whose
@@ -246,7 +263,8 @@
 		// FIDFeatureReader is used which returns copies of the features,
 		// so modifying the attributes does not effect the features
 		// in the collection!)
-		FeatureCollection<SimpleFeatureType, SimpleFeature> fc1 = FeatureCollections.newCollection(fc.getID());
+		FeatureCollection<SimpleFeatureType, SimpleFeature> fc1 = FeatureCollections
+				.newCollection(fc.getID());
 		fc1.addAll(fc);
 		fc = fc1;
 
@@ -271,8 +289,10 @@
 	 *         hiet auf readFeaturesFromShapeURL(file.getURL) umgeleitet werden
 	 *         (SK)
 	 */
-	public static FeatureCollection<SimpleFeatureType, SimpleFeature> readFeaturesFromShapeFile(File file) throws Exception {
-		ShapefileDataStore store = new ShapefileDataStore(DataUtilities.fileToURL(file));
+	public static FeatureCollection<SimpleFeatureType, SimpleFeature> readFeaturesFromShapeFile(
+			File file) throws Exception {
+		ShapefileDataStore store = new ShapefileDataStore(DataUtilities
+				.fileToURL(file));
 		File prjFile = IOUtil.changeFileExt(file, "prj");
 		boolean delPrjFile = false;
 		try {
@@ -291,7 +311,8 @@
 			delPrjFile = true; // von DataStore erzeugte Datei wieder loeschen
 		}
 		String[] typeNames = store.getTypeNames();
-		FeatureCollection<SimpleFeatureType, SimpleFeature> fc = store.getFeatureSource(typeNames[0]).getFeatures();
+		FeatureCollection<SimpleFeatureType, SimpleFeature> fc = store
+				.getFeatureSource(typeNames[0]).getFeatures();
 		if (delPrjFile)
 			prjFile.delete();
 
@@ -302,7 +323,8 @@
 		// is used which returns copies of the features, so modifying the
 		// attributes
 		// does not effect the features in the collection!)
-		FeatureCollection<SimpleFeatureType, SimpleFeature> fc1 = FeatureCollections.newCollection(fc.getID());
+		FeatureCollection<SimpleFeatureType, SimpleFeature> fc1 = FeatureCollections
+				.newCollection(fc.getID());
 		fc1.addAll(fc);
 		fc = fc1;
 
@@ -311,19 +333,25 @@
 
 	/**
 	 * Creates a {@link DataStore} from shape file
-	 * @param shpURL URL to shape file
-	 * @param prjURL URL to projection file
-	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Kr&uuml;ger</a>
-	 * @throws IOException if an error occur
+	 * 
+	 * @param shpURL
+	 *            URL to shape file
+	 * @param prjURL
+	 *            URL to projection file
+	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
+	 *         Kr&uuml;ger</a>
+	 * @throws IOException
+	 *             if an error occur
 	 */
-	public static DataStore readDataStoreFromShape(URL shpURL, URL prjURL) throws IOException {
-		Map<Object,Object> map = new HashMap<Object,Object>();
+	public static DataStore readDataStoreFromShape(URL shpURL, URL prjURL)
+			throws IOException {
+		Map<Object, Object> map = new HashMap<Object, Object>();
 		map.put("url", shpURL);
 		map.put("create spatial index", true);
 
 		// DataStore dataStore = DataStoreFinder.getDataStore( map );
-		DataStore dataStore = new IndexedShapefileDataStore(
-		        shpURL, null, false, true, IndexType.QIX);
+		DataStore dataStore = new IndexedShapefileDataStore(shpURL, null,
+				false, true, IndexType.QIX);
 		// DataStore dataStore = new ShapefileDataStore(shpURL);
 		LOGGER.debug("DataStore = " + dataStore.getClass().toString());
 		IndexedShapefileDataStore dataStoreIndex = (IndexedShapefileDataStore) dataStore;
@@ -353,11 +381,11 @@
 	 */
 	public static Vector<Geometry> readGeometriesFromShapeFile(File file)
 			throws Exception {
-//		FileChannel in = new FileInputStream(file).getChannel();
-//		ShapefileReader r = new ShapefileReader(in, new Lock());
+		// FileChannel in = new FileInputStream(file).getChannel();
+		// ShapefileReader r = new ShapefileReader(in, new Lock());
 
 		ShapefileReader r = new ShapefileReader(new ShpFiles(file), true, false);
-		
+
 		Vector<Geometry> geomList = new Vector<Geometry>();
 		for (int i = 1; r.hasNext(); i++) {
 			// org.geotools.renderer.geom.Geometry shape =
@@ -372,228 +400,259 @@
 		return geomList;
 	}
 
-    ///////////////////////////////////////////////////////////////////////////
-    //              RASTER IMPORT (GridCoverage2D)
-    ///////////////////////////////////////////////////////////////////////////
+	// /////////////////////////////////////////////////////////////////////////
+	// RASTER IMPORT (GridCoverage2D)
+	// /////////////////////////////////////////////////////////////////////////
 
-    /**
-     * Imports a raster from file or URL in
-     * ArcInfoASCII format. The CRS is taken from prj-file (EPSG-Code
-     * "EPSG:..." oder WKT-Definition). If not present the {@link #DEFAULT_CRS}
-     * is used.
-     * @param input file or URL to the input file
-     * @param crs   CRS forced to use (can be <code>null</code>)
-     */
-    public static GridCoverage2D readGridFromArcInfoASCII(Object input) throws Exception {
-      return readGridFromArcInfoASCII(input, null);
-    }
+	/**
+	 * Imports a raster from file or URL in ArcInfoASCII format. The CRS is
+	 * taken from prj-file (EPSG-Code "EPSG:..." oder WKT-Definition). If not
+	 * present the {@link #DEFAULT_CRS} is used.
+	 * 
+	 * @param input
+	 *            file or URL to the input file
+	 * @param crs
+	 *            CRS forced to use (can be <code>null</code>)
+	 */
+	public static GridCoverage2D readGridFromArcInfoASCII(Object input)
+			throws Exception {
+		return readGridFromArcInfoASCII(input, null);
+	}
 
-    /**
-     * Imports a raster from file or URL in
-     * ArcInfoASCII format. The CRS is taken from prj-file (EPSG-Code
-     * "EPSG:..." oder WKT-Definition). If not present the {@link #DEFAULT_CRS}
-     * is used.
-     * @param input file or URL to the input file
-     * @param crs   CRS forced to use (can be <code>null</code>)
-     */
-    public static GridCoverage2D readGridFromArcInfoASCII(Object input, CoordinateReferenceSystem crs) throws Exception {
-      switch( getAsciiRasterImportMode() ) {
-        case USE_ARCGRIDREADER: return readGridFromArcInfoASCII_ArcGridReader(input, crs); 
-        case USE_ARCGRIDRASTER: return readGridFromArcInfoASCII_ArcGridRaster(input, crs); 
-      }
-      throw new UnsupportedOperationException("ASCII raster import mode not supported: "+getAsciiRasterImportMode());
-    }
-    
-    /**
-     * Uses the <b>{@link ArcGridReader} class</b> (standard GT) to import a raster
-     * from file or URL in ArcInfoASCII format. The CRS is taken from prj-file (EPSG-Code
-     * "EPSG:..." oder WKT-Definition). If not present the {@link #DEFAULT_CRS}
-     * is used.
-     * @param input file or URL to the input file
-     * @param crs   CRS forced to use (can be <code>null</code>)
-     */
-    private static GridCoverage2D readGridFromArcInfoASCII_ArcGridReader(Object input, CoordinateReferenceSystem crs) throws Exception {
-      Hints hints = new Hints();
-      if (crs != null) {
-        hints.put(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM, crs);
-      }
-      ArcGridReader reader = new ArcGridReader(input ,hints);
-      GridCoverage2D gc = (GridCoverage2D) reader.read(null);
-      return gc;
-    }
-    
-    /**
-     * Uses the <b>{@link ArcGridRaster} class</b> (standard GT) to import a raster
-     * from file or URL in ArcInfoASCII format. The CRS is taken from prj-file (EPSG-Code
-     * "EPSG:..." oder WKT-Definition). If not present the {@link #DEFAULT_CRS}
-     * is used.
-     * @param input file or URL to the input file
-     * @param crs   CRS forced to use (can be <code>null</code>)
-     */
-    private static GridCoverage2D readGridFromArcInfoASCII_ArcGridRaster(Object input, CoordinateReferenceSystem crs) throws Exception {
-      // Import raster data
-      ArcGridRaster reader = null;
-      if (input instanceof File)
-        reader = new ArcGridRaster( new BufferedReader( new InputStreamReader( new FileInputStream((File)input) ) ), false );
-      else if (input instanceof URL)
-        reader = new ArcGridRaster( (URL)input );
-      else
-        throw new UnsupportedOperationException("Import source not supported: "+LangUtil.getSimpleClassName(input));
-      WritableRaster raster = reader.readRaster();
-      
-      // Import CRS
-      if (crs == null) {
-        if (input instanceof File)
-          crs = determineProjection((File)input);
-        else if (input instanceof URL)
-          crs = determineProjection((URL)input);
-      }
-      
-//      LOGGER.debug("Position  "+reader.getXlCorner()+" / "+reader.getYlCorner());
-//      LOGGER.debug("Size      "+reader.getNCols()+" / "+reader.getNRows());
-//      LOGGER.debug("Min/Max   "+reader.getMinValue()+" / "+reader.getMaxValue());
-//      LOGGER.debug("NoData    "+reader.getNoData());
-//      LOGGER.debug("CellSize  "+reader.getCellSize());
-      
-      float x = (float) reader.getXlCorner(); // SW corner!
-      float y = (float) reader.getYlCorner(); // SW corner!
-      // real width = colums * cell size
-      float w = (float) (reader.getNCols() * reader.getCellSize());
-      // real hight = rows * cell size
-      float h = (float) (reader.getNRows() * reader.getCellSize());
-      Envelope2D envelope = new Envelope2D(crs, new Rectangle2D.Float(x, y, w, h));
-      
-      // WICHTIG: Name des Rasters sollte Leer-String sein, da ansonsten
-      //          das Coloring des Rasters nicht klappt.
-      // --> Name der Categories muss (warum auch immer) mit dem Namen
-      //     des Rasters uebereinstimmen!!!
-      return new GridCoverageFactory().create("", raster, envelope);
-    }
+	/**
+	 * Imports a raster from file or URL in ArcInfoASCII format. The CRS is
+	 * taken from prj-file (EPSG-Code "EPSG:..." oder WKT-Definition). If not
+	 * present the {@link #DEFAULT_CRS} is used.
+	 * 
+	 * @param input
+	 *            file or URL to the input file
+	 * @param crs
+	 *            CRS forced to use (can be <code>null</code>)
+	 */
+	public static GridCoverage2D readGridFromArcInfoASCII(Object input,
+			CoordinateReferenceSystem crs) throws Exception {
+		switch (getAsciiRasterImportMode()) {
+		case USE_ARCGRIDREADER:
+			return readGridFromArcInfoASCII_ArcGridReader(input, crs);
+		case USE_ARCGRIDRASTER:
+			return readGridFromArcInfoASCII_ArcGridRaster(input, crs);
+		}
+		throw new UnsupportedOperationException(
+				"ASCII raster import mode not supported: "
+						+ getAsciiRasterImportMode());
+	}
 
- // NOT USED ANYMORE: File and URL are handled by the same method using Object
-//  /**
-//   * Diese Methode importiert ein Raster aus einer Datei im
-//   * ArcInfoASCII-Grid-Format. Das CRS wird aus einem prj-File (EPSG-Code
-//   * "EPSG:..." oder WKT-Definition) gelesen. Ist dies nicht erfolgreich, wird
-//   * {@link #DEFAULT_CRS} als CRS verwendet.
-//   * @param file ASCII-File
-//   * @throws java.lang.Exception bei irgendeinem Fehler
-//   * @return {@link GridCoverage2D}
-//   */
-//  public static GridCoverage2D readGridFromArcInfoASCII(File file) throws Exception {
-//    return readGridFromArcInfoASCII(file, null);
-//  }
-//
-//  /**
-//   * Diese Methode importiert ein Raster aus einer Datei im
-//   * ArcInfoASCII-Grid-Format. Wenn kein CRS angegeben wird, wird versucht das
-//   * CRS aus einem prj-File (EPSG-Code "EPSG:..." oder WKT-Definition) zu
-//   * lesen. Ist dies nicht erfolgreich, wird {@link #DEFAULT_CRS} als CRS
-//   * verwendet.
-//   * @param file  ASCII-File
-//   * @param crs   CoordinateReferenceSystem fuer das Raster (kann {@code null} sein)
-//   * @throws MalformedURLException if the file can not be converted to URL
-//   * @throws Exception bei irgendeinem Fehler
-//   */
-//  public static GridCoverage2D readGridFromArcInfoASCII(File file, CoordinateReferenceSystem crs) throws MalformedURLException, Exception  {
-//      return readGridFromArcInfoASCII(file.toURI().toURL(), crs);
-//  }
+	/**
+	 * Uses the <b>{@link ArcGridReader} class</b> (standard GT) to import a
+	 * raster from file or URL in ArcInfoASCII format. The CRS is taken from
+	 * prj-file (EPSG-Code "EPSG:..." oder WKT-Definition). If not present the
+	 * {@link #DEFAULT_CRS} is used.
+	 * 
+	 * @param input
+	 *            file or URL to the input file
+	 * @param crs
+	 *            CRS forced to use (can be <code>null</code>)
+	 */
+	private static GridCoverage2D readGridFromArcInfoASCII_ArcGridReader(
+			Object input, CoordinateReferenceSystem crs) throws Exception {
+		Hints hints = new Hints();
+		if (crs != null) {
+			hints.put(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM, crs);
+		}
+		ArcGridReader reader = new ArcGridReader(input, hints);
+		GridCoverage2D gc = (GridCoverage2D) reader.read(null);
+		return gc;
+	}
 
-    /**
-     * Diese Methode importiert ein Raster aus einer Datei im GeoTIFF-Format.
-     * 
-     * @param file
-     *            GeoTIFF-File
-     * @throws java.lang.Exception
-     *             bei irgendeinem Fehler
-     * @see #readGridFromGeoTiff(File, CoordinateReferenceSystem)
-     */
-    public static GridCoverage2D readGridFromGeoTiff(File file) throws Exception {
-        return readGridFromGeoTiff(file, null);
-    }
+	/**
+	 * Uses the <b>{@link ArcGridRaster} class</b> (standard GT) to import a
+	 * raster from file or URL in ArcInfoASCII format. The CRS is taken from
+	 * prj-file (EPSG-Code "EPSG:..." oder WKT-Definition). If not present the
+	 * {@link #DEFAULT_CRS} is used.
+	 * 
+	 * @param input
+	 *            file or URL to the input file
+	 * @param crs
+	 *            CRS forced to use (can be <code>null</code>)
+	 */
+	private static GridCoverage2D readGridFromArcInfoASCII_ArcGridRaster(
+			Object input, CoordinateReferenceSystem crs) throws Exception {
+		// Import raster data
+		ArcGridRaster reader = null;
+		if (input instanceof File)
+			reader = new ArcGridRaster(new BufferedReader(
+					new InputStreamReader(new FileInputStream((File) input))),
+					false);
+		else if (input instanceof URL)
+			reader = new ArcGridRaster((URL) input);
+		else
+			throw new UnsupportedOperationException(
+					"Import source not supported: "
+							+ LangUtil.getSimpleClassName(input));
+		WritableRaster raster = reader.readRaster();
 
-    /**
-     * Diese Methode importiert ein Raster aus einer Datei im GeoTIFF-Format.
-     * 
-     * @param file
-     *            GeoTIFF-File
-     * @param crs
-     *            erzwungenes CoordinateReferenceSystem fuer das Raster (kann
-     *            {@code null} sein)
-     * @throws java.lang.Exception
-     *             bei irgendeinem Fehler
-     * @see #createGridReaderFromGeoTiff(File, CoordinateReferenceSystem)
-     */
-    public static GridCoverage2D readGridFromGeoTiff(File file, CoordinateReferenceSystem crs) throws Exception {
-        // return (GridCoverage2D)createGridReaderFromGeoTiff(file, crs).read(null);
-        GridCoverage2D gc = null;
-        // Versuchen Geo-Information aus Tiff zu lesen
-        try {
-            Hints hints = new Hints();
+		// Import CRS
+		if (crs == null) {
+			if (input instanceof File)
+				crs = determineProjection((File) input);
+			else if (input instanceof URL)
+				crs = determineProjection((URL) input);
+		}
 
-            // Wenn CRS angegeben, dieses durch Hint erzwingen
-            if (crs != null)
-                hints.put(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM, crs);
-            // Reader (mit Metadaten) erzeugen
-            GeoTiffReader reader = new GeoTiffReader(file, hints);
-            // Wenn kein Referenzsystem vorhanden, versuchen ein prj-File zu
-            // verwenden
-            if (reader.getOriginalEnvelope().getCoordinateReferenceSystem() == null) {
-                LOGGER.warn("No projection information found in '"
-                        + file.getName() + "'. Using prj-file...");
-                hints.put(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM,
-                        determineProjection(file));
-                reader = new GeoTiffReader(file, hints);
-            }
-            gc = (GridCoverage2D) reader.read(null);
-            return gc;
-        } catch (UnsupportedOperationException err) {
-            // erwartet, wenn keine Geo-Information im Tiff vorhanden ist
-            // ExceptionMonitor.show(null, err,
-            // "No geoinformation in TIFF, importing it as a normal file. Trying to read it as normal TIFF + Worldfile.");
-        } catch (NullPointerException err) {
-            // erwartet, wenn keine Geo-Information im Tiff vorhanden ist
-        }
+		// LOGGER.debug("Position  "+reader.getXlCorner()+" / "+reader.getYlCorner());
+		// LOGGER.debug("Size      "+reader.getNCols()+" / "+reader.getNRows());
+		// LOGGER.debug("Min/Max   "+reader.getMinValue()+" / "+reader.getMaxValue());
+		// LOGGER.debug("NoData    "+reader.getNoData());
+		// LOGGER.debug("CellSize  "+reader.getCellSize());
 
-        // keine Geo-Informationen in Tiff
-        // --> Raster ueber ImageIO einlesen und WorldFile/ProjectionFile
-        // verwenden
-        LOGGER.warn("No geo information found in '" + file.getName()
-                + "'. Using world- and prj-file...");
-        BufferedImage im = ImageIO.read(file);
-        if (im == null)
-            throw new IIOException("No image reader found for this image type!");
-        // World-File einlesen
-        File tfw = IOUtil.changeFileExt(file, "tfw");
-        double[] tfwInfo = readWorldFile(tfw);
-        float w = (float) (im.getWidth() * tfwInfo[0]); // reale Breite =
-        // RasterSpalten * hor.
-        // Aufloesung
-        float h = (float) (im.getHeight() * (-tfwInfo[3])); // reale Hoehe =
-        // RasterZeilen *
-        // vert. Aufloesung
-        float x = (float) tfwInfo[4]; // Suedwestliche Ecke!
-        float y = (float) tfwInfo[5] - h; // Suedwestliche Ecke (im tfw-File
-        // steht die Nordwestliche!)
-        // ggf. Projektion einlesen
-        if (crs == null)
-            crs = determineProjection(file);
-        Envelope2D envelope = new Envelope2D(crs, new Rectangle2D.Float(x, y,
-                w, h));
-        // WICHTIG: Name des Rasters sollte Leer-String sein, da ansonsten das
-        // Coloring des Rasters nicht klappt.
-        // --> Name der Categories muss (warum auch immer) mit dem Namen
-        // des Rasters uebereinstimmen!!!
-        gc = new GridCoverageFactory().create("", im.copyData(null), envelope);
-        return gc;
-    }
+		float x = (float) reader.getXlCorner(); // SW corner!
+		float y = (float) reader.getYlCorner(); // SW corner!
+		// real width = colums * cell size
+		float w = (float) (reader.getNCols() * reader.getCellSize());
+		// real hight = rows * cell size
+		float h = (float) (reader.getNRows() * reader.getCellSize());
+		Envelope2D envelope = new Envelope2D(crs, new Rectangle2D.Float(x, y,
+				w, h));
 
-    
-    ///////////////////////////////////////////////////////////////////////////
-    //              RASTER IMPORT (AbstractGridCoverage2DReader)
-    ///////////////////////////////////////////////////////////////////////////
-    
+		// WICHTIG: Name des Rasters sollte Leer-String sein, da ansonsten
+		// das Coloring des Rasters nicht klappt.
+		// --> Name der Categories muss (warum auch immer) mit dem Namen
+		// des Rasters uebereinstimmen!!!
+		return new GridCoverageFactory().create("", raster, envelope);
+	}
+
+	// NOT USED ANYMORE: File and URL are handled by the same method using
+	// Object
+	// /**
+	// * Diese Methode importiert ein Raster aus einer Datei im
+	// * ArcInfoASCII-Grid-Format. Das CRS wird aus einem prj-File (EPSG-Code
+	// * "EPSG:..." oder WKT-Definition) gelesen. Ist dies nicht erfolgreich,
+	// wird
+	// * {@link #DEFAULT_CRS} als CRS verwendet.
+	// * @param file ASCII-File
+	// * @throws java.lang.Exception bei irgendeinem Fehler
+	// * @return {@link GridCoverage2D}
+	// */
+	// public static GridCoverage2D readGridFromArcInfoASCII(File file) throws
+	// Exception {
+	// return readGridFromArcInfoASCII(file, null);
+	// }
+	//
+	// /**
+	// * Diese Methode importiert ein Raster aus einer Datei im
+	// * ArcInfoASCII-Grid-Format. Wenn kein CRS angegeben wird, wird versucht
+	// das
+	// * CRS aus einem prj-File (EPSG-Code "EPSG:..." oder WKT-Definition) zu
+	// * lesen. Ist dies nicht erfolgreich, wird {@link #DEFAULT_CRS} als CRS
+	// * verwendet.
+	// * @param file ASCII-File
+	// * @param crs CoordinateReferenceSystem fuer das Raster (kann {@code null}
+	// sein)
+	// * @throws MalformedURLException if the file can not be converted to URL
+	// * @throws Exception bei irgendeinem Fehler
+	// */
+	// public static GridCoverage2D readGridFromArcInfoASCII(File file,
+	// CoordinateReferenceSystem crs) throws MalformedURLException, Exception {
+	// return readGridFromArcInfoASCII(file.toURI().toURL(), crs);
+	// }
+
 	/**
+	 * Diese Methode importiert ein Raster aus einer Datei im GeoTIFF-Format.
+	 * 
+	 * @param file
+	 *            GeoTIFF-File
+	 * @throws java.lang.Exception
+	 *             bei irgendeinem Fehler
+	 * @see #readGridFromGeoTiff(File, CoordinateReferenceSystem)
+	 */
+	public static GridCoverage2D readGridFromGeoTiff(File file)
+			throws Exception {
+		return readGridFromGeoTiff(file, null);
+	}
+
+	/**
+	 * Diese Methode importiert ein Raster aus einer Datei im GeoTIFF-Format.
+	 * 
+	 * @param file
+	 *            GeoTIFF-File
+	 * @param crs
+	 *            erzwungenes CoordinateReferenceSystem fuer das Raster (kann
+	 *            {@code null} sein)
+	 * @throws java.lang.Exception
+	 *             bei irgendeinem Fehler
+	 * @see #createGridReaderFromGeoTiff(File, CoordinateReferenceSystem)
+	 */
+	public static GridCoverage2D readGridFromGeoTiff(File file,
+			CoordinateReferenceSystem crs) throws Exception {
+		// return (GridCoverage2D)createGridReaderFromGeoTiff(file,
+		// crs).read(null);
+		GridCoverage2D gc = null;
+		// Versuchen Geo-Information aus Tiff zu lesen
+		try {
+			Hints hints = new Hints();
+
+			// Wenn CRS angegeben, dieses durch Hint erzwingen
+			if (crs != null)
+				hints.put(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM, crs);
+			// Reader (mit Metadaten) erzeugen
+			GeoTiffReader reader = new GeoTiffReader(file, hints);
+			// Wenn kein Referenzsystem vorhanden, versuchen ein prj-File zu
+			// verwenden
+			if (reader.getOriginalEnvelope().getCoordinateReferenceSystem() == null) {
+				LOGGER.warn("No projection information found in '"
+						+ file.getName() + "'. Using prj-file...");
+				hints.put(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM,
+						determineProjection(file));
+				reader = new GeoTiffReader(file, hints);
+			}
+			gc = (GridCoverage2D) reader.read(null);
+			return gc;
+		} catch (UnsupportedOperationException err) {
+			// erwartet, wenn keine Geo-Information im Tiff vorhanden ist
+			// ExceptionMonitor.show(null, err,
+			// "No geoinformation in TIFF, importing it as a normal file. Trying to read it as normal TIFF + Worldfile.");
+		} catch (NullPointerException err) {
+			// erwartet, wenn keine Geo-Information im Tiff vorhanden ist
+		}
+
+		// keine Geo-Informationen in Tiff
+		// --> Raster ueber ImageIO einlesen und WorldFile/ProjectionFile
+		// verwenden
+		LOGGER.warn("No geo information found in '" + file.getName()
+				+ "'. Using world- and prj-file...");
+		BufferedImage im = ImageIO.read(file);
+		if (im == null)
+			throw new IIOException("No image reader found for this image type!");
+		// World-File einlesen
+		File tfw = IOUtil.changeFileExt(file, "tfw");
+		double[] tfwInfo = readWorldFile(tfw);
+		float w = (float) (im.getWidth() * tfwInfo[0]); // reale Breite =
+		// RasterSpalten * hor.
+		// Aufloesung
+		float h = (float) (im.getHeight() * (-tfwInfo[3])); // reale Hoehe =
+		// RasterZeilen *
+		// vert. Aufloesung
+		float x = (float) tfwInfo[4]; // Suedwestliche Ecke!
+		float y = (float) tfwInfo[5] - h; // Suedwestliche Ecke (im tfw-File
+		// steht die Nordwestliche!)
+		// ggf. Projektion einlesen
+		if (crs == null)
+			crs = determineProjection(file);
+		Envelope2D envelope = new Envelope2D(crs, new Rectangle2D.Float(x, y,
+				w, h));
+		// WICHTIG: Name des Rasters sollte Leer-String sein, da ansonsten das
+		// Coloring des Rasters nicht klappt.
+		// --> Name der Categories muss (warum auch immer) mit dem Namen
+		// des Rasters uebereinstimmen!!!
+		gc = new GridCoverageFactory().create("", im.copyData(null), envelope);
+		return gc;
+	}
+
+	// /////////////////////////////////////////////////////////////////////////
+	// RASTER IMPORT (AbstractGridCoverage2DReader)
+	// /////////////////////////////////////////////////////////////////////////
+
+	/**
 	 * Diese Methode erzeugt einen {@link AbstractGridCoverage2DReader} aus
 	 * einer Datei im GeoTIFF-Format. Zunaechst wird versucht, die
 	 * Geo-Informationen (Referenz+CRS) aus den TIFF-Metadaten zu ermitteln. Ist
@@ -669,94 +728,117 @@
 		return createGridReaderFromGeoTiff(file, null);
 	}
 
-    ///////////////////////////////////////////////////////////////////////////
-    //              RASTER IMPORT (WritableGridRaster)
-    ///////////////////////////////////////////////////////////////////////////
+	// /////////////////////////////////////////////////////////////////////////
+	// RASTER IMPORT (WritableGridRaster)
+	// /////////////////////////////////////////////////////////////////////////
 
-    /**
-     * Import a raster from file or URL in ArcInfoASCII format.
-     * The CRS is taken from prj-file (EPSG-Code "EPSG:..." oder WKT-Definition).
-     * If not present the {@link #DEFAULT_CRS} is used.
-     * @param input ASCII file or URL to the input file
-     */
-	public static WritableGridRaster readGridRasterFromArcInfoASCII(Object input) throws Exception {
-	  return readGridRasterFromArcInfoASCII(input, null);
+	/**
+	 * Import a raster from file or URL in ArcInfoASCII format. The CRS is taken
+	 * from prj-file (EPSG-Code "EPSG:..." oder WKT-Definition). If not present
+	 * the {@link #DEFAULT_CRS} is used.
+	 * 
+	 * @param input
+	 *            ASCII file or URL to the input file
+	 */
+	public static WritableGridRaster readGridRasterFromArcInfoASCII(Object input)
+			throws Exception {
+		return readGridRasterFromArcInfoASCII(input, null);
 	}
 
-    /**
-     * Import a raster from file or URL in ArcInfoASCII format.
-     * The CRS is taken from prj-file (EPSG-Code "EPSG:..." oder WKT-Definition).
-     * If not present the {@link #DEFAULT_CRS} is used.
-     * @param input ASCII file or URL to the input file
-	 * @param crs   CRS forced to use (can be <code>null</code>)
+	/**
+	 * Import a raster from file or URL in ArcInfoASCII format. The CRS is taken
+	 * from prj-file (EPSG-Code "EPSG:..." oder WKT-Definition). If not present
+	 * the {@link #DEFAULT_CRS} is used.
+	 * 
+	 * @param input
+	 *            ASCII file or URL to the input file
+	 * @param crs
+	 *            CRS forced to use (can be <code>null</code>)
 	 */
-	public static WritableGridRaster readGridRasterFromArcInfoASCII(Object input, CoordinateReferenceSystem crs) throws Exception {
-      switch( getAsciiRasterImportMode() ) {
-        case USE_ARCGRIDREADER: return readGridRasterFromArcInfoASCII_ArcGridReader(input, crs); 
-        case USE_ARCGRIDRASTER: return readGridRasterFromArcInfoASCII_ArcGridRaster(input, crs); 
-      }
-      throw new UnsupportedOperationException("ASCII raster import mode not supported: "+getAsciiRasterImportMode());
+	public static WritableGridRaster readGridRasterFromArcInfoASCII(
+			Object input, CoordinateReferenceSystem crs) throws Exception {
+		switch (getAsciiRasterImportMode()) {
+		case USE_ARCGRIDREADER:
+			return readGridRasterFromArcInfoASCII_ArcGridReader(input, crs);
+		case USE_ARCGRIDRASTER:
+			return readGridRasterFromArcInfoASCII_ArcGridRaster(input, crs);
+		}
+		throw new UnsupportedOperationException(
+				"ASCII raster import mode not supported: "
+						+ getAsciiRasterImportMode());
 	}
 
-    /**
-     * Uses the <b>{@link ArcGridReader} class</b> (standard GT) to
-     * import a raster from file or URL in ArcInfoASCII format.
-     * The CRS is taken from prj-file (EPSG-Code "EPSG:..." oder WKT-Definition).
-     * If not present the {@link #DEFAULT_CRS} is used.
-     * @param input file or URL to the input file
-     * @param crs   CRS forced to use (can be <code>null</code>)
-     */
-    private static WritableGridRaster readGridRasterFromArcInfoASCII_ArcGridReader(Object input, CoordinateReferenceSystem crs) throws Exception {
-        GridCoverage2D grid = readGridFromArcInfoASCII(input, crs);
-        WritableRaster raster = grid.getRenderedImage().copyData(null);
-        return new WritableGridRaster(raster,grid.getEnvelope2D()) ;
-    }
-	
-    /**
-     * Uses the <b>{@link ArcGridRaster} class</b> (standard GT) to
-     * import a raster from file or URL in ArcInfoASCII format.
-     * The CRS is taken from prj-file (EPSG-Code "EPSG:..." oder WKT-Definition).
-     * If not present the {@link #DEFAULT_CRS} is used.
-     * @param input file or URL to the input file
-     * @param crs   CRS forced to use (can be <code>null</code>)
-     */
-    private static WritableGridRaster readGridRasterFromArcInfoASCII_ArcGridRaster(Object input, CoordinateReferenceSystem crs) throws Exception {
-      // Import raster data
-      ArcGridRaster reader = null;
-      if (input instanceof File)
-        reader = new ArcGridRaster( new BufferedReader( new InputStreamReader( new FileInputStream((File)input) ) ), false );
-      else if (input instanceof URL)
-        reader = new ArcGridRaster( (URL)input );
-      else
-        throw new UnsupportedOperationException("Import source not supported: "+LangUtil.getSimpleClassName(input));
-      WritableRaster raster = reader.readRaster();
-      
-      // Import CRS
-      if (crs == null) {
-        if (input instanceof File)
-          crs = determineProjection((File)input);
-        else if (input instanceof URL)
-          crs = determineProjection((URL)input);
-      }
-      
-//      LOGGER.debug("Position  "+reader.getXlCorner()+" / "+reader.getYlCorner());
-//      LOGGER.debug("Size      "+reader.getNCols()+" / "+reader.getNRows());
-//      LOGGER.debug("Min/Max   "+reader.getMinValue()+" / "+reader.getMaxValue());
-//      LOGGER.debug("NoData    "+reader.getNoData());
-//      LOGGER.debug("CellSize  "+reader.getCellSize());
-      
-      float x = (float) reader.getXlCorner(); // SW corner!
-      float y = (float) reader.getYlCorner(); // SW corner!
-      // real width = colums * cell size
-      float w = (float) (reader.getNCols() * reader.getCellSize());
-      // real hight = rows * cell size
-      float h = (float) (reader.getNRows() * reader.getCellSize());
-      Rectangle2D envelope = new Rectangle2D.Float(x, y, w, h);
+	/**
+	 * Uses the <b>{@link ArcGridReader} class</b> (standard GT) to import a
+	 * raster from file or URL in ArcInfoASCII format. The CRS is taken from
+	 * prj-file (EPSG-Code "EPSG:..." oder WKT-Definition). If not present the
+	 * {@link #DEFAULT_CRS} is used.
+	 * 
+	 * @param input
+	 *            file or URL to the input file
+	 * @param crs
+	 *            CRS forced to use (can be <code>null</code>)
+	 */
+	private static WritableGridRaster readGridRasterFromArcInfoASCII_ArcGridReader(
+			Object input, CoordinateReferenceSystem crs) throws Exception {
+		GridCoverage2D grid = readGridFromArcInfoASCII(input, crs);
+		WritableRaster raster = grid.getRenderedImage().copyData(null);
+		return new WritableGridRaster(raster, grid.getEnvelope2D());
+	}
 
-      return new WritableGridRaster(raster, envelope, crs);
-   }
-    	
 	/**
+	 * Uses the <b>{@link ArcGridRaster} class</b> (standard GT) to import a
+	 * raster from file or URL in ArcInfoASCII format. The CRS is taken from
+	 * prj-file (EPSG-Code "EPSG:..." oder WKT-Definition). If not present the
+	 * {@link #DEFAULT_CRS} is used.
+	 * 
+	 * @param input
+	 *            file or URL to the input file
+	 * @param crs
+	 *            CRS forced to use (can be <code>null</code>)
+	 */
+	private static WritableGridRaster readGridRasterFromArcInfoASCII_ArcGridRaster(
+			Object input, CoordinateReferenceSystem crs) throws Exception {
+		// Import raster data
+		ArcGridRaster reader = null;
+		if (input instanceof File)
+			reader = new ArcGridRaster(new BufferedReader(
+					new InputStreamReader(new FileInputStream((File) input))),
+					false);
+		else if (input instanceof URL)
+			reader = new ArcGridRaster((URL) input);
+		else
+			throw new UnsupportedOperationException(
+					"Import source not supported: "
+							+ LangUtil.getSimpleClassName(input));
+		WritableRaster raster = reader.readRaster();
+
+		// Import CRS
+		if (crs == null) {
+			if (input instanceof File)
+				crs = determineProjection((File) input);
+			else if (input instanceof URL)
+				crs = determineProjection((URL) input);
+		}
+
+		// LOGGER.debug("Position  "+reader.getXlCorner()+" / "+reader.getYlCorner());
+		// LOGGER.debug("Size      "+reader.getNCols()+" / "+reader.getNRows());
+		// LOGGER.debug("Min/Max   "+reader.getMinValue()+" / "+reader.getMaxValue());
+		// LOGGER.debug("NoData    "+reader.getNoData());
+		// LOGGER.debug("CellSize  "+reader.getCellSize());
+
+		float x = (float) reader.getXlCorner(); // SW corner!
+		float y = (float) reader.getYlCorner(); // SW corner!
+		// real width = colums * cell size
+		float w = (float) (reader.getNCols() * reader.getCellSize());
+		// real hight = rows * cell size
+		float h = (float) (reader.getNRows() * reader.getCellSize());
+		Rectangle2D envelope = new Rectangle2D.Float(x, y, w, h);
+
+		return new WritableGridRaster(raster, envelope, crs);
+	}
+
+	/**
 	 * Diese Methode importiert ein Raster aus einer Datei im GeoTIFF-Format.
 	 * Zunaechst wird versucht, die Geo-Informationen (Referenz+CRS) aus den
 	 * TIFF-Metadaten zu ermitteln. Ist dies nicht erfolgreich, werden ein
@@ -770,7 +852,8 @@
 	 * @throws java.lang.Exception
 	 *             bei irgendeinem Fehler
 	 */
-	public static WritableGridRaster readGridRasterFromGeoTiff(File file) throws Exception {
+	public static WritableGridRaster readGridRasterFromGeoTiff(File file)
+			throws Exception {
 		return readGridRasterFromGeoTiff(file, null);
 	}
 
@@ -783,12 +866,16 @@
 	 * WKT-Definition erlaubt. Kann kein CRS ermitteln werden, wird
 	 * {@link #DEFAULT_CRS} als CRS verwendet.
 	 * 
-	 * @param file GeoTIFF-File
-	 * @param crs  erzwungenes CoordinateReferenceSystem fuer das Raster (kann
+	 * @param file
+	 *            GeoTIFF-File
+	 * @param crs
+	 *            erzwungenes CoordinateReferenceSystem fuer das Raster (kann
 	 *            {@code null} sein)
-	 * @throws java.lang.Exception bei irgendeinem Fehler
+	 * @throws java.lang.Exception
+	 *             bei irgendeinem Fehler
 	 */
-	public static WritableGridRaster readGridRasterFromGeoTiff(File file, CoordinateReferenceSystem crs) throws Exception {
+	public static WritableGridRaster readGridRasterFromGeoTiff(File file,
+			CoordinateReferenceSystem crs) throws Exception {
 		// // GeoTiff-File einlesen
 		// BufferedImage im = ImageIO.read( file );
 		// if ( im == null )
@@ -820,24 +907,20 @@
 		// );
 		//
 
-		GridCoverage2D gc  = readGridFromGeoTiff(file, crs);
-		Rectangle2D    env = gc.getEnvelope2D();
-		RenderedImage  im  = gc.getRenderedImage();
-		WritableGridRaster raster = new WritableGridRaster(
-		    im.getData().getDataBuffer().getDataType(),
-		    0, 0,
-		    im.getWidth(), im.getHeight(),
-		    env, 
-		    crs
-		);
+		GridCoverage2D gc = readGridFromGeoTiff(file, crs);
+		Rectangle2D env = gc.getEnvelope2D();
+		RenderedImage im = gc.getRenderedImage();
+		WritableGridRaster raster = new WritableGridRaster(im.getData()
+				.getDataBuffer().getDataType(), 0, 0, im.getWidth(), im
+				.getHeight(), env, crs);
 		im.copyData(raster);
 
 		return raster;
 	}
 
-    ///////////////////////////////////////////////////////////////////////////
-    //              META DATA IMPORT (WORLD FILE)
-    ///////////////////////////////////////////////////////////////////////////
+	// /////////////////////////////////////////////////////////////////////////
+	// META DATA IMPORT (WORLD FILE)
+	// /////////////////////////////////////////////////////////////////////////
 	/**
 	 * Liest ein World-File (.tfw) ein und liefert die darin zeilenweise
 	 * gespeicherten Werte zurueck. Leer- und Kommentarzeilen werden dabei
@@ -939,9 +1022,9 @@
 		return ret;
 	}
 
-    ///////////////////////////////////////////////////////////////////////////
-    //              META DATA IMPORT (PROJECTION)
-    ///////////////////////////////////////////////////////////////////////////
+	// /////////////////////////////////////////////////////////////////////////
+	// META DATA IMPORT (PROJECTION)
+	// /////////////////////////////////////////////////////////////////////////
 
 	/**
 	 * Liest das CRS aus einer Datei. Zunaechst wird versucht das CRS aus der
@@ -952,8 +1035,9 @@
 	 *            Datei
 	 * @return {@code null}, wenn kein CRS gelesen werden konnte
 	 */
-	public static CoordinateReferenceSystem determineProjection(File file) throws IOException {
-	  return determineProjection(DataUtilities.fileToURL(file));
+	public static CoordinateReferenceSystem determineProjection(File file)
+			throws IOException {
+		return determineProjection(DataUtilities.fileToURL(file));
 	}
 
 	/**
@@ -967,24 +1051,26 @@
 	public static CoordinateReferenceSystem determineProjection(URL prjUrl) {
 		CoordinateReferenceSystem crs = null;
 		// Versuchen CRS aus angegebener Datei zu lesen
-		LOGGER.debug("determineProjection: Try to read a projection from URL " + prjUrl);
+		LOGGER.debug("determineProjection: Try to read a projection from URL "
+				+ prjUrl);
 		try {
 			crs = GeoImportUtil.readProjectionFile(prjUrl);
 		} catch (IOException e) {
 		}
 
 		if (crs == null) {
-		  try {
-		    crs = GeoImportUtil.readProjectionFile(IOUtil.changeUrlExt(prjUrl, "prj"));
-		  } catch (IllegalArgumentException e) {
-		  } catch (IOException e) {
-		  }
+			try {
+				crs = GeoImportUtil.readProjectionFile(IOUtil.changeUrlExt(
+						prjUrl, "prj"));
+			} catch (IllegalArgumentException e) {
+			} catch (IOException e) {
+			}
 		}
 
 		// Wenn nicht erfolgreich, Default verwenden
 		if (crs == null) {
-		  LOGGER.warn("No projection found in URL. Default CRS used.");
-		  crs = getDefaultCRS();
+			LOGGER.warn("No projection found in URL. Default CRS used.");
+			crs = getDefaultCRS();
 		}
 		return crs;
 	}
@@ -1005,10 +1091,11 @@
 	 * @throws IOException
 	 *             falls die URL nicht wie erwartet gelesen werden konnte.
 	 */
-	public static CoordinateReferenceSystem readProjectionFile(URL prjURL) throws IOException {
-	  String crsDefinition = readProjectionString(prjURL);
-	  CoordinateReferenceSystem crs = GTUtil.createCRS(crsDefinition);
-	  return crs;
+	public static CoordinateReferenceSystem readProjectionFile(URL prjURL)
+			throws IOException {
+		String crsDefinition = readProjectionString(prjURL);
+		CoordinateReferenceSystem crs = GTUtil.createCRS(crsDefinition);
+		return crs;
 	}
 
 	/**
@@ -1023,7 +1110,8 @@
 	 * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a>
 	 *         (University of Bonn/Germany)
 	 */
-	public static CoordinateReferenceSystem readProjectionFile(File prjFile) throws IOException {
+	public static CoordinateReferenceSystem readProjectionFile(File prjFile)
+			throws IOException {
 		String crsDefinition = readProjectionString(prjFile);
 		CoordinateReferenceSystem crs = GTUtil.createCRS(crsDefinition);
 		// if ( crs == null )
@@ -1084,29 +1172,37 @@
 	 */
 	public static String readProjectionString(URL url) throws IOException {
 		if (url == null) {
-			LOGGER.debug("readProjectionString returned empty String for url==null");
+			LOGGER
+					.debug("readProjectionString returned empty String for url==null");
 			return "";
 		}
 
-		BufferedReader input = new BufferedReader(new InputStreamReader(url.openStream()));
+		final InputStream openStream = url.openStream();
 		try {
-			// Alle Zeilen der Datei aneinander haengen
-			StringBuffer buffer = new StringBuffer();
-			String line = null;
-			while (input.ready() && (line = input.readLine()) != null) {
-				if (!IOUtil.isCommentLine(line))
-					buffer.append(" ").append(line);
-				if (buffer.length() > 3000) {
-					// LOGGER.warn("The URL " + url +
-					// " doesn't seem point to a .prj file, because size is > 3000 characters. Returning \"\"");
-					return "";
+
+			BufferedReader input = new BufferedReader(new InputStreamReader(
+					openStream));
+			try {
+				// Alle Zeilen der Datei aneinander haengen
+				StringBuffer buffer = new StringBuffer();
+				String line = null;
+				while (input.ready() && (line = input.readLine()) != null) {
+					if (!IOUtil.isCommentLine(line))
+						buffer.append(" ").append(line);
+					if (buffer.length() > 3000) {
+						// LOGGER.warn("The URL " + url +
+						// " doesn't seem point to a .prj file, because size is > 3000 characters. Returning \"\"");
+						return "";
+					}
 				}
+				final String prjString = buffer.toString().trim();
+				// LOGGER.debug("This is the PRJ String from URL = \n"+prjString);
+				return prjString;
+			} finally {
+				input.close();
 			}
-			final String prjString = buffer.toString().trim();
-			// LOGGER.debug("This is the PRJ String from URL = \n"+prjString);
-			return prjString;
 		} finally {
-			input.close();
+			openStream.close();
 		}
 	}
 }

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/FeatureSelectedEvent.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/FeatureSelectedEvent.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/FeatureSelectedEvent.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -29,15 +29,17 @@
  ******************************************************************************/
 package schmitzm.geotools.map.event;
 
+import gtmig.org.geotools.swing.XMapPane;
+
 import org.geotools.feature.FeatureCollection;
 import org.geotools.map.MapLayer;
 
-import schmitzm.geotools.gui.JMapPane;
+import schmitzm.geotools.gui.SelectableXMapPane;
 
 import com.vividsolutions.jts.geom.Envelope;
 
 /**
- * Diese Klasse stellt ein Ereignis dar, das ein {@link JMapPane} ausloest,
+ * Diese Klasse stellt ein Ereignis dar, das ein {@link XMapPane} ausloest,
  * wenn der Anwender Features in der Karte ausgewaehlt hat.
  * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
  * @version 1.0
@@ -52,7 +54,7 @@
    * @param sourceObject   Objekt, das die Selektion initiiert hat (wenn {@code null},
    *                       wird das MapPane als Ausloeser gesetzt)
    */
-  public FeatureSelectedEvent(JMapPane sourceMap, MapLayer sourceLayer, Envelope envelope, FeatureCollection result, Object sourceObject) {
+  public FeatureSelectedEvent(SelectableXMapPane sourceMap, MapLayer sourceLayer, Envelope envelope, FeatureCollection result, Object sourceObject) {
     super(sourceMap, sourceLayer, envelope, result, sourceObject);
   }
 
@@ -63,7 +65,7 @@
    * @param envelope       Bereich der selektiert wurde
    * @param result         selektierte Features
    */
-  public FeatureSelectedEvent(JMapPane sourceMap, MapLayer sourceLayer, Envelope envelope, FeatureCollection result) {
+  public FeatureSelectedEvent(SelectableXMapPane sourceMap, MapLayer sourceLayer, Envelope envelope, FeatureCollection result) {
     this(sourceMap, sourceLayer, envelope, result,null);
   }
 

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/GeneralSelectionEvent.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/GeneralSelectionEvent.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/GeneralSelectionEvent.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -29,18 +29,19 @@
  ******************************************************************************/
 package schmitzm.geotools.map.event;
 
-import schmitzm.geotools.gui.JMapPane;
+import gtmig.org.geotools.swing.XMapPane;
+import schmitzm.geotools.gui.SelectableXMapPane;
 
 import com.vividsolutions.jts.geom.Envelope;
 
 /**
- * Diese Klasse stellt ein Ereignis dar, das ein {@link JMapPane} ausloest,
+ * Diese Klasse stellt ein Ereignis dar, das ein {@link SelectableXMapPane} ausloest,
  * wenn der Anwender (irgendeinen) einen Bereich in der Karte ausgewaehlt hat,
  * auch wenn dort keine Objekte selektiert wurden.
  * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
  * @version 1.0
  */
-public class GeneralSelectionEvent extends JMapPaneEvent {
+public class GeneralSelectionEvent extends MapPaneEvent {
   /** Bereich der selektiert wurde. */
   protected Envelope envelope    = null;
 
@@ -51,7 +52,7 @@
    * @param sourceObject Objekt, das die Selektion initiiert hat (wenn {@code null},
    *                     wird das MapPane als Ausloeser gesetzt)
    */
-  public GeneralSelectionEvent(JMapPane source, Envelope envelope, Object sourceObject) {
+  public GeneralSelectionEvent(SelectableXMapPane source, Envelope envelope, Object sourceObject) {
     super(source, sourceObject);
     this.envelope = envelope;
   }
@@ -61,7 +62,7 @@
    * @param sourceMap Karte in der die Selektion vorgenommen wurde
    * @param envelope  Bereich der selektiert wurde
    */
-  public GeneralSelectionEvent(JMapPane sourceMap, Envelope envelope) {
+  public GeneralSelectionEvent(SelectableXMapPane sourceMap, Envelope envelope) {
     this(sourceMap,envelope,null);
   }
 

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/GridCoverageSelectedEvent.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/GridCoverageSelectedEvent.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/GridCoverageSelectedEvent.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -29,15 +29,17 @@
  ******************************************************************************/
 package schmitzm.geotools.map.event;
 
+import gtmig.org.geotools.swing.XMapPane;
+
 import org.geotools.coverage.grid.GridCoverage2D;
 import org.geotools.map.MapLayer;
 
-import schmitzm.geotools.gui.JMapPane;
+import schmitzm.geotools.gui.SelectableXMapPane;
 
 import com.vividsolutions.jts.geom.Envelope;
 
 /**
- * Diese Klasse stellt ein Ereignis dar, das ein {@link JMapPane} ausloest,
+ * Diese Klasse stellt ein Ereignis dar, das ein {@link XMapPane} ausloest,
  * wenn der Anwender ein Raster in der Karte ausgewaehlt hat.
  * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
  * @version 1.0
@@ -53,7 +55,7 @@
    * @param sourceObject   Objekt, das die Selektion initiiert hat (wenn {@code null},
    *                       wird das MapPane als Ausloeser gesetzt)
    */
-  public GridCoverageSelectedEvent(JMapPane sourceMap, MapLayer sourceLayer, Envelope envelope, GridCoverage2D result, Object sourceObject) {
+  public GridCoverageSelectedEvent(SelectableXMapPane sourceMap, MapLayer sourceLayer, Envelope envelope, GridCoverage2D result, Object sourceObject) {
     super(sourceMap,sourceLayer,envelope,result,sourceObject);
   }
 
@@ -64,7 +66,7 @@
    * @param envelope       Bereich der selektiert wurde
    * @param result         selektierters Teil-Raster
    */
-  public GridCoverageSelectedEvent(JMapPane sourceMap, MapLayer sourceLayer, Envelope envelope, GridCoverage2D result) {
+  public GridCoverageSelectedEvent(SelectableXMapPane sourceMap, MapLayer sourceLayer, Envelope envelope, GridCoverage2D result) {
     this(sourceMap,sourceLayer,envelope,result,null);
   }
 

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/GridCoverageValueSelectedEvent.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/GridCoverageValueSelectedEvent.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/GridCoverageValueSelectedEvent.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -33,12 +33,12 @@
 
 import org.geotools.map.MapLayer;
 
-import schmitzm.geotools.gui.JMapPane;
+import schmitzm.geotools.gui.SelectableXMapPane;
 
 import com.vividsolutions.jts.geom.Envelope;
 
 /**
- * Diese Klasse stellt ein Ereignis dar, das ein {@link JMapPane} ausloest,
+ * Diese Klasse stellt ein Ereignis dar, das ein {@link SelectableXMapPane} ausloest,
  * wenn der Anwender den Wert eines Rasters in der Karte ausgewaehlt hat.
  *
  * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
@@ -68,7 +68,7 @@
    * @param sourceObject   Objekt, das die Selektion initiiert hat (wenn {@code null},
    *                       wird das MapPane als Ausloeser gesetzt)
    */
-  public GridCoverageValueSelectedEvent(JMapPane sourceMap, MapLayer sourceLayer, Point2D point, double[] result, Object sourceObject) {
+  public GridCoverageValueSelectedEvent(SelectableXMapPane sourceMap, MapLayer sourceLayer, Point2D point, double[] result, Object sourceObject) {
     super(sourceMap,sourceLayer,new Envelope(point.getX(),point.getX(),point.getY(),point.getY()),result, sourceObject);
     this.point = point;
   }
@@ -80,7 +80,7 @@
    * @param point          Punkt der selektiert wurde
    * @param result         selektierters Teil-Raster
    */
-  public GridCoverageValueSelectedEvent(JMapPane sourceMap, MapLayer sourceLayer, Point2D point, double[] result) {
+  public GridCoverageValueSelectedEvent(SelectableXMapPane sourceMap, MapLayer sourceLayer, Point2D point, double[] result) {
     this(sourceMap,sourceLayer,point,result,null);
   }
 

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/JEditorPaneEvent.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/JEditorPaneEvent.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/JEditorPaneEvent.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -40,7 +40,7 @@
  * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
  * @version 1.0
  */
-public abstract class JEditorPaneEvent extends JMapPaneEvent {
+public abstract class JEditorPaneEvent extends MapPaneEvent {
   /** Das bearbeitete Layer. */
   protected MapLayer layer = null;
   /** Bearbeitungs-Modus (zum Zeitpunkt des Events) */

Deleted: branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/JMapPaneEvent.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/JMapPaneEvent.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/JMapPaneEvent.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -1,78 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009 Martin O. J. Schmitz.
- * 
- * This file is part of the SCHMITZM library - a collection of utility 
- * classes based on Java 1.6, focusing (not only) on Java Swing 
- * and the Geotools library.
- * 
- * The SCHMITZM project is hosted at:
- * http://wald.intevation.org/projects/schmitzm/
- * 
- * 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:
- *     Martin O. J. Schmitz - initial API and implementation
- *     Stefan A. Krüger - additional utility classes
- ******************************************************************************/
-package schmitzm.geotools.map.event;
-
-import schmitzm.geotools.gui.JMapPane;
-
-/**
- * Diese Klasse stellt ein Ereignis dar, das von einem {@link JMapPane}
- * ausgeloest wurde (z.B. Aenderung der Aufloesung).
- * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
- * @version 1.0
- */
-public abstract class JMapPaneEvent {
-  /** Beinhaltet das {@link JMapPane}, das das Ereignis ausgeloest hat */
-  protected JMapPane source = null;
-  /** Beinhaltet ein Objekt, das das Ereignis initiiert hat */
-  protected Object sourceObject = null;
-
-  /**
-   * Erzeugt ein neues Ereignis.
-   * @param source {@link JMapPane}, das das Ereignis ausgeloest hat
-   * @param sourceObject Objeckt, das das Ereignis initiiert hat (wenn {@code null},
-   *        wird das MapPane als Ausloeser gesetzt)
-   */
-  public JMapPaneEvent(JMapPane source, Object sourceObject) {
-    this.source       = source;
-    this.sourceObject = (sourceObject != null) ? sourceObject : source;
-  }
-
-  /**
-   * Erzeugt ein neues Ereignis.
-   * @param source {@link JMapPane}, das das Ereignis ausgeloest hat
-   */
-  public JMapPaneEvent(JMapPane source) {
-    this(source,null);
-  }
-
-  /**
-   * Liefert das {@link JMapPane}, das das Ereignis ausgeloest hat.
-   */
-  public JMapPane getSource() {
-    return source;
-  }
-
-  /**
-   * Liefert das Object, das das Ereignis initiiert hat.
-   */
-  public Object getSourceObject() {
-    return sourceObject;
-  }
-}

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/JMapPaneListener.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/JMapPaneListener.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/JMapPaneListener.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -30,12 +30,12 @@
 package schmitzm.geotools.map.event;
 
 // fuer Doku
-import schmitzm.geotools.gui.JMapPane;
+import schmitzm.geotools.gui.SelectableXMapPane;
 
 /**
- * Diese Klasse stellt einen Listener fuer Ereignisse des {@link JMapPane}
+ * Diese Klasse stellt einen Listener fuer Ereignisse des {@link SelectableXMapPane}
  * dar (z.B. Aenderung der Aufloesung).
- * @see JMapPaneEvent
+ * @see MapPaneEvent
  * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
  * @version 1.0
  */
@@ -44,5 +44,5 @@
    * Verarbeitet ein JMapPane-Ereignis.
    * @param e Ereignis
    */
-  public void performMapPaneEvent(JMapPaneEvent e);
+  public void performMapPaneEvent(MapPaneEvent e);
 }

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/MapAreaChangedEvent.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/MapAreaChangedEvent.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/MapAreaChangedEvent.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -29,17 +29,17 @@
  ******************************************************************************/
 package schmitzm.geotools.map.event;
 
-import schmitzm.geotools.gui.JMapPane;
+import schmitzm.geotools.gui.SelectableXMapPane;
 
 import com.vividsolutions.jts.geom.Envelope;
 
 /**
- * Diese Klasse stellt ein Ereignis dar, das ein {@link JMapPane} ausloest,
+ * Diese Klasse stellt ein Ereignis dar, das ein {@link SelectableXMapPane} ausloest,
  * wenn sich die Ausdehnung der dargestellte Karten-Ausschnitt aendert.
  * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
  * @version 1.0
  */
-public class MapAreaChangedEvent extends JMapPaneEvent {
+public class MapAreaChangedEvent extends MapPaneEvent {
   private Envelope oldEnvelope = null;
   private Envelope newEnvelope = null;
 
@@ -48,7 +48,7 @@
    * @param oldEnvelope vormalige Ausdehnung
    * @param newEnvelope neue Ausdehnung
    */
-  public MapAreaChangedEvent(JMapPane source, Envelope oldEnvelope, Envelope newEnvelope) {
+  public MapAreaChangedEvent(SelectableXMapPane source, Envelope oldEnvelope, Envelope newEnvelope) {
     super(source);
     this.oldEnvelope = oldEnvelope;
     this.newEnvelope = newEnvelope;

Copied: branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/MapPaneEvent.java (from rev 505, branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/JMapPaneEvent.java)
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/JMapPaneEvent.java	2009-10-31 10:53:43 UTC (rev 505)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/MapPaneEvent.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2009 Martin O. J. Schmitz.
+ * 
+ * This file is part of the SCHMITZM library - a collection of utility 
+ * classes based on Java 1.6, focusing (not only) on Java Swing 
+ * and the Geotools library.
+ * 
+ * The SCHMITZM project is hosted at:
+ * http://wald.intevation.org/projects/schmitzm/
+ * 
+ * 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:
+ *     Martin O. J. Schmitz - initial API and implementation
+ *     Stefan A. Krüger - additional utility classes
+ ******************************************************************************/
+package schmitzm.geotools.map.event;
+
+import gtmig.org.geotools.swing.XMapPane;
+import schmitzm.geotools.gui.SelectableXMapPane;
+
+/**
+ * Diese Klasse stellt ein Ereignis dar, das von einem {@link SelectableXMapPane}
+ * ausgeloest wurde (z.B. Aenderung der Aufloesung).
+ * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
+ * @version 1.0
+ */
+public abstract class MapPaneEvent {
+  /** Beinhaltet das {@link XMapPane}, das das Ereignis ausgeloest hat */
+  protected SelectableXMapPane source = null;
+  /** Beinhaltet ein Objekt, das das Ereignis initiiert hat */
+  protected Object sourceObject = null;
+
+  /**
+   * Erzeugt ein neues Ereignis.
+   * @param source {@link XMapPane}, das das Ereignis ausgeloest hat
+   * @param sourceObject Objeckt, das das Ereignis initiiert hat (wenn {@code null},
+   *        wird das MapPane als Ausloeser gesetzt)
+   */
+  public MapPaneEvent(SelectableXMapPane source, Object sourceObject) {
+    this.source       = source;
+    this.sourceObject = (sourceObject != null) ? sourceObject : source;
+  }
+
+  /**
+   * Erzeugt ein neues Ereignis.
+   * @param source {@link XMapPane}, das das Ereignis ausgeloest hat
+   */
+  public MapPaneEvent(SelectableXMapPane source) {
+    this(source,null);
+  }
+
+  /**
+   * Liefert das {@link SelectableXMapPane}, das das Ereignis ausgeloest hat.
+   */
+  public SelectableXMapPane getSource() {
+    return source;
+  }
+
+  /**
+   * Liefert das Object, das das Ereignis initiiert hat.
+   */
+  public Object getSourceObject() {
+    return sourceObject;
+  }
+}

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/ObjectSelectionEvent.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/ObjectSelectionEvent.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/ObjectSelectionEvent.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -29,15 +29,17 @@
  ******************************************************************************/
 package schmitzm.geotools.map.event;
 
+import gtmig.org.geotools.swing.XMapPane;
+
 import org.geotools.map.MapLayer;
 
-import schmitzm.geotools.gui.JMapPane;
+import schmitzm.geotools.gui.SelectableXMapPane;
 
 import com.vividsolutions.jts.geom.Envelope;
 
 /**
  * Diese Klasse stellt eine Oberklasse fuer die Ereignisse dar, die ein
- * {@link JMapPane} ausloest, wenn der Anwender einen Bereich in der Karte ausgewaehlt hat
+ * {@link XMapPane} ausloest, wenn der Anwender einen Bereich in der Karte ausgewaehlt hat
  * und dabei Objekte selektiert wurde.
  * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
  * @version 1.0
@@ -55,7 +57,7 @@
    * @param sourceObject   Objekt, das die Selektion initiiert hat (wenn {@code null},
    *                       wird das MapPane als Ausloeser gesetzt)
    */
-  public ObjectSelectionEvent(JMapPane sourceMap, MapLayer sourceLayer, Envelope envelope, E result, Object sourceObject) {
+  public ObjectSelectionEvent(SelectableXMapPane sourceMap, MapLayer sourceLayer, Envelope envelope, E result, Object sourceObject) {
     super(sourceMap,envelope,sourceObject);
     this.sourceLayer = sourceLayer;
     this.result      = result;
@@ -68,7 +70,7 @@
    * @param envelope       Bereich der selektiert wurde
    * @param result         selektierte Objekte
    */
-  public ObjectSelectionEvent(JMapPane sourceMap, MapLayer sourceLayer, Envelope envelope, E result) {
+  public ObjectSelectionEvent(SelectableXMapPane sourceMap, MapLayer sourceLayer, Envelope envelope, E result) {
     this(sourceMap,sourceLayer,envelope, result, null);
   }
   /**

Modified: branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/ScaleChangedEvent.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/ScaleChangedEvent.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/map/event/ScaleChangedEvent.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -29,15 +29,15 @@
  ******************************************************************************/
 package schmitzm.geotools.map.event;
 
-import schmitzm.geotools.gui.JMapPane;
+import schmitzm.geotools.gui.SelectableXMapPane;
 
 /**
- * Diese Klasse stellt ein Ereignis dar, das ein {@link JMapPane} ausloest,
+ * Diese Klasse stellt ein Ereignis dar, das ein {@link SelectableXMapPane} ausloest,
  * wenn sich die Skalierung/Aufloesung der Karte aendert.
  * @author <a href="mailto:martin.schmitz at koeln.de">Martin Schmitz</a> (University of Bonn/Germany)
  * @version 1.0
  */
-public class ScaleChangedEvent extends JMapPaneEvent {
+public class ScaleChangedEvent extends MapPaneEvent {
   private double oldScale = 0;
   private double newScale = 0;
 
@@ -46,7 +46,7 @@
    * @param oldScale vormalige Aufloesung
    * @param newScale neue Aufloesung
    */
-  public ScaleChangedEvent(JMapPane source, double oldScale, double newScale) {
+  public ScaleChangedEvent(SelectableXMapPane source, double oldScale, double newScale) {
     super(source);
     this.oldScale = oldScale;
     this.newScale = newScale;

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-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/geotools/styling/StylingUtil.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -29,6 +29,8 @@
  ******************************************************************************/
 package schmitzm.geotools.styling;
 
+import gtmig.org.geotools.swing.XMapPane;
+
 import java.awt.Color;
 import java.io.ByteArrayInputStream;
 import java.io.File;
@@ -61,11 +63,13 @@
 import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
 import org.geotools.data.FeatureSource;
 import org.geotools.data.memory.MemoryFeatureCollection;
+import org.geotools.data.store.EmptyFeatureCollection;
 import org.geotools.factory.CommonFactoryFinder;
 import org.geotools.factory.GeoTools;
 import org.geotools.feature.FeatureCollection;
 import org.geotools.feature.GeometryAttributeType;
 import org.geotools.filter.ConstantExpression;
+import org.geotools.geometry.jts.ReferencedEnvelope;
 import org.geotools.renderer.lite.RendererUtilities;
 import org.geotools.resources.i18n.Vocabulary;
 import org.geotools.resources.i18n.VocabularyKeys;
@@ -149,12 +153,12 @@
 	/** Standard-Instanz eines {@link SLDTransformer}. */
 	public final static SLDTransformer SLDTRANSFORMER = new SLDTransformer();
 
-//	/**
-//	 * Standard-Instanz eines {@link StyleBuilder}.
-//	 * 
-//	 * @deprecated wurde ersetzt durch {@link #STYLE_BUILDER}
-//	 */
-//	public static final StyleBuilder builder = STYLE_BUILDER;
+	// /**
+	// * Standard-Instanz eines {@link StyleBuilder}.
+	// *
+	// * @deprecated wurde ersetzt durch {@link #STYLE_BUILDER}
+	// */
+	// public static final StyleBuilder builder = STYLE_BUILDER;
 
 	/** Standard-Instanz einer {@link StyleFactory} */
 	public static final StyleFactory STYLE_FACTORY = CommonFactoryFinder
@@ -1158,6 +1162,10 @@
 	 * 
 	 *         TODO Was ist mit raster?!
 	 * 
+	 *         TODO Das sollte man besser machen: Zuerst die FIlter der
+	 *         sichtbaren regeln raussuchen, und dann direkt am anfang damitmit
+	 *         mitfiltern...
+	 * 
 	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
 	 *         Kr&uuml;ger</a>
 	 */
@@ -1579,8 +1587,7 @@
 	 * @param colors
 	 *            colors for the palette
 	 */
-	public static BrewerPalette createBrewerPalette(String name, Color[] colors)
-			 {
+	public static BrewerPalette createBrewerPalette(String name, Color[] colors) {
 		BrewerPalette palette = new BrewerPalette();
 		palette.setColors(colors);
 		palette.setName(name);
@@ -1589,14 +1596,17 @@
 		// set suitability to UNKNOWN for all viewers
 		PaletteSuitability suitability = new PaletteSuitability();
 		try {
-			suitability.setSuitability(colors.length, new String[] { "?", "?", "?",
-					"?", "?", "?" });
+			suitability.setSuitability(colors.length, new String[] { "?", "?",
+					"?", "?", "?", "?" });
 			palette.setPaletteSuitability(suitability);
 		} catch (IOException e) {
-			LOGGER.error("Unabel to PaletteSuitability.setSuitablility for colors.length="+colors,e);
+			LOGGER.error(
+					"Unabel to PaletteSuitability.setSuitablility for colors.length="
+							+ colors, e);
 		}
 
-		// Create the trivial scheme for the palette (requested colors equals number of colors)
+		// Create the trivial scheme for the palette (requested colors equals
+		// number of colors)
 		int[] schema = new int[colors.length];
 		for (int j = 0; j < colors.length; j++)
 			schema[j] = j;
@@ -1605,12 +1615,10 @@
 		// set the trivial scheme for all schemas
 		for (int j = 2; j < schema.length; j++) {
 			sampleScheme.setSampleScheme(j, schema);
-//			sampleScheme.setSampleScheme(schema.length, schema);
+			// sampleScheme.setSampleScheme(schema.length, schema);
 		}
-		
-		
+
 		palette.setColorScheme(sampleScheme);
-		
 
 		return palette;
 	}
@@ -1656,7 +1664,7 @@
 		Symbolizer[] symbolizers = new Symbolizer[0];
 
 		switch (geometryForm) {
- 
+
 		case POINT:
 			PointSymbolizer ps = STYLE_FACTORY.createPointSymbolizer();
 			ps.setGraphic(SELECTION_GRAPHIC1);
@@ -2270,4 +2278,39 @@
 		return maxScale;
 	}
 
+	/**
+	 * SLD Rules können die Paramter MinScaleDenominator und MaxScaleDenominator
+	 * enthalten. Dadurch können Elemente für manche Zoom-Stufen deaktiviert
+	 * werden.
+	 * 
+	 * @param fc
+	 *            Die zu filternde FeatureCollection. Diese wird nicht
+	 *            verändert.
+	 * @param style
+	 *            Der Style, mit dem die Features gerendert werden (z.b.
+	 *            layer.getStyle() )
+	 * 
+	 * @return Eine FeatureCollection in welcher nur die Features enthalten
+	 *         sind, welche bei aktuellen Scale mit dem übergebenen Style
+	 *         gerendert werden.
+	 * 
+	 * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons
+	 *         Kr&uuml;ger</a>
+	 */
+	public static FeatureCollection<SimpleFeatureType, SimpleFeature> filterSLDVisibleOnly(
+			final FeatureCollection<SimpleFeatureType, SimpleFeature> fc,
+			final Style style, XMapPane xMapPane) {
+
+		if (xMapPane == null || style == null)
+			return new EmptyFeatureCollection(fc.getSchema());
+
+		// Der "scaleDenominator" der aktuellen JMapPane
+		Double scaleDenominator = RendererUtilities.calculateOGCScale(
+				new ReferencedEnvelope(xMapPane.getMapArea(), xMapPane
+						.getContext().getCoordinateReferenceSystem()), xMapPane
+						.getBounds().width, null);
+
+		return filterSLDVisibleOnly(fc, style, scaleDenominator);
+	}
+
 }

Modified: branches/1.0-gt2-2.6/src/schmitzm/jfree/JFreeChartUtil.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/jfree/JFreeChartUtil.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/jfree/JFreeChartUtil.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -31,7 +31,6 @@
 
 import java.awt.Color;
 import java.text.DecimalFormat;
-import java.text.NumberFormat;
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;

Modified: branches/1.0-gt2-2.6/src/schmitzm/jfree/chart/SelectableChartPanel.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/jfree/chart/SelectableChartPanel.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/jfree/chart/SelectableChartPanel.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -29,8 +29,6 @@
  ******************************************************************************/
 package schmitzm.jfree.chart;
 
-import java.awt.BasicStroke;
-import java.awt.Color;
 import java.awt.event.MouseEvent;
 import java.awt.geom.Rectangle2D;
 import java.util.HashSet;

Modified: branches/1.0-gt2-2.6/src/schmitzm/jfree/chart/renderer/PointSelectionCategoryRenderer.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/jfree/chart/renderer/PointSelectionCategoryRenderer.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/jfree/chart/renderer/PointSelectionCategoryRenderer.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -32,7 +32,6 @@
 import java.awt.Color;
 import java.awt.Graphics2D;
 import java.awt.Paint;
-import java.awt.Stroke;
 import java.awt.geom.Rectangle2D;
 
 import org.apache.log4j.Logger;

Modified: branches/1.0-gt2-2.6/src/schmitzm/jfree/chart/renderer/PointSelectionXYRenderer.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/jfree/chart/renderer/PointSelectionXYRenderer.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/jfree/chart/renderer/PointSelectionXYRenderer.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -29,18 +29,10 @@
  ******************************************************************************/
 package schmitzm.jfree.chart.renderer;
 
-import java.awt.BasicStroke;
 import java.awt.Color;
-import java.awt.Graphics;
 import java.awt.Graphics2D;
 import java.awt.Paint;
-import java.awt.Stroke;
-import java.awt.Rectangle;
-import java.awt.TexturePaint;
-import java.awt.geom.Ellipse2D;
-import java.awt.geom.Line2D;
 import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
 
 import org.apache.log4j.Logger;
 import org.jfree.chart.axis.ValueAxis;
@@ -52,7 +44,6 @@
 import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
 import org.jfree.data.general.Dataset;
 import org.jfree.data.xy.XYDataset;
-import org.jfree.util.BooleanList;
 
 import schmitzm.jfree.JFreeChartUtil;
 import schmitzm.jfree.chart.selection.SeriesDatasetSelectionModel;

Modified: branches/1.0-gt2-2.6/src/schmitzm/jfree/chart/renderer/SelectionRenderer.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/jfree/chart/renderer/SelectionRenderer.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/jfree/chart/renderer/SelectionRenderer.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -30,7 +30,6 @@
 package schmitzm.jfree.chart.renderer;
 
 import java.awt.Paint;
-import java.awt.Stroke;
 
 import schmitzm.jfree.chart.selection.DatasetSelectionModel;
 import schmitzm.jfree.chart.selection.DatasetSelectionModelProvider;

Modified: branches/1.0-gt2-2.6/src/schmitzm/jfree/chart/renderer/SelectionXYLineAndShapeRenderer.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/jfree/chart/renderer/SelectionXYLineAndShapeRenderer.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/jfree/chart/renderer/SelectionXYLineAndShapeRenderer.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -32,7 +32,6 @@
 import java.awt.Color;
 import java.awt.Graphics2D;
 import java.awt.Paint;
-import java.awt.Stroke;
 import java.awt.geom.Rectangle2D;
 import java.util.HashMap;
 import java.util.Map;

Modified: branches/1.0-gt2-2.6/src/schmitzm/swing/SwingUtil.java
===================================================================
--- branches/1.0-gt2-2.6/src/schmitzm/swing/SwingUtil.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/schmitzm/swing/SwingUtil.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -29,18 +29,24 @@
  ******************************************************************************/
 package schmitzm.swing;
 
+import java.awt.AlphaComposite;
 import java.awt.BorderLayout;
 import java.awt.Color;
 import java.awt.Component;
+import java.awt.Composite;
 import java.awt.Container;
 import java.awt.Cursor;
 import java.awt.Dimension;
 import java.awt.Frame;
+import java.awt.Graphics2D;
 import java.awt.GridBagConstraints;
 import java.awt.Image;
 import java.awt.Point;
+import java.awt.Rectangle;
 import java.awt.Toolkit;
 import java.awt.Window;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
 import java.text.NumberFormat;
 import java.util.Enumeration;
 import java.util.Locale;
@@ -1032,26 +1038,97 @@
 	 * Allows to define a renderer and min- and max width of a column with just
 	 * one line of code ;-)
 	 * 
-	 * @param table 
-	 * @param modelIdx column index in model
-	 * @param cellRenderer <code>null</code> allowed
-	 * @param minwidth <code>null</code> allowed
-	 * @param prefwidth <code>null</code> allowed
-	 * @param maxwidth <code>null</code> allowed
+	 * @param table
+	 * @param modelIdx
+	 *            column index in model
+	 * @param cellRenderer
+	 *            <code>null</code> allowed
+	 * @param minwidth
+	 *            <code>null</code> allowed
+	 * @param prefwidth
+	 *            <code>null</code> allowed
+	 * @param maxwidth
+	 *            <code>null</code> allowed
 	 */
 	public static void setColumnLook(JTable table, Integer modelIdx,
-			TableCellRenderer cellRenderer, Integer minWidth, Integer preferredWidth, Integer maxWidth) {
+			TableCellRenderer cellRenderer, Integer minWidth,
+			Integer preferredWidth, Integer maxWidth) {
 
 		int idx = table.convertColumnIndexToView(modelIdx);
 		if (cellRenderer != null)
 			table.getColumnModel().getColumn(idx).setCellRenderer(cellRenderer);
 		if (minWidth != null)
 			table.getColumnModel().getColumn(idx).setMinWidth(minWidth);
-		if (preferredWidth!= null)
-			table.getColumnModel().getColumn(idx).setPreferredWidth(preferredWidth);
+		if (preferredWidth != null)
+			table.getColumnModel().getColumn(idx).setPreferredWidth(
+					preferredWidth);
 		if (maxWidth != null)
 			table.getColumnModel().getColumn(idx).setMaxWidth(maxWidth);
 
 	}
 
+	/**
+	 * Erase an image. This is much faster than recreating a new BufferedImage
+	 */
+	public static void clearImage(BufferedImage image) {
+		Graphics2D baseImageGraphics = (Graphics2D) image.getGraphics();
+		Composite composite = baseImageGraphics.getComposite();
+		baseImageGraphics.setComposite(AlphaComposite.Clear);
+		Rectangle2D.Double rect = new Rectangle2D.Double(0, 0,
+				image.getWidth(), image.getHeight());
+		baseImageGraphics.fill(rect);
+		baseImageGraphics.setComposite(composite);
+	}
+
+	/**
+	 * Clears the four rectengular areas around a given inner {@link Rectangle}.
+	 * Clearing is faster than painting.
+	 * 
+	 * @param paintArea
+	 *            The {@link Rectangle} that shall not be cleared.
+	 * @param clearArea
+	 *            The {@link Rectangle} that shall be cleared, except for where
+	 *            it intersects with the paintArea.
+	 */
+	public static void clearAround(Graphics2D graphics, Rectangle paintArea,
+			Rectangle clearArea) {
+
+		// Clear left of the painted area if needed
+		if (clearArea.getMinX() < paintArea.getMinX()) {
+			graphics.clearRect(
+					(int) clearArea.getMinX(), 
+					(int) clearArea.getMinY(), 
+					(int) paintArea.getMinX(), 
+					(int) clearArea.getMaxY());
+		}
+
+		// Clear right of the painted area if needed
+		if (clearArea.getMaxX() > paintArea.getMaxX()) {
+			graphics.clearRect(
+					(int) paintArea.getMaxX(), 
+					(int) clearArea.getMinY(), 
+					(int) clearArea.getMaxX(), 
+					(int) clearArea.getMaxY());
+		}
+		
+		// Clear above of the painted area if needed
+		if (clearArea.getMinY() < paintArea.getMinY()) {
+			graphics.clearRect(
+					(int) clearArea.getMinX(), 
+					(int) clearArea.getMinY(), 
+					(int) clearArea.getMaxX(), 
+					(int) paintArea.getMinY());
+		}
+		
+		// Clear below of the painted area if needed
+		if (clearArea.getMaxY() > paintArea.getMaxY()) {
+			graphics.clearRect(
+					(int) clearArea.getMinX(), 
+					(int) paintArea.getMaxY(), 
+					(int) clearArea.getMaxX(), 
+					(int) clearArea.getMaxY());
+		}
+		
+	}
+
 }

Modified: branches/1.0-gt2-2.6/src/skrueger/geotools/MapPaneToolBar.java
===================================================================
--- branches/1.0-gt2-2.6/src/skrueger/geotools/MapPaneToolBar.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/skrueger/geotools/MapPaneToolBar.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -52,8 +52,8 @@
 
 import org.apache.log4j.Logger;
 
-import schmitzm.geotools.gui.JMapPane;
-import schmitzm.geotools.map.event.JMapPaneEvent;
+import schmitzm.geotools.gui.SelectableXMapPane;
+import schmitzm.geotools.map.event.MapPaneEvent;
 import schmitzm.geotools.map.event.JMapPaneListener;
 import schmitzm.geotools.map.event.MapAreaChangedEvent;
 import schmitzm.lang.LangUtil;
@@ -66,7 +66,7 @@
 import com.vividsolutions.jts.geom.Envelope;
 
 /**
- * A toolbar to control an {@link JMapPane} (Atlas visualization). This contains
+ * A toolbar to control an {@link SelectableXMapPane} (Atlas visualization). This contains
  * two types of buttons. A group of <i>tools</i> for the mouse actions on the
  * map represented by {@link JToggleButton JToggleButtons}, where only one tool
  * can be activated every time. And some (general) <i>actions</i>, represented
@@ -140,8 +140,8 @@
 	// /** Holds the action buttons of the bar. */
 	// protected SortedMap<Integer, JButton> actionButtons = null;
 
-	/** Holds the {@link JMapPane} this tool bar controls. */
-	protected JMapPane mapPane = null;
+	/** Holds the {@link SelectableXMapPane} this tool bar controls. */
+	protected SelectableXMapPane mapPane = null;
 
 	/**
 	 * A List to remember the last Envelopes that have been watched. Used for
@@ -176,7 +176,7 @@
 
 	/**
 	 * Creates a new toolbar. Notice: This toolbar does nothing until
-	 * {@link #setMapPane(JMapPane)} is called!
+	 * {@link #setMapPane(SelectableXMapPane)} is called!
 	 */
 	public MapPaneToolBar() {
 		this(null);
@@ -195,9 +195,9 @@
 	 * Creates a new tool bar.
 	 * 
 	 * @param mapPane
-	 *            {@link JMapPane} the tool bar controls
+	 *            {@link SelectableXMapPane} the tool bar controls
 	 */
-	public MapPaneToolBar(JMapPane mapPane) {
+	public MapPaneToolBar(SelectableXMapPane mapPane) {
 		super("Control the map", JToolBar.HORIZONTAL);
 
 		// I want to see nothing on the background
@@ -208,7 +208,7 @@
 
 		// Create a Listener to listen to the zooms on the JMapPane
 		this.mapPaneListener = new JMapPaneListener() {
-			public void performMapPaneEvent(JMapPaneEvent e) {
+			public void performMapPaneEvent(MapPaneEvent e) {
 				if (!(e instanceof MapAreaChangedEvent))
 					return;
 
@@ -269,13 +269,13 @@
 	}
 
 	/**
-	 * Sets the {@link JMapPane} controlled by this tool bar.
+	 * Sets the {@link SelectableXMapPane} controlled by this tool bar.
 	 * 
 	 * @param mapPane
-	 *            {@link JMapPane} to control (if {@code null} this tool bar
+	 *            {@link SelectableXMapPane} to control (if {@code null} this tool bar
 	 *            controls NOTHING!)
 	 */
-	public void setMapPane(JMapPane mapPane) {
+	public void setMapPane(SelectableXMapPane mapPane) {
 		// Remove listener from old MapPane
 		if (this.mapPane != null)
 			this.mapPane.removeMapPaneListener(mapPaneListener);
@@ -426,39 +426,31 @@
 		switch (tool) {
 		case TOOL_PAN:
 			// Set the mouse tool to "Panning"
-			mapPane.setWindowSelectionState(JMapPane.NONE);
-			mapPane.setState(JMapPane.PAN);
-			mapPane.setNormalCursor(SwingUtil.PAN_CURSOR);
+			mapPane.setState(SelectableXMapPane.PAN);
+//			mapPane.setNormalCursor(SwingUtil.PAN_CURSOR);
 			break;
 		case TOOL_INFO:
 			// Set the mouse tool to "Info"
-			mapPane.setWindowSelectionState(JMapPane.NONE);
-			mapPane.setState(JMapPane.SELECT_TOP); // Why not:
-			// JMapPane.SELECT_TOP_ONEONLY
-			// properly removed it to save
-			// performance
-			mapPane.setNormalCursor(SwingUtil.CROSSHAIR_CURSOR);
+			mapPane.setState(SelectableXMapPane.SELECT_ONE_FROM_TOP); 
+//			mapPane.setNormalCursor(SwingUtil.CROSSHAIR_CURSOR);
 			break;
 		case TOOL_ZOOMIN:
 			// Set the mouse tool to "Zoom in"
-			mapPane.setWindowSelectionState(JMapPane.ZOOM_IN);
-			mapPane.setState(JMapPane.ZOOM_IN);
-			mapPane.setNormalCursor(SwingUtil.ZOOMIN_CURSOR);
+			mapPane.setState(SelectableXMapPane.ZOOM_IN);
+//			mapPane.setNormalCursor(SwingUtil.ZOOMIN_CURSOR);
 			break;
 		case TOOL_ZOOMOUT:
 			// Set the mouse tool to "Zoom out"
-			mapPane.setWindowSelectionState(JMapPane.NONE);
-			mapPane.setState(JMapPane.ZOOM_OUT);
-			mapPane.setNormalCursor(SwingUtil.ZOOMOUT_CURSOR);
+			mapPane.setState(SelectableXMapPane.ZOOM_OUT);
+//			mapPane.setNormalCursor(SwingUtil.ZOOMOUT_CURSOR);
 			break;
 		default:
 			// Set map actions to default
-			mapPane.setWindowSelectionState(JMapPane.NONE);
-			mapPane.setState(JMapPane.NONE);
-			mapPane.setNormalCursor(null);
+			mapPane.setState(SelectableXMapPane.NONE);
+//			mapPane.setNormalCursor(null);
 			break;
 		}
-		mapPane.updateCursor();
+//		mapPane.updateCursorAndRepaintTimer();
 	}
 
 	/**

Modified: branches/1.0-gt2-2.6/src/skrueger/geotools/MapView.java
===================================================================
--- branches/1.0-gt2-2.6/src/skrueger/geotools/MapView.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/skrueger/geotools/MapView.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -42,9 +42,9 @@
 import org.apache.log4j.Logger;
 
 import schmitzm.geotools.gui.GeoMapPane;
-import schmitzm.geotools.gui.JMapPane;
 import schmitzm.geotools.gui.MapContextControlPane;
 import schmitzm.geotools.gui.MapPaneStatusBar;
+import schmitzm.geotools.gui.SelectableXMapPane;
 import schmitzm.geotools.styling.ColorMapManager;
 
 /**
@@ -71,21 +71,20 @@
 	/**
 	 * Creates a new {@link MapView}. A {@link MapView} is a combination of a
 	 * {@link GeoMapPane}, a {@link MapContextManagerInterface} on the left, and
-	 * some buttons floating over the {@link JMapPane}
+	 * some buttons floating over the {@link SelectableXMapPane}
 	 */
 	public MapView(Component parentGui, MapPaneToolBar toolBar) {
 		super(new BorderLayout());
 		// Call initialize() by yourself afterwards.
 		// Needed because variables for the overwritten methods
 		// are not yet set.
-		getGeoMapPane().getMapPane().setWaitCursorComponent(parentGui);
 		jToolBar = toolBar;
 	}
 
 	/**
 	 * Creates a new {@link MapView}. A {@link MapView} is a combination of a
 	 * {@link GeoMapPane}, a {@link MapContextManagerInterface} on the left, and
-	 * some buttons floating over the {@link JMapPane}
+	 * some buttons floating over the {@link SelectableXMapPane}
 	 */
 	public MapView(Component parentGui) {
 		this(parentGui, null);
@@ -226,7 +225,7 @@
 	/**
 	 * Liefert den Karten-Bereich der Komponente.
 	 */
-	public final JMapPane getMapPane() {
+	public final SelectableXMapPane getMapPane() {
 		return getGeoMapPane().getMapPane();
 	}
 

Modified: branches/1.0-gt2-2.6/src/skrueger/geotools/labelsearch/LabelSearch.java
===================================================================
--- branches/1.0-gt2-2.6/src/skrueger/geotools/labelsearch/LabelSearch.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/skrueger/geotools/labelsearch/LabelSearch.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -73,9 +73,9 @@
 		return RESOURCE.getString(key, values);
 	}
 
-	protected final schmitzm.geotools.gui.JMapPane mapPane;
+	protected final schmitzm.geotools.gui.SelectableXMapPane mapPane;
 
-	public LabelSearch(final schmitzm.geotools.gui.JMapPane mapPane) {
+	public LabelSearch(final schmitzm.geotools.gui.SelectableXMapPane mapPane) {
 		this.mapPane = mapPane;
 	}
 

Modified: branches/1.0-gt2-2.6/src/skrueger/geotools/labelsearch/SearchMapDialog.java
===================================================================
--- branches/1.0-gt2-2.6/src/skrueger/geotools/labelsearch/SearchMapDialog.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/skrueger/geotools/labelsearch/SearchMapDialog.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -59,7 +59,7 @@
 import org.apache.log4j.Logger;
 import org.geotools.swing.ExceptionMonitor;
 
-import schmitzm.geotools.gui.JMapPane;
+import schmitzm.geotools.gui.SelectableXMapPane;
 import schmitzm.swing.SortableJTable;
 import schmitzm.swing.SwingUtil;
 
@@ -83,10 +83,10 @@
 		searchTextField.setText(text);
 	}
 
-	private final JMapPane mapPane;
+	private final SelectableXMapPane mapPane;
 
 	/**
-	 * The dialog will be relative to the {@link JMapPane}s parent
+	 * The dialog will be relative to the {@link SelectableXMapPane}s parent
 	 * {@link Window}.
 	 * 
 	 * @param parent
@@ -95,7 +95,7 @@
 	 * @param windowTitle
 	 *            A title to be used for the dialog.
 	 */
-	public SearchMapDialog(LabelSearch labelSearch, JMapPane mapPane,
+	public SearchMapDialog(LabelSearch labelSearch, SelectableXMapPane mapPane,
 			final String windowTitle) {
 		super(SwingUtil.getParentWindow(mapPane), windowTitle);
 		this.labelSearch = labelSearch;
@@ -157,7 +157,7 @@
 	}
 
 	/**
-	 * Performes a search on the {@link JMapPane}'s labels and outputs the
+	 * Performes a search on the {@link SelectableXMapPane}'s labels and outputs the
 	 * possible numerouse results.
 	 * 
 	 * @param text

Modified: branches/1.0-gt2-2.6/src/skrueger/geotools/labelsearch/SearchResultFeature.java
===================================================================
--- branches/1.0-gt2-2.6/src/skrueger/geotools/labelsearch/SearchResultFeature.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/skrueger/geotools/labelsearch/SearchResultFeature.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -41,13 +41,13 @@
 
 	private final SimpleFeature feature;
 	private final String title;
-	private final schmitzm.geotools.gui.JMapPane mapPane;
+	private final schmitzm.geotools.gui.SelectableXMapPane mapPane;
 	private final String inTitle;
 
 	private final MapLayer mapLayer;
 
 	public SearchResultFeature(SimpleFeature feature, String title, String inTitle,
-			schmitzm.geotools.gui.JMapPane mapPane, MapLayer mapLayer) {
+			schmitzm.geotools.gui.SelectableXMapPane mapPane, MapLayer mapLayer) {
 		this.feature = feature;
 		this.title = title;
 		this.inTitle = inTitle;

Modified: branches/1.0-gt2-2.6/src/skrueger/geotools/selection/FeatureMapLayerSelectionSynchronizer.java
===================================================================
--- branches/1.0-gt2-2.6/src/skrueger/geotools/selection/FeatureMapLayerSelectionSynchronizer.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/skrueger/geotools/selection/FeatureMapLayerSelectionSynchronizer.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -42,11 +42,9 @@
  **/
 package skrueger.geotools.selection;
 
-import java.awt.RenderingHints;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.io.File;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Set;
@@ -60,9 +58,6 @@
 import org.geotools.feature.FeatureIterator;
 import org.geotools.filter.FidFilterImpl;
 import org.geotools.map.MapLayer;
-import org.geotools.renderer.GTRenderer;
-import org.geotools.renderer.label.LabelCacheImpl;
-import org.geotools.renderer.lite.StreamingRenderer;
 import org.geotools.styling.FeatureTypeStyle;
 import org.geotools.styling.Style;
 import org.geotools.styling.visitor.DuplicatingStyleVisitor;
@@ -73,10 +68,9 @@
 import org.opengis.filter.identity.FeatureId;
 
 import schmitzm.geotools.FilterUtil;
-import schmitzm.geotools.GTUtil;
-import schmitzm.geotools.gui.JMapPane;
+import schmitzm.geotools.gui.SelectableXMapPane;
 import schmitzm.geotools.map.event.FeatureSelectedEvent;
-import schmitzm.geotools.map.event.JMapPaneEvent;
+import schmitzm.geotools.map.event.MapPaneEvent;
 import schmitzm.geotools.map.event.JMapPaneListener;
 import schmitzm.geotools.styling.StylingUtil;
 import skrueger.geotools.MapPaneToolBar;
@@ -110,9 +104,8 @@
 	 */
 	protected final MapLayer mapLayer;
 	protected final StyledFeaturesInterface<?> styledLayer;
-	protected final JMapPane mapPane;
+	protected final SelectableXMapPane mapPane;
 	private final MapPaneToolBar toolBar;
-	private final HashMap<Object, Object> defaultGTRenderingHints;
 
 	/**
 	 * Creates a new synchronizer
@@ -127,8 +120,7 @@
 	public FeatureMapLayerSelectionSynchronizer(
 			StyledFeatureLayerSelectionModel layerSelModel,
 			StyledFeaturesInterface<?> styledLayer, MapLayer mapLayer,
-			JMapPane mapPane, MapPaneToolBar toolBar,
-			HashMap<Object, Object> defaultGTRenderingHints) {
+			SelectableXMapPane mapPane, MapPaneToolBar toolBar) {
 
 		super(layerSelModel);
 		this.styledLayer = styledLayer;
@@ -136,10 +128,6 @@
 		this.mapLayer = mapLayer;
 		this.mapPane = mapPane;
 		this.toolBar = toolBar;
-		if (defaultGTRenderingHints != null)
-			this.defaultGTRenderingHints = defaultGTRenderingHints;
-		else
-			this.defaultGTRenderingHints = new HashMap<Object, Object>();
 	}
 
 	/**
@@ -405,40 +393,43 @@
 		return false;
 	}
 
+	/**
+	 * Replaces the local renderer 
+	 */
 	private void replaceRenderer() {
-		//
-		// // Has to be done before we apply the new Renderer
-		// mapLayer.setStyle(style);
+//		//
+//		// // Has to be done before we apply the new Renderer
+//		// mapLayer.setStyle(style);
+//
+//		GTRenderer oldRenderer = mapPane.getLocalRenderer();
+//
+//		/**
+//		 * Explicitly putting a new instance of LabelCacheDefault into the
+//		 * renderer instance, so JMapPane doesn't reuse the old one. This is
+//		 * very useful when changing the TextSymbolizer with AtlasStyler<br/>
+//		 * SK 9.7.09: It's not enought to user LabelCache.clear(). We can not
+//		 * reuse the old Renderer - better to create a new one!
+//		 */
+//		final GTRenderer newRenderer = GTUtil.createGTRenderer();
+//
+//		final HashMap<Object, Object> rendererHints = defaultGTRenderingHints;
+//		rendererHints.put(StreamingRenderer.LABEL_CACHE_KEY,
+//				new LabelCacheImpl());
+//
+//		newRenderer.setRendererHints(rendererHints);
+//		mapPane.setLocalRenderer(newRenderer);
+//
+//		if (oldRenderer != null) {
+//
+//			RenderingHints java2DHints = oldRenderer.getJava2DHints();
+//			if (java2DHints != null) {
+//				newRenderer.setJava2DHints(java2DHints);
+//			}
+//
+//			oldRenderer.setContext(null);
+//			oldRenderer = null;
+//		}
 
-		GTRenderer oldRenderer = mapPane.getRenderer();
-
-		/**
-		 * Explicitly putting a new instance of LabelCacheDefault into the
-		 * renderer instance, so JMapPane doesn't reuse the old one. This is
-		 * very useful when changing the TextSymbolizer with AtlasStyler<br/>
-		 * SK 9.7.09: It's not enought to user LabelCache.clear(). We can not
-		 * reuse the old Renderer - better to create a new one!
-		 */
-		final GTRenderer newRenderer = GTUtil.createGTRenderer();
-
-		final HashMap<Object, Object> rendererHints = defaultGTRenderingHints;
-		rendererHints.put(StreamingRenderer.LABEL_CACHE_KEY,
-				new LabelCacheImpl());
-
-		newRenderer.setRendererHints(rendererHints);
-		mapPane.setRenderer(newRenderer);
-
-		if (oldRenderer != null) {
-
-			RenderingHints java2DHints = oldRenderer.getJava2DHints();
-			if (java2DHints != null) {
-				newRenderer.setJava2DHints(java2DHints);
-			}
-
-			oldRenderer.setContext(null);
-			oldRenderer = null;
-		}
-
 		mapPane.refresh();
 
 	}
@@ -448,7 +439,7 @@
 	 * {@link StyledFeatureLayerSelectionModel}
 	 */
 	@Override
-	public void performMapPaneEvent(JMapPaneEvent e) {
+	public void performMapPaneEvent(MapPaneEvent e) {
 
 		// Ignore event if it is caused by us or the synchronizer is disabled.
 		if (!isEnabled() || selectionChangeCausedByMe)

Modified: branches/1.0-gt2-2.6/src/skrueger/swing/CancellableDialogManager.java
===================================================================
--- branches/1.0-gt2-2.6/src/skrueger/swing/CancellableDialogManager.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/skrueger/swing/CancellableDialogManager.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -27,7 +27,7 @@
 	}
 
 	/**
-	 * Tells the suer that the dialog shall be closed. The user may save, cancel or abort the closing.
+	 * Tells the user that the dialog shall be closed. The user may save, cancel or abort the closing.
 	 * 
 	 * @return <code>true</code> if there is no open instance or the instance has been disposed
 	 */

Modified: branches/1.0-gt2-2.6/src/skrueger/swing/CancellableTabbedDialogAdapter.java
===================================================================
--- branches/1.0-gt2-2.6/src/skrueger/swing/CancellableTabbedDialogAdapter.java	2009-11-03 14:38:26 UTC (rev 508)
+++ branches/1.0-gt2-2.6/src/skrueger/swing/CancellableTabbedDialogAdapter.java	2009-11-05 08:51:33 UTC (rev 509)
@@ -10,7 +10,6 @@
 
 import net.miginfocom.swing.MigLayout;
 import schmitzm.swing.JPanel;
-import schmitzm.swing.SwingUtil;
 
 public abstract class CancellableTabbedDialogAdapter extends
 		CancellableDialogAdapter {



More information about the Schmitzm-commits mailing list